diff options
Diffstat (limited to 'lib')
126 files changed, 14088 insertions, 19004 deletions
diff --git a/lib/doc-support/Makefile b/lib/doc-support/Makefile deleted file mode 100644 index 553b61f..0000000 --- a/lib/doc-support/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -GETOPT = ${topdir}/builtins/getopt.o -OBJECTS = texindex.o $(GETOPT) -SOURCES = texindex.c - -LDFLAGS = -g - -srcdir = . -VPATH = .:$(srcdir) - -.c.o: - rm -f $@ - $(CC) $(CFLAGS) -c $< - -all: texindex - -texindex: texindex.o - $(CC) $(LDFLAGS) -o $@ $(OBJECTS) $(LIBS) - -clean: - rm -f texindex.o - -realclean distclean maintainer-clean: clean - rm -f texindex diff --git a/lib/doc-support/getopt.h b/lib/doc-support/getopt.h deleted file mode 100644 index 45541f5..0000000 --- a/lib/doc-support/getopt.h +++ /dev/null @@ -1,129 +0,0 @@ -/* Declarations for getopt. - Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef _GETOPT_H -#define _GETOPT_H 1 - -#ifdef __cplusplus -extern "C" { -#endif - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -extern char *optarg; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns EOF, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -extern int optind; - -/* Callers store zero here to inhibit the error message `getopt' prints - for unrecognized options. */ - -extern int opterr; - -/* Set to an option character which was unrecognized. */ - -extern int optopt; - -/* Describe the long-named options requested by the application. - The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector - of `struct option' terminated by an element containing a name which is - zero. - - The field `has_arg' is: - no_argument (or 0) if the option does not take an argument, - required_argument (or 1) if the option requires an argument, - optional_argument (or 2) if the option takes an optional argument. - - If the field `flag' is not NULL, it points to a variable that is set - to the value given in the field `val' when the option is found, but - left unchanged if the option is not found. - - To have a long-named option do something other than set an `int' to - a compiled-in constant, such as set a value from `optarg', set the - option's `flag' field to zero and its `val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero `flag' field, `getopt' - returns the contents of the `val' field. */ - -struct option -{ -#if __STDC__ - const char *name; -#else - char *name; -#endif - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; -}; - -/* Names for the values of the `has_arg' field of `struct option'. */ - -#define no_argument 0 -#define required_argument 1 -#define optional_argument 2 - -#if __STDC__ -#if defined(__GNU_LIBRARY__) -/* Many other libraries have conflicting prototypes for getopt, with - differences in the consts, in stdlib.h. To avoid compilation - errors, only prototype getopt for the GNU C library. */ -extern int getopt (int argc, char *const *argv, const char *shortopts); -#else /* not __GNU_LIBRARY__ */ -extern int getopt (); -#endif /* not __GNU_LIBRARY__ */ -extern int getopt_long (int argc, char *const *argv, const char *shortopts, - const struct option *longopts, int *longind); -extern int getopt_long_only (int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind); - -/* Internal only. Users should not call this directly. */ -extern int _getopt_internal (int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind, - int long_only); -#else /* not __STDC__ */ -extern int getopt (); -extern int getopt_long (); -extern int getopt_long_only (); - -extern int _getopt_internal (); -#endif /* not __STDC__ */ - -#ifdef __cplusplus -} -#endif - -#endif /* _GETOPT_H */ diff --git a/lib/doc-support/texindex.c b/lib/doc-support/texindex.c deleted file mode 100644 index 9233bab..0000000 --- a/lib/doc-support/texindex.c +++ /dev/null @@ -1,1666 +0,0 @@ -/* Prepare TeX index dribble output into an actual index. - - Version 1.45 - - Copyright (C) 1987, 1991, 1992 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - - -#include <stdio.h> -#include <ctype.h> -#include <errno.h> -#include "getopt.h" -#include "bashansi.h" - -#if !defined (errno) -extern int errno; -#endif - -#if defined (HAVE_UNISTD_H) -# include <unistd.h> -#else /* !HAVE_UNISTD_H */ -extern long lseek (); -#endif /* !HAVE_UNISTD_H */ - -extern char *mktemp (); - -#if !defined (HAVE_STRERROR) -extern int sys_nerr; -extern char *sys_errlist[]; -#endif - -#include <sys/types.h> - -#if defined (_AIX) || !defined (_POSIX_VERSION) -# include <sys/file.h> -#endif - -#include <fcntl.h> - -#define TI_NO_ERROR 0 -#define TI_FATAL_ERROR 1 - -#if !defined (SEEK_SET) -# define SEEK_SET 0 -# define SEEK_CUR 1 -# define SEEK_END 2 -#endif /* !SEEK_SET */ - -/* When sorting in core, this structure describes one line - and the position and length of its first keyfield. */ -struct lineinfo -{ - char *text; /* The actual text of the line. */ - union { - char *text; /* The start of the key (for textual comparison). */ - long number; /* The numeric value (for numeric comparison). */ - } key; - long keylen; /* Length of KEY field. */ -}; - -/* This structure describes a field to use as a sort key. */ -struct keyfield -{ - int startwords; /* Number of words to skip. */ - int startchars; /* Number of additional chars to skip. */ - int endwords; /* Number of words to ignore at end. */ - int endchars; /* Ditto for characters of last word. */ - char ignore_blanks; /* Non-zero means ignore spaces and tabs. */ - char fold_case; /* Non-zero means case doesn't matter. */ - char reverse; /* Non-zero means compare in reverse order. */ - char numeric; /* Non-zeros means field is ASCII numeric. */ - char positional; /* Sort according to file position. */ - char braced; /* Count balanced-braced groupings as fields. */ -}; - -/* Vector of keyfields to use. */ -struct keyfield keyfields[3]; - -/* Number of keyfields stored in that vector. */ -int num_keyfields = 3; - -/* Vector of input file names, terminated with a null pointer. */ -char **infiles; - -/* Vector of corresponding output file names, or NULL, meaning default it - (add an `s' to the end). */ -char **outfiles; - -/* Length of `infiles'. */ -int num_infiles; - -/* Pointer to the array of pointers to lines being sorted. */ -char **linearray; - -/* The allocated length of `linearray'. */ -long nlines; - -/* Directory to use for temporary files. On Unix, it ends with a slash. */ -char *tempdir; - -/* Start of filename to use for temporary files. */ -char *tempbase; - -/* Number of last temporary file. */ -int tempcount; - -/* Number of last temporary file already deleted. - Temporary files are deleted by `flush_tempfiles' in order of creation. */ -int last_deleted_tempcount; - -/* During in-core sort, this points to the base of the data block - which contains all the lines of data. */ -char *text_base; - -/* Additional command switches .*/ - -/* Nonzero means do not delete tempfiles -- for debugging. */ -int keep_tempfiles; - -/* The name this program was run with. */ -char *program_name; - -/* Forward declarations of functions in this file. */ - -void decode_command (); -void sort_in_core (); -void sort_offline (); -char **parsefile (); -char *find_field (); -char *find_pos (); -long find_value (); -char *find_braced_pos (); -char *find_braced_end (); -void writelines (); -int compare_field (); -int compare_full (); -long readline (); -int merge_files (); -int merge_direct (); -void pfatal_with_name (); -void fatal (); -void error (); -void *xmalloc (), *xrealloc (); -char *concat (); -char *maketempname (); -void flush_tempfiles (); -char *tempcopy (); - -#define MAX_IN_CORE_SORT 500000 - -void -main (argc, argv) - int argc; - char **argv; -{ - int i; - - tempcount = 0; - last_deleted_tempcount = 0; - program_name = argv[0]; - - /* Describe the kind of sorting to do. */ - /* The first keyfield uses the first braced field and folds case. */ - keyfields[0].braced = 1; - keyfields[0].fold_case = 1; - keyfields[0].endwords = -1; - keyfields[0].endchars = -1; - - /* The second keyfield uses the second braced field, numerically. */ - keyfields[1].braced = 1; - keyfields[1].numeric = 1; - keyfields[1].startwords = 1; - keyfields[1].endwords = -1; - keyfields[1].endchars = -1; - - /* The third keyfield (which is ignored while discarding duplicates) - compares the whole line. */ - keyfields[2].endwords = -1; - keyfields[2].endchars = -1; - - decode_command (argc, argv); - - tempbase = mktemp (concat ("txiXXXXXX", "", "")); - - /* Process input files completely, one by one. */ - - for (i = 0; i < num_infiles; i++) - { - int desc; - long ptr; - char *outfile; - - desc = open (infiles[i], O_RDONLY, 0); - if (desc < 0) - pfatal_with_name (infiles[i]); - lseek (desc, 0L, SEEK_END); - ptr = lseek (desc, 0L, SEEK_CUR); - - close (desc); - - outfile = outfiles[i]; - if (!outfile) - { - outfile = concat (infiles[i], "s", ""); - } - - if (ptr < MAX_IN_CORE_SORT) - /* Sort a small amount of data. */ - sort_in_core (infiles[i], ptr, outfile); - else - sort_offline (infiles[i], ptr, outfile); - } - - flush_tempfiles (tempcount); - exit (TI_NO_ERROR); -} - -void -usage () -{ - fprintf (stderr, "\ -Usage: %s [-k] infile [-o outfile] ...\n", program_name); - exit (1); -} - -/* Decode the command line arguments to set the parameter variables - and set up the vector of keyfields and the vector of input files. */ - -void -decode_command (argc, argv) - int argc; - char **argv; -{ - int optc; - char **ip; - char **op; - - /* Store default values into parameter variables. */ - - tempdir = getenv ("TMPDIR"); - if (tempdir == NULL) - tempdir = "/tmp/"; - else - tempdir = concat (tempdir, "/", ""); - - keep_tempfiles = 0; - - /* Allocate ARGC input files, which must be enough. */ - - infiles = (char **) xmalloc (argc * sizeof (char *)); - outfiles = (char **) xmalloc (argc * sizeof (char *)); - ip = infiles; - op = outfiles; - - while ((optc = getopt (argc, argv, "-ko:")) != EOF) - { - switch (optc) - { - case 1: /* Non-option filename. */ - *ip++ = optarg; - *op++ = NULL; - break; - - case 'k': - keep_tempfiles = 1; - break; - - case 'o': - if (op > outfiles) - *(op - 1) = optarg; - break; - - default: - usage (); - } - } - - /* Record number of keyfields and terminate list of filenames. */ - num_infiles = ip - infiles; - *ip = 0; - if (num_infiles == 0) - usage (); -} - -/* Return a name for a temporary file. */ - -char * -maketempname (count) - int count; -{ - char tempsuffix[10]; - sprintf (tempsuffix, "%d", count); - return concat (tempdir, tempbase, tempsuffix); -} - -/* Delete all temporary files up to TO_COUNT. */ - -void -flush_tempfiles (to_count) - int to_count; -{ - if (keep_tempfiles) - return; - while (last_deleted_tempcount < to_count) - unlink (maketempname (++last_deleted_tempcount)); -} - -/* Copy the input file open on IDESC into a temporary file - and return the temporary file name. */ - -#define BUFSIZE 1024 - -char * -tempcopy (idesc) - int idesc; -{ - char *outfile = maketempname (++tempcount); - int odesc; - char buffer[BUFSIZE]; - - odesc = open (outfile, O_WRONLY | O_CREAT, 0666); - - if (odesc < 0) - pfatal_with_name (outfile); - - while (1) - { - int nread = read (idesc, buffer, BUFSIZE); - write (odesc, buffer, nread); - if (!nread) - break; - } - - close (odesc); - - return outfile; -} - -/* Compare LINE1 and LINE2 according to the specified set of keyfields. */ - -int -compare_full (line1, line2) - char **line1, **line2; -{ - int i; - - /* Compare using the first keyfield; - if that does not distinguish the lines, try the second keyfield; - and so on. */ - - for (i = 0; i < num_keyfields; i++) - { - long length1, length2; - char *start1 = find_field (&keyfields[i], *line1, &length1); - char *start2 = find_field (&keyfields[i], *line2, &length2); - int tem = compare_field (&keyfields[i], start1, length1, *line1 - text_base, - start2, length2, *line2 - text_base); - if (tem) - { - if (keyfields[i].reverse) - return -tem; - return tem; - } - } - - return 0; /* Lines match exactly. */ -} - -/* Compare LINE1 and LINE2, described by structures - in which the first keyfield is identified in advance. - For positional sorting, assumes that the order of the lines in core - reflects their nominal order. */ - -int -compare_prepared (line1, line2) - struct lineinfo *line1, *line2; -{ - int i; - int tem; - char *text1, *text2; - - /* Compare using the first keyfield, which has been found for us already. */ - if (keyfields->positional) - { - if (line1->text - text_base > line2->text - text_base) - tem = 1; - else - tem = -1; - } - else if (keyfields->numeric) - tem = line1->key.number - line2->key.number; - else - tem = compare_field (keyfields, line1->key.text, line1->keylen, 0, - line2->key.text, line2->keylen, 0); - if (tem) - { - if (keyfields->reverse) - return -tem; - return tem; - } - - text1 = line1->text; - text2 = line2->text; - - /* Compare using the second keyfield; - if that does not distinguish the lines, try the third keyfield; - and so on. */ - - for (i = 1; i < num_keyfields; i++) - { - long length1, length2; - char *start1 = find_field (&keyfields[i], text1, &length1); - char *start2 = find_field (&keyfields[i], text2, &length2); - int tem = compare_field (&keyfields[i], start1, length1, text1 - text_base, - start2, length2, text2 - text_base); - if (tem) - { - if (keyfields[i].reverse) - return -tem; - return tem; - } - } - - return 0; /* Lines match exactly. */ -} - -/* Like compare_full but more general. - You can pass any strings, and you can say how many keyfields to use. - POS1 and POS2 should indicate the nominal positional ordering of - the two lines in the input. */ - -int -compare_general (str1, str2, pos1, pos2, use_keyfields) - char *str1, *str2; - long pos1, pos2; - int use_keyfields; -{ - int i; - - /* Compare using the first keyfield; - if that does not distinguish the lines, try the second keyfield; - and so on. */ - - for (i = 0; i < use_keyfields; i++) - { - long length1, length2; - char *start1 = find_field (&keyfields[i], str1, &length1); - char *start2 = find_field (&keyfields[i], str2, &length2); - int tem = compare_field (&keyfields[i], start1, length1, pos1, - start2, length2, pos2); - if (tem) - { - if (keyfields[i].reverse) - return -tem; - return tem; - } - } - - return 0; /* Lines match exactly. */ -} - -/* Find the start and length of a field in STR according to KEYFIELD. - A pointer to the starting character is returned, and the length - is stored into the int that LENGTHPTR points to. */ - -char * -find_field (keyfield, str, lengthptr) - struct keyfield *keyfield; - char *str; - long *lengthptr; -{ - char *start; - char *end; - char *(*fun) (); - - if (keyfield->braced) - fun = find_braced_pos; - else - fun = find_pos; - - start = (*fun) (str, keyfield->startwords, keyfield->startchars, - keyfield->ignore_blanks); - if (keyfield->endwords < 0) - { - if (keyfield->braced) - end = find_braced_end (start); - else - { - end = start; - while (*end && *end != '\n') - end++; - } - } - else - { - end = (*fun) (str, keyfield->endwords, keyfield->endchars, 0); - if (end - str < start - str) - end = start; - } - *lengthptr = end - start; - return start; -} - -/* Return a pointer to a specified place within STR, - skipping (from the beginning) WORDS words and then CHARS chars. - If IGNORE_BLANKS is nonzero, we skip all blanks - after finding the specified word. */ - -char * -find_pos (str, words, chars, ignore_blanks) - char *str; - int words, chars; - int ignore_blanks; -{ - int i; - char *p = str; - - for (i = 0; i < words; i++) - { - char c; - /* Find next bunch of nonblanks and skip them. */ - while ((c = *p) == ' ' || c == '\t') - p++; - while ((c = *p) && c != '\n' && !(c == ' ' || c == '\t')) - p++; - if (!*p || *p == '\n') - return p; - } - - while (*p == ' ' || *p == '\t') - p++; - - for (i = 0; i < chars; i++) - { - if (!*p || *p == '\n') - break; - p++; - } - return p; -} - -/* Like find_pos but assumes that each field is surrounded by braces - and that braces within fields are balanced. */ - -char * -find_braced_pos (str, words, chars, ignore_blanks) - char *str; - int words, chars; - int ignore_blanks; -{ - int i; - int bracelevel; - char *p = str; - char c; - - for (i = 0; i < words; i++) - { - bracelevel = 1; - while ((c = *p++) != '{' && c != '\n' && c) - /* Do nothing. */ ; - if (c != '{') - return p - 1; - while (bracelevel) - { - c = *p++; - if (c == '{') - bracelevel++; - if (c == '}') - bracelevel--; - if (c == 0 || c == '\n') - return p - 1; - } - } - - while ((c = *p++) != '{' && c != '\n' && c) - /* Do nothing. */ ; - - if (c != '{') - return p - 1; - - if (ignore_blanks) - while ((c = *p) == ' ' || c == '\t') - p++; - - for (i = 0; i < chars; i++) - { - if (!*p || *p == '\n') - break; - p++; - } - return p; -} - -/* Find the end of the balanced-brace field which starts at STR. - The position returned is just before the closing brace. */ - -char * -find_braced_end (str) - char *str; -{ - int bracelevel; - char *p = str; - char c; - - bracelevel = 1; - while (bracelevel) - { - c = *p++; - if (c == '{') - bracelevel++; - if (c == '}') - bracelevel--; - if (c == 0 || c == '\n') - return p - 1; - } - return p - 1; -} - -long -find_value (start, length) - char *start; - long length; -{ - while (length != 0L) - { - if (isdigit (*start)) - return atol (start); - length--; - start++; - } - return 0l; -} - -/* Vector used to translate characters for comparison. - This is how we make all alphanumerics follow all else, - and ignore case in the first sorting. */ -int char_order[256]; - -void -init_char_order () -{ - int i; - for (i = 1; i < 256; i++) - char_order[i] = i; - - for (i = '0'; i <= '9'; i++) - char_order[i] += 512; - - for (i = 'a'; i <= 'z'; i++) - { - char_order[i] = 512 + i; - char_order[i + 'A' - 'a'] = 512 + i; - } -} - -/* Compare two fields (each specified as a start pointer and a character count) - according to KEYFIELD. - The sign of the value reports the relation between the fields. */ - -int -compare_field (keyfield, start1, length1, pos1, start2, length2, pos2) - struct keyfield *keyfield; - char *start1; - long length1; - long pos1; - char *start2; - long length2; - long pos2; -{ - if (keyfields->positional) - { - if (pos1 > pos2) - return 1; - else - return -1; - } - if (keyfield->numeric) - { - long value = find_value (start1, length1) - find_value (start2, length2); - if (value > 0) - return 1; - if (value < 0) - return -1; - return 0; - } - else - { - char *p1 = start1; - char *p2 = start2; - char *e1 = start1 + length1; - char *e2 = start2 + length2; - - while (1) - { - int c1, c2; - - if (p1 == e1) - c1 = 0; - else - c1 = *p1++; - if (p2 == e2) - c2 = 0; - else - c2 = *p2++; - - if (char_order[c1] != char_order[c2]) - return char_order[c1] - char_order[c2]; - if (!c1) - break; - } - - /* Strings are equal except possibly for case. */ - p1 = start1; - p2 = start2; - while (1) - { - int c1, c2; - - if (p1 == e1) - c1 = 0; - else - c1 = *p1++; - if (p2 == e2) - c2 = 0; - else - c2 = *p2++; - - if (c1 != c2) - /* Reverse sign here so upper case comes out last. */ - return c2 - c1; - if (!c1) - break; - } - - return 0; - } -} - -/* A `struct linebuffer' is a structure which holds a line of text. - `readline' reads a line from a stream into a linebuffer - and works regardless of the length of the line. */ - -struct linebuffer -{ - long size; - char *buffer; -}; - -/* Initialize LINEBUFFER for use. */ - -void -initbuffer (linebuffer) - struct linebuffer *linebuffer; -{ - linebuffer->size = 200; - linebuffer->buffer = (char *) xmalloc (200); -} - -/* Read a line of text from STREAM into LINEBUFFER. - Return the length of the line. */ - -long -readline (linebuffer, stream) - struct linebuffer *linebuffer; - FILE *stream; -{ - char *buffer = linebuffer->buffer; - char *p = linebuffer->buffer; - char *end = p + linebuffer->size; - - while (1) - { - int c = getc (stream); - if (p == end) - { - buffer = (char *) xrealloc (buffer, linebuffer->size *= 2); - p += buffer - linebuffer->buffer; - end += buffer - linebuffer->buffer; - linebuffer->buffer = buffer; - } - if (c < 0 || c == '\n') - { - *p = 0; - break; - } - *p++ = c; - } - - return p - buffer; -} - -/* Sort an input file too big to sort in core. */ - -void -sort_offline (infile, nfiles, total, outfile) - char *infile; - int nfiles; - long total; - char *outfile; -{ - /* More than enough. */ - int ntemps = 2 * (total + MAX_IN_CORE_SORT - 1) / MAX_IN_CORE_SORT; - char **tempfiles = (char **) xmalloc (ntemps * sizeof (char *)); - FILE *istream = fopen (infile, "r"); - int i; - struct linebuffer lb; - long linelength; - int failure = 0; - - initbuffer (&lb); - - /* Read in one line of input data. */ - - linelength = readline (&lb, istream); - - if (lb.buffer[0] != '\\' && lb.buffer[0] != '@') - { - error ("%s: not a texinfo index file", infile); - return; - } - - /* Split up the input into `ntemps' temporary files, or maybe fewer, - and put the new files' names into `tempfiles' */ - - for (i = 0; i < ntemps; i++) - { - char *outname = maketempname (++tempcount); - FILE *ostream = fopen (outname, "w"); - long tempsize = 0; - - if (!ostream) - pfatal_with_name (outname); - tempfiles[i] = outname; - - /* Copy lines into this temp file as long as it does not make file - "too big" or until there are no more lines. */ - - while (tempsize + linelength + 1 <= MAX_IN_CORE_SORT) - { - tempsize += linelength + 1; - fputs (lb.buffer, ostream); - putc ('\n', ostream); - - /* Read another line of input data. */ - - linelength = readline (&lb, istream); - if (!linelength && feof (istream)) - break; - - if (lb.buffer[0] != '\\' && lb.buffer[0] != '@') - { - error ("%s: not a texinfo index file", infile); - failure = 1; - goto fail; - } - } - fclose (ostream); - if (feof (istream)) - break; - } - - free (lb.buffer); - -fail: - /* Record number of temp files we actually needed. */ - - ntemps = i; - - /* Sort each tempfile into another tempfile. - Delete the first set of tempfiles and put the names of the second - into `tempfiles'. */ - - for (i = 0; i < ntemps; i++) - { - char *newtemp = maketempname (++tempcount); - sort_in_core (&tempfiles[i], MAX_IN_CORE_SORT, newtemp); - if (!keep_tempfiles) - unlink (tempfiles[i]); - tempfiles[i] = newtemp; - } - - if (failure) - return; - - /* Merge the tempfiles together and indexify. */ - - merge_files (tempfiles, ntemps, outfile); -} - -/* Sort INFILE, whose size is TOTAL, - assuming that is small enough to be done in-core, - then indexify it and send the output to OUTFILE (or to stdout). */ - -void -sort_in_core (infile, total, outfile) - char *infile; - long total; - char *outfile; -{ - char **nextline; - char *data = (char *) xmalloc (total + 1); - char *file_data; - long file_size; - int i; - FILE *ostream = stdout; - struct lineinfo *lineinfo; - - /* Read the contents of the file into the moby array `data'. */ - - int desc = open (infile, O_RDONLY, 0); - - if (desc < 0) - fatal ("failure reopening %s", infile); - for (file_size = 0;;) - { - i = read (desc, data + file_size, total - file_size); - if (i <= 0) - break; - file_size += i; - } - file_data = data; - data[file_size] = 0; - - close (desc); - - if (file_size > 0 && data[0] != '\\' && data[0] != '@') - { - error ("%s: not a texinfo index file", infile); - return; - } - - init_char_order (); - - /* Sort routines want to know this address. */ - - text_base = data; - - /* Create the array of pointers to lines, with a default size - frequently enough. */ - - nlines = total / 50; - if (!nlines) - nlines = 2; - linearray = (char **) xmalloc (nlines * sizeof (char *)); - - /* `nextline' points to the next free slot in this array. - `nlines' is the allocated size. */ - - nextline = linearray; - - /* Parse the input file's data, and make entries for the lines. */ - - nextline = parsefile (infile, nextline, file_data, file_size); - if (nextline == 0) - { - error ("%s: not a texinfo index file", infile); - return; - } - - /* Sort the lines. */ - - /* If we have enough space, find the first keyfield of each line in advance. - Make a `struct lineinfo' for each line, which records the keyfield - as well as the line, and sort them. */ - - lineinfo = (struct lineinfo *) malloc ((nextline - linearray) * sizeof (struct lineinfo)); - - if (lineinfo) - { - struct lineinfo *lp; - char **p; - - for (lp = lineinfo, p = linearray; p != nextline; lp++, p++) - { - lp->text = *p; - lp->key.text = find_field (keyfields, *p, &lp->keylen); - if (keyfields->numeric) - lp->key.number = find_value (lp->key.text, lp->keylen); - } - - qsort (lineinfo, nextline - linearray, sizeof (struct lineinfo), compare_prepared); - - for (lp = lineinfo, p = linearray; p != nextline; lp++, p++) - *p = lp->text; - - free (lineinfo); - } - else - qsort (linearray, nextline - linearray, sizeof (char *), compare_full); - - /* Open the output file. */ - - if (outfile) - { - ostream = fopen (outfile, "w"); - if (!ostream) - pfatal_with_name (outfile); - } - - writelines (linearray, nextline - linearray, ostream); - if (outfile) - fclose (ostream); - - free (linearray); - free (data); -} - -/* Parse an input string in core into lines. - DATA is the input string, and SIZE is its length. - Data goes in LINEARRAY starting at NEXTLINE. - The value returned is the first entry in LINEARRAY still unused. - Value 0 means input file contents are invalid. */ - -char ** -parsefile (filename, nextline, data, size) - char *filename; - char **nextline; - char *data; - long size; -{ - char *p, *end; - char **line = nextline; - - p = data; - end = p + size; - *end = 0; - - while (p != end) - { - if (p[0] != '\\' && p[0] != '@') - return 0; - - *line = p; - while (*p && *p != '\n') - p++; - if (p != end) - p++; - - line++; - if (line == linearray + nlines) - { - char **old = linearray; - linearray = (char **) xrealloc (linearray, sizeof (char *) * (nlines *= 4)); - line += linearray - old; - } - } - - return line; -} - -/* Indexification is a filter applied to the sorted lines - as they are being written to the output file. - Multiple entries for the same name, with different page numbers, - get combined into a single entry with multiple page numbers. - The first braced field, which is used for sorting, is discarded. - However, its first character is examined, folded to lower case, - and if it is different from that in the previous line fed to us - a \initial line is written with one argument, the new initial. - - If an entry has four braced fields, then the second and third - constitute primary and secondary names. - In this case, each change of primary name - generates a \primary line which contains only the primary name, - and in between these are \secondary lines which contain - just a secondary name and page numbers. */ - -/* The last primary name we wrote a \primary entry for. - If only one level of indexing is being done, this is the last name seen. */ -char *lastprimary; -/* Length of storage allocated for lastprimary. */ -int lastprimarylength; - -/* Similar, for the secondary name. */ -char *lastsecondary; -int lastsecondarylength; - -/* Zero if we are not in the middle of writing an entry. - One if we have written the beginning of an entry but have not - yet written any page numbers into it. - Greater than one if we have written the beginning of an entry - plus at least one page number. */ -int pending; - -/* The initial (for sorting purposes) of the last primary entry written. - When this changes, a \initial {c} line is written */ - -char *lastinitial; - -int lastinitiallength; - -/* When we need a string of length 1 for the value of lastinitial, - store it here. */ - -char lastinitial1[2]; - -/* Initialize static storage for writing an index. */ - -static void -xbzero(s, n) - char *s; - int n; -{ - register char *p; - for (p = s; n--; ) - *p++ = '\0'; -} - -void -init_index () -{ - pending = 0; - lastinitial = lastinitial1; - lastinitial1[0] = 0; - lastinitial1[1] = 0; - lastinitiallength = 0; - lastprimarylength = 100; - lastprimary = (char *) xmalloc (lastprimarylength + 1); - xbzero (lastprimary, lastprimarylength + 1); - lastsecondarylength = 100; - lastsecondary = (char *) xmalloc (lastsecondarylength + 1); - xbzero (lastsecondary, lastsecondarylength + 1); -} - -/* Indexify. Merge entries for the same name, - insert headers for each initial character, etc. */ - -void -indexify (line, ostream) - char *line; - FILE *ostream; -{ - char *primary, *secondary, *pagenumber; - int primarylength, secondarylength = 0, pagelength; - int nosecondary; - int initiallength; - char *initial; - char initial1[2]; - register char *p; - - /* First, analyze the parts of the entry fed to us this time. */ - - p = find_braced_pos (line, 0, 0, 0); - if (*p == '{') - { - initial = p; - /* Get length of inner pair of braces starting at `p', - including that inner pair of braces. */ - initiallength = find_braced_end (p + 1) + 1 - p; - } - else - { - initial = initial1; - initial1[0] = *p; - initial1[1] = 0; - initiallength = 1; - - if (initial1[0] >= 'a' && initial1[0] <= 'z') - initial1[0] -= 040; - } - - pagenumber = find_braced_pos (line, 1, 0, 0); - pagelength = find_braced_end (pagenumber) - pagenumber; - if (pagelength == 0) - abort (); - - primary = find_braced_pos (line, 2, 0, 0); - primarylength = find_braced_end (primary) - primary; - - secondary = find_braced_pos (line, 3, 0, 0); - nosecondary = !*secondary; - if (!nosecondary) - secondarylength = find_braced_end (secondary) - secondary; - - /* If the primary is different from before, make a new primary entry. */ - if (strncmp (primary, lastprimary, primarylength)) - { - /* Close off current secondary entry first, if one is open. */ - if (pending) - { - fputs ("}\n", ostream); - pending = 0; - } - - /* If this primary has a different initial, include an entry for - the initial. */ - if (initiallength != lastinitiallength || - strncmp (initial, lastinitial, initiallength)) - { - fprintf (ostream, "\\initial {"); - fwrite (initial, 1, initiallength, ostream); - fprintf (ostream, "}\n", initial); - if (initial == initial1) - { - lastinitial = lastinitial1; - *lastinitial1 = *initial1; - } - else - { - lastinitial = initial; - } - lastinitiallength = initiallength; - } - - /* Make the entry for the primary. */ - if (nosecondary) - fputs ("\\entry {", ostream); - else - fputs ("\\primary {", ostream); - fwrite (primary, primarylength, 1, ostream); - if (nosecondary) - { - fputs ("}{", ostream); - pending = 1; - } - else - fputs ("}\n", ostream); - - /* Record name of most recent primary. */ - if (lastprimarylength < primarylength) - { - lastprimarylength = primarylength + 100; - lastprimary = (char *) xrealloc (lastprimary, - 1 + lastprimarylength); - } - strncpy (lastprimary, primary, primarylength); - lastprimary[primarylength] = 0; - - /* There is no current secondary within this primary, now. */ - lastsecondary[0] = 0; - } - - /* Should not have an entry with no subtopic following one with a subtopic. */ - - if (nosecondary && *lastsecondary) - error ("entry %s follows an entry with a secondary name", line); - - /* Start a new secondary entry if necessary. */ - if (!nosecondary && strncmp (secondary, lastsecondary, secondarylength)) - { - if (pending) - { - fputs ("}\n", ostream); - pending = 0; - } - - /* Write the entry for the secondary. */ - fputs ("\\secondary {", ostream); - fwrite (secondary, secondarylength, 1, ostream); - fputs ("}{", ostream); - pending = 1; - - /* Record name of most recent secondary. */ - if (lastsecondarylength < secondarylength) - { - lastsecondarylength = secondarylength + 100; - lastsecondary = (char *) xrealloc (lastsecondary, - 1 + lastsecondarylength); - } - strncpy (lastsecondary, secondary, secondarylength); - lastsecondary[secondarylength] = 0; - } - - /* Here to add one more page number to the current entry. */ - if (pending++ != 1) - fputs (", ", ostream); /* Punctuate first, if this is not the first. */ - fwrite (pagenumber, pagelength, 1, ostream); -} - -/* Close out any unfinished output entry. */ - -void -finish_index (ostream) - FILE *ostream; -{ - if (pending) - fputs ("}\n", ostream); - free (lastprimary); - free (lastsecondary); -} - -/* Copy the lines in the sorted order. - Each line is copied out of the input file it was found in. */ - -void -writelines (linearray, nlines, ostream) - char **linearray; - int nlines; - FILE *ostream; -{ - char **stop_line = linearray + nlines; - char **next_line; - - init_index (); - - /* Output the text of the lines, and free the buffer space. */ - - for (next_line = linearray; next_line != stop_line; next_line++) - { - /* If -u was specified, output the line only if distinct from previous one. */ - if (next_line == linearray - /* Compare previous line with this one, using only the - explicitly specd keyfields. */ - || compare_general (*(next_line - 1), *next_line, 0L, 0L, num_keyfields - 1)) - { - char *p = *next_line; - char c; - - while ((c = *p++) && c != '\n') - /* Do nothing. */ ; - *(p - 1) = 0; - indexify (*next_line, ostream); - } - } - - finish_index (ostream); -} - -/* Assume (and optionally verify) that each input file is sorted; - merge them and output the result. - Returns nonzero if any input file fails to be sorted. - - This is the high-level interface that can handle an unlimited - number of files. */ - -#define MAX_DIRECT_MERGE 10 - -int -merge_files (infiles, nfiles, outfile) - char **infiles; - int nfiles; - char *outfile; -{ - char **tempfiles; - int ntemps; - int i; - int value = 0; - int start_tempcount = tempcount; - - if (nfiles <= MAX_DIRECT_MERGE) - return merge_direct (infiles, nfiles, outfile); - - /* Merge groups of MAX_DIRECT_MERGE input files at a time, - making a temporary file to hold each group's result. */ - - ntemps = (nfiles + MAX_DIRECT_MERGE - 1) / MAX_DIRECT_MERGE; - tempfiles = (char **) xmalloc (ntemps * sizeof (char *)); - for (i = 0; i < ntemps; i++) - { - int nf = MAX_DIRECT_MERGE; - if (i + 1 == ntemps) - nf = nfiles - i * MAX_DIRECT_MERGE; - tempfiles[i] = maketempname (++tempcount); - value |= merge_direct (&infiles[i * MAX_DIRECT_MERGE], nf, tempfiles[i]); - } - - /* All temporary files that existed before are no longer needed - since their contents have been merged into our new tempfiles. - So delete them. */ - flush_tempfiles (start_tempcount); - - /* Now merge the temporary files we created. */ - - merge_files (tempfiles, ntemps, outfile); - - free (tempfiles); - - return value; -} - -/* Assume (and optionally verify) that each input file is sorted; - merge them and output the result. - Returns nonzero if any input file fails to be sorted. - - This version of merging will not work if the number of - input files gets too high. Higher level functions - use it only with a bounded number of input files. */ - -int -merge_direct (infiles, nfiles, outfile) - char **infiles; - int nfiles; - char *outfile; -{ - struct linebuffer *lb1, *lb2; - struct linebuffer **thisline, **prevline; - FILE **streams; - int i; - int nleft; - int lossage = 0; - int *file_lossage; - struct linebuffer *prev_out = 0; - FILE *ostream = stdout; - - if (outfile) - { - ostream = fopen (outfile, "w"); - } - if (!ostream) - pfatal_with_name (outfile); - - init_index (); - - if (nfiles == 0) - { - if (outfile) - fclose (ostream); - return 0; - } - - /* For each file, make two line buffers. - Also, for each file, there is an element of `thisline' - which points at any time to one of the file's two buffers, - and an element of `prevline' which points to the other buffer. - `thisline' is supposed to point to the next available line from the file, - while `prevline' holds the last file line used, - which is remembered so that we can verify that the file is properly sorted. */ - - /* lb1 and lb2 contain one buffer each per file. */ - lb1 = (struct linebuffer *) xmalloc (nfiles * sizeof (struct linebuffer)); - lb2 = (struct linebuffer *) xmalloc (nfiles * sizeof (struct linebuffer)); - - /* thisline[i] points to the linebuffer holding the next available line in file i, - or is zero if there are no lines left in that file. */ - thisline = (struct linebuffer **) - xmalloc (nfiles * sizeof (struct linebuffer *)); - /* prevline[i] points to the linebuffer holding the last used line - from file i. This is just for verifying that file i is properly - sorted. */ - prevline = (struct linebuffer **) - xmalloc (nfiles * sizeof (struct linebuffer *)); - /* streams[i] holds the input stream for file i. */ - streams = (FILE **) xmalloc (nfiles * sizeof (FILE *)); - /* file_lossage[i] is nonzero if we already know file i is not - properly sorted. */ - file_lossage = (int *) xmalloc (nfiles * sizeof (int)); - - /* Allocate and initialize all that storage. */ - - for (i = 0; i < nfiles; i++) - { - initbuffer (&lb1[i]); - initbuffer (&lb2[i]); - thisline[i] = &lb1[i]; - prevline[i] = &lb2[i]; - file_lossage[i] = 0; - streams[i] = fopen (infiles[i], "r"); - if (!streams[i]) - pfatal_with_name (infiles[i]); - - readline (thisline[i], streams[i]); - } - - /* Keep count of number of files not at eof. */ - nleft = nfiles; - - while (nleft) - { - struct linebuffer *best = 0; - struct linebuffer *exch; - int bestfile = -1; - int i; - - /* Look at the next avail line of each file; choose the least one. */ - - for (i = 0; i < nfiles; i++) - { - if (thisline[i] && - (!best || - 0 < compare_general (best->buffer, thisline[i]->buffer, - (long) bestfile, (long) i, num_keyfields))) - { - best = thisline[i]; - bestfile = i; - } - } - - /* Output that line, unless it matches the previous one and we - don't want duplicates. */ - - if (!(prev_out && - !compare_general (prev_out->buffer, - best->buffer, 0L, 1L, num_keyfields - 1))) - indexify (best->buffer, ostream); - prev_out = best; - - /* Now make the line the previous of its file, and fetch a new - line from that file. */ - - exch = prevline[bestfile]; - prevline[bestfile] = thisline[bestfile]; - thisline[bestfile] = exch; - - while (1) - { - /* If the file has no more, mark it empty. */ - - if (feof (streams[bestfile])) - { - thisline[bestfile] = 0; - /* Update the number of files still not empty. */ - nleft--; - break; - } - readline (thisline[bestfile], streams[bestfile]); - if (thisline[bestfile]->buffer[0] || !feof (streams[bestfile])) - break; - } - } - - finish_index (ostream); - - /* Free all storage and close all input streams. */ - - for (i = 0; i < nfiles; i++) - { - fclose (streams[i]); - free (lb1[i].buffer); - free (lb2[i].buffer); - } - free (file_lossage); - free (lb1); - free (lb2); - free (thisline); - free (prevline); - free (streams); - - if (outfile) - fclose (ostream); - - return lossage; -} - -/* Print error message and exit. */ - -void -fatal (s1, s2) - char *s1, *s2; -{ - error (s1, s2); - exit (TI_FATAL_ERROR); -} - -/* Print error message. S1 is printf control string, S2 is arg for it. */ - -void -error (s1, s2) - char *s1, *s2; -{ - printf ("%s: ", program_name); - printf (s1, s2); - printf ("\n"); -} - -#if !defined (HAVE_STRERROR) -static char * -strerror (n) - int n; -{ - static char ebuf[40]; - - if (n < sys_nerr) - return sys_errlist[n]; - else - { - sprintf (ebuf, "Unknown error %d", n); - return ebuf; - } -} -#endif - -void -perror_with_name (name) - char *name; -{ - char *s; - - s = concat ("", strerror (errno), " for %s"); - error (s, name); -} - -void -pfatal_with_name (name) - char *name; -{ - char *s; - - s = concat ("", strerror (errno), " for %s"); - fatal (s, name); -} - -/* Return a newly-allocated string whose contents concatenate those of - S1, S2, S3. */ - -char * -concat (s1, s2, s3) - char *s1, *s2, *s3; -{ - int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3); - char *result = (char *) xmalloc (len1 + len2 + len3 + 1); - - strcpy (result, s1); - strcpy (result + len1, s2); - strcpy (result + len1 + len2, s3); - *(result + len1 + len2 + len3) = 0; - - return result; -} - -/* Just like malloc, but kills the program in case of fatal error. */ -void * -xmalloc (nbytes) - int nbytes; -{ - void *temp = (void *) malloc (nbytes); - - if (nbytes && temp == (void *)NULL) - memory_error ("xmalloc", nbytes); - - return (temp); -} - -/* Like realloc (), but barfs if there isn't enough memory. */ -void * -xrealloc (pointer, nbytes) - void *pointer; - int nbytes; -{ - void *temp; - - if (!pointer) - temp = (void *)xmalloc (nbytes); - else - temp = (void *)realloc (pointer, nbytes); - - if (nbytes && !temp) - memory_error ("xrealloc", nbytes); - - return (temp); -} - -memory_error (callers_name, bytes_wanted) - char *callers_name; - int bytes_wanted; -{ - char printable_string[80]; - - sprintf (printable_string, - "Virtual memory exhausted in %s ()! Needed %d bytes.", - callers_name, bytes_wanted); - - error (printable_string, ""); - abort (); -} diff --git a/lib/glob/Makefile b/lib/glob/Makefile.in index 5811ba2..4471c18 100644 --- a/lib/glob/Makefile +++ b/lib/glob/Makefile.in @@ -4,39 +4,46 @@ # # #################################################################### -# This Makefile is hand made from a template file, found in -# ../template. Each library must provide several Makefile -# targets: `all', `clean', `documentation', `install', and -# `what-tar'. The `what-tar' target reports the names of the -# files that need to be included in a tarfile to build the full -# code and documentation for this library. - -# Please note that the values for INCLUDES, CC, AR, RM, CP, -# RANLIB, and selfdir are passed in from ../Makefile, and do -# not need to be defined here. -srcdir = . -VPATH = .:$(srcdir) +srcdir = @srcdir@ +VPATH = .:@srcdir@ +topdir = @top_srcdir@ +BUILD_DIR = @BUILD_DIR@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +CC = @CC@ +RANLIB = @RANLIB@ +AR = @AR@ +RM = rm +CP = cp +MV = mv + +CFLAGS = @CFLAGS@ +LOCAL_CFLAGS = @LOCAL_CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ @LOCAL_LDFLAGS@ + +DEFS = @DEFS@ + +INCLUDES = -I. -I../.. -I$(topdir) -I$(topdir)/lib + +CCFLAGS = $(DEFS) $(CPPFLAGS) ${INCLUDES} $(LOCAL_CFLAGS) $(CFLAGS) # Here is a rule for making .o files from .c files that doesn't force # the type of the machine (like -sun3) into the flags. .c.o: - $(CC) -c $(CFLAGS) $(INCLUDES) $(LOCAL_DEFINES) $(CPPFLAGS) $< - -# LOCAL_DEFINES are flags that are specific to this library. -# Define -DUSG if you are using a System V operating system. -LOCAL_DEFINES = $(LOCAL_INCLUDES) #-DUSG - -# For libraries which include headers from other libraries. -LOCAL_INCLUDES = -I.. + $(CC) -c $(CCFLAGS) $< # The name of the library target. LIBRARY_NAME = libglob.a # The C code source files for this library. -CSOURCES = $(srcdir)glob.c $(srcdir)fnmatch.c +CSOURCES = $(srcdir)/glob.c $(srcdir)/fnmatch.c # The header files for this library. -HSOURCES = $(srcdir)fnmatch.h +HSOURCES = $(srcdir)/fnmatch.h OBJECTS = glob.o fnmatch.o @@ -58,8 +65,8 @@ all: $(LIBRARY_NAME) $(LIBRARY_NAME): $(OBJECTS) $(RM) -f $@ - $(AR) cq $@ $(OBJECTS) - -[ -n "$(RANLIB)" ] && $(RANLIB) $@ + $(AR) cr $@ $(OBJECTS) + -test -n "$(RANLIB)" && $(RANLIB) $@ what-tar: @for file in $(THINGS_TO_TAR); do \ @@ -67,24 +74,24 @@ what-tar: done documentation: force - -(cd doc && $(MAKE) $(MFLAGS)) - + -(cd doc; $(MAKE) $(MFLAGS)) force: # The rule for 'includes' is written funny so that the if statement # always returns TRUE unless there really was an error installing the # include files. install: - -$(MV) $(bindir)/$(LIBRARY_NAME) $(bindir)/$(LIBRARY_NAME)-old - $(CP) $(LIBRARY_NAME) $(bindir)/$(LIBRARY_NAME) - -[ -n "$(RANLIB)" ] && $(RANLIB) -t $(bindir)/$(LIBRARY_NAME) clean: rm -f $(OBJECTS) $(LIBRARY_NAME) - -(cd doc && $(MAKE) $(MFLAGS) $@) + -(cd doc && $(MAKE) $(MFLAGS) $@ ) -maintainer-clean realclean mostlyclean distclean: clean - -(cd doc && $(MAKE) $(MFLAGS) $@) +realclean distclean maintainer-clean: clean + -( cd doc && $(MAKE) $(MFLAGS) $@ ) + $(RM) -f Makefile + +mostlyclean: clean + -( cd doc && $(MAKE) $(MFLAGS) $@ ) ###################################################################### # # @@ -93,3 +100,6 @@ maintainer-clean realclean mostlyclean distclean: clean ###################################################################### fnmatch.o: fnmatch.c fnmatch.h + +fnmatch.o: $(BUILD_DIR)/config.h +glob.o: $(BUILD_DIR)/config.h diff --git a/lib/glob/doc/Makefile b/lib/glob/doc/Makefile index 1b6084c..8dca606 100644 --- a/lib/glob/doc/Makefile +++ b/lib/glob/doc/Makefile @@ -1,5 +1,5 @@ all: cp glob.texi glob.info -maintainer-clean realclean distclean clean: +clean distclean mostlyclean maintainer-clean: rm -f glob.?? glob.info diff --git a/lib/glob/fnmatch.c b/lib/glob/fnmatch.c index 6a8b574..0763609 100644 --- a/lib/glob/fnmatch.c +++ b/lib/glob/fnmatch.c @@ -68,10 +68,14 @@ fnmatch (pattern, string, flags) (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/'))) return (FNM_NOMATCH); - for (c = *p++; c == '?' || c == '*'; c = *p++, ++n) - if (((flags & FNM_PATHNAME) && *n == '/') || - (c == '?' && *n == '\0')) - return (FNM_NOMATCH); + for (c = *p++; c == '?' || c == '*'; c = *p++) + { + if (((flags & FNM_PATHNAME) && *n == '/') || + (c == '?' && *n == '\0')) + return (FNM_NOMATCH); + if (c == '?') + n++; + } if (c == '\0') return (0); diff --git a/lib/glob/glob.c b/lib/glob/glob.c index 6ff2cb4..412e15c 100644 --- a/lib/glob/glob.c +++ b/lib/glob/glob.c @@ -14,45 +14,48 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - + /* To whomever it may concern: I have never seen the code which most Unix programs use to perform this function. I wrote this from scratch based on specifications for the pattern matching. --RMS. */ -#if defined (SHELL) -# if defined (HAVE_STDLIB_H) -# include <stdlib.h> -# else +#include <config.h> + +#if !defined (__GNUC__) && !defined (HAVE_ALLOCA_H) && defined (_AIX) + #pragma alloca +#endif /* _AIX && RISC6000 && !__GNUC__ */ + +#if defined (HAVE_UNISTD_H) +# include <unistd.h> +#endif + +#if defined (HAVE_STDLIB_H) +# include <stdlib.h> +#else +# if defined (SHELL) # include "ansi_stdlib.h" -# endif /* HAVE_STDLIB_H */ -# include <config.h> +# endif /* SHELL */ #endif #include <sys/types.h> -#if !defined (SHELL) && (defined (_POSIX_VERSION) || defined (USGr3)) -# if !defined (HAVE_DIRENT_H) -# define HAVE_DIRENT_H -# endif /* !HAVE_DIRENT_H */ -#endif /* !SHELL && (_POSIX_VERSION || USGr3) */ - #if defined (HAVE_DIRENT_H) # include <dirent.h> -# if !defined (direct) -# define direct dirent -# endif /* !direct */ # define D_NAMLEN(d) strlen ((d)->d_name) #else /* !HAVE_DIRENT_H */ # define D_NAMLEN(d) ((d)->d_namlen) -# if defined (USG) -# if defined (Xenix) -# include <sys/ndir.h> -# else /* !Xenix (but USG...) */ -# include "ndir.h" -# endif /* !Xenix */ -# else /* !USG */ +# if defined (HAVE_SYS_NDIR_H) +# include <sys/ndir.h> +# endif +# if defined (HAVE_SYS_DIR_H) # include <sys/dir.h> -# endif /* !USG */ +# endif /* HAVE_SYS_DIR_H */ +# if defined (HAVE_NDIR_H) +# include <ndir.h> +# endif +# if !defined (dirent) +# define dirent direct +# endif #endif /* !HAVE_DIRENT_H */ #if defined (_POSIX_SOURCE) @@ -63,34 +66,18 @@ # define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) #endif /* _POSIX_SOURCE */ -#if defined (USG) || defined (NeXT) -# if !defined (HAVE_STRING_H) -# define HAVE_STRING_H -# endif /* !HAVE_STRING_H */ -#endif /* USG || NeXT */ - #if defined (HAVE_STRING_H) # include <string.h> #else /* !HAVE_STRING_H */ # include <strings.h> #endif /* !HAVE_STRING_H */ -#if defined (USG) -# if !defined (isc386) -# include <memory.h> -# endif /* !isc386 */ -# if defined (RISC6000) -extern void bcopy (); -# else /* !RISC6000 */ -# define bcopy(s, d, n) ((void) memcpy ((d), (s), (n))) -# endif /* !RISC6000 */ -#endif /* USG */ - -#include "fnmatch.h" +#if !defined (HAVE_BCOPY) +# define bcopy(s, d, n) ((void) memcpy ((d), (s), (n))) +#endif /* !HAVE_BCOPY */ /* If the opendir () on your system lets you open non-directory files, - then we consider that not robust. Define OPENDIR_NOT_ROBUST in the - SYSDEP_CFLAGS for your machines entry in machines.h. */ + then we consider that not robust. */ #if defined (OPENDIR_NOT_ROBUST) # if defined (SHELL) # include "posixstat.h" @@ -99,7 +86,10 @@ extern void bcopy (); # endif /* !SHELL */ #endif /* OPENDIR_NOT_ROBUST */ -#if !defined (HAVE_STDLIB_H) +#include "memalloc.h" +#include "fnmatch.h" + +#if !defined (HAVE_STDLIB_H) && !defined (SHELL) extern char *malloc (), *realloc (); extern void free (); #endif /* !HAVE_STDLIB_H */ @@ -123,7 +113,6 @@ int noglob_dot_filenames = 1; /* Global variable to return to signify an error in globbing. */ char *glob_error_return; - /* Return nonzero if PATTERN has any special globbing chars in it. */ int glob_pattern_p (pattern) @@ -205,7 +194,7 @@ glob_vector (pat, dir) }; DIR *d; - register struct direct *dp; + register struct dirent *dp; struct globval *lastlink; register struct globval *nextlink; register char *nextname; @@ -365,7 +354,14 @@ glob_dir_to_array (dir, array) + strlen (array[i]) + 1); if (result[i] == NULL) return (NULL); - sprintf (result[i], "%s%s%s", dir, add_slash ? "/" : "", array[i]); +#if 1 + strcpy (result[i], dir); + if (add_slash) + result[i][l] = '/'; + strcpy (result[i] + l + add_slash, array[i]); +#else + (void)sprintf (result[i], "%s%s%s", dir, add_slash ? "/" : "", array[i]); +#endif } result[i] = NULL; @@ -432,7 +428,7 @@ glob_filename (pathname) goto memory_error; else if (directories == (char **)&glob_error_return) { - free ((char *)result); + free ((char *) result); return ((char **) &glob_error_return); } else if (*directories == NULL) diff --git a/lib/glob/glob.h b/lib/glob/glob.h new file mode 100644 index 0000000..a72dede --- /dev/null +++ b/lib/glob/glob.h @@ -0,0 +1,30 @@ +/* File-name wildcard pattern matching for GNU. + Copyright (C) 1985, 1988, 1989 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef _GLOB_H_ +#define _GLOB_H_ + +#include "stdc.h" + +extern int glob_pattern_p __P((char *)); +extern char **glob_vector __P((char *, char *)); +extern char **glob_filename __P((char *)); + +extern char *glob_error_return; +extern int noglob_dot_filenames; + +#endif /* _GLOB_H_ */ diff --git a/lib/malloc/Makefile b/lib/malloc/Makefile deleted file mode 100644 index 4c0ab72..0000000 --- a/lib/malloc/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -# Skeleton Makefile for the GNU malloc code -# -# Maybe this should really create a library instead of just compiling -# source files - -srcdir = . -VPATH = .:$(srcdir) - -.c.o: - $(CC) $(CFLAGS) $(CPPFLAGS) -c $< - -.s.o: - $(CC) $(CFLAGS) $(CPPFLAGS) -c $< - -MALLOC_SOURCE = malloc.c - -ALLOCA_SOURCE = alloca.c -ALLOCA_OBJECT = alloca.o - -malloc.o: malloc.c getpagesize.h - -$(ALLOCA_OBJECT): $(ALLOCA_SOURCE) - -alloca.o: $(ALLOCA_SOURCE) - $(CC) $(CFLAGS) $(CPPFLAGS) -c $< - @- if [ "$(ALLOCA_OBJECT)" != alloca.o ]; then \ - mv $(ALLOCA_OBJECT) alloca.o >/dev/null 2>&1 ; \ - fi diff --git a/lib/malloc/Makefile.in b/lib/malloc/Makefile.in new file mode 100644 index 0000000..6bba7d1 --- /dev/null +++ b/lib/malloc/Makefile.in @@ -0,0 +1,68 @@ +# Skeleton Makefile for the GNU malloc code +# + +srcdir = @srcdir@ +VPATH = .:@srcdir@ +topdir = @top_srcdir@ +BUILD_DIR = @BUILD_DIR@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +CC = @CC@ +RANLIB = @RANLIB@ +AR = @AR@ +RM = rm -f +CP = cp +MV = mv + +CFLAGS = @CFLAGS@ +LOCAL_CFLAGS = @LOCAL_CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ + +DEFS = @DEFS@ + +INCLUDES = -I. -I../.. -I$(topdir) -I$(topdir)/lib + +CCFLAGS = ${INCLUDES} $(DEFS) $(LOCAL_CFLAGS) $(CFLAGS) $(MALLOC_CFLAGS) $(CPPFLAGS) + +.c.o: + $(CC) $(CCFLAGS) -c $< + +.s.o: + $(CC) $(CCFLAGS) -c $< + +MALLOC_SOURCE = malloc.c + +ALLOCA_SOURCE = alloca.c +ALLOCA_OBJECT = alloca.o + +MALLOC_SRC = @MALLOC_SRC@ +MALLOC = @MALLOC@ +ALLOCA = @ALLOCA@ + +libmalloc.a: $(MALLOC) $(ALLOCA) stub.o + $(RM) $@ + $(AR) cr $@ $(MALLOC) $(ALLOCA) stub.o + -test -n "$(RANLIB)" && $(RANLIB) $@ + +malloc.o: malloc.c getpagesize.h + +alloca.o: $(ALLOCA_SOURCE) + $(CC) $(CCFLAGS) -c $(ALLOCA_SOURCE) + @- if test "$(ALLOCA_OBJECT)" != alloca.o ; then \ + mv $(ALLOCA_OBJECT) alloca.o >/dev/null 2>&1 ; \ + fi + +mostlyclean clean: + $(RM) *.o libmalloc.a + +distclean realclean maintainer-clean: clean + $(RM) Makefile + +alloca.o: $(BUILD_DIR)/config.h +malloc.o: $(BUILD_DIR)/config.h +xmalloc.o: $(BUILD_DIR)/config.h +gmalloc.o: $(BUILD_DIR)/config.h diff --git a/lib/malloc/gmalloc.c b/lib/malloc/gmalloc.c new file mode 100644 index 0000000..8690b12 --- /dev/null +++ b/lib/malloc/gmalloc.c @@ -0,0 +1,1579 @@ +/* DO NOT EDIT THIS FILE -- it is automagically generated. -*- C -*- */ + +#define _MALLOC_INTERNAL + +/* The malloc headers and source files from the C library follow here. */ + +/* Declarations for `malloc' and friends. + Copyright 1990, 91, 92, 93, 95, 96 Free Software Foundation, Inc. + Written May 1989 by Mike Haertel. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. + + The author may be reached (Email) at the address mike@ai.mit.edu, + or (US mail) as Mike Haertel c/o Free Software Foundation. */ + +#ifndef _MALLOC_H + +#define _MALLOC_H 1 + +#ifdef _MALLOC_INTERNAL + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#if defined(_LIBC) || defined(STDC_HEADERS) || defined(USG) +#include <string.h> +#else +#ifndef memset +#define memset(s, zero, n) bzero ((s), (n)) +#endif +#ifndef memcpy +#define memcpy(d, s, n) bcopy ((s), (d), (n)) +#endif +#endif + +#if defined (__GNU_LIBRARY__) || (defined (__STDC__) && __STDC__) +#include <limits.h> +#else +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif +#endif + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#endif /* _MALLOC_INTERNAL. */ + + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if defined (__cplusplus) || (defined (__STDC__) && __STDC__) +#undef __P +#define __P(args) args +#undef __ptr_t +#define __ptr_t void * +#else /* Not C++ or ANSI C. */ +#undef __P +#define __P(args) () +#undef const +#define const +#undef __ptr_t +#define __ptr_t char * +#endif /* C++ or ANSI C. */ + +#if defined (__STDC__) && __STDC__ +#include <stddef.h> +#define __malloc_size_t size_t +#define __malloc_ptrdiff_t ptrdiff_t +#else +#define __malloc_size_t unsigned int +#define __malloc_ptrdiff_t int +#endif + +#ifndef NULL +#define NULL 0 +#endif + + +/* Allocate SIZE bytes of memory. */ +extern __ptr_t malloc __P ((__malloc_size_t __size)); +/* Re-allocate the previously allocated block + in __ptr_t, making the new block SIZE bytes long. */ +extern __ptr_t realloc __P ((__ptr_t __ptr, __malloc_size_t __size)); +/* Allocate NMEMB elements of SIZE bytes each, all initialized to 0. */ +extern __ptr_t calloc __P ((__malloc_size_t __nmemb, __malloc_size_t __size)); +/* Free a block allocated by `malloc', `realloc' or `calloc'. */ +extern void free __P ((__ptr_t __ptr)); + +/* Allocate SIZE bytes allocated to ALIGNMENT bytes. */ +#if ! (defined (_MALLOC_INTERNAL) && __DJGPP__ - 0 == 1) /* Avoid conflict. */ +extern __ptr_t memalign __P ((__malloc_size_t __alignment, + __malloc_size_t __size)); +#endif + +/* Allocate SIZE bytes on a page boundary. */ +#if ! (defined (_MALLOC_INTERNAL) && defined (emacs)) /* Avoid conflict. */ +extern __ptr_t valloc __P ((__malloc_size_t __size)); +#endif + + +#ifdef _MALLOC_INTERNAL + +/* The allocator divides the heap into blocks of fixed size; large + requests receive one or more whole blocks, and small requests + receive a fragment of a block. Fragment sizes are powers of two, + and all fragments of a block are the same size. When all the + fragments in a block have been freed, the block itself is freed. */ +#define INT_BIT (CHAR_BIT * sizeof(int)) +#define BLOCKLOG (INT_BIT > 16 ? 12 : 9) +#define BLOCKSIZE (1 << BLOCKLOG) +#define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE) + +/* Determine the amount of memory spanned by the initial heap table + (not an absolute limit). */ +#define HEAP (INT_BIT > 16 ? 4194304 : 65536) + +/* Number of contiguous free blocks allowed to build up at the end of + memory before they will be returned to the system. */ +#define FINAL_FREE_BLOCKS 8 + +/* Data structure giving per-block information. */ +typedef union + { + /* Heap information for a busy block. */ + struct + { + /* Zero for a large (multiblock) object, or positive giving the + logarithm to the base two of the fragment size. */ + int type; + union + { + struct + { + __malloc_size_t nfree; /* Free frags in a fragmented block. */ + __malloc_size_t first; /* First free fragment of the block. */ + } frag; + /* For a large object, in its first block, this has the number + of blocks in the object. In the other blocks, this has a + negative number which says how far back the first block is. */ + __malloc_ptrdiff_t size; + } info; + } busy; + /* Heap information for a free block + (that may be the first of a free cluster). */ + struct + { + __malloc_size_t size; /* Size (in blocks) of a free cluster. */ + __malloc_size_t next; /* Index of next free cluster. */ + __malloc_size_t prev; /* Index of previous free cluster. */ + } free; + } malloc_info; + +/* Pointer to first block of the heap. */ +extern char *_heapbase; + +/* Table indexed by block number giving per-block information. */ +extern malloc_info *_heapinfo; + +/* Address to block number and vice versa. */ +#define BLOCK(A) (((char *) (A) - _heapbase) / BLOCKSIZE + 1) +#define ADDRESS(B) ((__ptr_t) (((B) - 1) * BLOCKSIZE + _heapbase)) + +/* Current search index for the heap table. */ +extern __malloc_size_t _heapindex; + +/* Limit of valid info table indices. */ +extern __malloc_size_t _heaplimit; + +/* Doubly linked lists of free fragments. */ +struct list + { + struct list *next; + struct list *prev; + }; + +/* Free list headers for each fragment size. */ +extern struct list _fraghead[]; + +/* List of blocks allocated with `memalign' (or `valloc'). */ +struct alignlist + { + struct alignlist *next; + __ptr_t aligned; /* The address that memaligned returned. */ + __ptr_t exact; /* The address that malloc returned. */ + }; +extern struct alignlist *_aligned_blocks; + +/* Instrumentation. */ +extern __malloc_size_t _chunks_used; +extern __malloc_size_t _bytes_used; +extern __malloc_size_t _chunks_free; +extern __malloc_size_t _bytes_free; + +/* Internal versions of `malloc', `realloc', and `free' + used when these functions need to call each other. + They are the same but don't call the hooks. */ +extern __ptr_t _malloc_internal __P ((__malloc_size_t __size)); +extern __ptr_t _realloc_internal __P ((__ptr_t __ptr, __malloc_size_t __size)); +extern void _free_internal __P ((__ptr_t __ptr)); + +#endif /* _MALLOC_INTERNAL. */ + +/* Given an address in the middle of a malloc'd object, + return the address of the beginning of the object. */ +extern __ptr_t malloc_find_object_address __P ((__ptr_t __ptr)); + +/* Underlying allocation function; successive calls should + return contiguous pieces of memory. */ +extern __ptr_t (*__morecore) __P ((__malloc_ptrdiff_t __size)); + +/* Default value of `__morecore'. */ +extern __ptr_t __default_morecore __P ((__malloc_ptrdiff_t __size)); + +/* If not NULL, this function is called after each time + `__morecore' is called to increase the data size. */ +extern void (*__after_morecore_hook) __P ((void)); + +/* Number of extra blocks to get each time we ask for more core. + This reduces the frequency of calling `(*__morecore)'. */ +extern __malloc_size_t __malloc_extra_blocks; + +/* Nonzero if `malloc' has been called and done its initialization. */ +extern int __malloc_initialized; +/* Function called to initialize malloc data structures. */ +extern int __malloc_initialize __P ((void)); + +/* Hooks for debugging versions. */ +extern void (*__malloc_initialize_hook) __P ((void)); +extern void (*__free_hook) __P ((__ptr_t __ptr)); +extern __ptr_t (*__malloc_hook) __P ((__malloc_size_t __size)); +extern __ptr_t (*__realloc_hook) __P ((__ptr_t __ptr, __malloc_size_t __size)); +extern __ptr_t (*__memalign_hook) __P ((__malloc_size_t __size, + __malloc_size_t __alignment)); + +/* Return values for `mprobe': these are the kinds of inconsistencies that + `mcheck' enables detection of. */ +enum mcheck_status + { + MCHECK_DISABLED = -1, /* Consistency checking is not turned on. */ + MCHECK_OK, /* Block is fine. */ + MCHECK_FREE, /* Block freed twice. */ + MCHECK_HEAD, /* Memory before the block was clobbered. */ + MCHECK_TAIL /* Memory after the block was clobbered. */ + }; + +/* Activate a standard collection of debugging hooks. This must be called + before `malloc' is ever called. ABORTFUNC is called with an error code + (see enum above) when an inconsistency is detected. If ABORTFUNC is + null, the standard function prints on stderr and then calls `abort'. */ +extern int mcheck __P ((void (*__abortfunc) __P ((enum mcheck_status)))); + +/* Check for aberrations in a particular malloc'd block. You must have + called `mcheck' already. These are the same checks that `mcheck' does + when you free or reallocate a block. */ +extern enum mcheck_status mprobe __P ((__ptr_t __ptr)); + +/* Activate a standard collection of tracing hooks. */ +extern void mtrace __P ((void)); +extern void muntrace __P ((void)); + +/* Statistics available to the user. */ +struct mstats + { + __malloc_size_t bytes_total; /* Total size of the heap. */ + __malloc_size_t chunks_used; /* Chunks allocated by the user. */ + __malloc_size_t bytes_used; /* Byte total of user-allocated chunks. */ + __malloc_size_t chunks_free; /* Chunks in the free list. */ + __malloc_size_t bytes_free; /* Byte total of chunks in the free list. */ + }; + +/* Pick up the current statistics. */ +extern struct mstats mstats __P ((void)); + +/* Call WARNFUN with a warning message when memory usage is high. */ +extern void memory_warnings __P ((__ptr_t __start, + void (*__warnfun) __P ((const char *)))); + + +/* Relocating allocator. */ + +/* Allocate SIZE bytes, and store the address in *HANDLEPTR. */ +extern __ptr_t r_alloc __P ((__ptr_t *__handleptr, __malloc_size_t __size)); + +/* Free the storage allocated in HANDLEPTR. */ +extern void r_alloc_free __P ((__ptr_t *__handleptr)); + +/* Adjust the block at HANDLEPTR to be SIZE bytes long. */ +extern __ptr_t r_re_alloc __P ((__ptr_t *__handleptr, __malloc_size_t __size)); + + +#ifdef __cplusplus +} +#endif + +#endif /* malloc.h */ +/* Memory allocator `malloc'. + Copyright 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. + Written May 1989 by Mike Haertel. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. + + The author may be reached (Email) at the address mike@ai.mit.edu, + or (US mail) as Mike Haertel c/o Free Software Foundation. */ + +#ifndef _MALLOC_INTERNAL +#define _MALLOC_INTERNAL +#include <malloc.h> +#endif +#include <errno.h> + +/* How to really get more memory. */ +__ptr_t (*__morecore) __P ((ptrdiff_t __size)) = __default_morecore; + +/* Debugging hook for `malloc'. */ +__ptr_t (*__malloc_hook) __P ((__malloc_size_t __size)); + +/* Pointer to the base of the first block. */ +char *_heapbase; + +/* Block information table. Allocated with align/__free (not malloc/free). */ +malloc_info *_heapinfo; + +/* Number of info entries. */ +static __malloc_size_t heapsize; + +/* Search index in the info table. */ +__malloc_size_t _heapindex; + +/* Limit of valid info table indices. */ +__malloc_size_t _heaplimit; + +/* Free lists for each fragment size. */ +struct list _fraghead[BLOCKLOG]; + +/* Instrumentation. */ +__malloc_size_t _chunks_used; +__malloc_size_t _bytes_used; +__malloc_size_t _chunks_free; +__malloc_size_t _bytes_free; + +/* Are you experienced? */ +int __malloc_initialized; + +__malloc_size_t __malloc_extra_blocks; + +void (*__malloc_initialize_hook) __P ((void)); +void (*__after_morecore_hook) __P ((void)); + + +/* Aligned allocation. */ +static __ptr_t align __P ((__malloc_size_t)); +static __ptr_t +align (size) + __malloc_size_t size; +{ + __ptr_t result; + unsigned long int adj; + + result = (*__morecore) (size); + adj = (unsigned long int) ((unsigned long int) ((char *) result - + (char *) NULL)) % BLOCKSIZE; + if (adj != 0) + { + __ptr_t new; + adj = BLOCKSIZE - adj; + new = (*__morecore) (adj); + result = (char *) result + adj; + } + + if (__after_morecore_hook) + (*__after_morecore_hook) (); + + return result; +} + +/* Get SIZE bytes, if we can get them starting at END. + Return the address of the space we got. + If we cannot get space at END, fail and return -1. */ +static __ptr_t get_contiguous_space __P ((__malloc_ptrdiff_t, __ptr_t)); +static __ptr_t +get_contiguous_space (size, position) + __malloc_ptrdiff_t size; + __ptr_t position; +{ + __ptr_t before; + __ptr_t after; + + before = (*__morecore) (0); + /* If we can tell in advance that the break is at the wrong place, + fail now. */ + if (before != position) + return 0; + + /* Allocate SIZE bytes and get the address of them. */ + after = (*__morecore) (size); + if (!after) + return 0; + + /* It was not contiguous--reject it. */ + if (after != position) + { + (*__morecore) (- size); + return 0; + } + + return after; +} + + +/* This is called when `_heapinfo' and `heapsize' have just + been set to describe a new info table. Set up the table + to describe itself and account for it in the statistics. */ +static void register_heapinfo __P ((void)); +#ifdef __GNUC__ +__inline__ +#endif +static void +register_heapinfo () +{ + __malloc_size_t block, blocks; + + block = BLOCK (_heapinfo); + blocks = BLOCKIFY (heapsize * sizeof (malloc_info)); + + /* Account for the _heapinfo block itself in the statistics. */ + _bytes_used += blocks * BLOCKSIZE; + ++_chunks_used; + + /* Describe the heapinfo block itself in the heapinfo. */ + _heapinfo[block].busy.type = 0; + _heapinfo[block].busy.info.size = blocks; + /* Leave back-pointers for malloc_find_address. */ + while (--blocks > 0) + _heapinfo[block + blocks].busy.info.size = -blocks; +} + +/* Set everything up and remember that we have. */ +int +__malloc_initialize () +{ + if (__malloc_initialized) + return 0; + + if (__malloc_initialize_hook) + (*__malloc_initialize_hook) (); + + heapsize = HEAP / BLOCKSIZE; + _heapinfo = (malloc_info *) align (heapsize * sizeof (malloc_info)); + if (_heapinfo == NULL) + return 0; + memset (_heapinfo, 0, heapsize * sizeof (malloc_info)); + _heapinfo[0].free.size = 0; + _heapinfo[0].free.next = _heapinfo[0].free.prev = 0; + _heapindex = 0; + _heapbase = (char *) _heapinfo; + _heaplimit = BLOCK (_heapbase + heapsize * sizeof (malloc_info)); + + register_heapinfo (); + + __malloc_initialized = 1; + return 1; +} + +static int morecore_recursing; + +/* Get neatly aligned memory, initializing or + growing the heap info table as necessary. */ +static __ptr_t morecore __P ((__malloc_size_t)); +static __ptr_t +morecore (size) + __malloc_size_t size; +{ + __ptr_t result; + malloc_info *newinfo, *oldinfo; + __malloc_size_t newsize; + + if (morecore_recursing) + /* Avoid recursion. The caller will know how to handle a null return. */ + return NULL; + + result = align (size); + if (result == NULL) + return NULL; + + /* Check if we need to grow the info table. */ + if ((__malloc_size_t) BLOCK ((char *) result + size) > heapsize) + { + /* Calculate the new _heapinfo table size. We do not account for the + added blocks in the table itself, as we hope to place them in + existing free space, which is already covered by part of the + existing table. */ + newsize = heapsize; + do + newsize *= 2; + while ((__malloc_size_t) BLOCK ((char *) result + size) > newsize); + + /* We must not reuse existing core for the new info table when called + from realloc in the case of growing a large block, because the + block being grown is momentarily marked as free. In this case + _heaplimit is zero so we know not to reuse space for internal + allocation. */ + if (_heaplimit != 0) + { + /* First try to allocate the new info table in core we already + have, in the usual way using realloc. If realloc cannot + extend it in place or relocate it to existing sufficient core, + we will get called again, and the code above will notice the + `morecore_recursing' flag and return null. */ + int save = errno; /* Don't want to clobber errno with ENOMEM. */ + morecore_recursing = 1; + newinfo = (malloc_info *) _realloc_internal + (_heapinfo, newsize * sizeof (malloc_info)); + morecore_recursing = 0; + if (newinfo == NULL) + errno = save; + else + { + /* We found some space in core, and realloc has put the old + table's blocks on the free list. Now zero the new part + of the table and install the new table location. */ + memset (&newinfo[heapsize], 0, + (newsize - heapsize) * sizeof (malloc_info)); + _heapinfo = newinfo; + heapsize = newsize; + goto got_heap; + } + } + + /* Allocate new space for the malloc info table. */ + while (1) + { + newinfo = (malloc_info *) align (newsize * sizeof (malloc_info)); + + /* Did it fail? */ + if (newinfo == NULL) + { + (*__morecore) (-size); + return NULL; + } + + /* Is it big enough to record status for its own space? + If so, we win. */ + if ((__malloc_size_t) BLOCK ((char *) newinfo + + newsize * sizeof (malloc_info)) + < newsize) + break; + + /* Must try again. First give back most of what we just got. */ + (*__morecore) (- newsize * sizeof (malloc_info)); + newsize *= 2; + } + + /* Copy the old table to the beginning of the new, + and zero the rest of the new table. */ + memcpy (newinfo, _heapinfo, heapsize * sizeof (malloc_info)); + memset (&newinfo[heapsize], 0, + (newsize - heapsize) * sizeof (malloc_info)); + oldinfo = _heapinfo; + _heapinfo = newinfo; + heapsize = newsize; + + register_heapinfo (); + + /* Reset _heaplimit so _free_internal never decides + it can relocate or resize the info table. */ + _heaplimit = 0; + _free_internal (oldinfo); + + /* The new heap limit includes the new table just allocated. */ + _heaplimit = BLOCK ((char *) newinfo + heapsize * sizeof (malloc_info)); + return result; + } + + got_heap: + _heaplimit = BLOCK ((char *) result + size); + return result; +} + +/* Allocate memory from the heap. */ +__ptr_t +_malloc_internal (size) + __malloc_size_t size; +{ + __ptr_t result; + __malloc_size_t block, blocks, lastblocks, start; + register __malloc_size_t i; + struct list *next; + + /* ANSI C allows `malloc (0)' to either return NULL, or to return a + valid address you can realloc and free (though not dereference). + + It turns out that some extant code (sunrpc, at least Ultrix's version) + expects `malloc (0)' to return non-NULL and breaks otherwise. + Be compatible. */ + +#if 0 + if (size == 0) + return NULL; +#endif + + if (size < sizeof (struct list)) + size = sizeof (struct list); + +#ifdef SUNOS_LOCALTIME_BUG + if (size < 16) + size = 16; +#endif + + /* Determine the allocation policy based on the request size. */ + if (size <= BLOCKSIZE / 2) + { + /* Small allocation to receive a fragment of a block. + Determine the logarithm to base two of the fragment size. */ + register __malloc_size_t log = 1; + --size; + while ((size /= 2) != 0) + ++log; + + /* Look in the fragment lists for a + free fragment of the desired size. */ + next = _fraghead[log].next; + if (next != NULL) + { + /* There are free fragments of this size. + Pop a fragment out of the fragment list and return it. + Update the block's nfree and first counters. */ + result = (__ptr_t) next; + next->prev->next = next->next; + if (next->next != NULL) + next->next->prev = next->prev; + block = BLOCK (result); + if (--_heapinfo[block].busy.info.frag.nfree != 0) + _heapinfo[block].busy.info.frag.first = (unsigned long int) + ((unsigned long int) ((char *) next->next - (char *) NULL) + % BLOCKSIZE) >> log; + + /* Update the statistics. */ + ++_chunks_used; + _bytes_used += 1 << log; + --_chunks_free; + _bytes_free -= 1 << log; + } + else + { + /* No free fragments of the desired size, so get a new block + and break it into fragments, returning the first. */ + result = malloc (BLOCKSIZE); + if (result == NULL) + return NULL; + + /* Link all fragments but the first into the free list. */ + next = (struct list *) ((char *) result + (1 << log)); + next->next = NULL; + next->prev = &_fraghead[log]; + _fraghead[log].next = next; + + for (i = 2; i < (__malloc_size_t) (BLOCKSIZE >> log); ++i) + { + next = (struct list *) ((char *) result + (i << log)); + next->next = _fraghead[log].next; + next->prev = &_fraghead[log]; + next->prev->next = next; + next->next->prev = next; + } + + /* Initialize the nfree and first counters for this block. */ + block = BLOCK (result); + _heapinfo[block].busy.type = log; + _heapinfo[block].busy.info.frag.nfree = i - 1; + _heapinfo[block].busy.info.frag.first = i - 1; + + _chunks_free += (BLOCKSIZE >> log) - 1; + _bytes_free += BLOCKSIZE - (1 << log); + _bytes_used -= BLOCKSIZE - (1 << log); + } + } + else + { + /* Large allocation to receive one or more blocks. + Search the free list in a circle starting at the last place visited. + If we loop completely around without finding a large enough + space we will have to get more memory from the system. */ + blocks = BLOCKIFY (size); + start = block = _heapindex; + while (_heapinfo[block].free.size < blocks) + { + block = _heapinfo[block].free.next; + if (block == start) + { + /* Need to get more from the system. Get a little extra. */ + __malloc_size_t wantblocks = blocks + __malloc_extra_blocks; + block = _heapinfo[0].free.prev; + lastblocks = _heapinfo[block].free.size; + /* Check to see if the new core will be contiguous with the + final free block; if so we don't need to get as much. */ + if (_heaplimit != 0 && block + lastblocks == _heaplimit && + /* We can't do this if we will have to make the heap info + table bigger to accomodate the new space. */ + block + wantblocks <= heapsize && + get_contiguous_space ((wantblocks - lastblocks) * BLOCKSIZE, + ADDRESS (block + lastblocks))) + { + /* We got it contiguously. Which block we are extending + (the `final free block' referred to above) might have + changed, if it got combined with a freed info table. */ + block = _heapinfo[0].free.prev; + _heapinfo[block].free.size += (wantblocks - lastblocks); + _bytes_free += (wantblocks - lastblocks) * BLOCKSIZE; + _heaplimit += wantblocks - lastblocks; + continue; + } + result = morecore (wantblocks * BLOCKSIZE); + if (result == NULL) + return NULL; + block = BLOCK (result); + /* Put the new block at the end of the free list. */ + _heapinfo[block].free.size = wantblocks; + _heapinfo[block].free.prev = _heapinfo[0].free.prev; + _heapinfo[block].free.next = 0; + _heapinfo[0].free.prev = block; + _heapinfo[_heapinfo[block].free.prev].free.next = block; + ++_chunks_free; + /* Now loop to use some of that block for this allocation. */ + } + } + + /* At this point we have found a suitable free list entry. + Figure out how to remove what we need from the list. */ + result = ADDRESS (block); + if (_heapinfo[block].free.size > blocks) + { + /* The block we found has a bit left over, + so relink the tail end back into the free list. */ + _heapinfo[block + blocks].free.size + = _heapinfo[block].free.size - blocks; + _heapinfo[block + blocks].free.next + = _heapinfo[block].free.next; + _heapinfo[block + blocks].free.prev + = _heapinfo[block].free.prev; + _heapinfo[_heapinfo[block].free.prev].free.next + = _heapinfo[_heapinfo[block].free.next].free.prev + = _heapindex = block + blocks; + } + else + { + /* The block exactly matches our requirements, + so just remove it from the list. */ + _heapinfo[_heapinfo[block].free.next].free.prev + = _heapinfo[block].free.prev; + _heapinfo[_heapinfo[block].free.prev].free.next + = _heapindex = _heapinfo[block].free.next; + --_chunks_free; + } + + _heapinfo[block].busy.type = 0; + _heapinfo[block].busy.info.size = blocks; + ++_chunks_used; + _bytes_used += blocks * BLOCKSIZE; + _bytes_free -= blocks * BLOCKSIZE; + + /* Mark all the blocks of the object just allocated except for the + first with a negative number so you can find the first block by + adding that adjustment. */ + while (--blocks > 0) + _heapinfo[block + blocks].busy.info.size = -blocks; + } + + return result; +} + +__ptr_t +malloc (size) + __malloc_size_t size; +{ + if (!__malloc_initialized && !__malloc_initialize ()) + return NULL; + + return (__malloc_hook != NULL ? *__malloc_hook : _malloc_internal) (size); +} + +#ifndef _LIBC + +/* On some ANSI C systems, some libc functions call _malloc, _free + and _realloc. Make them use the GNU functions. */ + +__ptr_t +_malloc (size) + __malloc_size_t size; +{ + return malloc (size); +} + +void +_free (ptr) + __ptr_t ptr; +{ + free (ptr); +} + +__ptr_t +_realloc (ptr, size) + __ptr_t ptr; + __malloc_size_t size; +{ + return realloc (ptr, size); +} + +#endif +/* Free a block of memory allocated by `malloc'. + Copyright 1990, 1991, 1992, 1994, 1995 Free Software Foundation, Inc. + Written May 1989 by Mike Haertel. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. + + The author may be reached (Email) at the address mike@ai.mit.edu, + or (US mail) as Mike Haertel c/o Free Software Foundation. */ + +#ifndef _MALLOC_INTERNAL +#define _MALLOC_INTERNAL +#include <malloc.h> +#endif + + +/* Cope with systems lacking `memmove'. */ +#ifndef memmove +#if (defined (MEMMOVE_MISSING) || \ + !defined(_LIBC) && !defined(STDC_HEADERS) && !defined(USG)) +#ifdef emacs +#undef __malloc_safe_bcopy +#define __malloc_safe_bcopy safe_bcopy +#endif +/* This function is defined in realloc.c. */ +extern void __malloc_safe_bcopy __P ((__ptr_t, __ptr_t, __malloc_size_t)); +#define memmove(to, from, size) __malloc_safe_bcopy ((from), (to), (size)) +#endif +#endif + + +/* Debugging hook for free. */ +void (*__free_hook) __P ((__ptr_t __ptr)); + +/* List of blocks allocated by memalign. */ +struct alignlist *_aligned_blocks = NULL; + +/* Return memory to the heap. + Like `free' but don't call a __free_hook if there is one. */ +void +_free_internal (ptr) + __ptr_t ptr; +{ + int type; + __malloc_size_t block, blocks; + register __malloc_size_t i; + struct list *prev, *next; + __ptr_t curbrk; + const __malloc_size_t lesscore_threshold + /* Threshold of free space at which we will return some to the system. */ + = FINAL_FREE_BLOCKS + 2 * __malloc_extra_blocks; + + register struct alignlist *l; + + if (ptr == NULL) + return; + + for (l = _aligned_blocks; l != NULL; l = l->next) + if (l->aligned == ptr) + { + l->aligned = NULL; /* Mark the slot in the list as free. */ + ptr = l->exact; + break; + } + + block = BLOCK (ptr); + + type = _heapinfo[block].busy.type; + switch (type) + { + case 0: + /* Get as many statistics as early as we can. */ + --_chunks_used; + _bytes_used -= _heapinfo[block].busy.info.size * BLOCKSIZE; + _bytes_free += _heapinfo[block].busy.info.size * BLOCKSIZE; + + /* Find the free cluster previous to this one in the free list. + Start searching at the last block referenced; this may benefit + programs with locality of allocation. */ + i = _heapindex; + if (i > block) + while (i > block) + i = _heapinfo[i].free.prev; + else + { + do + i = _heapinfo[i].free.next; + while (i > 0 && i < block); + i = _heapinfo[i].free.prev; + } + + /* Determine how to link this block into the free list. */ + if (block == i + _heapinfo[i].free.size) + { + /* Coalesce this block with its predecessor. */ + _heapinfo[i].free.size += _heapinfo[block].busy.info.size; + block = i; + } + else + { + /* Really link this block back into the free list. */ + _heapinfo[block].free.size = _heapinfo[block].busy.info.size; + _heapinfo[block].free.next = _heapinfo[i].free.next; + _heapinfo[block].free.prev = i; + _heapinfo[i].free.next = block; + _heapinfo[_heapinfo[block].free.next].free.prev = block; + ++_chunks_free; + } + + /* Now that the block is linked in, see if we can coalesce it + with its successor (by deleting its successor from the list + and adding in its size). */ + if (block + _heapinfo[block].free.size == _heapinfo[block].free.next) + { + _heapinfo[block].free.size + += _heapinfo[_heapinfo[block].free.next].free.size; + _heapinfo[block].free.next + = _heapinfo[_heapinfo[block].free.next].free.next; + _heapinfo[_heapinfo[block].free.next].free.prev = block; + --_chunks_free; + } + + /* How many trailing free blocks are there now? */ + blocks = _heapinfo[block].free.size; + + /* Where is the current end of accessible core? */ + curbrk = (*__morecore) (0); + + if (_heaplimit != 0 && curbrk == ADDRESS (_heaplimit)) + { + /* The end of the malloc heap is at the end of accessible core. + It's possible that moving _heapinfo will allow us to + return some space to the system. */ + + __malloc_size_t info_block = BLOCK (_heapinfo); + __malloc_size_t info_blocks = _heapinfo[info_block].busy.info.size; + __malloc_size_t prev_block = _heapinfo[block].free.prev; + __malloc_size_t prev_blocks = _heapinfo[prev_block].free.size; + __malloc_size_t next_block = _heapinfo[block].free.next; + __malloc_size_t next_blocks = _heapinfo[next_block].free.size; + + if (/* Win if this block being freed is last in core, the info table + is just before it, the previous free block is just before the + info table, and the two free blocks together form a useful + amount to return to the system. */ + (block + blocks == _heaplimit && + info_block + info_blocks == block && + prev_block != 0 && prev_block + prev_blocks == info_block && + blocks + prev_blocks >= lesscore_threshold) || + /* Nope, not the case. We can also win if this block being + freed is just before the info table, and the table extends + to the end of core or is followed only by a free block, + and the total free space is worth returning to the system. */ + (block + blocks == info_block && + ((info_block + info_blocks == _heaplimit && + blocks >= lesscore_threshold) || + (info_block + info_blocks == next_block && + next_block + next_blocks == _heaplimit && + blocks + next_blocks >= lesscore_threshold))) + ) + { + malloc_info *newinfo; + __malloc_size_t oldlimit = _heaplimit; + + /* Free the old info table, clearing _heaplimit to avoid + recursion into this code. We don't want to return the + table's blocks to the system before we have copied them to + the new location. */ + _heaplimit = 0; + _free_internal (_heapinfo); + _heaplimit = oldlimit; + + /* Tell malloc to search from the beginning of the heap for + free blocks, so it doesn't reuse the ones just freed. */ + _heapindex = 0; + + /* Allocate new space for the info table and move its data. */ + newinfo = (malloc_info *) _malloc_internal (info_blocks + * BLOCKSIZE); + memmove (newinfo, _heapinfo, info_blocks * BLOCKSIZE); + _heapinfo = newinfo; + + /* We should now have coalesced the free block with the + blocks freed from the old info table. Examine the entire + trailing free block to decide below whether to return some + to the system. */ + block = _heapinfo[0].free.prev; + blocks = _heapinfo[block].free.size; + } + + /* Now see if we can return stuff to the system. */ + if (block + blocks == _heaplimit && blocks >= lesscore_threshold) + { + register __malloc_size_t bytes = blocks * BLOCKSIZE; + _heaplimit -= blocks; + (*__morecore) (-bytes); + _heapinfo[_heapinfo[block].free.prev].free.next + = _heapinfo[block].free.next; + _heapinfo[_heapinfo[block].free.next].free.prev + = _heapinfo[block].free.prev; + block = _heapinfo[block].free.prev; + --_chunks_free; + _bytes_free -= bytes; + } + } + + /* Set the next search to begin at this block. */ + _heapindex = block; + break; + + default: + /* Do some of the statistics. */ + --_chunks_used; + _bytes_used -= 1 << type; + ++_chunks_free; + _bytes_free += 1 << type; + + /* Get the address of the first free fragment in this block. */ + prev = (struct list *) ((char *) ADDRESS (block) + + (_heapinfo[block].busy.info.frag.first << type)); + + if (_heapinfo[block].busy.info.frag.nfree == (BLOCKSIZE >> type) - 1) + { + /* If all fragments of this block are free, remove them + from the fragment list and free the whole block. */ + next = prev; + for (i = 1; i < (__malloc_size_t) (BLOCKSIZE >> type); ++i) + next = next->next; + prev->prev->next = next; + if (next != NULL) + next->prev = prev->prev; + _heapinfo[block].busy.type = 0; + _heapinfo[block].busy.info.size = 1; + + /* Keep the statistics accurate. */ + ++_chunks_used; + _bytes_used += BLOCKSIZE; + _chunks_free -= BLOCKSIZE >> type; + _bytes_free -= BLOCKSIZE; + + free (ADDRESS (block)); + } + else if (_heapinfo[block].busy.info.frag.nfree != 0) + { + /* If some fragments of this block are free, link this + fragment into the fragment list after the first free + fragment of this block. */ + next = (struct list *) ptr; + next->next = prev->next; + next->prev = prev; + prev->next = next; + if (next->next != NULL) + next->next->prev = next; + ++_heapinfo[block].busy.info.frag.nfree; + } + else + { + /* No fragments of this block are free, so link this + fragment into the fragment list and announce that + it is the first free fragment of this block. */ + prev = (struct list *) ptr; + _heapinfo[block].busy.info.frag.nfree = 1; + _heapinfo[block].busy.info.frag.first = (unsigned long int) + ((unsigned long int) ((char *) ptr - (char *) NULL) + % BLOCKSIZE >> type); + prev->next = _fraghead[type].next; + prev->prev = &_fraghead[type]; + prev->prev->next = prev; + if (prev->next != NULL) + prev->next->prev = prev; + } + break; + } +} + +/* Return memory to the heap. */ +void +free (ptr) + __ptr_t ptr; +{ + if (__free_hook != NULL) + (*__free_hook) (ptr); + else + _free_internal (ptr); +} + +/* Define the `cfree' alias for `free'. */ +#ifdef weak_alias +weak_alias (free, cfree) +#else +void +cfree (ptr) + __ptr_t ptr; +{ + free (ptr); +} +#endif +/* Change the size of a block allocated by `malloc'. + Copyright 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. + Written May 1989 by Mike Haertel. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. + + The author may be reached (Email) at the address mike@ai.mit.edu, + or (US mail) as Mike Haertel c/o Free Software Foundation. */ + +#ifndef _MALLOC_INTERNAL +#define _MALLOC_INTERNAL +#include <malloc.h> +#endif + + + +/* Cope with systems lacking `memmove'. */ +#if (defined (MEMMOVE_MISSING) || \ + !defined(_LIBC) && !defined(STDC_HEADERS) && !defined(USG)) + +#ifdef emacs +#undef __malloc_safe_bcopy +#define __malloc_safe_bcopy safe_bcopy +#else + +/* Snarfed directly from Emacs src/dispnew.c: + XXX Should use system bcopy if it handles overlap. */ + +/* Like bcopy except never gets confused by overlap. */ + +void +__malloc_safe_bcopy (afrom, ato, size) + __ptr_t afrom; + __ptr_t ato; + __malloc_size_t size; +{ + char *from = afrom, *to = ato; + + if (size <= 0 || from == to) + return; + + /* If the source and destination don't overlap, then bcopy can + handle it. If they do overlap, but the destination is lower in + memory than the source, we'll assume bcopy can handle that. */ + if (to < from || from + size <= to) + bcopy (from, to, size); + + /* Otherwise, we'll copy from the end. */ + else + { + register char *endf = from + size; + register char *endt = to + size; + + /* If TO - FROM is large, then we should break the copy into + nonoverlapping chunks of TO - FROM bytes each. However, if + TO - FROM is small, then the bcopy function call overhead + makes this not worth it. The crossover point could be about + anywhere. Since I don't think the obvious copy loop is too + bad, I'm trying to err in its favor. */ + if (to - from < 64) + { + do + *--endt = *--endf; + while (endf != from); + } + else + { + for (;;) + { + endt -= (to - from); + endf -= (to - from); + + if (endt < to) + break; + + bcopy (endf, endt, to - from); + } + + /* If SIZE wasn't a multiple of TO - FROM, there will be a + little left over. The amount left over is + (endt + (to - from)) - to, which is endt - from. */ + bcopy (from, to, endt - from); + } + } +} +#endif /* emacs */ + +#ifndef memmove +extern void __malloc_safe_bcopy __P ((__ptr_t, __ptr_t, __malloc_size_t)); +#define memmove(to, from, size) __malloc_safe_bcopy ((from), (to), (size)) +#endif + +#endif + + +#define min(A, B) ((A) < (B) ? (A) : (B)) + +/* Debugging hook for realloc. */ +__ptr_t (*__realloc_hook) __P ((__ptr_t __ptr, __malloc_size_t __size)); + +/* Resize the given region to the new size, returning a pointer + to the (possibly moved) region. This is optimized for speed; + some benchmarks seem to indicate that greater compactness is + achieved by unconditionally allocating and copying to a + new region. This module has incestuous knowledge of the + internals of both free and malloc. */ +__ptr_t +_realloc_internal (ptr, size) + __ptr_t ptr; + __malloc_size_t size; +{ + __ptr_t result; + int type; + __malloc_size_t block, blocks, oldlimit; + + if (size == 0) + { + _free_internal (ptr); + return _malloc_internal (0); + } + else if (ptr == NULL) + return _malloc_internal (size); + + block = BLOCK (ptr); + + type = _heapinfo[block].busy.type; + switch (type) + { + case 0: + /* Maybe reallocate a large block to a small fragment. */ + if (size <= BLOCKSIZE / 2) + { + result = _malloc_internal (size); + if (result != NULL) + { + memcpy (result, ptr, size); + _free_internal (ptr); + return result; + } + } + + /* The new size is a large allocation as well; + see if we can hold it in place. */ + blocks = BLOCKIFY (size); + if (blocks < _heapinfo[block].busy.info.size) + { + /* The new size is smaller; return + excess memory to the free list. */ + _heapinfo[block + blocks].busy.type = 0; + _heapinfo[block + blocks].busy.info.size + = _heapinfo[block].busy.info.size - blocks; + _heapinfo[block].busy.info.size = blocks; + /* We have just created a new chunk by splitting a chunk in two. + Now we will free this chunk; increment the statistics counter + so it doesn't become wrong when _free_internal decrements it. */ + ++_chunks_used; + _free_internal (ADDRESS (block + blocks)); + result = ptr; + } + else if (blocks == _heapinfo[block].busy.info.size) + /* No size change necessary. */ + result = ptr; + else + { + /* Won't fit, so allocate a new region that will. + Free the old region first in case there is sufficient + adjacent free space to grow without moving. */ + blocks = _heapinfo[block].busy.info.size; + /* Prevent free from actually returning memory to the system. */ + oldlimit = _heaplimit; + _heaplimit = 0; + _free_internal (ptr); + result = _malloc_internal (size); + if (_heaplimit == 0) + _heaplimit = oldlimit; + if (result == NULL) + { + /* Now we're really in trouble. We have to unfree + the thing we just freed. Unfortunately it might + have been coalesced with its neighbors. */ + if (_heapindex == block) + (void) _malloc_internal (blocks * BLOCKSIZE); + else + { + __ptr_t previous + = _malloc_internal ((block - _heapindex) * BLOCKSIZE); + (void) _malloc_internal (blocks * BLOCKSIZE); + _free_internal (previous); + } + return NULL; + } + if (ptr != result) + memmove (result, ptr, blocks * BLOCKSIZE); + } + break; + + default: + /* Old size is a fragment; type is logarithm + to base two of the fragment size. */ + if (size > (__malloc_size_t) (1 << (type - 1)) && + size <= (__malloc_size_t) (1 << type)) + /* The new size is the same kind of fragment. */ + result = ptr; + else + { + /* The new size is different; allocate a new space, + and copy the lesser of the new size and the old. */ + result = _malloc_internal (size); + if (result == NULL) + return NULL; + memcpy (result, ptr, min (size, (__malloc_size_t) 1 << type)); + _free_internal (ptr); + } + break; + } + + return result; +} + +__ptr_t +realloc (ptr, size) + __ptr_t ptr; + __malloc_size_t size; +{ + if (!__malloc_initialized && !__malloc_initialize ()) + return NULL; + + return (__realloc_hook != NULL ? *__realloc_hook : _realloc_internal) + (ptr, size); +} +/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. + + The author may be reached (Email) at the address mike@ai.mit.edu, + or (US mail) as Mike Haertel c/o Free Software Foundation. */ + +#ifndef _MALLOC_INTERNAL +#define _MALLOC_INTERNAL +#include <malloc.h> +#endif + +/* Allocate an array of NMEMB elements each SIZE bytes long. + The entire array is initialized to zeros. */ +__ptr_t +calloc (nmemb, size) + register __malloc_size_t nmemb; + register __malloc_size_t size; +{ + register __ptr_t result = malloc (nmemb * size); + + if (result != NULL) + (void) memset (result, 0, nmemb * size); + + return result; +} +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the GNU C Library; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef _MALLOC_INTERNAL +#define _MALLOC_INTERNAL +#include <malloc.h> +#endif + +#ifndef __GNU_LIBRARY__ +#define __sbrk sbrk +#endif + +#ifdef __GNU_LIBRARY__ +/* It is best not to declare this and cast its result on foreign operating + systems with potentially hostile include files. */ + +#include <stddef.h> +extern __ptr_t __sbrk __P ((ptrdiff_t increment)); +#endif + +#ifndef NULL +#define NULL 0 +#endif + +/* Allocate INCREMENT more bytes of data space, + and return the start of data space, or NULL on errors. + If INCREMENT is negative, shrink data space. */ +__ptr_t +__default_morecore (increment) + __malloc_ptrdiff_t increment; +{ + __ptr_t result = (__ptr_t) __sbrk (increment); + if (result == (__ptr_t) -1) + return NULL; + return result; +} +/* Copyright (C) 1991, 92, 93, 94, 95, 96 Free Software Foundation, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _MALLOC_INTERNAL +#define _MALLOC_INTERNAL +#include <malloc.h> +#endif + +#if __DJGPP__ - 0 == 1 + +/* There is some problem with memalign in DJGPP v1 and we are supposed + to omit it. Noone told me why, they just told me to do it. */ + +#else + +__ptr_t (*__memalign_hook) __P ((size_t __size, size_t __alignment)); + +__ptr_t +memalign (alignment, size) + __malloc_size_t alignment; + __malloc_size_t size; +{ + __ptr_t result; + unsigned long int adj, lastadj; + + if (__memalign_hook) + return (*__memalign_hook) (alignment, size); + + /* Allocate a block with enough extra space to pad the block with up to + (ALIGNMENT - 1) bytes if necessary. */ + result = malloc (size + alignment - 1); + if (result == NULL) + return NULL; + + /* Figure out how much we will need to pad this particular block + to achieve the required alignment. */ + adj = (unsigned long int) ((char *) result - (char *) NULL) % alignment; + + do + { + /* Reallocate the block with only as much excess as it needs. */ + free (result); + result = malloc (adj + size); + if (result == NULL) /* Impossible unless interrupted. */ + return NULL; + + lastadj = adj; + adj = (unsigned long int) ((char *) result - (char *) NULL) % alignment; + /* It's conceivable we might have been so unlucky as to get a + different block with weaker alignment. If so, this block is too + short to contain SIZE after alignment correction. So we must + try again and get another block, slightly larger. */ + } while (adj > lastadj); + + if (adj != 0) + { + /* Record this block in the list of aligned blocks, so that `free' + can identify the pointer it is passed, which will be in the middle + of an allocated block. */ + + struct alignlist *l; + for (l = _aligned_blocks; l != NULL; l = l->next) + if (l->aligned == NULL) + /* This slot is free. Use it. */ + break; + if (l == NULL) + { + l = (struct alignlist *) malloc (sizeof (struct alignlist)); + if (l == NULL) + { + free (result); + return NULL; + } + l->next = _aligned_blocks; + _aligned_blocks = l; + } + l->exact = result; + result = l->aligned = (char *) result + alignment - adj; + } + + return result; +} + +#endif /* Not DJGPP v1 */ diff --git a/lib/malloc/malloc.c b/lib/malloc/malloc.c index 78fb640..88217db 100644 --- a/lib/malloc/malloc.c +++ b/lib/malloc/malloc.c @@ -58,34 +58,27 @@ what you give them. Help stamp out software-hoarding! */ #endif */ +/* Define this to have free() write 0xcf into memory as it's freed, to + uncover callers that refer to freed memory. */ +/* SCO 3.2v4 getcwd and possibly other libc routines fail with MEMSCRAMBLE */ +#if !defined (NO_MEMSCRAMBLE) +# define MEMSCRAMBLE +#endif + #if defined (emacs) || defined (HAVE_CONFIG_H) -# include "config.h" +# include <config.h> #endif /* emacs */ -#if !defined (USG) -# if defined (HPUX) || defined (UnixPC) || defined (Xenix) -# define USG -# endif /* HPUX || UnixPC || Xenix */ -#endif /* !USG */ +#if defined (HAVE_UNISTD_H) +# include <unistd.h> +#endif /* Determine which kind of system this is. */ #include <sys/types.h> #include <signal.h> -#if !defined (USG) && !defined (USGr4) -# ifndef SIGTSTP -# ifndef USG -# define USG -# endif /* !USG */ -# else /* SIGTSTP */ -# ifdef SIGIO -# define BSD4_2 -# endif /* SIGIO */ -# endif /* SIGTSTP */ -#endif /* !USG && !USGr4 */ - -#ifndef BSD4_2 - /* Define getpagesize () if the system does not. */ +/* Define getpagesize () if the system does not. */ +#ifndef HAVE_GETPAGESIZE # include "getpagesize.h" #endif @@ -100,6 +93,10 @@ what you give them. Help stamp out software-hoarding! */ # undef HAVE_RESOURCE #endif +#if !defined (NULL) +# define NULL 0 +#endif + #define start_of_data() &etext #define ISALLOC ((char) 0xf7) /* magic byte that implies allocation */ @@ -111,12 +108,11 @@ what you give them. Help stamp out software-hoarding! */ beginning of the block. */ extern char etext; -#if !defined (NO_SBRK_DECL) +#if !defined (SBRK_DECLARED) extern char *sbrk (); -#endif /* !NO_SBRK_DECL */ +#endif /* !SBRK_DECLARED */ /* These two are for user programs to look at, when they are interested. */ - unsigned int malloc_sbrk_used; /* amount of data space used now */ unsigned int malloc_sbrk_unused; /* amount more we can have */ @@ -143,7 +139,7 @@ struct mhead { /* Remainder are valid only when block is allocated */ unsigned short mh_size; /* size, if < 0x10000 */ #ifdef rcheck - unsigned mh_nbytes; /* number of bytes allocated */ + unsigned int mh_nbytes; /* number of bytes allocated */ int mh_magic4; /* should be == MAGIC4 */ #endif /* rcheck */ }; @@ -241,7 +237,7 @@ malloc_usable_size (mem) return blocksize - sizeof (struct mhead) - EXTRA; } - + static void morecore (nu) /* ask system for more memory */ register int nu; /* size index to get more of */ @@ -249,11 +245,19 @@ morecore (nu) /* ask system for more memory */ register char *cp; register int nblks; register unsigned int siz; - int oldmask; -#if defined (BSD4_2) + /* Block all signals in case we are executed from a signal handler. */ +#if defined (HAVE_BSD_SIGNALS) + int oldmask; oldmask = sigsetmask (-1); -#endif /* BSD4_2 */ +#else +# if defined (HAVE_POSIX_SIGNALS) + sigset_t set, oset; + sigfillset (&set); + sigemptyset (&oset); + sigprocmask (SIG_BLOCK, &set, &oset); +# endif /* HAVE_POSIX_SIGNALS */ +#endif /* HAVE_BSD_SIGNALS */ if (!data_space_start) { @@ -331,9 +335,13 @@ morecore (nu) /* ask system for more memory */ } CHAIN ((struct mhead *) cp) = 0; -#if defined (BSD4_2) +#if defined (HAVE_BSD_SIGNALS) sigsetmask (oldmask); -#endif /* BSD4_2 */ +#else +# if defined (HAVE_POSIX_SIGNALS) + sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL); +# endif +#endif /* HAVE_BSD_SIGNALS */ } static void @@ -373,10 +381,26 @@ getpool () cp += 8 << nu; } } - + +#if defined (MEMSCRAMBLE) || !defined (NO_CALLOC) +static char * +zmemset (s, c, n) + char *s; + int c; + register int n; +{ + register char *sp; + + sp = s; + while (--n >= 0) + *sp++ = c; + return (s); +} +#endif /* MEMSCRAMBLE || !NO_CALLOC */ + char * malloc (n) /* get a block */ - unsigned n; + unsigned int n; { register struct mhead *p; register unsigned int nbytes; @@ -436,6 +460,9 @@ malloc (n) /* get a block */ #else /* not rcheck */ p -> mh_size = n; #endif /* not rcheck */ +#ifdef MEMSCRAMBLE + zmemset ((char *)(p + 1), 0xdf, n); /* scramble previous contents */ +#endif #ifdef MSTATS nmalloc[nunits]++; nmal++; @@ -474,7 +501,7 @@ free (mem) if (p -> mh_alloc == ISFREE) botch ("free: Called with already freed block argument\n"); else - botch ("free: Called with bad argument\n"); + botch ("free: Called with unallocated block argument\n"); } ASSERT (p -> mh_magic4 == MAGIC4); @@ -483,6 +510,18 @@ free (mem) ASSERT (*ap++ == MAGIC1); ASSERT (*ap == MAGIC1); #endif /* rcheck */ } +#ifdef MEMSCRAMBLE + { + register int n; + +#ifdef rcheck + n = p->mh_nbytes; +#else /* not rcheck */ + n = p->mh_size; +#endif /* not rcheck */ + zmemset (mem, 0xcf, n); + } +#endif { register int nunits = p -> mh_index; @@ -506,7 +545,7 @@ free (mem) char * realloc (mem, n) char *mem; - register unsigned n; + register unsigned int n; { register struct mhead *p; register unsigned int tocopy; @@ -565,12 +604,14 @@ realloc (mem, n) char * memalign (alignment, size) - unsigned alignment, size; + unsigned int alignment, size; { - register char *ptr = malloc (size + alignment); + register char *ptr; register char *aligned; register struct mhead *p; + ptr = malloc (size + alignment); + if (ptr == 0) return 0; /* If entire block has the desired alignment, just accept it. */ @@ -587,16 +628,44 @@ memalign (alignment, size) return aligned; } -#if !defined (HPUX) && !defined (Multimax) && !defined (Multimax32k) +#if !defined (HPUX) /* This runs into trouble with getpagesize on HPUX, and Multimax machines. Patching out seems cleaner than the ugly fix needed. */ +#if defined (__STDC__) +void * +#else char * +#endif valloc (size) + size_t size; { return memalign (getpagesize (), size); } -#endif /* !HPUX && !Multimax && !Multimax32k */ - +#endif /* !HPUX */ + +#ifndef NO_CALLOC +char * +calloc (n, s) + size_t n, s; +{ + size_t total; + char *result; + + total = n * s; + result = malloc (total); + if (result) + zmemset (result, 0, total); + return result; +} + +void +cfree (p) + char *p; +{ + free (p); +} +#endif /* !NO_CALLOC */ + #ifdef MSTATS /* Return statistics describing allocation of blocks of size 2**n. */ @@ -633,7 +702,7 @@ malloc_stats (size) return v; } #endif /* MSTATS */ - + /* * This function returns the total number of bytes that the process * will be allowed to allocate via the sbrk(2) system call. On diff --git a/lib/malloc/stub.c b/lib/malloc/stub.c new file mode 100644 index 0000000..d297c65 --- /dev/null +++ b/lib/malloc/stub.c @@ -0,0 +1,4 @@ +void +bash_malloc_stub() +{ +} diff --git a/lib/malloc/xmalloc.c b/lib/malloc/xmalloc.c index 4f6dc76..4160651 100644 --- a/lib/malloc/xmalloc.c +++ b/lib/malloc/xmalloc.c @@ -19,8 +19,10 @@ along with Readline; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ -#if defined (ALREADY_HAVE_XMALLOC) -#else +#if defined (HAVE_CONFIG_H) +#include <config.h> +#endif + #include <stdio.h> #if defined (HAVE_STDLIB_H) @@ -44,9 +46,10 @@ char * xmalloc (bytes) int bytes; { - char *temp = (char *)malloc (bytes); + char *temp; - if (!temp) + temp = (char *)malloc (bytes); + if (temp == 0) memory_error_and_abort ("xmalloc"); return (temp); } @@ -58,12 +61,9 @@ xrealloc (pointer, bytes) { char *temp; - if (!pointer) - temp = (char *)malloc (bytes); - else - temp = (char *)realloc (pointer, bytes); + temp = pointer ? (char *)realloc (pointer, bytes) : (char *)malloc (bytes); - if (!temp) + if (temp == 0) memory_error_and_abort ("xrealloc"); return (temp); } @@ -72,7 +72,16 @@ static void memory_error_and_abort (fname) char *fname; { - fprintf (stderr, "%s: Out of virtual memory!\n", fname); - abort (); + fprintf (stderr, "%s: out of virtual memory\n", fname); + exit (2); +} + +/* Use this as the function to call when adding unwind protects so we + don't need to know what free() returns. */ +void +xfree (string) + char *string; +{ + if (string) + free (string); } -#endif /* !ALREADY_HAVE_XMALLOC */ diff --git a/lib/malloclib/Makefile b/lib/malloclib/Makefile deleted file mode 100644 index 7a449c3..0000000 --- a/lib/malloclib/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright (C) 1991 Free Software Foundation, Inc. -# This file is part of the GNU C Library. - -# The GNU C Library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Library General Public License -# as published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. - -# The GNU C Library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Library General Public License for more details. - -# You should have received a copy of the GNU Library General Public -# License along with the GNU C Library; see the file COPYING.LIB. If -# not, write to the Free Software Foundation, Inc., 675 Mass Ave, -# Cambridge, MA 02139, USA. - -# Makefile for standalone distribution of malloc. - -srcdir = . -VPATH = .:$(srcdir) - -all: libmalloc.a - -sources = calloc.c cfree.c free.c malloc.c mcheck.c morecore.c \ - memalign.c mstats.c mtrace.c realloc.c valloc.c -objects = calloc.o cfree.o free.o malloc.o mcheck.o morecore.o \ - memalign.o mstats.o mtrace.o realloc.o valloc.o -headers = malloc.h getpagesize.h - -libmalloc.a: $(objects) - ar crv $@ $(objects) - ranlib $@ - -.c.o: - $(CC) $(CFLAGS) $(CPPFLAGS) -I. -c $< $(OUTPUT_OPTION) - -.PHONY: clean realclean malloc-clean malloc-realclean -clean malloc-clean: - -rm -f libmalloc.a $(objects) core -realclean malloc-realclean: clean - -rm -f TAGS tags *~ - -calloc.o: malloc.h -free.o: malloc.h -malloc.o: malloc.h -mcheck.o: malloc.h -memalign.o: malloc.h -mstats.o: malloc.h -mtrace.o: malloc.h -realloc.o: malloc.h -valloc.o: malloc.h getpagesize.h diff --git a/lib/malloclib/alloca.c b/lib/malloclib/alloca.c deleted file mode 100644 index 918d023..0000000 --- a/lib/malloclib/alloca.c +++ /dev/null @@ -1,189 +0,0 @@ -/* alloca -- (mostly) portable public-domain implementation -- D A Gwyn - - last edit: 86/05/30 rms - include config.h, since on VMS it renames some symbols. - Use xmalloc instead of malloc. - - This implementation of the PWB library alloca() function, - which is used to allocate space off the run-time stack so - that it is automatically reclaimed upon procedure exit, - was inspired by discussions with J. Q. Johnson of Cornell. - - It should work under any C implementation that uses an - actual procedure stack (as opposed to a linked list of - frames). There are some preprocessor constants that can - be defined when compiling for your specific system, for - improved efficiency; however, the defaults should be okay. - - The general concept of this implementation is to keep - track of all alloca()-allocated blocks, and reclaim any - that are found to be deeper in the stack than the current - invocation. This heuristic does not reclaim storage as - soon as it becomes invalid, but it will do so eventually. - - As a special case, alloca(0) reclaims storage without - allocating any. It is a good idea to use alloca(0) in - your main control loop, etc. to force garbage collection. -*/ -#ifndef lint -static char SCCSid[] = "@(#)alloca.c 1.1"; /* for the "what" utility */ -#endif - -#ifdef emacs -#include "config.h" -#ifdef static -/* actually, only want this if static is defined as "" - -- this is for usg, in which emacs must undefine static - in order to make unexec workable - */ -#ifndef STACK_DIRECTION -you -lose --- must know STACK_DIRECTION at compile-time -#endif /* STACK_DIRECTION undefined */ -#endif /* static */ -#endif /* emacs */ - -#ifdef X3J11 -typedef void *pointer; /* generic pointer type */ -#else -typedef char *pointer; /* generic pointer type */ -#endif /* X3J11 */ - -#define NULL 0 /* null pointer constant */ - -extern void free(); -extern pointer xmalloc(); - -/* - Define STACK_DIRECTION if you know the direction of stack - growth for your system; otherwise it will be automatically - deduced at run-time. - - STACK_DIRECTION > 0 => grows toward higher addresses - STACK_DIRECTION < 0 => grows toward lower addresses - STACK_DIRECTION = 0 => direction of growth unknown -*/ - -#ifndef STACK_DIRECTION -#define STACK_DIRECTION 0 /* direction unknown */ -#endif - -#if STACK_DIRECTION != 0 - -#define STACK_DIR STACK_DIRECTION /* known at compile-time */ - -#else /* STACK_DIRECTION == 0; need run-time code */ - -static int stack_dir; /* 1 or -1 once known */ -#define STACK_DIR stack_dir - -static void -find_stack_direction (/* void */) -{ - static char *addr = NULL; /* address of first - `dummy', once known */ - auto char dummy; /* to get stack address */ - - if (addr == NULL) - { /* initial entry */ - addr = &dummy; - - find_stack_direction (); /* recurse once */ - } - else /* second entry */ - if (&dummy > addr) - stack_dir = 1; /* stack grew upward */ - else - stack_dir = -1; /* stack grew downward */ -} - -#endif /* STACK_DIRECTION == 0 */ - -/* - An "alloca header" is used to: - (a) chain together all alloca()ed blocks; - (b) keep track of stack depth. - - It is very important that sizeof(header) agree with malloc() - alignment chunk size. The following default should work okay. -*/ - -#ifndef ALIGN_SIZE -#define ALIGN_SIZE sizeof(double) -#endif - -typedef union hdr -{ - char align[ALIGN_SIZE]; /* to force sizeof(header) */ - struct - { - union hdr *next; /* for chaining headers */ - char *deep; /* for stack depth measure */ - } h; -} header; - -/* - alloca( size ) returns a pointer to at least `size' bytes of - storage which will be automatically reclaimed upon exit from - the procedure that called alloca(). Originally, this space - was supposed to be taken from the current stack frame of the - caller, but that method cannot be made to work for some - implementations of C, for example under Gould's UTX/32. -*/ - -static header *last_alloca_header = NULL; /* -> last alloca header */ - -pointer -alloca (size) /* returns pointer to storage */ - unsigned size; /* # bytes to allocate */ -{ - auto char probe; /* probes stack depth: */ - register char *depth = &probe; - -#if STACK_DIRECTION == 0 - if (STACK_DIR == 0) /* unknown growth direction */ - find_stack_direction (); -#endif - - /* Reclaim garbage, defined as all alloca()ed storage that - was allocated from deeper in the stack than currently. */ - { - register header *hp; /* traverses linked list */ - - for (hp = last_alloca_header; hp != NULL;) - if (STACK_DIR > 0 && hp->h.deep > depth - || STACK_DIR < 0 && hp->h.deep < depth) - { - register header *np = hp->h.next; - - free ((pointer) hp); /* collect garbage */ - - hp = np; /* -> next header */ - } - else - break; /* rest are not deeper */ - - last_alloca_header = hp; /* -> last valid storage */ - } - - if (size == 0) - return NULL; /* no allocation required */ - - /* Allocate combined header + user data storage. */ - - { - register pointer new = xmalloc (sizeof (header) + size); - /* address of header */ - - ((header *)new)->h.next = last_alloca_header; - ((header *)new)->h.deep = depth; - - last_alloca_header = (header *)new; - - /* User storage begins just after header. */ - - return (pointer)((char *)new + sizeof(header)); - } -} - diff --git a/lib/malloclib/calloc.c b/lib/malloclib/calloc.c deleted file mode 100644 index f870e94..0000000 --- a/lib/malloclib/calloc.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. - - The author may be reached (Email) at the address mike@ai.mit.edu, - or (US mail) as Mike Haertel c/o Free Software Foundation. */ - -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include <malloc.h> -#endif - -/* Allocate an array of NMEMB elements each SIZE bytes long. - The entire array is initialized to zeros. */ -__ptr_t -calloc (nmemb, size) - register size_t nmemb; - register size_t size; -{ - register __ptr_t result = malloc (nmemb * size); - - if (result != NULL) - (void) memset (result, 0, nmemb * size); - - return result; -} diff --git a/lib/malloclib/cfree.c b/lib/malloclib/cfree.c deleted file mode 100644 index adc1ff6..0000000 --- a/lib/malloclib/cfree.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (C) 1991, 1993 Free Software Foundation, Inc. -This file is part of the GNU C Library. - -The GNU C Library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -The GNU C Library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with the GNU C Library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. */ - -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include <malloc.h> -#endif - -#undef cfree - -#ifdef _LIBC - -#include <ansidecl.h> -#include <gnu-stabs.h> - -function_alias(cfree, free, void, (ptr), - DEFUN(cfree, (ptr), PTR ptr)) - -#else - -void -cfree (ptr) - __ptr_t ptr; -{ - free (ptr); -} - -#endif diff --git a/lib/malloclib/free.c b/lib/malloclib/free.c deleted file mode 100644 index db97fcb..0000000 --- a/lib/malloclib/free.c +++ /dev/null @@ -1,212 +0,0 @@ -/* Free a block of memory allocated by `malloc'. - Copyright 1990, 1991, 1992 Free Software Foundation - Written May 1989 by Mike Haertel. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. - - The author may be reached (Email) at the address mike@ai.mit.edu, - or (US mail) as Mike Haertel c/o Free Software Foundation. */ - -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include <malloc.h> -#endif - -/* Debugging hook for free. */ -void (*__free_hook) __P ((__ptr_t __ptr)); - -/* List of blocks allocated by memalign. */ -struct alignlist *_aligned_blocks = NULL; - -/* Return memory to the heap. - Like `free' but don't call a __free_hook if there is one. */ -void -_free_internal (ptr) - __ptr_t ptr; -{ - int type; - size_t block, blocks; - register size_t i; - struct list *prev, *next; - - block = BLOCK (ptr); - - type = _heapinfo[block].busy.type; - switch (type) - { - case 0: - /* Get as many statistics as early as we can. */ - --_chunks_used; - _bytes_used -= _heapinfo[block].busy.info.size * BLOCKSIZE; - _bytes_free += _heapinfo[block].busy.info.size * BLOCKSIZE; - - /* Find the free cluster previous to this one in the free list. - Start searching at the last block referenced; this may benefit - programs with locality of allocation. */ - i = _heapindex; - if (i > block) - while (i > block) - i = _heapinfo[i].free.prev; - else - { - do - i = _heapinfo[i].free.next; - while (i > 0 && i < block); - i = _heapinfo[i].free.prev; - } - - /* Determine how to link this block into the free list. */ - if (block == i + _heapinfo[i].free.size) - { - /* Coalesce this block with its predecessor. */ - _heapinfo[i].free.size += _heapinfo[block].busy.info.size; - block = i; - } - else - { - /* Really link this block back into the free list. */ - _heapinfo[block].free.size = _heapinfo[block].busy.info.size; - _heapinfo[block].free.next = _heapinfo[i].free.next; - _heapinfo[block].free.prev = i; - _heapinfo[i].free.next = block; - _heapinfo[_heapinfo[block].free.next].free.prev = block; - ++_chunks_free; - } - - /* Now that the block is linked in, see if we can coalesce it - with its successor (by deleting its successor from the list - and adding in its size). */ - if (block + _heapinfo[block].free.size == _heapinfo[block].free.next) - { - _heapinfo[block].free.size - += _heapinfo[_heapinfo[block].free.next].free.size; - _heapinfo[block].free.next - = _heapinfo[_heapinfo[block].free.next].free.next; - _heapinfo[_heapinfo[block].free.next].free.prev = block; - --_chunks_free; - } - - /* Now see if we can return stuff to the system. */ - blocks = _heapinfo[block].free.size; - if (blocks >= FINAL_FREE_BLOCKS && block + blocks == _heaplimit - && (*__morecore) (0) == ADDRESS (block + blocks)) - { - register size_t bytes = blocks * BLOCKSIZE; - _heaplimit -= blocks; - (*__morecore) (-bytes); - _heapinfo[_heapinfo[block].free.prev].free.next - = _heapinfo[block].free.next; - _heapinfo[_heapinfo[block].free.next].free.prev - = _heapinfo[block].free.prev; - block = _heapinfo[block].free.prev; - --_chunks_free; - _bytes_free -= bytes; - } - - /* Set the next search to begin at this block. */ - _heapindex = block; - break; - - default: - /* Do some of the statistics. */ - --_chunks_used; - _bytes_used -= 1 << type; - ++_chunks_free; - _bytes_free += 1 << type; - - /* Get the address of the first free fragment in this block. */ - prev = (struct list *) ((char *) ADDRESS (block) + - (_heapinfo[block].busy.info.frag.first << type)); - - if (_heapinfo[block].busy.info.frag.nfree == (BLOCKSIZE >> type) - 1 - && _fragblocks[type] > 1) - { - /* If all fragments of this block are free, remove them - from the fragment list and free the whole block. */ - --_fragblocks[type]; - next = prev; - for (i = 1; i < (size_t) (BLOCKSIZE >> type); ++i) - next = next->next; - prev->prev->next = next; - if (next != NULL) - next->prev = prev->prev; - _heapinfo[block].busy.type = 0; - _heapinfo[block].busy.info.size = 1; - - /* Keep the statistics accurate. */ - ++_chunks_used; - _bytes_used += BLOCKSIZE; - _chunks_free -= BLOCKSIZE >> type; - _bytes_free -= BLOCKSIZE; - - free (ADDRESS (block)); - } - else if (_heapinfo[block].busy.info.frag.nfree != 0) - { - /* If some fragments of this block are free, link this - fragment into the fragment list after the first free - fragment of this block. */ - next = (struct list *) ptr; - next->next = prev->next; - next->prev = prev; - prev->next = next; - if (next->next != NULL) - next->next->prev = next; - ++_heapinfo[block].busy.info.frag.nfree; - } - else - { - /* No fragments of this block are free, so link this - fragment into the fragment list and announce that - it is the first free fragment of this block. */ - prev = (struct list *) ptr; - _heapinfo[block].busy.info.frag.nfree = 1; - _heapinfo[block].busy.info.frag.first = (unsigned long int) - ((unsigned long int) ((char *) ptr - (char *) NULL) - % BLOCKSIZE >> type); - prev->next = _fraghead[type].next; - prev->prev = &_fraghead[type]; - prev->prev->next = prev; - if (prev->next != NULL) - prev->next->prev = prev; - } - break; - } -} - -/* Return memory to the heap. */ -void -free (ptr) - __ptr_t ptr; -{ - register struct alignlist *l; - - if (ptr == NULL) - return; - - for (l = _aligned_blocks; l != NULL; l = l->next) - if (l->aligned == ptr) - { - l->aligned = NULL; /* Mark the slot in the list as free. */ - ptr = l->exact; - break; - } - - if (__free_hook != NULL) - (*__free_hook) (ptr); - else - _free_internal (ptr); -} diff --git a/lib/malloclib/getpagesize.h b/lib/malloclib/getpagesize.h deleted file mode 100644 index b3aa4ba..0000000 --- a/lib/malloclib/getpagesize.h +++ /dev/null @@ -1,56 +0,0 @@ -/* Emulation of getpagesize() for systems that need it. - Copyright (C) 1991 Free Software Foundation, Inc. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#if !defined (USG) -extern size_t getpagesize __P ((void)); -# if !defined (HAVE_GETPAGESIZE) -# define HAVE_GETPAGESIZE -# endif /* !HAVE_GETPAGESIZE */ -#endif /* !USG */ - -#if !defined (HAVE_GETPAGESIZE) && defined (HAVE_UNISTD_H) -# include <unistd.h> -# if defined (_SC_PAGESIZE) -# define getpagesize() sysconf(_SC_PAGESIZE) -# endif /* _SC_PAGESIZE */ -#endif - -#if !defined (HAVE_GETPAGESIZE) -# include <sys/param.h> -# if defined (PAGESIZE) -# define getpagesize() PAGESIZE -# else /* !PAGESIZE */ -# if defined (EXEC_PAGESIZE) -# define getpagesize() EXEC_PAGESIZE -# else /* !EXEC_PAGESIZE */ -# if defined (NBPG) -# if !defined (CLSIZE) -# define CLSIZE 1 -# endif /* !CLSIZE */ -# define getpagesize() (NBPG * CLSIZE) -# else /* !NBPG */ -# if defined (NBPC) -# define getpagesize() NBPC -# endif /* NBPC */ -# endif /* !NBPG */ -# endif /* !EXEC_PAGESIZE */ -# endif /* !PAGESIZE */ -#endif /* !getpagesize */ - -#if !defined (HAVE_GETPAGESIZE) && !defined (getpagesize) -# define getpagesize() 4096 /* Just punt and use reasonable value */ -#endif /* !HAVE_GETPAGESIZE && !getpagesize */ diff --git a/lib/malloclib/i386-alloca.s b/lib/malloclib/i386-alloca.s deleted file mode 100644 index 01b2cfe..0000000 --- a/lib/malloclib/i386-alloca.s +++ /dev/null @@ -1,16 +0,0 @@ - .file "alloca.s" - .text - .align 4 - .def alloca; .val alloca; .scl 2; .type 044; .endef - .globl alloca -alloca: - popl %edx - popl %eax - addl $3,%eax - andl $0xfffffffc,%eax - subl %eax,%esp - movl %esp,%eax - pushl %eax - pushl %edx - ret - .def alloca; .val .; .scl -1; .endef diff --git a/lib/malloclib/malloc.c b/lib/malloclib/malloc.c deleted file mode 100644 index 1d9bc03..0000000 --- a/lib/malloclib/malloc.c +++ /dev/null @@ -1,324 +0,0 @@ -/* Memory allocator `malloc'. - Copyright 1990, 1991, 1992, 1993 Free Software Foundation - Written May 1989 by Mike Haertel. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. - - The author may be reached (Email) at the address mike@ai.mit.edu, - or (US mail) as Mike Haertel c/o Free Software Foundation. */ - -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include <malloc.h> -#endif - -/* How to really get more memory. */ -__ptr_t (*__morecore) __P ((ptrdiff_t __size)) = __default_morecore; - -/* Debugging hook for `malloc'. */ -__ptr_t (*__malloc_hook) __P ((size_t __size)); - -/* Pointer to the base of the first block. */ -char *_heapbase; - -/* Block information table. Allocated with align/__free (not malloc/free). */ -malloc_info *_heapinfo; - -/* Number of info entries. */ -static size_t heapsize; - -/* Search index in the info table. */ -size_t _heapindex; - -/* Limit of valid info table indices. */ -size_t _heaplimit; - -/* Count of large blocks allocated for each fragment size. */ -int _fragblocks[BLOCKLOG]; - -/* Free lists for each fragment size. */ -struct list _fraghead[BLOCKLOG]; - -/* Instrumentation. */ -size_t _chunks_used; -size_t _bytes_used; -size_t _chunks_free; -size_t _bytes_free; - -/* Are you experienced? */ -int __malloc_initialized; - -void (*__after_morecore_hook) __P ((void)); - -/* Aligned allocation. */ -static __ptr_t align __P ((size_t)); -static __ptr_t -align (size) - size_t size; -{ - __ptr_t result; - unsigned long int adj; - - result = (*__morecore) (size); - adj = (unsigned long int) ((unsigned long int) ((char *) result - - (char *) NULL)) % BLOCKSIZE; - if (adj != 0) - { - adj = BLOCKSIZE - adj; - (void) (*__morecore) (adj); - result = (char *) result + adj; - } - - if (__after_morecore_hook) - (*__after_morecore_hook) (); - - return result; -} - -/* Set everything up and remember that we have. */ -static int initialize __P ((void)); -static int -initialize () -{ - heapsize = HEAP / BLOCKSIZE; - _heapinfo = (malloc_info *) align (heapsize * sizeof (malloc_info)); - - _bytes_used = heapsize * sizeof (malloc_info); - _chunks_used++; - - if (_heapinfo == NULL) - return 0; - memset (_heapinfo, 0, heapsize * sizeof (malloc_info)); - _heapinfo[0].free.size = 0; - _heapinfo[0].free.next = _heapinfo[0].free.prev = 0; - _heapindex = 0; - _heapbase = (char *) _heapinfo; - __malloc_initialized = 1; - return 1; -} - -/* Get neatly aligned memory, initializing or - growing the heap info table as necessary. */ -static __ptr_t morecore __P ((size_t)); -static __ptr_t -morecore (size) - size_t size; -{ - __ptr_t result; - malloc_info *newinfo, *oldinfo; - size_t newsize; - - result = align (size); - if (result == NULL) - return NULL; - - /* Check if we need to grow the info table. */ - if ((size_t) BLOCK ((char *) result + size) > heapsize) - { - newsize = heapsize; - while ((size_t) BLOCK ((char *) result + size) > newsize) - newsize *= 2; - newinfo = (malloc_info *) align (newsize * sizeof (malloc_info)); - if (newinfo == NULL) - { - (*__morecore) (-size); - return NULL; - } - - _bytes_used += newsize * sizeof (malloc_info); - _chunks_used++; - - memset (newinfo, 0, newsize * sizeof (malloc_info)); - memcpy (newinfo, _heapinfo, heapsize * sizeof (malloc_info)); - oldinfo = _heapinfo; - newinfo[BLOCK (oldinfo)].busy.type = 0; - newinfo[BLOCK (oldinfo)].busy.info.size - = BLOCKIFY (heapsize * sizeof (malloc_info)); - _heapinfo = newinfo; - - heapsize = newsize; - } - - _heaplimit = BLOCK ((char *) result + size); - return result; -} - -/* Allocate memory from the heap. */ -__ptr_t -malloc (size) - size_t size; -{ - __ptr_t result; - size_t block, blocks, lastblocks, start; - register size_t i; - struct list *next; - - if (size == 0) - return NULL; - - if (__malloc_hook != NULL) - return (*__malloc_hook) (size); - - if (!__malloc_initialized) - if (!initialize ()) - return NULL; - - if (size < sizeof (struct list)) - size = sizeof (struct list); - - /* Determine the allocation policy based on the request size. */ - if (size <= BLOCKSIZE / 2) - { - /* Small allocation to receive a fragment of a block. - Determine the logarithm to base two of the fragment size. */ - register size_t log = 1; - --size; - while ((size /= 2) != 0) - ++log; - - /* Look in the fragment lists for a - free fragment of the desired size. */ - next = _fraghead[log].next; - if (next != NULL) - { - /* There are free fragments of this size. - Pop a fragment out of the fragment list and return it. - Update the block's nfree and first counters. */ - result = (__ptr_t) next; - next->prev->next = next->next; - if (next->next != NULL) - next->next->prev = next->prev; - block = BLOCK (result); - if (--_heapinfo[block].busy.info.frag.nfree != 0) - _heapinfo[block].busy.info.frag.first = (unsigned long int) - ((unsigned long int) ((char *) next->next - (char *) NULL) - % BLOCKSIZE) >> log; - - /* Update the statistics. */ - ++_chunks_used; - _bytes_used += 1 << log; - --_chunks_free; - _bytes_free -= 1 << log; - } - else - { - /* No free fragments of the desired size, so get a new block - and break it into fragments, returning the first. */ - result = malloc (BLOCKSIZE); - if (result == NULL) - return NULL; - ++_fragblocks[log]; - - /* Link all fragments but the first into the free list. */ - for (i = 1; i < (size_t) (BLOCKSIZE >> log); ++i) - { - next = (struct list *) ((char *) result + (i << log)); - next->next = _fraghead[log].next; - next->prev = &_fraghead[log]; - next->prev->next = next; - if (next->next != NULL) - next->next->prev = next; - } - - /* Initialize the nfree and first counters for this block. */ - block = BLOCK (result); - _heapinfo[block].busy.type = log; - _heapinfo[block].busy.info.frag.nfree = i - 1; - _heapinfo[block].busy.info.frag.first = i - 1; - - _chunks_free += (BLOCKSIZE >> log) - 1; - _bytes_free += BLOCKSIZE - (1 << log); - _bytes_used -= BLOCKSIZE - (1 << log); - } - } - else - { - /* Large allocation to receive one or more blocks. - Search the free list in a circle starting at the last place visited. - If we loop completely around without finding a large enough - space we will have to get more memory from the system. */ - blocks = BLOCKIFY (size); - start = block = _heapindex; - while (_heapinfo[block].free.size < blocks) - { - block = _heapinfo[block].free.next; - if (block == start) - { - /* Need to get more from the system. Check to see if - the new core will be contiguous with the final free - block; if so we don't need to get as much. */ - block = _heapinfo[0].free.prev; - lastblocks = _heapinfo[block].free.size; - if (_heaplimit != 0 && block + lastblocks == _heaplimit && - (*__morecore) (0) == ADDRESS (block + lastblocks) && - (morecore ((blocks - lastblocks) * BLOCKSIZE)) != NULL) - { - /* Note that morecore() can change the location of - the final block if it moves the info table and the - old one gets coalesced into the final block. */ - block = _heapinfo[0].free.prev; - _heapinfo[block].free.size += blocks - lastblocks; - continue; - } - result = morecore (blocks * BLOCKSIZE); - if (result == NULL) - return NULL; - block = BLOCK (result); - _heapinfo[block].busy.type = 0; - _heapinfo[block].busy.info.size = blocks; - ++_chunks_used; - _bytes_used += blocks * BLOCKSIZE; - return result; - } - } - - /* At this point we have found a suitable free list entry. - Figure out how to remove what we need from the list. */ - result = ADDRESS (block); - if (_heapinfo[block].free.size > blocks) - { - /* The block we found has a bit left over, - so relink the tail end back into the free list. */ - _heapinfo[block + blocks].free.size - = _heapinfo[block].free.size - blocks; - _heapinfo[block + blocks].free.next - = _heapinfo[block].free.next; - _heapinfo[block + blocks].free.prev - = _heapinfo[block].free.prev; - _heapinfo[_heapinfo[block].free.prev].free.next - = _heapinfo[_heapinfo[block].free.next].free.prev - = _heapindex = block + blocks; - } - else - { - /* The block exactly matches our requirements, - so just remove it from the list. */ - _heapinfo[_heapinfo[block].free.next].free.prev - = _heapinfo[block].free.prev; - _heapinfo[_heapinfo[block].free.prev].free.next - = _heapindex = _heapinfo[block].free.next; - --_chunks_free; - } - - _heapinfo[block].busy.type = 0; - _heapinfo[block].busy.info.size = blocks; - ++_chunks_used; - _bytes_used += blocks * BLOCKSIZE; - _bytes_free -= blocks * BLOCKSIZE; - } - - return result; -} diff --git a/lib/malloclib/malloc.h b/lib/malloclib/malloc.h deleted file mode 100644 index 705a8c0..0000000 --- a/lib/malloclib/malloc.h +++ /dev/null @@ -1,268 +0,0 @@ -/* Declarations for `malloc' and friends. - Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc. - Written May 1989 by Mike Haertel. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. - - The author may be reached (Email) at the address mike@ai.mit.edu, - or (US mail) as Mike Haertel c/o Free Software Foundation. */ - -#ifndef _MALLOC_H - -#define _MALLOC_H 1 - -#ifdef _MALLOC_INTERNAL -/* Harmless, gets __GNU_LIBRARY__ defined. - We must do this before #defining size_t and ptrdiff_t - because <stdio.h> tries to typedef them on some systems. */ -#include <stdio.h> -#endif - -#ifdef __cplusplus -extern "C" -{ -#endif - -#if defined (__cplusplus) || (defined (__STDC__) && __STDC__) -#undef __P -#define __P(args) args -#undef __ptr_t -#define __ptr_t void * -#else /* Not C++ or ANSI C. */ -#undef __P -#define __P(args) () -#undef const -#define const -#undef __ptr_t -#define __ptr_t char * -#endif /* C++ or ANSI C. */ - -#ifndef NULL -#define NULL 0 -#endif - -#ifdef __STDC__ -#include <stddef.h> -#else -#undef size_t -#define size_t unsigned int -#undef ptrdiff_t -#define ptrdiff_t int -#endif - - -/* Allocate SIZE bytes of memory. */ -extern __ptr_t malloc __P ((size_t __size)); -/* Re-allocate the previously allocated block - in __ptr_t, making the new block SIZE bytes long. */ -extern __ptr_t realloc __P ((__ptr_t __ptr, size_t __size)); -/* Allocate NMEMB elements of SIZE bytes each, all initialized to 0. */ -extern __ptr_t calloc __P ((size_t __nmemb, size_t __size)); -/* Free a block allocated by `malloc', `realloc' or `calloc'. */ -extern void free __P ((__ptr_t __ptr)); - -/* Allocate SIZE bytes allocated to ALIGNMENT bytes. */ -extern __ptr_t memalign __P ((size_t __alignment, size_t __size)); - -/* Allocate SIZE bytes on a page boundary. */ -extern __ptr_t valloc __P ((size_t __size)); - - -#ifdef _MALLOC_INTERNAL - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#if defined(__GNU_LIBRARY__) || defined(STDC_HEADERS) || defined(USG) -#include <string.h> -#else -#ifndef memset -#define memset(s, zero, n) bzero ((s), (n)) -#endif -#ifndef memcpy -#define memcpy(d, s, n) bcopy ((s), (d), (n)) -#endif -#ifndef memmove -#define memmove(d, s, n) bcopy ((s), (d), (n)) -#endif -#endif - - -#if defined(__GNU_LIBRARY__) || defined(__STDC__) -#include <limits.h> -#else -#define CHAR_BIT 8 -#endif - -/* The allocator divides the heap into blocks of fixed size; large - requests receive one or more whole blocks, and small requests - receive a fragment of a block. Fragment sizes are powers of two, - and all fragments of a block are the same size. When all the - fragments in a block have been freed, the block itself is freed. */ -#define INT_BIT (CHAR_BIT * sizeof(int)) -#define BLOCKLOG (INT_BIT > 16 ? 12 : 9) -#define BLOCKSIZE (1 << BLOCKLOG) -#define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE) - -/* Determine the amount of memory spanned by the initial heap table - (not an absolute limit). */ -#define HEAP (INT_BIT > 16 ? 4194304 : 65536) - -/* Number of contiguous free blocks allowed to build up at the end of - memory before they will be returned to the system. */ -#define FINAL_FREE_BLOCKS 8 - -/* Data structure giving per-block information. */ -typedef union - { - /* Heap information for a busy block. */ - struct - { - /* Zero for a large block, or positive giving the - logarithm to the base two of the fragment size. */ - int type; - union - { - struct - { - size_t nfree; /* Free fragments in a fragmented block. */ - size_t first; /* First free fragment of the block. */ - } frag; - /* Size (in blocks) of a large cluster. */ - size_t size; - } info; - } busy; - /* Heap information for a free block - (that may be the first of a free cluster). */ - struct - { - size_t size; /* Size (in blocks) of a free cluster. */ - size_t next; /* Index of next free cluster. */ - size_t prev; /* Index of previous free cluster. */ - } free; - } malloc_info; - -/* Pointer to first block of the heap. */ -extern char *_heapbase; - -/* Table indexed by block number giving per-block information. */ -extern malloc_info *_heapinfo; - -/* Address to block number and vice versa. */ -#define BLOCK(A) (((char *) (A) - _heapbase) / BLOCKSIZE + 1) -#define ADDRESS(B) ((__ptr_t) (((B) - 1) * BLOCKSIZE + _heapbase)) - -/* Current search index for the heap table. */ -extern size_t _heapindex; - -/* Limit of valid info table indices. */ -extern size_t _heaplimit; - -/* Doubly linked lists of free fragments. */ -struct list - { - struct list *next; - struct list *prev; - }; - -/* Count of blocks for each fragment size. */ -extern int _fragblocks[]; - -/* Free list headers for each fragment size. */ -extern struct list _fraghead[]; - -/* List of blocks allocated with `memalign' (or `valloc'). */ -struct alignlist - { - struct alignlist *next; - __ptr_t aligned; /* The address that memaligned returned. */ - __ptr_t exact; /* The address that malloc returned. */ - }; -extern struct alignlist *_aligned_blocks; - -/* Instrumentation. */ -extern size_t _chunks_used; -extern size_t _bytes_used; -extern size_t _chunks_free; -extern size_t _bytes_free; - -/* Internal version of `free' used in `morecore' (malloc.c). */ -extern void _free_internal __P ((__ptr_t __ptr)); - -#endif /* _MALLOC_INTERNAL. */ - -/* Underlying allocation function; successive calls should - return contiguous pieces of memory. */ -extern __ptr_t (*__morecore) __P ((ptrdiff_t __size)); - -/* Default value of `__morecore'. */ -extern __ptr_t __default_morecore __P ((ptrdiff_t __size)); - -/* If not NULL, this function is called after each time - `__morecore' is called to increase the data size. */ -extern void (*__after_morecore_hook) __P ((void)); - -/* Nonzero if `malloc' has been called and done its initialization. */ -extern int __malloc_initialized; - -/* Hooks for debugging versions. */ -extern void (*__free_hook) __P ((__ptr_t __ptr)); -extern __ptr_t (*__malloc_hook) __P ((size_t __size)); -extern __ptr_t (*__realloc_hook) __P ((__ptr_t __ptr, size_t __size)); - -/* Activate a standard collection of debugging hooks. */ -extern int mcheck __P ((void (*__bfunc) __P ((char *)), - void (*__afunc) __P ((void)))); - -/* Activate a standard collection of tracing hooks. */ -extern void mtrace __P ((void)); - -/* Statistics available to the user. */ -struct mstats - { - size_t bytes_total; /* Total size of the heap. */ - size_t chunks_used; /* Chunks allocated by the user. */ - size_t bytes_used; /* Byte total of user-allocated chunks. */ - size_t chunks_free; /* Chunks in the free list. */ - size_t bytes_free; /* Byte total of chunks in the free list. */ - }; - -/* Pick up the current statistics. */ -extern struct mstats mstats __P ((void)); - -/* Call WARNFUN with a warning message when memory usage is high. */ -extern void memory_warnings __P ((__ptr_t __start, - void (*__warnfun) __P ((__const char *)))); - - -/* Relocating allocator. */ - -/* Allocate SIZE bytes, and store the address in *HANDLEPTR. */ -extern __ptr_t r_alloc __P ((__ptr_t *__handleptr, size_t __size)); - -/* Free the storage allocated in HANDLEPTR. */ -extern void r_alloc_free __P ((__ptr_t *__handleptr)); - -/* Adjust the block at HANDLEPTR to be SIZE bytes long. */ -extern __ptr_t r_re_alloc __P ((__ptr_t *__handleptr, size_t __size)); - - -#ifdef __cplusplus -} -#endif - -#endif /* malloc.h */ diff --git a/lib/malloclib/mcheck.c b/lib/malloclib/mcheck.c deleted file mode 100644 index f7d9d4f..0000000 --- a/lib/malloclib/mcheck.c +++ /dev/null @@ -1,133 +0,0 @@ -/* Standard debugging hooks for `malloc'. - Copyright 1990, 1991, 1992, 1993 Free Software Foundation - Written May 1989 by Mike Haertel. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. - - The author may be reached (Email) at the address mike@ai.mit.edu, - or (US mail) as Mike Haertel c/o Free Software Foundation. */ - -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include <malloc.h> -#endif - -/* Old hook values. */ -static void (*old_free_hook) __P ((__ptr_t ptr)); -static __ptr_t (*old_malloc_hook) __P ((size_t size)); -static __ptr_t (*old_realloc_hook) __P ((__ptr_t ptr, size_t size)); - -/* Function to call when something awful happens. */ -static void (*abortfunc) __P ((void)); - -/* Arbitrary magical numbers. */ -#define MAGICWORD 0xfedabeeb -#define MAGICBYTE ((char) 0xd7) - -struct hdr - { - size_t size; /* Exact size requested by user. */ - unsigned long int magic; /* Magic number to check header integrity. */ - }; - -static void checkhdr __P ((const struct hdr *)); -static void -checkhdr (hdr) - const struct hdr *hdr; -{ - if (hdr->magic != MAGICWORD || ((char *) &hdr[1])[hdr->size] != MAGICBYTE) - (*abortfunc) (); -} - -static void freehook __P ((__ptr_t)); -static void -freehook (ptr) - __ptr_t ptr; -{ - struct hdr *hdr = ((struct hdr *) ptr) - 1; - checkhdr (hdr); - hdr->magic = 0; - __free_hook = old_free_hook; - free (hdr); - __free_hook = freehook; -} - -static __ptr_t mallochook __P ((size_t)); -static __ptr_t -mallochook (size) - size_t size; -{ - struct hdr *hdr; - - __malloc_hook = old_malloc_hook; - hdr = (struct hdr *) malloc (sizeof (struct hdr) + size + 1); - __malloc_hook = mallochook; - if (hdr == NULL) - return NULL; - - hdr->size = size; - hdr->magic = MAGICWORD; - ((char *) &hdr[1])[size] = MAGICBYTE; - return (__ptr_t) (hdr + 1); -} - -static __ptr_t reallochook __P ((__ptr_t, size_t)); -static __ptr_t -reallochook (ptr, size) - __ptr_t ptr; - size_t size; -{ - struct hdr *hdr = ((struct hdr *) ptr) - 1; - - checkhdr (hdr); - __free_hook = old_free_hook; - __malloc_hook = old_malloc_hook; - __realloc_hook = old_realloc_hook; - hdr = (struct hdr *) realloc ((__ptr_t) hdr, sizeof (struct hdr) + size + 1); - __free_hook = freehook; - __malloc_hook = mallochook; - __realloc_hook = reallochook; - if (hdr == NULL) - return NULL; - - hdr->size = size; - ((char *) &hdr[1])[size] = MAGICBYTE; - return (__ptr_t) (hdr + 1); -} - -int -mcheck (func) - void (*func) __P ((void)); -{ - extern void abort __P ((void)); - static int mcheck_used = 0; - - abortfunc = (func != NULL) ? func : abort; - - /* These hooks may not be safely inserted if malloc is already in use. */ - if (!__malloc_initialized && !mcheck_used) - { - old_free_hook = __free_hook; - __free_hook = freehook; - old_malloc_hook = __malloc_hook; - __malloc_hook = mallochook; - old_realloc_hook = __realloc_hook; - __realloc_hook = reallochook; - mcheck_used = 1; - } - - return mcheck_used ? 0 : -1; -} diff --git a/lib/malloclib/memalign.c b/lib/malloclib/memalign.c deleted file mode 100644 index f5ad17c..0000000 --- a/lib/malloclib/memalign.c +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. */ - -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include <malloc.h> -#endif - -__ptr_t -memalign (alignment, size) - size_t alignment; - size_t size; -{ - __ptr_t result; - unsigned long int adj; - - size = ((size + alignment - 1) / alignment) * alignment; - - result = malloc (size); - if (result == NULL) - return NULL; - adj = (unsigned long int) ((unsigned long int) ((char *) result - - (char *) NULL)) % alignment; - if (adj != 0) - { - struct alignlist *l; - for (l = _aligned_blocks; l != NULL; l = l->next) - if (l->aligned == NULL) - /* This slot is free. Use it. */ - break; - if (l == NULL) - { - l = (struct alignlist *) malloc (sizeof (struct alignlist)); - if (l == NULL) - { - free (result); - return NULL; - } - } - l->exact = result; - result = l->aligned = (char *) result + alignment - adj; - l->next = _aligned_blocks; - _aligned_blocks = l; - } - - return result; -} diff --git a/lib/malloclib/morecore.c b/lib/malloclib/morecore.c deleted file mode 100644 index c9a9ca5..0000000 --- a/lib/malloclib/morecore.c +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. -This file is part of the GNU C Library. - -The GNU C Library is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -The GNU C Library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with the GNU C Library; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include <malloc.h> -#endif - -#ifndef __GNU_LIBRARY__ -#define __sbrk sbrk -#endif - -extern __ptr_t __sbrk __P ((int increment)); - -#ifndef NULL -#define NULL 0 -#endif - -/* Allocate INCREMENT more bytes of data space, - and return the start of data space, or NULL on errors. - If INCREMENT is negative, shrink data space. */ -__ptr_t -__default_morecore (increment) - ptrdiff_t increment; -{ - __ptr_t result = __sbrk ((int) increment); - if (result == (__ptr_t) -1) - return NULL; - return result; -} diff --git a/lib/malloclib/mstats.c b/lib/malloclib/mstats.c deleted file mode 100644 index 511cdad..0000000 --- a/lib/malloclib/mstats.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Access the statistics maintained by `malloc'. - Copyright 1990, 1991, 1992 Free Software Foundation - Written May 1989 by Mike Haertel. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. - - The author may be reached (Email) at the address mike@ai.mit.edu, - or (US mail) as Mike Haertel c/o Free Software Foundation. */ - -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include <malloc.h> -#endif - -struct mstats -mstats () -{ - struct mstats result; - - result.bytes_total = (char *) (*__morecore) (0) - _heapbase; - result.chunks_used = _chunks_used; - result.bytes_used = _bytes_used; - result.chunks_free = _chunks_free; - result.bytes_free = _bytes_free; - return result; -} diff --git a/lib/malloclib/mtrace.awk b/lib/malloclib/mtrace.awk deleted file mode 100644 index d7689ce..0000000 --- a/lib/malloclib/mtrace.awk +++ /dev/null @@ -1,36 +0,0 @@ -# -# Awk program to analyze mtrace.c output. -# -$1 == "+" { if (allocated[$2] != "") - print "+", $2, "Alloc", NR, "duplicate:", allocated[$2]; - else - allocated[$2] = $3; - } -$1 == "-" { if (allocated[$2] != "") { - allocated[$2] = ""; - if (allocated[$2] != "") - print "DELETE FAILED", $2, allocated[$2]; - } else - print "-", $2, "Free", NR, "was never alloc'd"; - } -$1 == "<" { if (allocated[$2] != "") - allocated[$2] = ""; - else - print "-", $2, "Realloc", NR, "was never alloc'd"; - } -$1 == ">" { if (allocated[$2] != "") - print "+", $2, "Realloc", NR, "duplicate:", allocated[$2]; - else - allocated[$2] = $3; - } - -# Ignore "= Start" -$1 == "=" { } -# Ignore failed realloc attempts for now -$1 == "!" { } - - -END { for (x in allocated) - if (allocated[x] != "") - print "+", x, allocated[x]; - } diff --git a/lib/malloclib/mtrace.c b/lib/malloclib/mtrace.c deleted file mode 100644 index ea1d3a4..0000000 --- a/lib/malloclib/mtrace.c +++ /dev/null @@ -1,150 +0,0 @@ -/* More debugging hooks for `malloc'. - Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. - Written April 2, 1991 by John Gilmore of Cygnus Support. - Based on mcheck.c by Mike Haertel. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. - - The author may be reached (Email) at the address mike@ai.mit.edu, - or (US mail) as Mike Haertel c/o Free Software Foundation. */ - -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include <malloc.h> -#endif - -/* Don't #include <stdio.h> because <malloc.h> did it for us. */ - -#ifndef __GNU_LIBRARY__ -extern char *getenv (); -#else -#include <stdlib.h> -#endif - -static FILE *mallstream; -static char mallenv[]= "MALLOC_TRACE"; -static char mallbuf[BUFSIZ]; /* Buffer for the output. */ - -/* Address to breakpoint on accesses to... */ -__ptr_t mallwatch; - -/* Old hook values. */ -static void (*tr_old_free_hook) __P ((__ptr_t ptr)); -static __ptr_t (*tr_old_malloc_hook) __P ((size_t size)); -static __ptr_t (*tr_old_realloc_hook) __P ((__ptr_t ptr, size_t size)); - -/* This function is called when the block being alloc'd, realloc'd, or - freed has an address matching the variable "mallwatch". In a debugger, - set "mallwatch" to the address of interest, then put a breakpoint on - tr_break. */ - -void tr_break __P ((void)); -void -tr_break () -{ -} - -static void tr_freehook __P ((__ptr_t)); -static void -tr_freehook (ptr) - __ptr_t ptr; -{ - fprintf (mallstream, "- %p\n", ptr); /* Be sure to print it first. */ - if (ptr == mallwatch) - tr_break (); - __free_hook = tr_old_free_hook; - free (ptr); - __free_hook = tr_freehook; -} - -static __ptr_t tr_mallochook __P ((size_t)); -static __ptr_t -tr_mallochook (size) - size_t size; -{ - __ptr_t hdr; - - __malloc_hook = tr_old_malloc_hook; - hdr = (__ptr_t) malloc (size); - __malloc_hook = tr_mallochook; - - /* We could be printing a NULL here; that's OK. */ - fprintf (mallstream, "+ %p %x\n", hdr, size); - - if (hdr == mallwatch) - tr_break (); - - return hdr; -} - -static __ptr_t tr_reallochook __P ((__ptr_t, size_t)); -static __ptr_t -tr_reallochook (ptr, size) - __ptr_t ptr; - size_t size; -{ - __ptr_t hdr; - - if (ptr == mallwatch) - tr_break (); - - __free_hook = tr_old_free_hook; - __malloc_hook = tr_old_malloc_hook; - __realloc_hook = tr_old_realloc_hook; - hdr = (__ptr_t) realloc (ptr, size); - __free_hook = tr_freehook; - __malloc_hook = tr_mallochook; - __realloc_hook = tr_reallochook; - if (hdr == NULL) - /* Failed realloc. */ - fprintf (mallstream, "! %p %x\n", ptr, size); - else - fprintf (mallstream, "< %p\n> %p %x\n", ptr, hdr, size); - - if (hdr == mallwatch) - tr_break (); - - return hdr; -} - -/* We enable tracing if either the environment variable MALLOC_TRACE - is set, or if the variable mallwatch has been patched to an address - that the debugging user wants us to stop on. When patching mallwatch, - don't forget to set a breakpoint on tr_break! */ - -void -mtrace () -{ - char *mallfile; - - mallfile = getenv (mallenv); - if (mallfile != NULL || mallwatch != NULL) - { - mallstream = fopen (mallfile != NULL ? mallfile : "/dev/null", "w"); - if (mallstream != NULL) - { - /* Be sure it doesn't malloc its buffer! */ - setbuf (mallstream, mallbuf); - fprintf (mallstream, "= Start\n"); - tr_old_free_hook = __free_hook; - __free_hook = tr_freehook; - tr_old_malloc_hook = __malloc_hook; - __malloc_hook = tr_mallochook; - tr_old_realloc_hook = __realloc_hook; - __realloc_hook = tr_reallochook; - } - } -} diff --git a/lib/malloclib/realloc.c b/lib/malloclib/realloc.c deleted file mode 100644 index 2d31766..0000000 --- a/lib/malloclib/realloc.c +++ /dev/null @@ -1,146 +0,0 @@ -/* Change the size of a block allocated by `malloc'. - Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc. - Written May 1989 by Mike Haertel. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. - - The author may be reached (Email) at the address mike@ai.mit.edu, - or (US mail) as Mike Haertel c/o Free Software Foundation. */ - -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include <malloc.h> -#endif - -#define min(A, B) ((A) < (B) ? (A) : (B)) - -/* Debugging hook for realloc. */ -__ptr_t (*__realloc_hook) __P ((__ptr_t __ptr, size_t __size)); - -/* Resize the given region to the new size, returning a pointer - to the (possibly moved) region. This is optimized for speed; - some benchmarks seem to indicate that greater compactness is - achieved by unconditionally allocating and copying to a - new region. This module has incestuous knowledge of the - internals of both free and malloc. */ -__ptr_t -realloc (ptr, size) - __ptr_t ptr; - size_t size; -{ - __ptr_t result; - int type; - size_t block, blocks, oldlimit; - - if (size == 0) - { - free (ptr); - return malloc (0); - } - else if (ptr == NULL) - return malloc (size); - - if (__realloc_hook != NULL) - return (*__realloc_hook) (ptr, size); - - block = BLOCK (ptr); - - type = _heapinfo[block].busy.type; - switch (type) - { - case 0: - /* Maybe reallocate a large block to a small fragment. */ - if (size <= BLOCKSIZE / 2) - { - result = malloc (size); - if (result != NULL) - { - memcpy (result, ptr, size); - free (ptr); - return result; - } - } - - /* The new size is a large allocation as well; - see if we can hold it in place. */ - blocks = BLOCKIFY (size); - if (blocks < _heapinfo[block].busy.info.size) - { - /* The new size is smaller; return - excess memory to the free list. */ - _heapinfo[block + blocks].busy.type = 0; - _heapinfo[block + blocks].busy.info.size - = _heapinfo[block].busy.info.size - blocks; - _heapinfo[block].busy.info.size = blocks; - free (ADDRESS (block + blocks)); - result = ptr; - } - else if (blocks == _heapinfo[block].busy.info.size) - /* No size change necessary. */ - result = ptr; - else - { - /* Won't fit, so allocate a new region that will. - Free the old region first in case there is sufficient - adjacent free space to grow without moving. */ - blocks = _heapinfo[block].busy.info.size; - /* Prevent free from actually returning memory to the system. */ - oldlimit = _heaplimit; - _heaplimit = 0; - free (ptr); - _heaplimit = oldlimit; - result = malloc (size); - if (result == NULL) - { - /* Now we're really in trouble. We have to unfree - the thing we just freed. Unfortunately it might - have been coalesced with its neighbors. */ - if (_heapindex == block) - (void) malloc (blocks * BLOCKSIZE); - else - { - __ptr_t previous = malloc ((block - _heapindex) * BLOCKSIZE); - (void) malloc (blocks * BLOCKSIZE); - free (previous); - } - return NULL; - } - if (ptr != result) - memmove (result, ptr, blocks * BLOCKSIZE); - } - break; - - default: - /* Old size is a fragment; type is logarithm - to base two of the fragment size. */ - if (size > (size_t) (1 << (type - 1)) && size <= (size_t) (1 << type)) - /* The new size is the same kind of fragment. */ - result = ptr; - else - { - /* The new size is different; allocate a new space, - and copy the lesser of the new size and the old. */ - result = malloc (size); - if (result == NULL) - return NULL; - memcpy (result, ptr, min (size, (size_t) 1 << type)); - free (ptr); - } - break; - } - - return result; -} diff --git a/lib/malloclib/valloc.c b/lib/malloclib/valloc.c deleted file mode 100644 index eb5d372..0000000 --- a/lib/malloclib/valloc.c +++ /dev/null @@ -1,48 +0,0 @@ -/* Allocate memory on a page boundary. - Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. - - The author may be reached (Email) at the address mike@ai.mit.edu, - or (US mail) as Mike Haertel c/o Free Software Foundation. */ - -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include <malloc.h> -#endif - -#if defined (emacs) || defined (HAVE_CONFIG_H) -#include "config.h" -#endif - -#ifdef __GNU_LIBRARY__ -extern size_t __getpagesize __P ((void)); -#else -#include "getpagesize.h" -#define __getpagesize() getpagesize() -#endif - -static size_t pagesize; - -__ptr_t -valloc (size) - size_t size; -{ - if (pagesize == 0) - pagesize = __getpagesize (); - - return memalign (pagesize, size); -} diff --git a/lib/malloclib/x386-alloca.s b/lib/malloclib/x386-alloca.s deleted file mode 100644 index 112d33c..0000000 --- a/lib/malloclib/x386-alloca.s +++ /dev/null @@ -1,63 +0,0 @@ -;; alloca386.s 1.2 -;; GNU-compatible stack allocation function for Xenix/386. -;; Written by Chip Salzenberg at ComDev. -;; Last modified 90/01/11 -;;> Is your alloca clearly better than the one in i386-alloca.s? I haven't -;;> looked at either. -;; -;;They're different because Xenix/386 has a different assembler. SCO -;;Xenix has the Microsoft C compiler and the Microsoft macro assembler, -;;called "masm". MASM's assembler syntax is quite different from AT&T's -;;in all sorts of ways. Xenix people can't use the AT&T version. -;;-- -;;Chip Salzenberg at ComDev/TCT <chip@tct.uucp>, <uunet!ateng!tct!chip> - - TITLE $alloca386 - - .386 -DGROUP GROUP CONST, _BSS, _DATA -_DATA SEGMENT DWORD USE32 PUBLIC 'DATA' -_DATA ENDS -_BSS SEGMENT DWORD USE32 PUBLIC 'BSS' -_BSS ENDS -CONST SEGMENT DWORD USE32 PUBLIC 'CONST' -CONST ENDS -_TEXT SEGMENT DWORD USE32 PUBLIC 'CODE' - ASSUME CS: _TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP - - PUBLIC _alloca -_alloca PROC NEAR - -; Get argument. - pop edx ; edx -> return address - pop eax ; eax = amount to allocate - -; Validate allocation amount. - add eax,3 - and eax,not 3 - cmp eax,0 - jg aa_size_ok - mov eax,4 -aa_size_ok: - -; Allocate stack space. - mov ecx,esp ; ecx -> old stack pointer - sub esp,eax ; perform allocation - mov eax,esp ; eax -> new stack pointer - -; Copy the three saved register variables from old stack top to new stack top. -; They may not be there. So we waste twelve bytes. Big fat hairy deal. - push DWORD PTR 8[ecx] - push DWORD PTR 4[ecx] - push DWORD PTR 0[ecx] - -; Push something so the caller can pop it off. - push eax - -; Return to caller. - jmp edx - -_alloca ENDP - -_TEXT ENDS - END diff --git a/lib/malloclib/xmalloc.c b/lib/malloclib/xmalloc.c deleted file mode 100644 index a25cb11..0000000 --- a/lib/malloclib/xmalloc.c +++ /dev/null @@ -1,69 +0,0 @@ -/* xmalloc.c -- safe versions of malloc and realloc */ - -/* Copyright (C) 1991 Free Software Foundation, Inc. - - This file is part of GNU Readline, a library for reading lines - of text with interactive input and history editing. - - Readline is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 1, or (at your option) any - later version. - - Readline is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Readline; see the file COPYING. If not, write to the Free - Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include <stdio.h> - -static void memory_error_and_abort (); - -/* **************************************************************** */ -/* */ -/* Memory Allocation and Deallocation. */ -/* */ -/* **************************************************************** */ - -/* Return a pointer to free()able block of memory large enough - to hold BYTES number of bytes. If the memory cannot be allocated, - print an error message and abort. */ -char * -xmalloc (bytes) - int bytes; -{ - char *temp = (char *)malloc (bytes); - - if (!temp) - memory_error_and_abort ("xmalloc"); - return (temp); -} - -char * -xrealloc (pointer, bytes) - char *pointer; - int bytes; -{ - char *temp; - - if (!pointer) - temp = (char *)malloc (bytes); - else - temp = (char *)realloc (pointer, bytes); - - if (!temp) - memory_error_and_abort ("xrealloc"); - return (temp); -} - -static void -memory_error_and_abort (fname) - char *fname; -{ - fprintf (stderr, "%s: Out of virtual memory!\n", fname); - abort (); -} diff --git a/lib/posixheaders/filecntl.h b/lib/posixheaders/filecntl.h index c0b2081..cf5054d 100644 --- a/lib/posixheaders/filecntl.h +++ b/lib/posixheaders/filecntl.h @@ -33,4 +33,13 @@ #define SET_CLOSE_ON_EXEC(fd) (fcntl ((fd), F_SETFD, FD_CLOEXEC)) #define SET_OPEN_ON_EXEC(fd) (fcntl ((fd), F_SETFD, FD_NCLOEXEC)) +/* How to open a file in non-blocking mode, the Posix.1 way. */ +#if !defined (O_NONBLOCK) +# if defined (O_NDELAY) +# define O_NONBLOCK O_NDELAY +# else +# define O_NONBLOCK 0 +# endif +#endif + #endif /* ! _FILECNTL_H_ */ diff --git a/lib/posixheaders/memalloc.h b/lib/posixheaders/memalloc.h index 750d53d..ba210bb 100644 --- a/lib/posixheaders/memalloc.h +++ b/lib/posixheaders/memalloc.h @@ -19,8 +19,8 @@ with Bash; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ -#if !defined (__MEMALLOC_H__) -# define __MEMALLOC_H__ +#if !defined (_MEMALLOC_H_) +# define _MEMALLOC_H_ #if defined (sparc) && defined (sun) && !defined (HAVE_ALLOCA_H) # define HAVE_ALLOCA_H @@ -34,8 +34,6 @@ # define HAVE_ALLOCA #endif /* HAVE_ALLOCA_H && !HAVE_ALLOCA */ -#if !defined (BUILDING_MAKEFILE) - #if defined (__GNUC__) # undef alloca # define alloca __builtin_alloca @@ -46,11 +44,15 @@ # else /* !IBMESA */ # include <alloca.h> # endif /* !IBMESA */ -# else +# else /* !HAVE_ALLOCA_H */ +# if defined (hpux_9) && defined (__STDC__) && !defined (alloca) +extern void *alloca (); +# else +# if !defined (alloca) extern char *alloca (); +# endif /* !alloca */ +# endif /* !hpux_9 || !__STDC__ && !alloca */ # endif /* !HAVE_ALLOCA_H */ #endif /* !__GNUC__ */ -#endif /* !BUILDING_MAKEFILE */ - -#endif /* __MEMALLOC_H__ */ +#endif /* _MEMALLOC_H_ */ diff --git a/lib/posixheaders/posixdir.h b/lib/posixheaders/posixdir.h new file mode 100644 index 0000000..8b0e5bc --- /dev/null +++ b/lib/posixheaders/posixdir.h @@ -0,0 +1,49 @@ +/* posixdir.h -- Posix directory reading includes and defines. */ + +/* Copyright (C) 1987,1991 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + Bash is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with Bash; see the file COPYING. If not, write to the Free + Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* This file should be included instead of <dirent.h> or <sys/dir.h>. */ + +#if !defined (_POSIXDIR_H_) +#define _POSIXDIR_H_ + +#if defined (HAVE_DIRENT_H) +# include <dirent.h> +# define D_NAMLEN(d) (strlen ((d)->d_name)) +#else +# if defined (HAVE_SYS_NDIR_H) +# include <sys/ndir.h> +# endif +# if defined (HAVE_SYS_DIR_H) +# include <sys/dir.h> +# endif +# if defined (HAVE_NDIR_H) +# include <ndir.h> +# endif +# if !defined (dirent) +# define dirent direct +# endif /* !dirent */ +# define D_NAMLEN(d) ((d)->d_namlen) +#endif /* !HAVE_DIRENT_H */ + +#if defined (STRUCT_DIRENT_HAS_D_INO) +# define d_fileno d_ino +#endif + +#endif /* !_POSIXDIR_H_ */ diff --git a/lib/posixheaders/posixstat.h b/lib/posixheaders/posixstat.h index 7d1cece..bfce8c0 100644 --- a/lib/posixheaders/posixstat.h +++ b/lib/posixheaders/posixstat.h @@ -21,34 +21,27 @@ /* This file should be included instead of <sys/stat.h>. It relies on the local sys/stat.h to work though. */ -#if !defined (_POSIXSTAT_H) -#define _POSIXSTAT_H +#if !defined (_POSIXSTAT_H_) +#define _POSIXSTAT_H_ #include <sys/stat.h> -#if defined (isc386) -# if !defined (S_IFDIR) -# define S_IFDIR 0040000 -# endif /* !S_IFDIR */ -# if !defined (S_IFMT) -# define S_IFMT 0170000 -# endif /* !S_IFMT */ -#endif /* isc386 */ - -/* This text is taken directly from the Cadmus I was trying to - compile on: - the following MACROs are defined for X/OPEN compatibility - however, is the param correct ?? - #define S_ISBLK(s) ((s.st_mode & S_IFMT) == S_IFBLK) - - Well, the answer is no. Thus... */ -#if defined (BrainDeath) +#if defined (STAT_MACROS_BROKEN) # undef S_ISBLK # undef S_ISCHR # undef S_ISDIR # undef S_ISFIFO # undef S_ISREG -#endif /* BrainDeath */ +# undef S_ISLNK +#endif /* STAT_MACROS_BROKEN */ + +/* These are guaranteed to work only on isc386 */ +#if !defined (S_IFDIR) && !defined (S_ISDIR) +# define S_IFDIR 0040000 +#endif /* !S_IFDIR && !S_ISDIR */ +#if !defined (S_IFMT) +# define S_IFMT 0170000 +#endif /* !S_IFMT */ /* Posix 1003.1 5.6.1.1 <sys/stat.h> file types */ @@ -114,7 +107,7 @@ /* * POSIX 1003.1 5.6.1.2 <sys/stat.h> File Modes */ - + #if !defined (S_IRWXU) # if !defined (S_IREAD) # define S_IREAD 00400 @@ -146,4 +139,4 @@ #define S_IWUGO (S_IWUSR | S_IWGRP | S_IWOTH) #define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH) -#endif /* _POSIXSTAT_H */ +#endif /* _POSIXSTAT_H_ */ diff --git a/lib/posixheaders/stdc.h b/lib/posixheaders/stdc.h index 5dcc32b..f1590c6 100644 --- a/lib/posixheaders/stdc.h +++ b/lib/posixheaders/stdc.h @@ -19,14 +19,15 @@ along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ -#if !defined (__STDC_H__) -#define __STDC_H__ +#if !defined (_STDC_H_) +#define _STDC_H_ /* Adapted from BSD /usr/include/sys/cdefs.h. */ /* A function can be defined using prototypes and compile on both ANSI C and traditional C compilers with something like this: extern char *func __P((char *, char *, int)); */ + #if defined (__STDC__) # if !defined (__P) @@ -75,4 +76,4 @@ #endif /* !__STDC__ */ -#endif /* !__STDC_H__ */ +#endif /* !_STDC_H_ */ diff --git a/lib/readline/COPYING b/lib/readline/COPYING index 1bb82d1..a43ea21 100644 --- a/lib/readline/COPYING +++ b/lib/readline/COPYING @@ -1,46 +1,40 @@ - GNU GENERAL PUBLIC LICENSE - Version 1, February 1989 + Version 2, June 1991 - Copyright (C) 1989 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. -The Free Software Foundation has exempted Bash from the requirement of -Paragraph 2c of the General Public License. This is to say, there is -no requirement for Bash to print a notice when it is started -interactively in the usual way. We made this exception because users -and standards expect shells not to print such messages. This -exception applies to any program that serves as a shell and that is -based primarily on Bash as opposed to other GNU software. - Preamble - The license agreements of most software companies try to keep users -at the mercy of those companies. By contrast, our General Public + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. The -General Public License applies to the Free Software Foundation's -software and to any other program whose authors commit to using it. -You can use it for your programs, too. +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. When we speak of free software, we are referring to freedom, not -price. Specifically, the General Public License is designed to make -sure that you have the freedom to give away or sell copies of free -software, that you receive source code or can get it if you want it, -that you can change the software or use pieces of it in new free -programs; and that you know you can do these things. +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. - For example, if you distribute copies of a such a program, whether + For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the -source code. And you must tell them their rights. +source code. And you must show them these terms so they know their +rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, @@ -53,122 +47,209 @@ want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - 0. This License Agreement applies to any program or other work which -contains a notice placed by the copyright holder saying it may be -distributed under the terms of this General Public License. The -"Program", below, refers to any such program or work, and a "work based -on the Program" means either the Program or any work containing the -Program or a portion of it, either verbatim or with modifications. Each -licensee is addressed as "you". - - 1. You may copy and distribute verbatim copies of the Program's source -code as you receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice and -disclaimer of warranty; keep intact all the notices that refer to this -General Public License and to the absence of any warranty; and give any -other recipients of the Program a copy of this General Public License -along with the Program. You may charge a fee for the physical act of -transferring a copy. - - 2. You may modify your copy or copies of the Program or any portion of -it, and copy and distribute such modifications under the terms of Paragraph -1 above, provided that you also do the following: - - a) cause the modified files to carry prominent notices stating that - you changed the files and the date of any change; and - - b) cause the whole of any work that you distribute or publish, that - in whole or in part contains the Program or any part thereof, either - with or without modifications, to be licensed at no charge to all - third parties under the terms of this General Public License (except - that you may choose to grant warranty protection to some or all - third parties, at your option). - - c) If the modified program normally reads commands interactively when - run, you must cause it, when started running for such interactive use - in the simplest and most usual way, to print or display an - announcement including an appropriate copyright notice and a notice - that there is no warranty (or else, saying that you provide a - warranty) and that users may redistribute the program under these - conditions, and telling the user how to view a copy of this General - Public License. - - d) You may charge a fee for the physical act of transferring a - copy, and you may at your option offer warranty protection in - exchange for a fee. - -Mere aggregation of another independent work with the Program (or its -derivative) on a volume of a storage or distribution medium does not bring -the other work under the scope of these terms. + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) - 3. You may copy and distribute the Program (or a portion or derivative of -it, under Paragraph 2) in object code or executable form under the terms of -Paragraphs 1 and 2 above provided that you also do one of the following: - - a) accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of - Paragraphs 1 and 2 above; or, - - b) accompany it with a written offer, valid for at least three - years, to give any third party free (except for a nominal charge - for the cost of distribution) a complete machine-readable copy of the - corresponding source code, to be distributed under the terms of - Paragraphs 1 and 2 above; or, - - c) accompany it with the information you received as to where the - corresponding source code may be obtained. (This alternative is +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you - received the program in object code or executable form alone.) - -Source code for a work means the preferred form of the work for making -modifications to it. For an executable file, complete source code means -all the source code for all modules it contains; but, as a special -exception, it need not include source code for modules which are standard -libraries that accompany the operating system on which the executable -file runs, or for standard header files or definitions files that -accompany that operating system. - - 4. You may not copy, modify, sublicense, distribute or transfer the -Program except as expressly provided under this General Public License. -Any attempt otherwise to copy, modify, sublicense, distribute or transfer -the Program is void, and will automatically terminate your rights to use -the Program under this License. However, parties who have received -copies, or rights to use copies, from you under this General Public -License will not have their licenses terminated so long as such parties -remain in full compliance. - - 5. By copying, distributing or modifying the Program (or any work based -on the Program) you indicate your acceptance of this license to do so, -and all its terms and conditions. + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the original -licensor to copy, distribute or modify the Program subject to these -terms and conditions. You may not impose any further restrictions on the -recipients' exercise of the rights granted herein. +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. - 7. The Free Software Foundation may publish revised and/or new versions + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. -Each version is given a distinguishing version number. If the Program -specifies a version number of the license which applies to it and "any +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of -the license, you may choose any version ever published by the Free Software +this License, you may choose any version ever published by the Free Software Foundation. - 8. If you wish to incorporate parts of the Program into other free + 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free +to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and @@ -176,7 +257,7 @@ of promoting the sharing and reuse of software generally. NO WARRANTY - 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED @@ -186,7 +267,7 @@ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING @@ -201,22 +282,21 @@ POSSIBILITY OF SUCH DAMAGES. Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest -possible use to humanity, the best way to achieve this is to make it -free software which everyone can redistribute and change under these -terms. +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. - To do so, attach the following notices to the program. It is safest to -attach them to the start of each source file to most effectively convey -the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. <one line to give the program's name and a brief idea of what it does.> - Copyright (C) 19yy <name of author> + Copyright (C) 19yy <name of author> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 1, or (at your option) - any later version. + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -232,26 +312,28 @@ Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: - Gnomovision version 69, Copyright (C) 19xx name of author + Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. -The hypothetical commands `show w' and `show c' should show the -appropriate parts of the General Public License. Of course, the -commands you use may be called something other than `show w' and `show -c'; they could even be mouse-clicks or menu items--whatever suits your -program. +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here a sample; alter the names: +necessary. Here is a sample; alter the names: - Yoyodyne, Inc., hereby disclaims all copyright interest in the - program `Gnomovision' (a program to direct compilers to make passes - at assemblers) written by James Hacker. + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. <signature of Ty Coon>, 1 April 1989 Ty Coon, President of Vice -That's all there is to it! +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/lib/readline/Makefile b/lib/readline/Makefile deleted file mode 100644 index b36cab7..0000000 --- a/lib/readline/Makefile +++ /dev/null @@ -1,134 +0,0 @@ -## -*- text -*- #################################################### -# # -# Makefile for the GNU Readline and History Libraries. # -# # -#################################################################### - -srcdir = . -VPATH = .:$(srcdir) - -INSTALL = install -c -INSTALL_PROGRAM = ${INSTALL} -INSTALL_DATA = ${INSTALL} -m 644 - -RANLIB = ranlib -AR = ar -RM = rm -CP = cp -MV = mv - -# See the file STANDALONE for the -D defines that readline understands -DEFS = -# For libraries which include headers from other libraries. -LOCAL_INCLUDES = -I. -I.. - -CPPFLAGS = $(DEFS) $(LOCAL_INCLUDES) - -# Here is a rule for making .o files from .c files that doesn't force -# the type of the machine (like -sun3) into the flags. -.c.o: - $(CC) -c $(CPPFLAGS) $(CFLAGS) $< - -# The name of the main library target. -LIBRARY_NAME = libreadline.a - -# The C code source files for this library. -CSOURCES = $(srcdir)readline.c $(srcdir)funmap.c $(srcdir)keymaps.c \ - $(srcdir)vi_mode.c $(srcdir)parens.c $(srcdir)rltty.c \ - $(srcdir)complete.c $(srcdir)bind.c $(srcdir)isearch.c \ - $(srcdir)display.c $(srcdir)signals.c $(srcdir)emacs_keymap.c \ - $(srcdir)vi_keymap.c $(srcdir)history.c $(srcdir)tilde.c \ - $(srcdir)xmalloc.c - -# The header files for this library. -HSOURCES = readline.h rldefs.h chardefs.h keymaps.h history.h \ - posixstat.h tilde.h rlconf.h - -OBJECTS = readline.o vi_mode.o funmap.o keymaps.o parens.o search.o \ - rltty.o complete.o bind.o isearch.o display.o signals.o \ - history.o tilde.o xmalloc.o - -# The texinfo files which document this library. -DOCSOURCE = doc/rlman.texinfo doc/rltech.texinfo doc/rluser.texinfo -DOCOBJECT = doc/readline.dvi -DOCSUPPORT = doc/Makefile -DOCUMENTATION = $(DOCSOURCE) $(DOCOBJECT) $(DOCSUPPORT) - -SUPPORT = Makefile ChangeLog $(DOCSUPPORT) examples/[-a-z.]* - -SOURCES = $(CSOURCES) $(HSOURCES) $(DOCSOURCE) - -THINGS_TO_TAR = $(SOURCES) $(SUPPORT) - -########################################################################## - -all: libreadline.a libhistory.a - -libreadline.a: $(OBJECTS) - $(RM) -f $@ - $(AR) cq $@ $(OBJECTS) - -[ -n "$(RANLIB)" ] && $(RANLIB) $@ - -libhistory.a: history.o - $(RM) -f $@ - $(AR) cq $@ history.o - -[ -n "$(RANLIB)" ] && $(RANLIB) $@ - -documentation: force - [ ! -d doc ] && mkdir doc - (if [ -d doc ]; then cd doc; $(MAKE) $(MFLAGS); fi) - -force: - -# The rule for 'includes' is written funny so that the if statement -# always returns TRUE unless there really was an error installing the -# include files. -install: installdirs libreadline.a - ${INSTALL_DATA} readline.h keymaps.h chardefs.h history.h \ - $(incdir)/readline - -${MV} $(libdir)/libreadline.a $(libdir)/libreadline.old - ${INSTALL_DATA} libreadline.a $(bindir)/libreadline.a - -[ -n "$(RANLIB)" ] && $(RANLIB) -t $(bindir)/libreadline.a - -installdirs: - [ ! -d $(incdir)/readline ] && { \ - mkdir $(incdir)/readline && chmod chmod 755 $(incdir)/readline; } - -uninstall: - cd $(incdir)/readline && ${RM} -f ${INSTALLED_HEADERS} - cd $(libdir) && ${RM} -f libreadline.a libreadline.old - -tags: force - etags $(CSOURCES) $(HSOURCES) - -TAGS: force - ctags -x $(CSOURCES) $(HSOURCES) > $@ - -readline: readline.h rldefs.h chardefs.h -readline: $(OBJECTS) - $(CC) $(CFLAGS) $(CPPFLAGS) $(READLINE_DEFINES) \ - $(LOCAL_INCLUDES) -DTEST -o readline readline.c vi_mode.o funmap.o \ - keymaps.o -ltermcap - -clean: - $(RM) -f $(OBJECTS) libreadline.a libhistory.a - (if [ -d doc ]; then cd doc; $(MAKE) $(MFLAGS) $@; fi) - -maintainer-clean realclean distclean mostlyclean: clean - (if [ -d doc ]; then cd doc; $(MAKE) $(MFLAGS) $@; fi) - -# Dependencies -readline.o: readline.c readline.h rldefs.h rlconf.h chardefs.h -readline.o: keymaps.h history.h -vi_mode.o: rldefs.h rlconf.h readline.h history.h -funmap.o: funmap.c readline.h rlconf.h -keymaps.o: keymaps.c emacs_keymap.c vi_keymap.c keymaps.h chardefs.h rlconf.h -history.o: history.h memalloc.h -isearch.o: memalloc.h readline.h history.h -search.o: memalloc.h readline.h history.h -display.o: readline.h history.h rldefs.h rlconf.h -complete.o: readline.h rldefs.h rlconf.h -rltty.o: rldefs.h rlconf.h readline.h -bind.o: rldefs.h rlconf.h readline.h history.h -signals.o: rldefs.h rlconf.h readline.h history.h -parens.o: readline.h diff --git a/lib/readline/Makefile.in b/lib/readline/Makefile.in new file mode 100644 index 0000000..c5ac183 --- /dev/null +++ b/lib/readline/Makefile.in @@ -0,0 +1,192 @@ +## -*- text -*- #################################################### +# # +# Makefile for the GNU Readline and History Libraries. # +# # +#################################################################### + +srcdir = @srcdir@ +VPATH = .:@srcdir@ +topdir = @top_srcdir@ +BUILD_DIR = @BUILD_DIR@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +CC = @CC@ +RANLIB = @RANLIB@ +AR = @AR@ +RM = rm -f +CP = cp +MV = mv + +# See the file STANDALONE for the -D defines that readline understands + +CFLAGS = @CFLAGS@ +LOCAL_CFLAGS = @LOCAL_CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ + +DEFS = @DEFS@ + +INCLUDES = -I. -I$(BUILD_DIR) -I$(topdir) -I$(topdir)/lib + +CCFLAGS = $(DEFS) $(APP_CFLAGS) $(CPPFLAGS) ${INCLUDES} $(LOCAL_CFLAGS) $(CFLAGS) + +# Here is a rule for making .o files from .c files that doesn't force +# the type of the machine (like -sun3) into the flags. +.c.o: + $(CC) -c $(CCFLAGS) $< + +# The name of the main library target. +LIBRARY_NAME = libreadline.a + +# The C code source files for this library. +CSOURCES = $(srcdir)/readline.c $(srcdir)/funmap.c $(srcdir)/keymaps.c \ + $(srcdir)/vi_mode.c $(srcdir)/parens.c $(srcdir)/rltty.c \ + $(srcdir)/complete.c $(srcdir)/bind.c $(srcdir)/isearch.c \ + $(srcdir)/display.c $(srcdir)/signals.c $(srcdir)/emacs_keymap.c \ + $(srcdir)/vi_keymap.c $(srcdir)/util.c $(srcdir)/kill.c \ + $(srcdir)/undo.c $(srcdir)/macro.c $(srcdir)/input.c \ + $(srcdir)/callback.c $(srcdir)/terminal.c $(srcdir)/xmalloc.c \ + $(srcdir)/history.c $(srcdir)/histsearch.c $(srcdir)/histexpand.c \ + $(srcdir)/histfile.c $(srcdir)/nls.c \ + $(srcdir)/tilde.c \ + +# The header files for this library. +HSOURCES = readline.h rldefs.h chardefs.h keymaps.h history.h histlib.h \ + posixstat.h tilde.h rlconf.h tcap.h + +HISTOBJ = history.o histexpand.o histfile.o histsearch.o +TILDEOBJ= tilde.o +OBJECTS = readline.o vi_mode.o funmap.o keymaps.o parens.o search.o \ + rltty.o complete.o bind.o isearch.o display.o signals.o \ + util.o kill.o undo.o macro.o input.o callback.o terminal.o \ + nls.o xmalloc.o \ + $(HISTOBJ) $(TILDEOBJ) + +# The texinfo files which document this library. +DOCSOURCE = doc/rlman.texinfo doc/rltech.texinfo doc/rluser.texinfo +DOCOBJECT = doc/readline.dvi +DOCSUPPORT = doc/Makefile +DOCUMENTATION = $(DOCSOURCE) $(DOCOBJECT) $(DOCSUPPORT) + +SUPPORT = Makefile ChangeLog $(DOCSUPPORT) examples/[-a-z.]* + +SOURCES = $(CSOURCES) $(HSOURCES) $(DOCSOURCE) + +THINGS_TO_TAR = $(SOURCES) $(SUPPORT) + +INSTALLED_HEADERS = readline.h chardefs.h keymaps.h history.h tilde.h + +########################################################################## + +all: libreadline.a libhistory.a + +libreadline.a: $(OBJECTS) + $(RM) -f $@ + $(AR) cr $@ $(OBJECTS) + -test -n "$(RANLIB)" && $(RANLIB) $@ + +libhistory.a: $(HISTOBJ) xmalloc.o + $(RM) -f $@ + $(AR) cr $@ $(HISTOBJ) xmalloc.o + -test -n "$(RANLIB)" && $(RANLIB) $@ + +documentation: force + test -d doc || mkdir doc + -( cd doc && $(MAKE) $(MFLAGS) ) + +force: + +# The rule for 'includes' is written funny so that the if statement +# always returns TRUE unless there really was an error installing the +# include files. +install: installdirs libreadline.a + for file in $(INSTALLED_HEADERS) ; do \ + $(INSTALL_DATA) $(srcdir)/$$file $(includedir)/readline ; \ + done + -${MV} $(libdir)/libreadline.a $(libdir)/libreadline.old + ${INSTALL_DATA} libreadline.a $(libdir)/libreadline.a + -test -n "$(RANLIB)" && $(RANLIB) -t $(bindir)/libreadline.a + +installdirs: $(topdir)/support/mkdirs + $(SHELL) $(topdir)/support/mkdirs $(includedir) \ + $(includedir)/readline $(libdir) $(infodir) $(man3dir) + +uninstall: + cd $(includedir)/readline && ${RM} -f ${INSTALLED_HEADERS} + cd $(libdir) && ${RM} -f libreadline.a libreadline.old + +tags: force + etags $(CSOURCES) $(HSOURCES) + +TAGS: force + ctags -x $(CSOURCES) $(HSOURCES) > $@ + +readline: readline.h rldefs.h chardefs.h +readline: $(OBJECTS) + $(CC) $(CFLAGS) $(CPPFLAGS) $(READLINE_DEFINES) \ + $(LOCAL_INCLUDES) -DTEST -o readline readline.c vi_mode.o funmap.o \ + keymaps.o -ltermcap + +clean: force + $(RM) $(OBJECTS) *.a + -( cd doc && $(MAKE) $(MFLAGS) $@ ) + +distclean realclean maintainer-clean: clean + -( cd doc && $(MAKE) $(MFLAGS) $@ ) + $(RM) Makefile + +mostlyclean: clean + -( cd doc && $(MAKE) $(MFLAGS) $@ ) + +# Dependencies +readline.o: readline.c readline.h rldefs.h rlconf.h chardefs.h tcap.h +readline.o: keymaps.h history.h +vi_mode.o: rldefs.h rlconf.h readline.h history.h +funmap.o: funmap.c readline.h rlconf.h +keymaps.o: keymaps.c emacs_keymap.c vi_keymap.c keymaps.h chardefs.h rlconf.h +history.o: history.h histlib.h +histexpand.o: history.h histlib.h +histsearch.o: history.h histlib.h +histfile.o: history.h histlib.h +isearch.o: readline.h history.h +search.o: readline.h history.h +display.o: readline.h history.h rldefs.h rlconf.h tcap.h +complete.o: readline.h rldefs.h rlconf.h posixdir.h posixstat.h +rltty.o: rldefs.h rlconf.h readline.h rltty.h +bind.o: rldefs.h rlconf.h readline.h history.h +signals.o: rldefs.h rlconf.h readline.h history.h +parens.o: readline.h +kill.o: rldefs.h rlconf.h readline.h history.h +macro.o: rldefs.h rlconf.h readline.h history.h +undo.o: rldefs.h rlconf.h readline.h history.h +input.o: rldefs.h rlconf.h readline.h history.h +callback.o: rlconf.h rldefs.h readline.h +terminal.o: rlconf.h rldefs.h readline.h tcap.h history.h + +bind.o: $(BUILD_DIR)/config.h +callback.o: $(BUILD_DIR)/config.h +complete.o: $(BUILD_DIR)/config.h +display.o: $(BUILD_DIR)/config.h +funmap.o: $(BUILD_DIR)/config.h +histexpand.o: $(BUILD_DIR)/config.h +histfile.o: $(BUILD_DIR)/config.h +history.o: $(BUILD_DIR)/config.h +histsearch.o: $(BUILD_DIR)/config.h +input.o: $(BUILD_DIR)/config.h +isearch.o: $(BUILD_DIR)/config.h +keymaps.o: $(BUILD_DIR)/config.h +kill.o: $(BUILD_DIR)/config.h +macro.o: $(BUILD_DIR)/config.h +parens.o: $(BUILD_DIR)/config.h +readline.o: $(BUILD_DIR)/config.h +rltty.o: $(BUILD_DIR)/config.h +search.o: $(BUILD_DIR)/config.h +signals.o: $(BUILD_DIR)/config.h +tilde.o: $(BUILD_DIR)/config.h +undo.o: $(BUILD_DIR)/config.h +util.o: $(BUILD_DIR)/config.h +vi_mode.o: $(BUILD_DIR)/config.h +xmalloc.o: $(BUILD_DIR)/config.h diff --git a/lib/readline/STANDALONE b/lib/readline/STANDALONE index c1387f3..f999e8d 100644 --- a/lib/readline/STANDALONE +++ b/lib/readline/STANDALONE @@ -15,6 +15,7 @@ HAVE_DIRENT_H <dirent.h> exists and is usable HAVE_SYS_PTEM_H <sys/ptem.h> exists HAVE_SYS_PTE_H <sys/pte.h> exists HAVE_SYS_STREAM_H <sys/stream.h> exists +HAVE_SYS_SELECT_H <sys/select.h> exists System-specific options: diff --git a/lib/readline/bind.c b/lib/readline/bind.c index 8821599..bd899ca 100644 --- a/lib/readline/bind.c +++ b/lib/readline/bind.c @@ -21,13 +21,16 @@ 675 Mass Ave, Cambridge, MA 02139, USA. */ #define READLINE_LIBRARY +#if defined (HAVE_CONFIG_H) +# include <config.h> +#endif + #include <stdio.h> #include <sys/types.h> #include <fcntl.h> -#if !defined (NO_SYS_FILE) +#if defined (HAVE_SYS_FILE_H) # include <sys/file.h> -#endif /* !NO_SYS_FILE */ -#include <signal.h> +#endif /* HAVE_SYS_FILE_H */ #if defined (HAVE_UNISTD_H) # include <unistd.h> @@ -39,8 +42,9 @@ # include "ansi_stdlib.h" #endif /* HAVE_STDLIB_H */ +#include <signal.h> #include <errno.h> -/* Not all systems declare ERRNO in errno.h... and some systems #define it! */ + #if !defined (errno) extern int errno; #endif /* !errno */ @@ -65,6 +69,8 @@ extern int _rl_meta_flag; extern int _rl_convert_meta_chars_to_ascii; extern int _rl_output_meta_chars; extern int _rl_complete_show_all; +extern int _rl_complete_mark_directories; +extern int _rl_enable_keypad; #if defined (PAREN_MATCHING) extern int rl_blink_matching_paren; #endif /* PAREN_MATCHING */ @@ -73,36 +79,31 @@ extern int rl_visible_stats; #endif /* VISIBLE_STATS */ extern int rl_complete_with_tilde_expansion; extern int rl_completion_query_items; -#if defined (VI_MODE) -extern char *rl_vi_comment_begin; -#endif +extern int rl_inhibit_completion; +extern char *_rl_comment_begin; extern int rl_explicit_arg; extern int rl_editing_mode; -extern unsigned short _rl_parsing_conditionalized_out; +extern unsigned char _rl_parsing_conditionalized_out; extern Keymap _rl_keymap; extern char *possible_control_prefixes[], *possible_meta_prefixes[]; extern char **rl_funmap_names (); +extern int rl_add_funmap_entry (); + +extern char *_rl_strindex (); + +/* Variables exported by this file. */ +Keymap rl_binding_keymap; /* Forward declarations */ void rl_set_keymap_from_edit_mode (); static int glean_key_from_name (); +static int substring_member_of_array (); -#if defined (HAVE_STRCASECMP) -#define stricmp strcasecmp -#define strnicmp strncasecmp -#else -static int stricmp (), strnicmp (); -#endif - -#if defined (STATIC_MALLOC) -static char *xmalloc (), *xrealloc (); -#else extern char *xmalloc (), *xrealloc (); -#endif /* STATIC_MALLOC */ /* **************************************************************** */ /* */ @@ -113,6 +114,7 @@ extern char *xmalloc (), *xrealloc (); /* rl_add_defun (char *name, Function *function, int key) Add NAME to the list of named functions. Make FUNCTION be the function that gets called. If KEY is not -1, then bind it. */ +int rl_add_defun (name, function, key) char *name; Function *function; @@ -150,6 +152,7 @@ rl_bind_key (key, function) _rl_keymap[key].type = ISFUNC; _rl_keymap[key].function = function; + rl_binding_keymap = _rl_keymap; return (0); } @@ -162,8 +165,9 @@ rl_bind_key_in_map (key, function, map) Keymap map; { int result; - Keymap oldmap = _rl_keymap; + Keymap oldmap; + oldmap = _rl_keymap; _rl_keymap = map; result = rl_bind_key (key, function); _rl_keymap = oldmap; @@ -192,6 +196,7 @@ rl_unbind_key_in_map (key, map) /* Bind the key sequence represented by the string KEYSEQ to FUNCTION. This makes new keymaps as necessary. The initial place to do bindings is in MAP. */ +int rl_set_key (keyseq, function, map) char *keyseq; Function *function; @@ -203,6 +208,7 @@ rl_set_key (keyseq, function, map) /* Bind the key sequence represented by the string KEYSEQ to the string of characters MACRO. This makes new keymaps as necessary. The initial place to do bindings is in MAP. */ +int rl_macro_bind (keyseq, macro, map) char *keyseq, *macro; Keymap map; @@ -226,6 +232,7 @@ rl_macro_bind (keyseq, macro, map) pointed to by DATA, right now this can be a function (ISFUNC), a macro (ISMACR), or a keymap (ISKMAP). This makes new keymaps as necessary. The initial place to do bindings is in MAP. */ +int rl_generic_bind (type, keyseq, data, map) int type; char *keyseq, *data; @@ -286,6 +293,8 @@ rl_generic_bind (type, keyseq, data, map) map[ic].function = KEYMAP_TO_FUNCTION (data); map[ic].type = type; } + + rl_binding_keymap = map; } free (keys); return 0; @@ -294,30 +303,30 @@ rl_generic_bind (type, keyseq, data, map) /* Translate the ASCII representation of SEQ, stuffing the values into ARRAY, an array of characters. LEN gets the final length of ARRAY. Return non-zero if there was an error parsing SEQ. */ +int rl_translate_keyseq (seq, array, len) char *seq, *array; int *len; { - register int i, c, l = 0; + register int i, c, l; - for (i = 0; c = seq[i]; i++) + for (i = l = 0; c = seq[i]; i++) { if (c == '\\') { c = seq[++i]; - if (!c) + if (c == 0) break; - if (((c == 'C' || c == 'M') && seq[i + 1] == '-') || - (c == 'e')) + if (((c == 'C' || c == 'M') && seq[i + 1] == '-') || (c == 'e')) { /* Handle special case of backwards define. */ if (strncmp (&seq[i], "C-\\M-", 5) == 0) { array[l++] = ESC; i += 5; - array[l++] = CTRL (to_upper (seq[i])); + array[l++] = CTRL (_rl_to_upper (seq[i])); if (!seq[i]) i--; continue; @@ -327,16 +336,13 @@ rl_translate_keyseq (seq, array, len) { case 'M': i++; - array[l++] = ESC; + array[l++] = ESC; /* XXX */ break; case 'C': i += 2; /* Special hack for C-?... */ - if (seq[i] == '?') - array[l++] = RUBOUT; - else - array[l++] = CTRL (to_upper (seq[i])); + array[l++] = (seq[i] == '?') ? RUBOUT : CTRL (_rl_to_upper (seq[i])); break; case 'e': @@ -354,6 +360,52 @@ rl_translate_keyseq (seq, array, len) return (0); } +char * +rl_untranslate_keyseq (seq) + int seq; +{ + static char kseq[16]; + int i, c; + + i = 0; + c = seq; + if (META_CHAR (c)) + { + kseq[i++] = '\\'; + kseq[i++] = 'M'; + kseq[i++] = '-'; + c = UNMETA (c); + } + else if (CTRL_CHAR (c)) + { + kseq[i++] = '\\'; + kseq[i++] = 'C'; + kseq[i++] = '-'; + c = UNCTRL (c); + } + else if (c == RUBOUT) + { + kseq[i++] = '\\'; + kseq[i++] = 'C'; + kseq[i++] = '-'; + c = '?'; + } + + if (c == ESC) + { + kseq[i++] = '\\'; + kseq[i++] = 'e'; + } + else if (c == '\\' || c == '"') + { + kseq[i++] = '\\'; + } + + kseq[i++] = (unsigned char) c; + kseq[i] = '\0'; + return kseq; +} + /* Return a pointer to the function that STRING represents. If STRING doesn't have a matching function, then a NULL pointer is returned. */ @@ -366,7 +418,7 @@ rl_named_function (string) rl_initialize_funmap (); for (i = 0; funmap[i]; i++) - if (stricmp (funmap[i]->name, string) == 0) + if (_rl_stricmp (funmap[i]->name, string) == 0) return (funmap[i]->function); return ((Function *)NULL); } @@ -435,7 +487,12 @@ rl_function_of_keyseq (keyseq, map, type) /* The last key bindings file read. */ static char *last_readline_init_file = (char *)NULL; +/* The file we're currently reading key bindings from. */ +static char *current_readline_init_file; +static int current_readline_init_lineno; + /* Re-read the current keybindings file. */ +int rl_re_read_init_file (count, ignore) int count, ignore; { @@ -462,18 +519,19 @@ rl_read_init_file (filename) int file; /* Default the filename. */ - if (!filename) + if (filename == 0) { filename = last_readline_init_file; - if (!filename) + if (filename == 0) filename = getenv ("INPUTRC"); - if (!filename) + if (filename == 0) filename = DEFAULT_INPUTRC; } - if (!*filename) + if (*filename == 0) filename = DEFAULT_INPUTRC; + current_readline_init_file = filename; openname = tilde_expand (filename); if ((stat (openname, &finfo) < 0) || @@ -503,6 +561,7 @@ rl_read_init_file (filename) /* Loop over the lines in the file. Lines that start with `#' are comments; all other lines are commands for readline initialization. */ + current_readline_init_lineno = 1; line = buffer; end = buffer + finfo.st_size; while (line < end) @@ -526,11 +585,21 @@ rl_read_init_file (filename) /* Move to the next line. */ line += i + 1; + current_readline_init_lineno++; } free (buffer); return (0); } +static void +_rl_init_file_error (msg) + char *msg; +{ + fprintf (stderr, "readline: %s: line %d: %s\n", current_readline_init_file, + current_readline_init_lineno, + msg); +} + /* **************************************************************** */ /* */ /* Parser Directives */ @@ -544,8 +613,8 @@ char *rl_readline_name = "other"; /* Stack of previous values of parsing_conditionalized_out. */ static unsigned char *if_stack = (unsigned char *)NULL; -static int if_stack_depth = 0; -static int if_stack_size = 0; +static int if_stack_depth; +static int if_stack_size; /* Push _rl_parsing_conditionalized_out, and set parser state based on ARGS. */ @@ -579,7 +648,7 @@ parser_if (args) /* Handle "if term=foo" and "if mode=emacs" constructs. If this isn't term=foo, or mode=emacs, then check to see if the first word in ARGS is the same as the value stored in rl_readline_name. */ - if (rl_terminal_name && strnicmp (args, "term=", 5) == 0) + if (rl_terminal_name && _rl_strnicmp (args, "term=", 5) == 0) { char *tem, *tname; @@ -593,35 +662,28 @@ parser_if (args) if someone has a `sun-cmd' and does not want to have bindings that will be executed if the terminal is a `sun', they can put `$if term=sun-cmd' into their .inputrc. */ - if ((stricmp (args + 5, tname) == 0) || - (stricmp (args + 5, rl_terminal_name) == 0)) - _rl_parsing_conditionalized_out = 0; - else - _rl_parsing_conditionalized_out = 1; - + _rl_parsing_conditionalized_out = _rl_stricmp (args + 5, tname) && + _rl_stricmp (args + 5, rl_terminal_name); free (tname); } #if defined (VI_MODE) - else if (strnicmp (args, "mode=", 5) == 0) + else if (_rl_strnicmp (args, "mode=", 5) == 0) { int mode; - if (stricmp (args + 5, "emacs") == 0) + if (_rl_stricmp (args + 5, "emacs") == 0) mode = emacs_mode; - else if (stricmp (args + 5, "vi") == 0) + else if (_rl_stricmp (args + 5, "vi") == 0) mode = vi_mode; else mode = no_mode; - if (mode == rl_editing_mode) - _rl_parsing_conditionalized_out = 0; - else - _rl_parsing_conditionalized_out = 1; + _rl_parsing_conditionalized_out = mode != rl_editing_mode; } #endif /* VI_MODE */ /* Check to see if the first word in ARGS is the same as the value stored in rl_readline_name. */ - else if (stricmp (args, rl_readline_name) == 0) + else if (_rl_stricmp (args, rl_readline_name) == 0) _rl_parsing_conditionalized_out = 0; else _rl_parsing_conditionalized_out = 1; @@ -705,7 +767,7 @@ handle_parser_directive (statement) /* Lookup the command, and act on it. */ for (i = 0; parser_directives[i].name; i++) - if (stricmp (directive, parser_directives[i].name) == 0) + if (_rl_stricmp (directive, parser_directives[i].name) == 0) { (*parser_directives[i].function) (args); return (0); @@ -715,12 +777,11 @@ handle_parser_directive (statement) return (1); } -static int substring_member_of_array (); - /* Read the binding command from STRING and perform it. A key binding command looks like: Keyname: function-name\0, a variable binding command looks like: set variable value. A new-style keybinding looks like "\C-x\C-x": exchange-point-and-mark. */ +int rl_parse_and_bind (string) char *string; { @@ -770,6 +831,12 @@ rl_parse_and_bind (string) if (c == '"') break; } + /* If we didn't find a closing quote, abort the line. */ + if (string[i] == '\0') + { + _rl_init_file_error ("no closing `\"' in key binding"); + return 1; + } } /* Advance to the colon (:) or whitespace which separates the two objects. */ @@ -786,7 +853,7 @@ rl_parse_and_bind (string) string[i++] = '\0'; /* If this is a command to set a variable, then do that. */ - if (stricmp (string, "set") == 0) + if (_rl_stricmp (string, "set") == 0) { char *var = string + i; char *value; @@ -915,7 +982,7 @@ rl_parse_and_bind (string) /* Add in control and meta bits. */ if (substring_member_of_array (string, possible_control_prefixes)) - key = CTRL (to_upper (key)); + key = CTRL (_rl_to_upper (key)); if (substring_member_of_array (string, possible_meta_prefixes)) key = META (key); @@ -934,7 +1001,7 @@ rl_parse_and_bind (string) } #if defined (PREFIX_META_HACK) /* Ugly, but working hack to keep prefix-meta around. */ - else if (stricmp (funname, "prefix-meta") == 0) + else if (_rl_stricmp (funname, "prefix-meta") == 0) { char seq[2]; @@ -956,22 +1023,27 @@ static struct { char *name; int *value; } boolean_varlist [] = { - { "horizontal-scroll-mode", &_rl_horizontal_scroll_mode }, - { "mark-modified-lines", &_rl_mark_modified_lines }, - { "meta-flag", &_rl_meta_flag }, #if defined (PAREN_MATCHING) { "blink-matching-paren", &rl_blink_matching_paren }, #endif { "convert-meta", &_rl_convert_meta_chars_to_ascii }, - { "show-all-if-ambiguous", &_rl_complete_show_all }, + { "disable-completion", &rl_inhibit_completion }, + { "enable-keypad", &_rl_enable_keypad }, + { "expand-tilde", &rl_complete_with_tilde_expansion }, + { "horizontal-scroll-mode", &_rl_horizontal_scroll_mode }, + { "input-meta", &_rl_meta_flag }, + { "mark-directories", &_rl_complete_mark_directories }, + { "mark-modified-lines", &_rl_mark_modified_lines }, + { "meta-flag", &_rl_meta_flag }, { "output-meta", &_rl_output_meta_chars }, + { "show-all-if-ambiguous", &_rl_complete_show_all }, #if defined (VISIBLE_STATS) { "visible-stats", &rl_visible_stats }, #endif /* VISIBLE_STATS */ - { "expand-tilde", &rl_complete_with_tilde_expansion }, { (char *)NULL, (int *)NULL } }; +int rl_variable_bind (name, value) char *name, *value; { @@ -980,15 +1052,12 @@ rl_variable_bind (name, value) /* Check for simple variables first. */ for (i = 0; boolean_varlist[i].name; i++) { - if (stricmp (name, boolean_varlist[i].name) == 0) + if (_rl_stricmp (name, boolean_varlist[i].name) == 0) { /* A variable is TRUE if the "value" is "on", "1" or "". */ - if ((!*value) || - (stricmp (value, "On") == 0) || - (value[0] == '1' && value[1] == '\0')) - *boolean_varlist[i].value = 1; - else - *boolean_varlist[i].value = 0; + *boolean_varlist[i].value = *value == 0 || + _rl_stricmp (value, "on") == 0 || + (value[0] == '1' && value[1] == '\0'); return 0; } } @@ -996,16 +1065,16 @@ rl_variable_bind (name, value) /* Not a boolean variable, so check for specials. */ /* Editing mode change? */ - if (stricmp (name, "editing-mode") == 0) + if (_rl_stricmp (name, "editing-mode") == 0) { - if (strnicmp (value, "vi", 2) == 0) + if (_rl_strnicmp (value, "vi", 2) == 0) { #if defined (VI_MODE) _rl_keymap = vi_insertion_keymap; rl_editing_mode = vi_mode; #endif /* VI_MODE */ } - else if (strnicmp (value, "emacs", 5) == 0) + else if (_rl_strnicmp (value, "emacs", 5) == 0) { _rl_keymap = emacs_standard_keymap; rl_editing_mode = emacs_mode; @@ -1013,19 +1082,17 @@ rl_variable_bind (name, value) } /* Comment string change? */ - else if (stricmp (name, "comment-begin") == 0) + else if (_rl_stricmp (name, "comment-begin") == 0) { -#if defined (VI_MODE) if (*value) { - if (rl_vi_comment_begin) - free (rl_vi_comment_begin); + if (_rl_comment_begin) + free (_rl_comment_begin); - rl_vi_comment_begin = savestring (value); + _rl_comment_begin = savestring (value); } -#endif /* VI_MODE */ } - else if (stricmp (name, "completion-query-items") == 0) + else if (_rl_stricmp (name, "completion-query-items") == 0) { int nval = 100; if (*value) @@ -1036,31 +1103,31 @@ rl_variable_bind (name, value) } rl_completion_query_items = nval; } - else if (stricmp (name, "keymap") == 0) + else if (_rl_stricmp (name, "keymap") == 0) { Keymap kmap; kmap = rl_get_keymap_by_name (value); if (kmap) rl_set_keymap (kmap); } - else if (stricmp (name, "bell-style") == 0) + else if (_rl_stricmp (name, "bell-style") == 0) { if (!*value) _rl_bell_preference = AUDIBLE_BELL; else { - if (stricmp (value, "none") == 0 || stricmp (value, "off") == 0) + if (_rl_stricmp (value, "none") == 0 || _rl_stricmp (value, "off") == 0) _rl_bell_preference = NO_BELL; - else if (stricmp (value, "audible") == 0 || stricmp (value, "on") == 0) + else if (_rl_stricmp (value, "audible") == 0 || _rl_stricmp (value, "on") == 0) _rl_bell_preference = AUDIBLE_BELL; - else if (stricmp (value, "visible") == 0) + else if (_rl_stricmp (value, "visible") == 0) _rl_bell_preference = VISIBLE_BELL; } } - else if (stricmp (name, "prefer-visible-bell") == 0) + else if (_rl_stricmp (name, "prefer-visible-bell") == 0) { /* Backwards compatibility. */ - if (*value && (stricmp (value, "on") == 0 || + if (*value && (_rl_stricmp (value, "on") == 0 || (*value == '1' && !value[1]))) _rl_bell_preference = VISIBLE_BELL; else @@ -1100,7 +1167,7 @@ glean_key_from_name (name) register int i; for (i = 0; name_key_alist[i].name; i++) - if (stricmp (name, name_key_alist[i].name) == 0) + if (_rl_stricmp (name, name_key_alist[i].name) == 0) return (name_key_alist[i].value); return (*(unsigned char *)name); /* XXX was return (*name) */ @@ -1136,6 +1203,17 @@ rl_get_keymap_by_name (name) return ((Keymap) NULL); } +char * +rl_get_keymap_name (map) + Keymap map; +{ + register int i; + for (i = 0; keymap_names[i].name; i++) + if (map == keymap_names[i].map) + return (keymap_names[i].name); + return ((char *)NULL); +} + void rl_set_keymap (map) Keymap map; @@ -1160,7 +1238,20 @@ rl_set_keymap_from_edit_mode () _rl_keymap = vi_insertion_keymap; #endif /* VI_MODE */ } - + +char * +rl_get_keymap_name_from_edit_mode () +{ + if (rl_editing_mode == emacs_mode) + return "emacs"; +#if defined (VI_MODE) + else if (rl_editing_mode == vi_mode) + return "vi"; +#endif /* VI_MODE */ + else + return "none"; +} + /* **************************************************************** */ /* */ /* Key Binding and Function Information */ @@ -1174,8 +1265,7 @@ rl_set_keymap_from_edit_mode () /* Print the names of functions known to Readline. */ void -rl_list_funmap_names (count, ignore) - int count, ignore; +rl_list_funmap_names () { register int i; char **funmap_names; @@ -1191,6 +1281,67 @@ rl_list_funmap_names (count, ignore) free (funmap_names); } +static char * +_rl_get_keyname (key) + int key; +{ + char *keyname; + int i, c; + + keyname = (char *)xmalloc (8); + + c = key; + /* Since this is going to be used to write out keysequence-function + pairs for possible inclusion in an inputrc file, we don't want to + do any special meta processing on KEY. */ + +#if 0 + /* We might want to do this, but the old version of the code did not. */ + + /* If this is an escape character, we don't want to do any more processing. + Just add the special ESC key sequence and return. */ + if (c == ESC) + { + keyseq[0] = '\\'; + keyseq[1] = 'e'; + keyseq[2] = '\0'; + return keyseq; + } +#endif + + /* RUBOUT is translated directly into \C-? */ + if (key == RUBOUT) + { + keyname[0] = '\\'; + keyname[1] = 'C'; + keyname[2] = '-'; + keyname[3] = '?'; + keyname[4] = '\0'; + return keyname; + } + + i = 0; + /* Now add special prefixes needed for control characters. This can + potentially change C. */ + if (CTRL_CHAR (c)) + { + keyname[i++] = '\\'; + keyname[i++] = 'C'; + keyname[i++] = '-'; + c = _rl_to_lower (UNCTRL (c)); + } + + /* Now, if the character needs to be quoted with a backslash, do that. */ + if (c == '\\' || c == '"') + keyname[i++] = '\\'; + + /* Now add the key, terminate the string, and return it. */ + keyname[i++] = (char) c; + keyname[i] = '\0'; + + return keyname; +} + /* Return a NULL terminated array of strings which represent the key sequences that are used to invoke FUNCTION in MAP. */ char ** @@ -1205,7 +1356,7 @@ rl_invoking_keyseqs_in_map (function, map) result = (char **)NULL; result_index = result_size = 0; - for (key = 0; key < 128; key++) + for (key = 0; key < KEYMAP_SIZE; key++) { switch (map[key].type) { @@ -1217,27 +1368,15 @@ rl_invoking_keyseqs_in_map (function, map) then add the current KEY to the list of invoking keys. */ if (map[key].function == function) { - char *keyname = (char *)xmalloc (5); + char *keyname; - if (CTRL_CHAR (key)) - sprintf (keyname, "\\C-%c", to_lower (UNCTRL (key))); - else if (key == RUBOUT) - sprintf (keyname, "\\C-?"); - else if (key == '\\' || key == '"') - { - keyname[0] = '\\'; - keyname[1] = (char) key; - keyname[2] = '\0'; - } - else - { - keyname[0] = (char) key; - keyname[1] = '\0'; - } + keyname = _rl_get_keyname (key); if (result_index + 2 > result_size) - result = (char **) xrealloc - (result, (result_size += 10) * sizeof (char *)); + { + result_size += 10; + result = (char **) xrealloc (result, result_size * sizeof (char *)); + } result[result_index++] = keyname; result[result_index] = (char *)NULL; @@ -1246,53 +1385,56 @@ rl_invoking_keyseqs_in_map (function, map) case ISKMAP: { - char **seqs = (char **)NULL; + char **seqs; + register int i; /* Find the list of keyseqs in this map which have FUNCTION as their target. Add the key sequences found to RESULT. */ if (map[key].function) seqs = rl_invoking_keyseqs_in_map (function, FUNCTION_TO_KEYMAP (map, key)); + else + break; + + if (seqs == 0) + break; - if (seqs) + for (i = 0; seqs[i]; i++) { - register int i; + char *keyname = (char *)xmalloc (6 + strlen (seqs[i])); + + if (key == ESC) + sprintf (keyname, "\\e"); + else if (CTRL_CHAR (key)) + sprintf (keyname, "\\C-%c", _rl_to_lower (UNCTRL (key))); + else if (key == RUBOUT) + sprintf (keyname, "\\C-?"); + else if (key == '\\' || key == '"') + { + keyname[0] = '\\'; + keyname[1] = (char) key; + keyname[2] = '\0'; + } + else + { + keyname[0] = (char) key; + keyname[1] = '\0'; + } + + strcat (keyname, seqs[i]); + free (seqs[i]); - for (i = 0; seqs[i]; i++) + if (result_index + 2 > result_size) { - char *keyname = (char *)xmalloc (6 + strlen (seqs[i])); - - if (key == ESC) - sprintf (keyname, "\\e"); - else if (CTRL_CHAR (key)) - sprintf (keyname, "\\C-%c", to_lower (UNCTRL (key))); - else if (key == RUBOUT) - sprintf (keyname, "\\C-?"); - else if (key == '\\' || key == '"') - { - keyname[0] = '\\'; - keyname[1] = (char) key; - keyname[2] = '\0'; - } - else - { - keyname[0] = (char) key; - keyname[1] = '\0'; - } - - strcat (keyname, seqs[i]); - free (seqs[i]); - - if (result_index + 2 > result_size) - result = (char **) xrealloc - (result, (result_size += 10) * sizeof (char *)); - - result[result_index++] = keyname; - result[result_index] = (char *)NULL; + result_size += 10; + result = (char **) xrealloc (result, result_size * sizeof (char *)); } - free (seqs); + result[result_index++] = keyname; + result[result_index] = (char *)NULL; } + + free (seqs); } break; } @@ -1309,18 +1451,6 @@ rl_invoking_keyseqs (function) return (rl_invoking_keyseqs_in_map (function, _rl_keymap)); } -/* Print all of the current functions and their bindings to - rl_outstream. If an explicit argument is given, then print - the output in such a way that it can be read back in. */ -int -rl_dump_functions (count, key) - int count, key; -{ - rl_function_dumper (rl_explicit_arg); - rl_on_new_line (); - return (0); -} - /* Print all of the functions and their bindings to rl_outstream. If PRINT_READABLY is non-zero, then print the output in such a way that it can be read back in. */ @@ -1391,6 +1521,164 @@ rl_function_dumper (print_readably) } } +/* Print all of the current functions and their bindings to + rl_outstream. If an explicit argument is given, then print + the output in such a way that it can be read back in. */ +int +rl_dump_functions (count, key) + int count, key; +{ + rl_function_dumper (rl_explicit_arg); + rl_on_new_line (); + return (0); +} + +static void +_rl_macro_dumper_internal (print_readably, map, prefix) + int print_readably; + Keymap map; + char *prefix; +{ + register int key; + char *keyname, *out; + int prefix_len; + + for (key = 0; key < KEYMAP_SIZE; key++) + { + switch (map[key].type) + { + case ISMACR: + keyname = _rl_get_keyname (key); + out = (char *)map[key].function; + if (print_readably) + fprintf (rl_outstream, "\"%s%s\": \"%s\"\n", prefix ? prefix : "", + keyname, + out ? out : ""); + else + fprintf (rl_outstream, "%s%s outputs %s\n", prefix ? prefix : "", + keyname, + out ? out : ""); + free (keyname); + break; + case ISFUNC: + break; + case ISKMAP: + prefix_len = prefix ? strlen (prefix) : 0; + if (key == ESC) + { + keyname = xmalloc (3 + prefix_len); + if (prefix) + strcpy (keyname, prefix); + keyname[prefix_len] = '\\'; + keyname[prefix_len + 1] = 'e'; + keyname[prefix_len + 2] = '\0'; + } + else + { + keyname = _rl_get_keyname (key); + if (prefix) + { + out = xmalloc (strlen (keyname) + prefix_len + 1); + strcpy (out, prefix); + strcpy (out + prefix_len, keyname); + free (keyname); + keyname = out; + } + } + + _rl_macro_dumper_internal (print_readably, FUNCTION_TO_KEYMAP (map, key), keyname); + free (keyname); + break; + } + } +} + +void +rl_macro_dumper (print_readably) + int print_readably; +{ + _rl_macro_dumper_internal (print_readably, _rl_keymap, (char *)NULL); +} + +int +rl_dump_macros (count, key) + int count, key; +{ + rl_macro_dumper (rl_explicit_arg); + rl_on_new_line (); + return (0); +} + +void +rl_variable_dumper (print_readably) + int print_readably; +{ + int i; + char *kname; + + for (i = 0; boolean_varlist[i].name; i++) + { + if (print_readably) + fprintf (rl_outstream, "set %s %s\n", boolean_varlist[i].name, + *boolean_varlist[i].value ? "on" : "off"); + else + fprintf (rl_outstream, "%s is set to `%s'\n", boolean_varlist[i].name, + *boolean_varlist[i].value ? "on" : "off"); + } + + /* bell-style */ + switch (_rl_bell_preference) + { + case NO_BELL: kname = "none"; break; + case VISIBLE_BELL: kname = "visible"; break; + case AUDIBLE_BELL: + default: kname = "audible"; break; + } + if (print_readably) + fprintf (rl_outstream, "set bell-style %s\n", kname); + else + fprintf (rl_outstream, "bell-style is set to `%s'\n", kname); + + /* comment-begin */ + if (print_readably) + fprintf (rl_outstream, "set comment-begin %s\n", _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT); + else + fprintf (rl_outstream, "comment-begin is set to `%s'\n", _rl_comment_begin ? _rl_comment_begin : ""); + + /* completion-query-items */ + if (print_readably) + fprintf (rl_outstream, "set completion-query-items %d\n", rl_completion_query_items); + else + fprintf (rl_outstream, "completion-query-items is set to `%d'\n", rl_completion_query_items); + + /* editing-mode */ + if (print_readably) + fprintf (rl_outstream, "set editing-mode %s\n", (rl_editing_mode == emacs_mode) ? "emacs" : "vi"); + else + fprintf (rl_outstream, "editing-mode is set to `%s'\n", (rl_editing_mode == emacs_mode) ? "emacs" : "vi"); + + /* keymap */ + kname = rl_get_keymap_name (_rl_keymap); + if (kname == 0) + kname = rl_get_keymap_name_from_edit_mode (); + if (print_readably) + fprintf (rl_outstream, "set keymap %s\n", kname ? kname : "none"); + else + fprintf (rl_outstream, "keymap is set to `%s'\n", kname ? kname : "none"); +} + +/* Print all of the current variables and their values to + rl_outstream. If an explicit argument is given, then print + the output in such a way that it can be read back in. */ +int +rl_dump_variables (count, key) + int count, key; +{ + rl_variable_dumper (rl_explicit_arg); + rl_on_new_line (); + return (0); +} + /* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. */ void _rl_bind_if_unbound (keyseq, default_func) @@ -1407,14 +1695,6 @@ _rl_bind_if_unbound (keyseq, default_func) } } -/* **************************************************************** */ -/* */ -/* String Utility Functions */ -/* */ -/* **************************************************************** */ - -static char *strindex (); - /* Return non-zero if any members of ARRAY are a substring in STRING. */ static int substring_member_of_array (string, array) @@ -1422,66 +1702,9 @@ substring_member_of_array (string, array) { while (*array) { - if (strindex (string, *array)) + if (_rl_strindex (string, *array)) return (1); array++; } return (0); } - -#if !defined (HAVE_STRCASECMP) -/* Whoops, Unix doesn't have strnicmp. */ - -/* Compare at most COUNT characters from string1 to string2. Case - doesn't matter. */ -static int -strnicmp (string1, string2, count) - char *string1, *string2; - int count; -{ - register char ch1, ch2; - - while (count) - { - ch1 = *string1++; - ch2 = *string2++; - if (to_upper(ch1) == to_upper(ch2)) - count--; - else - break; - } - return (count); -} - -/* strcmp (), but caseless. */ -static int -stricmp (string1, string2) - char *string1, *string2; -{ - register char ch1, ch2; - - while (*string1 && *string2) - { - ch1 = *string1++; - ch2 = *string2++; - if (to_upper(ch1) != to_upper(ch2)) - return (1); - } - return (*string1 - *string2); -} -#endif /* !HAVE_STRCASECMP */ - -/* Determine if s2 occurs in s1. If so, return a pointer to the - match in s1. The compare is case insensitive. */ -static char * -strindex (s1, s2) - register char *s1, *s2; -{ - register int i, l = strlen (s2); - register int len = strlen (s1); - - for (i = 0; (len - i) >= l; i++) - if (strnicmp (s1 + i, s2, l) == 0) - return (s1 + i); - return ((char *)NULL); -} diff --git a/lib/readline/callback.c b/lib/readline/callback.c new file mode 100644 index 0000000..ad57f75 --- /dev/null +++ b/lib/readline/callback.c @@ -0,0 +1,144 @@ +/* callback.c -- functions to use readline as an X `callback' mechanism. */ + +/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library, a library for + reading lines of text with interactive input and history editing. + + The GNU Readline Library is free software; you can redistribute it + and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 1, or + (at your option) any later version. + + The GNU Readline Library is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + The GNU General Public License is often shipped with GNU software, and + is generally kept in a file called COPYING or LICENSE. If you do not + have a copy of the license, write to the Free Software Foundation, + 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include <config.h> +#endif + +#include "rlconf.h" + +#if defined (READLINE_CALLBACKS) + +#include <sys/types.h> +#include <stdio.h> + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" +#include "readline.h" + +extern void readline_internal_startup (); +extern char *readline_internal_teardown (); +extern int readline_internal_char (); + +extern int _rl_meta_flag; +extern char *rl_prompt; +extern int rl_visible_prompt_length; + +/* **************************************************************** */ +/* */ +/* Callback Readline Functions */ +/* */ +/* **************************************************************** */ + +/* Allow using readline in situations where a program may have multiple + things to handle at once, and dispatches them via select(). Call + rl_callback_handler_install() with the prompt and a function to call + whenever a complete line of input is ready. The user must then + call readline_char() every time some input is available, and + readline_char() will call the user's function with the complete text + read in at each end of line. The terminal is kept prepped and signals + handled all the time, except during calls to the user's function. */ + +VFunction *rl_linefunc; /* user callback function */ +static int in_handler; /* terminal_prepped and signals set? */ + +/* Make sure the terminal is set up, initialize readline, and prompt. */ +static void +_rl_callback_newline () +{ + rl_initialize (); + + if (in_handler == 0) + { + in_handler = 1; + + (*rl_prep_term_function) (_rl_meta_flag); + +#if defined (HANDLE_SIGNALS) + rl_set_signals (); +#endif + } + + readline_internal_setup (); +} + +/* Install a readline handler, set up the terminal, and issue the prompt. */ +void +rl_callback_handler_install (prompt, linefunc) + char *prompt; + VFunction *linefunc; +{ + rl_prompt = prompt; + rl_visible_prompt_length = rl_prompt ? rl_expand_prompt (rl_prompt) : 0; + rl_linefunc = linefunc; + _rl_callback_newline (); +} + +/* Read one character, and dispatch to the handler if it ends the line. */ +void +rl_callback_read_char () +{ + char *line; + int eof; + + if (rl_linefunc == NULL) + { + fprintf (stderr, "readline: readline_callback_read_char() called with no handler!\r\n"); + abort (); + } + + eof = readline_internal_char (); + + if (rl_done) + { + line = readline_internal_teardown (eof); + + (*rl_deprep_term_function) (); +#if defined (HANDLE_SIGNALS) + rl_clear_signals (); +#endif + in_handler = 0; + (*rl_linefunc) (line); + + /* Redisplay the prompt if readline_handler_{install,remove} not called. */ + if (in_handler == 0 && rl_linefunc) + _rl_callback_newline (); + } +} + +/* Remove the handler, and make sure the terminal is in its normal state. */ +void +rl_callback_handler_remove () +{ + rl_linefunc = NULL; + if (in_handler) + { + in_handler = 0; + (*rl_deprep_term_function) (); +#if defined (HANDLE_SIGNALS) + rl_clear_signals (); +#endif + } +} + +#endif diff --git a/lib/readline/chardefs.h b/lib/readline/chardefs.h index 8c92811..8e6f0ef 100644 --- a/lib/readline/chardefs.h +++ b/lib/readline/chardefs.h @@ -20,16 +20,20 @@ have a copy of the license, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef _CHARDEFS_H -#define _CHARDEFS_H +#ifndef _CHARDEFS_H_ +#define _CHARDEFS_H_ #include <ctype.h> -#if defined (HAVE_STRING_H) -# include <string.h> +#if defined (HAVE_CONFIG_H) +# if defined (HAVE_STRING_H) +# include <string.h> +# else +# include <strings.h> +# endif /* HAVE_STRING_H */ #else -# include <strings.h> -#endif /* HAVE_STRING_H */ +# include <string.h> +#endif /* !HAVE_CONFIG_H */ #ifndef whitespace #define whitespace(c) (((c) == ' ') || ((c) == '\t')) @@ -47,39 +51,40 @@ #define meta_character_bit 0x080 /* x0000000, must be on. */ #define largest_char 255 /* Largest character value. */ -#define CTRL_CHAR(c) ((c) < control_character_threshold) +#define CTRL_CHAR(c) ((c) < control_character_threshold && (c) >= 0) #define META_CHAR(c) ((c) > meta_character_threshold && (c) <= largest_char) #define CTRL(c) ((c) & control_character_mask) #define META(c) ((c) | meta_character_bit) #define UNMETA(c) ((c) & (~meta_character_bit)) -#define UNCTRL(c) to_upper(((c)|control_character_bit)) +#define UNCTRL(c) _rl_to_upper(((c)|control_character_bit)) /* Old versions -#define lowercase_p(c) (((c) > ('a' - 1) && (c) < ('z' + 1))) -#define uppercase_p(c) (((c) > ('A' - 1) && (c) < ('Z' + 1))) -#define digit_p(c) ((c) >= '0' && (c) <= '9') +#define _rl_lowercase_p(c) (((c) > ('a' - 1) && (c) < ('z' + 1))) +#define _rl_uppercase_p(c) (((c) > ('A' - 1) && (c) < ('Z' + 1))) +#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9') */ -#define lowercase_p(c) (islower(c)) -#define uppercase_p(c) (isupper(c)) -#define digit_p(x) (isdigit (x)) +#define _rl_lowercase_p(c) (islower(c)) +#define _rl_uppercase_p(c) (isupper(c)) +#define _rl_digit_p(x) (isdigit (x)) -#define pure_alphabetic(c) (lowercase_p(c) || uppercase_p(c)) +#define _rl_pure_alphabetic(c) (_rl_lowercase_p(c) || _rl_uppercase_p(c)) +#define ALPHABETIC(c) (_rl_lowercase_p(c) || _rl_uppercase_p(c) || _rl_digit_p(c)) /* Old versions -# define to_upper(c) (lowercase_p(c) ? ((c) - 32) : (c)) -# define to_lower(c) (uppercase_p(c) ? ((c) + 32) : (c)) +# define _rl_to_upper(c) (_rl_lowercase_p(c) ? ((c) - 32) : (c)) +# define _rl_to_lower(c) (_rl_uppercase_p(c) ? ((c) + 32) : (c)) */ -#ifndef to_upper -# define to_upper(c) (islower(c) ? toupper(c) : (c)) -# define to_lower(c) (isupper(c) ? tolower(c) : (c)) +#ifndef _rl_to_upper +# define _rl_to_upper(c) (islower(c) ? toupper(c) : (c)) +# define _rl_to_lower(c) (isupper(c) ? tolower(c) : (c)) #endif -#ifndef digit_value -#define digit_value(x) ((x) - '0') +#ifndef _rl_digit_value +#define _rl_digit_value(x) ((x) - '0') #endif #ifndef NEWLINE @@ -119,4 +124,4 @@ #define ESC CTRL('[') -#endif /* _CHARDEFS_H */ +#endif /* _CHARDEFS_H_ */ diff --git a/lib/readline/complete.c b/lib/readline/complete.c index f219877..f9e27eb 100644 --- a/lib/readline/complete.c +++ b/lib/readline/complete.c @@ -22,15 +22,15 @@ #define READLINE_LIBRARY #if defined (HAVE_CONFIG_H) -# include "config.h" +# include <config.h> #endif #include <stdio.h> #include <sys/types.h> #include <fcntl.h> -#if !defined (NO_SYS_FILE) -# include <sys/file.h> -#endif /* !NO_SYS_FILE */ +#if defined (HAVE_SYS_FILE_H) +#include <sys/file.h> +#endif #if defined (HAVE_UNISTD_H) # include <unistd.h> @@ -43,13 +43,12 @@ #endif /* HAVE_STDLIB_H */ #include <errno.h> -/* Not all systems declare ERRNO in errno.h... and some systems #define it! */ #if !defined (errno) extern int errno; #endif /* !errno */ #include <pwd.h> -#if defined (USG) && !defined (HAVE_GETPW_DECLS) +#if !defined (HAVE_GETPW_DECLS) extern struct passwd *getpwent (); #endif /* USG && !HAVE_GETPW_DECLS */ @@ -62,6 +61,7 @@ extern struct passwd *getpwent (); # endif /* !__STDC__ */ #endif /* isc386 && _POSIX_SOURCE */ +#include "posixdir.h" #include "posixstat.h" /* System-specific feature definitions and include files. */ @@ -70,35 +70,36 @@ extern struct passwd *getpwent (); /* Some standard library routines. */ #include "readline.h" -/* Possible values for do_replace in rl_complete_internal. */ -#define NO_MATCH 0 -#define SINGLE_MATCH 1 -#define MULT_MATCH 2 - -#if !defined (strchr) && !defined (__STDC__) -extern char *strchr (), *strrchr (); -#endif /* !strchr && !__STDC__ */ - extern char *tilde_expand (); extern char *rl_copy_text (); +extern void _rl_abort_internal (); +extern int _rl_qsort_string_compare (); extern Function *rl_last_func; extern int rl_editing_mode; extern int screenwidth; +extern void _rl_move_vert (); +extern int _rl_vis_botlin; +extern int rl_display_fixed; + /* Forward declarations for functions defined and used in this file. */ char *filename_completion_function (); char **completion_matches (); -static int compare_strings (); +static char *rl_quote_filename (); static char *rl_strpbrk (); -#if defined (STATIC_MALLOC) -static char *xmalloc (), *xrealloc (); -#else +static char **remove_duplicate_matches (); +static void insert_text (); +static void insert_match (); +static void append_to_match (); +static void insert_all_matches (); +static void display_matches (); +static int compute_lcd_of_matches (); + extern char *xmalloc (), *xrealloc (); -#endif /* STATIC_MALLOC */ - + /* If non-zero, then this is the address of a function to call when completing on a directory name. The function is called with the address of a string (the current directory name) as an arg. */ @@ -110,6 +111,9 @@ int rl_complete_with_tilde_expansion = 0; /* If non-zero, non-unique completions always show the list of matches. */ int _rl_complete_show_all = 0; +/* If non-zero, completed directory names have a slash appended. */ +int _rl_complete_mark_directories = 1; + #if defined (VISIBLE_STATS) # if !defined (X_OK) # define X_OK 1 @@ -129,6 +133,9 @@ int rl_visible_stats = 0; /* */ /* **************************************************************** */ +/* Local variable states what happened during the last completion attempt. */ +static int completion_changed_buffer; + /* Pointer to the generator function for completion_matches (). NULL means to use filename_entry_function (), the default filename completer. */ @@ -147,54 +154,10 @@ CPPFunction *rl_attempted_completion_function = (CPPFunction *)NULL; user-specified completion function has been called. */ int rl_attempted_completion_over = 0; -/* Local variable states what happened during the last completion attempt. */ -static int completion_changed_buffer = 0; - -/* Complete the word at or before point. You have supplied the function - that does the initial simple matching selection algorithm (see - completion_matches ()). The default is to do filename completion. */ - -rl_complete (ignore, invoking_key) - int ignore, invoking_key; -{ - if (rl_last_func == rl_complete && !completion_changed_buffer) - return (rl_complete_internal ('?')); - else if (_rl_complete_show_all) - return (rl_complete_internal ('!')); - else - return (rl_complete_internal (TAB)); -} - -/* List the possible completions. See description of rl_complete (). */ -rl_possible_completions (ignore, invoking_key) - int ignore, invoking_key; -{ - return (rl_complete_internal ('?')); -} - -rl_insert_completions (ignore, invoking_key) - int ignore, invoking_key; -{ - return (rl_complete_internal ('*')); -} - -/* The user must press "y" or "n". Non-zero return means "y" pressed. */ -get_y_or_n () -{ - int c; - - for (;;) - { - c = rl_read_key (); - if (c == 'y' || c == 'Y' || c == ' ') - return (1); - if (c == 'n' || c == 'N' || c == RUBOUT) - return (0); - if (c == ABORT_CHAR) - rl_abort (); - ding (); - } -} +/* Set to a character indicating the type of completion being performed + by rl_complete_internal, available for use by application completion + functions. */ +int rl_completion_type = 0; /* Up to this many items will be displayed in response to a possible-completions call. After that, we ask the user if @@ -206,6 +169,9 @@ int rl_completion_query_items = 100; in the shell, i.e. " \t\n\"\\'`@$><=" */ char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{("; +/* List of basic quoting characters. */ +char *rl_basic_quote_characters = "\"'"; + /* The list of characters that signal a break between words for rl_complete_internal. The default list is the contents of rl_basic_word_break_characters. */ @@ -217,6 +183,9 @@ char *rl_completer_word_break_characters = (char *)NULL; unless they also appear within this list. */ char *rl_completer_quote_characters = (char *)NULL; +/* List of characters that should be quoted in filenames by the completer. */ +char *rl_filename_quote_characters = (char *)NULL; + /* List of characters that are word break characters, but should be left in TEXT when it is passed to the completion function. The shell uses this to help determine what kind of completing to do. */ @@ -232,7 +201,7 @@ int rl_filename_completion_desired = 0; /* Non-zero means that the results of the matches are to be quoted using double quotes (or an application-specific quoting mechanism) if the - filename contains any characters in rl_word_break_chars. This is + filename contains any characters in rl_filename_quote_chars. This is ALWAYS non-zero on entry, and can only be changed within a completion entry finder function. */ int rl_filename_quoting_desired = 1; @@ -248,43 +217,80 @@ int rl_filename_quoting_desired = 1; to implement FIGNORE a la SunOS csh. */ Function *rl_ignore_some_completions_function = (Function *)NULL; -#if defined (SHELL) -/* A function to strip quotes that are not protected by backquotes. It - allows single quotes to appear within double quotes, and vice versa. - It should be smarter. It's fairly shell-specific, hence the SHELL - definition wrapper. */ -static char * -_delete_quotes (text) - char *text; +/* Set to a function to quote a filename in an application-specific fashion. + Called with the text to quote, the type of match found (single or multiple) + and a pointer to the quoting character to be used, which the function can + reset if desired. */ +CPFunction *rl_filename_quoting_function = rl_quote_filename; + +/* Function to call to remove quoting characters from a filename. Called + before completion is attempted, so the embedded quotes do not interfere + with matching names in the file system. Readline doesn't do anything + with this; it's set only by applications. */ +CPFunction *rl_filename_dequoting_function = (CPFunction *)NULL; + +/* Function to call to decide whether or not a word break character is + quoted. If a character is quoted, it does not break words for the + completer. */ +Function *rl_char_is_quoted_p = (Function *)NULL; + +/* Character appended to completed words when at the end of the line. The + default is a space. */ +int rl_completion_append_character = ' '; + +/* If non-zero, inhibit completion (temporarily). */ +int rl_inhibit_completion; + +/* Complete the word at or before point. You have supplied the function + that does the initial simple matching selection algorithm (see + completion_matches ()). The default is to do filename completion. */ +int +rl_complete (ignore, invoking_key) + int ignore, invoking_key; +{ + if (rl_inhibit_completion) + return (rl_insert (ignore, invoking_key)); + else if (rl_last_func == rl_complete && !completion_changed_buffer) + return (rl_complete_internal ('?')); + else if (_rl_complete_show_all) + return (rl_complete_internal ('!')); + else + return (rl_complete_internal (TAB)); +} + +/* List the possible completions. See description of rl_complete (). */ +int +rl_possible_completions (ignore, invoking_key) + int ignore, invoking_key; +{ + return (rl_complete_internal ('?')); +} + +int +rl_insert_completions (ignore, invoking_key) + int ignore, invoking_key; { - char *ret, *p, *r; - int l, quoted; + return (rl_complete_internal ('*')); +} - l = strlen (text); - ret = xmalloc (l + 1); - for (quoted = 0, p = text, r = ret; p && *p; p++) +/* The user must press "y" or "n". Non-zero return means "y" pressed. */ +static int +get_y_or_n () +{ + int c; + + for (;;) { - /* Allow backslash-quoted characters to pass through unscathed. */ - if (*p == '\\') - continue; - /* Close quote. */ - if (quoted && *p == quoted) - { - quoted = 0; - continue; - } - /* Open quote. */ - if (quoted == 0 && (*p == '\'' || *p == '"')) - { - quoted = *p; - continue; - } - *r++ = *p; + c = rl_read_key (); + if (c == 'y' || c == 'Y' || c == ' ') + return (1); + if (c == 'n' || c == 'N' || c == RUBOUT) + return (0); + if (c == ABORT_CHAR) + _rl_abort_internal (); + ding (); } - *r = '\0'; - return ret; } -#endif /* SHELL */ /* Return the portion of PATHNAME that should be output when listing possible completions. If we are hacking filename completion, we @@ -294,20 +300,16 @@ static char * printable_part (pathname) char *pathname; { - char *temp = (char *)NULL; - - if (rl_filename_completion_desired) - temp = strrchr (pathname, '/'); + char *temp; - if (!temp) - return (pathname); - else - return (++temp); + temp = rl_filename_completion_desired ? strrchr (pathname, '/') : (char *)NULL; + return (temp ? ++temp : pathname); } /* Output TO_PRINT to rl_outstream. If VISIBLE_STATS is defined and we are using it, check for and output a single character for `special' filenames. Return 1 if we printed an extension character, 0 if not. */ + #define PUTX(c) \ if (CTRL_CHAR (c)) \ { \ @@ -315,12 +317,12 @@ printable_part (pathname) putc (UNCTRL (c), rl_outstream); \ } \ else if (c == RUBOUT) \ - { \ - putc ('^', rl_outstream); \ - putc ('?', rl_outstream); \ - } \ + { \ + putc ('^', rl_outstream); \ + putc ('?', rl_outstream); \ + } \ else \ - putc (c, rl_outstream) + putc (c, rl_outstream) static int print_filename (to_print, full_pathname) @@ -336,14 +338,14 @@ print_filename (to_print, full_pathname) return 0; #else char *s, c, *new_full_pathname; - int extension_char = 0, slen, tlen; + int extension_char, slen, tlen; for (s = to_print; *s; s++) { PUTX (*s); - } + } - if (rl_filename_completion_desired && rl_visible_stats) + if (rl_filename_completion_desired && rl_visible_stats) { /* If to_print != full_pathname, to_print is the basename of the path passed. In this case, we try to expand the directory @@ -386,139 +388,160 @@ print_filename (to_print, full_pathname) #endif /* VISIBLE_STATS */ } -/* Complete the word at or before point. - WHAT_TO_DO says what to do with the completion. - `?' means list the possible completions. - TAB means do standard completion. - `*' means insert all of the possible completions. - `!' means to do standard completion, and list all possible completions if - there is more than one. */ -rl_complete_internal (what_to_do) - int what_to_do; +static char * +rl_quote_filename (s, rtype, qcp) + char *s; + int rtype; + char *qcp; { - char **matches; - Function *our_func; - int start, scan, end, delimiter = 0, pass_next; - char *text, *saved_line_buffer; - char *replacement; - char quote_char = '\0'; - int found_quote = 0; - - if (rl_line_buffer) - saved_line_buffer = savestring (rl_line_buffer); - else - saved_line_buffer = (char *)NULL; - - if (rl_completion_entry_function) - our_func = rl_completion_entry_function; - else - our_func = (Function *)filename_completion_function; + char *r; + + r = xmalloc (strlen (s) + 2); + *r = *rl_completer_quote_characters; + strcpy (r + 1, s); + if (qcp) + *qcp = *rl_completer_quote_characters; + return r; +} - /* Only the completion entry function can change these. */ - rl_filename_completion_desired = 0; - rl_filename_quoting_desired = 1; +/* Find the bounds of the current word for completion purposes, and leave + rl_point set to the end of the word. This function skips quoted + substrings (characters between matched pairs of characters in + rl_completer_quote_characters. First we try to find an unclosed + quoted substring on which to do matching. If one is not found, we use + the word break characters to find the boundaries of the current word. + We call an application-specific function to decide whether or not a + particular word break character is quoted; if that function returns a + non-zero result, the character does not break a word. This function + returns the opening quote character if we found an unclosed quoted + substring, '\0' otherwise. FP, if non-null, is set to a value saying + which (shell-like) quote characters we found (single quote, double + quote, or backslash) anywhere in the string. DP, if non-null, is set to + the value of the delimiter character that caused a word break. */ + +static char +find_completion_word (fp, dp) + int *fp, *dp; +{ + int scan, end, found_quote, delimiter, pass_next, isbrk; + char quote_char; - /* We now look backwards for the start of a filename/variable word. */ end = rl_point; + found_quote = delimiter = 0; + quote_char = '\0'; - if (rl_point) + if (rl_completer_quote_characters) { - if (rl_completer_quote_characters) + /* We have a list of characters which can be used in pairs to + quote substrings for the completer. Try to find the start + of an unclosed quoted substring. */ + /* FOUND_QUOTE is set so we know what kind of quotes we found. */ + for (scan = pass_next = 0; scan < end; scan++) { - /* We have a list of characters which can be used in pairs to - quote substrings for the completer. Try to find the start - of an unclosed quoted substring. */ - /* FOUND_QUOTE is set so we know what kind of quotes we found. */ - for (scan = pass_next = 0; scan < end; scan++) + if (pass_next) { - if (pass_next) - { - pass_next = 0; - continue; - } + pass_next = 0; + continue; + } - if (rl_line_buffer[scan] == '\\') - { - pass_next = 1; - found_quote |= 4; - continue; - } + if (rl_line_buffer[scan] == '\\') + { + pass_next = 1; + found_quote |= RL_QF_BACKSLASH; + continue; + } - if (quote_char != '\0') - { - /* Ignore everything until the matching close quote char. */ - if (rl_line_buffer[scan] == quote_char) - { - /* Found matching close. Abandon this substring. */ - quote_char = '\0'; - rl_point = end; - } - } - else if (strchr (rl_completer_quote_characters, rl_line_buffer[scan])) + if (quote_char != '\0') + { + /* Ignore everything until the matching close quote char. */ + if (rl_line_buffer[scan] == quote_char) { - /* Found start of a quoted substring. */ - quote_char = rl_line_buffer[scan]; - rl_point = scan + 1; - /* Shell-like quoting conventions. */ - if (quote_char == '\'') - found_quote |= 1; - else if (quote_char == '"') - found_quote |= 2; + /* Found matching close. Abandon this substring. */ + quote_char = '\0'; + rl_point = end; } } + else if (strchr (rl_completer_quote_characters, rl_line_buffer[scan])) + { + /* Found start of a quoted substring. */ + quote_char = rl_line_buffer[scan]; + rl_point = scan + 1; + /* Shell-like quoting conventions. */ + if (quote_char == '\'') + found_quote |= RL_QF_SINGLE_QUOTE; + else if (quote_char == '"') + found_quote |= RL_QF_DOUBLE_QUOTE; + } } + } - if (rl_point == end && quote_char == '\0') + if (rl_point == end && quote_char == '\0') + { + /* We didn't find an unclosed quoted substring upon which to do + completion, so use the word break characters to find the + substring on which to complete. */ + while (--rl_point) { - int quoted = 0; - /* We didn't find an unclosed quoted substring upon which to do - completion, so use the word break characters to find the - substring on which to complete. */ - while (--rl_point) - { - scan = rl_line_buffer[rl_point]; + scan = rl_line_buffer[rl_point]; - if (strchr (rl_completer_word_break_characters, scan) == 0) - continue; + if (strchr (rl_completer_word_break_characters, scan) == 0) + continue; -#if defined (SHELL) - /* Don't let word break characters in quoted substrings break - words for the completer. */ - if (found_quote && char_is_quoted (rl_line_buffer, rl_point)) - continue; -#endif /* SHELL */ - - /* Convoluted code, but it avoids an n^2 algorithm with calls - to char_is_quoted. */ - break; - } - } + /* Call the application-specific function to tell us whether + this word break character is quoted and should be skipped. */ + if (rl_char_is_quoted_p && found_quote && + (*rl_char_is_quoted_p) (rl_line_buffer, rl_point)) + continue; - /* If we are at an unquoted word break, then advance past it. */ - scan = rl_line_buffer[rl_point]; -#if defined (SHELL) - if ((found_quote == 0 || char_is_quoted (rl_line_buffer, rl_point) == 0) && - strchr (rl_completer_word_break_characters, scan)) -#else - if (strchr (rl_completer_word_break_characters, scan)) -#endif - { - /* If the character that caused the word break was a quoting - character, then remember it as the delimiter. */ - if (strchr ("\"'", scan) && (end - rl_point) > 1) - delimiter = scan; - - /* If the character isn't needed to determine something special - about what kind of completion to perform, then advance past it. */ - if (!rl_special_prefixes || strchr (rl_special_prefixes, scan) == 0) - rl_point++; + /* Convoluted code, but it avoids an n^2 algorithm with calls + to char_is_quoted. */ + break; } } - /* At this point, we know we have an open quote if quote_char != '\0'. */ - start = rl_point; - rl_point = end; - text = rl_copy_text (start, end); + /* If we are at an unquoted word break, then advance past it. */ + scan = rl_line_buffer[rl_point]; + + /* If there is an application-specific function to say whether or not + a character is quoted and we found a quote character, let that + function decide whether or not a character is a word break, even + if it is found in rl_completer_word_break_characters. */ + if (rl_char_is_quoted_p) + isbrk = (found_quote == 0 || + (*rl_char_is_quoted_p) (rl_line_buffer, rl_point) == 0) && + strchr (rl_completer_word_break_characters, scan) != 0; + else + isbrk = strchr (rl_completer_word_break_characters, scan) != 0; + + if (isbrk) + { + /* If the character that caused the word break was a quoting + character, then remember it as the delimiter. */ + if (rl_basic_quote_characters && strchr (rl_basic_quote_characters, scan) && (end - rl_point) > 1) + delimiter = scan; + + /* If the character isn't needed to determine something special + about what kind of completion to perform, then advance past it. */ + if (rl_special_prefixes == 0 || strchr (rl_special_prefixes, scan) == 0) + rl_point++; + } + + if (fp) + *fp = found_quote; + if (dp) + *dp = delimiter; + + return (quote_char); +} + +static char ** +gen_completion_matches (text, start, end, our_func, found_quote, quote_char) + char *text; + int start, end; + Function *our_func; + int found_quote, quote_char; +{ + char **matches, *temp; /* If the user wants to TRY to complete, but then wants to give up and use the default completion function, they set the @@ -530,424 +553,524 @@ rl_complete_internal (what_to_do) if (matches || rl_attempted_completion_over) { rl_attempted_completion_over = 0; - our_func = (Function *)NULL; - goto after_usual_completion; + return (matches); } } -#if defined (SHELL) /* Beware -- we're stripping the quotes here. Do this only if we know - we are doing filename completion. */ - if (found_quote && our_func == (Function *)filename_completion_function) + we are doing filename completion and the application has defined a + filename dequoting function. */ + temp = (char *)NULL; + if (found_quote && our_func == (Function *)filename_completion_function && + rl_filename_dequoting_function) { /* delete single and double quotes */ - replacement = _delete_quotes (text); - free (text); - text = replacement; - replacement = (char *)0; + temp = (*rl_filename_dequoting_function) (text, quote_char); + text = temp; /* not freeing text is not a memory leak */ } -#endif /* SHELL */ matches = completion_matches (text, our_func); + FREE (temp); + return matches; +} - after_usual_completion: - free (text); +/* Filter out duplicates in MATCHES. This frees up the strings in + MATCHES. */ +static char ** +remove_duplicate_matches (matches) + char **matches; +{ + char *lowest_common; + int i, j, newlen; + char dead_slot; + char **temp_array; - if (!matches) - ding (); - else - { - register int i; - int should_quote; + /* Sort the items. */ + for (i = 0; matches[i]; i++) + ; + + /* Sort the array without matches[0], since we need it to + stay in place no matter what. */ + if (i) + qsort (matches+1, i-1, sizeof (char *), _rl_qsort_string_compare); + + /* Remember the lowest common denominator for it may be unique. */ + lowest_common = savestring (matches[0]); - /* It seems to me that in all the cases we handle we would like - to ignore duplicate possiblilities. Scan for the text to - insert being identical to the other completions. */ - if (rl_ignore_completion_duplicates) + for (i = newlen = 0; matches[i + 1]; i++) + { + if (strcmp (matches[i], matches[i + 1]) == 0) { - char *lowest_common; - int j, newlen = 0; - char dead_slot; - char **temp_array; - - /* Sort the items. */ - /* It is safe to sort this array, because the lowest common - denominator found in matches[0] will remain in place. */ - for (i = 0; matches[i]; i++) - ; - /* Try sorting the array without matches[0], since we need it to - stay in place no matter what. */ - if (i) - qsort (matches+1, i-1, sizeof (char *), compare_strings); + free (matches[i]); + matches[i] = (char *)&dead_slot; + } + else + newlen++; + } - /* Remember the lowest common denominator for it may be unique. */ - lowest_common = savestring (matches[0]); + /* We have marked all the dead slots with (char *)&dead_slot. + Copy all the non-dead entries into a new array. */ + temp_array = (char **)xmalloc ((3 + newlen) * sizeof (char *)); + for (i = j = 1; matches[i]; i++) + { + if (matches[i] != (char *)&dead_slot) + temp_array[j++] = matches[i]; + } + temp_array[j] = (char *)NULL; - for (i = 0; matches[i + 1]; i++) - { - if (strcmp (matches[i], matches[i + 1]) == 0) - { - free (matches[i]); - matches[i] = (char *)&dead_slot; - } - else - newlen++; - } + if (matches[0] != (char *)&dead_slot) + free (matches[0]); - /* We have marked all the dead slots with (char *)&dead_slot. - Copy all the non-dead entries into a new array. */ - temp_array = (char **)xmalloc ((3 + newlen) * sizeof (char *)); - for (i = j = 1; matches[i]; i++) - { - if (matches[i] != (char *)&dead_slot) - temp_array[j++] = matches[i]; - } - temp_array[j] = (char *)NULL; + /* Place the lowest common denominator back in [0]. */ + temp_array[0] = lowest_common; + + /* If there is one string left, and it is identical to the + lowest common denominator, then the LCD is the string to + insert. */ + if (j == 2 && strcmp (temp_array[0], temp_array[1]) == 0) + { + free (temp_array[1]); + temp_array[1] = (char *)NULL; + } + return (temp_array); +} - if (matches[0] != (char *)&dead_slot) - free (matches[0]); - free (matches); +static void +display_matches (matches) + char **matches; +{ + int len, count, limit, max, printed_len; + int i, j, k, l; + char *temp; - matches = temp_array; + /* Move to the last visible line of a possibly-multiple-line command. */ + _rl_move_vert (_rl_vis_botlin); - /* Place the lowest common denominator back in [0]. */ - matches[0] = lowest_common; + /* Handle simple case first. What if there is only one answer? */ + if (matches[1] == 0) + { + temp = printable_part (matches[0]); + crlf (); + print_filename (temp, matches[0]); + crlf (); +#if 0 + rl_on_new_line (); +#else + rl_forced_update_display (); + rl_display_fixed = 1; +#endif + return; + } - /* If there is one string left, and it is identical to the - lowest common denominator, then the LCD is the string to - insert. */ - if (j == 2 && strcmp (matches[0], matches[1]) == 0) - { - free (matches[1]); - matches[1] = (char *)NULL; - } + /* There is more than one answer. Find out how many there are, + and find the maximum printed length of a single entry. */ + for (max = 0, i = 1; matches[i]; i++) + { + temp = printable_part (matches[i]); + len = strlen (temp); + + if (len > max) + max = len; + } + + len = i - 1; + + /* If there are many items, then ask the user if she really wants to + see them all. */ + if (len >= rl_completion_query_items) + { + crlf (); + fprintf (rl_outstream, "Display all %d possibilities? (y or n)", len); + fflush (rl_outstream); + if (get_y_or_n () == 0) + { + crlf (); +#if 0 + rl_on_new_line (); +#else + rl_forced_update_display (); + rl_display_fixed = 1; +#endif + return; } + } + + /* How many items of MAX length can we fit in the screen window? */ + max += 2; + limit = screenwidth / max; + if (limit != 1 && (limit * max == screenwidth)) + limit--; + + /* Avoid a possible floating exception. If max > screenwidth, + limit will be 0 and a divide-by-zero fault will result. */ + if (limit == 0) + limit = 1; + + /* How many iterations of the printing loop? */ + count = (len + (limit - 1)) / limit; - switch (what_to_do) + /* Watch out for special case. If LEN is less than LIMIT, then + just do the inner printing loop. + 0 < len <= limit implies count = 1. */ + + /* Sort the items if they are not already sorted. */ + if (rl_ignore_completion_duplicates == 0) + qsort (matches + 1, len, sizeof (char *), _rl_qsort_string_compare); + + /* Print the sorted items, up-and-down alphabetically, like ls. */ + crlf (); + + for (i = 1; i <= count; i++) + { + for (j = 0, l = i; j < limit; j++) { - case TAB: - case '!': - /* If we are matching filenames, then here is our chance to - do clever processing by re-examining the list. Call the - ignore function with the array as a parameter. It can - munge the array, deleting matches as it desires. */ - if (rl_ignore_some_completions_function && - our_func == (Function *)filename_completion_function) + if (l > len || matches[l] == 0) + break; + else { - (void)(*rl_ignore_some_completions_function)(matches); - if (matches == 0 || matches[0] == 0) - { - if (matches) - free (matches); - ding (); - return; - } + temp = printable_part (matches[l]); + printed_len = strlen (temp) + print_filename (temp, matches[l]); + + if (j + 1 < limit) + for (k = 0; k < max - printed_len; k++) + putc (' ', rl_outstream); } + l += count; + } + crlf (); + } - /* If we are doing completion on quoted substrings, and any matches - contain any of the completer_word_break_characters, then auto- - matically prepend the substring with a quote character (just pick - the first one from the list of such) if it does not already begin - with a quote string. FIXME: Need to remove any such automatically - inserted quote character when it no longer is necessary, such as - if we change the string we are completing on and the new set of - matches don't require a quoted substring. */ - replacement = matches[0]; - - should_quote = matches[0] && rl_completer_quote_characters && - rl_filename_completion_desired && - rl_filename_quoting_desired; - - if (should_quote) -#if defined (SHELL) - should_quote = should_quote && (!quote_char || quote_char == '"'); +#if 0 + rl_on_new_line (); #else - should_quote = should_quote && !quote_char; + rl_forced_update_display (); + rl_display_fixed = 1; #endif +} - if (should_quote) - { - int do_replace; - - do_replace = NO_MATCH; +static void +insert_text (text, start, end) + char *text; + int start, end; +{ + rl_begin_undo_group (); + rl_delete_text (start, end + 1); + rl_point = start; + rl_insert_text (text); + rl_end_undo_group (); +} - /* If there is a single match, see if we need to quote it. - This also checks whether the common prefix of several - matches needs to be quoted. If the common prefix should - not be checked, add !matches[1] to the if clause. */ - should_quote = rl_strpbrk (matches[0], rl_completer_word_break_characters) != 0; +static char * +make_quoted_replacement (match, mtype, quote_char) + char *match; + int mtype, quote_char; +{ + int should_quote, do_replace; + char *replacement, qc; + + /* If we are doing completion on quoted substrings, and any matches + contain any of the completer_word_break_characters, then auto- + matically prepend the substring with a quote character (just pick + the first one from the list of such) if it does not already begin + with a quote string. FIXME: Need to remove any such automatically + inserted quote character when it no longer is necessary, such as + if we change the string we are completing on and the new set of + matches don't require a quoted substring. */ + replacement = match; + + should_quote = match && rl_completer_quote_characters && + rl_filename_completion_desired && + rl_filename_quoting_desired; + + if (should_quote) #if defined (SHELL) - should_quote = should_quote || rl_strpbrk (matches[0], "#$`?*[!") != 0; + should_quote = should_quote && (!quote_char || quote_char == '"' || quote_char == '\''); +#else + should_quote = should_quote && !quote_char; #endif - if (should_quote) - do_replace = matches[1] ? MULT_MATCH : SINGLE_MATCH; - - if (do_replace != NO_MATCH) - { -#if defined (SHELL) - /* Quote the replacement, since we found an - embedded word break character in a potential - match. */ - char *rtext, *mtext; - int rlen; - extern char *double_quote (); /* in builtins/common.c */ - - /* If DO_REPLACE == MULT_MATCH, it means that there is - more than one match. In this case, we do not add - the closing quote or attempt to perform tilde - expansion. If DO_REPLACE == SINGLE_MATCH, we try - to perform tilde expansion, because double quotes - inhibit tilde expansion by the shell. */ - - mtext = matches[0]; - if (mtext[0] == '~' && do_replace == SINGLE_MATCH) - mtext = tilde_expand (matches[0]); - rtext = double_quote (mtext); - if (mtext != matches[0]) - free (mtext); - - rlen = strlen (rtext); - replacement = xmalloc (rlen + 1); - /* If we're completing on a quoted string where the user - has already supplied the opening quote, we don't want - the quote in the replacement text, and we reset - QUOTE_CHAR to 0 to avoid an extra closing quote. */ - if (quote_char == '"') - { - strcpy (replacement, rtext + 1); - rlen--; - quote_char = 0; - } - else - strcpy (replacement, rtext); - if (do_replace == MULT_MATCH) - replacement[rlen - 1] = '\0'; - free (rtext); -#else /* !SHELL */ - /* Found an embedded word break character in a potential - match, so we need to prepend a quote character if we - are replacing the completion string. */ - replacement = xmalloc (strlen (matches[0]) + 2); - quote_char = *rl_completer_quote_characters; - *replacement = quote_char; - strcpy (replacement + 1, matches[0]); -#endif /* SHELL */ - } - } + if (should_quote) + { + /* If there is a single match, see if we need to quote it. + This also checks whether the common prefix of several + matches needs to be quoted. */ + should_quote = rl_strpbrk (match, rl_filename_quote_characters) != 0; - if (replacement) + do_replace = should_quote ? mtype : NO_MATCH; + if (do_replace != NO_MATCH) + { + /* Quote the replacement, since we found an embedded + word break character in a potential match. */ + if (rl_filename_quoting_function) { - rl_begin_undo_group (); - rl_delete_text (start, rl_point); - rl_point = start; - rl_insert_text (replacement); - rl_end_undo_group (); - if (replacement != matches[0]) - free (replacement); + qc = quote_char; /* must pass a (char *) to quoting function */ + replacement = (*rl_filename_quoting_function) + (match, do_replace, &qc); + quote_char = qc; } + } + } + return (replacement); +} - /* If there are more matches, ring the bell to indicate. - If this was the only match, and we are hacking files, - check the file to see if it was a directory. If so, - add a '/' to the name. If not, and we are at the end - of the line, then add a space. */ - if (matches[1]) - { - if (what_to_do == '!') - goto display_matches; /* XXX */ - else if (rl_editing_mode != vi_mode) - ding (); /* There are other matches remaining. */ - } - else - { - char temp_string[4]; - int temp_string_index = 0; +static void +insert_match (match, start, mtype, quote_char) + char *match; + int start, mtype, quote_char; +{ + char *replacement; - if (quote_char) - temp_string[temp_string_index++] = quote_char; + replacement = make_quoted_replacement (match, mtype, quote_char); - temp_string[temp_string_index++] = delimiter ? delimiter : ' '; - temp_string[temp_string_index++] = '\0'; + /* Now insert the match. */ + if (replacement) + { + /* Don't double an opening quote character. */ + if (quote_char && start && rl_line_buffer[start - 1] == quote_char && + replacement[0] == quote_char) + start--; + insert_text (replacement, start, rl_point - 1); + if (replacement != match) + free (replacement); + } +} - if (rl_filename_completion_desired) - { - struct stat finfo; - char *filename = tilde_expand (matches[0]); - - if ((stat (filename, &finfo) == 0) && S_ISDIR (finfo.st_mode)) - { - if (rl_line_buffer[rl_point] != '/') - rl_insert_text ("/"); - } - else - { - if (rl_point == rl_end) - rl_insert_text (temp_string); - } - free (filename); - } - else - { - if (rl_point == rl_end) - rl_insert_text (temp_string); - } - } - break; +/* Append any necessary closing quote and a separator character to the + just-inserted match. If the user has specified that directories + should be marked by a trailing `/', append one of those instead. The + default trailing character */ +static void +append_to_match (text, delimiter, quote_char) + char *text; + int delimiter, quote_char; +{ + char temp_string[4], *filename; + int temp_string_index; + struct stat finfo; - case '*': - { - int i = 1; - - rl_begin_undo_group (); - rl_delete_text (start, rl_point); - rl_point = start; - if (matches[1]) - { - while (matches[i]) - { - rl_insert_text (matches[i++]); - rl_insert_text (" "); - } - } - else - { - rl_insert_text (matches[0]); - rl_insert_text (" "); - } - rl_end_undo_group (); - } - break; + temp_string_index = 0; + if (quote_char && rl_point && rl_line_buffer[rl_point - 1] != quote_char) + temp_string[temp_string_index++] = quote_char; - case '?': - { - int len, count, limit, max; - int j, k, l; - - /* Handle simple case first. What if there is only one answer? */ - if (!matches[1]) - { - char *temp; - - temp = printable_part (matches[0]); - crlf (); - print_filename (temp, matches[0]); - crlf (); - goto restart; - } - - /* There is more than one answer. Find out how many there are, - and find out what the maximum printed length of a single entry - is. */ - display_matches: - for (max = 0, i = 1; matches[i]; i++) - { - char *temp; - int name_length; - - temp = printable_part (matches[i]); - name_length = strlen (temp); - - if (name_length > max) - max = name_length; - } - - len = i - 1; - - /* If there are many items, then ask the user if she - really wants to see them all. */ - if (len >= rl_completion_query_items) - { - crlf (); - fprintf (rl_outstream, - "There are %d possibilities. Do you really", len); - crlf (); - fprintf (rl_outstream, "wish to see them all? (y or n)"); - fflush (rl_outstream); - if (!get_y_or_n ()) - { - crlf (); - goto restart; - } - } - - /* How many items of MAX length can we fit in the screen window? */ - max += 2; - limit = screenwidth / max; - if (limit != 1 && (limit * max == screenwidth)) - limit--; - - /* Avoid a possible floating exception. If max > screenwidth, - limit will be 0 and a divide-by-zero fault will result. */ - if (limit == 0) - limit = 1; - - /* How many iterations of the printing loop? */ - count = (len + (limit - 1)) / limit; - - /* Watch out for special case. If LEN is less than LIMIT, then - just do the inner printing loop. - 0 < len <= limit implies count = 1. */ - - /* Sort the items if they are not already sorted. */ - if (!rl_ignore_completion_duplicates) - qsort (matches + 1, len - 1, sizeof (char *), compare_strings); - - /* Print the sorted items, up-and-down alphabetically, like - ls might. */ - crlf (); - - for (i = 1; i <= count; i++) - { - for (j = 0, l = i; j < limit; j++) - { - if (l > len || !matches[l]) - break; - else - { - char *temp; - int printed_length; - - temp = printable_part (matches[l]); - printed_length = strlen (temp); - printed_length += print_filename (temp, matches[l]); - - if (j + 1 < limit) - { - for (k = 0; k < max - printed_length; k++) - putc (' ', rl_outstream); - } - } - l += count; - } - crlf (); - } - restart: - - rl_on_new_line (); - } - break; + if (delimiter) + temp_string[temp_string_index++] = delimiter; + else if (rl_completion_append_character) + temp_string[temp_string_index++] = rl_completion_append_character; + + temp_string[temp_string_index++] = '\0'; + + if (rl_filename_completion_desired) + { + filename = tilde_expand (text); + if (stat (filename, &finfo) == 0 && S_ISDIR (finfo.st_mode)) + { + if (_rl_complete_mark_directories && rl_line_buffer[rl_point] != '/') + rl_insert_text ("/"); + } + else + { + if (rl_point == rl_end) + rl_insert_text (temp_string); + } + free (filename); + } + else + { + if (rl_point == rl_end) + rl_insert_text (temp_string); + } +} - default: - fprintf (stderr, "\r\nreadline: bad value for what_to_do in rl_complete\n"); - abort (); +static void +insert_all_matches (matches, point, quote_char) + char **matches; + int point, quote_char; +{ + int i; + char *rp; + + rl_begin_undo_group (); + /* remove any opening quote character; make_quoted_replacement will add + it back. */ + if (quote_char && point && rl_line_buffer[point - 1] == quote_char) + point--; + rl_delete_text (point, rl_point); + rl_point = point; + + if (matches[1]) + { + for (i = 1; matches[i]; i++) + { + rp = make_quoted_replacement (matches[i], SINGLE_MATCH, quote_char); + rl_insert_text (rp); + rl_insert_text (" "); + if (rp != matches[i]) + free (rp); } + } + else + { + rp = make_quoted_replacement (matches[0], SINGLE_MATCH, quote_char); + rl_insert_text (rp); + rl_insert_text (" "); + if (rp != matches[0]) + free (rp); + } + rl_end_undo_group (); +} + +/* Complete the word at or before point. + WHAT_TO_DO says what to do with the completion. + `?' means list the possible completions. + TAB means do standard completion. + `*' means insert all of the possible completions. + `!' means to do standard completion, and list all possible completions if + there is more than one. */ +int +rl_complete_internal (what_to_do) + int what_to_do; +{ + char **matches, **temp_matches; + Function *our_func; + int start, end, delimiter, found_quote, nmatch, i; + char *text, *saved_line_buffer, *t; + char quote_char; + + saved_line_buffer = rl_line_buffer ? savestring (rl_line_buffer) : (char *)NULL; + + our_func = rl_completion_entry_function + ? rl_completion_entry_function + : (Function *)filename_completion_function; + + /* Only the completion entry function can change these. */ + rl_filename_completion_desired = 0; + rl_filename_quoting_desired = 1; + + rl_completion_type = what_to_do; + + /* We now look backwards for the start of a filename/variable word. */ + end = rl_point; + + found_quote = delimiter = 0; + quote_char = '\0'; + + if (rl_point) + /* This (possibly) changes rl_point. If it returns a non-zero char, + we know we have an open quote. */ + quote_char = find_completion_word (&found_quote, &delimiter); + + start = rl_point; + rl_point = end; + + text = rl_copy_text (start, end); + matches = gen_completion_matches (text, start, end, our_func, found_quote, quote_char); + free (text); - for (i = 0; matches[i]; i++) - free (matches[i]); + if (matches == 0) + { + ding (); + FREE (saved_line_buffer); + return 0; + } + + /* It seems to me that in all the cases we handle we would like + to ignore duplicate possiblilities. Scan for the text to + insert being identical to the other completions. */ + if (rl_ignore_completion_duplicates) + { + temp_matches = remove_duplicate_matches (matches); free (matches); + matches = temp_matches; } - /* Check to see if the line has changed through all of this manipulation. */ - if (saved_line_buffer) + /* If we are matching filenames, then here is our chance to + do clever processing by re-examining the list. Call the + ignore function with the array as a parameter. It can + munge the array, deleting matches as it desires. */ + if (rl_ignore_some_completions_function && + our_func == (Function *)filename_completion_function) { - if (strcmp (rl_line_buffer, saved_line_buffer) != 0) - completion_changed_buffer = 1; + for (nmatch = 1; matches[nmatch]; nmatch++) + ; + (void)(*rl_ignore_some_completions_function) (matches); + if (matches == 0 || matches[0] == 0) + { + FREE (matches); + ding (); + FREE (saved_line_buffer); + return 0; + } else - completion_changed_buffer = 0; + { + /* If we removed some matches, recompute the common prefix. */ + for (i = 1; matches[i]; i++) + ; + if (i > 1 && i < nmatch) + { + t = matches[0]; + compute_lcd_of_matches (matches, i - 1, text); + FREE (t); + } + } + } + switch (what_to_do) + { + case TAB: + case '!': + /* Insert the first match with proper quoting. */ + if (*matches[0]) + insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, quote_char); + + /* If there are more matches, ring the bell to indicate. + If we are in vi mode, Posix.2 says to not ring the bell. + If the `show-all-if-ambiguous' variable is set, display + all the matches immediately. Otherwise, if this was the + only match, and we are hacking files, check the file to + see if it was a directory. If so, and the `mark-directories' + variable is set, add a '/' to the name. If not, and we + are at the end of the line, then add a space. */ + if (matches[1]) + { + if (what_to_do == '!') + { + display_matches (matches); + break; + } + else if (rl_editing_mode != vi_mode) + ding (); /* There are other matches remaining. */ + } + else + append_to_match (matches[0], delimiter, quote_char); + + break; + + case '*': + insert_all_matches (matches, start, quote_char); + break; + + case '?': + display_matches (matches); + break; + + default: + fprintf (stderr, "\r\nreadline: bad value %d for what_to_do in rl_complete\n", what_to_do); + ding (); + FREE (saved_line_buffer); + return 1; + } + + for (i = 0; matches[i]; i++) + free (matches[i]); + free (matches); + + /* Check to see if the line has changed through all of this manipulation. */ + if (saved_line_buffer) + { + completion_changed_buffer = strcmp (rl_line_buffer, saved_line_buffer) != 0; free (saved_line_buffer); } + return 0; } @@ -956,7 +1079,10 @@ rl_complete_internal (what_to_do) `@' for symbolic links `/' for directories `*' for executables - `=' for sockets */ + `=' for sockets + `|' for FIFOs + `%' for character special devices + `#' for block special devices */ static int stat_char (filename) char *filename; @@ -964,7 +1090,7 @@ stat_char (filename) struct stat finfo; int character, r; -#if defined (S_ISLNK) +#if defined (HAVE_LSTAT) && defined (S_ISLNK) r = lstat (filename, &finfo); #else r = stat (filename, &finfo); @@ -976,6 +1102,10 @@ stat_char (filename) character = 0; if (S_ISDIR (finfo.st_mode)) character = '/'; + else if (S_ISCHR (finfo.st_mode)) + character = '%'; + else if (S_ISBLK (finfo.st_mode)) + character = '#'; #if defined (S_ISLNK) else if (S_ISLNK (finfo.st_mode)) character = '@'; @@ -984,6 +1114,10 @@ stat_char (filename) else if (S_ISSOCK (finfo.st_mode)) character = '='; #endif /* S_ISSOCK */ +#if defined (S_ISFIFO) + else if (S_ISFIFO (finfo.st_mode)) + character = '|'; +#endif else if (S_ISREG (finfo.st_mode)) { if (access (filename, X_OK) == 0) @@ -993,20 +1127,6 @@ stat_char (filename) } #endif /* VISIBLE_STATS */ -/* Stupid comparison routine for qsort () ing strings. */ -static int -compare_strings (s1, s2) - char **s1, **s2; -{ - int result; - - result = **s1 - **s2; - if (result == 0) - result = strcmp (*s1, *s2); - - return result; -} - /* A completion function for usernames. TEXT contains a partial username preceded by a random character (usually `~'). */ @@ -1015,24 +1135,20 @@ username_completion_function (text, state) int state; char *text; { -#if defined (__GO32__) +#if defined (__GO32__) || defined (__WIN32__) return (char *)NULL; #else /* !__GO32__ */ static char *username = (char *)NULL; static struct passwd *entry; static int namelen, first_char, first_char_loc; + char *value; - if (!state) + if (state == 0) { - if (username) - free (username); + FREE (username); first_char = *text; - - if (first_char == '~') - first_char_loc = 1; - else - first_char_loc = 0; + first_char_loc = first_char == '~'; username = savestring (&text[first_char_loc]); namelen = strlen (username); @@ -1042,21 +1158,18 @@ username_completion_function (text, state) while (entry = getpwent ()) { /* Null usernames should result in all users as possible completions. */ - if (namelen == 0) - break; - else if ((username[0] == entry->pw_name[0]) && - (strncmp (username, entry->pw_name, namelen) == 0)) + if (namelen == 0 || (STREQN (username, entry->pw_name, namelen))) break; } - if (!entry) + if (entry == 0) { endpwent (); return ((char *)NULL); } else { - char *value = xmalloc (2 + strlen (entry->pw_name)); + value = xmalloc (2 + strlen (entry->pw_name)); *value = *text; @@ -1069,7 +1182,7 @@ username_completion_function (text, state) } #endif /* !__GO32__ */ } - + /* **************************************************************** */ /* */ /* Completion */ @@ -1079,6 +1192,70 @@ username_completion_function (text, state) /* Non-zero means that case is not significant in completion. */ int completion_case_fold = 0; +/* Find the common prefix of the list of matches, and put it into + matches[0]. */ +static int +compute_lcd_of_matches (match_list, matches, text) + char **match_list; + int matches; + char *text; +{ + register int i, c1, c2, si; + int low; /* Count of max-matched characters. */ + + /* If only one match, just use that. Otherwise, compare each + member of the list with the next, finding out where they + stop matching. */ + if (matches == 1) + { + match_list[0] = match_list[1]; + match_list[1] = (char *)NULL; + return 1; + } + + for (i = 1, low = 100000; i < matches; i++) + { + if (completion_case_fold) + { + for (si = 0; + (c1 = _rl_to_lower(match_list[i][si])) && + (c2 = _rl_to_lower(match_list[i + 1][si])); + si++) + if (c1 != c2) + break; + } + else + { + for (si = 0; + (c1 = match_list[i][si]) && + (c2 = match_list[i + 1][si]); + si++) + if (c1 != c2) + break; + } + + if (low > si) + low = si; + } + + /* If there were multiple matches, but none matched up to even the + first character, and the user typed something, use that as the + value of matches[0]. */ + if (low == 0 && text && *text) + { + match_list[0] = xmalloc (strlen (text) + 1); + strcpy (match_list[0], text); + } + else + { + match_list[0] = xmalloc (low + 1); + strncpy (match_list[0], match_list[1], low); + match_list[0][low] = '\0'; + } + + return matches; +} + /* Return an array of (char *) which is a list of completions for TEXT. If there are no completions, return a NULL pointer. The first entry in the returned array is the substitution for TEXT. @@ -1100,15 +1277,17 @@ completion_matches (text, entry_function) int match_list_size; /* The list of matches. */ - char **match_list = - (char **)xmalloc (((match_list_size = 10) + 1) * sizeof (char *)); + char **match_list; /* Number of matches actually found. */ - int matches = 0; + int matches; /* Temporary string binder. */ char *string; + matches = 0; + match_list_size = 10; + match_list = (char **)xmalloc ((match_list_size + 1) * sizeof (char *)); match_list[1] = (char *)NULL; while (string = (*entry_function) (text, matches)) @@ -1124,50 +1303,7 @@ completion_matches (text, entry_function) /* If there were any matches, then look through them finding out the lowest common denominator. That then becomes match_list[0]. */ if (matches) - { - register int i = 1; - int low = 100000; /* Count of max-matched characters. */ - - /* If only one match, just use that. */ - if (matches == 1) - { - match_list[0] = match_list[1]; - match_list[1] = (char *)NULL; - } - else - { - /* Otherwise, compare each member of the list with - the next, finding out where they stop matching. */ - - while (i < matches) - { - register int c1, c2, si; - - if (completion_case_fold) - { - for (si = 0; - (c1 = to_lower(match_list[i][si])) && - (c2 = to_lower(match_list[i + 1][si])); - si++) - if (c1 != c2) break; - } - else - { - for (si = 0; - (c1 = match_list[i][si]) && - (c2 = match_list[i + 1][si]); - si++) - if (c1 != c2) break; - } - - if (low > si) low = si; - i++; - } - match_list[0] = xmalloc (low + 1); - strncpy (match_list[0], match_list[1], low); - match_list[0][low] = '\0'; - } - } + compute_lcd_of_matches (match_list, matches, text); else /* There were no matches. */ { free (match_list); @@ -1190,20 +1326,20 @@ filename_completion_function (text, state) static char *dirname = (char *)NULL; static char *users_dirname = (char *)NULL; static int filename_len; - - struct dirent *entry = (struct dirent *)NULL; + char *temp; + int dirlen; + struct dirent *entry; /* If we don't have any state, then do some initialization. */ - if (!state) + if (state == 0) { - char *temp; - - if (dirname) free (dirname); - if (filename) free (filename); - if (users_dirname) free (users_dirname); + FREE (dirname); + FREE (filename); + FREE (users_dirname); filename = savestring (text); - if (!*text) text = "."; + if (*text == 0) + text = "."; dirname = savestring (text); temp = strrchr (dirname, '/'); @@ -1214,29 +1350,29 @@ filename_completion_function (text, state) *temp = '\0'; } else - strcpy (dirname, "."); + { + dirname[0] = '.'; + dirname[1] = '\0'; + } /* We aren't done yet. We also support the "~user" syntax. */ /* Save the version of the directory that the user typed. */ users_dirname = savestring (dirname); - { - char *temp_dirname; - int replace_dirname; - - temp_dirname = tilde_expand (dirname); - free (dirname); - dirname = temp_dirname; - - replace_dirname = 0; - if (rl_directory_completion_hook) - replace_dirname = (*rl_directory_completion_hook) (&dirname); - if (replace_dirname) - { - free (users_dirname); - users_dirname = savestring (dirname); - } - } + + if (*dirname == '~') + { + temp = tilde_expand (dirname); + free (dirname); + dirname = temp; + } + + if (rl_directory_completion_hook && (*rl_directory_completion_hook) (&dirname)) + { + free (users_dirname); + users_dirname = savestring (dirname); + } + directory = opendir (dirname); filename_len = strlen (filename); @@ -1251,14 +1387,16 @@ filename_completion_function (text, state) /* Now that we have some state, we can read the directory. */ + entry = (struct dirent *)NULL; while (directory && (entry = readdir (directory))) { /* Special case for no filename. All entries except "." and ".." match. */ - if (!filename_len) + if (filename_len == 0) { - if ((strcmp (entry->d_name, ".") != 0) && - (strcmp (entry->d_name, "..") != 0)) + if (entry->d_name[0] != '.' || + (entry->d_name[1] && + (entry->d_name[1] != '.' || entry->d_name[2]))) break; } else @@ -1272,7 +1410,7 @@ filename_completion_function (text, state) } } - if (!entry) + if (entry == 0) { if (directory) { @@ -1299,34 +1437,33 @@ filename_completion_function (text, state) } else { - char *temp; - /* dirname && (strcmp (dirname, ".") != 0) */ if (dirname && (dirname[0] != '.' || dirname[1])) { if (rl_complete_with_tilde_expansion && *users_dirname == '~') { - int dirlen = strlen (dirname); + dirlen = strlen (dirname); temp = xmalloc (2 + dirlen + D_NAMLEN (entry)); strcpy (temp, dirname); - /* Canonicalization cuts off any final slash present. We need - to add it back. */ + /* Canonicalization cuts off any final slash present. We + may need to add it back. */ if (dirname[dirlen - 1] != '/') { - temp[dirlen] = '/'; - temp[dirlen + 1] = '\0'; + temp[dirlen++] = '/'; + temp[dirlen] = '\0'; } } else { - temp = xmalloc (1 + strlen (users_dirname) + D_NAMLEN (entry)); + dirlen = strlen (users_dirname); + temp = xmalloc (1 + dirlen + D_NAMLEN (entry)); strcpy (temp, users_dirname); } - strcat (temp, entry->d_name); + strcpy (temp + dirlen, entry->d_name); /* strcat (temp, entry->d_name); */ } else - temp = (savestring (entry->d_name)); + temp = savestring (entry->d_name); return (temp); } @@ -1338,7 +1475,8 @@ rl_tilde_expand (ignore, key) int ignore, key; { register int start, end; - char *homedir; + char *homedir, *temp; + int len; end = rl_point; start = end - 1; @@ -1346,20 +1484,20 @@ rl_tilde_expand (ignore, key) if (rl_point == rl_end && rl_line_buffer[rl_point] == '~') { homedir = tilde_expand ("~"); - goto insert; + insert_text (homedir, start, end); + return (0); } else if (rl_line_buffer[start] != '~') { - for (; !whitespace (rl_line_buffer[start]) && start >= 0; start--); + for (; !whitespace (rl_line_buffer[start]) && start >= 0; start--) + ; start++; } end = start; do - { - end++; - } - while (!whitespace (rl_line_buffer[end]) && end < rl_end); + end++; + while (whitespace (rl_line_buffer[end]) == 0 && end < rl_end); if (whitespace (rl_line_buffer[end]) || end >= rl_end) end--; @@ -1369,9 +1507,6 @@ rl_tilde_expand (ignore, key) nothing. */ if (rl_line_buffer[start] == '~') { - char *temp; - int len; - len = end - start + 1; temp = xmalloc (len + 1); strncpy (temp, rl_line_buffer + start, len); @@ -1379,12 +1514,7 @@ rl_tilde_expand (ignore, key) homedir = tilde_expand (temp); free (temp); - insert: - rl_begin_undo_group (); - rl_delete_text (start, end + 1); - rl_point = start; - rl_insert_text (homedir); - rl_end_undo_group (); + insert_text (homedir, start, end); } return (0); @@ -1410,50 +1540,3 @@ rl_strpbrk (string1, string2) } return ((char *)NULL); } - -#if defined (STATIC_MALLOC) - -/* **************************************************************** */ -/* */ -/* xmalloc and xrealloc () */ -/* */ -/* **************************************************************** */ - -static void memory_error_and_abort (); - -static char * -xmalloc (bytes) - int bytes; -{ - char *temp = (char *)malloc (bytes); - - if (!temp) - memory_error_and_abort (); - return (temp); -} - -static char * -xrealloc (pointer, bytes) - char *pointer; - int bytes; -{ - char *temp; - - if (!pointer) - temp = (char *)malloc (bytes); - else - temp = (char *)realloc (pointer, bytes); - - if (!temp) - memory_error_and_abort (); - - return (temp); -} - -static void -memory_error_and_abort () -{ - fprintf (stderr, "readline: Out of virtual memory!\n"); - abort (); -} -#endif /* STATIC_MALLOC */ diff --git a/lib/readline/display.c b/lib/readline/display.c index daf736c..c0dff1f 100644 --- a/lib/readline/display.c +++ b/lib/readline/display.c @@ -22,7 +22,7 @@ #define READLINE_LIBRARY #if defined (HAVE_CONFIG_H) -# include "config.h" +# include <config.h> #endif #include <stdio.h> @@ -43,6 +43,9 @@ /* System-specific feature definitions and include files. */ #include "rldefs.h" +/* Termcap library stuff. */ +#include "tcap.h" + /* Some standard library routines. */ #include "readline.h" #include "history.h" @@ -55,20 +58,22 @@ extern char *strchr (), *strrchr (); imported from readline.c. */ extern char *rl_prompt; extern int readline_echoing_p; -extern char *term_clreol, *term_im, *term_ic, *term_ei, *term_DC; -/* Termcap variables. */ -extern char *term_up, *term_dc, *term_cr, *term_IC; -extern int screenheight, screenwidth, screenchars; -extern int terminal_can_insert, term_xn; - -extern void _rl_output_some_chars (); -extern int _rl_output_character_function (); extern int _rl_output_meta_chars; extern int _rl_horizontal_scroll_mode; extern int _rl_mark_modified_lines; extern int _rl_prefer_visible_bell; +/* Variables and functions imported from terminal.c */ +extern void _rl_output_some_chars (); +extern int _rl_output_character_function (); +extern int _rl_backspace (); + +extern char *term_clreol, *term_im, *term_ic, *term_ei, *term_DC; +extern char *term_up, *term_dc, *term_cr, *term_IC; +extern int screenheight, screenwidth, screenchars; +extern int terminal_can_insert, _rl_term_autowrap; + /* Pseudo-global functions (local to the readline library) exported by this file. */ void _rl_move_cursor_relative (), _rl_output_some_chars (); @@ -76,6 +81,9 @@ void _rl_move_vert (); static void update_line (), clear_to_eol (), space_to_eol (); static void delete_chars (), insert_some_chars (); +static void cr (); + +static int *inv_lbreaks, *vis_lbreaks; extern char *xmalloc (), *xrealloc (); @@ -110,10 +118,15 @@ extern char *xmalloc (), *xrealloc (); this function know that the display has been fixed by setting the RL_DISPLAY_FIXED variable. This is good for efficiency. */ +/* Application-specific redisplay function. */ +VFunction *rl_redisplay_function = rl_redisplay; + /* Global variables declared here. */ /* What YOU turn on when you have handled all redisplay yourself. */ int rl_display_fixed = 0; +int _rl_suppress_redisplay = 0; + /* The stuff that gets printed out before the actual text of the line. This is usually pointing to rl_prompt. */ char *rl_display_prompt = (char *)NULL; @@ -129,7 +142,7 @@ int _rl_vis_botlin = 0; /* Variables used only in this file. */ /* The last left edge of text that was displayed. This is used when doing horizontal scrolling. It shifts in thirds of a screenwidth. */ -static int last_lmargin = 0; +static int last_lmargin; /* The line display buffers. One is the line currently displayed on the screen. The other is the line about to be displayed. */ @@ -140,26 +153,32 @@ static char *invisible_line = (char *)NULL; static char msg_buf[128]; /* Non-zero forces the redisplay even if we thought it was unnecessary. */ -static int forced_display = 0; +static int forced_display; /* Default and initial buffer size. Can grow. */ static int line_size = 1024; -static char *last_prompt_string = (char *)NULL; static char *local_prompt, *local_prompt_prefix; static int visible_length, prefix_length; /* The number of invisible characters in the line currently being displayed on the screen. */ -static int visible_wrap_offset = 0; +static int visible_wrap_offset; + +/* static so it can be shared between rl_redisplay and update_line */ +static int wrap_offset; + +/* The index of the last invisible_character in the prompt string. */ +static int last_invisible; /* The length (buffer offset) of the first line of the last (possibly multi-line) buffer displayed on the screen. */ -static int visible_first_line_len = 0; +static int visible_first_line_len; /* Expand the prompt string S and return the number of visible characters in *LP, if LP is not null. This is currently more-or-less - a placeholder for expansion. */ + a placeholder for expansion. LIP, if non-null is a place to store the + index of the last invisible character in ther eturned string. */ /* Current implementation: \001 (^A) start non-visible characters @@ -169,12 +188,12 @@ static int visible_first_line_len = 0; \002 are assumed to be `visible'. */ static char * -expand_prompt (pmt, lp) +expand_prompt (pmt, lp, lip) char *pmt; - int *lp; + int *lp, *lip; { char *r, *ret, *p; - int l, rl, ignoring; + int l, rl, last, ignoring; /* Short-circuit if we can. */ if (strchr (pmt, RL_PROMPT_START_IGNORE) == 0) @@ -185,10 +204,10 @@ expand_prompt (pmt, lp) return r; } - l = pmt ? strlen (pmt) : 0; + l = strlen (pmt); r = ret = xmalloc (l + 1); - for (rl = ignoring = 0, p = pmt; p && *p; p++) + for (rl = ignoring = last = 0, p = pmt; p && *p; p++) { /* This code strips the invisible character string markers RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */ @@ -200,6 +219,7 @@ expand_prompt (pmt, lp) else if (ignoring && *p == RL_PROMPT_END_IGNORE) { ignoring = 0; + last = r - ret - 1; continue; } else @@ -213,6 +233,8 @@ expand_prompt (pmt, lp) *r = '\0'; if (lp) *lp = rl; + if (lip) + *lip = last; return ret; } @@ -246,15 +268,16 @@ rl_expand_prompt (prompt) if (local_prompt_prefix) free (local_prompt_prefix); local_prompt = local_prompt_prefix = (char *)0; + last_invisible = 0; - if (prompt == 0 || *prompt == '\0') + if (prompt == 0 || *prompt == 0) return (0); p = strrchr (prompt, '\n'); if (!p) { /* The prompt is only one line. */ - local_prompt = expand_prompt (prompt, &visible_length); + local_prompt = expand_prompt (prompt, &visible_length, &last_invisible); local_prompt_prefix = (char *)0; return (visible_length); } @@ -262,11 +285,11 @@ rl_expand_prompt (prompt) { /* The prompt spans multiple lines. */ t = ++p; - local_prompt = expand_prompt (p, &visible_length); + local_prompt = expand_prompt (p, &visible_length, &last_invisible); c = *t; *t = '\0'; /* The portion of the prompt string up to and including the final newline is now null-terminated. */ - local_prompt_prefix = expand_prompt (prompt, &prefix_length); + local_prompt_prefix = expand_prompt (prompt, &prefix_length, (int *)NULL); *t = c; return (prefix_length); } @@ -276,9 +299,10 @@ rl_expand_prompt (prompt) void rl_redisplay () { - register int in, out, c, linenum; - register char *line = invisible_line; - int c_pos = 0, inv_botlin = 0, wrap_offset, wrap_column; + register int in, out, c, linenum, cursor_linenum; + register char *line; + int c_pos, inv_botlin, lb_botlin, lb_linenum; + int newlines, lpos; char *prompt_this_line; if (!readline_echoing_p) @@ -287,25 +311,32 @@ rl_redisplay () if (!rl_display_prompt) rl_display_prompt = ""; - if (!invisible_line) + if (invisible_line == 0) { visible_line = xmalloc (line_size); invisible_line = xmalloc (line_size); - line = invisible_line; for (in = 0; in < line_size; in++) { visible_line[in] = 0; invisible_line[in] = 1; } + + /* should be enough, but then again, this is just for testing. */ + inv_lbreaks = (int *)malloc (256 * sizeof (int)); + vis_lbreaks = (int *)malloc (256 * sizeof (int)); + inv_lbreaks[0] = vis_lbreaks[0] = 0; + rl_on_new_line (); } /* Draw the line into the buffer. */ c_pos = -1; + line = invisible_line; + out = inv_botlin = 0; + /* Mark the line as modified or not. We only do this for history lines. */ - out = 0; if (_rl_mark_modified_lines && current_history () && rl_undo_list) { line[out++] = '*'; @@ -322,15 +353,17 @@ rl_redisplay () one passed to readline()), use the values we have already expanded. If not, use what's already in rl_display_prompt. WRAP_OFFSET is the number of non-visible characters in the prompt string. */ - if (rl_display_prompt == rl_prompt) + if (rl_display_prompt == rl_prompt || local_prompt) { int local_len = local_prompt ? strlen (local_prompt) : 0; if (local_prompt_prefix && forced_display) _rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix)); if (local_len > 0) - strncpy (line + out, local_prompt, local_len); - out += local_len; + { + strncpy (line + out, local_prompt, local_len); + out += local_len; + } line[out] = '\0'; wrap_offset = local_len - visible_length; } @@ -344,7 +377,13 @@ rl_redisplay () { prompt_this_line++; if (forced_display) - _rl_output_some_chars (rl_display_prompt, prompt_this_line - rl_display_prompt); + { + _rl_output_some_chars (rl_display_prompt, prompt_this_line - rl_display_prompt); + /* Make sure we are at column zero even after a newline, + regardless of the state of terminal output processing. */ + if (prompt_this_line[-2] != '\r') + cr (); + } } pmtlen = strlen (prompt_this_line); @@ -354,7 +393,20 @@ rl_redisplay () wrap_offset = 0; } - for (in = 0; in < rl_end; in++) +#define CHECK_LPOS() \ + do { \ + lpos++; \ + if (lpos >= screenwidth) \ + { \ + inv_lbreaks[++newlines] = out; \ + lpos = 0; \ + } \ + } while (0) + + /* inv_lbreaks[i] is where line i starts in the buffer. */ + inv_lbreaks[newlines = 0] = 0; + + for (in = 0, lpos = out - wrap_offset; in < rl_end; in++) { c = (unsigned char)rl_line_buffer[in]; @@ -367,42 +419,88 @@ rl_redisplay () } if (in == rl_point) - c_pos = out; + { + c_pos = out; + lb_linenum = newlines; + } if (META_CHAR (c)) { if (_rl_output_meta_chars == 0) { sprintf (line + out, "\\%o", c); + + if (lpos + 4 >= screenwidth) + { + register int temp; + + temp = screenwidth - lpos; + inv_lbreaks[++newlines] = out + temp; + lpos = 4 - temp; + } + else + lpos += 4; + out += 4; } else - line[out++] = c; + { + line[out++] = c; + CHECK_LPOS(); + } } #if defined (DISPLAY_TABS) else if (c == '\t') { - register int newout = (out | (int)7) + 1; - while (out < newout) - line[out++] = ' '; + register int temp, newout; + newout = (out | (int)7) + 1; + temp = newout - out; + if (lpos + temp >= screenwidth) + { + register int temp2; + temp2 = screenwidth - lpos; + inv_lbreaks[++newlines] = out + temp2; + lpos = temp - temp2; + while (out < newout) + line[out++] = ' '; + } + else + { + while (out < newout) + line[out++] = ' '; + lpos += temp; + } } #endif - else if (c < ' ') + else if (c == '\n' && _rl_horizontal_scroll_mode == 0 && term_up && *term_up) + { + line[out++] = '\0'; /* XXX - sentinel */ + inv_lbreaks[++newlines] = out; + lpos = 0; + } + else if (CTRL_CHAR (c) || c == RUBOUT) { line[out++] = '^'; - line[out++] = UNCTRL (c); /* XXX was c ^ 0x40 */ + CHECK_LPOS(); + line[out++] = CTRL_CHAR (c) ? UNCTRL (c) : '?'; + CHECK_LPOS(); } - else if (c == 127) + else { - line[out++] = '^'; - line[out++] = '?'; + line[out++] = c; + CHECK_LPOS(); } - else - line[out++] = c; } line[out] = '\0'; if (c_pos < 0) - c_pos = out; + { + c_pos = out; + lb_linenum = newlines; + } + + inv_botlin = lb_botlin = newlines; + inv_lbreaks[newlines+1] = out; + cursor_linenum = lb_linenum; /* C_POS == position in buffer where cursor should be placed. */ @@ -415,10 +513,9 @@ rl_redisplay () otherwise, let long lines display in a single terminal line, and horizontally scroll it. */ - if (!_rl_horizontal_scroll_mode && term_up && *term_up) + if (_rl_horizontal_scroll_mode == 0 && term_up && *term_up) { - int total_screen_chars = screenchars; - int nleft, cursor_linenum, pos, changed_screen_line; + int nleft, pos, changed_screen_line; if (!rl_display_fixed || forced_display) { @@ -426,42 +523,35 @@ rl_redisplay () /* If we have more than a screenful of material to display, then only display a screenful. We should display the last screen, - not the first. I'll fix this in a minute. */ - if (out >= total_screen_chars) - out = total_screen_chars - 1; - - /* Number of screen lines to display. The first line wraps at - (screenwidth + wrap_offset) chars, the rest of the lines have - screenwidth chars. */ - nleft = out - wrap_offset + term_xn - 1; - inv_botlin = (nleft > 0) ? nleft / screenwidth : 0; + not the first. */ + if (out >= screenchars) + out = screenchars - 1; /* The first line is at character position 0 in the buffer. The - second and subsequent lines start at N * screenwidth, offset by - OFFSET. OFFSET is wrap_offset for the invisible line and - visible_wrap_offset for the line currently displayed. */ + second and subsequent lines start at inv_lbreaks[N], offset by + OFFSET (which has already been calculated above). */ #define W_OFFSET(line, offset) ((line) == 0 ? offset : 0) -#define L_OFFSET(n, offset) ((n) > 0 ? ((n) * screenwidth) + (offset) : 0) -#define VIS_CHARS(line) &visible_line[L_OFFSET((line), visible_wrap_offset)] +#define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l])) +#define INV_LLEN(l) (inv_lbreaks[l+1] - inv_lbreaks[l]) +#define VIS_CHARS(line) (visible_line + vis_lbreaks[line]) #define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line) -#define INV_LINE(line) &invisible_line[L_OFFSET((line), wrap_offset)] +#define INV_LINE(line) (invisible_line + inv_lbreaks[line]) /* For each line in the buffer, do the updating display. */ for (linenum = 0; linenum <= inv_botlin; linenum++) { update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum, - screenwidth + W_OFFSET(linenum, visible_wrap_offset), - screenwidth + W_OFFSET(linenum, wrap_offset), - inv_botlin); + VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin); /* If this is the line with the prompt, we might need to compensate for invisible characters in the new line. Do this only if there is not more than one new line (which implies that we completely overwrite the old visible line) - and the new line is shorter than the old. */ + and the new line is shorter than the old. Make sure we are + at the end of the new line before clearing. */ if (linenum == 0 && - inv_botlin == 0 && + inv_botlin == 0 && _rl_last_c_pos == out && (wrap_offset > visible_wrap_offset) && (_rl_last_c_pos < visible_first_line_len)) { @@ -472,7 +562,7 @@ rl_redisplay () /* Since the new first line is now visible, save its length. */ if (linenum == 0) - visible_first_line_len = (inv_botlin > 0) ? screenwidth : out - wrap_offset; + visible_first_line_len = (inv_botlin > 0) ? inv_lbreaks[1] : out - wrap_offset; } /* We may have deleted some lines. If so, clear the left over @@ -491,11 +581,6 @@ rl_redisplay () } _rl_vis_botlin = inv_botlin; - /* Move the cursor where it should be. */ - /* Which line? */ - nleft = c_pos - wrap_offset + term_xn - 1; - cursor_linenum = (nleft > 0) ? nleft / screenwidth : 0; - /* CHANGED_SCREEN_LINE is set to 1 if we have moved to a different screen line during this redisplay. */ changed_screen_line = _rl_last_v_pos != cursor_linenum; @@ -512,10 +597,12 @@ rl_redisplay () /* We have to reprint the prompt if it contains invisible characters, since it's not generally OK to just reprint - the characters from the current cursor position. */ + the characters from the current cursor position. But we + only need to reprint it if the cursor is before the last + invisible character in the prompt string. */ nleft = visible_length + wrap_offset; if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 && - _rl_last_c_pos <= nleft && local_prompt) + _rl_last_c_pos <= last_invisible && local_prompt) { if (term_cr) tputs (term_cr, 1, _rl_output_character_function); @@ -525,17 +612,17 @@ rl_redisplay () /* Where on that line? And where does that line start in the buffer? */ - pos = L_OFFSET(cursor_linenum, wrap_offset); + pos = inv_lbreaks[cursor_linenum]; /* nleft == number of characters in the line buffer between the start of the line and the cursor position. */ nleft = c_pos - pos; - /* Since backspace() doesn't know about invisible characters in the + /* Since _rl_backspace() doesn't know about invisible characters in the prompt, and there's no good way to tell it, we compensate for - those characters here and call backspace() directly. */ + those characters here and call _rl_backspace() directly. */ if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos) { - backspace (_rl_last_c_pos - nleft); + _rl_backspace (_rl_last_c_pos - nleft); _rl_last_c_pos = nleft; } @@ -638,8 +725,11 @@ rl_redisplay () /* Swap visible and non-visible lines. */ { char *temp = visible_line; + int *itemp = vis_lbreaks; visible_line = invisible_line; invisible_line = temp; + vis_lbreaks = inv_lbreaks; + inv_lbreaks = itemp; rl_display_fixed = 0; /* If we are displaying on a single line, and last_lmargin is > 0, we are not displaying any invisible characters, so set visible_wrap_offset @@ -670,10 +760,11 @@ new: eddie> Oh, my little buggy says to me, as lurgid as static void update_line (old, new, current_line, omax, nmax, inv_botlin) register char *old, *new; - int current_line, omax, nmax; + int current_line, omax, nmax, inv_botlin; { register char *ofd, *ols, *oe, *nfd, *nls, *ne; int temp, lendiff, wsatend, od, nd; + int current_invis_chars; /* If we're at the right edge of a terminal that supports xn, we're ready to wrap around, so do so. This fixes problems with knowing @@ -681,7 +772,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) emulators. In this calculation, TEMP is the physical screen position of the cursor. */ temp = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset); - if (temp == screenwidth && term_xn && !_rl_horizontal_scroll_mode + if (temp == screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode && _rl_last_v_pos == current_line - 1) { if (new[0]) @@ -734,33 +825,53 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) nls++; } - _rl_move_vert (current_line); + /* count of invisible characters in the current invisible line. */ + current_invis_chars = W_OFFSET (current_line, wrap_offset); + if (_rl_last_v_pos != current_line) + { + _rl_move_vert (current_line); + if (current_line == 0 && visible_wrap_offset) + _rl_last_c_pos += visible_wrap_offset; + } /* If this is the first line and there are invisible characters in the - prompt string, and the prompt string has not changed, then redraw - the entire prompt string. We can only do this reliably if the - terminal supports a `cr' capability. + prompt string, and the prompt string has not changed, and the current + cursor position is before the last invisible character in the prompt, + and the index of the character to move to is past the end of the prompt + string, then redraw the entire prompt string. We can only do this + reliably if the terminal supports a `cr' capability. - This is more than just an efficiency hack -- there is a problem with - redrawing portions of the prompt string if they contain terminal - escape sequences (like drawing the `unbold' sequence without a - corresponding `bold') that manifests itself on certain terminals. */ + This is not an efficiency hack -- there is a problem with redrawing + portions of the prompt string if they contain terminal escape + sequences (like drawing the `unbold' sequence without a corresponding + `bold') that manifests itself on certain terminals. */ lendiff = local_prompt ? strlen (local_prompt) : 0; + od = ofd - old; /* index of first difference in visible line */ if (current_line == 0 && !_rl_horizontal_scroll_mode && - lendiff > visible_length && - _rl_last_c_pos > 0 && (ofd - old) >= lendiff && term_cr) + term_cr && lendiff > visible_length && _rl_last_c_pos > 0 && + od > lendiff && _rl_last_c_pos < last_invisible) { tputs (term_cr, 1, _rl_output_character_function); _rl_output_some_chars (local_prompt, lendiff); _rl_last_c_pos = lendiff; } - _rl_move_cursor_relative (ofd - old, old); + _rl_move_cursor_relative (od, old); /* if (len (new) > len (old)) */ lendiff = (nls - nfd) - (ols - ofd); + /* If we are changing the number of invisible characters in a line, and + the spot of first difference is before the end of the invisible chars, + lendiff needs to be adjusted. */ + if (current_line == 0 && !_rl_horizontal_scroll_mode && + current_invis_chars != visible_wrap_offset) + { + temp = visible_wrap_offset - current_invis_chars; + lendiff += temp; + } + /* Insert (diff (len (old), len (new)) ch. */ temp = ne - nfd; if (lendiff > 0) @@ -771,25 +882,36 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) use the terminal's capabilities. If we're growing the number of lines, make sure we actually cause the new line to wrap around on auto-wrapping terminals. */ - if (terminal_can_insert && ((2 * temp) >= lendiff || term_IC) && (!term_xn || !gl)) + if (terminal_can_insert && ((2 * temp) >= lendiff || term_IC) && (!_rl_term_autowrap || !gl)) { /* If lendiff > visible_length and _rl_last_c_pos == 0 and _rl_horizontal_scroll_mode == 1, inserting the characters with term_IC or term_ic will screw up the screen because of the invisible characters. We need to just draw them. */ if (*ols && (!_rl_horizontal_scroll_mode || _rl_last_c_pos > 0 || - lendiff <= visible_length)) + lendiff <= visible_length || !current_invis_chars)) { insert_some_chars (nfd, lendiff); _rl_last_c_pos += lendiff; } - else + else if (*ols == 0) { /* At the end of a line the characters do not have to be "inserted". They can just be placed on the screen. */ + /* However, this screws up the rest of this block, which + assumes you've done the insert because you can. */ _rl_output_some_chars (nfd, lendiff); _rl_last_c_pos += lendiff; } + else + { + /* We have horizontal scrolling and we are not inserting at + the end. We have invisible characters in this line. This + is a dumb update. */ + _rl_output_some_chars (nfd, temp); + _rl_last_c_pos += temp; + return; + } /* Copy (new) chars to screen from first diff to last match. */ temp = nls - nfd; if ((temp - lendiff) > 0) @@ -837,7 +959,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) _rl_last_c_pos += temp; } lendiff = (oe - old) - (ne - new); - if (term_xn && current_line < inv_botlin) + if (_rl_term_autowrap && current_line < inv_botlin) space_to_eol (lendiff); else clear_to_eol (lendiff); @@ -846,6 +968,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) } /* Tell the update routines that we have moved onto a new (empty) line. */ +int rl_on_new_line () { if (visible_line) @@ -853,21 +976,26 @@ rl_on_new_line () _rl_last_c_pos = _rl_last_v_pos = 0; _rl_vis_botlin = last_lmargin = 0; + if (vis_lbreaks) + vis_lbreaks[0] = vis_lbreaks[1] = 0; + visible_wrap_offset = 0; return 0; } /* Actually update the display, period. */ +int rl_forced_update_display () { if (visible_line) { register char *temp = visible_line; - while (*temp) *temp++ = '\0'; + while (*temp) + *temp++ = '\0'; } rl_on_new_line (); forced_display++; - rl_redisplay (); + (*rl_redisplay_function) (); return 0; } @@ -888,7 +1016,8 @@ _rl_move_cursor_relative (new, data) of moving backwards. */ /* i == current physical cursor position. */ i = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset); - if (CR_FASTER (new, _rl_last_c_pos) || (term_xn && i == screenwidth)) + if (new == 0 || CR_FASTER (new, _rl_last_c_pos) || + (_rl_term_autowrap && i == screenwidth)) { #if defined (__MSDOS__) putc ('\r', rl_outstream); @@ -924,7 +1053,7 @@ _rl_move_cursor_relative (new, data) #endif /* HACK_TERMCAP_MOTION */ } else if (_rl_last_c_pos != new) - backspace (_rl_last_c_pos - new); + _rl_backspace (_rl_last_c_pos - new); _rl_last_c_pos = new; } @@ -966,6 +1095,7 @@ _rl_move_vert (to) /* Physically print C on rl_outstream. This is for functions which know how to optimize the display. Return the number of characters output. */ +int rl_show_char (c) int c; { @@ -978,14 +1108,14 @@ rl_show_char (c) } #if defined (DISPLAY_TABS) - if (c < 32 && c != '\t') + if ((CTRL_CHAR (c) && c != '\t') || c == RUBOUT) #else - if (c < 32) + if (CTRL_CHAR (c) || c == RUBOUT) #endif /* !DISPLAY_TABS */ { fprintf (rl_outstream, "C-"); n += 2; - c += 64; + c = CTRL_CHAR (c) ? UNCTRL (c) : '?'; } putc (c, rl_outstream); @@ -1013,47 +1143,65 @@ rl_character_len (c, pos) #endif /* !DISPLAY_TABS */ } + if (CTRL_CHAR (c) || c == RUBOUT) + return (2); + return ((isprint (uc)) ? 1 : 2); } /* How to print things in the "echo-area". The prompt is treated as a mini-modeline. */ -#if defined (HAVE_VARARGS_H) +#if defined (USE_VARARGS) +int +#if defined (PREFER_STDARG) +rl_message (const char *format, ...) +#else rl_message (va_alist) va_dcl +#endif { - char *format; va_list args; +#if defined (PREFER_VARARGS) + char *format; +#endif +#if defined (PREFER_STDARG) + va_start (args, format); +#else va_start (args); format = va_arg (args, char *); +#endif + vsprintf (msg_buf, format, args); va_end (args); rl_display_prompt = msg_buf; - rl_redisplay (); + (*rl_redisplay_function) (); return 0; } -#else /* !HAVE_VARARGS_H */ +#else /* !USE_VARARGS */ +int rl_message (format, arg1, arg2) char *format; { sprintf (msg_buf, format, arg1, arg2); rl_display_prompt = msg_buf; - rl_redisplay (); + (*rl_redisplay_function) (); return 0; } -#endif /* !HAVE_VARARGS_H */ +#endif /* !USE_VARARGS */ /* How to clear things from the "echo-area". */ +int rl_clear_message () { rl_display_prompt = rl_prompt; - rl_redisplay (); + (*rl_redisplay_function) (); return 0; } +int rl_reset_line_state () { rl_on_new_line (); @@ -1063,6 +1211,70 @@ rl_reset_line_state () return 0; } +static char *saved_local_prompt; +static char *saved_local_prefix; +static int saved_last_invisible; +static int saved_visible_length; + +void +_rl_save_prompt () +{ + saved_local_prompt = local_prompt; + saved_local_prefix = local_prompt_prefix; + saved_last_invisible = last_invisible; + saved_visible_length = visible_length; + + local_prompt = local_prompt_prefix = (char *)0; + last_invisible = visible_length = 0; +} + +void +_rl_restore_prompt () +{ + if (local_prompt) + free (local_prompt); + if (local_prompt_prefix) + free (local_prompt_prefix); + + local_prompt = saved_local_prompt; + local_prompt_prefix = saved_local_prefix; + last_invisible = saved_last_invisible; + visible_length = saved_visible_length; +} + +char * +_rl_make_prompt_for_search (pchar) + int pchar; +{ + int len; + char *pmt; + + _rl_save_prompt (); + + if (saved_local_prompt == 0) + { + len = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0; + pmt = xmalloc (len + 2); + if (len) + strcpy (pmt, rl_prompt); + pmt[len] = pchar; + pmt[len+1] = '\0'; + } + else + { + len = *saved_local_prompt ? strlen (saved_local_prompt) : 0; + pmt = xmalloc (len + 2); + if (len) + strcpy (pmt, saved_local_prompt); + pmt[len] = pchar; + pmt[len+1] = '\0'; + local_prompt = savestring (pmt); + last_invisible = saved_last_invisible; + visible_length = saved_visible_length + 1; + } + return pmt; +} + /* Quick redisplay hack when erasing characters at the end of the line. */ void _rl_erase_at_end_of_line (l) @@ -1070,10 +1282,10 @@ _rl_erase_at_end_of_line (l) { register int i; - backspace (l); + _rl_backspace (l); for (i = 0; i < l; i++) putc (' ', rl_outstream); - backspace (l); + _rl_backspace (l); for (i = 0; i < l; i++) visible_line[--_rl_last_c_pos] = '\0'; rl_display_fixed++; @@ -1132,7 +1344,7 @@ insert_some_chars (string, count) /* If IC is defined, then we do not have to "enter" insert mode. */ if (term_IC) { - char *tgoto (), *buffer; + char *buffer; buffer = tgoto (term_IC, 0, count); tputs (buffer, 1, _rl_output_character_function); _rl_output_some_chars (string, count); @@ -1186,7 +1398,7 @@ delete_chars (count) if (term_DC && *term_DC) { - char *tgoto (), *buffer; + char *buffer; buffer = tgoto (term_DC, count, count); tputs (buffer, count, _rl_output_character_function); } @@ -1205,17 +1417,20 @@ _rl_update_final () int full_lines; full_lines = 0; - if (_rl_vis_botlin && visible_line[screenwidth * _rl_vis_botlin] == 0) + /* If the cursor is the only thing on an otherwise-blank last line, + compensate so we don't print an extra CRLF. */ + if (_rl_vis_botlin && _rl_last_c_pos == 0 && + visible_line[inv_lbreaks[_rl_vis_botlin]+1] == 0) { _rl_vis_botlin--; full_lines = 1; } _rl_move_vert (_rl_vis_botlin); - if (full_lines && term_xn) + /* If we've wrapped lines, remove the final xterm line-wrap flag. */ + if (full_lines && _rl_term_autowrap && (VIS_LLEN(_rl_vis_botlin) == screenwidth)) { - /* Remove final line-wrap flag in xterm. */ char *last_line; - last_line = &visible_line[screenwidth * _rl_vis_botlin]; + last_line = &visible_line[inv_lbreaks[_rl_vis_botlin]]; _rl_move_cursor_relative (screenwidth - 1, last_line); clear_to_eol (0); putc (last_line[screenwidth - 1], rl_outstream); @@ -1274,3 +1489,15 @@ _rl_redisplay_after_sigwinch () else rl_forced_update_display (); } + +void +_rl_clean_up_for_exit () +{ + if (readline_echoing_p) + { + _rl_move_vert (_rl_vis_botlin); + _rl_vis_botlin = 0; + fflush (rl_outstream); + rl_restart_output (); + } +} diff --git a/lib/readline/doc/Makefile b/lib/readline/doc/Makefile index 72b8ce7..9dbab24 100644 --- a/lib/readline/doc/Makefile +++ b/lib/readline/doc/Makefile @@ -1,10 +1,11 @@ -# This makefile for History library documentation is in -*- text -*- mode. +# This makefile for Readline library documentation is in -*- text -*- mode. # Emacs likes it that way. +TEXI2DVI = texi2dvi -DOC_SUPPORT = ../../doc-support/ -TEXINDEX = $(DOC_SUPPORT)/texindex +RM = rm -f -TEX = tex +INSTALL_DATA = cp +infodir = /usr/local/info RLSRC = rlman.texinfo rluser.texinfo rltech.texinfo HISTSRC = hist.texinfo hsuser.texinfo hstech.texinfo @@ -12,26 +13,23 @@ HISTSRC = hist.texinfo hsuser.texinfo hstech.texinfo DVIOBJ = readline.dvi history.dvi INFOOBJ = readline.info history.info PSOBJ = readline.ps history.ps +HTMLOBJ = readline.html history.html -all: info dvi +all: info dvi html readline.dvi: $(RLSRC) - $(TEX) rlman.texinfo - $(TEXINDEX) rlman.?? - $(TEX) rlman.texinfo + $(TEXI2DVI) rlman.texinfo mv rlman.dvi readline.dvi readline.info: $(RLSRC) - makeinfo rlman.texinfo + makeinfo --no-split -o $@ rlman.texinfo history.dvi: ${HISTSRC} - $(TEX) hist.texinfo - $(TEXINDEX) hist.?? - $(TEX) hist.texinfo + $(TEXI2DVI) hist.texinfo mv hist.dvi history.dvi history.info: ${HISTSRC} - makeinfo hist.texinfo + makeinfo --no-split -o $@ hist.texinfo readline.ps: readline.dvi dvips -D 300 -o $@ readline.dvi @@ -39,17 +37,33 @@ readline.ps: readline.dvi history.ps: history.dvi dvips -D 300 -o $@ history.dvi +readline.html: ${RLSRC} + texi2html rlman.texinfo + sed -e 's:rlman.html:readline.html:' -e 's:rlman_toc.html:readline_toc.html:' rlman.html > readline.html + sed -e 's:rlman.html:readline.html:' -e 's:rlman_toc.html:readline_toc.html:' rlman_toc.html > readline_toc.html + rm -f rlman.html rlman_toc.html + +history.html: ${HISTSRC} + texi2html hist.texinfo + sed -e 's:hist.html:history.html:' -e 's:hist_toc.html:history_toc.html:' hist.html > history.html + sed -e 's:hist.html:history.html:' -e 's:hist_toc.html:history_toc.html:' hist_toc.html > history_toc.html + rm -f hist.html hist_toc.html + info: $(INFOOBJ) dvi: $(DVIOBJ) ps: $(PSOBJ) +html: $(HTMLOBJ) +clean: + $(RM) *.aux *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr *.cps *.pgs \ + *.fns *.kys *.tps *.vrs *.o core -$(TEXINDEX): - (cd $(DOC_SUPPORT); $(MAKE) $(MFLAGS) CFLAGS='$(CFLAGS)' texindex) +distclean: clean +mostlyclean: clean -distclean mostlyclean clean: - rm -f *.aux *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr *.cps *.pgs \ - *.fns *.kys *.tps *.vrs *.o core +maintainer-clean: clean + $(RM) *.dvi *.info *.info-* *.ps *.html -maintainer-clean realclean: clean - rm -f *.dvi *.info *.info-* *.ps +install: info + ${INSTALL_DATA} readline.info $(infodir)/readline.info + ${INSTALL_DATA} history.info $(infodir)/history.info diff --git a/lib/readline/doc/hist.texinfo b/lib/readline/doc/hist.texinfo index cc80efa..aa04553 100644 --- a/lib/readline/doc/hist.texinfo +++ b/lib/readline/doc/hist.texinfo @@ -7,20 +7,20 @@ @setchapternewpage odd @ignore -last change: Wed Jul 20 09:57:17 EDT 1994 +last change: Thu Mar 21 16:07:29 EST 1996 @end ignore -@set EDITION 2.0 -@set VERSION 2.0 -@set UPDATED 20 July 1994 -@set UPDATE-MONTH July 1994 +@set EDITION 2.1 +@set VERSION 2.1 +@set UPDATED 21 March 1996 +@set UPDATE-MONTH March 1996 @ifinfo This document describes the GNU History library, a programming tool that provides a consistent user interface for recalling lines of previously typed input. -Copyright (C) 1988, 1991 Free Software Foundation, Inc. +Copyright (C) 1988, 1991, 1993, 1995, 1996 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice @@ -45,7 +45,6 @@ by the Foundation. @end ifinfo @titlepage -@sp 10 @title GNU History Library @subtitle Edition @value{EDITION}, for @code{History Library} Version @value{VERSION}. @subtitle @value{UPDATE-MONTH} diff --git a/lib/readline/doc/history.dvi b/lib/readline/doc/history.dvi Binary files differdeleted file mode 100644 index 60d7376..0000000 --- a/lib/readline/doc/history.dvi +++ /dev/null diff --git a/lib/readline/doc/history.info b/lib/readline/doc/history.info deleted file mode 100644 index 6df0bd9..0000000 --- a/lib/readline/doc/history.info +++ /dev/null @@ -1,744 +0,0 @@ -This is Info file history.info, produced by Makeinfo-1.55 from the -input file hist.texinfo. - - This document describes the GNU History library, a programming tool -that provides a consistent user interface for recalling lines of -previously typed input. - - Copyright (C) 1988, 1991 Free Software Foundation, Inc. - - Permission is granted to make and distribute verbatim copies of this -manual provided the copyright notice and this permission notice pare -preserved on all copies. - - Permission is granted to copy and distribute modified versions of -this manual under the conditions for verbatim copying, provided that -the entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - - Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions, except that this permission notice may be stated in a -translation approved by the Foundation. - - -File: history.info, Node: Top, Next: Using History Interactively, Prev: (DIR), Up: (DIR) - -GNU History Library -******************* - - This document describes the GNU History library, a programming tool -that provides a consistent user interface for recalling lines of -previously typed input. - -* Menu: - -* Using History Interactively:: GNU History User's Manual. -* Programming with GNU History:: GNU History Programmer's Manual. -* Concept Index:: Index of concepts described in this manual. -* Function and Variable Index:: Index of externally visible functions - and variables. - - -File: history.info, Node: Using History Interactively, Next: Programming with GNU History, Prev: Top, Up: Top - -Using History Interactively -*************************** - - This chapter describes how to use the GNU History Library -interactively, from a user's standpoint. It should be considered a -user's guide. For information on using the GNU History Library in your -own programs, *note Programming with GNU History::.. - -* Menu: - -* History Interaction:: What it feels like using History as a user. - - -File: history.info, Node: History Interaction, Up: Using History Interactively - -History Interaction -=================== - - The History library provides a history expansion feature that is -similar to the history expansion provided by `csh'. The following text -describes the syntax used to manipulate the history information. - - History expansion takes place in two parts. The first is to -determine which line from the previous history should be used during -substitution. The second is to select portions of that line for -inclusion into the current one. The line selected from the previous -history is called the "event", and the portions of that line that are -acted upon are called "words". The line is broken into words in the -same fashion that Bash does, so that several English (or Unix) words -surrounded by quotes are considered as one word. - -* Menu: - -* Event Designators:: How to specify which history line to use. -* Word Designators:: Specifying which words are of interest. -* Modifiers:: Modifying the results of substitution. - - -File: history.info, Node: Event Designators, Next: Word Designators, Up: History Interaction - -Event Designators ------------------ - - An event designator is a reference to a command line entry in the -history list. - -`!' - Start a history substitution, except when followed by a space, tab, - the end of the line, = or (. - -`!!' - Refer to the previous command. This is a synonym for `!-1'. - -`!n' - Refer to command line N. - -`!-n' - Refer to the command N lines back. - -`!string' - Refer to the most recent command starting with STRING. - -`!?string'[`?'] - Refer to the most recent command containing STRING. - -`!#' - The entire command line typed so far. - -`^string1^string2^' - Quick Substitution. Repeat the last command, replacing STRING1 - with STRING2. Equivalent to `!!:s/string1/string2/'. - - -File: history.info, Node: Word Designators, Next: Modifiers, Prev: Event Designators, Up: History Interaction - -Word Designators ----------------- - - A : separates the event specification from the word designator. It -can be omitted if the word designator begins with a ^, $, * or %. -Words are numbered from the beginning of the line, with the first word -being denoted by a 0 (zero). - -`0 (zero)' - The `0'th word. For many applications, this is the command word. - -`n' - The Nth word. - -`^' - The first argument; that is, word 1. - -`$' - The last argument. - -`%' - The word matched by the most recent `?string?' search. - -`x-y' - A range of words; `-Y' abbreviates `0-Y'. - -`*' - All of the words, except the `0'th. This is a synonym for `1-$'. - It is not an error to use * if there is just one word in the event; - the empty string is returned in that case. - -`x*' - Abbreviates `x-$' - -`x-' - Abbreviates `x-$' like `x*', but omits the last word. - - -File: history.info, Node: Modifiers, Prev: Word Designators, Up: History Interaction - -Modifiers ---------- - - After the optional word designator, you can add a sequence of one or -more of the following modifiers, each preceded by a :. - -`h' - Remove a trailing pathname component, leaving only the head. - -`r' - Remove a trailing suffix of the form `.'SUFFIX, leaving the - basename. - -`e' - Remove all but the trailing suffix. - -`t' - Remove all leading pathname components, leaving the tail. - -`p' - Print the new command but do not execute it. - -`s/old/new/' - Substitute NEW for the first occurrence of OLD in the event line. - Any delimiter may be used in place of /. The delimiter may be - quoted in OLD and NEW with a single backslash. If & appears in - NEW, it is replaced by OLD. A single backslash will quote the &. - The final delimiter is optional if it is the last character on the - input line. - -`&' - Repeat the previous substitution. - -`g' - Cause changes to be applied over the entire event line. Used in - conjunction with `s', as in `gs/old/new/', or with `&'. - - -File: history.info, Node: Programming with GNU History, Next: Concept Index, Prev: Using History Interactively, Up: Top - -Programming with GNU History -**************************** - - This chapter describes how to interface programs that you write with -the GNU History Library. It should be considered a technical guide. -For information on the interactive use of GNU History, *note Using -History Interactively::.. - -* Menu: - -* Introduction to History:: What is the GNU History library for? -* History Storage:: How information is stored. -* History Functions:: Functions that you can use. -* History Variables:: Variables that control behaviour. -* History Programming Example:: Example of using the GNU History Library. - - -File: history.info, Node: Introduction to History, Next: History Storage, Up: Programming with GNU History - -Introduction to History -======================= - - Many programs read input from the user a line at a time. The GNU -History library is able to keep track of those lines, associate -arbitrary data with each line, and utilize information from previous -lines in composing new ones. - - The programmer using the History library has available functions for -remembering lines on a history list, associating arbitrary data with a -line, removing lines from the list, searching through the list for a -line containing an arbitrary text string, and referencing any line in -the list directly. In addition, a history "expansion" function is -available which provides for a consistent user interface across -different programs. - - The user using programs written with the History library has the -benefit of a consistent user interface with a set of well-known -commands for manipulating the text of previous lines and using that text -in new commands. The basic history manipulation commands are similar to -the history substitution provided by `csh'. - - If the programmer desires, he can use the Readline library, which -includes some history manipulation by default, and has the added -advantage of command line editing. - - -File: history.info, Node: History Storage, Next: History Functions, Prev: Introduction to History, Up: Programming with GNU History - -History Storage -=============== - - The history list is an array of history entries. A history entry is -declared as follows: - - typedef struct _hist_entry { - char *line; - char *data; - } HIST_ENTRY; - - The history list itself might therefore be declared as - - HIST_ENTRY **the_history_list; - - The state of the History library is encapsulated into a single -structure: - - /* A structure used to pass the current state of the history stuff around. */ - typedef struct _hist_state { - HIST_ENTRY **entries; /* Pointer to the entries themselves. */ - int offset; /* The location pointer within this array. */ - int length; /* Number of elements within this array. */ - int size; /* Number of slots allocated to this array. */ - int flags; - } HISTORY_STATE; - - If the flags member includes `HS_STIFLED', the history has been -stifled. - - -File: history.info, Node: History Functions, Next: History Variables, Prev: History Storage, Up: Programming with GNU History - -History Functions -================= - - This section describes the calling sequence for the various functions -present in GNU History. - -* Menu: - -* Initializing History and State Management:: Functions to call when you - want to use history in a - program. -* History List Management:: Functions used to manage the list - of history entries. -* Information About the History List:: Functions returning information about - the history list. -* Moving Around the History List:: Functions used to change the position - in the history list. -* Searching the History List:: Functions to search the history list - for entries containing a string. -* Managing the History File:: Functions that read and write a file - containing the history list. -* History Expansion:: Functions to perform csh-like history - expansion. - - -File: history.info, Node: Initializing History and State Management, Next: History List Management, Up: History Functions - -Initializing History and State Management ------------------------------------------ - - This section describes functions used to initialize and manage the -state of the History library when you want to use the history functions -in your program. - - - Function: void using_history () - Begin a session in which the history functions might be used. This - initializes the interactive variables. - - - Function: HISTORY_STATE * history_get_history_state () - Return a structure describing the current state of the input - history. - - - Function: void history_set_history_state (HISTORY_STATE *state) - Set the state of the history list according to STATE. - - -File: history.info, Node: History List Management, Next: Information About the History List, Prev: Initializing History and State Management, Up: History Functions - -History List Management ------------------------ - - These functions manage individual entries on the history list, or set -parameters managing the list itself. - - - Function: void add_history (char *string) - Place STRING at the end of the history list. The associated data - field (if any) is set to `NULL'. - - - Function: HIST_ENTRY * remove_history (int which) - Remove history entry at offset WHICH from the history. The - removed element is returned so you can free the line, data, and - containing structure. - - - Function: HIST_ENTRY * replace_history_entry (int which, char *line, - char *data) - Make the history entry at offset WHICH have LINE and DATA. This - returns the old entry so you can dispose of the data. In the case - of an invalid WHICH, a `NULL' pointer is returned. - - - Function: void stifle_history (int max) - Stifle the history list, remembering only the last MAX entries. - - - Function: int unstifle_history () - Stop stifling the history. This returns the previous amount the - history was stifled. The value is positive if the history was - stifled, negative if it wasn't. - - - Function: int history_is_stifled () - Returns non-zero if the history is stifled, zero if it is not. - - -File: history.info, Node: Information About the History List, Next: Moving Around the History List, Prev: History List Management, Up: History Functions - -Information About the History List ----------------------------------- - - These functions return information about the entire history list or -individual list entries. - - - Function: HIST_ENTRY ** history_list () - Return a `NULL' terminated array of `HIST_ENTRY' which is the - current input history. Element 0 of this list is the beginning of - time. If there is no history, return `NULL'. - - - Function: int where_history () - Returns the offset of the current history element. - - - Function: HIST_ENTRY * current_history () - Return the history entry at the current position, as determined by - `where_history ()'. If there is no entry there, return a `NULL' - pointer. - - - Function: HIST_ENTRY * history_get (int offset) - Return the history entry at position OFFSET, starting from - `history_base'. If there is no entry there, or if OFFSET is - greater than the history length, return a `NULL' pointer. - - - Function: int history_total_bytes () - Return the number of bytes that the primary history entries are - using. This function returns the sum of the lengths of all the - lines in the history. - - -File: history.info, Node: Moving Around the History List, Next: Searching the History List, Prev: Information About the History List, Up: History Functions - -Moving Around the History List ------------------------------- - - These functions allow the current index into the history list to be -set or changed. - - - Function: int history_set_pos (int pos) - Set the position in the history list to POS, an absolute index - into the list. - - - Function: HIST_ENTRY * previous_history () - Back up the current history offset to the previous history entry, - and return a pointer to that entry. If there is no previous - entry, return a `NULL' pointer. - - - Function: HIST_ENTRY * next_history () - Move the current history offset forward to the next history entry, - and return the a pointer to that entry. If there is no next - entry, return a `NULL' pointer. - - -File: history.info, Node: Searching the History List, Next: Managing the History File, Prev: Moving Around the History List, Up: History Functions - -Searching the History List --------------------------- - - These functions allow searching of the history list for entries -containing a specific string. Searching may be performed both forward -and backward from the current history position. The search may be -"anchored", meaning that the string must match at the beginning of the -history entry. - - - Function: int history_search (char *string, int direction) - Search the history for STRING, starting at the current history - offset. If DIRECTION < 0, then the search is through previous - entries, else through subsequent. If STRING is found, then the - current history index is set to that history entry, and the value - returned is the offset in the line of the entry where STRING was - found. Otherwise, nothing is changed, and a -1 is returned. - - - Function: int history_search_prefix (char *string, int direction) - Search the history for STRING, starting at the current history - offset. The search is anchored: matching lines must begin with - STRING. If DIRECTION < 0, then the search is through previous - entries, else through subsequent. If STRING is found, then the - current history index is set to that entry, and the return value - is 0. Otherwise, nothing is changed, and a -1 is returned. - - - Function: int history_search_pos (char *string, int direction, int - pos) - Search for STRING in the history list, starting at POS, an - absolute index into the list. If DIRECTION is negative, the search - proceeds backward from POS, otherwise forward. Returns the - absolute index of the history element where STRING was found, or - -1 otherwise. - - -File: history.info, Node: Managing the History File, Next: History Expansion, Prev: Searching the History List, Up: History Functions - -Managing the History File -------------------------- - - The History library can read the history from and write it to a file. -This section documents the functions for managing a history file. - - - Function: int read_history (char *filename) - Add the contents of FILENAME to the history list, a line at a - time. If FILENAME is `NULL', then read from `~/.history'. - Returns 0 if successful, or errno if not. - - - Function: int read_history_range (char *filename, int from, int to) - Read a range of lines from FILENAME, adding them to the history - list. Start reading at line FROM and end at TO. If FROM is zero, - start at the beginning. If TO is less than FROM, then read until - the end of the file. If FILENAME is `NULL', then read from - `~/.history'. Returns 0 if successful, or `errno' if not. - - - Function: int write_history (char *filename) - Write the current history to FILENAME, overwriting FILENAME if - necessary. If FILENAME is `NULL', then write the history list to - `~/.history'. Values returned are as in `read_history ()'. - - - Function: int append_history (int nelements, char *filename) - Append the last NELEMENTS of the history list to FILENAME. - - - Function: int history_truncate_file (char *filename, int nlines) - Truncate the history file FILENAME, leaving only the last NLINES - lines. - - -File: history.info, Node: History Expansion, Prev: Managing the History File, Up: History Functions - -History Expansion ------------------ - - These functions implement `csh'-like history expansion. - - - Function: int history_expand (char *string, char **output) - Expand STRING, placing the result into OUTPUT, a pointer to a - string (*note History Interaction::.). Returns: - `0' - If no expansions took place (or, if the only change in the - text was the de-slashifying of the history expansion - character); - - `1' - if expansions did take place; - - `-1' - if there was an error in expansion; - - `2' - if the returned line should only be displayed, but not - executed, as with the `:p' modifier (*note Modifiers::.). - - If an error ocurred in expansion, then OUTPUT contains a - descriptive error message. - - - Function: char * history_arg_extract (int first, int last, char - *string) - Extract a string segment consisting of the FIRST through LAST - arguments present in STRING. Arguments are broken up as in Bash. - - - Function: char * get_history_event (char *string, int *cindex, int - qchar) - Returns the text of the history event beginning at STRING + - *CINDEX. *CINDEX is modified to point to after the event - specifier. At function entry, CINDEX points to the index into - STRING where the history event specification begins. QCHAR is a - character that is allowed to end the event specification in - addition to the "normal" terminating characters. - - - Function: char ** history_tokenize (char *string) - Return an array of tokens parsed out of STRING, much as the shell - might. The tokens are split on white space and on the characters - `()<>;&|$', and shell quoting conventions are obeyed. - - -File: history.info, Node: History Variables, Next: History Programming Example, Prev: History Functions, Up: Programming with GNU History - -History Variables -================= - - This section describes the externally visible variables exported by -the GNU History Library. - - - Variable: int history_base - The logical offset of the first entry in the history list. - - - Variable: int history_length - The number of entries currently stored in the history list. - - - Variable: int max_input_history - The maximum number of history entries. This must be changed using - `stifle_history ()'. - - - Variable: char history_expansion_char - The character that starts a history event. The default is `!'. - - - Variable: char history_subst_char - The character that invokes word substitution if found at the start - of a line. The default is `^'. - - - Variable: char history_comment_char - During tokenization, if this character is seen as the first - character of a word, then it and all subsequent characters up to a - newline are ignored, suppressing history expansion for the - remainder of the line. This is disabled by default. - - - Variable: char * history_no_expand_chars - The list of characters which inhibit history expansion if found - immediately following HISTORY_EXPANSION_CHAR. The default is - whitespace and `='. - - -File: history.info, Node: History Programming Example, Prev: History Variables, Up: Programming with GNU History - -History Programming Example -=========================== - - The following program demonstrates simple use of the GNU History -Library. - - main () - { - char line[1024], *t; - int len, done = 0; - - line[0] = 0; - - using_history (); - while (!done) - { - printf ("history$ "); - fflush (stdout); - t = fgets (line, sizeof (line) - 1, stdin); - if (t && *t) - { - len = strlen (t); - if (t[len - 1] == '\n') - t[len - 1] = '\0'; - } - - if (!t) - strcpy (line, "quit"); - - if (line[0]) - { - char *expansion; - int result; - - result = history_expand (line, &expansion); - if (result) - fprintf (stderr, "%s\n", expansion); - - if (result < 0 || result == 2) - { - free (expansion); - continue; - } - - add_history (expansion); - strncpy (line, expansion, sizeof (line) - 1); - free (expansion); - } - - if (strcmp (line, "quit") == 0) - done = 1; - else if (strcmp (line, "save") == 0) - write_history ("history_file"); - else if (strcmp (line, "read") == 0) - read_history ("history_file"); - else if (strcmp (line, "list") == 0) - { - register HIST_ENTRY **the_list; - register int i; - - the_list = history_list (); - if (the_list) - for (i = 0; the_list[i]; i++) - printf ("%d: %s\n", i + history_base, the_list[i]->line); - } - else if (strncmp (line, "delete", 6) == 0) - { - int which; - if ((sscanf (line + 6, "%d", &which)) == 1) - { - HIST_ENTRY *entry = remove_history (which); - if (!entry) - fprintf (stderr, "No such entry %d\n", which); - else - { - free (entry->line); - free (entry); - } - } - else - { - fprintf (stderr, "non-numeric arg given to `delete'\n"); - } - } - } - } - - -File: history.info, Node: Concept Index, Next: Function and Variable Index, Prev: Programming with GNU History, Up: Top - -Concept Index -************* - -* Menu: - -* anchored search: Searching the History List. -* event designators: Event Designators. -* expansion: History Interaction. -* history events: Event Designators. -* History Searching: Searching the History List. - - -File: history.info, Node: Function and Variable Index, Prev: Concept Index, Up: Top - -Function and Variable Index -*************************** - -* Menu: - -* add_history: History List Management. -* append_history: Managing the History File. -* current_history: Information About the History List. -* get_history_event: History Expansion. -* history_arg_extract: History Expansion. -* history_base: History Variables. -* history_comment_char: History Variables. -* history_expand: History Expansion. -* history_expansion_char: History Variables. -* history_get: Information About the History List. -* history_get_history_state: Initializing History and State Management. -* history_is_stifled: History List Management. -* history_length: History Variables. -* history_list: Information About the History List. -* history_no_expand_chars: History Variables. -* history_search: Searching the History List. -* history_search_pos: Searching the History List. -* history_search_prefix: Searching the History List. -* history_set_history_state: Initializing History and State Management. -* history_set_pos: Moving Around the History List. -* history_subst_char: History Variables. -* history_tokenize: History Expansion. -* history_total_bytes: Information About the History List. -* history_truncate_file: Managing the History File. -* max_input_history: History Variables. -* next_history: Moving Around the History List. -* previous_history: Moving Around the History List. -* read_history: Managing the History File. -* read_history_range: Managing the History File. -* remove_history: History List Management. -* replace_history_entry: History List Management. -* stifle_history: History List Management. -* unstifle_history: History List Management. -* using_history: Initializing History and State Management. -* where_history: Information About the History List. -* write_history: Managing the History File. - - - -Tag Table: -Node: Top975 -Node: Using History Interactively1569 -Node: History Interaction2077 -Node: Event Designators3122 -Node: Word Designators3952 -Node: Modifiers4936 -Node: Programming with GNU History6065 -Node: Introduction to History6791 -Node: History Storage8112 -Node: History Functions9205 -Node: Initializing History and State Management10176 -Node: History List Management10968 -Node: Information About the History List12396 -Node: Moving Around the History List13702 -Node: Searching the History List14587 -Node: Managing the History File16419 -Node: History Expansion17925 -Node: History Variables19769 -Node: History Programming Example21138 -Node: Concept Index23742 -Node: Function and Variable Index24223 - -End Tag Table diff --git a/lib/readline/doc/history.ps b/lib/readline/doc/history.ps deleted file mode 100644 index 839598f..0000000 --- a/lib/readline/doc/history.ps +++ /dev/null @@ -1,2037 +0,0 @@ -%!PS-Adobe-2.0 -%%Creator: dvipsk 5.490s Copyright 1986, 1992 Radical Eye Software -%%Title: history.dvi -%%Pages: 22 1 -%%BoundingBox: 0 0 612 792 -%%EndComments -%DVIPSCommandLine: dvips -D 300 -o history.ps history.dvi -%%BeginProcSet: tex.pro -%! -/TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N /X{S N} -B /TR{translate}N /isls false N /vsize 11 72 mul N /@rigin{isls{[0 -1 1 0 0 0] -concat}if 72 Resolution div 72 VResolution div neg scale isls{Resolution hsize --72 div mul 0 TR}if Resolution VResolution vsize -72 div 1 add mul TR matrix -currentmatrix dup dup 4 get round 4 exch put dup dup 5 get round 5 exch put -setmatrix}N /@landscape{/isls true N}B /@manualfeed{statusdict /manualfeed -true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N -/IE 0 N /ctr 0 N /df-tail{/nn 8 dict N nn begin /FontType 3 N /FontMatrix -fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{ -CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn -put /ctr 0 N[}B /df{/sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 -0 sf neg 0 0]N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data -dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{128 -ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127 -sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type -/stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N -/cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get -S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height -sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0 --1 -.1 ch-xoff sub ch-yoff .1 add]{ch-image}imagemask restore}B /D{/cc X dup -type /stringtype ne{]}if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 -ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N} -B /I{cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin -0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul add -.99 lt{/FV}{/RV}ifelse load def pop}N /eop{SI restore showpage userdict -/eop-hook known{eop-hook}if}N /@start{userdict /start-hook known{start-hook} -if /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255{IE -S 1 string dup 0 3 index put cvn put}for 65781.76 div /vsize X 65781.76 div -/hsize X}N /p{show}N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N /ruley -0 N /v{/ruley X /rulex X V}B /V{}B /RV statusdict begin /product where{pop -product dup length 7 ge{0 7 getinterval dup(Display)eq exch 0 4 getinterval -(NeXT)eq or}{pop false}ifelse}{false}ifelse end{{gsave TR -.1 -.1 TR 1 1 scale -rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1 -.1 TR rulex -ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /FV{gsave -transform round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg -rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail{dup -/delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M}B /d{-3 M} -B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{4 M}B /w{0 -rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{p 1 w}B /r{p 2 w} -B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save N}B -/eos{SS restore}B end -%%EndProcSet -TeXDict begin 40258431 52099146 1000 300 300 @start /Fa 1 59 -df<70F8F8F87005057C840D>58 D E /Fb 1 59 df<78FCFCFCFC7806067B8510>58 -D E /Fc 24 123 df<1FC0007FF000707800201800001C00001C0007FC001FFC003C1C00701C00 -E01C00E01C00E01C00707C003FFF800F8F8011107E8F14>97 D<FC0000FC00001C00001C00001C -00001C00001C00001CF8001DFE001F07001E03001C03801C01C01C01C01C01C01C01C01C01C01C -01C01C03801E03001F0E001DFC000CF8001217809614>I<03F80FFC1C1C380870006000E000E0 -00E000E00060007000380E1C1E0FFC03F00F107E8F14>I<007E00007E00000E00000E00000E00 -000E00000E0007CE000FFE001C3E00301E00700E00E00E00E00E00E00E00E00E00E00E00E00E00 -700E00301E00383E001FEFC007CFC012177F9614>I<07E00FF01C38301C700CE00EE00EFFFEFF -FEE00060007000380E1C1E0FFC03F00F107E8F14>I<007C00FE01CE03840380038003807FFEFF -FE0380038003800380038003800380038003800380038003807FFC7FFC0F177F9614>I<07CF00 -1FFF80383B80301800701C00701C00701C003018003838003FF00037C0007000007000003FF800 -1FFC003FFE00700F00E00380E00380E00380E003807007003C1E001FFC0007F00011197F8F14> -I<FC0000FC00001C00001C00001C00001C00001C00001C78001DFE001F86001E07001C07001C07 -001C07001C07001C07001C07001C07001C07001C07001C0700FF8FE0FF8FE01317809614>I<03 -0007800780030000000000000000007F807F800380038003800380038003800380038003800380 -03800380FFFCFFFC0E187D9714>I<FC0000FC00001C00001C00001C00001C00001C00001DFF80 -1DFF801C3C001C78001CF0001DE0001FC0001FC0001FE0001EF0001C70001C38001C38001C1C00 -FE3F80FE3F8011177F9614>107 D<FF80FF800380038003800380038003800380038003800380 -038003800380038003800380038003800380FFFEFFFE0F177E9614>I<FB8E00FFDF003CF3803C -F38038E38038E38038E38038E38038E38038E38038E38038E38038E38038E380FEFBE0FE79E013 -10808F14>I<FC7800FDFE001F86001E07001C07001C07001C07001C07001C07001C07001C0700 -1C07001C07001C0700FF8FE0FF8FE01310808F14>I<07C01FF03C78701C701CE00EE00EE00EE0 -0EE00EE00E701C783C3C781FF007C00F107E8F14>I<FCF800FDFE001F07001E03001C03801C01 -C01C01C01C01C01C01C01C01C01C01C01C03801E03001F0E001DFC001CF8001C00001C00001C00 -001C00001C00001C0000FF8000FF80001218808F14>I<FE1F00FE7F800EE3800F81000F00000F -00000E00000E00000E00000E00000E00000E00000E00000E0000FFF000FFF00011107F8F14> -114 D<0FD83FF86038C038C038F0007F803FF007F8001C6006E006F006F81CFFF8CFE00F107E8F -14>I<030007000700070007007FFCFFFC07000700070007000700070007000700070E070E070E -070C03FC00F00F157F9414>I<FC3F00FC3F001C07001C07001C07001C07001C07001C07001C07 -001C07001C07001C07001C07001C1F000FFFE003E7E01310808F14>I<FE3F80FE3F801C1C001C -1C001C1C001C1C000E38000E38000E380006300007700007700007700003E00003E00003E00011 -107F8F14>I<FF7F80FF7F80380E00380E00380E00380E0039CE0039CE0019CC001B6C001B6C00 -1A6C001A6C001E7C000E78000E780011107F8F14>I<7E3F007E3F001E38000E780007700007E0 -0003E00001C00003C00003E0000770000E78000E38001C1C00FE3F80FE3F8011107F8F14>I<FE -3F80FE3F801C1C001C1C001C1C000E1C000E38000E380007380007300007300003700003700001 -E00001E00001E00001C00001C00001C0000380007380007700007E00003C000011187F8F14>I< -3FFF7FFF700E701C7038007000E001C0038007000E001C0738077007FFFFFFFF10107F8F14>I -E /Fd 1 59 df<60F0F06004047D830B>58 D E /Fe 25 122 df<078018603030303060186018 -E01CE01CE01CE01CE01CE01CE01CE01CE01CE01CE01CE01C6018601870383030186007800E187E -9713>48 D<03000700FF0007000700070007000700070007000700070007000700070007000700 -070007000700070007000700FFF00C187D9713>I<0F80106020304038803CC01CE01C401C003C -003800380070006000C001800100020004040804100430083FF87FF8FFF80E187E9713>I<01E0 -06100C1818383038300070006000E000E7C0E860F030F018E018E01CE01CE01C601C601C701830 -183030186007C00E187E9713>54 D<40007FFE7FFC7FFC40088010801080200040004000800180 -01800100030003000300030007000700070007000700070002000F197E9813>I<078018603030 -201860186018601870103C303E600F8007C019F030F86038401CC00CC00CC00CC00C6008201018 -600FC00E187E9713>I<07801860303070306018E018E018E01CE01CE01C601C603C303C185C0F -9C001C00180018003870307060604021801F000E187E9713>I<FFE7FF0E00700E00700E00700E -00700E00700E00700E00700E00700E00700E00700E00700FFFF00E00700E00700E00700E00700E -00700E00700E00700E00700E00700E00700E00700E0070FFE7FF181A7E991D>72 -D<0FC21836200E6006C006C002C002C002E00070007E003FE01FF807FC003E000E000700038003 -80038003C002C006E004D81887E0101A7E9915>83 D<3F8070C070E020700070007007F01C7030 -707070E070E071E071E0F171FB1E3C10107E8F13>97 D<07F80C1C381C30087000E000E000E000 -E000E000E0007000300438080C1807E00E107F8F11>99 D<007E00000E00000E00000E00000E00 -000E00000E00000E00000E00000E0003CE000C3E00380E00300E00700E00E00E00E00E00E00E00 -E00E00E00E00E00E00600E00700E00381E001C2E0007CFC0121A7F9915>I<07C01C3030187018 -600CE00CFFFCE000E000E000E0006000300438080C1807E00E107F8F11>I<0FCE187330307038 -703870387038303018602FC02000600070003FF03FFC1FFE600FC003C003C003C0036006381C07 -E010187F8F13>103 D<FC00001C00001C00001C00001C00001C00001C00001C00001C00001C00 -001CF8001D0C001E0E001E0E001C0E001C0E001C0E001C0E001C0E001C0E001C0E001C0E001C0E -001C0E001C0E00FF9FC0121A7F9915>I<18003C003C001800000000000000000000000000FC00 -1C001C001C001C001C001C001C001C001C001C001C001C001C001C00FF80091A80990A>I<FCF8 -001D0C001E0E001E0E001C0E001C0E001C0E001C0E001C0E001C0E001C0E001C0E001C0E001C0E -001C0E00FF9FC012107F8F15>110 D<07E01C38300C700E6006E007E007E007E007E007E00760 -06700E381C1C3807E010107F8F13>I<FCF8001F0E001E07001C03801C03801C01C01C01C01C01 -C01C01C01C01C01C01C01C03801C03001E07001F0C001CF0001C00001C00001C00001C00001C00 -001C0000FF800012177F8F15>I<FCE01D701E701E201C001C001C001C001C001C001C001C001C -001C001C00FFC00C107F8F0F>114 D<1F2060E04020C020C020F0007F003FC01FE000F0807080 -30C030C020F0408F800C107F8F0F>I<0400040004000C000C001C003C00FFC01C001C001C001C -001C001C001C001C001C201C201C201C201C200E4003800B177F960F>I<FF1F803C06001C0400 -1C04001E0C000E08000E080007100007100007900003A00003A00001C00001C00001C000008000 -11107F8F14>118 D<FF3F803C1C001C18000E100007200007600003C00001C00001E00003E000 -027000043800083800181C00381E00FC3FC012107F8F14>120 D<FF1F803C06001C04001C0400 -1E0C000E08000E080007100007100007900003A00003A00001C00001C00001C000008000008000 -010000010000E10000E20000E4000078000011177F8F14>I E /Ff 2 42 -df<007000E001C00380078007000E001E001E003C003C003C0078007800780078007000F000F0 -00F000F000F000F000F000F000F000F000F000F000700078007800780078003C003C003C001E00 -1E000E0007000780038001C000E000700C2E7EA112>40 D<E000700038001C001E000E00070007 -80078003C003C003C001E001E001E001E000E000F000F000F000F000F000F000F000F000F000F0 -00F000F000E001E001E001E001E003C003C003C00780078007000E001E001C0038007000E0000C -2E7DA112>I E /Fg 25 123 df<0007F800007FFC0001FC0E0003F01F0007E03F000FC03F000F -C03F000FC03F000FC01E000FC00C000FC000000FC000000FC0FF80FFFFFF80FFFFFF800FC01F80 -0FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F -800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F807FF8FFF07FF8FFF01C23 -7FA220>12 D<000FFF80007FFF8001FC1F8003F03F8007E03F800FC03F800FC01F800FC01F800F -C01F800FC01F800FC01F800FC01F800FC01F80FFFFFF80FFFFFF800FC01F800FC01F800FC01F80 -0FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F -800FC01F800FC01F800FC01F800FC01F800FC01F807FF8FFF07FF8FFF01C237FA220>I<07FE00 -001FFF80003F07E0003F03F0003F01F0003F01F8001E01F8000001F8000001F800003FF80003FD -F8001F81F8003E01F8007C01F800F801F800F801F800F801F800F801F8007C02F8007E0CF8001F -F87F8007E03F8019167E951C>97 D<FF800000FF8000001F8000001F8000001F8000001F800000 -1F8000001F8000001F8000001F8000001F8000001F8000001F8000001F87F0001FBFFC001FF03E -001FC01F001F800F801F800FC01F8007C01F8007E01F8007E01F8007E01F8007E01F8007E01F80 -07E01F8007E01F8007C01F8007C01F800FC01F800F801FC01F001E707E001C3FFC00180FE0001B -237EA220>I<00FF8007FFE00F83F01F03F03E03F07E03F07C01E07C0000FC0000FC0000FC0000 -FC0000FC0000FC00007C00007E00007E00003F00301F00600FC0E007FF8000FE0014167E9519> -I<0001FF000001FF0000003F0000003F0000003F0000003F0000003F0000003F0000003F000000 -3F0000003F0000003F0000003F0000FE3F0007FFBF000FC1FF001F007F003E003F007E003F007C -003F007C003F00FC003F00FC003F00FC003F00FC003F00FC003F00FC003F00FC003F007C003F00 -7E003F003E003F001F007F000F81FF0007FF3FE001FC3FE01B237EA220>I<00FE0007FF800F83 -C01F01E03E00F07E00F07C00F87C0078FC0078FFFFF8FFFFF8FC0000FC0000FC00007C00007C00 -003E00183E00181F00300F80E003FFC000FF0015167E951A>I<00FE0F8003FF9FC00F83E3C01F -01F3C01E00F0003E00F8003E00F8003E00F8003E00F8003E00F8001E00F0001F01F0000F83E000 -0BFF800008FE000018000000180000001C0000001FFFE0001FFFFC000FFFFF0007FFFF001FFFFF -807C001FC078000FC0F80007C0F80007C0F80007C07C000F803E001F001F807E000FFFFC0001FF -E0001A217F951D>103 D<FF800000FF8000001F8000001F8000001F8000001F8000001F800000 -1F8000001F8000001F8000001F8000001F8000001F8000001F83F0001F8FFC001F987E001FA03E -001FC03F001FC03F001F803F001F803F001F803F001F803F001F803F001F803F001F803F001F80 -3F001F803F001F803F001F803F001F803F001F803F001F803F00FFF1FFE0FFF1FFE01B237DA220 ->I<1E003F007F807F807F807F803F001E00000000000000000000000000FF80FF801F801F801F -801F801F801F801F801F801F801F801F801F801F801F801F801F801F801F80FFF0FFF00C247EA3 -0F>I<FF800000FF8000001F8000001F8000001F8000001F8000001F8000001F8000001F800000 -1F8000001F8000001F8000001F8000001F80FF801F80FF801F803C001F8030001F80E0001F81C0 -001F8300001F8600001F9E00001FBE00001FFF00001FDF80001F8FC0001F07C0001F07E0001F03 -F0001F01F8001F00F8001F00FC001F007E00FFE1FFC0FFE1FFC01A237EA21E>107 -D<FF80FF801F801F801F801F801F801F801F801F801F801F801F801F801F801F801F801F801F80 -1F801F801F801F801F801F801F801F801F801F801F801F801F801F80FFF0FFF00C237EA20F>I< -FF03F803F800FF0FFE0FFE001F183F183F001F201F201F001F401FC01F801F401FC01F801F801F -801F801F801F801F801F801F801F801F801F801F801F801F801F801F801F801F801F801F801F80 -1F801F801F801F801F801F801F801F801F801F801F801F801F801F801F801F801F801F801F801F -801F80FFF0FFF0FFF0FFF0FFF0FFF02C167D9531>I<FF03F000FF0FFC001F187E001F203E001F -403F001F403F001F803F001F803F001F803F001F803F001F803F001F803F001F803F001F803F00 -1F803F001F803F001F803F001F803F001F803F001F803F00FFF1FFE0FFF1FFE01B167D9520>I< -00FF0007FFE00F81F01F00F83E007C7C003E7C003E7C003EFC003FFC003FFC003FFC003FFC003F -FC003FFC003F7C003E7E007E3E007C1F00F80F81F007FFE000FF0018167E951D>I<FF87F000FF -BFFC001FF07E001FC01F001F800F801F800FC01F800FC01F8007E01F8007E01F8007E01F8007E0 -1F8007E01F8007E01F8007E01F8007C01F800FC01F800FC01F801F801FC01F001FF07E001FBFFC -001F8FE0001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F800000FFF0 -0000FFF000001B207E9520>I<FF0F80FF1FE01F33F01F63F01F43F01F43F01FC1E01F80001F80 -001F80001F80001F80001F80001F80001F80001F80001F80001F80001F80001F8000FFF800FFF8 -0014167E9518>114 D<07F9801FFF80380780700380F00180F00180F80000FF0000FFF8007FFE -003FFF001FFF8007FF80003FC0C007C0C003C0E003C0E003C0F00380FC0F00EFFE00C3F8001216 -7E9517>I<00C00000C00000C00000C00001C00001C00003C00007C0000FC0001FC000FFFF00FF -FF000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC1800F -C1800FC1800FC1800FC18007C18007E30003FE0000FC0011207F9F16>I<FF81FF00FF81FF001F -803F001F803F001F803F001F803F001F803F001F803F001F803F001F803F001F803F001F803F00 -1F803F001F803F001F803F001F803F001F803F001F807F001F80FF000FC1BF0007FF3FE001FC3F -E01B167D9520>I<FFF01FE0FFF01FE00FC007000FC006000FE00E0007E00C0007F01C0003F018 -0003F8180001F8300001F8300000FC600000FC6000007EC000007EC000007FC000003F8000003F -8000001F0000001F0000000E0000000E00001B167F951E>I<FFF3FF87FCFFF3FF87FC1F807C00 -E00FC07C00C00FC07E00C00FE03E01C007E03F018007E07F018003F07F030003F0CF830001F8CF -860001F8CFC60001FD87C60000FD87CC0000FF03EC00007F03F800007F03F800007E01F800003E -01F000003C00F000001C00E000001800600026167F9529>I<FFF0FFC0FFF0FFC00FC01C0007E0 -380007F0700003F0E00001F8C00000FD8000007F0000007F0000003F0000001F8000003FC00000 -37E0000067F00000C3F00001C1F8000380FC000700FE000E007E00FFC1FFE0FFC1FFE01B167F95 -1E>I<FFF01FE0FFF01FE00FC007000FC006000FE00E0007E00C0007F01C0003F0180003F81800 -01F8300001F8300000FC600000FC6000007EC000007EC000007FC000003F8000003F8000001F00 -00001F0000000E0000000E0000000C0000000C00000018000078180000FC380000FC300000FC60 -000069E000007F8000001F0000001B207F951E>I<7FFFE07FFFE0780FC0701FC0601F80E03F00 -C07F00C07E00C0FC0001FC0001F80003F00007F03007E0300FC0301FC0701F80703F00607F00E0 -7E03E0FFFFE0FFFFE014167E9519>I E /Fh 22 119 df<00E00000E00000E00000E00040E040 -F0E1E0F8E3E07EEFC01FFF0007FC0003F80007FC001FFF007EEFC0F8E3E0F0E1E040E04000E000 -00E00000E00000E00013157D991A>42 D<003800007C00007C00006C0000EE0000EE0000EE0000 -EE0000C60001C70001C70001C70001C7000383800383800383800383800783C00701C007FFC007 -FFC007FFC00E00E00E00E00E00E00E00E01C00707F83FCFF83FE7F83FC171E7F9D1A>65 -D<7FFFFCFFFFFC7FFFFC0E001C0E001C0E001C0E001C0E001C0E00000E00000E07000E07000E07 -000FFF000FFF000FFF000E07000E07000E07000E00000E00000E00000E000E0E000E0E000E0E00 -0E0E000E7FFFFEFFFFFE7FFFFE171E7F9D1A>69 D<FF8FF8FF8FF8FF8FF81C01C01C01C01C01C0 -1C01C01C01C01C01C01C01C01C01C01C01C01C01C01FFFC01FFFC01FFFC01C01C01C01C01C01C0 -1C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C0FF8FF8FF8FF8FF8FF8151E7E9D1A> -72 D<FFFF80FFFF80FFFF8001C00001C00001C00001C00001C00001C00001C00001C00001C000 -01C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C000 -01C00001C000FFFF80FFFF80FFFF80111E7C9D1A>I<FE0FF8FF0FF8FF0FF81D81C01D81C01D81 -C01D81C01DC1C01CC1C01CC1C01CE1C01CE1C01C61C01C61C01C71C01C71C01C31C01C31C01C39 -C01C39C01C19C01C19C01C1DC01C0DC01C0DC01C0DC01C0DC0FF87C0FF87C0FF83C0151E7E9D1A ->78 D<0FFE003FFF807FFFC07C07C07001C0F001E0E000E0E000E0E000E0E000E0E000E0E000E0 -E000E0E000E0E000E0E000E0E000E0E000E0E000E0E000E0E000E0E000E0E000E0F001E0F001E0 -7001C07C07C07FFFC03FFF800FFE00131E7D9D1A>I<FFF000FFFC00FFFF001C0F801C07801C03 -C01C01C01C01C01C01C01C01C01C03C01C07801C0F801FFF001FFC001FFE001C0F001C07001C03 -801C03801C03801C03801C03801C03841C038E1C038E1C038EFF81FCFF81FCFF8070171E7E9D1A ->82 D<03F1C00FFDC03FFFC07C0FC07003C0E003C0E001C0E001C0E001C0E00000700000780000 -3F00001FF00007FE0000FF00000F800003C00001C00000E00000E06000E0E000E0E000E0E001C0 -F001C0FC0780FFFF80EFFE00E3F800131E7D9D1A>I<7FFFFEFFFFFEFFFFFEE0380EE0380EE038 -0EE0380EE0380E0038000038000038000038000038000038000038000038000038000038000038 -0000380000380000380000380000380000380000380000380003FF8007FFC003FF80171E7F9D1A ->I<FF01FEFF83FEFF01FE1E00F00E00E00E00E00701C00701C003838003838003C78001C70001 -C70000EE0000EE00007C00007C0000380000380000380000380000380000380000380000380000 -380000380001FF0001FF0001FF00171E7F9D1A>89 D<7FFFC0FFFFE0FFFFE07FFFC013047D7E1A ->95 D<1FF0003FFC007FFE00780F00300700000380000380007F8007FF801FFF803F8380780380 -700380E00380E00380E00380700780780F803FFFFC1FFDFC07F0FC16157D941A>97 -D<00FF8003FFC00FFFE01F01E03C00C0780000700000700000E00000E00000E00000E00000E000 -007000007000007800703C00701F01F00FFFE003FFC000FE0014157D941A>99 -D<001FC0001FC0001FC00001C00001C00001C00001C00001C00001C001F1C007FDC00FFFC01E0F -C03C07C07803C07001C0E001C0E001C0E001C0E001C0E001C0E001C0E001C07003C07003C03807 -C03E0FC01FFFFC07FDFC01F1FC161E7E9D1A>I<FE0000FE0000FE00000E00000E00000E00000E -00000E00000E00000E3E000EFF800FFFC00FC1C00F80E00F00E00E00E00E00E00E00E00E00E00E -00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E0FFE3FEFFE3FEFFE3FE171E7F9D1A> -104 D<01C00003E00003E00003E00001C0000000000000000000000000000000007FE000FFE000 -7FE00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E000 -00E00000E00000E000FFFFC0FFFFC0FFFFC0121F7C9E1A>I<FE3E00FEFF80FFFFC00FC1C00F80 -E00F00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00 -E0FFE3FEFFE3FEFFE3FE17157F941A>110 D<01F00007FC001FFF003E0F803C07807803C07001 -C0E000E0E000E0E000E0E000E0E000E0E000E0F001E07001C07803C03C07803E0F801FFF0007FC -0001F00013157D941A>I<FF83F0FF8FF8FFBFFC03FC3C03F01803E00003C00003C00003800003 -8000038000038000038000038000038000038000038000038000FFFF00FFFF80FFFF0016157E94 -1A>114 D<00C00001C00001C00001C00001C00001C00001C0007FFFE0FFFFE0FFFFE001C00001 -C00001C00001C00001C00001C00001C00001C00001C00001C00001C07001C07001C07001C07000 -E0E000FFE0007FC0001F00141C7F9B1A>116 D<7FC7FCFFC7FE7FC7FC0E00E00E00E00F01E007 -01C00701C00783C003838003838003838001C70001C70001C70000EE0000EE0000EE00007C0000 -7C0000380017157F941A>118 D E /Fi 41 123 df<0003FC00003FFE00007E070001F80F8003 -F01F8003E01F8007E01F8007E01F8007E01F8007E0060007E0000007E0000007E0000007E0FFC0 -FFFFFFC0FFFFFFC007E00FC007E00FC007E00FC007E00FC007E00FC007E00FC007E00FC007E00F -C007E00FC007E00FC007E00FC007E00FC007E00FC007E00FC007E00FC007E00FC007E00FC007E0 -0FC007E00FC007E00FC07FFC7FFC7FFC7FFC1E267FA522>12 D<3C7EFFFFFFFF7E3C08087C8711 ->46 D<001C00003C0000FC00FFFC00FFFC0000FC0000FC0000FC0000FC0000FC0000FC0000FC00 -00FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC00 -00FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC007FFFFC7FFFFC16237CA21F>49 -D<01FF0007FFC01E07F03803F86001FC7C00FEFE00FEFE00FFFE007FFE007F7C007F3800FF0000 -FF0000FE0000FE0001FC0001F80003F00007E0000780000F00001E00003C0000700000E00301C0 -030380070700060600060FFFFE1FFFFE3FFFFE7FFFFCFFFFFCFFFFFC18237DA21F>I<01FF0007 -FFE01E03F03801F83C01FC7E00FE7E00FE7E00FE3E00FE1C01FE0001FC0001FC0003F80007F000 -0FC001FF0001FF000007E00001F00001F80000FC0000FE0000FF0000FF1000FF7C00FFFE00FFFE -00FFFE00FEFE00FE7C01FC7001F83E07F00FFFC001FF0018237DA21F>I<000038000000780000 -0078000000F8000001F8000003F8000007F8000006F800000CF800001CF8000038F8000030F800 -0060F80000E0F80001C0F8000180F8000300F8000700F8000E00F8001C00F8001800F8003000F8 -007000F800E000F800FFFFFFC0FFFFFFC00001F8000001F8000001F8000001F8000001F8000001 -F8000001F800007FFFC0007FFFC01A237EA21F>I<18000C1F007C1FFFF81FFFF01FFFE01FFFC0 -1FFF801FFE0018000018000018000018000018000018FF001BFFE01F01F01C00F80800FC00007E -00007E00007E00007F00007F78007FFC007FFC007FFC007FFC007EF8007E6000FC7000FC3801F8 -1E07E007FFC001FE0018237DA21F>I<001FC0007FF001F83803E00C07803E0F807E1F007E3F00 -7E3F007E7E003C7E00007E00007E0000FE3FC0FE7FF0FE80F8FF80FCFF007CFF007EFE007EFE00 -7FFE007FFE007FFE007F7E007F7E007F7E007F7E007F3E007E3F007E1F007C0F80F807C1F003FF -C0007F0018237DA21F>I<300000003C0000003FFFFFC03FFFFFC03FFFFF807FFFFF007FFFFE00 -7FFFFC006000180060001800E0003000C0006000C000C000000180000001800000030000000700 -0000060000000E0000001E0000001E0000001E0000003C0000003C0000007C0000007C0000007C -0000007C000000FC000000FC000000FC000000FC000000FC000000FC000000FC00000078000000 -3000001A257DA41F>I<00001C00000000001C00000000003E00000000003E00000000003E0000 -0000007F00000000007F0000000000FF8000000000FF8000000000FF80000000019FC000000001 -9FC0000000031FE0000000030FE0000000030FE00000000607F00000000607F00000000C07F800 -00000C03F80000001C03FC0000001801FC0000001801FC0000003001FE0000003000FE0000007F -FFFF0000007FFFFF00000060007F000000C0007F800000C0003F800001C0003FC0000180001FC0 -000180001FC0000300000FE0000300000FE0000780000FF000FFF801FFFF80FFF801FFFF802925 -7EA42E>65 D<FFFFFFE00000FFFFFFFC000003F800FF000003F8001FC00003F80007E00003F800 -03F00003F80001F80003F80001FC0003F80000FC0003F80000FE0003F80000FE0003F800007F00 -03F800007F0003F800007F0003F800007F8003F800007F8003F800007F8003F800007F8003F800 -007F8003F800007F8003F800007F8003F800007F8003F800007F8003F800007F8003F800007F00 -03F800007F0003F800007F0003F80000FE0003F80000FE0003F80001FC0003F80001F80003F800 -03F00003F80007E00003F8001FC00003F800FF8000FFFFFFFE0000FFFFFFE0000029257EA42F> -68 D<FFFFFFFF00FFFFFFFF0003F8007F0003F8000F8003F800078003F800038003F800038003 -F800018003F800018003F800018003F80000C003F80600C003F80600C003F806000003F8060000 -03F80E000003F81E000003FFFE000003FFFE000003F81E000003F80E000003F806000003F80600 -0003F806006003F806006003F800006003F80000C003F80000C003F80000C003F80000C003F800 -01C003F80003C003F80003C003F8000F8003F8003F80FFFFFFFF80FFFFFFFF8023257EA428>I< -FFFFFFFE00FFFFFFFE0003F800FE0003F8001F0003F8000F0003F800070003F800070003F80003 -0003F800030003F800030003F800018003F806018003F806018003F806000003F806000003F80E -000003F81E000003FFFE000003FFFE000003F81E000003F80E000003F806000003F806000003F8 -06000003F806000003F800000003F800000003F800000003F800000003F800000003F800000003 -F800000003F800000003F800000003F8000000FFFFF00000FFFFF0000021257EA427>I<FFFFE0 -FFFFE0FFFFE0FFFFE003F80003F80003F80003F80003F80003F80003F80003F80003F80003F800 -03F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F800 -03F80003F80003F80003F80003F80003F80003F80003FFFFFFF80003FFFFFFF80003F80003F800 -03F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F800 -03F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F800 -03F80003F80003F80003F800FFFFE0FFFFE0FFFFE0FFFFE02B257EA430>72 -D<FFFFE0FFFFE003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F8 -0003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F8 -0003F80003F80003F80003F80003F80003F80003F80003F80003F800FFFFE0FFFFE013257EA417 ->I<FFFFF000FFFFF00003F8000003F8000003F8000003F8000003F8000003F8000003F8000003 -F8000003F8000003F8000003F8000003F8000003F8000003F8000003F8000003F8000003F80000 -03F8000003F8000003F8000003F8000003F8000603F8000603F8000603F8000C03F8000C03F800 -0C03F8001C03F8001C03F8003C03F8007C03F800F803F803F8FFFFFFF8FFFFFFF81F257EA425> -76 D<FFF8000000FFF8FFFC000001FFF803FC000001FE00037E0000037E00037E0000037E0003 -7E0000037E00033F0000067E00033F0000067E00031F80000C7E00031F80000C7E00030FC00018 -7E00030FC000187E000307E000307E000307E000307E000307E000307E000303F000607E000303 -F000607E000301F800C07E000301F800C07E000300FC01807E000300FC01807E0003007E03007E -0003007E03007E0003007E03007E0003003F06007E0003003F06007E0003001F8C007E0003001F -8C007E0003000FD8007E0003000FD8007E00030007F0007E00030007F0007E00030007F0007E00 -030003E0007E00078003E0007E00FFFC01C01FFFF8FFFC01C01FFFF835257EA43A>I<00FF0080 -07FFE3800F80F7801E001F803C000F807800078078000380F8000380F8000180F8000180FC0001 -80FC000000FF0000007FE000007FFF00003FFFE0003FFFF8001FFFFE0007FFFF0003FFFF80007F -FF800003FFC000003FC000000FE0000007E0000007E0C00003E0C00003E0C00003E0C00003C0E0 -0003C0F00007C0F8000780FC000F00FFC03E00E3FFF800803FE0001B257DA422>83 -D<FFFF83FFFE01FFF0FFFF83FFFE01FFF007F0001FC0000F0007F0001FC000060003F8000FE000 -0C0003F8000FE0000C0003FC000FF0001C0001FC0007F000180001FC0007F000180000FE000FF8 -00300000FE000FF800300000FE000FFC003000007F0019FC006000007F0019FC006000007F8039 -FE00E000003F8030FE00C000003F8030FE00C000001FC0607F018000001FC0607F018000001FE0 -607F818000000FE0C03F830000000FE0C03F830000000FF1C03FC700000007F1801FC600000007 -F1801FC600000003FB000FEC00000003FB000FEC00000003FF000FFC00000001FE0007F8000000 -01FE0007F800000001FE0007F800000000FC0003F000000000FC0003F000000000780001E00000 -0000780001E000000000780001E000000000300000C000003C257FA43F>87 -D<07FF00001FFFC0003E03E0003F01F0003F01F8003F00FC001E00FC000000FC000000FC000000 -FC00003FFC0003FCFC000FC0FC003F00FC007E00FC007E00FC00FC00FC00FC00FC00FC00FC00FC -017C007E017C003F067C001FFC3FE007F01FE01B187E971E>97 D<FFC00000FFC000000FC00000 -0FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000 -000FC000000FC3F8000FCFFE000FF81F800FE00FC00FC007E00FC007E00FC003F00FC003F00FC0 -03F80FC003F80FC003F80FC003F80FC003F80FC003F80FC003F80FC003F80FC003F00FC003F00F -C007E00FC007C00FE00FC00F383F000E1FFE000C07F0001D267EA522>I<007FE003FFF807C07C -1F80FC1F00FC3F00FC7E00787E0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000 -7E00007F00003F000C1F800C1FC01807E07003FFE0007F0016187E971B>I<0001FF800001FF80 -00001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F -8000001F8000001F80007F1F8003FFDF8007E0FF801F803F803F001F803F001F807E001F807E00 -1F80FE001F80FE001F80FE001F80FE001F80FE001F80FE001F80FE001F80FE001F807E001F807E -001F803F001F803F003F801F807F800FC0FF8003FF9FF800FE1FF81D267EA522>I<007F0003FF -C007C1F00F80F81F00F83F007C7E007C7E007EFE007EFE007EFFFFFEFFFFFEFE0000FE0000FE00 -007E00007E00007E00063F00061F000C0F801807E07003FFE0007F8017187E971C>I<000FC000 -7FF000F8F001F1F803F1F803E1F807E0F007E00007E00007E00007E00007E00007E00007E000FF -FF00FFFF0007E00007E00007E00007E00007E00007E00007E00007E00007E00007E00007E00007 -E00007E00007E00007E00007E00007E00007E00007E00007E0007FFF007FFF0015267EA513>I< -01FF07C007FFDFE00F83F1E01F01F1E03E00F8007E00FC007E00FC007E00FC007E00FC007E00FC -007E00FC003E00F8001F01F0000F83E0000FFFC00011FF00003000000030000000380000003C00 -00003FFFE0001FFFFC001FFFFE000FFFFF001FFFFF803C003F8078000FC0F80007C0F80007C0F8 -0007C0F80007C07C000F803E001F001F807E0007FFF80000FFC0001B247E971F>I<FFC00000FF -C000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC00000 -0FC000000FC000000FC000000FC1F8000FC7FE000FCC3F000FD01F000FF01F800FE01F800FE01F -800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC0 -1F800FC01F800FC01F800FC01F800FC01F800FC01F80FFFCFFF8FFFCFFF81D267DA522>I<0F00 -1F803FC03FC03FC03FC01F800F000000000000000000000000000000FFC0FFC00FC00FC00FC00F -C00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC0FFF8FFF80D27 -7EA611>I<FFC0FFC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC0 -0FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC0FF -FCFFFC0E267EA511>108 D<FF81FC01FC00FF87FF07FF000F8C1F8C1F800F980F980F800FB00F -F00FC00FA00FE00FC00FA00FE00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC0 -0FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00F -C00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC0FFFCFFFCFFFCFFFCFFFCFFFC -2E187D9733>I<FF81F800FF87FE000F8C3F000F901F000FB01F800FA01F800FA01F800FC01F80 -0FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F -800FC01F800FC01F800FC01F800FC01F80FFFCFFF8FFFCFFF81D187D9722>I<007F800003FFF0 -0007C0F8001F807E003F003F003F003F007E001F807E001F80FE001FC0FE001FC0FE001FC0FE00 -1FC0FE001FC0FE001FC0FE001FC0FE001FC07E001F807E001F803F003F003F003F001F807E000F -C0FC0003FFF000007F80001A187E971F>I<FFC3F800FFCFFE000FF83F800FE00FC00FC00FE00F -C007E00FC007F00FC003F00FC003F80FC003F80FC003F80FC003F80FC003F80FC003F80FC003F8 -0FC003F80FC007F00FC007F00FC007E00FC00FC00FE01FC00FF83F000FDFFE000FC7F0000FC000 -000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC00000FFFC0000FFFC -00001D237E9722>I<FF87C0FF8FF00F98F80FB1F80FA1F80FA1F80FE0F00FC0000FC0000FC000 -0FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC000FFFE00 -FFFE0015187E9719>114 D<07F9801FFF803C0F80700380F00180F00180F00180FC0000FF8000 -7FFC007FFE003FFF800FFFC003FFC0001FE00003E0C001E0C001E0E001E0E001C0F003C0FC0780 -EFFF00C3FC0013187E9718>I<00600000600000600000600000E00000E00001E00001E00003E0 -0007E0001FE000FFFFC0FFFFC007E00007E00007E00007E00007E00007E00007E00007E00007E0 -0007E00007E00007E00007E06007E06007E06007E06007E06007E06003E0C003F0C001FF80007E -0013237FA218>I<FFC1FF80FFC1FF800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F -800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC0 -1F800FC03F800FC03F8007C07F8007E0DF8003FF9FF800FE1FF81D187D9722>I<FFF80FF8FFF8 -0FF80FC003C00FE0018007E0030007E0030003F0060003F0060003F80E0001F80C0001FC1C0000 -FC180000FE1800007E3000007E3000003F6000003F6000001FC000001FC000001FC000000F8000 -000F800000070000000700001D187F9720>I<FFF83FF0FFF83FF00FC00F0007E00C0003F01C00 -03F8380001FC700000FCE000007EC000003F8000003F8000001F8000000FC000001FE000001FF0 -000033F8000071F80000E0FC0001C07E0003807F0003003F000F001F80FFC07FF8FFC07FF81D18 -7F9720>120 D<FFF80FF8FFF80FF80FC003C00FE0018007E0030007E0030003F0060003F00600 -03F80E0001F80C0001FC1C0000FC180000FE1800007E3000007E3000003F6000003F6000001FC0 -00001FC000001FC000000F8000000F800000070000000700000006000000060000000C0000300C -0000781C0000FC180000FC380000FC70000078E000007FC000001F0000001D237F9720>I<3FFF -F83FFFF83E03F03807F0300FE0700FC0701F80603F80603F00607E0000FE0000FC0001F80003F8 -1803F01807E0180FE0180FC0381F80303F80707F00707E01F0FFFFF0FFFFF015187E971B>I -E /Fj 29 122 df<0003F07C001E0DC600380F0F00701E0F00E01E0E00E00C0001C01C0001C01C -0001C01C0001C01C0001C01C00038038007FFFFFC0038038000380380003803800038038000700 -700007007000070070000700700007007000070070000E00E0000E00E0000E00E0000E00E0000E -00E0000E00E0001C01C0001E01E000FF8FFE0020207E9F1B>11 D<0003E0001C1800381800703C -00E03C00E03801C00001C00001C00001C00001C0000380007FFFF0038070038070038070038070 -0700E00700E00700E00700E00700E00700E00E01C00E01C00E01C00E01C00E01C00E01C01C0380 -1E03C0FF0FF816207E9F19>I<0003F03F00001E09E08000380F80C000701F01E000E03E01E000 -E01E01C001C01C000001C01C000001C01C000001C01C000001C01C000003803800007FFFFFFF80 -038038038003803803800380380380038038038007007007000700700700070070070007007007 -00070070070007007007000E00E00E000E00E00E000E00E00E000E00E00E000E00E00E000E00E0 -0E001C01C01C001E01E01E00FF8FF8FFC023207E9F26>14 D<0020000060000060000060000060 -007061C03843800E4E0007580001E00001E00006B8001C9C00708700E083800180000180000180 -0001800001000012147AA117>42 D<FFC0FFC00A027D8A0F>45 D<000C001C00FC0F3800380038 -00380038003800700070007000700070007000E000E000E000E000E000E001C001C001C001C001 -C001C0038003C0FFFE0F1E7C9D17>49 D<003F8000C1E00100F00200780400780400780F007C0F -807C0F807C0F00780600780000F80000F00001E00001C0000380000700000E00001C0000380000 -600000C0000180000300200600200800401000403FFFC07FFF80FFFF80161E7E9D17>I<07F800 -0C0C001E06001E07001C070000070000070000070000FF0007C7001E07003C0E00780E00F00E10 -F00E10F00E10F01E10F02E20784F401F878014147D9317>97 D<01FC07060E0F1C0F380E780070 -00F000F000F000F000E000E000E000E000F0027004300818300FC010147C9314>99 -D<0000700003F00000F00000700000700000E00000E00000E00000E00000E00000E00001C000F9 -C00305C00E03C01C03C03801C0780380700380F00380F00380F00380F00380E00700E00700E007 -00E00700E00700700F00301E00186F000F8FE014207C9F19>I<00F800070E000E07001C070038 -0380780380700380F00380F00380FFFF80F00000E00000E00000E00000E00000F0010070020030 -04001C180007E00011147D9314>I<0007800018C00031E00061E000E1C000C00001C00001C000 -01C00001C00001C0000380007FF800038000038000038000038000070000070000070000070000 -0700000700000E00000E00000E00000E00000E00000E00001C00001E0000FFE00013207E9F0E> -I<00000E003E1100E1A301C1C20381E00780E00701E00F01E00F01E00F01E00703C00703800787 -0004FC000800000800001800001C00000FFF000FFFC007FFE01800F0300030600030C00030C000 -30C000306000603000C01C070007FC00181F809417>I<00E00007E00001E00000E00000E00001 -C00001C00001C00001C00001C00001C000038000038F800390E003A0E003C0600380600780E007 -00E00700E00700E00700E00700E00E01C00E01C00E01C00E01C00E01C00E01C01C03801E03C0FF -CFF815207E9F19>I<01C003E003E003C0018000000000000000000000000003801F8007800380 -03800700070007000700070007000E000E000E000E000E000E001C001E00FF800B1F7F9E0C>I< -00E007E001E000E000E001C001C001C001C001C001C00380038003800380038003800700070007 -000700070007000E000E000E000E000E000E001C001E00FFC00B207F9F0C>108 -D<0387C07C001F9861860007A072070003C0340300038038030007807807000700700700070070 -07000700700700070070070007007007000E00E00E000E00E00E000E00E00E000E00E00E000E00 -E00E000E00E00E001C01C01C001E01E01E00FFCFFCFFC022147E9326>I<038F801F90E007A0E0 -03C0600380600780E00700E00700E00700E00700E00700E00E01C00E01C00E01C00E01C00E01C0 -0E01C01C03801E03C0FFCFF815147E9319>I<00FC000387000E01801C00C03800E03800E07000 -F0F000F0F000F0F000F0F000F0E001E0E001E0E001C0E003C0F00380700700380E001C1C0007E0 -0014147D9317>I<00E3E007EC3800F01C00E01E00E00E01C00E01C00F01C00F01C00F01C00F01 -C00F03801E03801E03801C03803C0380380380700740E00721C0071F000700000700000700000E -00000E00000E00000E00001E0000FFC000181D809319>I<00F040038CC00E04C01C03C03C03C0 -780380780380F00380F00380F00380F00380E00700E00700E00700F00700F00F00700F00301E00 -186E000F8E00000E00000E00000E00001C00001C00001C00001C00003C0001FF80121D7C9318> -I<038E001FB38007C78003C7800383000780000700000700000700000700000700000E00000E00 -000E00000E00000E00000E00001C00001E0000FFE00011147E9312>I<01F2060E080618061802 -380438001E001FE00FF003F8003C401C400C400C600C6018E010D0608FC00F147E9312>I<0080 -010001000100030007000F001E00FFF80E000E000E000E001C001C001C001C001C001C00380038 -203820382038203840384018800F000D1C7C9B12>I<1C0380FC1F803C07801C03801C03803807 -00380700380700380700380700380700700E00700E00700E00700E00701E00701E00703C00305E -001F9FC012147B9319>I<FF83F81E00E01C00C01C00800E00800E01000E02000E02000F040007 -040007080007080007100003900003A00003E00003C00003800001800001000015147C9318>I< -FF9FE1FC3E0780701C0300601C0300401C0380401C0380800E0780800E0581000E0981000E09C2 -000E11C2000731C4000721C4000760C8000740C8000780F0000780F0000300E000030060000200 -40001E147C9321>I<1FF0FF03C07801C06001C04000E08000E180007300007600003C00003C00 -001C00002E00004E000087000107000203800603800C01C03E03E0FF07FC18147F9318>I<0FF8 -3F8001E00E0001C00C0001C0080000E0180000E0100000E0200000E0200000F040000070400000 -708000007080000071000000390000003A0000003E0000003C0000003800000018000000100000 -0010000000200000002000000040000070C00000F0800000F1000000E20000007C000000191D80 -9318>I E /Fk 36 122 df<0001C0000003C000000FC000007FC0001FFFC000FFFFC000FFBFC0 -00E03FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003F -C000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC00000 -3FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000 -003FC000003FC000003FC000003FC000003FC000003FC000003FC0007FFFFFE07FFFFFE07FFFFF -E01B2E7AAD28>49 D<003FE00001FFFE0007FFFF800F80FFC01E003FE038001FF07C000FF87E00 -07FCFF0007FCFF8007FEFF8007FEFF8003FEFF8003FE7F0003FE3E0007FE000007FE000007FC00 -0007FC00000FF800000FF800000FF000001FE000001FC000003F8000007F0000007E000000F800 -0001F0000003E0000007C000000F0000001E000E003C000E0038000E0070001E00E0001C01C000 -1C0300003C07FFFFFC0FFFFFFC1FFFFFFC3FFFFFFC7FFFFFF8FFFFFFF8FFFFFFF8FFFFFFF81F2E -7CAD28>I<0000007800000000000078000000000000FC000000000000FC000000000000FC0000 -00000001FE000000000001FE000000000003FF000000000003FF000000000007FF800000000007 -FF800000000007FF80000000000FFFC0000000000E7FC0000000001E7FE0000000001C3FE00000 -00001C3FE000000000383FF000000000381FF000000000781FF800000000700FF800000000700F -F800000000E00FFC00000000E007FC00000001E007FE00000001C003FE00000001C003FE000000 -038003FF000000038001FF000000078001FF800000070000FF800000070000FF8000000FFFFFFF -C000000FFFFFFFC000001FFFFFFFE000001C00003FE000003C00003FF000003800001FF0000038 -00001FF000007000001FF800007000000FF80000F000000FFC0000E0000007FC0000E0000007FC -0001C0000007FE0003E0000003FE00FFFF8001FFFFFCFFFF8001FFFFFCFFFF8001FFFFFC36317D -B03D>65 D<FFFFFFFFE00000FFFFFFFFFE0000FFFFFFFFFF800000FF0000FFC00000FF00003FF0 -0000FF00001FF80000FF00000FF80000FF000007FC0000FF000007FC0000FF000007FE0000FF00 -0003FE0000FF000003FE0000FF000003FE0000FF000003FE0000FF000007FE0000FF000007FE00 -00FF000007FC0000FF000007FC0000FF00000FF80000FF00001FF00000FF00003FE00000FF0000 -FF800000FF000FFF000000FFFFFFFE000000FFFFFFFFC00000FF00001FF00000FF000007F80000 -FF000003FE0000FF000003FE0000FF000001FF0000FF000001FF8000FF000000FF8000FF000000 -FFC000FF000000FFC000FF000000FFC000FF000000FFC000FF000000FFC000FF000000FFC000FF -000000FFC000FF000000FF8000FF000001FF8000FF000001FF0000FF000003FF0000FF000007FE -0000FF00000FFC0000FF00007FF800FFFFFFFFFFE000FFFFFFFFFF8000FFFFFFFFFC000032317E -B039>I<000003FF80018000003FFFF003800001FFFFFC07800007FF003F0F80001FF800079F80 -003FC00001FF8000FF800000FF8001FE0000007F8003FC0000003F8007FC0000001F8007F80000 -000F800FF00000000F801FF000000007801FF000000007803FE000000007803FE000000003807F -E000000003807FE000000003807FC000000000007FC00000000000FFC00000000000FFC0000000 -0000FFC00000000000FFC00000000000FFC00000000000FFC00000000000FFC00000000000FFC0 -0000000000FFC000000000007FC000000000007FC000000000007FE000000000007FE000000003 -803FE000000003803FE000000003801FF000000003801FF000000007800FF0000000070007F800 -0000070007FC0000000E0003FC0000001E0001FE0000001C0000FF8000007800003FC00000F000 -001FF80003E0000007FF003F80000001FFFFFE000000003FFFF80000000003FF80000031317CB0 -3A>I<FFFFFFFFFFE0FFFFFFFFFFE0FFFFFFFFFFE000FF80007FE000FF80000FF000FF800003F0 -00FF800001F000FF800001F000FF800000F000FF800000F000FF8000007000FF8000007000FF80 -00007000FF8000003800FF8000003800FF8007003800FF8007003800FF8007000000FF80070000 -00FF8007000000FF800F000000FF801F000000FF803F000000FFFFFF000000FFFFFF000000FFFF -FF000000FF803F000000FF801F000000FF800F000000FF8007000000FF8007000000FF80070000 -00FF8007000000FF8007000000FF8000000000FF8000000000FF8000000000FF8000000000FF80 -00000000FF8000000000FF8000000000FF8000000000FF8000000000FF8000000000FF80000000 -00FF80000000FFFFFFE00000FFFFFFE00000FFFFFFE000002D317EB033>70 -D<000003FF00030000007FFFF007000001FFFFFC0F000007FF007E1F00001FF0000FBF00007FC0 -0003FF0000FF800001FF0001FE0000007F0003FC0000007F0007FC0000003F000FF80000001F00 -0FF00000001F001FF00000000F001FF00000000F003FE000000007003FE000000007007FE00000 -0007007FE000000007007FC00000000000FFC00000000000FFC00000000000FFC00000000000FF -C00000000000FFC00000000000FFC00000000000FFC00000000000FFC00000000000FFC0000000 -0000FFC00000000000FFC00007FFFFFC7FC00007FFFFFC7FE00007FFFFFC7FE0000001FF003FE0 -000001FF003FE0000001FF001FF0000001FF001FF0000001FF000FF0000001FF000FF8000001FF -0007FC000001FF0003FC000001FF0001FE000001FF0000FF800001FF00007FC00003FF00001FF8 -00077F000007FF003E3F000001FFFFFC1F0000007FFFF00F00000003FF80030036317CB03F>I< -FFFFFF807FFFFFC0FFFFFF807FFFFFC0FFFFFF807FFFFFC000FF8000007FC00000FF8000007FC0 -0000FF8000007FC00000FF8000007FC00000FF8000007FC00000FF8000007FC00000FF8000007F -C00000FF8000007FC00000FF8000007FC00000FF8000007FC00000FF8000007FC00000FF800000 -7FC00000FF8000007FC00000FF8000007FC00000FF8000007FC00000FF8000007FC00000FF8000 -007FC00000FF8000007FC00000FF8000007FC00000FFFFFFFFFFC00000FFFFFFFFFFC00000FFFF -FFFFFFC00000FF8000007FC00000FF8000007FC00000FF8000007FC00000FF8000007FC00000FF -8000007FC00000FF8000007FC00000FF8000007FC00000FF8000007FC00000FF8000007FC00000 -FF8000007FC00000FF8000007FC00000FF8000007FC00000FF8000007FC00000FF8000007FC000 -00FF8000007FC00000FF8000007FC00000FF8000007FC00000FF8000007FC00000FF8000007FC0 -0000FF8000007FC00000FF8000007FC000FFFFFF807FFFFFC0FFFFFF807FFFFFC0FFFFFF807FFF -FFC03A317EB03F>I<FFFFFF80FFFFFF80FFFFFF8000FF800000FF800000FF800000FF800000FF -800000FF800000FF800000FF800000FF800000FF800000FF800000FF800000FF800000FF800000 -FF800000FF800000FF800000FF800000FF800000FF800000FF800000FF800000FF800000FF8000 -00FF800000FF800000FF800000FF800000FF800000FF800000FF800000FF800000FF800000FF80 -0000FF800000FF800000FF800000FF800000FF800000FF800000FF800000FF800000FF8000FFFF -FF80FFFFFF80FFFFFF8019317EB01E>I<FFFF800001FFFFC0FFFFC00001FFFFC0FFFFE00001FF -FFC000FFF0000003E00000FFF8000001C00000EFFC000001C00000E7FC000001C00000E7FE0000 -01C00000E3FF000001C00000E1FF800001C00000E0FFC00001C00000E07FE00001C00000E03FE0 -0001C00000E03FF00001C00000E01FF80001C00000E00FFC0001C00000E007FE0001C00000E003 -FE0001C00000E001FF0001C00000E001FF8001C00000E000FFC001C00000E0007FE001C00000E0 -003FF001C00000E0001FF001C00000E0001FF801C00000E0000FFC01C00000E00007FE01C00000 -E00003FF01C00000E00001FF81C00000E00000FF81C00000E00000FFC1C00000E000007FE1C000 -00E000003FF1C00000E000001FF9C00000E000000FFDC00000E0000007FDC00000E0000007FFC0 -0000E0000003FFC00000E0000001FFC00000E0000000FFC00000E00000007FC00000E00000003F -C00000E00000003FC00000E00000001FC00000E00000000FC00001F000000007C000FFFFE00000 -03C000FFFFE0000001C000FFFFE0000001C0003A317EB03F>78 D<FFFFFFFFE000FFFFFFFFFE00 -FFFFFFFFFF8000FF8000FFE000FF80003FF000FF80000FF800FF800007FC00FF800007FC00FF80 -0003FE00FF800003FE00FF800003FF00FF800003FF00FF800003FF00FF800003FF00FF800003FF -00FF800003FF00FF800003FF00FF800003FE00FF800003FE00FF800007FC00FF800007F800FF80 -000FF800FF80003FE000FF8000FFC000FFFFFFFF0000FFFFFFF80000FF8000000000FF80000000 -00FF8000000000FF8000000000FF8000000000FF8000000000FF8000000000FF8000000000FF80 -00000000FF8000000000FF8000000000FF8000000000FF8000000000FF8000000000FF80000000 -00FF8000000000FF8000000000FF8000000000FF8000000000FF80000000FFFFFF800000FFFFFF -800000FFFFFF80000030317EB037>80 D<7FFFFFFFFFFF007FFFFFFFFFFF007FFFFFFFFFFF007F -C00FF801FF007E000FF8003F007C000FF8001F0078000FF8000F0078000FF8000F0070000FF800 -0700F0000FF8000780F0000FF8000780F0000FF8000780E0000FF8000380E0000FF8000380E000 -0FF8000380E0000FF8000380E0000FF800038000000FF800000000000FF800000000000FF80000 -0000000FF800000000000FF800000000000FF800000000000FF800000000000FF800000000000F -F800000000000FF800000000000FF800000000000FF800000000000FF800000000000FF8000000 -00000FF800000000000FF800000000000FF800000000000FF800000000000FF800000000000FF8 -00000000000FF800000000000FF800000000000FF800000000000FF800000000000FF800000000 -000FF800000000000FF800000000000FF8000000007FFFFFFF0000007FFFFFFF0000007FFFFFFF -000031307DAF38>84 D<FFFFFF8003FFFF80FFFFFF8003FFFF80FFFFFF8003FFFF8000FF800000 -07C00000FF80000003800000FF80000003800000FF80000003800000FF80000003800000FF8000 -0003800000FF80000003800000FF80000003800000FF80000003800000FF80000003800000FF80 -000003800000FF80000003800000FF80000003800000FF80000003800000FF80000003800000FF -80000003800000FF80000003800000FF80000003800000FF80000003800000FF80000003800000 -FF80000003800000FF80000003800000FF80000003800000FF80000003800000FF800000038000 -00FF80000003800000FF80000003800000FF80000003800000FF80000003800000FF8000000380 -0000FF80000003800000FF80000003800000FF800000038000007F800000038000007F80000007 -0000007FC00000070000003FC000000E0000003FC000000E0000001FE000001C0000000FF00000 -3800000007F800007000000003FC0001E000000000FF801FC0000000003FFFFF80000000000FFF -FE000000000000FFE000000039317EB03E>I<FFFFFC0000FFFFFFFFFC0000FFFFFFFFFC0000FF -FF03FF00000003C001FF000000038001FF800000078000FF800000070000FFC000000700007FC0 -00000E00007FC000000E00007FE000001E00003FE000001C00003FF000003C00001FF000003800 -001FF800003800000FF800007000000FFC000070000007FC0000E0000007FC0000E0000007FE00 -01E0000003FE0001C0000003FF0003C0000001FF000380000001FF800380000000FF8007000000 -00FFC00700000000FFC00F000000007FC00E000000007FE01E000000003FE01C000000003FF03C -000000001FF038000000001FF838000000000FF870000000000FF870000000000FFCF000000000 -07FCE00000000007FFE00000000003FFC00000000003FFC00000000001FF800000000001FF8000 -00000000FF000000000000FF000000000000FF0000000000007E0000000000007E000000000000 -3C0000000000003C00000038317EB03D>I<00FFF0000003FFFE00000F803F80000FC00FE0001F -E007F0001FE007F0001FE003F8000FC003FC00078003FC00000003FC00000003FC00000003FC00 -000003FC000000FFFC00001FFFFC0000FFE3FC0003FC03FC000FF003FC001FC003FC003FC003FC -007F8003FC007F8003FC00FF0003FC00FF0003FC00FF0003FC00FF0007FC00FF0007FC007F800D -FC003FC019FE001FE070FFF007FFE07FF000FF803FF024207E9F27>97 D<01F8000000FFF80000 -00FFF8000000FFF80000000FF800000007F800000007F800000007F800000007F800000007F800 -000007F800000007F800000007F800000007F800000007F800000007F800000007F800000007F8 -00000007F83FE00007F8FFFC0007FBE07F0007FF001F8007FE000FC007FC000FE007F80007F007 -F80007F807F80007F807F80003FC07F80003FC07F80003FC07F80003FE07F80003FE07F80003FE -07F80003FE07F80003FE07F80003FE07F80003FE07F80003FE07F80003FC07F80003FC07F80003 -FC07F80007F807F80007F807F80007F007FC000FE007FE000FC007E7003F8007C3C0FE000780FF -F80007003FC00027327EB12D>I<000FFF00007FFFC001FC01F003F003F007E007F80FE007F81F -C007F83FC003F03FC001E07F8000007F8000007F800000FF800000FF800000FF800000FF800000 -FF800000FF800000FF800000FF8000007F8000007F8000007F8000003FC0001C3FC0001C1FC000 -380FE0003807E0007003F001E001FC07C0007FFF00000FF8001E207D9F24>I<0000000FC00000 -07FFC0000007FFC0000007FFC00000007FC00000003FC00000003FC00000003FC00000003FC000 -00003FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC0 -0000003FC00007F83FC0003FFF3FC000FE07BFC003F801FFC007E0007FC00FE0007FC01FC0003F -C03FC0003FC03FC0003FC07F80003FC07F80003FC07F80003FC0FF80003FC0FF80003FC0FF8000 -3FC0FF80003FC0FF80003FC0FF80003FC0FF80003FC0FF80003FC07F80003FC07F80003FC07F80 -003FC03FC0003FC03FC0003FC01FC0003FC00FE0007FC007E000FFC003F003FFE001FC0F3FFE00 -7FFE3FFE000FF03FFE27327DB12D>I<000FFC00007FFF8001FC0FC003F003E007E001F00FE001 -F81FC000FC3FC000FE3FC000FE7F80007E7F80007F7F80007FFF80007FFF80007FFFFFFFFFFFFF -FFFFFF800000FF800000FF800000FF8000007F8000007F8000007F8000003FC000071FC000071F -C0000E0FE0000E07F0001C03F8007800FE03E0003FFFC00007FE0020207E9F25>I<0001FE0000 -0FFF80001FC3C0007F07E000FE0FF001FE0FF001FC0FF003FC0FF003FC07E003FC018003FC0000 -03FC000003FC000003FC000003FC000003FC000003FC000003FC0000FFFFFC00FFFFFC00FFFFFC -0003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC -000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003 -FC000003FC000003FC000003FC000003FC000003FC000003FC00007FFFF0007FFFF0007FFFF000 -1C327EB119>I<001FF007C000FFFE3FE001F83F79F007E00FC3F00FE00FE1F00FC007E0E01FC0 -07F0001FC007F0003FC007F8003FC007F8003FC007F8003FC007F8003FC007F8001FC007F0001F -C007F0000FC007E0000FE00FE00007E00FC00003F83F000006FFFE00000E1FF000000E00000000 -1E000000001E000000001F000000001F800000001FFFFF80000FFFFFF0000FFFFFFC0007FFFFFE -0003FFFFFF0003FFFFFF800FFFFFFFC01F00007FC07E00001FE07C00000FE0FC000007E0FC0000 -07E0FC000007E0FC000007E07E00000FC03E00000F803F00001F800FC0007E0007F803FC0001FF -FFF000001FFF0000242F7E9F28>I<01F8000000FFF8000000FFF8000000FFF80000000FF80000 -0007F800000007F800000007F800000007F800000007F800000007F800000007F800000007F800 -000007F800000007F800000007F800000007F800000007F800000007F807F80007F83FFE0007F8 -783F0007F8C03F8007F9801FC007FB001FC007FE001FE007FC001FE007FC001FE007FC001FE007 -F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE0 -07F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001F -E007F8001FE007F8001FE007F8001FE0FFFFC3FFFFFFFFC3FFFFFFFFC3FFFF28327DB12D>I<03 -C00007E0000FF0001FF8001FF8001FF8001FF8000FF00007E00003C00000000000000000000000 -000000000000000000000000000000000001F800FFF800FFF800FFF8000FF80007F80007F80007 -F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007 -F80007F80007F80007F80007F80007F80007F80007F80007F800FFFF80FFFF80FFFF8011337DB2 -17>I<01F800FFF800FFF800FFF8000FF80007F80007F80007F80007F80007F80007F80007F800 -07F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F800 -07F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F800 -07F80007F80007F80007F80007F80007F80007F80007F80007F800FFFFC0FFFFC0FFFFC012327D -B117>108 D<03F007F8001FE000FFF03FFE00FFF800FFF0783F01E0FC00FFF0C03F8300FE000F -F1801FC6007F0007F3001FCC007F0007F6001FF8007F8007FC001FF0007F8007FC001FF0007F80 -07FC001FF0007F8007F8001FE0007F8007F8001FE0007F8007F8001FE0007F8007F8001FE0007F -8007F8001FE0007F8007F8001FE0007F8007F8001FE0007F8007F8001FE0007F8007F8001FE000 -7F8007F8001FE0007F8007F8001FE0007F8007F8001FE0007F8007F8001FE0007F8007F8001FE0 -007F8007F8001FE0007F8007F8001FE0007F8007F8001FE0007F8007F8001FE0007F8007F8001F -E0007F80FFFFC3FFFF0FFFFCFFFFC3FFFF0FFFFCFFFFC3FFFF0FFFFC3E207D9F43>I<03F007F8 -00FFF03FFE00FFF0783F00FFF0C03F800FF1801FC007F3001FC007F6001FE007FC001FE007FC00 -1FE007FC001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8 -001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007 -F8001FE007F8001FE007F8001FE007F8001FE007F8001FE0FFFFC3FFFFFFFFC3FFFFFFFFC3FFFF -28207D9F2D>I<0007FC0000007FFFC00001FC07F00003F001F80007E000FC000FC0007E001FC0 -007F003FC0007F803F80003F807F80003FC07F80003FC07F80003FC0FF80003FE0FF80003FE0FF -80003FE0FF80003FE0FF80003FE0FF80003FE0FF80003FE0FF80003FE07F80003FC07F80003FC0 -7F80003FC03FC0007F803FC0007F801FC0007F000FE000FE0007E000FC0003F803F80001FE0FF0 -00007FFFC0000007FC000023207E9F28>I<01F83FE000FFF8FFFC00FFFBE07F00FFFF003F8007 -FE001FC007FC000FE007F8000FF007F80007F807F80007F807F80007FC07F80003FC07F80003FC -07F80003FE07F80003FE07F80003FE07F80003FE07F80003FE07F80003FE07F80003FE07F80003 -FE07F80003FC07F80007FC07F80007FC07F80007F807F80007F807F8000FF007FC000FE007FE00 -1FC007FF003F8007FBC0FE0007F8FFF80007F83FC00007F800000007F800000007F800000007F8 -00000007F800000007F800000007F800000007F800000007F800000007F800000007F8000000FF -FFC00000FFFFC00000FFFFC00000272E7E9F2D>I<03F03F00FFF07FC0FFF1C3E0FFF187E00FF3 -0FF007F60FF007F60FF007FC07E007FC03C007FC000007FC000007F8000007F8000007F8000007 -F8000007F8000007F8000007F8000007F8000007F8000007F8000007F8000007F8000007F80000 -07F8000007F8000007F8000007F8000007F80000FFFFE000FFFFE000FFFFE0001C207E9F21> -114 D<01FF860007FFFE001F00FE003C003E0078001E0078000E00F8000E00F8000E00F8000E00 -FC000000FF800000FFFC00007FFFC0007FFFF0003FFFF8001FFFFC0007FFFE0001FFFF00003FFF -000000FF8000003F8060001F80E0000F80E0000F80F0000F80F0000F00F8000F00FC001E00FE00 -1C00FF807800F3FFF000C07F800019207D9F20>I<001C0000001C0000001C0000001C0000001C -0000003C0000003C0000003C0000007C0000007C000000FC000001FC000003FC000007FC00001F -FFFE00FFFFFE00FFFFFE0003FC000003FC000003FC000003FC000003FC000003FC000003FC0000 -03FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC03 -8003FC038003FC038003FC038003FC038003FC038003FC038001FC038001FC070000FE0700007F -0E00003FFC000007F000192E7FAD1F>I<01F80007E0FFF803FFE0FFF803FFE0FFF803FFE00FF8 -003FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007 -F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE0 -07F8001FE007F8001FE007F8001FE007F8001FE007F8003FE007F8003FE003F8007FE003F8007F -E001FC00DFF000FE039FFF007FFF1FFF000FFC1FFF28207D9F2D>I<FFFF801FFCFFFF801FFCFF -FF801FFC0FF80003C007F800038007FC00078003FC00070003FE000F0001FE000E0001FF000E00 -00FF001C0000FF001C00007F803800007F803800007FC07800003FC07000003FE0F000001FE0E0 -00001FF1E000000FF1C000000FF9C0000007FB80000007FB80000003FF00000003FF00000003FF -00000001FE00000001FE00000000FC00000000FC00000000780000000078000026207E9F2B>I< -FFFF1FFFE07FF8FFFF1FFFE07FF8FFFF1FFFE07FF80FF000FE0007800FF800FE00078007F800FE -00070007F8007F00070003FC007F000E0003FC00FF800E0003FE00FF801E0001FE00FF801C0001 -FE01DFC01C0001FF01DFC03C0000FF03DFE0380000FF838FE07800007F838FE07000007F8707F0 -7000007FC707F0F000003FCF07F8E000003FCE03F8E000001FEE03F9C000001FFC01FDC000001F -FC01FFC000000FFC01FF8000000FF800FF80000007F800FF00000007F0007F00000007F0007F00 -000003F0007E00000003E0003E00000001E0003C00000001C0001C000035207E9F3A>I<7FFF80 -7FFC7FFF807FFC7FFF807FFC03FE000F0001FE001E0000FF003C0000FF807800007FC07800003F -E0F000001FE1E000000FF3C000000FFF80000007FF00000003FE00000001FE00000000FF000000 -00FF80000000FFC0000001FFC0000003DFE00000078FF00000078FF800000F07FC00001E03FC00 -003C01FE00007800FF0000F000FF8000E0007FC001E0003FC0FFFC01FFFFFFFC01FFFFFFFC01FF -FF28207F9F2B>I<FFFF801FFCFFFF801FFCFFFF801FFC0FF80003C007F800038007FC00078003 -FC00070003FE000F0001FE000E0001FF000E0000FF001C0000FF001C00007F803800007F803800 -007FC07800003FC07000003FE0F000001FE0E000001FF1E000000FF1C000000FF9C0000007FB80 -000007FB80000003FF00000003FF00000003FF00000001FE00000001FE00000000FC00000000FC -000000007800000000780000000070000000007000000000F000000000E000000001E000007C01 -C00000FE03C00000FE03800000FE07800000FE0F000000FC1E000000787C0000003FF00000000F -C0000000262E7E9F2B>I E /Fl 1 14 df<0001FE00000007FF8000001E01E000007800780000 -E0001C000180000600030000030006000001800C000000C00C000000C018000000603000000030 -30000000303000000030600000001860000000186000000018C00000000CC00000000CC0000000 -0CC00000000CC00000000CC00000000CC00000000CC00000000CC00000000C6000000018600000 -0018600000001830000000303000000030300000003018000000600C000000C00C000000C00600 -0001800300000300018000060000E0001C000078007800001E01E0000007FF80000001FE000026 -2B7DA02D>13 D E /Fm 46 122 df<3C007F00FF80FF80FFC0FFC0FFC07FC03EC000C000C00180 -018001800300030006000E001C00380030000A157B8813>44 D<1C007F007F00FF80FF80FF807F -007F001C0009097B8813>46 D<000E00001E00007E0007FE00FFFE00FFFE00F8FE0000FE0000FE -0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE -0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE -0000FE007FFFFE7FFFFE7FFFFE17277BA622>49 D<00FF800007FFF0000FFFFC001E03FE003800 -FF807C003F80FE003FC0FF001FC0FF001FE0FF000FE0FF000FE07E000FE03C001FE000001FE000 -001FC000001FC000003F8000003F0000007E000000FC000000F8000001F0000003E00000078000 -000F0000001E0000003C00E0007000E000E000E001C001C0038001C0060001C00FFFFFC01FFFFF -C03FFFFFC07FFFFFC0FFFFFF80FFFFFF80FFFFFF801B277DA622>I<007F800003FFF00007FFFC -000F80FE001F007F003F807F003F803F803F803F803F803F801F803F801F003F8000007F000000 -7F0000007E000000FC000001F8000007F00000FFC00000FFC0000001F80000007E0000003F0000 -003F8000001FC000001FC000001FE000001FE03C001FE07E001FE0FF001FE0FF001FE0FF001FC0 -FF003FC0FE003F807C007F003F00FE001FFFFC0007FFF00000FF80001B277DA622>I<00000E00 -00001E0000003E0000007E000000FE000000FE000001FE000003FE0000077E00000E7E00000E7E -00001C7E0000387E0000707E0000E07E0000E07E0001C07E0003807E0007007E000E007E000E00 -7E001C007E0038007E0070007E00E0007E00FFFFFFF8FFFFFFF8FFFFFFF80000FE000000FE0000 -00FE000000FE000000FE000000FE000000FE000000FE00007FFFF8007FFFF8007FFFF81D277EA6 -22>I<180003001F801F001FFFFE001FFFFC001FFFF8001FFFF0001FFFC0001FFF00001C000000 -1C0000001C0000001C0000001C0000001C0000001C0000001C7FC0001DFFF8001F80FC001E003F -0008003F0000001F8000001FC000001FC000001FE000001FE018001FE07C001FE0FE001FE0FE00 -1FE0FE001FE0FE001FC0FC001FC078003F8078003F803C007F001F01FE000FFFFC0003FFF00000 -FF80001B277DA622>I<380000003E0000003FFFFFF03FFFFFF03FFFFFF07FFFFFE07FFFFFC07F -FFFF807FFFFF0070000E0070000E0070001C00E0003800E0007000E000E0000001E0000001C000 -000380000007800000070000000F0000001F0000001E0000003E0000003E0000007E0000007C00 -00007C000000FC000000FC000000FC000000FC000001FC000001FC000001FC000001FC000001FC -000001FC000001FC000000F80000007000001C297CA822>55 D<00000780000000000780000000 -000FC0000000000FC0000000000FC0000000001FE0000000001FE0000000003FF0000000003FF0 -000000003FF00000000077F80000000077F800000000F7FC00000000E3FC00000000E3FC000000 -01C1FE00000001C1FE00000003C1FF0000000380FF0000000380FF00000007007F80000007007F -8000000F007FC000000E003FC000000E003FC000001C001FE000001C001FE000003FFFFFF00000 -3FFFFFF000003FFFFFF00000700007F80000700007F80000F00007FC0000E00003FC0000E00003 -FC0001C00001FE0001C00001FE0003C00001FF00FFFE003FFFFCFFFE003FFFFCFFFE003FFFFC2E -297EA833>65 D<FFFFFFF800FFFFFFFF00FFFFFFFFC003F8001FE003F8000FF003F80007F803F8 -0003F803F80003FC03F80003FC03F80001FC03F80001FC03F80001FC03F80003FC03F80003F803 -F80003F803F80007F003F8000FF003F8001FC003F800FF8003FFFFFE0003FFFFFFC003F8000FF0 -03F80003F803F80001FC03F80001FE03F80000FE03F80000FE03F80000FF03F80000FF03F80000 -FF03F80000FF03F80000FF03F80000FF03F80000FE03F80001FE03F80003FC03F80007FC03F800 -1FF8FFFFFFFFE0FFFFFFFFC0FFFFFFFE0028297DA830>I<00007FE0030007FFFC07001FFFFF0F -007FF00F9F00FF0001FF01FC0000FF03F800007F07F000003F0FE000001F1FC000001F1FC00000 -0F3F8000000F3F800000077F800000077F800000077F00000000FF00000000FF00000000FF0000 -0000FF00000000FF00000000FF00000000FF00000000FF00000000FF000000007F000000007F80 -0000007F800000073F800000073F800000071FC00000071FC000000E0FE000000E07F000001C03 -F800003C01FC00007800FF0001F0007FF007C0001FFFFF800007FFFE0000007FF00028297CA831 ->I<FFFFFFFFE0FFFFFFFFE0FFFFFFFFE003FC001FE003FC0007F003FC0001F003FC0001F003FC -0000F003FC00007003FC00007003FC00007003FC01C07803FC01C03803FC01C03803FC01C03803 -FC03C00003FC03C00003FC0FC00003FFFFC00003FFFFC00003FFFFC00003FC0FC00003FC03C000 -03FC03C00003FC01C00E03FC01C00E03FC01C00E03FC01C01C03FC00001C03FC00001C03FC0000 -1C03FC00003C03FC00003803FC00007803FC0000F803FC0001F803FC0003F803FC001FF8FFFFFF -FFF0FFFFFFFFF0FFFFFFFFF027297EA82C>69 D<FFFFFFFFC0FFFFFFFFC0FFFFFFFFC003FC003F -C003FC000FE003FC0003E003FC0001E003FC0001E003FC0000E003FC0000E003FC0000E003FC00 -00F003FC01C07003FC01C07003FC01C07003FC01C00003FC03C00003FC03C00003FC0FC00003FF -FFC00003FFFFC00003FFFFC00003FC0FC00003FC03C00003FC03C00003FC01C00003FC01C00003 -FC01C00003FC01C00003FC00000003FC00000003FC00000003FC00000003FC00000003FC000000 -03FC00000003FC00000003FC000000FFFFFC0000FFFFFC0000FFFFFC000024297EA82A>I<0000 -7FE003000007FFFC0700001FFFFF0F00007FF00F9F0000FF0001FF0001FC0000FF0003F800007F -0007F000003F000FE000001F001FC000001F001FC000000F003F8000000F003F80000007007F80 -000007007F80000007007F0000000000FF0000000000FF0000000000FF0000000000FF00000000 -00FF0000000000FF0000000000FF0000000000FF0000000000FF0000FFFFF87F0000FFFFF87F80 -00FFFFF87F800000FF003F800000FF003F800000FF001FC00000FF001FC00000FF000FE00000FF -0007F00000FF0003F80000FF0001FC0000FF0000FF0001FF00007FF007FF00001FFFFF9F000007 -FFFE0F0000007FF003002D297CA835>I<FFFFF00FFFFFFFFFF00FFFFFFFFFF00FFFFF03FC0000 -3FC003FC00003FC003FC00003FC003FC00003FC003FC00003FC003FC00003FC003FC00003FC003 -FC00003FC003FC00003FC003FC00003FC003FC00003FC003FC00003FC003FC00003FC003FC0000 -3FC003FC00003FC003FFFFFFFFC003FFFFFFFFC003FFFFFFFFC003FC00003FC003FC00003FC003 -FC00003FC003FC00003FC003FC00003FC003FC00003FC003FC00003FC003FC00003FC003FC0000 -3FC003FC00003FC003FC00003FC003FC00003FC003FC00003FC003FC00003FC003FC00003FC003 -FC00003FC003FC00003FC0FFFFF00FFFFFFFFFF00FFFFFFFFFF00FFFFF30297EA835>I<FFFFFC -FFFFFCFFFFFC01FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE00 -01FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE00 -01FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE00FFFFFCFFFFFC -FFFFFC16297FA819>I<FFFE0000003FFF80FFFE0000003FFF80FFFF0000007FFF8003FF000000 -7FE00003FF0000007FE00003BF800000EFE00003BF800000EFE000039FC00001CFE000039FC000 -01CFE000038FE000038FE000038FE000038FE000038FE000038FE0000387F000070FE0000387F0 -00070FE0000383F8000E0FE0000383F8000E0FE0000381FC001C0FE0000381FC001C0FE0000381 -FC001C0FE0000380FE00380FE0000380FE00380FE00003807F00700FE00003807F00700FE00003 -803F80E00FE00003803F80E00FE00003803F80E00FE00003801FC1C00FE00003801FC1C00FE000 -03800FE3800FE00003800FE3800FE000038007F7000FE000038007F7000FE000038007F7000FE0 -00038003FE000FE000038003FE000FE000038001FC000FE000038001FC000FE000038000F8000F -E000FFFE00F803FFFF80FFFE00F803FFFF80FFFE007003FFFF8039297DA840>77 -D<FFFC00007FFFFFFE00007FFFFFFF00007FFF03FF800001C003FFC00001C003BFE00001C0039F -E00001C0039FF00001C0038FF80001C00387FC0001C00383FE0001C00381FF0001C00380FF8001 -C003807F8001C003807FC001C003803FE001C003801FF001C003800FF801C0038007FC01C00380 -03FC01C0038003FE01C0038001FF01C0038000FF81C00380007FC1C00380003FE1C00380001FF1 -C00380000FF1C00380000FF9C003800007FDC003800003FFC003800001FFC003800000FFC00380 -00007FC0038000007FC0038000003FC0038000001FC0038000000FC00380000007C0FFFE000003 -C0FFFE000001C0FFFE000001C030297EA835>I<FFFFFFF800FFFFFFFF00FFFFFFFFC003FC003F -E003FC0007F003FC0003F803FC0003FC03FC0001FC03FC0001FE03FC0001FE03FC0001FE03FC00 -01FE03FC0001FE03FC0001FE03FC0001FE03FC0001FC03FC0003FC03FC0003F803FC0007F003FC -003FE003FFFFFF8003FFFFFE0003FC00000003FC00000003FC00000003FC00000003FC00000003 -FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC000000 -03FC00000003FC00000003FC000000FFFFF00000FFFFF00000FFFFF0000027297EA82E>80 -D<FFFFFFE00000FFFFFFFE0000FFFFFFFF800003FC003FE00003FC000FF00003FC0007F80003FC -0003FC0003FC0001FC0003FC0001FE0003FC0001FE0003FC0001FE0003FC0001FE0003FC0001FE -0003FC0001FE0003FC0001FC0003FC0003F80003FC0007F80003FC000FE00003FC003FC00003FF -FFFE000003FFFFFE000003FC00FF800003FC003FC00003FC001FE00003FC000FF00003FC0007F8 -0003FC0007F80003FC0007F80003FC0007F80003FC0007F80003FC0007F80003FC0007F80003FC -0007F80003FC0007F80003FC0007F80E03FC0007F80E03FC0003F80E03FC0001FC1CFFFFF000FE -1CFFFFF0007FF8FFFFF0000FE02F297EA832>82 D<00FF00C003FFE1C00FFFF9C01F80FFC03F00 -3FC03E000FC07C0007C07C0007C0FC0003C0FC0003C0FC0001C0FE0001C0FE0001C0FF000000FF -C000007FFC00007FFFE0003FFFF8001FFFFE001FFFFF0007FFFF8003FFFFC000FFFFC0000FFFE0 -00007FE000001FF000000FF0000007F0E00003F0E00003F0E00003F0E00003F0F00003E0F00003 -E0F80007E0FC0007C0FF000F80FFE01F80E3FFFF00E1FFFC00C01FF0001C297CA825>I<FFFFF0 -00FFFEFFFFF000FFFEFFFFF000FFFE03FC0000038003FC0000038003FC0000038003FC00000380 -03FC0000038003FC0000038003FC0000038003FC0000038003FC0000038003FC0000038003FC00 -00038003FC0000038003FC0000038003FC0000038003FC0000038003FC0000038003FC00000380 -03FC0000038003FC0000038003FC0000038003FC0000038003FC0000038003FC0000038003FC00 -00038003FC0000038003FC0000038003FC0000038003FC0000038001FC0000070001FE00000700 -00FE00000E00007F00000E00003F00003C00001FC0007800000FF003F0000007FFFFE0000000FF -FF800000001FFC00002F297EA834>85 D<FFFFF0007FFFFFFFF0007FFFFFFFF0007FFF03FE0000 -01C001FE0000038001FE0000038000FF0000070000FF0000070000FF80000F00007F80000E0000 -7FC0000E00003FC0001C00003FE0001C00001FE0003800001FE0003800001FF0007800000FF000 -7000000FF800F0000007F800E0000007FC00E0000003FC01C0000003FC01C0000003FE03C00000 -01FE0380000001FF0780000000FF0700000000FF87000000007F8E000000007F8E000000007FDE -000000003FDC000000003FFC000000001FF8000000001FF8000000000FF0000000000FF0000000 -000FF00000000007E00000000007E00000000003C00000000003C0000030297FA833>I<FFFFE0 -FFFFE01FFFC0FFFFE0FFFFE01FFFC0FFFFE0FFFFE01FFFC003FC0003FC0000700003FC0003FC00 -00700003FE0003FE0000F00001FE0001FE0000E00001FE0001FE0000E00001FF0001FF0001E000 -00FF0001FF0001C00000FF0001FF0001C000007F8003FF80038000007F8003FF80038000007FC0 -07FFC0078000003FC0073FC0070000003FC0073FC0070000003FE00F3FE00F0000001FE00E1FE0 -0E0000001FE00E1FE00E0000000FF01C0FF01C0000000FF01C0FF01C0000000FF01C0FF81C0000 -0007F83807F83800000007F83807F83800000007FC7807FC7800000003FC7003FC7000000003FC -7003FC7000000003FEF003FEF000000001FEE001FEE000000001FEE001FEE000000000FFC000FF -C000000000FFC000FFC000000000FFC000FFC0000000007F80007F80000000007F80007F800000 -00007F80007F80000000003F00003F00000000003F00003F00000000003F00003F00000000001E -00001E00000000001E00001E00000042297FA845>I<03FF80000FFFF0001F01FC003F80FE003F -807F003F803F003F803F801F003F8000003F8000003F8000003F8000003F80003FFF8001FC3F80 -0FE03F801F803F803F003F807E003F80FC003F80FC003F80FC003F80FC003F80FC005F807E00DF -803F839FFC1FFE0FFC03F803FC1E1B7E9A21>97 D<FFE00000FFE00000FFE000000FE000000FE0 -00000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000F -E000000FE1FE000FE7FF800FFE07E00FF803F00FF001F80FE000FC0FE000FC0FE0007E0FE0007E -0FE0007F0FE0007F0FE0007F0FE0007F0FE0007F0FE0007F0FE0007F0FE0007F0FE0007E0FE000 -7E0FE0007E0FE000FC0FE000FC0FF001F80FF803F00F9C0FE00F0FFF800E01FC00202A7EA925> -I<003FF00001FFFC0003F03E000FC07F001F807F003F007F003F007F007F003E007E0000007E00 -0000FE000000FE000000FE000000FE000000FE000000FE000000FE0000007E0000007E0000007F -0000003F0003803F8003801F8007000FE00E0003F83C0001FFF800003FC000191B7E9A1E>I<00 -007FF000007FF000007FF0000007F0000007F0000007F0000007F0000007F0000007F0000007F0 -000007F0000007F0000007F0000007F0000007F0003F87F001FFF7F007F03FF00FC00FF01F8007 -F03F0007F03F0007F07E0007F07E0007F07E0007F0FE0007F0FE0007F0FE0007F0FE0007F0FE00 -07F0FE0007F0FE0007F0FE0007F07E0007F07E0007F03F0007F03F0007F01F800FF00FC01FF007 -E07FFF01FFE7FF007F87FF202A7EA925>I<003FC00001FFF00003E07C000F803E001F801F001F -001F003F000F807E000F807E000FC07E000FC0FE0007C0FE0007C0FFFFFFC0FFFFFFC0FE000000 -FE000000FE0000007E0000007E0000007F0000003F0001C01F0001C00F80038007C0070003F01E -0000FFFC00003FE0001A1B7E9A1F>I<0007F8003FFC007E3E01FC7F03F87F03F07F07F07F07F0 -3E07F00007F00007F00007F00007F00007F00007F000FFFFC0FFFFC0FFFFC007F00007F00007F0 -0007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F0 -0007F00007F00007F00007F00007F0007FFF807FFF807FFF80182A7EA915>I<007F80F001FFE3 -F807C0FE1C0F807C7C1F003E7C1F003E103F003F003F003F003F003F003F003F003F003F003F00 -3F001F003E001F003E000F807C0007C0F80005FFE0000C7F8000180000001C0000001C0000001E -0000001FFFF8001FFFFF000FFFFFC007FFFFE003FFFFF00FFFFFF03E0007F07C0001F8F80000F8 -F80000F8F80000F8F80000F87C0001F07C0001F03F0007E00FC01F8007FFFF00007FF0001E287E -9A22>I<FFE00000FFE00000FFE000000FE000000FE000000FE000000FE000000FE000000FE000 -000FE000000FE000000FE000000FE000000FE000000FE000000FE07E000FE1FF800FE30FC00FE4 -0FE00FE807E00FF807F00FF007F00FF007F00FE007F00FE007F00FE007F00FE007F00FE007F00F -E007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F0 -0FE007F0FFFE3FFFFFFE3FFFFFFE3FFF202A7DA925>I<07000F801FC03FE03FE03FE01FC00F80 -07000000000000000000000000000000FFE0FFE0FFE00FE00FE00FE00FE00FE00FE00FE00FE00F -E00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE0FFFEFFFEFFFE0F2B7EAA12>I<FF -E0FFE0FFE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE0 -0FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE0FF -FEFFFEFFFE0F2A7EA912>108 D<FFC07F001FC000FFC1FFC07FF000FFC307E0C1F8000FC407F1 -01FC000FC803F200FC000FD803FE00FE000FD003FC00FE000FD003FC00FE000FE003F800FE000F -E003F800FE000FE003F800FE000FE003F800FE000FE003F800FE000FE003F800FE000FE003F800 -FE000FE003F800FE000FE003F800FE000FE003F800FE000FE003F800FE000FE003F800FE000FE0 -03F800FE000FE003F800FE000FE003F800FE000FE003F800FE00FFFE3FFF8FFFE0FFFE3FFF8FFF -E0FFFE3FFF8FFFE0331B7D9A38>I<FFC07E00FFC1FF80FFC30FC00FC40FE00FC807E00FD807F0 -0FD007F00FD007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007 -F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F0FFFE3FFFFFFE -3FFFFFFE3FFF201B7D9A25>I<003FE00001FFFC0003F07E000FC01F801F800FC03F0007E03F00 -07E07E0003F07E0003F07E0003F0FE0003F8FE0003F8FE0003F8FE0003F8FE0003F8FE0003F8FE -0003F8FE0003F87E0003F07E0003F03F0007E03F0007E01F800FC00FC01F8007F07F0001FFFC00 -003FE0001D1B7E9A22>I<FFE1FE00FFE7FF80FFFE0FE00FF803F00FF001F80FE001FC0FE000FC -0FE000FE0FE000FE0FE0007F0FE0007F0FE0007F0FE0007F0FE0007F0FE0007F0FE0007F0FE000 -7F0FE0007E0FE000FE0FE000FE0FE000FC0FE001FC0FF001F80FF803F00FFC0FE00FEFFF800FE1 -FC000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE00000FF -FE0000FFFE0000FFFE000020277E9A25>I<FFC3E0FFC7F8FFCC7C0FD8FE0FD0FE0FD0FE0FF0FE -0FE07C0FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE000 -0FE0000FE0000FE0000FE000FFFF00FFFF00FFFF00171B7E9A1B>114 D<03FE300FFFF03E03F0 -7800F07000F0F00070F00070F80070FE0000FFE0007FFF007FFFC03FFFE01FFFF007FFF800FFF8 -0007FC0000FCE0007CE0003CF0003CF00038F80038FC0070FF01E0E7FFC0C1FF00161B7E9A1B> -I<00700000700000700000700000F00000F00000F00001F00003F00003F00007F0001FFFE0FFFF -E0FFFFE007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F0 -0007F00007F07007F07007F07007F07007F07007F07007F07003F0E001F8C000FFC0003F001426 -7FA51A>I<FFE07FF0FFE07FF0FFE07FF00FE007F00FE007F00FE007F00FE007F00FE007F00FE0 -07F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00F -E007F00FE007F00FE007F00FE00FF00FE00FF007E017F003F067FF01FFC7FF007F87FF201B7D9A -25>I<FFFE07FFFFFE07FFFFFE07FF07F000E007F000E007F801E003F801C003F801C001FC0380 -01FC038001FE078000FE070000FF0F00007F0E00007F0E00003F9C00003F9C00003FFC00001FF8 -00001FF800000FF000000FF000000FF0000007E0000007E0000003C0000003C000201B7F9A23> -I<FFFC7FFC1FFCFFFC7FFC1FFCFFFC7FFC1FFC0FE00FE001C007F007E0038007F007E0038007F8 -07F0078003F807F0070003F807F8070001FC0FF80E0001FC0FF80E0001FE1FFC1E0000FE1CFC1C -0000FE1CFE1C0000FF387E3C00007F387E3800007F787F3800003FF03F7000003FF03F7000003F -E01FF000001FE01FE000001FE01FE000000FC00FC000000FC00FC000000FC00FC0000007800780 -000007800780002E1B7F9A31>I<FFFC1FFEFFFC1FFEFFFC1FFE07F0078003F8070001FC0F0001 -FE1E0000FE3C00007F7800003FF800003FF000001FE000000FE0000007F0000007F800000FF800 -001FFC00003DFE000038FF0000787F0000F03F8001E03FC003C01FE003800FE0FFF03FFFFFF03F -FFFFF03FFF201B7F9A23>I<FFFE07FFFFFE07FFFFFE07FF07F000E007F000E007F801E003F801 -C003F801C001FC038001FC038001FE078000FE070000FF0F00007F0E00007F0E00003F9C00003F -9C00003FFC00001FF800001FF800000FF000000FF0000007F0000007E0000007E0000003C00000 -03C000000380000003800000078000380700007C070000FE0E0000FE0E0000FE1C0000FE380000 -7C7000003FE000000F80000020277F9A23>I E /Fn 75 127 df<70F8F8F8F8F8F8F8F8F8F8F8 -F8F8F8F8F870000000000070F8F8F870051C779B18>33 D<4010E038F078E038E038E038E038E0 -38E038E038E038E038E03860300D0E7B9C18>I<030600078F00078F00078F00078F00078F0007 -8F007FFFC0FFFFE0FFFFE07FFFC00F1E000F1E000F1E000F1E000F1E000F1E007FFFC0FFFFE0FF -FFE07FFFC01E3C001E3C001E3C001E3C001E3C001E3C000C1800131C7E9B18>I<00C00001C000 -01C00001C00003F0000FFC003FFE007DCF0071C700E1C380E1C780E1C780E1C780F1C00079C000 -3DC0001FE0000FF80003FC0001DE0001CF0001C70061C380F1C380F1C380E1C380E1C70071C700 -79DE003FFE001FF80007E00001C00001C00001C00000C00011247D9F18>I<3803007C07807C07 -80EE0F80EE0F00EE0F00EE1F00EE1E00EE1E00EE3E007C3C007C3C00387C0000780000780000F8 -0000F00001F00001E00001E00003E00003C00003C00007C0000783800787C00F87C00F0EE00F0E -E01F0EE01E0EE01E0EE03E0EE03C07C03C07C018038013247E9F18>I<01C00007E0000FF0000E -70001C38001C38001C38001C38001C73F01C73F01CE3F00FE3800FC7000F87000F07001F0E003F -0E007B8E0073DC00E1DC00E0F800E0F800E07070E0787070FC707FFFE03FCFE00F03C0141C7F9B -18>I<387C7C7E3E0E0E0E1C1C38F8F0C0070E789B18>I<007000F001E003C007800F001E001C00 -380038007000700070007000E000E000E000E000E000E000E000E0007000700070007000380038 -001C001E000F00078003C001F000F000700C24799F18>I<6000F00078003C001E000F00078003 -8001C001C000E000E000E000E00070007000700070007000700070007000E000E000E000E001C0 -01C0038007800F001E003C007800F00060000C247C9F18>I<01C00001C00001C00001C000C1C1 -80F1C780F9CF807FFF001FFC0007F00007F0001FFC007FFF00F9CF80F1C780C1C18001C00001C0 -0001C00001C00011147D9718>I<00600000F00000F00000F00000F00000F00000F00000F0007F -FFC0FFFFE0FFFFE07FFFC000F00000F00000F00000F00000F00000F00000F00000600013147E97 -18>I<1C3E7E7F3F1F070E1E7CF860080C788518>I<7FFF00FFFF80FFFF807FFF0011047D8F18> -I<3078FCFC78300606778518>I<000300000780000780000F80000F00001F00001E00001E0000 -3E00003C00007C0000780000780000F80000F00001F00001E00003E00003C00003C00007C00007 -80000F80000F00000F00001F00001E00003E00003C00003C00007C0000780000F80000F00000F0 -000060000011247D9F18>I<01F00007FC000FFE001F1F001C07003803807803C07001C07001C0 -E000E0E000E0E000E0E000E0E000E0E000E0E000E0E000E0E000E0F001E07001C07001C07803C0 -3803801C07001F1F000FFE0007FC0001F000131C7E9B18>I<01800380038007800F803F80FF80 -FB80438003800380038003800380038003800380038003800380038003800380038003807FFCFF -FE7FFC0F1C7B9B18>I<03F0000FFE003FFF007C0F807003C0E001C0F000E0F000E06000E00000 -E00000E00001C00001C00003C0000780000F00001E00003C0000780000F00001E00007C0000F80 -001E00E03C00E07FFFE0FFFFE07FFFE0131C7E9B18>I<001F00003F0000770000770000E70001 -E70001C7000387000787000707000E07001E07003C0700380700780700F00700FFFFF8FFFFF8FF -FFF8000700000700000700000700000700000700007FF000FFF8007FF0151C7F9B18>52 -D<007E0001FF0007FF800F83C01E03C01C03C0380180380000700000700000E1F800E7FE00FFFF -00FE0780F803C0F001C0F000E0E000E0F000E07000E07000E07000E03801C03C03C01E07800FFF -0007FE0001F800131C7E9B18>54 D<3078FCFC783000000000000000003078FCFC783006147793 -18>58 D<183C7E7E3C180000000000000000183C7E7E3E1E0E1C3C78F060071A789318>I<0003 -00000780001F80003F00007E0001FC0003F00007E0001FC0003F00007E0000FC0000FC00007E00 -003F00001FC00007E00003F00001FC00007E00003F00001F8000078000030011187D9918>I<7F -FFC0FFFFE0FFFFE0FFFFE0000000000000000000000000FFFFE0FFFFE0FFFFE07FFFC0130C7E93 -18>I<600000F00000FC00007E00003F00001FC00007E00003F00001FC00007E00003F00001F80 -001F80003F00007E0001FC0003F00007E0001FC0003F00007E0000FC0000F0000060000011187D -9918>I<0FF0003FFC007FFF00700F00F00380F00380600780000F00003E00007C0001F00001E0 -0003C00003C00003C00003C00003C00003800000000000000000000000000000000003800007C0 -0007C00007C000038000111C7D9B18>I<00700000F80000F80000D80000D80001DC0001DC0001 -DC00018C00038E00038E00038E00038E000306000707000707000707000707000FFF800FFF800F -FF800E03800E03801C01C01C01C07F07F0FF8FF87F07F0151C7F9B18>65 -D<7FF800FFFE007FFF001C0F801C03C01C03C01C01E01C00E01C00E01C00F01C00701C00701C00 -701C00701C00701C00701C00701C00701C00F01C00E01C00E01C01E01C01C01C03C01C0F807FFF -00FFFE007FF800141C7F9B18>68 D<FFFFF0FFFFF0FFFFF01C00701C00701C00701C00701C0000 -1C00001C0E001C0E001C0E001FFE001FFE001FFE001C0E001C0E001C0E001C00001C00001C0038 -1C00381C00381C00381C0038FFFFF8FFFFF8FFFFF8151C7F9B18>I<FFFFE0FFFFE0FFFFE01C00 -E01C00E01C00E01C00E01C00001C00001C1C001C1C001C1C001FFC001FFC001FFC001C1C001C1C -001C1C001C00001C00001C00001C00001C00001C00001C0000FFC000FFC000FFC000131C7E9B18 ->I<7F07F0FF8FF87F07F01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01F -FFC01FFFC01FFFC01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C07F -07F0FF8FF87F07F0151C7F9B18>72 D<7FFF00FFFF807FFF0001C00001C00001C00001C00001C0 -0001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C0 -0001C00001C00001C00001C0007FFF00FFFF807FFF00111C7D9B18>I<7FE000FFE0007FE0000E -00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E -00000E00000E00000E00000E00700E00700E00700E00700E00707FFFF0FFFFF07FFFF0141C7F9B -18>76 D<7E07F0FF0FF87F07F01D81C01D81C01D81C01DC1C01CC1C01CC1C01CE1C01CE1C01CE1 -C01C61C01C71C01C71C01C31C01C39C01C39C01C39C01C19C01C19C01C1DC01C0DC01C0DC01C0D -C07F07C0FF87C07F03C0151C7F9B18>78 D<0FF8003FFE007FFF00780F00700700F00780E00380 -E00380E00380E00380E00380E00380E00380E00380E00380E00380E00380E00380E00380E00380 -E00380E00380F00780700700780F007FFF003FFE000FF800111C7D9B18>I<FFFE00FFFF80FFFF -C01C03C01C01E01C00E01C00701C00701C00701C00701C00701C00E01C01E01C03C01FFFC01FFF -801FFE001C00001C00001C00001C00001C00001C00001C00001C0000FF8000FF8000FF8000141C -7F9B18>I<7FF800FFFE007FFF001C0F801C03801C03C01C01C01C01C01C01C01C03C01C03801C -0F801FFF001FFE001FFE001C0F001C07001C03801C03801C03801C03801C03801C039C1C039C1C -039C7F01F8FF81F87F00F0161C7F9B18>82 D<03F3801FFF803FFF807C0F80700780E00380E003 -80E00380E000007000007800003F00001FF00007FE0000FF00000F800003C00001C00000E00000 -E06000E0E000E0E001E0F001C0F80780FFFF80FFFE00E7F800131C7E9B18>I<7FFFF8FFFFF8FF -FFF8E07038E07038E07038E0703800700000700000700000700000700000700000700000700000 -700000700000700000700000700000700000700000700000700000700007FF0007FF0007FF0015 -1C7F9B18>I<FF83FEFF83FEFF83FE1C00701C00701C00701C00701C00701C00701C00701C0070 -1C00701C00701C00701C00701C00701C00701C00701C00701C00701C00701C00700E00E00F01E0 -0783C003FF8001FF00007C00171C809B18>I<FF07F8FF07F8FF07F81C01C01E03C00E03800F07 -80070700070700038E00038E0001DC0001DC0001DC0000F80000F8000070000070000070000070 -0000700000700000700000700000700001FC0003FE0001FC00151C7F9B18>89 -D<FFF8FFF8FFF8E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000 -E000E000E000E000E000E000E000E000E000E000E000E000E000E000FFF8FFF8FFF80D24779F18 ->91 D<600000F00000F00000F800007800007C00003C00003C00003E00001E00001F00000F0000 -0F00000F800007800007C00003C00003C00003E00001E00001F00000F00000F800007800007800 -007C00003C00003E00001E00001E00001F00000F00000F8000078000078000030011247D9F18> -I<FFF8FFF8FFF80038003800380038003800380038003800380038003800380038003800380038 -00380038003800380038003800380038003800380038003800380038FFF8FFF8FFF80D247F9F18 ->I<018007C01FF07EFCF83EE00E0F067C9B18>I<7FFF00FFFF80FFFF807FFF0011047D7F18>I< -061E3E387070E0E0E0F8FC7C7C38070E789E18>I<1FE0003FF8007FFC00781E00300E00000700 -00070000FF0007FF001FFF007F0700780700E00700E00700E00700F00F00781F003FFFF01FFBF0 -07E1F014147D9318>I<7E0000FE00007E00000E00000E00000E00000E00000E00000E3E000EFF -800FFFC00FC1E00F80E00F00700E00700E00380E00380E00380E00380E00380E00380F00700F00 -700F80E00FC1E00FFFC00EFF80063E00151C809B18>I<01FE0007FF001FFF803E078038030070 -0000700000E00000E00000E00000E00000E00000E000007000007001C03801C03E03C01FFF8007 -FF0001FC0012147D9318>I<001F80003F80001F8000038000038000038000038000038003E380 -0FFB801FFF803C1F80380F80700780700380E00380E00380E00380E00380E00380E00380700780 -700780380F803C1F801FFFF00FFBF803E3F0151C7E9B18>I<01F00007FC001FFE003E0F003807 -80700380700380E001C0E001C0FFFFC0FFFFC0FFFFC0E000007000007001C03801C03E03C01FFF -8007FF0001FC0012147D9318>I<001F80007FC000FFE000E1E001C0C001C00001C00001C0007F -FFC0FFFFC0FFFFC001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001 -C00001C00001C00001C0007FFF007FFF007FFF00131C7F9B18>I<01E1F007FFF80FFFF81E1E30 -1C0E003807003807003807003807003807001C0E001E1E001FFC001FF80039E0003800001C0000 -1FFE001FFFC03FFFE07801F0700070E00038E00038E00038E000387800F07E03F01FFFC00FFF80 -01FC00151F7F9318>I<7E0000FE00007E00000E00000E00000E00000E00000E00000E3E000EFF -800FFFC00FC1C00F80E00F00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00 -E00E00E00E00E07FC3FCFFE7FE7FC3FC171C809B18>I<03800007C00007C00007C00003800000 -00000000000000000000007FC000FFC0007FC00001C00001C00001C00001C00001C00001C00001 -C00001C00001C00001C00001C00001C00001C00001C000FFFF00FFFF80FFFF00111D7C9C18>I< -7FE000FFE0007FE00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E000 -00E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E0007FFFC0 -FFFFE07FFFC0131C7E9B18>108 D<7CE0E000FFFBF8007FFFF8001F1F1C001E1E1C001E1E1C00 -1C1C1C001C1C1C001C1C1C001C1C1C001C1C1C001C1C1C001C1C1C001C1C1C001C1C1C001C1C1C -001C1C1C007F1F1F00FFBFBF807F1F1F001914819318>I<7E3E00FEFF807FFFC00FC1C00F80E0 -0F00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E07FC3FC -FFE7FE7FC3FC1714809318>I<01F0000FFE001FFF003E0F803803807001C07001C0E000E0E000 -E0E000E0E000E0E000E0F001E07001C07803C03C07803E0F801FFF000FFE0001F00013147E9318 ->I<7E3E00FEFF807FFFC00FC1E00F80E00F00700E00700E00380E00380E00380E00380E00380E -00380F00700F00700F80E00FC1E00FFFC00EFF800E3E000E00000E00000E00000E00000E00000E -00000E00007FC000FFE0007FC000151E809318>I<01E38007FB801FFF803E1F80380F80700780 -700780E00380E00380E00380E00380E00380E00380700780700780380F803C1F801FFF800FFB80 -03E380000380000380000380000380000380000380000380003FF8003FF8003FF8151E7E9318> -I<7F87E0FF9FF07FBFF803F87803F03003E00003C00003C0000380000380000380000380000380 -000380000380000380000380007FFE00FFFF007FFE0015147F9318>I<07F7003FFF007FFF0078 -0F00E00700E00700E007007C00007FE0001FFC0003FE00001F00600780E00380E00380F00380F8 -0F00FFFF00FFFC00E7F00011147D9318>I<0180000380000380000380000380007FFFC0FFFFC0 -FFFFC00380000380000380000380000380000380000380000380000380000380400380E00380E0 -0380E001C1C001FFC000FF80003E0013197F9818>I<7E07E0FE0FE07E07E00E00E00E00E00E00 -E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E01E00F03E007FFFC03FF -FE01FCFC1714809318>I<7F8FF0FF8FF87F8FF01E03C00E03800E03800E038007070007070007 -0700038E00038E00038E00038E0001DC0001DC0001DC0000F80000F80000700015147F9318>I< -FF8FF8FF8FF8FF8FF83800E03800E03800E01C01C01C01C01C71C01CF9C01CF9C01CD9C01CD9C0 -0DDD800DDD800DDD800D8D800F8F800F8F8007070015147F9318>I<7F8FF07F9FF07F8FF00707 -00078E00039E0001DC0001F80000F80000700000F00000F80001DC00039E00038E000707000F07 -807F8FF0FF8FF87F8FF015147F9318>I<7F8FF0FF8FF87F8FF00E01C00E03800E038007038007 -0700070700038700038600038E0001CE0001CE0000CC0000CC0000DC0000780000780000780000 -700000700000700000F00000E00079E0007BC0007F80003F00001E0000151E7F9318>I<3FFFF0 -7FFFF07FFFF07001E07003C0700780000F00001E00003C0000F80001F00003C0000780000F0070 -1E00703C0070780070FFFFF0FFFFF0FFFFF014147F9318>I<0007E0001FE0007FE000780000E0 -0000E00000E00000E00000E00000E00000E00000E00000E00000E00000E00001E0007FC000FF80 -00FF80007FC00001E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E0 -0000E000007800007FE0001FE00007E013247E9F18>I<60F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 -F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0600424769F18>I<7C0000FF0000FFC00003C000 -00E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000F000007FC0 -003FE0003FE0007FC000F00000E00000E00000E00000E00000E00000E00000E00000E00000E000 -00E00000E00003C000FFC000FF00007C000013247E9F18>I<060C1F1E3FBEFBF8F1F060C00F06 -7C9B18>I E /Fo 75 123 df<001F83E000F06E3001C078780380F8780300F030070070000700 -70000700700007007000070070000700700007007000FFFFFF8007007000070070000700700007 -007000070070000700700007007000070070000700700007007000070070000700700007007000 -07007000070070000700700007007000070070007FE3FF001D20809F1B>11 -D<003F0000E0C001C0C00381E00701E00701E0070000070000070000070000070000070000FFFF -E00700E00700E00700E00700E00700E00700E00700E00700E00700E00700E00700E00700E00700 -E00700E00700E00700E00700E00700E07FC3FE1720809F19>I<003FE000E0E001C1E00381E007 -00E00700E00700E00700E00700E00700E00700E00700E0FFFFE00700E00700E00700E00700E007 -00E00700E00700E00700E00700E00700E00700E00700E00700E00700E00700E00700E00700E007 -00E07FE7FE1720809F19>I<001F81F80000F04F040001C07C06000380F80F000300F00F000700 -F00F00070070000007007000000700700000070070000007007000000700700000FFFFFFFF0007 -007007000700700700070070070007007007000700700700070070070007007007000700700700 -070070070007007007000700700700070070070007007007000700700700070070070007007007 -00070070070007007007007FE3FE3FF02420809F26>I<7038F87CFC7EFC7E743A040204020402 -0804080410081008201040200F0E7E9F17>34 D<70F8FCFC74040404080810102040060E7C9F0D ->39 D<0020004000800100020006000C000C00180018003000300030007000600060006000E000 -E000E000E000E000E000E000E000E000E000E000E0006000600060007000300030003000180018 -000C000C000600020001000080004000200B2E7DA112>I<800040002000100008000C00060006 -000300030001800180018001C000C000C000C000E000E000E000E000E000E000E000E000E000E0 -00E000E000C000C000C001C001800180018003000300060006000C00080010002000400080000B -2E7DA112>I<70F8FCFC74040404080810102040060E7C840D>44 D<FFC0FFC00A027F8A0F>I<70 -F8F8F87005057C840D>I<03F0000E1C001C0E00180600380700700380700380700380700380F0 -03C0F003C0F003C0F003C0F003C0F003C0F003C0F003C0F003C0F003C0F003C0F003C0F003C070 -03807003807003807807803807001806001C0E000E1C0003F000121F7E9D17>48 -D<018003800F80F380038003800380038003800380038003800380038003800380038003800380 -03800380038003800380038003800380038007C0FFFE0F1E7C9D17>I<03F0000C1C00100E0020 -0700400780800780F007C0F803C0F803C0F803C02007C00007C0000780000780000F00000E0000 -1C0000380000700000600000C0000180000300000600400C00401800401000803FFF807FFF80FF -FF80121E7E9D17>I<03F0000C1C00100E00200F00780F80780780780780380F80000F80000F00 -000F00000E00001C0000380003F000003C00000E00000F000007800007800007C02007C0F807C0 -F807C0F807C0F00780400780400F00200E001C3C0003F000121F7E9D17>I<000600000600000E -00000E00001E00002E00002E00004E00008E00008E00010E00020E00020E00040E00080E00080E -00100E00200E00200E00400E00C00E00FFFFF0000E00000E00000E00000E00000E00000E00000E -0000FFE0141E7F9D17>I<1803001FFE001FFC001FF8001FE00010000010000010000010000010 -000010000011F000161C00180E001007001007800003800003800003C00003C00003C07003C0F0 -03C0F003C0E00380400380400700200600100E000C380003E000121F7E9D17>I<007C00018200 -0701000E03800C07801C0780380300380000780000700000700000F1F000F21C00F40600F80700 -F80380F80380F003C0F003C0F003C0F003C0F003C07003C07003C0700380380380380700180700 -0C0E00061C0001F000121F7E9D17>I<4000007FFFC07FFF807FFF804001008002008002008004 -0000080000080000100000200000200000400000400000C00000C00001C0000180000380000380 -00038000038000078000078000078000078000078000078000078000030000121F7D9D17>I<03 -F0000C0C001006003003002001806001806001806001807001807803003E03003F06001FC8000F -F00003F80007FC000C7E00103F00300F806003804001C0C001C0C000C0C000C0C000C0C0008060 -01802001001002000C0C0003F000121F7E9D17>I<03F0000E18001C0C00380600380700700700 -700380F00380F00380F003C0F003C0F003C0F003C0F003C07007C07007C03807C0180BC00E13C0 -03E3C0000380000380000380000700300700780600780E00700C002018001070000FC000121F7E -9D17>I<70F8F8F8700000000000000000000070F8F8F87005147C930D>I<70F8F8F87000000000 -00000000000070F0F8F878080808101010202040051D7C930D>I<000100000003800000038000 -000380000007C0000007C0000007C0000009E0000009E0000009E0000010F0000010F0000010F0 -0000207800002078000020780000403C0000403C0000403C0000801E0000801E0000FFFE000100 -0F0001000F0001000F00020007800200078002000780040003C00E0003C01F0007E0FFC03FFE1F -207F9F22>65 D<FFFFE0000F80380007801E0007801F0007800F0007800F8007800F8007800F80 -07800F8007800F8007800F0007801F0007801E0007803C0007FFF00007803C0007801E0007800F -0007800F8007800780078007C0078007C0078007C0078007C0078007C00780078007800F800780 -0F0007801F000F803C00FFFFF0001A1F7E9E20>I<000FC040007030C001C009C0038005C00700 -03C00E0001C01E0000C01C0000C03C0000C07C0000407C00004078000040F8000000F8000000F8 -000000F8000000F8000000F8000000F8000000F8000000F8000000780000007C0000407C000040 -3C0000401C0000401E0000800E000080070001000380020001C0040000703800000FC0001A217D -9F21>I<FFFFE0000F803C0007801E000780070007800380078003C0078001E0078001E0078001 -F0078000F0078000F0078000F8078000F8078000F8078000F8078000F8078000F8078000F80780 -00F8078000F8078000F0078000F0078000F0078001E0078001E0078003C0078003800780070007 -800E000F803C00FFFFE0001D1F7E9E23>I<FFFFFF000F800F0007800300078003000780010007 -800180078000800780008007800080078080800780800007808000078080000781800007FF8000 -078180000780800007808000078080000780800007800020078000200780002007800040078000 -4007800040078000C0078000C0078001800F800F80FFFFFF801B1F7E9E1F>I<FFFFFF000F800F -000780030007800300078001000780018007800080078000800780008007800080078080000780 -800007808000078080000781800007FF8000078180000780800007808000078080000780800007 -800000078000000780000007800000078000000780000007800000078000000FC00000FFFE0000 -191F7E9E1E>I<000FE0200078186000E004E0038002E0070001E00F0000E01E0000601E000060 -3C0000603C0000207C00002078000020F8000000F8000000F8000000F8000000F8000000F80000 -00F8000000F8007FFCF80003E0780001E07C0001E03C0001E03C0001E01E0001E01E0001E00F00 -01E0070001E0038002E000E0046000781820000FE0001E217D9F24>I<FFF8FFF80F800F800780 -0F0007800F0007800F0007800F0007800F0007800F0007800F0007800F0007800F0007800F0007 -800F0007800F0007FFFF0007800F0007800F0007800F0007800F0007800F0007800F0007800F00 -07800F0007800F0007800F0007800F0007800F0007800F0007800F000F800F80FFF8FFF81D1F7E -9E22>I<FFFC0FC007800780078007800780078007800780078007800780078007800780078007 -80078007800780078007800780078007800780078007800FC0FFFC0E1F7F9E10>I<0FFFC0007C -00003C00003C00003C00003C00003C00003C00003C00003C00003C00003C00003C00003C00003C -00003C00003C00003C00003C00003C00003C00003C00003C00203C00F83C00F83C00F83C00F038 -0040780040700030E0000F800012207E9E17>I<FFFE000FC00007800007800007800007800007 -800007800007800007800007800007800007800007800007800007800007800007800007800007 -800007800207800207800207800207800607800407800407800C07801C0F807CFFFFFC171F7E9E -1C>76 D<FF80001FF80F80001F800780001F0005C0002F0005C0002F0005C0002F0004E0004F00 -04E0004F000470008F000470008F000470008F000438010F000438010F000438010F00041C020F -00041C020F00041C020F00040E040F00040E040F00040E040F000407080F000407080F00040708 -0F000403900F000403900F000401E00F000401E00F000401E00F000E00C00F001F00C01F80FFE0 -C1FFF8251F7E9E2A>I<FF803FF807C007C007C0038005E0010005E0010004F001000478010004 -780100043C0100043C0100041E0100040F0100040F010004078100040781000403C1000401E100 -0401E1000400F1000400F1000400790004003D0004003D0004001F0004001F0004000F00040007 -00040007000E0003001F000300FFE001001D1F7E9E22>I<001F800000F0F00001C0380007801E -000F000F000E0007001E0007803C0003C03C0003C07C0003E0780001E0780001E0F80001F0F800 -01F0F80001F0F80001F0F80001F0F80001F0F80001F0F80001F0F80001F0780001E07C0003E07C -0003E03C0003C03C0003C01E0007800E0007000F000F0007801E0001C0380000F0F000001F8000 -1C217D9F23>I<FFFFE0000F80780007801C0007801E0007800F0007800F8007800F8007800F80 -07800F8007800F8007800F8007800F0007801E0007801C000780780007FFE00007800000078000 -000780000007800000078000000780000007800000078000000780000007800000078000000780 -0000078000000FC00000FFFC0000191F7E9E1F>I<001F800000F0F00001C0380007801E000F00 -0F000E0007001E0007803C0003C03C0003C07C0003E07C0003E0780001E0F80001F0F80001F0F8 -0001F0F80001F0F80001F0F80001F0F80001F0F80001F0F80001F0780001E0780001E07C0003E0 -3C0003C03C0F03C01E1087800E2047000F204F0007A03E0001E0380000F0F010001FB010000030 -10000038300000387000003FF000001FE000001FE000000FC0000007801C297D9F23>I<FFFF80 -000F80F0000780780007803C0007801E0007801E0007801F0007801F0007801F0007801F000780 -1E0007801E0007803C00078078000780F00007FF80000781C0000780E0000780F0000780700007 -807800078078000780780007807C0007807C0007807C0007807C0407807E0407803E040FC01E08 -FFFC0F10000003E01E207E9E21>I<07E0800C1980100780300380600180600180E00180E00080 -E00080E00080F00000F000007800007F00003FF0001FFC000FFE0003FF00001F800007800003C0 -0003C00001C08001C08001C08001C08001C0C00180C00380E00300F00600CE0C0081F80012217D -9F19>I<7FFFFFE0780F01E0600F0060400F0020400F0020C00F0030800F0010800F0010800F00 -10800F0010000F0000000F0000000F0000000F0000000F0000000F0000000F0000000F0000000F -0000000F0000000F0000000F0000000F0000000F0000000F0000000F0000000F0000000F000000 -0F0000001F800007FFFE001C1F7E9E21>I<FFFC3FF80FC007C007800380078001000780010007 -800100078001000780010007800100078001000780010007800100078001000780010007800100 -078001000780010007800100078001000780010007800100078001000780010007800100038002 -000380020001C0020001C0040000E008000070180000382000000FC0001D207E9E22>I<FFF003 -FE1F8000F80F0000600F800060078000400780004003C0008003C0008003C0008001E0010001E0 -010001F0010000F0020000F0020000F806000078040000780400003C0800003C0800003C080000 -1E1000001E1000001F3000000F2000000F20000007C0000007C0000007C0000003800000038000 -00038000000100001F207F9E22>I<FFF07FF81FF01F800FC007C00F00078003800F0007800100 -0F0007C00100078007C00200078007C00200078007C0020003C009E0040003C009E0040003C009 -E0040003E010F00C0001E010F0080001E010F0080001F02078080000F02078100000F020781000 -00F0403C10000078403C20000078403C20000078C03E2000003C801E4000003C801E4000003C80 -1E4000001F000F8000001F000F8000001F000F8000001E00078000000E00070000000E00070000 -000C000300000004000200002C207F9E2F>I<FEFEC0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0 -C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0FEFE072D7CA10D>91 -D<080410082010201040204020804080408040B85CFC7EFC7E7C3E381C0F0E7B9F17>I<FEFE06 -060606060606060606060606060606060606060606060606060606060606060606060606060606 -06FEFE072D7FA10D>I<081020204040808080B8FCFC7C38060E7D9F0D>96 -D<1FE000303000781800781C00300E00000E00000E00000E0000FE00078E001E0E00380E00780E -00F00E10F00E10F00E10F01E10781E103867200F83C014147E9317>I<0E0000FE00000E00000E -00000E00000E00000E00000E00000E00000E00000E00000E00000E3E000EC3800F01C00F00E00E -00E00E00700E00700E00780E00780E00780E00780E00780E00780E00700E00700E00E00F00E00D -01C00CC300083E0015207F9F19>I<03F80E0C1C1E381E380C70007000F000F000F000F000F000 -F00070007000380138011C020E0C03F010147E9314>I<000380003F8000038000038000038000 -038000038000038000038000038000038000038003E380061B801C078038038038038070038070 -0380F00380F00380F00380F00380F00380F003807003807003803803803807801C07800E1B8003 -E3F815207E9F19>I<03F0000E1C001C0E00380700380700700700700380F00380F00380FFFF80 -F00000F00000F000007000007000003800801800800C010007060001F80011147F9314>I<007C -00C6018F038F07060700070007000700070007000700FFF0070007000700070007000700070007 -0007000700070007000700070007000700070007007FF01020809F0E>I<0000E003E3300E3C30 -1C1C30380E00780F00780F00780F00780F00780F00380E001C1C001E380033E000200000200000 -3000003000003FFE001FFF800FFFC03001E0600070C00030C00030C00030C000306000603000C0 -1C038003FC00141F7F9417>I<0E0000FE00000E00000E00000E00000E00000E00000E00000E00 -000E00000E00000E00000E3E000E43000E81800F01C00F01C00E01C00E01C00E01C00E01C00E01 -C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C0FFE7FC16207F9F19>I<1C -003E003E003E001C000000000000000000000000000E007E000E000E000E000E000E000E000E00 -0E000E000E000E000E000E000E000E000E000E00FFC00A1F809E0C>I<00E001F001F001F000E0 -000000000000000000000000007007F000F0007000700070007000700070007000700070007000 -7000700070007000700070007000700070007000706070F060F0C061803F000C28829E0E>I<0E -0000FE00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E0FF00E -03C00E03000E02000E04000E08000E10000E30000E70000EF8000F38000E1C000E1E000E0E000E -07000E07800E03800E03C00E03E0FFCFF815207F9F18>I<0E00FE000E000E000E000E000E000E -000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E00 -0E000E000E000E00FFE00B20809F0C>I<0E1F01F000FE618618000E81C81C000F00F00E000F00 -F00E000E00E00E000E00E00E000E00E00E000E00E00E000E00E00E000E00E00E000E00E00E000E -00E00E000E00E00E000E00E00E000E00E00E000E00E00E000E00E00E000E00E00E00FFE7FE7FE0 -23147F9326>I<0E3E00FE43000E81800F01C00F01C00E01C00E01C00E01C00E01C00E01C00E01 -C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C0FFE7FC16147F9319>I<01F80007 -0E001C03803801C03801C07000E07000E0F000F0F000F0F000F0F000F0F000F0F000F07000E070 -00E03801C03801C01C0380070E0001F80014147F9317>I<0E3E00FEC3800F01C00F00E00E00E0 -0E00F00E00700E00780E00780E00780E00780E00780E00780E00700E00F00E00E00F01E00F01C0 -0EC3000E3E000E00000E00000E00000E00000E00000E00000E00000E0000FFE000151D7F9319> -I<03E0800619801C05803C0780380380780380700380F00380F00380F00380F00380F00380F003 -807003807803803803803807801C0B800E138003E3800003800003800003800003800003800003 -80000380000380003FF8151D7E9318>I<0E78FE8C0F1E0F1E0F0C0E000E000E000E000E000E00 -0E000E000E000E000E000E000E000E00FFE00F147F9312>I<1F9030704030C010C010C010E000 -78007F803FE00FF00070803880188018C018C018E030D0608F800D147E9312>I<020002000200 -060006000E000E003E00FFF80E000E000E000E000E000E000E000E000E000E000E000E080E080E -080E080E080610031001E00D1C7F9B12>I<0E01C0FE1FC00E01C00E01C00E01C00E01C00E01C0 -0E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E03C00603C0030DC001F1FC -16147F9319>I<FF83F81E01E01C00C00E00800E00800E00800701000701000382000382000382 -0001C40001C40001EC0000E80000E80000700000700000700000200015147F9318>I<FF9FE1FC -3C0780701C0300601C0380200E0380400E0380400E03C0400707C0800704C0800704E080038861 -000388710003C8730001D0320001D03A0000F03C0000E01C0000E01C0000601800004008001E14 -7F9321>I<7FC3FC0F01E00701C007018003810001C20000E40000EC00007800003800003C0000 -7C00004E000087000107000303800201C00601E01E01E0FF07FE1714809318>I<FF83F81E01E0 -1C00C00E00800E00800E008007010007010003820003820003820001C40001C40001EC0000E800 -00E800007000007000007000002000002000004000004000004000F08000F08000F10000620000 -3C0000151D7F9318>I<3FFF380E200E201C40384078407000E001E001C00380078007010E011E -011C0338027006700EFFFE10147F9314>I E /Fp 13 122 df<0000001FFC0000C000000003FF -FFC001C00000001FFFFFF003C00000007FFFFFFC07C0000001FFFC00FE0FC0000007FFC0001F9F -C000000FFE000007FFC000003FF8000003FFC000007FF0000000FFC00000FFE00000007FC00001 -FFC00000007FC00001FF800000003FC00003FF000000001FC00007FE000000001FC0000FFE0000 -00000FC0000FFC000000000FC0001FFC0000000007C0001FFC0000000007C0003FF80000000007 -C0003FF80000000003C0003FF80000000003C0007FF80000000003C0007FF80000000003C0007F -F0000000000000007FF000000000000000FFF000000000000000FFF000000000000000FFF00000 -0000000000FFF000000000000000FFF000000000000000FFF000000000000000FFF00000000000 -0000FFF000000000000000FFF000000000000000FFF000000000000000FFF000001FFFFFFF807F -F000001FFFFFFF807FF000001FFFFFFF807FF800001FFFFFFF807FF800000001FFC0003FF80000 -0001FFC0003FF800000001FFC0003FF800000001FFC0001FFC00000001FFC0001FFC00000001FF -C0000FFE00000001FFC0000FFE00000001FFC00007FF00000001FFC00003FF00000001FFC00001 -FF80000001FFC00001FFC0000001FFC00000FFE0000001FFC000007FF0000003FFC000003FFC00 -0003FFC000000FFF000007FFC0000007FFC0001FBFC0000001FFFC00FF1FC00000007FFFFFFE0F -C00000001FFFFFF803C000000003FFFFE000C0000000001FFE00000000413D7BBB4C>71 -D<FFFFFFF803FFFFFFE0FFFFFFF803FFFFFFE0FFFFFFF803FFFFFFE0FFFFFFF803FFFFFFE0007F -F0000001FFC000007FF0000001FFC000007FF0000001FFC000007FF0000001FFC000007FF00000 -01FFC000007FF0000001FFC000007FF0000001FFC000007FF0000001FFC000007FF0000001FFC0 -00007FF0000001FFC000007FF0000001FFC000007FF0000001FFC000007FF0000001FFC000007F -F0000001FFC000007FF0000001FFC000007FF0000001FFC000007FF0000001FFC000007FF00000 -01FFC000007FF0000001FFC000007FF0000001FFC000007FF0000001FFC000007FF0000001FFC0 -00007FFFFFFFFFFFC000007FFFFFFFFFFFC000007FFFFFFFFFFFC000007FFFFFFFFFFFC000007F -F0000001FFC000007FF0000001FFC000007FF0000001FFC000007FF0000001FFC000007FF00000 -01FFC000007FF0000001FFC000007FF0000001FFC000007FF0000001FFC000007FF0000001FFC0 -00007FF0000001FFC000007FF0000001FFC000007FF0000001FFC000007FF0000001FFC000007F -F0000001FFC000007FF0000001FFC000007FF0000001FFC000007FF0000001FFC000007FF00000 -01FFC000007FF0000001FFC000007FF0000001FFC000007FF0000001FFC000007FF0000001FFC0 -00007FF0000001FFC000007FF0000001FFC000007FF0000001FFC000FFFFFFF803FFFFFFE0FFFF -FFF803FFFFFFE0FFFFFFF803FFFFFFE0FFFFFFF803FFFFFFE0433B7CBA4C>I<FFFFFFFE000000 -FFFFFFFE000000FFFFFFFE000000FFFFFFFE000000007FF000000000007FF000000000007FF000 -000000007FF000000000007FF000000000007FF000000000007FF000000000007FF00000000000 -7FF000000000007FF000000000007FF000000000007FF000000000007FF000000000007FF00000 -0000007FF000000000007FF000000000007FF000000000007FF000000000007FF000000000007F -F000000000007FF000000000007FF000000000007FF000000000007FF000000000007FF0000000 -00007FF000000000007FF000000000007FF000000000007FF000000000007FF000000000007FF0 -00000000007FF000000780007FF000000780007FF000000780007FF000000780007FF000000780 -007FF000000F80007FF000000F00007FF000000F00007FF000000F00007FF000001F00007FF000 -001F00007FF000001F00007FF000003F00007FF000003F00007FF000007F00007FF00000FF0000 -7FF00001FF00007FF00003FF00007FF0000FFE00007FF0007FFE00FFFFFFFFFFFE00FFFFFFFFFF -FE00FFFFFFFFFFFE00FFFFFFFFFFFE00313B7CBA3A>76 D<FFFFF0000007FFFFE0FFFFF8000007 -FFFFE0FFFFFC000007FFFFE0FFFFFE000007FFFFE0007FFE00000007E000007FFF00000003C000 -007FFF80000003C000007BFFC0000003C000007BFFE0000003C0000079FFE0000003C0000078FF -F0000003C00000787FF8000003C00000783FFC000003C00000783FFE000003C00000781FFE0000 -03C00000780FFF000003C000007807FF800003C000007803FFC00003C000007803FFE00003C000 -007801FFE00003C000007800FFF00003C0000078007FF80003C0000078003FFC0003C000007800 -3FFE0003C0000078001FFF0003C0000078000FFF0003C00000780007FF8003C00000780003FFC0 -03C00000780003FFE003C00000780001FFF003C00000780000FFF003C000007800007FF803C000 -007800003FFC03C000007800003FFE03C000007800001FFF03C000007800000FFF03C000007800 -0007FF83C0000078000003FFC3C0000078000003FFE3C0000078000001FFF3C0000078000000FF -F3C00000780000007FFBC00000780000003FFFC00000780000003FFFC00000780000001FFFC000 -00780000000FFFC000007800000007FFC000007800000003FFC000007800000003FFC000007800 -000001FFC000007800000000FFC0000078000000007FC0000078000000003FC000007800000000 -3FC00000FC000000001FC000FFFFFC0000000FC000FFFFFC00000007C000FFFFFC00000003C000 -FFFFFC00000003C000433B7CBA4C>78 D<FFFFFFF8001FFFFF80FFFFFFF8001FFFFF80FFFFFFF8 -001FFFFF80FFFFFFF8001FFFFF80007FF00000001F8000007FF00000000F0000007FF00000000F -0000007FF00000000F0000007FF00000000F0000007FF00000000F0000007FF00000000F000000 -7FF00000000F0000007FF00000000F0000007FF00000000F0000007FF00000000F0000007FF000 -00000F0000007FF00000000F0000007FF00000000F0000007FF00000000F0000007FF00000000F -0000007FF00000000F0000007FF00000000F0000007FF00000000F0000007FF00000000F000000 -7FF00000000F0000007FF00000000F0000007FF00000000F0000007FF00000000F0000007FF000 -00000F0000007FF00000000F0000007FF00000000F0000007FF00000000F0000007FF00000000F -0000007FF00000000F0000007FF00000000F0000007FF00000000F0000007FF00000000F000000 -7FF00000000F0000007FF00000000F0000007FF00000000F0000007FF00000000F0000007FF000 -00000F0000007FF00000000F0000007FF00000000F0000003FF00000001E0000003FF00000001E -0000003FF80000001E0000001FF80000003C0000001FF80000003C0000000FFC00000078000000 -07FC000000F800000007FE000001F000000003FF000003F000000001FF800007E000000000FFE0 -001FC0000000003FFC01FF80000000001FFFFFFE000000000007FFFFF8000000000000FFFFE000 -00000000000FFE00000000413C7CBA4A>85 D<003FFE00000001FFFFE0000007FFFFF800000FE0 -07FC00000FF001FE00001FF800FF00001FF8007F80001FF8007FC0001FF8003FC0000FF0003FE0 -0007E0003FE00003C0003FE0000000003FE0000000003FE0000000003FE0000000003FE0000000 -FFFFE000001FFFFFE000007FF83FE00003FF803FE00007FC003FE0000FF0003FE0001FE0003FE0 -003FE0003FE0007FC0003FE0007FC0003FE000FF80003FE000FF80003FE000FF80003FE000FF80 -003FE000FF80007FE0007FC0007FE0007FC000DFE0003FE0039FF0001FF80F0FFFE007FFFE0FFF -E001FFF807FFE0003FE000FFE02B267DA52F>97 D<00FE00000000FFFE00000000FFFE00000000 -FFFE00000000FFFE0000000007FE0000000003FE0000000003FE0000000003FE0000000003FE00 -00000003FE0000000003FE0000000003FE0000000003FE0000000003FE0000000003FE00000000 -03FE0000000003FE0000000003FE0000000003FE0000000003FE0000000003FE0000000003FE01 -FF000003FE1FFFF00003FE7FFFFC0003FEFC03FE0003FFF000FF0003FFC0003F8003FF00001FC0 -03FE00001FE003FE00000FF003FE00000FF803FE00000FF803FE000007FC03FE000007FC03FE00 -0007FC03FE000007FE03FE000007FE03FE000007FE03FE000007FE03FE000007FE03FE000007FE -03FE000007FE03FE000007FE03FE000007FE03FE000007FC03FE000007FC03FE000007FC03FE00 -000FFC03FE00000FF803FE00000FF003FE00001FF003FF00001FE003FF80003FC003FFC0007F80 -03F9E000FF0003F0FC07FE0003F07FFFF80003E01FFFE00003C003FE00002F3C7DBB36>I<01E0 -0007F8000FFC000FFC001FFE001FFE001FFE001FFE000FFC000FFC0007F80001E0000000000000 -0000000000000000000000000000000000000000000000000000000000FE00FFFE00FFFE00FFFE -00FFFE0007FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE -0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE -0003FE0003FE0003FE0003FE00FFFFF0FFFFF0FFFFF0FFFFF0143D7DBC1A>105 -D<0001FFC00000000FFFF80000007FFFFF000000FF80FF800003FE003FE00007F8000FF0000FF0 -0007F8000FF00007F8001FE00003FC003FE00003FE003FE00003FE007FC00001FF007FC00001FF -007FC00001FF007FC00001FF00FFC00001FF80FFC00001FF80FFC00001FF80FFC00001FF80FFC0 -0001FF80FFC00001FF80FFC00001FF80FFC00001FF80FFC00001FF807FC00001FF007FC00001FF -007FC00001FF003FE00003FE003FE00003FE001FE00003FC001FF00007FC000FF00007F80007F8 -000FF00003FE003FE00000FF80FF8000007FFFFF0000000FFFF800000001FFC0000029267DA530 ->111 D<01FC03F000FFFC0FFC00FFFC1FFF00FFFC3C3F80FFFC707F8007FCE0FFC003FCC0FFC0 -03FD80FFC003FD80FFC003FF807F8003FF003F0003FF001E0003FF00000003FE00000003FE0000 -0003FE00000003FE00000003FE00000003FE00000003FE00000003FE00000003FE00000003FE00 -000003FE00000003FE00000003FE00000003FE00000003FE00000003FE00000003FE00000003FE -00000003FE00000003FE00000003FE000000FFFFFC0000FFFFFC0000FFFFFC0000FFFFFC000022 -267DA528>114 D<003FF07003FFFEF007FFFFF01FC01FF03F0003F03E0001F07C0001F07C0000 -F0FC0000F0FC0000F0FE0000F0FF000000FFC00000FFFC00007FFFF0003FFFFE003FFFFF801FFF -FFC00FFFFFE003FFFFF000FFFFF8001FFFFC00007FFC000007FE700001FEF00000FEF000007EF8 -00007EF800007EFC00007EFC00007CFE0000FCFF0000F8FF8001F0FFF00FE0F9FFFFC0F07FFF00 -C01FF8001F267DA526>I<000F0000000F0000000F0000000F0000000F0000001F0000001F0000 -001F0000001F0000003F0000003F0000007F0000007F000000FF000001FF000003FF000007FF00 -001FFFFFF0FFFFFFF0FFFFFFF0FFFFFFF001FF000001FF000001FF000001FF000001FF000001FF -000001FF000001FF000001FF000001FF000001FF000001FF000001FF000001FF000001FF000001 -FF000001FF000001FF000001FF000001FF003C01FF003C01FF003C01FF003C01FF003C01FF003C -01FF003C01FF003C00FF007800FF8078007F80F0003FC1E0001FFFC0000FFF800001FE001E377E -B626>I<FFFFF001FFFCFFFFF001FFFCFFFFF001FFFCFFFFF001FFFC03FE00001F8003FF00001F -0001FF00001E0001FF80003E0000FF80003C0000FF80003C00007FC0007800007FC0007800007F -E000F800003FE000F000003FF001F000001FF001E000001FF803E000000FF803C000000FFC03C0 -000007FC0780000007FC0780000007FE0F80000003FE0F00000003FF1F00000001FF1E00000001 -FFBE00000000FFBC00000000FFFC000000007FF8000000007FF8000000007FF8000000003FF000 -0000003FF0000000001FE0000000001FE0000000000FC0000000000FC000000000078000000000 -0780000000000F80000000000F00000000001F00000000001E00000008003E0000007F003C0000 -007F007C000000FF8078000000FF80F8000000FF80F0000000FF81E00000007F07C00000007C1F -800000003FFF000000001FFE0000000007F0000000002E377EA533>121 -D E end -%%EndProlog -%%BeginSetup -%%Feature: *Resolution 300dpi -TeXDict begin - -%%EndSetup -%%Page: 1 1 -0 bop 0 1152 a Fp(GNU)33 b(History)f(Library)p 0 1201 1950 -17 v 1035 1250 a Fo(Edition)16 b(2.0,)e(for)h Fn(History)f(Library)g -Fo(V)l(ersion)i(2.0.)1759 1304 y(July)g(1994)0 2443 y Fm(Brian)23 -b(F)-6 b(o)n(x,)23 b(F)-6 b(ree)23 b(Soft)n(w)n(are)f(F)-6 -b(oundation)0 2509 y(Chet)22 b(Ramey)-6 b(,)23 b(Case)e(W)-6 -b(estern)23 b(Reserv)n(e)f(Univ)n(ersit)n(y)p 0 2545 1950 9 -v eop -%%Page: 2 2 -1 bop 0 295 a Fo(This)16 b(do)q(cumen)o(t)g(describ)q(es)h(the)f(GNU)f -(History)g(library)l(,)h(a)g(programming)e(to)q(ol)i(that)f(pro)o(vides)h(a)f -(consisten)o(t)0 358 y(user)g(in)o(terface)h(for)e(recalling)j(lines)g(of)e -(previously)h(t)o(yp)q(ed)g(input.)0 495 y(Published)h(b)o(y)f(the)f(F)l(ree) -g(Soft)o(w)o(are)f(F)l(oundation)0 557 y(675)g(Massac)o(h)o(usetts)g(Av)o(en) -o(ue,)0 619 y(Cam)o(bridge,)h(MA)g(02139)f(USA)0 756 y(P)o(ermission)f(is)g -(gran)o(ted)f(to)f(mak)o(e)h(and)h(distribute)h(v)o(erbatim)e(copies)h(of)f -(this)h(man)o(ual)g(pro)o(vided)g(the)f(cop)o(yrigh)o(t)0 818 -y(notice)k(and)f(this)h(p)q(ermission)h(notice)e(are)g(preserv)o(ed)h(on)f -(all)h(copies.)0 955 y(P)o(ermission)f(is)f(gran)o(ted)f(to)h(cop)o(y)g(and)g -(distribute)h(mo)q(di\014ed)h(v)o(ersions)e(of)f(this)i(man)o(ual)f(under)h -(the)f(conditions)0 1018 y(for)e(v)o(erbatim)g(cop)o(ying,)h(pro)o(vided)h -(that)d(the)i(en)o(tire)g(resulting)h(deriv)o(ed)f(w)o(ork)f(is)h -(distributed)h(under)f(the)g(terms)0 1080 y(of)i(a)g(p)q(ermission)h(notice)g -(iden)o(tical)h(to)e(this)g(one.)0 1217 y(P)o(ermission)20 -b(is)g(gran)o(ted)f(to)g(cop)o(y)h(and)f(distribute)i(translations)f(of)f -(this)h(man)o(ual)f(in)o(to)h(another)f(language,)0 1279 y(under)c(the)f(ab)q -(o)o(v)o(e)g(conditions)h(for)e(mo)q(di\014ed)j(v)o(ersions,)e(except)g(that) -g(this)g(p)q(ermission)i(notice)e(ma)o(y)g(b)q(e)h(stated)0 -1341 y(in)h(a)f(translation)g(appro)o(v)o(ed)g(b)o(y)g(the)g(F)l(oundation.)0 -2636 y(Cop)o(yrigh)o(t)226 2635 y(c)214 2636 y Fl(\015)g Fo(1989,)f(1991)g(F) -l(ree)h(Soft)o(w)o(are)f(F)l(oundation,)h(Inc.)p eop -%%Page: 1 3 -2 bop 0 -83 a Fo(Chapter)15 b(1:)k(Using)d(History)f(In)o(teractiv)o(ely)1157 -b(1)0 158 y Fk(1)41 b(Using)14 b(History)h(In)n(teractiv)n(ely)62 -330 y Fo(This)i(c)o(hapter)e(describ)q(es)j(ho)o(w)d(to)h(use)g(the)g(GNU)g -(History)f(Library)i(in)o(teractiv)o(ely)l(,)g(from)e(a)g(user's)h(stand-)0 -392 y(p)q(oin)o(t.)23 b(It)16 b(should)h(b)q(e)f(considered)i(a)d(user's)h -(guide.)23 b(F)l(or)15 b(information)h(on)g(using)h(the)f(GNU)g(History)f -(Library)0 454 y(in)h(y)o(our)f(o)o(wn)f(programs,)g(see)i(Chapter)e(2)h -([Programming)f(with)i(GNU)f(History],)f(page)h(5.)0 663 y -Fm(1.1)33 b(History)15 b(In)n(teraction)62 800 y Fo(The)j(History)g(library)g -(pro)o(vides)h(a)e(history)h(expansion)h(feature)e(that)g(is)i(similar)g(to)e -(the)h(history)f(expan-)0 862 y(sion)k(pro)o(vided)h(b)o(y)f -Fn(csh)p Fo(.)36 b(The)22 b(follo)o(wing)f(text)g(describ)q(es)h(the)f(syn)o -(tax)f(used)i(to)e(manipulate)i(the)f(history)0 924 y(information.)62 -1061 y(History)11 b(expansion)i(tak)o(es)d(place)i(in)h(t)o(w)o(o)d(parts.)18 -b(The)11 b(\014rst)g(is)h(to)f(determine)h(whic)o(h)g(line)h(from)e(the)g -(previous)0 1124 y(history)h(should)h(b)q(e)f(used)h(during)f(substitution.) -20 b(The)12 b(second)g(is)h(to)e(select)h(p)q(ortions)g(of)g(that)f(line)i -(for)f(inclusion)0 1186 y(in)o(to)f(the)h(curren)o(t)f(one.)18 -b(The)12 b(line)h(selected)f(from)f(the)g(previous)h(history)g(is)f(called)i -(the)e Fj(ev)o(en)o(t)p Fo(,)h(and)f(the)h(p)q(ortions)0 1248 -y(of)h(that)g(line)i(that)e(are)g(acted)g(up)q(on)h(are)g(called)h -Fj(w)o(ords)p Fo(.)j(The)c(line)h(is)f(brok)o(en)f(in)o(to)h(w)o(ords)f(in)h -(the)f(same)h(fashion)0 1310 y(that)j(Bash)h(do)q(es,)h(so)e(that)g(sev)o -(eral)h(English)i(\(or)d(Unix\))h(w)o(ords)f(surrounded)i(b)o(y)f(quotes)f -(are)h(considered)h(as)0 1373 y(one)c(w)o(ord.)0 1565 y Fi(1.1.1)30 -b(Ev)n(en)n(t)16 b(Designators)62 1702 y Fo(An)g(ev)o(en)o(t)f(designator)g -(is)g(a)g(reference)h(to)f(a)g(command)g(line)i(en)o(try)d(in)i(the)g -(history)f(list.)0 1847 y Fn(!)216 b Fo(Start)14 b(a)g(history)h -(substitution,)g(except)h(when)f(follo)o(w)o(ed)g(b)o(y)g(a)f(space,)h(tab,)f -(the)h(end)g(of)g(the)g(line,)240 1909 y Fn(=)g Fo(or)g Fn(\()p -Fo(.)0 1989 y Fn(!!)192 b Fo(Refer)16 b(to)e(the)i(previous)f(command.)20 -b(This)c(is)g(a)f(synon)o(ym)g(for)f Fn(!-1)p Fo(.)0 2068 y -Fn(!n)192 b Fo(Refer)16 b(to)e(command)h(line)i Fj(n)p Fo(.)0 -2148 y Fn(!-n)168 b Fo(Refer)16 b(to)e(the)i(command)f Fj(n)g -Fo(lines)i(bac)o(k.)0 2227 y Fn(!string)72 b Fo(Refer)16 b(to)e(the)i(most)e -(recen)o(t)h(command)g(starting)g(with)g Fj(string)p Fo(.)0 -2298 y Fn(!?string)p Fo([)p Fn(?)p Fo(])240 2360 y(Refer)h(to)e(the)i(most)e -(recen)o(t)h(command)g(con)o(taining)h Fj(string)p Fo(.)0 2440 -y Fn(!#)192 b Fo(The)15 b(en)o(tire)h(command)f(line)i(t)o(yp)q(ed)f(so)e -(far.)0 2510 y Fn(^string1^string2^)240 2573 y Fo(Quic)o(k)j(Substitution.)22 -b(Rep)q(eat)16 b(the)g(last)f(command,)h(replacing)h Fj(string1)h -Fo(with)e Fj(string2)p Fo(.)21 b(Equiv-)240 2635 y(alen)o(t)15 -b(to)g Fn(!!:s/string1/string2/)p Fo(.)p eop -%%Page: 2 4 -3 bop 0 -83 a Fo(2)1497 b(GNU)15 b(History)g(Library)0 158 -y Fi(1.1.2)30 b(W)-5 b(ord)15 b(Designators)62 295 y Fo(A)i -Fn(:)g Fo(separates)f(the)h(ev)o(en)o(t)f(sp)q(eci\014cation)j(from)d(the)g -(w)o(ord)g(designator.)25 b(It)17 b(can)g(b)q(e)g(omitted)g(if)g(the)g(w)o -(ord)0 358 y(designator)d(b)q(egins)h(with)f(a)f Fn(^)p Fo(,)h -Fn($)p Fo(,)f Fn(*)h Fo(or)f Fn(\045)p Fo(.)20 b(W)l(ords)13 -b(are)h(n)o(um)o(b)q(ered)g(from)f(the)h(b)q(eginning)i(of)d(the)h(line,)i -(with)e(the)0 420 y(\014rst)h(w)o(ord)f(b)q(eing)j(denoted)f(b)o(y)f(a)g(0)f -(\(zero\).)0 569 y Fn(0)h(\(zero\))57 b Fo(The)15 b Fn(0)p -Fo(th)g(w)o(ord.)20 b(F)l(or)14 b(man)o(y)h(applications,)h(this)g(is)g(the)f -(command)g(w)o(ord.)0 656 y Fn(n)216 b Fo(The)15 b Fj(n)p Fo(th)h(w)o(ord.)0 -744 y Fn(^)216 b Fo(The)15 b(\014rst)g(argumen)o(t;)f(that)h(is,)g(w)o(ord)g -(1.)0 831 y Fn($)216 b Fo(The)15 b(last)h(argumen)o(t.)0 918 -y Fn(\045)216 b Fo(The)15 b(w)o(ord)g(matc)o(hed)g(b)o(y)g(the)g(most)g -(recen)o(t)g Fn(?string?)f Fo(searc)o(h.)0 1005 y Fn(x-y)168 -b Fo(A)15 b(range)g(of)g(w)o(ords;)f Fn(-)p Fj(y)19 b Fo(abbreviates)c -Fn(0-)p Fj(y)t Fo(.)0 1092 y Fn(*)216 b Fo(All)17 b(of)f(the)g(w)o(ords,)f -(except)i(the)f Fn(0)p Fo(th.)22 b(This)17 b(is)f(a)g(synon)o(ym)g(for)f -Fn(1-$)p Fo(.)22 b(It)17 b(is)f(not)g(an)g(error)f(to)h(use)240 -1155 y Fn(*)f Fo(if)h(there)f(is)h(just)f(one)g(w)o(ord)f(in)i(the)g(ev)o(en) -o(t;)e(the)i(empt)o(y)e(string)i(is)f(returned)h(in)g(that)e(case.)0 -1242 y Fn(x*)192 b Fo(Abbreviates)16 b Fn(x-$)0 1329 y(x-)192 -b Fo(Abbreviates)16 b Fn(x-$)f Fo(lik)o(e)h Fn(x*)p Fo(,)e(but)i(omits)f(the) -g(last)g(w)o(ord.)0 1537 y Fi(1.1.3)30 b(Mo)r(di\014ers)62 -1674 y Fo(After)20 b(the)f(optional)i(w)o(ord)e(designator,)h(y)o(ou)f(can)h -(add)g(a)g(sequence)h(of)e(one)h(or)f(more)g(of)g(the)h(follo)o(wing)0 -1736 y(mo)q(di\014ers,)c(eac)o(h)f(preceded)i(b)o(y)e(a)g Fn(:)p -Fo(.)0 1885 y Fn(h)216 b Fo(Remo)o(v)o(e)15 b(a)g(trailing)h(pathname)f(comp) -q(onen)o(t,)g(lea)o(ving)h(only)g(the)f(head.)0 1973 y Fn(r)216 -b Fo(Remo)o(v)o(e)15 b(a)g(trailing)h(su\016x)f(of)g(the)g(form)g(`)p -Fn(.)p Fo(')p Fj(su\016x)p Fo(,)f(lea)o(ving)i(the)f(basename.)0 -2060 y Fn(e)216 b Fo(Remo)o(v)o(e)15 b(all)h(but)g(the)f(trailing)h(su\016x.) -0 2147 y Fn(t)216 b Fo(Remo)o(v)o(e)15 b(all)h(leading)h(pathname)e(comp)q -(onen)o(ts,)g(lea)o(ving)h(the)f(tail.)0 2234 y Fn(p)216 b -Fo(Prin)o(t)15 b(the)g(new)h(command)f(but)g(do)g(not)g(execute)h(it.)0 -2309 y Fn(s/old/new/)240 2371 y Fo(Substitute)g Fj(new)k Fo(for)15 -b(the)h(\014rst)f(o)q(ccurrence)h(of)g Fj(old)h Fo(in)g(the)e(ev)o(en)o(t)h -(line.)22 b(An)o(y)16 b(delimiter)h(ma)o(y)e(b)q(e)240 2433 -y(used)e(in)f(place)h(of)f Fn(/)p Fo(.)19 b(The)12 b(delimiter)i(ma)o(y)d(b)q -(e)i(quoted)f(in)h Fj(old)h Fo(and)e Fj(new)17 b Fo(with)12 -b(a)g(single)h(bac)o(kslash.)240 2496 y(If)g Fn(&)h Fo(app)q(ears)f(in)h -Fj(new)p Fo(,)f(it)h(is)g(replaced)g(b)o(y)f Fj(old)p Fo(.)20 -b(A)13 b(single)i(bac)o(kslash)e(will)i(quote)e(the)h Fn(&)p -Fo(.)19 b(The)13 b(\014nal)240 2558 y(delimiter)k(is)f(optional)g(if)f(it)h -(is)f(the)h(last)f(c)o(haracter)f(on)h(the)h(input)g(line.)0 -2645 y Fn(&)216 b Fo(Rep)q(eat)16 b(the)f(previous)h(substitution.)p -eop -%%Page: 3 5 -4 bop 0 -83 a Fo(Chapter)15 b(1:)k(Using)d(History)f(In)o(teractiv)o(ely)1157 -b(3)0 158 y Fn(g)216 b Fo(Cause)15 b(c)o(hanges)g(to)f(b)q(e)i(applied)h(o)o -(v)o(er)d(the)h(en)o(tire)g(ev)o(en)o(t)g(line.)21 b(Used)16 -b(in)g(conjunction)g(with)f Fn(s)p Fo(,)f(as)240 221 y(in)i -Fn(gs/old/new/)p Fo(,)d(or)i(with)h Fn(&)p Fo(.)p eop -%%Page: 4 6 -5 bop 0 -83 a Fo(4)1497 b(GNU)15 b(History)g(Library)p eop -%%Page: 5 7 -6 bop 0 -83 a Fo(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g(History)1039 -b(5)0 158 y Fk(2)41 b(Programming)16 b(with)f(GNU)h(History)62 -347 y Fo(This)e(c)o(hapter)f(describ)q(es)i(ho)o(w)d(to)h(in)o(terface)g -(programs)f(that)h(y)o(ou)g(write)g(with)g(the)h(GNU)f(History)g(Library)l(.) -0 409 y(It)j(should)g(b)q(e)g(considered)h(a)f(tec)o(hnical)h(guide.)22 -b(F)l(or)15 b(information)h(on)f(the)h(in)o(teractiv)o(e)g(use)g(of)f(GNU)g -(History)l(,)0 471 y(see)g(Chapter)g(1)g([Using)h(History)f(In)o(teractiv)o -(ely],)g(page)g(1.)0 698 y Fm(2.1)33 b(In)n(tro)r(duction)17 -b(to)e(History)62 835 y Fo(Man)o(y)j(programs)g(read)h(input)h(from)e(the)g -(user)h(a)g(line)h(at)f(a)f(time.)31 b(The)19 b(GNU)g(History)f(library)i(is) -f(able)0 897 y(to)e(k)o(eep)g(trac)o(k)f(of)h(those)g(lines,)i(asso)q(ciate)e -(arbitrary)g(data)g(with)g(eac)o(h)g(line,)j(and)d(utilize)i(information)f -(from)0 960 y(previous)e(lines)h(in)f(comp)q(osing)f(new)h(ones.)62 -1097 y(The)i(programmer)f(using)h(the)g(History)g(library)g(has)g(a)o(v)m -(ailable)h(functions)g(for)e(remem)o(b)q(ering)h(lines)i(on)d(a)0 -1159 y(history)f(list,)g(asso)q(ciating)g(arbitrary)g(data)f(with)h(a)f -(line,)j(remo)o(ving)d(lines)j(from)d(the)h(list,)g(searc)o(hing)g(through)0 -1221 y(the)h(list)h(for)e(a)h(line)h(con)o(taining)g(an)f(arbitrary)f(text)h -(string,)g(and)g(referencing)h(an)o(y)f(line)h(in)g(the)f(list)h(directly)l -(.)0 1284 y(In)d(addition,)h(a)e(history)h Fj(expansion)h Fo(function)g(is)f -(a)o(v)m(ailable)h(whic)o(h)g(pro)o(vides)f(for)f(a)h(consisten)o(t)g(user)g -(in)o(terface)0 1346 y(across)f(di\013eren)o(t)i(programs.)62 -1483 y(The)i(user)g(using)g(programs)f(written)g(with)h(the)g(History)f -(library)i(has)e(the)h(b)q(ene\014t)h(of)e(a)g(consisten)o(t)h(user)0 -1545 y(in)o(terface)d(with)g(a)f(set)h(of)f(w)o(ell-kno)o(wn)h(commands)g -(for)f(manipulating)i(the)f(text)f(of)g(previous)h(lines)h(and)f(using)0 -1608 y(that)g(text)g(in)i(new)e(commands.)22 b(The)15 b(basic)i(history)e -(manipulation)j(commands)d(are)g(similar)i(to)e(the)h(history)0 -1670 y(substitution)g(pro)o(vided)g(b)o(y)f Fn(csh)p Fo(.)62 -1807 y(If)g(the)g(programmer)e(desires,)i(he)g(can)g(use)g(the)f(Readline)j -(library)l(,)e(whic)o(h)h(includes)g(some)f(history)f(manip-)0 -1870 y(ulation)i(b)o(y)f(default,)h(and)f(has)g(the)g(added)h(adv)m(an)o -(tage)f(of)g(command)g(line)h(editing.)0 2096 y Fm(2.2)33 b(History)15 -b(Storage)62 2234 y Fo(The)h(history)f(list)h(is)g(an)f(arra)o(y)f(of)g -(history)i(en)o(tries.)k(A)15 b(history)g(en)o(try)g(is)h(declared)g(as)f -(follo)o(ws:)120 2358 y Fn(typedef)23 b(struct)g(_hist_entry)f({)168 -2408 y(char)h(*line;)168 2458 y(char)g(*data;)120 2508 y(})h(HIST_ENTRY;)62 -2645 y Fo(The)16 b(history)f(list)h(itself)g(migh)o(t)f(therefore)g(b)q(e)h -(declared)g(as)p eop -%%Page: 6 8 -7 bop 0 -83 a Fo(6)1497 b(GNU)15 b(History)g(Library)120 158 -y Fn(HIST_ENTRY)22 b(**the_history_list;)62 302 y Fo(The)16 -b(state)e(of)h(the)g(History)g(library)h(is)g(encapsulated)g(in)o(to)f(a)g -(single)i(structure:)120 434 y Fn(/*)24 b(A)f(structure)g(used)g(to)h(pass)f -(the)h(current)f(state)g(of)g(the)h(history)f(stuff)g(around.)g(*/)120 -484 y(typedef)g(struct)g(_hist_state)f({)168 534 y(HIST_ENTRY)g(**entries;) -214 b(/*)23 b(Pointer)g(to)h(the)f(entries)g(themselves.)f(*/)168 -584 y(int)h(offset;)453 b(/*)23 b(The)h(location)e(pointer)h(within)g(this)h -(array.)f(*/)168 633 y(int)g(length;)453 b(/*)23 b(Number)g(of)h(elements)f -(within)g(this)g(array.)g(*/)168 683 y(int)g(size;)501 b(/*)23 -b(Number)g(of)h(slots)f(allocated)g(to)g(this)h(array.)f(*/)168 -733 y(int)g(flags;)120 783 y(})h(HISTORY_STATE;)62 927 y Fo(If)16 -b(the)f(\015ags)g(mem)o(b)q(er)g(includes)j Fn(HS_STIFLED)p -Fo(,)13 b(the)i(history)h(has)f(b)q(een)h(sti\015ed.)0 1215 -y Fm(2.3)33 b(History)15 b(F)-6 b(unctions)62 1359 y Fo(This)16 -b(section)g(describ)q(es)h(the)e(calling)i(sequence)f(for)f(the)g(v)m(arious) -h(functions)g(presen)o(t)f(in)h(GNU)f(History)l(.)0 1631 y -Fi(2.3.1)30 b(Initializing)15 b(History)g(and)g(State)g(Managemen)n(t)62 -1775 y Fo(This)j(section)g(describ)q(es)h(functions)f(used)g(to)e(initialize) -21 b(and)c(manage)g(the)g(state)g(of)g(the)g(History)g(library)0 -1837 y(when)f(y)o(ou)f(w)o(an)o(t)f(to)g(use)i(the)f(history)g(functions)h -(in)g(y)o(our)f(program.)1725 2021 y(F)l(unction)-1899 b Fh(void)20 -b Fg(using)p 258 2021 18 3 v 20 w(history)j Ff(\(\))120 2083 -y Fo(Begin)g(a)f(session)g(in)h(whic)o(h)g(the)f(history)g(functions)g(migh)o -(t)g(b)q(e)h(used.)40 b(This)23 b(initializes)i(the)120 2145 -y(in)o(teractiv)o(e)16 b(v)m(ariables.)1725 2328 y(F)l(unction)-1899 -b Fh(HISTORY_STATE)21 b(*)e Fg(history)p 582 2328 V 21 w(get)p -680 2328 V 21 w(history)p 876 2328 V 21 w(state)j Ff(\(\))120 -2391 y Fo(Return)16 b(a)f(structure)g(describing)i(the)e(curren)o(t)g(state)f -(of)h(the)g(input)i(history)l(.)1725 2574 y(F)l(unction)-1899 -b Fh(void)20 b Fg(history)p 302 2574 V 20 w(set)p 393 2574 -V 21 w(history)p 589 2574 V 21 w(state)j Ff(\()p Fn(HISTORY_STATE)13 -b(*state)p Ff(\))120 2636 y Fo(Set)i(the)h(state)e(of)h(the)g(history)g(list) -h(according)g(to)e Fj(state)p Fo(.)p eop -%%Page: 7 9 -8 bop 0 -83 a Fo(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g(History)1039 -b(7)0 158 y Fi(2.3.2)30 b(History)15 b(List)g(Managemen)n(t)62 -295 y Fo(These)i(functions)h(manage)e(individual)k(en)o(tries)d(on)f(the)h -(history)g(list,)g(or)f(set)h(parameters)e(managing)i(the)0 -358 y(list)f(itself.)1725 520 y(F)l(unction)-1899 b Fh(void)20 -b Fg(add)p 219 520 18 3 v 20 w(history)j Ff(\()p Fn(char)14 -b(*string)p Ff(\))120 582 y Fo(Place)j Fj(string)k Fo(at)16 -b(the)g(end)i(of)e(the)g(history)h(list.)25 b(The)17 b(asso)q(ciated)g(data)f -(\014eld)h(\(if)g(an)o(y\))f(is)h(set)g(to)120 644 y Fn(NULL)p -Fo(.)1725 806 y(F)l(unction)-1899 b Fh(HIST_ENTRY)21 b(*)e -Fg(remo)n(v)n(e)p 509 806 V 20 w(history)k Ff(\()p Fn(int)14 -b(which)p Ff(\))120 868 y Fo(Remo)o(v)o(e)d(history)g(en)o(try)g(at)g -(o\013set)f Fj(whic)o(h)i Fo(from)f(the)g(history)l(.)19 b(The)11 -b(remo)o(v)o(ed)g(elemen)o(t)h(is)g(returned)120 930 y(so)j(y)o(ou)g(can)g -(free)g(the)h(line,)g(data,)e(and)i(con)o(taining)g(structure.)1725 -1092 y(F)l(unction)-1899 b Fh(HIST_ENTRY)21 b(*)e Fg(replace)p -505 1092 V 22 w(history)p 702 1092 V 20 w(en)n(try)24 b Ff(\()p -Fn(int)14 b(which,)g(char)h(*line,)f(char)208 1155 y(*data)p -Ff(\))120 1217 y Fo(Mak)o(e)d(the)i(history)f(en)o(try)g(at)f(o\013set)h -Fj(whic)o(h)h Fo(ha)o(v)o(e)e Fj(line)17 b Fo(and)12 b Fj(data)p -Fo(.)19 b(This)12 b(returns)g(the)h(old)g(en)o(try)e(so)120 -1279 y(y)o(ou)i(can)g(disp)q(ose)h(of)e(the)h(data.)19 b(In)13 -b(the)g(case)g(of)f(an)h(in)o(v)m(alid)i Fj(whic)o(h)p Fo(,)f(a)f -Fn(NULL)f Fo(p)q(oin)o(ter)i(is)f(returned.)1725 1441 y(F)l(unction)-1899 -b Fh(void)20 b Fg(sti\015e)p 245 1441 V 21 w(history)j Ff(\()p -Fn(int)14 b(max)p Ff(\))120 1503 y Fo(Sti\015e)i(the)f(history)h(list,)f -(remem)o(b)q(ering)h(only)g(the)f(last)g Fj(max)j Fo(en)o(tries.)1725 -1665 y(F)l(unction)-1899 b Fh(int)20 b Fg(unsti\015e)p 283 -1665 V 21 w(history)i Ff(\(\))120 1728 y Fo(Stop)13 b(sti\015ing)h(the)f -(history)l(.)19 b(This)14 b(returns)f(the)g(previous)h(amoun)o(t)e(the)h -(history)g(w)o(as)g(sti\015ed.)20 b(The)120 1790 y(v)m(alue)c(is)g(p)q -(ositiv)o(e)g(if)g(the)f(history)g(w)o(as)g(sti\015ed,)h(negativ)o(e)f(if)g -(it)h(w)o(asn't.)1725 1952 y(F)l(unction)-1899 b Fh(int)20 -b Fg(history)p 276 1952 V 20 w(is)p 334 1952 V 21 w(sti\015ed)k -Ff(\(\))120 2014 y Fo(Returns)16 b(non-zero)f(if)h(the)f(history)g(is)h -(sti\015ed,)g(zero)f(if)g(it)h(is)g(not.)0 2222 y Fi(2.3.3)30 -b(Information)14 b(Ab)r(out)h(the)g(History)g(List)62 2359 -y Fo(These)h(functions)g(return)f(information)g(ab)q(out)g(the)h(en)o(tire)f -(history)g(list)h(or)f(individual)j(list)f(en)o(tries.)1725 -2521 y(F)l(unction)-1899 b Fh(HIST_ENTRY)21 b(**)e Fg(history)p -530 2521 V 21 w(list)24 b Ff(\(\))120 2583 y Fo(Return)e(a)e -Fn(NULL)h Fo(terminated)g(arra)o(y)f(of)g Fn(HIST_ENTRY)g Fo(whic)o(h)i(is)f -(the)g(curren)o(t)g(input)h(history)l(.)120 2645 y(Elemen)o(t)16 -b(0)f(of)f(this)i(list)g(is)g(the)f(b)q(eginning)i(of)e(time.)20 -b(If)c(there)f(is)h(no)f(history)l(,)g(return)g Fn(NULL)p Fo(.)p -eop -%%Page: 8 10 -9 bop 0 -83 a Fo(8)1497 b(GNU)15 b(History)g(Library)1725 158 -y(F)l(unction)-1899 b Fh(int)20 b Fg(where)p 250 158 18 3 v -20 w(history)j Ff(\(\))120 221 y Fo(Returns)16 b(the)f(o\013set)f(of)h(the)g -(curren)o(t)g(history)g(elemen)o(t.)1725 378 y(F)l(unction)-1899 -b Fh(HIST_ENTRY)21 b(*)e Fg(curren)n(t)p 512 378 V 21 w(history)k -Ff(\(\))120 440 y Fo(Return)14 b(the)g(history)g(en)o(try)f(at)h(the)g -(curren)o(t)f(p)q(osition,)i(as)e(determined)j(b)o(y)d Fn(where_history)h -(\(\))p Fo(.)120 502 y(If)h(there)h(is)f(no)h(en)o(try)e(there,)h(return)g(a) -g Fn(NULL)g Fo(p)q(oin)o(ter.)1725 660 y(F)l(unction)-1899 -b Fh(HIST_ENTRY)21 b(*)e Fg(history)p 504 660 V 21 w(get)j -Ff(\()p Fn(int)15 b(offset)p Ff(\))120 722 y Fo(Return)g(the)g(history)f(en)o -(try)g(at)g(p)q(osition)i Fj(o\013set)p Fo(,)d(starting)h(from)g -Fn(history_base)p Fo(.)k(If)c(there)h(is)g(no)120 784 y(en)o(try)g(there,)g -(or)f(if)i Fj(o\013set)f Fo(is)h(greater)e(than)h(the)h(history)f(length,)g -(return)g(a)g Fn(NULL)g Fo(p)q(oin)o(ter.)1725 942 y(F)l(unction)-1899 -b Fh(int)20 b Fg(history)p 276 942 V 20 w(total)p 412 942 V -22 w(b)n(ytes)j Ff(\(\))120 1004 y Fo(Return)17 b(the)f(n)o(um)o(b)q(er)g(of) -g(b)o(ytes)g(that)f(the)h(primary)g(history)g(en)o(tries)h(are)e(using.)23 -b(This)17 b(function)120 1066 y(returns)e(the)g(sum)h(of)e(the)i(lengths)f -(of)g(all)h(the)g(lines)g(in)g(the)g(history)l(.)0 1265 y Fi(2.3.4)30 -b(Mo)n(ving)15 b(Around)h(the)f(History)g(List)62 1402 y Fo(These)h -(functions)g(allo)o(w)f(the)g(curren)o(t)h(index)g(in)o(to)f(the)h(history)f -(list)h(to)e(b)q(e)i(set)f(or)g(c)o(hanged.)1725 1559 y(F)l(unction)-1899 -b Fh(int)20 b Fg(history)p 276 1559 V 20 w(set)p 367 1559 V -21 w(p)r(os)h Ff(\()p Fn(int)15 b(pos)p Ff(\))120 1621 y Fo(Set)g(the)h(p)q -(osition)g(in)g(the)f(history)g(list)h(to)f Fj(p)q(os)p Fo(,)g(an)g(absolute) -g(index)i(in)o(to)e(the)g(list.)1725 1779 y(F)l(unction)-1899 -b Fh(HIST_ENTRY)21 b(*)e Fg(previous)p 540 1779 V 20 w(history)k -Ff(\(\))120 1841 y Fo(Bac)o(k)16 b(up)h(the)g(curren)o(t)f(history)h -(o\013set)e(to)h(the)h(previous)g(history)g(en)o(try)l(,)f(and)h(return)f(a)g -(p)q(oin)o(ter)120 1903 y(to)f(that)f(en)o(try)l(.)20 b(If)15 -b(there)g(is)h(no)f(previous)h(en)o(try)l(,)f(return)g(a)g -Fn(NULL)g Fo(p)q(oin)o(ter.)1725 2061 y(F)l(unction)-1899 b -Fh(HIST_ENTRY)21 b(*)e Fg(next)p 439 2061 V 21 w(history)k -Ff(\(\))120 2123 y Fo(Mo)o(v)o(e)c(the)h(curren)o(t)g(history)f(o\013set)g -(forw)o(ard)g(to)g(the)h(next)g(history)g(en)o(try)l(,)g(and)g(return)g(the)g -(a)120 2185 y(p)q(oin)o(ter)c(to)e(that)h(en)o(try)l(.)k(If)d(there)f(is)h -(no)f(next)g(en)o(try)l(,)g(return)g(a)g Fn(NULL)g Fo(p)q(oin)o(ter.)0 -2384 y Fi(2.3.5)30 b(Searc)n(hing)15 b(the)h(History)f(List)62 -2521 y Fo(These)e(functions)g(allo)o(w)f(searc)o(hing)h(of)f(the)g(history)g -(list)h(for)f(en)o(tries)h(con)o(taining)g(a)f(sp)q(eci\014c)i(string.)19 -b(Searc)o(h-)0 2583 y(ing)e(ma)o(y)g(b)q(e)g(p)q(erformed)g(b)q(oth)g(forw)o -(ard)f(and)h(bac)o(kw)o(ard)f(from)g(the)h(curren)o(t)f(history)h(p)q -(osition.)26 b(The)17 b(searc)o(h)0 2645 y(ma)o(y)d(b)q(e)i -Fj(anc)o(hored)p Fo(,)f(meaning)h(that)f(the)g(string)g(m)o(ust)g(matc)o(h)f -(at)h(the)g(b)q(eginning)i(of)e(the)h(history)f(en)o(try)l(.)p -eop -%%Page: 9 11 -10 bop 0 -83 a Fo(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g(History)1039 -b(9)1725 158 y(F)l(unction)-1899 b Fh(int)20 b Fg(history)p -276 158 18 3 v 20 w(searc)n(h)j Ff(\()p Fn(char)14 b(*string,)g(int)h -(direction)p Ff(\))120 221 y Fo(Searc)o(h)k(the)g(history)g(for)f -Fj(string)p Fo(,)i(starting)e(at)g(the)h(curren)o(t)g(history)g(o\013set.)30 -b(If)19 b Fj(direction)h Fn(<)f Fo(0,)120 283 y(then)14 b(the)f(searc)o(h)g -(is)h(through)e(previous)i(en)o(tries,)g(else)g(through)f(subsequen)o(t.)20 -b(If)13 b Fj(string)k Fo(is)d(found,)120 345 y(then)f(the)g(curren)o(t)g -(history)g(index)i(is)e(set)g(to)f(that)h(history)g(en)o(try)l(,)f(and)i(the) -f(v)m(alue)h(returned)f(is)h(the)120 407 y(o\013set)h(in)i(the)f(line)i(of)d -(the)h(en)o(try)g(where)g Fj(string)k Fo(w)o(as)c(found.)22 -b(Otherwise,)17 b(nothing)f(is)h(c)o(hanged,)120 470 y(and)e(a)g(-1)g(is)h -(returned.)1725 659 y(F)l(unction)-1899 b Fh(int)20 b Fg(history)p -276 659 V 20 w(searc)n(h)p 452 659 V 21 w(pre\014x)i Ff(\()p -Fn(char)15 b(*string,)f(int)g(direction)p Ff(\))120 721 y Fo(Searc)o(h)22 -b(the)h(history)f(for)f Fj(string)p Fo(,)j(starting)e(at)f(the)i(curren)o(t)f -(history)g(o\013set.)40 b(The)22 b(searc)o(h)g(is)120 783 y(anc)o(hored:)i -(matc)o(hing)18 b(lines)h(m)o(ust)d(b)q(egin)j(with)f Fj(string)p -Fo(.)26 b(If)17 b Fj(direction)i Fn(<)e Fo(0,)g(then)h(the)f(searc)o(h)g(is) -120 845 y(through)e(previous)h(en)o(tries,)f(else)i(through)d(subsequen)o(t.) -21 b(If)16 b Fj(string)j Fo(is)d(found,)f(then)h(the)f(curren)o(t)120 -908 y(history)20 b(index)i(is)e(set)g(to)g(that)f(en)o(try)l(,)i(and)f(the)g -(return)h(v)m(alue)g(is)g(0.)34 b(Otherwise,)22 b(nothing)e(is)120 -970 y(c)o(hanged,)15 b(and)h(a)e(-1)h(is)h(returned.)1725 1159 -y(F)l(unction)-1899 b Fh(int)20 b Fg(history)p 276 1159 V 20 -w(searc)n(h)p 452 1159 V 21 w(p)r(os)h Ff(\()p Fn(char)15 b(*string,)f(int)g -(direction,)g(int)h(pos)p Ff(\))120 1221 y Fo(Searc)o(h)d(for)f -Fj(string)k Fo(in)d(the)g(history)f(list,)i(starting)e(at)g -Fj(p)q(os)p Fo(,)h(an)f(absolute)h(index)h(in)o(to)e(the)h(list.)19 -b(If)12 b Fj(di-)120 1283 y(rection)g Fo(is)h(negativ)o(e,)f(the)g(searc)o(h) -g(pro)q(ceeds)h(bac)o(kw)o(ard)e(from)g Fj(p)q(os)p Fo(,)i(otherwise)f(forw)o -(ard.)17 b(Returns)120 1345 y(the)e(absolute)h(index)g(of)f(the)g(history)h -(elemen)o(t)f(where)h Fj(string)j Fo(w)o(as)14 b(found,)h(or)g(-1)g -(otherwise.)0 1634 y Fi(2.3.6)30 b(Managing)14 b(the)i(History)f(File)62 -1780 y Fo(The)f(History)g(library)h(can)f(read)g(the)g(history)g(from)f(and)i -(write)f(it)g(to)f(a)h(\014le.)20 b(This)15 b(section)g(do)q(cumen)o(ts)f -(the)0 1842 y(functions)i(for)f(managing)g(a)f(history)i(\014le.)1725 -2031 y(F)l(unction)-1899 b Fh(int)20 b Fg(read)p 211 2031 V -20 w(history)i Ff(\()p Fn(char)15 b(*filename)p Ff(\))120 2093 -y Fo(Add)i(the)f(con)o(ten)o(ts)g(of)g Fj(\014lename)k Fo(to)c(the)h(history) -f(list,)h(a)f(line)i(at)e(a)g(time.)24 b(If)17 b Fj(\014lename)j -Fo(is)d Fn(NULL)p Fo(,)120 2155 y(then)f(read)f(from)f(`)p -Fn(~/.history)p Fo('.)k(Returns)e(0)e(if)i(successful,)g(or)f(errno)g(if)h -(not.)1725 2344 y(F)l(unction)-1899 b Fh(int)20 b Fg(read)p -211 2344 V 20 w(history)p 406 2344 V 20 w(range)i Ff(\()p Fn(char)15 -b(*filename,)e(int)i(from,)g(int)f(to)p Ff(\))120 2407 y Fo(Read)j(a)e(range) -h(of)f(lines)j(from)d Fj(\014lename)p Fo(,)i(adding)f(them)g(to)f(the)h -(history)g(list.)23 b(Start)15 b(reading)i(at)120 2469 y(line)f -Fj(from)f Fo(and)g(end)g(at)f Fj(to)p Fo(.)19 b(If)d Fj(from)e -Fo(is)h(zero,)f(start)g(at)g(the)h(b)q(eginning.)22 b(If)15 -b Fj(to)i Fo(is)e(less)g(than)g Fj(from)p Fo(,)120 2531 y(then)i(read)g(un)o -(til)h(the)f(end)g(of)g(the)g(\014le.)25 b(If)17 b Fj(\014lename)k -Fo(is)c Fn(NULL)p Fo(,)f(then)i(read)e(from)g(`)p Fn(~/.history)p -Fo('.)120 2593 y(Returns)g(0)f(if)g(successful,)h(or)f Fn(errno)g -Fo(if)g(not.)p eop -%%Page: 10 12 -11 bop 0 -83 a Fo(10)1474 b(GNU)15 b(History)g(Library)1725 -158 y(F)l(unction)-1899 b Fh(int)20 b Fg(write)p 229 158 18 -3 v 22 w(history)i Ff(\()p Fn(char)15 b(*filename)p Ff(\))120 -221 y Fo(W)l(rite)20 b(the)g(curren)o(t)f(history)h(to)f Fj(\014lename)p -Fo(,)i(o)o(v)o(erwriting)f Fj(\014lename)j Fo(if)d(necessary)l(.)34 -b(If)20 b Fj(\014lename)120 283 y Fo(is)d Fn(NULL)p Fo(,)g(then)g(write)g -(the)g(history)g(list)h(to)e(`)p Fn(~/.history)p Fo('.)23 b(V)l(alues)18 -b(returned)g(are)e(as)h(in)h Fn(read_)120 345 y(history)c(\(\))p -Fo(.)1725 504 y(F)l(unction)-1899 b Fh(int)20 b Fg(app)r(end)p -285 504 V 19 w(history)j Ff(\()p Fn(int)14 b(nelements,)g(char)h(*filename)p -Ff(\))120 566 y Fo(App)q(end)i(the)e(last)g Fj(nelemen)o(ts)j -Fo(of)d(the)g(history)g(list)h(to)f Fj(\014lename)p Fo(.)1725 -724 y(F)l(unction)-1899 b Fh(int)20 b Fg(history)p 276 724 -V 20 w(truncate)p 507 724 V 21 w(\014le)k Ff(\()p Fn(char)14 -b(*filename,)g(int)h(nlines)p Ff(\))120 787 y Fo(T)l(runcate)g(the)h(history) -f(\014le)h Fj(\014lename)p Fo(,)g(lea)o(ving)g(only)g(the)f(last)g -Fj(nlines)k Fo(lines.)0 988 y Fi(2.3.7)30 b(History)15 b(Expansion)62 -1125 y Fo(These)h(functions)g(implemen)o(t)g Fn(csh)p Fo(-lik)o(e)g(history)g -(expansion.)1725 1283 y(F)l(unction)-1899 b Fh(int)20 b Fg(history)p -276 1283 V 20 w(expand)j Ff(\()p Fn(char)14 b(*string,)g(char)h(**output)p -Ff(\))120 1345 y Fo(Expand)20 b Fj(string)p Fo(,)f(placing)i(the)e(result)h -(in)o(to)f Fj(output)p Fo(,)h(a)f(p)q(oin)o(ter)h(to)e(a)h(string)h(\(see)f -(Section)h(1.1)120 1408 y([History)15 b(In)o(teraction],)f(page)h(1\).)20 -b(Returns:)120 1555 y Fn(0)216 b Fo(If)21 b(no)g(expansions)h(to)q(ok)e -(place)h(\(or,)g(if)h(the)f(only)g(c)o(hange)g(in)h(the)f(text)f(w)o(as)g -(the)360 1618 y(de-slashifying)d(of)e(the)g(history)h(expansion)g(c)o -(haracter\);)120 1701 y Fn(1)216 b Fo(if)16 b(expansions)g(did)g(tak)o(e)e -(place;)120 1785 y Fn(-1)192 b Fo(if)16 b(there)f(w)o(as)f(an)h(error)g(in)h -(expansion;)120 1869 y Fn(2)216 b Fo(if)14 b(the)f(returned)h(line)h(should)f -(only)g(b)q(e)f(displa)o(y)o(ed,)i(but)e(not)g(executed,)h(as)f(with)h(the) -360 1931 y Fn(:p)h Fo(mo)q(di\014er)h(\(see)f(Section)h(1.1.3)e([Mo)q -(di\014ers],)h(page)g(2\).)120 2079 y(If)g(an)h(error)e(o)q(curred)i(in)g -(expansion,)f(then)h Fj(output)g Fo(con)o(tains)f(a)g(descriptiv)o(e)i(error) -d(message.)1725 2238 y(F)l(unction)-1899 b Fh(char)20 b(*)f -Fg(history)p 347 2238 V 21 w(arg)p 449 2238 V 19 w(extract)24 -b Ff(\()p Fn(int)14 b(first,)h(int)g(last,)f(char)h(*string)p -Ff(\))120 2300 y Fo(Extract)10 b(a)h(string)g(segmen)o(t)g(consisting)h(of)f -(the)g Fj(\014rst)h Fo(through)f Fj(last)h Fo(argumen)o(ts)e(presen)o(t)h(in) -h Fj(string)p Fo(.)120 2362 y(Argumen)o(ts)j(are)g(brok)o(en)g(up)g(as)g(in)h -(Bash.)1725 2521 y(F)l(unction)-1899 b Fh(char)20 b(*)f Fg(get)p -249 2521 V 21 w(history)p 445 2521 V 20 w(ev)n(en)n(t)25 b -Ff(\()p Fn(char)14 b(*string,)g(int)h(*cindex,)f(int)h(qchar)p -Ff(\))120 2583 y Fo(Returns)e(the)f(text)f(of)h(the)g(history)g(ev)o(en)o(t)f -(b)q(eginning)k(at)c Fj(string)16 b Fn(+)c Fj(*cindex)p Fo(.)20 -b Fj(*cindex)c Fo(is)d(mo)q(di\014ed)120 2645 y(to)h(p)q(oin)o(t)h(to)f -(after)h(the)f(ev)o(en)o(t)h(sp)q(eci\014er.)21 b(A)o(t)15 -b(function)g(en)o(try)l(,)f Fj(cindex)20 b Fo(p)q(oin)o(ts)15 -b(to)f(the)h(index)h(in)o(to)p eop -%%Page: 11 13 -12 bop 0 -83 a Fo(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g(History)1017 -b(11)120 158 y Fj(string)17 b Fo(where)d(the)f(history)h(ev)o(en)o(t)f(sp)q -(eci\014cation)i(b)q(egins.)20 b Fj(qc)o(har)d Fo(is)c(a)g(c)o(haracter)g -(that)g(is)h(allo)o(w)o(ed)120 221 y(to)h(end)g(the)h(ev)o(en)o(t)f(sp)q -(eci\014cation)i(in)f(addition)g(to)f(the)g(\\normal")g(terminating)g(c)o -(haracters.)1725 394 y(F)l(unction)-1899 b Fh(char)20 b(**)f -Fg(history)p 373 394 18 3 v 21 w(tok)n(enize)25 b Ff(\()p Fn(char)14 -b(*string)p Ff(\))120 456 y Fo(Return)k(an)f(arra)o(y)f(of)h(tok)o(ens)f -(parsed)i(out)e(of)h Fj(string)p Fo(,)g(m)o(uc)o(h)h(as)e(the)i(shell)g(migh) -o(t.)26 b(The)17 b(tok)o(ens)120 519 y(are)c(split)h(on)f(white)g(space)h -(and)f(on)g(the)g(c)o(haracters)f Fn(\(\)<>;&|$)p Fo(,)g(and)h(shell)i -(quoting)e(con)o(v)o(en)o(tions)120 581 y(are)i(ob)q(ey)o(ed.)0 -840 y Fm(2.4)33 b(History)15 b(V)-6 b(ariables)62 981 y Fo(This)16 -b(section)g(describ)q(es)h(the)e(externally)h(visible)i(v)m(ariables)e(exp)q -(orted)g(b)o(y)f(the)g(GNU)g(History)g(Library)l(.)1736 1155 -y(V)l(ariable)-1899 b Fh(int)20 b Fg(history)p 276 1155 V 20 -w(base)120 1217 y Fo(The)15 b(logical)i(o\013set)d(of)h(the)g(\014rst)g(en)o -(try)g(in)h(the)f(history)g(list.)1736 1390 y(V)l(ariable)-1899 -b Fh(int)20 b Fg(history)p 276 1390 V 20 w(length)120 1453 -y Fo(The)15 b(n)o(um)o(b)q(er)h(of)f(en)o(tries)g(curren)o(tly)h(stored)f(in) -h(the)f(history)g(list.)1736 1626 y(V)l(ariable)-1899 b Fh(int)20 -b Fg(max)p 208 1626 V 19 w(input)p 360 1626 V 21 w(history)120 -1689 y Fo(The)12 b(maxim)o(um)g(n)o(um)o(b)q(er)g(of)f(history)h(en)o(tries.) -19 b(This)12 b(m)o(ust)f(b)q(e)h(c)o(hanged)g(using)h Fn(stifle_history)120 -1751 y(\(\))p Fo(.)1736 1924 y(V)l(ariable)-1899 b Fh(char)20 -b Fg(history)p 302 1924 V 20 w(expansion)p 569 1924 V 21 w(c)n(har)120 -1987 y Fo(The)15 b(c)o(haracter)g(that)f(starts)g(a)h(history)g(ev)o(en)o(t.) -20 b(The)15 b(default)h(is)g(`)p Fn(!)p Fo('.)1736 2160 y(V)l(ariable)-1899 -b Fh(char)20 b Fg(history)p 302 2160 V 20 w(subst)p 454 2160 -V 20 w(c)n(har)120 2222 y Fo(The)13 b(c)o(haracter)e(that)h(in)o(v)o(ok)o(es) -g(w)o(ord)g(substitution)h(if)g(found)g(at)e(the)i(start)e(of)h(a)g(line.)21 -b(The)12 b(default)120 2285 y(is)k(`)p Fn(^)p Fo('.)1736 2458 -y(V)l(ariable)-1899 b Fh(char)20 b Fg(history)p 302 2458 V -20 w(commen)n(t)p 552 2458 V 19 w(c)n(har)120 2521 y Fo(During)12 -b(tok)o(enization,)h(if)f(this)h(c)o(haracter)e(is)i(seen)f(as)g(the)g -(\014rst)f(c)o(haracter)g(of)h(a)g(w)o(ord,)f(then)i(it)f(and)120 -2583 y(all)19 b(subsequen)o(t)g(c)o(haracters)e(up)h(to)g(a)f(newline)j(are)e -(ignored,)h(suppressing)g(history)f(expansion)120 2645 y(for)d(the)g -(remainder)h(of)f(the)g(line.)21 b(This)16 b(is)g(disabled)h(b)o(y)e -(default.)p eop -%%Page: 12 14 -13 bop 0 -83 a Fo(12)1474 b(GNU)15 b(History)g(Library)1736 -158 y(V)l(ariable)-1899 b Fh(char)20 b(*)f Fg(history)p 347 -158 18 3 v 21 w(no)p 429 158 V 20 w(expand)p 629 158 V 20 w(c)n(hars)120 -221 y Fo(The)f(list)g(of)g(c)o(haracters)e(whic)o(h)j(inhibit)h(history)d -(expansion)i(if)f(found)g(immediately)h(follo)o(wing)120 283 -y Fj(history)p 261 283 14 2 v 16 w(expansion)p 472 283 V 18 -w(c)o(har)p Fo(.)g(The)d(default)f(is)h(whitespace)g(and)g(`)p -Fn(=)p Fo('.)0 575 y Fm(2.5)33 b(History)15 b(Programming)h(Example)62 -720 y Fo(The)g(follo)o(wing)g(program)e(demonstrates)g(simple)j(use)e(of)g -(the)g(GNU)g(History)g(Library)l(.)120 852 y Fn(main)23 b(\(\))120 -902 y({)168 951 y(char)g(line[1024],)f(*t;)168 1001 y(int)h(len,)g(done)h(=)g -(0;)168 1101 y(line[0])f(=)g(0;)168 1201 y(using_history)f(\(\);)168 -1250 y(while)h(\(!done\))215 1300 y({)263 1350 y(printf)g(\("history$)g("\);) -263 1400 y(fflush)g(\(stdout\);)263 1450 y(t)h(=)g(fgets)f(\(line,)g(sizeof)g -(\(line\))g(-)h(1,)f(stdin\);)263 1499 y(if)h(\(t)f(&&)h(*t\))311 -1549 y({)359 1599 y(len)f(=)h(strlen)f(\(t\);)359 1649 y(if)g(\(t[len)g(-)h -(1])g(==)f('\\n'\))406 1699 y(t[len)h(-)f(1])h(=)g('\\0';)311 -1748 y(})263 1848 y(if)g(\(!t\))311 1898 y(strcpy)f(\(line,)g("quit"\);)263 -1998 y(if)h(\(line[0]\))311 2047 y({)359 2097 y(char)f(*expansion;)359 -2147 y(int)g(result;)359 2247 y(result)g(=)g(history_expand)f(\(line,)h -(&expansion\);)359 2296 y(if)g(\(result\))406 2346 y(fprintf)g(\(stderr,)g -("\045s\\n",)g(expansion\);)359 2446 y(if)g(\(result)g(<)h(0)g(||)f(result)g -(==)h(2\))406 2496 y({)454 2545 y(free)f(\(expansion\);)454 -2595 y(continue;)406 2645 y(})p eop -%%Page: 13 15 -14 bop 0 -83 a Fo(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g(History)1017 -b(13)359 208 y Fn(add_history)22 b(\(expansion\);)359 258 y(strncpy)h -(\(line,)g(expansion,)f(sizeof)h(\(line\))g(-)h(1\);)359 308 -y(free)f(\(expansion\);)311 358 y(})263 457 y(if)h(\(strcmp)f(\(line,)g -("quit"\))g(==)g(0\))311 507 y(done)g(=)h(1;)263 557 y(else)f(if)h(\(strcmp)f -(\(line,)g("save"\))g(==)h(0\))311 607 y(write_history)e(\("history_file"\);) -263 656 y(else)h(if)h(\(strcmp)f(\(line,)g("read"\))g(==)h(0\))311 -706 y(read_history)e(\("history_file"\);)263 756 y(else)h(if)h(\(strcmp)f -(\(line,)g("list"\))g(==)h(0\))311 806 y({)359 856 y(register)e(HIST_ENTRY)h -(**the_list;)359 906 y(register)f(int)i(i;)359 1005 y(the_list)e(=)i -(history_list)e(\(\);)359 1055 y(if)h(\(the_list\))406 1105 -y(for)h(\(i)f(=)h(0;)g(the_list[i];)e(i++\))454 1155 y(printf)h(\("\045d:)g -(\045s\\n",)g(i)h(+)g(history_base,)e(the_list[i]->line\);)311 -1204 y(})263 1254 y(else)h(if)h(\(strncmp)f(\(line,)g("delete",)g(6\))g(==)h -(0\))311 1304 y({)359 1354 y(int)f(which;)359 1404 y(if)g(\(\(sscanf)g -(\(line)g(+)h(6,)f("\045d",)h(&which\)\))e(==)i(1\))406 1453 -y({)454 1503 y(HIST_ENTRY)f(*entry)g(=)g(remove_history)f(\(which\);)454 -1553 y(if)i(\(!entry\))502 1603 y(fprintf)f(\(stderr,)f("No)i(such)f(entry)g -(\045d\\n",)g(which\);)454 1653 y(else)502 1703 y({)550 1752 -y(free)g(\(entry->line\);)550 1802 y(free)g(\(entry\);)502 -1852 y(})406 1902 y(})359 1952 y(else)406 2001 y({)454 2051 -y(fprintf)g(\(stderr,)g("non-numeric)f(arg)h(given)h(to)f(`delete'\\n"\);)406 -2101 y(})311 2151 y(})215 2201 y(})120 2250 y(})p eop -%%Page: 14 16 -15 bop 0 -83 a Fo(14)1474 b(GNU)15 b(History)g(Library)p eop -%%Page: 15 17 -16 bop 0 -83 a Fo(App)q(endix)17 b(A:)e(Concept)g(Index)1346 -b(15)0 158 y Fk(App)r(endix)13 b(A)41 b(Concept)15 b(Index)0 -405 y Fm(A)0 471 y Fe(anc)o(hored)f(searc)o(h)5 b Fd(:)i(:)f(:)g(:)g(:)g(:)g -(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)18 b Fe(8)0 -579 y Fm(E)0 646 y Fe(ev)o(en)o(t)13 b(designators)g Fd(:)6 -b(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)23 -b Fe(1)1015 405 y(expansion)5 b Fd(:)k(:)d(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) -g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)18 b Fe(1)1015 -521 y Fm(H)1015 587 y Fe(history)d(ev)o(en)o(ts)5 b Fd(:)i(:)f(:)g(:)g(:)g(:) -g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)18 b -Fe(1)1015 646 y(History)c(Searc)o(hing)7 b Fd(:)h(:)e(:)g(:)g(:)g(:)g(:)h(:)f -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)20 b Fe(8)p eop -%%Page: 16 18 -17 bop 0 -83 a Fo(16)1474 b(GNU)15 b(History)g(Library)p eop -%%Page: 17 19 -18 bop 0 -83 a Fo(App)q(endix)17 b(B:)e(F)l(unction)h(and)g(V)l(ariable)g -(Index)1069 b(17)0 158 y Fk(App)r(endix)13 b(B)41 b(F)-7 b(unction)15 -b(and)g(V)-7 b(ariable)14 b(Index)0 405 y Fm(A)0 471 y Fc(add)p -62 471 12 2 v 13 w(history)8 b Fd(:)s(:)e(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)20 b Fe(7)0 529 y Fc(append)p -122 529 V 12 w(history)9 b Fd(:)d(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f -(:)g(:)g(:)g(:)24 b Fe(10)0 654 y Fm(C)0 720 y Fc(current)p -142 720 V 11 w(history)9 b Fd(:)d(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)24 b Fe(8)0 845 y Fm(G)0 911 y Fc(get)p 62 911 -V 13 w(history)p 215 911 V 11 w(event)9 b Fd(:)d(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f -(:)g(:)g(:)g(:)g(:)23 b Fe(10)0 1036 y Fm(H)0 1102 y Fc(history)p -142 1102 V 11 w(arg)p 213 1102 V 13 w(extract)8 b Fd(:)t(:)e(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)21 b Fe(10)0 1160 y Fc(history)p 142 1160 -V 11 w(base)e Fd(:)6 b(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) -g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h -(:)f(:)g(:)20 b Fe(11)0 1218 y Fc(history)p 142 1218 V 11 w(comment)p -293 1218 V 12 w(char)g Fd(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)21 -b Fe(11)0 1276 y Fc(history)p 142 1276 V 11 w(expand)10 b Fd(:)c(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)24 b Fe(10)0 -1335 y Fc(history)p 142 1335 V 11 w(expansion)p 333 1335 V -11 w(char)17 b Fd(:)7 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)19 b Fe(11)0 -1393 y Fc(history)p 142 1393 V 11 w(get)8 b Fd(:)d(:)h(:)g(:)g(:)g(:)g(:)h(:) -f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)20 b Fe(8)0 -1451 y Fc(history)p 142 1451 V 11 w(get)p 213 1451 V 13 w(history)p -366 1451 V 12 w(state)t Fd(:)t(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)17 b Fe(6)0 -1509 y Fc(history)p 142 1509 V 11 w(is)p 193 1509 V 14 w(stifled)7 -b Fd(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)23 b -Fe(7)0 1567 y Fc(history)p 142 1567 V 11 w(length)16 b Fd(:)6 -b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)18 -b Fe(11)0 1625 y Fc(history)p 142 1625 V 11 w(list)7 b Fd(:)t(:)g(:)f(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)19 -b Fe(7)0 1683 y Fc(history)p 142 1683 V 11 w(no)p 193 1683 -V 14 w(expand)p 327 1683 V 12 w(chars)f Fd(:)6 b(:)g(:)g(:)g(:)g(:)g(:)h(:)f -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)20 -b Fe(12)0 1741 y Fc(history)p 142 1741 V 11 w(search)t Fd(:)t(:)6 -b(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)17 -b Fe(9)0 1800 y Fc(history)p 142 1800 V 11 w(search)p 273 1800 -V 12 w(pos)9 b Fd(:)d(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)23 -b Fe(9)0 1858 y Fc(history)p 142 1858 V 11 w(search)p 273 1858 -V 12 w(prefix)6 b Fd(:)t(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)19 -b Fe(9)0 1916 y Fc(history)p 142 1916 V 11 w(set)p 213 1916 -V 13 w(history)p 366 1916 V 12 w(state)t Fd(:)t(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)17 -b Fe(6)0 1974 y Fc(history)p 142 1974 V 11 w(set)p 213 1974 -V 13 w(pos)5 b Fd(:)h(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g -(:)g(:)18 b Fe(8)0 2032 y Fc(history)p 142 2032 V 11 w(subst)p -253 2032 V 13 w(char)k Fd(:)6 b(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)24 -b Fe(11)1015 405 y Fc(history)p 1157 405 V 12 w(tokenize)9 -b Fd(:)s(:)d(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)22 -b Fe(11)1015 463 y Fc(history)p 1157 463 V 12 w(total)p 1269 -463 V 12 w(bytes)9 b Fd(:)t(:)d(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)22 -b Fe(8)1015 521 y Fc(history)p 1157 521 V 12 w(truncate)p 1329 -521 V 11 w(file)5 b Fd(:)g(:)h(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:) -f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)19 -b Fe(10)1015 629 y Fm(M)1015 695 y Fc(max)p 1077 695 V 13 w(input)p -1190 695 V 13 w(history)14 b Fd(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g -(:)g(:)17 b Fe(11)1015 803 y Fm(N)1015 870 y Fc(next)p 1097 -870 V 13 w(history)7 b Fd(:)s(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)20 b Fe(8)1015 978 y Fm(P)1015 1044 -y Fc(previous)p 1177 1044 V 12 w(history)7 b Fd(:)f(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h -(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)23 b Fe(8)1015 1152 y Fm(R)1015 -1218 y Fc(read)p 1097 1218 V 13 w(history)7 b Fd(:)s(:)f(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)20 b Fe(9)1015 -1276 y Fc(read)p 1097 1276 V 13 w(history)p 1250 1276 V 11 -w(range)9 b Fd(:)d(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:) -g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)23 -b Fe(9)1015 1335 y Fc(remove)p 1137 1335 V 12 w(history)t Fd(:)t(:)6 -b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)17 -b Fe(7)1015 1393 y Fc(replace)p 1157 1393 V 12 w(history)p -1309 1393 V 11 w(entry)6 b Fd(:)f(:)h(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h -(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)19 -b Fe(7)1015 1501 y Fm(S)1015 1567 y Fc(stifle)p 1137 1567 V -12 w(history)t Fd(:)t(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h -(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g -(:)g(:)g(:)g(:)17 b Fe(7)1015 1675 y Fm(U)1015 1741 y Fc(unstifle)p -1177 1741 V 12 w(history)7 b Fd(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h -(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g -(:)g(:)g(:)g(:)23 b Fe(7)1015 1800 y Fc(using)p 1117 1800 V -13 w(history)5 b Fd(:)s(:)h(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)h(:)f(:)g(:)18 b Fe(6)1015 1907 y Fm(W)1015 1974 y Fc(where)p -1117 1974 V 13 w(history)5 b Fd(:)s(:)h(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)18 b Fe(8)1015 2032 y Fc(write)p -1117 2032 V 13 w(history)5 b Fd(:)s(:)h(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)18 b Fe(9)p eop -%%Page: 18 20 -19 bop 0 -83 a Fo(18)1474 b(GNU)15 b(History)g(Library)p eop -%%Page: -1 21 -20 bop 1937 -83 a Fo(i)0 158 y Fk(T)-7 b(able)15 b(of)g(Con)n(ten)n(ts)0 -333 y Fm(1)67 b(Using)22 b(History)h(In)n(teractiv)n(ely)9 -b Fb(:)k(:)d(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g -(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)31 b Fm(1)149 411 y Fo(1.1)45 -b(History)15 b(In)o(teraction)9 b Fa(:)f(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g -(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g -(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)23 -b Fo(1)299 473 y(1.1.1)44 b(Ev)o(en)o(t)14 b(Designators)6 -b Fa(:)h(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g -(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f -(:)g(:)g(:)20 b Fo(1)299 535 y(1.1.2)44 b(W)l(ord)15 b(Designators)9 -b Fa(:)d(:)h(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h -(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g -(:)h(:)f(:)23 b Fo(2)299 597 y(1.1.3)44 b(Mo)q(di\014ers)14 -b Fa(:)8 b(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:) -g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g -(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)28 b Fo(2)0 722 -y Fm(2)67 b(Programming)23 b(with)g(GNU)f(History)13 b Fb(:)e(:)f(:)g(:)g(:)h -(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)36 b -Fm(5)149 800 y Fo(2.1)45 b(In)o(tro)q(duction)16 b(to)f(History)6 -b Fa(:)h(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g -(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f -(:)g(:)g(:)g(:)h(:)f(:)g(:)20 b Fo(5)149 862 y(2.2)45 b(History)15 -b(Storage)d Fa(:)7 b(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g -(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f -(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)27 -b Fo(5)149 924 y(2.3)45 b(History)15 b(F)l(unctions)c Fa(:)d(:)f(:)h(:)f(:)g -(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f -(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h -(:)f(:)g(:)g(:)g(:)h(:)25 b Fo(6)299 986 y(2.3.1)44 b(Initializing)18 -b(History)d(and)h(State)e(Managemen)o(t)f Fa(:)7 b(:)g(:)g(:)h(:)f(:)g(:)g(:) -g(:)h(:)f(:)g(:)g(:)g(:)h(:)27 b Fo(6)299 1049 y(2.3.2)44 b(History)15 -b(List)h(Managemen)o(t)c Fa(:)7 b(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h -(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g -(:)28 b Fo(7)299 1111 y(2.3.3)44 b(Information)15 b(Ab)q(out)g(the)h(History) -f(List)5 b Fa(:)i(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g -(:)g(:)g(:)h(:)f(:)g(:)g(:)19 b Fo(7)299 1173 y(2.3.4)44 b(Mo)o(ving)15 -b(Around)g(the)g(History)g(List)6 b Fa(:)i(:)f(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:) -g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)20 -b Fo(8)299 1236 y(2.3.5)44 b(Searc)o(hing)16 b(the)f(History)g(List)7 -b Fa(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f -(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)21 b -Fo(8)299 1298 y(2.3.6)44 b(Managing)15 b(the)g(History)g(File)5 -b Fa(:)j(:)f(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g -(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)19 b -Fo(9)299 1360 y(2.3.7)44 b(History)15 b(Expansion)d Fa(:)7 -b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g -(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)26 -b Fo(10)149 1422 y(2.4)45 b(History)15 b(V)l(ariables)5 b Fa(:)k(:)e(:)g(:)g -(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g -(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f -(:)g(:)g(:)g(:)h(:)f(:)g(:)20 b Fo(11)149 1485 y(2.5)45 b(History)15 -b(Programming)f(Example)8 b Fa(:)g(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:) -g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f -(:)g(:)g(:)g(:)23 b Fo(12)0 1609 y Fm(App)r(endix)h(A)67 b(Concept)22 -b(Index)15 b Fb(:)c(:)f(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g -(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)37 b Fm(15)0 1749 -y(App)r(endix)24 b(B)67 b(F)-6 b(unction)25 b(and)e(V)-6 b(ariable)24 -b(Index)8 b Fb(:)j(:)f(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)31 -b Fm(17)p eop -%%Page: -2 22 -21 bop 0 -83 a Fo(ii)1496 b(GNU)15 b(History)g(Library)p eop -%%Trailer -end -userdict /end-hook known{end-hook}if -%%EOF diff --git a/lib/readline/doc/hstech.texinfo b/lib/readline/doc/hstech.texinfo index 5f0f600..be41318 100644 --- a/lib/readline/doc/hstech.texinfo +++ b/lib/readline/doc/hstech.texinfo @@ -1,7 +1,7 @@ @ignore This file documents the user interface to the GNU History library. -Copyright (C) 1988, 1991 Free Software Foundation, Inc. +Copyright (C) 1988, 1991, 1994, 1996 Free Software Foundation, Inc. Authored by Brian Fox and Chet Ramey. Permission is granted to make and distribute verbatim copies of this manual @@ -168,6 +168,10 @@ This returns the old entry so you can dispose of the data. In the case of an invalid @var{which}, a @code{NULL} pointer is returned. @end deftypefun +@deftypefun void clear_history () +Clear the history list by deleting all the entries. +@end deftypefun + @deftypefun void stifle_history (int max) Stifle the history list, remembering only the last @var{max} entries. @end deftypefun @@ -400,6 +404,17 @@ following @var{history_expansion_char}. The default is whitespace and @samp{=}. @end deftypevar +@deftypevar {char *} history_search_delimiter_chars +The list of additional characters which can delimit a history search +string, in addition to whitespace, @samp{:} and @samp{?} in the case of +a substring search. The default is empty. +@end deftypevar + +@deftypevar int history_quotes_inhibit_expansion +If non-zero, single-quoted words are not scanned for the history expansion +character. The default value is 0. +@end deftypevar + @node History Programming Example @section History Programming Example diff --git a/lib/readline/doc/hsuser.texinfo b/lib/readline/doc/hsuser.texinfo index 51327a3..6e95649 100644 --- a/lib/readline/doc/hsuser.texinfo +++ b/lib/readline/doc/hsuser.texinfo @@ -1,7 +1,7 @@ @ignore This file documents the user interface to the GNU History library. -Copyright (C) 1988, 1991 Free Software Foundation, Inc. +Copyright (C) 1988, 1991, 1996 Free Software Foundation, Inc. Authored by Brian Fox and Chet Ramey. Permission is granted to make and distribute verbatim copies of this manual @@ -39,26 +39,124 @@ information on using the GNU History Library in your own programs, @pxref{Programming with GNU History}. @end ifclear +@ifset BashFeatures @menu +* Bash History Facilities:: How Bash lets you manipulate your command + history. * History Interaction:: What it feels like using History as a user. @end menu +@end ifset +@ifclear BashFeatures +@menu +* History Interaction:: What it feels like using History as a user. +@end menu +@end ifclear + +@ifset BashFeatures +@node Bash History Facilities +@section Bash History Facilities +@cindex command history +@cindex history list + +When the @samp{-o history} option to the @code{set} builtin +is enabled (@pxref{The Set Builtin}), +the shell provides access to the @var{command history}, +the list of commands previously typed. The text of the last +@code{HISTSIZE} +commands (default 500) is saved in a history list. The shell +stores each command in the history list prior to parameter and +variable expansion +but after history expansion is performed, subject to the +values of the shell variables +@code{HISTIGNORE} and @code{HISTCONTROL}. +When the shell starts up, the history is initialized from the +file named by the @code{HISTFILE} variable (default @file{~/.bash_history}). +@code{HISTFILE} is truncated, if necessary, to contain no more than +the number of lines specified by the value of the @code{HISTFILESIZE} +variable. When an interactive shell exits, the last +@code{HISTSIZE} lines are copied from the history list to @code{HISTFILE}. +If the @code{histappend} shell option is set (@pxref{Bash Builtins}), +the lines are appended to the history file, +otherwise the history file is overwritten. +If @code{HISTFILE} +is unset, or if the history file is unwritable, the history is +not saved. After saving the history, the history file is truncated +to contain no more than @code{$HISTFILESIZE} +lines. If @code{HISTFILESIZE} is not set, no truncation is performed. + +The builtin command @code{fc} (@pxref{Korn Shell Builtins}) +may be used to list or edit and re-execute a portion of +the history list. The @code{history} builtin (@pxref{C Shell Builtins}) +can be used to display or modify the history list and +manipulate the history file. +When using the command-line editing, search commands +are available in each editing mode that provide access to the +history list. + +The shell allows control over which commands are saved on the history +list. The @code{HISTCONTROL} and @code{HISTIGNORE} +variables may be set to cause the shell to save only a subset of the +commands entered. +The @code{cmdhist} +shell option, if enabled, causes the shell to attempt to save each +line of a multi-line command in the same history entry, adding +semicolons where necessary to preserve syntactic correctness. +The @code{lithist} +shell option causes the shell to save the command with embedded newlines +instead of semicolons. +@xref{Bash Builtins} for a description of @code{shopt}. +@end ifset @node History Interaction -@section History Interaction -@cindex expansion +@section Interactive History Expansion +@cindex history expansion The History library provides a history expansion feature that is similar -to the history expansion provided by @code{csh}. The following text +to the history expansion provided by @code{csh}. This section describes the syntax used to manipulate the history information. +History expansions introduce words from the history list into +the input stream, making it easy to repeat commands, insert the +arguments to a previous command into the current input line, or +fix errors in previous commands quickly. + History expansion takes place in two parts. The first is to determine which line from the previous history should be used during substitution. The second is to select portions of that line for inclusion into the current one. The line selected from the previous history is called the @dfn{event}, and the portions of that line that are acted upon are -called @dfn{words}. The line is broken into words in the same fashion +called @dfn{words}. Various @dfn{modifiers} are available to manipulate +the selected words. The line is broken into words in the same fashion that Bash does, so that several English (or Unix) words surrounded by quotes are considered as one word. +History expansions are introduced by the appearance of the +history expansion character, which is @samp{!} by default. +@ifset BashFeatures +Only @samp{\} and @samp{'} may be used to escape the history expansion +character. +@end ifset + +@ifset BashFeatures +Several shell options settable with the @code{shopt} +builtin (@pxref{Bash Builtins}) may be used to tailor +the behavior of history expansion. If the +@code{histverify} shell option is enabled, and Readline +is being used, history substitutions are not immediately passed to +the shell parser. +Instead, the expanded line is reloaded into the Readline +editing buffer for further modification. +If Readline is being used, and the @code{histreedit} +shell option is enabled, a failed history expansion will be +reloaded into the Readline editing buffer for correction. +The @samp{-p} option to the @code{history} builtin command +may be used to see what a history expansion will do before using it. +The @samp{-s} option to the @code{history} builtin may be used to +add commands to the end of the history list without actually executing +them, so that they are available for subsequent recall. + +The shell allows control of the various characters used by the +history expansion mechanism with the @code{histchars} variable. +@end ifset @menu * Event Designators:: How to specify which history line to use. @@ -80,92 +178,100 @@ history list. Start a history substitution, except when followed by a space, tab, the end of the line, @key{=} or @key{(}. -@item @code{!!} -Refer to the previous command. This is a synonym for @code{!-1}. - -@item @code{!n} +@item @code{!@var{n}} Refer to command line @var{n}. -@item @code{!-n} +@item @code{!-@var{n}} Refer to the command @var{n} lines back. -@item @code{!string} +@item @code{!!} +Refer to the previous command. This is a synonym for @samp{!-1}. + +@item @code{!@var{string}} Refer to the most recent command starting with @var{string}. -@item @code{!?string}[@code{?}] -Refer to the most recent command containing @var{string}. +@item @code{!?@var{string}[?]} +Refer to the most recent command containing @var{string}. The trailing +@samp{?} may be omitted if the @var{string} is followed immediately by +a newline. -@item @code{!#} -The entire command line typed so far. - -@item @code{^string1^string2^} +@item @code{^@var{string1}^@var{string2}^} Quick Substitution. Repeat the last command, replacing @var{string1} with @var{string2}. Equivalent to -@code{!!:s/string1/string2/}. +@code{!!:s/@var{string1}/@var{string2}/}. + +@item @code{!#} +The entire command line typed so far. @end table @node Word Designators @subsection Word Designators -A @key{:} separates the event specification from the word designator. It -can be omitted if the word designator begins with a @key{^}, @key{$}, -@key{*} or @key{%}. Words are numbered from the beginning of the line, -with the first word being denoted by a 0 (zero). +Word designators are used to select desired words from the event. +A @samp{:} separates the event specification from the word designator. It +can be omitted if the word designator begins with a @samp{^}, @samp{$}, +@samp{*}, @samp{-}, or @samp{%}. Words are numbered from the beginning +of the line, with the first word being denoted by 0 (zero). Words are +inserted into the current line separated by single spaces. @table @code @item 0 (zero) The @code{0}th word. For many applications, this is the command word. -@item n +@item @var{n} The @var{n}th word. @item ^ -The first argument; that is, word 1. +The first argument; that is, word 1. @item $ The last argument. @item % -The word matched by the most recent @code{?string?} search. +The word matched by the most recent @samp{?@var{string}?} search. -@item x-y -A range of words; @code{-@var{y}} abbreviates @code{0-@var{y}}. +@item @var{x}-@var{y} +A range of words; @samp{-@var{y}} abbreviates @samp{0-@var{y}}. @item * -All of the words, except the @code{0}th. This is a synonym for @code{1-$}. -It is not an error to use @key{*} if there is just one word in the event; +All of the words, except the @code{0}th. This is a synonym for @samp{1-$}. +It is not an error to use @samp{*} if there is just one word in the event; the empty string is returned in that case. -@item x* -Abbreviates @code{x-$} +@item @var{x}* +Abbreviates @samp{@var{x}-$} -@item x- -Abbreviates @code{x-$} like @code{x*}, but omits the last word. +@item @var{x}- +Abbreviates @samp{@var{x}-$} like @samp{@var{x}*}, but omits the last word. @end table +If a word designator is supplied without an event specification, the +previous command is used as the event. + @node Modifiers @subsection Modifiers After the optional word designator, you can add a sequence of one or more -of the following modifiers, each preceded by a @key{:}. +of the following modifiers, each preceded by a @samp{:}. @table @code @item h Remove a trailing pathname component, leaving only the head. +@item t +Remove all leading pathname components, leaving the tail. + @item r -Remove a trailing suffix of the form @samp{.}@var{suffix}, leaving the basename. +Remove a trailing suffix of the form @samp{.@var{suffix}}, leaving +the basename. @item e Remove all but the trailing suffix. -@item t -Remove all leading pathname components, leaving the tail. - @item p Print the new command but do not execute it. @@ -174,17 +280,17 @@ Print the new command but do not execute it. Quote the substituted words, escaping further substitutions. @item x -Quote the substituted words as with @code{q}, +Quote the substituted words as with @samp{q}, but break into words at spaces, tabs, and newlines. @end ifset -@item s/old/new/ +@item s/@var{old}/@var{new}/ Substitute @var{new} for the first occurrence of @var{old} in the -event line. Any delimiter may be used in place of @key{/}. +event line. Any delimiter may be used in place of @samp{/}. The delimiter may be quoted in @var{old} and @var{new} -with a single backslash. If @key{&} appears in @var{new}, +with a single backslash. If @samp{&} appears in @var{new}, it is replaced by @var{old}. A single backslash will quote -the @key{&}. The final delimiter is optional if it is the last +the @samp{&}. The final delimiter is optional if it is the last character on the input line. @item & @@ -192,7 +298,7 @@ Repeat the previous substitution. @item g Cause changes to be applied over the entire event line. Used in -conjunction with @code{s}, as in @code{gs/old/new/}, or with -@code{&}. +conjunction with @samp{s}, as in @code{gs/@var{old}/@var{new}/}, +or with @samp{&}. @end table diff --git a/lib/readline/doc/readline.dvi b/lib/readline/doc/readline.dvi Binary files differdeleted file mode 100644 index aea321a..0000000 --- a/lib/readline/doc/readline.dvi +++ /dev/null diff --git a/lib/readline/doc/readline.info b/lib/readline/doc/readline.info deleted file mode 100644 index 6df0bd9..0000000 --- a/lib/readline/doc/readline.info +++ /dev/null @@ -1,744 +0,0 @@ -This is Info file history.info, produced by Makeinfo-1.55 from the -input file hist.texinfo. - - This document describes the GNU History library, a programming tool -that provides a consistent user interface for recalling lines of -previously typed input. - - Copyright (C) 1988, 1991 Free Software Foundation, Inc. - - Permission is granted to make and distribute verbatim copies of this -manual provided the copyright notice and this permission notice pare -preserved on all copies. - - Permission is granted to copy and distribute modified versions of -this manual under the conditions for verbatim copying, provided that -the entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - - Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions, except that this permission notice may be stated in a -translation approved by the Foundation. - - -File: history.info, Node: Top, Next: Using History Interactively, Prev: (DIR), Up: (DIR) - -GNU History Library -******************* - - This document describes the GNU History library, a programming tool -that provides a consistent user interface for recalling lines of -previously typed input. - -* Menu: - -* Using History Interactively:: GNU History User's Manual. -* Programming with GNU History:: GNU History Programmer's Manual. -* Concept Index:: Index of concepts described in this manual. -* Function and Variable Index:: Index of externally visible functions - and variables. - - -File: history.info, Node: Using History Interactively, Next: Programming with GNU History, Prev: Top, Up: Top - -Using History Interactively -*************************** - - This chapter describes how to use the GNU History Library -interactively, from a user's standpoint. It should be considered a -user's guide. For information on using the GNU History Library in your -own programs, *note Programming with GNU History::.. - -* Menu: - -* History Interaction:: What it feels like using History as a user. - - -File: history.info, Node: History Interaction, Up: Using History Interactively - -History Interaction -=================== - - The History library provides a history expansion feature that is -similar to the history expansion provided by `csh'. The following text -describes the syntax used to manipulate the history information. - - History expansion takes place in two parts. The first is to -determine which line from the previous history should be used during -substitution. The second is to select portions of that line for -inclusion into the current one. The line selected from the previous -history is called the "event", and the portions of that line that are -acted upon are called "words". The line is broken into words in the -same fashion that Bash does, so that several English (or Unix) words -surrounded by quotes are considered as one word. - -* Menu: - -* Event Designators:: How to specify which history line to use. -* Word Designators:: Specifying which words are of interest. -* Modifiers:: Modifying the results of substitution. - - -File: history.info, Node: Event Designators, Next: Word Designators, Up: History Interaction - -Event Designators ------------------ - - An event designator is a reference to a command line entry in the -history list. - -`!' - Start a history substitution, except when followed by a space, tab, - the end of the line, = or (. - -`!!' - Refer to the previous command. This is a synonym for `!-1'. - -`!n' - Refer to command line N. - -`!-n' - Refer to the command N lines back. - -`!string' - Refer to the most recent command starting with STRING. - -`!?string'[`?'] - Refer to the most recent command containing STRING. - -`!#' - The entire command line typed so far. - -`^string1^string2^' - Quick Substitution. Repeat the last command, replacing STRING1 - with STRING2. Equivalent to `!!:s/string1/string2/'. - - -File: history.info, Node: Word Designators, Next: Modifiers, Prev: Event Designators, Up: History Interaction - -Word Designators ----------------- - - A : separates the event specification from the word designator. It -can be omitted if the word designator begins with a ^, $, * or %. -Words are numbered from the beginning of the line, with the first word -being denoted by a 0 (zero). - -`0 (zero)' - The `0'th word. For many applications, this is the command word. - -`n' - The Nth word. - -`^' - The first argument; that is, word 1. - -`$' - The last argument. - -`%' - The word matched by the most recent `?string?' search. - -`x-y' - A range of words; `-Y' abbreviates `0-Y'. - -`*' - All of the words, except the `0'th. This is a synonym for `1-$'. - It is not an error to use * if there is just one word in the event; - the empty string is returned in that case. - -`x*' - Abbreviates `x-$' - -`x-' - Abbreviates `x-$' like `x*', but omits the last word. - - -File: history.info, Node: Modifiers, Prev: Word Designators, Up: History Interaction - -Modifiers ---------- - - After the optional word designator, you can add a sequence of one or -more of the following modifiers, each preceded by a :. - -`h' - Remove a trailing pathname component, leaving only the head. - -`r' - Remove a trailing suffix of the form `.'SUFFIX, leaving the - basename. - -`e' - Remove all but the trailing suffix. - -`t' - Remove all leading pathname components, leaving the tail. - -`p' - Print the new command but do not execute it. - -`s/old/new/' - Substitute NEW for the first occurrence of OLD in the event line. - Any delimiter may be used in place of /. The delimiter may be - quoted in OLD and NEW with a single backslash. If & appears in - NEW, it is replaced by OLD. A single backslash will quote the &. - The final delimiter is optional if it is the last character on the - input line. - -`&' - Repeat the previous substitution. - -`g' - Cause changes to be applied over the entire event line. Used in - conjunction with `s', as in `gs/old/new/', or with `&'. - - -File: history.info, Node: Programming with GNU History, Next: Concept Index, Prev: Using History Interactively, Up: Top - -Programming with GNU History -**************************** - - This chapter describes how to interface programs that you write with -the GNU History Library. It should be considered a technical guide. -For information on the interactive use of GNU History, *note Using -History Interactively::.. - -* Menu: - -* Introduction to History:: What is the GNU History library for? -* History Storage:: How information is stored. -* History Functions:: Functions that you can use. -* History Variables:: Variables that control behaviour. -* History Programming Example:: Example of using the GNU History Library. - - -File: history.info, Node: Introduction to History, Next: History Storage, Up: Programming with GNU History - -Introduction to History -======================= - - Many programs read input from the user a line at a time. The GNU -History library is able to keep track of those lines, associate -arbitrary data with each line, and utilize information from previous -lines in composing new ones. - - The programmer using the History library has available functions for -remembering lines on a history list, associating arbitrary data with a -line, removing lines from the list, searching through the list for a -line containing an arbitrary text string, and referencing any line in -the list directly. In addition, a history "expansion" function is -available which provides for a consistent user interface across -different programs. - - The user using programs written with the History library has the -benefit of a consistent user interface with a set of well-known -commands for manipulating the text of previous lines and using that text -in new commands. The basic history manipulation commands are similar to -the history substitution provided by `csh'. - - If the programmer desires, he can use the Readline library, which -includes some history manipulation by default, and has the added -advantage of command line editing. - - -File: history.info, Node: History Storage, Next: History Functions, Prev: Introduction to History, Up: Programming with GNU History - -History Storage -=============== - - The history list is an array of history entries. A history entry is -declared as follows: - - typedef struct _hist_entry { - char *line; - char *data; - } HIST_ENTRY; - - The history list itself might therefore be declared as - - HIST_ENTRY **the_history_list; - - The state of the History library is encapsulated into a single -structure: - - /* A structure used to pass the current state of the history stuff around. */ - typedef struct _hist_state { - HIST_ENTRY **entries; /* Pointer to the entries themselves. */ - int offset; /* The location pointer within this array. */ - int length; /* Number of elements within this array. */ - int size; /* Number of slots allocated to this array. */ - int flags; - } HISTORY_STATE; - - If the flags member includes `HS_STIFLED', the history has been -stifled. - - -File: history.info, Node: History Functions, Next: History Variables, Prev: History Storage, Up: Programming with GNU History - -History Functions -================= - - This section describes the calling sequence for the various functions -present in GNU History. - -* Menu: - -* Initializing History and State Management:: Functions to call when you - want to use history in a - program. -* History List Management:: Functions used to manage the list - of history entries. -* Information About the History List:: Functions returning information about - the history list. -* Moving Around the History List:: Functions used to change the position - in the history list. -* Searching the History List:: Functions to search the history list - for entries containing a string. -* Managing the History File:: Functions that read and write a file - containing the history list. -* History Expansion:: Functions to perform csh-like history - expansion. - - -File: history.info, Node: Initializing History and State Management, Next: History List Management, Up: History Functions - -Initializing History and State Management ------------------------------------------ - - This section describes functions used to initialize and manage the -state of the History library when you want to use the history functions -in your program. - - - Function: void using_history () - Begin a session in which the history functions might be used. This - initializes the interactive variables. - - - Function: HISTORY_STATE * history_get_history_state () - Return a structure describing the current state of the input - history. - - - Function: void history_set_history_state (HISTORY_STATE *state) - Set the state of the history list according to STATE. - - -File: history.info, Node: History List Management, Next: Information About the History List, Prev: Initializing History and State Management, Up: History Functions - -History List Management ------------------------ - - These functions manage individual entries on the history list, or set -parameters managing the list itself. - - - Function: void add_history (char *string) - Place STRING at the end of the history list. The associated data - field (if any) is set to `NULL'. - - - Function: HIST_ENTRY * remove_history (int which) - Remove history entry at offset WHICH from the history. The - removed element is returned so you can free the line, data, and - containing structure. - - - Function: HIST_ENTRY * replace_history_entry (int which, char *line, - char *data) - Make the history entry at offset WHICH have LINE and DATA. This - returns the old entry so you can dispose of the data. In the case - of an invalid WHICH, a `NULL' pointer is returned. - - - Function: void stifle_history (int max) - Stifle the history list, remembering only the last MAX entries. - - - Function: int unstifle_history () - Stop stifling the history. This returns the previous amount the - history was stifled. The value is positive if the history was - stifled, negative if it wasn't. - - - Function: int history_is_stifled () - Returns non-zero if the history is stifled, zero if it is not. - - -File: history.info, Node: Information About the History List, Next: Moving Around the History List, Prev: History List Management, Up: History Functions - -Information About the History List ----------------------------------- - - These functions return information about the entire history list or -individual list entries. - - - Function: HIST_ENTRY ** history_list () - Return a `NULL' terminated array of `HIST_ENTRY' which is the - current input history. Element 0 of this list is the beginning of - time. If there is no history, return `NULL'. - - - Function: int where_history () - Returns the offset of the current history element. - - - Function: HIST_ENTRY * current_history () - Return the history entry at the current position, as determined by - `where_history ()'. If there is no entry there, return a `NULL' - pointer. - - - Function: HIST_ENTRY * history_get (int offset) - Return the history entry at position OFFSET, starting from - `history_base'. If there is no entry there, or if OFFSET is - greater than the history length, return a `NULL' pointer. - - - Function: int history_total_bytes () - Return the number of bytes that the primary history entries are - using. This function returns the sum of the lengths of all the - lines in the history. - - -File: history.info, Node: Moving Around the History List, Next: Searching the History List, Prev: Information About the History List, Up: History Functions - -Moving Around the History List ------------------------------- - - These functions allow the current index into the history list to be -set or changed. - - - Function: int history_set_pos (int pos) - Set the position in the history list to POS, an absolute index - into the list. - - - Function: HIST_ENTRY * previous_history () - Back up the current history offset to the previous history entry, - and return a pointer to that entry. If there is no previous - entry, return a `NULL' pointer. - - - Function: HIST_ENTRY * next_history () - Move the current history offset forward to the next history entry, - and return the a pointer to that entry. If there is no next - entry, return a `NULL' pointer. - - -File: history.info, Node: Searching the History List, Next: Managing the History File, Prev: Moving Around the History List, Up: History Functions - -Searching the History List --------------------------- - - These functions allow searching of the history list for entries -containing a specific string. Searching may be performed both forward -and backward from the current history position. The search may be -"anchored", meaning that the string must match at the beginning of the -history entry. - - - Function: int history_search (char *string, int direction) - Search the history for STRING, starting at the current history - offset. If DIRECTION < 0, then the search is through previous - entries, else through subsequent. If STRING is found, then the - current history index is set to that history entry, and the value - returned is the offset in the line of the entry where STRING was - found. Otherwise, nothing is changed, and a -1 is returned. - - - Function: int history_search_prefix (char *string, int direction) - Search the history for STRING, starting at the current history - offset. The search is anchored: matching lines must begin with - STRING. If DIRECTION < 0, then the search is through previous - entries, else through subsequent. If STRING is found, then the - current history index is set to that entry, and the return value - is 0. Otherwise, nothing is changed, and a -1 is returned. - - - Function: int history_search_pos (char *string, int direction, int - pos) - Search for STRING in the history list, starting at POS, an - absolute index into the list. If DIRECTION is negative, the search - proceeds backward from POS, otherwise forward. Returns the - absolute index of the history element where STRING was found, or - -1 otherwise. - - -File: history.info, Node: Managing the History File, Next: History Expansion, Prev: Searching the History List, Up: History Functions - -Managing the History File -------------------------- - - The History library can read the history from and write it to a file. -This section documents the functions for managing a history file. - - - Function: int read_history (char *filename) - Add the contents of FILENAME to the history list, a line at a - time. If FILENAME is `NULL', then read from `~/.history'. - Returns 0 if successful, or errno if not. - - - Function: int read_history_range (char *filename, int from, int to) - Read a range of lines from FILENAME, adding them to the history - list. Start reading at line FROM and end at TO. If FROM is zero, - start at the beginning. If TO is less than FROM, then read until - the end of the file. If FILENAME is `NULL', then read from - `~/.history'. Returns 0 if successful, or `errno' if not. - - - Function: int write_history (char *filename) - Write the current history to FILENAME, overwriting FILENAME if - necessary. If FILENAME is `NULL', then write the history list to - `~/.history'. Values returned are as in `read_history ()'. - - - Function: int append_history (int nelements, char *filename) - Append the last NELEMENTS of the history list to FILENAME. - - - Function: int history_truncate_file (char *filename, int nlines) - Truncate the history file FILENAME, leaving only the last NLINES - lines. - - -File: history.info, Node: History Expansion, Prev: Managing the History File, Up: History Functions - -History Expansion ------------------ - - These functions implement `csh'-like history expansion. - - - Function: int history_expand (char *string, char **output) - Expand STRING, placing the result into OUTPUT, a pointer to a - string (*note History Interaction::.). Returns: - `0' - If no expansions took place (or, if the only change in the - text was the de-slashifying of the history expansion - character); - - `1' - if expansions did take place; - - `-1' - if there was an error in expansion; - - `2' - if the returned line should only be displayed, but not - executed, as with the `:p' modifier (*note Modifiers::.). - - If an error ocurred in expansion, then OUTPUT contains a - descriptive error message. - - - Function: char * history_arg_extract (int first, int last, char - *string) - Extract a string segment consisting of the FIRST through LAST - arguments present in STRING. Arguments are broken up as in Bash. - - - Function: char * get_history_event (char *string, int *cindex, int - qchar) - Returns the text of the history event beginning at STRING + - *CINDEX. *CINDEX is modified to point to after the event - specifier. At function entry, CINDEX points to the index into - STRING where the history event specification begins. QCHAR is a - character that is allowed to end the event specification in - addition to the "normal" terminating characters. - - - Function: char ** history_tokenize (char *string) - Return an array of tokens parsed out of STRING, much as the shell - might. The tokens are split on white space and on the characters - `()<>;&|$', and shell quoting conventions are obeyed. - - -File: history.info, Node: History Variables, Next: History Programming Example, Prev: History Functions, Up: Programming with GNU History - -History Variables -================= - - This section describes the externally visible variables exported by -the GNU History Library. - - - Variable: int history_base - The logical offset of the first entry in the history list. - - - Variable: int history_length - The number of entries currently stored in the history list. - - - Variable: int max_input_history - The maximum number of history entries. This must be changed using - `stifle_history ()'. - - - Variable: char history_expansion_char - The character that starts a history event. The default is `!'. - - - Variable: char history_subst_char - The character that invokes word substitution if found at the start - of a line. The default is `^'. - - - Variable: char history_comment_char - During tokenization, if this character is seen as the first - character of a word, then it and all subsequent characters up to a - newline are ignored, suppressing history expansion for the - remainder of the line. This is disabled by default. - - - Variable: char * history_no_expand_chars - The list of characters which inhibit history expansion if found - immediately following HISTORY_EXPANSION_CHAR. The default is - whitespace and `='. - - -File: history.info, Node: History Programming Example, Prev: History Variables, Up: Programming with GNU History - -History Programming Example -=========================== - - The following program demonstrates simple use of the GNU History -Library. - - main () - { - char line[1024], *t; - int len, done = 0; - - line[0] = 0; - - using_history (); - while (!done) - { - printf ("history$ "); - fflush (stdout); - t = fgets (line, sizeof (line) - 1, stdin); - if (t && *t) - { - len = strlen (t); - if (t[len - 1] == '\n') - t[len - 1] = '\0'; - } - - if (!t) - strcpy (line, "quit"); - - if (line[0]) - { - char *expansion; - int result; - - result = history_expand (line, &expansion); - if (result) - fprintf (stderr, "%s\n", expansion); - - if (result < 0 || result == 2) - { - free (expansion); - continue; - } - - add_history (expansion); - strncpy (line, expansion, sizeof (line) - 1); - free (expansion); - } - - if (strcmp (line, "quit") == 0) - done = 1; - else if (strcmp (line, "save") == 0) - write_history ("history_file"); - else if (strcmp (line, "read") == 0) - read_history ("history_file"); - else if (strcmp (line, "list") == 0) - { - register HIST_ENTRY **the_list; - register int i; - - the_list = history_list (); - if (the_list) - for (i = 0; the_list[i]; i++) - printf ("%d: %s\n", i + history_base, the_list[i]->line); - } - else if (strncmp (line, "delete", 6) == 0) - { - int which; - if ((sscanf (line + 6, "%d", &which)) == 1) - { - HIST_ENTRY *entry = remove_history (which); - if (!entry) - fprintf (stderr, "No such entry %d\n", which); - else - { - free (entry->line); - free (entry); - } - } - else - { - fprintf (stderr, "non-numeric arg given to `delete'\n"); - } - } - } - } - - -File: history.info, Node: Concept Index, Next: Function and Variable Index, Prev: Programming with GNU History, Up: Top - -Concept Index -************* - -* Menu: - -* anchored search: Searching the History List. -* event designators: Event Designators. -* expansion: History Interaction. -* history events: Event Designators. -* History Searching: Searching the History List. - - -File: history.info, Node: Function and Variable Index, Prev: Concept Index, Up: Top - -Function and Variable Index -*************************** - -* Menu: - -* add_history: History List Management. -* append_history: Managing the History File. -* current_history: Information About the History List. -* get_history_event: History Expansion. -* history_arg_extract: History Expansion. -* history_base: History Variables. -* history_comment_char: History Variables. -* history_expand: History Expansion. -* history_expansion_char: History Variables. -* history_get: Information About the History List. -* history_get_history_state: Initializing History and State Management. -* history_is_stifled: History List Management. -* history_length: History Variables. -* history_list: Information About the History List. -* history_no_expand_chars: History Variables. -* history_search: Searching the History List. -* history_search_pos: Searching the History List. -* history_search_prefix: Searching the History List. -* history_set_history_state: Initializing History and State Management. -* history_set_pos: Moving Around the History List. -* history_subst_char: History Variables. -* history_tokenize: History Expansion. -* history_total_bytes: Information About the History List. -* history_truncate_file: Managing the History File. -* max_input_history: History Variables. -* next_history: Moving Around the History List. -* previous_history: Moving Around the History List. -* read_history: Managing the History File. -* read_history_range: Managing the History File. -* remove_history: History List Management. -* replace_history_entry: History List Management. -* stifle_history: History List Management. -* unstifle_history: History List Management. -* using_history: Initializing History and State Management. -* where_history: Information About the History List. -* write_history: Managing the History File. - - - -Tag Table: -Node: Top975 -Node: Using History Interactively1569 -Node: History Interaction2077 -Node: Event Designators3122 -Node: Word Designators3952 -Node: Modifiers4936 -Node: Programming with GNU History6065 -Node: Introduction to History6791 -Node: History Storage8112 -Node: History Functions9205 -Node: Initializing History and State Management10176 -Node: History List Management10968 -Node: Information About the History List12396 -Node: Moving Around the History List13702 -Node: Searching the History List14587 -Node: Managing the History File16419 -Node: History Expansion17925 -Node: History Variables19769 -Node: History Programming Example21138 -Node: Concept Index23742 -Node: Function and Variable Index24223 - -End Tag Table diff --git a/lib/readline/doc/readline.ps b/lib/readline/doc/readline.ps deleted file mode 100644 index 839598f..0000000 --- a/lib/readline/doc/readline.ps +++ /dev/null @@ -1,2037 +0,0 @@ -%!PS-Adobe-2.0 -%%Creator: dvipsk 5.490s Copyright 1986, 1992 Radical Eye Software -%%Title: history.dvi -%%Pages: 22 1 -%%BoundingBox: 0 0 612 792 -%%EndComments -%DVIPSCommandLine: dvips -D 300 -o history.ps history.dvi -%%BeginProcSet: tex.pro -%! -/TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N /X{S N} -B /TR{translate}N /isls false N /vsize 11 72 mul N /@rigin{isls{[0 -1 1 0 0 0] -concat}if 72 Resolution div 72 VResolution div neg scale isls{Resolution hsize --72 div mul 0 TR}if Resolution VResolution vsize -72 div 1 add mul TR matrix -currentmatrix dup dup 4 get round 4 exch put dup dup 5 get round 5 exch put -setmatrix}N /@landscape{/isls true N}B /@manualfeed{statusdict /manualfeed -true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N -/IE 0 N /ctr 0 N /df-tail{/nn 8 dict N nn begin /FontType 3 N /FontMatrix -fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{ -CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn -put /ctr 0 N[}B /df{/sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 -0 sf neg 0 0]N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data -dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{128 -ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127 -sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type -/stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N -/cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get -S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height -sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0 --1 -.1 ch-xoff sub ch-yoff .1 add]{ch-image}imagemask restore}B /D{/cc X dup -type /stringtype ne{]}if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 -ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N} -B /I{cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin -0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul add -.99 lt{/FV}{/RV}ifelse load def pop}N /eop{SI restore showpage userdict -/eop-hook known{eop-hook}if}N /@start{userdict /start-hook known{start-hook} -if /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255{IE -S 1 string dup 0 3 index put cvn put}for 65781.76 div /vsize X 65781.76 div -/hsize X}N /p{show}N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N /ruley -0 N /v{/ruley X /rulex X V}B /V{}B /RV statusdict begin /product where{pop -product dup length 7 ge{0 7 getinterval dup(Display)eq exch 0 4 getinterval -(NeXT)eq or}{pop false}ifelse}{false}ifelse end{{gsave TR -.1 -.1 TR 1 1 scale -rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1 -.1 TR rulex -ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /FV{gsave -transform round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg -rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail{dup -/delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M}B /d{-3 M} -B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{4 M}B /w{0 -rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{p 1 w}B /r{p 2 w} -B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save N}B -/eos{SS restore}B end -%%EndProcSet -TeXDict begin 40258431 52099146 1000 300 300 @start /Fa 1 59 -df<70F8F8F87005057C840D>58 D E /Fb 1 59 df<78FCFCFCFC7806067B8510>58 -D E /Fc 24 123 df<1FC0007FF000707800201800001C00001C0007FC001FFC003C1C00701C00 -E01C00E01C00E01C00707C003FFF800F8F8011107E8F14>97 D<FC0000FC00001C00001C00001C -00001C00001C00001CF8001DFE001F07001E03001C03801C01C01C01C01C01C01C01C01C01C01C -01C01C03801E03001F0E001DFC000CF8001217809614>I<03F80FFC1C1C380870006000E000E0 -00E000E00060007000380E1C1E0FFC03F00F107E8F14>I<007E00007E00000E00000E00000E00 -000E00000E0007CE000FFE001C3E00301E00700E00E00E00E00E00E00E00E00E00E00E00E00E00 -700E00301E00383E001FEFC007CFC012177F9614>I<07E00FF01C38301C700CE00EE00EFFFEFF -FEE00060007000380E1C1E0FFC03F00F107E8F14>I<007C00FE01CE03840380038003807FFEFF -FE0380038003800380038003800380038003800380038003807FFC7FFC0F177F9614>I<07CF00 -1FFF80383B80301800701C00701C00701C003018003838003FF00037C0007000007000003FF800 -1FFC003FFE00700F00E00380E00380E00380E003807007003C1E001FFC0007F00011197F8F14> -I<FC0000FC00001C00001C00001C00001C00001C00001C78001DFE001F86001E07001C07001C07 -001C07001C07001C07001C07001C07001C07001C07001C0700FF8FE0FF8FE01317809614>I<03 -0007800780030000000000000000007F807F800380038003800380038003800380038003800380 -03800380FFFCFFFC0E187D9714>I<FC0000FC00001C00001C00001C00001C00001C00001DFF80 -1DFF801C3C001C78001CF0001DE0001FC0001FC0001FE0001EF0001C70001C38001C38001C1C00 -FE3F80FE3F8011177F9614>107 D<FF80FF800380038003800380038003800380038003800380 -038003800380038003800380038003800380FFFEFFFE0F177E9614>I<FB8E00FFDF003CF3803C -F38038E38038E38038E38038E38038E38038E38038E38038E38038E38038E380FEFBE0FE79E013 -10808F14>I<FC7800FDFE001F86001E07001C07001C07001C07001C07001C07001C07001C0700 -1C07001C07001C0700FF8FE0FF8FE01310808F14>I<07C01FF03C78701C701CE00EE00EE00EE0 -0EE00EE00E701C783C3C781FF007C00F107E8F14>I<FCF800FDFE001F07001E03001C03801C01 -C01C01C01C01C01C01C01C01C01C01C01C03801E03001F0E001DFC001CF8001C00001C00001C00 -001C00001C00001C0000FF8000FF80001218808F14>I<FE1F00FE7F800EE3800F81000F00000F -00000E00000E00000E00000E00000E00000E00000E00000E0000FFF000FFF00011107F8F14> -114 D<0FD83FF86038C038C038F0007F803FF007F8001C6006E006F006F81CFFF8CFE00F107E8F -14>I<030007000700070007007FFCFFFC07000700070007000700070007000700070E070E070E -070C03FC00F00F157F9414>I<FC3F00FC3F001C07001C07001C07001C07001C07001C07001C07 -001C07001C07001C07001C07001C1F000FFFE003E7E01310808F14>I<FE3F80FE3F801C1C001C -1C001C1C001C1C000E38000E38000E380006300007700007700007700003E00003E00003E00011 -107F8F14>I<FF7F80FF7F80380E00380E00380E00380E0039CE0039CE0019CC001B6C001B6C00 -1A6C001A6C001E7C000E78000E780011107F8F14>I<7E3F007E3F001E38000E780007700007E0 -0003E00001C00003C00003E0000770000E78000E38001C1C00FE3F80FE3F8011107F8F14>I<FE -3F80FE3F801C1C001C1C001C1C000E1C000E38000E380007380007300007300003700003700001 -E00001E00001E00001C00001C00001C0000380007380007700007E00003C000011187F8F14>I< -3FFF7FFF700E701C7038007000E001C0038007000E001C0738077007FFFFFFFF10107F8F14>I -E /Fd 1 59 df<60F0F06004047D830B>58 D E /Fe 25 122 df<078018603030303060186018 -E01CE01CE01CE01CE01CE01CE01CE01CE01CE01CE01CE01C6018601870383030186007800E187E -9713>48 D<03000700FF0007000700070007000700070007000700070007000700070007000700 -070007000700070007000700FFF00C187D9713>I<0F80106020304038803CC01CE01C401C003C -003800380070006000C001800100020004040804100430083FF87FF8FFF80E187E9713>I<01E0 -06100C1818383038300070006000E000E7C0E860F030F018E018E01CE01CE01C601C601C701830 -183030186007C00E187E9713>54 D<40007FFE7FFC7FFC40088010801080200040004000800180 -01800100030003000300030007000700070007000700070002000F197E9813>I<078018603030 -201860186018601870103C303E600F8007C019F030F86038401CC00CC00CC00CC00C6008201018 -600FC00E187E9713>I<07801860303070306018E018E018E01CE01CE01C601C603C303C185C0F -9C001C00180018003870307060604021801F000E187E9713>I<FFE7FF0E00700E00700E00700E -00700E00700E00700E00700E00700E00700E00700E00700FFFF00E00700E00700E00700E00700E -00700E00700E00700E00700E00700E00700E00700E0070FFE7FF181A7E991D>72 -D<0FC21836200E6006C006C002C002C002E00070007E003FE01FF807FC003E000E000700038003 -80038003C002C006E004D81887E0101A7E9915>83 D<3F8070C070E020700070007007F01C7030 -707070E070E071E071E0F171FB1E3C10107E8F13>97 D<07F80C1C381C30087000E000E000E000 -E000E000E0007000300438080C1807E00E107F8F11>99 D<007E00000E00000E00000E00000E00 -000E00000E00000E00000E00000E0003CE000C3E00380E00300E00700E00E00E00E00E00E00E00 -E00E00E00E00E00E00600E00700E00381E001C2E0007CFC0121A7F9915>I<07C01C3030187018 -600CE00CFFFCE000E000E000E0006000300438080C1807E00E107F8F11>I<0FCE187330307038 -703870387038303018602FC02000600070003FF03FFC1FFE600FC003C003C003C0036006381C07 -E010187F8F13>103 D<FC00001C00001C00001C00001C00001C00001C00001C00001C00001C00 -001CF8001D0C001E0E001E0E001C0E001C0E001C0E001C0E001C0E001C0E001C0E001C0E001C0E -001C0E001C0E00FF9FC0121A7F9915>I<18003C003C001800000000000000000000000000FC00 -1C001C001C001C001C001C001C001C001C001C001C001C001C001C00FF80091A80990A>I<FCF8 -001D0C001E0E001E0E001C0E001C0E001C0E001C0E001C0E001C0E001C0E001C0E001C0E001C0E -001C0E00FF9FC012107F8F15>110 D<07E01C38300C700E6006E007E007E007E007E007E00760 -06700E381C1C3807E010107F8F13>I<FCF8001F0E001E07001C03801C03801C01C01C01C01C01 -C01C01C01C01C01C01C01C03801C03001E07001F0C001CF0001C00001C00001C00001C00001C00 -001C0000FF800012177F8F15>I<FCE01D701E701E201C001C001C001C001C001C001C001C001C -001C001C00FFC00C107F8F0F>114 D<1F2060E04020C020C020F0007F003FC01FE000F0807080 -30C030C020F0408F800C107F8F0F>I<0400040004000C000C001C003C00FFC01C001C001C001C -001C001C001C001C001C201C201C201C201C200E4003800B177F960F>I<FF1F803C06001C0400 -1C04001E0C000E08000E080007100007100007900003A00003A00001C00001C00001C000008000 -11107F8F14>118 D<FF3F803C1C001C18000E100007200007600003C00001C00001E00003E000 -027000043800083800181C00381E00FC3FC012107F8F14>120 D<FF1F803C06001C04001C0400 -1E0C000E08000E080007100007100007900003A00003A00001C00001C00001C000008000008000 -010000010000E10000E20000E4000078000011177F8F14>I E /Ff 2 42 -df<007000E001C00380078007000E001E001E003C003C003C0078007800780078007000F000F0 -00F000F000F000F000F000F000F000F000F000F000700078007800780078003C003C003C001E00 -1E000E0007000780038001C000E000700C2E7EA112>40 D<E000700038001C001E000E00070007 -80078003C003C003C001E001E001E001E000E000F000F000F000F000F000F000F000F000F000F0 -00F000F000E001E001E001E001E003C003C003C00780078007000E001E001C0038007000E0000C -2E7DA112>I E /Fg 25 123 df<0007F800007FFC0001FC0E0003F01F0007E03F000FC03F000F -C03F000FC03F000FC01E000FC00C000FC000000FC000000FC0FF80FFFFFF80FFFFFF800FC01F80 -0FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F -800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F807FF8FFF07FF8FFF01C23 -7FA220>12 D<000FFF80007FFF8001FC1F8003F03F8007E03F800FC03F800FC01F800FC01F800F -C01F800FC01F800FC01F800FC01F800FC01F80FFFFFF80FFFFFF800FC01F800FC01F800FC01F80 -0FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F -800FC01F800FC01F800FC01F800FC01F800FC01F807FF8FFF07FF8FFF01C237FA220>I<07FE00 -001FFF80003F07E0003F03F0003F01F0003F01F8001E01F8000001F8000001F800003FF80003FD -F8001F81F8003E01F8007C01F800F801F800F801F800F801F800F801F8007C02F8007E0CF8001F -F87F8007E03F8019167E951C>97 D<FF800000FF8000001F8000001F8000001F8000001F800000 -1F8000001F8000001F8000001F8000001F8000001F8000001F8000001F87F0001FBFFC001FF03E -001FC01F001F800F801F800FC01F8007C01F8007E01F8007E01F8007E01F8007E01F8007E01F80 -07E01F8007E01F8007C01F8007C01F800FC01F800F801FC01F001E707E001C3FFC00180FE0001B -237EA220>I<00FF8007FFE00F83F01F03F03E03F07E03F07C01E07C0000FC0000FC0000FC0000 -FC0000FC0000FC00007C00007E00007E00003F00301F00600FC0E007FF8000FE0014167E9519> -I<0001FF000001FF0000003F0000003F0000003F0000003F0000003F0000003F0000003F000000 -3F0000003F0000003F0000003F0000FE3F0007FFBF000FC1FF001F007F003E003F007E003F007C -003F007C003F00FC003F00FC003F00FC003F00FC003F00FC003F00FC003F00FC003F007C003F00 -7E003F003E003F001F007F000F81FF0007FF3FE001FC3FE01B237EA220>I<00FE0007FF800F83 -C01F01E03E00F07E00F07C00F87C0078FC0078FFFFF8FFFFF8FC0000FC0000FC00007C00007C00 -003E00183E00181F00300F80E003FFC000FF0015167E951A>I<00FE0F8003FF9FC00F83E3C01F -01F3C01E00F0003E00F8003E00F8003E00F8003E00F8003E00F8001E00F0001F01F0000F83E000 -0BFF800008FE000018000000180000001C0000001FFFE0001FFFFC000FFFFF0007FFFF001FFFFF -807C001FC078000FC0F80007C0F80007C0F80007C07C000F803E001F001F807E000FFFFC0001FF -E0001A217F951D>103 D<FF800000FF8000001F8000001F8000001F8000001F8000001F800000 -1F8000001F8000001F8000001F8000001F8000001F8000001F83F0001F8FFC001F987E001FA03E -001FC03F001FC03F001F803F001F803F001F803F001F803F001F803F001F803F001F803F001F80 -3F001F803F001F803F001F803F001F803F001F803F001F803F00FFF1FFE0FFF1FFE01B237DA220 ->I<1E003F007F807F807F807F803F001E00000000000000000000000000FF80FF801F801F801F -801F801F801F801F801F801F801F801F801F801F801F801F801F801F801F80FFF0FFF00C247EA3 -0F>I<FF800000FF8000001F8000001F8000001F8000001F8000001F8000001F8000001F800000 -1F8000001F8000001F8000001F8000001F80FF801F80FF801F803C001F8030001F80E0001F81C0 -001F8300001F8600001F9E00001FBE00001FFF00001FDF80001F8FC0001F07C0001F07E0001F03 -F0001F01F8001F00F8001F00FC001F007E00FFE1FFC0FFE1FFC01A237EA21E>107 -D<FF80FF801F801F801F801F801F801F801F801F801F801F801F801F801F801F801F801F801F80 -1F801F801F801F801F801F801F801F801F801F801F801F801F801F80FFF0FFF00C237EA20F>I< -FF03F803F800FF0FFE0FFE001F183F183F001F201F201F001F401FC01F801F401FC01F801F801F -801F801F801F801F801F801F801F801F801F801F801F801F801F801F801F801F801F801F801F80 -1F801F801F801F801F801F801F801F801F801F801F801F801F801F801F801F801F801F801F801F -801F80FFF0FFF0FFF0FFF0FFF0FFF02C167D9531>I<FF03F000FF0FFC001F187E001F203E001F -403F001F403F001F803F001F803F001F803F001F803F001F803F001F803F001F803F001F803F00 -1F803F001F803F001F803F001F803F001F803F001F803F00FFF1FFE0FFF1FFE01B167D9520>I< -00FF0007FFE00F81F01F00F83E007C7C003E7C003E7C003EFC003FFC003FFC003FFC003FFC003F -FC003FFC003F7C003E7E007E3E007C1F00F80F81F007FFE000FF0018167E951D>I<FF87F000FF -BFFC001FF07E001FC01F001F800F801F800FC01F800FC01F8007E01F8007E01F8007E01F8007E0 -1F8007E01F8007E01F8007E01F8007C01F800FC01F800FC01F801F801FC01F001FF07E001FBFFC -001F8FE0001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F800000FFF0 -0000FFF000001B207E9520>I<FF0F80FF1FE01F33F01F63F01F43F01F43F01FC1E01F80001F80 -001F80001F80001F80001F80001F80001F80001F80001F80001F80001F80001F8000FFF800FFF8 -0014167E9518>114 D<07F9801FFF80380780700380F00180F00180F80000FF0000FFF8007FFE -003FFF001FFF8007FF80003FC0C007C0C003C0E003C0E003C0F00380FC0F00EFFE00C3F8001216 -7E9517>I<00C00000C00000C00000C00001C00001C00003C00007C0000FC0001FC000FFFF00FF -FF000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC1800F -C1800FC1800FC1800FC18007C18007E30003FE0000FC0011207F9F16>I<FF81FF00FF81FF001F -803F001F803F001F803F001F803F001F803F001F803F001F803F001F803F001F803F001F803F00 -1F803F001F803F001F803F001F803F001F803F001F807F001F80FF000FC1BF0007FF3FE001FC3F -E01B167D9520>I<FFF01FE0FFF01FE00FC007000FC006000FE00E0007E00C0007F01C0003F018 -0003F8180001F8300001F8300000FC600000FC6000007EC000007EC000007FC000003F8000003F -8000001F0000001F0000000E0000000E00001B167F951E>I<FFF3FF87FCFFF3FF87FC1F807C00 -E00FC07C00C00FC07E00C00FE03E01C007E03F018007E07F018003F07F030003F0CF830001F8CF -860001F8CFC60001FD87C60000FD87CC0000FF03EC00007F03F800007F03F800007E01F800003E -01F000003C00F000001C00E000001800600026167F9529>I<FFF0FFC0FFF0FFC00FC01C0007E0 -380007F0700003F0E00001F8C00000FD8000007F0000007F0000003F0000001F8000003FC00000 -37E0000067F00000C3F00001C1F8000380FC000700FE000E007E00FFC1FFE0FFC1FFE01B167F95 -1E>I<FFF01FE0FFF01FE00FC007000FC006000FE00E0007E00C0007F01C0003F0180003F81800 -01F8300001F8300000FC600000FC6000007EC000007EC000007FC000003F8000003F8000001F00 -00001F0000000E0000000E0000000C0000000C00000018000078180000FC380000FC300000FC60 -000069E000007F8000001F0000001B207F951E>I<7FFFE07FFFE0780FC0701FC0601F80E03F00 -C07F00C07E00C0FC0001FC0001F80003F00007F03007E0300FC0301FC0701F80703F00607F00E0 -7E03E0FFFFE0FFFFE014167E9519>I E /Fh 22 119 df<00E00000E00000E00000E00040E040 -F0E1E0F8E3E07EEFC01FFF0007FC0003F80007FC001FFF007EEFC0F8E3E0F0E1E040E04000E000 -00E00000E00000E00013157D991A>42 D<003800007C00007C00006C0000EE0000EE0000EE0000 -EE0000C60001C70001C70001C70001C7000383800383800383800383800783C00701C007FFC007 -FFC007FFC00E00E00E00E00E00E00E00E01C00707F83FCFF83FE7F83FC171E7F9D1A>65 -D<7FFFFCFFFFFC7FFFFC0E001C0E001C0E001C0E001C0E001C0E00000E00000E07000E07000E07 -000FFF000FFF000FFF000E07000E07000E07000E00000E00000E00000E000E0E000E0E000E0E00 -0E0E000E7FFFFEFFFFFE7FFFFE171E7F9D1A>69 D<FF8FF8FF8FF8FF8FF81C01C01C01C01C01C0 -1C01C01C01C01C01C01C01C01C01C01C01C01C01C01FFFC01FFFC01FFFC01C01C01C01C01C01C0 -1C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C0FF8FF8FF8FF8FF8FF8151E7E9D1A> -72 D<FFFF80FFFF80FFFF8001C00001C00001C00001C00001C00001C00001C00001C00001C000 -01C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C000 -01C00001C000FFFF80FFFF80FFFF80111E7C9D1A>I<FE0FF8FF0FF8FF0FF81D81C01D81C01D81 -C01D81C01DC1C01CC1C01CC1C01CE1C01CE1C01C61C01C61C01C71C01C71C01C31C01C31C01C39 -C01C39C01C19C01C19C01C1DC01C0DC01C0DC01C0DC01C0DC0FF87C0FF87C0FF83C0151E7E9D1A ->78 D<0FFE003FFF807FFFC07C07C07001C0F001E0E000E0E000E0E000E0E000E0E000E0E000E0 -E000E0E000E0E000E0E000E0E000E0E000E0E000E0E000E0E000E0E000E0E000E0F001E0F001E0 -7001C07C07C07FFFC03FFF800FFE00131E7D9D1A>I<FFF000FFFC00FFFF001C0F801C07801C03 -C01C01C01C01C01C01C01C01C01C03C01C07801C0F801FFF001FFC001FFE001C0F001C07001C03 -801C03801C03801C03801C03801C03841C038E1C038E1C038EFF81FCFF81FCFF8070171E7E9D1A ->82 D<03F1C00FFDC03FFFC07C0FC07003C0E003C0E001C0E001C0E001C0E00000700000780000 -3F00001FF00007FE0000FF00000F800003C00001C00000E00000E06000E0E000E0E000E0E001C0 -F001C0FC0780FFFF80EFFE00E3F800131E7D9D1A>I<7FFFFEFFFFFEFFFFFEE0380EE0380EE038 -0EE0380EE0380E0038000038000038000038000038000038000038000038000038000038000038 -0000380000380000380000380000380000380000380000380003FF8007FFC003FF80171E7F9D1A ->I<FF01FEFF83FEFF01FE1E00F00E00E00E00E00701C00701C003838003838003C78001C70001 -C70000EE0000EE00007C00007C0000380000380000380000380000380000380000380000380000 -380000380001FF0001FF0001FF00171E7F9D1A>89 D<7FFFC0FFFFE0FFFFE07FFFC013047D7E1A ->95 D<1FF0003FFC007FFE00780F00300700000380000380007F8007FF801FFF803F8380780380 -700380E00380E00380E00380700780780F803FFFFC1FFDFC07F0FC16157D941A>97 -D<00FF8003FFC00FFFE01F01E03C00C0780000700000700000E00000E00000E00000E00000E000 -007000007000007800703C00701F01F00FFFE003FFC000FE0014157D941A>99 -D<001FC0001FC0001FC00001C00001C00001C00001C00001C00001C001F1C007FDC00FFFC01E0F -C03C07C07803C07001C0E001C0E001C0E001C0E001C0E001C0E001C0E001C07003C07003C03807 -C03E0FC01FFFFC07FDFC01F1FC161E7E9D1A>I<FE0000FE0000FE00000E00000E00000E00000E -00000E00000E00000E3E000EFF800FFFC00FC1C00F80E00F00E00E00E00E00E00E00E00E00E00E -00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E0FFE3FEFFE3FEFFE3FE171E7F9D1A> -104 D<01C00003E00003E00003E00001C0000000000000000000000000000000007FE000FFE000 -7FE00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E000 -00E00000E00000E000FFFFC0FFFFC0FFFFC0121F7C9E1A>I<FE3E00FEFF80FFFFC00FC1C00F80 -E00F00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00 -E0FFE3FEFFE3FEFFE3FE17157F941A>110 D<01F00007FC001FFF003E0F803C07807803C07001 -C0E000E0E000E0E000E0E000E0E000E0E000E0F001E07001C07803C03C07803E0F801FFF0007FC -0001F00013157D941A>I<FF83F0FF8FF8FFBFFC03FC3C03F01803E00003C00003C00003800003 -8000038000038000038000038000038000038000038000038000FFFF00FFFF80FFFF0016157E94 -1A>114 D<00C00001C00001C00001C00001C00001C00001C0007FFFE0FFFFE0FFFFE001C00001 -C00001C00001C00001C00001C00001C00001C00001C00001C00001C07001C07001C07001C07000 -E0E000FFE0007FC0001F00141C7F9B1A>116 D<7FC7FCFFC7FE7FC7FC0E00E00E00E00F01E007 -01C00701C00783C003838003838003838001C70001C70001C70000EE0000EE0000EE00007C0000 -7C0000380017157F941A>118 D E /Fi 41 123 df<0003FC00003FFE00007E070001F80F8003 -F01F8003E01F8007E01F8007E01F8007E01F8007E0060007E0000007E0000007E0000007E0FFC0 -FFFFFFC0FFFFFFC007E00FC007E00FC007E00FC007E00FC007E00FC007E00FC007E00FC007E00F -C007E00FC007E00FC007E00FC007E00FC007E00FC007E00FC007E00FC007E00FC007E00FC007E0 -0FC007E00FC007E00FC07FFC7FFC7FFC7FFC1E267FA522>12 D<3C7EFFFFFFFF7E3C08087C8711 ->46 D<001C00003C0000FC00FFFC00FFFC0000FC0000FC0000FC0000FC0000FC0000FC0000FC00 -00FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC00 -00FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC007FFFFC7FFFFC16237CA21F>49 -D<01FF0007FFC01E07F03803F86001FC7C00FEFE00FEFE00FFFE007FFE007F7C007F3800FF0000 -FF0000FE0000FE0001FC0001F80003F00007E0000780000F00001E00003C0000700000E00301C0 -030380070700060600060FFFFE1FFFFE3FFFFE7FFFFCFFFFFCFFFFFC18237DA21F>I<01FF0007 -FFE01E03F03801F83C01FC7E00FE7E00FE7E00FE3E00FE1C01FE0001FC0001FC0003F80007F000 -0FC001FF0001FF000007E00001F00001F80000FC0000FE0000FF0000FF1000FF7C00FFFE00FFFE -00FFFE00FEFE00FE7C01FC7001F83E07F00FFFC001FF0018237DA21F>I<000038000000780000 -0078000000F8000001F8000003F8000007F8000006F800000CF800001CF8000038F8000030F800 -0060F80000E0F80001C0F8000180F8000300F8000700F8000E00F8001C00F8001800F8003000F8 -007000F800E000F800FFFFFFC0FFFFFFC00001F8000001F8000001F8000001F8000001F8000001 -F8000001F800007FFFC0007FFFC01A237EA21F>I<18000C1F007C1FFFF81FFFF01FFFE01FFFC0 -1FFF801FFE0018000018000018000018000018000018FF001BFFE01F01F01C00F80800FC00007E -00007E00007E00007F00007F78007FFC007FFC007FFC007FFC007EF8007E6000FC7000FC3801F8 -1E07E007FFC001FE0018237DA21F>I<001FC0007FF001F83803E00C07803E0F807E1F007E3F00 -7E3F007E7E003C7E00007E00007E0000FE3FC0FE7FF0FE80F8FF80FCFF007CFF007EFE007EFE00 -7FFE007FFE007FFE007F7E007F7E007F7E007F7E007F3E007E3F007E1F007C0F80F807C1F003FF -C0007F0018237DA21F>I<300000003C0000003FFFFFC03FFFFFC03FFFFF807FFFFF007FFFFE00 -7FFFFC006000180060001800E0003000C0006000C000C000000180000001800000030000000700 -0000060000000E0000001E0000001E0000001E0000003C0000003C0000007C0000007C0000007C -0000007C000000FC000000FC000000FC000000FC000000FC000000FC000000FC00000078000000 -3000001A257DA41F>I<00001C00000000001C00000000003E00000000003E00000000003E0000 -0000007F00000000007F0000000000FF8000000000FF8000000000FF80000000019FC000000001 -9FC0000000031FE0000000030FE0000000030FE00000000607F00000000607F00000000C07F800 -00000C03F80000001C03FC0000001801FC0000001801FC0000003001FE0000003000FE0000007F -FFFF0000007FFFFF00000060007F000000C0007F800000C0003F800001C0003FC0000180001FC0 -000180001FC0000300000FE0000300000FE0000780000FF000FFF801FFFF80FFF801FFFF802925 -7EA42E>65 D<FFFFFFE00000FFFFFFFC000003F800FF000003F8001FC00003F80007E00003F800 -03F00003F80001F80003F80001FC0003F80000FC0003F80000FE0003F80000FE0003F800007F00 -03F800007F0003F800007F0003F800007F8003F800007F8003F800007F8003F800007F8003F800 -007F8003F800007F8003F800007F8003F800007F8003F800007F8003F800007F8003F800007F00 -03F800007F0003F800007F0003F80000FE0003F80000FE0003F80001FC0003F80001F80003F800 -03F00003F80007E00003F8001FC00003F800FF8000FFFFFFFE0000FFFFFFE0000029257EA42F> -68 D<FFFFFFFF00FFFFFFFF0003F8007F0003F8000F8003F800078003F800038003F800038003 -F800018003F800018003F800018003F80000C003F80600C003F80600C003F806000003F8060000 -03F80E000003F81E000003FFFE000003FFFE000003F81E000003F80E000003F806000003F80600 -0003F806006003F806006003F800006003F80000C003F80000C003F80000C003F80000C003F800 -01C003F80003C003F80003C003F8000F8003F8003F80FFFFFFFF80FFFFFFFF8023257EA428>I< -FFFFFFFE00FFFFFFFE0003F800FE0003F8001F0003F8000F0003F800070003F800070003F80003 -0003F800030003F800030003F800018003F806018003F806018003F806000003F806000003F80E -000003F81E000003FFFE000003FFFE000003F81E000003F80E000003F806000003F806000003F8 -06000003F806000003F800000003F800000003F800000003F800000003F800000003F800000003 -F800000003F800000003F800000003F8000000FFFFF00000FFFFF0000021257EA427>I<FFFFE0 -FFFFE0FFFFE0FFFFE003F80003F80003F80003F80003F80003F80003F80003F80003F80003F800 -03F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F800 -03F80003F80003F80003F80003F80003F80003F80003FFFFFFF80003FFFFFFF80003F80003F800 -03F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F800 -03F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F800 -03F80003F80003F80003F800FFFFE0FFFFE0FFFFE0FFFFE02B257EA430>72 -D<FFFFE0FFFFE003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F8 -0003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F8 -0003F80003F80003F80003F80003F80003F80003F80003F80003F800FFFFE0FFFFE013257EA417 ->I<FFFFF000FFFFF00003F8000003F8000003F8000003F8000003F8000003F8000003F8000003 -F8000003F8000003F8000003F8000003F8000003F8000003F8000003F8000003F8000003F80000 -03F8000003F8000003F8000003F8000003F8000603F8000603F8000603F8000C03F8000C03F800 -0C03F8001C03F8001C03F8003C03F8007C03F800F803F803F8FFFFFFF8FFFFFFF81F257EA425> -76 D<FFF8000000FFF8FFFC000001FFF803FC000001FE00037E0000037E00037E0000037E0003 -7E0000037E00033F0000067E00033F0000067E00031F80000C7E00031F80000C7E00030FC00018 -7E00030FC000187E000307E000307E000307E000307E000307E000307E000303F000607E000303 -F000607E000301F800C07E000301F800C07E000300FC01807E000300FC01807E0003007E03007E -0003007E03007E0003007E03007E0003003F06007E0003003F06007E0003001F8C007E0003001F -8C007E0003000FD8007E0003000FD8007E00030007F0007E00030007F0007E00030007F0007E00 -030003E0007E00078003E0007E00FFFC01C01FFFF8FFFC01C01FFFF835257EA43A>I<00FF0080 -07FFE3800F80F7801E001F803C000F807800078078000380F8000380F8000180F8000180FC0001 -80FC000000FF0000007FE000007FFF00003FFFE0003FFFF8001FFFFE0007FFFF0003FFFF80007F -FF800003FFC000003FC000000FE0000007E0000007E0C00003E0C00003E0C00003E0C00003C0E0 -0003C0F00007C0F8000780FC000F00FFC03E00E3FFF800803FE0001B257DA422>83 -D<FFFF83FFFE01FFF0FFFF83FFFE01FFF007F0001FC0000F0007F0001FC000060003F8000FE000 -0C0003F8000FE0000C0003FC000FF0001C0001FC0007F000180001FC0007F000180000FE000FF8 -00300000FE000FF800300000FE000FFC003000007F0019FC006000007F0019FC006000007F8039 -FE00E000003F8030FE00C000003F8030FE00C000001FC0607F018000001FC0607F018000001FE0 -607F818000000FE0C03F830000000FE0C03F830000000FF1C03FC700000007F1801FC600000007 -F1801FC600000003FB000FEC00000003FB000FEC00000003FF000FFC00000001FE0007F8000000 -01FE0007F800000001FE0007F800000000FC0003F000000000FC0003F000000000780001E00000 -0000780001E000000000780001E000000000300000C000003C257FA43F>87 -D<07FF00001FFFC0003E03E0003F01F0003F01F8003F00FC001E00FC000000FC000000FC000000 -FC00003FFC0003FCFC000FC0FC003F00FC007E00FC007E00FC00FC00FC00FC00FC00FC00FC00FC -017C007E017C003F067C001FFC3FE007F01FE01B187E971E>97 D<FFC00000FFC000000FC00000 -0FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000 -000FC000000FC3F8000FCFFE000FF81F800FE00FC00FC007E00FC007E00FC003F00FC003F00FC0 -03F80FC003F80FC003F80FC003F80FC003F80FC003F80FC003F80FC003F80FC003F00FC003F00F -C007E00FC007C00FE00FC00F383F000E1FFE000C07F0001D267EA522>I<007FE003FFF807C07C -1F80FC1F00FC3F00FC7E00787E0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000 -7E00007F00003F000C1F800C1FC01807E07003FFE0007F0016187E971B>I<0001FF800001FF80 -00001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F -8000001F8000001F80007F1F8003FFDF8007E0FF801F803F803F001F803F001F807E001F807E00 -1F80FE001F80FE001F80FE001F80FE001F80FE001F80FE001F80FE001F80FE001F807E001F807E -001F803F001F803F003F801F807F800FC0FF8003FF9FF800FE1FF81D267EA522>I<007F0003FF -C007C1F00F80F81F00F83F007C7E007C7E007EFE007EFE007EFFFFFEFFFFFEFE0000FE0000FE00 -007E00007E00007E00063F00061F000C0F801807E07003FFE0007F8017187E971C>I<000FC000 -7FF000F8F001F1F803F1F803E1F807E0F007E00007E00007E00007E00007E00007E00007E000FF -FF00FFFF0007E00007E00007E00007E00007E00007E00007E00007E00007E00007E00007E00007 -E00007E00007E00007E00007E00007E00007E00007E00007E0007FFF007FFF0015267EA513>I< -01FF07C007FFDFE00F83F1E01F01F1E03E00F8007E00FC007E00FC007E00FC007E00FC007E00FC -007E00FC003E00F8001F01F0000F83E0000FFFC00011FF00003000000030000000380000003C00 -00003FFFE0001FFFFC001FFFFE000FFFFF001FFFFF803C003F8078000FC0F80007C0F80007C0F8 -0007C0F80007C07C000F803E001F001F807E0007FFF80000FFC0001B247E971F>I<FFC00000FF -C000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC00000 -0FC000000FC000000FC000000FC1F8000FC7FE000FCC3F000FD01F000FF01F800FE01F800FE01F -800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC0 -1F800FC01F800FC01F800FC01F800FC01F800FC01F80FFFCFFF8FFFCFFF81D267DA522>I<0F00 -1F803FC03FC03FC03FC01F800F000000000000000000000000000000FFC0FFC00FC00FC00FC00F -C00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC0FFF8FFF80D27 -7EA611>I<FFC0FFC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC0 -0FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC0FF -FCFFFC0E267EA511>108 D<FF81FC01FC00FF87FF07FF000F8C1F8C1F800F980F980F800FB00F -F00FC00FA00FE00FC00FA00FE00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC0 -0FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00F -C00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC0FFFCFFFCFFFCFFFCFFFCFFFC -2E187D9733>I<FF81F800FF87FE000F8C3F000F901F000FB01F800FA01F800FA01F800FC01F80 -0FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F -800FC01F800FC01F800FC01F800FC01F80FFFCFFF8FFFCFFF81D187D9722>I<007F800003FFF0 -0007C0F8001F807E003F003F003F003F007E001F807E001F80FE001FC0FE001FC0FE001FC0FE00 -1FC0FE001FC0FE001FC0FE001FC0FE001FC07E001F807E001F803F003F003F003F001F807E000F -C0FC0003FFF000007F80001A187E971F>I<FFC3F800FFCFFE000FF83F800FE00FC00FC00FE00F -C007E00FC007F00FC003F00FC003F80FC003F80FC003F80FC003F80FC003F80FC003F80FC003F8 -0FC003F80FC007F00FC007F00FC007E00FC00FC00FE01FC00FF83F000FDFFE000FC7F0000FC000 -000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC00000FFFC0000FFFC -00001D237E9722>I<FF87C0FF8FF00F98F80FB1F80FA1F80FA1F80FE0F00FC0000FC0000FC000 -0FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC000FFFE00 -FFFE0015187E9719>114 D<07F9801FFF803C0F80700380F00180F00180F00180FC0000FF8000 -7FFC007FFE003FFF800FFFC003FFC0001FE00003E0C001E0C001E0E001E0E001C0F003C0FC0780 -EFFF00C3FC0013187E9718>I<00600000600000600000600000E00000E00001E00001E00003E0 -0007E0001FE000FFFFC0FFFFC007E00007E00007E00007E00007E00007E00007E00007E00007E0 -0007E00007E00007E00007E06007E06007E06007E06007E06007E06003E0C003F0C001FF80007E -0013237FA218>I<FFC1FF80FFC1FF800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F -800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC01F800FC0 -1F800FC03F800FC03F8007C07F8007E0DF8003FF9FF800FE1FF81D187D9722>I<FFF80FF8FFF8 -0FF80FC003C00FE0018007E0030007E0030003F0060003F0060003F80E0001F80C0001FC1C0000 -FC180000FE1800007E3000007E3000003F6000003F6000001FC000001FC000001FC000000F8000 -000F800000070000000700001D187F9720>I<FFF83FF0FFF83FF00FC00F0007E00C0003F01C00 -03F8380001FC700000FCE000007EC000003F8000003F8000001F8000000FC000001FE000001FF0 -000033F8000071F80000E0FC0001C07E0003807F0003003F000F001F80FFC07FF8FFC07FF81D18 -7F9720>120 D<FFF80FF8FFF80FF80FC003C00FE0018007E0030007E0030003F0060003F00600 -03F80E0001F80C0001FC1C0000FC180000FE1800007E3000007E3000003F6000003F6000001FC0 -00001FC000001FC000000F8000000F800000070000000700000006000000060000000C0000300C -0000781C0000FC180000FC380000FC70000078E000007FC000001F0000001D237F9720>I<3FFF -F83FFFF83E03F03807F0300FE0700FC0701F80603F80603F00607E0000FE0000FC0001F80003F8 -1803F01807E0180FE0180FC0381F80303F80707F00707E01F0FFFFF0FFFFF015187E971B>I -E /Fj 29 122 df<0003F07C001E0DC600380F0F00701E0F00E01E0E00E00C0001C01C0001C01C -0001C01C0001C01C0001C01C00038038007FFFFFC0038038000380380003803800038038000700 -700007007000070070000700700007007000070070000E00E0000E00E0000E00E0000E00E0000E -00E0000E00E0001C01C0001E01E000FF8FFE0020207E9F1B>11 D<0003E0001C1800381800703C -00E03C00E03801C00001C00001C00001C00001C0000380007FFFF0038070038070038070038070 -0700E00700E00700E00700E00700E00700E00E01C00E01C00E01C00E01C00E01C00E01C01C0380 -1E03C0FF0FF816207E9F19>I<0003F03F00001E09E08000380F80C000701F01E000E03E01E000 -E01E01C001C01C000001C01C000001C01C000001C01C000001C01C000003803800007FFFFFFF80 -038038038003803803800380380380038038038007007007000700700700070070070007007007 -00070070070007007007000E00E00E000E00E00E000E00E00E000E00E00E000E00E00E000E00E0 -0E001C01C01C001E01E01E00FF8FF8FFC023207E9F26>14 D<0020000060000060000060000060 -007061C03843800E4E0007580001E00001E00006B8001C9C00708700E083800180000180000180 -0001800001000012147AA117>42 D<FFC0FFC00A027D8A0F>45 D<000C001C00FC0F3800380038 -00380038003800700070007000700070007000E000E000E000E000E000E001C001C001C001C001 -C001C0038003C0FFFE0F1E7C9D17>49 D<003F8000C1E00100F00200780400780400780F007C0F -807C0F807C0F00780600780000F80000F00001E00001C0000380000700000E00001C0000380000 -600000C0000180000300200600200800401000403FFFC07FFF80FFFF80161E7E9D17>I<07F800 -0C0C001E06001E07001C070000070000070000070000FF0007C7001E07003C0E00780E00F00E10 -F00E10F00E10F01E10F02E20784F401F878014147D9317>97 D<01FC07060E0F1C0F380E780070 -00F000F000F000F000E000E000E000E000F0027004300818300FC010147C9314>99 -D<0000700003F00000F00000700000700000E00000E00000E00000E00000E00000E00001C000F9 -C00305C00E03C01C03C03801C0780380700380F00380F00380F00380F00380E00700E00700E007 -00E00700E00700700F00301E00186F000F8FE014207C9F19>I<00F800070E000E07001C070038 -0380780380700380F00380F00380FFFF80F00000E00000E00000E00000E00000F0010070020030 -04001C180007E00011147D9314>I<0007800018C00031E00061E000E1C000C00001C00001C000 -01C00001C00001C0000380007FF800038000038000038000038000070000070000070000070000 -0700000700000E00000E00000E00000E00000E00000E00001C00001E0000FFE00013207E9F0E> -I<00000E003E1100E1A301C1C20381E00780E00701E00F01E00F01E00F01E00703C00703800787 -0004FC000800000800001800001C00000FFF000FFFC007FFE01800F0300030600030C00030C000 -30C000306000603000C01C070007FC00181F809417>I<00E00007E00001E00000E00000E00001 -C00001C00001C00001C00001C00001C000038000038F800390E003A0E003C0600380600780E007 -00E00700E00700E00700E00700E00E01C00E01C00E01C00E01C00E01C00E01C01C03801E03C0FF -CFF815207E9F19>I<01C003E003E003C0018000000000000000000000000003801F8007800380 -03800700070007000700070007000E000E000E000E000E000E001C001E00FF800B1F7F9E0C>I< -00E007E001E000E000E001C001C001C001C001C001C00380038003800380038003800700070007 -000700070007000E000E000E000E000E000E001C001E00FFC00B207F9F0C>108 -D<0387C07C001F9861860007A072070003C0340300038038030007807807000700700700070070 -07000700700700070070070007007007000E00E00E000E00E00E000E00E00E000E00E00E000E00 -E00E000E00E00E001C01C01C001E01E01E00FFCFFCFFC022147E9326>I<038F801F90E007A0E0 -03C0600380600780E00700E00700E00700E00700E00700E00E01C00E01C00E01C00E01C00E01C0 -0E01C01C03801E03C0FFCFF815147E9319>I<00FC000387000E01801C00C03800E03800E07000 -F0F000F0F000F0F000F0F000F0E001E0E001E0E001C0E003C0F00380700700380E001C1C0007E0 -0014147D9317>I<00E3E007EC3800F01C00E01E00E00E01C00E01C00F01C00F01C00F01C00F01 -C00F03801E03801E03801C03803C0380380380700740E00721C0071F000700000700000700000E -00000E00000E00000E00001E0000FFC000181D809319>I<00F040038CC00E04C01C03C03C03C0 -780380780380F00380F00380F00380F00380E00700E00700E00700F00700F00F00700F00301E00 -186E000F8E00000E00000E00000E00001C00001C00001C00001C00003C0001FF80121D7C9318> -I<038E001FB38007C78003C7800383000780000700000700000700000700000700000E00000E00 -000E00000E00000E00000E00001C00001E0000FFE00011147E9312>I<01F2060E080618061802 -380438001E001FE00FF003F8003C401C400C400C600C6018E010D0608FC00F147E9312>I<0080 -010001000100030007000F001E00FFF80E000E000E000E001C001C001C001C001C001C00380038 -203820382038203840384018800F000D1C7C9B12>I<1C0380FC1F803C07801C03801C03803807 -00380700380700380700380700380700700E00700E00700E00700E00701E00701E00703C00305E -001F9FC012147B9319>I<FF83F81E00E01C00C01C00800E00800E01000E02000E02000F040007 -040007080007080007100003900003A00003E00003C00003800001800001000015147C9318>I< -FF9FE1FC3E0780701C0300601C0300401C0380401C0380800E0780800E0581000E0981000E09C2 -000E11C2000731C4000721C4000760C8000740C8000780F0000780F0000300E000030060000200 -40001E147C9321>I<1FF0FF03C07801C06001C04000E08000E180007300007600003C00003C00 -001C00002E00004E000087000107000203800603800C01C03E03E0FF07FC18147F9318>I<0FF8 -3F8001E00E0001C00C0001C0080000E0180000E0100000E0200000E0200000F040000070400000 -708000007080000071000000390000003A0000003E0000003C0000003800000018000000100000 -0010000000200000002000000040000070C00000F0800000F1000000E20000007C000000191D80 -9318>I E /Fk 36 122 df<0001C0000003C000000FC000007FC0001FFFC000FFFFC000FFBFC0 -00E03FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003F -C000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC00000 -3FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000 -003FC000003FC000003FC000003FC000003FC000003FC000003FC0007FFFFFE07FFFFFE07FFFFF -E01B2E7AAD28>49 D<003FE00001FFFE0007FFFF800F80FFC01E003FE038001FF07C000FF87E00 -07FCFF0007FCFF8007FEFF8007FEFF8003FEFF8003FE7F0003FE3E0007FE000007FE000007FC00 -0007FC00000FF800000FF800000FF000001FE000001FC000003F8000007F0000007E000000F800 -0001F0000003E0000007C000000F0000001E000E003C000E0038000E0070001E00E0001C01C000 -1C0300003C07FFFFFC0FFFFFFC1FFFFFFC3FFFFFFC7FFFFFF8FFFFFFF8FFFFFFF8FFFFFFF81F2E -7CAD28>I<0000007800000000000078000000000000FC000000000000FC000000000000FC0000 -00000001FE000000000001FE000000000003FF000000000003FF000000000007FF800000000007 -FF800000000007FF80000000000FFFC0000000000E7FC0000000001E7FE0000000001C3FE00000 -00001C3FE000000000383FF000000000381FF000000000781FF800000000700FF800000000700F -F800000000E00FFC00000000E007FC00000001E007FE00000001C003FE00000001C003FE000000 -038003FF000000038001FF000000078001FF800000070000FF800000070000FF8000000FFFFFFF -C000000FFFFFFFC000001FFFFFFFE000001C00003FE000003C00003FF000003800001FF0000038 -00001FF000007000001FF800007000000FF80000F000000FFC0000E0000007FC0000E0000007FC -0001C0000007FE0003E0000003FE00FFFF8001FFFFFCFFFF8001FFFFFCFFFF8001FFFFFC36317D -B03D>65 D<FFFFFFFFE00000FFFFFFFFFE0000FFFFFFFFFF800000FF0000FFC00000FF00003FF0 -0000FF00001FF80000FF00000FF80000FF000007FC0000FF000007FC0000FF000007FE0000FF00 -0003FE0000FF000003FE0000FF000003FE0000FF000003FE0000FF000007FE0000FF000007FE00 -00FF000007FC0000FF000007FC0000FF00000FF80000FF00001FF00000FF00003FE00000FF0000 -FF800000FF000FFF000000FFFFFFFE000000FFFFFFFFC00000FF00001FF00000FF000007F80000 -FF000003FE0000FF000003FE0000FF000001FF0000FF000001FF8000FF000000FF8000FF000000 -FFC000FF000000FFC000FF000000FFC000FF000000FFC000FF000000FFC000FF000000FFC000FF -000000FFC000FF000000FF8000FF000001FF8000FF000001FF0000FF000003FF0000FF000007FE -0000FF00000FFC0000FF00007FF800FFFFFFFFFFE000FFFFFFFFFF8000FFFFFFFFFC000032317E -B039>I<000003FF80018000003FFFF003800001FFFFFC07800007FF003F0F80001FF800079F80 -003FC00001FF8000FF800000FF8001FE0000007F8003FC0000003F8007FC0000001F8007F80000 -000F800FF00000000F801FF000000007801FF000000007803FE000000007803FE000000003807F -E000000003807FE000000003807FC000000000007FC00000000000FFC00000000000FFC0000000 -0000FFC00000000000FFC00000000000FFC00000000000FFC00000000000FFC00000000000FFC0 -0000000000FFC000000000007FC000000000007FC000000000007FE000000000007FE000000003 -803FE000000003803FE000000003801FF000000003801FF000000007800FF0000000070007F800 -0000070007FC0000000E0003FC0000001E0001FE0000001C0000FF8000007800003FC00000F000 -001FF80003E0000007FF003F80000001FFFFFE000000003FFFF80000000003FF80000031317CB0 -3A>I<FFFFFFFFFFE0FFFFFFFFFFE0FFFFFFFFFFE000FF80007FE000FF80000FF000FF800003F0 -00FF800001F000FF800001F000FF800000F000FF800000F000FF8000007000FF8000007000FF80 -00007000FF8000003800FF8000003800FF8007003800FF8007003800FF8007000000FF80070000 -00FF8007000000FF800F000000FF801F000000FF803F000000FFFFFF000000FFFFFF000000FFFF -FF000000FF803F000000FF801F000000FF800F000000FF8007000000FF8007000000FF80070000 -00FF8007000000FF8007000000FF8000000000FF8000000000FF8000000000FF8000000000FF80 -00000000FF8000000000FF8000000000FF8000000000FF8000000000FF8000000000FF80000000 -00FF80000000FFFFFFE00000FFFFFFE00000FFFFFFE000002D317EB033>70 -D<000003FF00030000007FFFF007000001FFFFFC0F000007FF007E1F00001FF0000FBF00007FC0 -0003FF0000FF800001FF0001FE0000007F0003FC0000007F0007FC0000003F000FF80000001F00 -0FF00000001F001FF00000000F001FF00000000F003FE000000007003FE000000007007FE00000 -0007007FE000000007007FC00000000000FFC00000000000FFC00000000000FFC00000000000FF -C00000000000FFC00000000000FFC00000000000FFC00000000000FFC00000000000FFC0000000 -0000FFC00000000000FFC00007FFFFFC7FC00007FFFFFC7FE00007FFFFFC7FE0000001FF003FE0 -000001FF003FE0000001FF001FF0000001FF001FF0000001FF000FF0000001FF000FF8000001FF -0007FC000001FF0003FC000001FF0001FE000001FF0000FF800001FF00007FC00003FF00001FF8 -00077F000007FF003E3F000001FFFFFC1F0000007FFFF00F00000003FF80030036317CB03F>I< -FFFFFF807FFFFFC0FFFFFF807FFFFFC0FFFFFF807FFFFFC000FF8000007FC00000FF8000007FC0 -0000FF8000007FC00000FF8000007FC00000FF8000007FC00000FF8000007FC00000FF8000007F -C00000FF8000007FC00000FF8000007FC00000FF8000007FC00000FF8000007FC00000FF800000 -7FC00000FF8000007FC00000FF8000007FC00000FF8000007FC00000FF8000007FC00000FF8000 -007FC00000FF8000007FC00000FF8000007FC00000FFFFFFFFFFC00000FFFFFFFFFFC00000FFFF -FFFFFFC00000FF8000007FC00000FF8000007FC00000FF8000007FC00000FF8000007FC00000FF -8000007FC00000FF8000007FC00000FF8000007FC00000FF8000007FC00000FF8000007FC00000 -FF8000007FC00000FF8000007FC00000FF8000007FC00000FF8000007FC00000FF8000007FC000 -00FF8000007FC00000FF8000007FC00000FF8000007FC00000FF8000007FC00000FF8000007FC0 -0000FF8000007FC00000FF8000007FC000FFFFFF807FFFFFC0FFFFFF807FFFFFC0FFFFFF807FFF -FFC03A317EB03F>I<FFFFFF80FFFFFF80FFFFFF8000FF800000FF800000FF800000FF800000FF -800000FF800000FF800000FF800000FF800000FF800000FF800000FF800000FF800000FF800000 -FF800000FF800000FF800000FF800000FF800000FF800000FF800000FF800000FF800000FF8000 -00FF800000FF800000FF800000FF800000FF800000FF800000FF800000FF800000FF800000FF80 -0000FF800000FF800000FF800000FF800000FF800000FF800000FF800000FF800000FF8000FFFF -FF80FFFFFF80FFFFFF8019317EB01E>I<FFFF800001FFFFC0FFFFC00001FFFFC0FFFFE00001FF -FFC000FFF0000003E00000FFF8000001C00000EFFC000001C00000E7FC000001C00000E7FE0000 -01C00000E3FF000001C00000E1FF800001C00000E0FFC00001C00000E07FE00001C00000E03FE0 -0001C00000E03FF00001C00000E01FF80001C00000E00FFC0001C00000E007FE0001C00000E003 -FE0001C00000E001FF0001C00000E001FF8001C00000E000FFC001C00000E0007FE001C00000E0 -003FF001C00000E0001FF001C00000E0001FF801C00000E0000FFC01C00000E00007FE01C00000 -E00003FF01C00000E00001FF81C00000E00000FF81C00000E00000FFC1C00000E000007FE1C000 -00E000003FF1C00000E000001FF9C00000E000000FFDC00000E0000007FDC00000E0000007FFC0 -0000E0000003FFC00000E0000001FFC00000E0000000FFC00000E00000007FC00000E00000003F -C00000E00000003FC00000E00000001FC00000E00000000FC00001F000000007C000FFFFE00000 -03C000FFFFE0000001C000FFFFE0000001C0003A317EB03F>78 D<FFFFFFFFE000FFFFFFFFFE00 -FFFFFFFFFF8000FF8000FFE000FF80003FF000FF80000FF800FF800007FC00FF800007FC00FF80 -0003FE00FF800003FE00FF800003FF00FF800003FF00FF800003FF00FF800003FF00FF800003FF -00FF800003FF00FF800003FF00FF800003FE00FF800003FE00FF800007FC00FF800007F800FF80 -000FF800FF80003FE000FF8000FFC000FFFFFFFF0000FFFFFFF80000FF8000000000FF80000000 -00FF8000000000FF8000000000FF8000000000FF8000000000FF8000000000FF8000000000FF80 -00000000FF8000000000FF8000000000FF8000000000FF8000000000FF8000000000FF80000000 -00FF8000000000FF8000000000FF8000000000FF8000000000FF80000000FFFFFF800000FFFFFF -800000FFFFFF80000030317EB037>80 D<7FFFFFFFFFFF007FFFFFFFFFFF007FFFFFFFFFFF007F -C00FF801FF007E000FF8003F007C000FF8001F0078000FF8000F0078000FF8000F0070000FF800 -0700F0000FF8000780F0000FF8000780F0000FF8000780E0000FF8000380E0000FF8000380E000 -0FF8000380E0000FF8000380E0000FF800038000000FF800000000000FF800000000000FF80000 -0000000FF800000000000FF800000000000FF800000000000FF800000000000FF800000000000F -F800000000000FF800000000000FF800000000000FF800000000000FF800000000000FF8000000 -00000FF800000000000FF800000000000FF800000000000FF800000000000FF800000000000FF8 -00000000000FF800000000000FF800000000000FF800000000000FF800000000000FF800000000 -000FF800000000000FF800000000000FF8000000007FFFFFFF0000007FFFFFFF0000007FFFFFFF -000031307DAF38>84 D<FFFFFF8003FFFF80FFFFFF8003FFFF80FFFFFF8003FFFF8000FF800000 -07C00000FF80000003800000FF80000003800000FF80000003800000FF80000003800000FF8000 -0003800000FF80000003800000FF80000003800000FF80000003800000FF80000003800000FF80 -000003800000FF80000003800000FF80000003800000FF80000003800000FF80000003800000FF -80000003800000FF80000003800000FF80000003800000FF80000003800000FF80000003800000 -FF80000003800000FF80000003800000FF80000003800000FF80000003800000FF800000038000 -00FF80000003800000FF80000003800000FF80000003800000FF80000003800000FF8000000380 -0000FF80000003800000FF80000003800000FF800000038000007F800000038000007F80000007 -0000007FC00000070000003FC000000E0000003FC000000E0000001FE000001C0000000FF00000 -3800000007F800007000000003FC0001E000000000FF801FC0000000003FFFFF80000000000FFF -FE000000000000FFE000000039317EB03E>I<FFFFFC0000FFFFFFFFFC0000FFFFFFFFFC0000FF -FF03FF00000003C001FF000000038001FF800000078000FF800000070000FFC000000700007FC0 -00000E00007FC000000E00007FE000001E00003FE000001C00003FF000003C00001FF000003800 -001FF800003800000FF800007000000FFC000070000007FC0000E0000007FC0000E0000007FE00 -01E0000003FE0001C0000003FF0003C0000001FF000380000001FF800380000000FF8007000000 -00FFC00700000000FFC00F000000007FC00E000000007FE01E000000003FE01C000000003FF03C -000000001FF038000000001FF838000000000FF870000000000FF870000000000FFCF000000000 -07FCE00000000007FFE00000000003FFC00000000003FFC00000000001FF800000000001FF8000 -00000000FF000000000000FF000000000000FF0000000000007E0000000000007E000000000000 -3C0000000000003C00000038317EB03D>I<00FFF0000003FFFE00000F803F80000FC00FE0001F -E007F0001FE007F0001FE003F8000FC003FC00078003FC00000003FC00000003FC00000003FC00 -000003FC000000FFFC00001FFFFC0000FFE3FC0003FC03FC000FF003FC001FC003FC003FC003FC -007F8003FC007F8003FC00FF0003FC00FF0003FC00FF0003FC00FF0007FC00FF0007FC007F800D -FC003FC019FE001FE070FFF007FFE07FF000FF803FF024207E9F27>97 D<01F8000000FFF80000 -00FFF8000000FFF80000000FF800000007F800000007F800000007F800000007F800000007F800 -000007F800000007F800000007F800000007F800000007F800000007F800000007F800000007F8 -00000007F83FE00007F8FFFC0007FBE07F0007FF001F8007FE000FC007FC000FE007F80007F007 -F80007F807F80007F807F80003FC07F80003FC07F80003FC07F80003FE07F80003FE07F80003FE -07F80003FE07F80003FE07F80003FE07F80003FE07F80003FE07F80003FC07F80003FC07F80003 -FC07F80007F807F80007F807F80007F007FC000FE007FE000FC007E7003F8007C3C0FE000780FF -F80007003FC00027327EB12D>I<000FFF00007FFFC001FC01F003F003F007E007F80FE007F81F -C007F83FC003F03FC001E07F8000007F8000007F800000FF800000FF800000FF800000FF800000 -FF800000FF800000FF800000FF8000007F8000007F8000007F8000003FC0001C3FC0001C1FC000 -380FE0003807E0007003F001E001FC07C0007FFF00000FF8001E207D9F24>I<0000000FC00000 -07FFC0000007FFC0000007FFC00000007FC00000003FC00000003FC00000003FC00000003FC000 -00003FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC0 -0000003FC00007F83FC0003FFF3FC000FE07BFC003F801FFC007E0007FC00FE0007FC01FC0003F -C03FC0003FC03FC0003FC07F80003FC07F80003FC07F80003FC0FF80003FC0FF80003FC0FF8000 -3FC0FF80003FC0FF80003FC0FF80003FC0FF80003FC0FF80003FC07F80003FC07F80003FC07F80 -003FC03FC0003FC03FC0003FC01FC0003FC00FE0007FC007E000FFC003F003FFE001FC0F3FFE00 -7FFE3FFE000FF03FFE27327DB12D>I<000FFC00007FFF8001FC0FC003F003E007E001F00FE001 -F81FC000FC3FC000FE3FC000FE7F80007E7F80007F7F80007FFF80007FFF80007FFFFFFFFFFFFF -FFFFFF800000FF800000FF800000FF8000007F8000007F8000007F8000003FC000071FC000071F -C0000E0FE0000E07F0001C03F8007800FE03E0003FFFC00007FE0020207E9F25>I<0001FE0000 -0FFF80001FC3C0007F07E000FE0FF001FE0FF001FC0FF003FC0FF003FC07E003FC018003FC0000 -03FC000003FC000003FC000003FC000003FC000003FC000003FC0000FFFFFC00FFFFFC00FFFFFC -0003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC -000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003 -FC000003FC000003FC000003FC000003FC000003FC000003FC00007FFFF0007FFFF0007FFFF000 -1C327EB119>I<001FF007C000FFFE3FE001F83F79F007E00FC3F00FE00FE1F00FC007E0E01FC0 -07F0001FC007F0003FC007F8003FC007F8003FC007F8003FC007F8003FC007F8001FC007F0001F -C007F0000FC007E0000FE00FE00007E00FC00003F83F000006FFFE00000E1FF000000E00000000 -1E000000001E000000001F000000001F800000001FFFFF80000FFFFFF0000FFFFFFC0007FFFFFE -0003FFFFFF0003FFFFFF800FFFFFFFC01F00007FC07E00001FE07C00000FE0FC000007E0FC0000 -07E0FC000007E0FC000007E07E00000FC03E00000F803F00001F800FC0007E0007F803FC0001FF -FFF000001FFF0000242F7E9F28>I<01F8000000FFF8000000FFF8000000FFF80000000FF80000 -0007F800000007F800000007F800000007F800000007F800000007F800000007F800000007F800 -000007F800000007F800000007F800000007F800000007F800000007F807F80007F83FFE0007F8 -783F0007F8C03F8007F9801FC007FB001FC007FE001FE007FC001FE007FC001FE007FC001FE007 -F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE0 -07F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001F -E007F8001FE007F8001FE007F8001FE0FFFFC3FFFFFFFFC3FFFFFFFFC3FFFF28327DB12D>I<03 -C00007E0000FF0001FF8001FF8001FF8001FF8000FF00007E00003C00000000000000000000000 -000000000000000000000000000000000001F800FFF800FFF800FFF8000FF80007F80007F80007 -F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007 -F80007F80007F80007F80007F80007F80007F80007F80007F800FFFF80FFFF80FFFF8011337DB2 -17>I<01F800FFF800FFF800FFF8000FF80007F80007F80007F80007F80007F80007F80007F800 -07F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F800 -07F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F800 -07F80007F80007F80007F80007F80007F80007F80007F80007F800FFFFC0FFFFC0FFFFC012327D -B117>108 D<03F007F8001FE000FFF03FFE00FFF800FFF0783F01E0FC00FFF0C03F8300FE000F -F1801FC6007F0007F3001FCC007F0007F6001FF8007F8007FC001FF0007F8007FC001FF0007F80 -07FC001FF0007F8007F8001FE0007F8007F8001FE0007F8007F8001FE0007F8007F8001FE0007F -8007F8001FE0007F8007F8001FE0007F8007F8001FE0007F8007F8001FE0007F8007F8001FE000 -7F8007F8001FE0007F8007F8001FE0007F8007F8001FE0007F8007F8001FE0007F8007F8001FE0 -007F8007F8001FE0007F8007F8001FE0007F8007F8001FE0007F8007F8001FE0007F8007F8001F -E0007F80FFFFC3FFFF0FFFFCFFFFC3FFFF0FFFFCFFFFC3FFFF0FFFFC3E207D9F43>I<03F007F8 -00FFF03FFE00FFF0783F00FFF0C03F800FF1801FC007F3001FC007F6001FE007FC001FE007FC00 -1FE007FC001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8 -001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007 -F8001FE007F8001FE007F8001FE007F8001FE007F8001FE0FFFFC3FFFFFFFFC3FFFFFFFFC3FFFF -28207D9F2D>I<0007FC0000007FFFC00001FC07F00003F001F80007E000FC000FC0007E001FC0 -007F003FC0007F803F80003F807F80003FC07F80003FC07F80003FC0FF80003FE0FF80003FE0FF -80003FE0FF80003FE0FF80003FE0FF80003FE0FF80003FE0FF80003FE07F80003FC07F80003FC0 -7F80003FC03FC0007F803FC0007F801FC0007F000FE000FE0007E000FC0003F803F80001FE0FF0 -00007FFFC0000007FC000023207E9F28>I<01F83FE000FFF8FFFC00FFFBE07F00FFFF003F8007 -FE001FC007FC000FE007F8000FF007F80007F807F80007F807F80007FC07F80003FC07F80003FC -07F80003FE07F80003FE07F80003FE07F80003FE07F80003FE07F80003FE07F80003FE07F80003 -FE07F80003FC07F80007FC07F80007FC07F80007F807F80007F807F8000FF007FC000FE007FE00 -1FC007FF003F8007FBC0FE0007F8FFF80007F83FC00007F800000007F800000007F800000007F8 -00000007F800000007F800000007F800000007F800000007F800000007F800000007F8000000FF -FFC00000FFFFC00000FFFFC00000272E7E9F2D>I<03F03F00FFF07FC0FFF1C3E0FFF187E00FF3 -0FF007F60FF007F60FF007FC07E007FC03C007FC000007FC000007F8000007F8000007F8000007 -F8000007F8000007F8000007F8000007F8000007F8000007F8000007F8000007F8000007F80000 -07F8000007F8000007F8000007F8000007F80000FFFFE000FFFFE000FFFFE0001C207E9F21> -114 D<01FF860007FFFE001F00FE003C003E0078001E0078000E00F8000E00F8000E00F8000E00 -FC000000FF800000FFFC00007FFFC0007FFFF0003FFFF8001FFFFC0007FFFE0001FFFF00003FFF -000000FF8000003F8060001F80E0000F80E0000F80F0000F80F0000F00F8000F00FC001E00FE00 -1C00FF807800F3FFF000C07F800019207D9F20>I<001C0000001C0000001C0000001C0000001C -0000003C0000003C0000003C0000007C0000007C000000FC000001FC000003FC000007FC00001F -FFFE00FFFFFE00FFFFFE0003FC000003FC000003FC000003FC000003FC000003FC000003FC0000 -03FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC03 -8003FC038003FC038003FC038003FC038003FC038003FC038001FC038001FC070000FE0700007F -0E00003FFC000007F000192E7FAD1F>I<01F80007E0FFF803FFE0FFF803FFE0FFF803FFE00FF8 -003FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007 -F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE0 -07F8001FE007F8001FE007F8001FE007F8001FE007F8003FE007F8003FE003F8007FE003F8007F -E001FC00DFF000FE039FFF007FFF1FFF000FFC1FFF28207D9F2D>I<FFFF801FFCFFFF801FFCFF -FF801FFC0FF80003C007F800038007FC00078003FC00070003FE000F0001FE000E0001FF000E00 -00FF001C0000FF001C00007F803800007F803800007FC07800003FC07000003FE0F000001FE0E0 -00001FF1E000000FF1C000000FF9C0000007FB80000007FB80000003FF00000003FF00000003FF -00000001FE00000001FE00000000FC00000000FC00000000780000000078000026207E9F2B>I< -FFFF1FFFE07FF8FFFF1FFFE07FF8FFFF1FFFE07FF80FF000FE0007800FF800FE00078007F800FE -00070007F8007F00070003FC007F000E0003FC00FF800E0003FE00FF801E0001FE00FF801C0001 -FE01DFC01C0001FF01DFC03C0000FF03DFE0380000FF838FE07800007F838FE07000007F8707F0 -7000007FC707F0F000003FCF07F8E000003FCE03F8E000001FEE03F9C000001FFC01FDC000001F -FC01FFC000000FFC01FF8000000FF800FF80000007F800FF00000007F0007F00000007F0007F00 -000003F0007E00000003E0003E00000001E0003C00000001C0001C000035207E9F3A>I<7FFF80 -7FFC7FFF807FFC7FFF807FFC03FE000F0001FE001E0000FF003C0000FF807800007FC07800003F -E0F000001FE1E000000FF3C000000FFF80000007FF00000003FE00000001FE00000000FF000000 -00FF80000000FFC0000001FFC0000003DFE00000078FF00000078FF800000F07FC00001E03FC00 -003C01FE00007800FF0000F000FF8000E0007FC001E0003FC0FFFC01FFFFFFFC01FFFFFFFC01FF -FF28207F9F2B>I<FFFF801FFCFFFF801FFCFFFF801FFC0FF80003C007F800038007FC00078003 -FC00070003FE000F0001FE000E0001FF000E0000FF001C0000FF001C00007F803800007F803800 -007FC07800003FC07000003FE0F000001FE0E000001FF1E000000FF1C000000FF9C0000007FB80 -000007FB80000003FF00000003FF00000003FF00000001FE00000001FE00000000FC00000000FC -000000007800000000780000000070000000007000000000F000000000E000000001E000007C01 -C00000FE03C00000FE03800000FE07800000FE0F000000FC1E000000787C0000003FF00000000F -C0000000262E7E9F2B>I E /Fl 1 14 df<0001FE00000007FF8000001E01E000007800780000 -E0001C000180000600030000030006000001800C000000C00C000000C018000000603000000030 -30000000303000000030600000001860000000186000000018C00000000CC00000000CC0000000 -0CC00000000CC00000000CC00000000CC00000000CC00000000CC00000000C6000000018600000 -0018600000001830000000303000000030300000003018000000600C000000C00C000000C00600 -0001800300000300018000060000E0001C000078007800001E01E0000007FF80000001FE000026 -2B7DA02D>13 D E /Fm 46 122 df<3C007F00FF80FF80FFC0FFC0FFC07FC03EC000C000C00180 -018001800300030006000E001C00380030000A157B8813>44 D<1C007F007F00FF80FF80FF807F -007F001C0009097B8813>46 D<000E00001E00007E0007FE00FFFE00FFFE00F8FE0000FE0000FE -0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE -0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE -0000FE007FFFFE7FFFFE7FFFFE17277BA622>49 D<00FF800007FFF0000FFFFC001E03FE003800 -FF807C003F80FE003FC0FF001FC0FF001FE0FF000FE0FF000FE07E000FE03C001FE000001FE000 -001FC000001FC000003F8000003F0000007E000000FC000000F8000001F0000003E00000078000 -000F0000001E0000003C00E0007000E000E000E001C001C0038001C0060001C00FFFFFC01FFFFF -C03FFFFFC07FFFFFC0FFFFFF80FFFFFF80FFFFFF801B277DA622>I<007F800003FFF00007FFFC -000F80FE001F007F003F807F003F803F803F803F803F803F801F803F801F003F8000007F000000 -7F0000007E000000FC000001F8000007F00000FFC00000FFC0000001F80000007E0000003F0000 -003F8000001FC000001FC000001FE000001FE03C001FE07E001FE0FF001FE0FF001FE0FF001FC0 -FF003FC0FE003F807C007F003F00FE001FFFFC0007FFF00000FF80001B277DA622>I<00000E00 -00001E0000003E0000007E000000FE000000FE000001FE000003FE0000077E00000E7E00000E7E -00001C7E0000387E0000707E0000E07E0000E07E0001C07E0003807E0007007E000E007E000E00 -7E001C007E0038007E0070007E00E0007E00FFFFFFF8FFFFFFF8FFFFFFF80000FE000000FE0000 -00FE000000FE000000FE000000FE000000FE000000FE00007FFFF8007FFFF8007FFFF81D277EA6 -22>I<180003001F801F001FFFFE001FFFFC001FFFF8001FFFF0001FFFC0001FFF00001C000000 -1C0000001C0000001C0000001C0000001C0000001C0000001C7FC0001DFFF8001F80FC001E003F -0008003F0000001F8000001FC000001FC000001FE000001FE018001FE07C001FE0FE001FE0FE00 -1FE0FE001FE0FE001FC0FC001FC078003F8078003F803C007F001F01FE000FFFFC0003FFF00000 -FF80001B277DA622>I<380000003E0000003FFFFFF03FFFFFF03FFFFFF07FFFFFE07FFFFFC07F -FFFF807FFFFF0070000E0070000E0070001C00E0003800E0007000E000E0000001E0000001C000 -000380000007800000070000000F0000001F0000001E0000003E0000003E0000007E0000007C00 -00007C000000FC000000FC000000FC000000FC000001FC000001FC000001FC000001FC000001FC -000001FC000001FC000000F80000007000001C297CA822>55 D<00000780000000000780000000 -000FC0000000000FC0000000000FC0000000001FE0000000001FE0000000003FF0000000003FF0 -000000003FF00000000077F80000000077F800000000F7FC00000000E3FC00000000E3FC000000 -01C1FE00000001C1FE00000003C1FF0000000380FF0000000380FF00000007007F80000007007F -8000000F007FC000000E003FC000000E003FC000001C001FE000001C001FE000003FFFFFF00000 -3FFFFFF000003FFFFFF00000700007F80000700007F80000F00007FC0000E00003FC0000E00003 -FC0001C00001FE0001C00001FE0003C00001FF00FFFE003FFFFCFFFE003FFFFCFFFE003FFFFC2E -297EA833>65 D<FFFFFFF800FFFFFFFF00FFFFFFFFC003F8001FE003F8000FF003F80007F803F8 -0003F803F80003FC03F80003FC03F80001FC03F80001FC03F80001FC03F80003FC03F80003F803 -F80003F803F80007F003F8000FF003F8001FC003F800FF8003FFFFFE0003FFFFFFC003F8000FF0 -03F80003F803F80001FC03F80001FE03F80000FE03F80000FE03F80000FF03F80000FF03F80000 -FF03F80000FF03F80000FF03F80000FF03F80000FE03F80001FE03F80003FC03F80007FC03F800 -1FF8FFFFFFFFE0FFFFFFFFC0FFFFFFFE0028297DA830>I<00007FE0030007FFFC07001FFFFF0F -007FF00F9F00FF0001FF01FC0000FF03F800007F07F000003F0FE000001F1FC000001F1FC00000 -0F3F8000000F3F800000077F800000077F800000077F00000000FF00000000FF00000000FF0000 -0000FF00000000FF00000000FF00000000FF00000000FF00000000FF000000007F000000007F80 -0000007F800000073F800000073F800000071FC00000071FC000000E0FE000000E07F000001C03 -F800003C01FC00007800FF0001F0007FF007C0001FFFFF800007FFFE0000007FF00028297CA831 ->I<FFFFFFFFE0FFFFFFFFE0FFFFFFFFE003FC001FE003FC0007F003FC0001F003FC0001F003FC -0000F003FC00007003FC00007003FC00007003FC01C07803FC01C03803FC01C03803FC01C03803 -FC03C00003FC03C00003FC0FC00003FFFFC00003FFFFC00003FFFFC00003FC0FC00003FC03C000 -03FC03C00003FC01C00E03FC01C00E03FC01C00E03FC01C01C03FC00001C03FC00001C03FC0000 -1C03FC00003C03FC00003803FC00007803FC0000F803FC0001F803FC0003F803FC001FF8FFFFFF -FFF0FFFFFFFFF0FFFFFFFFF027297EA82C>69 D<FFFFFFFFC0FFFFFFFFC0FFFFFFFFC003FC003F -C003FC000FE003FC0003E003FC0001E003FC0001E003FC0000E003FC0000E003FC0000E003FC00 -00F003FC01C07003FC01C07003FC01C07003FC01C00003FC03C00003FC03C00003FC0FC00003FF -FFC00003FFFFC00003FFFFC00003FC0FC00003FC03C00003FC03C00003FC01C00003FC01C00003 -FC01C00003FC01C00003FC00000003FC00000003FC00000003FC00000003FC00000003FC000000 -03FC00000003FC00000003FC000000FFFFFC0000FFFFFC0000FFFFFC000024297EA82A>I<0000 -7FE003000007FFFC0700001FFFFF0F00007FF00F9F0000FF0001FF0001FC0000FF0003F800007F -0007F000003F000FE000001F001FC000001F001FC000000F003F8000000F003F80000007007F80 -000007007F80000007007F0000000000FF0000000000FF0000000000FF0000000000FF00000000 -00FF0000000000FF0000000000FF0000000000FF0000000000FF0000FFFFF87F0000FFFFF87F80 -00FFFFF87F800000FF003F800000FF003F800000FF001FC00000FF001FC00000FF000FE00000FF -0007F00000FF0003F80000FF0001FC0000FF0000FF0001FF00007FF007FF00001FFFFF9F000007 -FFFE0F0000007FF003002D297CA835>I<FFFFF00FFFFFFFFFF00FFFFFFFFFF00FFFFF03FC0000 -3FC003FC00003FC003FC00003FC003FC00003FC003FC00003FC003FC00003FC003FC00003FC003 -FC00003FC003FC00003FC003FC00003FC003FC00003FC003FC00003FC003FC00003FC003FC0000 -3FC003FC00003FC003FFFFFFFFC003FFFFFFFFC003FFFFFFFFC003FC00003FC003FC00003FC003 -FC00003FC003FC00003FC003FC00003FC003FC00003FC003FC00003FC003FC00003FC003FC0000 -3FC003FC00003FC003FC00003FC003FC00003FC003FC00003FC003FC00003FC003FC00003FC003 -FC00003FC003FC00003FC0FFFFF00FFFFFFFFFF00FFFFFFFFFF00FFFFF30297EA835>I<FFFFFC -FFFFFCFFFFFC01FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE00 -01FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE00 -01FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE00FFFFFCFFFFFC -FFFFFC16297FA819>I<FFFE0000003FFF80FFFE0000003FFF80FFFF0000007FFF8003FF000000 -7FE00003FF0000007FE00003BF800000EFE00003BF800000EFE000039FC00001CFE000039FC000 -01CFE000038FE000038FE000038FE000038FE000038FE000038FE0000387F000070FE0000387F0 -00070FE0000383F8000E0FE0000383F8000E0FE0000381FC001C0FE0000381FC001C0FE0000381 -FC001C0FE0000380FE00380FE0000380FE00380FE00003807F00700FE00003807F00700FE00003 -803F80E00FE00003803F80E00FE00003803F80E00FE00003801FC1C00FE00003801FC1C00FE000 -03800FE3800FE00003800FE3800FE000038007F7000FE000038007F7000FE000038007F7000FE0 -00038003FE000FE000038003FE000FE000038001FC000FE000038001FC000FE000038000F8000F -E000FFFE00F803FFFF80FFFE00F803FFFF80FFFE007003FFFF8039297DA840>77 -D<FFFC00007FFFFFFE00007FFFFFFF00007FFF03FF800001C003FFC00001C003BFE00001C0039F -E00001C0039FF00001C0038FF80001C00387FC0001C00383FE0001C00381FF0001C00380FF8001 -C003807F8001C003807FC001C003803FE001C003801FF001C003800FF801C0038007FC01C00380 -03FC01C0038003FE01C0038001FF01C0038000FF81C00380007FC1C00380003FE1C00380001FF1 -C00380000FF1C00380000FF9C003800007FDC003800003FFC003800001FFC003800000FFC00380 -00007FC0038000007FC0038000003FC0038000001FC0038000000FC00380000007C0FFFE000003 -C0FFFE000001C0FFFE000001C030297EA835>I<FFFFFFF800FFFFFFFF00FFFFFFFFC003FC003F -E003FC0007F003FC0003F803FC0003FC03FC0001FC03FC0001FE03FC0001FE03FC0001FE03FC00 -01FE03FC0001FE03FC0001FE03FC0001FE03FC0001FC03FC0003FC03FC0003F803FC0007F003FC -003FE003FFFFFF8003FFFFFE0003FC00000003FC00000003FC00000003FC00000003FC00000003 -FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC000000 -03FC00000003FC00000003FC000000FFFFF00000FFFFF00000FFFFF0000027297EA82E>80 -D<FFFFFFE00000FFFFFFFE0000FFFFFFFF800003FC003FE00003FC000FF00003FC0007F80003FC -0003FC0003FC0001FC0003FC0001FE0003FC0001FE0003FC0001FE0003FC0001FE0003FC0001FE -0003FC0001FE0003FC0001FC0003FC0003F80003FC0007F80003FC000FE00003FC003FC00003FF -FFFE000003FFFFFE000003FC00FF800003FC003FC00003FC001FE00003FC000FF00003FC0007F8 -0003FC0007F80003FC0007F80003FC0007F80003FC0007F80003FC0007F80003FC0007F80003FC -0007F80003FC0007F80003FC0007F80E03FC0007F80E03FC0003F80E03FC0001FC1CFFFFF000FE -1CFFFFF0007FF8FFFFF0000FE02F297EA832>82 D<00FF00C003FFE1C00FFFF9C01F80FFC03F00 -3FC03E000FC07C0007C07C0007C0FC0003C0FC0003C0FC0001C0FE0001C0FE0001C0FF000000FF -C000007FFC00007FFFE0003FFFF8001FFFFE001FFFFF0007FFFF8003FFFFC000FFFFC0000FFFE0 -00007FE000001FF000000FF0000007F0E00003F0E00003F0E00003F0E00003F0F00003E0F00003 -E0F80007E0FC0007C0FF000F80FFE01F80E3FFFF00E1FFFC00C01FF0001C297CA825>I<FFFFF0 -00FFFEFFFFF000FFFEFFFFF000FFFE03FC0000038003FC0000038003FC0000038003FC00000380 -03FC0000038003FC0000038003FC0000038003FC0000038003FC0000038003FC0000038003FC00 -00038003FC0000038003FC0000038003FC0000038003FC0000038003FC0000038003FC00000380 -03FC0000038003FC0000038003FC0000038003FC0000038003FC0000038003FC0000038003FC00 -00038003FC0000038003FC0000038003FC0000038003FC0000038001FC0000070001FE00000700 -00FE00000E00007F00000E00003F00003C00001FC0007800000FF003F0000007FFFFE0000000FF -FF800000001FFC00002F297EA834>85 D<FFFFF0007FFFFFFFF0007FFFFFFFF0007FFF03FE0000 -01C001FE0000038001FE0000038000FF0000070000FF0000070000FF80000F00007F80000E0000 -7FC0000E00003FC0001C00003FE0001C00001FE0003800001FE0003800001FF0007800000FF000 -7000000FF800F0000007F800E0000007FC00E0000003FC01C0000003FC01C0000003FE03C00000 -01FE0380000001FF0780000000FF0700000000FF87000000007F8E000000007F8E000000007FDE -000000003FDC000000003FFC000000001FF8000000001FF8000000000FF0000000000FF0000000 -000FF00000000007E00000000007E00000000003C00000000003C0000030297FA833>I<FFFFE0 -FFFFE01FFFC0FFFFE0FFFFE01FFFC0FFFFE0FFFFE01FFFC003FC0003FC0000700003FC0003FC00 -00700003FE0003FE0000F00001FE0001FE0000E00001FE0001FE0000E00001FF0001FF0001E000 -00FF0001FF0001C00000FF0001FF0001C000007F8003FF80038000007F8003FF80038000007FC0 -07FFC0078000003FC0073FC0070000003FC0073FC0070000003FE00F3FE00F0000001FE00E1FE0 -0E0000001FE00E1FE00E0000000FF01C0FF01C0000000FF01C0FF01C0000000FF01C0FF81C0000 -0007F83807F83800000007F83807F83800000007FC7807FC7800000003FC7003FC7000000003FC -7003FC7000000003FEF003FEF000000001FEE001FEE000000001FEE001FEE000000000FFC000FF -C000000000FFC000FFC000000000FFC000FFC0000000007F80007F80000000007F80007F800000 -00007F80007F80000000003F00003F00000000003F00003F00000000003F00003F00000000001E -00001E00000000001E00001E00000042297FA845>I<03FF80000FFFF0001F01FC003F80FE003F -807F003F803F003F803F801F003F8000003F8000003F8000003F8000003F80003FFF8001FC3F80 -0FE03F801F803F803F003F807E003F80FC003F80FC003F80FC003F80FC003F80FC005F807E00DF -803F839FFC1FFE0FFC03F803FC1E1B7E9A21>97 D<FFE00000FFE00000FFE000000FE000000FE0 -00000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000F -E000000FE1FE000FE7FF800FFE07E00FF803F00FF001F80FE000FC0FE000FC0FE0007E0FE0007E -0FE0007F0FE0007F0FE0007F0FE0007F0FE0007F0FE0007F0FE0007F0FE0007F0FE0007E0FE000 -7E0FE0007E0FE000FC0FE000FC0FF001F80FF803F00F9C0FE00F0FFF800E01FC00202A7EA925> -I<003FF00001FFFC0003F03E000FC07F001F807F003F007F003F007F007F003E007E0000007E00 -0000FE000000FE000000FE000000FE000000FE000000FE000000FE0000007E0000007E0000007F -0000003F0003803F8003801F8007000FE00E0003F83C0001FFF800003FC000191B7E9A1E>I<00 -007FF000007FF000007FF0000007F0000007F0000007F0000007F0000007F0000007F0000007F0 -000007F0000007F0000007F0000007F0000007F0003F87F001FFF7F007F03FF00FC00FF01F8007 -F03F0007F03F0007F07E0007F07E0007F07E0007F0FE0007F0FE0007F0FE0007F0FE0007F0FE00 -07F0FE0007F0FE0007F0FE0007F07E0007F07E0007F03F0007F03F0007F01F800FF00FC01FF007 -E07FFF01FFE7FF007F87FF202A7EA925>I<003FC00001FFF00003E07C000F803E001F801F001F -001F003F000F807E000F807E000FC07E000FC0FE0007C0FE0007C0FFFFFFC0FFFFFFC0FE000000 -FE000000FE0000007E0000007E0000007F0000003F0001C01F0001C00F80038007C0070003F01E -0000FFFC00003FE0001A1B7E9A1F>I<0007F8003FFC007E3E01FC7F03F87F03F07F07F07F07F0 -3E07F00007F00007F00007F00007F00007F00007F000FFFFC0FFFFC0FFFFC007F00007F00007F0 -0007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F0 -0007F00007F00007F00007F00007F0007FFF807FFF807FFF80182A7EA915>I<007F80F001FFE3 -F807C0FE1C0F807C7C1F003E7C1F003E103F003F003F003F003F003F003F003F003F003F003F00 -3F001F003E001F003E000F807C0007C0F80005FFE0000C7F8000180000001C0000001C0000001E -0000001FFFF8001FFFFF000FFFFFC007FFFFE003FFFFF00FFFFFF03E0007F07C0001F8F80000F8 -F80000F8F80000F8F80000F87C0001F07C0001F03F0007E00FC01F8007FFFF00007FF0001E287E -9A22>I<FFE00000FFE00000FFE000000FE000000FE000000FE000000FE000000FE000000FE000 -000FE000000FE000000FE000000FE000000FE000000FE000000FE07E000FE1FF800FE30FC00FE4 -0FE00FE807E00FF807F00FF007F00FF007F00FE007F00FE007F00FE007F00FE007F00FE007F00F -E007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F0 -0FE007F0FFFE3FFFFFFE3FFFFFFE3FFF202A7DA925>I<07000F801FC03FE03FE03FE01FC00F80 -07000000000000000000000000000000FFE0FFE0FFE00FE00FE00FE00FE00FE00FE00FE00FE00F -E00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE0FFFEFFFEFFFE0F2B7EAA12>I<FF -E0FFE0FFE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE0 -0FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE0FF -FEFFFEFFFE0F2A7EA912>108 D<FFC07F001FC000FFC1FFC07FF000FFC307E0C1F8000FC407F1 -01FC000FC803F200FC000FD803FE00FE000FD003FC00FE000FD003FC00FE000FE003F800FE000F -E003F800FE000FE003F800FE000FE003F800FE000FE003F800FE000FE003F800FE000FE003F800 -FE000FE003F800FE000FE003F800FE000FE003F800FE000FE003F800FE000FE003F800FE000FE0 -03F800FE000FE003F800FE000FE003F800FE000FE003F800FE00FFFE3FFF8FFFE0FFFE3FFF8FFF -E0FFFE3FFF8FFFE0331B7D9A38>I<FFC07E00FFC1FF80FFC30FC00FC40FE00FC807E00FD807F0 -0FD007F00FD007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007 -F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F0FFFE3FFFFFFE -3FFFFFFE3FFF201B7D9A25>I<003FE00001FFFC0003F07E000FC01F801F800FC03F0007E03F00 -07E07E0003F07E0003F07E0003F0FE0003F8FE0003F8FE0003F8FE0003F8FE0003F8FE0003F8FE -0003F8FE0003F87E0003F07E0003F03F0007E03F0007E01F800FC00FC01F8007F07F0001FFFC00 -003FE0001D1B7E9A22>I<FFE1FE00FFE7FF80FFFE0FE00FF803F00FF001F80FE001FC0FE000FC -0FE000FE0FE000FE0FE0007F0FE0007F0FE0007F0FE0007F0FE0007F0FE0007F0FE0007F0FE000 -7F0FE0007E0FE000FE0FE000FE0FE000FC0FE001FC0FF001F80FF803F00FFC0FE00FEFFF800FE1 -FC000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE00000FF -FE0000FFFE0000FFFE000020277E9A25>I<FFC3E0FFC7F8FFCC7C0FD8FE0FD0FE0FD0FE0FF0FE -0FE07C0FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE000 -0FE0000FE0000FE0000FE000FFFF00FFFF00FFFF00171B7E9A1B>114 D<03FE300FFFF03E03F0 -7800F07000F0F00070F00070F80070FE0000FFE0007FFF007FFFC03FFFE01FFFF007FFF800FFF8 -0007FC0000FCE0007CE0003CF0003CF00038F80038FC0070FF01E0E7FFC0C1FF00161B7E9A1B> -I<00700000700000700000700000F00000F00000F00001F00003F00003F00007F0001FFFE0FFFF -E0FFFFE007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F0 -0007F00007F07007F07007F07007F07007F07007F07007F07003F0E001F8C000FFC0003F001426 -7FA51A>I<FFE07FF0FFE07FF0FFE07FF00FE007F00FE007F00FE007F00FE007F00FE007F00FE0 -07F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00F -E007F00FE007F00FE007F00FE00FF00FE00FF007E017F003F067FF01FFC7FF007F87FF201B7D9A -25>I<FFFE07FFFFFE07FFFFFE07FF07F000E007F000E007F801E003F801C003F801C001FC0380 -01FC038001FE078000FE070000FF0F00007F0E00007F0E00003F9C00003F9C00003FFC00001FF8 -00001FF800000FF000000FF000000FF0000007E0000007E0000003C0000003C000201B7F9A23> -I<FFFC7FFC1FFCFFFC7FFC1FFCFFFC7FFC1FFC0FE00FE001C007F007E0038007F007E0038007F8 -07F0078003F807F0070003F807F8070001FC0FF80E0001FC0FF80E0001FE1FFC1E0000FE1CFC1C -0000FE1CFE1C0000FF387E3C00007F387E3800007F787F3800003FF03F7000003FF03F7000003F -E01FF000001FE01FE000001FE01FE000000FC00FC000000FC00FC000000FC00FC0000007800780 -000007800780002E1B7F9A31>I<FFFC1FFEFFFC1FFEFFFC1FFE07F0078003F8070001FC0F0001 -FE1E0000FE3C00007F7800003FF800003FF000001FE000000FE0000007F0000007F800000FF800 -001FFC00003DFE000038FF0000787F0000F03F8001E03FC003C01FE003800FE0FFF03FFFFFF03F -FFFFF03FFF201B7F9A23>I<FFFE07FFFFFE07FFFFFE07FF07F000E007F000E007F801E003F801 -C003F801C001FC038001FC038001FE078000FE070000FF0F00007F0E00007F0E00003F9C00003F -9C00003FFC00001FF800001FF800000FF000000FF0000007F0000007E0000007E0000003C00000 -03C000000380000003800000078000380700007C070000FE0E0000FE0E0000FE1C0000FE380000 -7C7000003FE000000F80000020277F9A23>I E /Fn 75 127 df<70F8F8F8F8F8F8F8F8F8F8F8 -F8F8F8F8F870000000000070F8F8F870051C779B18>33 D<4010E038F078E038E038E038E038E0 -38E038E038E038E038E03860300D0E7B9C18>I<030600078F00078F00078F00078F00078F0007 -8F007FFFC0FFFFE0FFFFE07FFFC00F1E000F1E000F1E000F1E000F1E000F1E007FFFC0FFFFE0FF -FFE07FFFC01E3C001E3C001E3C001E3C001E3C001E3C000C1800131C7E9B18>I<00C00001C000 -01C00001C00003F0000FFC003FFE007DCF0071C700E1C380E1C780E1C780E1C780F1C00079C000 -3DC0001FE0000FF80003FC0001DE0001CF0001C70061C380F1C380F1C380E1C380E1C70071C700 -79DE003FFE001FF80007E00001C00001C00001C00000C00011247D9F18>I<3803007C07807C07 -80EE0F80EE0F00EE0F00EE1F00EE1E00EE1E00EE3E007C3C007C3C00387C0000780000780000F8 -0000F00001F00001E00001E00003E00003C00003C00007C0000783800787C00F87C00F0EE00F0E -E01F0EE01E0EE01E0EE03E0EE03C07C03C07C018038013247E9F18>I<01C00007E0000FF0000E -70001C38001C38001C38001C38001C73F01C73F01CE3F00FE3800FC7000F87000F07001F0E003F -0E007B8E0073DC00E1DC00E0F800E0F800E07070E0787070FC707FFFE03FCFE00F03C0141C7F9B -18>I<387C7C7E3E0E0E0E1C1C38F8F0C0070E789B18>I<007000F001E003C007800F001E001C00 -380038007000700070007000E000E000E000E000E000E000E000E0007000700070007000380038 -001C001E000F00078003C001F000F000700C24799F18>I<6000F00078003C001E000F00078003 -8001C001C000E000E000E000E00070007000700070007000700070007000E000E000E000E001C0 -01C0038007800F001E003C007800F00060000C247C9F18>I<01C00001C00001C00001C000C1C1 -80F1C780F9CF807FFF001FFC0007F00007F0001FFC007FFF00F9CF80F1C780C1C18001C00001C0 -0001C00001C00011147D9718>I<00600000F00000F00000F00000F00000F00000F00000F0007F -FFC0FFFFE0FFFFE07FFFC000F00000F00000F00000F00000F00000F00000F00000600013147E97 -18>I<1C3E7E7F3F1F070E1E7CF860080C788518>I<7FFF00FFFF80FFFF807FFF0011047D8F18> -I<3078FCFC78300606778518>I<000300000780000780000F80000F00001F00001E00001E0000 -3E00003C00007C0000780000780000F80000F00001F00001E00003E00003C00003C00007C00007 -80000F80000F00000F00001F00001E00003E00003C00003C00007C0000780000F80000F00000F0 -000060000011247D9F18>I<01F00007FC000FFE001F1F001C07003803807803C07001C07001C0 -E000E0E000E0E000E0E000E0E000E0E000E0E000E0E000E0E000E0F001E07001C07001C07803C0 -3803801C07001F1F000FFE0007FC0001F000131C7E9B18>I<01800380038007800F803F80FF80 -FB80438003800380038003800380038003800380038003800380038003800380038003807FFCFF -FE7FFC0F1C7B9B18>I<03F0000FFE003FFF007C0F807003C0E001C0F000E0F000E06000E00000 -E00000E00001C00001C00003C0000780000F00001E00003C0000780000F00001E00007C0000F80 -001E00E03C00E07FFFE0FFFFE07FFFE0131C7E9B18>I<001F00003F0000770000770000E70001 -E70001C7000387000787000707000E07001E07003C0700380700780700F00700FFFFF8FFFFF8FF -FFF8000700000700000700000700000700000700007FF000FFF8007FF0151C7F9B18>52 -D<007E0001FF0007FF800F83C01E03C01C03C0380180380000700000700000E1F800E7FE00FFFF -00FE0780F803C0F001C0F000E0E000E0F000E07000E07000E07000E03801C03C03C01E07800FFF -0007FE0001F800131C7E9B18>54 D<3078FCFC783000000000000000003078FCFC783006147793 -18>58 D<183C7E7E3C180000000000000000183C7E7E3E1E0E1C3C78F060071A789318>I<0003 -00000780001F80003F00007E0001FC0003F00007E0001FC0003F00007E0000FC0000FC00007E00 -003F00001FC00007E00003F00001FC00007E00003F00001F8000078000030011187D9918>I<7F -FFC0FFFFE0FFFFE0FFFFE0000000000000000000000000FFFFE0FFFFE0FFFFE07FFFC0130C7E93 -18>I<600000F00000FC00007E00003F00001FC00007E00003F00001FC00007E00003F00001F80 -001F80003F00007E0001FC0003F00007E0001FC0003F00007E0000FC0000F0000060000011187D -9918>I<0FF0003FFC007FFF00700F00F00380F00380600780000F00003E00007C0001F00001E0 -0003C00003C00003C00003C00003C00003800000000000000000000000000000000003800007C0 -0007C00007C000038000111C7D9B18>I<00700000F80000F80000D80000D80001DC0001DC0001 -DC00018C00038E00038E00038E00038E000306000707000707000707000707000FFF800FFF800F -FF800E03800E03801C01C01C01C07F07F0FF8FF87F07F0151C7F9B18>65 -D<7FF800FFFE007FFF001C0F801C03C01C03C01C01E01C00E01C00E01C00F01C00701C00701C00 -701C00701C00701C00701C00701C00701C00F01C00E01C00E01C01E01C01C01C03C01C0F807FFF -00FFFE007FF800141C7F9B18>68 D<FFFFF0FFFFF0FFFFF01C00701C00701C00701C00701C0000 -1C00001C0E001C0E001C0E001FFE001FFE001FFE001C0E001C0E001C0E001C00001C00001C0038 -1C00381C00381C00381C0038FFFFF8FFFFF8FFFFF8151C7F9B18>I<FFFFE0FFFFE0FFFFE01C00 -E01C00E01C00E01C00E01C00001C00001C1C001C1C001C1C001FFC001FFC001FFC001C1C001C1C -001C1C001C00001C00001C00001C00001C00001C00001C0000FFC000FFC000FFC000131C7E9B18 ->I<7F07F0FF8FF87F07F01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01F -FFC01FFFC01FFFC01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C07F -07F0FF8FF87F07F0151C7F9B18>72 D<7FFF00FFFF807FFF0001C00001C00001C00001C00001C0 -0001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C0 -0001C00001C00001C00001C0007FFF00FFFF807FFF00111C7D9B18>I<7FE000FFE0007FE0000E -00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E -00000E00000E00000E00000E00700E00700E00700E00700E00707FFFF0FFFFF07FFFF0141C7F9B -18>76 D<7E07F0FF0FF87F07F01D81C01D81C01D81C01DC1C01CC1C01CC1C01CE1C01CE1C01CE1 -C01C61C01C71C01C71C01C31C01C39C01C39C01C39C01C19C01C19C01C1DC01C0DC01C0DC01C0D -C07F07C0FF87C07F03C0151C7F9B18>78 D<0FF8003FFE007FFF00780F00700700F00780E00380 -E00380E00380E00380E00380E00380E00380E00380E00380E00380E00380E00380E00380E00380 -E00380E00380F00780700700780F007FFF003FFE000FF800111C7D9B18>I<FFFE00FFFF80FFFF -C01C03C01C01E01C00E01C00701C00701C00701C00701C00701C00E01C01E01C03C01FFFC01FFF -801FFE001C00001C00001C00001C00001C00001C00001C00001C0000FF8000FF8000FF8000141C -7F9B18>I<7FF800FFFE007FFF001C0F801C03801C03C01C01C01C01C01C01C01C03C01C03801C -0F801FFF001FFE001FFE001C0F001C07001C03801C03801C03801C03801C03801C039C1C039C1C -039C7F01F8FF81F87F00F0161C7F9B18>82 D<03F3801FFF803FFF807C0F80700780E00380E003 -80E00380E000007000007800003F00001FF00007FE0000FF00000F800003C00001C00000E00000 -E06000E0E000E0E001E0F001C0F80780FFFF80FFFE00E7F800131C7E9B18>I<7FFFF8FFFFF8FF -FFF8E07038E07038E07038E0703800700000700000700000700000700000700000700000700000 -700000700000700000700000700000700000700000700000700000700007FF0007FF0007FF0015 -1C7F9B18>I<FF83FEFF83FEFF83FE1C00701C00701C00701C00701C00701C00701C00701C0070 -1C00701C00701C00701C00701C00701C00701C00701C00701C00701C00701C00700E00E00F01E0 -0783C003FF8001FF00007C00171C809B18>I<FF07F8FF07F8FF07F81C01C01E03C00E03800F07 -80070700070700038E00038E0001DC0001DC0001DC0000F80000F8000070000070000070000070 -0000700000700000700000700000700001FC0003FE0001FC00151C7F9B18>89 -D<FFF8FFF8FFF8E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000 -E000E000E000E000E000E000E000E000E000E000E000E000E000E000FFF8FFF8FFF80D24779F18 ->91 D<600000F00000F00000F800007800007C00003C00003C00003E00001E00001F00000F0000 -0F00000F800007800007C00003C00003C00003E00001E00001F00000F00000F800007800007800 -007C00003C00003E00001E00001E00001F00000F00000F8000078000078000030011247D9F18> -I<FFF8FFF8FFF80038003800380038003800380038003800380038003800380038003800380038 -00380038003800380038003800380038003800380038003800380038FFF8FFF8FFF80D247F9F18 ->I<018007C01FF07EFCF83EE00E0F067C9B18>I<7FFF00FFFF80FFFF807FFF0011047D7F18>I< -061E3E387070E0E0E0F8FC7C7C38070E789E18>I<1FE0003FF8007FFC00781E00300E00000700 -00070000FF0007FF001FFF007F0700780700E00700E00700E00700F00F00781F003FFFF01FFBF0 -07E1F014147D9318>I<7E0000FE00007E00000E00000E00000E00000E00000E00000E3E000EFF -800FFFC00FC1E00F80E00F00700E00700E00380E00380E00380E00380E00380E00380F00700F00 -700F80E00FC1E00FFFC00EFF80063E00151C809B18>I<01FE0007FF001FFF803E078038030070 -0000700000E00000E00000E00000E00000E00000E000007000007001C03801C03E03C01FFF8007 -FF0001FC0012147D9318>I<001F80003F80001F8000038000038000038000038000038003E380 -0FFB801FFF803C1F80380F80700780700380E00380E00380E00380E00380E00380E00380700780 -700780380F803C1F801FFFF00FFBF803E3F0151C7E9B18>I<01F00007FC001FFE003E0F003807 -80700380700380E001C0E001C0FFFFC0FFFFC0FFFFC0E000007000007001C03801C03E03C01FFF -8007FF0001FC0012147D9318>I<001F80007FC000FFE000E1E001C0C001C00001C00001C0007F -FFC0FFFFC0FFFFC001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001 -C00001C00001C00001C0007FFF007FFF007FFF00131C7F9B18>I<01E1F007FFF80FFFF81E1E30 -1C0E003807003807003807003807003807001C0E001E1E001FFC001FF80039E0003800001C0000 -1FFE001FFFC03FFFE07801F0700070E00038E00038E00038E000387800F07E03F01FFFC00FFF80 -01FC00151F7F9318>I<7E0000FE00007E00000E00000E00000E00000E00000E00000E3E000EFF -800FFFC00FC1C00F80E00F00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00 -E00E00E00E00E07FC3FCFFE7FE7FC3FC171C809B18>I<03800007C00007C00007C00003800000 -00000000000000000000007FC000FFC0007FC00001C00001C00001C00001C00001C00001C00001 -C00001C00001C00001C00001C00001C00001C00001C000FFFF00FFFF80FFFF00111D7C9C18>I< -7FE000FFE0007FE00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E000 -00E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E0007FFFC0 -FFFFE07FFFC0131C7E9B18>108 D<7CE0E000FFFBF8007FFFF8001F1F1C001E1E1C001E1E1C00 -1C1C1C001C1C1C001C1C1C001C1C1C001C1C1C001C1C1C001C1C1C001C1C1C001C1C1C001C1C1C -001C1C1C007F1F1F00FFBFBF807F1F1F001914819318>I<7E3E00FEFF807FFFC00FC1C00F80E0 -0F00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E07FC3FC -FFE7FE7FC3FC1714809318>I<01F0000FFE001FFF003E0F803803807001C07001C0E000E0E000 -E0E000E0E000E0E000E0F001E07001C07803C03C07803E0F801FFF000FFE0001F00013147E9318 ->I<7E3E00FEFF807FFFC00FC1E00F80E00F00700E00700E00380E00380E00380E00380E00380E -00380F00700F00700F80E00FC1E00FFFC00EFF800E3E000E00000E00000E00000E00000E00000E -00000E00007FC000FFE0007FC000151E809318>I<01E38007FB801FFF803E1F80380F80700780 -700780E00380E00380E00380E00380E00380E00380700780700780380F803C1F801FFF800FFB80 -03E380000380000380000380000380000380000380000380003FF8003FF8003FF8151E7E9318> -I<7F87E0FF9FF07FBFF803F87803F03003E00003C00003C0000380000380000380000380000380 -000380000380000380000380007FFE00FFFF007FFE0015147F9318>I<07F7003FFF007FFF0078 -0F00E00700E00700E007007C00007FE0001FFC0003FE00001F00600780E00380E00380F00380F8 -0F00FFFF00FFFC00E7F00011147D9318>I<0180000380000380000380000380007FFFC0FFFFC0 -FFFFC00380000380000380000380000380000380000380000380000380000380400380E00380E0 -0380E001C1C001FFC000FF80003E0013197F9818>I<7E07E0FE0FE07E07E00E00E00E00E00E00 -E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E01E00F03E007FFFC03FF -FE01FCFC1714809318>I<7F8FF0FF8FF87F8FF01E03C00E03800E03800E038007070007070007 -0700038E00038E00038E00038E0001DC0001DC0001DC0000F80000F80000700015147F9318>I< -FF8FF8FF8FF8FF8FF83800E03800E03800E01C01C01C01C01C71C01CF9C01CF9C01CD9C01CD9C0 -0DDD800DDD800DDD800D8D800F8F800F8F8007070015147F9318>I<7F8FF07F9FF07F8FF00707 -00078E00039E0001DC0001F80000F80000700000F00000F80001DC00039E00038E000707000F07 -807F8FF0FF8FF87F8FF015147F9318>I<7F8FF0FF8FF87F8FF00E01C00E03800E038007038007 -0700070700038700038600038E0001CE0001CE0000CC0000CC0000DC0000780000780000780000 -700000700000700000F00000E00079E0007BC0007F80003F00001E0000151E7F9318>I<3FFFF0 -7FFFF07FFFF07001E07003C0700780000F00001E00003C0000F80001F00003C0000780000F0070 -1E00703C0070780070FFFFF0FFFFF0FFFFF014147F9318>I<0007E0001FE0007FE000780000E0 -0000E00000E00000E00000E00000E00000E00000E00000E00000E00000E00001E0007FC000FF80 -00FF80007FC00001E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E0 -0000E000007800007FE0001FE00007E013247E9F18>I<60F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 -F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0600424769F18>I<7C0000FF0000FFC00003C000 -00E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000F000007FC0 -003FE0003FE0007FC000F00000E00000E00000E00000E00000E00000E00000E00000E00000E000 -00E00000E00003C000FFC000FF00007C000013247E9F18>I<060C1F1E3FBEFBF8F1F060C00F06 -7C9B18>I E /Fo 75 123 df<001F83E000F06E3001C078780380F8780300F030070070000700 -70000700700007007000070070000700700007007000FFFFFF8007007000070070000700700007 -007000070070000700700007007000070070000700700007007000070070000700700007007000 -07007000070070000700700007007000070070007FE3FF001D20809F1B>11 -D<003F0000E0C001C0C00381E00701E00701E0070000070000070000070000070000070000FFFF -E00700E00700E00700E00700E00700E00700E00700E00700E00700E00700E00700E00700E00700 -E00700E00700E00700E00700E00700E07FC3FE1720809F19>I<003FE000E0E001C1E00381E007 -00E00700E00700E00700E00700E00700E00700E00700E0FFFFE00700E00700E00700E00700E007 -00E00700E00700E00700E00700E00700E00700E00700E00700E00700E00700E00700E00700E007 -00E07FE7FE1720809F19>I<001F81F80000F04F040001C07C06000380F80F000300F00F000700 -F00F00070070000007007000000700700000070070000007007000000700700000FFFFFFFF0007 -007007000700700700070070070007007007000700700700070070070007007007000700700700 -070070070007007007000700700700070070070007007007000700700700070070070007007007 -00070070070007007007007FE3FE3FF02420809F26>I<7038F87CFC7EFC7E743A040204020402 -0804080410081008201040200F0E7E9F17>34 D<70F8FCFC74040404080810102040060E7C9F0D ->39 D<0020004000800100020006000C000C00180018003000300030007000600060006000E000 -E000E000E000E000E000E000E000E000E000E000E0006000600060007000300030003000180018 -000C000C000600020001000080004000200B2E7DA112>I<800040002000100008000C00060006 -000300030001800180018001C000C000C000C000E000E000E000E000E000E000E000E000E000E0 -00E000E000C000C000C001C001800180018003000300060006000C00080010002000400080000B -2E7DA112>I<70F8FCFC74040404080810102040060E7C840D>44 D<FFC0FFC00A027F8A0F>I<70 -F8F8F87005057C840D>I<03F0000E1C001C0E00180600380700700380700380700380700380F0 -03C0F003C0F003C0F003C0F003C0F003C0F003C0F003C0F003C0F003C0F003C0F003C0F003C070 -03807003807003807807803807001806001C0E000E1C0003F000121F7E9D17>48 -D<018003800F80F380038003800380038003800380038003800380038003800380038003800380 -03800380038003800380038003800380038007C0FFFE0F1E7C9D17>I<03F0000C1C00100E0020 -0700400780800780F007C0F803C0F803C0F803C02007C00007C0000780000780000F00000E0000 -1C0000380000700000600000C0000180000300000600400C00401800401000803FFF807FFF80FF -FF80121E7E9D17>I<03F0000C1C00100E00200F00780F80780780780780380F80000F80000F00 -000F00000E00001C0000380003F000003C00000E00000F000007800007800007C02007C0F807C0 -F807C0F807C0F00780400780400F00200E001C3C0003F000121F7E9D17>I<000600000600000E -00000E00001E00002E00002E00004E00008E00008E00010E00020E00020E00040E00080E00080E -00100E00200E00200E00400E00C00E00FFFFF0000E00000E00000E00000E00000E00000E00000E -0000FFE0141E7F9D17>I<1803001FFE001FFC001FF8001FE00010000010000010000010000010 -000010000011F000161C00180E001007001007800003800003800003C00003C00003C07003C0F0 -03C0F003C0E00380400380400700200600100E000C380003E000121F7E9D17>I<007C00018200 -0701000E03800C07801C0780380300380000780000700000700000F1F000F21C00F40600F80700 -F80380F80380F003C0F003C0F003C0F003C0F003C07003C07003C0700380380380380700180700 -0C0E00061C0001F000121F7E9D17>I<4000007FFFC07FFF807FFF804001008002008002008004 -0000080000080000100000200000200000400000400000C00000C00001C0000180000380000380 -00038000038000078000078000078000078000078000078000078000030000121F7D9D17>I<03 -F0000C0C001006003003002001806001806001806001807001807803003E03003F06001FC8000F -F00003F80007FC000C7E00103F00300F806003804001C0C001C0C000C0C000C0C000C0C0008060 -01802001001002000C0C0003F000121F7E9D17>I<03F0000E18001C0C00380600380700700700 -700380F00380F00380F003C0F003C0F003C0F003C0F003C07007C07007C03807C0180BC00E13C0 -03E3C0000380000380000380000700300700780600780E00700C002018001070000FC000121F7E -9D17>I<70F8F8F8700000000000000000000070F8F8F87005147C930D>I<70F8F8F87000000000 -00000000000070F0F8F878080808101010202040051D7C930D>I<000100000003800000038000 -000380000007C0000007C0000007C0000009E0000009E0000009E0000010F0000010F0000010F0 -0000207800002078000020780000403C0000403C0000403C0000801E0000801E0000FFFE000100 -0F0001000F0001000F00020007800200078002000780040003C00E0003C01F0007E0FFC03FFE1F -207F9F22>65 D<FFFFE0000F80380007801E0007801F0007800F0007800F8007800F8007800F80 -07800F8007800F8007800F0007801F0007801E0007803C0007FFF00007803C0007801E0007800F -0007800F8007800780078007C0078007C0078007C0078007C0078007C00780078007800F800780 -0F0007801F000F803C00FFFFF0001A1F7E9E20>I<000FC040007030C001C009C0038005C00700 -03C00E0001C01E0000C01C0000C03C0000C07C0000407C00004078000040F8000000F8000000F8 -000000F8000000F8000000F8000000F8000000F8000000F8000000780000007C0000407C000040 -3C0000401C0000401E0000800E000080070001000380020001C0040000703800000FC0001A217D -9F21>I<FFFFE0000F803C0007801E000780070007800380078003C0078001E0078001E0078001 -F0078000F0078000F0078000F8078000F8078000F8078000F8078000F8078000F8078000F80780 -00F8078000F8078000F0078000F0078000F0078001E0078001E0078003C0078003800780070007 -800E000F803C00FFFFE0001D1F7E9E23>I<FFFFFF000F800F0007800300078003000780010007 -800180078000800780008007800080078080800780800007808000078080000781800007FF8000 -078180000780800007808000078080000780800007800020078000200780002007800040078000 -4007800040078000C0078000C0078001800F800F80FFFFFF801B1F7E9E1F>I<FFFFFF000F800F -000780030007800300078001000780018007800080078000800780008007800080078080000780 -800007808000078080000781800007FF8000078180000780800007808000078080000780800007 -800000078000000780000007800000078000000780000007800000078000000FC00000FFFE0000 -191F7E9E1E>I<000FE0200078186000E004E0038002E0070001E00F0000E01E0000601E000060 -3C0000603C0000207C00002078000020F8000000F8000000F8000000F8000000F8000000F80000 -00F8000000F8007FFCF80003E0780001E07C0001E03C0001E03C0001E01E0001E01E0001E00F00 -01E0070001E0038002E000E0046000781820000FE0001E217D9F24>I<FFF8FFF80F800F800780 -0F0007800F0007800F0007800F0007800F0007800F0007800F0007800F0007800F0007800F0007 -800F0007800F0007FFFF0007800F0007800F0007800F0007800F0007800F0007800F0007800F00 -07800F0007800F0007800F0007800F0007800F0007800F0007800F000F800F80FFF8FFF81D1F7E -9E22>I<FFFC0FC007800780078007800780078007800780078007800780078007800780078007 -80078007800780078007800780078007800780078007800FC0FFFC0E1F7F9E10>I<0FFFC0007C -00003C00003C00003C00003C00003C00003C00003C00003C00003C00003C00003C00003C00003C -00003C00003C00003C00003C00003C00003C00003C00003C00203C00F83C00F83C00F83C00F038 -0040780040700030E0000F800012207E9E17>I<FFFE000FC00007800007800007800007800007 -800007800007800007800007800007800007800007800007800007800007800007800007800007 -800007800207800207800207800207800607800407800407800C07801C0F807CFFFFFC171F7E9E -1C>76 D<FF80001FF80F80001F800780001F0005C0002F0005C0002F0005C0002F0004E0004F00 -04E0004F000470008F000470008F000470008F000438010F000438010F000438010F00041C020F -00041C020F00041C020F00040E040F00040E040F00040E040F000407080F000407080F00040708 -0F000403900F000403900F000401E00F000401E00F000401E00F000E00C00F001F00C01F80FFE0 -C1FFF8251F7E9E2A>I<FF803FF807C007C007C0038005E0010005E0010004F001000478010004 -780100043C0100043C0100041E0100040F0100040F010004078100040781000403C1000401E100 -0401E1000400F1000400F1000400790004003D0004003D0004001F0004001F0004000F00040007 -00040007000E0003001F000300FFE001001D1F7E9E22>I<001F800000F0F00001C0380007801E -000F000F000E0007001E0007803C0003C03C0003C07C0003E0780001E0780001E0F80001F0F800 -01F0F80001F0F80001F0F80001F0F80001F0F80001F0F80001F0F80001F0780001E07C0003E07C -0003E03C0003C03C0003C01E0007800E0007000F000F0007801E0001C0380000F0F000001F8000 -1C217D9F23>I<FFFFE0000F80780007801C0007801E0007800F0007800F8007800F8007800F80 -07800F8007800F8007800F8007800F0007801E0007801C000780780007FFE00007800000078000 -000780000007800000078000000780000007800000078000000780000007800000078000000780 -0000078000000FC00000FFFC0000191F7E9E1F>I<001F800000F0F00001C0380007801E000F00 -0F000E0007001E0007803C0003C03C0003C07C0003E07C0003E0780001E0F80001F0F80001F0F8 -0001F0F80001F0F80001F0F80001F0F80001F0F80001F0F80001F0780001E0780001E07C0003E0 -3C0003C03C0F03C01E1087800E2047000F204F0007A03E0001E0380000F0F010001FB010000030 -10000038300000387000003FF000001FE000001FE000000FC0000007801C297D9F23>I<FFFF80 -000F80F0000780780007803C0007801E0007801E0007801F0007801F0007801F0007801F000780 -1E0007801E0007803C00078078000780F00007FF80000781C0000780E0000780F0000780700007 -807800078078000780780007807C0007807C0007807C0007807C0407807E0407803E040FC01E08 -FFFC0F10000003E01E207E9E21>I<07E0800C1980100780300380600180600180E00180E00080 -E00080E00080F00000F000007800007F00003FF0001FFC000FFE0003FF00001F800007800003C0 -0003C00001C08001C08001C08001C08001C0C00180C00380E00300F00600CE0C0081F80012217D -9F19>I<7FFFFFE0780F01E0600F0060400F0020400F0020C00F0030800F0010800F0010800F00 -10800F0010000F0000000F0000000F0000000F0000000F0000000F0000000F0000000F0000000F -0000000F0000000F0000000F0000000F0000000F0000000F0000000F0000000F0000000F000000 -0F0000001F800007FFFE001C1F7E9E21>I<FFFC3FF80FC007C007800380078001000780010007 -800100078001000780010007800100078001000780010007800100078001000780010007800100 -078001000780010007800100078001000780010007800100078001000780010007800100038002 -000380020001C0020001C0040000E008000070180000382000000FC0001D207E9E22>I<FFF003 -FE1F8000F80F0000600F800060078000400780004003C0008003C0008003C0008001E0010001E0 -010001F0010000F0020000F0020000F806000078040000780400003C0800003C0800003C080000 -1E1000001E1000001F3000000F2000000F20000007C0000007C0000007C0000003800000038000 -00038000000100001F207F9E22>I<FFF07FF81FF01F800FC007C00F00078003800F0007800100 -0F0007C00100078007C00200078007C00200078007C0020003C009E0040003C009E0040003C009 -E0040003E010F00C0001E010F0080001E010F0080001F02078080000F02078100000F020781000 -00F0403C10000078403C20000078403C20000078C03E2000003C801E4000003C801E4000003C80 -1E4000001F000F8000001F000F8000001F000F8000001E00078000000E00070000000E00070000 -000C000300000004000200002C207F9E2F>I<FEFEC0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0 -C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0FEFE072D7CA10D>91 -D<080410082010201040204020804080408040B85CFC7EFC7E7C3E381C0F0E7B9F17>I<FEFE06 -060606060606060606060606060606060606060606060606060606060606060606060606060606 -06FEFE072D7FA10D>I<081020204040808080B8FCFC7C38060E7D9F0D>96 -D<1FE000303000781800781C00300E00000E00000E00000E0000FE00078E001E0E00380E00780E -00F00E10F00E10F00E10F01E10781E103867200F83C014147E9317>I<0E0000FE00000E00000E -00000E00000E00000E00000E00000E00000E00000E00000E00000E3E000EC3800F01C00F00E00E -00E00E00700E00700E00780E00780E00780E00780E00780E00780E00700E00700E00E00F00E00D -01C00CC300083E0015207F9F19>I<03F80E0C1C1E381E380C70007000F000F000F000F000F000 -F00070007000380138011C020E0C03F010147E9314>I<000380003F8000038000038000038000 -038000038000038000038000038000038000038003E380061B801C078038038038038070038070 -0380F00380F00380F00380F00380F00380F003807003807003803803803807801C07800E1B8003 -E3F815207E9F19>I<03F0000E1C001C0E00380700380700700700700380F00380F00380FFFF80 -F00000F00000F000007000007000003800801800800C010007060001F80011147F9314>I<007C -00C6018F038F07060700070007000700070007000700FFF0070007000700070007000700070007 -0007000700070007000700070007000700070007007FF01020809F0E>I<0000E003E3300E3C30 -1C1C30380E00780F00780F00780F00780F00780F00380E001C1C001E380033E000200000200000 -3000003000003FFE001FFF800FFFC03001E0600070C00030C00030C00030C000306000603000C0 -1C038003FC00141F7F9417>I<0E0000FE00000E00000E00000E00000E00000E00000E00000E00 -000E00000E00000E00000E3E000E43000E81800F01C00F01C00E01C00E01C00E01C00E01C00E01 -C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C0FFE7FC16207F9F19>I<1C -003E003E003E001C000000000000000000000000000E007E000E000E000E000E000E000E000E00 -0E000E000E000E000E000E000E000E000E000E00FFC00A1F809E0C>I<00E001F001F001F000E0 -000000000000000000000000007007F000F0007000700070007000700070007000700070007000 -7000700070007000700070007000700070007000706070F060F0C061803F000C28829E0E>I<0E -0000FE00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E0FF00E -03C00E03000E02000E04000E08000E10000E30000E70000EF8000F38000E1C000E1E000E0E000E -07000E07800E03800E03C00E03E0FFCFF815207F9F18>I<0E00FE000E000E000E000E000E000E -000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E00 -0E000E000E000E00FFE00B20809F0C>I<0E1F01F000FE618618000E81C81C000F00F00E000F00 -F00E000E00E00E000E00E00E000E00E00E000E00E00E000E00E00E000E00E00E000E00E00E000E -00E00E000E00E00E000E00E00E000E00E00E000E00E00E000E00E00E000E00E00E00FFE7FE7FE0 -23147F9326>I<0E3E00FE43000E81800F01C00F01C00E01C00E01C00E01C00E01C00E01C00E01 -C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C0FFE7FC16147F9319>I<01F80007 -0E001C03803801C03801C07000E07000E0F000F0F000F0F000F0F000F0F000F0F000F07000E070 -00E03801C03801C01C0380070E0001F80014147F9317>I<0E3E00FEC3800F01C00F00E00E00E0 -0E00F00E00700E00780E00780E00780E00780E00780E00780E00700E00F00E00E00F01E00F01C0 -0EC3000E3E000E00000E00000E00000E00000E00000E00000E00000E0000FFE000151D7F9319> -I<03E0800619801C05803C0780380380780380700380F00380F00380F00380F00380F00380F003 -807003807803803803803807801C0B800E138003E3800003800003800003800003800003800003 -80000380000380003FF8151D7E9318>I<0E78FE8C0F1E0F1E0F0C0E000E000E000E000E000E00 -0E000E000E000E000E000E000E000E00FFE00F147F9312>I<1F9030704030C010C010C010E000 -78007F803FE00FF00070803880188018C018C018E030D0608F800D147E9312>I<020002000200 -060006000E000E003E00FFF80E000E000E000E000E000E000E000E000E000E000E000E080E080E -080E080E080610031001E00D1C7F9B12>I<0E01C0FE1FC00E01C00E01C00E01C00E01C00E01C0 -0E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E03C00603C0030DC001F1FC -16147F9319>I<FF83F81E01E01C00C00E00800E00800E00800701000701000382000382000382 -0001C40001C40001EC0000E80000E80000700000700000700000200015147F9318>I<FF9FE1FC -3C0780701C0300601C0380200E0380400E0380400E03C0400707C0800704C0800704E080038861 -000388710003C8730001D0320001D03A0000F03C0000E01C0000E01C0000601800004008001E14 -7F9321>I<7FC3FC0F01E00701C007018003810001C20000E40000EC00007800003800003C0000 -7C00004E000087000107000303800201C00601E01E01E0FF07FE1714809318>I<FF83F81E01E0 -1C00C00E00800E00800E008007010007010003820003820003820001C40001C40001EC0000E800 -00E800007000007000007000002000002000004000004000004000F08000F08000F10000620000 -3C0000151D7F9318>I<3FFF380E200E201C40384078407000E001E001C00380078007010E011E -011C0338027006700EFFFE10147F9314>I E /Fp 13 122 df<0000001FFC0000C000000003FF -FFC001C00000001FFFFFF003C00000007FFFFFFC07C0000001FFFC00FE0FC0000007FFC0001F9F -C000000FFE000007FFC000003FF8000003FFC000007FF0000000FFC00000FFE00000007FC00001 -FFC00000007FC00001FF800000003FC00003FF000000001FC00007FE000000001FC0000FFE0000 -00000FC0000FFC000000000FC0001FFC0000000007C0001FFC0000000007C0003FF80000000007 -C0003FF80000000003C0003FF80000000003C0007FF80000000003C0007FF80000000003C0007F -F0000000000000007FF000000000000000FFF000000000000000FFF000000000000000FFF00000 -0000000000FFF000000000000000FFF000000000000000FFF000000000000000FFF00000000000 -0000FFF000000000000000FFF000000000000000FFF000000000000000FFF000001FFFFFFF807F -F000001FFFFFFF807FF000001FFFFFFF807FF800001FFFFFFF807FF800000001FFC0003FF80000 -0001FFC0003FF800000001FFC0003FF800000001FFC0001FFC00000001FFC0001FFC00000001FF -C0000FFE00000001FFC0000FFE00000001FFC00007FF00000001FFC00003FF00000001FFC00001 -FF80000001FFC00001FFC0000001FFC00000FFE0000001FFC000007FF0000003FFC000003FFC00 -0003FFC000000FFF000007FFC0000007FFC0001FBFC0000001FFFC00FF1FC00000007FFFFFFE0F -C00000001FFFFFF803C000000003FFFFE000C0000000001FFE00000000413D7BBB4C>71 -D<FFFFFFF803FFFFFFE0FFFFFFF803FFFFFFE0FFFFFFF803FFFFFFE0FFFFFFF803FFFFFFE0007F -F0000001FFC000007FF0000001FFC000007FF0000001FFC000007FF0000001FFC000007FF00000 -01FFC000007FF0000001FFC000007FF0000001FFC000007FF0000001FFC000007FF0000001FFC0 -00007FF0000001FFC000007FF0000001FFC000007FF0000001FFC000007FF0000001FFC000007F -F0000001FFC000007FF0000001FFC000007FF0000001FFC000007FF0000001FFC000007FF00000 -01FFC000007FF0000001FFC000007FF0000001FFC000007FF0000001FFC000007FF0000001FFC0 -00007FFFFFFFFFFFC000007FFFFFFFFFFFC000007FFFFFFFFFFFC000007FFFFFFFFFFFC000007F -F0000001FFC000007FF0000001FFC000007FF0000001FFC000007FF0000001FFC000007FF00000 -01FFC000007FF0000001FFC000007FF0000001FFC000007FF0000001FFC000007FF0000001FFC0 -00007FF0000001FFC000007FF0000001FFC000007FF0000001FFC000007FF0000001FFC000007F -F0000001FFC000007FF0000001FFC000007FF0000001FFC000007FF0000001FFC000007FF00000 -01FFC000007FF0000001FFC000007FF0000001FFC000007FF0000001FFC000007FF0000001FFC0 -00007FF0000001FFC000007FF0000001FFC000007FF0000001FFC000FFFFFFF803FFFFFFE0FFFF -FFF803FFFFFFE0FFFFFFF803FFFFFFE0FFFFFFF803FFFFFFE0433B7CBA4C>I<FFFFFFFE000000 -FFFFFFFE000000FFFFFFFE000000FFFFFFFE000000007FF000000000007FF000000000007FF000 -000000007FF000000000007FF000000000007FF000000000007FF000000000007FF00000000000 -7FF000000000007FF000000000007FF000000000007FF000000000007FF000000000007FF00000 -0000007FF000000000007FF000000000007FF000000000007FF000000000007FF000000000007F -F000000000007FF000000000007FF000000000007FF000000000007FF000000000007FF0000000 -00007FF000000000007FF000000000007FF000000000007FF000000000007FF000000000007FF0 -00000000007FF000000780007FF000000780007FF000000780007FF000000780007FF000000780 -007FF000000F80007FF000000F00007FF000000F00007FF000000F00007FF000001F00007FF000 -001F00007FF000001F00007FF000003F00007FF000003F00007FF000007F00007FF00000FF0000 -7FF00001FF00007FF00003FF00007FF0000FFE00007FF0007FFE00FFFFFFFFFFFE00FFFFFFFFFF -FE00FFFFFFFFFFFE00FFFFFFFFFFFE00313B7CBA3A>76 D<FFFFF0000007FFFFE0FFFFF8000007 -FFFFE0FFFFFC000007FFFFE0FFFFFE000007FFFFE0007FFE00000007E000007FFF00000003C000 -007FFF80000003C000007BFFC0000003C000007BFFE0000003C0000079FFE0000003C0000078FF -F0000003C00000787FF8000003C00000783FFC000003C00000783FFE000003C00000781FFE0000 -03C00000780FFF000003C000007807FF800003C000007803FFC00003C000007803FFE00003C000 -007801FFE00003C000007800FFF00003C0000078007FF80003C0000078003FFC0003C000007800 -3FFE0003C0000078001FFF0003C0000078000FFF0003C00000780007FF8003C00000780003FFC0 -03C00000780003FFE003C00000780001FFF003C00000780000FFF003C000007800007FF803C000 -007800003FFC03C000007800003FFE03C000007800001FFF03C000007800000FFF03C000007800 -0007FF83C0000078000003FFC3C0000078000003FFE3C0000078000001FFF3C0000078000000FF -F3C00000780000007FFBC00000780000003FFFC00000780000003FFFC00000780000001FFFC000 -00780000000FFFC000007800000007FFC000007800000003FFC000007800000003FFC000007800 -000001FFC000007800000000FFC0000078000000007FC0000078000000003FC000007800000000 -3FC00000FC000000001FC000FFFFFC0000000FC000FFFFFC00000007C000FFFFFC00000003C000 -FFFFFC00000003C000433B7CBA4C>78 D<FFFFFFF8001FFFFF80FFFFFFF8001FFFFF80FFFFFFF8 -001FFFFF80FFFFFFF8001FFFFF80007FF00000001F8000007FF00000000F0000007FF00000000F -0000007FF00000000F0000007FF00000000F0000007FF00000000F0000007FF00000000F000000 -7FF00000000F0000007FF00000000F0000007FF00000000F0000007FF00000000F0000007FF000 -00000F0000007FF00000000F0000007FF00000000F0000007FF00000000F0000007FF00000000F -0000007FF00000000F0000007FF00000000F0000007FF00000000F0000007FF00000000F000000 -7FF00000000F0000007FF00000000F0000007FF00000000F0000007FF00000000F0000007FF000 -00000F0000007FF00000000F0000007FF00000000F0000007FF00000000F0000007FF00000000F -0000007FF00000000F0000007FF00000000F0000007FF00000000F0000007FF00000000F000000 -7FF00000000F0000007FF00000000F0000007FF00000000F0000007FF00000000F0000007FF000 -00000F0000007FF00000000F0000007FF00000000F0000003FF00000001E0000003FF00000001E -0000003FF80000001E0000001FF80000003C0000001FF80000003C0000000FFC00000078000000 -07FC000000F800000007FE000001F000000003FF000003F000000001FF800007E000000000FFE0 -001FC0000000003FFC01FF80000000001FFFFFFE000000000007FFFFF8000000000000FFFFE000 -00000000000FFE00000000413C7CBA4A>85 D<003FFE00000001FFFFE0000007FFFFF800000FE0 -07FC00000FF001FE00001FF800FF00001FF8007F80001FF8007FC0001FF8003FC0000FF0003FE0 -0007E0003FE00003C0003FE0000000003FE0000000003FE0000000003FE0000000003FE0000000 -FFFFE000001FFFFFE000007FF83FE00003FF803FE00007FC003FE0000FF0003FE0001FE0003FE0 -003FE0003FE0007FC0003FE0007FC0003FE000FF80003FE000FF80003FE000FF80003FE000FF80 -003FE000FF80007FE0007FC0007FE0007FC000DFE0003FE0039FF0001FF80F0FFFE007FFFE0FFF -E001FFF807FFE0003FE000FFE02B267DA52F>97 D<00FE00000000FFFE00000000FFFE00000000 -FFFE00000000FFFE0000000007FE0000000003FE0000000003FE0000000003FE0000000003FE00 -00000003FE0000000003FE0000000003FE0000000003FE0000000003FE0000000003FE00000000 -03FE0000000003FE0000000003FE0000000003FE0000000003FE0000000003FE0000000003FE01 -FF000003FE1FFFF00003FE7FFFFC0003FEFC03FE0003FFF000FF0003FFC0003F8003FF00001FC0 -03FE00001FE003FE00000FF003FE00000FF803FE00000FF803FE000007FC03FE000007FC03FE00 -0007FC03FE000007FE03FE000007FE03FE000007FE03FE000007FE03FE000007FE03FE000007FE -03FE000007FE03FE000007FE03FE000007FE03FE000007FC03FE000007FC03FE000007FC03FE00 -000FFC03FE00000FF803FE00000FF003FE00001FF003FF00001FE003FF80003FC003FFC0007F80 -03F9E000FF0003F0FC07FE0003F07FFFF80003E01FFFE00003C003FE00002F3C7DBB36>I<01E0 -0007F8000FFC000FFC001FFE001FFE001FFE001FFE000FFC000FFC0007F80001E0000000000000 -0000000000000000000000000000000000000000000000000000000000FE00FFFE00FFFE00FFFE -00FFFE0007FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE -0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE -0003FE0003FE0003FE0003FE00FFFFF0FFFFF0FFFFF0FFFFF0143D7DBC1A>105 -D<0001FFC00000000FFFF80000007FFFFF000000FF80FF800003FE003FE00007F8000FF0000FF0 -0007F8000FF00007F8001FE00003FC003FE00003FE003FE00003FE007FC00001FF007FC00001FF -007FC00001FF007FC00001FF00FFC00001FF80FFC00001FF80FFC00001FF80FFC00001FF80FFC0 -0001FF80FFC00001FF80FFC00001FF80FFC00001FF80FFC00001FF807FC00001FF007FC00001FF -007FC00001FF003FE00003FE003FE00003FE001FE00003FC001FF00007FC000FF00007F80007F8 -000FF00003FE003FE00000FF80FF8000007FFFFF0000000FFFF800000001FFC0000029267DA530 ->111 D<01FC03F000FFFC0FFC00FFFC1FFF00FFFC3C3F80FFFC707F8007FCE0FFC003FCC0FFC0 -03FD80FFC003FD80FFC003FF807F8003FF003F0003FF001E0003FF00000003FE00000003FE0000 -0003FE00000003FE00000003FE00000003FE00000003FE00000003FE00000003FE00000003FE00 -000003FE00000003FE00000003FE00000003FE00000003FE00000003FE00000003FE00000003FE -00000003FE00000003FE00000003FE000000FFFFFC0000FFFFFC0000FFFFFC0000FFFFFC000022 -267DA528>114 D<003FF07003FFFEF007FFFFF01FC01FF03F0003F03E0001F07C0001F07C0000 -F0FC0000F0FC0000F0FE0000F0FF000000FFC00000FFFC00007FFFF0003FFFFE003FFFFF801FFF -FFC00FFFFFE003FFFFF000FFFFF8001FFFFC00007FFC000007FE700001FEF00000FEF000007EF8 -00007EF800007EFC00007EFC00007CFE0000FCFF0000F8FF8001F0FFF00FE0F9FFFFC0F07FFF00 -C01FF8001F267DA526>I<000F0000000F0000000F0000000F0000000F0000001F0000001F0000 -001F0000001F0000003F0000003F0000007F0000007F000000FF000001FF000003FF000007FF00 -001FFFFFF0FFFFFFF0FFFFFFF0FFFFFFF001FF000001FF000001FF000001FF000001FF000001FF -000001FF000001FF000001FF000001FF000001FF000001FF000001FF000001FF000001FF000001 -FF000001FF000001FF000001FF000001FF003C01FF003C01FF003C01FF003C01FF003C01FF003C -01FF003C01FF003C00FF007800FF8078007F80F0003FC1E0001FFFC0000FFF800001FE001E377E -B626>I<FFFFF001FFFCFFFFF001FFFCFFFFF001FFFCFFFFF001FFFC03FE00001F8003FF00001F -0001FF00001E0001FF80003E0000FF80003C0000FF80003C00007FC0007800007FC0007800007F -E000F800003FE000F000003FF001F000001FF001E000001FF803E000000FF803C000000FFC03C0 -000007FC0780000007FC0780000007FE0F80000003FE0F00000003FF1F00000001FF1E00000001 -FFBE00000000FFBC00000000FFFC000000007FF8000000007FF8000000007FF8000000003FF000 -0000003FF0000000001FE0000000001FE0000000000FC0000000000FC000000000078000000000 -0780000000000F80000000000F00000000001F00000000001E00000008003E0000007F003C0000 -007F007C000000FF8078000000FF80F8000000FF80F0000000FF81E00000007F07C00000007C1F -800000003FFF000000001FFE0000000007F0000000002E377EA533>121 -D E end -%%EndProlog -%%BeginSetup -%%Feature: *Resolution 300dpi -TeXDict begin - -%%EndSetup -%%Page: 1 1 -0 bop 0 1152 a Fp(GNU)33 b(History)f(Library)p 0 1201 1950 -17 v 1035 1250 a Fo(Edition)16 b(2.0,)e(for)h Fn(History)f(Library)g -Fo(V)l(ersion)i(2.0.)1759 1304 y(July)g(1994)0 2443 y Fm(Brian)23 -b(F)-6 b(o)n(x,)23 b(F)-6 b(ree)23 b(Soft)n(w)n(are)f(F)-6 -b(oundation)0 2509 y(Chet)22 b(Ramey)-6 b(,)23 b(Case)e(W)-6 -b(estern)23 b(Reserv)n(e)f(Univ)n(ersit)n(y)p 0 2545 1950 9 -v eop -%%Page: 2 2 -1 bop 0 295 a Fo(This)16 b(do)q(cumen)o(t)g(describ)q(es)h(the)f(GNU)f -(History)g(library)l(,)h(a)g(programming)e(to)q(ol)i(that)f(pro)o(vides)h(a)f -(consisten)o(t)0 358 y(user)g(in)o(terface)h(for)e(recalling)j(lines)g(of)e -(previously)h(t)o(yp)q(ed)g(input.)0 495 y(Published)h(b)o(y)f(the)f(F)l(ree) -g(Soft)o(w)o(are)f(F)l(oundation)0 557 y(675)g(Massac)o(h)o(usetts)g(Av)o(en) -o(ue,)0 619 y(Cam)o(bridge,)h(MA)g(02139)f(USA)0 756 y(P)o(ermission)f(is)g -(gran)o(ted)f(to)f(mak)o(e)h(and)h(distribute)h(v)o(erbatim)e(copies)h(of)f -(this)h(man)o(ual)g(pro)o(vided)g(the)f(cop)o(yrigh)o(t)0 818 -y(notice)k(and)f(this)h(p)q(ermission)h(notice)e(are)g(preserv)o(ed)h(on)f -(all)h(copies.)0 955 y(P)o(ermission)f(is)f(gran)o(ted)f(to)h(cop)o(y)g(and)g -(distribute)h(mo)q(di\014ed)h(v)o(ersions)e(of)f(this)i(man)o(ual)f(under)h -(the)f(conditions)0 1018 y(for)e(v)o(erbatim)g(cop)o(ying,)h(pro)o(vided)h -(that)d(the)i(en)o(tire)g(resulting)h(deriv)o(ed)f(w)o(ork)f(is)h -(distributed)h(under)f(the)g(terms)0 1080 y(of)i(a)g(p)q(ermission)h(notice)g -(iden)o(tical)h(to)e(this)g(one.)0 1217 y(P)o(ermission)20 -b(is)g(gran)o(ted)f(to)g(cop)o(y)h(and)f(distribute)i(translations)f(of)f -(this)h(man)o(ual)f(in)o(to)h(another)f(language,)0 1279 y(under)c(the)f(ab)q -(o)o(v)o(e)g(conditions)h(for)e(mo)q(di\014ed)j(v)o(ersions,)e(except)g(that) -g(this)g(p)q(ermission)i(notice)e(ma)o(y)g(b)q(e)h(stated)0 -1341 y(in)h(a)f(translation)g(appro)o(v)o(ed)g(b)o(y)g(the)g(F)l(oundation.)0 -2636 y(Cop)o(yrigh)o(t)226 2635 y(c)214 2636 y Fl(\015)g Fo(1989,)f(1991)g(F) -l(ree)h(Soft)o(w)o(are)f(F)l(oundation,)h(Inc.)p eop -%%Page: 1 3 -2 bop 0 -83 a Fo(Chapter)15 b(1:)k(Using)d(History)f(In)o(teractiv)o(ely)1157 -b(1)0 158 y Fk(1)41 b(Using)14 b(History)h(In)n(teractiv)n(ely)62 -330 y Fo(This)i(c)o(hapter)e(describ)q(es)j(ho)o(w)d(to)h(use)g(the)g(GNU)g -(History)f(Library)i(in)o(teractiv)o(ely)l(,)g(from)e(a)g(user's)h(stand-)0 -392 y(p)q(oin)o(t.)23 b(It)16 b(should)h(b)q(e)f(considered)i(a)d(user's)h -(guide.)23 b(F)l(or)15 b(information)h(on)g(using)h(the)f(GNU)g(History)f -(Library)0 454 y(in)h(y)o(our)f(o)o(wn)f(programs,)g(see)i(Chapter)e(2)h -([Programming)f(with)i(GNU)f(History],)f(page)h(5.)0 663 y -Fm(1.1)33 b(History)15 b(In)n(teraction)62 800 y Fo(The)j(History)g(library)g -(pro)o(vides)h(a)e(history)h(expansion)h(feature)e(that)g(is)i(similar)g(to)e -(the)h(history)f(expan-)0 862 y(sion)k(pro)o(vided)h(b)o(y)f -Fn(csh)p Fo(.)36 b(The)22 b(follo)o(wing)f(text)g(describ)q(es)h(the)f(syn)o -(tax)f(used)i(to)e(manipulate)i(the)f(history)0 924 y(information.)62 -1061 y(History)11 b(expansion)i(tak)o(es)d(place)i(in)h(t)o(w)o(o)d(parts.)18 -b(The)11 b(\014rst)g(is)h(to)f(determine)h(whic)o(h)g(line)h(from)e(the)g -(previous)0 1124 y(history)h(should)h(b)q(e)f(used)h(during)f(substitution.) -20 b(The)12 b(second)g(is)h(to)e(select)h(p)q(ortions)g(of)g(that)f(line)i -(for)f(inclusion)0 1186 y(in)o(to)f(the)h(curren)o(t)f(one.)18 -b(The)12 b(line)h(selected)f(from)f(the)g(previous)h(history)g(is)f(called)i -(the)e Fj(ev)o(en)o(t)p Fo(,)h(and)f(the)h(p)q(ortions)0 1248 -y(of)h(that)g(line)i(that)e(are)g(acted)g(up)q(on)h(are)g(called)h -Fj(w)o(ords)p Fo(.)j(The)c(line)h(is)f(brok)o(en)f(in)o(to)h(w)o(ords)f(in)h -(the)f(same)h(fashion)0 1310 y(that)j(Bash)h(do)q(es,)h(so)e(that)g(sev)o -(eral)h(English)i(\(or)d(Unix\))h(w)o(ords)f(surrounded)i(b)o(y)f(quotes)f -(are)h(considered)h(as)0 1373 y(one)c(w)o(ord.)0 1565 y Fi(1.1.1)30 -b(Ev)n(en)n(t)16 b(Designators)62 1702 y Fo(An)g(ev)o(en)o(t)f(designator)g -(is)g(a)g(reference)h(to)f(a)g(command)g(line)i(en)o(try)d(in)i(the)g -(history)f(list.)0 1847 y Fn(!)216 b Fo(Start)14 b(a)g(history)h -(substitution,)g(except)h(when)f(follo)o(w)o(ed)g(b)o(y)g(a)f(space,)h(tab,)f -(the)h(end)g(of)g(the)g(line,)240 1909 y Fn(=)g Fo(or)g Fn(\()p -Fo(.)0 1989 y Fn(!!)192 b Fo(Refer)16 b(to)e(the)i(previous)f(command.)20 -b(This)c(is)g(a)f(synon)o(ym)g(for)f Fn(!-1)p Fo(.)0 2068 y -Fn(!n)192 b Fo(Refer)16 b(to)e(command)h(line)i Fj(n)p Fo(.)0 -2148 y Fn(!-n)168 b Fo(Refer)16 b(to)e(the)i(command)f Fj(n)g -Fo(lines)i(bac)o(k.)0 2227 y Fn(!string)72 b Fo(Refer)16 b(to)e(the)i(most)e -(recen)o(t)h(command)g(starting)g(with)g Fj(string)p Fo(.)0 -2298 y Fn(!?string)p Fo([)p Fn(?)p Fo(])240 2360 y(Refer)h(to)e(the)i(most)e -(recen)o(t)h(command)g(con)o(taining)h Fj(string)p Fo(.)0 2440 -y Fn(!#)192 b Fo(The)15 b(en)o(tire)h(command)f(line)i(t)o(yp)q(ed)f(so)e -(far.)0 2510 y Fn(^string1^string2^)240 2573 y Fo(Quic)o(k)j(Substitution.)22 -b(Rep)q(eat)16 b(the)g(last)f(command,)h(replacing)h Fj(string1)h -Fo(with)e Fj(string2)p Fo(.)21 b(Equiv-)240 2635 y(alen)o(t)15 -b(to)g Fn(!!:s/string1/string2/)p Fo(.)p eop -%%Page: 2 4 -3 bop 0 -83 a Fo(2)1497 b(GNU)15 b(History)g(Library)0 158 -y Fi(1.1.2)30 b(W)-5 b(ord)15 b(Designators)62 295 y Fo(A)i -Fn(:)g Fo(separates)f(the)h(ev)o(en)o(t)f(sp)q(eci\014cation)j(from)d(the)g -(w)o(ord)g(designator.)25 b(It)17 b(can)g(b)q(e)g(omitted)g(if)g(the)g(w)o -(ord)0 358 y(designator)d(b)q(egins)h(with)f(a)f Fn(^)p Fo(,)h -Fn($)p Fo(,)f Fn(*)h Fo(or)f Fn(\045)p Fo(.)20 b(W)l(ords)13 -b(are)h(n)o(um)o(b)q(ered)g(from)f(the)h(b)q(eginning)i(of)d(the)h(line,)i -(with)e(the)0 420 y(\014rst)h(w)o(ord)f(b)q(eing)j(denoted)f(b)o(y)f(a)g(0)f -(\(zero\).)0 569 y Fn(0)h(\(zero\))57 b Fo(The)15 b Fn(0)p -Fo(th)g(w)o(ord.)20 b(F)l(or)14 b(man)o(y)h(applications,)h(this)g(is)g(the)f -(command)g(w)o(ord.)0 656 y Fn(n)216 b Fo(The)15 b Fj(n)p Fo(th)h(w)o(ord.)0 -744 y Fn(^)216 b Fo(The)15 b(\014rst)g(argumen)o(t;)f(that)h(is,)g(w)o(ord)g -(1.)0 831 y Fn($)216 b Fo(The)15 b(last)h(argumen)o(t.)0 918 -y Fn(\045)216 b Fo(The)15 b(w)o(ord)g(matc)o(hed)g(b)o(y)g(the)g(most)g -(recen)o(t)g Fn(?string?)f Fo(searc)o(h.)0 1005 y Fn(x-y)168 -b Fo(A)15 b(range)g(of)g(w)o(ords;)f Fn(-)p Fj(y)19 b Fo(abbreviates)c -Fn(0-)p Fj(y)t Fo(.)0 1092 y Fn(*)216 b Fo(All)17 b(of)f(the)g(w)o(ords,)f -(except)i(the)f Fn(0)p Fo(th.)22 b(This)17 b(is)f(a)g(synon)o(ym)g(for)f -Fn(1-$)p Fo(.)22 b(It)17 b(is)f(not)g(an)g(error)f(to)h(use)240 -1155 y Fn(*)f Fo(if)h(there)f(is)h(just)f(one)g(w)o(ord)f(in)i(the)g(ev)o(en) -o(t;)e(the)i(empt)o(y)e(string)i(is)f(returned)h(in)g(that)e(case.)0 -1242 y Fn(x*)192 b Fo(Abbreviates)16 b Fn(x-$)0 1329 y(x-)192 -b Fo(Abbreviates)16 b Fn(x-$)f Fo(lik)o(e)h Fn(x*)p Fo(,)e(but)i(omits)f(the) -g(last)g(w)o(ord.)0 1537 y Fi(1.1.3)30 b(Mo)r(di\014ers)62 -1674 y Fo(After)20 b(the)f(optional)i(w)o(ord)e(designator,)h(y)o(ou)f(can)h -(add)g(a)g(sequence)h(of)e(one)h(or)f(more)g(of)g(the)h(follo)o(wing)0 -1736 y(mo)q(di\014ers,)c(eac)o(h)f(preceded)i(b)o(y)e(a)g Fn(:)p -Fo(.)0 1885 y Fn(h)216 b Fo(Remo)o(v)o(e)15 b(a)g(trailing)h(pathname)f(comp) -q(onen)o(t,)g(lea)o(ving)h(only)g(the)f(head.)0 1973 y Fn(r)216 -b Fo(Remo)o(v)o(e)15 b(a)g(trailing)h(su\016x)f(of)g(the)g(form)g(`)p -Fn(.)p Fo(')p Fj(su\016x)p Fo(,)f(lea)o(ving)i(the)f(basename.)0 -2060 y Fn(e)216 b Fo(Remo)o(v)o(e)15 b(all)h(but)g(the)f(trailing)h(su\016x.) -0 2147 y Fn(t)216 b Fo(Remo)o(v)o(e)15 b(all)h(leading)h(pathname)e(comp)q -(onen)o(ts,)g(lea)o(ving)h(the)f(tail.)0 2234 y Fn(p)216 b -Fo(Prin)o(t)15 b(the)g(new)h(command)f(but)g(do)g(not)g(execute)h(it.)0 -2309 y Fn(s/old/new/)240 2371 y Fo(Substitute)g Fj(new)k Fo(for)15 -b(the)h(\014rst)f(o)q(ccurrence)h(of)g Fj(old)h Fo(in)g(the)e(ev)o(en)o(t)h -(line.)22 b(An)o(y)16 b(delimiter)h(ma)o(y)e(b)q(e)240 2433 -y(used)e(in)f(place)h(of)f Fn(/)p Fo(.)19 b(The)12 b(delimiter)i(ma)o(y)d(b)q -(e)i(quoted)f(in)h Fj(old)h Fo(and)e Fj(new)17 b Fo(with)12 -b(a)g(single)h(bac)o(kslash.)240 2496 y(If)g Fn(&)h Fo(app)q(ears)f(in)h -Fj(new)p Fo(,)f(it)h(is)g(replaced)g(b)o(y)f Fj(old)p Fo(.)20 -b(A)13 b(single)i(bac)o(kslash)e(will)i(quote)e(the)h Fn(&)p -Fo(.)19 b(The)13 b(\014nal)240 2558 y(delimiter)k(is)f(optional)g(if)f(it)h -(is)f(the)h(last)f(c)o(haracter)f(on)h(the)h(input)g(line.)0 -2645 y Fn(&)216 b Fo(Rep)q(eat)16 b(the)f(previous)h(substitution.)p -eop -%%Page: 3 5 -4 bop 0 -83 a Fo(Chapter)15 b(1:)k(Using)d(History)f(In)o(teractiv)o(ely)1157 -b(3)0 158 y Fn(g)216 b Fo(Cause)15 b(c)o(hanges)g(to)f(b)q(e)i(applied)h(o)o -(v)o(er)d(the)h(en)o(tire)g(ev)o(en)o(t)g(line.)21 b(Used)16 -b(in)g(conjunction)g(with)f Fn(s)p Fo(,)f(as)240 221 y(in)i -Fn(gs/old/new/)p Fo(,)d(or)i(with)h Fn(&)p Fo(.)p eop -%%Page: 4 6 -5 bop 0 -83 a Fo(4)1497 b(GNU)15 b(History)g(Library)p eop -%%Page: 5 7 -6 bop 0 -83 a Fo(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g(History)1039 -b(5)0 158 y Fk(2)41 b(Programming)16 b(with)f(GNU)h(History)62 -347 y Fo(This)e(c)o(hapter)f(describ)q(es)i(ho)o(w)d(to)h(in)o(terface)g -(programs)f(that)h(y)o(ou)g(write)g(with)g(the)h(GNU)f(History)g(Library)l(.) -0 409 y(It)j(should)g(b)q(e)g(considered)h(a)f(tec)o(hnical)h(guide.)22 -b(F)l(or)15 b(information)h(on)f(the)h(in)o(teractiv)o(e)g(use)g(of)f(GNU)g -(History)l(,)0 471 y(see)g(Chapter)g(1)g([Using)h(History)f(In)o(teractiv)o -(ely],)g(page)g(1.)0 698 y Fm(2.1)33 b(In)n(tro)r(duction)17 -b(to)e(History)62 835 y Fo(Man)o(y)j(programs)g(read)h(input)h(from)e(the)g -(user)h(a)g(line)h(at)f(a)f(time.)31 b(The)19 b(GNU)g(History)f(library)i(is) -f(able)0 897 y(to)e(k)o(eep)g(trac)o(k)f(of)h(those)g(lines,)i(asso)q(ciate)e -(arbitrary)g(data)g(with)g(eac)o(h)g(line,)j(and)d(utilize)i(information)f -(from)0 960 y(previous)e(lines)h(in)f(comp)q(osing)f(new)h(ones.)62 -1097 y(The)i(programmer)f(using)h(the)g(History)g(library)g(has)g(a)o(v)m -(ailable)h(functions)g(for)e(remem)o(b)q(ering)h(lines)i(on)d(a)0 -1159 y(history)f(list,)g(asso)q(ciating)g(arbitrary)g(data)f(with)h(a)f -(line,)j(remo)o(ving)d(lines)j(from)d(the)h(list,)g(searc)o(hing)g(through)0 -1221 y(the)h(list)h(for)e(a)h(line)h(con)o(taining)g(an)f(arbitrary)f(text)h -(string,)g(and)g(referencing)h(an)o(y)f(line)h(in)g(the)f(list)h(directly)l -(.)0 1284 y(In)d(addition,)h(a)e(history)h Fj(expansion)h Fo(function)g(is)f -(a)o(v)m(ailable)h(whic)o(h)g(pro)o(vides)f(for)f(a)h(consisten)o(t)g(user)g -(in)o(terface)0 1346 y(across)f(di\013eren)o(t)i(programs.)62 -1483 y(The)i(user)g(using)g(programs)f(written)g(with)h(the)g(History)f -(library)i(has)e(the)h(b)q(ene\014t)h(of)e(a)g(consisten)o(t)h(user)0 -1545 y(in)o(terface)d(with)g(a)f(set)h(of)f(w)o(ell-kno)o(wn)h(commands)g -(for)f(manipulating)i(the)f(text)f(of)g(previous)h(lines)h(and)f(using)0 -1608 y(that)g(text)g(in)i(new)e(commands.)22 b(The)15 b(basic)i(history)e -(manipulation)j(commands)d(are)g(similar)i(to)e(the)h(history)0 -1670 y(substitution)g(pro)o(vided)g(b)o(y)f Fn(csh)p Fo(.)62 -1807 y(If)g(the)g(programmer)e(desires,)i(he)g(can)g(use)g(the)f(Readline)j -(library)l(,)e(whic)o(h)h(includes)g(some)f(history)f(manip-)0 -1870 y(ulation)i(b)o(y)f(default,)h(and)f(has)g(the)g(added)h(adv)m(an)o -(tage)f(of)g(command)g(line)h(editing.)0 2096 y Fm(2.2)33 b(History)15 -b(Storage)62 2234 y Fo(The)h(history)f(list)h(is)g(an)f(arra)o(y)f(of)g -(history)i(en)o(tries.)k(A)15 b(history)g(en)o(try)g(is)h(declared)g(as)f -(follo)o(ws:)120 2358 y Fn(typedef)23 b(struct)g(_hist_entry)f({)168 -2408 y(char)h(*line;)168 2458 y(char)g(*data;)120 2508 y(})h(HIST_ENTRY;)62 -2645 y Fo(The)16 b(history)f(list)h(itself)g(migh)o(t)f(therefore)g(b)q(e)h -(declared)g(as)p eop -%%Page: 6 8 -7 bop 0 -83 a Fo(6)1497 b(GNU)15 b(History)g(Library)120 158 -y Fn(HIST_ENTRY)22 b(**the_history_list;)62 302 y Fo(The)16 -b(state)e(of)h(the)g(History)g(library)h(is)g(encapsulated)g(in)o(to)f(a)g -(single)i(structure:)120 434 y Fn(/*)24 b(A)f(structure)g(used)g(to)h(pass)f -(the)h(current)f(state)g(of)g(the)h(history)f(stuff)g(around.)g(*/)120 -484 y(typedef)g(struct)g(_hist_state)f({)168 534 y(HIST_ENTRY)g(**entries;) -214 b(/*)23 b(Pointer)g(to)h(the)f(entries)g(themselves.)f(*/)168 -584 y(int)h(offset;)453 b(/*)23 b(The)h(location)e(pointer)h(within)g(this)h -(array.)f(*/)168 633 y(int)g(length;)453 b(/*)23 b(Number)g(of)h(elements)f -(within)g(this)g(array.)g(*/)168 683 y(int)g(size;)501 b(/*)23 -b(Number)g(of)h(slots)f(allocated)g(to)g(this)h(array.)f(*/)168 -733 y(int)g(flags;)120 783 y(})h(HISTORY_STATE;)62 927 y Fo(If)16 -b(the)f(\015ags)g(mem)o(b)q(er)g(includes)j Fn(HS_STIFLED)p -Fo(,)13 b(the)i(history)h(has)f(b)q(een)h(sti\015ed.)0 1215 -y Fm(2.3)33 b(History)15 b(F)-6 b(unctions)62 1359 y Fo(This)16 -b(section)g(describ)q(es)h(the)e(calling)i(sequence)f(for)f(the)g(v)m(arious) -h(functions)g(presen)o(t)f(in)h(GNU)f(History)l(.)0 1631 y -Fi(2.3.1)30 b(Initializing)15 b(History)g(and)g(State)g(Managemen)n(t)62 -1775 y Fo(This)j(section)g(describ)q(es)h(functions)f(used)g(to)e(initialize) -21 b(and)c(manage)g(the)g(state)g(of)g(the)g(History)g(library)0 -1837 y(when)f(y)o(ou)f(w)o(an)o(t)f(to)g(use)i(the)f(history)g(functions)h -(in)g(y)o(our)f(program.)1725 2021 y(F)l(unction)-1899 b Fh(void)20 -b Fg(using)p 258 2021 18 3 v 20 w(history)j Ff(\(\))120 2083 -y Fo(Begin)g(a)f(session)g(in)h(whic)o(h)g(the)f(history)g(functions)g(migh)o -(t)g(b)q(e)h(used.)40 b(This)23 b(initializes)i(the)120 2145 -y(in)o(teractiv)o(e)16 b(v)m(ariables.)1725 2328 y(F)l(unction)-1899 -b Fh(HISTORY_STATE)21 b(*)e Fg(history)p 582 2328 V 21 w(get)p -680 2328 V 21 w(history)p 876 2328 V 21 w(state)j Ff(\(\))120 -2391 y Fo(Return)16 b(a)f(structure)g(describing)i(the)e(curren)o(t)g(state)f -(of)h(the)g(input)i(history)l(.)1725 2574 y(F)l(unction)-1899 -b Fh(void)20 b Fg(history)p 302 2574 V 20 w(set)p 393 2574 -V 21 w(history)p 589 2574 V 21 w(state)j Ff(\()p Fn(HISTORY_STATE)13 -b(*state)p Ff(\))120 2636 y Fo(Set)i(the)h(state)e(of)h(the)g(history)g(list) -h(according)g(to)e Fj(state)p Fo(.)p eop -%%Page: 7 9 -8 bop 0 -83 a Fo(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g(History)1039 -b(7)0 158 y Fi(2.3.2)30 b(History)15 b(List)g(Managemen)n(t)62 -295 y Fo(These)i(functions)h(manage)e(individual)k(en)o(tries)d(on)f(the)h -(history)g(list,)g(or)f(set)h(parameters)e(managing)i(the)0 -358 y(list)f(itself.)1725 520 y(F)l(unction)-1899 b Fh(void)20 -b Fg(add)p 219 520 18 3 v 20 w(history)j Ff(\()p Fn(char)14 -b(*string)p Ff(\))120 582 y Fo(Place)j Fj(string)k Fo(at)16 -b(the)g(end)i(of)e(the)g(history)h(list.)25 b(The)17 b(asso)q(ciated)g(data)f -(\014eld)h(\(if)g(an)o(y\))f(is)h(set)g(to)120 644 y Fn(NULL)p -Fo(.)1725 806 y(F)l(unction)-1899 b Fh(HIST_ENTRY)21 b(*)e -Fg(remo)n(v)n(e)p 509 806 V 20 w(history)k Ff(\()p Fn(int)14 -b(which)p Ff(\))120 868 y Fo(Remo)o(v)o(e)d(history)g(en)o(try)g(at)g -(o\013set)f Fj(whic)o(h)i Fo(from)f(the)g(history)l(.)19 b(The)11 -b(remo)o(v)o(ed)g(elemen)o(t)h(is)g(returned)120 930 y(so)j(y)o(ou)g(can)g -(free)g(the)h(line,)g(data,)e(and)i(con)o(taining)g(structure.)1725 -1092 y(F)l(unction)-1899 b Fh(HIST_ENTRY)21 b(*)e Fg(replace)p -505 1092 V 22 w(history)p 702 1092 V 20 w(en)n(try)24 b Ff(\()p -Fn(int)14 b(which,)g(char)h(*line,)f(char)208 1155 y(*data)p -Ff(\))120 1217 y Fo(Mak)o(e)d(the)i(history)f(en)o(try)g(at)f(o\013set)h -Fj(whic)o(h)h Fo(ha)o(v)o(e)e Fj(line)17 b Fo(and)12 b Fj(data)p -Fo(.)19 b(This)12 b(returns)g(the)h(old)g(en)o(try)e(so)120 -1279 y(y)o(ou)i(can)g(disp)q(ose)h(of)e(the)h(data.)19 b(In)13 -b(the)g(case)g(of)f(an)h(in)o(v)m(alid)i Fj(whic)o(h)p Fo(,)f(a)f -Fn(NULL)f Fo(p)q(oin)o(ter)i(is)f(returned.)1725 1441 y(F)l(unction)-1899 -b Fh(void)20 b Fg(sti\015e)p 245 1441 V 21 w(history)j Ff(\()p -Fn(int)14 b(max)p Ff(\))120 1503 y Fo(Sti\015e)i(the)f(history)h(list,)f -(remem)o(b)q(ering)h(only)g(the)f(last)g Fj(max)j Fo(en)o(tries.)1725 -1665 y(F)l(unction)-1899 b Fh(int)20 b Fg(unsti\015e)p 283 -1665 V 21 w(history)i Ff(\(\))120 1728 y Fo(Stop)13 b(sti\015ing)h(the)f -(history)l(.)19 b(This)14 b(returns)f(the)g(previous)h(amoun)o(t)e(the)h -(history)g(w)o(as)g(sti\015ed.)20 b(The)120 1790 y(v)m(alue)c(is)g(p)q -(ositiv)o(e)g(if)g(the)f(history)g(w)o(as)g(sti\015ed,)h(negativ)o(e)f(if)g -(it)h(w)o(asn't.)1725 1952 y(F)l(unction)-1899 b Fh(int)20 -b Fg(history)p 276 1952 V 20 w(is)p 334 1952 V 21 w(sti\015ed)k -Ff(\(\))120 2014 y Fo(Returns)16 b(non-zero)f(if)h(the)f(history)g(is)h -(sti\015ed,)g(zero)f(if)g(it)h(is)g(not.)0 2222 y Fi(2.3.3)30 -b(Information)14 b(Ab)r(out)h(the)g(History)g(List)62 2359 -y Fo(These)h(functions)g(return)f(information)g(ab)q(out)g(the)h(en)o(tire)f -(history)g(list)h(or)f(individual)j(list)f(en)o(tries.)1725 -2521 y(F)l(unction)-1899 b Fh(HIST_ENTRY)21 b(**)e Fg(history)p -530 2521 V 21 w(list)24 b Ff(\(\))120 2583 y Fo(Return)e(a)e -Fn(NULL)h Fo(terminated)g(arra)o(y)f(of)g Fn(HIST_ENTRY)g Fo(whic)o(h)i(is)f -(the)g(curren)o(t)g(input)h(history)l(.)120 2645 y(Elemen)o(t)16 -b(0)f(of)f(this)i(list)g(is)g(the)f(b)q(eginning)i(of)e(time.)20 -b(If)c(there)f(is)h(no)f(history)l(,)g(return)g Fn(NULL)p Fo(.)p -eop -%%Page: 8 10 -9 bop 0 -83 a Fo(8)1497 b(GNU)15 b(History)g(Library)1725 158 -y(F)l(unction)-1899 b Fh(int)20 b Fg(where)p 250 158 18 3 v -20 w(history)j Ff(\(\))120 221 y Fo(Returns)16 b(the)f(o\013set)f(of)h(the)g -(curren)o(t)g(history)g(elemen)o(t.)1725 378 y(F)l(unction)-1899 -b Fh(HIST_ENTRY)21 b(*)e Fg(curren)n(t)p 512 378 V 21 w(history)k -Ff(\(\))120 440 y Fo(Return)14 b(the)g(history)g(en)o(try)f(at)h(the)g -(curren)o(t)f(p)q(osition,)i(as)e(determined)j(b)o(y)d Fn(where_history)h -(\(\))p Fo(.)120 502 y(If)h(there)h(is)f(no)h(en)o(try)e(there,)h(return)g(a) -g Fn(NULL)g Fo(p)q(oin)o(ter.)1725 660 y(F)l(unction)-1899 -b Fh(HIST_ENTRY)21 b(*)e Fg(history)p 504 660 V 21 w(get)j -Ff(\()p Fn(int)15 b(offset)p Ff(\))120 722 y Fo(Return)g(the)g(history)f(en)o -(try)g(at)g(p)q(osition)i Fj(o\013set)p Fo(,)d(starting)h(from)g -Fn(history_base)p Fo(.)k(If)c(there)h(is)g(no)120 784 y(en)o(try)g(there,)g -(or)f(if)i Fj(o\013set)f Fo(is)h(greater)e(than)h(the)h(history)f(length,)g -(return)g(a)g Fn(NULL)g Fo(p)q(oin)o(ter.)1725 942 y(F)l(unction)-1899 -b Fh(int)20 b Fg(history)p 276 942 V 20 w(total)p 412 942 V -22 w(b)n(ytes)j Ff(\(\))120 1004 y Fo(Return)17 b(the)f(n)o(um)o(b)q(er)g(of) -g(b)o(ytes)g(that)f(the)h(primary)g(history)g(en)o(tries)h(are)e(using.)23 -b(This)17 b(function)120 1066 y(returns)e(the)g(sum)h(of)e(the)i(lengths)f -(of)g(all)h(the)g(lines)g(in)g(the)g(history)l(.)0 1265 y Fi(2.3.4)30 -b(Mo)n(ving)15 b(Around)h(the)f(History)g(List)62 1402 y Fo(These)h -(functions)g(allo)o(w)f(the)g(curren)o(t)h(index)g(in)o(to)f(the)h(history)f -(list)h(to)e(b)q(e)i(set)f(or)g(c)o(hanged.)1725 1559 y(F)l(unction)-1899 -b Fh(int)20 b Fg(history)p 276 1559 V 20 w(set)p 367 1559 V -21 w(p)r(os)h Ff(\()p Fn(int)15 b(pos)p Ff(\))120 1621 y Fo(Set)g(the)h(p)q -(osition)g(in)g(the)f(history)g(list)h(to)f Fj(p)q(os)p Fo(,)g(an)g(absolute) -g(index)i(in)o(to)e(the)g(list.)1725 1779 y(F)l(unction)-1899 -b Fh(HIST_ENTRY)21 b(*)e Fg(previous)p 540 1779 V 20 w(history)k -Ff(\(\))120 1841 y Fo(Bac)o(k)16 b(up)h(the)g(curren)o(t)f(history)h -(o\013set)e(to)h(the)h(previous)g(history)g(en)o(try)l(,)f(and)h(return)f(a)g -(p)q(oin)o(ter)120 1903 y(to)f(that)f(en)o(try)l(.)20 b(If)15 -b(there)g(is)h(no)f(previous)h(en)o(try)l(,)f(return)g(a)g -Fn(NULL)g Fo(p)q(oin)o(ter.)1725 2061 y(F)l(unction)-1899 b -Fh(HIST_ENTRY)21 b(*)e Fg(next)p 439 2061 V 21 w(history)k -Ff(\(\))120 2123 y Fo(Mo)o(v)o(e)c(the)h(curren)o(t)g(history)f(o\013set)g -(forw)o(ard)g(to)g(the)h(next)g(history)g(en)o(try)l(,)g(and)g(return)g(the)g -(a)120 2185 y(p)q(oin)o(ter)c(to)e(that)h(en)o(try)l(.)k(If)d(there)f(is)h -(no)f(next)g(en)o(try)l(,)g(return)g(a)g Fn(NULL)g Fo(p)q(oin)o(ter.)0 -2384 y Fi(2.3.5)30 b(Searc)n(hing)15 b(the)h(History)f(List)62 -2521 y Fo(These)e(functions)g(allo)o(w)f(searc)o(hing)h(of)f(the)g(history)g -(list)h(for)f(en)o(tries)h(con)o(taining)g(a)f(sp)q(eci\014c)i(string.)19 -b(Searc)o(h-)0 2583 y(ing)e(ma)o(y)g(b)q(e)g(p)q(erformed)g(b)q(oth)g(forw)o -(ard)f(and)h(bac)o(kw)o(ard)f(from)g(the)h(curren)o(t)f(history)h(p)q -(osition.)26 b(The)17 b(searc)o(h)0 2645 y(ma)o(y)d(b)q(e)i -Fj(anc)o(hored)p Fo(,)f(meaning)h(that)f(the)g(string)g(m)o(ust)g(matc)o(h)f -(at)h(the)g(b)q(eginning)i(of)e(the)h(history)f(en)o(try)l(.)p -eop -%%Page: 9 11 -10 bop 0 -83 a Fo(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g(History)1039 -b(9)1725 158 y(F)l(unction)-1899 b Fh(int)20 b Fg(history)p -276 158 18 3 v 20 w(searc)n(h)j Ff(\()p Fn(char)14 b(*string,)g(int)h -(direction)p Ff(\))120 221 y Fo(Searc)o(h)k(the)g(history)g(for)f -Fj(string)p Fo(,)i(starting)e(at)g(the)h(curren)o(t)g(history)g(o\013set.)30 -b(If)19 b Fj(direction)h Fn(<)f Fo(0,)120 283 y(then)14 b(the)f(searc)o(h)g -(is)h(through)e(previous)i(en)o(tries,)g(else)g(through)f(subsequen)o(t.)20 -b(If)13 b Fj(string)k Fo(is)d(found,)120 345 y(then)f(the)g(curren)o(t)g -(history)g(index)i(is)e(set)g(to)f(that)h(history)g(en)o(try)l(,)f(and)i(the) -f(v)m(alue)h(returned)f(is)h(the)120 407 y(o\013set)h(in)i(the)f(line)i(of)d -(the)h(en)o(try)g(where)g Fj(string)k Fo(w)o(as)c(found.)22 -b(Otherwise,)17 b(nothing)f(is)h(c)o(hanged,)120 470 y(and)e(a)g(-1)g(is)h -(returned.)1725 659 y(F)l(unction)-1899 b Fh(int)20 b Fg(history)p -276 659 V 20 w(searc)n(h)p 452 659 V 21 w(pre\014x)i Ff(\()p -Fn(char)15 b(*string,)f(int)g(direction)p Ff(\))120 721 y Fo(Searc)o(h)22 -b(the)h(history)f(for)f Fj(string)p Fo(,)j(starting)e(at)f(the)i(curren)o(t)f -(history)g(o\013set.)40 b(The)22 b(searc)o(h)g(is)120 783 y(anc)o(hored:)i -(matc)o(hing)18 b(lines)h(m)o(ust)d(b)q(egin)j(with)f Fj(string)p -Fo(.)26 b(If)17 b Fj(direction)i Fn(<)e Fo(0,)g(then)h(the)f(searc)o(h)g(is) -120 845 y(through)e(previous)h(en)o(tries,)f(else)i(through)d(subsequen)o(t.) -21 b(If)16 b Fj(string)j Fo(is)d(found,)f(then)h(the)f(curren)o(t)120 -908 y(history)20 b(index)i(is)e(set)g(to)g(that)f(en)o(try)l(,)i(and)f(the)g -(return)h(v)m(alue)g(is)g(0.)34 b(Otherwise,)22 b(nothing)e(is)120 -970 y(c)o(hanged,)15 b(and)h(a)e(-1)h(is)h(returned.)1725 1159 -y(F)l(unction)-1899 b Fh(int)20 b Fg(history)p 276 1159 V 20 -w(searc)n(h)p 452 1159 V 21 w(p)r(os)h Ff(\()p Fn(char)15 b(*string,)f(int)g -(direction,)g(int)h(pos)p Ff(\))120 1221 y Fo(Searc)o(h)d(for)f -Fj(string)k Fo(in)d(the)g(history)f(list,)i(starting)e(at)g -Fj(p)q(os)p Fo(,)h(an)f(absolute)h(index)h(in)o(to)e(the)h(list.)19 -b(If)12 b Fj(di-)120 1283 y(rection)g Fo(is)h(negativ)o(e,)f(the)g(searc)o(h) -g(pro)q(ceeds)h(bac)o(kw)o(ard)e(from)g Fj(p)q(os)p Fo(,)i(otherwise)f(forw)o -(ard.)17 b(Returns)120 1345 y(the)e(absolute)h(index)g(of)f(the)g(history)h -(elemen)o(t)f(where)h Fj(string)j Fo(w)o(as)14 b(found,)h(or)g(-1)g -(otherwise.)0 1634 y Fi(2.3.6)30 b(Managing)14 b(the)i(History)f(File)62 -1780 y Fo(The)f(History)g(library)h(can)f(read)g(the)g(history)g(from)f(and)i -(write)f(it)g(to)f(a)h(\014le.)20 b(This)15 b(section)g(do)q(cumen)o(ts)f -(the)0 1842 y(functions)i(for)f(managing)g(a)f(history)i(\014le.)1725 -2031 y(F)l(unction)-1899 b Fh(int)20 b Fg(read)p 211 2031 V -20 w(history)i Ff(\()p Fn(char)15 b(*filename)p Ff(\))120 2093 -y Fo(Add)i(the)f(con)o(ten)o(ts)g(of)g Fj(\014lename)k Fo(to)c(the)h(history) -f(list,)h(a)f(line)i(at)e(a)g(time.)24 b(If)17 b Fj(\014lename)j -Fo(is)d Fn(NULL)p Fo(,)120 2155 y(then)f(read)f(from)f(`)p -Fn(~/.history)p Fo('.)k(Returns)e(0)e(if)i(successful,)g(or)f(errno)g(if)h -(not.)1725 2344 y(F)l(unction)-1899 b Fh(int)20 b Fg(read)p -211 2344 V 20 w(history)p 406 2344 V 20 w(range)i Ff(\()p Fn(char)15 -b(*filename,)e(int)i(from,)g(int)f(to)p Ff(\))120 2407 y Fo(Read)j(a)e(range) -h(of)f(lines)j(from)d Fj(\014lename)p Fo(,)i(adding)f(them)g(to)f(the)h -(history)g(list.)23 b(Start)15 b(reading)i(at)120 2469 y(line)f -Fj(from)f Fo(and)g(end)g(at)f Fj(to)p Fo(.)19 b(If)d Fj(from)e -Fo(is)h(zero,)f(start)g(at)g(the)h(b)q(eginning.)22 b(If)15 -b Fj(to)i Fo(is)e(less)g(than)g Fj(from)p Fo(,)120 2531 y(then)i(read)g(un)o -(til)h(the)f(end)g(of)g(the)g(\014le.)25 b(If)17 b Fj(\014lename)k -Fo(is)c Fn(NULL)p Fo(,)f(then)i(read)e(from)g(`)p Fn(~/.history)p -Fo('.)120 2593 y(Returns)g(0)f(if)g(successful,)h(or)f Fn(errno)g -Fo(if)g(not.)p eop -%%Page: 10 12 -11 bop 0 -83 a Fo(10)1474 b(GNU)15 b(History)g(Library)1725 -158 y(F)l(unction)-1899 b Fh(int)20 b Fg(write)p 229 158 18 -3 v 22 w(history)i Ff(\()p Fn(char)15 b(*filename)p Ff(\))120 -221 y Fo(W)l(rite)20 b(the)g(curren)o(t)f(history)h(to)f Fj(\014lename)p -Fo(,)i(o)o(v)o(erwriting)f Fj(\014lename)j Fo(if)d(necessary)l(.)34 -b(If)20 b Fj(\014lename)120 283 y Fo(is)d Fn(NULL)p Fo(,)g(then)g(write)g -(the)g(history)g(list)h(to)e(`)p Fn(~/.history)p Fo('.)23 b(V)l(alues)18 -b(returned)g(are)e(as)h(in)h Fn(read_)120 345 y(history)c(\(\))p -Fo(.)1725 504 y(F)l(unction)-1899 b Fh(int)20 b Fg(app)r(end)p -285 504 V 19 w(history)j Ff(\()p Fn(int)14 b(nelements,)g(char)h(*filename)p -Ff(\))120 566 y Fo(App)q(end)i(the)e(last)g Fj(nelemen)o(ts)j -Fo(of)d(the)g(history)g(list)h(to)f Fj(\014lename)p Fo(.)1725 -724 y(F)l(unction)-1899 b Fh(int)20 b Fg(history)p 276 724 -V 20 w(truncate)p 507 724 V 21 w(\014le)k Ff(\()p Fn(char)14 -b(*filename,)g(int)h(nlines)p Ff(\))120 787 y Fo(T)l(runcate)g(the)h(history) -f(\014le)h Fj(\014lename)p Fo(,)g(lea)o(ving)g(only)g(the)f(last)g -Fj(nlines)k Fo(lines.)0 988 y Fi(2.3.7)30 b(History)15 b(Expansion)62 -1125 y Fo(These)h(functions)g(implemen)o(t)g Fn(csh)p Fo(-lik)o(e)g(history)g -(expansion.)1725 1283 y(F)l(unction)-1899 b Fh(int)20 b Fg(history)p -276 1283 V 20 w(expand)j Ff(\()p Fn(char)14 b(*string,)g(char)h(**output)p -Ff(\))120 1345 y Fo(Expand)20 b Fj(string)p Fo(,)f(placing)i(the)e(result)h -(in)o(to)f Fj(output)p Fo(,)h(a)f(p)q(oin)o(ter)h(to)e(a)h(string)h(\(see)f -(Section)h(1.1)120 1408 y([History)15 b(In)o(teraction],)f(page)h(1\).)20 -b(Returns:)120 1555 y Fn(0)216 b Fo(If)21 b(no)g(expansions)h(to)q(ok)e -(place)h(\(or,)g(if)h(the)f(only)g(c)o(hange)g(in)h(the)f(text)f(w)o(as)g -(the)360 1618 y(de-slashifying)d(of)e(the)g(history)h(expansion)g(c)o -(haracter\);)120 1701 y Fn(1)216 b Fo(if)16 b(expansions)g(did)g(tak)o(e)e -(place;)120 1785 y Fn(-1)192 b Fo(if)16 b(there)f(w)o(as)f(an)h(error)g(in)h -(expansion;)120 1869 y Fn(2)216 b Fo(if)14 b(the)f(returned)h(line)h(should)f -(only)g(b)q(e)f(displa)o(y)o(ed,)i(but)e(not)g(executed,)h(as)f(with)h(the) -360 1931 y Fn(:p)h Fo(mo)q(di\014er)h(\(see)f(Section)h(1.1.3)e([Mo)q -(di\014ers],)h(page)g(2\).)120 2079 y(If)g(an)h(error)e(o)q(curred)i(in)g -(expansion,)f(then)h Fj(output)g Fo(con)o(tains)f(a)g(descriptiv)o(e)i(error) -d(message.)1725 2238 y(F)l(unction)-1899 b Fh(char)20 b(*)f -Fg(history)p 347 2238 V 21 w(arg)p 449 2238 V 19 w(extract)24 -b Ff(\()p Fn(int)14 b(first,)h(int)g(last,)f(char)h(*string)p -Ff(\))120 2300 y Fo(Extract)10 b(a)h(string)g(segmen)o(t)g(consisting)h(of)f -(the)g Fj(\014rst)h Fo(through)f Fj(last)h Fo(argumen)o(ts)e(presen)o(t)h(in) -h Fj(string)p Fo(.)120 2362 y(Argumen)o(ts)j(are)g(brok)o(en)g(up)g(as)g(in)h -(Bash.)1725 2521 y(F)l(unction)-1899 b Fh(char)20 b(*)f Fg(get)p -249 2521 V 21 w(history)p 445 2521 V 20 w(ev)n(en)n(t)25 b -Ff(\()p Fn(char)14 b(*string,)g(int)h(*cindex,)f(int)h(qchar)p -Ff(\))120 2583 y Fo(Returns)e(the)f(text)f(of)h(the)g(history)g(ev)o(en)o(t)f -(b)q(eginning)k(at)c Fj(string)16 b Fn(+)c Fj(*cindex)p Fo(.)20 -b Fj(*cindex)c Fo(is)d(mo)q(di\014ed)120 2645 y(to)h(p)q(oin)o(t)h(to)f -(after)h(the)f(ev)o(en)o(t)h(sp)q(eci\014er.)21 b(A)o(t)15 -b(function)g(en)o(try)l(,)f Fj(cindex)20 b Fo(p)q(oin)o(ts)15 -b(to)f(the)h(index)h(in)o(to)p eop -%%Page: 11 13 -12 bop 0 -83 a Fo(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g(History)1017 -b(11)120 158 y Fj(string)17 b Fo(where)d(the)f(history)h(ev)o(en)o(t)f(sp)q -(eci\014cation)i(b)q(egins.)20 b Fj(qc)o(har)d Fo(is)c(a)g(c)o(haracter)g -(that)g(is)h(allo)o(w)o(ed)120 221 y(to)h(end)g(the)h(ev)o(en)o(t)f(sp)q -(eci\014cation)i(in)f(addition)g(to)f(the)g(\\normal")g(terminating)g(c)o -(haracters.)1725 394 y(F)l(unction)-1899 b Fh(char)20 b(**)f -Fg(history)p 373 394 18 3 v 21 w(tok)n(enize)25 b Ff(\()p Fn(char)14 -b(*string)p Ff(\))120 456 y Fo(Return)k(an)f(arra)o(y)f(of)h(tok)o(ens)f -(parsed)i(out)e(of)h Fj(string)p Fo(,)g(m)o(uc)o(h)h(as)e(the)i(shell)g(migh) -o(t.)26 b(The)17 b(tok)o(ens)120 519 y(are)c(split)h(on)f(white)g(space)h -(and)f(on)g(the)g(c)o(haracters)f Fn(\(\)<>;&|$)p Fo(,)g(and)h(shell)i -(quoting)e(con)o(v)o(en)o(tions)120 581 y(are)i(ob)q(ey)o(ed.)0 -840 y Fm(2.4)33 b(History)15 b(V)-6 b(ariables)62 981 y Fo(This)16 -b(section)g(describ)q(es)h(the)e(externally)h(visible)i(v)m(ariables)e(exp)q -(orted)g(b)o(y)f(the)g(GNU)g(History)g(Library)l(.)1736 1155 -y(V)l(ariable)-1899 b Fh(int)20 b Fg(history)p 276 1155 V 20 -w(base)120 1217 y Fo(The)15 b(logical)i(o\013set)d(of)h(the)g(\014rst)g(en)o -(try)g(in)h(the)f(history)g(list.)1736 1390 y(V)l(ariable)-1899 -b Fh(int)20 b Fg(history)p 276 1390 V 20 w(length)120 1453 -y Fo(The)15 b(n)o(um)o(b)q(er)h(of)f(en)o(tries)g(curren)o(tly)h(stored)f(in) -h(the)f(history)g(list.)1736 1626 y(V)l(ariable)-1899 b Fh(int)20 -b Fg(max)p 208 1626 V 19 w(input)p 360 1626 V 21 w(history)120 -1689 y Fo(The)12 b(maxim)o(um)g(n)o(um)o(b)q(er)g(of)f(history)h(en)o(tries.) -19 b(This)12 b(m)o(ust)f(b)q(e)h(c)o(hanged)g(using)h Fn(stifle_history)120 -1751 y(\(\))p Fo(.)1736 1924 y(V)l(ariable)-1899 b Fh(char)20 -b Fg(history)p 302 1924 V 20 w(expansion)p 569 1924 V 21 w(c)n(har)120 -1987 y Fo(The)15 b(c)o(haracter)g(that)f(starts)g(a)h(history)g(ev)o(en)o(t.) -20 b(The)15 b(default)h(is)g(`)p Fn(!)p Fo('.)1736 2160 y(V)l(ariable)-1899 -b Fh(char)20 b Fg(history)p 302 2160 V 20 w(subst)p 454 2160 -V 20 w(c)n(har)120 2222 y Fo(The)13 b(c)o(haracter)e(that)h(in)o(v)o(ok)o(es) -g(w)o(ord)g(substitution)h(if)g(found)g(at)e(the)i(start)e(of)h(a)g(line.)21 -b(The)12 b(default)120 2285 y(is)k(`)p Fn(^)p Fo('.)1736 2458 -y(V)l(ariable)-1899 b Fh(char)20 b Fg(history)p 302 2458 V -20 w(commen)n(t)p 552 2458 V 19 w(c)n(har)120 2521 y Fo(During)12 -b(tok)o(enization,)h(if)f(this)h(c)o(haracter)e(is)i(seen)f(as)g(the)g -(\014rst)f(c)o(haracter)g(of)h(a)g(w)o(ord,)f(then)i(it)f(and)120 -2583 y(all)19 b(subsequen)o(t)g(c)o(haracters)e(up)h(to)g(a)f(newline)j(are)e -(ignored,)h(suppressing)g(history)f(expansion)120 2645 y(for)d(the)g -(remainder)h(of)f(the)g(line.)21 b(This)16 b(is)g(disabled)h(b)o(y)e -(default.)p eop -%%Page: 12 14 -13 bop 0 -83 a Fo(12)1474 b(GNU)15 b(History)g(Library)1736 -158 y(V)l(ariable)-1899 b Fh(char)20 b(*)f Fg(history)p 347 -158 18 3 v 21 w(no)p 429 158 V 20 w(expand)p 629 158 V 20 w(c)n(hars)120 -221 y Fo(The)f(list)g(of)g(c)o(haracters)e(whic)o(h)j(inhibit)h(history)d -(expansion)i(if)f(found)g(immediately)h(follo)o(wing)120 283 -y Fj(history)p 261 283 14 2 v 16 w(expansion)p 472 283 V 18 -w(c)o(har)p Fo(.)g(The)d(default)f(is)h(whitespace)g(and)g(`)p -Fn(=)p Fo('.)0 575 y Fm(2.5)33 b(History)15 b(Programming)h(Example)62 -720 y Fo(The)g(follo)o(wing)g(program)e(demonstrates)g(simple)j(use)e(of)g -(the)g(GNU)g(History)g(Library)l(.)120 852 y Fn(main)23 b(\(\))120 -902 y({)168 951 y(char)g(line[1024],)f(*t;)168 1001 y(int)h(len,)g(done)h(=)g -(0;)168 1101 y(line[0])f(=)g(0;)168 1201 y(using_history)f(\(\);)168 -1250 y(while)h(\(!done\))215 1300 y({)263 1350 y(printf)g(\("history$)g("\);) -263 1400 y(fflush)g(\(stdout\);)263 1450 y(t)h(=)g(fgets)f(\(line,)g(sizeof)g -(\(line\))g(-)h(1,)f(stdin\);)263 1499 y(if)h(\(t)f(&&)h(*t\))311 -1549 y({)359 1599 y(len)f(=)h(strlen)f(\(t\);)359 1649 y(if)g(\(t[len)g(-)h -(1])g(==)f('\\n'\))406 1699 y(t[len)h(-)f(1])h(=)g('\\0';)311 -1748 y(})263 1848 y(if)g(\(!t\))311 1898 y(strcpy)f(\(line,)g("quit"\);)263 -1998 y(if)h(\(line[0]\))311 2047 y({)359 2097 y(char)f(*expansion;)359 -2147 y(int)g(result;)359 2247 y(result)g(=)g(history_expand)f(\(line,)h -(&expansion\);)359 2296 y(if)g(\(result\))406 2346 y(fprintf)g(\(stderr,)g -("\045s\\n",)g(expansion\);)359 2446 y(if)g(\(result)g(<)h(0)g(||)f(result)g -(==)h(2\))406 2496 y({)454 2545 y(free)f(\(expansion\);)454 -2595 y(continue;)406 2645 y(})p eop -%%Page: 13 15 -14 bop 0 -83 a Fo(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g(History)1017 -b(13)359 208 y Fn(add_history)22 b(\(expansion\);)359 258 y(strncpy)h -(\(line,)g(expansion,)f(sizeof)h(\(line\))g(-)h(1\);)359 308 -y(free)f(\(expansion\);)311 358 y(})263 457 y(if)h(\(strcmp)f(\(line,)g -("quit"\))g(==)g(0\))311 507 y(done)g(=)h(1;)263 557 y(else)f(if)h(\(strcmp)f -(\(line,)g("save"\))g(==)h(0\))311 607 y(write_history)e(\("history_file"\);) -263 656 y(else)h(if)h(\(strcmp)f(\(line,)g("read"\))g(==)h(0\))311 -706 y(read_history)e(\("history_file"\);)263 756 y(else)h(if)h(\(strcmp)f -(\(line,)g("list"\))g(==)h(0\))311 806 y({)359 856 y(register)e(HIST_ENTRY)h -(**the_list;)359 906 y(register)f(int)i(i;)359 1005 y(the_list)e(=)i -(history_list)e(\(\);)359 1055 y(if)h(\(the_list\))406 1105 -y(for)h(\(i)f(=)h(0;)g(the_list[i];)e(i++\))454 1155 y(printf)h(\("\045d:)g -(\045s\\n",)g(i)h(+)g(history_base,)e(the_list[i]->line\);)311 -1204 y(})263 1254 y(else)h(if)h(\(strncmp)f(\(line,)g("delete",)g(6\))g(==)h -(0\))311 1304 y({)359 1354 y(int)f(which;)359 1404 y(if)g(\(\(sscanf)g -(\(line)g(+)h(6,)f("\045d",)h(&which\)\))e(==)i(1\))406 1453 -y({)454 1503 y(HIST_ENTRY)f(*entry)g(=)g(remove_history)f(\(which\);)454 -1553 y(if)i(\(!entry\))502 1603 y(fprintf)f(\(stderr,)f("No)i(such)f(entry)g -(\045d\\n",)g(which\);)454 1653 y(else)502 1703 y({)550 1752 -y(free)g(\(entry->line\);)550 1802 y(free)g(\(entry\);)502 -1852 y(})406 1902 y(})359 1952 y(else)406 2001 y({)454 2051 -y(fprintf)g(\(stderr,)g("non-numeric)f(arg)h(given)h(to)f(`delete'\\n"\);)406 -2101 y(})311 2151 y(})215 2201 y(})120 2250 y(})p eop -%%Page: 14 16 -15 bop 0 -83 a Fo(14)1474 b(GNU)15 b(History)g(Library)p eop -%%Page: 15 17 -16 bop 0 -83 a Fo(App)q(endix)17 b(A:)e(Concept)g(Index)1346 -b(15)0 158 y Fk(App)r(endix)13 b(A)41 b(Concept)15 b(Index)0 -405 y Fm(A)0 471 y Fe(anc)o(hored)f(searc)o(h)5 b Fd(:)i(:)f(:)g(:)g(:)g(:)g -(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)18 b Fe(8)0 -579 y Fm(E)0 646 y Fe(ev)o(en)o(t)13 b(designators)g Fd(:)6 -b(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)23 -b Fe(1)1015 405 y(expansion)5 b Fd(:)k(:)d(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) -g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)18 b Fe(1)1015 -521 y Fm(H)1015 587 y Fe(history)d(ev)o(en)o(ts)5 b Fd(:)i(:)f(:)g(:)g(:)g(:) -g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)18 b -Fe(1)1015 646 y(History)c(Searc)o(hing)7 b Fd(:)h(:)e(:)g(:)g(:)g(:)g(:)h(:)f -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)20 b Fe(8)p eop -%%Page: 16 18 -17 bop 0 -83 a Fo(16)1474 b(GNU)15 b(History)g(Library)p eop -%%Page: 17 19 -18 bop 0 -83 a Fo(App)q(endix)17 b(B:)e(F)l(unction)h(and)g(V)l(ariable)g -(Index)1069 b(17)0 158 y Fk(App)r(endix)13 b(B)41 b(F)-7 b(unction)15 -b(and)g(V)-7 b(ariable)14 b(Index)0 405 y Fm(A)0 471 y Fc(add)p -62 471 12 2 v 13 w(history)8 b Fd(:)s(:)e(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)20 b Fe(7)0 529 y Fc(append)p -122 529 V 12 w(history)9 b Fd(:)d(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f -(:)g(:)g(:)g(:)24 b Fe(10)0 654 y Fm(C)0 720 y Fc(current)p -142 720 V 11 w(history)9 b Fd(:)d(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)24 b Fe(8)0 845 y Fm(G)0 911 y Fc(get)p 62 911 -V 13 w(history)p 215 911 V 11 w(event)9 b Fd(:)d(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f -(:)g(:)g(:)g(:)g(:)23 b Fe(10)0 1036 y Fm(H)0 1102 y Fc(history)p -142 1102 V 11 w(arg)p 213 1102 V 13 w(extract)8 b Fd(:)t(:)e(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)21 b Fe(10)0 1160 y Fc(history)p 142 1160 -V 11 w(base)e Fd(:)6 b(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) -g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h -(:)f(:)g(:)20 b Fe(11)0 1218 y Fc(history)p 142 1218 V 11 w(comment)p -293 1218 V 12 w(char)g Fd(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)21 -b Fe(11)0 1276 y Fc(history)p 142 1276 V 11 w(expand)10 b Fd(:)c(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)24 b Fe(10)0 -1335 y Fc(history)p 142 1335 V 11 w(expansion)p 333 1335 V -11 w(char)17 b Fd(:)7 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)19 b Fe(11)0 -1393 y Fc(history)p 142 1393 V 11 w(get)8 b Fd(:)d(:)h(:)g(:)g(:)g(:)g(:)h(:) -f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)20 b Fe(8)0 -1451 y Fc(history)p 142 1451 V 11 w(get)p 213 1451 V 13 w(history)p -366 1451 V 12 w(state)t Fd(:)t(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)17 b Fe(6)0 -1509 y Fc(history)p 142 1509 V 11 w(is)p 193 1509 V 14 w(stifled)7 -b Fd(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)23 b -Fe(7)0 1567 y Fc(history)p 142 1567 V 11 w(length)16 b Fd(:)6 -b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)18 -b Fe(11)0 1625 y Fc(history)p 142 1625 V 11 w(list)7 b Fd(:)t(:)g(:)f(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)19 -b Fe(7)0 1683 y Fc(history)p 142 1683 V 11 w(no)p 193 1683 -V 14 w(expand)p 327 1683 V 12 w(chars)f Fd(:)6 b(:)g(:)g(:)g(:)g(:)g(:)h(:)f -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)20 -b Fe(12)0 1741 y Fc(history)p 142 1741 V 11 w(search)t Fd(:)t(:)6 -b(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)17 -b Fe(9)0 1800 y Fc(history)p 142 1800 V 11 w(search)p 273 1800 -V 12 w(pos)9 b Fd(:)d(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)23 -b Fe(9)0 1858 y Fc(history)p 142 1858 V 11 w(search)p 273 1858 -V 12 w(prefix)6 b Fd(:)t(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)19 -b Fe(9)0 1916 y Fc(history)p 142 1916 V 11 w(set)p 213 1916 -V 13 w(history)p 366 1916 V 12 w(state)t Fd(:)t(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)17 -b Fe(6)0 1974 y Fc(history)p 142 1974 V 11 w(set)p 213 1974 -V 13 w(pos)5 b Fd(:)h(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g -(:)g(:)18 b Fe(8)0 2032 y Fc(history)p 142 2032 V 11 w(subst)p -253 2032 V 13 w(char)k Fd(:)6 b(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)24 -b Fe(11)1015 405 y Fc(history)p 1157 405 V 12 w(tokenize)9 -b Fd(:)s(:)d(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)22 -b Fe(11)1015 463 y Fc(history)p 1157 463 V 12 w(total)p 1269 -463 V 12 w(bytes)9 b Fd(:)t(:)d(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)22 -b Fe(8)1015 521 y Fc(history)p 1157 521 V 12 w(truncate)p 1329 -521 V 11 w(file)5 b Fd(:)g(:)h(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:) -f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)19 -b Fe(10)1015 629 y Fm(M)1015 695 y Fc(max)p 1077 695 V 13 w(input)p -1190 695 V 13 w(history)14 b Fd(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g -(:)g(:)17 b Fe(11)1015 803 y Fm(N)1015 870 y Fc(next)p 1097 -870 V 13 w(history)7 b Fd(:)s(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)20 b Fe(8)1015 978 y Fm(P)1015 1044 -y Fc(previous)p 1177 1044 V 12 w(history)7 b Fd(:)f(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h -(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)23 b Fe(8)1015 1152 y Fm(R)1015 -1218 y Fc(read)p 1097 1218 V 13 w(history)7 b Fd(:)s(:)f(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)20 b Fe(9)1015 -1276 y Fc(read)p 1097 1276 V 13 w(history)p 1250 1276 V 11 -w(range)9 b Fd(:)d(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:) -g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)23 -b Fe(9)1015 1335 y Fc(remove)p 1137 1335 V 12 w(history)t Fd(:)t(:)6 -b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)17 -b Fe(7)1015 1393 y Fc(replace)p 1157 1393 V 12 w(history)p -1309 1393 V 11 w(entry)6 b Fd(:)f(:)h(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h -(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)19 -b Fe(7)1015 1501 y Fm(S)1015 1567 y Fc(stifle)p 1137 1567 V -12 w(history)t Fd(:)t(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h -(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g -(:)g(:)g(:)g(:)17 b Fe(7)1015 1675 y Fm(U)1015 1741 y Fc(unstifle)p -1177 1741 V 12 w(history)7 b Fd(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h -(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g -(:)g(:)g(:)g(:)23 b Fe(7)1015 1800 y Fc(using)p 1117 1800 V -13 w(history)5 b Fd(:)s(:)h(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)h(:)f(:)g(:)18 b Fe(6)1015 1907 y Fm(W)1015 1974 y Fc(where)p -1117 1974 V 13 w(history)5 b Fd(:)s(:)h(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)18 b Fe(8)1015 2032 y Fc(write)p -1117 2032 V 13 w(history)5 b Fd(:)s(:)h(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g -(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)18 b Fe(9)p eop -%%Page: 18 20 -19 bop 0 -83 a Fo(18)1474 b(GNU)15 b(History)g(Library)p eop -%%Page: -1 21 -20 bop 1937 -83 a Fo(i)0 158 y Fk(T)-7 b(able)15 b(of)g(Con)n(ten)n(ts)0 -333 y Fm(1)67 b(Using)22 b(History)h(In)n(teractiv)n(ely)9 -b Fb(:)k(:)d(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g -(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)31 b Fm(1)149 411 y Fo(1.1)45 -b(History)15 b(In)o(teraction)9 b Fa(:)f(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g -(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g -(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)23 -b Fo(1)299 473 y(1.1.1)44 b(Ev)o(en)o(t)14 b(Designators)6 -b Fa(:)h(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g -(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f -(:)g(:)g(:)20 b Fo(1)299 535 y(1.1.2)44 b(W)l(ord)15 b(Designators)9 -b Fa(:)d(:)h(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h -(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g -(:)h(:)f(:)23 b Fo(2)299 597 y(1.1.3)44 b(Mo)q(di\014ers)14 -b Fa(:)8 b(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:) -g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g -(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)28 b Fo(2)0 722 -y Fm(2)67 b(Programming)23 b(with)g(GNU)f(History)13 b Fb(:)e(:)f(:)g(:)g(:)h -(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)36 b -Fm(5)149 800 y Fo(2.1)45 b(In)o(tro)q(duction)16 b(to)f(History)6 -b Fa(:)h(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g -(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f -(:)g(:)g(:)g(:)h(:)f(:)g(:)20 b Fo(5)149 862 y(2.2)45 b(History)15 -b(Storage)d Fa(:)7 b(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g -(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f -(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)27 -b Fo(5)149 924 y(2.3)45 b(History)15 b(F)l(unctions)c Fa(:)d(:)f(:)h(:)f(:)g -(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f -(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h -(:)f(:)g(:)g(:)g(:)h(:)25 b Fo(6)299 986 y(2.3.1)44 b(Initializing)18 -b(History)d(and)h(State)e(Managemen)o(t)f Fa(:)7 b(:)g(:)g(:)h(:)f(:)g(:)g(:) -g(:)h(:)f(:)g(:)g(:)g(:)h(:)27 b Fo(6)299 1049 y(2.3.2)44 b(History)15 -b(List)h(Managemen)o(t)c Fa(:)7 b(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h -(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g -(:)28 b Fo(7)299 1111 y(2.3.3)44 b(Information)15 b(Ab)q(out)g(the)h(History) -f(List)5 b Fa(:)i(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g -(:)g(:)g(:)h(:)f(:)g(:)g(:)19 b Fo(7)299 1173 y(2.3.4)44 b(Mo)o(ving)15 -b(Around)g(the)g(History)g(List)6 b Fa(:)i(:)f(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:) -g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)20 -b Fo(8)299 1236 y(2.3.5)44 b(Searc)o(hing)16 b(the)f(History)g(List)7 -b Fa(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f -(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)21 b -Fo(8)299 1298 y(2.3.6)44 b(Managing)15 b(the)g(History)g(File)5 -b Fa(:)j(:)f(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g -(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)19 b -Fo(9)299 1360 y(2.3.7)44 b(History)15 b(Expansion)d Fa(:)7 -b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g -(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)26 -b Fo(10)149 1422 y(2.4)45 b(History)15 b(V)l(ariables)5 b Fa(:)k(:)e(:)g(:)g -(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g -(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f -(:)g(:)g(:)g(:)h(:)f(:)g(:)20 b Fo(11)149 1485 y(2.5)45 b(History)15 -b(Programming)f(Example)8 b Fa(:)g(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:) -g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f -(:)g(:)g(:)g(:)23 b Fo(12)0 1609 y Fm(App)r(endix)h(A)67 b(Concept)22 -b(Index)15 b Fb(:)c(:)f(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g -(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)37 b Fm(15)0 1749 -y(App)r(endix)24 b(B)67 b(F)-6 b(unction)25 b(and)e(V)-6 b(ariable)24 -b(Index)8 b Fb(:)j(:)f(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)31 -b Fm(17)p eop -%%Page: -2 22 -21 bop 0 -83 a Fo(ii)1496 b(GNU)15 b(History)g(Library)p eop -%%Trailer -end -userdict /end-hook known{end-hook}if -%%EOF diff --git a/lib/readline/doc/rlman.texinfo b/lib/readline/doc/rlman.texinfo index ec14066..655f3db 100644 --- a/lib/readline/doc/rlman.texinfo +++ b/lib/readline/doc/rlman.texinfo @@ -7,13 +7,13 @@ @setchapternewpage odd @ignore -last change: Thu Jul 21 16:02:40 EDT 1994 +last change: Thu Mar 21 16:06:39 EST 1996 @end ignore -@set EDITION 2.0 -@set VERSION 2.0 -@set UPDATED 21 July 1994 -@set UPDATE-MONTH July 1994 +@set EDITION 2.1 +@set VERSION 2.1 +@set UPDATED 21 March 1996 +@set UPDATE-MONTH March 1996 @ifinfo This document describes the GNU Readline Library, a utility which aids @@ -45,7 +45,6 @@ by the Foundation. @end ifinfo @titlepage -@sp 10 @title GNU Readline Library @subtitle Edition @value{EDITION}, for @code{Readline Library} Version @value{VERSION}. @subtitle @value{UPDATE-MONTH} diff --git a/lib/readline/doc/rltech.texinfo b/lib/readline/doc/rltech.texinfo index 636c923..6704d0e 100644 --- a/lib/readline/doc/rltech.texinfo +++ b/lib/readline/doc/rltech.texinfo @@ -8,7 +8,7 @@ This document describes the GNU Readline Library, a utility for aiding in the consitency of user interface across discrete programs that need to provide a command line interface. -Copyright (C) 1988, 1994 Free Software Foundation, Inc. +Copyright (C) 1988, 1994, 1996 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice @@ -273,6 +273,10 @@ The prompt Readline uses. This is set from the argument to @code{readline ()}, and should not be assigned to directly. @end deftypevar +@deftypevar {char *} rl_library_version +The version number of this revision of the library. +@end deftypevar + @deftypevar {char *} rl_terminal_name The terminal type, used for initialization. @end deftypevar @@ -301,6 +305,30 @@ If non-zero, this is the address of a function to call periodically when readline is waiting for terminal input. @end deftypevar +@deftypevar {Function *} rl_getc_function +If non-zero, @code{readline} will call indirectly through this pointer +to get a character from the input stream. By default, it is set to +@code{rl_getc}, the default @code{readline} character input function +(@pxref{Utility Functions}). +@end deftypevar + +@deftypevar {Function *} rl_redisplay_function +If non-zero, @code{readline} will call indirectly through this pointer +to update the display with the current contents of the editing buffer. +By default, it is set to @code{rl_redisplay}, the default @code{readline} +redisplay function (@pxref{Redisplay}). +@end deftypevar + +@deftypevar {Keymap} rl_executing_keymap +This variable is set to the keymap (@pxref{Keymaps}) in which the +currently executing readline function was found. +@end deftypevar + +@deftypevar {Keymap} rl_binding_keymap +This variable is set to the keymap (@pxref{Keymaps}) in which the +last key binding occurred. +@end deftypevar + @node Readline Convenience Functions @section Readline Convenience Functions @@ -314,6 +342,7 @@ when readline is waiting for terminal input. * Redisplay:: Functions to control line display. * Modifying Text:: Functions to modify @code{rl_line_buffer}. * Utility Functions:: Generally useful functions and hooks. +* Alternate Interface:: Using Readline in a `callback' fashion. @end menu @node Function Naming @@ -611,6 +640,10 @@ the input stream via @var{pending input} (@pxref{Readline Variables}) and @code{rl_stuff_char ()}, macros, and characters read from the keyboard. @end deftypefun +@deftypefun int rl_getc (FILE *) +Return the next character available from the keyboard. +@end deftypefun + @deftypefun int rl_stuff_char (int c) Insert @var{c} into the Readline input stream. It will be "read" before Readline attempts to read characters from the terminal with @@ -666,6 +699,37 @@ lowercase character. If @var{c} is a number, return the value it represents. @end deftypefun +@node Alternate Interface +@subsection Alternate Interface + +An alternate interface is available to plain @code{readline()}. Some +applications need to interleave keyboard I/O with file, device, or +window system I/O, typically by using a main loop to @code{select()} +on various file descriptors. To accomodate this need, readline can +also be invoked as a `callback' function from an event loop. There +are functions available to make this easy. + +@deftypefun void rl_callback_handler_install (char *prompt, Vfunction *lhandler) +Set up the terminal for readline I/O and display the initial +expanded value of @var{prompt}. Save the value of @var{lhandler} to +use as a callback when a complete line of input has been entered. +@end deftypefun + +@deftypefun void rl_callback_read_char () +Whenever an application determines that keyboard input is available, it +should call @code{rl_callback_read_char()}, which will read the next +character from the current input source. If that character completes the +line, @code{rl_callback_read_char} will invoke the @var{lhandler} +function saved by @code{rl_callback_handler_install} to process the +line. @code{EOF} is indicated by calling @var{lhandler} with a +@code{NULL} line. +@end deftypefun + +@deftypefun void rl_callback_handler_remove () +Restore the terminal to its initial state and remove the line handler. +This may be called from within a callback as well as independently. +@end deftypefun + @subsection An Example Here is a function which changes lowercase characters to their uppercase @@ -894,6 +958,40 @@ returns @code{NULL}, or if this variable is set to @code{NULL}, then array of strings returned will be used. @end deftypevar +@deftypevar {CPFunction *} rl_filename_quoting_function +A pointer to a function that will quote a filename in an application- +specific fashion. This is called if filename completion is being +attempted and one of the characters in @code{rl_filename_quote_characters} +appears in a completed filename. The function is called with +@var{text}, @var{match_type}, and @var{quote_pointer}. The @var{text} +is the filename to be quoted. The @var{match_type} is either +@code{SINGLE_MATCH}, if there is only one completion match, or +@code{MULT_MATCH}. Some functions use this to decide whether or not to +insert a closing quote character. The @var{quote_pointer} is a pointer +to any opening quote character the user typed. Some functions choose +to reset this character. +@end deftypevar + +@deftypevar {CPFunction *} rl_filename_dequoting_function +A pointer to a function that will remove application-specific quoting +characters from a filename before completion is attempted, so those +characters do not interfere with matching the text against names in +the filesystem. It is called with @var{text}, the text of the word +to be dequoted, and @var{quote_char}, which is the quoting character +that delimits the filename (usually @samp{'} or @samp{"}). If +@var{quote_char} is zero, the filename was not in an embedded string. +@end deftypevar + +@deftypevar {Function *} rl_char_is_quoted_p +A pointer to a function to call that determines whether or not a specific +character in the line buffer is quoted, according to whatever quoting +mechanism the program calling readline uses. The function is called with +two arguments: @var{text}, the text of the line, and @var{index}, the +index of the character in the line. It is used to decide whether a +character found in @code{rl_completer_word_break_characters} should be +used to break words for the completer. +@end deftypevar + @deftypevar int rl_completion_query_items Up to this many items will be displayed in response to a possible-completions call. After that, we ask the user if she is sure @@ -907,6 +1005,10 @@ which break words for completion in Bash, i.e., @code{" \t\n\"\\'`@@$><=;|&@{("}. @end deftypevar +@deftypevar {char *} rl_basic_quote_characters +List of quote characters which can cause a word break. +@end deftypevar + @deftypevar {char *} rl_completer_word_break_characters The list of characters that signal a break between words for @code{rl_complete_internal ()}. The default list is the value of @@ -920,6 +1022,11 @@ Completion occurs on the entire substring, and within the substring unless they also appear within this list. @end deftypevar +@deftypevar {char *} rl_filename_quote_characters +A list of characters that cause a filename to be quoted by the completer +when they appear in a completed filename. The default is empty. +@end deftypevar + @deftypevar {char *} rl_special_prefixes The list of characters that are word break characters, but should be left in @var{text} when it is passed to the completion function. @@ -928,6 +1035,16 @@ For instance, Bash sets this variable to "$@@" so that it can complete shell variables and hostnames. @end deftypevar +@deftypevar {int} rl_completion_append_character +When a single completion alternative matches at the end of the command +line, this character is appended to the inserted completion text. The +default is a space character (@samp{ }). Setting this to the null +character (@samp{\0}) prevents anything being appended automatically. +This can be changed in custom completion functions to +provide the ``most sensible word separator character'' according to +an application-specific command line syntax specification. +@end deftypevar + @deftypevar int rl_ignore_completion_duplicates If non-zero, then disallow duplicates in the matches. Default is 1. @end deftypevar @@ -945,9 +1062,15 @@ characters. Non-zero means that the results of the matches are to be quoted using double quotes (or an application-specific quoting mechanism) if the completed filename contains any characters in -@code{rl_completer_word_break_chars}. This is @emph{always} non-zero +@code{rl_filename_quote_chars}. This is @emph{always} non-zero on entry, and can only be changed within a completion entry generator -function. +function. The quoting is effected via a call to the function pointed to +by @code{rl_filename_quoting_function}. +@end deftypevar + +@deftypevar int rl_inhibit_completion +If this variable is non-zero, completion is inhibited. The completion +character will be inserted as any other bound to @code{self-insert}. @end deftypevar @deftypevar {Function *} rl_ignore_some_completions_function @@ -1174,10 +1297,11 @@ initialize_readline () rl_attempted_completion_function = (CPPFunction *)fileman_completion; @} -/* Attempt to complete on the contents of TEXT. START and END show the - region of TEXT that contains the word to complete. We can use the - entire line in case we want to do some simple parsing. Return the - array of matches, or NULL if there aren't any. */ +/* Attempt to complete on the contents of TEXT. START and END bound the + region of rl_line_buffer that contains the word to complete. TEXT is + the word to complete. We can use the entire contents of rl_line_buffer + in case we want to do some simple parsing. Return the array of matches, + or NULL if there aren't any. */ char ** fileman_completion (text, start, end) char *text; diff --git a/lib/readline/doc/rluser.texinfo b/lib/readline/doc/rluser.texinfo index 3567549..65111f3 100644 --- a/lib/readline/doc/rluser.texinfo +++ b/lib/readline/doc/rluser.texinfo @@ -10,7 +10,7 @@ use these features. There is a document entitled "readline.texinfo" which contains both end-user and programmer documentation for the GNU Readline Library. -Copyright (C) 1988 Free Software Foundation, Inc. +Copyright (C) 1988, 1991, 1993, 1996 Free Software Foundation, Inc. Authored by Brian Fox and Chet Ramey. @@ -39,7 +39,7 @@ into another language, under the above conditions for modified versions. @node Command Line Editing @chapter Command Line Editing -This chapter describes the basic features of the GNU +This chapter describes the basic features of the @sc{GNU} command line editing interface. @menu @@ -59,11 +59,12 @@ The following paragraphs describe the notation used to represent keystrokes. The text @key{C-k} is read as `Control-K' and describes the character -produced when the Control key is depressed and the @key{k} key is struck. +produced when the @key{k} key is pressed while the Control key +is depressed. The text @key{M-k} is read as `Meta-K' and describes the character produced when the meta key (if you have one) is depressed, and the @key{k} -key is struck. If you do not have a meta key, the identical keystroke +key is pressed. If you do not have a meta key, the identical keystroke can be generated by typing @key{ESC} @i{first}, and then typing @key{k}. Either process is known as @dfn{metafying} the @key{k} key. @@ -73,7 +74,7 @@ character produced by @dfn{metafying} @key{C-k}. In addition, several keys have their own names. Specifically, @key{DEL}, @key{ESC}, @key{LFD}, @key{SPC}, @key{RET}, and @key{TAB} all stand for themselves when seen in this text, or in an init file -(@pxref{Readline Init File}, for more info). +(@pxref{Readline Init File}). @node Readline Interaction @section Readline Interaction @@ -95,10 +96,14 @@ regardless of the location of the cursor within the line. * Readline Movement Commands:: Moving about the input line. * Readline Killing Commands:: How to delete text, and how to get it back! * Readline Arguments:: Giving numeric arguments to commands. -@end menu +* Searching:: Searching through previous lines. + @end menu @node Readline Bare Essentials @subsection Readline Bare Essentials +@cindex notation, readline +@cindex command editing +@cindex editing command lines In order to enter characters into the line, simply type them. The typed character appears where the cursor was, and then the cursor moves one @@ -164,8 +169,8 @@ operate on characters while meta keystrokes operate on words. @node Readline Killing Commands @subsection Readline Killing Commands -@cindex Killing text -@cindex Yanking text +@cindex killing text +@cindex yanking text @dfn{Killing} text means to delete the text from the line, but to save it away for later use, usually by @dfn{yanking} (re-inserting) @@ -180,7 +185,7 @@ that when you yank it back, you get it all. The kill ring is not line specific; the text that you killed on a previously typed line is available to be yanked back later, when you are typing another line. -@cindex Kill ring +@cindex kill ring Here is the list of commands for killing text. @@ -222,24 +227,59 @@ argument acts as a repeat count, other times it is the @i{sign} of the argument that is significant. If you pass a negative argument to a command which normally acts in a forward direction, that command will act in a backward direction. For example, to kill text back to the -start of the line, you might type @key{M--} @key{C-k}. +start of the line, you might type @w{@kbd{M-- C-k}}. The general way to pass numeric arguments to a command is to type meta digits before the command. If the first `digit' you type is a minus sign (@key{-}), then the sign of the argument will be negative. Once you have typed one meta digit to get the argument started, you can type the remainder of the digits, and then the command. For example, to give -the @key{C-d} command an argument of 10, you could type @key{M-1 0 C-d}. +the @key{C-d} command an argument of 10, you could type @samp{M-1 0 C-d}. + +@node Searching +@subsection Searching for Commands in the History +Readline provides commands for searching through the command history +@ifset BashFeatures +(@pxref{Bash History Facilities}) +@end ifset +for lines containing a specified string. +There are two search modes: @var{incremental} and @var{non-incremental}. + +Incremental searches begin before the user has finished typing the +search string. +As each character of the search string is typed, readline displays +the next entry from the history matching the string typed so far. +An incremental search requires only as many characters as needed to +find the desired history entry. +The Escape character is used to terminate an incremental search. +Control-J will also terminate the search. +Control-G will abort an incremental search and restore the original +line. +When the search is terminated, the history entry containing the +search string becomes the current line. +To find other matching entries in the history list, type Control-S or +Control-R as appropriate. +This will search backward or forward in the history for the next +entry matching the search string typed so far. +Any other key sequence bound to a readline command will terminate +the search and execute that command. +For instance, a @code{newline} will terminate the search and accept +the line, thereby executing the command from the history list. + +Non-incremental searches read the entire search string before starting +to search for matching history lines. The search string may be +typed by the user or part of the contents of the current line. @node Readline Init File @section Readline Init File +@cindex initialization file, readline -Although the Readline library comes with a set of Emacs-like +Although the Readline library comes with a set of @code{emacs}-like keybindings installed by default, it is possible that you would like to use a different set of keybindings. You can customize programs that use Readline by putting -commands in an @dfn{init} file in your home directory. The name of this +commands in an @dfn{inputrc} file in your home directory. The name of this @ifset BashFeatures file is taken from the value of the shell variable @code{INPUTRC}. If @end ifset @@ -255,17 +295,20 @@ In addition, the @code{C-x C-r} command re-reads this init file, thus incorporating any changes that you might have made to it. @menu -* Readline Init Syntax:: Syntax for the commands in the inputrc file. +* Readline Init File Syntax:: Syntax for the commands in the inputrc file. + * Conditional Init Constructs:: Conditional key bindings in the inputrc file. + +* Sample Init File:: An example inputrc file. @end menu -@node Readline Init Syntax -@subsection Readline Init Syntax +@node Readline Init File Syntax +@subsection Readline Init File Syntax There are only a few basic constructs allowed in the Readline init file. Blank lines are ignored. -Lines beginning with a @key{#} are comments. -Lines beginning with a @key{$} indicate conditional +Lines beginning with a @samp{#} are comments. +Lines beginning with a @samp{$} indicate conditional constructs (@pxref{Conditional Init Constructs}). Other lines denote variable settings and key bindings. @@ -284,61 +327,20 @@ so few, in fact, that we just list them here: @table @code -@item editing-mode -@vindex editing-mode -The @code{editing-mode} variable controls which editing mode you are -using. By default, Readline starts up in Emacs editing mode, where -the keystrokes are most similar to Emacs. This variable can be -set to either @code{emacs} or @code{vi}. - -@item horizontal-scroll-mode -@vindex horizontal-scroll-mode -This variable can be set to either @code{On} or @code{Off}. Setting it -to @code{On} means that the text of the lines that you edit will scroll -horizontally on a single screen line when they are longer than the width -of the screen, instead of wrapping onto a new screen line. By default, -this variable is set to @code{Off}. - -@item mark-modified-lines -@vindex mark-modified-lines -This variable, when set to @code{On}, says to display an asterisk -(@samp{*}) at the start of history lines which have been modified. -This variable is @code{off} by default. - @item bell-style @vindex bell-style Controls what happens when Readline wants to ring the terminal bell. -If set to @code{none}, Readline never rings the bell. If set to -@code{visible}, Readline uses a visible bell if one is available. -If set to @code{audible} (the default), Readline attempts to ring +If set to @samp{none}, Readline never rings the bell. If set to +@samp{visible}, Readline uses a visible bell if one is available. +If set to @samp{audible} (the default), Readline attempts to ring the terminal's bell. @item comment-begin @vindex comment-begin The string to insert at the beginning of the line when the -@code{vi-comment} command is executed. The default value +@code{insert-comment} command is executed. The default value is @code{"#"}. -@item meta-flag -@vindex meta-flag -If set to @code{on}, Readline will enable eight-bit input (it -will not strip the eighth bit from the characters it reads), -regardless of what the terminal claims it can support. The -default value is @code{off}. - -@item convert-meta -@vindex convert-meta -If set to @code{on}, Readline will convert characters with the -eigth bit set to an ASCII key sequence by stripping the eigth -bit and prepending an @key{ESC} character, converting them to a -meta-prefixed key sequence. The default value is @code{on}. - -@item output-meta -@vindex output-meta -If set to @code{on}, Readline will display characters with the -eighth bit set directly rather than as a meta-prefixed escape -sequence. The default is @code{off}. - @item completion-query-items @vindex completion-query-items The number of possible completions that determines when the user is @@ -348,6 +350,45 @@ Readline will ask the user whether or not he wishes to view them; otherwise, they are simply listed. The default limit is @code{100}. +@item convert-meta +@vindex convert-meta +If set to @samp{on}, Readline will convert characters with the +eigth bit set to an ASCII key sequence by stripping the eigth +bit and prepending an @key{ESC} character, converting them to a +meta-prefixed key sequence. The default value is @samp{on}. + +@item disable-completion +@vindex disable-completion +If set to @samp{On}, readline will inhibit word completion. +Completion characters will be inserted into the line as if they had +been mapped to @code{self-insert}. The default is @samp{off}. + +@item editing-mode +@vindex editing-mode +The @code{editing-mode} variable controls which editing mode you are +using. By default, Readline starts up in Emacs editing mode, where +the keystrokes are most similar to Emacs. This variable can be +set to either @samp{emacs} or @samp{vi}. + +@item enable-keypad +@vindex enable-keypad +When set to @samp{on}, readline will try to enable the application +keypad when it is called. Some systems need this to enable the +arrow keys. The default is @samp{off}. + +@item expand-tilde +@vindex expand-tilde +If set to @samp{on}, tilde expansion is performed when Readline +attempts word completion. The default is @samp{off}. + +@item horizontal-scroll-mode +@vindex horizontal-scroll-mode +This variable can be set to either @samp{on} or @samp{off}. Setting it +to @samp{on} means that the text of the lines that you edit will scroll +horizontally on a single screen line when they are longer than the width +of the screen, instead of wrapping onto a new screen line. By default, +this variable is set to @samp{off}. + @item keymap @vindex keymap Sets Readline's idea of the current keymap for key binding commands. @@ -357,7 +398,6 @@ Acceptable @code{keymap} names are @code{emacs-meta}, @code{emacs-ctlx}, @code{vi}, -@code{vi-move}, @code{vi-command}, and @code{vi-insert}. @code{vi} is equivalent to @code{vi-command}; @code{emacs} is @@ -365,18 +405,44 @@ equivalent to @code{emacs-standard}. The default value is @code{emacs}. The value of the @code{editing-mode} variable also affects the default keymap. +@item mark-directories +If set to @samp{on}, completed directory names have a slash +appended. The default is @samp{on}. + +@item mark-modified-lines +@vindex mark-modified-lines +This variable, when set to @samp{on}, says to display an asterisk +(@samp{*}) at the start of history lines which have been modified. +This variable is @samp{off} by default. + +@item input-meta +@vindex input-meta +@vindex meta-flag +If set to @samp{on}, Readline will enable eight-bit input (it +will not strip the eighth bit from the characters it reads), +regardless of what the terminal claims it can support. The +default value is @samp{off}. The name @code{meta-flag} is a +synonym for this variable. + +@item output-meta +@vindex output-meta +If set to @samp{on}, Readline will display characters with the +eighth bit set directly rather than as a meta-prefixed escape +sequence. The default is @samp{off}. + @item show-all-if-ambiguous @vindex show-all-if-ambiguous This alters the default behavior of the completion functions. If -set to @code{on}, +set to @samp{on}, words which have more than one possible completion cause the matches to be listed immediately instead of ringing the bell. -The default value is @code{off}. +The default value is @samp{off}. -@item expand-tilde -@vindex expand-tilde -If set to @code{on}, tilde expansion is performed when Readline -attempts word completion. The default is @code{off}. +@item visible-stats +@vindex visible-stats +If set to @samp{on}, a character denoting a file's type +is appended to the filename when listing possible +completions. The default is @samp{off}. @end table @@ -399,13 +465,13 @@ comfortable for you. @example Control-u: universal-argument Meta-Rubout: backward-kill-word -Control-o: ">&output" +Control-o: "> output" @end example In the above example, @samp{C-u} is bound to the function @code{universal-argument}, and @samp{C-o} is bound to run the macro expressed on the right hand side (that is, to insert the text -@samp{>&output} into the line). +@samp{> output} into the line). @item @w{"@var{keyseq}": @var{function-name} or @var{macro}} @var{keyseq} differs from @var{keyname} above in that strings @@ -445,10 +511,10 @@ backslash When entering the text of a macro, single or double quotes should be used to indicate a macro definition. Unquoted text is assumed to be a function name. Backslash -will quote any character in the macro text, including @key{"} -and @key{'}. -For example, the following binding will make @kbd{C-x \} -insert a single @key{\} into the line: +will quote any character in the macro text, including @samp{"} +and @samp{'}. +For example, the following binding will make @samp{C-x \} +insert a single @samp{\} into the line: @example "\C-x\\": "\\" @end example @@ -464,7 +530,7 @@ compilation features of the C preprocessor which allows key bindings and variable settings to be performed as the result of tests. There are three parser directives used. -@ftable @code +@table @code @item $if The @code{$if} construct allows bindings to be made based on the editing mode, the terminal being used, or the application using @@ -486,7 +552,7 @@ key bindings, perhaps to bind the key sequences output by the terminal's function keys. The word on the right side of the @samp{=} is tested against the full name of the terminal and the portion of the terminal name before the first @samp{-}. This -allows @var{sun} to match both @var{sun} and @var{sun-cmd}, +allows @code{sun} to match both @code{sun} and @code{sun-cmd}, for instance. @item application @@ -497,7 +563,7 @@ This could be used to bind key sequences to functions useful for a specific program. For instance, the following command adds a key sequence that quotes the current or previous word in Bash: @example -$if bash +$if Bash # Quote the current or previous word "\C-xq": "\eb\"\ef\"" $endif @@ -511,7 +577,109 @@ This command, as you saw in the previous example, terminates an @item $else Commands in this branch of the @code{$if} directive are executed if the test fails. -@end ftable +@end table + +@node Sample Init File +@subsection Sample Init File + +Here is an example of an inputrc file. This illustrates key +binding, variable assignment, and conditional syntax. + +@example +@page +# This file controls the behaviour of line input editing for +# programs that use the Gnu Readline library. Existing programs +# include FTP, Bash, and Gdb. +# +# You can re-read the inputrc file with C-x C-r. +# Lines beginning with '#' are comments. +# +# Set various bindings for emacs mode. + +set editing-mode emacs + +$if mode=emacs + +Meta-Control-h: backward-kill-word Text after the function name is ignored + +# +# Arrow keys in keypad mode +# +#"\M-OD" backward-char +#"\M-OC" forward-char +#"\M-OA" previous-history +#"\M-OB" next-history +# +# Arrow keys in ANSI mode +# +"\M-[D" backward-char +"\M-[C" forward-char +"\M-[A" previous-history +"\M-[B" next-history +# +# Arrow keys in 8 bit keypad mode +# +#"\M-\C-OD" backward-char +#"\M-\C-OC" forward-char +#"\M-\C-OA" previous-history +#"\M-\C-OB" next-history +# +# Arrow keys in 8 bit ANSI mode +# +#"\M-\C-[D" backward-char +#"\M-\C-[C" forward-char +#"\M-\C-[A" previous-history +#"\M-\C-[B" next-history + +C-q: quoted-insert + +$endif + +# An old-style binding. This happens to be the default. +TAB: complete + +# Macros that are convenient for shell interaction +$if Bash +# edit the path +"\C-xp": "PATH=$@{PATH@}\e\C-e\C-a\ef\C-f" +# prepare to type a quoted word -- insert open and close double quotes +# and move to just after the open quote +"\C-x\"": "\"\"\C-b" +# insert a backslash (testing backslash escapes in sequences and macros) +"\C-x\\": "\\" +# Quote the current or previous word +"\C-xq": "\eb\"\ef\"" +# Add a binding to refresh the line, which is unbound +"\C-xr": redraw-current-line +# Edit variable on current line. +"\M-\C-v": "\C-a\C-k$\C-y\M-\C-e\C-a\C-y=" +$endif + +# use a visible bell if one is available +set bell-style visible + +# don't strip characters to 7 bits when reading +set input-meta on + +# allow iso-latin1 characters to be inserted rather than converted to +# prefix-meta sequences +set convert-meta off + +# display characters with the eighth bit set directly rather than +# as meta-prefixed characters +set output-meta on + +# if there are more than 150 possible completions for a word, ask the +# user if he wants to see all of them +set completion-query-items 150 + +# For FTP +$if Ftp +"\C-xg": "get \M-?" +"\C-xt": "put \M-?" +"\M-.": yank-last-arg +$endif +@end example @node Bindable Readline Commands @section Bindable Readline Commands @@ -527,6 +695,9 @@ the test fails. * Miscellaneous Commands:: Other miscellaneous commands. @end menu +This section describes Readline commands that may be bound to key +sequences. + @node Commands For Moving @subsection Commands For Moving @ftable @code @@ -608,12 +779,13 @@ for a string supplied by the user. @item history-search-forward () Search forward through the history for the string of characters -between the start of the current line and the current point. This -is a non-incremental search. By default, this command is unbound. +between the start of the current line and the current cursor +position (the `point'). This is a non-incremental search. By +default, this command is unbound. @item history-search-backward () Search backward through the history for the string of characters -between the start of the current line and the current point. This +between the start of the current line and the point. This is a non-incremental search. By default, this command is unbound. @item yank-nth-arg (M-C-y) @@ -624,8 +796,8 @@ in the previous command begin with word 0). A negative argument inserts the @var{n}th word from the end of the previous command. @item yank-last-arg (M-., M-_) -Insert last argument to the previous command (the last word on the -previous line). With an +Insert last argument to the previous command (the last word of the +previous history entry). With an argument, behave exactly like @code{yank-nth-arg}. @end ftable @@ -637,7 +809,7 @@ argument, behave exactly like @code{yank-nth-arg}. @item delete-char (C-d) Delete the character under the cursor. If the cursor is at the beginning of the line, there are no characters in the line, and -the last character typed was not C-d, then return EOF. +the last character typed was not @kbd{C-d}, then return @code{EOF}. @item backward-delete-char (Rubout) Delete the character behind the cursor. A numeric arg says to kill @@ -714,6 +886,23 @@ boundary. The killed text is saved on the kill-ring. @item delete-horizontal-space () Delete all spaces and tabs around point. By default, this is unbound. +@item kill-region () +Kill the text between the point and the @emph{mark} (saved +cursor position. This text is referred to as the @var{region}. +By default, this command is unbound. + +@item copy-region-as-kill () +Copy the text in the region to the kill buffer, so you can yank it +right away. By default, this command is unbound. + +@item copy-backward-word () +Copy the word before point to the kill buffer. +By default, this command is unbound. + +@item copy-forward-word () +Copy the word following point to the kill buffer. +By default, this command is unbound. + @item yank (C-y) Yank the top of the kill ring into the buffer at the current cursor position. @@ -729,7 +918,7 @@ the prior command is yank or yank-pop. @item digit-argument (M-0, M-1, ... M--) Add this digit to the argument already accumulating, or start a new -argument. M-- starts a negative argument. +argument. @key{M--} starts a negative argument. @item universal-argument () Each time this is executed, the argument count is multiplied by four. @@ -750,18 +939,74 @@ you can do command completion, if you are typing in a symbol to GDB, you can do symbol name completion, if you are typing in a variable to Bash, you can do variable name completion, and so on. @ifset BashFeatures -See the Bash manual page for a complete list of available completion -functions. +Bash attempts completion treating the text as a variable (if the +text begins with @samp{$}), username (if the text begins with +@samp{~}), hostname (if the text begins with @samp{@@}), or +command (including aliases and functions) in turn. If none +of these produces a match, filename completion is attempted. @end ifset @item possible-completions (M-?) List the possible completions of the text before the cursor. -@item insert-completions () +@item insert-completions (M-*) Insert all completions of the text before point that would have -been generated by @code{possible-completions}. By default, this -is not bound to a key. +been generated by @code{possible-completions}. +@ifset BashFeatures +@item complete-filename (M-/) +Attempt filename completion on the text before point. + +@item possible-filename-completions (C-x /) +List the possible completions of the text before point, +treating it as a filename. + +@item complete-username (M-~) +Attempt completion on the text before point, treating +it as a username. + +@item possible-username-completions (C-x ~) +List the possible completions of the text before point, +treating it as a username. + +@item complete-variable (M-$) +Attempt completion on the text before point, treating +it as a shell variable. + +@item possible-variable-completions (C-x $) +List the possible completions of the text before point, +treating it as a shell variable. + +@item complete-hostname (M-@@) +Attempt completion on the text before point, treating +it as a hostname. + +@item possible-hostname-completions (C-x @@) +List the possible completions of the text before point, +treating it as a hostname. + +@item complete-command (M-!) +Attempt completion on the text before point, treating +it as a command name. Command completion attempts to +match the text against aliases, reserved words, shell +functions, builtins, and finally executable filenames, +in that order. + +@item possible-command-completions (C-x !) +List the possible completions of the text before point, +treating it as a command name. + +@item dynamic-complete-history (M-TAB) +Attempt completion on the text before point, comparing +the text against lines from the history list for possible +completion matches. + +@item complete-into-braces (M-@{) +Perform filename completion and return the list of possible completions +enclosed within braces so the list is available to the shell +(@pxref{Brace Expansion}). + +@end ifset @end ftable @node Keyboard Macros @@ -786,7 +1031,7 @@ in the macro appear as if typed at the keyboard. @ftable @code @item re-read-init-file (C-x C-r) -Read in the contents of your init file, and incorporate +Read in the contents of the inputrc file, and incorporate any bindings or variable assignments found there. @item abort (C-g) @@ -794,9 +1039,9 @@ Abort the current editing command and ring the terminal's bell (subject to the setting of @code{bell-style}). -@item do-uppercase-version (M-a, M-b, ...) -Run the command that is bound to the corresoponding uppercase -character. +@item do-uppercase-version (M-a, M-b, M-@var{x}, @dots{}) +If the metafied character @var{x} is lowercase, run the command +that is bound to the corresponding uppercase character. @item prefix-meta (ESC) Make the next character that you type be metafied. This is for people @@ -813,13 +1058,59 @@ command enough times to get back to the beginning. @item tilde-expand (M-~) Perform tilde expansion on the current word. +@item set-mark (C-@@) +Set the mark to the current point. If a +numeric argument is supplied, the mark is set to that position. + +@item exchange-point-and-mark (C-x C-x) +Swap the point with the mark. The current cursor position is set to +the saved position, and the old cursor position is saved as the mark. + +@item character-search (C-]) +A character is read and point is moved to the next occurrence of that +character. A negative count searches for previous occurrences. + +@item character-search-backward (M-C-]) +A character is read and point is moved to the previous occurrence +of that character. A negative count searches for subsequent +occurrences. + +@item insert-comment (M-#) +The value of the @code{comment-begin} +variable is inserted at the beginning of the current line, +and the line is accepted as if a newline had been typed. +@ifset BashFeatures +This makes the current line a shell comment. +@end ifset + @item dump-functions () Print all of the functions and their key bindings to the readline output stream. If a numeric argument is supplied, the output is formatted in such a way that it can be made part -of an @var{inputrc} file. +of an @var{inputrc} file. This command is unbound by default. + +@item dump-variables () +Print all of the settable variables and their values to the +readline output stream. If a numeric argument is supplied, +the output is formatted in such a way that it can be made part +of an @var{inputrc} file. This command is unbound by default. + +@item dump-macros () +Print all of the readline key sequences bound to macros and the +strings they ouput. If a numeric argument is supplied, +the output is formatted in such a way that it can be made part +of an @var{inputrc} file. This command is unbound by default. @ifset BashFeatures +@item glob-expand-word (C-x *) +The word before point is treated as a pattern for pathname expansion, +and the list of matching file names is inserted, replacing the word. + +@item glob-list-expansions (C-x g) +The list of expansions that would have been generated by +@code{glob-expand-word} +is inserted into the line, replacing the word before point. + @item display-shell-version (C-x C-v) Display version information about the current instance of Bash. @@ -841,7 +1132,7 @@ argument is ignored. @item emacs-editing-mode (C-e) When in @code{vi} editing mode, this causes a switch back to -emacs editing mode, as if the command @code{set -o emacs} had +@code{emacs} editing mode, as if the command @samp{set -o emacs} had been executed. @end ifset @@ -854,15 +1145,15 @@ been executed. While the Readline library does not have a full set of @code{vi} editing functions, it does contain enough to allow simple editing of the line. The Readline @code{vi} mode behaves as specified in -the Posix 1003.2 standard. +the @sc{POSIX} 1003.2 standard. @ifset BashFeatures -In order to switch interactively between @code{Emacs} and @code{Vi} -editing modes, use the @code{set -o emacs} and @code{set -o vi} +In order to switch interactively between @code{emacs} and @code{vi} +editing modes, use the @samp{set -o emacs} and @samp{set -o vi} commands (@pxref{The Set Builtin}). @end ifset @ifclear BashFeatures -In order to switch interactively between @code{Emacs} and @code{Vi} +In order to switch interactively between @code{emacs} and @code{vi} editing modes, use the command M-C-j (toggle-editing-mode). @end ifclear The Readline default is @code{emacs} mode. @@ -871,5 +1162,5 @@ When you enter a line in @code{vi} mode, you are already placed in `insertion' mode, as if you had typed an @samp{i}. Pressing @key{ESC} switches you into `command' mode, where you can edit the text of the line with the standard @code{vi} movement keys, move to previous -history lines with @samp{k}, and following lines with @samp{j}, and +history lines with @samp{k} and subsequent lines with @samp{j}, and so forth. diff --git a/lib/readline/doc/texindex.c b/lib/readline/doc/texindex.c deleted file mode 100644 index 9233bab..0000000 --- a/lib/readline/doc/texindex.c +++ /dev/null @@ -1,1666 +0,0 @@ -/* Prepare TeX index dribble output into an actual index. - - Version 1.45 - - Copyright (C) 1987, 1991, 1992 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - - -#include <stdio.h> -#include <ctype.h> -#include <errno.h> -#include "getopt.h" -#include "bashansi.h" - -#if !defined (errno) -extern int errno; -#endif - -#if defined (HAVE_UNISTD_H) -# include <unistd.h> -#else /* !HAVE_UNISTD_H */ -extern long lseek (); -#endif /* !HAVE_UNISTD_H */ - -extern char *mktemp (); - -#if !defined (HAVE_STRERROR) -extern int sys_nerr; -extern char *sys_errlist[]; -#endif - -#include <sys/types.h> - -#if defined (_AIX) || !defined (_POSIX_VERSION) -# include <sys/file.h> -#endif - -#include <fcntl.h> - -#define TI_NO_ERROR 0 -#define TI_FATAL_ERROR 1 - -#if !defined (SEEK_SET) -# define SEEK_SET 0 -# define SEEK_CUR 1 -# define SEEK_END 2 -#endif /* !SEEK_SET */ - -/* When sorting in core, this structure describes one line - and the position and length of its first keyfield. */ -struct lineinfo -{ - char *text; /* The actual text of the line. */ - union { - char *text; /* The start of the key (for textual comparison). */ - long number; /* The numeric value (for numeric comparison). */ - } key; - long keylen; /* Length of KEY field. */ -}; - -/* This structure describes a field to use as a sort key. */ -struct keyfield -{ - int startwords; /* Number of words to skip. */ - int startchars; /* Number of additional chars to skip. */ - int endwords; /* Number of words to ignore at end. */ - int endchars; /* Ditto for characters of last word. */ - char ignore_blanks; /* Non-zero means ignore spaces and tabs. */ - char fold_case; /* Non-zero means case doesn't matter. */ - char reverse; /* Non-zero means compare in reverse order. */ - char numeric; /* Non-zeros means field is ASCII numeric. */ - char positional; /* Sort according to file position. */ - char braced; /* Count balanced-braced groupings as fields. */ -}; - -/* Vector of keyfields to use. */ -struct keyfield keyfields[3]; - -/* Number of keyfields stored in that vector. */ -int num_keyfields = 3; - -/* Vector of input file names, terminated with a null pointer. */ -char **infiles; - -/* Vector of corresponding output file names, or NULL, meaning default it - (add an `s' to the end). */ -char **outfiles; - -/* Length of `infiles'. */ -int num_infiles; - -/* Pointer to the array of pointers to lines being sorted. */ -char **linearray; - -/* The allocated length of `linearray'. */ -long nlines; - -/* Directory to use for temporary files. On Unix, it ends with a slash. */ -char *tempdir; - -/* Start of filename to use for temporary files. */ -char *tempbase; - -/* Number of last temporary file. */ -int tempcount; - -/* Number of last temporary file already deleted. - Temporary files are deleted by `flush_tempfiles' in order of creation. */ -int last_deleted_tempcount; - -/* During in-core sort, this points to the base of the data block - which contains all the lines of data. */ -char *text_base; - -/* Additional command switches .*/ - -/* Nonzero means do not delete tempfiles -- for debugging. */ -int keep_tempfiles; - -/* The name this program was run with. */ -char *program_name; - -/* Forward declarations of functions in this file. */ - -void decode_command (); -void sort_in_core (); -void sort_offline (); -char **parsefile (); -char *find_field (); -char *find_pos (); -long find_value (); -char *find_braced_pos (); -char *find_braced_end (); -void writelines (); -int compare_field (); -int compare_full (); -long readline (); -int merge_files (); -int merge_direct (); -void pfatal_with_name (); -void fatal (); -void error (); -void *xmalloc (), *xrealloc (); -char *concat (); -char *maketempname (); -void flush_tempfiles (); -char *tempcopy (); - -#define MAX_IN_CORE_SORT 500000 - -void -main (argc, argv) - int argc; - char **argv; -{ - int i; - - tempcount = 0; - last_deleted_tempcount = 0; - program_name = argv[0]; - - /* Describe the kind of sorting to do. */ - /* The first keyfield uses the first braced field and folds case. */ - keyfields[0].braced = 1; - keyfields[0].fold_case = 1; - keyfields[0].endwords = -1; - keyfields[0].endchars = -1; - - /* The second keyfield uses the second braced field, numerically. */ - keyfields[1].braced = 1; - keyfields[1].numeric = 1; - keyfields[1].startwords = 1; - keyfields[1].endwords = -1; - keyfields[1].endchars = -1; - - /* The third keyfield (which is ignored while discarding duplicates) - compares the whole line. */ - keyfields[2].endwords = -1; - keyfields[2].endchars = -1; - - decode_command (argc, argv); - - tempbase = mktemp (concat ("txiXXXXXX", "", "")); - - /* Process input files completely, one by one. */ - - for (i = 0; i < num_infiles; i++) - { - int desc; - long ptr; - char *outfile; - - desc = open (infiles[i], O_RDONLY, 0); - if (desc < 0) - pfatal_with_name (infiles[i]); - lseek (desc, 0L, SEEK_END); - ptr = lseek (desc, 0L, SEEK_CUR); - - close (desc); - - outfile = outfiles[i]; - if (!outfile) - { - outfile = concat (infiles[i], "s", ""); - } - - if (ptr < MAX_IN_CORE_SORT) - /* Sort a small amount of data. */ - sort_in_core (infiles[i], ptr, outfile); - else - sort_offline (infiles[i], ptr, outfile); - } - - flush_tempfiles (tempcount); - exit (TI_NO_ERROR); -} - -void -usage () -{ - fprintf (stderr, "\ -Usage: %s [-k] infile [-o outfile] ...\n", program_name); - exit (1); -} - -/* Decode the command line arguments to set the parameter variables - and set up the vector of keyfields and the vector of input files. */ - -void -decode_command (argc, argv) - int argc; - char **argv; -{ - int optc; - char **ip; - char **op; - - /* Store default values into parameter variables. */ - - tempdir = getenv ("TMPDIR"); - if (tempdir == NULL) - tempdir = "/tmp/"; - else - tempdir = concat (tempdir, "/", ""); - - keep_tempfiles = 0; - - /* Allocate ARGC input files, which must be enough. */ - - infiles = (char **) xmalloc (argc * sizeof (char *)); - outfiles = (char **) xmalloc (argc * sizeof (char *)); - ip = infiles; - op = outfiles; - - while ((optc = getopt (argc, argv, "-ko:")) != EOF) - { - switch (optc) - { - case 1: /* Non-option filename. */ - *ip++ = optarg; - *op++ = NULL; - break; - - case 'k': - keep_tempfiles = 1; - break; - - case 'o': - if (op > outfiles) - *(op - 1) = optarg; - break; - - default: - usage (); - } - } - - /* Record number of keyfields and terminate list of filenames. */ - num_infiles = ip - infiles; - *ip = 0; - if (num_infiles == 0) - usage (); -} - -/* Return a name for a temporary file. */ - -char * -maketempname (count) - int count; -{ - char tempsuffix[10]; - sprintf (tempsuffix, "%d", count); - return concat (tempdir, tempbase, tempsuffix); -} - -/* Delete all temporary files up to TO_COUNT. */ - -void -flush_tempfiles (to_count) - int to_count; -{ - if (keep_tempfiles) - return; - while (last_deleted_tempcount < to_count) - unlink (maketempname (++last_deleted_tempcount)); -} - -/* Copy the input file open on IDESC into a temporary file - and return the temporary file name. */ - -#define BUFSIZE 1024 - -char * -tempcopy (idesc) - int idesc; -{ - char *outfile = maketempname (++tempcount); - int odesc; - char buffer[BUFSIZE]; - - odesc = open (outfile, O_WRONLY | O_CREAT, 0666); - - if (odesc < 0) - pfatal_with_name (outfile); - - while (1) - { - int nread = read (idesc, buffer, BUFSIZE); - write (odesc, buffer, nread); - if (!nread) - break; - } - - close (odesc); - - return outfile; -} - -/* Compare LINE1 and LINE2 according to the specified set of keyfields. */ - -int -compare_full (line1, line2) - char **line1, **line2; -{ - int i; - - /* Compare using the first keyfield; - if that does not distinguish the lines, try the second keyfield; - and so on. */ - - for (i = 0; i < num_keyfields; i++) - { - long length1, length2; - char *start1 = find_field (&keyfields[i], *line1, &length1); - char *start2 = find_field (&keyfields[i], *line2, &length2); - int tem = compare_field (&keyfields[i], start1, length1, *line1 - text_base, - start2, length2, *line2 - text_base); - if (tem) - { - if (keyfields[i].reverse) - return -tem; - return tem; - } - } - - return 0; /* Lines match exactly. */ -} - -/* Compare LINE1 and LINE2, described by structures - in which the first keyfield is identified in advance. - For positional sorting, assumes that the order of the lines in core - reflects their nominal order. */ - -int -compare_prepared (line1, line2) - struct lineinfo *line1, *line2; -{ - int i; - int tem; - char *text1, *text2; - - /* Compare using the first keyfield, which has been found for us already. */ - if (keyfields->positional) - { - if (line1->text - text_base > line2->text - text_base) - tem = 1; - else - tem = -1; - } - else if (keyfields->numeric) - tem = line1->key.number - line2->key.number; - else - tem = compare_field (keyfields, line1->key.text, line1->keylen, 0, - line2->key.text, line2->keylen, 0); - if (tem) - { - if (keyfields->reverse) - return -tem; - return tem; - } - - text1 = line1->text; - text2 = line2->text; - - /* Compare using the second keyfield; - if that does not distinguish the lines, try the third keyfield; - and so on. */ - - for (i = 1; i < num_keyfields; i++) - { - long length1, length2; - char *start1 = find_field (&keyfields[i], text1, &length1); - char *start2 = find_field (&keyfields[i], text2, &length2); - int tem = compare_field (&keyfields[i], start1, length1, text1 - text_base, - start2, length2, text2 - text_base); - if (tem) - { - if (keyfields[i].reverse) - return -tem; - return tem; - } - } - - return 0; /* Lines match exactly. */ -} - -/* Like compare_full but more general. - You can pass any strings, and you can say how many keyfields to use. - POS1 and POS2 should indicate the nominal positional ordering of - the two lines in the input. */ - -int -compare_general (str1, str2, pos1, pos2, use_keyfields) - char *str1, *str2; - long pos1, pos2; - int use_keyfields; -{ - int i; - - /* Compare using the first keyfield; - if that does not distinguish the lines, try the second keyfield; - and so on. */ - - for (i = 0; i < use_keyfields; i++) - { - long length1, length2; - char *start1 = find_field (&keyfields[i], str1, &length1); - char *start2 = find_field (&keyfields[i], str2, &length2); - int tem = compare_field (&keyfields[i], start1, length1, pos1, - start2, length2, pos2); - if (tem) - { - if (keyfields[i].reverse) - return -tem; - return tem; - } - } - - return 0; /* Lines match exactly. */ -} - -/* Find the start and length of a field in STR according to KEYFIELD. - A pointer to the starting character is returned, and the length - is stored into the int that LENGTHPTR points to. */ - -char * -find_field (keyfield, str, lengthptr) - struct keyfield *keyfield; - char *str; - long *lengthptr; -{ - char *start; - char *end; - char *(*fun) (); - - if (keyfield->braced) - fun = find_braced_pos; - else - fun = find_pos; - - start = (*fun) (str, keyfield->startwords, keyfield->startchars, - keyfield->ignore_blanks); - if (keyfield->endwords < 0) - { - if (keyfield->braced) - end = find_braced_end (start); - else - { - end = start; - while (*end && *end != '\n') - end++; - } - } - else - { - end = (*fun) (str, keyfield->endwords, keyfield->endchars, 0); - if (end - str < start - str) - end = start; - } - *lengthptr = end - start; - return start; -} - -/* Return a pointer to a specified place within STR, - skipping (from the beginning) WORDS words and then CHARS chars. - If IGNORE_BLANKS is nonzero, we skip all blanks - after finding the specified word. */ - -char * -find_pos (str, words, chars, ignore_blanks) - char *str; - int words, chars; - int ignore_blanks; -{ - int i; - char *p = str; - - for (i = 0; i < words; i++) - { - char c; - /* Find next bunch of nonblanks and skip them. */ - while ((c = *p) == ' ' || c == '\t') - p++; - while ((c = *p) && c != '\n' && !(c == ' ' || c == '\t')) - p++; - if (!*p || *p == '\n') - return p; - } - - while (*p == ' ' || *p == '\t') - p++; - - for (i = 0; i < chars; i++) - { - if (!*p || *p == '\n') - break; - p++; - } - return p; -} - -/* Like find_pos but assumes that each field is surrounded by braces - and that braces within fields are balanced. */ - -char * -find_braced_pos (str, words, chars, ignore_blanks) - char *str; - int words, chars; - int ignore_blanks; -{ - int i; - int bracelevel; - char *p = str; - char c; - - for (i = 0; i < words; i++) - { - bracelevel = 1; - while ((c = *p++) != '{' && c != '\n' && c) - /* Do nothing. */ ; - if (c != '{') - return p - 1; - while (bracelevel) - { - c = *p++; - if (c == '{') - bracelevel++; - if (c == '}') - bracelevel--; - if (c == 0 || c == '\n') - return p - 1; - } - } - - while ((c = *p++) != '{' && c != '\n' && c) - /* Do nothing. */ ; - - if (c != '{') - return p - 1; - - if (ignore_blanks) - while ((c = *p) == ' ' || c == '\t') - p++; - - for (i = 0; i < chars; i++) - { - if (!*p || *p == '\n') - break; - p++; - } - return p; -} - -/* Find the end of the balanced-brace field which starts at STR. - The position returned is just before the closing brace. */ - -char * -find_braced_end (str) - char *str; -{ - int bracelevel; - char *p = str; - char c; - - bracelevel = 1; - while (bracelevel) - { - c = *p++; - if (c == '{') - bracelevel++; - if (c == '}') - bracelevel--; - if (c == 0 || c == '\n') - return p - 1; - } - return p - 1; -} - -long -find_value (start, length) - char *start; - long length; -{ - while (length != 0L) - { - if (isdigit (*start)) - return atol (start); - length--; - start++; - } - return 0l; -} - -/* Vector used to translate characters for comparison. - This is how we make all alphanumerics follow all else, - and ignore case in the first sorting. */ -int char_order[256]; - -void -init_char_order () -{ - int i; - for (i = 1; i < 256; i++) - char_order[i] = i; - - for (i = '0'; i <= '9'; i++) - char_order[i] += 512; - - for (i = 'a'; i <= 'z'; i++) - { - char_order[i] = 512 + i; - char_order[i + 'A' - 'a'] = 512 + i; - } -} - -/* Compare two fields (each specified as a start pointer and a character count) - according to KEYFIELD. - The sign of the value reports the relation between the fields. */ - -int -compare_field (keyfield, start1, length1, pos1, start2, length2, pos2) - struct keyfield *keyfield; - char *start1; - long length1; - long pos1; - char *start2; - long length2; - long pos2; -{ - if (keyfields->positional) - { - if (pos1 > pos2) - return 1; - else - return -1; - } - if (keyfield->numeric) - { - long value = find_value (start1, length1) - find_value (start2, length2); - if (value > 0) - return 1; - if (value < 0) - return -1; - return 0; - } - else - { - char *p1 = start1; - char *p2 = start2; - char *e1 = start1 + length1; - char *e2 = start2 + length2; - - while (1) - { - int c1, c2; - - if (p1 == e1) - c1 = 0; - else - c1 = *p1++; - if (p2 == e2) - c2 = 0; - else - c2 = *p2++; - - if (char_order[c1] != char_order[c2]) - return char_order[c1] - char_order[c2]; - if (!c1) - break; - } - - /* Strings are equal except possibly for case. */ - p1 = start1; - p2 = start2; - while (1) - { - int c1, c2; - - if (p1 == e1) - c1 = 0; - else - c1 = *p1++; - if (p2 == e2) - c2 = 0; - else - c2 = *p2++; - - if (c1 != c2) - /* Reverse sign here so upper case comes out last. */ - return c2 - c1; - if (!c1) - break; - } - - return 0; - } -} - -/* A `struct linebuffer' is a structure which holds a line of text. - `readline' reads a line from a stream into a linebuffer - and works regardless of the length of the line. */ - -struct linebuffer -{ - long size; - char *buffer; -}; - -/* Initialize LINEBUFFER for use. */ - -void -initbuffer (linebuffer) - struct linebuffer *linebuffer; -{ - linebuffer->size = 200; - linebuffer->buffer = (char *) xmalloc (200); -} - -/* Read a line of text from STREAM into LINEBUFFER. - Return the length of the line. */ - -long -readline (linebuffer, stream) - struct linebuffer *linebuffer; - FILE *stream; -{ - char *buffer = linebuffer->buffer; - char *p = linebuffer->buffer; - char *end = p + linebuffer->size; - - while (1) - { - int c = getc (stream); - if (p == end) - { - buffer = (char *) xrealloc (buffer, linebuffer->size *= 2); - p += buffer - linebuffer->buffer; - end += buffer - linebuffer->buffer; - linebuffer->buffer = buffer; - } - if (c < 0 || c == '\n') - { - *p = 0; - break; - } - *p++ = c; - } - - return p - buffer; -} - -/* Sort an input file too big to sort in core. */ - -void -sort_offline (infile, nfiles, total, outfile) - char *infile; - int nfiles; - long total; - char *outfile; -{ - /* More than enough. */ - int ntemps = 2 * (total + MAX_IN_CORE_SORT - 1) / MAX_IN_CORE_SORT; - char **tempfiles = (char **) xmalloc (ntemps * sizeof (char *)); - FILE *istream = fopen (infile, "r"); - int i; - struct linebuffer lb; - long linelength; - int failure = 0; - - initbuffer (&lb); - - /* Read in one line of input data. */ - - linelength = readline (&lb, istream); - - if (lb.buffer[0] != '\\' && lb.buffer[0] != '@') - { - error ("%s: not a texinfo index file", infile); - return; - } - - /* Split up the input into `ntemps' temporary files, or maybe fewer, - and put the new files' names into `tempfiles' */ - - for (i = 0; i < ntemps; i++) - { - char *outname = maketempname (++tempcount); - FILE *ostream = fopen (outname, "w"); - long tempsize = 0; - - if (!ostream) - pfatal_with_name (outname); - tempfiles[i] = outname; - - /* Copy lines into this temp file as long as it does not make file - "too big" or until there are no more lines. */ - - while (tempsize + linelength + 1 <= MAX_IN_CORE_SORT) - { - tempsize += linelength + 1; - fputs (lb.buffer, ostream); - putc ('\n', ostream); - - /* Read another line of input data. */ - - linelength = readline (&lb, istream); - if (!linelength && feof (istream)) - break; - - if (lb.buffer[0] != '\\' && lb.buffer[0] != '@') - { - error ("%s: not a texinfo index file", infile); - failure = 1; - goto fail; - } - } - fclose (ostream); - if (feof (istream)) - break; - } - - free (lb.buffer); - -fail: - /* Record number of temp files we actually needed. */ - - ntemps = i; - - /* Sort each tempfile into another tempfile. - Delete the first set of tempfiles and put the names of the second - into `tempfiles'. */ - - for (i = 0; i < ntemps; i++) - { - char *newtemp = maketempname (++tempcount); - sort_in_core (&tempfiles[i], MAX_IN_CORE_SORT, newtemp); - if (!keep_tempfiles) - unlink (tempfiles[i]); - tempfiles[i] = newtemp; - } - - if (failure) - return; - - /* Merge the tempfiles together and indexify. */ - - merge_files (tempfiles, ntemps, outfile); -} - -/* Sort INFILE, whose size is TOTAL, - assuming that is small enough to be done in-core, - then indexify it and send the output to OUTFILE (or to stdout). */ - -void -sort_in_core (infile, total, outfile) - char *infile; - long total; - char *outfile; -{ - char **nextline; - char *data = (char *) xmalloc (total + 1); - char *file_data; - long file_size; - int i; - FILE *ostream = stdout; - struct lineinfo *lineinfo; - - /* Read the contents of the file into the moby array `data'. */ - - int desc = open (infile, O_RDONLY, 0); - - if (desc < 0) - fatal ("failure reopening %s", infile); - for (file_size = 0;;) - { - i = read (desc, data + file_size, total - file_size); - if (i <= 0) - break; - file_size += i; - } - file_data = data; - data[file_size] = 0; - - close (desc); - - if (file_size > 0 && data[0] != '\\' && data[0] != '@') - { - error ("%s: not a texinfo index file", infile); - return; - } - - init_char_order (); - - /* Sort routines want to know this address. */ - - text_base = data; - - /* Create the array of pointers to lines, with a default size - frequently enough. */ - - nlines = total / 50; - if (!nlines) - nlines = 2; - linearray = (char **) xmalloc (nlines * sizeof (char *)); - - /* `nextline' points to the next free slot in this array. - `nlines' is the allocated size. */ - - nextline = linearray; - - /* Parse the input file's data, and make entries for the lines. */ - - nextline = parsefile (infile, nextline, file_data, file_size); - if (nextline == 0) - { - error ("%s: not a texinfo index file", infile); - return; - } - - /* Sort the lines. */ - - /* If we have enough space, find the first keyfield of each line in advance. - Make a `struct lineinfo' for each line, which records the keyfield - as well as the line, and sort them. */ - - lineinfo = (struct lineinfo *) malloc ((nextline - linearray) * sizeof (struct lineinfo)); - - if (lineinfo) - { - struct lineinfo *lp; - char **p; - - for (lp = lineinfo, p = linearray; p != nextline; lp++, p++) - { - lp->text = *p; - lp->key.text = find_field (keyfields, *p, &lp->keylen); - if (keyfields->numeric) - lp->key.number = find_value (lp->key.text, lp->keylen); - } - - qsort (lineinfo, nextline - linearray, sizeof (struct lineinfo), compare_prepared); - - for (lp = lineinfo, p = linearray; p != nextline; lp++, p++) - *p = lp->text; - - free (lineinfo); - } - else - qsort (linearray, nextline - linearray, sizeof (char *), compare_full); - - /* Open the output file. */ - - if (outfile) - { - ostream = fopen (outfile, "w"); - if (!ostream) - pfatal_with_name (outfile); - } - - writelines (linearray, nextline - linearray, ostream); - if (outfile) - fclose (ostream); - - free (linearray); - free (data); -} - -/* Parse an input string in core into lines. - DATA is the input string, and SIZE is its length. - Data goes in LINEARRAY starting at NEXTLINE. - The value returned is the first entry in LINEARRAY still unused. - Value 0 means input file contents are invalid. */ - -char ** -parsefile (filename, nextline, data, size) - char *filename; - char **nextline; - char *data; - long size; -{ - char *p, *end; - char **line = nextline; - - p = data; - end = p + size; - *end = 0; - - while (p != end) - { - if (p[0] != '\\' && p[0] != '@') - return 0; - - *line = p; - while (*p && *p != '\n') - p++; - if (p != end) - p++; - - line++; - if (line == linearray + nlines) - { - char **old = linearray; - linearray = (char **) xrealloc (linearray, sizeof (char *) * (nlines *= 4)); - line += linearray - old; - } - } - - return line; -} - -/* Indexification is a filter applied to the sorted lines - as they are being written to the output file. - Multiple entries for the same name, with different page numbers, - get combined into a single entry with multiple page numbers. - The first braced field, which is used for sorting, is discarded. - However, its first character is examined, folded to lower case, - and if it is different from that in the previous line fed to us - a \initial line is written with one argument, the new initial. - - If an entry has four braced fields, then the second and third - constitute primary and secondary names. - In this case, each change of primary name - generates a \primary line which contains only the primary name, - and in between these are \secondary lines which contain - just a secondary name and page numbers. */ - -/* The last primary name we wrote a \primary entry for. - If only one level of indexing is being done, this is the last name seen. */ -char *lastprimary; -/* Length of storage allocated for lastprimary. */ -int lastprimarylength; - -/* Similar, for the secondary name. */ -char *lastsecondary; -int lastsecondarylength; - -/* Zero if we are not in the middle of writing an entry. - One if we have written the beginning of an entry but have not - yet written any page numbers into it. - Greater than one if we have written the beginning of an entry - plus at least one page number. */ -int pending; - -/* The initial (for sorting purposes) of the last primary entry written. - When this changes, a \initial {c} line is written */ - -char *lastinitial; - -int lastinitiallength; - -/* When we need a string of length 1 for the value of lastinitial, - store it here. */ - -char lastinitial1[2]; - -/* Initialize static storage for writing an index. */ - -static void -xbzero(s, n) - char *s; - int n; -{ - register char *p; - for (p = s; n--; ) - *p++ = '\0'; -} - -void -init_index () -{ - pending = 0; - lastinitial = lastinitial1; - lastinitial1[0] = 0; - lastinitial1[1] = 0; - lastinitiallength = 0; - lastprimarylength = 100; - lastprimary = (char *) xmalloc (lastprimarylength + 1); - xbzero (lastprimary, lastprimarylength + 1); - lastsecondarylength = 100; - lastsecondary = (char *) xmalloc (lastsecondarylength + 1); - xbzero (lastsecondary, lastsecondarylength + 1); -} - -/* Indexify. Merge entries for the same name, - insert headers for each initial character, etc. */ - -void -indexify (line, ostream) - char *line; - FILE *ostream; -{ - char *primary, *secondary, *pagenumber; - int primarylength, secondarylength = 0, pagelength; - int nosecondary; - int initiallength; - char *initial; - char initial1[2]; - register char *p; - - /* First, analyze the parts of the entry fed to us this time. */ - - p = find_braced_pos (line, 0, 0, 0); - if (*p == '{') - { - initial = p; - /* Get length of inner pair of braces starting at `p', - including that inner pair of braces. */ - initiallength = find_braced_end (p + 1) + 1 - p; - } - else - { - initial = initial1; - initial1[0] = *p; - initial1[1] = 0; - initiallength = 1; - - if (initial1[0] >= 'a' && initial1[0] <= 'z') - initial1[0] -= 040; - } - - pagenumber = find_braced_pos (line, 1, 0, 0); - pagelength = find_braced_end (pagenumber) - pagenumber; - if (pagelength == 0) - abort (); - - primary = find_braced_pos (line, 2, 0, 0); - primarylength = find_braced_end (primary) - primary; - - secondary = find_braced_pos (line, 3, 0, 0); - nosecondary = !*secondary; - if (!nosecondary) - secondarylength = find_braced_end (secondary) - secondary; - - /* If the primary is different from before, make a new primary entry. */ - if (strncmp (primary, lastprimary, primarylength)) - { - /* Close off current secondary entry first, if one is open. */ - if (pending) - { - fputs ("}\n", ostream); - pending = 0; - } - - /* If this primary has a different initial, include an entry for - the initial. */ - if (initiallength != lastinitiallength || - strncmp (initial, lastinitial, initiallength)) - { - fprintf (ostream, "\\initial {"); - fwrite (initial, 1, initiallength, ostream); - fprintf (ostream, "}\n", initial); - if (initial == initial1) - { - lastinitial = lastinitial1; - *lastinitial1 = *initial1; - } - else - { - lastinitial = initial; - } - lastinitiallength = initiallength; - } - - /* Make the entry for the primary. */ - if (nosecondary) - fputs ("\\entry {", ostream); - else - fputs ("\\primary {", ostream); - fwrite (primary, primarylength, 1, ostream); - if (nosecondary) - { - fputs ("}{", ostream); - pending = 1; - } - else - fputs ("}\n", ostream); - - /* Record name of most recent primary. */ - if (lastprimarylength < primarylength) - { - lastprimarylength = primarylength + 100; - lastprimary = (char *) xrealloc (lastprimary, - 1 + lastprimarylength); - } - strncpy (lastprimary, primary, primarylength); - lastprimary[primarylength] = 0; - - /* There is no current secondary within this primary, now. */ - lastsecondary[0] = 0; - } - - /* Should not have an entry with no subtopic following one with a subtopic. */ - - if (nosecondary && *lastsecondary) - error ("entry %s follows an entry with a secondary name", line); - - /* Start a new secondary entry if necessary. */ - if (!nosecondary && strncmp (secondary, lastsecondary, secondarylength)) - { - if (pending) - { - fputs ("}\n", ostream); - pending = 0; - } - - /* Write the entry for the secondary. */ - fputs ("\\secondary {", ostream); - fwrite (secondary, secondarylength, 1, ostream); - fputs ("}{", ostream); - pending = 1; - - /* Record name of most recent secondary. */ - if (lastsecondarylength < secondarylength) - { - lastsecondarylength = secondarylength + 100; - lastsecondary = (char *) xrealloc (lastsecondary, - 1 + lastsecondarylength); - } - strncpy (lastsecondary, secondary, secondarylength); - lastsecondary[secondarylength] = 0; - } - - /* Here to add one more page number to the current entry. */ - if (pending++ != 1) - fputs (", ", ostream); /* Punctuate first, if this is not the first. */ - fwrite (pagenumber, pagelength, 1, ostream); -} - -/* Close out any unfinished output entry. */ - -void -finish_index (ostream) - FILE *ostream; -{ - if (pending) - fputs ("}\n", ostream); - free (lastprimary); - free (lastsecondary); -} - -/* Copy the lines in the sorted order. - Each line is copied out of the input file it was found in. */ - -void -writelines (linearray, nlines, ostream) - char **linearray; - int nlines; - FILE *ostream; -{ - char **stop_line = linearray + nlines; - char **next_line; - - init_index (); - - /* Output the text of the lines, and free the buffer space. */ - - for (next_line = linearray; next_line != stop_line; next_line++) - { - /* If -u was specified, output the line only if distinct from previous one. */ - if (next_line == linearray - /* Compare previous line with this one, using only the - explicitly specd keyfields. */ - || compare_general (*(next_line - 1), *next_line, 0L, 0L, num_keyfields - 1)) - { - char *p = *next_line; - char c; - - while ((c = *p++) && c != '\n') - /* Do nothing. */ ; - *(p - 1) = 0; - indexify (*next_line, ostream); - } - } - - finish_index (ostream); -} - -/* Assume (and optionally verify) that each input file is sorted; - merge them and output the result. - Returns nonzero if any input file fails to be sorted. - - This is the high-level interface that can handle an unlimited - number of files. */ - -#define MAX_DIRECT_MERGE 10 - -int -merge_files (infiles, nfiles, outfile) - char **infiles; - int nfiles; - char *outfile; -{ - char **tempfiles; - int ntemps; - int i; - int value = 0; - int start_tempcount = tempcount; - - if (nfiles <= MAX_DIRECT_MERGE) - return merge_direct (infiles, nfiles, outfile); - - /* Merge groups of MAX_DIRECT_MERGE input files at a time, - making a temporary file to hold each group's result. */ - - ntemps = (nfiles + MAX_DIRECT_MERGE - 1) / MAX_DIRECT_MERGE; - tempfiles = (char **) xmalloc (ntemps * sizeof (char *)); - for (i = 0; i < ntemps; i++) - { - int nf = MAX_DIRECT_MERGE; - if (i + 1 == ntemps) - nf = nfiles - i * MAX_DIRECT_MERGE; - tempfiles[i] = maketempname (++tempcount); - value |= merge_direct (&infiles[i * MAX_DIRECT_MERGE], nf, tempfiles[i]); - } - - /* All temporary files that existed before are no longer needed - since their contents have been merged into our new tempfiles. - So delete them. */ - flush_tempfiles (start_tempcount); - - /* Now merge the temporary files we created. */ - - merge_files (tempfiles, ntemps, outfile); - - free (tempfiles); - - return value; -} - -/* Assume (and optionally verify) that each input file is sorted; - merge them and output the result. - Returns nonzero if any input file fails to be sorted. - - This version of merging will not work if the number of - input files gets too high. Higher level functions - use it only with a bounded number of input files. */ - -int -merge_direct (infiles, nfiles, outfile) - char **infiles; - int nfiles; - char *outfile; -{ - struct linebuffer *lb1, *lb2; - struct linebuffer **thisline, **prevline; - FILE **streams; - int i; - int nleft; - int lossage = 0; - int *file_lossage; - struct linebuffer *prev_out = 0; - FILE *ostream = stdout; - - if (outfile) - { - ostream = fopen (outfile, "w"); - } - if (!ostream) - pfatal_with_name (outfile); - - init_index (); - - if (nfiles == 0) - { - if (outfile) - fclose (ostream); - return 0; - } - - /* For each file, make two line buffers. - Also, for each file, there is an element of `thisline' - which points at any time to one of the file's two buffers, - and an element of `prevline' which points to the other buffer. - `thisline' is supposed to point to the next available line from the file, - while `prevline' holds the last file line used, - which is remembered so that we can verify that the file is properly sorted. */ - - /* lb1 and lb2 contain one buffer each per file. */ - lb1 = (struct linebuffer *) xmalloc (nfiles * sizeof (struct linebuffer)); - lb2 = (struct linebuffer *) xmalloc (nfiles * sizeof (struct linebuffer)); - - /* thisline[i] points to the linebuffer holding the next available line in file i, - or is zero if there are no lines left in that file. */ - thisline = (struct linebuffer **) - xmalloc (nfiles * sizeof (struct linebuffer *)); - /* prevline[i] points to the linebuffer holding the last used line - from file i. This is just for verifying that file i is properly - sorted. */ - prevline = (struct linebuffer **) - xmalloc (nfiles * sizeof (struct linebuffer *)); - /* streams[i] holds the input stream for file i. */ - streams = (FILE **) xmalloc (nfiles * sizeof (FILE *)); - /* file_lossage[i] is nonzero if we already know file i is not - properly sorted. */ - file_lossage = (int *) xmalloc (nfiles * sizeof (int)); - - /* Allocate and initialize all that storage. */ - - for (i = 0; i < nfiles; i++) - { - initbuffer (&lb1[i]); - initbuffer (&lb2[i]); - thisline[i] = &lb1[i]; - prevline[i] = &lb2[i]; - file_lossage[i] = 0; - streams[i] = fopen (infiles[i], "r"); - if (!streams[i]) - pfatal_with_name (infiles[i]); - - readline (thisline[i], streams[i]); - } - - /* Keep count of number of files not at eof. */ - nleft = nfiles; - - while (nleft) - { - struct linebuffer *best = 0; - struct linebuffer *exch; - int bestfile = -1; - int i; - - /* Look at the next avail line of each file; choose the least one. */ - - for (i = 0; i < nfiles; i++) - { - if (thisline[i] && - (!best || - 0 < compare_general (best->buffer, thisline[i]->buffer, - (long) bestfile, (long) i, num_keyfields))) - { - best = thisline[i]; - bestfile = i; - } - } - - /* Output that line, unless it matches the previous one and we - don't want duplicates. */ - - if (!(prev_out && - !compare_general (prev_out->buffer, - best->buffer, 0L, 1L, num_keyfields - 1))) - indexify (best->buffer, ostream); - prev_out = best; - - /* Now make the line the previous of its file, and fetch a new - line from that file. */ - - exch = prevline[bestfile]; - prevline[bestfile] = thisline[bestfile]; - thisline[bestfile] = exch; - - while (1) - { - /* If the file has no more, mark it empty. */ - - if (feof (streams[bestfile])) - { - thisline[bestfile] = 0; - /* Update the number of files still not empty. */ - nleft--; - break; - } - readline (thisline[bestfile], streams[bestfile]); - if (thisline[bestfile]->buffer[0] || !feof (streams[bestfile])) - break; - } - } - - finish_index (ostream); - - /* Free all storage and close all input streams. */ - - for (i = 0; i < nfiles; i++) - { - fclose (streams[i]); - free (lb1[i].buffer); - free (lb2[i].buffer); - } - free (file_lossage); - free (lb1); - free (lb2); - free (thisline); - free (prevline); - free (streams); - - if (outfile) - fclose (ostream); - - return lossage; -} - -/* Print error message and exit. */ - -void -fatal (s1, s2) - char *s1, *s2; -{ - error (s1, s2); - exit (TI_FATAL_ERROR); -} - -/* Print error message. S1 is printf control string, S2 is arg for it. */ - -void -error (s1, s2) - char *s1, *s2; -{ - printf ("%s: ", program_name); - printf (s1, s2); - printf ("\n"); -} - -#if !defined (HAVE_STRERROR) -static char * -strerror (n) - int n; -{ - static char ebuf[40]; - - if (n < sys_nerr) - return sys_errlist[n]; - else - { - sprintf (ebuf, "Unknown error %d", n); - return ebuf; - } -} -#endif - -void -perror_with_name (name) - char *name; -{ - char *s; - - s = concat ("", strerror (errno), " for %s"); - error (s, name); -} - -void -pfatal_with_name (name) - char *name; -{ - char *s; - - s = concat ("", strerror (errno), " for %s"); - fatal (s, name); -} - -/* Return a newly-allocated string whose contents concatenate those of - S1, S2, S3. */ - -char * -concat (s1, s2, s3) - char *s1, *s2, *s3; -{ - int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3); - char *result = (char *) xmalloc (len1 + len2 + len3 + 1); - - strcpy (result, s1); - strcpy (result + len1, s2); - strcpy (result + len1 + len2, s3); - *(result + len1 + len2 + len3) = 0; - - return result; -} - -/* Just like malloc, but kills the program in case of fatal error. */ -void * -xmalloc (nbytes) - int nbytes; -{ - void *temp = (void *) malloc (nbytes); - - if (nbytes && temp == (void *)NULL) - memory_error ("xmalloc", nbytes); - - return (temp); -} - -/* Like realloc (), but barfs if there isn't enough memory. */ -void * -xrealloc (pointer, nbytes) - void *pointer; - int nbytes; -{ - void *temp; - - if (!pointer) - temp = (void *)xmalloc (nbytes); - else - temp = (void *)realloc (pointer, nbytes); - - if (nbytes && !temp) - memory_error ("xrealloc", nbytes); - - return (temp); -} - -memory_error (callers_name, bytes_wanted) - char *callers_name; - int bytes_wanted; -{ - char printable_string[80]; - - sprintf (printable_string, - "Virtual memory exhausted in %s ()! Needed %d bytes.", - callers_name, bytes_wanted); - - error (printable_string, ""); - abort (); -} diff --git a/lib/readline/emacs_keymap.c b/lib/readline/emacs_keymap.c index 849d85f..4ba3858 100644 --- a/lib/readline/emacs_keymap.c +++ b/lib/readline/emacs_keymap.c @@ -33,7 +33,7 @@ KEYMAP_ENTRY_ARRAY emacs_standard_keymap = { /* Control keys. */ - { ISFUNC, (Function *)0x0 }, /* Control-@ */ + { ISFUNC, rl_set_mark }, /* Control-@ */ { ISFUNC, rl_beg_of_line }, /* Control-a */ { ISFUNC, rl_backward }, /* Control-b */ { ISFUNC, (Function *)0x0 }, /* Control-c */ @@ -62,7 +62,7 @@ KEYMAP_ENTRY_ARRAY emacs_standard_keymap = { { ISFUNC, (Function *)0x0 }, /* Control-z */ { ISKMAP, (Function *)emacs_meta_keymap }, /* Control-[ */ { ISFUNC, (Function *)0x0 }, /* Control-\ */ - { ISFUNC, (Function *)0x0 }, /* Control-] */ + { ISFUNC, rl_char_search }, /* Control-] */ { ISFUNC, (Function *)0x0 }, /* Control-^ */ { ISFUNC, rl_undo_command }, /* Control-_ */ @@ -358,22 +358,22 @@ KEYMAP_ENTRY_ARRAY emacs_meta_keymap = { { ISFUNC, rl_complete }, /* Meta-Control-[ */ { ISFUNC, (Function *)0x0 }, /* Meta-Control-\ */ - { ISFUNC, (Function *)0x0 }, /* Meta-Control-] */ + { ISFUNC, rl_backward_char_search }, /* Meta-Control-] */ { ISFUNC, (Function *)0x0 }, /* Meta-Control-^ */ { ISFUNC, (Function *)0x0 }, /* Meta-Control-_ */ /* The start of printing characters. */ - { ISFUNC, (Function *)0x0 }, /* Meta-SPACE */ + { ISFUNC, rl_set_mark }, /* Meta-SPACE */ { ISFUNC, (Function *)0x0 }, /* Meta-! */ { ISFUNC, (Function *)0x0 }, /* Meta-" */ - { ISFUNC, (Function *)0x0 }, /* Meta-# */ + { ISFUNC, rl_insert_comment },/* Meta-# */ { ISFUNC, (Function *)0x0 }, /* Meta-$ */ { ISFUNC, (Function *)0x0 }, /* Meta-% */ { ISFUNC, rl_tilde_expand }, /* Meta-& */ { ISFUNC, (Function *)0x0 }, /* Meta-' */ { ISFUNC, (Function *)0x0 }, /* Meta-( */ { ISFUNC, (Function *)0x0 }, /* Meta-) */ - { ISFUNC, (Function *)0x0 }, /* Meta-* */ + { ISFUNC, rl_insert_completions }, /* Meta-* */ { ISFUNC, (Function *)0x0 }, /* Meta-+ */ { ISFUNC, (Function *)0x0 }, /* Meta-, */ { ISFUNC, rl_digit_argument }, /* Meta-- */ @@ -396,7 +396,7 @@ KEYMAP_ENTRY_ARRAY emacs_meta_keymap = { { ISFUNC, (Function *)0x0 }, /* Meta-: */ { ISFUNC, (Function *)0x0 }, /* Meta-; */ { ISFUNC, rl_beginning_of_history }, /* Meta-< */ - { ISFUNC, (Function *)0x0 }, /* Meta-= */ + { ISFUNC, rl_possible_completions }, /* Meta-= */ { ISFUNC, rl_end_of_history }, /* Meta-> */ { ISFUNC, rl_possible_completions }, /* Meta-? */ { ISFUNC, (Function *)0x0 }, /* Meta-@ */ @@ -632,7 +632,7 @@ KEYMAP_ENTRY_ARRAY emacs_ctlx_keymap = { { ISFUNC, rl_undo_command }, /* Control-u */ { ISFUNC, (Function *)0x0 }, /* Control-v */ { ISFUNC, (Function *)0x0 }, /* Control-w */ - { ISFUNC, (Function *)0x0 }, /* Control-x */ + { ISFUNC, rl_exchange_point_and_mark },/* Control-x */ { ISFUNC, (Function *)0x0 }, /* Control-y */ { ISFUNC, (Function *)0x0 }, /* Control-z */ { ISFUNC, (Function *)0x0 }, /* Control-[ */ diff --git a/lib/readline/examples/Makefile b/lib/readline/examples/Makefile index 3d1fc52..cfa7745 100644 --- a/lib/readline/examples/Makefile +++ b/lib/readline/examples/Makefile @@ -1,12 +1,19 @@ # This is the Makefile for the examples subdirectory of readline. -*- text -*- # - -EXECUTABLES = fileman -CFLAGS = -g -I../.. +EXECUTABLES = fileman rltest +CFLAGS = -g -I../.. -I.. LDFLAGS = -g -L.. +.c.o: + $(CC) $(CFLAGS) -c $< + +all: $(EXECUTABLES) + fileman: fileman.o - $(CC) $(LDFLAGS) -o fileman fileman.o -lreadline -ltermcap + $(CC) $(LDFLAGS) -o $@ fileman.o -lreadline -ltermcap + +rltest: rltest.o + $(CC) $(LDFLAGS) -o $@ rltest.o -lreadline -ltermcap fileman.o: fileman.c - +rltest.o: rltest.c diff --git a/lib/readline/examples/fileman.c b/lib/readline/examples/fileman.c index 3ecb9f1..8709120 100644 --- a/lib/readline/examples/fileman.c +++ b/lib/readline/examples/fileman.c @@ -194,10 +194,11 @@ initialize_readline () rl_attempted_completion_function = (CPPFunction *)fileman_completion; } -/* Attempt to complete on the contents of TEXT. START and END show the - region of TEXT that contains the word to complete. We can use the - entire line in case we want to do some simple parsing. Return the - array of matches, or NULL if there aren't any. */ +/* Attempt to complete on the contents of TEXT. START and END bound the + region of rl_line_buffer that contains the word to complete. TEXT is + the word to complete. We can use the entire contents of rl_line_buffer + in case we want to do some simple parsing. Return the array of matches, + or NULL if there aren't any. */ char ** fileman_completion (text, start, end) char *text; diff --git a/lib/readline/examples/rltest.c b/lib/readline/examples/rltest.c new file mode 100644 index 0000000..311629f --- /dev/null +++ b/lib/readline/examples/rltest.c @@ -0,0 +1,54 @@ +/* **************************************************************** */ +/* */ +/* Testing Readline */ +/* */ +/* **************************************************************** */ + +#include <stdio.h> +#include <sys/types.h> +#include "../readline.h" +#include "../history.h" + +main () +{ + HIST_ENTRY **history_list (); + char *temp = (char *)NULL; + char *prompt = "readline$ "; + int done = 0; + + while (!done) + { + temp = readline (prompt); + + /* Test for EOF. */ + if (!temp) + exit (1); + + /* If there is anything on the line, print it and remember it. */ + if (*temp) + { + fprintf (stderr, "%s\r\n", temp); + add_history (temp); + } + + /* Check for `command' that we handle. */ + if (strcmp (temp, "quit") == 0) + done = 1; + + if (strcmp (temp, "list") == 0) + { + HIST_ENTRY **list = history_list (); + register int i; + if (list) + { + for (i = 0; list[i]; i++) + { + fprintf (stderr, "%d: %s\r\n", i, list[i]->line); + free (list[i]->line); + } + free (list); + } + } + free (temp); + } +} diff --git a/lib/readline/funmap.c b/lib/readline/funmap.c index 9255974..6b7d351 100644 --- a/lib/readline/funmap.c +++ b/lib/readline/funmap.c @@ -21,11 +21,11 @@ 675 Mass Ave, Cambridge, MA 02139, USA. */ #define READLINE_LIBRARY -#if defined (STATIC_MALLOC) -static char *xmalloc (), *xrealloc (); -#else +#if defined (HAVE_CONFIG_H) +# include <config.h> +#endif + extern char *xmalloc (), *xrealloc (); -#endif /* STATIC_MALLOC */ #if !defined (BUFSIZ) #include <stdio.h> @@ -40,18 +40,17 @@ extern char *xmalloc (), *xrealloc (); #include "rlconf.h" #include "readline.h" -static int qsort_string_compare (); +extern int _rl_qsort_string_compare (); -FUNMAP **funmap = (FUNMAP **)NULL; -static int funmap_size = 0; -static int funmap_entry = 0; +FUNMAP **funmap; +static int funmap_size; +static int funmap_entry; /* After initializing the function map, this is the index of the first program specific function. */ int funmap_program_specific_entry_start; static FUNMAP default_funmap[] = { - { "abort", rl_abort }, { "accept-line", rl_newline }, { "arrow-key-prefix", rl_arrow_keys }, @@ -64,26 +63,35 @@ static FUNMAP default_funmap[] = { { "beginning-of-line", rl_beg_of_line }, { "call-last-kbd-macro", rl_call_last_kbd_macro }, { "capitalize-word", rl_capitalize_word }, + { "character-search", rl_char_search }, + { "character-search-backward", rl_backward_char_search }, { "clear-screen", rl_clear_screen }, { "complete", rl_complete }, + { "copy-backward-word", rl_copy_backward_word }, + { "copy-forward-word", rl_copy_forward_word }, + { "copy-region-as-kill", rl_copy_region_to_kill }, { "delete-char", rl_delete }, { "delete-horizontal-space", rl_delete_horizontal_space }, { "digit-argument", rl_digit_argument }, { "do-lowercase-version", rl_do_lowercase_version }, { "downcase-word", rl_downcase_word }, { "dump-functions", rl_dump_functions }, + { "dump-variables", rl_dump_variables }, { "emacs-editing-mode", rl_emacs_editing_mode }, { "end-kbd-macro", rl_end_kbd_macro }, { "end-of-history", rl_end_of_history }, { "end-of-line", rl_end_of_line }, + { "exchange-point-and-mark", rl_exchange_point_and_mark }, { "forward-char", rl_forward }, { "forward-search-history", rl_forward_search_history }, { "forward-word", rl_forward_word }, { "history-search-backward", rl_history_search_backward }, { "history-search-forward", rl_history_search_forward }, + { "insert-comment", rl_insert_comment }, { "insert-completions", rl_insert_completions }, { "kill-whole-line", rl_kill_full_line }, { "kill-line", rl_kill_line }, + { "kill-region", rl_kill_region }, { "kill-word", rl_kill_word }, { "next-history", rl_get_next_history }, { "non-incremental-forward-search-history", rl_noninc_forward_search }, @@ -98,6 +106,7 @@ static FUNMAP default_funmap[] = { { "reverse-search-history", rl_reverse_search_history }, { "revert-line", rl_revert_line }, { "self-insert", rl_insert }, + { "set-mark", rl_set_mark }, { "start-kbd-macro", rl_start_kbd_macro }, { "tab-insert", rl_tab_insert }, { "tilde-expand", rl_tilde_expand }, @@ -118,6 +127,7 @@ static FUNMAP default_funmap[] = { { "vi-append-eol", rl_vi_append_eol }, { "vi-append-mode", rl_vi_append_mode }, { "vi-arg-digit", rl_vi_arg_digit }, + { "vi-back-to-indent", rl_vi_back_to_indent }, { "vi-bWord", rl_vi_bWord }, { "vi-bracktype", rl_vi_bracktype }, { "vi-bword", rl_vi_bword }, @@ -126,7 +136,6 @@ static FUNMAP default_funmap[] = { { "vi-change-to", rl_vi_change_to }, { "vi-char-search", rl_vi_char_search }, { "vi-column", rl_vi_column }, - { "vi-comment", rl_vi_comment }, { "vi-complete", rl_vi_complete }, { "vi-delete", rl_vi_delete }, { "vi-delete-to", rl_vi_delete_to }, @@ -136,8 +145,10 @@ static FUNMAP default_funmap[] = { { "vi-eof-maybe", rl_vi_eof_maybe }, { "vi-eword", rl_vi_eword }, { "vi-fWord", rl_vi_fWord }, + { "vi-fetch-history", rl_vi_fetch_history }, { "vi-first-print", rl_vi_first_print }, { "vi-fword", rl_vi_fword }, + { "vi-goto-mark", rl_vi_goto_mark }, { "vi-insert-beg", rl_vi_insert_beg }, { "vi-insertion-mode", rl_vi_insertion_mode }, { "vi-match", rl_vi_match }, @@ -151,6 +162,7 @@ static FUNMAP default_funmap[] = { { "vi-replace", rl_vi_replace }, { "vi-search", rl_vi_search }, { "vi-search-again", rl_vi_search_again }, + { "vi-set-mark", rl_vi_set_mark }, { "vi-subst", rl_vi_subst }, { "vi-tilde-expand", rl_vi_tilde_expand }, { "vi-yank-arg", rl_vi_yank_arg }, @@ -160,16 +172,16 @@ static FUNMAP default_funmap[] = { {(char *)NULL, (Function *)NULL } }; +int rl_add_funmap_entry (name, function) char *name; Function *function; { if (funmap_entry + 2 >= funmap_size) - if (!funmap) - funmap = (FUNMAP **)xmalloc ((funmap_size = 80) * sizeof (FUNMAP *)); - else - funmap = - (FUNMAP **)xrealloc (funmap, (funmap_size += 80) * sizeof (FUNMAP *)); + { + funmap_size += 64; + funmap = (FUNMAP **)xrealloc (funmap, funmap_size * sizeof (FUNMAP *)); + } funmap[funmap_entry] = (FUNMAP *)xmalloc (sizeof (FUNMAP)); funmap[funmap_entry]->name = name; @@ -179,7 +191,7 @@ rl_add_funmap_entry (name, function) return funmap_entry; } -static int funmap_initialized = 0; +static int funmap_initialized; /* Make the funmap contain all of the default entries. */ void @@ -203,46 +215,28 @@ rl_initialize_funmap () char ** rl_funmap_names () { - char **result = (char **)NULL; + char **result; int result_size, result_index; - result_size = result_index = 0; - /* Make sure that the function map has been initialized. */ rl_initialize_funmap (); - for (result_index = 0; funmap[result_index]; result_index++) + for (result_index = result_size = 0, result = (char **)NULL; funmap[result_index]; result_index++) { if (result_index + 2 > result_size) { - if (!result) - result = (char **)xmalloc ((result_size = 20) * sizeof (char *)); - else - result = (char **) - xrealloc (result, (result_size += 20) * sizeof (char *)); + result_size += 20; + result = (char **)xrealloc (result, result_size * sizeof (char *)); } result[result_index] = funmap[result_index]->name; result[result_index + 1] = (char *)NULL; } - qsort (result, result_index, sizeof (char *), qsort_string_compare); + qsort (result, result_index, sizeof (char *), _rl_qsort_string_compare); return (result); } -/* Stupid comparison routine for qsort () ing strings. */ -static int -qsort_string_compare (s1, s2) - register char **s1, **s2; -{ - int r; - - r = **s1 - **s2; - if (r == 0) - r = strcmp (*s1, *s2); - return r; -} - /* Things that mean `Control'. */ char *possible_control_prefixes[] = { "Control-", "C-", "CTRL-", (char *)NULL @@ -251,49 +245,3 @@ char *possible_control_prefixes[] = { char *possible_meta_prefixes[] = { "Meta", "M-", (char *)NULL }; - -#if defined (STATIC_MALLOC) - -/* **************************************************************** */ -/* */ -/* xmalloc and xrealloc () */ -/* */ -/* **************************************************************** */ - -static void memory_error_and_abort (); - -static char * -xmalloc (bytes) - int bytes; -{ - char *temp = (char *)malloc (bytes); - - if (!temp) - memory_error_and_abort (); - return (temp); -} - -static char * -xrealloc (pointer, bytes) - char *pointer; - int bytes; -{ - char *temp; - - if (!pointer) - temp = (char *)malloc (bytes); - else - temp = (char *)realloc (pointer, bytes); - - if (!temp) - memory_error_and_abort (); - return (temp); -} - -static void -memory_error_and_abort () -{ - fprintf (stderr, "history: Out of virtual memory!\n"); - abort (); -} -#endif /* STATIC_MALLOC */ diff --git a/lib/readline/histexpand.c b/lib/readline/histexpand.c new file mode 100644 index 0000000..d916c74 --- /dev/null +++ b/lib/readline/histexpand.c @@ -0,0 +1,1358 @@ +/* histexpand.c -- history expansion. */ + +/* Copyright (C) 1989, 1992 Free Software Foundation, Inc. + + This file contains the GNU History Library (the Library), a set of + routines for managing the text of previously typed lines. + + The Library is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + The Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + The GNU General Public License is often shipped with GNU software, and + is generally kept in a file called COPYING or LICENSE. If you do not + have a copy of the license, write to the Free Software Foundation, + 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include <config.h> +#endif + +#include <stdio.h> + +#if defined (HAVE_STDLIB_H) +# include <stdlib.h> +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_UNISTD_H) +# include <unistd.h> +#endif + +#if defined (HAVE_STRING_H) +# include <string.h> +#else +# include <strings.h> +#endif /* !HAVE_STRING_H */ + +#include "history.h" +#include "histlib.h" + +static char error_pointer; + +static char *subst_lhs; +static char *subst_rhs; +static int subst_lhs_len; +static int subst_rhs_len; + +static char *get_history_word_specifier (); +static char *history_find_word (); + +extern int history_offset; + +#if defined (SHELL) +extern char *single_quote (); +#else +static char *single_quote (); +#endif /* !SHELL */ +static char *quote_breaks (); + +extern char *xmalloc (), *xrealloc (); + +/* Variables exported by this file. */ +/* The character that represents the start of a history expansion + request. This is usually `!'. */ +char history_expansion_char = '!'; + +/* The character that invokes word substitution if found at the start of + a line. This is usually `^'. */ +char history_subst_char = '^'; + +/* During tokenization, if this character is seen as the first character + of a word, then it, and all subsequent characters upto a newline are + ignored. For a Bourne shell, this should be '#'. Bash special cases + the interactive comment character to not be a comment delimiter. */ +char history_comment_char = '\0'; + +/* The list of characters which inhibit the expansion of text if found + immediately following history_expansion_char. */ +char *history_no_expand_chars = " \t\n\r="; + +/* If set to a non-zero value, single quotes inhibit history expansion. + The default is 0. */ +int history_quotes_inhibit_expansion = 0; + +/* **************************************************************** */ +/* */ +/* History Expansion */ +/* */ +/* **************************************************************** */ + +/* Hairy history expansion on text, not tokens. This is of general + use, and thus belongs in this library. */ + +/* The last string searched for by a !?string? search. */ +static char *search_string; + +/* The last string matched by a !?string? search. */ +static char *search_match; + +/* Return the event specified at TEXT + OFFSET modifying OFFSET to + point to after the event specifier. Just a pointer to the history + line is returned; NULL is returned in the event of a bad specifier. + You pass STRING with *INDEX equal to the history_expansion_char that + begins this specification. + DELIMITING_QUOTE is a character that is allowed to end the string + specification for what to search for in addition to the normal + characters `:', ` ', `\t', `\n', and sometimes `?'. + So you might call this function like: + line = get_history_event ("!echo:p", &index, 0); */ +char * +get_history_event (string, caller_index, delimiting_quote) + char *string; + int *caller_index; + int delimiting_quote; +{ + register int i; + register char c; + HIST_ENTRY *entry; + int which, sign, local_index, substring_okay; + Function *search_func; + char *temp; + + /* The event can be specified in a number of ways. + + !! the previous command + !n command line N + !-n current command-line minus N + !str the most recent command starting with STR + !?str[?] + the most recent command containing STR + + All values N are determined via HISTORY_BASE. */ + + i = *caller_index; + + if (string[i] != history_expansion_char) + return ((char *)NULL); + + /* Move on to the specification. */ + i++; + + sign = 1; + substring_okay = 0; + +#define RETURN_ENTRY(e, w) \ + return ((e = history_get (w)) ? e->line : (char *)NULL) + + /* Handle !! case. */ + if (string[i] == history_expansion_char) + { + i++; + which = history_base + (history_length - 1); + *caller_index = i; + RETURN_ENTRY (entry, which); + } + + /* Hack case of numeric line specification. */ + if (string[i] == '-') + { + sign = -1; + i++; + } + + if (_rl_digit_p (string[i])) + { + /* Get the extent of the digits and compute the value. */ + for (which = 0; _rl_digit_p (string[i]); i++) + which = (which * 10) + _rl_digit_value (string[i]); + + *caller_index = i; + + if (sign < 0) + which = (history_length + history_base) - which; + + RETURN_ENTRY (entry, which); + } + + /* This must be something to search for. If the spec begins with + a '?', then the string may be anywhere on the line. Otherwise, + the string must be found at the start of a line. */ + if (string[i] == '?') + { + substring_okay++; + i++; + } + + /* Only a closing `?' or a newline delimit a substring search string. */ + for (local_index = i; c = string[i]; i++) + if ((!substring_okay && (whitespace (c) || c == ':' || + (history_search_delimiter_chars && member (c, history_search_delimiter_chars)) || + string[i] == delimiting_quote)) || + string[i] == '\n' || + (substring_okay && string[i] == '?')) + break; + + which = i - local_index; + temp = xmalloc (1 + which); + if (which) + strncpy (temp, string + local_index, which); + temp[which] = '\0'; + + if (substring_okay && string[i] == '?') + i++; + + *caller_index = i; + +#define FAIL_SEARCH() \ + do { \ + history_offset = history_length; free (temp) ; return (char *)NULL; \ + } while (0) + + /* If there is no search string, try to use the previous search string, + if one exists. If not, fail immediately. */ + if (*temp == '\0' && substring_okay) + { + if (search_string) + { + free (temp); + temp = savestring (search_string); + } + else + FAIL_SEARCH (); + } + + search_func = substring_okay ? history_search : history_search_prefix; + while (1) + { + local_index = (*search_func) (temp, -1); + + if (local_index < 0) + FAIL_SEARCH (); + + if (local_index == 0 || substring_okay) + { + entry = current_history (); + history_offset = history_length; + + /* If this was a substring search, then remember the + string that we matched for word substitution. */ + if (substring_okay) + { + FREE (search_string); + search_string = temp; + + FREE (search_match); + search_match = history_find_word (entry->line, local_index); + } + else + free (temp); + + return (entry->line); + } + + if (history_offset) + history_offset--; + else + FAIL_SEARCH (); + } +#undef FAIL_SEARCH +#undef RETURN_ENTRY +} + +/* Function for extracting single-quoted strings. Used for inhibiting + history expansion within single quotes. */ + +/* Extract the contents of STRING as if it is enclosed in single quotes. + SINDEX, when passed in, is the offset of the character immediately + following the opening single quote; on exit, SINDEX is left pointing + to the closing single quote. */ +static void +hist_string_extract_single_quoted (string, sindex) + char *string; + int *sindex; +{ + register int i; + + for (i = *sindex; string[i] && string[i] != '\''; i++) + ; + + *sindex = i; +} + +#if !defined (SHELL) +/* Does shell-like quoting using single quotes. */ +static char * +single_quote (string) + char *string; +{ + register int c; + char *result, *r, *s; + + result = (char *)xmalloc (3 + (3 * strlen (string))); + r = result; + *r++ = '\''; + + for (s = string; s && (c = *s); s++) + { + *r++ = c; + + if (c == '\'') + { + *r++ = '\\'; /* insert escaped single quote */ + *r++ = '\''; + *r++ = '\''; /* start new quoted string */ + } + } + + *r++ = '\''; + *r = '\0'; + + return (result); +} +#endif /* !SHELL */ + +static char * +quote_breaks (s) + char *s; +{ + register char *p, *r; + char *ret; + int len = 3; + + for (p = s; p && *p; p++, len++) + { + if (*p == '\'') + len += 3; + else if (whitespace (*p) || *p == '\n') + len += 2; + } + + r = ret = xmalloc (len); + *r++ = '\''; + for (p = s; p && *p; ) + { + if (*p == '\'') + { + *r++ = '\''; + *r++ = '\\'; + *r++ = '\''; + *r++ = '\''; + p++; + } + else if (whitespace (*p) || *p == '\n') + { + *r++ = '\''; + *r++ = *p++; + *r++ = '\''; + } + else + *r++ = *p++; + } + *r++ = '\''; + *r = '\0'; + return ret; +} + +static char * +hist_error(s, start, current, errtype) + char *s; + int start, current, errtype; +{ + char *temp, *emsg; + int ll, elen; + + ll = current - start; + + switch (errtype) + { + case EVENT_NOT_FOUND: + emsg = "event not found"; + elen = 15; + break; + case BAD_WORD_SPEC: + emsg = "bad word specifier"; + elen = 18; + break; + case SUBST_FAILED: + emsg = "substitution failed"; + elen = 19; + break; + case BAD_MODIFIER: + emsg = "unrecognized history modifier"; + elen = 29; + break; + default: + emsg = "unknown expansion error"; + elen = 23; + break; + } + + temp = xmalloc (ll + elen + 3); + strncpy (temp, s + start, ll); + temp[ll] = ':'; + temp[ll + 1] = ' '; + strcpy (temp + ll + 2, emsg); + return (temp); +} + +/* Get a history substitution string from STR starting at *IPTR + and return it. The length is returned in LENPTR. + + A backslash can quote the delimiter. If the string is the + empty string, the previous pattern is used. If there is + no previous pattern for the lhs, the last history search + string is used. + + If IS_RHS is 1, we ignore empty strings and set the pattern + to "" anyway. subst_lhs is not changed if the lhs is empty; + subst_rhs is allowed to be set to the empty string. */ + +static char * +get_subst_pattern (str, iptr, delimiter, is_rhs, lenptr) + char *str; + int *iptr, delimiter, is_rhs, *lenptr; +{ + register int si, i, j, k; + char *s = (char *) NULL; + + i = *iptr; + + for (si = i; str[si] && str[si] != delimiter; si++) + if (str[si] == '\\' && str[si + 1] == delimiter) + si++; + + if (si > i || is_rhs) + { + s = xmalloc (si - i + 1); + for (j = 0, k = i; k < si; j++, k++) + { + /* Remove a backslash quoting the search string delimiter. */ + if (str[k] == '\\' && str[k + 1] == delimiter) + k++; + s[j] = str[k]; + } + s[j] = '\0'; + if (lenptr) + *lenptr = j; + } + + i = si; + if (str[i]) + i++; + *iptr = i; + + return s; +} + +static void +postproc_subst_rhs () +{ + char *new; + int i, j, new_size; + + new = xmalloc (new_size = subst_rhs_len + subst_lhs_len); + for (i = j = 0; i < subst_rhs_len; i++) + { + if (subst_rhs[i] == '&') + { + if (j + subst_lhs_len >= new_size) + new = xrealloc (new, (new_size = new_size * 2 + subst_lhs_len)); + strcpy (new + j, subst_lhs); + j += subst_lhs_len; + } + else + { + /* a single backslash protects the `&' from lhs interpolation */ + if (subst_rhs[i] == '\\' && subst_rhs[i + 1] == '&') + i++; + if (j >= new_size) + new = xrealloc (new, new_size *= 2); + new[j++] = subst_rhs[i]; + } + } + new[j] = '\0'; + free (subst_rhs); + subst_rhs = new; + subst_rhs_len = j; +} + +/* Expand the bulk of a history specifier starting at STRING[START]. + Returns 0 if everything is OK, -1 if an error occurred, and 1 + if the `p' modifier was supplied and the caller should just print + the returned string. Returns the new index into string in + *END_INDEX_PTR, and the expanded specifier in *RET_STRING. */ +static int +history_expand_internal (string, start, end_index_ptr, ret_string, current_line) + char *string; + int start, *end_index_ptr; + char **ret_string; + char *current_line; /* for !# */ +{ + int i, n, starting_index; + int substitute_globally, want_quotes, print_only; + char *event, *temp, *result, *tstr, *t, c, *word_spec; + int result_len; + + result = xmalloc (result_len = 128); + + i = start; + + /* If it is followed by something that starts a word specifier, + then !! is implied as the event specifier. */ + + if (member (string[i + 1], ":$*%^")) + { + char fake_s[3]; + int fake_i = 0; + i++; + fake_s[0] = fake_s[1] = history_expansion_char; + fake_s[2] = '\0'; + event = get_history_event (fake_s, &fake_i, 0); + } + else if (string[i + 1] == '#') + { + i += 2; + event = current_line; + } + else + { + int quoted_search_delimiter = 0; + + /* If the character before this `!' is a double or single + quote, then this expansion takes place inside of the + quoted string. If we have to search for some text ("!foo"), + allow the delimiter to end the search string. */ + if (i && (string[i - 1] == '\'' || string[i - 1] == '"')) + quoted_search_delimiter = string[i - 1]; + event = get_history_event (string, &i, quoted_search_delimiter); + } + + if (event == 0) + { + *ret_string = hist_error (string, start, i, EVENT_NOT_FOUND); + free (result); + return (-1); + } + + /* If a word specifier is found, then do what that requires. */ + starting_index = i; + word_spec = get_history_word_specifier (string, event, &i); + + /* There is no such thing as a `malformed word specifier'. However, + it is possible for a specifier that has no match. In that case, + we complain. */ + if (word_spec == (char *)&error_pointer) + { + *ret_string = hist_error (string, starting_index, i, BAD_WORD_SPEC); + free (result); + return (-1); + } + + /* If no word specifier, than the thing of interest was the event. */ + temp = word_spec ? savestring (word_spec) : savestring (event); + FREE (word_spec); + + /* Perhaps there are other modifiers involved. Do what they say. */ + want_quotes = substitute_globally = print_only = 0; + starting_index = i; + + while (string[i] == ':') + { + c = string[i + 1]; + + if (c == 'g') + { + substitute_globally = 1; + i++; + c = string[i + 1]; + } + + switch (c) + { + default: + *ret_string = hist_error (string, i+1, i+2, BAD_MODIFIER); + free (result); + free (temp); + return -1; + + case 'q': + want_quotes = 'q'; + break; + + case 'x': + want_quotes = 'x'; + break; + + /* :p means make this the last executed line. So we + return an error state after adding this line to the + history. */ + case 'p': + print_only++; + break; + + /* :t discards all but the last part of the pathname. */ + case 't': + tstr = strrchr (temp, '/'); + if (tstr) + { + tstr++; + t = savestring (tstr); + free (temp); + temp = t; + } + break; + + /* :h discards the last part of a pathname. */ + case 'h': + tstr = strrchr (temp, '/'); + if (tstr) + *tstr = '\0'; + break; + + /* :r discards the suffix. */ + case 'r': + tstr = strrchr (temp, '.'); + if (tstr) + *tstr = '\0'; + break; + + /* :e discards everything but the suffix. */ + case 'e': + tstr = strrchr (temp, '.'); + if (tstr) + { + t = savestring (tstr); + free (temp); + temp = t; + } + break; + + /* :s/this/that substitutes `that' for the first + occurrence of `this'. :gs/this/that substitutes `that' + for each occurrence of `this'. :& repeats the last + substitution. :g& repeats the last substitution + globally. */ + + case '&': + case 's': + { + char *new_event, *t; + int delimiter, failed, si, l_temp; + + if (c == 's') + { + if (i + 2 < (int)strlen (string)) + delimiter = string[i + 2]; + else + break; /* no search delimiter */ + + i += 3; + + t = get_subst_pattern (string, &i, delimiter, 0, &subst_lhs_len); + /* An empty substitution lhs with no previous substitution + uses the last search string as the lhs. */ + if (t) + { + FREE (subst_lhs); + subst_lhs = t; + } + else if (!subst_lhs) + { + if (search_string && *search_string) + { + subst_lhs = savestring (search_string); + subst_lhs_len = strlen (subst_lhs); + } + else + { + subst_lhs = (char *) NULL; + subst_lhs_len = 0; + } + } + + /* If there is no lhs, the substitution can't succeed. */ + if (subst_lhs_len == 0) + { + *ret_string = hist_error (string, starting_index, i, SUBST_FAILED); + free (result); + free (temp); + return -1; + } + + FREE (subst_rhs); + subst_rhs = get_subst_pattern (string, &i, delimiter, 1, &subst_rhs_len); + + /* If `&' appears in the rhs, it's supposed to be replaced + with the lhs. */ + if (member ('&', subst_rhs)) + postproc_subst_rhs (); + } + else + i += 2; + + l_temp = strlen (temp); + /* Ignore impossible cases. */ + if (subst_lhs_len > l_temp) + { + *ret_string = hist_error (string, starting_index, i, SUBST_FAILED); + free (result); + free (temp); + return (-1); + } + + /* Find the first occurrence of THIS in TEMP. */ + si = 0; + for (failed = 1; (si + subst_lhs_len) <= l_temp; si++) + if (STREQN (temp+si, subst_lhs, subst_lhs_len)) + { + int len = subst_rhs_len - subst_lhs_len + l_temp; + new_event = xmalloc (1 + len); + strncpy (new_event, temp, si); + strncpy (new_event + si, subst_rhs, subst_rhs_len); + strncpy (new_event + si + subst_rhs_len, + temp + si + subst_lhs_len, + l_temp - (si + subst_lhs_len)); + new_event[len] = '\0'; + free (temp); + temp = new_event; + + failed = 0; + + if (substitute_globally) + { + si += subst_rhs_len; + l_temp = strlen (temp); + substitute_globally++; + continue; + } + else + break; + } + + if (substitute_globally > 1) + { + substitute_globally = 0; + continue; /* don't want to increment i */ + } + + if (failed == 0) + continue; /* don't want to increment i */ + + *ret_string = hist_error (string, starting_index, i, SUBST_FAILED); + free (result); + free (temp); + return (-1); + } + } + i += 2; + } + /* Done with modfiers. */ + /* Believe it or not, we have to back the pointer up by one. */ + --i; + + if (want_quotes) + { + char *x; + + if (want_quotes == 'q') + x = single_quote (temp); + else if (want_quotes == 'x') + x = quote_breaks (temp); + else + x = savestring (temp); + + free (temp); + temp = x; + } + + n = strlen (temp); + if (n >= result_len) + result = xrealloc (result, n + 2); + strcpy (result, temp); + free (temp); + + *end_index_ptr = i; + *ret_string = result; + return (print_only); +} + +/* Expand the string STRING, placing the result into OUTPUT, a pointer + to a string. Returns: + + -1) If there was an error in expansion. + 0) If no expansions took place (or, if the only change in + the text was the de-slashifying of the history expansion + character) + 1) If expansions did take place + 2) If the `p' modifier was given and the caller should print the result + + If an error ocurred in expansion, then OUTPUT contains a descriptive + error message. */ + +#define ADD_STRING(s) \ + do \ + { \ + int sl = strlen (s); \ + j += sl; \ + if (j >= result_len) \ + { \ + while (j >= result_len) \ + result_len += 128; \ + result = xrealloc (result, result_len); \ + } \ + strcpy (result + j - sl, s); \ + } \ + while (0) + +#define ADD_CHAR(c) \ + do \ + { \ + if (j >= result_len - 1) \ + result = xrealloc (result, result_len += 64); \ + result[j++] = c; \ + result[j] = '\0'; \ + } \ + while (0) + +int +history_expand (hstring, output) + char *hstring; + char **output; +{ + register int j; + int i, r, l, passc, cc, modified, eindex, only_printing; + char *string; + + /* The output string, and its length. */ + int result_len; + char *result; + + /* Used when adding the string. */ + char *temp; + + /* Setting the history expansion character to 0 inhibits all + history expansion. */ + if (history_expansion_char == 0) + { + *output = savestring (hstring); + return (0); + } + + /* Prepare the buffer for printing error messages. */ + result = xmalloc (result_len = 256); + result[0] = '\0'; + + only_printing = modified = 0; + l = strlen (hstring); + + /* Grovel the string. Only backslash can quote the history escape + character. We also handle arg specifiers. */ + + /* Before we grovel forever, see if the history_expansion_char appears + anywhere within the text. */ + + /* The quick substitution character is a history expansion all right. That + is to say, "^this^that^" is equivalent to "!!:s^this^that^", and in fact, + that is the substitution that we do. */ + if (hstring[0] == history_subst_char) + { + string = xmalloc (l + 5); + + string[0] = string[1] = history_expansion_char; + string[2] = ':'; + string[3] = 's'; + strcpy (string + 4, hstring); + l += 4; + } + else + { + string = hstring; + /* If not quick substitution, still maybe have to do expansion. */ + + /* `!' followed by one of the characters in history_no_expand_chars + is NOT an expansion. */ + for (i = 0; string[i]; i++) + { + cc = string[i + 1]; + if (string[i] == history_expansion_char) + { + if (!cc || member (cc, history_no_expand_chars)) + continue; +#if defined (SHELL) + /* The shell uses ! as a pattern negation character + in globbing [...] expressions, so let those pass + without expansion. */ + else if (i > 0 && (string[i - 1] == '[') && + member (']', string + i + 1)) + continue; + /* The shell uses ! as the indirect expansion character, so + let those expansions pass as well. */ + else if (i > 1 && string[i - 1] == '{' && string[i - 2] == '$' && + member ('}', string + i + 1)) + continue; +#endif /* SHELL */ + else + break; + } + else if (history_quotes_inhibit_expansion && string[i] == '\'') + { + /* If this is bash, single quotes inhibit history expansion. */ + i++; + hist_string_extract_single_quoted (string, &i); + } + else if (history_quotes_inhibit_expansion && string[i] == '\\') + { + /* If this is bash, allow backslashes to quote single + quotes and the history expansion character. */ + if (cc == '\'' || cc == history_expansion_char) + i++; + } + } + + if (string[i] != history_expansion_char) + { + free (result); + *output = savestring (string); + return (0); + } + } + + /* Extract and perform the substitution. */ + for (passc = i = j = 0; i < l; i++) + { + int tchar = string[i]; + + if (passc) + { + passc = 0; + ADD_CHAR (tchar); + continue; + } + + if (tchar == history_expansion_char) + tchar = -3; + + switch (tchar) + { + default: + ADD_CHAR (string[i]); + break; + + case '\\': + passc++; + ADD_CHAR (tchar); + break; + + case '\'': + { + /* If history_quotes_inhibit_expansion is set, single quotes + inhibit history expansion. */ + if (history_quotes_inhibit_expansion) + { + int quote, slen; + + quote = i++; + hist_string_extract_single_quoted (string, &i); + + slen = i - quote + 2; + temp = xmalloc (slen); + strncpy (temp, string + quote, slen); + temp[slen - 1] = '\0'; + ADD_STRING (temp); + free (temp); + } + else + ADD_CHAR (string[i]); + break; + } + + case -3: /* history_expansion_char */ + cc = string[i + 1]; + + /* If the history_expansion_char is followed by one of the + characters in history_no_expand_chars, then it is not a + candidate for expansion of any kind. */ + if (member (cc, history_no_expand_chars)) + { + ADD_CHAR (string[i]); + break; + } + +#if defined (NO_BANG_HASH_MODIFIERS) + /* There is something that is listed as a `word specifier' in csh + documentation which means `the expanded text to this point'. + That is not a word specifier, it is an event specifier. If we + don't want to allow modifiers with `!#', just stick the current + output line in again. */ + if (cc == '#') + { + if (result) + { + temp = xmalloc (1 + strlen (result)); + strcpy (temp, result); + ADD_STRING (temp); + free (temp); + } + i++; + break; + } +#endif + + r = history_expand_internal (string, i, &eindex, &temp, result); + if (r < 0) + { + *output = temp; + free (result); + if (string != hstring) + free (string); + return -1; + } + else + { + if (temp) + { + modified++; + if (*temp) + ADD_STRING (temp); + free (temp); + } + only_printing = r == 1; + i = eindex; + } + break; + } + } + + *output = result; + if (string != hstring) + free (string); + + if (only_printing) + { + add_history (result); + return (2); + } + + return (modified != 0); +} + +/* Return a consed string which is the word specified in SPEC, and found + in FROM. NULL is returned if there is no spec. The address of + ERROR_POINTER is returned if the word specified cannot be found. + CALLER_INDEX is the offset in SPEC to start looking; it is updated + to point to just after the last character parsed. */ +static char * +get_history_word_specifier (spec, from, caller_index) + char *spec, *from; + int *caller_index; +{ + register int i = *caller_index; + int first, last; + int expecting_word_spec = 0; + char *result; + + /* The range of words to return doesn't exist yet. */ + first = last = 0; + result = (char *)NULL; + + /* If we found a colon, then this *must* be a word specification. If + it isn't, then it is an error. */ + if (spec[i] == ':') + { + i++; + expecting_word_spec++; + } + + /* Handle special cases first. */ + + /* `%' is the word last searched for. */ + if (spec[i] == '%') + { + *caller_index = i + 1; + return (search_match ? savestring (search_match) : savestring ("")); + } + + /* `*' matches all of the arguments, but not the command. */ + if (spec[i] == '*') + { + *caller_index = i + 1; + result = history_arg_extract (1, '$', from); + return (result ? result : savestring ("")); + } + + /* `$' is last arg. */ + if (spec[i] == '$') + { + *caller_index = i + 1; + return (history_arg_extract ('$', '$', from)); + } + + /* Try to get FIRST and LAST figured out. */ + + if (spec[i] == '-') + first = 0; + else if (spec[i] == '^') + first = 1; + else if (_rl_digit_p (spec[i]) && expecting_word_spec) + { + for (first = 0; _rl_digit_p (spec[i]); i++) + first = (first * 10) + _rl_digit_value (spec[i]); + } + else + return ((char *)NULL); /* no valid `first' for word specifier */ + + if (spec[i] == '^' || spec[i] == '*') + { + last = (spec[i] == '^') ? 1 : '$'; /* x* abbreviates x-$ */ + i++; + } + else if (spec[i] != '-') + last = first; + else + { + i++; + + if (_rl_digit_p (spec[i])) + { + for (last = 0; _rl_digit_p (spec[i]); i++) + last = (last * 10) + _rl_digit_value (spec[i]); + } + else if (spec[i] == '$') + { + i++; + last = '$'; + } + else if (!spec[i] || spec[i] == ':') /* could be modifier separator */ + last = -1; /* x- abbreviates x-$ omitting word `$' */ + } + + *caller_index = i; + + if (last >= first || last == '$' || last < 0) + result = history_arg_extract (first, last, from); + + return (result ? result : (char *)&error_pointer); +} + +/* Extract the args specified, starting at FIRST, and ending at LAST. + The args are taken from STRING. If either FIRST or LAST is < 0, + then make that arg count from the right (subtract from the number of + tokens, so that FIRST = -1 means the next to last token on the line). + If LAST is `$' the last arg from STRING is used. */ +char * +history_arg_extract (first, last, string) + int first, last; + char *string; +{ + register int i, len; + char *result; + int size, offset; + char **list; + + /* XXX - think about making history_tokenize return a struct array, + each struct in array being a string and a length to avoid the + calls to strlen below. */ + if ((list = history_tokenize (string)) == NULL) + return ((char *)NULL); + + for (len = 0; list[len]; len++) + ; + + if (last < 0) + last = len + last - 1; + + if (first < 0) + first = len + first - 1; + + if (last == '$') + last = len - 1; + + if (first == '$') + first = len - 1; + + last++; + + if (first >= len || last > len || first < 0 || last < 0 || first > last) + result = ((char *)NULL); + else + { + for (size = 0, i = first; i < last; i++) + size += strlen (list[i]) + 1; + result = xmalloc (size + 1); + result[0] = '\0'; + + for (i = first, offset = 0; i < last; i++) + { + strcpy (result + offset, list[i]); + offset += strlen (list[i]); + if (i + 1 < last) + { + result[offset++] = ' '; + result[offset] = 0; + } + } + } + + for (i = 0; i < len; i++) + free (list[i]); + free (list); + + return (result); +} + +#define slashify_in_quotes "\\`\"$" + +/* Parse STRING into tokens and return an array of strings. If WIND is + not -1 and INDP is not null, we also want the word surrounding index + WIND. The position in the returned array of strings is returned in + *INDP. */ +static char ** +history_tokenize_internal (string, wind, indp) + char *string; + int wind, *indp; +{ + char **result; + register int i, start, result_index, size; + int len, delimiter; + + /* Get a token, and stuff it into RESULT. The tokens are split + exactly where the shell would split them. */ + for (i = result_index = size = 0, result = (char **)NULL; string[i]; ) + { + delimiter = 0; + + /* Skip leading whitespace. */ + for (; string[i] && whitespace (string[i]); i++) + ; + if (string[i] == 0 || string[i] == history_comment_char) + return (result); + + start = i; + + if (member (string[i], "()\n")) + { + i++; + goto got_token; + } + + if (member (string[i], "<>;&|$")) + { + int peek = string[i + 1]; + + if (peek == string[i] && peek != '$') + { + if (peek == '<' && string[i + 2] == '-') + i++; + i += 2; + goto got_token; + } + else + { + if ((peek == '&' && (string[i] == '>' || string[i] == '<')) || + ((peek == '>') && (string[i] == '&')) || + ((peek == '(') && (string[i] == '$'))) + { + i += 2; + goto got_token; + } + } + if (string[i] != '$') + { + i++; + goto got_token; + } + } + + /* Get word from string + i; */ + + if (member (string[i], "\"'`")) + delimiter = string[i++]; + + for (; string[i]; i++) + { + if (string[i] == '\\' && string[i + 1] == '\n') + { + i++; + continue; + } + + if (string[i] == '\\' && delimiter != '\'' && + (delimiter != '"' || member (string[i], slashify_in_quotes))) + { + i++; + continue; + } + + if (delimiter && string[i] == delimiter) + { + delimiter = 0; + continue; + } + + if (!delimiter && (member (string[i], " \t\n;&()|<>"))) + break; + + if (!delimiter && member (string[i], "\"'`")) + delimiter = string[i]; + } + + got_token: + + /* If we are looking for the word in which the character at a + particular index falls, remember it. */ + if (indp && wind != -1 && wind >= start && wind < i) + *indp = result_index; + + len = i - start; + if (result_index + 2 >= size) + result = (char **)xrealloc (result, ((size += 10) * sizeof (char *))); + result[result_index] = xmalloc (1 + len); + strncpy (result[result_index], string + start, len); + result[result_index][len] = '\0'; + result[++result_index] = (char *)NULL; + } + + return (result); +} + +/* Return an array of tokens, much as the shell might. The tokens are + parsed out of STRING. */ +char ** +history_tokenize (string) + char *string; +{ + return (history_tokenize_internal (string, -1, (int *)NULL)); +} + +/* Find and return the word which contains the character at index IND + in the history line LINE. Used to save the word matched by the + last history !?string? search. */ +static char * +history_find_word (line, ind) + char *line; + int ind; +{ + char **words, *s; + int i, wind; + + words = history_tokenize_internal (line, ind, &wind); + if (wind == -1) + return ((char *)NULL); + s = words[wind]; + for (i = 0; i < wind; i++) + free (words[i]); + for (i = wind + 1; words[i]; i++) + free (words[i]); + free (words); + return s; +} diff --git a/lib/readline/histfile.c b/lib/readline/histfile.c new file mode 100644 index 0000000..355d46e --- /dev/null +++ b/lib/readline/histfile.c @@ -0,0 +1,324 @@ +/* histfile.c - functions to manipulate the history file. */ + +/* Copyright (C) 1989, 1992 Free Software Foundation, Inc. + + This file contains the GNU History Library (the Library), a set of + routines for managing the text of previously typed lines. + + The Library is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + The Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + The GNU General Public License is often shipped with GNU software, and + is generally kept in a file called COPYING or LICENSE. If you do not + have a copy of the license, write to the Free Software Foundation, + 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* The goal is to make the implementation transparent, so that you + don't have to know what data types are used, just what functions + you can call. I think I have done that. */ +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include <config.h> +#endif + +#include <stdio.h> + +#include <sys/types.h> +#include <sys/file.h> +#include <sys/stat.h> +#include <fcntl.h> + +#if defined (HAVE_STDLIB_H) +# include <stdlib.h> +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_UNISTD_H) +# include <unistd.h> +#endif + +#if defined (HAVE_STRING_H) +# include <string.h> +#else +# include <strings.h> +#endif /* !HAVE_STRING_H */ + +#include <errno.h> +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +#include "history.h" +#include "histlib.h" + +extern char *xmalloc (), *xrealloc (); + +/* Return the string that should be used in the place of this + filename. This only matters when you don't specify the + filename to read_history (), or write_history (). */ +static char * +history_filename (filename) + char *filename; +{ + char *return_val, *home; + int home_len; + + return_val = filename ? savestring (filename) : (char *)NULL; + + if (return_val) + return (return_val); + + home = getenv ("HOME"); + + if (home == 0) + { + home = "."; + home_len = 1; + } + else + home_len = strlen (home); + + return_val = xmalloc (2 + home_len + 8); /* strlen(".history") == 8 */ + strcpy (return_val, home); + return_val[home_len] = '/'; + strcpy (return_val + home_len + 1, ".history"); + + return (return_val); +} + +/* Add the contents of FILENAME to the history list, a line at a time. + If FILENAME is NULL, then read from ~/.history. Returns 0 if + successful, or errno if not. */ +int +read_history (filename) + char *filename; +{ + return (read_history_range (filename, 0, -1)); +} + +/* Read a range of lines from FILENAME, adding them to the history list. + Start reading at the FROM'th line and end at the TO'th. If FROM + is zero, start at the beginning. If TO is less than FROM, read + until the end of the file. If FILENAME is NULL, then read from + ~/.history. Returns 0 if successful, or errno if not. */ +int +read_history_range (filename, from, to) + char *filename; + int from, to; +{ + register int line_start, line_end; + char *input, *buffer = (char *)NULL; + int file, current_line; + struct stat finfo; + + input = history_filename (filename); + file = open (input, O_RDONLY, 0666); + + if ((file < 0) || (fstat (file, &finfo) == -1)) + goto error_and_exit; + + buffer = xmalloc ((int)finfo.st_size + 1); + + if (read (file, buffer, finfo.st_size) != finfo.st_size) + { + error_and_exit: + if (file >= 0) + close (file); + + FREE (input); + FREE (buffer); + + return (errno); + } + + close (file); + + /* Set TO to larger than end of file if negative. */ + if (to < 0) + to = finfo.st_size; + + /* Start at beginning of file, work to end. */ + line_start = line_end = current_line = 0; + + /* Skip lines until we are at FROM. */ + while (line_start < finfo.st_size && current_line < from) + { + for (line_end = line_start; line_end < finfo.st_size; line_end++) + if (buffer[line_end] == '\n') + { + current_line++; + line_start = line_end + 1; + if (current_line == from) + break; + } + } + + /* If there are lines left to gobble, then gobble them now. */ + for (line_end = line_start; line_end < finfo.st_size; line_end++) + if (buffer[line_end] == '\n') + { + buffer[line_end] = '\0'; + + if (buffer[line_start]) + add_history (buffer + line_start); + + current_line++; + + if (current_line >= to) + break; + + line_start = line_end + 1; + } + + FREE (input); + FREE (buffer); + + return (0); +} + +/* Truncate the history file FNAME, leaving only LINES trailing lines. + If FNAME is NULL, then use ~/.history. */ +int +history_truncate_file (fname, lines) + char *fname; + register int lines; +{ + register int i; + int file, chars_read; + char *buffer = (char *)NULL, *filename; + struct stat finfo; + + filename = history_filename (fname); + file = open (filename, O_RDONLY, 0666); + + if (file == -1 || fstat (file, &finfo) == -1) + goto truncate_exit; + + buffer = xmalloc ((int)finfo.st_size + 1); + chars_read = read (file, buffer, finfo.st_size); + close (file); + + if (chars_read <= 0) + goto truncate_exit; + + /* Count backwards from the end of buffer until we have passed + LINES lines. */ + for (i = chars_read - 1; lines && i; i--) + { + if (buffer[i] == '\n') + lines--; + } + + /* If this is the first line, then the file contains exactly the + number of lines we want to truncate to, so we don't need to do + anything. It's the first line if we don't find a newline between + the current value of i and 0. Otherwise, write from the start of + this line until the end of the buffer. */ + for ( ; i; i--) + if (buffer[i] == '\n') + { + i++; + break; + } + + /* Write only if there are more lines in the file than we want to + truncate to. */ + if (i && ((file = open (filename, O_WRONLY|O_TRUNC, 0666)) != -1)) + { + write (file, buffer + i, finfo.st_size - i); + close (file); + } + + truncate_exit: + + FREE (buffer); + + free (filename); + return 0; +} + +/* Workhorse function for writing history. Writes NELEMENT entries + from the history list to FILENAME. OVERWRITE is non-zero if you + wish to replace FILENAME with the entries. */ +static int +history_do_write (filename, nelements, overwrite) + char *filename; + int nelements, overwrite; +{ + register int i; + char *output = history_filename (filename); + int file, mode; + + mode = overwrite ? O_WRONLY | O_CREAT | O_TRUNC : O_WRONLY | O_APPEND; + + if ((file = open (output, mode, 0666)) == -1) + { + FREE (output); + return (errno); + } + + if (nelements > history_length) + nelements = history_length; + + /* Build a buffer of all the lines to write, and write them in one syscall. + Suggested by Peter Ho (peter@robosts.oxford.ac.uk). */ + { + HIST_ENTRY **the_history; /* local */ + register int j; + int buffer_size; + char *buffer; + + the_history = history_list (); + /* Calculate the total number of bytes to write. */ + for (buffer_size = 0, i = history_length - nelements; i < history_length; i++) + buffer_size += 1 + strlen (the_history[i]->line); + + /* Allocate the buffer, and fill it. */ + buffer = xmalloc (buffer_size); + + for (j = 0, i = history_length - nelements; i < history_length; i++) + { + strcpy (buffer + j, the_history[i]->line); + j += strlen (the_history[i]->line); + buffer[j++] = '\n'; + } + + write (file, buffer, buffer_size); + free (buffer); + } + + close (file); + + FREE (output); + + return (0); +} + +/* Append NELEMENT entries to FILENAME. The entries appended are from + the end of the list minus NELEMENTs up to the end of the list. */ +int +append_history (nelements, filename) + int nelements; + char *filename; +{ + return (history_do_write (filename, nelements, HISTORY_APPEND)); +} + +/* Overwrite FILENAME with the current history. If FILENAME is NULL, + then write the history list to ~/.history. Values returned + are as in read_history ().*/ +int +write_history (filename) + char *filename; +{ + return (history_do_write (filename, history_length, HISTORY_OVERWRITE)); +} diff --git a/lib/readline/histlib.h b/lib/readline/histlib.h new file mode 100644 index 0000000..10a40d7 --- /dev/null +++ b/lib/readline/histlib.h @@ -0,0 +1,81 @@ +/* histlib.h -- internal definitions for the history library. */ +/* Copyright (C) 1989, 1992 Free Software Foundation, Inc. + + This file contains the GNU History Library (the Library), a set of + routines for managing the text of previously typed lines. + + The Library is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + The Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + The GNU General Public License is often shipped with GNU software, and + is generally kept in a file called COPYING or LICENSE. If you do not + have a copy of the license, write to the Free Software Foundation, + 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#if !defined (_HISTLIB_H_) +#define _HISTLIB_H_ + +/* Function pointers can be declared as (Function *)foo. */ +#if !defined (_FUNCTION_DEF) +# define _FUNCTION_DEF +typedef int Function (); +typedef void VFunction (); +typedef char *CPFunction (); +typedef char **CPPFunction (); +#endif /* _FUNCTION_DEF */ + +#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0)) +#define STREQN(a, b, n) (((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0)) + +#ifndef savestring +# ifndef strcpy +extern char *strcpy (); +# endif +#define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x)) +#endif + +#ifndef whitespace +#define whitespace(c) (((c) == ' ') || ((c) == '\t')) +#endif + +#ifndef _rl_digit_p +#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9') +#endif + +#ifndef _rl_digit_value +#define _rl_digit_value(c) ((c) - '0') +#endif + +#ifndef member +# ifndef strchr +extern char *strchr (); +# endif +#define member(c, s) ((c) ? ((char *)strchr ((s), (c)) != (char *)NULL) : 0) +#endif + +#ifndef FREE +# define FREE(x) if (x) free (x) +#endif + +/* Possible history errors passed to hist_error. */ +#define EVENT_NOT_FOUND 0 +#define BAD_WORD_SPEC 1 +#define SUBST_FAILED 2 +#define BAD_MODIFIER 3 + +/* Possible definitions for history starting point specification. */ +#define ANCHORED_SEARCH 1 +#define NON_ANCHORED_SEARCH 0 + +/* Possible definitions for what style of writing the history file we want. */ +#define HISTORY_APPEND 0 +#define HISTORY_OVERWRITE 1 + +#endif /* !_HISTLIB_H_ */ diff --git a/lib/readline/history.c b/lib/readline/history.c index 9172755..fb9d68e 100644 --- a/lib/readline/history.c +++ b/lib/readline/history.c @@ -25,88 +25,35 @@ you can call. I think I have done that. */ #define READLINE_LIBRARY +#if defined (HAVE_CONFIG_H) +# include <config.h> +#endif + #include <stdio.h> -#include <sys/types.h> -#include <sys/file.h> -#include <sys/stat.h> -#include <fcntl.h> + #if defined (HAVE_STDLIB_H) # include <stdlib.h> #else # include "ansi_stdlib.h" #endif /* HAVE_STDLIB_H */ + #if defined (HAVE_UNISTD_H) # include <unistd.h> #endif + #if defined (HAVE_STRING_H) # include <string.h> #else # include <strings.h> #endif /* !HAVE_STRING_H */ -#include <errno.h> - -/* Not all systems declare ERRNO in errno.h... and some systems #define it! */ -#if !defined (errno) -extern int errno; -#endif /* !errno */ -#include "memalloc.h" #include "history.h" +#include "histlib.h" -#if defined (STATIC_MALLOC) -static char *xmalloc (), *xrealloc (); -#else extern char *xmalloc (), *xrealloc (); -#endif /* STATIC_MALLOC */ - -#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0)) -#define STREQN(a, b, n) (((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0)) - -#ifndef savestring -# ifndef strcpy -extern char *strcpy (); -# endif -#define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x)) -#endif - -#ifndef whitespace -#define whitespace(c) (((c) == ' ') || ((c) == '\t')) -#endif - -#ifndef digit_p -#define digit_p(c) ((c) >= '0' && (c) <= '9') -#endif - -#ifndef digit_value -#define digit_value(c) ((c) - '0') -#endif - -#ifndef member -# ifndef strchr -extern char *strchr (); -# endif -#define member(c, s) ((c) ? ((char *)strchr ((s), (c)) != (char *)NULL) : 0) -#endif - -/* Possible history errors passed to hist_error. */ -#define EVENT_NOT_FOUND 0 -#define BAD_WORD_SPEC 1 -#define SUBST_FAILED 2 -#define BAD_MODIFIER 3 - -static char error_pointer; - -static char *subst_lhs; -static char *subst_rhs; -static int subst_lhs_len = 0; -static int subst_rhs_len = 0; -static char *get_history_word_specifier (); -static char *history_find_word (); - -#if defined (SHELL) -extern char *single_quote (); -#endif +/* The number of slots to increase the_history by. */ +#define DEFAULT_HISTORY_GROW_SIZE 50 /* **************************************************************** */ /* */ @@ -119,7 +66,7 @@ static HIST_ENTRY **the_history = (HIST_ENTRY **)NULL; /* Non-zero means that we have enforced a limit on the amount of history that we save. */ -static int history_stifled = 0; +static int history_stifled; /* If HISTORY_STIFLED is non-zero, then this is the maximum number of entries to remember. */ @@ -127,34 +74,13 @@ int max_input_history; /* The current location of the interactive history pointer. Just makes life easier for outside callers. */ -static int history_offset = 0; +int history_offset; -/* The number of strings currently stored in the input_history list. */ -int history_length = 0; +/* The number of strings currently stored in the history list. */ +int history_length; /* The current number of slots allocated to the input_history. */ -static int history_size = 0; - -/* The number of slots to increase the_history by. */ -#define DEFAULT_HISTORY_GROW_SIZE 50 - -/* The character that represents the start of a history expansion - request. This is usually `!'. */ -char history_expansion_char = '!'; - -/* The character that invokes word substitution if found at the start of - a line. This is usually `^'. */ -char history_subst_char = '^'; - -/* During tokenization, if this character is seen as the first character - of a word, then it, and all subsequent characters upto a newline are - ignored. For a Bourne shell, this should be '#'. Bash special cases - the interactive comment character to not be a comment delimiter. */ -char history_comment_char = '\0'; - -/* The list of characters which inhibit the expansion of text if found - immediately following history_expansion_char. */ -char *history_no_expand_chars = " \t\n\r="; +static int history_size; /* The logical `base' of the history array. It defaults to 1. */ int history_base = 1; @@ -213,6 +139,77 @@ history_total_bytes () return (result); } +/* Returns the magic number which says what history element we are + looking at now. In this implementation, it returns history_offset. */ +int +where_history () +{ + return (history_offset); +} + +/* Make the current history item be the one at POS, an absolute index. + Returns zero if POS is out of range, else non-zero. */ +int +history_set_pos (pos) + int pos; +{ + if (pos > history_length || pos < 0 || !the_history) + return (0); + history_offset = pos; + return (1); +} + +/* Return the current history array. The caller has to be carefull, since this + is the actual array of data, and could be bashed or made corrupt easily. + The array is terminated with a NULL pointer. */ +HIST_ENTRY ** +history_list () +{ + return (the_history); +} + +/* Return the history entry at the current position, as determined by + history_offset. If there is no entry there, return a NULL pointer. */ +HIST_ENTRY * +current_history () +{ + return ((history_offset == history_length) || the_history == 0) + ? (HIST_ENTRY *)NULL + : the_history[history_offset]; +} + +/* Back up history_offset to the previous history entry, and return + a pointer to that entry. If there is no previous entry then return + a NULL pointer. */ +HIST_ENTRY * +previous_history () +{ + return history_offset ? the_history[--history_offset] : (HIST_ENTRY *)NULL; +} + +/* Move history_offset forward to the next history entry, and return + a pointer to that entry. If there is no next entry then return a + NULL pointer. */ +HIST_ENTRY * +next_history () +{ + return (history_offset == history_length) ? (HIST_ENTRY *)NULL : the_history[++history_offset]; +} + +/* Return the history entry which is logically at OFFSET in the history array. + OFFSET is relative to history_base. */ +HIST_ENTRY * +history_get (offset) + int offset; +{ + int local_index; + + local_index = offset - history_base; + return (local_index >= history_length || local_index < 0 || !the_history) + ? (HIST_ENTRY *)NULL + : the_history[local_index]; +} + /* Place STRING at the end of the history list. The data field is set to NULL. */ void @@ -242,16 +239,14 @@ add_history (string) the_history[i] = the_history[i + 1]; history_base++; - } else { - if (!history_size) + if (history_size == 0) { history_size = DEFAULT_HISTORY_GROW_SIZE; the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *)); history_length = 1; - } else { @@ -297,136 +292,6 @@ replace_history_entry (which, line, data) return (old_value); } -/* Returns the magic number which says what history element we are - looking at now. In this implementation, it returns history_offset. */ -int -where_history () -{ - return (history_offset); -} - -/* Search the history for STRING, starting at history_offset. - If DIRECTION < 0, then the search is through previous entries, else - through subsequent. If ANCHORED is non-zero, the string must - appear at the beginning of a history line, otherwise, the string - may appear anywhere in the line. If the string is found, then - current_history () is the history entry, and the value of this - function is the offset in the line of that history entry that the - string was found in. Otherwise, nothing is changed, and a -1 is - returned. */ - -#define ANCHORED_SEARCH 1 -#define NON_ANCHORED_SEARCH 0 - -static int -history_search_internal (string, direction, anchored) - char *string; - int direction, anchored; -{ - register int i, reverse; - register char *line; - register int line_index; - int string_len; - - i = history_offset; - reverse = (direction < 0); - - /* Take care of trivial cases first. */ - if (string == 0 || *string == '\0') - return (-1); - - if (!history_length || ((i == history_length) && !reverse)) - return (-1); - - if (reverse && (i == history_length)) - i--; - -#define NEXT_LINE() do { if (reverse) i--; else i++; } while (0) - - string_len = strlen (string); - while (1) - { - /* Search each line in the history list for STRING. */ - - /* At limit for direction? */ - if ((reverse && i < 0) || (!reverse && i == history_length)) - return (-1); - - line = the_history[i]->line; - line_index = strlen (line); - - /* If STRING is longer than line, no match. */ - if (string_len > line_index) - { - NEXT_LINE (); - continue; - } - - /* Handle anchored searches first. */ - if (anchored == ANCHORED_SEARCH) - { - if (STREQN (string, line, string_len)) - { - history_offset = i; - return (0); - } - - NEXT_LINE (); - continue; - } - - /* Do substring search. */ - if (reverse) - { - line_index -= string_len; - - while (line_index >= 0) - { - if (STREQN (string, line + line_index, string_len)) - { - history_offset = i; - return (line_index); - } - line_index--; - } - } - else - { - register int limit = line_index - string_len + 1; - line_index = 0; - - while (line_index < limit) - { - if (STREQN (string, line + line_index, string_len)) - { - history_offset = i; - return (line_index); - } - line_index++; - } - } - NEXT_LINE (); - } -} - -/* Do a non-anchored search for STRING through the history in DIRECTION. */ -int -history_search (string, direction) - char *string; - int direction; -{ - return (history_search_internal (string, direction, NON_ANCHORED_SEARCH)); -} - -/* Do an anchored search for string through the history in DIRECTION. */ -int -history_search_prefix (string, direction) - char *string; - int direction; -{ - return (history_search_internal (string, direction, ANCHORED_SEARCH)); -} - /* Remove history element WHICH from the history. The removed element is returned to you so you can free the line, data, and containing structure. */ @@ -465,7 +330,7 @@ stifle_history (max) register int i, j; /* This loses because we cannot free the data. */ - for (i = 0; i < (history_length - max); i++) + for (i = 0, j = history_length - max; i < j; i++) { free (the_history[i]->line); free (the_history[i]); @@ -482,21 +347,19 @@ stifle_history (max) max_input_history = max; } -/* Stop stifling the history. This returns the previous amount the history - was stifled by. The value is positive if the history was stifled, negative - if it wasn't. */ +/* Stop stifling the history. This returns the previous amount the + history was stifled by. The value is positive if the history was + stifled, negative if it wasn't. */ int unstifle_history () { - int result = max_input_history; - if (history_stifled) { - result = -result; history_stifled = 0; + return (-max_input_history); } - return (result); + return (max_input_history); } int @@ -505,1714 +368,18 @@ history_is_stifled () return (history_stifled); } -/* Return the string that should be used in the place of this - filename. This only matters when you don't specify the - filename to read_history (), or write_history (). */ -static char * -history_filename (filename) - char *filename; -{ - char *return_val = filename ? savestring (filename) : (char *)NULL; - - if (!return_val) - { - char *home; - int home_len; - - home = getenv ("HOME"); - - if (!home) - home = "."; - - home_len = strlen (home); - /* strlen(".history") == 8 */ - return_val = xmalloc (2 + home_len + 8); - - strcpy (return_val, home); - return_val[home_len] = '/'; - strcpy (return_val + home_len + 1, ".history"); - } - - return (return_val); -} - -/* Add the contents of FILENAME to the history list, a line at a time. - If FILENAME is NULL, then read from ~/.history. Returns 0 if - successful, or errno if not. */ -int -read_history (filename) - char *filename; -{ - return (read_history_range (filename, 0, -1)); -} - -/* Read a range of lines from FILENAME, adding them to the history list. - Start reading at the FROM'th line and end at the TO'th. If FROM - is zero, start at the beginning. If TO is less than FROM, read - until the end of the file. If FILENAME is NULL, then read from - ~/.history. Returns 0 if successful, or errno if not. */ -int -read_history_range (filename, from, to) - char *filename; - int from, to; -{ - register int line_start, line_end; - char *input, *buffer = (char *)NULL; - int file, current_line; - struct stat finfo; - - input = history_filename (filename); - file = open (input, O_RDONLY, 0666); - - if ((file < 0) || (fstat (file, &finfo) == -1)) - goto error_and_exit; - - buffer = xmalloc ((int)finfo.st_size + 1); - - if (read (file, buffer, finfo.st_size) != finfo.st_size) - { - error_and_exit: - if (file >= 0) - close (file); - - if (input) - free (input); - - if (buffer) - free (buffer); - - return (errno); - } - - close (file); - - /* Set TO to larger than end of file if negative. */ - if (to < 0) - to = finfo.st_size; - - /* Start at beginning of file, work to end. */ - line_start = line_end = current_line = 0; - - /* Skip lines until we are at FROM. */ - while (line_start < finfo.st_size && current_line < from) - { - for (line_end = line_start; line_end < finfo.st_size; line_end++) - if (buffer[line_end] == '\n') - { - current_line++; - line_start = line_end + 1; - if (current_line == from) - break; - } - } - - /* If there are lines left to gobble, then gobble them now. */ - for (line_end = line_start; line_end < finfo.st_size; line_end++) - if (buffer[line_end] == '\n') - { - buffer[line_end] = '\0'; - - if (buffer[line_start]) - add_history (buffer + line_start); - - current_line++; - - if (current_line >= to) - break; - - line_start = line_end + 1; - } - - if (input) - free (input); - - if (buffer) - free (buffer); - - return (0); -} - -/* Truncate the history file FNAME, leaving only LINES trailing lines. - If FNAME is NULL, then use ~/.history. */ -int -history_truncate_file (fname, lines) - char *fname; - register int lines; -{ - register int i; - int file, chars_read; - char *buffer = (char *)NULL, *filename; - struct stat finfo; - - filename = history_filename (fname); - file = open (filename, O_RDONLY, 0666); - - if (file == -1 || fstat (file, &finfo) == -1) - goto truncate_exit; - - buffer = xmalloc ((int)finfo.st_size + 1); - chars_read = read (file, buffer, finfo.st_size); - close (file); - - if (chars_read <= 0) - goto truncate_exit; - - /* Count backwards from the end of buffer until we have passed - LINES lines. */ - for (i = chars_read - 1; lines && i; i--) - { - if (buffer[i] == '\n') - lines--; - } - - /* If this is the first line, then the file contains exactly the - number of lines we want to truncate to, so we don't need to do - anything. It's the first line if we don't find a newline between - the current value of i and 0. Otherwise, write from the start of - this line until the end of the buffer. */ - for ( ; i; i--) - if (buffer[i] == '\n') - { - i++; - break; - } - - /* Write only if there are more lines in the file than we want to - truncate to. */ - if (i && ((file = open (filename, O_WRONLY|O_TRUNC, 0666)) != -1)) - { - write (file, buffer + i, finfo.st_size - i); - close (file); - } - - truncate_exit: - if (buffer) - free (buffer); - - free (filename); - return 0; -} - -#define HISTORY_APPEND 0 -#define HISTORY_OVERWRITE 1 - -/* Workhorse function for writing history. Writes NELEMENT entries - from the history list to FILENAME. OVERWRITE is non-zero if you - wish to replace FILENAME with the entries. */ -static int -history_do_write (filename, nelements, overwrite) - char *filename; - int nelements, overwrite; +void +clear_history () { register int i; - char *output = history_filename (filename); - int file, mode; - - mode = overwrite ? O_WRONLY | O_CREAT | O_TRUNC : O_WRONLY | O_APPEND; - - if ((file = open (output, mode, 0666)) == -1) - { - if (output) - free (output); - - return (errno); - } - - if (nelements > history_length) - nelements = history_length; - - /* Build a buffer of all the lines to write, and write them in one syscall. - Suggested by Peter Ho (peter@robosts.oxford.ac.uk). */ - { - register int j = 0; - int buffer_size = 0; - char *buffer; - - /* Calculate the total number of bytes to write. */ - for (i = history_length - nelements; i < history_length; i++) - buffer_size += 1 + strlen (the_history[i]->line); - - /* Allocate the buffer, and fill it. */ - buffer = xmalloc (buffer_size); - - for (i = history_length - nelements; i < history_length; i++) - { - strcpy (buffer + j, the_history[i]->line); - j += strlen (the_history[i]->line); - buffer[j++] = '\n'; - } - - write (file, buffer, buffer_size); - free (buffer); - } - - close (file); - - if (output) - free (output); - - return (0); -} - -/* Append NELEMENT entries to FILENAME. The entries appended are from - the end of the list minus NELEMENTs up to the end of the list. */ -int -append_history (nelements, filename) - int nelements; - char *filename; -{ - return (history_do_write (filename, nelements, HISTORY_APPEND)); -} - -/* Overwrite FILENAME with the current history. If FILENAME is NULL, - then write the history list to ~/.history. Values returned - are as in read_history ().*/ -int -write_history (filename) - char *filename; -{ - return (history_do_write (filename, history_length, HISTORY_OVERWRITE)); -} - -/* Return the history entry at the current position, as determined by - history_offset. If there is no entry there, return a NULL pointer. */ -HIST_ENTRY * -current_history () -{ - if ((history_offset == history_length) || !the_history) - return ((HIST_ENTRY *)NULL); - else - return (the_history[history_offset]); -} - -/* Back up history_offset to the previous history entry, and return - a pointer to that entry. If there is no previous entry then return - a NULL pointer. */ -HIST_ENTRY * -previous_history () -{ - if (!history_offset) - return ((HIST_ENTRY *)NULL); - else - return (the_history[--history_offset]); -} - -/* Move history_offset forward to the next history entry, and return - a pointer to that entry. If there is no next entry then return a - NULL pointer. */ -HIST_ENTRY * -next_history () -{ - if (history_offset == history_length) - return ((HIST_ENTRY *)NULL); - else - return (the_history[++history_offset]); -} - -/* Return the current history array. The caller has to be carefull, since this - is the actual array of data, and could be bashed or made corrupt easily. - The array is terminated with a NULL pointer. */ -HIST_ENTRY ** -history_list () -{ - return (the_history); -} - -/* Return the history entry which is logically at OFFSET in the history array. - OFFSET is relative to history_base. */ -HIST_ENTRY * -history_get (offset) - int offset; -{ - int local_index = offset - history_base; - - if (local_index >= history_length || - local_index < 0 || - !the_history) - return ((HIST_ENTRY *)NULL); - return (the_history[local_index]); -} - -/* Search for STRING in the history list. DIR is < 0 for searching - backwards. POS is an absolute index into the history list at - which point to begin searching. */ -int -history_search_pos (string, dir, pos) - char *string; - int dir, pos; -{ - int ret, old = where_history (); - history_set_pos (pos); - if (history_search (string, dir) == -1) - { - history_set_pos (old); - return (-1); - } - ret = where_history (); - history_set_pos (old); - return ret; -} - -/* Make the current history item be the one at POS, an absolute index. - Returns zero if POS is out of range, else non-zero. */ -int -history_set_pos (pos) - int pos; -{ - if (pos > history_length || pos < 0 || !the_history) - return (0); - history_offset = pos; - return (1); -} - - -/* **************************************************************** */ -/* */ -/* History Expansion */ -/* */ -/* **************************************************************** */ - -/* Hairy history expansion on text, not tokens. This is of general - use, and thus belongs in this library. */ - -/* The last string searched for in a !?string? search. */ -static char *search_string = (char *)NULL; - -/* The last string matched by a !?string? search. */ -static char *search_match = (char *)NULL; - -/* Return the event specified at TEXT + OFFSET modifying OFFSET to - point to after the event specifier. Just a pointer to the history - line is returned; NULL is returned in the event of a bad specifier. - You pass STRING with *INDEX equal to the history_expansion_char that - begins this specification. - DELIMITING_QUOTE is a character that is allowed to end the string - specification for what to search for in addition to the normal - characters `:', ` ', `\t', `\n', and sometimes `?'. - So you might call this function like: - line = get_history_event ("!echo:p", &index, 0); */ -char * -get_history_event (string, caller_index, delimiting_quote) - char *string; - int *caller_index; - int delimiting_quote; -{ - register int i = *caller_index; - register char c; - HIST_ENTRY *entry; - int which, sign = 1; - int local_index, search_mode, substring_okay = 0; - char *temp; - - /* The event can be specified in a number of ways. - - !! the previous command - !n command line N - !-n current command-line minus N - !str the most recent command starting with STR - !?str[?] - the most recent command containing STR - - All values N are determined via HISTORY_BASE. */ - - if (string[i] != history_expansion_char) - return ((char *)NULL); - - /* Move on to the specification. */ - i++; - -#define RETURN_ENTRY(e, w) \ - return ((e = history_get (w)) ? e->line : (char *)NULL) - - /* Handle !! case. */ - if (string[i] == history_expansion_char) - { - i++; - which = history_base + (history_length - 1); - *caller_index = i; - RETURN_ENTRY (entry, which); - } - - /* Hack case of numeric line specification. */ - if (string[i] == '-') - { - sign = -1; - i++; - } - - if (digit_p (string[i])) - { - /* Get the extent of the digits and compute the value. */ - for (which = 0; digit_p (string[i]); i++) - which = (which * 10) + digit_value (string[i]); - - *caller_index = i; - - if (sign < 0) - which = (history_length + history_base) - which; - - RETURN_ENTRY (entry, which); - } - /* This must be something to search for. If the spec begins with - a '?', then the string may be anywhere on the line. Otherwise, - the string must be found at the start of a line. */ - if (string[i] == '?') + /* This loses because we cannot free the data. */ + for (i = 0; i < history_length; i++) { - substring_okay++; - i++; + free (the_history[i]->line); + free (the_history[i]); + the_history[i] = (HIST_ENTRY *)NULL; } - /* Only a closing `?' or a newline delimit a substring search string. */ - for (local_index = i; c = string[i]; i++) - if ((!substring_okay && (whitespace (c) || c == ':' || -#if defined (SHELL) - member (c, ";&()|<>") || -#endif /* SHELL */ - string[i] == delimiting_quote)) || - string[i] == '\n' || - (substring_okay && string[i] == '?')) - break; - - temp = xmalloc (1 + (i - local_index)); - strncpy (temp, &string[local_index], (i - local_index)); - temp[i - local_index] = '\0'; - - if (substring_okay && string[i] == '?') - i++; - - *caller_index = i; - -#define FAIL_SEARCH() \ - do { history_offset = history_length; free (temp) ; return (char *)NULL; } while (0) - - search_mode = substring_okay ? NON_ANCHORED_SEARCH : ANCHORED_SEARCH; - while (1) - { - local_index = history_search_internal (temp, -1, search_mode); - - if (local_index < 0) - FAIL_SEARCH (); - - if (local_index == 0 || substring_okay) - { - entry = current_history (); - history_offset = history_length; - - /* If this was a substring search, then remember the - string that we matched for word substitution. */ - if (substring_okay) - { - if (search_string) - free (search_string); - search_string = temp; - - if (search_match) - free (search_match); - search_match = history_find_word (entry->line, local_index); - } - else - free (temp); - return (entry->line); - } - - if (history_offset) - history_offset--; - else - FAIL_SEARCH (); - } -#undef FAIL_SEARCH -#undef RETURN_ENTRY -} -#if defined (SHELL) -/* Function for extracting single-quoted strings. Used for inhibiting - history expansion within single quotes. */ - -/* Extract the contents of STRING as if it is enclosed in single quotes. - SINDEX, when passed in, is the offset of the character immediately - following the opening single quote; on exit, SINDEX is left pointing - to the closing single quote. */ -static void -rl_string_extract_single_quoted (string, sindex) - char *string; - int *sindex; -{ - register int i = *sindex; - - while (string[i] && string[i] != '\'') - i++; - - *sindex = i; -} - -static char * -quote_breaks (s) - char *s; -{ - register char *p, *r; - char *ret; - int len = 3; - - for (p = s; p && *p; p++, len++) - { - if (*p == '\'') - len += 3; - else if (whitespace (*p) || *p == '\n') - len += 2; - } - - r = ret = xmalloc (len); - *r++ = '\''; - for (p = s; p && *p; ) - { - if (*p == '\'') - { - *r++ = '\''; - *r++ = '\\'; - *r++ = '\''; - *r++ = '\''; - p++; - } - else if (whitespace (*p) || *p == '\n') - { - *r++ = '\''; - *r++ = *p++; - *r++ = '\''; - } - else - *r++ = *p++; - } - *r++ = '\''; - *r = '\0'; - return ret; -} -#endif /* SHELL */ - -static char * -hist_error(s, start, current, errtype) - char *s; - int start, current, errtype; -{ - char *temp, *emsg; - int ll, elen; - - ll = current - start; - - switch (errtype) - { - case EVENT_NOT_FOUND: - emsg = "event not found"; - elen = 15; - break; - case BAD_WORD_SPEC: - emsg = "bad word specifier"; - elen = 18; - break; - case SUBST_FAILED: - emsg = "substitution failed"; - elen = 19; - break; - case BAD_MODIFIER: - emsg = "unrecognized history modifier"; - elen = 29; - break; - default: - emsg = "unknown expansion error"; - elen = 23; - break; - } - - temp = xmalloc (ll + elen + 3); - strncpy (temp, s + start, ll); - temp[ll] = ':'; - temp[ll + 1] = ' '; - strcpy (temp + ll + 2, emsg); - return (temp); -} - -/* Get a history substitution string from STR starting at *IPTR - and return it. The length is returned in LENPTR. - - A backslash can quote the delimiter. If the string is the - empty string, the previous pattern is used. If there is - no previous pattern for the lhs, the last history search - string is used. - - If IS_RHS is 1, we ignore empty strings and set the pattern - to "" anyway. subst_lhs is not changed if the lhs is empty; - subst_rhs is allowed to be set to the empty string. */ - -static char * -get_subst_pattern (str, iptr, delimiter, is_rhs, lenptr) - char *str; - int *iptr, delimiter, is_rhs, *lenptr; -{ - register int si, i, j, k; - char *s = (char *) NULL; - - i = *iptr; - - for (si = i; str[si] && str[si] != delimiter; si++) - if (str[si] == '\\' && str[si + 1] == delimiter) - si++; - - if (si > i || is_rhs) - { - s = xmalloc (si - i + 1); - for (j = 0, k = i; k < si; j++, k++) - { - /* Remove a backslash quoting the search string delimiter. */ - if (str[k] == '\\' && str[k + 1] == delimiter) - k++; - s[j] = str[k]; - } - s[j] = '\0'; - if (lenptr) - *lenptr = j; - } - - i = si; - if (str[i]) - i++; - *iptr = i; - - return s; -} - -static void -postproc_subst_rhs () -{ - char *new; - int i, j, new_size; - - new = xmalloc (new_size = subst_rhs_len + subst_lhs_len); - for (i = j = 0; i < subst_rhs_len; i++) - { - if (subst_rhs[i] == '&') - { - if (j + subst_lhs_len >= new_size) - new = xrealloc (new, (new_size = new_size * 2 + subst_lhs_len)); - strcpy (new + j, subst_lhs); - j += subst_lhs_len; - } - else - { - /* a single backslash protects the `&' from lhs interpolation */ - if (subst_rhs[i] == '\\' && subst_rhs[i + 1] == '&') - i++; - if (j >= new_size) - new = xrealloc (new, new_size *= 2); - new[j++] = subst_rhs[i]; - } - } - new[j] = '\0'; - free (subst_rhs); - subst_rhs = new; - subst_rhs_len = j; -} - -/* Expand the bulk of a history specifier starting at STRING[START]. - Returns 0 if everything is OK, -1 if an error occurred, and 1 - if the `p' modifier was supplied and the caller should just print - the returned string. Returns the new index into string in - *END_INDEX_PTR, and the expanded specifier in *RET_STRING. */ -static int -history_expand_internal (string, start, end_index_ptr, ret_string, current_line) - char *string; - int start, *end_index_ptr; - char **ret_string; - char *current_line; /* for !# */ -{ - int i, n, starting_index; - int substitute_globally, want_quotes, print_only; - char *event, *temp, *result, *tstr, *t, c, *word_spec; - int result_len; - - result = xmalloc (result_len = 128); - - i = start; - - /* If it is followed by something that starts a word specifier, - then !! is implied as the event specifier. */ - - if (member (string[i + 1], ":$*%^")) - { - char fake_s[3]; - int fake_i = 0; - i++; - fake_s[0] = fake_s[1] = history_expansion_char; - fake_s[2] = '\0'; - event = get_history_event (fake_s, &fake_i, 0); - } - else if (string[i + 1] == '#') - { - i += 2; - event = current_line; - } - else - { - int quoted_search_delimiter = 0; - - /* If the character before this `!' is a double or single - quote, then this expansion takes place inside of the - quoted string. If we have to search for some text ("!foo"), - allow the delimiter to end the search string. */ - if (i && (string[i - 1] == '\'' || string[i - 1] == '"')) - quoted_search_delimiter = string[i - 1]; - event = get_history_event (string, &i, quoted_search_delimiter); - } - - if (!event) - { - *ret_string = hist_error (string, start, i, EVENT_NOT_FOUND); - free (result); - return (-1); - } - - /* If a word specifier is found, then do what that requires. */ - starting_index = i; - word_spec = get_history_word_specifier (string, event, &i); - - /* There is no such thing as a `malformed word specifier'. However, - it is possible for a specifier that has no match. In that case, - we complain. */ - if (word_spec == (char *)&error_pointer) - { - *ret_string = hist_error (string, starting_index, i, BAD_WORD_SPEC); - free (result); - return (-1); - } - - /* If no word specifier, than the thing of interest was the event. */ - if (!word_spec) - temp = savestring (event); - else - { - temp = savestring (word_spec); - free (word_spec); - } - - /* Perhaps there are other modifiers involved. Do what they say. */ - want_quotes = substitute_globally = print_only = 0; - starting_index = i; - - while (string[i] == ':') - { - c = string[i + 1]; - - if (c == 'g') - { - substitute_globally = 1; - i++; - c = string[i + 1]; - } - - switch (c) - { - default: - *ret_string = hist_error (string, i+1, i+2, BAD_MODIFIER); - free (result); - free (temp); - return -1; - -#if defined (SHELL) - case 'q': - want_quotes = 'q'; - break; - - case 'x': - want_quotes = 'x'; - break; -#endif /* SHELL */ - - /* :p means make this the last executed line. So we - return an error state after adding this line to the - history. */ - case 'p': - print_only++; - break; - - /* :t discards all but the last part of the pathname. */ - case 't': - tstr = strrchr (temp, '/'); - if (tstr) - { - tstr++; - t = savestring (tstr); - free (temp); - temp = t; - } - break; - - /* :h discards the last part of a pathname. */ - case 'h': - tstr = strrchr (temp, '/'); - if (tstr) - *tstr = '\0'; - break; - - /* :r discards the suffix. */ - case 'r': - tstr = strrchr (temp, '.'); - if (tstr) - *tstr = '\0'; - break; - - /* :e discards everything but the suffix. */ - case 'e': - tstr = strrchr (temp, '.'); - if (tstr) - { - t = savestring (tstr); - free (temp); - temp = t; - } - break; - - /* :s/this/that substitutes `that' for the first - occurrence of `this'. :gs/this/that substitutes `that' - for each occurrence of `this'. :& repeats the last - substitution. :g& repeats the last substitution - globally. */ - - case '&': - case 's': - { - char *new_event, *t; - int delimiter, failed, si, l_temp; - - if (c == 's') - { - if (i + 2 < (int)strlen (string)) - delimiter = string[i + 2]; - else - break; /* no search delimiter */ - - i += 3; - - t = get_subst_pattern (string, &i, delimiter, 0, &subst_lhs_len); - /* An empty substitution lhs with no previous substitution - uses the last search string as the lhs. */ - if (t) - { - if (subst_lhs) - free (subst_lhs); - subst_lhs = t; - } - else if (!subst_lhs) - { - if (search_string && *search_string) - { - subst_lhs = savestring (search_string); - subst_lhs_len = strlen (subst_lhs); - } - else - { - subst_lhs = (char *) NULL; - subst_lhs_len = 0; - } - } - - /* If there is no lhs, the substitution can't succeed. */ - if (subst_lhs_len == 0) - { - *ret_string = hist_error (string, starting_index, i, SUBST_FAILED); - free (result); - free (temp); - return -1; - } - - if (subst_rhs) - free (subst_rhs); - subst_rhs = get_subst_pattern (string, &i, delimiter, 1, &subst_rhs_len); - - /* If `&' appears in the rhs, it's supposed to be replaced - with the lhs. */ - if (member ('&', subst_rhs)) - postproc_subst_rhs (); - } - else - i += 2; - - l_temp = strlen (temp); - /* Ignore impossible cases. */ - if (subst_lhs_len > l_temp) - { - *ret_string = hist_error (string, starting_index, i, SUBST_FAILED); - free (result); - free (temp); - return (-1); - } - - /* Find the first occurrence of THIS in TEMP. */ - si = 0; - for (failed = 1; (si + subst_lhs_len) <= l_temp; si++) - if (STREQN (temp+si, subst_lhs, subst_lhs_len)) - { - int len = subst_rhs_len - subst_lhs_len + l_temp; - new_event = xmalloc (1 + len); - strncpy (new_event, temp, si); - strncpy (new_event + si, subst_rhs, subst_rhs_len); - strncpy (new_event + si + subst_rhs_len, - temp + si + subst_lhs_len, - l_temp - (si + subst_lhs_len)); - new_event[len] = '\0'; - free (temp); - temp = new_event; - - failed = 0; - - if (substitute_globally) - { - si += subst_rhs_len; - l_temp = strlen (temp); - substitute_globally++; - continue; - } - else - break; - } - - if (substitute_globally > 1) - { - substitute_globally = 0; - continue; /* don't want to increment i */ - } - - if (failed == 0) - continue; /* don't want to increment i */ - - *ret_string = hist_error (string, starting_index, i, SUBST_FAILED); - free (result); - free (temp); - return (-1); - } - } - i += 2; - } - /* Done with modfiers. */ - /* Believe it or not, we have to back the pointer up by one. */ - --i; - -#if defined (SHELL) - if (want_quotes) - { - char *x; - - if (want_quotes == 'q') - x = single_quote (temp); - else if (want_quotes == 'x') - x = quote_breaks (temp); - else - x = savestring (temp); - - free (temp); - temp = x; - } -#endif /* SHELL */ - - n = strlen (temp); - if (n > result_len) - result = xrealloc (result, n + 2); - strcpy (result, temp); - free (temp); - - *end_index_ptr = i; - *ret_string = result; - return (print_only); + history_offset = history_length = 0; } - -/* Expand the string STRING, placing the result into OUTPUT, a pointer - to a string. Returns: - - -1) If there was an error in expansion. - 0) If no expansions took place (or, if the only change in - the text was the de-slashifying of the history expansion - character) - 1) If expansions did take place - 2) If the `p' modifier was given and the caller should print the result - - If an error ocurred in expansion, then OUTPUT contains a descriptive - error message. */ - -#define ADD_STRING(s) \ - do \ - { \ - int sl = strlen (s); \ - j += sl; \ - if (j >= result_len) \ - { \ - while (j >= result_len) \ - result_len += 128; \ - result = xrealloc (result, result_len); \ - } \ - strcpy (result + j - sl, s); \ - } \ - while (0) - -#define ADD_CHAR(c) \ - do \ - { \ - if (j >= result_len - 1) \ - result = xrealloc (result, result_len += 64); \ - result[j++] = c; \ - result[j] = '\0'; \ - } \ - while (0) - -int -history_expand (hstring, output) - char *hstring; - char **output; -{ - register int j; - int i, r, l, passc, cc, modified, eindex, only_printing; - char *string; - - /* The output string, and its length. */ - int result_len; - char *result; - - /* Used when adding the string. */ - char *temp; - - /* Setting the history expansion character to 0 inhibits all - history expansion. */ - if (history_expansion_char == 0) - { - *output = savestring (hstring); - return (0); - } - - /* Prepare the buffer for printing error messages. */ - result = xmalloc (result_len = 256); - result[0] = '\0'; - - only_printing = modified = 0; - l = strlen (hstring); - - /* Grovel the string. Only backslash can quote the history escape - character. We also handle arg specifiers. */ - - /* Before we grovel forever, see if the history_expansion_char appears - anywhere within the text. */ - - /* The quick substitution character is a history expansion all right. That - is to say, "^this^that^" is equivalent to "!!:s^this^that^", and in fact, - that is the substitution that we do. */ - if (hstring[0] == history_subst_char) - { - string = xmalloc (l + 5); - - string[0] = string[1] = history_expansion_char; - string[2] = ':'; - string[3] = 's'; - strcpy (string + 4, hstring); - l += 4; - } - else - { - string = hstring; - /* If not quick substitution, still maybe have to do expansion. */ - - /* `!' followed by one of the characters in history_no_expand_chars - is NOT an expansion. */ - for (i = 0; string[i]; i++) - { - cc = string[i + 1]; - if (string[i] == history_expansion_char) - { - if (!cc || member (cc, history_no_expand_chars)) - continue; -#if defined (SHELL) - /* The shell uses ! as a pattern negation character - in globbing [...] expressions, so let those pass - without expansion. */ - else if (i > 0 && (string[i - 1] == '[') && - member (']', string + i + 1)) - continue; -#endif /* SHELL */ - else - break; - } -#if defined (SHELL) - else if (string[i] == '\'') - { - /* If this is bash, single quotes inhibit history expansion. */ - i++; - rl_string_extract_single_quoted (string, &i); - } - else if (string[i] == '\\') - { - /* If this is bash, allow backslashes to quote single - quotes and - the history expansion character. */ - if (cc == '\'' || cc == history_expansion_char) - i++; - } -#endif /* SHELL */ - } - - if (string[i] != history_expansion_char) - { - free (result); - *output = savestring (string); - return (0); - } - } - - /* Extract and perform the substitution. */ - for (passc = i = j = 0; i < l; i++) - { - int tchar = string[i]; - - if (passc) - { - passc = 0; - ADD_CHAR (tchar); - continue; - } - - if (tchar == history_expansion_char) - tchar = -3; - - switch (tchar) - { - default: - ADD_CHAR (string[i]); - break; - - case '\\': - passc++; - ADD_CHAR (tchar); - break; - -#if defined (SHELL) - case '\'': - { - /* If this is bash, single quotes inhibit history expansion. */ - int quote, slen; - - quote = i++; - rl_string_extract_single_quoted (string, &i); - - slen = i - quote + 2; - temp = xmalloc (slen); - strncpy (temp, string + quote, slen); - temp[slen - 1] = '\0'; - ADD_STRING (temp); - free (temp); - break; - } -#endif /* SHELL */ - - case -3: /* history_expansion_char */ - cc = string[i + 1]; - - /* If the history_expansion_char is followed by one of the - characters in history_no_expand_chars, then it is not a - candidate for expansion of any kind. */ - if (member (cc, history_no_expand_chars)) - { - ADD_CHAR (string[i]); - break; - } - -#if defined (NO_BANG_HASH_MODIFIERS) - /* There is something that is listed as a `word specifier' in csh - documentation which means `the expanded text to this point'. - That is not a word specifier, it is an event specifier. If we - don't want to allow modifiers with `!#', just stick the current - output line in again. */ - if (cc == '#') - { - if (result) - { - temp = xmalloc (1 + strlen (result)); - strcpy (temp, result); - ADD_STRING (temp); - free (temp); - } - i++; - break; - } -#endif - - r = history_expand_internal (string, i, &eindex, &temp, result); - if (r < 0) - { - *output = temp; - free (result); - if (string != hstring) - free (string); - return -1; - } - else - { - if (temp) - { - modified++; - if (*temp) - ADD_STRING (temp); - free (temp); - } - only_printing = r == 1; - i = eindex; - } - break; - } - } - - *output = result; - if (string != hstring) - free (string); - - if (only_printing) - { - add_history (result); - return (2); - } - - return (modified != 0); -} - -/* Return a consed string which is the word specified in SPEC, and found - in FROM. NULL is returned if there is no spec. The address of - ERROR_POINTER is returned if the word specified cannot be found. - CALLER_INDEX is the offset in SPEC to start looking; it is updated - to point to just after the last character parsed. */ -static char * -get_history_word_specifier (spec, from, caller_index) - char *spec, *from; - int *caller_index; -{ - register int i = *caller_index; - int first, last; - int expecting_word_spec = 0; - char *result; - - /* The range of words to return doesn't exist yet. */ - first = last = 0; - result = (char *)NULL; - - /* If we found a colon, then this *must* be a word specification. If - it isn't, then it is an error. */ - if (spec[i] == ':') - { - i++; - expecting_word_spec++; - } - - /* Handle special cases first. */ - - /* `%' is the word last searched for. */ - if (spec[i] == '%') - { - *caller_index = i + 1; - return (search_match ? savestring (search_match) : savestring ("")); - } - - /* `*' matches all of the arguments, but not the command. */ - if (spec[i] == '*') - { - *caller_index = i + 1; - result = history_arg_extract (1, '$', from); - return (result ? result : savestring ("")); - } - - /* `$' is last arg. */ - if (spec[i] == '$') - { - *caller_index = i + 1; - return (history_arg_extract ('$', '$', from)); - } - - /* Try to get FIRST and LAST figured out. */ - - if (spec[i] == '-') - first = 0; - else if (spec[i] == '^') - first = 1; - else if (digit_p (spec[i]) && expecting_word_spec) - { - for (first = 0; digit_p (spec[i]); i++) - first = (first * 10) + digit_value (spec[i]); - } - else - return ((char *)NULL); /* no valid `first' for word specifier */ - - if (spec[i] == '^' || spec[i] == '*') - { - last = (spec[i] == '^') ? 1 : '$'; /* x* abbreviates x-$ */ - i++; - } - else if (spec[i] != '-') - last = first; - else - { - i++; - - if (digit_p (spec[i])) - { - for (last = 0; digit_p (spec[i]); i++) - last = (last * 10) + digit_value (spec[i]); - } - else if (spec[i] == '$') - { - i++; - last = '$'; - } - else if (!spec[i] || spec[i] == ':') /* could be modifier separator */ - last = -1; /* x- abbreviates x-$ omitting word `$' */ - } - - *caller_index = i; - - if (last >= first || last == '$' || last < 0) - result = history_arg_extract (first, last, from); - - return (result ? result : (char *)&error_pointer); -} - -/* Extract the args specified, starting at FIRST, and ending at LAST. - The args are taken from STRING. If either FIRST or LAST is < 0, - then make that arg count from the right (subtract from the number of - tokens, so that FIRST = -1 means the next to last token on the line). - If LAST is `$' the last arg from STRING is used. */ -char * -history_arg_extract (first, last, string) - int first, last; - char *string; -{ - register int i, len; - char *result = (char *)NULL; - int size = 0, offset = 0; - char **list; - - /* XXX - think about making history_tokenize return a struct array, - each struct in array being a string and a length to avoid the - calls to strlen below. */ - if ((list = history_tokenize (string)) == NULL) - return ((char *)NULL); - - for (len = 0; list[len]; len++) - ; - - if (last < 0) - last = len + last - 1; - - if (first < 0) - first = len + first - 1; - - if (last == '$') - last = len - 1; - - if (first == '$') - first = len - 1; - - last++; - - if (first >= len || last > len || first < 0 || last < 0 || first > last) - result = ((char *)NULL); - else - { - for (size = 0, i = first; i < last; i++) - size += strlen (list[i]) + 1; - result = xmalloc (size + 1); - result[0] = '\0'; - - for (i = first; i < last; i++) - { - strcpy (result + offset, list[i]); - offset += strlen (list[i]); - if (i + 1 < last) - { - result[offset++] = ' '; - result[offset] = 0; - } - } - } - - for (i = 0; i < len; i++) - free (list[i]); - free (list); - - return (result); -} - -#define slashify_in_quotes "\\`\"$" - -/* Parse STRING into tokens and return an array of strings. If WIND is - not -1 and INDP is not null, we also want the word surrounding index - WIND. The position in the returned array of strings is returned in - *INDP. */ -static char ** -history_tokenize_internal (string, wind, indp) - char *string; - int wind, *indp; -{ - char **result = (char **)NULL; - register int i, start, result_index, size; - int len; - - i = result_index = size = 0; - - /* Get a token, and stuff it into RESULT. The tokens are split - exactly where the shell would split them. */ - while (string[i]) - { - int delimiter = 0; - - /* Skip leading whitespace. */ - for (; string[i] && whitespace (string[i]); i++) - ; - if (!string[i] || string[i] == history_comment_char) - return (result); - - start = i; - - if (member (string[i], "()\n")) - { - i++; - goto got_token; - } - - if (member (string[i], "<>;&|$")) - { - int peek = string[i + 1]; - - if (peek == string[i] && peek != '$') - { - if (peek == '<' && string[i + 2] == '-') - i++; - i += 2; - goto got_token; - } - else - { - if ((peek == '&' && (string[i] == '>' || string[i] == '<')) || - ((peek == '>') && (string[i] == '&')) || - ((peek == '(') && (string[i] == '$'))) - { - i += 2; - goto got_token; - } - } - if (string[i] != '$') - { - i++; - goto got_token; - } - } - - /* Get word from string + i; */ - - if (member (string[i], "\"'`")) - delimiter = string[i++]; - - for (; string[i]; i++) - { - if (string[i] == '\\' && string[i + 1] == '\n') - { - i++; - continue; - } - - if (string[i] == '\\' && delimiter != '\'' && - (delimiter != '"' || member (string[i], slashify_in_quotes))) - { - i++; - continue; - } - - if (delimiter && string[i] == delimiter) - { - delimiter = 0; - continue; - } - - if (!delimiter && (member (string[i], " \t\n;&()|<>"))) - break; - - if (!delimiter && member (string[i], "\"'`")) - delimiter = string[i]; - } - got_token: - - /* If we are looking for the word in which the character at a - particular index falls, remember it. */ - if (indp && wind >= 0 && wind >= start && wind < i) - *indp = result_index; - - len = i - start; - if (result_index + 2 >= size) - result = (char **)xrealloc (result, ((size += 10) * sizeof (char *))); - result[result_index] = xmalloc (1 + len); - strncpy (result[result_index], string + start, len); - result[result_index][len] = '\0'; - result[++result_index] = (char *)NULL; - } - - return (result); -} - -/* Return an array of tokens, much as the shell might. The tokens are - parsed out of STRING. */ -char ** -history_tokenize (string) - char *string; -{ - return (history_tokenize_internal (string, -1, (int *)NULL)); -} - -/* Find and return the word which contains the character at index IND - in the history line LINE. Used to save the word matched by the - last history !?string? search. */ -static char * -history_find_word (line, ind) - char *line; - int ind; -{ - char **words, *s; - int i, wind; - - words = history_tokenize_internal (line, ind, &wind); - if (wind == -1) - return ((char *)NULL); - s = words[wind]; - for (i = 0; i < wind; i++) - free (words[i]); - for (i = wind + 1; words[i]; i++) - free (words[i]); - free (words); - return s; -} - -#if defined (STATIC_MALLOC) - -/* **************************************************************** */ -/* */ -/* xmalloc and xrealloc () */ -/* */ -/* **************************************************************** */ - -static void memory_error_and_abort (); - -static char * -xmalloc (bytes) - int bytes; -{ - char *temp = (char *)malloc (bytes); - - if (!temp) - memory_error_and_abort (); - return (temp); -} - -static char * -xrealloc (pointer, bytes) - char *pointer; - int bytes; -{ - char *temp; - - if (!pointer) - temp = (char *)xmalloc (bytes); - else - temp = (char *)realloc (pointer, bytes); - - if (!temp) - memory_error_and_abort (); - - return (temp); -} - -static void -memory_error_and_abort () -{ - fprintf (stderr, "history: Out of virtual memory!\n"); - abort (); -} -#endif /* STATIC_MALLOC */ - -/* **************************************************************** */ -/* */ -/* Test Code */ -/* */ -/* **************************************************************** */ -#ifdef TEST -main () -{ - char line[1024], *t; - int done = 0; - - line[0] = 0; - - while (!done) - { - fprintf (stdout, "history%% "); - t = gets (line); - - if (!t) - strcpy (line, "quit"); - - if (line[0]) - { - char *expansion; - int result; - - using_history (); - - result = history_expand (line, &expansion); - strcpy (line, expansion); - free (expansion); - if (result) - fprintf (stderr, "%s\n", line); - - if (result < 0) - continue; - - add_history (line); - } - - if (strcmp (line, "quit") == 0) done = 1; - if (strcmp (line, "save") == 0) write_history (0); - if (strcmp (line, "read") == 0) read_history (0); - if (strcmp (line, "list") == 0) - { - register HIST_ENTRY **the_list = history_list (); - register int i; - - if (the_list) - for (i = 0; the_list[i]; i++) - fprintf (stdout, "%d: %s\n", i + history_base, the_list[i]->line); - } - if (strncmp (line, "delete", strlen ("delete")) == 0) - { - int which; - if ((sscanf (line + strlen ("delete"), "%d", &which)) == 1) - { - HIST_ENTRY *entry = remove_history (which); - if (!entry) - fprintf (stderr, "No such entry %d\n", which); - else - { - free (entry->line); - free (entry); - } - } - else - { - fprintf (stderr, "non-numeric arg given to `delete'\n"); - } - } - } -} - -#endif /* TEST */ - -/* -* Local variables: -* compile-command: "gcc -g -DTEST -o history history.c" -* end: -*/ diff --git a/lib/readline/history.h b/lib/readline/history.h index 6935efd..17ec877 100644 --- a/lib/readline/history.h +++ b/lib/readline/history.h @@ -1,4 +1,26 @@ /* History.h -- the names of functions that you can call in history. */ +/* Copyright (C) 1989, 1992 Free Software Foundation, Inc. + + This file contains the GNU History Library (the Library), a set of + routines for managing the text of previously typed lines. + + The Library is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + The Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + The GNU General Public License is often shipped with GNU software, and + is generally kept in a file called COPYING or LICENSE. If you do not + have a copy of the license, write to the Free Software Foundation, + 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef _HISTORY_H_ +#define _HISTORY_H_ /* The structure used to store a history entry. */ typedef struct _hist_entry { @@ -46,6 +68,9 @@ extern HIST_ENTRY *remove_history (); invalid WHICH, a NULL pointer is returned. */ extern HIST_ENTRY *replace_history_entry (); +/* Clear the history list and start over. */ +extern void clear_history (); + /* Stifle the history list, remembering only MAX number of entries. */ extern void stifle_history (); @@ -179,3 +204,7 @@ extern char history_expansion_char; extern char history_subst_char; extern char history_comment_char; extern char *history_no_expand_chars; +extern char *history_search_delimiter_chars; +extern int history_quotes_inhibit_expansion; + +#endif /* !_HISTORY_H_ */ diff --git a/lib/readline/histsearch.c b/lib/readline/histsearch.c new file mode 100644 index 0000000..a72a68b --- /dev/null +++ b/lib/readline/histsearch.c @@ -0,0 +1,197 @@ +/* histsearch.c -- searching the history list. */ + +/* Copyright (C) 1989, 1992 Free Software Foundation, Inc. + + This file contains the GNU History Library (the Library), a set of + routines for managing the text of previously typed lines. + + The Library is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + The Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + The GNU General Public License is often shipped with GNU software, and + is generally kept in a file called COPYING or LICENSE. If you do not + have a copy of the license, write to the Free Software Foundation, + 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include <config.h> +#endif + +#include <stdio.h> +#if defined (HAVE_STDLIB_H) +# include <stdlib.h> +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ +#if defined (HAVE_UNISTD_H) +# include <unistd.h> +#endif +#if defined (HAVE_STRING_H) +# include <string.h> +#else +# include <strings.h> +#endif /* !HAVE_STRING_H */ + +#include "history.h" +#include "histlib.h" + +/* Variables imported from other history library files. */ +extern int history_offset; + +/* The list of alternate characters that can delimit a history search + string. */ +char *history_search_delimiter_chars = (char *)NULL; + +/* Search the history for STRING, starting at history_offset. + If DIRECTION < 0, then the search is through previous entries, else + through subsequent. If ANCHORED is non-zero, the string must + appear at the beginning of a history line, otherwise, the string + may appear anywhere in the line. If the string is found, then + current_history () is the history entry, and the value of this + function is the offset in the line of that history entry that the + string was found in. Otherwise, nothing is changed, and a -1 is + returned. */ + +static int +history_search_internal (string, direction, anchored) + char *string; + int direction, anchored; +{ + register int i, reverse; + register char *line; + register int line_index; + int string_len; + HIST_ENTRY **the_history; /* local */ + + i = history_offset; + reverse = (direction < 0); + + /* Take care of trivial cases first. */ + if (string == 0 || *string == '\0') + return (-1); + + if (!history_length || ((i == history_length) && !reverse)) + return (-1); + + if (reverse && (i == history_length)) + i--; + +#define NEXT_LINE() do { if (reverse) i--; else i++; } while (0) + + the_history = history_list (); + string_len = strlen (string); + while (1) + { + /* Search each line in the history list for STRING. */ + + /* At limit for direction? */ + if ((reverse && i < 0) || (!reverse && i == history_length)) + return (-1); + + line = the_history[i]->line; + line_index = strlen (line); + + /* If STRING is longer than line, no match. */ + if (string_len > line_index) + { + NEXT_LINE (); + continue; + } + + /* Handle anchored searches first. */ + if (anchored == ANCHORED_SEARCH) + { + if (STREQN (string, line, string_len)) + { + history_offset = i; + return (0); + } + + NEXT_LINE (); + continue; + } + + /* Do substring search. */ + if (reverse) + { + line_index -= string_len; + + while (line_index >= 0) + { + if (STREQN (string, line + line_index, string_len)) + { + history_offset = i; + return (line_index); + } + line_index--; + } + } + else + { + register int limit; + + limit = line_index - string_len + 1; + line_index = 0; + + while (line_index < limit) + { + if (STREQN (string, line + line_index, string_len)) + { + history_offset = i; + return (line_index); + } + line_index++; + } + } + NEXT_LINE (); + } +} + +/* Do a non-anchored search for STRING through the history in DIRECTION. */ +int +history_search (string, direction) + char *string; + int direction; +{ + return (history_search_internal (string, direction, NON_ANCHORED_SEARCH)); +} + +/* Do an anchored search for string through the history in DIRECTION. */ +int +history_search_prefix (string, direction) + char *string; + int direction; +{ + return (history_search_internal (string, direction, ANCHORED_SEARCH)); +} + +/* Search for STRING in the history list. DIR is < 0 for searching + backwards. POS is an absolute index into the history list at + which point to begin searching. */ +int +history_search_pos (string, dir, pos) + char *string; + int dir, pos; +{ + int ret, old; + + old = where_history (); + history_set_pos (pos); + if (history_search (string, dir) == -1) + { + history_set_pos (old); + return (-1); + } + ret = where_history (); + history_set_pos (old); + return ret; +} diff --git a/lib/readline/input.c b/lib/readline/input.c new file mode 100644 index 0000000..7e3c0fe --- /dev/null +++ b/lib/readline/input.c @@ -0,0 +1,449 @@ +/* input.c -- character input functions for readline. */ + +/* Copyright (C) 1994 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library, a library for + reading lines of text with interactive input and history editing. + + The GNU Readline Library is free software; you can redistribute it + and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2, or + (at your option) any later version. + + The GNU Readline Library is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + The GNU General Public License is often shipped with GNU software, and + is generally kept in a file called COPYING or LICENSE. If you do not + have a copy of the license, write to the Free Software Foundation, + 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include <config.h> +#endif + +#include <sys/types.h> +#include <fcntl.h> +#if defined (HAVE_SYS_FILE_H) +# include <sys/file.h> +#endif /* HAVE_SYS_FILE_H */ + +#if defined (HAVE_UNISTD_H) +# include <unistd.h> +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include <stdlib.h> +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_SELECT) +# if !defined (HAVE_SYS_SELECT_H) || !defined (M_UNIX) +# include <sys/time.h> +# endif +#endif /* HAVE_SELECT */ +#if defined (HAVE_SYS_SELECT_H) +# include <sys/select.h> +#endif + +#if defined (FIONREAD_IN_SYS_IOCTL) +# include <sys/ioctl.h> +#endif + +#include <stdio.h> +#include <errno.h> + +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" + +/* Some standard library routines. */ +#include "readline.h" + +/* What kind of non-blocking I/O do we have? */ +#if !defined (O_NDELAY) && defined (O_NONBLOCK) +# define O_NDELAY O_NONBLOCK /* Posix style */ +#endif + +/* Functions imported from other files in the library. */ +extern char *xmalloc (), *xrealloc (); + +/* Variables and functions from macro.c. */ +extern void _rl_add_macro_char (); +extern void _rl_with_macro_input (); +extern int _rl_next_macro_key (); +extern int _rl_defining_kbd_macro; + +#if defined (VI_MODE) +extern void _rl_vi_set_last (); +extern int _rl_vi_textmod_command (); +#endif /* VI_MODE */ + +extern FILE *rl_instream, *rl_outstream; +extern Function *rl_last_func; +extern int rl_key_sequence_length; +extern int rl_pending_input; +extern int rl_editing_mode; + +extern Keymap _rl_keymap; + +extern int _rl_convert_meta_chars_to_ascii; + +#if defined (__GO32__) +# include <pc.h> +#endif /* __GO32__ */ + +/* Non-null means it is a pointer to a function to run while waiting for + character input. */ +Function *rl_event_hook = (Function *)NULL; + +Function *rl_getc_function = rl_getc; + +/* **************************************************************** */ +/* */ +/* Character Input Buffering */ +/* */ +/* **************************************************************** */ + +static int pop_index, push_index; +static unsigned char ibuffer[512]; +static int ibuffer_len = sizeof (ibuffer) - 1; + +#define any_typein (push_index != pop_index) + +int +_rl_any_typein () +{ + return any_typein; +} + +/* Add KEY to the buffer of characters to be read. */ +int +rl_stuff_char (key) + int key; +{ + if (key == EOF) + { + key = NEWLINE; + rl_pending_input = EOF; + } + ibuffer[push_index++] = key; + if (push_index >= ibuffer_len) + push_index = 0; + return push_index; +} + +/* Make C be the next command to be executed. */ +int +rl_execute_next (c) + int c; +{ + rl_pending_input = c; + return 0; +} + +/* Return the amount of space available in the + buffer for stuffing characters. */ +static int +ibuffer_space () +{ + if (pop_index > push_index) + return (pop_index - push_index); + else + return (ibuffer_len - (push_index - pop_index)); +} + +/* Get a key from the buffer of characters to be read. + Return the key in KEY. + Result is KEY if there was a key, or 0 if there wasn't. */ +static int +rl_get_char (key) + int *key; +{ + if (push_index == pop_index) + return (0); + + *key = ibuffer[pop_index++]; + + if (pop_index >= ibuffer_len) + pop_index = 0; + + return (1); +} + +/* Stuff KEY into the *front* of the input buffer. + Returns non-zero if successful, zero if there is + no space left in the buffer. */ +static int +rl_unget_char (key) + int key; +{ + if (ibuffer_space ()) + { + pop_index--; + if (pop_index < 0) + pop_index = ibuffer_len - 1; + ibuffer[pop_index] = key; + return (1); + } + return (0); +} + +/* If a character is available to be read, then read it + and stuff it into IBUFFER. Otherwise, just return. */ +static void +rl_gather_tyi () +{ +#if defined (__GO32__) + char input; + + if (isatty (0) && kbhit () && ibuffer_space ()) + { + int i; + i = (*rl_getc_function) (rl_instream); + rl_stuff_char (i); + } +#else /* !__GO32__ */ + + int tty; + register int tem, result; + int chars_avail; + char input; +#if defined(HAVE_SELECT) + fd_set readfds, exceptfds; + struct timeval timeout; +#endif + + tty = fileno (rl_instream); + +#if defined (HAVE_SELECT) + FD_ZERO (&readfds); + FD_ZERO (&exceptfds); + FD_SET (tty, &readfds); + FD_SET (tty, &exceptfds); + timeout.tv_sec = 0; + timeout.tv_usec = 100000; /* 0.1 seconds */ + if (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) <= 0) + return; /* Nothing to read. */ +#endif + + result = -1; +#if defined (FIONREAD) + result = ioctl (tty, FIONREAD, &chars_avail); +#endif + +#if defined (O_NDELAY) + if (result == -1) + { + tem = fcntl (tty, F_GETFL, 0); + + fcntl (tty, F_SETFL, (tem | O_NDELAY)); + chars_avail = read (tty, &input, 1); + + fcntl (tty, F_SETFL, tem); + if (chars_avail == -1 && errno == EAGAIN) + return; + } +#endif /* O_NDELAY */ + + /* If there's nothing available, don't waste time trying to read + something. */ + if (chars_avail <= 0) + return; + + tem = ibuffer_space (); + + if (chars_avail > tem) + chars_avail = tem; + + /* One cannot read all of the available input. I can only read a single + character at a time, or else programs which require input can be + thwarted. If the buffer is larger than one character, I lose. + Damn! */ + if (tem < ibuffer_len) + chars_avail = 0; + + if (result != -1) + { + while (chars_avail--) + rl_stuff_char ((*rl_getc_function) (rl_instream)); + } + else + { + if (chars_avail) + rl_stuff_char (input); + } +#endif /* !__GO32__ */ +} + +/* Is there input available to be read on the readline input file + descriptor? Only works if the system has select(2) or FIONREAD. */ +int +_rl_input_available () +{ +#if defined(HAVE_SELECT) + fd_set readfds, exceptfds; + struct timeval timeout; +#endif +#if defined(FIONREAD) + int chars_avail; +#endif + int tty; + + tty = fileno (rl_instream); + +#if defined (HAVE_SELECT) + FD_ZERO (&readfds); + FD_ZERO (&exceptfds); + FD_SET (tty, &readfds); + FD_SET (tty, &exceptfds); + timeout.tv_sec = 0; + timeout.tv_usec = 100000; /* 0.1 seconds */ + return (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) > 0); +#endif + +#if defined (FIONREAD) + if (ioctl (tty, FIONREAD, &chars_avail) == 0) + return (chars_avail); +#endif + + return 0; +} + +void +_rl_insert_typein (c) + int c; +{ + int key, t, i; + char *string; + + i = key = 0; + string = xmalloc (ibuffer_len + 1); + string[i++] = (char) c; + + while ((t = rl_get_char (&key)) && + _rl_keymap[key].type == ISFUNC && + _rl_keymap[key].function == rl_insert) + string[i++] = key; + + if (t) + rl_unget_char (key); + + string[i] = '\0'; + rl_insert_text (string); + free (string); +} + +/* **************************************************************** */ +/* */ +/* Character Input */ +/* */ +/* **************************************************************** */ + +/* Read a key, including pending input. */ +int +rl_read_key () +{ + int c; + + rl_key_sequence_length++; + + if (rl_pending_input) + { + c = rl_pending_input; + rl_pending_input = 0; + } + else + { + /* If input is coming from a macro, then use that. */ + if (c = _rl_next_macro_key ()) + return (c); + + /* If the user has an event function, then call it periodically. */ + if (rl_event_hook) + { + while (rl_event_hook && rl_get_char (&c) == 0) + { + (*rl_event_hook) (); + rl_gather_tyi (); + } + } + else + { + if (rl_get_char (&c) == 0) + c = (*rl_getc_function) (rl_instream); + } + } + + return (c); +} + +int +rl_getc (stream) + FILE *stream; +{ + int result, flags; + unsigned char c; + +#if defined (__GO32__) + if (isatty (0)) + return (getkey () & 0x7F); +#endif /* __GO32__ */ + + while (1) + { + result = read (fileno (stream), &c, sizeof (unsigned char)); + + if (result == sizeof (unsigned char)) + return (c); + + /* If zero characters are returned, then the file that we are + reading from is empty! Return EOF in that case. */ + if (result == 0) + return (EOF); + +#if defined (EWOULDBLOCK) + if (errno == EWOULDBLOCK) + { + if ((flags = fcntl (fileno (stream), F_GETFL, 0)) < 0) + return (EOF); + if (flags & O_NDELAY) + { + flags &= ~O_NDELAY; + fcntl (fileno (stream), F_SETFL, flags); + continue; + } + continue; + } +#endif /* EWOULDBLOCK */ + +#if defined (_POSIX_VERSION) && defined (EAGAIN) && defined (O_NONBLOCK) + if (errno == EAGAIN) + { + if ((flags = fcntl (fileno (stream), F_GETFL, 0)) < 0) + return (EOF); + if (flags & O_NONBLOCK) + { + flags &= ~O_NONBLOCK; + fcntl (fileno (stream), F_SETFL, flags); + continue; + } + } +#endif /* _POSIX_VERSION && EAGAIN && O_NONBLOCK */ + +#if !defined (__GO32__) + /* If the error that we received was SIGINT, then try again, + this is simply an interrupted system call to read (). + Otherwise, some error ocurred, also signifying EOF. */ + if (errno != EINTR) + return (EOF); +#endif /* !__GO32__ */ + } +} diff --git a/lib/readline/isearch.c b/lib/readline/isearch.c index 1a0193f..fa60fa4 100644 --- a/lib/readline/isearch.c +++ b/lib/readline/isearch.c @@ -26,19 +26,22 @@ 675 Mass Ave, Cambridge, MA 02139, USA. */ #define READLINE_LIBRARY +#if defined (HAVE_CONFIG_H) +# include <config.h> +#endif + #include <stdio.h> #if defined (HAVE_UNISTD_H) # include <unistd.h> #endif -#include "memalloc.h" +#include <sys/types.h> + +#include "rldefs.h" #include "readline.h" #include "history.h" -#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0)) -#define STREQN(a, b, n) (((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0)) - /* Variables imported from other files in the readline library. */ extern Keymap _rl_keymap; extern HIST_ENTRY *saved_line_for_history; @@ -46,6 +49,14 @@ extern int rl_line_buffer_len; extern int rl_point, rl_end; extern char *rl_line_buffer; +extern void _rl_save_prompt (); +extern void _rl_restore_prompt (); + +extern int rl_execute_next (); +extern void rl_extend_line_buffer (); + +extern int _rl_input_available (); + extern char *xmalloc (), *xrealloc (); static int rl_search_history (); @@ -56,18 +67,18 @@ static char *prev_line_found; /* Search backwards through the history looking for a string which is typed interactively. Start with the current line. */ +int rl_reverse_search_history (sign, key) - int sign; - int key; + int sign, key; { return (rl_search_history (-sign, key)); } /* Search forwards through the history looking for a string which is typed interactively. Start with the current line. */ +int rl_forward_search_history (sign, key) - int sign; - int key; + int sign, key; { return (rl_search_history (sign, key)); } @@ -83,29 +94,43 @@ rl_display_search (search_string, reverse_p, where) int reverse_p, where; { char *message; + int msglen, searchlen; + + searchlen = (search_string && *search_string) ? strlen (search_string) : 0; - message = xmalloc (1 + (search_string ? strlen (search_string) : 0) + 30); - *message = '\0'; + message = xmalloc (searchlen + 33); + msglen = 0; #if defined (NOTDEF) if (where != -1) - sprintf (message, "[%d]", where + history_base); + { + sprintf (message, "[%d]", where + history_base); + msglen = strlen (message); + } #endif /* NOTDEF */ - strcat (message, "("); + message[msglen++] = '('; if (reverse_p) - strcat (message, "reverse-"); + { + strcpy (message + msglen, "reverse-"); + msglen += 8; + } - strcat (message, "i-search)`"); + strcpy (message + msglen, "i-search)`"); + msglen += 10; if (search_string) - strcat (message, search_string); + { + strcpy (message + msglen, search_string); + msglen += searchlen; + } + + strcpy (message + msglen, "': "); - strcat (message, "': "); rl_message ("%s", message, 0); free (message); - rl_redisplay (); + (*rl_redisplay_function) (); } /* Search through the history looking for an interactively typed string. @@ -114,8 +139,7 @@ rl_display_search (search_string, reverse_p, where) backwards. */ static int rl_search_history (direction, invoking_key) - int direction; - int invoking_key; + int direction, invoking_key; { /* The string that the user types in to search for. */ char *search_string; @@ -127,19 +151,17 @@ rl_search_history (direction, invoking_key) int search_string_size; /* The list of lines to search through. */ - char **lines, *allocated_line = (char *)NULL; + char **lines, *allocated_line; /* The length of LINES. */ int hlen; /* Where we get LINES from. */ - HIST_ENTRY **hlist = history_list (); + HIST_ENTRY **hlist; - register int i = 0; - int orig_point = rl_point; - int orig_line = where_history (); - int last_found_line = orig_line; - int c, done = 0, found, failed, sline_len; + register int i; + int orig_point, orig_line, last_found_line; + int c, found, failed, sline_len; /* The line currently being searched. */ char *sline; @@ -148,10 +170,17 @@ rl_search_history (direction, invoking_key) int line_index; /* Non-zero if we are doing a reverse search. */ - int reverse = (direction < 0); + int reverse; + + orig_point = rl_point; + last_found_line = orig_line = where_history (); + reverse = direction < 0; + hlist = history_list (); + allocated_line = (char *)NULL; /* Create an arrary of pointers to the lines that we want to search. */ maybe_replace_line (); + i = 0; if (hlist) for (i = 0; hlist[i]; i++); @@ -176,6 +205,8 @@ rl_search_history (direction, invoking_key) /* The line where we start the search. */ i = orig_line; + _rl_save_prompt (); + /* Initialize search parameters. */ search_string = xmalloc (search_string_size = 128); *search_string = '\0'; @@ -192,14 +223,13 @@ rl_search_history (direction, invoking_key) line_index = rl_point; found = failed = 0; - while (!done) + for (;;) { Function *f = (Function *)NULL; /* Read a key and decide how to proceed. */ c = rl_read_key (); - /* Hack C to Do What I Mean. */ if (_rl_keymap[c].type == ISFUNC) { f = _rl_keymap[c].function; @@ -210,78 +240,81 @@ rl_search_history (direction, invoking_key) c = !reverse ? -1 : -2; } - switch (c) + /* Let NEWLINE (^J) terminate the search for people who don't like + using ESC. ^M can still be used to terminate the search and + immediately execute the command. */ + if (c == ESC || c == NEWLINE) + { + /* ESC still terminates the search, but if there is pending + input or if input arrives within 0.1 seconds (on systems + with select(2)) it is used as a prefix character + with rl_execute_next. WATCH OUT FOR THIS! This is intended + to allow the arrow keys to be used like ^F and ^B are used + to terminate the search and execute the movement command. */ + if (c == ESC && _rl_input_available ()) /* XXX */ + rl_execute_next (ESC); + break; + } + + if (c >= 0 && (CTRL_CHAR (c) || META_CHAR (c) || c == RUBOUT)) { - case ESC: - done = 1; - continue; + rl_execute_next (c); + break; + } + switch (c) + { case -1: - if (!search_string_index) + if (search_string_index == 0) continue; + else if (reverse) + --line_index; + else if (line_index != sline_len) + ++line_index; else - { - if (reverse) - --line_index; - else - { - if (line_index != sline_len) - ++line_index; - else - ding (); - } - } + ding (); break; /* switch directions */ case -2: direction = -direction; - reverse = (direction < 0); + reverse = direction < 0; break; case CTRL ('G'): strcpy (rl_line_buffer, lines[orig_line]); rl_point = orig_point; rl_end = strlen (rl_line_buffer); + _rl_restore_prompt(); rl_clear_message (); free (allocated_line); free (lines); return 0; default: - if (CTRL_CHAR (c) || META_CHAR (c) || c == RUBOUT) + /* Add character to search string and continue search. */ + if (search_string_index + 2 >= search_string_size) { - rl_execute_next (c); - done = 1; - continue; - } - else - { - /* Add character to search string and continue search. */ - if (search_string_index + 2 >= search_string_size) - { - search_string_size += 128; - search_string = xrealloc (search_string, search_string_size); - } - search_string[search_string_index++] = c; - search_string[search_string_index] = '\0'; - break; + search_string_size += 128; + search_string = xrealloc (search_string, search_string_size); } + search_string[search_string_index++] = c; + search_string[search_string_index] = '\0'; + break; } - found = failed = 0; - while (1) + for (found = failed = 0;;) { int limit = sline_len - search_string_index + 1; /* Search the current line. */ while (reverse ? (line_index >= 0) : (line_index < limit)) { - if (STREQN(search_string, sline + line_index, search_string_index)) - { - found++; - break; - } + if (STREQN (search_string, sline + line_index, search_string_index)) + { + found++; + break; + } else line_index += direction; } @@ -314,10 +347,7 @@ rl_search_history (direction, invoking_key) break; /* Now set up the line for searching... */ - if (reverse) - line_index = sline_len - search_string_index; - else - line_index = 0; + line_index = reverse ? sline_len - search_string_index : 0; } if (failed) @@ -357,6 +387,8 @@ rl_search_history (direction, invoking_key) /* First put back the original state. */ strcpy (rl_line_buffer, lines[orig_line]); + _rl_restore_prompt (); + /* Free the search string. */ free (search_string); diff --git a/lib/readline/keymaps.c b/lib/readline/keymaps.c index e1be552..9359749 100644 --- a/lib/readline/keymaps.c +++ b/lib/readline/keymaps.c @@ -21,7 +21,7 @@ #define READLINE_LIBRARY #if defined (HAVE_CONFIG_H) -# include "config.h" +# include <config.h> #endif #if defined (HAVE_STDLIB_H) @@ -41,11 +41,7 @@ extern int rl_do_lowercase_version (); extern int rl_rubout (), rl_insert (); -#if defined (STATIC_MALLOC) -static char *xmalloc (), *xrealloc (); -#else extern char *xmalloc (), *xrealloc (); -#endif /* STATIC_MALLOC */ /* **************************************************************** */ /* */ @@ -109,7 +105,7 @@ rl_make_keymap () newmap[i].function = rl_insert; newmap[TAB].function = rl_insert; - newmap[RUBOUT].function = rl_rubout; + newmap[RUBOUT].function = rl_rubout; /* RUBOUT == 127 */ newmap[CTRL('H')].function = rl_rubout; #if KEYMAP_SIZE > 128 @@ -152,49 +148,3 @@ rl_discard_keymap (map) } } } - -#if defined (STATIC_MALLOC) - -/* **************************************************************** */ -/* */ -/* xmalloc and xrealloc () */ -/* */ -/* **************************************************************** */ - -static void memory_error_and_abort (); - -static char * -xmalloc (bytes) - int bytes; -{ - char *temp = (char *)malloc (bytes); - - if (!temp) - memory_error_and_abort (); - return (temp); -} - -static char * -xrealloc (pointer, bytes) - char *pointer; - int bytes; -{ - char *temp; - - if (!pointer) - temp = (char *)malloc (bytes); - else - temp = (char *)realloc (pointer, bytes); - - if (!temp) - memory_error_and_abort (); - return (temp); -} - -static void -memory_error_and_abort () -{ - fprintf (stderr, "readline: Out of virtual memory!\n"); - abort (); -} -#endif /* STATIC_MALLOC */ diff --git a/lib/readline/keymaps.h b/lib/readline/keymaps.h index f0eda3d..f8d0e2e 100644 --- a/lib/readline/keymaps.h +++ b/lib/readline/keymaps.h @@ -29,8 +29,8 @@ # include <readline/chardefs.h> #endif -#if !defined (__FUNCTION_DEF) -# define __FUNCTION_DEF +#if !defined (_FUNCTION_DEF) +# define _FUNCTION_DEF typedef int Function (); typedef void VFunction (); typedef char *CPFunction (); diff --git a/lib/readline/kill.c b/lib/readline/kill.c new file mode 100644 index 0000000..89f6b55 --- /dev/null +++ b/lib/readline/kill.c @@ -0,0 +1,547 @@ +/* kill.c -- kill ring management. */ + +/* Copyright (C) 1994 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library, a library for + reading lines of text with interactive input and history editing. + + The GNU Readline Library is free software; you can redistribute it + and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 1, or + (at your option) any later version. + + The GNU Readline Library is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + The GNU General Public License is often shipped with GNU software, and + is generally kept in a file called COPYING or LICENSE. If you do not + have a copy of the license, write to the Free Software Foundation, + 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include <config.h> +#endif + +#include <sys/types.h> + +#if defined (HAVE_UNISTD_H) +# include <unistd.h> /* for _POSIX_VERSION */ +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include <stdlib.h> +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include <stdio.h> + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +extern int _rl_last_command_was_kill; +extern int rl_editing_mode; +extern int rl_explicit_arg; +extern Function *rl_last_func; + +extern void _rl_init_argument (); +extern int _rl_set_mark_at_pos (); +extern void _rl_abort_internal (); + +extern char *xmalloc (), *xrealloc (); + +/* **************************************************************** */ +/* */ +/* Killing Mechanism */ +/* */ +/* **************************************************************** */ + +/* What we assume for a max number of kills. */ +#define DEFAULT_MAX_KILLS 10 + +/* The real variable to look at to find out when to flush kills. */ +static int rl_max_kills = DEFAULT_MAX_KILLS; + +/* Where to store killed text. */ +static char **rl_kill_ring = (char **)NULL; + +/* Where we are in the kill ring. */ +static int rl_kill_index; + +/* How many slots we have in the kill ring. */ +static int rl_kill_ring_length; + +/* How to say that you only want to save a certain amount + of kill material. */ +int +rl_set_retained_kills (num) + int num; +{ + return 0; +} + +/* Add TEXT to the kill ring, allocating a new kill ring slot as necessary. + This uses TEXT directly, so the caller must not free it. If APPEND is + non-zero, and the last command was a kill, the text is appended to the + current kill ring slot, otherwise prepended. */ +static int +_rl_copy_to_kill_ring (text, append) + char *text; + int append; +{ + char *old, *new; + int slot; + + /* First, find the slot to work with. */ + if (_rl_last_command_was_kill == 0) + { + /* Get a new slot. */ + if (rl_kill_ring == 0) + { + /* If we don't have any defined, then make one. */ + rl_kill_ring = (char **) + xmalloc (((rl_kill_ring_length = 1) + 1) * sizeof (char *)); + rl_kill_ring[slot = 0] = (char *)NULL; + } + else + { + /* We have to add a new slot on the end, unless we have + exceeded the max limit for remembering kills. */ + slot = rl_kill_ring_length; + if (slot == rl_max_kills) + { + register int i; + free (rl_kill_ring[0]); + for (i = 0; i < slot; i++) + rl_kill_ring[i] = rl_kill_ring[i + 1]; + } + else + { + slot = rl_kill_ring_length += 1; + rl_kill_ring = (char **)xrealloc (rl_kill_ring, slot * sizeof (char *)); + } + rl_kill_ring[--slot] = (char *)NULL; + } + } + else + slot = rl_kill_ring_length - 1; + + /* If the last command was a kill, prepend or append. */ + if (_rl_last_command_was_kill && rl_editing_mode != vi_mode) + { + old = rl_kill_ring[slot]; + new = xmalloc (1 + strlen (old) + strlen (text)); + + if (append) + { + strcpy (new, old); + strcat (new, text); + } + else + { + strcpy (new, text); + strcat (new, old); + } + free (old); + free (text); + rl_kill_ring[slot] = new; + } + else + rl_kill_ring[slot] = text; + + rl_kill_index = slot; + return 0; +} + +/* The way to kill something. This appends or prepends to the last + kill, if the last command was a kill command. if FROM is less + than TO, then the text is appended, otherwise prepended. If the + last command was not a kill command, then a new slot is made for + this kill. */ +int +rl_kill_text (from, to) + int from, to; +{ + char *text; + + /* Is there anything to kill? */ + if (from == to) + { + _rl_last_command_was_kill++; + return 0; + } + + text = rl_copy_text (from, to); + + /* Delete the copied text from the line. */ + rl_delete_text (from, to); + + _rl_copy_to_kill_ring (text, from < to); + + _rl_last_command_was_kill++; + return 0; +} + +/* Now REMEMBER! In order to do prepending or appending correctly, kill + commands always make rl_point's original position be the FROM argument, + and rl_point's extent be the TO argument. */ + +/* **************************************************************** */ +/* */ +/* Killing Commands */ +/* */ +/* **************************************************************** */ + +/* Delete the word at point, saving the text in the kill ring. */ +int +rl_kill_word (count, key) + int count, key; +{ + int orig_point = rl_point; + + if (count < 0) + return (rl_backward_kill_word (-count, key)); + else + { + rl_forward_word (count, key); + + if (rl_point != orig_point) + rl_kill_text (orig_point, rl_point); + + rl_point = orig_point; + } + return 0; +} + +/* Rubout the word before point, placing it on the kill ring. */ +int +rl_backward_kill_word (count, ignore) + int count, ignore; +{ + int orig_point = rl_point; + + if (count < 0) + return (rl_kill_word (-count, ignore)); + else + { + rl_backward_word (count, ignore); + + if (rl_point != orig_point) + rl_kill_text (orig_point, rl_point); + } + return 0; +} + +/* Kill from here to the end of the line. If DIRECTION is negative, kill + back to the line start instead. */ +int +rl_kill_line (direction, ignore) + int direction, ignore; +{ + int orig_point = rl_point; + + if (direction < 0) + return (rl_backward_kill_line (1, ignore)); + else + { + rl_end_of_line (1, ignore); + if (orig_point != rl_point) + rl_kill_text (orig_point, rl_point); + rl_point = orig_point; + } + return 0; +} + +/* Kill backwards to the start of the line. If DIRECTION is negative, kill + forwards to the line end instead. */ +int +rl_backward_kill_line (direction, ignore) + int direction, ignore; +{ + int orig_point = rl_point; + + if (direction < 0) + return (rl_kill_line (1, ignore)); + else + { + if (!rl_point) + ding (); + else + { + rl_beg_of_line (1, ignore); + rl_kill_text (orig_point, rl_point); + } + } + return 0; +} + +/* Kill the whole line, no matter where point is. */ +int +rl_kill_full_line (count, ignore) + int count, ignore; +{ + rl_begin_undo_group (); + rl_point = 0; + rl_kill_text (rl_point, rl_end); + rl_end_undo_group (); + return 0; +} + +/* The next two functions mimic unix line editing behaviour, except they + save the deleted text on the kill ring. This is safer than not saving + it, and since we have a ring, nobody should get screwed. */ + +/* This does what C-w does in Unix. We can't prevent people from + using behaviour that they expect. */ +int +rl_unix_word_rubout (count, key) + int count, key; +{ + int orig_point; + + if (rl_point == 0) + ding (); + else + { + orig_point = rl_point; + if (count <= 0) + count = 1; + + while (count--) + { + while (rl_point && whitespace (rl_line_buffer[rl_point - 1])) + rl_point--; + + while (rl_point && (whitespace (rl_line_buffer[rl_point - 1]) == 0)) + rl_point--; + } + + rl_kill_text (orig_point, rl_point); + } + return 0; +} + +/* Here is C-u doing what Unix does. You don't *have* to use these + key-bindings. We have a choice of killing the entire line, or + killing from where we are to the start of the line. We choose the + latter, because if you are a Unix weenie, then you haven't backspaced + into the line at all, and if you aren't, then you know what you are + doing. */ +int +rl_unix_line_discard (count, key) + int count, key; +{ + if (rl_point == 0) + ding (); + else + { + rl_kill_text (rl_point, 0); + rl_point = 0; + } + return 0; +} + +/* Copy the text in the `region' to the kill ring. If DELETE is non-zero, + delete the text from the line as well. */ +static int +region_kill_internal (delete) + int delete; +{ + char *text; + + if (rl_mark == rl_point) + { + _rl_last_command_was_kill++; + return 0; + } + + text = rl_copy_text (rl_point, rl_mark); + if (delete) + rl_delete_text (rl_point, rl_mark); + _rl_copy_to_kill_ring (text, rl_point < rl_mark); + + _rl_last_command_was_kill++; + return 0; +} + +/* Copy the text in the region to the kill ring. */ +int +rl_copy_region_to_kill (count, ignore) + int count, ignore; +{ + return (region_kill_internal (0)); +} + +/* Kill the text between the point and mark. */ +int +rl_kill_region (count, ignore) + int count, ignore; +{ + return (region_kill_internal (1)); +} + +/* Copy COUNT words to the kill ring. DIR says which direction we look + to find the words. */ +static int +_rl_copy_word_as_kill (count, dir) + int count, dir; +{ + int om, op, r; + + om = rl_mark; + op = rl_point; + + if (dir > 0) + rl_forward_word (count, 0); + else + rl_backward_word (count, 0); + + rl_mark = rl_point; + + if (dir > 0) + rl_backward_word (count, 0); + else + rl_forward_word (count, 0); + + r = region_kill_internal (0); + + rl_mark = om; + rl_point = op; + + return r; +} + +int +rl_copy_forward_word (count, key) + int count, key; +{ + if (count < 0) + return (rl_copy_backward_word (-count, key)); + + return (_rl_copy_word_as_kill (count, 1)); +} + +int +rl_copy_backward_word (count, key) + int count, key; +{ + if (count < 0) + return (rl_copy_forward_word (-count, key)); + + return (_rl_copy_word_as_kill (count, -1)); +} + +/* Yank back the last killed text. This ignores arguments. */ +int +rl_yank (count, ignore) + int count, ignore; +{ + if (rl_kill_ring == 0) + { + _rl_abort_internal (); + return -1; + } + + _rl_set_mark_at_pos (rl_point); + rl_insert_text (rl_kill_ring[rl_kill_index]); + return 0; +} + +/* If the last command was yank, or yank_pop, and the text just + before point is identical to the current kill item, then + delete that text from the line, rotate the index down, and + yank back some other text. */ +int +rl_yank_pop (count, key) + int count, key; +{ + int l, n; + + if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) || + !rl_kill_ring) + { + _rl_abort_internal (); + return -1; + } + + l = strlen (rl_kill_ring[rl_kill_index]); + n = rl_point - l; + if (n >= 0 && STREQN (rl_line_buffer + n, rl_kill_ring[rl_kill_index], l)) + { + rl_delete_text (n, rl_point); + rl_point = n; + rl_kill_index--; + if (rl_kill_index < 0) + rl_kill_index = rl_kill_ring_length - 1; + rl_yank (1, 0); + return 0; + } + else + { + _rl_abort_internal (); + return -1; + } +} + +/* Yank the COUNTth argument from the previous history line. */ +int +rl_yank_nth_arg (count, ignore) + int count, ignore; +{ + register HIST_ENTRY *entry; + char *arg; + + entry = previous_history (); + if (entry) + next_history (); + else + { + ding (); + return -1; + } + + arg = history_arg_extract (count, count, entry->line); + if (!arg || !*arg) + { + ding (); + return -1; + } + + rl_begin_undo_group (); + +#if defined (VI_MODE) + /* Vi mode always inserts a space before yanking the argument, and it + inserts it right *after* rl_point. */ + if (rl_editing_mode == vi_mode) + { + rl_vi_append_mode (); + rl_insert_text (" "); + } +#endif /* VI_MODE */ + + rl_insert_text (arg); + free (arg); + + rl_end_undo_group (); + return 0; +} + +/* Yank the last argument from the previous history line. This `knows' + how rl_yank_nth_arg treats a count of `$'. With an argument, this + behaves the same as rl_yank_nth_arg. */ +int +rl_yank_last_arg (count, key) + int count, key; +{ + if (rl_explicit_arg) + return (rl_yank_nth_arg (count, key)); + else + return (rl_yank_nth_arg ('$', key)); +} diff --git a/lib/readline/macro.c b/lib/readline/macro.c new file mode 100644 index 0000000..f3c442b --- /dev/null +++ b/lib/readline/macro.c @@ -0,0 +1,277 @@ +/* macro.c -- keyboard macros for readline. */ + +/* Copyright (C) 1994 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library, a library for + reading lines of text with interactive input and history editing. + + The GNU Readline Library is free software; you can redistribute it + and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 1, or + (at your option) any later version. + + The GNU Readline Library is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + The GNU General Public License is often shipped with GNU software, and + is generally kept in a file called COPYING or LICENSE. If you do not + have a copy of the license, write to the Free Software Foundation, + 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include <config.h> +#endif + +#include <sys/types.h> + +#if defined (HAVE_UNISTD_H) +# include <unistd.h> /* for _POSIX_VERSION */ +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include <stdlib.h> +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include <stdio.h> + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#define SWAP(s, e) do { int t; t = s; s = e; e = t; } while (0) + +/* Forward definitions. */ +void _rl_push_executing_macro (), _rl_pop_executing_macro (); +void _rl_add_macro_char (); + +/* Extern declarations. */ +extern int rl_explicit_arg; +extern int rl_key_sequence_length; + +extern void _rl_abort_internal (); + +extern char *xmalloc (), *xrealloc (); + +/* **************************************************************** */ +/* */ +/* Hacking Keyboard Macros */ +/* */ +/* **************************************************************** */ + +/* Non-zero means to save keys that we dispatch on in a kbd macro. */ +int _rl_defining_kbd_macro = 0; + +/* The currently executing macro string. If this is non-zero, + then it is a malloc ()'ed string where input is coming from. */ +char *_rl_executing_macro = (char *)NULL; + +/* The offset in the above string to the next character to be read. */ +static int executing_macro_index; + +/* The current macro string being built. Characters get stuffed + in here by add_macro_char (). */ +static char *current_macro = (char *)NULL; + +/* The size of the buffer allocated to current_macro. */ +static int current_macro_size; + +/* The index at which characters are being added to current_macro. */ +static int current_macro_index; + +/* A structure used to save nested macro strings. + It is a linked list of string/index for each saved macro. */ +struct saved_macro { + struct saved_macro *next; + char *string; + int sindex; +}; + +/* The list of saved macros. */ +static struct saved_macro *macro_list = (struct saved_macro *)NULL; + +/* Set up to read subsequent input from STRING. + STRING is free ()'ed when we are done with it. */ +void +_rl_with_macro_input (string) + char *string; +{ + _rl_push_executing_macro (); + _rl_executing_macro = string; + executing_macro_index = 0; +} + +/* Return the next character available from a macro, or 0 if + there are no macro characters. */ +int +_rl_next_macro_key () +{ + if (_rl_executing_macro == 0) + return (0); + + if (_rl_executing_macro[executing_macro_index] == 0) + { + _rl_pop_executing_macro (); + return (_rl_next_macro_key ()); + } + + return (_rl_executing_macro[executing_macro_index++]); +} + +/* Save the currently executing macro on a stack of saved macros. */ +void +_rl_push_executing_macro () +{ + struct saved_macro *saver; + + saver = (struct saved_macro *)xmalloc (sizeof (struct saved_macro)); + saver->next = macro_list; + saver->sindex = executing_macro_index; + saver->string = _rl_executing_macro; + + macro_list = saver; +} + +/* Discard the current macro, replacing it with the one + on the top of the stack of saved macros. */ +void +_rl_pop_executing_macro () +{ + struct saved_macro *macro; + + if (_rl_executing_macro) + free (_rl_executing_macro); + + _rl_executing_macro = (char *)NULL; + executing_macro_index = 0; + + if (macro_list) + { + macro = macro_list; + _rl_executing_macro = macro_list->string; + executing_macro_index = macro_list->sindex; + macro_list = macro_list->next; + free (macro); + } +} + +/* Add a character to the macro being built. */ +void +_rl_add_macro_char (c) + int c; +{ + if (current_macro_index + 1 >= current_macro_size) + { + if (current_macro == 0) + current_macro = xmalloc (current_macro_size = 25); + else + current_macro = xrealloc (current_macro, current_macro_size += 25); + } + + current_macro[current_macro_index++] = c; + current_macro[current_macro_index] = '\0'; +} + +void +_rl_kill_kbd_macro () +{ + if (current_macro) + { + free (current_macro); + current_macro = (char *) NULL; + } + current_macro_size = current_macro_index = 0; + + if (_rl_executing_macro) + { + free (_rl_executing_macro); + _rl_executing_macro = (char *) NULL; + } + executing_macro_index = 0; + + _rl_defining_kbd_macro = 0; +} + +/* Begin defining a keyboard macro. + Keystrokes are recorded as they are executed. + End the definition with rl_end_kbd_macro (). + If a numeric argument was explicitly typed, then append this + definition to the end of the existing macro, and start by + re-executing the existing macro. */ +int +rl_start_kbd_macro (ignore1, ignore2) + int ignore1, ignore2; +{ + if (_rl_defining_kbd_macro) + { + _rl_abort_internal (); + return -1; + } + + if (rl_explicit_arg) + { + if (current_macro) + _rl_with_macro_input (savestring (current_macro)); + } + else + current_macro_index = 0; + + _rl_defining_kbd_macro = 1; + return 0; +} + +/* Stop defining a keyboard macro. + A numeric argument says to execute the macro right now, + that many times, counting the definition as the first time. */ +int +rl_end_kbd_macro (count, ignore) + int count, ignore; +{ + if (_rl_defining_kbd_macro == 0) + { + _rl_abort_internal (); + return -1; + } + + current_macro_index -= rl_key_sequence_length - 1; + current_macro[current_macro_index] = '\0'; + + _rl_defining_kbd_macro = 0; + + return (rl_call_last_kbd_macro (--count, 0)); +} + +/* Execute the most recently defined keyboard macro. + COUNT says how many times to execute it. */ +int +rl_call_last_kbd_macro (count, ignore) + int count, ignore; +{ + if (current_macro == 0) + _rl_abort_internal (); + + if (_rl_defining_kbd_macro) + { + ding (); /* no recursive macros */ + current_macro[--current_macro_index] = '\0'; /* erase this char */ + return 0; + } + + while (count--) + _rl_with_macro_input (savestring (current_macro)); + return 0; +} + +void +rl_push_macro_input (macro) + char *macro; +{ + _rl_with_macro_input (macro); +} diff --git a/lib/readline/memalloc.h b/lib/readline/memalloc.h deleted file mode 100644 index 750d53d..0000000 --- a/lib/readline/memalloc.h +++ /dev/null @@ -1,56 +0,0 @@ -/* memalloc.h -- consolidate code for including alloca.h or malloc.h and - defining alloca. */ - -/* Copyright (C) 1993 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2, or (at your option) any later - version. - - Bash is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with Bash; see the file COPYING. If not, write to the Free Software - Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#if !defined (__MEMALLOC_H__) -# define __MEMALLOC_H__ - -#if defined (sparc) && defined (sun) && !defined (HAVE_ALLOCA_H) -# define HAVE_ALLOCA_H -#endif - -#if defined (__GNUC__) && !defined (HAVE_ALLOCA) -# define HAVE_ALLOCA -#endif - -#if defined (HAVE_ALLOCA_H) && !defined (HAVE_ALLOCA) -# define HAVE_ALLOCA -#endif /* HAVE_ALLOCA_H && !HAVE_ALLOCA */ - -#if !defined (BUILDING_MAKEFILE) - -#if defined (__GNUC__) -# undef alloca -# define alloca __builtin_alloca -#else /* !__GNUC__ */ -# if defined (HAVE_ALLOCA_H) -# if defined (IBMESA) -# include <malloc.h> -# else /* !IBMESA */ -# include <alloca.h> -# endif /* !IBMESA */ -# else -extern char *alloca (); -# endif /* !HAVE_ALLOCA_H */ -#endif /* !__GNUC__ */ - -#endif /* !BUILDING_MAKEFILE */ - -#endif /* __MEMALLOC_H__ */ diff --git a/lib/readline/nls.c b/lib/readline/nls.c new file mode 100644 index 0000000..fad5201 --- /dev/null +++ b/lib/readline/nls.c @@ -0,0 +1,198 @@ +/* nls.c -- skeletal internationalization code. */ + +/* Copyright (C) 1996 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library, a library for + reading lines of text with interactive input and history editing. + + The GNU Readline Library is free software; you can redistribute it + and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 1, or + (at your option) any later version. + + The GNU Readline Library is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + The GNU General Public License is often shipped with GNU software, and + is generally kept in a file called COPYING or LICENSE. If you do not + have a copy of the license, write to the Free Software Foundation, + 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include <config.h> +#endif + +#if defined (HAVE_UNISTD_H) +# include <unistd.h> +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include <stdlib.h> +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_LOCALE_H) +# include <locale.h> +#endif + +#include <ctype.h> + +#include "rldefs.h" + +extern int _rl_convert_meta_chars_to_ascii; +extern int _rl_output_meta_chars; +extern int _rl_meta_flag; + +/* A list of legal values for the LANG or LC_CTYPE environment variables. + If a locale name in this list is the value for the LC_ALL, LC_CTYPE, + or LANG environment variable (using the first of those with a value), + readline eight-bit mode is enabled. */ +static char *legal_lang_values[] = +{ + "iso88591", + "iso88592", + "iso88593", + "iso88594", + "iso88595", + "iso88596", + "iso88597", + "iso88598", + "iso88599", + "iso885910", + "koi8r", + 0 +}; + +static char *normalize_codeset (); +static char *find_codeset (); + +/* Check for LC_ALL, LC_CTYPE, and LANG and use the first with a value + to decide the defaults for 8-bit character input and output. Returns + 1 if we set eight-bit mode. */ +int +_rl_init_eightbit () +{ + char *lspec, *t; + int i; + + lspec = getenv ("LC_ALL"); + if (lspec == 0) lspec = getenv ("LC_CTYPE"); + if (lspec == 0) lspec = getenv ("LANG"); + if (lspec == 0 || (t = normalize_codeset (lspec)) == 0) + return (0); + for (i = 0; t && legal_lang_values[i]; i++) + if (STREQ (t, legal_lang_values[i])) + { + _rl_meta_flag = 1; + _rl_convert_meta_chars_to_ascii = 0; + _rl_output_meta_chars = 1; +#if defined (HAVE_SETLOCALE) + setlocale (LC_CTYPE, lspec); +#endif + break; + } + free (t); + return (legal_lang_values[i] ? 1 : 0); +} + +static char * +normalize_codeset (codeset) + char *codeset; +{ + size_t namelen, i; + int len, all_digits; + char *wp, *retval; + + codeset = find_codeset (codeset, &namelen); + + if (codeset == 0) + return (codeset); + + all_digits = 1; + for (len = 0, i = 0; i < namelen; i++) + { + if (isalnum (codeset[i])) + { + len++; + all_digits &= isdigit (codeset[i]); + } + } + + retval = (char *)malloc ((all_digits ? 3 : 0) + len + 1); + if (retval == 0) + return ((char *)0); + + wp = retval; + /* Add `iso' to beginning of an all-digit codeset */ + if (all_digits) + { + *wp++ = 'i'; + *wp++ = 's'; + *wp++ = 'o'; + } + + for (i = 0; i < namelen; i++) + if (isalpha (codeset[i])) + *wp++ = (isupper (codeset[i])) ? tolower (codeset[i]) : codeset[i]; + else if (isdigit (codeset[i])) + *wp++ = codeset[i]; + *wp = '\0'; + + return retval; +} + +/* Isolate codeset portion of locale specification. */ +static char * +find_codeset (name, lenp) + char *name; + size_t *lenp; +{ + char *cp, *language, *result; + + cp = language = name; + result = (char *)0; + + while (*cp && *cp != '_' && *cp != '@' && *cp != '+' && *cp != ',') + cp++; + + /* This does not make sense: language has to be specified. As + an exception we allow the variable to contain only the codeset + name. Perhaps there are funny codeset names. */ + if (language == cp) + { + *lenp = strlen (language); + result = language; + } + else + { + /* Next is the territory. */ + if (*cp == '_') + do + ++cp; + while (*cp && *cp != '.' && *cp != '@' && *cp != '+' && *cp != ',' && *cp != '_'); + + /* Now, finally, is the codeset. */ + result = cp; + if (*cp == '.') + do + ++cp; + while (*cp && *cp != '@'); + + if (cp - result > 2) + { + result++; + *lenp = cp - result; + } + else + { + *lenp = strlen (language); + result = language; + } + } + + return result; +} diff --git a/lib/readline/parens.c b/lib/readline/parens.c index 57a9777..50683f9 100644 --- a/lib/readline/parens.c +++ b/lib/readline/parens.c @@ -1,4 +1,4 @@ -/* parens.c -- Implemenation of matching parenthesis feature. */ +/* parens.c -- Implementation of matching parentheses feature. */ /* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc. @@ -24,7 +24,9 @@ #include "rlconf.h" #if !defined (PAREN_MATCHING) +extern int rl_insert (); +int rl_insert_close (count, invoking_key) int count, invoking_key; { @@ -33,25 +35,49 @@ rl_insert_close (count, invoking_key) #else /* PAREN_MATCHING */ +#if defined (HAVE_CONFIG_H) +# include <config.h> +#endif + #include <stdio.h> #include <sys/types.h> -#if defined (FD_SET) + +#if defined (FD_SET) && !defined (HAVE_SELECT) +# define HAVE_SELECT +#endif + +#if defined (HAVE_SELECT) # include <sys/time.h> -#endif /* FD_SET */ +#endif /* HAVE_SELECT */ +#if defined (HAVE_SYS_SELECT_H) +# include <sys/select.h> +#endif + +#if defined (HAVE_STRING_H) +# include <string.h> +#else /* !HAVE_STRING_H */ +# include <strings.h> +#endif /* !HAVE_STRING_H */ + +#if !defined (strchr) && !defined (__STDC__) +extern char *strchr (), *strrchr (); +#endif /* !strchr && !__STDC__ */ + #include "readline.h" extern int rl_explicit_arg; /* Non-zero means try to blink the matching open parenthesis when the close parenthesis is inserted. */ -#if defined (FD_SET) +#if defined (HAVE_SELECT) int rl_blink_matching_paren = 1; -#else /* !FD_SET */ +#else /* !HAVE_SELECT */ int rl_blink_matching_paren = 0; -#endif /* !FD_SET */ +#endif /* !HAVE_SELECT */ static int find_matching_open (); +int rl_insert_close (count, invoking_key) int count, invoking_key; { @@ -59,13 +85,13 @@ rl_insert_close (count, invoking_key) rl_insert (count, invoking_key); else { -#if defined (FD_SET) +#if defined (HAVE_SELECT) int orig_point, match_point, ready; struct timeval timer; fd_set readfds; rl_insert (1, invoking_key); - rl_redisplay (); + (*rl_redisplay_function) (); match_point = find_matching_open (rl_line_buffer, rl_point - 2, invoking_key); @@ -80,12 +106,12 @@ rl_insert_close (count, invoking_key) orig_point = rl_point; rl_point = match_point; - rl_redisplay (); + (*rl_redisplay_function) (); ready = select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer); rl_point = orig_point; -#else /* !FD_SET */ +#else /* !HAVE_SELECT */ rl_insert (count, invoking_key); -#endif /* !FD_SET */ +#endif /* !HAVE_SELECT */ } return 0; } @@ -114,8 +140,8 @@ find_matching_open (string, from, closer) { if (delimiter && (string[i] == delimiter)) delimiter = 0; - else if ((string[i] == '\'') || (string[i] == '"')) - delimiter = rl_line_buffer[i]; + else if (rl_basic_quote_characters && strchr (rl_basic_quote_characters, string[i])) + delimiter = string[i]; else if (!delimiter && (string[i] == closer)) level++; else if (!delimiter && (string[i] == opener)) diff --git a/lib/readline/posixdir.h b/lib/readline/posixdir.h new file mode 100644 index 0000000..8b0e5bc --- /dev/null +++ b/lib/readline/posixdir.h @@ -0,0 +1,49 @@ +/* posixdir.h -- Posix directory reading includes and defines. */ + +/* Copyright (C) 1987,1991 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + Bash is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with Bash; see the file COPYING. If not, write to the Free + Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* This file should be included instead of <dirent.h> or <sys/dir.h>. */ + +#if !defined (_POSIXDIR_H_) +#define _POSIXDIR_H_ + +#if defined (HAVE_DIRENT_H) +# include <dirent.h> +# define D_NAMLEN(d) (strlen ((d)->d_name)) +#else +# if defined (HAVE_SYS_NDIR_H) +# include <sys/ndir.h> +# endif +# if defined (HAVE_SYS_DIR_H) +# include <sys/dir.h> +# endif +# if defined (HAVE_NDIR_H) +# include <ndir.h> +# endif +# if !defined (dirent) +# define dirent direct +# endif /* !dirent */ +# define D_NAMLEN(d) ((d)->d_namlen) +#endif /* !HAVE_DIRENT_H */ + +#if defined (STRUCT_DIRENT_HAS_D_INO) +# define d_fileno d_ino +#endif + +#endif /* !_POSIXDIR_H_ */ diff --git a/lib/readline/posixstat.h b/lib/readline/posixstat.h index 7d1cece..bfce8c0 100644 --- a/lib/readline/posixstat.h +++ b/lib/readline/posixstat.h @@ -21,34 +21,27 @@ /* This file should be included instead of <sys/stat.h>. It relies on the local sys/stat.h to work though. */ -#if !defined (_POSIXSTAT_H) -#define _POSIXSTAT_H +#if !defined (_POSIXSTAT_H_) +#define _POSIXSTAT_H_ #include <sys/stat.h> -#if defined (isc386) -# if !defined (S_IFDIR) -# define S_IFDIR 0040000 -# endif /* !S_IFDIR */ -# if !defined (S_IFMT) -# define S_IFMT 0170000 -# endif /* !S_IFMT */ -#endif /* isc386 */ - -/* This text is taken directly from the Cadmus I was trying to - compile on: - the following MACROs are defined for X/OPEN compatibility - however, is the param correct ?? - #define S_ISBLK(s) ((s.st_mode & S_IFMT) == S_IFBLK) - - Well, the answer is no. Thus... */ -#if defined (BrainDeath) +#if defined (STAT_MACROS_BROKEN) # undef S_ISBLK # undef S_ISCHR # undef S_ISDIR # undef S_ISFIFO # undef S_ISREG -#endif /* BrainDeath */ +# undef S_ISLNK +#endif /* STAT_MACROS_BROKEN */ + +/* These are guaranteed to work only on isc386 */ +#if !defined (S_IFDIR) && !defined (S_ISDIR) +# define S_IFDIR 0040000 +#endif /* !S_IFDIR && !S_ISDIR */ +#if !defined (S_IFMT) +# define S_IFMT 0170000 +#endif /* !S_IFMT */ /* Posix 1003.1 5.6.1.1 <sys/stat.h> file types */ @@ -114,7 +107,7 @@ /* * POSIX 1003.1 5.6.1.2 <sys/stat.h> File Modes */ - + #if !defined (S_IRWXU) # if !defined (S_IREAD) # define S_IREAD 00400 @@ -146,4 +139,4 @@ #define S_IWUGO (S_IWUSR | S_IWGRP | S_IWOTH) #define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH) -#endif /* _POSIXSTAT_H */ +#endif /* _POSIXSTAT_H_ */ diff --git a/lib/readline/readline.c b/lib/readline/readline.c index 6040cbb..d85789d 100644 --- a/lib/readline/readline.c +++ b/lib/readline/readline.c @@ -22,13 +22,16 @@ 675 Mass Ave, Cambridge, MA 02139, USA. */ #define READLINE_LIBRARY -#include <stdio.h> +#if defined (HAVE_CONFIG_H) +# include <config.h> +#endif + #include <sys/types.h> +#include "posixstat.h" #include <fcntl.h> -#if !defined (NO_SYS_FILE) +#if defined (HAVE_SYS_FILE_H) # include <sys/file.h> -#endif /* !NO_SYS_FILE */ -#include <signal.h> +#endif /* HAVE_SYS_FILE_H */ #if defined (HAVE_UNISTD_H) # include <unistd.h> @@ -40,37 +43,61 @@ # include "ansi_stdlib.h" #endif /* HAVE_STDLIB_H */ -#include <errno.h> -/* Not all systems declare ERRNO in errno.h... and some systems #define it! */ -#if !defined (errno) -extern int errno; -#endif /* !errno */ +#if defined (HAVE_LOCALE_H) +# include <locale.h> +#endif +#include <signal.h> +#include <stdio.h> #include <setjmp.h> -#include "posixstat.h" - /* System-specific feature definitions and include files. */ #include "rldefs.h" -#if defined (GWINSZ_IN_SYS_IOCTL) || (defined (VSTATUS) && !defined (SunOS4)) -# include <sys/ioctl.h> -#endif /* GWINSZ_IN_SYS_IOCTL || VSTATUS */ +#include "tcap.h" /* Some standard library routines. */ #include "readline.h" #include "history.h" +#define SWAP(s, e) do { int t; t = s; s = e; e = t; } while (0) + /* NOTE: Functions and variables prefixed with `_rl_' are pseudo-global: they are global so they can be shared between files in the readline library, but are not intended to be visible to readline callers. */ -/* Functions imported from other files in the library. */ -extern char *tgetstr (); +/* Variables and functions imported from terminal.c */ +extern int _rl_init_terminal_io (); +extern void _rl_enable_meta_key (); +extern int _rl_output_character_function (); +extern void _rl_get_screen_size (); + +extern int _rl_enable_meta; +extern int _rl_term_autowrap; +extern char *term_backspace, *term_clreol, *term_clrpag; +extern int screenwidth, screenheight, screenchars; + +/* Variables and functions imported from rltty.c. */ extern void rl_prep_terminal (), rl_deprep_terminal (); +extern void rltty_set_default_bindings (); + +/* Functions imported from util.c. */ +extern void _rl_abort_internal (); +extern void rl_extend_line_buffer (); +extern int alphabetic (); +/* Functions imported from bind.c. */ extern void _rl_bind_if_unbound (); +extern int rl_set_keymap_from_edit_mode (); + +/* Functions imported from input.c. */ +extern int _rl_any_typein (); +extern void _rl_insert_typein (); +extern int rl_read_key (); + +/* Functions imported from nls.c */ +extern int _rl_init_eightbit (); /* External redisplay functions and variables from display.c */ extern void _rl_move_vert (); @@ -83,6 +110,7 @@ extern int _rl_vis_botlin; extern int _rl_last_c_pos; extern int _rl_horizontal_scroll_mode; extern int rl_display_fixed; +extern int _rl_suppress_redisplay; extern char *rl_display_prompt; /* Variables imported from complete.c. */ @@ -91,22 +119,32 @@ extern char *rl_basic_word_break_characters; extern int rl_completion_query_items; extern int rl_complete_with_tilde_expansion; +/* Variables and functions from macro.c. */ +extern void _rl_add_macro_char (); +extern void _rl_with_macro_input (); +extern int _rl_next_macro_key (); +extern int _rl_defining_kbd_macro; + #if defined (VI_MODE) +/* Functions imported from vi_mode.c. */ extern void _rl_vi_set_last (); extern void _rl_vi_reset_last (); extern void _rl_vi_done_inserting (); +extern int _rl_vi_textmod_command (); +extern void _rl_vi_initialize_line (); #endif /* VI_MODE */ +extern UNDO_LIST *rl_undo_list; +extern int _rl_doing_an_undo; + /* Forward declarations used in this file. */ void _rl_free_history_entry (); int _rl_dispatch (); -void _rl_set_screen_size (); -int _rl_output_character_function (); +int _rl_init_argument (); static char *readline_internal (); static void readline_initialize_everything (); -static int init_terminal_io (); static void start_using_history (); static void bind_arrow_keys (); @@ -115,24 +153,19 @@ static void readline_default_bindings (); #endif /* !__GO32__ */ #if defined (__GO32__) -# include <sys/pc.h> +# include <pc.h> # undef HANDLE_SIGNALS #endif /* __GO32__ */ -#if defined (STATIC_MALLOC) -static char *xmalloc (), *xrealloc (); -#else extern char *xmalloc (), *xrealloc (); -#endif /* STATIC_MALLOC */ - /* **************************************************************** */ /* */ /* Line editing input utility */ /* */ /* **************************************************************** */ -static char *LibraryVersion = "2.0"; +char *rl_library_version = "2.1"; /* A pointer to the keymap that is currently in use. By default, it is the standard emacs keymap. */ @@ -142,7 +175,7 @@ Keymap _rl_keymap = emacs_standard_keymap; int rl_editing_mode = emacs_mode; /* Non-zero if the previous command was a kill command. */ -static int last_command_was_kill = 0; +int _rl_last_command_was_kill = 0; /* The current value of the numeric argument specified by the user. */ int rl_numeric_arg = 1; @@ -154,10 +187,10 @@ int rl_explicit_arg = 0; int rl_arg_sign = 1; /* Non-zero means we have been called at least once before. */ -static int rl_initialized = 0; +static int rl_initialized; /* If non-zero, this program is running in an EMACS buffer. */ -static int running_in_emacs = 0; +static int running_in_emacs; /* The current offset in the current input line. */ int rl_point; @@ -175,10 +208,10 @@ int rl_done; Function *rl_last_func = (Function *)NULL; /* Top level environment for readline_internal (). */ -static jmp_buf readline_top_level; +jmp_buf readline_top_level; /* The streams we interact with. */ -static FILE *in_stream, *out_stream; +FILE *_rl_in_stream, *_rl_out_stream; /* The names of the streams that we do input and output to. */ FILE *rl_instream = (FILE *)NULL; @@ -222,16 +255,18 @@ int _rl_mark_modified_lines = 0; AUDIBLE_BELL, or VISIBLE_BELL. */ int _rl_bell_preference = AUDIBLE_BELL; +/* String inserted into the line by rl_insert_comment (). */ +char *_rl_comment_begin; + +/* Keymap holding the function currently being executed. */ +Keymap rl_executing_keymap; + /* Line buffer and maintenence. */ char *rl_line_buffer = (char *)NULL; int rl_line_buffer_len = 0; -#define DEFAULT_BUFFER_SIZE 256 /* Forward declarations used by the display and termcap code. */ -int term_xn; -int screenwidth, screenheight, screenchars; - /* **************************************************************** */ /* */ /* `Forward' declarations */ @@ -242,9 +277,6 @@ int screenwidth, screenheight, screenchars; parser directives. */ unsigned char _rl_parsing_conditionalized_out = 0; -/* Non-zero means to save keys that we dispatch on in a kbd macro. */ -static int defining_kbd_macro = 0; - /* Non-zero means to convert characters with the meta bit set to escape-prefixed characters so we can indirect through emacs_meta_keymap or vi_escape_keymap. */ @@ -254,10 +286,6 @@ int _rl_convert_meta_chars_to_ascii = 1; rather than as a meta-prefixed escape sequence. */ int _rl_output_meta_chars = 0; -/* Non-zero tells rl_delete_text and rl_insert_text to not add to - the undo list. */ -static int doing_an_undo = 0; - /* **************************************************************** */ /* */ /* Top Level Functions */ @@ -267,7 +295,7 @@ static int doing_an_undo = 0; /* Non-zero means treat 0200 bit in terminal input as Meta bit. */ int _rl_meta_flag = 0; /* Forward declaration */ -/* Read a line of input. Prompt with PROMPT. A NULL PROMPT means +/* Read a line of input. Prompt with PROMPT. An empty PROMPT means none. A return value of NULL means that EOF was encountered. */ char * readline (prompt) @@ -287,14 +315,14 @@ readline (prompt) rl_visible_prompt_length = rl_expand_prompt (rl_prompt); rl_initialize (); - rl_prep_terminal (_rl_meta_flag); + (*rl_prep_term_function) (_rl_meta_flag); #if defined (HANDLE_SIGNALS) rl_set_signals (); #endif value = readline_internal (); - rl_deprep_terminal (); + (*rl_deprep_term_function) (); #if defined (HANDLE_SIGNALS) rl_clear_signals (); @@ -303,55 +331,98 @@ readline (prompt) return (value); } -/* Read a line of input from the global rl_instream, doing output on - the global rl_outstream. - If rl_prompt is non-null, then that is our prompt. */ -static char * -readline_internal () -{ - int lastc, c, eof_found; - - in_stream = rl_instream; - out_stream = rl_outstream; +#if defined (READLINE_CALLBACKS) +# define STATIC_CALLBACK +#else +# define STATIC_CALLBACK static +#endif - lastc = -1; - eof_found = 0; +STATIC_CALLBACK void +readline_internal_setup () +{ + _rl_in_stream = rl_instream; + _rl_out_stream = rl_outstream; if (rl_startup_hook) (*rl_startup_hook) (); - if (!readline_echoing_p) + if (readline_echoing_p == 0) { if (rl_prompt) { - fprintf (out_stream, "%s", rl_prompt); - fflush (out_stream); + fprintf (_rl_out_stream, "%s", rl_prompt); + fflush (_rl_out_stream); } } else { rl_on_new_line (); - rl_redisplay (); + (*rl_redisplay_function) (); #if defined (VI_MODE) if (rl_editing_mode == vi_mode) rl_vi_insertion_mode (); #endif /* VI_MODE */ } +} + +STATIC_CALLBACK char * +readline_internal_teardown (eof) + int eof; +{ + char *temp; + HIST_ENTRY *entry; + + /* Restore the original of this history line, iff the line that we + are editing was originally in the history, AND the line has changed. */ + entry = current_history (); - while (!rl_done) + if (entry && rl_undo_list) { - int lk = last_command_was_kill; - int code; + temp = savestring (the_line); + rl_revert_line (1, 0); + entry = replace_history_entry (where_history (), the_line, (HIST_ENTRY *)NULL); + _rl_free_history_entry (entry); + + strcpy (the_line, temp); + free (temp); + } + + /* At any rate, it is highly likely that this line has an undo list. Get + rid of it now. */ + if (rl_undo_list) + free_undo_list (); + + return (eof ? (char *)NULL : savestring (the_line)); +} + +STATIC_CALLBACK int +#if defined (READLINE_CALLBACKS) +readline_internal_char () +#else +readline_internal_charloop () +#endif +{ + static int lastc, eof_found; + int c, code, lk; + + lastc = -1; + eof_found = 0; + +#if !defined (READLINE_CALLBACKS) + while (rl_done == 0) + { +#endif + lk = _rl_last_command_was_kill; code = setjmp (readline_top_level); if (code) - rl_redisplay (); + (*rl_redisplay_function) (); - if (!rl_pending_input) + if (rl_pending_input == 0) { /* Then initialize the argument and number of keys read. */ - rl_init_argument (); + _rl_init_argument (); rl_key_sequence_length = 0; } @@ -365,21 +436,22 @@ readline_internal () previous character is interpreted as EOF. */ if (((c == _rl_eof_char && lastc != c) || c == EOF) && !rl_end) { +#if defined (READLINE_CALLBACKS) + return (rl_done = 1); +#else eof_found = 1; break; +#endif } lastc = c; _rl_dispatch (c, _rl_keymap); - /* If there was no change in last_command_was_kill, then no kill + /* If there was no change in _rl_last_command_was_kill, then no kill has taken place. Note that if input is pending we are reading a prefix command, so nothing has changed yet. */ - if (!rl_pending_input) - { - if (lk == last_command_was_kill) - last_command_was_kill = 0; - } + if (rl_pending_input == 0 && lk == _rl_last_command_was_kill) + _rl_last_command_was_kill = 0; #if defined (VI_MODE) /* In vi mode, when you exit insert mode, the cursor moves back @@ -388,232 +460,49 @@ readline_internal () rl_vi_check (); #endif /* VI_MODE */ - if (!rl_done) - rl_redisplay (); - } - - /* Restore the original of this history line, iff the line that we - are editing was originally in the history, AND the line has changed. */ - { - HIST_ENTRY *entry = current_history (); - - if (entry && rl_undo_list) - { - char *temp = savestring (the_line); - rl_revert_line (); - entry = replace_history_entry (where_history (), the_line, - (HIST_ENTRY *)NULL); - _rl_free_history_entry (entry); - - strcpy (the_line, temp); - free (temp); - } - } + if (rl_done == 0) + (*rl_redisplay_function) (); - /* At any rate, it is highly likely that this line has an undo list. Get - rid of it now. */ - if (rl_undo_list) - free_undo_list (); - - if (eof_found) - return (char *)NULL; - else - return (savestring (the_line)); -} - -/* **************************************************************** */ -/* */ -/* Character Input Buffering */ -/* */ -/* **************************************************************** */ - -static int pop_index = 0, push_index = 0, ibuffer_len = 511; -static unsigned char ibuffer[512]; - -/* Non-null means it is a pointer to a function to run while waiting for - character input. */ -Function *rl_event_hook = (Function *)NULL; - -#define any_typein (push_index != pop_index) - -/* Add KEY to the buffer of characters to be read. */ -rl_stuff_char (key) - int key; -{ - if (key == EOF) - { - key = NEWLINE; - rl_pending_input = EOF; +#if defined (READLINE_CALLBACKS) + return 0; +#else } - ibuffer[push_index++] = key; - if (push_index >= ibuffer_len) - push_index = 0; - return push_index; -} -/* Return the amount of space available in the - buffer for stuffing characters. */ -int -ibuffer_space () -{ - if (pop_index > push_index) - return (pop_index - push_index); - else - return (ibuffer_len - (push_index - pop_index)); + return (eof_found); +#endif } -/* Get a key from the buffer of characters to be read. - Return the key in KEY. - Result is KEY if there was a key, or 0 if there wasn't. */ -int -rl_get_char (key) - int *key; +#if defined (READLINE_CALLBACKS) +static int +readline_internal_charloop () { - if (push_index == pop_index) - return (0); + int eof; - *key = ibuffer[pop_index++]; - - if (pop_index >= ibuffer_len) - pop_index = 0; - - return (1); -} - -/* Stuff KEY into the *front* of the input buffer. - Returns non-zero if successful, zero if there is - no space left in the buffer. */ -int -rl_unget_char (key) - int key; -{ - if (ibuffer_space ()) - { - pop_index--; - if (pop_index < 0) - pop_index = ibuffer_len - 1; - ibuffer[pop_index] = key; - return (1); - } - return (0); + while (rl_done == 0) + eof = readline_internal_char (); + return (eof); } +#endif /* READLINE_CALLBACKS */ -/* If a character is available to be read, then read it - and stuff it into IBUFFER. Otherwise, just return. */ -void -rl_gather_tyi () +/* Read a line of input from the global rl_instream, doing output on + the global rl_outstream. + If rl_prompt is non-null, then that is our prompt. */ +static char * +readline_internal () { -#if defined (__GO32__) - char input; - - if (isatty (0)) - { - int i = rl_getc (); - - if (i != EOF) - rl_stuff_char (i); - } - else if (kbhit () && ibuffer_space ()) - rl_stuff_char (getkey ()); -#else /* !__GO32__ */ - - int tty = fileno (in_stream); - register int tem, result = -1; - int chars_avail; - char input; + int eof; -#if defined (FIONREAD) - result = ioctl (tty, FIONREAD, &chars_avail); -#endif - -#if defined (O_NDELAY) - if (result == -1) - { - int flags; - - flags = fcntl (tty, F_GETFL, 0); - - fcntl (tty, F_SETFL, (flags | O_NDELAY)); - chars_avail = read (tty, &input, 1); - - fcntl (tty, F_SETFL, flags); - if (chars_avail == -1 && errno == EAGAIN) - return; - } -#endif /* O_NDELAY */ - - /* If there's nothing available, don't waste time trying to read - something. */ - if (chars_avail == 0) - return; - - tem = ibuffer_space (); - - if (chars_avail > tem) - chars_avail = tem; - - /* One cannot read all of the available input. I can only read a single - character at a time, or else programs which require input can be - thwarted. If the buffer is larger than one character, I lose. - Damn! */ - if (tem < ibuffer_len) - chars_avail = 0; - - if (result != -1) - { - while (chars_avail--) - rl_stuff_char (rl_getc (in_stream)); - } - else - { - if (chars_avail) - rl_stuff_char (input); - } -#endif /* !__GO32__ */ + readline_internal_setup (); + eof = readline_internal_charloop (); + return (readline_internal_teardown (eof)); } -static int next_macro_key (); -/* Read a key, including pending input. */ -int -rl_read_key () +void +_rl_set_the_line () { - int c; - - rl_key_sequence_length++; - - if (rl_pending_input) - { - c = rl_pending_input; - rl_pending_input = 0; - } - else - { - /* If input is coming from a macro, then use that. */ - if (c = next_macro_key ()) - return (c); - - /* If the user has an event function, then call it periodically. */ - if (rl_event_hook) - { - while (rl_event_hook && !rl_get_char (&c)) - { - (*rl_event_hook) (); - rl_gather_tyi (); - } - } - else - { - if (!rl_get_char (&c)) - c = rl_getc (in_stream); - } - } - - return (c); + the_line = rl_line_buffer; } -/* Found later in this file. */ -static void add_macro_char (), with_macro_input (); - /* Do the command associated with KEY in MAP. If the associated command is really a keymap, then read another key, and dispatch into that map. */ @@ -622,14 +511,16 @@ _rl_dispatch (key, map) register int key; Keymap map; { - int r = 0; + int r, newkey; + char *macro; + Function *func; if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii) { if (map[ESC].type == ISKMAP) { - if (defining_kbd_macro) - add_macro_char (ESC); + if (_rl_defining_kbd_macro) + _rl_add_macro_char (ESC); map = FUNCTION_TO_KEYMAP (map, ESC); key = UNMETA (key); rl_key_sequence_length += 2; @@ -640,49 +531,51 @@ _rl_dispatch (key, map) return 0; } - if (defining_kbd_macro) - add_macro_char (key); + if (_rl_defining_kbd_macro) + _rl_add_macro_char (key); + r = 0; switch (map[key].type) { case ISFUNC: - { - Function *func = map[key].function; - - if (func != (Function *)NULL) - { - /* Special case rl_do_lowercase_version (). */ - if (func == rl_do_lowercase_version) - return (_rl_dispatch (to_lower (key), map)); - - r = (*map[key].function)(rl_numeric_arg * rl_arg_sign, key); - - /* If we have input pending, then the last command was a prefix - command. Don't change the state of rl_last_func. Otherwise, - remember the last command executed in this variable. */ - if (!rl_pending_input) - rl_last_func = map[key].function; - } - else - { - rl_abort (); - return -1; - } - } + func = map[key].function; + if (func != (Function *)NULL) + { + /* Special case rl_do_lowercase_version (). */ + if (func == rl_do_lowercase_version) + return (_rl_dispatch (_rl_to_lower (key), map)); + + rl_executing_keymap = map; + +#if 0 + _rl_suppress_redisplay = (map[key].function == rl_insert) && _rl_input_available (); +#endif + + r = (*map[key].function)(rl_numeric_arg * rl_arg_sign, key); + + /* If we have input pending, then the last command was a prefix + command. Don't change the state of rl_last_func. Otherwise, + remember the last command executed in this variable. */ + if (!rl_pending_input) + rl_last_func = map[key].function; + } + else + { + _rl_abort_internal (); + return -1; + } break; case ISKMAP: if (map[key].function != (Function *)NULL) { - int newkey; - rl_key_sequence_length++; newkey = rl_read_key (); r = _rl_dispatch (newkey, FUNCTION_TO_KEYMAP (map, key)); } else { - rl_abort (); + _rl_abort_internal (); return -1; } break; @@ -690,230 +583,20 @@ _rl_dispatch (key, map) case ISMACR: if (map[key].function != (Function *)NULL) { - char *macro; - macro = savestring ((char *)map[key].function); - with_macro_input (macro); + _rl_with_macro_input (macro); return 0; } break; } #if defined (VI_MODE) if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap && - rl_vi_textmod_command (key)) + _rl_vi_textmod_command (key)) _rl_vi_set_last (key, rl_numeric_arg, rl_arg_sign); #endif return (r); } - -/* **************************************************************** */ -/* */ -/* Hacking Keyboard Macros */ -/* */ -/* **************************************************************** */ - -/* The currently executing macro string. If this is non-zero, - then it is a malloc ()'ed string where input is coming from. */ -static char *executing_macro = (char *)NULL; - -/* The offset in the above string to the next character to be read. */ -static int executing_macro_index = 0; - -/* The current macro string being built. Characters get stuffed - in here by add_macro_char (). */ -static char *current_macro = (char *)NULL; - -/* The size of the buffer allocated to current_macro. */ -static int current_macro_size = 0; - -/* The index at which characters are being added to current_macro. */ -static int current_macro_index = 0; - -/* A structure used to save nested macro strings. - It is a linked list of string/index for each saved macro. */ -struct saved_macro { - struct saved_macro *next; - char *string; - int sindex; -}; - -/* The list of saved macros. */ -struct saved_macro *macro_list = (struct saved_macro *)NULL; - -/* Forward declarations of static functions. Thank you C. */ -static void push_executing_macro (), pop_executing_macro (); - -/* This one has to be declared earlier in the file. */ -/* static void add_macro_char (); */ - -/* Set up to read subsequent input from STRING. - STRING is free ()'ed when we are done with it. */ -static void -with_macro_input (string) - char *string; -{ - push_executing_macro (); - executing_macro = string; - executing_macro_index = 0; -} - -/* Return the next character available from a macro, or 0 if - there are no macro characters. */ -static int -next_macro_key () -{ - if (!executing_macro) - return (0); - - if (!executing_macro[executing_macro_index]) - { - pop_executing_macro (); - return (next_macro_key ()); - } - - return (executing_macro[executing_macro_index++]); -} - -/* Save the currently executing macro on a stack of saved macros. */ -static void -push_executing_macro () -{ - struct saved_macro *saver; - - saver = (struct saved_macro *)xmalloc (sizeof (struct saved_macro)); - saver->next = macro_list; - saver->sindex = executing_macro_index; - saver->string = executing_macro; - - macro_list = saver; -} - -/* Discard the current macro, replacing it with the one - on the top of the stack of saved macros. */ -static void -pop_executing_macro () -{ - if (executing_macro) - free (executing_macro); - - executing_macro = (char *)NULL; - executing_macro_index = 0; - - if (macro_list) - { - struct saved_macro *disposer = macro_list; - executing_macro = macro_list->string; - executing_macro_index = macro_list->sindex; - macro_list = macro_list->next; - free (disposer); - } -} - -/* Add a character to the macro being built. */ -static void -add_macro_char (c) - int c; -{ - if (current_macro_index + 1 >= current_macro_size) - { - if (!current_macro) - current_macro = xmalloc (current_macro_size = 25); - else - current_macro = xrealloc (current_macro, current_macro_size += 25); - } - - current_macro[current_macro_index++] = c; - current_macro[current_macro_index] = '\0'; -} - -/* Begin defining a keyboard macro. - Keystrokes are recorded as they are executed. - End the definition with rl_end_kbd_macro (). - If a numeric argument was explicitly typed, then append this - definition to the end of the existing macro, and start by - re-executing the existing macro. */ -rl_start_kbd_macro (ignore1, ignore2) - int ignore1, ignore2; -{ - if (defining_kbd_macro) - { - rl_abort (); - return -1; - } - - if (rl_explicit_arg) - { - if (current_macro) - with_macro_input (savestring (current_macro)); - } - else - current_macro_index = 0; - - defining_kbd_macro = 1; - return 0; -} - -/* Stop defining a keyboard macro. - A numeric argument says to execute the macro right now, - that many times, counting the definition as the first time. */ -rl_end_kbd_macro (count, ignore) - int count, ignore; -{ - if (!defining_kbd_macro) - { - rl_abort (); - return -1; - } - - current_macro_index -= (rl_key_sequence_length - 1); - current_macro[current_macro_index] = '\0'; - - defining_kbd_macro = 0; - - return (rl_call_last_kbd_macro (--count, 0)); -} - -/* Execute the most recently defined keyboard macro. - COUNT says how many times to execute it. */ -rl_call_last_kbd_macro (count, ignore) - int count, ignore; -{ - if (!current_macro) - rl_abort (); - - if (defining_kbd_macro) - { - ding (); /* no recursive macros */ - current_macro[--current_macro_index] = '\0'; /* erase this char */ - return 0; - } - - while (count--) - with_macro_input (savestring (current_macro)); - return 0; -} - -void -_rl_kill_kbd_macro () -{ - if (current_macro) - { - free (current_macro); - current_macro = (char *) NULL; - } - current_macro_size = current_macro_index = 0; - - if (executing_macro) - { - free (executing_macro); - executing_macro = (char *) NULL; - } - executing_macro_index = 0; - - defining_kbd_macro = 0; -} - /* **************************************************************** */ /* */ /* Initializations */ @@ -921,6 +604,7 @@ _rl_kill_kbd_macro () /* **************************************************************** */ /* Initliaze readline (and terminal if not already). */ +int rl_initialize () { /* If we have never been called before, initialize the @@ -951,6 +635,11 @@ rl_initialize () /* Parsing of key-bindings begins in an enabled state. */ _rl_parsing_conditionalized_out = 0; +#if defined (VI_MODE) + if (rl_editing_mode == vi_mode) + _rl_vi_initialize_line (); +#endif + return 0; } @@ -958,8 +647,6 @@ rl_initialize () static void readline_initialize_everything () { - char *t; - /* Find out if we are running in Emacs. */ running_in_emacs = getenv ("EMACS") != (char *)0; @@ -970,17 +657,18 @@ readline_initialize_everything () if (!rl_outstream) rl_outstream = stdout; - /* Bind in_stream and out_stream immediately. These values may change, - but they may also be used before readline_internal () is called. */ - in_stream = rl_instream; - out_stream = rl_outstream; + /* Bind _rl_in_stream and _rl_out_stream immediately. These values + may change, but they may also be used before readline_internal () + is called. */ + _rl_in_stream = rl_instream; + _rl_out_stream = rl_outstream; /* Allocate data structures. */ if (!rl_line_buffer) rl_line_buffer = xmalloc (rl_line_buffer_len = DEFAULT_BUFFER_SIZE); /* Initialize the terminal interface. */ - init_terminal_io ((char *)NULL); + _rl_init_terminal_io ((char *)NULL); #if !defined (__GO32__) /* Bind tty characters to readline functions. */ @@ -990,22 +678,14 @@ readline_initialize_everything () /* Initialize the function names. */ rl_initialize_funmap (); - /* Check for LC_CTYPE and use its value to decide the defaults for - 8-bit character input and output. */ - t = getenv ("LC_CTYPE"); - if (t && (strcmp (t, "iso-8859-1") == 0 || strcmp (t, "iso_8859_1") == 0 || - strcmp (t, "ISO-8859-1") == 0)) - { - _rl_meta_flag = 1; - _rl_convert_meta_chars_to_ascii = 0; - _rl_output_meta_chars = 1; - } + /* Decide whether we should automatically go into eight-bit mode. */ + _rl_init_eightbit (); /* Read in the init file. */ rl_read_init_file ((char *)NULL); /* XXX */ - if (_rl_horizontal_scroll_mode && term_xn) + if (_rl_horizontal_scroll_mode && _rl_term_autowrap) { screenwidth--; screenchars -= screenheight; @@ -1018,6 +698,10 @@ readline_initialize_everything () /* Try to bind a common arrow key prefix, if not already bound. */ bind_arrow_keys (); + /* Enable the meta key, if this terminal has one. */ + if (_rl_enable_meta) + _rl_enable_meta_key (); + /* If the completion parser's default word break characters haven't been set yet, then do so now. */ if (rl_completer_word_break_characters == (char *)NULL) @@ -1089,8 +773,11 @@ bind_arrow_keys () static int rl_digit_loop () { - int key, c; + int key, c, sawminus; + _rl_save_prompt (); + + sawminus = 0; while (1) { rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg); @@ -1103,32 +790,35 @@ rl_digit_loop () continue; } c = UNMETA (c); - if (digit_p (c)) + if (_rl_digit_p (c)) { - if (rl_explicit_arg) - rl_numeric_arg = (rl_numeric_arg * 10) + (c - '0'); - else - rl_numeric_arg = (c - '0'); + rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) + c - '0' : c - '0'; rl_explicit_arg = 1; } else { - if (c == '-' && !rl_explicit_arg) + if (c == '-' && rl_explicit_arg == 0) { - rl_numeric_arg = 1; + rl_numeric_arg = sawminus = 1; rl_arg_sign = -1; } else { + /* Make M-- command equivalent to M--1 command. */ + if (sawminus && rl_numeric_arg == 1 && rl_explicit_arg == 0) + rl_explicit_arg = 1; + _rl_restore_prompt (); rl_clear_message (); return (_rl_dispatch (key, _rl_keymap)); } } } + return 0; } /* Add the current digit to the argument in progress. */ +int rl_digit_argument (ignore, key) int ignore, key; { @@ -1137,16 +827,18 @@ rl_digit_argument (ignore, key) } /* What to do when you abort reading an argument. */ +int rl_discard_argument () { ding (); rl_clear_message (); - rl_init_argument (); + _rl_init_argument (); return 0; } /* Create a default argument. */ -rl_init_argument () +int +_rl_init_argument () { rl_numeric_arg = rl_arg_sign = 1; rl_explicit_arg = 0; @@ -1156,507 +848,14 @@ rl_init_argument () /* C-u, universal argument. Multiply the current argument by 4. Read a key. If the key has nothing to do with arguments, then dispatch on it. If the key is the abort character then abort. */ -rl_universal_argument () -{ - rl_numeric_arg *= 4; - return (rl_digit_loop ()); -} - -/* **************************************************************** */ -/* */ -/* Terminal and Termcap */ -/* */ -/* **************************************************************** */ - -static char *term_buffer = (char *)NULL; -static char *term_string_buffer = (char *)NULL; - -static int tcap_initialized = 0; - -/* Non-zero means this terminal can't really do anything. */ -int dumb_term = 0; -/* On Solaris2, sys/types.h #includes sys/reg.h, which #defines PC. - Unfortunately, PC is a global variable used by the termcap library. */ -#undef PC - -#if !defined (__linux__) -/* If this causes problems, add back the `extern'. */ -/*extern*/ char PC, *BC, *UP; -#endif /* __linux__ */ - -/* Some strings to control terminal actions. These are output by tputs (). */ -char *term_goto, *term_clreol, *term_cr, *term_clrpag, *term_backspace; -char *term_pc; - -/* Non-zero if we determine that the terminal can do character insertion. */ -int terminal_can_insert = 0; - -/* How to insert characters. */ -char *term_im, *term_ei, *term_ic, *term_ip, *term_IC; - -/* How to delete characters. */ -char *term_dc, *term_DC; - -#if defined (HACK_TERMCAP_MOTION) -char *term_forward_char; -#endif /* HACK_TERMCAP_MOTION */ - -/* How to go up a line. */ -char *term_up; - -/* A visible bell, if the terminal can be made to flash the screen. */ -char *visible_bell; - -/* Non-zero means that this terminal has a meta key. */ -int term_has_meta; - -/* The string to write to turn on the meta key, if this term has one. */ -char *term_mm; - -/* The string to write to turn off the meta key, if this term has one. */ -char *term_mo; - -/* The key sequences output by the arrow keys, if this terminal has any. */ -char *term_ku, *term_kd, *term_kr, *term_kl; - -/* How to initialize and reset the arrow keys, if this terminal has any. */ -char *term_ks, *term_ke; - -/* Re-initialize the terminal considering that the TERM/TERMCAP variable - has changed. */ -rl_reset_terminal (terminal_name) - char *terminal_name; -{ - init_terminal_io (terminal_name); - return 0; -} - -/* Set readline's idea of the screen size. TTY is a file descriptor open - to the terminal. If IGNORE_ENV is true, we do not pay attention to the - values of $LINES and $COLUMNS. The tests for TERM_STRING_BUFFER being - non-null serve to check whether or not we have initialized termcap. */ -void -_rl_set_screen_size (tty, ignore_env) - int tty, ignore_env; -{ -#if defined (TIOCGWINSZ) - struct winsize window_size; -#endif /* TIOCGWINSZ */ - -#if defined (TIOCGWINSZ) - if (ioctl (tty, TIOCGWINSZ, &window_size) == 0) - { - screenwidth = (int) window_size.ws_col; - screenheight = (int) window_size.ws_row; - } -#endif /* TIOCGWINSZ */ - - /* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV - is unset. */ - if (screenwidth <= 0) - { - char *sw; - - if (!ignore_env && (sw = getenv ("COLUMNS"))) - screenwidth = atoi (sw); - - if (screenwidth <= 0 && term_string_buffer) - screenwidth = tgetnum ("co"); - } - - /* Environment variable LINES overrides setting of "li" if IGNORE_ENV - is unset. */ - if (screenheight <= 0) - { - char *sh; - - if (!ignore_env && (sh = getenv ("LINES"))) - screenheight = atoi (sh); - - if (screenheight <= 0 && term_string_buffer) - screenheight = tgetnum ("li"); - } - - /* If all else fails, default to 80x24 terminal. */ - if (screenwidth <= 1) - screenwidth = 80; - - if (screenheight <= 0) - screenheight = 24; - -#if defined (SHELL) - /* If we're being compiled as part of bash, set the environment - variables $LINES and $COLUMNS to new values. */ - set_lines_and_columns (screenheight, screenwidth); -#endif - - if (!term_xn) - screenwidth--; - - screenchars = screenwidth * screenheight; -} - -struct _tc_string { - char *tc_var; - char **tc_value; -}; - -/* This should be kept sorted, just in case we decide to change the - search algorithm to something smarter. */ -static struct _tc_string tc_strings[] = -{ - "DC", &term_DC, - "IC", &term_IC, - "ce", &term_clreol, - "cl", &term_clrpag, - "cr", &term_cr, - "dc", &term_dc, - "ei", &term_ei, - "ic", &term_ic, - "im", &term_im, - "kd", &term_kd, - "kl", &term_kl, - "kr", &term_kr, - "ku", &term_ku, - "ks", &term_ks, - "ke", &term_ke, - "le", &term_backspace, - "mm", &term_mm, - "mo", &term_mo, -#if defined (HACK_TERMCAP_MOTION) - "nd", &term_forward_char, -#endif - "pc", &term_pc, - "up", &term_up, - "vb", &visible_bell, -}; - -#define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string)) - -/* Read the desired terminal capability strings into BP. The capabilities - are described in the TC_STRINGS table. */ -static void -get_term_capabilities (bp) - char **bp; -{ - register int i; - - for (i = 0; i < NUM_TC_STRINGS; i++) - *(tc_strings[i].tc_value) = tgetstr (tc_strings[i].tc_var, bp); - tcap_initialized = 1; -} - -static int -init_terminal_io (terminal_name) - char *terminal_name; -{ -#if defined (__GO32__) - screenwidth = ScreenCols (); - screenheight = ScreenRows (); - screenchars = screenwidth * screenheight; - term_cr = "\r"; - term_im = term_ei = term_ic = term_IC = (char *)NULL; - term_up = term_dc = term_DC = visible_bell = (char *)NULL; - - /* Does the __GO32__ have a meta key? I don't know. */ - term_has_meta = 0; - term_mm = term_mo = (char *)NULL; - - /* It probably has arrow keys, but I don't know what they are. */ - term_ku = term_kd = term_kr = term_kl = (char *)NULL; - -#if defined (HACK_TERMCAP_MOTION) - term_forward_char = (char *)NULL; -#endif /* HACK_TERMCAP_MOTION */ - terminal_can_insert = term_xn = 0; - return; -#else /* !__GO32__ */ - - char *term, *buffer; - int tty; - Keymap xkeymap; - - term = terminal_name ? terminal_name : getenv ("TERM"); - - if (!term_string_buffer) - term_string_buffer = xmalloc (2048); - - if (!term_buffer) - term_buffer = xmalloc (2048); - - buffer = term_string_buffer; - - term_clrpag = term_cr = term_clreol = (char *)NULL; - - if (!term) - term = "dumb"; - - if (tgetent (term_buffer, term) <= 0) - { - dumb_term = 1; - screenwidth = 79; - screenheight = 24; - screenchars = 79 * 24; - term_cr = "\r"; - term_im = term_ei = term_ic = term_IC = (char *)NULL; - term_up = term_dc = term_DC = visible_bell = (char *)NULL; - term_ku = term_kd = term_kl = term_kr = (char *)NULL; -#if defined (HACK_TERMCAP_MOTION) - term_forward_char = (char *)NULL; -#endif - terminal_can_insert = 0; - return 0; - } - - get_term_capabilities (&buffer); - - /* Set up the variables that the termcap library expects the application - to provide. */ - PC = term_pc ? *term_pc : 0; - BC = term_backspace; - UP = term_up; - - if (!term_cr) - term_cr = "\r"; - - if (rl_instream) - tty = fileno (rl_instream); - else - tty = 0; - - screenwidth = screenheight = 0; - - term_xn = tgetflag ("am") && tgetflag ("xn"); - - _rl_set_screen_size (tty, 0); - - /* "An application program can assume that the terminal can do - character insertion if *any one of* the capabilities `IC', - `im', `ic' or `ip' is provided." But we can't do anything if - only `ip' is provided, so... */ - terminal_can_insert = (term_IC || term_im || term_ic); - - /* Check to see if this terminal has a meta key and clear the capability - variables if there is none. */ - term_has_meta = (tgetflag ("km") || tgetflag ("MT")); - if (!term_has_meta) - { - term_mm = (char *)NULL; - term_mo = (char *)NULL; - } - - /* Attempt to find and bind the arrow keys. Do not override already - bound keys in an overzealous attempt, however. */ - xkeymap = _rl_keymap; - - _rl_keymap = emacs_standard_keymap; - _rl_bind_if_unbound (term_ku, rl_get_previous_history); - _rl_bind_if_unbound (term_kd, rl_get_next_history); - _rl_bind_if_unbound (term_kr, rl_forward); - _rl_bind_if_unbound (term_kl, rl_backward); - -#if defined (VI_MODE) - _rl_keymap = vi_movement_keymap; - _rl_bind_if_unbound (term_ku, rl_get_previous_history); - _rl_bind_if_unbound (term_kd, rl_get_next_history); - _rl_bind_if_unbound (term_kr, rl_forward); - _rl_bind_if_unbound (term_kl, rl_backward); -#endif /* VI_MODE */ - - _rl_keymap = xkeymap; - -#endif /* !__GO32__ */ - return 0; -} - -char * -rl_get_termcap (cap) - char *cap; -{ - register int i; - - if (tcap_initialized == 0) - return ((char *)NULL); - for (i = 0; i < NUM_TC_STRINGS; i++) - { - if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0) - return *(tc_strings[i].tc_value); - } - return ((char *)NULL); -} - -/* A function for the use of tputs () */ -int -_rl_output_character_function (c) - int c; -{ - return putc (c, out_stream); -} - -/* Write COUNT characters from STRING to the output stream. */ -void -_rl_output_some_chars (string, count) - char *string; - int count; -{ - fwrite (string, 1, count, out_stream); -} - -/* Move the cursor back. */ -backspace (count) - int count; -{ - register int i; - -#if !defined (__GO32__) - if (term_backspace) - for (i = 0; i < count; i++) - tputs (term_backspace, 1, _rl_output_character_function); - else -#endif /* !__GO32__ */ - for (i = 0; i < count; i++) - putc ('\b', out_stream); - return 0; -} - -/* Move to the start of the next line. */ -crlf () -{ -#if defined (NEW_TTY_DRIVER) - tputs (term_cr, 1, _rl_output_character_function); -#endif /* NEW_TTY_DRIVER */ - putc ('\n', out_stream); - return 0; -} - -rl_tty_status (count, key) - int count, key; -{ -#if defined (TIOCSTAT) - ioctl (1, TIOCSTAT, (char *)0); - rl_refresh_line (); -#else - ding (); -#endif - return 0; -} - - -/* **************************************************************** */ -/* */ -/* Utility Functions */ -/* */ -/* **************************************************************** */ - -/* Return 0 if C is not a member of the class of characters that belong - in words, or 1 if it is. */ - -int allow_pathname_alphabetic_chars = 0; -char *pathname_alphabetic_chars = "/-_=~.#$"; - int -alphabetic (c) - int c; -{ - if (pure_alphabetic (c) || (digit_p (c))) - return (1); - - if (allow_pathname_alphabetic_chars) - return (strchr (pathname_alphabetic_chars, c) != NULL); - else - return (0); -} - -/* Ring the terminal bell. */ -int -ding () -{ - if (readline_echoing_p) - { -#if !defined (__GO32__) - switch (_rl_bell_preference) - { - case NO_BELL: - default: - break; - case VISIBLE_BELL: - if (visible_bell) - { - tputs (visible_bell, 1, _rl_output_character_function); - break; - } - /* FALLTHROUGH */ - case AUDIBLE_BELL: - fprintf (stderr, "\007"); - fflush (stderr); - break; - } -#else /* __GO32__ */ - fprintf (stderr, "\007"); - fflush (stderr); -#endif /* __GO32__ */ - return (0); - } - return (-1); -} - -/* How to abort things. */ -rl_abort (count, key) +rl_universal_argument (count, key) int count, key; { - ding (); - rl_clear_message (); - rl_init_argument (); - rl_pending_input = 0; - - defining_kbd_macro = 0; - while (executing_macro) - pop_executing_macro (); - - rl_last_func = (Function *)NULL; - longjmp (readline_top_level, 1); -} - -/* Return a copy of the string between FROM and TO. - FROM is inclusive, TO is not. */ -char * -rl_copy_text (from, to) - int from, to; -{ - register int length; - char *copy; - - /* Fix it if the caller is confused. */ - if (from > to) - { - int t = from; - from = to; - to = t; - } - - length = to - from; - copy = xmalloc (1 + length); - strncpy (copy, the_line + from, length); - copy[length] = '\0'; - return (copy); -} - -/* Increase the size of RL_LINE_BUFFER until it has enough space to hold - LEN characters. */ -void -rl_extend_line_buffer (len) - int len; -{ - while (len >= rl_line_buffer_len) - { - rl_line_buffer_len += DEFAULT_BUFFER_SIZE; - rl_line_buffer = xrealloc (rl_line_buffer, rl_line_buffer_len); - } - - the_line = rl_line_buffer; + rl_numeric_arg *= 4; + return (rl_digit_loop ()); } - /* **************************************************************** */ /* */ /* Insert and Delete */ @@ -1666,6 +865,7 @@ rl_extend_line_buffer (len) /* Insert a string of text into the line at point. This is the only way that you should do insertion. rl_insert () calls this function. */ +int rl_insert_text (string) char *string; { @@ -1679,7 +879,7 @@ rl_insert_text (string) strncpy (the_line + rl_point, string, l); /* Remember how to undo this if we aren't undoing something. */ - if (!doing_an_undo) + if (!_rl_doing_an_undo) { /* If possible and desirable, concatenate the undos. */ if ((l == 1) && @@ -1699,6 +899,7 @@ rl_insert_text (string) /* Delete the string between FROM and TO. FROM is inclusive, TO is not. */ +int rl_delete_text (from, to) int from, to; { @@ -1707,14 +908,15 @@ rl_delete_text (from, to) /* Fix it if the caller is confused. */ if (from > to) - { - int t = from; - from = to; - to = t; - } + SWAP (from, to); + /* fix boundaries */ if (to > rl_end) - to = rl_end; + { + to = rl_end; + if (from > to) + from = to; + } text = rl_copy_text (from, to); @@ -1724,7 +926,7 @@ rl_delete_text (from, to) the_line[i] = the_line[i + diff]; /* Remember how to undo this delete. */ - if (!doing_an_undo) + if (_rl_doing_an_undo == 0) rl_add_undo (UNDO_DELETE, from, to, text); else free (text); @@ -1734,7 +936,6 @@ rl_delete_text (from, to) return (diff); } - /* **************************************************************** */ /* */ /* Readline character functions */ @@ -1757,7 +958,6 @@ rl_delete_text (from, to) The second is the key which invoked this command. */ - /* **************************************************************** */ /* */ /* Movement Commands */ @@ -1770,11 +970,12 @@ rl_delete_text (from, to) might as well let rl_redisplay do that job. */ /* Move forward COUNT characters. */ +int rl_forward (count, key) int count, key; { if (count < 0) - rl_backward (-count); + rl_backward (-count, key); else if (count > 0) { int end = rl_point + count; @@ -1796,11 +997,12 @@ rl_forward (count, key) } /* Move backward COUNT characters. */ +int rl_backward (count, key) int count, key; { if (count < 0) - rl_forward (-count); + rl_forward (-count, key); else if (count > 0) { if (rl_point < count) @@ -1815,6 +1017,7 @@ rl_backward (count, key) } /* Move to the beginning of the line. */ +int rl_beg_of_line (count, key) int count, key; { @@ -1823,6 +1026,7 @@ rl_beg_of_line (count, key) } /* Move to the end of the line. */ +int rl_end_of_line (count, key) int count, key; { @@ -1831,6 +1035,7 @@ rl_end_of_line (count, key) } /* Move forward a word. We do what Emacs does. */ +int rl_forward_word (count, key) int count, key; { @@ -1838,7 +1043,7 @@ rl_forward_word (count, key) if (count < 0) { - rl_backward_word (-count); + rl_backward_word (-count, key); return 0; } @@ -1850,7 +1055,7 @@ rl_forward_word (count, key) /* If we are not in a word, move forward until we are in one. Then, move forward until we hit a non-alphabetic character. */ c = the_line[rl_point]; - if (!alphabetic (c)) + if (alphabetic (c) == 0) { while (++rl_point < rl_end) { @@ -1864,7 +1069,7 @@ rl_forward_word (count, key) while (++rl_point < rl_end) { c = the_line[rl_point]; - if (!alphabetic (c)) + if (alphabetic (c) == 0) break; } --count; @@ -1873,6 +1078,7 @@ rl_forward_word (count, key) } /* Move backward a word. We do what Emacs does. */ +int rl_backward_word (count, key) int count, key; { @@ -1880,7 +1086,7 @@ rl_backward_word (count, key) if (count < 0) { - rl_forward_word (-count); + rl_forward_word (-count, key); return 0; } @@ -1893,7 +1099,7 @@ rl_backward_word (count, key) just before point. */ c = the_line[rl_point - 1]; - if (!alphabetic (c)) + if (alphabetic (c) == 0) { while (--rl_point) { @@ -1906,7 +1112,7 @@ rl_backward_word (count, key) while (rl_point) { c = the_line[rl_point - 1]; - if (!alphabetic (c)) + if (alphabetic (c) == 0) break; else --rl_point; @@ -1917,6 +1123,7 @@ rl_backward_word (count, key) } /* Clear the current line. Numeric argument to C-l does this. */ +int rl_refresh_line () { int curr_line, nleft; @@ -1959,6 +1166,7 @@ rl_refresh_line () /* C-l typed to a line without quoting clears the screen, and then reprints the prompt and the current input line. Given a numeric arg, redraw only the current line. */ +int rl_clear_screen (count, key) int count, key; { @@ -1981,6 +1189,7 @@ rl_clear_screen (count, key) return 0; } +int rl_arrow_keys (count, c) int count, c; { @@ -1988,22 +1197,22 @@ rl_arrow_keys (count, c) ch = rl_read_key (); - switch (to_upper (ch)) + switch (_rl_to_upper (ch)) { case 'A': - rl_get_previous_history (count); + rl_get_previous_history (count, ch); break; case 'B': - rl_get_next_history (count); + rl_get_next_history (count, ch); break; case 'C': - rl_forward (count); + rl_forward (count, ch); break; case 'D': - rl_backward (count); + rl_backward (count, ch); break; default: @@ -2020,6 +1229,7 @@ rl_arrow_keys (count, c) /* **************************************************************** */ /* Insert the character C at the current location, moving point forward. */ +int rl_insert (count, c) int count, c; { @@ -2031,7 +1241,7 @@ rl_insert (count, c) /* If we can optimize, then do it. But don't let people crash readline because of extra large arguments. */ - if (count > 1 && count < 1024) + if (count > 1 && count <= 1024) { string = xmalloc (1 + count); @@ -2068,26 +1278,8 @@ rl_insert (count, c) If there is pending input, then make a string of all of the pending characters that are bound to rl_insert, and insert them all. */ - if (any_typein) - { - int key = 0, t; - - i = 0; - string = xmalloc (ibuffer_len + 1); - string[i++] = c; - - while ((t = rl_get_char (&key)) && - (_rl_keymap[key].type == ISFUNC && - _rl_keymap[key].function == rl_insert)) - string[i++] = key; - - if (t) - rl_unget_char (key); - - string[i] = '\0'; - rl_insert_text (string); - free (string); - } + if (_rl_any_typein ()) + _rl_insert_typein (c); else { /* Inserting a single character. */ @@ -2101,6 +1293,7 @@ rl_insert (count, c) } /* Insert the next typed character verbatim. */ +int rl_quoted_insert (count, key) int count, key; { @@ -2111,6 +1304,7 @@ rl_quoted_insert (count, key) } /* Insert a tab character. */ +int rl_tab_insert (count, key) int count, key; { @@ -2120,6 +1314,7 @@ rl_tab_insert (count, key) /* What to do when a NEWLINE is pressed. We accept the whole line. KEY is the key that invoked this command. I guess it could have meaning in the future. */ +int rl_newline (count, key) int count, key; { @@ -2128,7 +1323,6 @@ rl_newline (count, key) #if defined (VI_MODE) _rl_vi_done_inserting (); _rl_vi_reset_last (); - #endif /* VI_MODE */ if (readline_echoing_p) @@ -2136,22 +1330,11 @@ rl_newline (count, key) return 0; } -rl_clean_up_for_exit () -{ - if (readline_echoing_p) - { - _rl_move_vert (_rl_vis_botlin); - _rl_vis_botlin = 0; - fflush (out_stream); - rl_restart_output (); - } - return 0; -} - /* What to do for some uppercase characters, like meta characters, and some characters appearing in emacs_ctlx_keymap. This function is just a stub, you bind keys to it and the code in _rl_dispatch () is special cased. */ +int rl_do_lowercase_version (ignore1, ignore2) int ignore1, ignore2; { @@ -2159,12 +1342,13 @@ rl_do_lowercase_version (ignore1, ignore2) } /* Rubout the character behind point. */ +int rl_rubout (count, key) int count, key; { if (count < 0) { - rl_delete (-count); + rl_delete (-count, key); return 0; } @@ -2177,7 +1361,7 @@ rl_rubout (count, key) if (count > 1 || rl_explicit_arg) { int orig_point = rl_point; - rl_backward (count); + rl_backward (count, key); rl_kill_text (orig_point, rl_point); } else @@ -2197,13 +1381,12 @@ rl_rubout (count, key) /* Delete the character under the cursor. Given a numeric argument, kill that many characters instead. */ -rl_delete (count, invoking_key) - int count, invoking_key; +int +rl_delete (count, key) + int count, key; { if (count < 0) - { - return (rl_rubout (-count)); - } + return (rl_rubout (-count, key)); if (rl_point == rl_end) { @@ -2214,7 +1397,7 @@ rl_delete (count, invoking_key) if (count > 1 || rl_explicit_arg) { int orig_point = rl_point; - rl_forward (count); + rl_forward (count, key); rl_kill_text (orig_point, rl_point); rl_point = orig_point; return 0; @@ -2225,6 +1408,7 @@ rl_delete (count, invoking_key) } /* Delete all spaces and tabs around point. */ +int rl_delete_horizontal_space (count, ignore) int count, ignore; { @@ -2246,72 +1430,24 @@ rl_delete_horizontal_space (count, ignore) return 0; } - -/* **************************************************************** */ -/* */ -/* Kill commands */ -/* */ -/* **************************************************************** */ - -/* The next two functions mimic unix line editing behaviour, except they - save the deleted text on the kill ring. This is safer than not saving - it, and since we have a ring, nobody should get screwed. */ - -/* This does what C-w does in Unix. We can't prevent people from - using behaviour that they expect. */ -rl_unix_word_rubout (count, key) - int count, key; -{ - if (!rl_point) - ding (); - else - { - int orig_point = rl_point; - if (count <= 0) - count = 1; - - while (count--) - { - while (rl_point && whitespace (the_line[rl_point - 1])) - rl_point--; - - while (rl_point && !whitespace (the_line[rl_point - 1])) - rl_point--; - } - - rl_kill_text (orig_point, rl_point); - } - return 0; -} +#ifndef RL_COMMENT_BEGIN_DEFAULT +#define RL_COMMENT_BEGIN_DEFAULT "#" +#endif -/* Here is C-u doing what Unix does. You don't *have* to use these - key-bindings. We have a choice of killing the entire line, or - killing from where we are to the start of the line. We choose the - latter, because if you are a Unix weenie, then you haven't backspaced - into the line at all, and if you aren't, then you know what you are - doing. */ -rl_unix_line_discard (count, key) +/* Turn the current line into a comment in shell history. + A K*rn shell style function. */ +int +rl_insert_comment (count, key) int count, key; { - if (!rl_point) - ding (); - else - { - rl_kill_text (rl_point, 0); - rl_point = 0; - } - return 0; + rl_beg_of_line (1, key); + rl_insert_text (_rl_comment_begin ? _rl_comment_begin + : RL_COMMENT_BEGIN_DEFAULT); + (*rl_redisplay_function) (); + rl_newline (1, '\n'); + return (0); } - -/* **************************************************************** */ -/* */ -/* Commands For Typos */ -/* */ -/* **************************************************************** */ - -/* Random and interesting things in here. */ - /* **************************************************************** */ /* */ /* Changing Case */ @@ -2326,6 +1462,7 @@ rl_unix_line_discard (count, key) static int rl_change_case (); /* Uppercase the word at point. */ +int rl_upcase_word (count, key) int count, key; { @@ -2333,6 +1470,7 @@ rl_upcase_word (count, key) } /* Lowercase the word at point. */ +int rl_downcase_word (count, key) int count, key; { @@ -2340,6 +1478,7 @@ rl_downcase_word (count, key) } /* Upcase the first letter, downcase the rest. */ +int rl_capitalize_word (count, key) int count, key; { @@ -2355,46 +1494,35 @@ static int rl_change_case (count, op) int count, op; { - register int start = rl_point, end; - int state = 0; + register int start, end; + int inword, c; - rl_forward_word (count); + start = rl_point; + rl_forward_word (count, 0); end = rl_point; if (count < 0) - { - int temp = start; - start = end; - end = temp; - } + SWAP (start, end); /* We are going to modify some text, so let's prepare to undo it. */ rl_modifying (start, end); - for (; start < end; start++) + for (inword = 0; start < end; start++) { + c = the_line[start]; switch (op) { case UpCase: - the_line[start] = to_upper (the_line[start]); + the_line[start] = _rl_to_upper (c); break; case DownCase: - the_line[start] = to_lower (the_line[start]); + the_line[start] = _rl_to_lower (c); break; case CapCase: - if (state == 0) - { - the_line[start] = to_upper (the_line[start]); - state = 1; - } - else - { - the_line[start] = to_lower (the_line[start]); - } - if (!pure_alphabetic (the_line[start])) - state = 0; + the_line[start] = (inword == 0) ? _rl_to_upper (c) : _rl_to_lower (c); + inword = alphabetic (the_line[start]); break; default: @@ -2413,6 +1541,7 @@ rl_change_case (count, op) /* **************************************************************** */ /* Transpose the words at point. */ +int rl_transpose_words (count, key) int count, key; { @@ -2424,13 +1553,13 @@ rl_transpose_words (count, key) return 0; /* Find the two words. */ - rl_forward_word (count); + rl_forward_word (count, key); w2_end = rl_point; - rl_backward_word (1); + rl_backward_word (1, key); w2_beg = rl_point; - rl_backward_word (count); + rl_backward_word (count, key); w1_beg = rl_point; - rl_forward_word (1); + rl_forward_word (1, key); w1_end = rl_point; /* Do some check to make sure that there really are two words. */ @@ -2473,6 +1602,7 @@ rl_transpose_words (count, key) /* Transpose the characters at point. If point is at the end of the line, then transpose the characters before point. */ +int rl_transpose_chars (count, key) int count, key; { @@ -2511,180 +1641,77 @@ rl_transpose_chars (count, key) rl_end_undo_group (); return 0; } - + /* **************************************************************** */ /* */ -/* Undo, and Undoing */ +/* Character Searching */ /* */ /* **************************************************************** */ -/* The current undo list for THE_LINE. */ -UNDO_LIST *rl_undo_list = (UNDO_LIST *)NULL; - -/* Remember how to undo something. Concatenate some undos if that - seems right. */ -void -rl_add_undo (what, start, end, text) - enum undo_code what; - int start, end; - char *text; +int +_rl_char_search_internal (count, dir, schar) + int count, dir, schar; { - UNDO_LIST *temp = (UNDO_LIST *)xmalloc (sizeof (UNDO_LIST)); - temp->what = what; - temp->start = start; - temp->end = end; - temp->text = text; - temp->next = rl_undo_list; - rl_undo_list = temp; -} + int pos, inc; -/* Free the existing undo list. */ -void -free_undo_list () -{ - while (rl_undo_list) + pos = rl_point; + inc = (dir < 0) ? -1 : 1; + while (count) { - UNDO_LIST *release = rl_undo_list; - rl_undo_list = rl_undo_list->next; - - if (release->what == UNDO_DELETE) - free (release->text); + if ((dir < 0 && pos <= 0) || (dir > 0 && pos >= rl_end)) + { + ding (); + return -1; + } - free (release); + pos += inc; + do + { + if (rl_line_buffer[pos] == schar) + { + count--; + if (dir < 0) + rl_point = (dir == BTO) ? pos + 1 : pos; + else + rl_point = (dir == FTO) ? pos - 1 : pos; + break; + } + } + while ((dir < 0) ? pos-- : ++pos < rl_end); } - rl_undo_list = (UNDO_LIST *)NULL; -} - -/* Undo the next thing in the list. Return 0 if there - is nothing to undo, or non-zero if there was. */ -int -rl_do_undo () -{ - UNDO_LIST *release; - int waiting_for_begin = 0; - -undo_thing: - if (!rl_undo_list) - return (0); - - doing_an_undo = 1; - - switch (rl_undo_list->what) { - - /* Undoing deletes means inserting some text. */ - case UNDO_DELETE: - rl_point = rl_undo_list->start; - rl_insert_text (rl_undo_list->text); - free (rl_undo_list->text); - break; - - /* Undoing inserts means deleting some text. */ - case UNDO_INSERT: - rl_delete_text (rl_undo_list->start, rl_undo_list->end); - rl_point = rl_undo_list->start; - break; - - /* Undoing an END means undoing everything 'til we get to - a BEGIN. */ - case UNDO_END: - waiting_for_begin++; - break; - - /* Undoing a BEGIN means that we are done with this group. */ - case UNDO_BEGIN: - if (waiting_for_begin) - waiting_for_begin--; - else - ding (); - break; - } - - doing_an_undo = 0; - - release = rl_undo_list; - rl_undo_list = rl_undo_list->next; - free (release); - - if (waiting_for_begin) - goto undo_thing; - - return (1); -} - -/* Begin a group. Subsequent undos are undone as an atomic operation. */ -int -rl_begin_undo_group () -{ - rl_add_undo (UNDO_BEGIN, 0, 0, 0); - return 0; -} - -/* End an undo group started with rl_begin_undo_group (). */ -int -rl_end_undo_group () -{ - rl_add_undo (UNDO_END, 0, 0, 0); - return 0; + return (0); } -/* Save an undo entry for the text from START to END. */ -rl_modifying (start, end) - int start, end; +/* Search COUNT times for a character read from the current input stream. + FDIR is the direction to search if COUNT is non-negative; otherwise + the search goes in BDIR. */ +static int +_rl_char_search (count, fdir, bdir) + int count, fdir, bdir; { - if (start > end) - { - int t = start; - start = end; - end = t; - } + int c; - if (start != end) - { - char *temp = rl_copy_text (start, end); - rl_begin_undo_group (); - rl_add_undo (UNDO_DELETE, start, end, temp); - rl_add_undo (UNDO_INSERT, start, end, (char *)NULL); - rl_end_undo_group (); - } - return 0; + c = rl_read_key (); + if (count < 0) + return (_rl_char_search_internal (-count, bdir, c)); + else + return (_rl_char_search_internal (count, fdir, c)); } -/* Revert the current line to its previous state. */ int -rl_revert_line (count, key) +rl_char_search (count, key) int count, key; { - if (!rl_undo_list) - ding (); - else - { - while (rl_undo_list) - rl_do_undo (); - } - return 0; + return (_rl_char_search (count, FFIND, BFIND)); } -/* Do some undoing of things that were done. */ int -rl_undo_command (count, key) +rl_backward_char_search (count, key) int count, key; { - if (count < 0) - return 0; /* Nothing to do. */ - - while (count) - { - if (rl_do_undo ()) - count--; - else - { - ding (); - break; - } - } - return 0; + return (_rl_char_search (count, BFIND, FFIND)); } - + /* **************************************************************** */ /* */ /* History Utilities */ @@ -2692,8 +1719,8 @@ rl_undo_command (count, key) /* **************************************************************** */ /* We already have a history library, and that is what we use to control - the history features of readline. However, this is our local interface - to the history mechanism. */ + the history features of readline. This is our local interface to + the history mechanism. */ /* While we are editing the history, this is the saved version of the original line. */ @@ -2715,7 +1742,7 @@ void _rl_free_history_entry (entry) HIST_ENTRY *entry; { - if (!entry) + if (entry == 0) return; if (entry->line) free (entry->line); @@ -2723,10 +1750,12 @@ _rl_free_history_entry (entry) } /* Perhaps put back the current line if it has changed. */ +int maybe_replace_line () { - HIST_ENTRY *temp = current_history (); + HIST_ENTRY *temp; + temp = current_history (); /* If the current line has changed, save the changes. */ if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list)) { @@ -2738,12 +1767,13 @@ maybe_replace_line () } /* Put back the saved_line_for_history if there is one. */ +int maybe_unsave_line () { + int line_len; + if (saved_line_for_history) { - int line_len; - line_len = strlen (saved_line_for_history->line); if (line_len >= rl_line_buffer_len) @@ -2761,9 +1791,10 @@ maybe_unsave_line () } /* Save the current line in saved_line_for_history. */ +int maybe_save_line () { - if (!saved_line_for_history) + if (saved_line_for_history == 0) { saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY)); saved_line_for_history->line = savestring (the_line); @@ -2771,7 +1802,7 @@ maybe_save_line () } return 0; } - + /* **************************************************************** */ /* */ /* History Commands */ @@ -2779,13 +1810,15 @@ maybe_save_line () /* **************************************************************** */ /* Meta-< goes to the start of the history. */ +int rl_beginning_of_history (count, key) int count, key; { - return (rl_get_previous_history (1 + where_history ())); + return (rl_get_previous_history (1 + where_history (), key)); } /* Meta-> goes to the end of the history. (The current line). */ +int rl_end_of_history (count, key) int count, key; { @@ -2796,19 +1829,22 @@ rl_end_of_history (count, key) } /* Move down to the next history line. */ +int rl_get_next_history (count, key) int count, key; { - HIST_ENTRY *temp = (HIST_ENTRY *)NULL; + HIST_ENTRY *temp; + int line_len; if (count < 0) - return (rl_get_previous_history (-count)); + return (rl_get_previous_history (-count, key)); - if (!count) + if (count == 0) return 0; maybe_replace_line (); + temp = (HIST_ENTRY *)NULL; while (count) { temp = next_history (); @@ -2817,12 +1853,10 @@ rl_get_next_history (count, key) --count; } - if (!temp) + if (temp == 0) maybe_unsave_line (); else { - int line_len; - line_len = strlen (temp->line); if (line_len >= rl_line_buffer_len) @@ -2841,16 +1875,17 @@ rl_get_next_history (count, key) /* Get the previous item out of our interactive history, making it the current line. If there is no previous history, just ding. */ +int rl_get_previous_history (count, key) int count, key; { - HIST_ENTRY *old_temp = (HIST_ENTRY *)NULL; - HIST_ENTRY *temp = (HIST_ENTRY *)NULL; + HIST_ENTRY *old_temp, *temp; + int line_len; if (count < 0) - return (rl_get_next_history (-count)); + return (rl_get_next_history (-count, key)); - if (!count) + if (count == 0) return 0; /* If we don't have a line saved, then save this one. */ @@ -2859,13 +1894,14 @@ rl_get_previous_history (count, key) /* If the current line has changed, save the changes. */ maybe_replace_line (); + temp = old_temp = (HIST_ENTRY *)NULL; while (count) { temp = previous_history (); - if (!temp) + if (temp == 0) break; - else - old_temp = temp; + + old_temp = temp; --count; } @@ -2874,12 +1910,10 @@ rl_get_previous_history (count, key) if (!temp && old_temp) temp = old_temp; - if (!temp) + if (temp == 0) ding (); else { - int line_len; - line_len = strlen (temp->line); if (line_len >= rl_line_buffer_len) @@ -2897,14 +1931,6 @@ rl_get_previous_history (count, key) return 0; } -/* Make C be the next command to be executed. */ -rl_execute_next (c) - int c; -{ - rl_pending_input = c; - return 0; -} - /* **************************************************************** */ /* */ /* The Mark and the Region. */ @@ -2912,7 +1938,8 @@ rl_execute_next (c) /* **************************************************************** */ /* Set the mark at POSITION. */ -rl_set_mark (position) +int +_rl_set_mark_at_pos (position) int position; { if (position > rl_end) @@ -2922,8 +1949,17 @@ rl_set_mark (position) return 0; } +/* A bindable command to set the mark. */ +int +rl_set_mark (count, key) + int count, key; +{ + return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point)); +} + /* Exchange the position of mark and point. */ -rl_exchange_mark_and_point (count, key) +int +rl_exchange_point_and_mark (count, key) int count, key; { if (rl_mark > rl_end) @@ -2935,347 +1971,29 @@ rl_exchange_mark_and_point (count, key) return -1; } else - { - int temp = rl_point; + SWAP (rl_point, rl_mark); - rl_point = rl_mark; - rl_mark = temp; - } return 0; } - /* **************************************************************** */ /* */ -/* Killing Mechanism */ +/* Editing Modes */ /* */ /* **************************************************************** */ - -/* What we assume for a max number of kills. */ -#define DEFAULT_MAX_KILLS 10 - -/* The real variable to look at to find out when to flush kills. */ -int rl_max_kills = DEFAULT_MAX_KILLS; - -/* Where to store killed text. */ -char **rl_kill_ring = (char **)NULL; - -/* Where we are in the kill ring. */ -int rl_kill_index = 0; - -/* How many slots we have in the kill ring. */ -int rl_kill_ring_length = 0; - -/* How to say that you only want to save a certain amount - of kill material. */ -rl_set_retained_kills (num) - int num; -{ - return 0; -} - -/* The way to kill something. This appends or prepends to the last - kill, if the last command was a kill command. if FROM is less - than TO, then the text is appended, otherwise prepended. If the - last command was not a kill command, then a new slot is made for - this kill. */ -rl_kill_text (from, to) - int from, to; -{ - int slot; - char *text; - - /* Is there anything to kill? */ - if (from == to) - { - last_command_was_kill++; - return 0; - } - - text = rl_copy_text (from, to); - - /* Delete the copied text from the line. */ - rl_delete_text (from, to); - - /* First, find the slot to work with. */ - if (!last_command_was_kill) - { - /* Get a new slot. */ - if (!rl_kill_ring) - { - /* If we don't have any defined, then make one. */ - rl_kill_ring = (char **) - xmalloc (((rl_kill_ring_length = 1) + 1) * sizeof (char *)); - rl_kill_ring[slot = 0] = (char *)NULL; - } - else - { - /* We have to add a new slot on the end, unless we have - exceeded the max limit for remembering kills. */ - slot = rl_kill_ring_length; - if (slot == rl_max_kills) - { - register int i; - free (rl_kill_ring[0]); - for (i = 0; i < slot; i++) - rl_kill_ring[i] = rl_kill_ring[i + 1]; - } - else - { - slot = rl_kill_ring_length += 1; - rl_kill_ring = (char **)xrealloc (rl_kill_ring, slot * sizeof (char *)); - } - rl_kill_ring[--slot] = (char *)NULL; - } - } - else - slot = rl_kill_ring_length - 1; - - /* If the last command was a kill, prepend or append. */ - if (last_command_was_kill && rl_editing_mode != vi_mode) - { - char *old = rl_kill_ring[slot]; - char *new = xmalloc (1 + strlen (old) + strlen (text)); - - if (from < to) - { - strcpy (new, old); - strcat (new, text); - } - else - { - strcpy (new, text); - strcat (new, old); - } - free (old); - free (text); - rl_kill_ring[slot] = new; - } - else - { - rl_kill_ring[slot] = text; - } - rl_kill_index = slot; - last_command_was_kill++; - return 0; -} - -/* Now REMEMBER! In order to do prepending or appending correctly, kill - commands always make rl_point's original position be the FROM argument, - and rl_point's extent be the TO argument. */ - -/* **************************************************************** */ -/* */ -/* Killing Commands */ -/* */ -/* **************************************************************** */ - -/* Delete the word at point, saving the text in the kill ring. */ -rl_kill_word (count, key) - int count, key; -{ - int orig_point = rl_point; - - if (count < 0) - return (rl_backward_kill_word (-count)); - else - { - rl_forward_word (count); - - if (rl_point != orig_point) - rl_kill_text (orig_point, rl_point); - - rl_point = orig_point; - } - return 0; -} - -/* Rubout the word before point, placing it on the kill ring. */ -rl_backward_kill_word (count, ignore) - int count, ignore; -{ - int orig_point = rl_point; - - if (count < 0) - return (rl_kill_word (-count)); - else - { - rl_backward_word (count); - - if (rl_point != orig_point) - rl_kill_text (orig_point, rl_point); - } - return 0; -} - -/* Kill from here to the end of the line. If DIRECTION is negative, kill - back to the line start instead. */ -rl_kill_line (direction, ignore) - int direction, ignore; -{ - int orig_point = rl_point; - - if (direction < 0) - return (rl_backward_kill_line (1)); - else - { - rl_end_of_line (1, ignore); - if (orig_point != rl_point) - rl_kill_text (orig_point, rl_point); - rl_point = orig_point; - } - return 0; -} - -/* Kill backwards to the start of the line. If DIRECTION is negative, kill - forwards to the line end instead. */ -rl_backward_kill_line (direction, ignore) - int direction, ignore; -{ - int orig_point = rl_point; - - if (direction < 0) - return (rl_kill_line (1)); - else - { - if (!rl_point) - ding (); - else - { - rl_beg_of_line (1, ignore); - rl_kill_text (orig_point, rl_point); - } - } - return 0; -} - -/* Kill the whole line, no matter where point is. */ -rl_kill_full_line (count, ignore) - int count, ignore; -{ - rl_begin_undo_group (); - rl_point = 0; - rl_kill_text (rl_point, rl_end); - rl_end_undo_group (); - return 0; -} - -/* Yank back the last killed text. This ignores arguments. */ -rl_yank (count, ignore) - int count, ignore; -{ - if (!rl_kill_ring) - { - rl_abort (count, ignore); - return -1; - } - - rl_set_mark (rl_point); - rl_insert_text (rl_kill_ring[rl_kill_index]); - return 0; -} - -/* If the last command was yank, or yank_pop, and the text just - before point is identical to the current kill item, then - delete that text from the line, rotate the index down, and - yank back some other text. */ -rl_yank_pop (count, key) - int count, key; -{ - int l; - - if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) || - !rl_kill_ring) - { - rl_abort (1, key); - return -1; - } - - l = strlen (rl_kill_ring[rl_kill_index]); - if (((rl_point - l) >= 0) && - (strncmp (the_line + (rl_point - l), - rl_kill_ring[rl_kill_index], l) == 0)) - { - rl_delete_text ((rl_point - l), rl_point); - rl_point -= l; - rl_kill_index--; - if (rl_kill_index < 0) - rl_kill_index = rl_kill_ring_length - 1; - rl_yank (1, 0); - return 0; - } - else - { - rl_abort (1, key); - return -1; - } -} - -/* Yank the COUNTth argument from the previous history line. */ -rl_yank_nth_arg (count, ignore) - int count, ignore; -{ - register HIST_ENTRY *entry = previous_history (); - char *arg; - - if (entry) - next_history (); - else - { - ding (); - return -1; - } - - arg = history_arg_extract (count, count, entry->line); - if (!arg || !*arg) - { - ding (); - return -1; - } - - rl_begin_undo_group (); - -#if defined (VI_MODE) - /* Vi mode always inserts a space before yanking the argument, and it - inserts it right *after* rl_point. */ - if (rl_editing_mode == vi_mode) - { - rl_vi_append_mode (); - rl_insert_text (" "); - } -#endif /* VI_MODE */ - - rl_insert_text (arg); - free (arg); - - rl_end_undo_group (); - return 0; -} - -/* Yank the last argument from the previous history line. This `knows' - how rl_yank_nth_arg treats a count of `$'. With an argument, this - behaves the same as rl_yank_nth_arg. */ -int -rl_yank_last_arg (count, key) - int count, key; -{ - if (rl_explicit_arg) - return (rl_yank_nth_arg (count, key)); - else - return (rl_yank_nth_arg ('$', key)); -} - /* How to toggle back and forth between editing modes. */ +int rl_vi_editing_mode (count, key) int count, key; { #if defined (VI_MODE) rl_editing_mode = vi_mode; rl_vi_insertion_mode (); - return 0; #endif /* VI_MODE */ + return 0; } +int rl_emacs_editing_mode (count, key) int count, key; { @@ -3283,257 +2001,3 @@ rl_emacs_editing_mode (count, key) _rl_keymap = emacs_standard_keymap; return 0; } - - -/* **************************************************************** */ -/* */ -/* USG (System V) Support */ -/* */ -/* **************************************************************** */ - -int -rl_getc (stream) - FILE *stream; -{ - int result; - unsigned char c; - -#if defined (__GO32__) - if (isatty (0)) - return (getkey () & 0x7F); -#endif /* __GO32__ */ - - while (1) - { - result = read (fileno (stream), &c, sizeof (unsigned char)); - - if (result == sizeof (unsigned char)) - return (c); - - /* If zero characters are returned, then the file that we are - reading from is empty! Return EOF in that case. */ - if (result == 0) - return (EOF); - -#if defined (EWOULDBLOCK) - if (errno == EWOULDBLOCK) - { - int flags; - - if ((flags = fcntl (fileno (stream), F_GETFL, 0)) < 0) - return (EOF); - if (flags & O_NDELAY) - { - flags &= ~O_NDELAY; - fcntl (fileno (stream), F_SETFL, flags); - continue; - } - continue; - } -#endif /* EWOULDBLOCK */ - -#if defined (_POSIX_VERSION) && defined (EAGAIN) && defined (O_NONBLOCK) - if (errno == EAGAIN) - { - int flags; - - if ((flags = fcntl (fileno (stream), F_GETFL, 0)) < 0) - return (EOF); - if (flags & O_NONBLOCK) - { - flags &= ~O_NONBLOCK; - fcntl (fileno (stream), F_SETFL, flags); - continue; - } - } -#endif /* _POSIX_VERSION && EAGAIN && O_NONBLOCK */ - -#if !defined (__GO32__) - /* If the error that we received was SIGINT, then try again, - this is simply an interrupted system call to read (). - Otherwise, some error ocurred, also signifying EOF. */ - if (errno != EINTR) - return (EOF); -#endif /* !__GO32__ */ - } -} - -#if !defined (SHELL) -#ifdef savestring -#undef savestring -#endif -/* Backwards compatibilty, now that savestring has been removed from - all `public' readline header files. */ -char * -savestring (s) - char *s; -{ - return ((char *)strcpy (xmalloc (1 + (int)strlen (s)), (s))); -} -#endif - -/* Function equivalents for the macros defined in chartypes.h. */ -#undef uppercase_p -int -uppercase_p (c) - int c; -{ - return (isupper (c)); -} - -#undef lowercase_p -int -lowercase_p (c) - int c; -{ - return (islower (c)); -} - -#undef pure_alphabetic -int -pure_alphabetic (c) - int c; -{ - return (isupper (c) || islower (c)); -} - -#undef digit_p -int -digit_p (c) - int c; -{ - return (isdigit (c)); -} - -#undef to_lower -int -to_lower (c) - int c; -{ - return (isupper (c) ? tolower (c) : c); -} - -#undef to_upper -int -to_upper (c) - int c; -{ - return (islower (c) ? toupper (c) : c); -} - -#undef digit_value -int -digit_value (c) - int c; -{ - return (isdigit (c) ? c - '0' : c); -} - -#if defined (STATIC_MALLOC) - -/* **************************************************************** */ -/* */ -/* xmalloc and xrealloc () */ -/* */ -/* **************************************************************** */ - -static void memory_error_and_abort (); - -static char * -xmalloc (bytes) - int bytes; -{ - char *temp = (char *)malloc (bytes); - - if (!temp) - memory_error_and_abort (); - return (temp); -} - -static char * -xrealloc (pointer, bytes) - char *pointer; - int bytes; -{ - char *temp; - - if (!pointer) - temp = (char *)malloc (bytes); - else - temp = (char *)realloc (pointer, bytes); - - if (!temp) - memory_error_and_abort (); - - return (temp); -} - -static void -memory_error_and_abort () -{ - fprintf (stderr, "readline: Out of virtual memory!\n"); - abort (); -} -#endif /* STATIC_MALLOC */ - - -/* **************************************************************** */ -/* */ -/* Testing Readline */ -/* */ -/* **************************************************************** */ - -#if defined (TEST) - -main () -{ - HIST_ENTRY **history_list (); - char *temp = (char *)NULL; - char *prompt = "readline% "; - int done = 0; - - while (!done) - { - temp = readline (prompt); - - /* Test for EOF. */ - if (!temp) - exit (1); - - /* If there is anything on the line, print it and remember it. */ - if (*temp) - { - fprintf (stderr, "%s\r\n", temp); - add_history (temp); - } - - /* Check for `command' that we handle. */ - if (strcmp (temp, "quit") == 0) - done = 1; - - if (strcmp (temp, "list") == 0) - { - HIST_ENTRY **list = history_list (); - register int i; - if (list) - { - for (i = 0; list[i]; i++) - { - fprintf (stderr, "%d: %s\r\n", i, list[i]->line); - free (list[i]->line); - } - free (list); - } - } - free (temp); - } -} - -#endif /* TEST */ - - -/* - * Local variables: - * compile-command: "gcc -g -traditional -I. -I.. -DTEST -o readline readline.c keymaps.o funmap.o history.o -ltermcap" - * end: - */ diff --git a/lib/readline/readline.h b/lib/readline/readline.h index b397177..4f7d498 100644 --- a/lib/readline/readline.h +++ b/lib/readline/readline.h @@ -31,15 +31,44 @@ # include <readline/tilde.h> #endif -/* The functions for manipulating the text of the line within readline. -Most of these functions are bound to keys by default. */ +/* Readline data structures. */ + +/* Maintaining the state of undo. We remember individual deletes and inserts + on a chain of things to do. */ + +/* The actions that undo knows how to undo. Notice that UNDO_DELETE means + to insert some text, and UNDO_INSERT means to delete some text. I.e., + the code tells undo what to undo, not how to undo it. */ +enum undo_code { UNDO_DELETE, UNDO_INSERT, UNDO_BEGIN, UNDO_END }; + +/* What an element of THE_UNDO_LIST looks like. */ +typedef struct undo_list { + struct undo_list *next; + int start, end; /* Where the change took place. */ + char *text; /* The text to insert, if undoing a delete. */ + enum undo_code what; /* Delete, Insert, Begin, End. */ +} UNDO_LIST; + +/* The current undo list for RL_LINE_BUFFER. */ +extern UNDO_LIST *rl_undo_list; + +/* The data structure for mapping textual names to code addresses. */ +typedef struct _funmap { + char *name; + Function *function; +} FUNMAP; + +extern FUNMAP **funmap; + +/* Functions available to bind to key sequences. */ extern int - rl_tilde_expand (), + rl_tilde_expand (), rl_set_mark (), rl_exchange_point_and_mark (), rl_beg_of_line (), rl_backward (), rl_delete (), rl_end_of_line (), - rl_forward (), ding (), rl_backward (), rl_newline (), rl_kill_line (), + rl_forward (), ding (), rl_newline (), rl_kill_line (), + rl_copy_region_to_kill (), rl_kill_region (), rl_char_search (), rl_clear_screen (), rl_get_next_history (), rl_get_previous_history (), rl_quoted_insert (), rl_reverse_search_history (), rl_transpose_chars (), - rl_unix_line_discard (), rl_quoted_insert (), rl_unix_word_rubout (), + rl_unix_line_discard (), rl_unix_word_rubout (), rl_yank (), rl_rubout (), rl_backward_word (), rl_kill_word (), rl_forward_word (), rl_tab_insert (), rl_yank_pop (), rl_yank_nth_arg (), rl_backward_kill_word (), rl_backward_kill_line (), rl_transpose_words (), @@ -49,28 +78,21 @@ extern int rl_undo_command (), rl_revert_line (), rl_beginning_of_history (), rl_end_of_history (), rl_forward_search_history (), rl_insert (), rl_upcase_word (), rl_downcase_word (), rl_capitalize_word (), - rl_restart_output (), rl_re_read_init_file (), rl_dump_functions (), + rl_restart_output (), rl_re_read_init_file (), + rl_dump_functions (), rl_dump_variables (), rl_dump_macros (), rl_delete_horizontal_space (), rl_history_search_forward (), - rl_history_search_backward (), rl_tty_status (), rl_yank_last_arg (); - -/* `Public' utility functions. */ -extern int rl_insert_text (), rl_delete_text (), rl_kill_text (); -extern int rl_complete_internal (); -extern int rl_expand_prompt (); -extern int rl_initialize (); -extern int rl_set_signals (), rl_clear_signals (); -extern int rl_init_argument (), rl_digit_argument (); -extern int rl_read_key (), rl_getc (), rl_stuff_char (); -extern int maybe_save_line (), maybe_unsave_line (), maybe_replace_line (); -extern int rl_modifying (); - -extern int rl_begin_undo_group (), rl_end_undo_group (); -extern void rl_add_undo (), free_undo_list (); -extern int rl_do_undo (); + rl_history_search_backward (), rl_tty_status (), rl_yank_last_arg (), + rl_insert_comment (), rl_backward_char_search (), + rl_copy_forward_word (), rl_copy_backward_word (); /* Not available unless readline is compiled -DPAREN_MATCHING. */ extern int rl_insert_close (); +/* Not available unless READLINE_CALLBACKS is defined. */ +extern void rl_callback_handler_install (); +extern void rl_callback_read_char (); +extern void rl_callback_handler_remove (); + /* These are *both* defined even when VI_MODE is not. */ extern int rl_vi_editing_mode (), rl_emacs_editing_mode (); @@ -82,11 +104,11 @@ extern int /* Things for vi mode. Not available unless readline is compiled -DVI_MODE. */ extern int rl_vi_check (), rl_vi_textmod_command (); extern int - rl_vi_redo (), rl_vi_tilde_expand (), + rl_vi_undo (), rl_vi_redo (), rl_vi_tilde_expand (), rl_vi_movement_mode (), rl_vi_insertion_mode (), rl_vi_arg_digit (), rl_vi_prev_word (), rl_vi_next_word (), rl_vi_char_search (), rl_vi_eof_maybe (), rl_vi_append_mode (), rl_vi_put (), - rl_vi_append_eol (), rl_vi_insert_beg (), rl_vi_delete (), rl_vi_comment (), + rl_vi_append_eol (), rl_vi_insert_beg (), rl_vi_delete (), rl_vi_first_print (), rl_vi_fword (), rl_vi_fWord (), rl_vi_bword (), rl_vi_bWord (), rl_vi_eword (), rl_vi_eWord (), rl_vi_end_word (), rl_vi_change_case (), rl_vi_match (), rl_vi_bracktype (), @@ -94,40 +116,112 @@ extern int rl_vi_search_again (), rl_vi_subst (), rl_vi_overstrike (), rl_vi_overstrike_delete (), rl_vi_replace(), rl_vi_column (), rl_vi_delete_to (), rl_vi_change_to (), rl_vi_yank_to (), - rl_vi_complete (), rl_vi_fetch_history (); + rl_vi_complete (), rl_vi_fetch_history (), rl_vi_set_mark (), + rl_vi_goto_mark (), rl_vi_back_to_indent (); /* Keyboard macro commands. */ extern int rl_start_kbd_macro (), rl_end_kbd_macro (); extern int rl_call_last_kbd_macro (); +extern void rl_push_macro_input (); extern int rl_arrow_keys(), rl_refresh_line (); -/* Maintaining the state of undo. We remember individual deletes and inserts - on a chain of things to do. */ +/* **************************************************************** */ +/* */ +/* Well Published Functions */ +/* */ +/* **************************************************************** */ -/* The actions that undo knows how to undo. Notice that UNDO_DELETE means - to insert some text, and UNDO_INSERT means to delete some text. I.e., - the code tells undo what to undo, not how to undo it. */ -enum undo_code { UNDO_DELETE, UNDO_INSERT, UNDO_BEGIN, UNDO_END }; +/* Readline functions. */ +/* Read a line of input. Prompt with PROMPT. A NULL PROMPT means none. */ +extern char *readline (); -/* What an element of THE_UNDO_LIST looks like. */ -typedef struct undo_list { - struct undo_list *next; - int start, end; /* Where the change took place. */ - char *text; /* The text to insert, if undoing a delete. */ - enum undo_code what; /* Delete, Insert, Begin, End. */ -} UNDO_LIST; +/* These functions are from bind.c. */ +/* rl_add_defun (char *name, Function *function, int key) + Add NAME to the list of named functions. Make FUNCTION + be the function that gets called. + If KEY is not -1, then bind it. */ +extern int rl_add_defun (); -/* The current undo list for RL_LINE_BUFFER. */ -extern UNDO_LIST *rl_undo_list; +extern Keymap rl_make_bare_keymap (); +extern Keymap rl_copy_keymap (); +extern Keymap rl_make_keymap (); +extern void rl_discard_keymap (); +extern Keymap rl_get_keymap (), rl_get_keymap_by_name (); +extern void rl_set_keymap (); +extern char *rl_get_keymap_name (); -/* The data structure for mapping textual names to code addresses. */ -typedef struct { - char *name; - Function *function; -} FUNMAP; +extern int rl_bind_key (), rl_bind_key_in_map (); +extern int rl_unbind_key (), rl_unbind_key_in_map (); +extern int rl_set_key (); +extern int rl_generic_bind (); +extern int rl_parse_and_bind (); +/* Backwards compatibility, use rl_generic_bind instead. */ +extern int rl_macro_bind (), rl_variable_bind (); -extern FUNMAP **funmap; +extern int rl_read_init_file (); + +extern Function *rl_named_function (), *rl_function_of_keyseq (); +extern char **rl_invoking_keyseqs (), **rl_invoking_keyseqs_in_map (); +extern void rl_function_dumper (); +extern void rl_variable_dumper (); +extern void rl_macro_dumper (); +extern void rl_list_funmap_names (); + +/* Undocumented in the texinfo manual; not really useful to programs. */ +extern int rl_translate_keyseq (); +extern void rl_initialize_funmap (); + +/* Functions for undoing. */ +extern int rl_begin_undo_group (), rl_end_undo_group (); +extern void rl_add_undo (), free_undo_list (); +extern int rl_do_undo (); +extern int rl_modifying (); + +/* Functions for redisplay. */ +extern void rl_redisplay (); +extern int rl_forced_update_display (); +extern int rl_clear_message (); +extern int rl_reset_line_state (); +extern int rl_on_new_line (); + +#if defined (__STDC__) && defined (USE_VARARGS) && defined (PREFER_STDARG) +extern int rl_message (const char *, ...); +#else +extern int rl_message (); +#endif + +/* Undocumented in texinfo manual. */ +extern int rl_character_len (); +extern int rl_show_char (); +extern int crlf (); + +/* Modifying text. */ +extern int rl_insert_text (), rl_delete_text (); +extern int rl_kill_text (); +extern char *rl_copy_text (); + +/* `Public' utility functions. */ +extern int rl_reset_terminal (); +extern int rl_stuff_char (); +extern int rl_read_key (), rl_getc (); + +extern int rl_initialize (); + +/* Undocumented. */ +extern int rl_expand_prompt (); +extern int rl_set_signals (), rl_clear_signals (); +extern int maybe_save_line (), maybe_unsave_line (), maybe_replace_line (); + +/* Completion functions. */ +/* These functions are from complete.c. */ +extern int rl_complete_internal (); + +/* Return an array of strings which are the result of repeatadly calling + FUNC with TEXT. */ +extern char **completion_matches (); +extern char *username_completion_function (); +extern char *filename_completion_function (); /* **************************************************************** */ /* */ @@ -135,6 +229,9 @@ extern FUNMAP **funmap; /* */ /* **************************************************************** */ +/* The version of this incarnation of the readline library. */ +extern char *rl_library_version; + /* The name of the calling program. You should initialize this to whatever was in argv[0]. It is used when parsing conditionals. */ extern char *rl_readline_name; @@ -145,33 +242,36 @@ extern char *rl_line_buffer; /* The location of point, and end. */ extern int rl_point, rl_end; +extern int rl_mark; + +extern int rl_done; + +extern int rl_pending_input; + /* The name of the terminal to use. */ extern char *rl_terminal_name; /* The input and output streams. */ extern FILE *rl_instream, *rl_outstream; -/* The basic list of characters that signal a break between words for the - completer routine. The initial contents of this variable is what - breaks words in the shell, i.e. "n\"\\'`@$>". */ -extern char *rl_basic_word_break_characters; +/* If non-zero, then this is the address of a function to call just + before readline_internal () prints the first prompt. */ +extern Function *rl_startup_hook; -/* The list of characters that signal a break between words for - rl_complete_internal. The default list is the contents of - rl_basic_word_break_characters. */ -extern char *rl_completer_word_break_characters; +/* The address of a function to call periodically while Readline is + awaiting character input, or NULL, for no event handling. */ +extern Function *rl_event_hook; -/* List of characters which can be used to quote a substring of the line. - Completion occurs on the entire substring, and within the substring - rl_completer_word_break_characters are treated as any other character, - unless they also appear within this list. */ -extern char *rl_completer_quote_characters; +extern Function *rl_getc_function; +extern VFunction *rl_redisplay_function; +extern VFunction *rl_prep_term_function; +extern VFunction *rl_deprep_term_function; -/* List of characters that are word break characters, but should be left - in TEXT when it is passed to the completion function. The shell uses - this to help determine what kind of completing to do. */ -extern char *rl_special_prefixes; +/* Dispatch variables. */ +extern Keymap rl_executing_keymap; +extern Keymap rl_binding_keymap; +/* Completion variables. */ /* Pointer to the generator function for completion_matches (). NULL means to use filename_entry_function (), the default filename completer. */ @@ -194,9 +294,32 @@ extern Function *rl_ignore_some_completions_function; array of strings returned. */ extern CPPFunction *rl_attempted_completion_function; -/* If non-zero, then this is the address of a function to call just - before readline_internal () prints the first prompt. */ -extern Function *rl_startup_hook; +/* The basic list of characters that signal a break between words for the + completer routine. The initial contents of this variable is what + breaks words in the shell, i.e. "n\"\\'`@$>". */ +extern char *rl_basic_word_break_characters; + +/* The list of characters that signal a break between words for + rl_complete_internal. The default list is the contents of + rl_basic_word_break_characters. */ +extern char *rl_completer_word_break_characters; + +/* List of characters which can be used to quote a substring of the line. + Completion occurs on the entire substring, and within the substring + rl_completer_word_break_characters are treated as any other character, + unless they also appear within this list. */ +extern char *rl_completer_quote_characters; + +/* List of quote characters which cause a word break. */ +extern char *rl_basic_quote_characters; + +/* List of characters that need to be quoted in filenames by the completer. */ +extern char *rl_filename_quote_characters; + +/* List of characters that are word break characters, but should be left + in TEXT when it is passed to the completion function. The shell uses + this to help determine what kind of completing to do. */ +extern char *rl_special_prefixes; /* If non-zero, then this is the address of a function to call when completing on a directory name. The function is called with @@ -206,14 +329,6 @@ extern Function *rl_directory_completion_hook; /* Backwards compatibility with previous versions of readline. */ #define rl_symbolic_link_hook rl_directory_completion_hook -/* The address of a function to call periodically while Readline is - awaiting character input, or NULL, for no event handling. */ -extern Function *rl_event_hook; - -/* Non-zero means that modified history lines are preceded - with an asterisk. */ -extern int rl_show_star; - /* Non-zero means that the results of the matches are to be treated as filenames. This is ALWAYS zero on entry, and can only be changed within a completion entry finder function. */ @@ -226,62 +341,49 @@ extern int rl_filename_completion_desired; entry finder function. */ extern int rl_filename_quoting_desired; -/* Non-zero means to suppress normal filename completion after the - user-specified completion function has been called. */ -extern int rl_attempted_completion_over; - -/* **************************************************************** */ -/* */ -/* Well Published Functions */ -/* */ -/* **************************************************************** */ +/* Set to a function to quote a filename in an application-specific fashion. + Called with the text to quote, the type of match found (single or multiple) + and a pointer to the quoting character to be used, which the function can + reset if desired. */ +extern CPFunction *rl_filename_quoting_function; -/* Read a line of input. Prompt with PROMPT. A NULL PROMPT means none. */ -extern char *readline (); +/* Function to call to remove quoting characters from a filename. Called + before completion is attempted, so the embedded quotes do not interfere + with matching names in the file system. */ +extern CPFunction *rl_filename_dequoting_function; -/* These functions are from complete.c. */ -/* Return an array of strings which are the result of repeatadly calling - FUNC with TEXT. */ -extern char **completion_matches (); -extern char *username_completion_function (); -extern char *filename_completion_function (); +/* Function to call to decide whether or not a word break character is + quoted. If a character is quoted, it does not break words for the + completer. */ +extern Function *rl_char_is_quoted_p; -/* These functions are from bind.c. */ -/* rl_add_defun (char *name, Function *function, int key) - Add NAME to the list of named functions. Make FUNCTION - be the function that gets called. - If KEY is not -1, then bind it. */ -extern int rl_add_defun (); -extern int rl_bind_key (), rl_bind_key_in_map (); -extern int rl_unbind_key (), rl_unbind_key_in_map (); -extern int rl_set_key (); -extern int rl_macro_bind (), rl_generic_bind (), rl_variable_bind (); -extern int rl_translate_keyseq (); -extern Function *rl_named_function (), *rl_function_of_keyseq (); -extern int rl_parse_and_bind (); -extern Keymap rl_get_keymap (), rl_get_keymap_by_name (); -extern void rl_set_keymap (); -extern char **rl_invoking_keyseqs (), **rl_invoking_keyseqs_in_map (); -extern void rl_function_dumper (); -extern int rl_read_init_file (); +/* Non-zero means to suppress normal filename completion after the + user-specified completion function has been called. */ +extern int rl_attempted_completion_over; -/* Functions in funmap.c */ -extern void rl_list_funmap_names (); -extern void rl_initialize_funmap (); +/* Set to a character describing the type of completion being attempted by + rl_complete_internal; available for use by application completion + functions. */ +extern int rl_completion_type; -/* Functions in display.c */ -extern void rl_redisplay (); -extern int rl_message (), rl_clear_message (); -extern int rl_reset_line_state (); -extern int rl_character_len (); -extern int rl_show_char (); -extern int crlf (), rl_on_new_line (); -extern int rl_forced_update_display (); +/* Character appended to completed words when at the end of the line. The + default is a space. Nothing is added if this is '\0'. */ +extern int rl_completion_append_character; +/* If this is non-zero, completion is (temporarily) inhibited, and the + completion character will be inserted as any other. */ +extern int rl_inhibit_completion; + /* Definitions available for use by readline clients. */ #define RL_PROMPT_START_IGNORE '\001' #define RL_PROMPT_END_IGNORE '\002' +/* Possible values for do_replace argument to rl_filename_quoting_function, + called by rl_complete_internal. */ +#define NO_MATCH 0 +#define SINGLE_MATCH 1 +#define MULT_MATCH 2 + #if !defined (savestring) extern char *savestring (); /* XXX backwards compatibility */ #endif diff --git a/lib/readline/rlconf.h b/lib/readline/rlconf.h index 0035b93..8f07db1 100644 --- a/lib/readline/rlconf.h +++ b/lib/readline/rlconf.h @@ -51,7 +51,13 @@ over a character when updating the line rather than rewriting it. */ /* #define HACK_TERMCAP_MOTION */ -/* The string inserted by the vi-mode `insert comment' command. */ -#define VI_COMMENT_BEGIN_DEFAULT "#" +/* The string inserted by the `insert comment' command. */ +#define RL_COMMENT_BEGIN_DEFAULT "#" + +/* Define this if you want code that allows readline to be used in an + X `callback' style. */ +#if !defined (SHELL) +# define READLINE_CALLBACKS +#endif #endif /* _RLCONF_H_ */ diff --git a/lib/readline/rldefs.h b/lib/readline/rldefs.h index 683f8b5..5a9e62a 100644 --- a/lib/readline/rldefs.h +++ b/lib/readline/rldefs.h @@ -23,106 +23,33 @@ have a copy of the license, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ -#if !defined (_RLDEFS_H) -#define _RLDEFS_H +#if !defined (_RLDEFS_H_) +#define _RLDEFS_H_ #if defined (HAVE_CONFIG_H) # include "config.h" #endif -#if !defined (PRAGMA_ALLOCA) -# include "memalloc.h" -#endif - -#define NEW_TTY_DRIVER -#define HAVE_BSD_SIGNALS -/* #define USE_XON_XOFF */ - -#if defined (__linux__) || defined (HAVE_TERMCAP_H) -# include <termcap.h> -#endif /* __linux__ || HAVE_TERMCAP_H */ - -/* Some USG machines have BSD signal handling (sigblock, sigsetmask, etc.) */ -#if defined (USG) && !defined (hpux) -# undef HAVE_BSD_SIGNALS -#endif - -/* System V machines use termio. */ -#if !defined (_POSIX_VERSION) -# if defined (USG) || defined (hpux) || defined (Xenix) || defined (sgi) || \ - defined (DGUX) || defined (HAVE_TERMIO_H) -# undef NEW_TTY_DRIVER +#if defined (_POSIX_VERSION) && !defined (TERMIOS_MISSING) +# define TERMIOS_TTY_DRIVER +#else +# if defined (HAVE_TERMIO_H) # define TERMIO_TTY_DRIVER -# include <termio.h> -# if !defined (TCOON) -# define TCOON 1 -# endif -# endif /* USG || hpux || Xenix || sgi || DUGX || HAVE_TERMIO_H */ -#endif /* !_POSIX_VERSION */ - -/* Posix systems use termios and the Posix signal functions. */ -#if defined (_POSIX_VERSION) -# if !defined (TERMIOS_MISSING) -# undef NEW_TTY_DRIVER -# define TERMIOS_TTY_DRIVER -# include <termios.h> -# endif /* !TERMIOS_MISSING */ -# define HAVE_POSIX_SIGNALS -# if !defined (O_NDELAY) -# define O_NDELAY O_NONBLOCK /* Posix-style non-blocking i/o */ -# endif /* O_NDELAY */ -#endif /* _POSIX_VERSION */ - -/* System V.3 machines have the old 4.1 BSD `reliable' signal interface. */ -#if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS) -# if defined (USGr3) && !defined (XENIX_22) -# if !defined (HAVE_USG_SIGHOLD) -# define HAVE_USG_SIGHOLD -# endif /* !HAVE_USG_SIGHOLD */ -# endif /* USGr3 && !XENIX_22 */ -#endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */ - -/* Other (BSD) machines use sgtty. */ -#if defined (NEW_TTY_DRIVER) -# include <sgtty.h> +# else +# define NEW_TTY_DRIVER +# endif #endif -#if !defined (SHELL) && (defined (_POSIX_VERSION) || defined (USGr3)) -# if !defined (HAVE_DIRENT_H) -# define HAVE_DIRENT_H -# endif /* !HAVE_DIRENT_H */ -#endif /* !SHELL && (_POSIX_VERSION || USGr3) */ - -#if defined (HAVE_DIRENT_H) -# include <dirent.h> -# define D_NAMLEN(d) strlen ((d)->d_name) -#else /* !HAVE_DIRENT_H */ -# define D_NAMLEN(d) ((d)->d_namlen) -# if defined (USG) -# if defined (Xenix) -# include <sys/ndir.h> -# else /* !Xenix (but USG...) */ -# include "ndir.h" -# endif /* !Xenix */ -# else /* !USG */ -# include <sys/dir.h> -# endif /* !USG */ -# if !defined (dirent) -# define dirent direct -# endif /* !dirent */ -#endif /* !HAVE_DIRENT_H */ - -#if defined (USG) && defined (TIOCGWINSZ) && !defined (Linux) -# if defined (HAVE_SYS_STREAM_H) -# include <sys/stream.h> -# endif /* HAVE_SYS_STREAM_H */ -# if defined (HAVE_SYS_PTEM_H) -# include <sys/ptem.h> -# endif /* HAVE_SYS_PTEM_H */ -# if defined (HAVE_SYS_PTE_H) -# include <sys/pte.h> -# endif /* HAVE_SYS_PTE_H */ -#endif /* USG && TIOCGWINSZ && !Linux */ +#if defined (HAVE_SYS_STREAM_H) +# include <sys/stream.h> +#endif /* HAVE_SYS_STREAM_H */ +#if defined (HAVE_SYS_PTEM_H) +# include <sys/ptem.h> +# define _IO_PTEM_H /* work around SVR4.2 1.1.4 bug */ +#endif /* HAVE_SYS_PTEM_H */ +#if defined (HAVE_SYS_PTE_H) +# include <sys/pte.h> +#endif /* HAVE_SYS_PTE_H */ /* Posix macro to check file in statbuf for directory-ness. This requires that <sys/stat.h> be included before this test. */ @@ -133,12 +60,6 @@ /* Decide which flavor of the header file describing the C library string functions to include and include it. */ -#if defined (USG) || defined (NeXT) -# if !defined (HAVE_STRING_H) -# define HAVE_STRING_H -# endif /* !HAVE_STRING_H */ -#endif /* USG || NeXT */ - #if defined (HAVE_STRING_H) # include <string.h> #else /* !HAVE_STRING_H */ @@ -149,33 +70,20 @@ extern char *strchr (), *strrchr (); #endif /* !strchr && !__STDC__ */ -#if defined (HAVE_VARARGS_H) -# include <varargs.h> -#endif /* HAVE_VARARGS_H */ - -/* This is needed to include support for TIOCGWINSZ and window resizing. */ -#if defined (OSF1) || defined (BSD386) || defined (NetBSD) || \ - defined (__BSD_4_4__) || defined (FreeBSD) || defined (_386BSD) || \ - defined (AIX) -# define GWINSZ_IN_SYS_IOCTL +#if defined (PREFER_STDARG) +# include <stdarg.h> +#else +# if defined (PREFER_VARARGS) +# include <varargs.h> +# endif #endif -/* Define _POSIX_VDISABLE if we are not using the `new' tty driver and - it is not already defined. It is used both to determine if a - special character is disabled and to disable certain special - characters. Posix systems should set to 0, USG systems to -1. */ -#if !defined (NEW_TTY_DRIVER) && !defined (_POSIX_VDISABLE) -# if defined (_SVR4_VDISABLE) -# define _POSIX_VDISABLE _SVR4_VDISABLE -# else -# if defined (_POSIX_VERSION) -# define _POSIX_VDISABLE 0 -# else /* !_POSIX_VERSION */ -# define _POSIX_VDISABLE -1 -# endif /* !_POSIX_VERSION */ -# endif /* !_SVR4_VDISABLE */ -#endif /* !NEW_TTY_DRIVER && !_POSIX_VDISABLE */ - +#if defined (HAVE_STRCASECMP) +#define _rl_stricmp strcasecmp +#define _rl_strnicmp strncasecmp +#else +extern int _rl_stricmp (), _rl_strnicmp (); +#endif #if !defined (emacs_mode) # define no_mode -1 @@ -206,7 +114,33 @@ extern char *xmalloc (); #define AUDIBLE_BELL 1 #define VISIBLE_BELL 2 +/* Definitions used when searching the line for characters. */ +/* NOTE: it is necessary that opposite directions are inverses */ +#define FTO 1 /* forward to */ +#define BTO -1 /* backward to */ +#define FFIND 2 /* forward find */ +#define BFIND -2 /* backward find */ + +/* Possible values for the found_quote flags word used by the completion + functions. It says what kind of (shell-like) quoting we found anywhere + in the line. */ +#define RL_QF_SINGLE_QUOTE 0x1 +#define RL_QF_DOUBLE_QUOTE 0x2 +#define RL_QF_BACKSLASH 0x4 + +/* Default readline line buffer length. */ +#define DEFAULT_BUFFER_SIZE 256 + +#if !defined (STREQ) +#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0)) +#define STREQN(a, b, n) (((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0)) +#endif + +#if !defined (FREE) +# define FREE(x) if (x) free (x) +#endif + /* CONFIGURATION SECTION */ #include "rlconf.h" -#endif /* !_RLDEFS_H */ +#endif /* !_RLDEFS_H_ */ diff --git a/lib/readline/rltty.c b/lib/readline/rltty.c index 02c036d..d35eb6a 100644 --- a/lib/readline/rltty.c +++ b/lib/readline/rltty.c @@ -23,7 +23,7 @@ #define READLINE_LIBRARY #if defined (HAVE_CONFIG_H) -# include "config.h" +# include <config.h> #endif #include <sys/types.h> @@ -36,6 +36,12 @@ #endif /* HAVE_UNISTD_H */ #include "rldefs.h" + +#if !defined (SHELL) && defined (GWINSZ_IN_SYS_IOCTL) +# include <sys/ioctl.h> +#endif /* !SHELL && GWINSZ_IN_SYS_IOCTL */ + +#include "rltty.h" #include "readline.h" #if !defined (errno) @@ -45,11 +51,19 @@ extern int errno; extern int readline_echoing_p; extern int _rl_eof_char; +extern int _rl_enable_keypad, _rl_enable_meta; + #if defined (__GO32__) -# include <sys/pc.h> +# include <pc.h> # undef HANDLE_SIGNALS #endif /* __GO32__ */ +/* Indirect functions to allow apps control over terminal management. */ +extern void rl_prep_terminal (), rl_deprep_terminal (); + +VFunction *rl_prep_term_function = rl_prep_terminal; +VFunction *rl_deprep_term_function = rl_deprep_terminal; + /* **************************************************************** */ /* */ /* Signal Management */ @@ -64,7 +78,7 @@ static int sigint_oldmask; # endif /* HAVE_BSD_SIGNALS */ #endif /* !HAVE_POSIX_SIGNALS */ -static int sigint_blocked = 0; +static int sigint_blocked; /* Cause SIGINT to not be delivered until the corresponding call to release_sigint(). */ @@ -115,64 +129,35 @@ release_sigint () /* **************************************************************** */ /* */ -/* Controlling the Meta Key and Keypad */ -/* */ -/* **************************************************************** */ - -extern int term_has_meta; -extern char *term_mm; -extern char *term_mo; - -extern char *term_ks; -extern char *term_ke; - -static int -outchar (c) - int c; -{ - return putc (c, rl_outstream); -} - -/* Turn on/off the meta key depending on ON. */ -static void -control_meta_key (on) - int on; -{ - if (term_has_meta) - { - if (on && term_mm) - tputs (term_mm, 1, outchar); - else if (!on && term_mo) - tputs (term_mo, 1, outchar); - } -} - -#if 0 -static void -control_keypad (on) - int on; -{ - if (on && term_ks) - tputs (term_ks, 1, outchar); - else if (!on && term_ke) - tputs (term_ke, 1, outchar); -} -#endif - -/* **************************************************************** */ -/* */ /* Saving and Restoring the TTY */ /* */ /* **************************************************************** */ /* Non-zero means that the terminal is in a prepped state. */ -static int terminal_prepped = 0; +static int terminal_prepped; /* If non-zero, means that this process has called tcflow(fd, TCOOFF) and output is suspended. */ #if defined (__ksr1__) -static int ksrflow = 0; +static int ksrflow; #endif + +#if !defined (SHELL) && defined (TIOCGWINSZ) +/* Dummy call to force a backgrounded readline to stop before it tries + to get the tty settings. */ +static void +set_winsize (tty) + int tty; +{ + struct winsize w; + + if (ioctl (tty, TIOCGWINSZ, &w) == 0) + (void) ioctl (tty, TIOCSWINSZ, &w); +} +#else /* SHELL || !TIOCGWINSZ */ +# define set_winsize(tty) +#endif /* SHELL || !TIOCGWINSZ */ + #if defined (NEW_TTY_DRIVER) /* Values for the `flags' field of a struct bsdtty. This tells which @@ -204,12 +189,7 @@ get_tty_settings (tty, tiop) int tty; TIOTYPE *tiop; { -#if !defined (SHELL) && defined (TIOCGWINSZ) - struct winsize w; - - if (ioctl (tty, TIOCGWINSZ, &w) == 0) - (void) ioctl (tty, TIOCSWINSZ, &w); -#endif + set_winsize (tty); tiop->flags = tiop->lflag = 0; @@ -234,6 +214,7 @@ get_tty_settings (tty, tiop) return 0; } +static int set_tty_settings (tty, tiop) int tty; TIOTYPE *tiop; @@ -360,7 +341,11 @@ prepare_terminal_settings (meta_flag, otio, tiop) # define TIOTYPE struct termios # define DRAIN_OUTPUT(fd) tcdrain (fd) # define GETATTR(tty, tiop) (tcgetattr (tty, tiop)) -# define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop)) +# ifdef M_UNIX +# define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop)) +# else +# define SETATTR(tty, tiop) (tcsetattr (tty, TCSADRAIN, tiop)) +# endif /* !M_UNIX */ #else # define TIOTYPE struct termio # define DRAIN_OUTPUT(fd) @@ -376,29 +361,61 @@ static TIOTYPE otio; # define OUTPUT_BEING_FLUSHED(tp) 0 #endif +static void +rltty_warning (msg) + char *msg; +{ + fprintf (stderr, "readline: warning: %s\n", msg); +} + +#if defined (_AIX) +void +setopost(tp) +TIOTYPE *tp; +{ + if ((tp->c_oflag & OPOST) == 0) + { + rltty_warning ("turning on OPOST for terminal\r"); + tp->c_oflag |= OPOST|ONLCR; + } +} +#endif + static int get_tty_settings (tty, tiop) int tty; TIOTYPE *tiop; { int ioctl_ret; -#if !defined (SHELL) && defined (TIOCGWINSZ) - struct winsize w; + set_winsize (tty); - if (ioctl (tty, TIOCGWINSZ, &w) == 0) - (void) ioctl (tty, TIOCSWINSZ, &w); -#endif - - /* Keep looping if output is being flushed after a ^O (or whatever - the flush character is). */ - while ((ioctl_ret = GETATTR (tty, tiop)) < 0 || OUTPUT_BEING_FLUSHED (tiop)) + while (1) { - if (ioctl_ret < 0 && errno != EINTR) - return -1; + ioctl_ret = GETATTR (tty, tiop); + if (ioctl_ret < 0) + { + if (errno != EINTR) + return -1; + else + continue; + } if (OUTPUT_BEING_FLUSHED (tiop)) - continue; - errno = 0; + { +#if defined (FLUSHO) && defined (_AIX41) + rltty_warning ("turning off output flushing"); + tiop->c_lflag &= ~FLUSHO; + break; +#else + continue; +#endif + } + break; } + +#if defined (_AIX) + setopost(tiop); +#endif + return 0; } @@ -503,7 +520,7 @@ rl_prep_terminal (meta_flag) int meta_flag; { #if !defined (__GO32__) - int tty = fileno (rl_instream); + int tty; TIOTYPE tio; if (terminal_prepped) @@ -512,6 +529,8 @@ rl_prep_terminal (meta_flag) /* Try to keep this function from being INTerrupted. */ block_sigint (); + tty = fileno (rl_instream); + if (get_tty_settings (tty, &tio) < 0) { release_sigint (); @@ -528,10 +547,9 @@ rl_prep_terminal (meta_flag) return; } - control_meta_key (1); -#if 0 - control_keypad (1); -#endif + if (_rl_enable_keypad) + _rl_control_keypad (1); + fflush (rl_outstream); terminal_prepped = 1; @@ -544,18 +562,19 @@ void rl_deprep_terminal () { #if !defined (__GO32__) - int tty = fileno (rl_instream); + int tty; if (!terminal_prepped) return; - /* Try to keep this function from being INTerrupted. */ + /* Try to keep this function from being interrupted. */ block_sigint (); - control_meta_key (0); -#if 0 - control_keypad (0); -#endif + tty = fileno (rl_instream); + + if (_rl_enable_keypad) + _rl_control_keypad (0); + fflush (rl_outstream); if (set_tty_settings (tty, &otio) < 0) @@ -576,6 +595,7 @@ rl_deprep_terminal () /* */ /* **************************************************************** */ +int rl_restart_output (count, key) int count, key; { @@ -608,6 +628,7 @@ rl_restart_output (count, key) return 0; } +int rl_stop_output (count, key) int count, key; { @@ -634,7 +655,7 @@ rl_stop_output (count, key) return 0; } - + /* **************************************************************** */ /* */ /* Default Key Bindings */ diff --git a/lib/readline/rltty.h b/lib/readline/rltty.h new file mode 100644 index 0000000..3ee6b3f --- /dev/null +++ b/lib/readline/rltty.h @@ -0,0 +1,61 @@ +/* rltty.h - tty driver-related definitions used by some library files. */ + +/* Copyright (C) 1995 Free Software Foundation, Inc. + + This file contains the Readline Library (the Library), a set of + routines for providing Emacs style line input to programs that ask + for it. + + The Library is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + The Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + The GNU General Public License is often shipped with GNU software, and + is generally kept in a file called COPYING or LICENSE. If you do not + have a copy of the license, write to the Free Software Foundation, + 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#if !defined (_RLTTY_H_) +#define _RLTTY_H + +/* Posix systems use termios and the Posix signal functions. */ +#if defined (TERMIOS_TTY_DRIVER) +# include <termios.h> +#endif /* TERMIOS_TTY_DRIVER */ + +/* System V machines use termio. */ +#if defined (TERMIO_TTY_DRIVER) +# include <termio.h> +# if !defined (TCOON) +# define TCOON 1 +# endif +#endif /* TERMIO_TTY_DRIVER */ + +/* Other (BSD) machines use sgtty. */ +#if defined (NEW_TTY_DRIVER) +# include <sgtty.h> +#endif + +/* Define _POSIX_VDISABLE if we are not using the `new' tty driver and + it is not already defined. It is used both to determine if a + special character is disabled and to disable certain special + characters. Posix systems should set to 0, USG systems to -1. */ +#if !defined (NEW_TTY_DRIVER) && !defined (_POSIX_VDISABLE) +# if defined (_SVR4_VDISABLE) +# define _POSIX_VDISABLE _SVR4_VDISABLE +# else +# if defined (_POSIX_VERSION) +# define _POSIX_VDISABLE 0 +# else /* !_POSIX_VERSION */ +# define _POSIX_VDISABLE -1 +# endif /* !_POSIX_VERSION */ +# endif /* !_SVR4_DISABLE */ +#endif /* !NEW_TTY_DRIVER && !_POSIX_VDISABLE */ + +#endif /* _RLTTY_H_ */ diff --git a/lib/readline/search.c b/lib/readline/search.c index d56e554..05641a1 100644 --- a/lib/readline/search.c +++ b/lib/readline/search.c @@ -22,6 +22,10 @@ 675 Mass Ave, Cambridge, MA 02139, USA. */ #define READLINE_LIBRARY +#if defined (HAVE_CONFIG_H) +# include <config.h> +#endif + #include <sys/types.h> #include <stdio.h> @@ -33,16 +37,12 @@ #include "readline.h" #include "history.h" -#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0)) -#define STREQN(a, b, n) (((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0)) - #define abs(x) (((x) > 0) ? (x) : -(x)) extern char *xmalloc (), *xrealloc (); /* Variables imported from readline.c */ extern int rl_point, rl_end, rl_line_buffer_len; -extern Keymap _rl_keymap; extern int rl_editing_mode; extern char *rl_prompt; extern char *rl_line_buffer; @@ -51,9 +51,12 @@ extern Function *rl_last_func; /* Functions imported from the rest of the library. */ extern int _rl_free_history_entry (); +extern char *_rl_make_prompt_for_search (); +extern void _rl_restore_prompt (); +extern void rl_extend_line_buffer (); static char *noninc_search_string = (char *) NULL; -static int noninc_history_pos = 0; +static int noninc_history_pos; static char *prev_line_found = (char *) NULL; /* Search the history list for STRING starting at absolute history position @@ -91,7 +94,7 @@ noninc_dosearch (string, dir) char *string; int dir; { - int oldpos, pos; + int oldpos, pos, line_len; HIST_ENTRY *entry; if (string == 0 || *string == '\0' || noninc_history_pos < 0) @@ -121,14 +124,10 @@ noninc_dosearch (string, dir) #endif history_set_pos (oldpos); - { - int line_len; - - line_len = strlen (entry->line); - if (line_len >= rl_line_buffer_len) - rl_extend_line_buffer (line_len); - strcpy (rl_line_buffer, entry->line); - } + line_len = strlen (entry->line); + if (line_len >= rl_line_buffer_len) + rl_extend_line_buffer (line_len); + strcpy (rl_line_buffer, entry->line); rl_undo_list = (UNDO_LIST *)entry->data; rl_end = strlen (rl_line_buffer); @@ -150,7 +149,7 @@ noninc_search (dir, pchar) int dir; int pchar; { - int saved_point, c, pmtlen; + int saved_point, c; char *p; maybe_save_line (); @@ -160,17 +159,12 @@ noninc_search (dir, pchar) rl_line_buffer[0] = 0; rl_end = rl_point = 0; - /* XXX - this needs fixing to work with the prompt expansion stuff - XXX */ - pmtlen = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0; - p = xmalloc (2 + pmtlen); - if (pmtlen) - strcpy (p, rl_prompt); - p[pmtlen] = pchar ? pchar : ':'; - p[pmtlen + 1] = '\0'; - + p = _rl_make_prompt_for_search (pchar ? pchar : ':'); rl_message (p, 0, 0); free (p); +#define SEARCH_RETURN _rl_restore_prompt (); return + /* Read the search string. */ while (c = rl_read_key ()) { @@ -183,9 +177,9 @@ noninc_search (dir, pchar) maybe_unsave_line (); rl_clear_message (); rl_point = saved_point; - return; + SEARCH_RETURN; } - rl_rubout (1); + rl_rubout (1, c); break; case CTRL('W'): @@ -208,13 +202,13 @@ noninc_search (dir, pchar) rl_clear_message (); rl_point = saved_point; ding (); - return; + SEARCH_RETURN; default: rl_insert (1, c); break; } - rl_redisplay (); + (*rl_redisplay_function) (); } dosearch: @@ -226,7 +220,7 @@ noninc_search (dir, pchar) if (!noninc_search_string) { ding (); - return; + SEARCH_RETURN; } } else @@ -238,35 +232,33 @@ noninc_search (dir, pchar) noninc_search_string = savestring (rl_line_buffer); } + _rl_restore_prompt (); noninc_dosearch (noninc_search_string, dir); } /* Search forward through the history list for a string. If the vi-mode code calls this, KEY will be `?'. */ +int rl_noninc_forward_search (count, key) int count, key; { - if (key == '?') - noninc_search (1, '?'); - else - noninc_search (1, 0); + noninc_search (1, (key == '?') ? '?' : 0); return 0; } /* Reverse search the history list for a string. If the vi-mode code calls this, KEY will be `/'. */ +int rl_noninc_reverse_search (count, key) int count, key; { - if (key == '/') - noninc_search (-1, '/'); - else - noninc_search (-1, 0); + noninc_search (-1, (key == '/') ? '/' : 0); return 0; } /* Search forward through the history list for the last string searched for. If there is no saved search string, abort. */ +int rl_noninc_forward_search_again (count, key) int count, key; { @@ -281,6 +273,7 @@ rl_noninc_forward_search_again (count, key) /* Reverse search in the history list for the last string searched for. If there is no saved search string, abort. */ +int rl_noninc_reverse_search_again (count, key) int count, key; { @@ -306,8 +299,14 @@ rl_history_search_internal (count, direction) while (count) { temp = (direction < 0) ? previous_history () : next_history (); - if (!temp) + if (temp == 0) break; + /* On an empty prefix, make this the same as previous-history. */ + if (rl_point == 0) + { + count--; + continue; + } if (STREQN (rl_line_buffer, temp->line, rl_point)) { /* Don't find multiple instances of the same line. */ @@ -320,7 +319,7 @@ rl_history_search_internal (count, direction) } } - if (!temp) + if (temp == 0) { if (direction < 0 && old_temp) temp = old_temp; diff --git a/lib/readline/signals.c b/lib/readline/signals.c index e3d93a0..2fe7953 100644 --- a/lib/readline/signals.c +++ b/lib/readline/signals.c @@ -21,32 +21,18 @@ 675 Mass Ave, Cambridge, MA 02139, USA. */ #define READLINE_LIBRARY -#include <stdio.h> +#if defined (HAVE_CONFIG_H) +# include <config.h> +#endif + +#include <stdio.h> /* Just for NULL. Yuck. */ #include <sys/types.h> -#include <fcntl.h> -#if !defined (NO_SYS_FILE) -# include <sys/file.h> -#endif /* !NO_SYS_FILE */ #include <signal.h> #if defined (HAVE_UNISTD_H) # include <unistd.h> #endif /* HAVE_UNISTD_H */ -#if defined (HAVE_STDLIB_H) -# include <stdlib.h> -#else -# include "ansi_stdlib.h" -#endif /* HAVE_STDLIB_H */ - -#include <errno.h> -/* Not all systems declare ERRNO in errno.h... and some systems #define it! */ -#if !defined (errno) -extern int errno; -#endif /* !errno */ - -#include "posixstat.h" - /* System-specific feature definitions and include files. */ #include "rldefs.h" @@ -54,6 +40,11 @@ extern int errno; # include <sys/ioctl.h> #endif /* GWINSZ_IN_SYS_IOCTL */ +#if defined (__GO32__) +# undef HANDLE_SIGNALS +#endif /* __GO32__ */ + +#if defined (HANDLE_SIGNALS) /* Some standard library routines. */ #include "readline.h" #include "history.h" @@ -63,72 +54,60 @@ extern int rl_pending_input; extern int _rl_meta_flag; extern void free_undo_list (); +extern void _rl_get_screen_size (); +extern void _rl_redisplay_after_sigwinch (); +extern void _rl_clean_up_for_exit (); +extern void _rl_kill_kbd_macro (); +extern void _rl_init_argument (); +extern void rl_deprep_terminal (), rl_prep_terminal (); + +#if !defined (RETSIGTYPE) +# if defined (VOID_SIGHANDLER) +# define RETSIGTYPE void +# else +# define RETSIGTYPE int +# endif /* !VOID_SIGHANDLER */ +#endif /* !RETSIGTYPE */ #if defined (VOID_SIGHANDLER) -# define sighandler void +# define SIGHANDLER_RETURN return #else -# define sighandler int -#endif /* VOID_SIGHANDLER */ +# define SIGHANDLER_RETURN return (0) +#endif /* This typedef is equivalant to the one for Function; it allows us to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */ -typedef sighandler SigHandler (); +typedef RETSIGTYPE SigHandler (); -#if defined (__GO32__) -# undef HANDLE_SIGNALS -#endif /* __GO32__ */ +static SigHandler *rl_set_sighandler (); -#if defined (STATIC_MALLOC) -static char *xmalloc (), *xrealloc (); -#else -extern char *xmalloc (), *xrealloc (); -#endif /* STATIC_MALLOC */ - - /* **************************************************************** */ /* */ /* Signal Handling */ /* */ /* **************************************************************** */ -#if defined (SIGWINCH) -static SigHandler *old_sigwinch = (SigHandler *)NULL; - -static sighandler -rl_handle_sigwinch (sig) - int sig; -{ - if (readline_echoing_p) - { - _rl_set_screen_size (fileno (rl_instream), 1); - _rl_redisplay_after_sigwinch (); - } +#if defined (HAVE_POSIX_SIGNALS) +typedef struct sigaction sighandler_cxt; +# define rl_sigaction(s, nh, oh) sigaction(s, nh, oh) +#else +typedef struct { SigHandler *sa_handler; } sighandler_cxt; +# define sigemptyset(m) +#endif /* !HAVE_POSIX_SIGNALS */ - if (old_sigwinch && - old_sigwinch != (SigHandler *)SIG_IGN && - old_sigwinch != (SigHandler *)SIG_DFL) - (*old_sigwinch) (sig); -#if !defined (VOID_SIGHANDLER) - return (0); -#endif /* VOID_SIGHANDLER */ -} -#endif /* SIGWINCH */ +static sighandler_cxt old_int, old_alrm; -#if defined (HANDLE_SIGNALS) -/* Interrupt handling. */ -static SigHandler - *old_int = (SigHandler *)NULL, - *old_alrm = (SigHandler *)NULL; #if !defined (SHELL) -static SigHandler - *old_tstp = (SigHandler *)NULL, - *old_ttou = (SigHandler *)NULL, - *old_ttin = (SigHandler *)NULL, - *old_cont = (SigHandler *)NULL; +static sighandler_cxt old_tstp, old_ttou, old_ttin, old_term; #endif /* !SHELL */ -/* Handle an interrupt character. */ -static sighandler +#if defined (SIGWINCH) +static sighandler_cxt old_winch; +#endif + +/* Readline signal handler functions. */ + +static RETSIGTYPE rl_signal_handler (sig) int sig; { @@ -143,9 +122,9 @@ rl_signal_handler (sig) #if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS) /* Since the signal will not be blocked while we are in the signal handler, ignore it until rl_clear_signals resets the catcher. */ - if (sig == SIGINT) - signal (sig, SIG_IGN); -#endif /* !HAVE_BSD_SIGNALS */ + if (sig == SIGINT || sig == SIGALRM) + rl_set_sighandler (sig, SIG_IGN, (sighandler_cxt *)NULL); +#endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */ switch (sig) { @@ -161,7 +140,7 @@ rl_signal_handler (sig) } _rl_kill_kbd_macro (); rl_clear_message (); - rl_init_argument (); + _rl_init_argument (); #if defined (SIGTSTP) case SIGTSTP: @@ -169,8 +148,9 @@ rl_signal_handler (sig) case SIGTTIN: #endif /* SIGTSTP */ case SIGALRM: - rl_clean_up_for_exit (); - rl_deprep_terminal (); + case SIGTERM: + _rl_clean_up_for_exit (); + (*rl_deprep_term_function) (); rl_clear_signals (); rl_pending_input = 0; @@ -194,92 +174,159 @@ rl_signal_handler (sig) # endif /* HAVE_BSD_SIGNALS */ #endif /* !HAVE_POSIX_SIGNALS */ - rl_prep_terminal (_rl_meta_flag); + (*rl_prep_term_function) (_rl_meta_flag); rl_set_signals (); } -#if !defined (VOID_SIGHANDLER) - return (0); -#endif /* !VOID_SIGHANDLER */ + SIGHANDLER_RETURN; } -#if defined (HAVE_POSIX_SIGNALS) +#if defined (SIGWINCH) +static RETSIGTYPE +rl_handle_sigwinch (sig) + int sig; +{ + SigHandler *oh; + + if (readline_echoing_p) + { + _rl_get_screen_size (fileno (rl_instream), 1); + _rl_redisplay_after_sigwinch (); + } + + /* If another sigwinch handler has been installed, call it. */ + oh = (SigHandler *)old_winch.sa_handler; + if (oh && oh != (SigHandler *)SIG_IGN && oh != (SigHandler *)SIG_DFL) + (*oh) (sig); + + SIGHANDLER_RETURN; +} +#endif /* SIGWINCH */ + +/* Functions to manage signal handling. */ + +#if !defined (HAVE_POSIX_SIGNALS) +static int +rl_sigaction (sig, nh, oh) + int sig; + sighandler_cxt *nh, *oh; +{ + oh->sa_handler = signal (sig, nh->sa_handler); + return 0; +} +#endif /* !HAVE_POSIX_SIGNALS */ + +/* Set up a readline-specific signal handler, saving the old signal + information in OHANDLER. Return the old signal handler, like + signal(). */ static SigHandler * -rl_set_sighandler (sig, handler) +rl_set_sighandler (sig, handler, ohandler) int sig; SigHandler *handler; + sighandler_cxt *ohandler; { - struct sigaction act, oact; +#if defined (HAVE_POSIX_SIGNALS) + struct sigaction act; act.sa_handler = handler; act.sa_flags = 0; sigemptyset (&act.sa_mask); - sigemptyset (&oact.sa_mask); - sigaction (sig, &act, &oact); - return (oact.sa_handler); -} - -#else /* !HAVE_POSIX_SIGNALS */ -# define rl_set_sighandler(sig, handler) (SigHandler *)signal (sig, handler) + sigemptyset (&ohandler->sa_mask); + sigaction (sig, &act, ohandler); +#else + ohandler->sa_handler = (SigHandler *)signal (sig, handler); #endif /* !HAVE_POSIX_SIGNALS */ + return (ohandler->sa_handler); +} +int rl_set_signals () { - old_int = (SigHandler *)rl_set_sighandler (SIGINT, rl_signal_handler); - if (old_int == (SigHandler *)SIG_IGN) - rl_set_sighandler (SIGINT, SIG_IGN); + sighandler_cxt dummy; + SigHandler *oh; + +#if defined (HAVE_POSIX_SIGNALS) + sigemptyset (&dummy.sa_mask); +#endif - old_alrm = (SigHandler *)rl_set_sighandler (SIGALRM, rl_signal_handler); - if (old_alrm == (SigHandler *)SIG_IGN) - rl_set_sighandler (SIGALRM, SIG_IGN); + oh = rl_set_sighandler (SIGINT, rl_signal_handler, &old_int); + if (oh == (SigHandler *)SIG_IGN) + rl_sigaction (SIGINT, &old_int, &dummy); + + oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm); + if (oh == (SigHandler *)SIG_IGN) + rl_sigaction (SIGALRM, &old_alrm, &dummy); +#if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART) + /* If the application using readline has already installed a signal + handler with SA_RESTART, SIGALRM will cause reads to be restarted + automatically, so readline should just get out of the way. Since + we tested for SIG_IGN above, we can just test for SIG_DFL here. */ + if (oh != (SigHandler *)SIG_DFL && (old_alrm.sa_flags & SA_RESTART)) + rl_sigaction (SIGALRM, &old_alrm, &dummy); +#endif /* HAVE_POSIX_SIGNALS */ #if !defined (SHELL) #if defined (SIGTSTP) - old_tstp = (SigHandler *)rl_set_sighandler (SIGTSTP, rl_signal_handler); - if (old_tstp == (SigHandler *)SIG_IGN) - rl_set_sighandler (SIGTSTP, SIG_IGN); + oh = rl_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp); + if (oh == (SigHandler *)SIG_IGN) + rl_sigaction (SIGTSTP, &old_tstp, &dummy); +#else + oh = (SigHandler *)NULL; #endif /* SIGTSTP */ + #if defined (SIGTTOU) - old_ttou = (SigHandler *)rl_set_sighandler (SIGTTOU, rl_signal_handler); - old_ttin = (SigHandler *)rl_set_sighandler (SIGTTIN, rl_signal_handler); + rl_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou); + rl_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin); - if (old_tstp == (SigHandler *)SIG_IGN) + if (oh == (SigHandler *)SIG_IGN) { - rl_set_sighandler (SIGTTOU, SIG_IGN); - rl_set_sighandler (SIGTTIN, SIG_IGN); + rl_set_sighandler (SIGTTOU, SIG_IGN, &dummy); + rl_set_sighandler (SIGTTIN, SIG_IGN, &dummy); } #endif /* SIGTTOU */ + /* Handle SIGTERM if we're not being compiled as part of bash. */ + rl_set_sighandler (SIGTERM, rl_signal_handler, &old_term); #endif /* !SHELL */ #if defined (SIGWINCH) - old_sigwinch = - (SigHandler *) rl_set_sighandler (SIGWINCH, rl_handle_sigwinch); + rl_set_sighandler (SIGWINCH, rl_handle_sigwinch, &old_winch); #endif /* SIGWINCH */ + return 0; } +int rl_clear_signals () { - rl_set_sighandler (SIGINT, old_int); - rl_set_sighandler (SIGALRM, old_alrm); + sighandler_cxt dummy; + +#if defined (HAVE_POSIX_SIGNALS) + sigemptyset (&dummy.sa_mask); +#endif + + rl_sigaction (SIGINT, &old_int, &dummy); + rl_sigaction (SIGALRM, &old_alrm, &dummy); #if !defined (SHELL) #if defined (SIGTSTP) - rl_set_sighandler (SIGTSTP, old_tstp); + rl_sigaction (SIGTSTP, &old_tstp, &dummy); #endif #if defined (SIGTTOU) - rl_set_sighandler (SIGTTOU, old_ttou); - rl_set_sighandler (SIGTTIN, old_ttin); + rl_sigaction (SIGTTOU, &old_ttou, &dummy); + rl_sigaction (SIGTTIN, &old_ttin, &dummy); #endif /* SIGTTOU */ + rl_sigaction (SIGTERM, &old_term, &dummy); + #endif /* !SHELL */ #if defined (SIGWINCH) - rl_set_sighandler (SIGWINCH, old_sigwinch); + sigemptyset (&dummy.sa_mask); + rl_sigaction (SIGWINCH, &old_winch, &dummy); #endif return 0; diff --git a/lib/readline/tcap.h b/lib/readline/tcap.h new file mode 100644 index 0000000..0673288 --- /dev/null +++ b/lib/readline/tcap.h @@ -0,0 +1,57 @@ +/* tcap.h -- termcap library functions and variables. */ + +/* Copyright (C) 1996 Free Software Foundation, Inc. + + This file contains the Readline Library (the Library), a set of + routines for providing Emacs style line input to programs that ask + for it. + + The Library is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + The Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + The GNU General Public License is often shipped with GNU software, and + is generally kept in a file called COPYING or LICENSE. If you do not + have a copy of the license, write to the Free Software Foundation, + 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#if !defined (_RLTCAP_H_) +#define _RLTCAP_H_ + +#if defined (HAVE_CONFIG_H) +# include "config.h" +#endif + +#if defined (HAVE_TERMCAP_H) +# include <termcap.h> +#else + +/* On Solaris2, sys/types.h #includes sys/reg.h, which #defines PC. + Unfortunately, PC is a global variable used by the termcap library. */ +#ifdef PC +# undef PC +#endif + +extern char PC; +extern char *UP, *BC; + +extern short ospeed; + +extern int tgetent (); +extern int tgetflag (); +extern int tgetnum (); +extern char *tgetstr (); + +extern int tputs (); + +extern char *tgoto (); + +#endif /* HAVE_TERMCAP_H */ + +#endif /* !_RLTCAP_H_ */ diff --git a/lib/readline/terminal.c b/lib/readline/terminal.c new file mode 100644 index 0000000..9ca9bc6 --- /dev/null +++ b/lib/readline/terminal.c @@ -0,0 +1,554 @@ +/* terminal.c -- controlling the terminal with termcap. */ + +/* Copyright (C) 1996 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library, a library for + reading lines of text with interactive input and history editing. + + The GNU Readline Library is free software; you can redistribute it + and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 1, or + (at your option) any later version. + + The GNU Readline Library is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + The GNU General Public License is often shipped with GNU software, and + is generally kept in a file called COPYING or LICENSE. If you do not + have a copy of the license, write to the Free Software Foundation, + 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include <config.h> +#endif + +#include <sys/types.h> +#include "posixstat.h" +#include <fcntl.h> +#if defined (HAVE_SYS_FILE_H) +# include <sys/file.h> +#endif /* HAVE_SYS_FILE_H */ + +#if defined (HAVE_UNISTD_H) +# include <unistd.h> +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include <stdlib.h> +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_LOCALE_H) +# include <locale.h> +#endif + +#include <signal.h> +#include <stdio.h> +#include <setjmp.h> + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" + +#include "tcap.h" + +#if defined (GWINSZ_IN_SYS_IOCTL) +# include <sys/ioctl.h> +#endif /* GWINSZ_IN_SYS_IOCTL */ + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +/* Variables and functions imported from readline.c */ +extern FILE *_rl_in_stream, *_rl_out_stream; +extern int readline_echoing_p; +extern int _rl_bell_preference; +extern Keymap _rl_keymap; + +/* **************************************************************** */ +/* */ +/* Terminal and Termcap */ +/* */ +/* **************************************************************** */ + +static char *term_buffer = (char *)NULL; +static char *term_string_buffer = (char *)NULL; + +static int tcap_initialized; + +/* Non-zero means this terminal can't really do anything. */ +static int dumb_term; + +#if !defined (__linux__) +/* If this causes problems, add back the `extern'. */ +/*extern*/ char PC, *BC, *UP; +#endif /* __linux__ */ + +/* Some strings to control terminal actions. These are output by tputs (). */ +char *term_goto, *term_clreol, *term_cr, *term_clrpag, *term_backspace; +char *term_pc; + +/* Non-zero if we determine that the terminal can do character insertion. */ +int terminal_can_insert = 0; + +/* How to insert characters. */ +char *term_im, *term_ei, *term_ic, *term_ip, *term_IC; + +/* How to delete characters. */ +char *term_dc, *term_DC; + +#if defined (HACK_TERMCAP_MOTION) +char *term_forward_char; +#endif /* HACK_TERMCAP_MOTION */ + +/* How to go up a line. */ +char *term_up; + +/* A visible bell, if the terminal can be made to flash the screen. */ +static char *visible_bell; + +/* Non-zero means the terminal can auto-wrap lines. */ +int _rl_term_autowrap; + +/* Non-zero means that this terminal has a meta key. */ +static int term_has_meta; + +/* The sequences to write to turn on and off the meta key, if this + terminal has one. */ +static char *term_mm, *term_mo; + +/* The key sequences output by the arrow keys, if this terminal has any. */ +static char *term_ku, *term_kd, *term_kr, *term_kl; + +/* How to initialize and reset the arrow keys, if this terminal has any. */ +static char *term_ks, *term_ke; + +/* The key sequences sent by the Home and End keys, if any. */ +static char *term_kh, *term_kH; + +/* Variables that hold the screen dimensions, used by the display code. */ +int screenwidth, screenheight, screenchars; + +/* Non-zero means the user wants to enable the keypad. */ +int _rl_enable_keypad; + +/* Non-zero means the user wants to enable a meta key. */ +int _rl_enable_meta = 1; + +/* Re-initialize the terminal considering that the TERM/TERMCAP variable + has changed. */ +int +rl_reset_terminal (terminal_name) + char *terminal_name; +{ + _rl_init_terminal_io (terminal_name); + return 0; +} + +#if !defined (SHELL) +static void +set_lines_and_columns (lines, cols) + int lines, cols; +{ + char *b; + +#if defined (HAVE_PUTENV) + b = xmalloc (24); + sprintf (b, "LINES=%d", lines); + putenv (b); + b = xmalloc (24); + sprintf (b, "COLUMNS=%d", cols); + putenv (b); +#else /* !HAVE_PUTENV */ +# if defined (HAVE_SETENV) + b = xmalloc (8); + sprintf (b, "%d", lines); + setenv ("LINES", b, 1); + b = xmalloc (8); + sprintf (b, "%d", cols); + setenv ("COLUMNS", b, 1); +# endif /* HAVE_SETENV */ +#endif /* !HAVE_PUTENV */ +} +#else /* SHELL */ +extern void set_lines_and_columns (); +#endif /* SHELL */ + +/* Get readline's idea of the screen size. TTY is a file descriptor open + to the terminal. If IGNORE_ENV is true, we do not pay attention to the + values of $LINES and $COLUMNS. The tests for TERM_STRING_BUFFER being + non-null serve to check whether or not we have initialized termcap. */ +void +_rl_get_screen_size (tty, ignore_env) + int tty, ignore_env; +{ + char *ss; +#if defined (TIOCGWINSZ) + struct winsize window_size; +#endif /* TIOCGWINSZ */ + +#if defined (TIOCGWINSZ) + if (ioctl (tty, TIOCGWINSZ, &window_size) == 0) + { + screenwidth = (int) window_size.ws_col; + screenheight = (int) window_size.ws_row; + } +#endif /* TIOCGWINSZ */ + + /* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV + is unset. */ + if (screenwidth <= 0) + { + if (ignore_env == 0 && (ss = getenv ("COLUMNS"))) + screenwidth = atoi (ss); + + if (screenwidth <= 0 && term_string_buffer) + screenwidth = tgetnum ("co"); + } + + /* Environment variable LINES overrides setting of "li" if IGNORE_ENV + is unset. */ + if (screenheight <= 0) + { + if (ignore_env == 0 && (ss = getenv ("LINES"))) + screenheight = atoi (ss); + + if (screenheight <= 0 && term_string_buffer) + screenheight = tgetnum ("li"); + } + + /* If all else fails, default to 80x24 terminal. */ + if (screenwidth <= 1) + screenwidth = 80; + + if (screenheight <= 0) + screenheight = 24; + + /* If we're being compiled as part of bash, set the environment + variables $LINES and $COLUMNS to new values. Otherwise, just + do a pair of putenv () or setenv () calls. */ + set_lines_and_columns (screenheight, screenwidth); + + if (!_rl_term_autowrap) + screenwidth--; + + screenchars = screenwidth * screenheight; +} + +void +_rl_set_screen_size (rows, cols) + int rows, cols; +{ + screenheight = rows; + screenwidth = cols; + + if (_rl_term_autowrap == 0) + screenwidth--; + + screenchars = screenwidth * screenheight; +} + +struct _tc_string { + char *tc_var; + char **tc_value; +}; + +/* This should be kept sorted, just in case we decide to change the + search algorithm to something smarter. */ +static struct _tc_string tc_strings[] = +{ + "DC", &term_DC, + "IC", &term_IC, + "ce", &term_clreol, + "cl", &term_clrpag, + "cr", &term_cr, + "dc", &term_dc, + "ei", &term_ei, + "ic", &term_ic, + "im", &term_im, + "kd", &term_kd, + "kh", &term_kh, /* home */ + "kH", &term_kH, /* end */ + "kl", &term_kl, + "kr", &term_kr, + "ku", &term_ku, + "ks", &term_ks, + "ke", &term_ke, + "le", &term_backspace, + "mm", &term_mm, + "mo", &term_mo, +#if defined (HACK_TERMCAP_MOTION) + "nd", &term_forward_char, +#endif + "pc", &term_pc, + "up", &term_up, + "vb", &visible_bell, +}; + +#define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string)) + +/* Read the desired terminal capability strings into BP. The capabilities + are described in the TC_STRINGS table. */ +static void +get_term_capabilities (bp) + char **bp; +{ + register int i; + + for (i = 0; i < NUM_TC_STRINGS; i++) + *(tc_strings[i].tc_value) = tgetstr (tc_strings[i].tc_var, bp); + tcap_initialized = 1; +} + +int +_rl_init_terminal_io (terminal_name) + char *terminal_name; +{ +#if defined (__GO32__) + screenwidth = ScreenCols (); + screenheight = ScreenRows (); + screenchars = screenwidth * screenheight; + term_cr = "\r"; + term_im = term_ei = term_ic = term_IC = (char *)NULL; + term_up = term_dc = term_DC = visible_bell = (char *)NULL; + + /* Does the __GO32__ have a meta key? I don't know. */ + term_has_meta = 0; + term_mm = term_mo = (char *)NULL; + + /* It probably has arrow keys, but I don't know what they are. */ + term_ku = term_kd = term_kr = term_kl = (char *)NULL; + +#if defined (HACK_TERMCAP_MOTION) + term_forward_char = (char *)NULL; +#endif /* HACK_TERMCAP_MOTION */ + terminal_can_insert = _rl_term_autowrap = 0; + return; +#else /* !__GO32__ */ + + char *term, *buffer; + int tty; + Keymap xkeymap; + + term = terminal_name ? terminal_name : getenv ("TERM"); + + if (term_string_buffer == 0) + term_string_buffer = xmalloc (2032); + + if (term_buffer == 0) + term_buffer = xmalloc (4080); + + buffer = term_string_buffer; + + term_clrpag = term_cr = term_clreol = (char *)NULL; + + if (term == 0) + term = "dumb"; + + if (tgetent (term_buffer, term) <= 0) + { + dumb_term = 1; + screenwidth = 79; + screenheight = 24; + screenchars = 79 * 24; + term_cr = "\r"; + term_im = term_ei = term_ic = term_IC = (char *)NULL; + term_up = term_dc = term_DC = visible_bell = (char *)NULL; + term_ku = term_kd = term_kl = term_kr = (char *)NULL; +#if defined (HACK_TERMCAP_MOTION) + term_forward_char = (char *)NULL; +#endif + terminal_can_insert = 0; + return 0; + } + + get_term_capabilities (&buffer); + + /* Set up the variables that the termcap library expects the application + to provide. */ + PC = term_pc ? *term_pc : 0; + BC = term_backspace; + UP = term_up; + + if (!term_cr) + term_cr = "\r"; + + tty = rl_instream ? fileno (rl_instream) : 0; + + screenwidth = screenheight = 0; + + _rl_term_autowrap = tgetflag ("am") && tgetflag ("xn"); + + _rl_get_screen_size (tty, 0); + + /* "An application program can assume that the terminal can do + character insertion if *any one of* the capabilities `IC', + `im', `ic' or `ip' is provided." But we can't do anything if + only `ip' is provided, so... */ + terminal_can_insert = (term_IC || term_im || term_ic); + + /* Check to see if this terminal has a meta key and clear the capability + variables if there is none. */ + term_has_meta = (tgetflag ("km") || tgetflag ("MT")); + if (!term_has_meta) + term_mm = term_mo = (char *)NULL; + + /* Attempt to find and bind the arrow keys. Do not override already + bound keys in an overzealous attempt, however. */ + xkeymap = _rl_keymap; + + _rl_keymap = emacs_standard_keymap; + _rl_bind_if_unbound (term_ku, rl_get_previous_history); + _rl_bind_if_unbound (term_kd, rl_get_next_history); + _rl_bind_if_unbound (term_kr, rl_forward); + _rl_bind_if_unbound (term_kl, rl_backward); + + _rl_bind_if_unbound (term_kh, rl_beg_of_line); /* Home */ + _rl_bind_if_unbound (term_kH, rl_end_of_line); /* End */ + +#if defined (VI_MODE) + _rl_keymap = vi_movement_keymap; + _rl_bind_if_unbound (term_ku, rl_get_previous_history); + _rl_bind_if_unbound (term_kd, rl_get_next_history); + _rl_bind_if_unbound (term_kr, rl_forward); + _rl_bind_if_unbound (term_kl, rl_backward); + + _rl_bind_if_unbound (term_kh, rl_beg_of_line); /* Home */ + _rl_bind_if_unbound (term_kH, rl_end_of_line); /* End */ +#endif /* VI_MODE */ + + _rl_keymap = xkeymap; + +#endif /* !__GO32__ */ + return 0; +} + +char * +rl_get_termcap (cap) + char *cap; +{ + register int i; + + if (tcap_initialized == 0) + return ((char *)NULL); + for (i = 0; i < NUM_TC_STRINGS; i++) + { + if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0) + return *(tc_strings[i].tc_value); + } + return ((char *)NULL); +} + +/* A function for the use of tputs () */ +int +_rl_output_character_function (c) + int c; +{ + return putc (c, _rl_out_stream); +} + +/* Write COUNT characters from STRING to the output stream. */ +void +_rl_output_some_chars (string, count) + char *string; + int count; +{ + fwrite (string, 1, count, _rl_out_stream); +} + +/* Move the cursor back. */ +int +_rl_backspace (count) + int count; +{ + register int i; + +#if !defined (__GO32__) + if (term_backspace) + for (i = 0; i < count; i++) + tputs (term_backspace, 1, _rl_output_character_function); + else +#endif /* !__GO32__ */ + for (i = 0; i < count; i++) + putc ('\b', _rl_out_stream); + return 0; +} + +/* Move to the start of the next line. */ +int +crlf () +{ +#if defined (NEW_TTY_DRIVER) + if (term_cr) + tputs (term_cr, 1, _rl_output_character_function); +#endif /* NEW_TTY_DRIVER */ + putc ('\n', _rl_out_stream); + return 0; +} + +/* Ring the terminal bell. */ +int +ding () +{ + if (readline_echoing_p) + { +#if !defined (__GO32__) + switch (_rl_bell_preference) + { + case NO_BELL: + default: + break; + case VISIBLE_BELL: + if (visible_bell) + { + tputs (visible_bell, 1, _rl_output_character_function); + break; + } + /* FALLTHROUGH */ + case AUDIBLE_BELL: + fprintf (stderr, "\007"); + fflush (stderr); + break; + } +#else /* __GO32__ */ + fprintf (stderr, "\007"); + fflush (stderr); +#endif /* __GO32__ */ + return (0); + } + return (-1); +} + +/* **************************************************************** */ +/* */ +/* Controlling the Meta Key and Keypad */ +/* */ +/* **************************************************************** */ + +static int +outchar (c) + int c; +{ + return putc (c, rl_outstream); +} + +int +_rl_enable_meta_key () +{ + if (term_has_meta && term_mm) + tputs (term_mm, 1, outchar); +} + +void +_rl_control_keypad (on) + int on; +{ + if (on && term_ks) + tputs (term_ks, 1, outchar); + else if (!on && term_ke) + tputs (term_ke, 1, outchar); +} diff --git a/lib/readline/tilde.c b/lib/readline/tilde.c index da75d95..69f5768 100644 --- a/lib/readline/tilde.c +++ b/lib/readline/tilde.c @@ -19,6 +19,10 @@ along with Readline; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ +#if defined (HAVE_CONFIG_H) +# include <config.h> +#endif + #if defined (HAVE_STRING_H) # include <string.h> #else /* !HAVE_STRING_H */ @@ -31,13 +35,14 @@ # include "ansi_stdlib.h" #endif /* HAVE_STDLIB_H */ -#include "tilde.h" #include <sys/types.h> #include <pwd.h> -#if defined (USG) && !defined (HAVE_GETPW_DECLS) +#include "tilde.h" + +#if !defined (HAVE_GETPW_DECLS) extern struct passwd *getpwuid (), *getpwnam (); -#endif /* USG && !defined (HAVE_GETPW_DECLS) */ +#endif /* !HAVE_GETPW_DECLS */ #if !defined (savestring) extern char *xmalloc (); @@ -171,7 +176,7 @@ tilde_expand (string) /* Copy the skipped text into the result. */ if ((result_index + start + 1) > result_size) - result = (char *)xrealloc (result, 1 + (result_size += (start + 20))); + result = xrealloc (result, 1 + (result_size += (start + 20))); strncpy (result + result_index, string, start); result_index += start; @@ -188,7 +193,7 @@ tilde_expand (string) break; /* Expand the entire tilde word, and copy it into RESULT. */ - tilde_word = (char *)xmalloc (1 + end); + tilde_word = xmalloc (1 + end); strncpy (tilde_word, string, end); tilde_word[end] = '\0'; string += end; @@ -198,7 +203,7 @@ tilde_expand (string) len = strlen (expansion); if ((result_index + len + 1) > result_size) - result = (char *)xrealloc (result, 1 + (result_size += (len + 20))); + result = xrealloc (result, 1 + (result_size += (len + 20))); strcpy (result + result_index, expansion); result_index += len; @@ -217,85 +222,90 @@ tilde_expand_word (filename) char *filename; { char *dirname; + char *temp_name; - dirname = filename ? savestring (filename) : (char *)NULL; + if (filename == (char *)0) + return ((char *)NULL); - if (dirname && *dirname == '~') + dirname = savestring (filename); + + if (*dirname != '~') + return (dirname); + + if (!dirname[1] || dirname[1] == '/') { - char *temp_name; - if (!dirname[1] || dirname[1] == '/') + /* Prepend $HOME to the rest of the string. */ + char *temp_home = (char *)getenv ("HOME"); + int home_len; + + /* If there is no HOME variable, look up the directory in + the password database. */ + if (!temp_home) { - /* Prepend $HOME to the rest of the string. */ - char *temp_home = (char *)getenv ("HOME"); + struct passwd *entry; - /* If there is no HOME variable, look up the directory in - the password database. */ - if (!temp_home) - { - struct passwd *entry; + entry = getpwuid (getuid ()); + if (entry) + temp_home = entry->pw_dir; + } - entry = getpwuid (getuid ()); - if (entry) - temp_home = entry->pw_dir; - } + home_len = temp_home ? strlen (temp_home) : 0; + temp_name = xmalloc (1 + strlen (dirname + 1) + home_len); + + if (temp_home) + strcpy (temp_name, temp_home); + strcpy (temp_name + home_len, dirname + 1); + free (dirname); + dirname = temp_name; + } + else + { + char *username; + struct passwd *user_entry; + int i, len; - temp_name = xmalloc (1 + strlen (&dirname[1]) - + (temp_home ? strlen (temp_home) : 0)); - temp_name[0] = '\0'; - if (temp_home) - strcpy (temp_name, temp_home); - strcat (temp_name, dirname + 1); - free (dirname); - dirname = temp_name; - } - else + username = xmalloc (strlen (dirname)); + for (i = 1; dirname[i] && dirname[i] != '/'; i++) + username[i - 1] = dirname[i]; + username[i - 1] = '\0'; + + if ((user_entry = getpwnam (username)) == (struct passwd *)0) { - char *username; - struct passwd *user_entry; - int i; + /* If the calling program has a special syntax for + expanding tildes, and we couldn't find a standard + expansion, then let them try. */ + if (tilde_expansion_failure_hook) + { + char *expansion; - username = xmalloc (strlen (dirname)); - for (i = 1; dirname[i] && dirname[i] != '/'; i++) - username[i - 1] = dirname[i]; - username[i - 1] = '\0'; + expansion = (*tilde_expansion_failure_hook) (username); - if ((user_entry = getpwnam (username)) == 0) - { - /* If the calling program has a special syntax for - expanding tildes, and we couldn't find a standard - expansion, then let them try. */ - if (tilde_expansion_failure_hook) + if (expansion) { - char *expansion; - - expansion = (*tilde_expansion_failure_hook) (username); - - if (expansion) - { - temp_name = xmalloc (1 + strlen (expansion) - + strlen (&dirname[i])); - strcpy (temp_name, expansion); - strcat (temp_name, &dirname[i]); - free (expansion); - free (dirname); - dirname = temp_name; - } + len = strlen (expansion); + temp_name = xmalloc (1 + len + strlen (dirname + i)); + strcpy (temp_name, expansion); + strcpy (temp_name + len, dirname + i); + free (expansion); + free (dirname); + dirname = temp_name; } - /* We shouldn't report errors. */ - } - else - { - temp_name = xmalloc (1 + strlen (user_entry->pw_dir) - + strlen (&dirname[i])); - strcpy (temp_name, user_entry->pw_dir); - strcat (temp_name, &dirname[i]); - free (dirname); - dirname = temp_name; } - endpwent (); - free (username); + /* We shouldn't report errors. */ } + else + { + len = strlen (user_entry->pw_dir); + temp_name = xmalloc (1 + len + strlen (dirname + i)); + strcpy (temp_name, user_entry->pw_dir); + strcpy (temp_name + len, dirname + i); + free (dirname); + dirname = temp_name; + } + endpwent (); + free (username); } + return (dirname); } @@ -368,7 +378,7 @@ xrealloc (pointer, bytes) static void memory_error_and_abort () { - fprintf (stderr, "readline: Out of virtual memory!\n"); + fprintf (stderr, "readline: out of virtual memory\n"); abort (); } diff --git a/lib/readline/tilde.h b/lib/readline/tilde.h index 726d081..6f0898c 100644 --- a/lib/readline/tilde.h +++ b/lib/readline/tilde.h @@ -1,11 +1,32 @@ /* tilde.h: Externally available variables and function in libtilde.a. */ -#if !defined (__TILDE_H__) -# define __TILDE_H__ +/* Copyright (C) 1992 Free Software Foundation, Inc. + + This file contains the Readline Library (the Library), a set of + routines for providing Emacs style line input to programs that ask + for it. + + The Library is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + The Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + The GNU General Public License is often shipped with GNU software, and + is generally kept in a file called COPYING or LICENSE. If you do not + have a copy of the license, write to the Free Software Foundation, + 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#if !defined (_TILDE_H_) +# define _TILDE_H_ /* Function pointers can be declared as (Function *)foo. */ -#if !defined (__FUNCTION_DEF) -# define __FUNCTION_DEF +#if !defined (_FUNCTION_DEF) +# define _FUNCTION_DEF typedef int Function (); typedef void VFunction (); typedef char *CPFunction (); @@ -35,4 +56,4 @@ extern char *tilde_expand (); tilde. If there is no expansion, call tilde_expansion_failure_hook. */ extern char *tilde_expand_word (); -#endif /* __TILDE_H__ */ +#endif /* _TILDE_H_ */ diff --git a/lib/readline/undo.c b/lib/readline/undo.c new file mode 100644 index 0000000..af7ccc3 --- /dev/null +++ b/lib/readline/undo.c @@ -0,0 +1,261 @@ +/* readline.c -- a general facility for reading lines of input + with emacs style editing and completion. */ + +/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library, a library for + reading lines of text with interactive input and history editing. + + The GNU Readline Library is free software; you can redistribute it + and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 1, or + (at your option) any later version. + + The GNU Readline Library is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + The GNU General Public License is often shipped with GNU software, and + is generally kept in a file called COPYING or LICENSE. If you do not + have a copy of the license, write to the Free Software Foundation, + 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include <config.h> +#endif + +#include <sys/types.h> + +#if defined (HAVE_UNISTD_H) +# include <unistd.h> /* for _POSIX_VERSION */ +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include <stdlib.h> +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include <setjmp.h> +#include <stdio.h> + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#define SWAP(s, e) do { int t; t = s; s = e; e = t; } while (0) + +/* Non-zero tells rl_delete_text and rl_insert_text to not add to + the undo list. */ +int _rl_doing_an_undo = 0; + +/* How many unclosed undo groups we currently have. */ +int _rl_undo_group_level = 0; + +/* The current undo list for THE_LINE. */ +UNDO_LIST *rl_undo_list = (UNDO_LIST *)NULL; + +/* **************************************************************** */ +/* */ +/* Undo, and Undoing */ +/* */ +/* **************************************************************** */ + +/* Remember how to undo something. Concatenate some undos if that + seems right. */ +void +rl_add_undo (what, start, end, text) + enum undo_code what; + int start, end; + char *text; +{ + UNDO_LIST *temp = (UNDO_LIST *)xmalloc (sizeof (UNDO_LIST)); + temp->what = what; + temp->start = start; + temp->end = end; + temp->text = text; + temp->next = rl_undo_list; + rl_undo_list = temp; +} + +/* Free the existing undo list. */ +void +free_undo_list () +{ + while (rl_undo_list) + { + UNDO_LIST *release = rl_undo_list; + rl_undo_list = rl_undo_list->next; + + if (release->what == UNDO_DELETE) + free (release->text); + + free (release); + } + rl_undo_list = (UNDO_LIST *)NULL; +} + +/* Undo the next thing in the list. Return 0 if there + is nothing to undo, or non-zero if there was. */ +int +rl_do_undo () +{ + UNDO_LIST *release; + int waiting_for_begin = 0; + int start, end; + +#define TRANS(i) ((i) == -1 ? rl_point : ((i) == -2 ? rl_end : (i))) + + do + { + if (!rl_undo_list) + return (0); + + _rl_doing_an_undo = 1; + + /* To better support vi-mode, a start or end value of -1 means + rl_point, and a value of -2 means rl_end. */ + if (rl_undo_list->what == UNDO_DELETE || rl_undo_list->what == UNDO_INSERT) + { + start = TRANS (rl_undo_list->start); + end = TRANS (rl_undo_list->end); + } + + switch (rl_undo_list->what) + { + /* Undoing deletes means inserting some text. */ + case UNDO_DELETE: + rl_point = start; + rl_insert_text (rl_undo_list->text); + free (rl_undo_list->text); + break; + + /* Undoing inserts means deleting some text. */ + case UNDO_INSERT: + rl_delete_text (start, end); + rl_point = start; + break; + + /* Undoing an END means undoing everything 'til we get to a BEGIN. */ + case UNDO_END: + waiting_for_begin++; + break; + + /* Undoing a BEGIN means that we are done with this group. */ + case UNDO_BEGIN: + if (waiting_for_begin) + waiting_for_begin--; + else + ding (); + break; + } + + _rl_doing_an_undo = 0; + + release = rl_undo_list; + rl_undo_list = rl_undo_list->next; + free (release); + } + while (waiting_for_begin); + + return (1); +} +#undef TRANS + +int +_rl_fix_last_undo_of_type (type, start, end) + int type, start, end; +{ + UNDO_LIST *rl; + + for (rl = rl_undo_list; rl; rl = rl->next) + { + if (rl->what == type) + { + rl->start = start; + rl->end = end; + return 0; + } + } + return 1; +} + +/* Begin a group. Subsequent undos are undone as an atomic operation. */ +int +rl_begin_undo_group () +{ + rl_add_undo (UNDO_BEGIN, 0, 0, 0); + _rl_undo_group_level++; + return 0; +} + +/* End an undo group started with rl_begin_undo_group (). */ +int +rl_end_undo_group () +{ + rl_add_undo (UNDO_END, 0, 0, 0); + _rl_undo_group_level--; + return 0; +} + +/* Save an undo entry for the text from START to END. */ +int +rl_modifying (start, end) + int start, end; +{ + if (start > end) + { + SWAP (start, end); + } + + if (start != end) + { + char *temp = rl_copy_text (start, end); + rl_begin_undo_group (); + rl_add_undo (UNDO_DELETE, start, end, temp); + rl_add_undo (UNDO_INSERT, start, end, (char *)NULL); + rl_end_undo_group (); + } + return 0; +} + +/* Revert the current line to its previous state. */ +int +rl_revert_line (count, key) + int count, key; +{ + if (!rl_undo_list) + ding (); + else + { + while (rl_undo_list) + rl_do_undo (); + } + return 0; +} + +/* Do some undoing of things that were done. */ +int +rl_undo_command (count, key) + int count, key; +{ + if (count < 0) + return 0; /* Nothing to do. */ + + while (count) + { + if (rl_do_undo ()) + count--; + else + { + ding (); + break; + } + } + return 0; +} diff --git a/lib/readline/util.c b/lib/readline/util.c new file mode 100644 index 0000000..f63293a --- /dev/null +++ b/lib/readline/util.c @@ -0,0 +1,315 @@ +/* util.c -- readline utility functions */ + +/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library, a library for + reading lines of text with interactive input and history editing. + + The GNU Readline Library is free software; you can redistribute it + and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 1, or + (at your option) any later version. + + The GNU Readline Library is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + The GNU General Public License is often shipped with GNU software, and + is generally kept in a file called COPYING or LICENSE. If you do not + have a copy of the license, write to the Free Software Foundation, + 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include <config.h> +#endif + +#include <stdio.h> +#include <sys/types.h> +#include <fcntl.h> +#include <setjmp.h> +#include <ctype.h> + +#if defined (HAVE_UNISTD_H) +# include <unistd.h> /* for _POSIX_VERSION */ +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include <stdlib.h> +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" + +#if defined (TIOCSTAT_IN_SYS_IOCTL) +# include <sys/ioctl.h> +#endif /* TIOCSTAT_IN_SYS_IOCTL */ + +/* Some standard library routines. */ +#include "readline.h" + +#define SWAP(s, e) do { int t; t = s; s = e; e = t; } while (0) + +/* Pseudo-globals imported from readline.c */ +extern int readline_echoing_p; +extern jmp_buf readline_top_level; +extern int rl_line_buffer_len; +extern Function *rl_last_func; + +extern int _rl_defining_kbd_macro; +extern char *_rl_executing_macro; + +/* Pseudo-global functions imported from other library files. */ +extern void _rl_pop_executing_macro (); +extern void _rl_set_the_line (); +extern void _rl_init_argument (); + +extern char *xmalloc (), *xrealloc (); + +/* **************************************************************** */ +/* */ +/* Utility Functions */ +/* */ +/* **************************************************************** */ + +/* Return 0 if C is not a member of the class of characters that belong + in words, or 1 if it is. */ + +int _rl_allow_pathname_alphabetic_chars = 0; +static char *pathname_alphabetic_chars = "/-_=~.#$"; + +int +alphabetic (c) + int c; +{ + if (ALPHABETIC (c)) + return (1); + + return (_rl_allow_pathname_alphabetic_chars && + strchr (pathname_alphabetic_chars, c) != NULL); +} + +/* How to abort things. */ +int +_rl_abort_internal () +{ + ding (); + rl_clear_message (); + _rl_init_argument (); + rl_pending_input = 0; + + _rl_defining_kbd_macro = 0; + while (_rl_executing_macro) + _rl_pop_executing_macro (); + + rl_last_func = (Function *)NULL; + longjmp (readline_top_level, 1); + return (0); +} + +int +rl_abort (count, key) + int count, key; +{ + return (_rl_abort_internal ()); +} + +int +rl_tty_status (count, key) + int count, key; +{ +#if defined (TIOCSTAT) + ioctl (1, TIOCSTAT, (char *)0); + rl_refresh_line (); +#else + ding (); +#endif + return 0; +} + +/* Return a copy of the string between FROM and TO. + FROM is inclusive, TO is not. */ +char * +rl_copy_text (from, to) + int from, to; +{ + register int length; + char *copy; + + /* Fix it if the caller is confused. */ + if (from > to) + SWAP (from, to); + + length = to - from; + copy = xmalloc (1 + length); + strncpy (copy, rl_line_buffer + from, length); + copy[length] = '\0'; + return (copy); +} + +/* Increase the size of RL_LINE_BUFFER until it has enough space to hold + LEN characters. */ +void +rl_extend_line_buffer (len) + int len; +{ + while (len >= rl_line_buffer_len) + { + rl_line_buffer_len += DEFAULT_BUFFER_SIZE; + rl_line_buffer = xrealloc (rl_line_buffer, rl_line_buffer_len); + } + + _rl_set_the_line (); +} + +/* **************************************************************** */ +/* */ +/* String Utility Functions */ +/* */ +/* **************************************************************** */ + +/* Determine if s2 occurs in s1. If so, return a pointer to the + match in s1. The compare is case insensitive. */ +char * +_rl_strindex (s1, s2) + register char *s1, *s2; +{ + register int i, l, len; + + for (i = 0, l = strlen (s2), len = strlen (s1); (len - i) >= l; i++) + if (_rl_strnicmp (s1 + i, s2, l) == 0) + return (s1 + i); + return ((char *)NULL); +} + +#if !defined (HAVE_STRCASECMP) +/* Compare at most COUNT characters from string1 to string2. Case + doesn't matter. */ +int +_rl_strnicmp (string1, string2, count) + char *string1, *string2; + int count; +{ + register char ch1, ch2; + + while (count) + { + ch1 = *string1++; + ch2 = *string2++; + if (_rl_to_upper(ch1) == _rl_to_upper(ch2)) + count--; + else + break; + } + return (count); +} + +/* strcmp (), but caseless. */ +int +_rl_stricmp (string1, string2) + char *string1, *string2; +{ + register char ch1, ch2; + + while (*string1 && *string2) + { + ch1 = *string1++; + ch2 = *string2++; + if (_rl_to_upper(ch1) != _rl_to_upper(ch2)) + return (1); + } + return (*string1 - *string2); +} +#endif /* !HAVE_STRCASECMP */ + +/* Stupid comparison routine for qsort () ing strings. */ +int +_rl_qsort_string_compare (s1, s2) + char **s1, **s2; +{ +#if defined (HAVE_STRCOLL) + return (strcoll (*s1, *s2)); +#else + int result; + + result = **s1 - **s2; + if (result == 0) + result = strcmp (*s1, *s2); + + return result; +#endif +} + +#if !defined (SHELL) +#ifdef savestring +#undef savestring +#endif +/* Backwards compatibility, now that savestring has been removed from + all `public' readline header files. */ +char * +savestring (s) + char *s; +{ + return ((char *)strcpy (xmalloc (1 + (int)strlen (s)), (s))); +} +#endif /* !SHELL */ + +/* Function equivalents for the macros defined in chartypes.h. */ +#undef _rl_uppercase_p +int +_rl_uppercase_p (c) + int c; +{ + return (isupper (c)); +} + +#undef _rl_lowercase_p +int +_rl_lowercase_p (c) + int c; +{ + return (islower (c)); +} + +#undef _rl_pure_alphabetic +int +_rl_pure_alphabetic (c) + int c; +{ + return (isupper (c) || islower (c)); +} + +#undef _rl_digit_p +int +_rl_digit_p (c) + int c; +{ + return (isdigit (c)); +} + +#undef _rl_to_lower +int +_rl_to_lower (c) + int c; +{ + return (isupper (c) ? tolower (c) : c); +} + +#undef _rl_to_upper +int +_rl_to_upper (c) + int c; +{ + return (islower (c) ? toupper (c) : c); +} + +#undef _rl_digit_value +int +_rl_digit_value (c) + int c; +{ + return (isdigit (c) ? c - '0' : c); +} diff --git a/lib/readline/vi_keymap.c b/lib/readline/vi_keymap.c index b8b3123..14929a3 100644 --- a/lib/readline/vi_keymap.c +++ b/lib/readline/vi_keymap.c @@ -65,13 +65,13 @@ KEYMAP_ENTRY_ARRAY vi_movement_keymap = { { ISFUNC, (Function *)0x0 }, /* Control-\ */ { ISFUNC, (Function *)0x0 }, /* Control-] */ { ISFUNC, (Function *)0x0 }, /* Control-^ */ - { ISFUNC, rl_undo_command }, /* Control-_ */ + { ISFUNC, rl_vi_undo }, /* Control-_ */ /* The start of printing characters. */ { ISFUNC, rl_forward }, /* SPACE */ { ISFUNC, (Function *)0x0 }, /* ! */ { ISFUNC, (Function *)0x0 }, /* " */ - { ISFUNC, rl_vi_comment }, /* # */ + { ISFUNC, rl_insert_comment }, /* # */ { ISFUNC, rl_end_of_line }, /* $ */ { ISFUNC, rl_vi_match }, /* % */ { ISFUNC, rl_vi_tilde_expand }, /* & */ @@ -140,7 +140,7 @@ KEYMAP_ENTRY_ARRAY vi_movement_keymap = { { ISFUNC, (Function *)0x0 }, /* ] */ { ISFUNC, rl_vi_first_print }, /* ^ */ { ISFUNC, rl_vi_yank_arg }, /* _ */ - { ISFUNC, (Function *)0x0 }, /* ` */ + { ISFUNC, rl_vi_goto_mark }, /* ` */ /* Lowercase alphabet. */ { ISFUNC, rl_vi_append_mode }, /* a */ @@ -155,7 +155,7 @@ KEYMAP_ENTRY_ARRAY vi_movement_keymap = { { ISFUNC, rl_get_next_history }, /* j */ { ISFUNC, rl_get_previous_history }, /* k */ { ISFUNC, rl_forward }, /* l */ - { ISFUNC, (Function *)0x0 }, /* m */ + { ISFUNC, rl_vi_set_mark }, /* m */ { ISFUNC, rl_vi_search_again }, /* n */ { ISFUNC, (Function *)0x0 }, /* o */ { ISFUNC, rl_vi_put }, /* p */ @@ -163,7 +163,7 @@ KEYMAP_ENTRY_ARRAY vi_movement_keymap = { { ISFUNC, rl_vi_change_char }, /* r */ { ISFUNC, rl_vi_subst }, /* s */ { ISFUNC, rl_vi_char_search }, /* t */ - { ISFUNC, rl_undo_command }, /* u */ + { ISFUNC, rl_vi_undo }, /* u */ { ISFUNC, (Function *)0x0 }, /* v */ { ISFUNC, rl_vi_next_word }, /* w */ { ISFUNC, rl_vi_delete }, /* x */ @@ -345,7 +345,7 @@ KEYMAP_ENTRY_ARRAY vi_insertion_keymap = { { ISFUNC, rl_insert }, /* Control-\ */ { ISFUNC, rl_insert }, /* Control-] */ { ISFUNC, rl_insert }, /* Control-^ */ - { ISFUNC, rl_undo_command }, /* Control-_ */ + { ISFUNC, rl_vi_undo }, /* Control-_ */ /* The start of printing characters. */ { ISFUNC, rl_insert }, /* SPACE */ @@ -630,7 +630,7 @@ KEYMAP_ENTRY_ARRAY vi_escape_keymap = { { ISFUNC, (Function *)0x0 }, /* Control-\ */ { ISFUNC, (Function *)0x0 }, /* Control-] */ { ISFUNC, (Function *)0x0 }, /* Control-^ */ - { ISFUNC, rl_undo_command }, /* Control-_ */ + { ISFUNC, rl_vi_undo }, /* Control-_ */ /* The start of printing characters. */ { ISFUNC, (Function *)0x0 }, /* SPACE */ diff --git a/lib/readline/vi_mode.c b/lib/readline/vi_mode.c index d0b9310..c730296 100644 --- a/lib/readline/vi_mode.c +++ b/lib/readline/vi_mode.c @@ -31,6 +31,10 @@ #if defined (VI_MODE) +#if defined (HAVE_CONFIG_H) +# include <config.h> +#endif + #include <sys/types.h> #if defined (HAVE_STDLIB_H) @@ -50,12 +54,12 @@ #include "readline.h" #include "history.h" -#ifndef digit_p -#define digit_p(c) ((c) >= '0' && (c) <= '9') +#ifndef _rl_digit_p +#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9') #endif -#ifndef digit_value -#define digit_value(c) ((c) - '0') +#ifndef _rl_digit_value +#define _rl_digit_value(c) ((c) - '0') #endif #ifndef member @@ -63,22 +67,14 @@ #endif #ifndef isident -#define isident(c) ((pure_alphabetic (c) || digit_p (c) || c == '_')) +#define isident(c) ((_rl_pure_alphabetic (c) || _rl_digit_p (c) || c == '_')) #endif #ifndef exchange #define exchange(x, y) do {int temp = x; x = y; y = temp;} while (0) #endif -#ifndef VI_COMMENT_BEGIN_DEFAULT -#define VI_COMMENT_BEGIN_DEFAULT "#" -#endif - -#if defined (STATIC_MALLOC) -static char *xmalloc (), *xrealloc (); -#else extern char *xmalloc (), *xrealloc (); -#endif /* STATIC_MALLOC */ /* Variables imported from readline.c */ extern int rl_point, rl_end, rl_mark, rl_done; @@ -89,48 +85,64 @@ extern char *rl_prompt; extern char *rl_line_buffer; extern int rl_arg_sign; +extern int _rl_doing_an_undo; +extern int _rl_undo_group_level; + extern void _rl_dispatch (); +extern int _rl_char_search_internal (); extern void rl_extend_line_buffer (); extern int rl_vi_check (); /* Non-zero means enter insertion mode. */ -static int _rl_vi_doing_insert = 0; +static int _rl_vi_doing_insert; -/* String inserted into the line by rl_vi_comment (). */ -char *rl_vi_comment_begin = (char *)NULL; - -/* *** UNCLEAN *** */ /* Command keys which do movement for xxx_to commands. */ static char *vi_motion = " hl^$0ftFt;,%wbeWBE|"; /* Keymap used for vi replace characters. Created dynamically since rarely used. */ -static Keymap vi_replace_map = (Keymap)NULL; +static Keymap vi_replace_map; /* The number of characters inserted in the last replace operation. */ -static int vi_replace_count = 0; +static int vi_replace_count; /* If non-zero, we have text inserted after a c[motion] command that put us implicitly into insert mode. Some people want this text to be attached to the command so that it is `redoable' with `.'. */ -static int vi_continued_command = 0; +static int vi_continued_command; +static char *vi_insert_buffer; +static int vi_insert_buffer_size; static int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */ static int _rl_vi_last_repeat = 1; static int _rl_vi_last_arg_sign = 1; -static int _rl_vi_last_motion = 0; -static int _rl_vi_last_search_char = 0; -static int _rl_vi_last_replacement = 0; +static int _rl_vi_last_motion; +static int _rl_vi_last_search_char; +static int _rl_vi_last_replacement; + +static int _rl_vi_last_key_before_insert; -static int vi_redoing = 0; +static int vi_redoing; /* Text modification commands. These are the `redoable' commands. */ static char *vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~"; +/* Arrays for the saved marks. */ +static int vi_mark_chars[27]; + static int rl_digit_loop1 (); void +_rl_vi_initialize_line () +{ + register int i; + + for (i = 0; i < sizeof (vi_mark_chars) / sizeof (int); i++) + vi_mark_chars[i] = -1; +} + +void _rl_vi_reset_last () { _rl_vi_last_command = 'i'; @@ -150,15 +162,26 @@ _rl_vi_set_last (key, repeat, sign) /* Is the command C a VI mode text modification command? */ int -rl_vi_textmod_command (c) +_rl_vi_textmod_command (c) int c; { return (member (c, vi_textmod)); } +static void +_rl_vi_stuff_insert (count) + int count; +{ + rl_begin_undo_group (); + while (count--) + rl_insert_text (vi_insert_buffer); + rl_end_undo_group (); +} + /* Bound to `.'. Called from command mode, so we know that we have to redo a text modification command. The default for _rl_vi_last_command puts you back into insert mode. */ +int rl_vi_redo (count, c) int count, c; { @@ -169,13 +192,32 @@ rl_vi_redo (count, c) } vi_redoing = 1; - _rl_dispatch (_rl_vi_last_command, _rl_keymap); + /* If we're redoing an insert with `i', stuff in the inserted text + and do not go into insertion mode. */ + if (_rl_vi_last_command == 'i' && vi_insert_buffer && *vi_insert_buffer) + { + _rl_vi_stuff_insert (count); + /* And back up point over the last character inserted. */ + if (rl_point > 0) + rl_point--; + } + else + _rl_dispatch (_rl_vi_last_command, _rl_keymap); vi_redoing = 0; return (0); } + +/* A placeholder for further expansion. */ +int +rl_vi_undo (count, key) + int count, key; +{ + return (rl_undo_command (count, key)); +} /* Yank the nth arg from the previous line into this line at point. */ +int rl_vi_yank_arg (count, key) int count, key; { @@ -191,10 +233,11 @@ rl_vi_yank_arg (count, key) /* With an argument, move back that many history lines, else move to the beginning of history. */ +int rl_vi_fetch_history (count, c) int count, c; { - int current = where_history (); + int wanted; /* Giving an argument of n means we want the nth command in the history file. The command number is interpreted the same way that the bash @@ -203,11 +246,11 @@ rl_vi_fetch_history (count, c) output of `history'. */ if (rl_explicit_arg) { - int wanted = history_base + current - count; + wanted = history_base + where_history () - count; if (wanted <= 0) rl_beginning_of_history (0, 0); else - rl_get_previous_history (wanted); + rl_get_previous_history (wanted, c); } else rl_beginning_of_history (count, 0); @@ -215,6 +258,7 @@ rl_vi_fetch_history (count, c) } /* Search again for the last thing searched for. */ +int rl_vi_search_again (count, key) int count, key; { @@ -232,6 +276,7 @@ rl_vi_search_again (count, key) } /* Do a vi style search. */ +int rl_vi_search (count, key) int count, key; { @@ -253,6 +298,7 @@ rl_vi_search (count, key) } /* Completion, from vi's point of view. */ +int rl_vi_complete (ignore, key) int ignore, key; { @@ -281,6 +327,7 @@ rl_vi_complete (ignore, key) } /* Tilde expansion for vi mode. */ +int rl_vi_tilde_expand (ignore, key) int ignore, key; { @@ -291,6 +338,7 @@ rl_vi_tilde_expand (ignore, key) } /* Previous word in vi mode. */ +int rl_vi_prev_word (count, key) int count, key; { @@ -303,7 +351,7 @@ rl_vi_prev_word (count, key) return (0); } - if (uppercase_p (key)) + if (_rl_uppercase_p (key)) rl_vi_bWord (count); else rl_vi_bword (count); @@ -312,6 +360,7 @@ rl_vi_prev_word (count, key) } /* Next word in vi mode. */ +int rl_vi_next_word (count, key) int count, key; { @@ -324,7 +373,7 @@ rl_vi_next_word (count, key) return (0); } - if (uppercase_p (key)) + if (_rl_uppercase_p (key)) rl_vi_fWord (count); else rl_vi_fword (count); @@ -332,6 +381,7 @@ rl_vi_next_word (count, key) } /* Move to the end of the ?next? word. */ +int rl_vi_end_word (count, key) int count, key; { @@ -341,7 +391,7 @@ rl_vi_end_word (count, key) return -1; } - if (uppercase_p (key)) + if (_rl_uppercase_p (key)) rl_vi_eWord (count); else rl_vi_eword (count); @@ -349,6 +399,7 @@ rl_vi_end_word (count, key) } /* Move forward a word the way that 'W' does. */ +int rl_vi_fWord (count) int count; { @@ -365,6 +416,7 @@ rl_vi_fWord (count) return (0); } +int rl_vi_bWord (count) int count; { @@ -388,6 +440,7 @@ rl_vi_bWord (count) return (0); } +int rl_vi_eWord (count) int count; { @@ -417,6 +470,7 @@ rl_vi_eWord (count) return (0); } +int rl_vi_fword (count) int count; { @@ -442,6 +496,7 @@ rl_vi_fword (count) return (0); } +int rl_vi_bword (count) int count; { @@ -480,6 +535,7 @@ rl_vi_bword (count) return (0); } +int rl_vi_eword (count) int count; { @@ -504,6 +560,7 @@ rl_vi_eword (count) return (0); } +int rl_vi_insert_beg (count, key) int count, key; { @@ -512,6 +569,7 @@ rl_vi_insert_beg (count, key) return (0); } +int rl_vi_append_mode (count, key) int count, key; { @@ -521,6 +579,7 @@ rl_vi_append_mode (count, key) return (0); } +int rl_vi_append_eol (count, key) int count, key; { @@ -530,6 +589,7 @@ rl_vi_append_eol (count, key) } /* What to do in the case of C-d. */ +int rl_vi_eof_maybe (count, c) int count, c; { @@ -540,13 +600,33 @@ rl_vi_eof_maybe (count, c) /* Switching from one mode to the other really just involves switching keymaps. */ +int rl_vi_insertion_mode (count, key) int count, key; { _rl_keymap = vi_insertion_keymap; + _rl_vi_last_key_before_insert = key; return (0); } +static void +_rl_vi_save_insert (up) + UNDO_LIST *up; +{ + int len, start, end; + + start = up->start; + end = up->end; + len = end - start + 1; + if (len >= vi_insert_buffer_size) + { + vi_insert_buffer_size += (len + 32) - (len % 32); + vi_insert_buffer = xrealloc (vi_insert_buffer, vi_insert_buffer_size); + } + strncpy (vi_insert_buffer, rl_line_buffer + start, len - 1); + vi_insert_buffer[len-1] = '\0'; +} + void _rl_vi_done_inserting () { @@ -555,38 +635,49 @@ _rl_vi_done_inserting () rl_end_undo_group (); /* Now, the text between rl_undo_list->next->start and rl_undo_list->next->end is what was inserted while in insert - mode. */ + mode. It gets copied to VI_INSERT_BUFFER because it depends + on absolute indices into the line which may change (though they + probably will not). */ _rl_vi_doing_insert = 0; + _rl_vi_save_insert (rl_undo_list->next); vi_continued_command = 1; } else - vi_continued_command = 0; + { + if (_rl_vi_last_key_before_insert == 'i' && rl_undo_list) + _rl_vi_save_insert (rl_undo_list); + /* XXX - Other keys probably need to be checked. */ + else if (_rl_vi_last_key_before_insert == 'C') + rl_end_undo_group (); + while (_rl_undo_group_level > 0) + rl_end_undo_group (); + vi_continued_command = 0; + } } +int rl_vi_movement_mode (count, key) int count, key; { if (rl_point > 0) - rl_backward (1); - -#if 0 - _rl_vi_reset_last (); -#endif + rl_backward (1, key); _rl_keymap = vi_movement_keymap; _rl_vi_done_inserting (); return (0); } +int rl_vi_arg_digit (count, c) int count, c; { if (c == '0' && rl_numeric_arg == 1 && !rl_explicit_arg) - return (rl_beg_of_line ()); + return (rl_beg_of_line (1, c)); else return (rl_digit_argument (count, c)); } +int rl_vi_change_case (count, ignore) int count, ignore; { @@ -598,14 +689,14 @@ rl_vi_change_case (count, ignore) while (count-- && rl_point < rl_end) { - if (uppercase_p (rl_line_buffer[rl_point])) - c = to_lower (rl_line_buffer[rl_point]); - else if (lowercase_p (rl_line_buffer[rl_point])) - c = to_upper (rl_line_buffer[rl_point]); + if (_rl_uppercase_p (rl_line_buffer[rl_point])) + c = _rl_to_lower (rl_line_buffer[rl_point]); + else if (_rl_lowercase_p (rl_line_buffer[rl_point])) + c = _rl_to_upper (rl_line_buffer[rl_point]); else { /* Just skip over characters neither upper nor lower case. */ - rl_forward (1); + rl_forward (1, c); continue; } @@ -619,22 +710,24 @@ rl_vi_change_case (count, ignore) rl_vi_check (); } else - rl_forward (1); + rl_forward (1, c); } return (0); } +int rl_vi_put (count, key) int count, key; { - if (!uppercase_p (key) && (rl_point + 1 <= rl_end)) + if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end)) rl_point++; rl_yank (); - rl_backward (1); + rl_backward (1, key); return (0); } +int rl_vi_check () { if (rl_point && rl_point == rl_end) @@ -642,11 +735,12 @@ rl_vi_check () return (0); } +int rl_vi_column (count, key) int count, key; { if (count > rl_end) - rl_end_of_line (); + rl_end_of_line (1, key); else rl_point = count - 1; return (0); @@ -665,10 +759,10 @@ rl_vi_domove (key, nextkey) if (!member (c, vi_motion)) { - if (digit_p (c)) + if (_rl_digit_p (c)) { save = rl_numeric_arg; - rl_numeric_arg = digit_value (c); + rl_numeric_arg = _rl_digit_value (c); rl_digit_loop1 (); rl_numeric_arg *= save; c = rl_read_key (); /* real command */ @@ -677,7 +771,7 @@ rl_vi_domove (key, nextkey) else if (key == c && (key == 'd' || key == 'y' || key == 'c')) { rl_mark = rl_end; - rl_beg_of_line (); + rl_beg_of_line (1, c); _rl_vi_last_motion = c; return (0); } @@ -708,13 +802,13 @@ rl_vi_domove (key, nextkey) /* rl_vi_f[wW]ord () leaves the cursor on the first character of the next word. If we are not at the end of the line, and we are on a non-whitespace character, move back one (presumably to whitespace). */ - if ((to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark && + if ((_rl_to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark && !whitespace (rl_line_buffer[rl_point])) rl_point--; /* If cw or cW, back up to the end of a word, so the behaviour of ce or cE is the actual result. Brute-force, no subtlety. */ - if (key == 'c' && rl_point >= rl_mark && (to_upper (c) == 'W')) + if (key == 'c' && rl_point >= rl_mark && (_rl_to_upper (c) == 'W')) { /* Don't move farther back than where we started. */ while (rl_point > rl_mark && whitespace (rl_line_buffer[rl_point])) @@ -760,12 +854,12 @@ rl_digit_loop1 () } c = UNMETA (c); - if (digit_p (c)) + if (_rl_digit_p (c)) { if (rl_explicit_arg) - rl_numeric_arg = (rl_numeric_arg * 10) + digit_value (c); + rl_numeric_arg = (rl_numeric_arg * 10) + _rl_digit_value (c); else - rl_numeric_arg = digit_value (c); + rl_numeric_arg = _rl_digit_value (c); rl_explicit_arg = 1; } else @@ -778,12 +872,13 @@ rl_digit_loop1 () return (0); } +int rl_vi_delete_to (count, key) int count, key; { int c; - if (uppercase_p (key)) + if (_rl_uppercase_p (key)) rl_stuff_char ('$'); else if (vi_redoing) rl_stuff_char (_rl_vi_last_motion); @@ -803,12 +898,13 @@ rl_vi_delete_to (count, key) return (0); } +int rl_vi_change_to (count, key) int count, key; { int c, start_pos; - if (uppercase_p (key)) + if (_rl_uppercase_p (key)) rl_stuff_char ('$'); else if (vi_redoing) rl_stuff_char (_rl_vi_last_motion); @@ -828,25 +924,41 @@ rl_vi_change_to (count, key) rl_mark++; /* The cursor never moves with c[wW]. */ - if ((to_upper (c) == 'W') && rl_point < start_pos) + if ((_rl_to_upper (c) == 'W') && rl_point < start_pos) rl_point = start_pos; - rl_kill_text (rl_point, rl_mark); - - rl_begin_undo_group (); - _rl_vi_doing_insert = 1; - _rl_vi_set_last (key, count, rl_arg_sign); - rl_vi_insertion_mode (1, key); + if (vi_redoing) + { + if (vi_insert_buffer && *vi_insert_buffer) + rl_begin_undo_group (); + rl_delete_text (rl_point, rl_mark); + if (vi_insert_buffer && *vi_insert_buffer) + { + rl_insert_text (vi_insert_buffer); + rl_end_undo_group (); + } + } + else + { + rl_begin_undo_group (); /* to make the `u' command work */ + rl_kill_text (rl_point, rl_mark); + /* `C' does not save the text inserted for undoing or redoing. */ + if (_rl_uppercase_p (key) == 0) + _rl_vi_doing_insert = 1; + _rl_vi_set_last (key, count, rl_arg_sign); + rl_vi_insertion_mode (1, key); + } return (0); } +int rl_vi_yank_to (count, key) int count, key; { int c, save = rl_point; - if (uppercase_p (key)) + if (_rl_uppercase_p (key)) rl_stuff_char ('$'); if (rl_vi_domove (key, &c)) @@ -869,6 +981,7 @@ rl_vi_yank_to (count, key) return (0); } +int rl_vi_delete (count, key) int count, key; { @@ -888,57 +1001,36 @@ rl_vi_delete (count, key) rl_kill_text (rl_point, end); if (rl_point > 0 && rl_point == rl_end) - rl_backward (1); + rl_backward (1, key); return (0); } -/* Turn the current line into a comment in shell history. - A K*rn shell style function. */ -rl_vi_comment (count, key) +int +rl_vi_back_to_indent (count, key) int count, key; { - rl_beg_of_line (); - - if (rl_vi_comment_begin != (char *)NULL) - rl_insert_text (rl_vi_comment_begin); - else - rl_insert_text (VI_COMMENT_BEGIN_DEFAULT); /* Default. */ - - rl_redisplay (); - rl_newline (1, '\n'); + rl_beg_of_line (1, key); + while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) + rl_point++; return (0); } +int rl_vi_first_print (count, key) int count, key; { - return (rl_back_to_indent ()); -} - -rl_back_to_indent (ignore1, ignore2) - int ignore1, ignore2; -{ - rl_beg_of_line (); - while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) - rl_point++; - return (0); + return (rl_vi_back_to_indent (1, key)); } -/* NOTE: it is necessary that opposite directions are inverses */ -#define FTO 1 /* forward to */ -#define BTO -1 /* backward to */ -#define FFIND 2 /* forward find */ -#define BFIND -2 /* backward find */ - +int rl_vi_char_search (count, key) int count, key; { static char target; static int orig_dir, dir; - int pos; if (key == ';' || key == ',') - dir = (key == ';' ? orig_dir : -orig_dir); + dir = key == ';' ? orig_dir : -orig_dir; else { if (vi_redoing) @@ -966,71 +1058,11 @@ rl_vi_char_search (count, key) } } - pos = rl_point; - - while (count--) - { - if (dir < 0) - { - if (pos == 0) - { - ding (); - return -1; - } - - pos--; - do - { - if (rl_line_buffer[pos] == target) - { - if (dir == BTO) - rl_point = pos + 1; - else - rl_point = pos; - break; - } - } - while (pos--); - - if (pos < 0) - { - ding (); - return -1; - } - } - else - { /* dir > 0 */ - if (pos >= rl_end) - { - ding (); - return -1; - } - - pos++; - do - { - if (rl_line_buffer[pos] == target) - { - if (dir == FTO) - rl_point = pos - 1; - else - rl_point = pos; - break; - } - } - while (++pos < rl_end); - - if (pos >= (rl_end - 1)) - { - ding (); - return -1; - } - } - } - return (0); + return (_rl_char_search_internal (count, dir, target)); } /* Match brackets */ +int rl_vi_match (ignore, key) int ignore, key; { @@ -1041,7 +1073,7 @@ rl_vi_match (ignore, key) { while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0 && rl_point < rl_end - 1) - rl_forward (1); + rl_forward (1, key); if (brack <= 0) { @@ -1111,6 +1143,7 @@ rl_vi_bracktype (c) } } +int rl_vi_change_char (count, key) int count, key; { @@ -1131,22 +1164,23 @@ rl_vi_change_char (count, key) rl_delete (1, c); rl_insert (1, c); if (count == 0) - rl_backward (1); + rl_backward (1, c); rl_end_undo_group (); } return (0); } +int rl_vi_subst (count, key) int count, key; { rl_begin_undo_group (); - if (uppercase_p (key)) + if (_rl_uppercase_p (key)) { - rl_beg_of_line (); - rl_kill_line (1); + rl_beg_of_line (1, key); + rl_kill_line (1, key); } else rl_delete_text (rl_point, rl_point+count); @@ -1155,13 +1189,26 @@ rl_vi_subst (count, key) _rl_vi_set_last (key, count, rl_arg_sign); - rl_begin_undo_group (); - _rl_vi_doing_insert = 1; - rl_vi_insertion_mode (1, key); + if (vi_redoing) + { + int o = _rl_doing_an_undo; + + _rl_doing_an_undo = 1; + if (vi_insert_buffer && *vi_insert_buffer) + rl_insert_text (vi_insert_buffer); + _rl_doing_an_undo = o; + } + else + { + rl_begin_undo_group (); + _rl_vi_doing_insert = 1; + rl_vi_insertion_mode (1, key); + } return (0); } +int rl_vi_overstrike (count, key) int count, key; { @@ -1191,8 +1238,9 @@ rl_vi_overstrike (count, key) return (0); } -rl_vi_overstrike_delete (count) - int count; +int +rl_vi_overstrike_delete (count, key) + int count, key; { int i, s; @@ -1209,7 +1257,7 @@ rl_vi_overstrike_delete (count) vi_replace_count--; if (rl_point == s) - rl_backward (1); + rl_backward (1, key); } if (vi_replace_count == 0 && _rl_vi_doing_insert) @@ -1221,6 +1269,7 @@ rl_vi_overstrike_delete (count) return (0); } +int rl_vi_replace (count, key) int count, key; { @@ -1256,6 +1305,7 @@ rl_vi_replace (count, key) /* Try to complete the word we are standing on or the word that ends with the previous character. A space matches everything. Word delimiters are space and ;. */ +int rl_vi_possible_completions() { int save_pos = rl_point; @@ -1279,51 +1329,50 @@ rl_vi_possible_completions() } #endif -#if defined (STATIC_MALLOC) - -/* **************************************************************** */ -/* */ -/* xmalloc and xrealloc () */ -/* */ -/* **************************************************************** */ - -static void memory_error_and_abort (); - -static char * -xmalloc (bytes) - int bytes; +/* Functions to save and restore marks. */ +int +rl_vi_set_mark (count, key) + int count, key; { - char *temp = (char *)malloc (bytes); + int ch; - if (!temp) - memory_error_and_abort (); - return (temp); + ch = rl_read_key (); + if (_rl_lowercase_p (ch) == 0) + { + ding (); + return -1; + } + ch -= 'a'; + vi_mark_chars[ch] = rl_point; + return 0; } -static char * -xrealloc (pointer, bytes) - char *pointer; - int bytes; +int +rl_vi_goto_mark (count, key) + int count, key; { - char *temp; - - if (!pointer) - temp = (char *)xmalloc (bytes); - else - temp = (char *)realloc (pointer, bytes); + int ch; - if (!temp) - memory_error_and_abort (); - - return (temp); -} + ch = rl_read_key (); + if (ch == '`') + { + rl_point = rl_mark; + return 0; + } + else if (_rl_lowercase_p (ch) == 0) + { + ding (); + return -1; + } -static void -memory_error_and_abort () -{ - fprintf (stderr, "readline: Out of virtual memory!\n"); - abort (); + ch -= 'a'; + if (vi_mark_chars[ch] == -1) + { + ding (); + return -1; + } + rl_point = vi_mark_chars[ch]; + return 0; } -#endif /* STATIC_MALLOC */ #endif /* VI_MODE */ diff --git a/lib/readline/xmalloc.c b/lib/readline/xmalloc.c index 4f6dc76..4160651 100644 --- a/lib/readline/xmalloc.c +++ b/lib/readline/xmalloc.c @@ -19,8 +19,10 @@ along with Readline; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ -#if defined (ALREADY_HAVE_XMALLOC) -#else +#if defined (HAVE_CONFIG_H) +#include <config.h> +#endif + #include <stdio.h> #if defined (HAVE_STDLIB_H) @@ -44,9 +46,10 @@ char * xmalloc (bytes) int bytes; { - char *temp = (char *)malloc (bytes); + char *temp; - if (!temp) + temp = (char *)malloc (bytes); + if (temp == 0) memory_error_and_abort ("xmalloc"); return (temp); } @@ -58,12 +61,9 @@ xrealloc (pointer, bytes) { char *temp; - if (!pointer) - temp = (char *)malloc (bytes); - else - temp = (char *)realloc (pointer, bytes); + temp = pointer ? (char *)realloc (pointer, bytes) : (char *)malloc (bytes); - if (!temp) + if (temp == 0) memory_error_and_abort ("xrealloc"); return (temp); } @@ -72,7 +72,16 @@ static void memory_error_and_abort (fname) char *fname; { - fprintf (stderr, "%s: Out of virtual memory!\n", fname); - abort (); + fprintf (stderr, "%s: out of virtual memory\n", fname); + exit (2); +} + +/* Use this as the function to call when adding unwind protects so we + don't need to know what free() returns. */ +void +xfree (string) + char *string; +{ + if (string) + free (string); } -#endif /* !ALREADY_HAVE_XMALLOC */ diff --git a/lib/termcap/Makefile b/lib/termcap/Makefile deleted file mode 100644 index b87de8d..0000000 --- a/lib/termcap/Makefile +++ /dev/null @@ -1,67 +0,0 @@ -## -*- text -*- #################################################### -# # -# Makefile for termcap replacement libbrary. # -# # -#################################################################### - -# Here is a rule for making .o files from .c files that doesn't force -# the type of the machine (like -sun3) into the flags. -.c.o: - $(CC) -c $(CFLAGS) $(LOCAL_INCLUDES) $(CPPFLAGS) $*.c - -# Destination installation directory. The libraries are copied to DESTDIR -# when you do a `make install'. -DESTDIR = /usr/local/lib - -DEBUG_FLAGS = -g -#OPTIMIZE_FLAGS = -O -LDFLAGS = $(DEBUG_FLAGS) -CFLAGS = $(DEBUG_FLAGS) $(OPTIMIZE_FLAGS) - -SHELL = /bin/sh - -# A good alternative is gcc -traditional. -#CC = gcc -traditional -CC = cc -RANLIB = ranlib -AR = ar -RM = rm -CP = cp - -CSOURCES = termcap.c tparam.c - -SOURCES = $(CSOURCES) - -OBJECTS = termcap.o tparam.o - -DOCUMENTATION = termcap.texinfo - -THINGS_TO_TAR = $(SOURCES) $(DOCUMENTATION) - -########################################################################## - -all: libtermcap.a - -libtermcap.a: $(OBJECTS) - $(RM) -f $@ - $(AR) clq $@ $(OBJECTS) - -[ -n "$(RANLIB)" ] && $(RANLIB) $@ - -termcap.tar: $(THINGS_TO_TAR) - tar -cf $@ $(THINGS_TO_TAR) - -termcap.tar.Z: termcap.tar - compress -f termcap.tar - -install: $(DESTDIR)/libtermcap.a - -clean: - rm -f *.o *.a *.log *.cp *.tp *.vr *.fn *.aux *.pg *.toc - -maintainer-clean realclean mostlyclean distclean: clean - - -$(DESTDIR)/libtermcap.a: libtermcap.a - -mv $(DESTDIR)/libtermcap.a $(DESTDIR)/libtermcap.old - cp libtermcap.a $@ - -[ -n "$(RANLIB) ] && $(RANLIB) -t $@ diff --git a/lib/termcap/Makefile.in b/lib/termcap/Makefile.in new file mode 100644 index 0000000..64635f8 --- /dev/null +++ b/lib/termcap/Makefile.in @@ -0,0 +1,69 @@ +## -*- text -*- #################################################### +# # +# Makefile for termcap replacement libbrary. # +# # +#################################################################### + +srcdir = @srcdir@ +VPATH = .:@srcdir@ +topdir = @top_srcdir@ +BUILD_DIR = @BUILD_DIR@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +CC = @CC@ +RANLIB = @RANLIB@ +AR = @AR@ +RM = rm -f +CP = cp +MV = mv + +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ + +DEFS = @DEFS@ + +INCLUDES = -I. -I../.. -I$(topdir) -I$(topdir)/lib + +CCFLAGS = $(CFLAGS) $(DEFS) $(CPPFLAGS) ${INCLUDES} + +# Here is a rule for making .o files from .c files that doesn't force +# the type of the machine (like -sun3) into the flags. +.c.o: + $(CC) -c $(CCFLAGS) $< + +SHELL = /bin/sh + +SOURCES = termcap.c tparam.c +OBJECTS = termcap.o tparam.o + +DOCUMENTATION = termcap.texinfo + +THINGS_TO_TAR = $(SOURCES) $(DOCUMENTATION) + +########################################################################## + +all: libtermcap.a + +libtermcap.a: $(OBJECTS) + $(RM) -f $@ + $(AR) cr $@ $(OBJECTS) + -test -n "$(RANLIB)" && $(RANLIB) $@ + +install: + +clean: + $(RM) *.o *.a *.log *.cp *.tp *.vr *.fn *.aux *.pg *.toc + +mostlyclean distclean maintainer-clean: clean + +$(DESTDIR)/libtermcap.a: libtermcap.a + ${INSTALL_DATA} -c -m 644 libtermcap.a $@ + -test -n "$(RANLIB)" && $(RANLIB) -t $@ + +termcap.o: $(BUILD_DIR)/config.h +tparam.o: $(BUILD_DIR)/config.h +version.o: $(BUILD_DIR)/config.h diff --git a/lib/termcap/grot/ChangeLog b/lib/termcap/grot/ChangeLog index 3a8b844..e8c4751 100644 --- a/lib/termcap/grot/ChangeLog +++ b/lib/termcap/grot/ChangeLog @@ -1,3 +1,92 @@ +Wed Aug 16 20:45:44 1995 David J. MacKenzie <djm@geech.gnu.ai.mit.edu> + + * version.c: Version 1.3. + + * termcap.c (tgetent): Use the user-supplied buffer even if we + don't find a matching terminal, so the program can set the buffer + if they want (`less' does this). From Bob Pegram + <pegram@emba.uvm.edu>. + +Wed Jul 26 11:44:51 1995 David J. MacKenzie <djm@geech.gnu.ai.mit.edu> + + * termcap.c: TERMCAP_NAME -> TERMCAP_FILE. + + * configure.in: Add --enable-install-termcap and --with-termcap + options. + + * Makefile.in: Add hooks for new configure options. + + * Makefile.in (DISTFILES): Add termcap.src. + (DEFS): Remove -DNO_ARG_ARRAY. + (install-data, uninstall-data): New targets. + + * tparam.c (tparam): Remove arg array version and the #ifdef. + + * termcap.c: Move #define of bcopy to after #include <string.h>. + + * termcap.h: Prototype the arg to the tputs outfun arg. + + * Makefile.in: realclean -> maintainer-clean. Use @prefix@ and + @exec_prefix@. + + * Makefile.in (DISTFILES): Add install-sh. + +Fri Apr 7 14:57:45 1995 Richard Stallman <rms@mole.gnu.ai.mit.edu> + + * termcap.c (tgetent): Don't try to return the allocated address. + Always return 1 if successful. + +Tue Feb 14 02:34:43 1995 Richard Stallman <rms@pogo.gnu.ai.mit.edu> + + * termcap.c (speeds): Make it ints. Add some higher speeds. + (tputs) [emacs]: If speed is high, convert to smaller units. + (tputs): Really use SPEED to calculate PADCOUNT. + +Sat Dec 17 07:20:24 1994 Richard Stallman <rms@mole.gnu.ai.mit.edu> + + * termcap.c (tgetst1): Let ^? stand for DEL character. + +Thu Jun 30 04:35:50 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * configure.in: Use AC_HAVE_HEADERS instead of AC_UNISTD_H. + Add AC_PROG_RANLIB. + * Makefile.in (AR, RANLIB): New variables. + (install, libtermcap.a): Use them instead of hard-wired commands. + +Sat Jun 4 12:21:41 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * termcap.c [HAVE_CONFIG_H]: Include <sys/file.h>, and include + <fcntl.h> #ifdef USG5, so we get O_* defns. + +Wed May 25 19:05:30 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * termcap.c (O_RDONLY): Define to 0 if not already defined. + (tgetent): Use O_RDONLY instead of explicit 0 in call to open. + +Wed Jan 5 22:20:15 1993 Morten Welinder (terra@diku.dk) + + * termcap.c (tgetent) [INTERNAL_TERMINAL]: Fake internal terminal + without reading any files. + (valid_file_name, tgetent) [MSDOS]: Drive letter support. + (tgetent) [MSDOS]: Use text mode for database. + +Fri Dec 17 00:22:43 1993 Mike Long (mike.long@analog.com) + + * termcap.c (tgetent): Replaced literal filenames for termcap + database with preprocessor symbol TERMCAP_NAME. + (TERMCAP_NAME): Define if not defined. + +Fri Sep 10 00:35:07 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makefile.in (.c.o): Put -I. before -I$(srcdir). + * termcap.c: Include <config.h> instead of "config.h". + * tparam.c: Likewise. + +Thu Jul 29 20:53:30 1993 David J. MacKenzie (djm@wookumz.gnu.ai.mit.edu) + + * Makefile.in (config.status): Run config.status --recheck, not + configure, to get the right args passed. + Thu Apr 15 12:45:10 1993 David J. MacKenzie (djm@kropotkin.gnu.ai.mit.edu) * Version 1.2. diff --git a/lib/termcap/grot/INSTALL b/lib/termcap/grot/INSTALL index 014e0f7..95d84c8 100644 --- a/lib/termcap/grot/INSTALL +++ b/lib/termcap/grot/INSTALL @@ -1,117 +1,176 @@ -This is a generic INSTALL file for utilities distributions. -If this package does not come with, e.g., installable documentation or -data files, please ignore the references to them below. - -To compile this package: - -1. Configure the package for your system. In the directory that this -file is in, type `./configure'. If you're using `csh' on an old -version of System V, you might need to type `sh configure' instead to -prevent `csh' from trying to execute `configure' itself. - -The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation, and -creates the Makefile(s) (one in each subdirectory of the source -directory). In some packages it creates a C header file containing -system-dependent definitions. It also creates a file `config.status' -that you can run in the future to recreate the current configuration. - -Running `configure' takes a minute or two. While it is running, it -prints some messages that tell what it is doing. If you don't want to -see the messages, run `configure' with its standard output redirected -to `/dev/null'; for example, `./configure >/dev/null'. - -To compile the package in a different directory from the one -containing the source code, you must use a version of `make' that -supports the VPATH variable, such as GNU `make'. `cd' to the directory -where you want the object files and executables to go and run -`configure'. `configure' automatically checks for the source code in -the directory that `configure' is in and in `..'. If for some reason -`configure' is not in the source code directory that you are -configuring, then it will report that it can't find the source code. -In that case, run `configure' with the option `--srcdir=DIR', where -DIR is the directory that contains the source code. - -By default, `make install' will install the package's files in -/usr/local/bin, /usr/local/lib, /usr/local/man, etc. You can specify -an installation prefix other than /usr/local by giving `configure' the -option `--prefix=PATH'. Alternately, you can do so by giving a value -for the `prefix' variable when you run `make', e.g., - make prefix=/usr/gnu - -You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If -you give `configure' the option `--exec-prefix=PATH' or set the -`make' variable `exec_prefix' to PATH, the package will use PATH as -the prefix for installing programs and libraries. Data files and -documentation will still use the regular prefix. Normally, all files -are installed using the regular prefix. - -Another `configure' option is useful mainly in `Makefile' rules for -updating `config.status' and `Makefile'. The `--no-create' option -figures out the configuration for your system and records it in -`config.status', without actually configuring the package (creating -`Makefile's and perhaps a configuration header file). Later, you can -run `./config.status' to actually configure the package. You can also -give `config.status' the `--recheck' option, which makes it re-run -`configure' with the same arguments you used before. This option is -useful if you change `configure'. - -Some packages pay attention to `--with-PACKAGE' options to `configure', -where PACKAGE is something like `gnu-libc' or `x' (for the X Window System). -The README should mention any --with- options that the package recognizes. - -`configure' ignores any other arguments that you give it. - -If your system requires unusual options for compilation or linking -that `configure' doesn't know about, you can give `configure' initial -values for some variables by setting them in the environment. In -Bourne-compatible shells, you can do that on the command line like +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like this: - CC='gcc -traditional' DEFS=-D_POSIX_SOURCE ./configure - -The `make' variables that you might want to override with environment -variables when running `configure' are: - -(For these variables, any value given in the environment overrides the -value that `configure' would choose:) -CC C compiler program. - Default is `cc', or `gcc' if `gcc' is in your PATH. -INSTALL Program to use to install files. - Default is `install' if you have it, `cp' otherwise. - -(For these variables, any value given in the environment is added to -the value that `configure' chooses:) -DEFS Configuration options, in the form `-Dfoo -Dbar ...' - Do not use this variable in packages that create a - configuration header file. -LIBS Libraries to link with, in the form `-lfoo -lbar ...' - -If you need to do unusual things to compile the package, we encourage -you to figure out how `configure' could check whether to do them, and -mail diffs or instructions to the address given in the README so we -can include them in the next release. - -2. Type `make' to compile the package. If you want, you can override -the `make' variables CFLAGS and LDFLAGS like this: - - make CFLAGS=-O2 LDFLAGS=-s - -3. If the package comes with self-tests and you want to run them, -type `make check'. If you're not sure whether there are any, try it; -if `make' responds with something like - make: *** No way to make target `check'. Stop. -then the package does not come with self-tests. - -4. Type `make install' to install programs, data files, and -documentation. - -5. You can remove the program binaries and object files from the -source directory by typing `make clean'. To also remove the -Makefile(s), the header file containing system-dependent definitions -(if the package uses one), and `config.status' (all the files that -`configure' created), type `make distclean'. - -The file `configure.in' is used as a template to create `configure' by -a program called `autoconf'. You will only need it if you want to -regenerate `configure' using a newer version of `autoconf'. + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. + diff --git a/lib/termcap/grot/Makefile.in b/lib/termcap/grot/Makefile.in index 309603d..66e5d02 100644 --- a/lib/termcap/grot/Makefile.in +++ b/lib/termcap/grot/Makefile.in @@ -1,5 +1,5 @@ # Makefile for GNU termcap library. -# Copyright (C) 1992, 1993 Free Software Foundation, Inc. +# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -21,26 +21,20 @@ srcdir = @srcdir@ VPATH = @srcdir@ CC = @CC@ +AR = ar +RANLIB = @RANLIB@ -# If you don't have a BSD or GNU install program, use cp. INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ MAKEINFO = makeinfo -# Things you might add to DEFS: -# -DHAVE_STRING_H If you have memcpy instead of bcopy. -# -DNO_ARG_ARRAY If you can't take the address of the first of -# a group of arguments and treat it as an array. -# We always define this, because it's not a big loss -# and can't be detected when cross-autoconfiguring. - -DEFS = @DEFS@ -DNO_ARG_ARRAY +DEFS = @DEFS@ -DTERMCAP_FILE=\"$(termcapfile)\" CFLAGS = -g -prefix = /usr/local -exec_prefix = $(prefix) +prefix = @prefix@ +exec_prefix = @exec_prefix@ # Directory in which to install libtermcap.a. libdir = $(exec_prefix)/lib @@ -57,6 +51,10 @@ oldincludedir = /usr/include # Directory in which to install the documentation info files. infodir = $(prefix)/info +# File to which `install-data' should install the data file +# if --enable-install-termcap was given. +termcapfile = @termcapfile@ + #### End of system configuration section. #### SHELL = /bin/sh @@ -65,35 +63,55 @@ SRCS = termcap.c tparam.c version.c OBJS = termcap.o tparam.o version.o HDRS = termcap.h DISTFILES = $(SRCS) $(HDRS) ChangeLog COPYING README INSTALL NEWS \ -termcap.texi termcap.info* \ -texinfo.tex Makefile.in configure configure.in +termcap.src termcap.texi termcap.info* \ +texinfo.tex Makefile.in configure configure.in mkinstalldirs install-sh -all: libtermcap.a termcap.info +all: libtermcap.a info .c.o: - $(CC) -c $(CPPFLAGS) $(DEFS) -I$(srcdir) $(CFLAGS) $< + $(CC) -c $(CPPFLAGS) $(DEFS) -I. -I$(srcdir) $(CFLAGS) $< -install: all +install: all installdirs @installdata@ $(INSTALL_DATA) libtermcap.a $(libdir)/libtermcap.a - -ranlib $(libdir)/libtermcap.a - test -d $(includedir) || mkdir $(includedir) + -$(RANLIB) $(libdir)/libtermcap.a cd $(srcdir); $(INSTALL_DATA) termcap.h $(includedir)/termcap.h -cd $(srcdir); test -z "$(oldincludedir)" || \ $(INSTALL_DATA) termcap.h $(oldincludedir)/termcap.h cd $(srcdir); for f in termcap.info*; \ do $(INSTALL_DATA) $$f $(infodir)/$$f; done -uninstall: +uninstall: @uninstalldata@ rm -f $(libdir)/libtermcap.a $(includedir)/termcap.h test -z "$(oldincludedir)" || rm -f $(oldincludedir)/termcap.h rm -f $(infodir)/termcap.info* +# These are separate targets to avoid trashing the user's existing +# termcap file unexpectedly. +install-data: + $(INSTALL_DATA) ${srcdir}/termcap.src ${termcapfile} + +uninstall-data: + rm -f ${termcapfile} + +installdirs: + $(SHELL) ${srcdir}/mkinstalldirs $(bindir) $(libdir) \ + $(includedir) $(infodir) + +Makefile: Makefile.in config.status + $(SHELL) config.status +config.status: configure + $(SHELL) config.status --recheck +configure: configure.in + cd $(srcdir) && autoconf + libtermcap.a: $(OBJS) - ar rc $@ $(OBJS) - -ranlib $@ + $(AR) rc $@ $(OBJS) + -$(RANLIB) $@ + +info: termcap.info termcap.info: termcap.texi - $(MAKEINFO) $(srcdir)/termcap.texi --output=$(srcdir)/termcap.info + $(MAKEINFO) $(srcdir)/termcap.texi --output=$@ TAGS: $(SRCS) etags $(SRCS) @@ -104,9 +122,11 @@ clean: mostlyclean: clean distclean: clean - rm -f Makefile config.status + rm -f Makefile config.status config.cache config.log -realclean: distclean +maintainer-clean: distclean + @echo "This command is intended for maintainers to use;" + @echo "rebuilding the deleted files requires makeinfo." rm -f TAGS *.info* dist: $(DISTFILES) @@ -114,5 +134,5 @@ dist: $(DISTFILES) rm -rf `cat .fname` mkdir `cat .fname` ln $(DISTFILES) `cat .fname` - tar chzf `cat .fname`.tar.z `cat .fname` + tar chzf `cat .fname`.tar.gz `cat .fname` rm -rf `cat .fname` .fname diff --git a/lib/termcap/grot/NEWS b/lib/termcap/grot/NEWS index c696fdf..e5d58b9 100644 --- a/lib/termcap/grot/NEWS +++ b/lib/termcap/grot/NEWS @@ -1,3 +1,11 @@ +Major changes in release 1.3: + +Termcap data file is now included in distribution and may optionally + be installed, or used in a non-default location. +Support for a fake internal terminal (no external files). +Higher tty speeds supported. +Portability tweaks. + Major changes in release 1.2: For `%.', only set the high bit on NUL. diff --git a/lib/termcap/grot/README b/lib/termcap/grot/README index 9db9095..ba1a19c 100644 --- a/lib/termcap/grot/README +++ b/lib/termcap/grot/README @@ -1,13 +1,33 @@ This is the GNU termcap library -- a library of C functions that enable programs to send control strings to terminals in a way -independent of the terminal type. Most of this package is also -distributed with GNU Emacs, but it is available in this separate -distribution to make it easier to install as -ltermcap. +independent of the terminal type. The GNU termcap library does not +place an arbitrary limit on the size of termcap entries, unlike most +other termcap libraries. -The GNU termcap library does not place an arbitrary limit on the size -of termcap entries, unlike most other termcap libraries. +Most of this package is also distributed with GNU Emacs, but it is +available in this separate distribution to make it easier to install +as -ltermcap. However, use of termcap is discouraged. Termcap is +being phased out in favor of the terminfo-based ncurses library, which +contains an emulation of the termcap library routines in addition to +an excellent curses implementation. ncurses is available from the +usual GNU archive sites. See the file INSTALL for compilation and installation instructions. +Additionally: + +This package contains termcap.src, the latest official termcap data +file. By default, it is not installed. The current version contains +some entries that are more than 1023 bytes long, which is the largest +value that is safe to use with the many historical applications that +only allocate a 1024 byte termcap buffer (telnet, for example). If +you make sure that all of your programs allocate buffers of at least +2500 bytes, or let the termcap library do it by passing a NULL +pointer, then it is safe to install the new termcap file, as described +below. + +You can give configure two special options: + --enable-install-termcap install the termcap data file + --with-termcap=FILE use data file FILE instead of /etc/termcap Please report any bugs in this library to bug-gnu-emacs@prep.ai.mit.edu. You can check which version of the library you have by using the RCS diff --git a/lib/termcap/grot/configure b/lib/termcap/grot/configure index bc34d0a..8a885fa 100755 --- a/lib/termcap/grot/configure +++ b/lib/termcap/grot/configure @@ -1,346 +1,998 @@ -#!/bin/sh +#! /bin/sh + # Guess values for system-dependent variables and create Makefiles. -# Generated automatically using autoconf. -# Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. +# Generated automatically using autoconf version 2.4 +# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --enable-install-termcap install the termcap data file" +ac_help="$ac_help + --with-termcap=FILE use data file FILE instead of /etc/termcap" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE + +# Initialize some other variables. +subdirs= + +ac_prev= +for ac_option +do -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + # Accept the important Cygnus configure options, so we can diagnose typos. -# Usage: configure [--srcdir=DIR] [--host=HOST] [--gas] [--nfp] [--no-create] -# [--prefix=PREFIX] [--exec-prefix=PREFIX] [--with-PACKAGE] [TARGET] -# Ignores all args except --srcdir, --prefix, --exec-prefix, --no-create, and -# --with-PACKAGE unless this script has special code to handle it. + case "$ac_option" in + -build | --build | --buil | --bui | --bu | --b) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=* | --b=*) + build="$ac_optarg" ;; -for arg -do - # Handle --exec-prefix with a space before the argument. - if test x$next_exec_prefix = xyes; then exec_prefix=$arg; next_exec_prefix= - # Handle --host with a space before the argument. - elif test x$next_host = xyes; then next_host= - # Handle --prefix with a space before the argument. - elif test x$next_prefix = xyes; then prefix=$arg; next_prefix= - # Handle --srcdir with a space before the argument. - elif test x$next_srcdir = xyes; then srcdir=$arg; next_srcdir= - else - case $arg in - # For backward compatibility, also recognize exact --exec_prefix. - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* | --exec=* | --exe=* | --ex=* | --e=*) - exec_prefix=`echo $arg | sed 's/[-a-z_]*=//'` ;; - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- | --exec | --exe | --ex | --e) - next_exec_prefix=yes ;; - - -gas | --gas | --ga | --g) ;; - - -host=* | --host=* | --hos=* | --ho=* | --h=*) ;; - -host | --host | --hos | --ho | --h) - next_host=yes ;; - - -nfp | --nfp | --nf) ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre | --no-cr | --no-c | --no- | --no) - no_create=1 ;; - - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=`echo $arg | sed 's/[-a-z_]*=//'` ;; - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - next_prefix=yes ;; - - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=* | --s=*) - srcdir=`echo $arg | sed 's/[-a-z_]*=//'` ;; - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr | --s) - next_srcdir=yes ;; - - -with-* | --with-*) - package=`echo $arg|sed 's/-*with-//'` - # Delete all the valid chars; see if any are left. - if test -n "`echo $package|sed 's/[-a-zA-Z0-9_]*//g'`"; then - echo "configure: $package: invalid package name" >&2; exit 1 - fi - eval "with_`echo $package|sed s/-/_/g`=1" ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb | --ver | --ve | --v) - verbose=yes ;; - - *) ;; + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; esac - fi + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=PREFIX install architecture-dependent files in PREFIX + [same as prefix] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +--enable and --with options recognized:$ac_help +EOF + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.4" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac done -trap 'rm -f conftest* core; exit 1' 1 3 15 +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi -rm -f conftest* -compile='${CC-cc} $CFLAGS $DEFS conftest.c -o conftest $LIBS >/dev/null 2>&1' +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set LANG and LC_ALL to C if already set. +# These must not be set unconditionally because not all systems understand +# e.g. LANG=C (notably SCO). +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LANG+set}" = set; then LANG=C; export LANG; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. -unique_file=termcap.h +ac_unique_file=termcap.h # Find the source files, if location was not specified. if test -z "$srcdir"; then - srcdirdefaulted=yes - # Try the directory containing this script, then `..'. - prog=$0 - confdir=`echo $prog|sed 's%/[^/][^/]*$%%'` - test "X$confdir" = "X$prog" && confdir=. - srcdir=$confdir - if test ! -r $srcdir/$unique_file; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi +else + ac_srcdir_defaulted=no fi -if test ! -r $srcdir/$unique_file; then - if test x$srcdirdefaulted = xyes; then - echo "configure: Can not find sources in \`${confdir}' or \`..'." 1>&2 +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } else - echo "configure: Can not find sources in \`${srcdir}'." 1>&2 + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } fi - exit 1 -fi -# Preserve a srcdir of `.' to avoid automounter screwups with pwd. -# But we can't avoid them for `..', to make subdirectories work. -case $srcdir in - .|/*|~*) ;; - *) srcdir=`cd $srcdir; pwd` ;; # Make relative path absolute. -esac - -if test -z "$CC"; then - echo checking for gcc - saveifs="$IFS"; IFS="${IFS}:" - for dir in $PATH; do - test -z "$dir" && dir=. - if test -f $dir/gcc; then - CC="gcc" +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5 2>&5' +ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5 2>&5' + +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +# Check whether --enable-install-termcap or --disable-install-termcap was given. +enableval="$enable_install_termcap" +if test -n "$enableval"; then + if test $enableval = yes; then + installdata=install-data uninstalldata=uninstall-data + fi +fi + + +# Check whether --with-termcap or --without-termcap was given. +withval="$with_termcap" +if test -n "$withval"; then + termcapfile=$withval +else + termcapfile=/etc/termcap +fi + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" break fi done - IFS="$saveifs" + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_CC" && ac_cv_prog_CC="cc" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 fi -test -z "$CC" && CC="cc" -# Find out if we are using GNU C, under whatever name. -cat > conftest.c <<EOF + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <<EOF #ifdef __GNUC__ - yes + yes; #endif EOF -${CC-cc} -E conftest.c > conftest.out 2>&1 -if egrep yes conftest.out >/dev/null 2>&1; then - GCC=1 # For later tests. +if ${CC-cc} -E conftest.c 2>&5 | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 +if test $ac_cv_prog_gcc = yes; then + GCC=yes + if test "${CFLAGS+set}" != set; then + echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_prog_gcc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_gcc_g=yes +else + ac_cv_prog_gcc_g=no fi rm -f conftest* -echo checking how to run the C preprocessor -if test -z "$CPP"; then - CPP='${CC-cc} -E' - cat > conftest.c <<EOF -#include <stdio.h> -EOF -err=`eval "($CPP $DEFS conftest.c >/dev/null) 2>&1"` -if test -z "$err"; then - : +fi + echo "$ac_t""$ac_cv_prog_gcc_g" 1>&6 + if test $ac_cv_prog_gcc_g = yes; then + CFLAGS="-g -O" + else + CFLAGS="-O" + fi + fi else - CPP=/lib/cpp + GCC= + test "${CFLAGS+set}" = set || CFLAGS="-g" +fi + +# Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" fi -rm -f conftest* +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 fi -# Make sure to not get the incompatible SysV /etc/install and -# /usr/sbin/install, which might be in PATH before a BSD-like install, -# or the SunOS /usr/etc/install directory, or the AIX /bin/install, -# or the AFS install, which mishandles nonexistent args. (Sigh.) +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 if test -z "$INSTALL"; then - echo checking for install - saveifs="$IFS"; IFS="${IFS}:" - for dir in $PATH; do - test -z "$dir" && dir=. - case $dir in - /etc|/usr/sbin|/usr/etc|/usr/afsws/bin) ;; +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; *) - if test -f $dir/installbsd; then - INSTALL="$dir/installbsd -c" # OSF1 - INSTALL_PROGRAM='$(INSTALL)' - INSTALL_DATA='$(INSTALL) -m 644' - break - fi - if test -f $dir/install; then - if grep dspmsg $dir/install >/dev/null 2>&1; then - : # AIX - else - INSTALL="$dir/install -c" - INSTALL_PROGRAM='$(INSTALL)' - INSTALL_DATA='$(INSTALL) -m 644' - break + # OSF1 and SCO ODT 3.0 have their own names for install. + for ac_prog in ginstall installbsd scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + # OSF/1 installbsd also uses dspmsg, but is usable. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi fi - fi + done ;; esac done - IFS="$saveifs" + IFS="$ac_save_ifs" + # As a last resort, use the slow shell script. + test -z "$ac_cv_path_install" && ac_cv_path_install="$ac_install_sh" fi -INSTALL=${INSTALL-cp} -INSTALL_PROGRAM=${INSTALL_PROGRAM-'$(INSTALL)'} -INSTALL_DATA=${INSTALL_DATA-'$(INSTALL)'} + INSTALL="$ac_cv_path_install" +fi +echo "$ac_t""$INSTALL" 1>&6 -for hdr in string.h -do -trhdr=HAVE_`echo $hdr | tr '[a-z]./' '[A-Z]__'` -echo checking for ${hdr} -cat > conftest.c <<EOF -#include <${hdr}> +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext <<EOF +#line 612 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext <<EOF +#line 626 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error EOF -err=`eval "($CPP $DEFS conftest.c >/dev/null) 2>&1"` -if test -z "$err"; then - { -test -n "$verbose" && \ -echo ' defining' ${trhdr} -DEFS="$DEFS -D${trhdr}=1" -} +eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 +for ac_hdr in string.h unistd.h +do +ac_safe=`echo "$ac_hdr" | tr './\055' '___'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 659 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | tr '[a-z]./\055' '[A-Z]___'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi done -echo checking for unistd.h -cat > conftest.c <<EOF -#include <unistd.h> +# If we cannot run a trivial program, we must be cross compiling. +echo $ac_n "checking whether cross-compiling""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_c_cross'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_c_cross=yes +else +cat > conftest.$ac_ext <<EOF +#line 696 "configure" +#include "confdefs.h" +main(){return(0);} EOF -err=`eval "($CPP $DEFS conftest.c >/dev/null) 2>&1"` -if test -z "$err"; then - { -test -n "$verbose" && \ -echo ' defining' HAVE_UNISTD_H -DEFS="$DEFS -DHAVE_UNISTD_H=1" -} - +eval $ac_link +if test -s conftest && (./conftest; exit) 2>/dev/null; then + ac_cv_c_cross=no +else + ac_cv_c_cross=yes fi -rm -f conftest* +fi +rm -fr conftest* +fi +cross_compiling=$ac_cv_c_cross +echo "$ac_t""$ac_cv_c_cross" 1>&6 -echo checking for ANSI C header files -cat > conftest.c <<EOF +echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 717 "configure" +#include "confdefs.h" #include <stdlib.h> #include <stdarg.h> #include <string.h> #include <float.h> EOF -err=`eval "($CPP $DEFS conftest.c >/dev/null) 2>&1"` -if test -z "$err"; then +eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + rm -rf conftest* + ac_cv_header_stdc=yes +else + echo "$ac_err" >&5 + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. -echo '#include <string.h>' > conftest.c -eval "$CPP $DEFS conftest.c > conftest.out 2>&1" -if egrep "memchr" conftest.out >/dev/null 2>&1; then - # SGI's /bin/cc from Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. -cat > conftest.c <<EOF +cat > conftest.$ac_ext <<EOF +#line 739 "configure" +#include "confdefs.h" +#include <string.h> +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "memchr" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. +cat > conftest.$ac_ext <<EOF +#line 757 "configure" +#include "confdefs.h" +#include <stdlib.h> +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "free" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. +if test "$cross_compiling" = yes; then + ac_cv_header_stdc=no +else +cat > conftest.$ac_ext <<EOF +#line 778 "configure" +#include "confdefs.h" #include <ctype.h> #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#define XOR(e,f) (((e) && !(f)) || (!(e) && (f))) +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -eval $compile +eval $ac_link if test -s conftest && (./conftest; exit) 2>/dev/null; then - { -test -n "$verbose" && \ -echo ' defining' STDC_HEADERS -DEFS="$DEFS -DSTDC_HEADERS=1" -} - + : +else + ac_cv_header_stdc=no fi -rm -f conftest* fi -rm -f conftest* +rm -fr conftest* +fi +fi +echo "$ac_t""$ac_cv_header_stdc" 1>&6 +if test $ac_cv_header_stdc = yes; then + cat >> confdefs.h <<\EOF +#define STDC_HEADERS 1 +EOF fi -rm -f conftest* -if test -n "$prefix"; then - test -z "$exec_prefix" && exec_prefix='${prefix}' - prsub="s%^prefix\\([ ]*\\)=\\([ ]*\\).*$%prefix\\1=\\2$prefix%" + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + sed -n "s/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=\${\1='\2'}/p" \ + >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi fi -if test -n "$exec_prefix"; then - prsub="$prsub -s%^exec_prefix\\([ ]*\\)=\\([ ]*\\).*$%\ -exec_prefix\\1=\\2$exec_prefix%" +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' fi -trap 'rm -f config.status; exit 1' 1 3 15 -echo creating config.status -rm -f config.status -cat > config.status <<EOF -#!/bin/sh +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) \(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS <<EOF +#! /bin/sh # Generated automatically by configure. # Run this file to recreate the current configuration. # This directory was configured as follows, # on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # -# $0 $* +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. -for arg +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option do - case "\$arg" in - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - exec /bin/sh $0 $* ;; - *) echo "Usage: config.status --recheck" 2>&1; exit 1 ;; + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.4" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; esac done -trap 'rm -f Makefile; exit 1' 1 3 15 -PROGS='$PROGS' -CC='$CC' -CPP='$CPP' -INSTALL='$INSTALL' -INSTALL_PROGRAM='$INSTALL_PROGRAM' -INSTALL_DATA='$INSTALL_DATA' -LIBS='$LIBS' -srcdir='$srcdir' -DEFS='$DEFS' -prefix='$prefix' -exec_prefix='$exec_prefix' -prsub='$prsub' +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g$/@g/; /@g$/s/[\\\\&%]/\\\\&/g; + s/@@/%@/; s/@@/@%/; s/@g$/%g/' > conftest.subs <<\CEOF +$ac_vpsub +$extrasub +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@installdata@%$installdata%g +s%@uninstalldata@%$uninstalldata%g +s%@termcapfile@%$termcapfile%g +s%@CC@%$CC%g +s%@RANLIB@%$RANLIB%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@CPP@%$CPP%g + +CEOF EOF -cat >> config.status <<\EOF +cat >> $CONFIG_STATUS <<EOF + +CONFIG_FILES=\${CONFIG_FILES-"Makefile"} +EOF +cat >> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust relative srcdir, etc. for subdirectories. -top_srcdir=$srcdir -for file in .. Makefile; do if [ "x$file" != "x.." ]; then - srcdir=$top_srcdir # Remove last slash and all that follows it. Not all systems have dirname. - dir=`echo $file|sed 's%/[^/][^/]*$%%'` - if test "$dir" != "$file"; then - test "$top_srcdir" != . && srcdir=$top_srcdir/$dir - test ! -d $dir && mkdir $dir + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= fi - echo creating $file - rm -f $file - echo "# Generated automatically from `echo $file|sed 's|.*/||'`.in by configure." > $file - sed -e " -$prsub -s%@PROGS@%$PROGS%g -s%@CC@%$CC%g -s%@CPP@%$CPP%g -s%@INSTALL@%$INSTALL%g -s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g -s%@INSTALL_DATA@%$INSTALL_DATA%g -s%@LIBS@%$LIBS%g + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g -s%@DEFS@%$DEFS% -" $top_srcdir/${file}.in >> $file +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" -f conftest.subs $ac_given_srcdir/$ac_file_in > $ac_file fi; done +rm -f conftest.subs + + exit 0 EOF -chmod +x config.status -test -n "$no_create" || ./config.status +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 diff --git a/lib/termcap/grot/configure.in b/lib/termcap/grot/configure.in index 1c2aaf2..f3f944f 100644 --- a/lib/termcap/grot/configure.in +++ b/lib/termcap/grot/configure.in @@ -1,10 +1,23 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(termcap.h) -AC_SUBST(PROGS)dnl + +AC_ARG_ENABLE(install-termcap, +[ --enable-install-termcap install the termcap data file], +[if test $enableval = yes; then + installdata=install-data uninstalldata=uninstall-data + fi]) +AC_SUBST(installdata)dnl +AC_SUBST(uninstalldata)dnl + +AC_ARG_WITH(termcap, +[ --with-termcap=FILE use data file FILE instead of /etc/termcap], +termcapfile=$withval, termcapfile=/etc/termcap) +AC_SUBST(termcapfile)dnl + AC_PROG_CC -AC_PROG_CPP +AC_PROG_RANLIB AC_PROG_INSTALL -AC_HAVE_HEADERS(string.h) -AC_UNISTD_H +AC_HAVE_HEADERS(string.h unistd.h) AC_STDC_HEADERS + AC_OUTPUT(Makefile) diff --git a/lib/termcap/grot/termcap.info b/lib/termcap/grot/termcap.info index f8515f1..f663195 100644 --- a/lib/termcap/grot/termcap.info +++ b/lib/termcap/grot/termcap.info @@ -1,5 +1,5 @@ -This is Info file /home/gd/gnu/termcap/termcap.info, produced by -Makeinfo-1.52 from the input file /home/gd/gnu/termcap/termcap.texi. +This is Info file ./termcap.info, produced by Makeinfo-1.55 from the +input file ./termcap.texi. This file documents the termcap library of the GNU system. @@ -21,60 +21,60 @@ translation approved by the Foundation. Indirect: -termcap.info-1: 912 -termcap.info-2: 47539 -termcap.info-3: 90314 -termcap.info-4: 138449 +termcap.info-1: 874 +termcap.info-2: 47411 +termcap.info-3: 90390 +termcap.info-4: 138827 Tag Table: (Indirect) -Node: Top912 -Node: Introduction4143 -Node: Library5870 -Node: Preparation6889 -Node: Find8072 -Node: Interrogate11620 -Node: Initialize16928 -Node: Padding18568 -Node: Why Pad19274 -Node: Not Enough20896 -Node: Describe Padding23464 -Node: Output Padding24954 -Node: Parameters28569 -Node: Encode Parameters30229 -Node: Using Parameters36313 -Node: tparam36908 -Node: tgoto38934 -Node: Data Base41489 -Node: Format42385 -Node: Capability Format44474 -Node: Naming47539 -Node: Inheriting52108 -Node: Changing54352 -Node: Capabilities55516 -Node: Basic58255 -Node: Screen Size62308 -Node: Cursor Motion64048 -Node: Wrapping74190 -Node: Scrolling77015 -Node: Windows82904 -Node: Clearing83638 -Node: Insdel Line85402 -Node: Insdel Char90314 -Node: Standout100299 -Node: Underlining109357 -Node: Cursor Visibility111776 -Node: Bell112524 -Node: Keypad113073 -Node: Meta Key117794 -Node: Initialization118748 -Node: Pad Specs121112 -Node: Status Line123165 -Node: Half-Line125049 -Node: Printer125851 -Node: Summary127530 -Node: Var Index137736 -Node: Cap Index138449 -Node: Index145507 +Node: Top874 +Node: Introduction4105 +Node: Library5832 +Node: Preparation6851 +Node: Find8034 +Node: Interrogate11492 +Node: Initialize16800 +Node: Padding18440 +Node: Why Pad19146 +Node: Not Enough20768 +Node: Describe Padding23336 +Node: Output Padding24826 +Node: Parameters28441 +Node: Encode Parameters30101 +Node: Using Parameters36185 +Node: tparam36780 +Node: tgoto38806 +Node: Data Base41361 +Node: Format42257 +Node: Capability Format44346 +Node: Naming47411 +Node: Inheriting51980 +Node: Changing54224 +Node: Capabilities55388 +Node: Basic58127 +Node: Screen Size62180 +Node: Cursor Motion63920 +Node: Wrapping74062 +Node: Scrolling77091 +Node: Windows82980 +Node: Clearing83714 +Node: Insdel Line85478 +Node: Insdel Char90390 +Node: Standout100375 +Node: Underlining109433 +Node: Cursor Visibility111852 +Node: Bell112600 +Node: Keypad113149 +Node: Meta Key117864 +Node: Initialization118818 +Node: Pad Specs121369 +Node: Status Line123422 +Node: Half-Line125306 +Node: Printer126108 +Node: Summary127787 +Node: Var Index138114 +Node: Cap Index138827 +Node: Index145991 End Tag Table diff --git a/lib/termcap/grot/termcap.info-1 b/lib/termcap/grot/termcap.info-1 index 8390359..a5b5da0 100644 --- a/lib/termcap/grot/termcap.info-1 +++ b/lib/termcap/grot/termcap.info-1 @@ -1,5 +1,5 @@ -This is Info file /home/gd/gnu/termcap/termcap.info, produced by -Makeinfo-1.52 from the input file /home/gd/gnu/termcap/termcap.texi. +This is Info file ./termcap.info, produced by Makeinfo-1.55 from the +input file ./termcap.texi. This file documents the termcap library of the GNU system. @@ -218,10 +218,9 @@ variable `TERM' using `getenv ("TERM")'. If you are using the GNU version of termcap, you can alternatively ask `tgetent' to allocate enough space. Pass a null pointer for -BUFFER, and `tgetent' itself allocates the storage using `malloc'. In -this case the returned value on success is the address of the storage, -cast to `int'. But normally there is no need for you to look at the -address. Do not free the storage yourself. +BUFFER, and `tgetent' itself allocates the storage using `malloc'. +There is no way to get the address that was allocated, and you +shouldn't try to free the storage. With the Unix version of termcap, you must allocate space for the description yourself and pass the address of the space as the argument @@ -881,7 +880,7 @@ preferable for cursor motion. File: termcap.info, Node: tparam, Next: tgoto, Up: Using Parameters `tparam' --------- +........ The function `tparam' can encode display commands with any number of parameters and allows you to specify the buffer space. It is the @@ -930,7 +929,7 @@ capability. File: termcap.info, Node: tgoto, Prev: tparam, Up: Using Parameters `tgoto' -------- +....... The special case of cursor motion is handled by `tgoto'. There are two reasons why you might choose to use `tgoto': diff --git a/lib/termcap/grot/termcap.info-2 b/lib/termcap/grot/termcap.info-2 index 7142dc8..6098d62 100644 --- a/lib/termcap/grot/termcap.info-2 +++ b/lib/termcap/grot/termcap.info-2 @@ -1,5 +1,5 @@ -This is Info file /home/gd/gnu/termcap/termcap.info, produced by -Makeinfo-1.52 from the input file /home/gd/gnu/termcap/termcap.texi. +This is Info file ./termcap.info, produced by Makeinfo-1.55 from the +input file ./termcap.texi. This file documents the termcap library of the GNU system. @@ -663,6 +663,11 @@ column. carriage-return newline, which will leave the cursor at the beginning of the following line. +`LP' + Flag whose presence means that it is safe to write in the last + column of the last line without worrying about undesired + scrolling. `LP' indicates the DEC flavor of `xn' strangeness. + File: termcap.info, Node: Scrolling, Next: Windows, Prev: Wrapping, Up: Capabilities diff --git a/lib/termcap/grot/termcap.info-3 b/lib/termcap/grot/termcap.info-3 index c1e6af9..d5b309f 100644 --- a/lib/termcap/grot/termcap.info-3 +++ b/lib/termcap/grot/termcap.info-3 @@ -1,5 +1,5 @@ -This is Info file /home/gd/gnu/termcap/termcap.info, produced by -Makeinfo-1.52 from the input file /home/gd/gnu/termcap/termcap.texi. +This is Info file ./termcap.info, produced by Makeinfo-1.55 from the +input file ./termcap.texi. This file documents the termcap library of the GNU system. @@ -566,12 +566,12 @@ a `ks' capability and send it, to make the keypad actually transmit. Such programs should also send the `ke' string when exiting. `ks' - String of commands to make the function keys transmit. If this + String of commands to make the keypad keys transmit. If this capability is not provided, but the others in this section are, - programs may assume that the function keys always transmit. + programs may assume that the keypad keys always transmit. `ke' - String of commands to make the function keys work locally. This + String of commands to make the keypad keys work locally. This capability is provided only if `ks' is. `kl' @@ -784,6 +784,11 @@ Initialization String of commands to set tab stop at current cursor column on all lines. +`NF' + Flag whose presence means that the terminal does not support + XON/XOFF flow control. Programs should not send XON (`C-q') or + XOFF (`C-s') characters to the terminal. + File: termcap.info, Node: Pad Specs, Next: Status Line, Prev: Initialization, Up: Capabilities @@ -1266,6 +1271,9 @@ definitions, see the index of capability names (*note Cap Index::.). `lm' Number: lines of display memory. +`LP' + Flag: writing to last column of last line will not scroll. + `mb' String to enter blinking mode. @@ -1305,6 +1313,9 @@ definitions, see the index of capability names (*note Cap Index::.). `nd' String to move the cursor right one column. +`NF' + Flag: do not use XON/XOFF flow control. + `nl' Obsolete alternative name for the `do' and `sf' capabilities. diff --git a/lib/termcap/grot/termcap.info-4 b/lib/termcap/grot/termcap.info-4 index 21dd81c..4b8bf79 100644 --- a/lib/termcap/grot/termcap.info-4 +++ b/lib/termcap/grot/termcap.info-4 @@ -1,5 +1,5 @@ -This is Info file /home/gd/gnu/termcap/termcap.info, produced by -Makeinfo-1.52 from the input file /home/gd/gnu/termcap/termcap.texi. +This is Info file ./termcap.info, produced by Makeinfo-1.55 from the +input file ./termcap.texi. This file documents the termcap library of the GNU system. @@ -28,8 +28,8 @@ Capability Index * Menu: * ae: Standout. -* AL: Insdel Line. * al: Insdel Line. +* AL: Insdel Line. * am: Wrapping. * as: Standout. * bc: Cursor Motion. @@ -42,8 +42,8 @@ Capability Index * ce: Clearing. * ch: Cursor Motion. * cl: Clearing. -* CM: Cursor Motion. * cm: Cursor Motion. +* CM: Cursor Motion. * co: Screen Size. * cr: Cursor Motion. * cS: Scrolling. @@ -61,8 +61,8 @@ Capability Index * DL: Insdel Line. * dm: Insdel Char. * dN: Pad Specs. -* DO: Cursor Motion. * do: Cursor Motion. +* DO: Cursor Motion. * ds: Status Line. * dT: Pad Specs. * ec: Clearing. @@ -100,6 +100,7 @@ Capability Index * li: Screen Size. * ll: Cursor Motion. * lm: Scrolling. +* LP: Wrapping. * mb: Standout. * md: Standout. * me: Standout. @@ -114,6 +115,7 @@ Capability Index * ms: Underlining. * nc: Cursor Motion. * nd: Cursor Motion. +* NF: Initialization. * nl: Cursor Motion. * ns: Scrolling. * nw: Cursor Motion. @@ -131,12 +133,12 @@ Capability Index * sa: Standout. * sc: Cursor Motion. * se: Standout. -* sf: Scrolling. * SF: Scrolling. +* sf: Scrolling. * sg: Standout. * so: Standout. -* sr: Scrolling. * SR: Scrolling. +* sr: Scrolling. * st: Initialization. * ta: Cursor Motion. * te: Initialization. @@ -158,8 +160,8 @@ Capability Index * xb: Basic. * xn: Wrapping. * xs: Standout. -* xt: Standout. * xt: Cursor Motion. +* xt: Standout. File: termcap.info, Node: Index, Prev: Cap Index, Up: Top @@ -199,8 +201,8 @@ Concept Index * repeat output: Basic. * reset: Initialization. * screen size: Screen Size. -* screen size: Screen Size. * screen size: Naming. +* screen size: Screen Size. * scrolling: Scrolling. * standout: Standout. * status line: Status Line. @@ -212,7 +214,7 @@ Concept Index * visibility: Cursor Visibility. * visible bell: Bell. * window: Windows. -* wrapping: Naming. * wrapping: Wrapping. +* wrapping: Naming. diff --git a/lib/termcap/grot/termcap.texi b/lib/termcap/grot/termcap.texi index d991838..7a6cd56 100644 --- a/lib/termcap/grot/termcap.texi +++ b/lib/termcap/grot/termcap.texi @@ -1,5 +1,5 @@ \input texinfo @c -*-texinfo-*- -@setfilename termcap +@setfilename termcap.info @settitle The Termcap Library @smallbook @@ -286,9 +286,8 @@ variable @code{TERM} using @code{getenv ("TERM")}. If you are using the GNU version of termcap, you can alternatively ask @code{tgetent} to allocate enough space. Pass a null pointer for @var{buffer}, and @code{tgetent} itself allocates the storage using -@code{malloc}. In this case the returned value on success is the address -of the storage, cast to @code{int}. But normally there is no need for you -to look at the address. Do not free the storage yourself.@refill +@code{malloc}. There is no way to get the address that was allocated, +and you shouldn't try to free the storage.@refill With the Unix version of termcap, you must allocate space for the description yourself and pass the address of the space as the argument @@ -1890,6 +1889,12 @@ flag, output a @samp{cm} absolute positioning command after writing in the last column. Another safe thing to do is to output carriage-return newline, which will leave the cursor at the beginning of the following line. + +@item LP +@kindex LP +Flag whose presence means that it is safe to write in the last column of +the last line without worrying about undesired scrolling. @samp{LP} +indicates the DEC flavor of @samp{xn} strangeness. @end table @node Scrolling, Windows, Wrapping, Capabilities @@ -2830,12 +2835,12 @@ Such programs should also send the @samp{ke} string when exiting. @table @asis @item @samp{ks} @kindex ka@dots{}ku -String of commands to make the function keys transmit. If this +String of commands to make the keypad keys transmit. If this capability is not provided, but the others in this section are, -programs may assume that the function keys always transmit. +programs may assume that the keypad keys always transmit. @item @samp{ke} -String of commands to make the function keys work locally. This +String of commands to make the keypad keys work locally. This capability is provided only if @samp{ks} is. @item @samp{kl} @@ -3065,6 +3070,12 @@ String of commands to clear all tab stops. @kindex st String of commands to set tab stop at current cursor column on all lines. + +@item NF +@kindex NF +Flag whose presence means that the terminal does not support XON/XOFF +flow control. Programs should not send XON (@kbd{C-q}) or XOFF +(@kbd{C-s}) characters to the terminal. @end table @node Pad Specs, Status Line, Initialization, Capabilities @@ -3460,6 +3471,8 @@ Number: height of the screen. String to position cursor at lower left corner. @item lm Number: lines of display memory. +@item LP +Flag: writing to last column of last line will not scroll. @item mb String to enter blinking mode. @item md @@ -3486,6 +3499,8 @@ Flag: cursor motion in standout mode is safe. Obsolete flag: do not use ASCII carriage-return on this terminal. @item nd String to move the cursor right one column. +@item NF +Flag: do not use XON/XOFF flow control. @item nl Obsolete alternative name for the @samp{do} and @samp{sf} capabilities. @item ns diff --git a/lib/termcap/grot/texinfo.tex b/lib/termcap/grot/texinfo.tex index d10917e..f62e9f5 100644 --- a/lib/termcap/grot/texinfo.tex +++ b/lib/termcap/grot/texinfo.tex @@ -1,6 +1,6 @@ %% TeX macros to handle texinfo files -% Copyright (C) 1985, 86, 88, 90, 91, 92, 1993 Free Software Foundation, Inc. +% Copyright (C) 1985, 86, 88, 90, 91, 92, 93, 1994 Free Software Foundation, Inc. %This texinfo.tex file is free software; you can redistribute it and/or %modify it under the terms of the GNU General Public License as @@ -22,15 +22,30 @@ %You are forbidden to forbid anyone else to use, share and improve %what you give them. Help stamp out software-hoarding! -\def\texinfoversion{2.104} + +% Send bug reports to bug-texinfo@prep.ai.mit.edu. +% Please include a *precise* test case in each bug report. + + +% Make it possible to create a .fmt file just by loading this file: +% if the underlying format is not loaded, start by loading it now. +% Added by gildea November 1993. +\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi + +% This automatically updates the version number based on RCS. +\def\deftexinfoversion$#1: #2 ${\def\texinfoversion{#2}} +\deftexinfoversion$Revision: 2.146 $ \message{Loading texinfo package [Version \texinfoversion]:} -\message{} -% Print the version number if in a .fmt file. -\everyjob{\message{[Texinfo version \texinfoversion]}\message{}} +% If in a .fmt file, print the version number +% and turn on active characters that we couldn't do earlier because +% they might have appeared in the input file name. +\everyjob{\message{[Texinfo version \texinfoversion]}\message{} + \catcode`+=\active \catcode`\_=\active} % Save some parts of plain tex whose names we will redefine. +\let\ptextilde=\~ \let\ptexlbrace=\{ \let\ptexrbrace=\} \let\ptexdots=\dots @@ -45,7 +60,15 @@ \let\ptexl=\l \let\ptexL=\L -\def\tie{\penalty 10000\ } % Save plain tex definition of ~. +% Be sure we're in horizontal mode when doing a tie, since we make space +% equivalent to this in @example-like environments. Otherwise, a space +% at the beginning of a line will start with \penalty -- and +% since \penalty is valid in vertical mode, we'd end up putting the +% penalty on the vertical list instead of in the new paragraph. +{\catcode`@ = 11 + \gdef\tie{\leavevmode\penalty\@M\ } +} +\let\~ = \tie % And make it available as @~. \message{Basics,} \chardef\other=12 @@ -54,8 +77,21 @@ % starts a new line in the output. \newlinechar = `^^J +% Set up fixed words for English. +\ifx\putwordChapter\undefined{\gdef\putwordChapter{Chapter}}\fi% +\def\putwordInfo{Info}% +\ifx\putwordSee\undefined{\gdef\putwordSee{See}}\fi% +\ifx\putwordsee\undefined{\gdef\putwordsee{see}}\fi% +\ifx\putwordfile\undefined{\gdef\putwordfile{file}}\fi% +\ifx\putwordpage\undefined{\gdef\putwordpage{page}}\fi% +\ifx\putwordsection\undefined{\gdef\putwordsection{section}}\fi% +\ifx\putwordSection\undefined{\gdef\putwordSection{Section}}\fi% +\ifx\putwordTableofContents\undefined{\gdef\putwordTableofContents{Table of Contents}}\fi% +\ifx\putwordShortContents\undefined{\gdef\putwordShortContents{Short Contents}}\fi% +\ifx\putwordAppendix\undefined{\gdef\putwordAppendix{Appendix}}\fi% + % Ignore a token. -% +% \def\gobble#1{} \hyphenation{ap-pen-dix} @@ -73,9 +109,9 @@ % since that produces some useless output on the terminal. % \def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% -\def\loggingall{\tracingcommands2 \tracingstats2 - \tracingpages1 \tracingoutput1 \tracinglostchars1 - \tracingmacros2 \tracingparagraphs1 \tracingrestores1 +\def\loggingall{\tracingcommands2 \tracingstats2 + \tracingpages1 \tracingoutput1 \tracinglostchars1 + \tracingmacros2 \tracingparagraphs1 \tracingrestores1 \showboxbreadth\maxdimen\showboxdepth\maxdimen }% @@ -139,15 +175,20 @@ \nointerlineskip \vbox{\line{\ewbot\hfill\ewbot}} }} - \advancepageno + \advancepageno \ifnum\outputpenalty>-20000 \else\dosupereject\fi} % % Do @cropmarks to get crop marks \def\cropmarks{\let\onepageout=\croppageout } +\newinsert\margin \dimen\margin=\maxdimen + \def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} {\catcode`\@ =11 \gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi +% marginal hacks, juha@viisa.uucp (Juha Takala) +\ifvoid\margin\else % marginal info is present + \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi \dimen@=\dp#1 \unvbox#1 \ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi \ifr@ggedbottom \kern-\dimen@ \vfil \fi} @@ -225,7 +266,7 @@ % here.) But this means we cannot call \removeactivespaces as part of % \argremovec{,omment}, since @c uses \parsearg, and thus the argument % that \parsearg gets might well have any character at all in it. -% +% \def\removeactivespaces#1{% \begingroup \ignoreactivespaces @@ -235,7 +276,7 @@ } % Change the active space to expand to nothing. -% +% \begingroup \obeyspaces \gdef\ignoreactivespaces{\obeyspaces\let =\empty} @@ -283,26 +324,28 @@ } % There is an environment #1, but it hasn't been started. Give an error. -% +% \def\unmatchedenderror#1{% \errhelp = \EMsimple \errmessage{This `@end #1' doesn't have a matching `@#1'}% } % Define the control sequence \E#1 to give an unmatched @end error. -% +% \def\defineunmatchedend#1{% \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}% } -% Single-spacing is done by various environments. - -\newskip\singlespaceskip \singlespaceskip = \baselineskip +% Single-spacing is done by various environments (specifically, in +% \nonfillstart and \quotations). +\newskip\singlespaceskip \singlespaceskip = 12.5pt \def\singlespace{% -{\advance \baselineskip by -\singlespaceskip -\kern \baselineskip}% -\baselineskip=\singlespaceskip + % Why was this kern here? It messes up equalizing space above and below + % environments. --karl, 6may93 + %{\advance \baselineskip by -\singlespaceskip + %\kern \baselineskip}% + \setleading \singlespaceskip } %% Simple single-character @ commands @@ -334,6 +377,15 @@ % @. is an end-of-sentence period. \def\.{.\spacefactor=3000 } +% @enddots{} is an end-of-sentence ellipsis. +\gdef\enddots{$\mathinner{\ldotp\ldotp\ldotp\ldotp}$\spacefactor=3000} + +% @! is an end-of-sentence bang. +\gdef\!{!\spacefactor=3000 } + +% @? is an end-of-sentence query. +\gdef\?{?\spacefactor=3000 } + % @w prevents a word break. Without the \leavevmode, @w at the % beginning of a paragraph, when TeX is still in vertical mode, would % produce a whole line of output instead of starting the paragraph. @@ -346,7 +398,7 @@ % max (\topskip - \ht (first item), 0). If that height is large, % therefore, no glue is inserted, and the space between the headline and % the text is small, which looks bad. -% +% \def\group{\begingroup \ifnum\catcode13=\active \else \errhelp = \groupinvalidhelp @@ -356,8 +408,8 @@ % The \vtop we start below produces a box with normal height and large % depth; thus, TeX puts \baselineskip glue before it, and (when the % next line of text is done) \lineskip glue after it. (See p.82 of - % the TeXbook.) But the next line of text also gets us \parskip glue. - % Final result: space below is slightly more than space above. + % the TeXbook.) Thus, space below is not quite equal to space + % above. But it's pretty close. \def\Egroup{% \egroup % End the \vtop. \endgroup % End the \group. @@ -372,8 +424,24 @@ % Hence this just inserts a strut at the beginning of each line. \everypar = {\strut}% % - % We do @comment here in case we are called inside an environment, - % such as @example, where each end-of-line in the input causes an + % Since we have a strut on every line, we don't need any of TeX's + % normal interline spacing. + \offinterlineskip + % + % OK, but now we have to do something about blank + % lines in the input in @example-like environments, which normally + % just turn into \lisppar, which will insert no space now that we've + % turned off the interline space. Simplest is to make them be an + % empty paragraph. + \ifx\par\lisppar + \edef\par{\leavevmode \par}% + % + % Reset ^^M's definition to new definition of \par. + \obeylines + \fi + % + % Do @comment since we are called inside an environment such as + % @example, where each end-of-line in the input causes an % end-of-line in the output. We don't want the end-of-line after % the `@group' to put extra space in the output. Since @group % should appear on a line by itself (according to the Texinfo @@ -383,7 +451,7 @@ % % TeX puts in an \escapechar (i.e., `@') at the beginning of the help % message, so this ends up printing `@group can only ...'. -% +% \newhelp\groupinvalidhelp{% group can only be used in environments such as @example,^^J% where each line of input produces a line of output.} @@ -414,13 +482,13 @@ where each line of input produces a line of output.} \allowbreak \nointerlineskip \vtop to #1\mil{\vfil}% - % + % % TeX does not even consider page breaks if a penalty added to the % main vertical list is 10000 or more. But in order to see if the % empty box we just added fits on the page, we must make it consider % page breaks. On the other hand, we don't want to actually break the % page after the empty box. So we use a penalty of 9999. - % + % % There is an extremely small chance that TeX will actually break the % page at this \penalty, if there are no other feasible breakpoints in % sight. (If the user is using lots of big @group commands, which @@ -534,8 +602,8 @@ where each line of input produces a line of output.} % Used in nested conditionals, where we have to parse the Texinfo source % and so want to turn off most commands, in case they are used -% incorrectly. -% +% incorrectly. +% \def\ignoremorecommands{% \let\defcv = \relax \let\deffn = \relax @@ -561,20 +629,30 @@ where each line of input produces a line of output.} \let\pxref = \relax \let\settitle = \relax \let\include = \relax + \let\lowersections = \relax + \let\down = \relax + \let\raisesections = \relax + \let\up = \relax + \let\set = \relax + \let\clear = \relax + \let\item = \relax + \let\message = \relax } % Ignore @ignore ... @end ignore. -% +% \def\ignore{\doignore{ignore}} -% Also ignore @ifinfo, @menu, and @direntry text. -% +% Also ignore @ifinfo, @ifhtml, @html, @menu, and @direntry text. +% \def\ifinfo{\doignore{ifinfo}} +\def\ifhtml{\doignore{ifhtml}} +\def\html{\doignore{html}} \def\menu{\doignore{menu}} \def\direntry{\doignore{direntry}} % Ignore text until a line `@end #1'. -% +% \def\doignore#1{\begingroup % Don't complain about control sequences we have declared \outer. \ignoresections @@ -590,7 +668,7 @@ where each line of input produces a line of output.} } % What we do to finish off ignored text. -% +% \def\enddoignore{\endgroup\ignorespaces}% \newif\ifwarnedobs\warnedobsfalse @@ -619,7 +697,7 @@ where each line of input produces a line of output.} % Ignore text, except that we keep track of conditional commands for % purposes of nesting, up to an `@end #1' command. -% +% \def\nestedignore#1{% \obstexwarn % We must actually expand the ignored text to look for the @end @@ -627,7 +705,7 @@ where each line of input produces a line of output.} % text into a \vbox and then do nothing with the result. To minimize % the change of memory overflow, we follow the approach outlined on % page 401 of the TeXbook: make the current font be a dummy font. - % + % \setbox0 = \vbox\bgroup % Don't complain about control sequences we have declared \outer. \ignoresections @@ -644,7 +722,7 @@ where each line of input produces a line of output.} % We can't do anything about stray @-signs, unfortunately; % they'll produce `undefined control sequence' errors. \ignoremorecommands - % + % % Set the current font to be \nullfont, a TeX primitive, and define % all the font commands to also use \nullfont. We don't use % dummy.tfm, as suggested in the TeXbook, because not all sites @@ -656,6 +734,11 @@ where each line of input produces a line of output.} \let\tenrm = \nullfont \let\tenit = \nullfont \let\tensl = \nullfont \let\tenbf = \nullfont \let\tentt = \nullfont \let\smallcaps = \nullfont \let\tensf = \nullfont + % Similarly for index fonts (mostly for their use in + % smallexample) + \let\indrm = \nullfont \let\indit = \nullfont \let\indsl = \nullfont + \let\indbf = \nullfont \let\indtt = \nullfont \let\indsc = \nullfont + \let\indsf = \nullfont % % Don't complain when characters are missing from the fonts. \tracinglostchars = 0 @@ -675,7 +758,7 @@ where each line of input produces a line of output.} % @set VAR sets the variable VAR to an empty value. % @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. -% +% % Since we want to separate VAR from REST-OF-LINE (which might be % empty), we can't just use \parsearg; we have to insert a space of our % own to delimit the rest of the line, and then take it out again if we @@ -689,7 +772,10 @@ where each line of input produces a line of output.} \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted. \fi } -\def\setzzz#1#2 \endsetzzz{\expandafter\xdef\csname SET#1\endcsname{#2}} +% Can't use \xdef to pre-expand #2 and save some time, since \temp or +% \next or other control sequences that we've defined might get us into +% an infinite loop. Consider `@set foo @cite{bar}'. +\def\setzzz#1#2 \endsetzzz{\expandafter\gdef\csname SET#1\endcsname{#2}} % @clear VAR clears (i.e., unsets) the variable VAR. % @@ -705,7 +791,7 @@ where each line of input produces a line of output.} % @ifset VAR ... @end ifset reads the `...' iff VAR has been defined % with @set. -% +% \def\ifset{\parsearg\ifsetxxx} \def\ifsetxxx #1{% \expandafter\ifx\csname SET#1\endcsname\relax @@ -720,7 +806,7 @@ where each line of input produces a line of output.} % @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been % defined with @set, or has been undefined with @clear. -% +% \def\ifclear{\parsearg\ifclearxxx} \def\ifclearxxx #1{% \expandafter\ifx\csname SET#1\endcsname\relax @@ -735,7 +821,7 @@ where each line of input produces a line of output.} % @iftex always succeeds; we read the text following, through @end % iftex). But `@end iftex' should be valid only after an @iftex. -% +% \def\iftex{\conditionalsucceed{iftex}} \defineunmatchedend{iftex} @@ -745,7 +831,7 @@ where each line of input produces a line of output.} % define \Eiftex to redefine itself to be its previous value. (We can't % just define it to fail again with an ``unmatched end'' error, since % the @ifset might be nested.) -% +% \def\conditionalsucceed#1{% \edef\temp{% % Remember the current value of \E#1. @@ -763,7 +849,7 @@ where each line of input produces a line of output.} \def\nece#1{\expandafter\noexpand\csname#1\endcsname} % @asis just yields its argument. Used with @table, for example. -% +% \def\asis#1{#1} % @math means output in math mode. @@ -772,10 +858,10 @@ where each line of input produces a line of output.} % we read the toc file back, the $'s will be normal characters (as they % should be, according to the definition of Texinfo). So we must use a % control sequence to switch into and out of math mode. -% +% % This isn't quite enough for @math to work properly in indices, but it % seems unlikely it will ever be needed there. -% +% \let\implicitmath = $ \def\math#1{\implicitmath #1\implicitmath} @@ -791,18 +877,18 @@ where each line of input produces a line of output.} \def\donoderef{\ifx\lastnode\relax\else \expandafter\expandafter\expandafter\setref{\lastnode}\fi -\let\lastnode=\relax} +\global\let\lastnode=\relax} \def\unnumbnoderef{\ifx\lastnode\relax\else \expandafter\expandafter\expandafter\unnumbsetref{\lastnode}\fi -\let\lastnode=\relax} +\global\let\lastnode=\relax} \def\appendixnoderef{\ifx\lastnode\relax\else \expandafter\expandafter\expandafter\appendixsetref{\lastnode}\fi -\let\lastnode=\relax} +\global\let\lastnode=\relax} \let\refill=\relax - + % @setfilename is done at the beginning of every texinfo file. % So open here the files we need to have open while reading the input. % This makes it possible to make a .fmt file for texinfo. @@ -818,7 +904,7 @@ where each line of input produces a line of output.} \outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} \def\inforef #1{\inforefzzz #1,,,,**} -\def\inforefzzz #1,#2,#3,#4**{See Info file \file{\ignorespaces #3{}}, +\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, node \samp{\ignorespaces#1{}}} \message{fonts,} @@ -834,95 +920,106 @@ where each line of input produces a line of output.} %% Try out Computer Modern fonts at \magstephalf \let\mainmagstep=\magstephalf +% Set the font macro #1 to the font named #2, adding on the +% specified font prefix (normally `cm'). +\def\setfont#1#2{\font#1=\fontprefix#2} + +% Use cm as the default font prefix. +% To specify the font prefix, you must define \fontprefix +% before you read in texinfo.tex. +\ifx\fontprefix\undefined +\def\fontprefix{cm} +\fi + \ifx\bigger\relax \let\mainmagstep=\magstep1 -\font\textrm=cmr12 -\font\texttt=cmtt12 +\setfont\textrm{r12} +\setfont\texttt{tt12} \else -\font\textrm=cmr10 scaled \mainmagstep -\font\texttt=cmtt10 scaled \mainmagstep +\setfont\textrm{r10 scaled \mainmagstep} +\setfont\texttt{tt10 scaled \mainmagstep} \fi % Instead of cmb10, you many want to use cmbx10. % cmbx10 is a prettier font on its own, but cmb10 % looks better when embedded in a line with cmr10. -\font\textbf=cmb10 scaled \mainmagstep -\font\textit=cmti10 scaled \mainmagstep -\font\textsl=cmsl10 scaled \mainmagstep -\font\textsf=cmss10 scaled \mainmagstep -\font\textsc=cmcsc10 scaled \mainmagstep +\setfont\textbf{b10 scaled \mainmagstep} +\setfont\textit{ti10 scaled \mainmagstep} +\setfont\textsl{sl10 scaled \mainmagstep} +\setfont\textsf{ss10 scaled \mainmagstep} +\setfont\textsc{csc10 scaled \mainmagstep} \font\texti=cmmi10 scaled \mainmagstep \font\textsy=cmsy10 scaled \mainmagstep % A few fonts for @defun, etc. -\font\defbf=cmbx10 scaled \magstep1 %was 1314 -\font\deftt=cmtt10 scaled \magstep1 +\setfont\defbf{bx10 scaled \magstep1} %was 1314 +\setfont\deftt{tt10 scaled \magstep1} \def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf} % Fonts for indices and small examples. -% We actually use the slanted font rather than the italic, +% We actually use the slanted font rather than the italic, % because texinfo normally uses the slanted fonts for that. % Do not make many font distinctions in general in the index, since they % aren't very useful. -\font\ninett=cmtt9 -\font\indrm=cmr9 -\font\indit=cmsl9 +\setfont\ninett{tt9} +\setfont\indrm{r9} +\setfont\indit{sl9} \let\indsl=\indit \let\indtt=\ninett \let\indsf=\indrm \let\indbf=\indrm -\let\indsc=\indrm +\setfont\indsc{csc10 at 9pt} \font\indi=cmmi9 \font\indsy=cmsy9 % Fonts for headings -\font\chaprm=cmbx12 scaled \magstep2 -\font\chapit=cmti12 scaled \magstep2 -\font\chapsl=cmsl12 scaled \magstep2 -\font\chaptt=cmtt12 scaled \magstep2 -\font\chapsf=cmss12 scaled \magstep2 +\setfont\chaprm{bx12 scaled \magstep2} +\setfont\chapit{ti12 scaled \magstep2} +\setfont\chapsl{sl12 scaled \magstep2} +\setfont\chaptt{tt12 scaled \magstep2} +\setfont\chapsf{ss12 scaled \magstep2} \let\chapbf=\chaprm -\font\chapsc=cmcsc10 scaled\magstep3 +\setfont\chapsc{csc10 scaled\magstep3} \font\chapi=cmmi12 scaled \magstep2 \font\chapsy=cmsy10 scaled \magstep3 -\font\secrm=cmbx12 scaled \magstep1 -\font\secit=cmti12 scaled \magstep1 -\font\secsl=cmsl12 scaled \magstep1 -\font\sectt=cmtt12 scaled \magstep1 -\font\secsf=cmss12 scaled \magstep1 -\font\secbf=cmbx12 scaled \magstep1 -\font\secsc=cmcsc10 scaled\magstep2 +\setfont\secrm{bx12 scaled \magstep1} +\setfont\secit{ti12 scaled \magstep1} +\setfont\secsl{sl12 scaled \magstep1} +\setfont\sectt{tt12 scaled \magstep1} +\setfont\secsf{ss12 scaled \magstep1} +\setfont\secbf{bx12 scaled \magstep1} +\setfont\secsc{csc10 scaled\magstep2} \font\seci=cmmi12 scaled \magstep1 \font\secsy=cmsy10 scaled \magstep2 -% \font\ssecrm=cmbx10 scaled \magstep1 % This size an font looked bad. -% \font\ssecit=cmti10 scaled \magstep1 % The letters were too crowded. -% \font\ssecsl=cmsl10 scaled \magstep1 -% \font\ssectt=cmtt10 scaled \magstep1 -% \font\ssecsf=cmss10 scaled \magstep1 +% \setfont\ssecrm{bx10 scaled \magstep1} % This size an font looked bad. +% \setfont\ssecit{cmti10 scaled \magstep1} % The letters were too crowded. +% \setfont\ssecsl{sl10 scaled \magstep1} +% \setfont\ssectt{tt10 scaled \magstep1} +% \setfont\ssecsf{ss10 scaled \magstep1} -%\font\ssecrm=cmb10 scaled 1315 % Note the use of cmb rather than cmbx. -%\font\ssecit=cmti10 scaled 1315 % Also, the size is a little larger than -%\font\ssecsl=cmsl10 scaled 1315 % being scaled magstep1. -%\font\ssectt=cmtt10 scaled 1315 -%\font\ssecsf=cmss10 scaled 1315 +%\setfont\ssecrm{b10 scaled 1315} % Note the use of cmb rather than cmbx. +%\setfont\ssecit{ti10 scaled 1315} % Also, the size is a little larger than +%\setfont\ssecsl{sl10 scaled 1315} % being scaled magstep1. +%\setfont\ssectt{tt10 scaled 1315} +%\setfont\ssecsf{ss10 scaled 1315} %\let\ssecbf=\ssecrm -\font\ssecrm=cmbx12 scaled \magstephalf -\font\ssecit=cmti12 scaled \magstephalf -\font\ssecsl=cmsl12 scaled \magstephalf -\font\ssectt=cmtt12 scaled \magstephalf -\font\ssecsf=cmss12 scaled \magstephalf -\font\ssecbf=cmbx12 scaled \magstephalf -\font\ssecsc=cmcsc10 scaled \magstep1 +\setfont\ssecrm{bx12 scaled \magstephalf} +\setfont\ssecit{ti12 scaled \magstephalf} +\setfont\ssecsl{sl12 scaled \magstephalf} +\setfont\ssectt{tt12 scaled \magstephalf} +\setfont\ssecsf{ss12 scaled \magstephalf} +\setfont\ssecbf{bx12 scaled \magstephalf} +\setfont\ssecsc{csc10 scaled \magstep1} \font\sseci=cmmi12 scaled \magstephalf \font\ssecsy=cmsy10 scaled \magstep1 % The smallcaps and symbol fonts should actually be scaled \magstep1.5, % but that is not a standard magnification. % Fonts for title page: -\font\titlerm = cmbx12 scaled \magstep3 +\setfont\titlerm{bx12 scaled \magstep3} \let\authorrm = \secrm % In order for the font changes to affect most math symbols and letters, @@ -930,7 +1027,7 @@ where each line of input produces a line of output.} % texinfo doesn't allow for producing subscripts and superscripts, we % don't bother to reset \scriptfont and \scriptscriptfont (which would % also require loading a lot more fonts). -% +% \def\resetmathfonts{% \textfont0 = \tenrm \textfont1 = \teni \textfont2 = \tensy \textfont\itfam = \tenit \textfont\slfam = \tensl \textfont\bffam = \tenbf @@ -943,14 +1040,14 @@ where each line of input produces a line of output.} % in math mode, where it is the current \fam that is relevant in most % cases, not the current. Plain TeX does, for example, % \def\bf{\fam=\bffam \tenbf} By redefining \tenbf, we obviate the need -% to redefine \bf itself. +% to redefine \bf itself. \def\textfonts{% \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy \resetmathfonts} \def\chapfonts{% - \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl + \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy \resetmathfonts} @@ -971,16 +1068,16 @@ where each line of input produces a line of output.} \resetmathfonts} % Set up the default fonts, so we can use them for creating boxes. -% +% \textfonts % Count depth in font-changes, for error checks \newcount\fontdepth \fontdepth=0 % Fonts for short table of contents. -\font\shortcontrm=cmr12 -\font\shortcontbf=cmbx12 -\font\shortcontsl=cmsl12 +\setfont\shortcontrm{r12} +\setfont\shortcontbf{bx12} +\setfont\shortcontsl{sl12} %% Add scribe-like font environments, plus @l for inline lisp (usually sans %% serif) and @ii for TeX italic @@ -1002,16 +1099,15 @@ where each line of input produces a line of output.} % We can't just use \exhyphenpenalty, because that only has effect at % the end of a paragraph. Restore normal hyphenation at the end of the % group within which \nohyphenation is presumably called. -% +% \def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation} \def\restorehyphenation{\hyphenchar\font = `- } \def\t#1{% - {\tt \nohyphenation \rawbackslash \frenchspacing #1}% + {\tt \rawbackslash \frenchspacing #1}% \null } -\let\ttfont = \t -%\def\samp #1{`{\tt \rawbackslash \frenchspacing #1}'\null} +\let\ttfont=\t \def\samp #1{`\tclose{#1}'\null} \def\key #1{{\tt \nohyphenation \uppercase{#1}}\null} \def\ctrl #1{{\tt \rawbackslash \hat}#1} @@ -1033,17 +1129,43 @@ where each line of input produces a line of output.} % % Turn off hyphenation. \nohyphenation - % + % \rawbackslash \frenchspacing #1% }% \null } -\let\code=\tclose + +% We *must* turn on hyphenation at `-' and `_' in \code. +% Otherwise, it is too hard to avoid overful hboxes +% in the Emacs manual, the Library manual, etc. + +% Unfortunately, TeX uses one parameter (\hyphenchar) to control +% both hyphenation at - and hyphenation within words. +% We must therefore turn them both off (\tclose does that) +% and arrange explicitly to hyphenate an a dash. +% -- rms. +{ +\catcode`\-=\active +\catcode`\_=\active +\global\def\code{\begingroup \catcode`\-=\active \let-\codedash \catcode`\_=\active \let_\codeunder \codex} +% The following is used by \doprintindex to insure that long function names +% wrap around. It is necessary for - and _ to be active before the index is +% read from the file, as \entry parses the arguments long before \code is +% ever called. -- mycroft +\global\def\indexbreaks{\catcode`\-=\active \let-\realdash \catcode`\_=\active \let_\realunder} +} + +\def\realdash{-} +\def\realunder{_} +\def\codedash{-\discretionary{}{}{}} +\def\codeunder{\normalunderscore\discretionary{}{}{}} +\def\codex #1{\tclose{#1}\endgroup} + %\let\exp=\tclose %Was temporary -% @kbd is like @code, except that if the argument is just one @key command, +% @kbd is like @code, except that if the argument is just one @key command, % then @kbd has no effect. \def\xkey{\key} @@ -1055,12 +1177,12 @@ where each line of input produces a line of output.} % Typeset a dimension, e.g., `in' or `pt'. The only reason for the % argument is to make the input look right: @dmn{pt} instead of % @dmn{}pt. -% +% \def\dmn#1{\thinspace #1} \def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par} -\def\l#1{{\li #1}\null} % +\def\l#1{{\li #1}\null} % \def\r#1{{\rm #1}} % roman font % Use of \lowercase was suggested. @@ -1099,7 +1221,7 @@ where each line of input produces a line of output.} \def\titlezzz##1{\leftline{\titlefont{##1}} % print a rule at the page bottom also. \finishedtitlepagefalse - \vskip4pt \hrule height 4pt \vskip4pt}% + \vskip4pt \hrule height 4pt width \hsize \vskip4pt}% % No rule at page bottom unless we print one at the top with @title. \finishedtitlepagetrue % @@ -1111,7 +1233,7 @@ where each line of input produces a line of output.} \def\author{\parsearg\authorzzz}% \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi {\authorfont \leftline{##1}}}% - % + % % Most title ``pages'' are actually two pages long, with space % at the top of the second. We don't want the ragged left on the second. \let\oldpage = \page @@ -1139,7 +1261,7 @@ where each line of input produces a line of output.} } \def\finishtitlepage{% - \vskip4pt \hrule height 2pt + \vskip4pt \hrule height 2pt width \hsize \vskip\titlepagebottomglue \finishedtitlepagetrue } @@ -1313,14 +1435,18 @@ July\or August\or September\or October\or November\or December\fi % They also define \itemindex % to index the item name in whatever manner is desired (perhaps none). +\newif\ifitemxneedsnegativevskip + +\def\itemxpar{\par\ifitemxneedsnegativevskip\vskip-\parskip\nobreak\fi} + \def\internalBitem{\smallbreak \parsearg\itemzzz} -\def\internalBitemx{\par \parsearg\itemzzz} +\def\internalBitemx{\itemxpar \parsearg\itemzzz} \def\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz} -\def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \par \parsearg\xitemzzz} +\def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \itemxpar \parsearg\xitemzzz} \def\internalBkitem{\smallbreak \parsearg\kitemzzz} -\def\internalBkitemx{\par \parsearg\kitemzzz} +\def\internalBkitemx{\itemxpar \parsearg\kitemzzz} \def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}% \itemzzz {#1}} @@ -1336,8 +1462,9 @@ July\or August\or September\or October\or November\or December\fi \nobreak % This prevents a break before @itemx. % % Be sure we are not still in the middle of a paragraph. - \parskip=0in - \par + %{\parskip = 0in + %\par + %}% % % If the item text does not fit in the space we have, put it on a line % by itself, and do not allow a page break either before or after that @@ -1345,17 +1472,36 @@ July\or August\or September\or October\or November\or December\fi % command is, e.g., @kindex, the whatsit would get put into the % horizontal list on a line by itself, resulting in extra blank space. \ifdim \wd0>\itemmax - \setbox0=\hbox{\hskip \leftskip \hskip -\tableindent \unhbox0}\box0 + % + % Make this a paragraph so we get the \parskip glue and wrapping, + % but leave it ragged-right. + \begingroup + \advance\leftskip by-\tableindent + \advance\hsize by\tableindent + \advance\rightskip by0pt plus1fil + \leavevmode\unhbox0\par + \endgroup + % + % We're going to be starting a paragraph, but we don't want the + % \parskip glue -- logically it's part of the @item we just started. + \nobreak \vskip-\parskip + % + % Stop a page break at the \parskip glue coming up. Unfortunately + % we can't prevent a possible page break at the following + % \baselineskip glue. \nobreak + \endgroup + \itemxneedsnegativevskipfalse \else % The item text fits into the space. Start a paragraph, so that the % following text (if any) will end up on the same line. Since that % text will be indented by \tableindent, we make the item text be in % a zero-width box. \noindent - \rlap{\hskip -\tableindent\box0}% + \rlap{\hskip -\tableindent\box0}\ignorespaces% + \endgroup% + \itemxneedsnegativevskiptrue% \fi - \endgroup } \def\item{\errmessage{@item while not in a table}} @@ -1377,14 +1523,14 @@ July\or August\or September\or October\or November\or December\fi {\obeylines\obeyspaces% \gdef\ftablex #1^^M{% \tabley\fnitemindex#1 \endtabley -\def\Eftable{\endgraf\endgroup\afterenvbreak}% +\def\Eftable{\endgraf\afterenvbreak\endgroup}% \let\Etable=\relax}} \def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex} {\obeylines\obeyspaces% \gdef\vtablex #1^^M{% \tabley\vritemindex#1 \endtabley -\def\Evtable{\endgraf\endgroup\afterenvbreak}% +\def\Evtable{\endgraf\afterenvbreak\endgroup}% \let\Etable=\relax}} \def\dontindex #1{} @@ -1411,7 +1557,7 @@ July\or August\or September\or October\or November\or December\fi \parindent = 0pt \parskip = \smallskipamount \ifdim \parskip=0pt \parskip=2pt \fi% -\def\Etable{\endgraf\endgroup\afterenvbreak}% +\def\Etable{\endgraf\afterenvbreak\endgroup}% \let\item = \internalBitem % \let\itemx = \internalBitemx % \let\kitem = \internalBkitem % @@ -1440,7 +1586,7 @@ July\or August\or September\or October\or November\or December\fi \parindent = 0pt % \parskip = \smallskipamount % \ifdim \parskip=0pt \parskip=2pt \fi% -\def#2{\endgraf\endgroup\afterenvbreak}% +\def#2{\endgraf\afterenvbreak\endgroup}% \def\itemcontents{#1}% \let\item=\itemizeitem} @@ -1451,13 +1597,13 @@ July\or August\or September\or October\or November\or December\fi % \splitoff TOKENS\endmark defines \first to be the first token in % TOKENS, and \rest to be the remainder. -% +% \def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}% % Allow an optional argument of an uppercase letter, lowercase letter, % or number, to specify the first label in the enumerated list. No % argument is the same as `1'. -% +% \def\enumerate{\parsearg\enumeratezzz} \def\enumeratezzz #1{\enumeratey #1 \endenumeratey} \def\enumeratey #1 #2\endenumeratey{% @@ -1479,11 +1625,11 @@ July\or August\or September\or October\or November\or December\fi % An ``uppercase letter'' is one whose \lccode is both nonzero, and % not equal to itself. % Otherwise, we assume it's a number. - % + % % We need the \relax at the end of the \ifnum lines to stop TeX from % continuing to look for a <number>. - % - \ifnum\lccode\expandafter`\thearg=0\relax + % + \ifnum\lccode\expandafter`\thearg=0\relax \numericenumerate % a number (we hope) \else % It's a letter. @@ -1501,7 +1647,7 @@ July\or August\or September\or October\or November\or December\fi % An @enumerate whose labels are integers. The starting integer is % given in \thearg. -% +% \def\numericenumerate{% \itemno = \thearg \startenumeration{\the\itemno}% @@ -1536,7 +1682,7 @@ July\or August\or September\or October\or November\or December\fi % Call itemizey, adding a period to the first argument and supplying the % common last two arguments. Also subtract one from the initial value in % \itemno, since @item increments \itemno. -% +% \def\startenumeration#1{% \advance\itemno by -1 \itemizey{#1.}\Eenumerate\flushcr @@ -1544,7 +1690,7 @@ July\or August\or September\or October\or November\or December\fi % @alphaenumerate and @capsenumerate are abbreviations for giving an arg % to @enumerate. -% +% \def\alphaenumerate{\enumerate{a}} \def\capsenumerate{\enumerate{A}} \def\Ealphaenumerate{\Eenumerate} @@ -1561,6 +1707,159 @@ July\or August\or September\or October\or November\or December\fi \vadjust{\penalty 1200}}% \flushcr} +% @multitable macros +% Amy Hendrickson, 8/18/94 +% +% @multitable ... @endmultitable will make as many columns as desired. +% Contents of each column will wrap at width given in preamble. Width +% can be specified either with sample text given in a template line, +% or in percent of \hsize, the current width of text on page. + +% Table can continue over pages but will only break between lines. + +% To make preamble: +% +% Either define widths of columns in terms of percent of \hsize: +% @multitable @percentofhsize .2 .3 .5 +% @item ... +% +% Numbers following @percentofhsize are the percent of the total +% current hsize to be used for each column. You may use as many +% columns as desired. + +% Or use a template: +% @multitable {Column 1 template} {Column 2 template} {Column 3 template} +% @item ... +% using the widest term desired in each column. + + +% Each new table line starts with @item, each subsequent new column +% starts with @tab. Empty columns may be produced by supplying @tab's +% with nothing between them for as many times as empty columns are needed, +% ie, @tab@tab@tab will produce two empty columns. + +% @item, @tab, @multicolumn or @endmulticolumn do not need to be on their +% own lines, but it will not hurt if they are. + +% Sample multitable: + +% @multitable {Column 1 template} {Column 2 template} {Column 3 template} +% @item first col stuff @tab second col stuff @tab third col +% @item +% first col stuff +% @tab +% second col stuff +% @tab +% third col +% @item first col stuff @tab second col stuff +% @tab Many paragraphs of text may be used in any column. +% +% They will wrap at the width determined by the template. +% @item@tab@tab This will be in third column. +% @endmultitable + +% Default dimensions may be reset by user. +% @intableparskip will set vertical space between paragraphs in table. +% @intableparindent will set paragraph indent in table. +% @spacebetweencols will set horizontal space to be left between columns. +% @spacebetweenlines will set vertical space to be left between lines. + +%%%% +% Dimensions + +\newdimen\intableparskip +\newdimen\intableparindent +\newdimen\spacebetweencols +\newdimen\spacebetweenlines +\intableparskip=0pt +\intableparindent=6pt +\spacebetweencols=12pt +\spacebetweenlines=12pt + +%%%% +% Macros used to set up halign preamble: +\let\endsetuptable\relax +\def\xendsetuptable{\endsetuptable} +\let\percentofhsize\relax +\def\xpercentofhsize{\percentofhsize} +\newif\ifsetpercent + +\newcount\colcount +\def\setuptable#1{\def\firstarg{#1}% +\ifx\firstarg\xendsetuptable\let\go\relax% +\else + \ifx\firstarg\xpercentofhsize\global\setpercenttrue% + \else + \ifsetpercent + \if#1.\else% + \global\advance\colcount by1 % + \expandafter\xdef\csname col\the\colcount\endcsname{.#1\hsize}% + \fi + \else + \global\advance\colcount by1 + \setbox0=\hbox{#1}% + \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}% + \fi% + \fi% + \let\go\setuptable% +\fi\go} +%%%% +% multitable syntax +\def\tab{&} + +%%%% +% @multitable ... @endmultitable definitions: + +\def\multitable#1\item{\bgroup +\let\item\cr +\tolerance=9500 +\hbadness=9500 +\parskip=\intableparskip +\parindent=\intableparindent +\overfullrule=0pt +\global\colcount=0\relax% +\def\Emultitable{\global\setpercentfalse\global\everycr{}\cr\egroup\egroup}% + % To parse everything between @multitable and @item : +\def\one{#1}\expandafter\setuptable\one\endsetuptable + % Need to reset this to 0 after \setuptable. +\global\colcount=0\relax% + % + % This preamble sets up a generic column definition, which will + % be used as many times as user calls for columns. + % \vtop will set a single line and will also let text wrap and + % continue for many paragraphs if desired. +\halign\bgroup&\global\advance\colcount by 1\relax% +\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname + % In order to keep entries from bumping into each other + % we will add a \leftskip of \spacebetweencols to all columns after + % the first one. + % If a template has been used, we will add \spacebetweencols + % to the width of each template entry. + % If user has set preamble in terms of percent of \hsize + % we will use that dimension as the width of the column, and + % the \leftskip will keep entries from bumping into each other. + % Table will start at left margin and final column will justify at + % right margin. +\ifnum\colcount=1 +\else + \ifsetpercent + \else + % If user has <not> set preamble in terms of percent of \hsize + % we will advance \hsize by \spacebetweencols + \advance\hsize by \spacebetweencols + \fi + % In either case we will make \leftskip=\spacebetweencols: +\leftskip=\spacebetweencols +\fi +\noindent##}\cr% + % \everycr will reset column counter, \colcount, at the end of + % each line. Every column entry will cause \colcount to advance by one. + % The table preamble + % looks at the current \colcount to find the correct column width. +\global\everycr{\noalign{\nointerlineskip\vskip\spacebetweenlines +\filbreak%% keeps underfull box messages off when table breaks over pages. +\global\colcount=0\relax}}} + \message{indexing,} % Index generation facilities @@ -1635,6 +1934,32 @@ July\or August\or September\or October\or November\or December\fi \def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}} \def\indexdummies{% +% Take care of the plain tex accent commands. +\def\"{\realbackslash "}% +\def\`{\realbackslash `}% +\def\'{\realbackslash '}% +\def\^{\realbackslash ^}% +\def\~{\realbackslash ~}% +\def\={\realbackslash =}% +\def\b{\realbackslash b}% +\def\c{\realbackslash c}% +\def\d{\realbackslash d}% +\def\u{\realbackslash u}% +\def\v{\realbackslash v}% +\def\H{\realbackslash H}% +% Take care of the plain tex special European modified letters. +\def\oe{\realbackslash oe}% +\def\ae{\realbackslash ae}% +\def\aa{\realbackslash aa}% +\def\OE{\realbackslash OE}% +\def\AE{\realbackslash AE}% +\def\AA{\realbackslash AA}% +\def\o{\realbackslash o}% +\def\O{\realbackslash O}% +\def\l{\realbackslash l}% +\def\L{\realbackslash L}% +\def\ss{\realbackslash ss}% +% Take care of texinfo commands likely to appear in an index entry. \def\_{{\realbackslash _}}% \def\w{\realbackslash w }% \def\bf{\realbackslash bf }% @@ -1672,6 +1997,31 @@ July\or August\or September\or October\or November\or December\fi \def\indexdummydots{...} \def\indexnofonts{% +% Just ignore accents. +\let\"=\indexdummyfont +\let\`=\indexdummyfont +\let\'=\indexdummyfont +\let\^=\indexdummyfont +\let\~=\indexdummyfont +\let\==\indexdummyfont +\let\b=\indexdummyfont +\let\c=\indexdummyfont +\let\d=\indexdummyfont +\let\u=\indexdummyfont +\let\v=\indexdummyfont +\let\H=\indexdummyfont +% Take care of the plain tex special European modified letters. +\def\oe{oe}% +\def\ae{ae}% +\def\aa{aa}% +\def\OE{OE}% +\def\AE{AE}% +\def\AA{AA}% +\def\o{o}% +\def\O{O}% +\def\l{l}% +\def\L{L}% +\def\ss{ss}% \let\w=\indexdummyfont \let\t=\indexdummyfont \let\r=\indexdummyfont @@ -1704,7 +2054,14 @@ July\or August\or September\or October\or November\or December\fi \let\indexbackslash=0 %overridden during \printindex. +\let\SETmarginindex=\relax %initialize! +% workhorse for all \fooindexes +% #1 is name of index, #2 is stuff to put there \def\doind #1#2{% +% Put the index entry in the margin if desired. +\ifx\SETmarginindex\relax\else% +\insert\margin{\hbox{\vrule height8pt depth3pt width0pt #2}}% +\fi% {\count10=\lastpenalty % {\indexdummies % Must do this here, since \bf, etc expand at this stage \escapechar=`\\% @@ -1760,7 +2117,7 @@ July\or August\or September\or October\or November\or December\fi % \secondary {subtopic}{pagelist} % for each subtopic. -% Define the user-accessible indexing commands +% Define the user-accessible indexing commands % @findex, @vindex, @kindex, @cindex. \def\findex {\fnindex} @@ -1788,8 +2145,9 @@ July\or August\or September\or October\or November\or December\fi \tex \dobreak \chapheadingskip {10000} \catcode`\%=\other\catcode`\&=\other\catcode`\#=\other - \catcode`\$=\other\catcode`\_=\other + \catcode`\$=\other \catcode`\~=\other + \indexbreaks % % The following don't help, since the chars were translated % when the raw index was written, and their fonts were discarded @@ -1807,7 +2165,7 @@ July\or August\or September\or October\or November\or December\fi % % See if the index file exists and is nonempty. \openin 1 \jobname.#1s - \ifeof 1 + \ifeof 1 % \enddoublecolumns gets confused if there is no text in the index, % and it loses the chapter title and the aux file entries for the % index. The easiest way to prevent this problem is to make sure @@ -1846,7 +2204,7 @@ July\or August\or September\or October\or November\or December\fi % This typesets a paragraph consisting of #1, dot leaders, and then #2 % flush to the right margin. It is used for index and table of contents % entries. The paragraph is indented by \leftskip. -% +% \def\entry #1#2{\begingroup % % Start a new paragraph if necessary, so our assignments below can't @@ -1867,7 +2225,7 @@ July\or August\or September\or October\or November\or December\fi % dots pretty far over on the line. Unfortunately, a large % indentation looks wrong when the entry text itself is broken across % lines. So we use a small indentation and put up with long leaders. - % + % % \hangafter is reset to 1 (which is the value we want) at the start % of each paragraph, so we need not do anything with that. \hangindent=2em @@ -1882,23 +2240,32 @@ July\or August\or September\or October\or November\or December\fi % % Insert the text of the index entry. TeX will do line-breaking on it. #1% - % - % If we must, put the page number on a line of its own, and fill out - % this line with blank space. (The \hfil is overwhelmed with the - % fill leaders glue in \indexdotfill if the page number does fit.) - \hfil\penalty50 - \null\nobreak\indexdotfill % Have leaders before the page number. - % - % The `\ ' here is removed by the implicit \unskip that TeX does as - % part of (the primitive) \par. Without it, a spurious underfull - % \hbox ensues. - \ #2% The page number ends the paragraph. + % The following is kluged to not output a line of dots in the index if + % there are no page numbers. The next person who breaks this will be + % cursed by a Unix daemon. + \def\tempa{{\rm }}% + \def\tempb{#2}% + \edef\tempc{\tempa}% + \edef\tempd{\tempb}% + \ifx\tempc\tempd\ \else% + % + % If we must, put the page number on a line of its own, and fill out + % this line with blank space. (The \hfil is overwhelmed with the + % fill leaders glue in \indexdotfill if the page number does fit.) + \hfil\penalty50 + \null\nobreak\indexdotfill % Have leaders before the page number. + % + % The `\ ' here is removed by the implicit \unskip that TeX does as + % part of (the primitive) \par. Without it, a spurious underfull + % \hbox ensues. + \ #2% The page number ends the paragraph. + \fi% \par \endgroup} % Like \dotfill except takes at least 1 em. \def\indexdotfill{\cleaders - \hbox{$\mathsurround=0pt \mkern1.5mu . \mkern1.5mu$}\hskip 1em plus 1fill} + \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill} \def\primary #1{\line{#1\hfil}} @@ -1932,17 +2299,17 @@ July\or August\or September\or October\or November\or December\fi % format, but then we repeat the same computation. Repeating a couple % of assignments once per index is clearly meaningless for the % execution time, so we may as well do it once. - % + % % First we halve the line length, less a little for the gutter between % the columns. We compute the gutter based on the line length, so it % changes automatically with the paper format. The magic constant % below is chosen so that the gutter has the same value (well, +- < % 1pt) as it did when we hard-coded it. - % + % % We put the result in a separate register, \doublecolumhsize, so we % can restore it in \pagesofar, after \hsize itself has (potentially) % been clobbered. - % + % \doublecolumnhsize = \hsize \advance\doublecolumnhsize by -.04154\hsize \divide\doublecolumnhsize by 2 @@ -2130,13 +2497,13 @@ July\or August\or September\or October\or November\or December\fi \def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz \def\chapterzzz #1{\seccheck{chapter}% \secno=0 \subsecno=0 \subsubsecno=0 -\global\advance \chapno by 1 \message{Chapter \the\chapno}% +\global\advance \chapno by 1 \message{\putwordChapter \the\chapno}% \chapmacro {#1}{\the\chapno}% \gdef\thissection{#1}% \gdef\thischaptername{#1}% % We don't substitute the actual chapter name into \thischapter % because we don't want its macros evaluated now. -\xdef\thischapter{Chapter \the\chapno: \noexpand\thischaptername}% +\xdef\thischapter{\putwordChapter{} \the\chapno: \noexpand\thischaptername}% {\chapternofonts% \edef\temp{{\realbackslash chapentry {#1}{\the\chapno}{\noexpand\folio}}}% \escapechar=`\\% @@ -2152,13 +2519,13 @@ July\or August\or September\or October\or November\or December\fi \def\appendixzzz #1{\seccheck{appendix}% \secno=0 \subsecno=0 \subsubsecno=0 \global\advance \appendixno by 1 \message{Appendix \appendixletter}% -\chapmacro {#1}{Appendix \appendixletter}% +\chapmacro {#1}{\putwordAppendix{} \appendixletter}% \gdef\thissection{#1}% \gdef\thischaptername{#1}% -\xdef\thischapter{Appendix \appendixletter: \noexpand\thischaptername}% +\xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}% {\chapternofonts% -\edef\temp{{\realbackslash chapentry - {#1}{Appendix \appendixletter}{\noexpand\folio}}}% +\edef\temp{{\realbackslash chapentry + {#1}{\putwordAppendix{} \appendixletter}{\noexpand\folio}}}% \escapechar=`\\% \write \contentsfile \temp % \appendixnoderef % @@ -2177,8 +2544,8 @@ July\or August\or September\or October\or November\or December\fi % argument to \message. Therefore, if #1 contained @-commands, TeX % expanded them. For example, in `@unnumbered The @cite{Book}', TeX % expanded @cite (which turns out to cause errors because \cite is meant -% to be executed, not expanded). -% +% to be executed, not expanded). +% % Anyway, we don't want the fully-expanded definition of @cite to appear % as a result of the \message, we just want `@cite' itself. We use % \the<toks register> to achieve this: TeX expands \the<toks> only once, @@ -2465,7 +2832,7 @@ July\or August\or September\or October\or November\or December\fi \let\paragraphindent=\comment % Section fonts are the base font at magstep2, which produces -% a size a bit more than 14 points in the default situation. +% a size a bit more than 14 points in the default situation. \def\secheading #1#2#3{\secheadingi {#2.#3\enspace #1}} \def\plainsecheading #1{\secheadingi {#1}} @@ -2477,7 +2844,7 @@ July\or August\or September\or October\or November\or December\fi \ifdim \parskip<10pt \kern 10pt\kern -\parskip\fi \penalty 10000 } -% Subsection fonts are the base font at magstep1, +% Subsection fonts are the base font at magstep1, % which produces a size of 12 points. \def\subsecheading #1#2#3#4{\subsecheadingi {#2.#3.#4\enspace #1}} @@ -2512,19 +2879,20 @@ July\or August\or September\or October\or November\or December\fi \ifnum \pageno>0 \pageno = -1 % Request roman numbered pages. \fi - % Don't need to put `Contents' or `Short Contents' in the headline. + % Don't need to put `Contents' or `Short Contents' in the headline. % It is abundantly clear what they are. \unnumbchapmacro{#1}\def\thischapter{}% \begingroup % Set up to handle contents files properly. \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11 + \catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi \raggedbottom % Worry more about breakpoints than the bottom. \advance\hsize by -\contentsrightmargin % Don't use the full line length. } - + % Normal (long) toc. \outer\def\contents{% - \startcontents{Table of Contents}% + \startcontents{\putwordTableofContents}% \input \jobname.toc \endgroup \vfill \eject @@ -2532,7 +2900,7 @@ July\or August\or September\or October\or November\or December\fi % And just the chapters. \outer\def\summarycontents{% - \startcontents{Short Contents}% + \startcontents{\putwordShortContents}% % \let\chapentry = \shortchapentry \let\unnumbchapentry = \shortunnumberedentry @@ -2571,7 +2939,7 @@ July\or August\or September\or October\or November\or December\fi % We could simplify the code here by writing out an \appendixentry % command in the toc file for appendices, instead of using \chapentry % for both, but it doesn't seem worth it. -\setbox0 = \hbox{\shortcontrm Appendix } +\setbox0 = \hbox{\shortcontrm \putwordAppendix } \newdimen\shortappendixwidth \shortappendixwidth = \wd0 \def\shortchaplabel#1{% @@ -2608,10 +2976,10 @@ July\or August\or September\or October\or November\or December\fi % This parameter controls the indentation of the various levels. \newdimen\tocindent \tocindent = 3pc -% Now for the actual typesetting. In all these, #1 is the text and #2 is the +% Now for the actual typesetting. In all these, #1 is the text and #2 is the % page number. % -% If the toc has to be broken over pages, we would want to be at chapters +% If the toc has to be broken over pages, we would want to be at chapters % if at all possible; hence the \penalty. \def\dochapentry#1#2{% \penalty-300 \vskip\baselineskip @@ -2641,10 +3009,11 @@ July\or August\or September\or October\or November\or December\fi % the index entries, but we want to suppress hyphenation here. (We % can't do that in the \entry macro, since index entries might consist % of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.) -% +% +% \turnoffactive is for the sake of @" used for umlauts. \def\tocentry#1#2{\begingroup \hyphenpenalty = 10000 - \entry{#1}{#2}% + \entry{\turnoffactive #1}{\turnoffactive #2}% \endgroup} % Space between chapter (or whatever) number and the title. @@ -2661,7 +3030,7 @@ July\or August\or September\or October\or November\or December\fi \message{environments,} -% Since these characters are used in examples, it should be an even number of +% Since these characters are used in examples, it should be an even number of % \tt widths. Each \tt character is 1en, so two makes it 1em. % Furthermore, these definitions must come after we define our fonts. \newbox\dblarrowbox \newbox\longdblarrowbox @@ -2725,6 +3094,7 @@ July\or August\or September\or October\or November\or December\fi \catcode`\>=12 \escapechar=`\\ % +\let\~=\ptextilde \let\{=\ptexlbrace \let\}=\ptexrbrace \let\.=\ptexdot @@ -2744,28 +3114,32 @@ July\or August\or September\or October\or November\or December\fi % Amount to narrow the margins by for @lisp. \newskip\lispnarrowing \lispnarrowing=0.4in -% This is the definition that ^M gets inside @lisp -% phr: changed space to \null, to avoid overfull hbox problems. -{\obeyspaces% -\gdef\lisppar{\null\endgraf}} +% This is the definition that ^^M gets inside @lisp, @example, and other +% such environments. \null is better than a space, since it doesn't +% have any width. +\def\lisppar{\null\endgraf} % Make each space character in the input produce a normal interword % space in the output. Don't allow a line break at this space, as this % is used only in environments like @example, where each line of input % should produce a line of output anyway. -% +% {\obeyspaces % \gdef\sepspaces{\obeyspaces\let =\tie}} % Define \obeyedspace to be our active space, whatever it is. This is % for use in \parsearg. -{\sepspaces % +{\sepspaces% \global\let\obeyedspace= } % This space is always present above and below environments. \newskip\envskipamount \envskipamount = 0pt -% Make spacing and below environment symmetrical. +% Make spacing and below environment symmetrical. We use \parskip here +% to help in doing that, since in @example-like environments \parskip +% is reset to zero; thus the \afterenvbreak inserts no space -- but the +% start of the next paragraph will insert \parskip +% \def\aboveenvbreak{{\advance\envskipamount by \parskip \endgraf \ifdim\lastskip<\envskipamount \removelastskip \penalty-50 \vskip\envskipamount \fi}} @@ -2800,7 +3174,7 @@ July\or August\or September\or October\or November\or December\fi \begingroup \lskip=\leftskip \rskip=\rightskip \leftskip=0pt\rightskip=0pt %we want these *outside*. - \cartinner=\hsize \advance\cartinner by-\lskip + \cartinner=\hsize \advance\cartinner by-\lskip \advance\cartinner by-\rskip \cartouter=\hsize \advance\cartouter by 18pt % allow for 3pt kerns on either @@ -2833,7 +3207,7 @@ July\or August\or September\or October\or November\or December\fi \cartbot \egroup \endgroup -}} +}} % This macro is called at the beginning of all the @example variants, @@ -2843,7 +3217,7 @@ July\or August\or September\or October\or November\or December\fi \inENV % This group ends at the end of the body \hfuzz = 12pt % Don't be fussy \sepspaces % Make spaces be word-separators rather than space tokens. - \singlespace % single space lines + \singlespace \let\par = \lisppar % don't ignore blank lines \obeylines % each line of input is a line of output \parskip = 0pt @@ -2859,37 +3233,45 @@ July\or August\or September\or October\or November\or December\fi \fi } -\def\Elisp{\endgroup\afterenvbreak}% +% To ending an @example-like environment, we first end the paragraph +% (via \afterenvbreak's vertical glue), and then the group. That way we +% keep the zero \parskip that the environments set -- \parskip glue +% will be inserted at the beginning of the next paragraph in the +% document, after the environment. +% +\def\nonfillfinish{\afterenvbreak\endgroup}% +% This macro is \def\lisp{\begingroup \nonfillstart - \def\Elisp{\endgroup\afterenvbreak}% + \let\Elisp = \nonfillfinish \tt - \rawbackslash % output the \ character from the current font + \rawbackslash % have \ input char produce \ char from current font \gobble } % Define the \E... control sequence only if we are inside the % environment, so the error checking in \end will work. -% +% % We must call \lisp last in the definition, since it reads the % return following the @example (or whatever) command. % -\def\example{\begingroup \def\Eexample{\Elisp\endgroup}\lisp} -\def\smallexample{\begingroup \def\Esmallexample{\Elisp\endgroup}\lisp} +\def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp} +\def\smallexample{\begingroup \def\Esmallexample{\nonfillfinish\endgroup}\lisp} +\def\smalllisp{\begingroup \def\Esmalllisp{\nonfillfinish\endgroup}\lisp} -% Macro for 9 pt. examples, necessary to print with 5" lines. From -% Pavel@xerox. This is not used for @smallexamples unless the -% @smallbook command is given. +% @smallexample and @smalllisp. This is not used unless the @smallbook +% command is given. Originally contributed by Pavel@xerox. % \def\smalllispx{\begingroup \nonfillstart - \def\Esmalllisp{\endgroup\afterenvbreak}% + \let\Esmalllisp = \nonfillfinish + \let\Esmallexample = \nonfillfinish % % Smaller interline space and fonts for small examples. - \baselineskip 10pt + \setleading{10pt}% \indexfonts \tt - \rawbackslash % output the \ character from the current font + \rawbackslash % make \ output the \ character from the current font (tt) \gobble } @@ -2897,7 +3279,7 @@ July\or August\or September\or October\or November\or December\fi % \def\display{\begingroup \nonfillstart - \def\Edisplay{\endgroup\afterenvbreak}% + \let\Edisplay = \nonfillfinish \gobble } @@ -2906,7 +3288,7 @@ July\or August\or September\or October\or November\or December\fi \def\format{\begingroup \let\nonarrowing = t \nonfillstart - \def\Eformat{\endgroup\afterenvbreak} + \let\Eformat = \nonfillfinish \gobble } @@ -2915,33 +3297,36 @@ July\or August\or September\or October\or November\or December\fi \def\flushleft{\begingroup \let\nonarrowing = t \nonfillstart - \def\Eflushleft{\endgroup\afterenvbreak}% + \let\Eflushleft = \nonfillfinish \gobble } \def\flushright{\begingroup \let\nonarrowing = t \nonfillstart - \def\Eflushright{\endgroup\afterenvbreak}% + \let\Eflushright = \nonfillfinish \advance\leftskip by 0pt plus 1fill \gobble} -% @quotation does normal linebreaking and narrows the margins. +% @quotation does normal linebreaking (hence we can't use \nonfillstart) +% and narrows the margins. % \def\quotation{% -\begingroup\inENV %This group ends at the end of the @quotation body -{\parskip=0pt % because we will skip by \parskip too, later -\aboveenvbreak}% -\singlespace -\parindent=0pt -\def\Equotation{\par\endgroup\afterenvbreak}% -% @cartouche defines \nonarrowing to inhibit narrowing -% at next level down. -\ifx\nonarrowing\relax -\advance \leftskip by \lispnarrowing -\advance \rightskip by \lispnarrowing -\exdentamount=\lispnarrowing -\let\nonarrowing=\relax -\fi} + \begingroup\inENV %This group ends at the end of the @quotation body + {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip + \singlespace + \parindent=0pt + % We have retained a nonzero parskip for the environment, since we're + % doing normal filling. So to avoid extra space below the environment... + \def\Equotation{\parskip = 0pt \nonfillfinish}% + % + % @cartouche defines \nonarrowing to inhibit narrowing at next level down. + \ifx\nonarrowing\relax + \advance\leftskip by \lispnarrowing + \advance\rightskip by \lispnarrowing + \exdentamount = \lispnarrowing + \let\nonarrowing = \relax + \fi +} \message{defuns,} % Define formatter for defuns @@ -2973,6 +3358,9 @@ July\or August\or September\or October\or November\or December\fi \gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 } \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} +% This is used to turn on special parens +% but make & act ordinary (given that it's active). +\gdef\boldbraxnoamp{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb\let&=\ampnr} % Definitions of (, ) and & used in args for functions. % This is the definition of ( outside of all parentheses. @@ -3020,7 +3408,7 @@ July\or August\or September\or October\or November\or December\fi \advance \hsize by -\dimen2 \advance \hsize by -\dimen3 \rlap{\rightline{{\rm #2}\hskip \deftypemargin}}}% % Make all lines underfull and no complaints: -\tolerance=10000 \hbadness=10000 +\tolerance=10000 \hbadness=10000 \advance\leftskip by -\defbodyindent \exdentamount=\defbodyindent {\df #1}\enskip % Generate function name @@ -3042,7 +3430,7 @@ July\or August\or September\or October\or November\or December\fi \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent \exdentamount=\defbodyindent \begingroup % -\catcode 61=\active % +\catcode 61=\active % 61 is `=' \obeylines\activeparens\spacesplit#3} \def\defmethparsebody #1#2#3#4 {\begingroup\inENV % @@ -3085,55 +3473,54 @@ July\or August\or September\or October\or November\or December\fi \catcode 61=\active % \obeylines\spacesplit#3} -\def\defvrparsebody #1#2#3#4 {\begingroup\inENV % -\medbreak % -% Define the end token that this defining construct specifies -% so that it will exit this group. -\def#1{\endgraf\endgroup\medbreak}% -\def#2##1 {\begingroup\obeylines\spacesplit{#3{##1}}}% -\parindent=0in -\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent -\exdentamount=\defbodyindent -\begingroup\obeylines\spacesplit{#3{#4}}} - -% This seems to work right in all cases. -\let\deftpparsebody=\defvrparsebody -% This fails to work. When given `@deftp {Data Type} foo_t', -% it thinks the type name is just `f'. -%%% This is the same as all the others except for the last line. We need -%%% to parse the arguments differently for @deftp, since the ``attributes'' -%%% there are optional. -%%% -%%\def\deftpparsebody #1#2#3#4 {\begingroup\inENV % -%%\medbreak % -%%% Define the end token that this defining construct specifies -%%% so that it will exit this group. -%%\def#1{\endgraf\endgroup\medbreak}% -%%\def#2##1 {\begingroup\obeylines\spacesplit{#3{##1}}}% -%%\parindent=0in -%%\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent -%%\exdentamount=\defbodyindent -%%\begingroup\obeylines\parsetpheaderline{#3{#4}}} - -%%{\obeylines % -%% % Parse the type name and any attributes (field names, etc.). -%% % #1 is the beginning of the macro call that will produce the output, -%% % i.e., \deftpheader{CLASS}; this is passed from \deftpparsebody. -%% % #2 is the type name, e.g., `struct termios'. -%% % #3 is the (possibly empty) attribute list. -%% % -%% \gdef\parsetpheaderline#1#2#3^^M{% -%% \endgroup % Started in \deftpparsebody. -%% % -%% % If the attribute list is in fact empty, there will be no space after -%% % #2; so we can't put a space in our TeX parameter list. But if it -%% % isn't empty, then #3 will begin with an unwanted space. -%% \def\theargs{\ignorespaces #3}% -%% % -%% % Call the macro to produce the output. -%% #1{#2}\theargs % -%% }% -%%} +% This is used for \def{tp,vr}parsebody. It could probably be used for +% some of the others, too, with some judicious conditionals. +% +\def\parsebodycommon#1#2#3{% + \begingroup\inENV % + \medbreak % + % Define the end token that this defining construct specifies + % so that it will exit this group. + \def#1{\endgraf\endgroup\medbreak}% + \def#2##1 {\begingroup\obeylines\spacesplit{#3{##1}}}% + \parindent=0in + \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent + \exdentamount=\defbodyindent + \begingroup\obeylines +} + +\def\defvrparsebody#1#2#3#4 {% + \parsebodycommon{#1}{#2}{#3}% + \spacesplit{#3{#4}}% +} + +% This loses on `@deftp {Data Type} {struct termios}' -- it thinks the +% type is just `struct', because we lose the braces in `{struct +% termios}' when \spacesplit reads its undelimited argument. Sigh. +% \let\deftpparsebody=\defvrparsebody +% +% So, to get around this, we put \empty in with the type name. That +% way, TeX won't find exactly `{...}' as an undelimited argument, and +% won't strip off the braces. +% +\def\deftpparsebody #1#2#3#4 {% + \parsebodycommon{#1}{#2}{#3}% + \spacesplit{\parsetpheaderline{#3{#4}}}\empty +} + +% Fine, but then we have to eventually remove the \empty *and* the +% braces (if any). That's what this does, putting the result in \tptemp. +% +\def\removeemptybraces\empty#1\relax{\def\tptemp{#1}}% + +% After \spacesplit has done its work, this is called -- #1 is the final +% thing to call, #2 the type name (which starts with \empty), and #3 +% (which might be empty) the arguments. +% +\def\parsetpheaderline#1#2#3{% + \removeemptybraces#2\relax + #1{\tptemp}{#3}% +}% \def\defopvarparsebody #1#2#3#4#5 {\begingroup\inENV % \medbreak % @@ -3182,8 +3569,9 @@ July\or August\or September\or October\or November\or December\fi \def\deftypefunargs #1{% % Expand, preventing hyphenation at `-' chars. % Note that groups don't affect changes in \hyphenchar. -\functionparens -\code{#1}% +% Use \boldbraxnoamp, not \functionparens, so that & is not special. +\boldbraxnoamp +\tclose{#1}% avoid \code because of side effects on active chars \interlinepenalty=10000 \advance\rightskip by 0pt plus 1fil \endgraf\penalty 10000\vskip -\parskip\penalty 10000% @@ -3219,7 +3607,7 @@ July\or August\or September\or October\or November\or December\fi % #1 is the data type, #2 the name, #3 the args. \def\deftypefunheaderx #1#2 #3\relax{% \doind {fn}{\code{#2}}% Make entry in function index -\begingroup\defname {\code{#1} #2}{Function}% +\begingroup\defname {\defheaderxcond#1\relax$$$#2}{Function}% \deftypefunargs {#3}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } @@ -3228,12 +3616,19 @@ July\or August\or September\or October\or November\or December\fi \def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader} +% \defheaderxcond#1\relax$$$ +% puts #1 in @code, followed by a space, but does nothing if #1 is null. +\def\defheaderxcond#1#2$$${\ifx#1\relax\else\code{#1#2} \fi} + % #1 is the classification. #2 is the data type. #3 is the name and args. \def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax} % #1 is the classification, #2 the data type, #3 the name, #4 the args. \def\deftypefnheaderx #1#2#3 #4\relax{% \doind {fn}{\code{#3}}% Make entry in function index -\begingroup\defname {\code{#2} #3}{#1}% +\begingroup +\normalparens % notably, turn off `&' magic, which prevents +% at least some C++ text from working +\defname {\defheaderxcond#2\relax$$$#3}{#1}% \deftypefunargs {#4}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } @@ -3361,7 +3756,7 @@ July\or August\or September\or October\or November\or December\fi % #1 is the data type. #2 is the name. \def\deftypevarheader #1#2{% \doind {vr}{\code{#2}}% Make entry in variables index -\begingroup\defname {\code{#1} #2}{Variable}% +\begingroup\defname {\defheaderxcond#1\relax$$$#2}{Variable}% \interlinepenalty=10000 \endgraf\penalty 10000\vskip -\parskip\penalty 10000 \endgroup} @@ -3371,7 +3766,7 @@ July\or August\or September\or October\or November\or December\fi \def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader} \def\deftypevrheader #1#2#3{\doind {vr}{\code{#3}}% -\begingroup\defname {\code{#2} #3}{#1} +\begingroup\defname {\defheaderxcond#2\relax$$$#3}{#1} \interlinepenalty=10000 \endgraf\penalty 10000\vskip -\parskip\penalty 10000 \endgroup} @@ -3412,17 +3807,17 @@ July\or August\or September\or October\or November\or December\fi % \setref{foo} defines a cross-reference point named foo. \def\setref#1{% -%\dosetq{#1-title}{Ytitle}% +\dosetq{#1-title}{Ytitle}% \dosetq{#1-pg}{Ypagenumber}% \dosetq{#1-snt}{Ysectionnumberandtype}} \def\unnumbsetref#1{% -%\dosetq{#1-title}{Ytitle}% +\dosetq{#1-title}{Ytitle}% \dosetq{#1-pg}{Ypagenumber}% \dosetq{#1-snt}{Ynothing}} \def\appendixsetref#1{% -%\dosetq{#1-title}{Ytitle}% +\dosetq{#1-title}{Ytitle}% \dosetq{#1-pg}{Ypagenumber}% \dosetq{#1-snt}{Yappendixletterandtype}} @@ -3431,44 +3826,64 @@ July\or August\or September\or October\or November\or December\fi % cross-reference, #3 the printed node name, #4 the name of the Info % file, #5 the name of the printed manual. All but the node name can be % omitted. -% -\def\pxref#1{see \xrefX[#1,,,,,,,]} -\def\xref#1{See \xrefX[#1,,,,,,,]} -\def\ref#1{\xrefX[#1,,,,,,,]} -\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup% -\def\printedmanual{\ignorespaces #5}% -\def\printednodename{\ignorespaces #3}% -% -\setbox1=\hbox{\printedmanual}% -\setbox0=\hbox{\printednodename}% -\ifdim \wd0=0pt% -\def\printednodename{\ignorespaces #1}% -%%% Uncommment the following line to make the actual chapter or section title -%%% appear inside the square brackets. -%\def\printednodename{#1-title}% -\fi% -% % -% If we use \unhbox0 and \unhbox1 to print the node names, TeX does -% not insert empty discretionaries after hyphens, which means that it -% will not find a line break at a hyphen in a node names. Since some -% manuals are best written with fairly long node names, containing -% hyphens, this is a loss. Therefore, we simply give the text of -% the node name again, so it is as if TeX is seeing it for the first -% time. -\ifdim \wd1>0pt -section ``\printednodename'' in \cite{\printedmanual}% -\else% -\turnoffactive% -\refx{#1-snt}{} [\printednodename], page\tie\refx{#1-pg}{}% -\fi +\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]} +\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} +\def\ref#1{\xrefX[#1,,,,,,,]} +\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup + \def\printedmanual{\ignorespaces #5}% + \def\printednodename{\ignorespaces #3}% + \setbox1=\hbox{\printedmanual}% + \setbox0=\hbox{\printednodename}% + \ifdim \wd0 = 0pt + % No printed node name was explicitly given. + \ifx\SETxref-automatic-section-title\relax % + % Use the actual chapter/section title appear inside + % the square brackets. Use the real section title if we have it. + \ifdim \wd1>0pt% + % It is in another manual, so we don't have it. + \def\printednodename{\ignorespaces #1}% + \else + \ifhavexrefs + % We know the real title if we have the xref values. + \def\printednodename{\refx{#1-title}}% + \else + % Otherwise just copy the Info node name. + \def\printednodename{\ignorespaces #1}% + \fi% + \fi + \def\printednodename{#1-title}% + \else + % Use the node name inside the square brackets. + \def\printednodename{\ignorespaces #1}% + \fi + \fi + % + % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not + % insert empty discretionaries after hyphens, which means that it will + % not find a line break at a hyphen in a node names. Since some manuals + % are best written with fairly long node names, containing hyphens, this + % is a loss. Therefore, we give the text of the node name again, so it + % is as if TeX is seeing it for the first time. + \ifdim \wd1 > 0pt + \putwordsection{} ``\printednodename'' in \cite{\printedmanual}% + \else + % _ (for example) has to be the character _ for the purposes of the + % control sequence corresponding to the node, but it has to expand + % into the usual \leavevmode...\vrule stuff for purposes of + % printing. So we \turnoffactive for the \refx-snt, back on for the + % printing, back off for the \refx-pg. + {\turnoffactive \refx{#1-snt}{}}% + \space [\printednodename],\space + \turnoffactive \putwordpage\tie\refx{#1-pg}{}% + \fi \endgroup} % \dosetq is the interface for calls from other macros % Use \turnoffactive so that punctuation chars such as underscore % work in node names. -\def\dosetq #1#2{{\let\folio=0 \turnoffactive% +\def\dosetq #1#2{{\let\folio=0 \turnoffactive \auxhat% \edef\next{\write\auxfile{\internalsetq {#1}{#2}}}% \next}} @@ -3482,33 +3897,33 @@ section ``\printednodename'' in \cite{\printedmanual}% \def\Ypagenumber{\folio} -\def\Ytitle{\thischapter} +\def\Ytitle{\thissection} \def\Ynothing{} \def\Ysectionnumberandtype{% -\ifnum\secno=0 Chapter\xreftie\the\chapno % -\else \ifnum \subsecno=0 Section\xreftie\the\chapno.\the\secno % +\ifnum\secno=0 \putwordChapter\xreftie\the\chapno % +\else \ifnum \subsecno=0 \putwordSection\xreftie\the\chapno.\the\secno % \else \ifnum \subsubsecno=0 % -Section\xreftie\the\chapno.\the\secno.\the\subsecno % +\putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno % \else % -Section\xreftie\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno % +\putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno % \fi \fi \fi } \def\Yappendixletterandtype{% -\ifnum\secno=0 Appendix\xreftie'char\the\appendixno{}% -\else \ifnum \subsecno=0 Section\xreftie'char\the\appendixno.\the\secno % +\ifnum\secno=0 \putwordAppendix\xreftie'char\the\appendixno{}% +\else \ifnum \subsecno=0 \putwordSection\xreftie'char\the\appendixno.\the\secno % \else \ifnum \subsubsecno=0 % -Section\xreftie'char\the\appendixno.\the\secno.\the\subsecno % +\putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno % \else % -Section\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno % +\putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno % \fi \fi \fi } \gdef\xreftie{'tie} % Use TeX 3.0's \inputlineno to get the line number, for better error % messages, but if we're using an old version of TeX, don't do anything. -% +% \ifx\inputlineno\thisisundefined \let\linenumber = \empty % Non-3.0. \else @@ -3589,6 +4004,15 @@ Section\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno % \catcode `\&=\other % `\+ does not work, so use 43. \catcode 43=\other +% Make the characters 128-255 be printing characters +{% + \count 1=128 + \def\loop{% + \catcode\count 1=\other + \advance\count 1 by 1 + \ifnum \count 1<256 \loop \fi + }% +}% % the aux file uses ' as the escape. % Turn off \ as an escape so we do not lose on % entries which were dumped with control sequences in their names. @@ -3598,6 +4022,7 @@ Section\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno % \catcode `\{=1 \catcode `\}=2 \catcode `\%=\other \catcode `\'=0 +\catcode`\^=7 % to make ^^e4 etc usable in xref tags \catcode `\\=\other \openin 1 \jobname.aux \ifeof 1 \else \closein 1 \input \jobname.aux \global\havexrefstrue @@ -3643,7 +4068,7 @@ Section\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno % % Don't bother with the trickery in plain.tex to not require the % footnote text as a parameter. Our footnotes don't need to be so general. -% +% \long\gdef\footnotezzz#1{\insert\footins{% % We want to typeset this text as a normal paragraph, even if the % footnote reference occurs in (for example) a display environment. @@ -3674,15 +4099,15 @@ Section\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno % % Set the baselineskip to #1, and the lineskip and strut size % correspondingly. There is no deep meaning behind these magic numbers % used as factors; they just match (closely enough) what Knuth defined. -% -\def\lineskipfactor{.1} -\def\strutheightpercent{.71} -\def\strutdepthpercent{.29} +% +\def\lineskipfactor{.08333} +\def\strutheightpercent{.70833} +\def\strutdepthpercent {.29167} % \def\setleading#1{% - \baselineskip = #1\relax - \normalbaselineskip = \baselineskip - \lineskip = \lineskipfactor\baselineskip + \normalbaselineskip = #1\relax + \normallineskip = \lineskipfactor\normalbaselineskip + \normalbaselines \setbox\strutbox =\hbox{% \vrule width0pt height\strutheightpercent\baselineskip depth \strutdepthpercent \baselineskip @@ -3694,7 +4119,7 @@ Section\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno % % change spans more than two lines of output. To handle that, we would % have adopt a much more difficult approach (putting marks into the main % vertical list for the beginning and end of each change). -% +% \def\|{% % \vadjust can only be used in horizontal mode. \leavevmode @@ -3721,7 +4146,7 @@ Section\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno % % For a final copy, take out the rectangles % that mark overfull boxes (in case you have decided % that the text looks ok even though it passes the margin). -% +% \def\finalout{\overfullrule=0pt} @@ -3758,7 +4183,7 @@ Section\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno % % using an old version of TeX, don't do anything. We want the amount of % stretch added to depend on the line length, hence the dependence on % \hsize. This makes it come to about 9pt for the 8.5x11 format. -% +% \ifx\emergencystretch\thisisundefined % Allow us to assign to \emergencystretch anyway. \def\emergencystretch{\dimen0}% @@ -3784,6 +4209,8 @@ Section\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno % \global\tolerance=700 \global\hfuzz=1pt \global\contentsrightmargin=0pt +\global\deftypemargin=0pt +\global\defbodyindent=.5cm \global\pagewidth=\hsize \global\pageheight=\vsize @@ -3813,6 +4240,32 @@ Section\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno % \global\pageheight=\vsize } +% Allow control of the text dimensions. Parameters in order: textheight; +% textwidth; \voffset; \hoffset (!); binding offset. All require a dimension; +% header is additional; added length extends the bottom of the page. + +\def\changepagesizes#1#2#3#4#5{ + \global\vsize= #1 + \advance\vsize by \topskip + \global\voffset= #3 + \global\hsize= #2 + \global\outerhsize=\hsize + \global\advance\outerhsize by 0.5in + \global\outervsize=\vsize + \global\advance\outervsize by 0.6in + \global\pagewidth=\hsize + \global\pageheight=\vsize + \global\normaloffset= #4 + \global\bindingoffset= #5} + +% This layout is compatible with Latex on A4 paper. + +\def\afourlatex{\changepagesizes{22cm}{15cm}{7mm}{4.6mm}{5mm}} + +% Use @afourwide to print on European A4 paper in wide format. +\def\afourwide{\afourpaper +\changepagesizes{9.5in}{6.5in}{\hoffset}{\normaloffset}{\bindingoffset}} + % Define macros to output various characters with catcode for normal text. \catcode`\"=\other \catcode`\~=\other @@ -3839,7 +4292,7 @@ Section\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno % % otherwise. Since all the Computer Modern typewriter fonts have zero % interword stretch (and shrink), and it is reasonable to expect all % typewriter fonts to have this, we can check that font parameter. -% +% \def\ifusingtt#1#2{\ifdim \fontdimen3\the\font=0pt #1\else #2\fi} % Turn off all special characters except @ @@ -3854,6 +4307,7 @@ Section\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno % \def~{{\tt \char '176}} \chardef\hat=`\^ \catcode`\^=\active +\def\auxhat{\def^{'hat}} \def^{{\tt \hat}} \catcode`\_=\active @@ -3881,21 +4335,19 @@ Section\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno % %\catcode 27=\active %\def^^[{$\diamondsuit$} -% Used sometimes to turn off (effectively) the active characters -% even after parsing them. -\def\turnoffactive{\let"=\normaldoublequote -\let~=\normaltilde -\let^=\normalcaret -\let_=\normalunderscore -\let|=\normalverticalbar -\let<=\normalless -\let>=\normalgreater -\let+=\normalplus} - % Set up an active definition for =, but don't enable it most of the time. {\catcode`\==\active \global\def={{\tt \char 61}}} +\catcode`+=\active +\catcode`\_=\active + +% If a .fmt file is being used, characters that might appear in a file +% name cannot be active until we have parsed the command line. +% So turn them off again, and have \everyjob (or @setfilename) turn them on. +% \otherifyactive is called near the end of this file. +\def\otherifyactive{\catcode`+=\other \catcode`\_=\other} + \catcode`\@=0 % \rawbackslashxx output one backslash character in current font @@ -3916,18 +4368,47 @@ Section\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno % % \catcode 17=0 % Define control-q \catcode`\\=\active +% Used sometimes to turn off (effectively) the active characters +% even after parsing them. +@def@turnoffactive{@let"=@normaldoublequote +@let\=@realbackslash +@let~=@normaltilde +@let^=@normalcaret +@let_=@normalunderscore +@let|=@normalverticalbar +@let<=@normalless +@let>=@normalgreater +@let+=@normalplus} + +@def@normalturnoffactive{@let"=@normaldoublequote +@let\=@normalbackslash +@let~=@normaltilde +@let^=@normalcaret +@let_=@normalunderscore +@let|=@normalverticalbar +@let<=@normalless +@let>=@normalgreater +@let+=@normalplus} + +% Make _ and + \other characters, temporarily. +% This is canceled by @fixbackslash. +@otherifyactive + % If a .fmt file is being used, we don't want the `\input texinfo' to show up. -% That is what \eatinput is for; after that, the `\' should revert to printing +% That is what \eatinput is for; after that, the `\' should revert to printing % a backslash. % @gdef@eatinput input texinfo{@fixbackslash} @global@let\ = @eatinput % On the other hand, perhaps the file did not have a `\input texinfo'. Then -% the first `\{ in the file would cause an error. This macro tries to fix +% the first `\{ in the file would cause an error. This macro tries to fix % that, assuming it is called before the first `\' could plausibly occur. -% -@gdef@fixbackslash{@ifx\@eatinput @let\ = @normalbackslash @fi} +% Also back turn on active characters that might appear in the input +% file name, in case not using a pre-dumped format. +% +@gdef@fixbackslash{@ifx\@eatinput @let\ = @normalbackslash @fi + @catcode`+=@active @catcode`@_=@active} %% These look ok in all fonts, so just make them not special. The @rm below %% makes sure that the current font starts out as the newly loaded cmr10 diff --git a/lib/termcap/termcap.c b/lib/termcap/termcap.c index 3d6125a..2a270c4 100644 --- a/lib/termcap/termcap.c +++ b/lib/termcap/termcap.c @@ -1,5 +1,5 @@ /* Work-alike for termcap, plus extra features. - Copyright (C) 1985, 1986, 1993 Free Software Foundation, Inc. + Copyright (C) 1985, 86, 93, 94, 95 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,13 +17,17 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Emacs config.h may rename various library functions such as malloc. */ #ifdef HAVE_CONFIG_H -#include "config.h" -#else /* not HAVE_CONFIG_H */ -#if defined(HAVE_STRING_H) || defined(STDC_HEADERS) -#define bcopy(s, d, n) memcpy ((d), (s), (n)) +#include <config.h> + +/* Get the O_* definitions for open et al. */ +#include <sys/file.h> +#ifdef USG5 +#include <fcntl.h> #endif +#else /* not HAVE_CONFIG_H */ + #ifdef STDC_HEADERS #include <stdlib.h> #include <string.h> @@ -33,6 +37,11 @@ char *malloc (); char *realloc (); #endif +/* Do this after the include, in case string.h prototypes bcopy. */ +#if (defined(HAVE_STRING_H) || defined(STDC_HEADERS)) && !defined(bcopy) +#define bcopy(s, d, n) memcpy ((d), (s), (n)) +#endif + #ifdef HAVE_UNISTD_H #include <unistd.h> #endif @@ -46,6 +55,10 @@ char *realloc (); #define NULL (char *) 0 #endif +#ifndef O_RDONLY +#define O_RDONLY 0 +#endif + /* BUFSIZE is the initial size allocated for the buffer for reading the termcap file. It is not a limit. @@ -63,6 +76,10 @@ int bufsize = 128; #endif #endif +#ifndef TERMCAP_FILE +#define TERMCAP_FILE "/etc/termcap" +#endif + #ifndef emacs static void memory_out () @@ -203,7 +220,13 @@ tgetst1 (ptr, area) while ((c = *p++) && c != ':' && c != '\n') { if (c == '^') - c = *p++ & 037; + { + c = *p++; + if (c == '?') + c = 0177; + else + c &= 037; + } else if (c == '\\') { c = *p++; @@ -245,14 +268,14 @@ char PC; /* Actual baud rate if positive; - baud rate / 100 if negative. */ -static short speeds[] = +static int speeds[] = { #ifdef VMS 0, 50, 75, 110, 134, 150, -3, -6, -12, -18, -20, -24, -36, -48, -72, -96, -192 #else /* not VMS */ 0, 50, 75, 110, 135, 150, -2, -3, -6, -12, - -18, -24, -48, -96, -192, -384 + -18, -24, -48, -96, -192, -288, -384, -576, -1152 #endif /* not VMS */ }; @@ -268,6 +291,10 @@ tputs (str, nlines, outfun) #ifdef emacs extern baud_rate; speed = baud_rate; + /* For quite high speeds, convert to the smaller + units to avoid overflow. */ + if (speed > 10000) + speed = - speed / 100; #else if (ospeed == 0) speed = tputs_baud_rate; @@ -296,11 +323,14 @@ tputs (str, nlines, outfun) while (*str) (*outfun) (*str++); - /* padcount is now in units of tenths of msec. */ - padcount *= speeds[ospeed]; + /* PADCOUNT is now in units of tenths of msec. + SPEED is measured in characters per 10 seconds + or in characters per .1 seconds (if negative). + We use the smaller units for larger speeds to avoid overflow. */ + padcount *= speed; padcount += 500; padcount /= 1000; - if (speeds[ospeed] < 0) + if (speed < 0) padcount = -padcount; else { @@ -357,7 +387,16 @@ valid_filename_p (fn) #else /* !VMS */ +#ifdef MSDOS /* MW, May 1993 */ +static int +valid_filename_p (fn) + char *fn; +{ + return *fn == '/' || fn[1] == ':'; +} +#else #define valid_filename_p(fn) (*(fn) == '/') +#endif #endif /* !VMS */ @@ -388,9 +427,36 @@ tgetent (bp, name) char *indirect = NULL; /* Terminal type in :tc= in TERMCAP value. */ int filep; +#ifdef INTERNAL_TERMINAL + /* For the internal terminal we don't want to read any termcap file, + so fake it. */ + if (!strcmp (name, "internal")) + { + term = INTERNAL_TERMINAL; + if (!bp) + { + malloc_size = 1 + strlen (term); + bp = (char *) xmalloc (malloc_size); + } + strcpy (bp, term); + goto ret; + } +#endif /* INTERNAL_TERMINAL */ + + /* For compatibility with programs like `less' that want to + put data in the termcap buffer themselves as a fallback. */ + if (bp) + term_entry = bp; + termcap_name = getenv ("TERMCAP"); if (termcap_name && *termcap_name == '\0') termcap_name = NULL; +#if defined (MSDOS) && !defined (TEST) + if (termcap_name && (*termcap_name == '\\' + || *termcap_name == '/' + || termcap_name[1] == ':')) + dostounix_filename(termcap_name); +#endif filep = termcap_name && valid_filename_p (termcap_name); @@ -419,15 +485,15 @@ tgetent (bp, name) } if (!termcap_name || !filep) -#ifdef VMS - termcap_name = "emacs_library:[etc]termcap.dat"; -#else - termcap_name = "/etc/termcap"; -#endif + termcap_name = TERMCAP_FILE; /* Here we know we must search a file and termcap_name has its name. */ - fd = open (termcap_name, 0, 0); +#ifdef MSDOS + fd = open (termcap_name, O_RDONLY|O_TEXT, 0); +#else + fd = open (termcap_name, O_RDONLY, 0); +#endif if (fd < 0) return -1; @@ -501,8 +567,6 @@ tgetent (bp, name) ret: term_entry = bp; - if (malloc_size) - return (int) bp; return 1; } diff --git a/lib/termcap/termcap.h b/lib/termcap/termcap.h index e9d9361..b19fb0a 100644 --- a/lib/termcap/termcap.h +++ b/lib/termcap/termcap.h @@ -1,5 +1,5 @@ /* Declarations for termcap library. - Copyright (C) 1991, 1992 Free Software Foundation, Inc. + Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -28,7 +28,7 @@ extern char *tgetstr (const char *name, char **area); extern char PC; extern short ospeed; -extern void tputs (const char *string, int nlines, int (*outfun) ()); +extern void tputs (const char *string, int nlines, int (*outfun) (int)); extern char *tparam (const char *ctlstring, char *buffer, int size, ...); diff --git a/lib/termcap/tparam.c b/lib/termcap/tparam.c index 4badb65..2470289 100644 --- a/lib/termcap/tparam.c +++ b/lib/termcap/tparam.c @@ -1,5 +1,5 @@ /* Merge parameters into a termcap entry string. - Copyright (C) 1985, 1987, 1993 Free Software Foundation, Inc. + Copyright (C) 1985, 87, 93, 95 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,7 +17,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Emacs config.h may rename various library functions such as malloc. */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include <config.h> #else /* not HAVE_CONFIG_H */ #if defined(HAVE_STRING_H) || defined(STDC_HEADERS) @@ -92,16 +92,13 @@ tparam (string, outstring, len, arg0, arg1, arg2, arg3) int len; int arg0, arg1, arg2, arg3; { -#ifdef NO_ARG_ARRAY int arg[4]; + arg[0] = arg0; arg[1] = arg1; arg[2] = arg2; arg[3] = arg3; return tparam1 (string, outstring, len, NULL, NULL, arg); -#else - return tparam1 (string, outstring, len, NULL, NULL, &arg0); -#endif } char *BC; diff --git a/lib/termcap/version.c b/lib/termcap/version.c index 51336db..f5623a2 100644 --- a/lib/termcap/version.c +++ b/lib/termcap/version.c @@ -1,2 +1,2 @@ /* Make the library identifiable with the RCS ident command. */ -static char *version_string = "\n$Version: GNU termcap 1.2 $\n"; +static char *version_string = "\n$Version: GNU termcap 1.3 $\n"; diff --git a/lib/tilde/Makefile b/lib/tilde/Makefile deleted file mode 100644 index 50b4285..0000000 --- a/lib/tilde/Makefile +++ /dev/null @@ -1,98 +0,0 @@ -## -*- text -*- #################################################### -# # -# Makefile for the GNU Tilde Library. # -# # -#################################################################### - -# This Makefile is hand made from a template file, found in -# ../template. Each library must provide several Makefile -# targets: `all', `clean', `documentation', `install', and -# `what-tar'. The `what-tar' target reports the names of the -# files that need to be included in a tarfile to build the full -# code and documentation for this library. - -# Please note that the values for INCLUDES, CC, AR, RM, CP, -# RANLIB, and selfdir are passed in from ../Makefile, and do -# not need to be defined here. -RM = rm -f -MV = mv -CP = cp - -srcdir = . -VPATH = .:$(srcdir) - -# Here is a rule for making .o files from .c files that doesn't force -# the type of the machine (like -sun3) into the flags. -.c.o: - $(CC) -c $(CFLAGS) $(INCLUDES) $(LOCAL_DEFINES) $(CPPFLAGS) $< - -# LOCAL_DEFINES are flags that are specific to this library. -# Define -DUSG if you are using a System V operating system. -LOCAL_DEFINES = $(LOCAL_INCLUDES) #-DUSG - -# For libraries which include headers from other libraries. -LOCAL_INCLUDES = -I.. - -# The name of the library target. -LIBRARY_NAME = libtilde.a - -# The C code source files for this library. -CSOURCES = $(srcdir)/tilde.c - -# The header files for this library. -HSOURCES = $(srcdir)/tilde.h - -OBJECTS = tilde.o - -# The texinfo files which document this library. -DOCSOURCE = doc/tilde.texi -DOCOBJECT = doc/tilde.dvi -DOCSUPPORT = doc/Makefile -DOCUMENTATION = $(DOCSOURCE) $(DOCOBJECT) $(DOCSUPPORT) - -SUPPORT = Makefile ChangeLog $(DOCSUPPORT) - -SOURCES = $(CSOURCES) $(HSOURCES) $(DOCSOURCE) - -THINGS_TO_TAR = $(SOURCES) $(SUPPORT) - -###################################################################### - -all: $(LIBRARY_NAME) - -$(LIBRARY_NAME): $(OBJECTS) - $(RM) $@ - $(AR) cq $@ $(OBJECTS) - -[ -n "$(RANLIB)" ] && $(RANLIB) $@ - -what-tar: - @for file in $(THINGS_TO_TAR); do \ - echo $(selfdir)$$file; \ - done - -documentation: force - -(cd doc; $(MAKE) $(MFLAGS)) -force: - -# The rule for 'includes' is written funny so that the if statement -# always returns TRUE unless there really was an error installing the -# include files. -install: - -$(MV) $(bindir)/$(LIBRARY_NAME) $(bindir)/$(LIBRARY_NAME)-old - $(CP) $(LIBRARY_NAME) $(bindir)/$(LIBRARY_NAME) - -[ -n "$(RANLIB)" ] && $(RANLIB) -t $(bindir)/$(LIBRARY_NAME) - -clean: - $(RM) $(OBJECTS) $(LIBRARY_NAME) - -(cd doc && $(MAKE) $(MFLAGS) $@) - -maintainer-clean realclean mostlyclean distclean: clean - - -###################################################################### -# # -# Dependencies for the object files which make up this library. # -# # -###################################################################### - -tilde.o: tilde.h tilde.c diff --git a/lib/tilde/Makefile.in b/lib/tilde/Makefile.in new file mode 100644 index 0000000..acecee3 --- /dev/null +++ b/lib/tilde/Makefile.in @@ -0,0 +1,98 @@ +## -*- text -*- #################################################### +# # +# Makefile for the GNU Tilde Library. # +# # +#################################################################### + +srcdir = @srcdir@ +VPATH = .:@srcdir@ +topdir = @top_srcdir@ +BUILD_DIR = @BUILD_DIR@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +CC = @CC@ +RANLIB = @RANLIB@ +AR = @AR@ +RM = rm +CP = cp +MV = mv + +CFLAGS = @CFLAGS@ @LOCAL_CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ @LOCAL_LDFLAGS@ + +DEFS = @DEFS@ + +INCLUDES = -I. -I../.. -I$(topdir) -I$(topdir)/lib + +CCFLAGS = $(CFLAGS) $(DEFS) $(CPPFLAGS) ${INCLUDES} + +.c.o: + $(CC) -c $(CCFLAGS) $< + +# The name of the library target. +LIBRARY_NAME = libtilde.a + +# The C code source files for this library. +CSOURCES = $(srcdir)/tilde.c + +# The header files for this library. +HSOURCES = $(srcdir)/tilde.h + +OBJECTS = tilde.o + +# The texinfo files which document this library. +DOCSOURCE = doc/tilde.texi +DOCOBJECT = doc/tilde.dvi +DOCSUPPORT = doc/Makefile +DOCUMENTATION = $(DOCSOURCE) $(DOCOBJECT) $(DOCSUPPORT) + +SUPPORT = Makefile ChangeLog $(DOCSUPPORT) + +SOURCES = $(CSOURCES) $(HSOURCES) $(DOCSOURCE) + +THINGS_TO_TAR = $(SOURCES) $(SUPPORT) + +###################################################################### + +all: $(LIBRARY_NAME) + +$(LIBRARY_NAME): $(OBJECTS) + $(RM) -f $@ + $(AR) cr $@ $(OBJECTS) + -test -n "$(RANLIB)" && $(RANLIB) $@ + +documentation: force + -(cd doc; $(MAKE) $(MFLAGS)) + +force: + +# The rule for 'includes' is written funny so that the if statement +# always returns TRUE unless there really was an error installing the +# include files. +install: + $(INSTALL_DATA) -c -m 644 $(LIBRARY_NAME) $(bindir)/$(LIBRARY_NAME) + -test -n "$(RANLIB)" && $(RANLIB) -t $(bindir)/$(LIBRARY_NAME) + +clean: + $(RM) -f $(OBJECTS) $(LIBRARY_NAME) + -( cd doc && $(MAKE) $(MFLAGS) $@ ) + +realclean distclean maintainer-clean: clean + -( cd doc && $(MAKE) $(MFLAGS) $@ ) + $(RM) -f Makefile + +mostlyclean: clean + -( cd doc && $(MAKE) $(MFLAGS) $@ ) + +###################################################################### +# # +# Dependencies for the object files which make up this library. # +# # +###################################################################### + +tilde.o: tilde.h tilde.c +tilde.o: $(BUILD_DIR)/config.h diff --git a/lib/tilde/doc/Makefile b/lib/tilde/doc/Makefile index 4e158bf..a2246db 100644 --- a/lib/tilde/doc/Makefile +++ b/lib/tilde/doc/Makefile @@ -1,5 +1,5 @@ +clean distclean mostlyclean maintainer-clean: + rm -f tilde.?? + all: cp tilde.texi tilde.info - -clean realclean maintainer-clean: - rm -f tilde.?? tilde.info diff --git a/lib/tilde/memalloc.h b/lib/tilde/memalloc.h deleted file mode 100644 index 750d53d..0000000 --- a/lib/tilde/memalloc.h +++ /dev/null @@ -1,56 +0,0 @@ -/* memalloc.h -- consolidate code for including alloca.h or malloc.h and - defining alloca. */ - -/* Copyright (C) 1993 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2, or (at your option) any later - version. - - Bash is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with Bash; see the file COPYING. If not, write to the Free Software - Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#if !defined (__MEMALLOC_H__) -# define __MEMALLOC_H__ - -#if defined (sparc) && defined (sun) && !defined (HAVE_ALLOCA_H) -# define HAVE_ALLOCA_H -#endif - -#if defined (__GNUC__) && !defined (HAVE_ALLOCA) -# define HAVE_ALLOCA -#endif - -#if defined (HAVE_ALLOCA_H) && !defined (HAVE_ALLOCA) -# define HAVE_ALLOCA -#endif /* HAVE_ALLOCA_H && !HAVE_ALLOCA */ - -#if !defined (BUILDING_MAKEFILE) - -#if defined (__GNUC__) -# undef alloca -# define alloca __builtin_alloca -#else /* !__GNUC__ */ -# if defined (HAVE_ALLOCA_H) -# if defined (IBMESA) -# include <malloc.h> -# else /* !IBMESA */ -# include <alloca.h> -# endif /* !IBMESA */ -# else -extern char *alloca (); -# endif /* !HAVE_ALLOCA_H */ -#endif /* !__GNUC__ */ - -#endif /* !BUILDING_MAKEFILE */ - -#endif /* __MEMALLOC_H__ */ diff --git a/lib/tilde/tilde.c b/lib/tilde/tilde.c index da75d95..69f5768 100644 --- a/lib/tilde/tilde.c +++ b/lib/tilde/tilde.c @@ -19,6 +19,10 @@ along with Readline; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ +#if defined (HAVE_CONFIG_H) +# include <config.h> +#endif + #if defined (HAVE_STRING_H) # include <string.h> #else /* !HAVE_STRING_H */ @@ -31,13 +35,14 @@ # include "ansi_stdlib.h" #endif /* HAVE_STDLIB_H */ -#include "tilde.h" #include <sys/types.h> #include <pwd.h> -#if defined (USG) && !defined (HAVE_GETPW_DECLS) +#include "tilde.h" + +#if !defined (HAVE_GETPW_DECLS) extern struct passwd *getpwuid (), *getpwnam (); -#endif /* USG && !defined (HAVE_GETPW_DECLS) */ +#endif /* !HAVE_GETPW_DECLS */ #if !defined (savestring) extern char *xmalloc (); @@ -171,7 +176,7 @@ tilde_expand (string) /* Copy the skipped text into the result. */ if ((result_index + start + 1) > result_size) - result = (char *)xrealloc (result, 1 + (result_size += (start + 20))); + result = xrealloc (result, 1 + (result_size += (start + 20))); strncpy (result + result_index, string, start); result_index += start; @@ -188,7 +193,7 @@ tilde_expand (string) break; /* Expand the entire tilde word, and copy it into RESULT. */ - tilde_word = (char *)xmalloc (1 + end); + tilde_word = xmalloc (1 + end); strncpy (tilde_word, string, end); tilde_word[end] = '\0'; string += end; @@ -198,7 +203,7 @@ tilde_expand (string) len = strlen (expansion); if ((result_index + len + 1) > result_size) - result = (char *)xrealloc (result, 1 + (result_size += (len + 20))); + result = xrealloc (result, 1 + (result_size += (len + 20))); strcpy (result + result_index, expansion); result_index += len; @@ -217,85 +222,90 @@ tilde_expand_word (filename) char *filename; { char *dirname; + char *temp_name; - dirname = filename ? savestring (filename) : (char *)NULL; + if (filename == (char *)0) + return ((char *)NULL); - if (dirname && *dirname == '~') + dirname = savestring (filename); + + if (*dirname != '~') + return (dirname); + + if (!dirname[1] || dirname[1] == '/') { - char *temp_name; - if (!dirname[1] || dirname[1] == '/') + /* Prepend $HOME to the rest of the string. */ + char *temp_home = (char *)getenv ("HOME"); + int home_len; + + /* If there is no HOME variable, look up the directory in + the password database. */ + if (!temp_home) { - /* Prepend $HOME to the rest of the string. */ - char *temp_home = (char *)getenv ("HOME"); + struct passwd *entry; - /* If there is no HOME variable, look up the directory in - the password database. */ - if (!temp_home) - { - struct passwd *entry; + entry = getpwuid (getuid ()); + if (entry) + temp_home = entry->pw_dir; + } - entry = getpwuid (getuid ()); - if (entry) - temp_home = entry->pw_dir; - } + home_len = temp_home ? strlen (temp_home) : 0; + temp_name = xmalloc (1 + strlen (dirname + 1) + home_len); + + if (temp_home) + strcpy (temp_name, temp_home); + strcpy (temp_name + home_len, dirname + 1); + free (dirname); + dirname = temp_name; + } + else + { + char *username; + struct passwd *user_entry; + int i, len; - temp_name = xmalloc (1 + strlen (&dirname[1]) - + (temp_home ? strlen (temp_home) : 0)); - temp_name[0] = '\0'; - if (temp_home) - strcpy (temp_name, temp_home); - strcat (temp_name, dirname + 1); - free (dirname); - dirname = temp_name; - } - else + username = xmalloc (strlen (dirname)); + for (i = 1; dirname[i] && dirname[i] != '/'; i++) + username[i - 1] = dirname[i]; + username[i - 1] = '\0'; + + if ((user_entry = getpwnam (username)) == (struct passwd *)0) { - char *username; - struct passwd *user_entry; - int i; + /* If the calling program has a special syntax for + expanding tildes, and we couldn't find a standard + expansion, then let them try. */ + if (tilde_expansion_failure_hook) + { + char *expansion; - username = xmalloc (strlen (dirname)); - for (i = 1; dirname[i] && dirname[i] != '/'; i++) - username[i - 1] = dirname[i]; - username[i - 1] = '\0'; + expansion = (*tilde_expansion_failure_hook) (username); - if ((user_entry = getpwnam (username)) == 0) - { - /* If the calling program has a special syntax for - expanding tildes, and we couldn't find a standard - expansion, then let them try. */ - if (tilde_expansion_failure_hook) + if (expansion) { - char *expansion; - - expansion = (*tilde_expansion_failure_hook) (username); - - if (expansion) - { - temp_name = xmalloc (1 + strlen (expansion) - + strlen (&dirname[i])); - strcpy (temp_name, expansion); - strcat (temp_name, &dirname[i]); - free (expansion); - free (dirname); - dirname = temp_name; - } + len = strlen (expansion); + temp_name = xmalloc (1 + len + strlen (dirname + i)); + strcpy (temp_name, expansion); + strcpy (temp_name + len, dirname + i); + free (expansion); + free (dirname); + dirname = temp_name; } - /* We shouldn't report errors. */ - } - else - { - temp_name = xmalloc (1 + strlen (user_entry->pw_dir) - + strlen (&dirname[i])); - strcpy (temp_name, user_entry->pw_dir); - strcat (temp_name, &dirname[i]); - free (dirname); - dirname = temp_name; } - endpwent (); - free (username); + /* We shouldn't report errors. */ } + else + { + len = strlen (user_entry->pw_dir); + temp_name = xmalloc (1 + len + strlen (dirname + i)); + strcpy (temp_name, user_entry->pw_dir); + strcpy (temp_name + len, dirname + i); + free (dirname); + dirname = temp_name; + } + endpwent (); + free (username); } + return (dirname); } @@ -368,7 +378,7 @@ xrealloc (pointer, bytes) static void memory_error_and_abort () { - fprintf (stderr, "readline: Out of virtual memory!\n"); + fprintf (stderr, "readline: out of virtual memory\n"); abort (); } diff --git a/lib/tilde/tilde.h b/lib/tilde/tilde.h index 726d081..6f0898c 100644 --- a/lib/tilde/tilde.h +++ b/lib/tilde/tilde.h @@ -1,11 +1,32 @@ /* tilde.h: Externally available variables and function in libtilde.a. */ -#if !defined (__TILDE_H__) -# define __TILDE_H__ +/* Copyright (C) 1992 Free Software Foundation, Inc. + + This file contains the Readline Library (the Library), a set of + routines for providing Emacs style line input to programs that ask + for it. + + The Library is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + The Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + The GNU General Public License is often shipped with GNU software, and + is generally kept in a file called COPYING or LICENSE. If you do not + have a copy of the license, write to the Free Software Foundation, + 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#if !defined (_TILDE_H_) +# define _TILDE_H_ /* Function pointers can be declared as (Function *)foo. */ -#if !defined (__FUNCTION_DEF) -# define __FUNCTION_DEF +#if !defined (_FUNCTION_DEF) +# define _FUNCTION_DEF typedef int Function (); typedef void VFunction (); typedef char *CPFunction (); @@ -35,4 +56,4 @@ extern char *tilde_expand (); tilde. If there is no expansion, call tilde_expansion_failure_hook. */ extern char *tilde_expand_word (); -#endif /* __TILDE_H__ */ +#endif /* _TILDE_H_ */ |