diff options
Diffstat (limited to 'lib/readline')
62 files changed, 9520 insertions, 13836 deletions
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 */ |