[libreadline-java] 01/21: Imported Upstream version 0.7.0
Tony Mancill
tmancill at moszumanska.debian.org
Sat Mar 22 16:49:32 UTC 2014
This is an automated email from the git hooks/post-receive script.
tmancill pushed a commit to branch master
in repository libreadline-java.
commit f389bf9e3d799ac7f661eb2141cb9482073d235f
Author: tony mancill <tmancill at debian.org>
Date: Fri Mar 21 06:40:16 2014 -0700
Imported Upstream version 0.7.0
---
COPYING.LIB | 458 ++++++++++++
ChangeLog | 71 ++
Makefile | 128 ++++
README | 86 +++
README.1st | 34 +
TODO | 3 +
VERSION | 1 +
contrib/bsh/BshCompleter.java | 38 +
contrib/bsh/Interpreter.java | 1002 +++++++++++++++++++++++++++
contrib/bsh/Interpreter.java.diff | 79 +++
contrib/bsh/README | 23 +
contrib/jpython/README | 10 +
contrib/jpython/ReadlineConsole.java | 46 ++
contrib/jpython/jpython.diff | 22 +
contrib/jpython/jpython.java | 272 ++++++++
contrib/jpython/jython-install.txt | 64 ++
etc/Makefile | 48 ++
etc/manifest.stub | 2 +
src/Makefile | 41 ++
src/mkrules.inc | 56 ++
src/native/Makefile | 51 ++
src/native/org_gnu_readline_Readline.c | 446 ++++++++++++
src/org/Makefile | 28 +
src/org/gnu/Makefile | 28 +
src/org/gnu/readline/Makefile | 30 +
src/org/gnu/readline/Readline.java | 475 +++++++++++++
src/org/gnu/readline/ReadlineCompleter.java | 101 +++
src/org/gnu/readline/ReadlineLibrary.java | 96 +++
src/org/gnu/readline/ReadlineReader.java | 149 ++++
src/test/Makefile | 30 +
src/test/ReadlineTest.java | 130 ++++
src/test/TestCompleter.java | 55 ++
src/test/tinputrc | 5 +
33 files changed, 4108 insertions(+)
diff --git a/COPYING.LIB b/COPYING.LIB
new file mode 100644
index 0000000..3b20440
--- /dev/null
+++ b/COPYING.LIB
@@ -0,0 +1,458 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not 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 and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, 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 library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete 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 distribute a copy of this License along with the
+Library.
+
+ 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 Library or any portion
+of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+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 Library, 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 Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you 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.
+
+ If distribution of 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 satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be 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.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library 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.
+
+ 9. 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 Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+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 with
+this License.
+
+ 11. 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 Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library 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 Library.
+
+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.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library 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.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser 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 Library
+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 Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author 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 of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. 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 LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..99c386b
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,71 @@
+For release 0.7.0:
+ - bugfix: setCompleter(null) crashed the virtual machine. Now, it sets
+ the completer back to default behaviour (filename completion)
+ - native functions added:
+ o cleanupReadlineImpl() does a reset of the readline lib and the
+ terminal. Exported as 'void cleanup()' to the java user.
+ o getLineBufferImpl() returns the current line buffer. This is
+ usually needed within completers to access the _full_ line (the
+ completer only gets the last word). Exported as
+ 'String getLineBuffer()' to the java user.
+ - documentation: complete example for ReadlineCompleter interface;
+ better indented example for Readline. Added cleanup() in the example.
+ - declare the 'UnsatisfiedLinkError' in the load() method for
+ documentation purposes.
+ (all changes provided by Henner Zeller)
+ - added note about Debian-packages in README
+ - new description on how to make Jython work with JavaReadline
+ (copied from a posting of Steve Cohen <SteveC at ignitesports.com> to
+ jython-users at lists.sourceforge.net)
+
+For release 0.6.1:
+ - bugfix: fallback-solution did not throw EOFException
+ - bugfix: missing P ("ureJava") in method Readline.byName()
+
+For release 0.6:
+ - added ReadlineLibrary
+ - implemented Editline-support
+ - improved documentation
+
+For release 0.5.2:
+ - added ReadlineReader (provided by Shane Celis <shane at terrapsring.com>)
+ - added contrib-directory with
+ * bsh (provided by Shane Celis <shane at terrapsring.com>)
+ * jpython (moved from my own website into this package)
+ - added section about LICENSING ISSUES in README
+ - updated TODO
+
+For release 0.5.1:
+ - added word break patch (sets rl_completer_word_break_characters,
+ provided by David Dribin <dave at dribin.org>)
+
+For release 0.5:
+ - added code for reading/writing history files
+ (provided by erik at skiinfo.fr)
+ - added code for setting a custom completer
+ (provided by erik at skiinfo.fr)
+ - added a sample custom completer
+ - changed ReadlineTest to include new methods
+
+For release 0.43:
+ - rewrote makefile(s)
+ - changed directory structure
+ - moved ReadlineTest to package test
+ - removed file INSTALL
+
+For release 0.42:
+ - Moved native code to native subdirectory
+ - Reorganized makefiles
+
+For release 0.41:
+ - Changed package name to org.gnu.readline (to be SUN compliant)
+
+For release 0.4:
+ - Added the following methods: readInitFile() and parseAndBind()
+
+For release 0.3:
+ - Added UTF-8 to UCS-1 conversion: characters with 8'th bit set are now
+ supported
+
+For release 0.2:
+ - Initial public release
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..412ef74
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,128 @@
+#**************************************************************************
+#* Makefile for libJavaReadline.so -- load library for JNI wrapper
+#* of GNU readline
+#*
+#* Copyright (c) 1987-1998 Free Software Foundation, Inc.
+#* Java Wrapper Copyright (c) 1998-2001 by Bernhard Bablok (mail at bablokb.de)
+#*
+#* This program is free software; you can redistribute it and/or modify
+#* it under the terms of the GNU Library General Public License as published
+#* by the Free Software Foundation; either version 2 of the License or
+#* (at your option) any later version.
+#*
+#* This 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 Library General Public License for more details.
+#*
+#* You should have received a copy of the GNU Library General Public License
+#* along with this program; see the file COPYING.LIB. If not, write to
+#* the Free Software Foundation Inc., 59 Temple Place - Suite 330,
+#* Boston, MA 02111-1307 USA
+#***************************************************************************
+#
+# Toplevel Makefile for Java-Readline
+#
+# $Author: Bablokb $
+# $Revision: 1.10 $
+#
+
+TARGET := java_readline
+README := README README.1st
+CHANGELOG := ChangeLog
+LICENSE := COPYING.LIB
+TODO := TODO
+NAME := The Java-Readline Library
+HOMEPAGE := http://www.bablokb.de/java/readline.html
+COPYRIGHT := Released under the LGPL, (c) Bernhard Bablok 1998-2001
+WTITLE := "$(NAME)"
+DTITLE = "$(NAME), Version $(VERSION)"
+DBOTTOM := "$(COPYRIGHT)<br>Homepage: <a href="$(HOMEPAGE)">$(HOMEPAGE)</a>"
+DHEADER = "<strong>$(NAME), Version $(VERSION)</strong>"
+DFOOTER = "<strong>$(NAME), Version $(VERSION)</strong>"
+PACKROOT :=
+SUBDIRS := src etc
+PACKAGES := test org.gnu.readline
+BIN_ADD = $(README) $(TODO) $(CHANGELOG) $(LICENSE) \
+ $(JAR) $(shell ls *.so) $(APIDIR)
+SRC_ADD := $(README) $(TODO) $(CHANGELOG) $(LICENSE) \
+ Makefile VERSION $(SUBDIRS) contrib
+MF_STUB := etc/manifest.stub
+
+# native stuff
+
+export JAVAINCLUDE := $(JAVA_HOME)/include
+export JAVANATINC := $(JAVA_HOME)/include/linux
+export INCLUDES := -I $(JAVAINCLUDE) -I $(JAVANATINC)
+export LIBPATH := -L/usr/lib/termcap
+export T_LIBS := JavaReadline JavaEditline
+export JavaReadline_LIBS := -lreadline -ltermcap -lhistory
+export JavaEditline_LIBS := -ledit -ltermcap
+
+VERSION := $(shell cat VERSION)
+export ROOTDIR := $(shell pwd)
+export BUILDDIR := $(shell pwd)/build
+export METADIR := $(BUILDDIR)/META-INF
+export CLASSDIR := $(BUILDDIR)
+export JAR := $(TARGET).jar
+APIDIR := ./api
+
+export JAVAC := jikes
+export CLASSPATH := $(BUILDDIR):$(JAVA_HOME)/jre/lib/rt.jar
+export JAVAC_OPT := -O +E
+
+.PHONY: src-dist bin-dist test apidoc jar subdirs $(SUBDIRS)
+
+jar: subdirs
+ $(MAKE) $(JAR)
+
+$(JAR): $(MF_STUB) $(shell find build -type f)
+ifeq ($(strip $(MF_STUB)),)
+ jar -cvf $(JAR) -C $(BUILDDIR)/ .
+else
+ jar -cvfm $(JAR) $(MF_STUB) -C $(BUILDDIR)/ .
+endif
+
+apidoc: $(APIDIR)
+ javadoc -sourcepath src -d $(APIDIR) -windowtitle $(WTITLE) \
+ -doctitle $(DTITLE) -footer $(DFOOTER) -header $(DHEADER) \
+ -bottom $(DBOTTOM) \
+ -version -author $(patsubst %,$(PACKROOT)%,$(PACKAGES))
+
+bin-dist: jar apidoc
+ tar -czf $(TARGET)-$(VERSION)-bin.tgz --exclude "CVS" $(BIN_ADD)
+ -rm -fr $(TARGET)-$(VERSION)
+ mkdir $(TARGET)-$(VERSION)
+ (cd $(TARGET)-$(VERSION); tar -xzf ../$(TARGET)-$(VERSION)-bin.tgz)
+ tar -cjf $(TARGET)-$(VERSION)-bin.tar.bz2 $(TARGET)-$(VERSION)
+ -rm -fr $(TARGET)-$(VERSION) $(TARGET)-$(VERSION)-bin.tgz
+
+src-dist: clean
+ tar -czf $(TARGET)-$(VERSION)-src.tgz --exclude "CVS" $(SRC_ADD)
+ -rm -fr $(TARGET)-$(VERSION)
+ mkdir $(TARGET)-$(VERSION)
+ (cd $(TARGET)-$(VERSION); tar -xzf ../$(TARGET)-$(VERSION)-src.tgz)
+ tar -cjf $(TARGET)-$(VERSION)-src.tar.bz2 $(TARGET)-$(VERSION)
+ rm -fr $(TARGET)-$(VERSION) $(TARGET)-$(VERSION)-src.tgz
+
+subdirs: $(BUILDDIR) $(METADIR) $(SUBDIRS)
+
+$(SUBDIRS):
+ $(MAKE) -C $@
+
+$(APIDIR):
+ mkdir $(APIDIR)
+
+$(BUILDDIR):
+ mkdir $(BUILDDIR)
+
+$(METADIR):
+ mkdir $(METADIR)
+
+test: jar
+ LD_LIBRARY_PATH=$(ROOTDIR) java -jar $(JAR) src/test/tinputrc
+clean:
+ -rm -fr $(JAR) $(TARGET)-*.tar.bz2 $(APIDIR) $(BUILDDIR) .rltest_history
+ for dir in $(SUBDIRS); do \
+ $(MAKE) -C $$dir clean; \
+ done
diff --git a/README b/README
new file mode 100644
index 0000000..2593168
--- /dev/null
+++ b/README
@@ -0,0 +1,86 @@
+This is my "port" of GNU-Readline to Java. Actually, it is a crude wrapper
+using the Java Native Interface (JNI).
+
+Starting from version 0.6, alternative libraries are supported. Currently
+only Editline is implemented, but adding support for other implementations
+should be easy.
+From 0.6 on, JavaReadline also has a fallback solution (System.in) for
+platforms without Readline or Editline support, making your programs portable
+again.
+
+This version implements basic readline functionality like line editing and
+filename completion, which should be just enough for normal use. Not all
+functionality is available with all implementations.
+
+Various people contributed code (see the file ChangeLog for details).
+Since I changed some of the code, all bugs are my fault and bugreports
+should be adressed to me.
+
+The binary distribution contains the API documentation, a JAR with the
+Readline class and the shared libraries libJavaReadline.so and
+libJavaEditline.so. It was compiled running Linux 2.2.18 with glibc 2.2.
+
+The source distribution contains all the source (I hope this doesn't surprise
+you ;-) and a system of makefiles. You need the JDK to compile it.
+
+
+LICENSING ISSUES
+================
+
+Although JavaReadline is distributed under the LGPL, the underlying
+Readline library is GPL code. The consequence is, that any program
+linking with JavaReadline+Readline, will fall under the GPL.
+
+There is a Readline replacement called Editline with a more liberal
+license. Use that library if you want to distribute your program
+under the LGPL instead of the GPL.
+
+You can fetch the Editline stuff at http://packages.debian.org. You
+need libedit2 and libedit-dev. Source code is also available, although
+I must admit I did not succeed in compiling it on my non-BSD and
+non-Debian system :-(
+
+
+COMPILATION
+===========
+
+Compilation should be no problem. Try "make". You should set the
+variable JAVA_HOME (or edit the makefile). Also, if you don't use jikes,
+you should change the variables JAVAC and JAVAC_OPT in the makefile. A better
+alternative is to install jikes, it will speed up your development by
+a factor of 2-3.
+
+If you don't have the Editline libraries installed, use
+"make T_LIBS=JavaReadline" (the default creates both JavaReadline and
+JavaEditline).
+
+
+INSTALLATION
+============
+
+Copy the files libJava*.so to one of your library directories or add
+the directory where you put libJava*.so to LD_LIBARY_PATH. Also, add
+java_readline.jar to your CLASSPATH. After building the jar and the shared
+library, you can run a program with something like:
+
+LD_LIBRARY_PATH=/usr/lib java -cp java_readline.jar org.foo.bar.MyClass
+
+assuming that you put libJava*.so into /usr/lib.
+
+
+DEBIAN
+======
+
+Thanks to Ben Burton, Debian-packages for JavaReadline are available!
+
+
+SUPPORT
+=======
+
+If you think you found a bug or want to contribute some code please drop
+me a note.
+
+Bernhard Bablok
+mail at bablokb.de
+http://www.bablokb.de
+
diff --git a/README.1st b/README.1st
new file mode 100644
index 0000000..6660af8
--- /dev/null
+++ b/README.1st
@@ -0,0 +1,34 @@
+IMPORTANT NOTE
+==============
+
+From 0.5.2 to 0.6 there have been two incompatible interface changes:
+
+1. You must call Readline.load(ReadlineLibrary lib); before using any
+ other methods.
+=====================================================================
+
+If you omit the call to the load()-method, the pure Java fallback
+solution is used. Possible values for lib are:
+
+ReadlineLibrary.PureJava
+ReadlineLibrary.GnuReadline
+ReadlineLibrary.Editline
+
+Note that all programs using Gnu-Readline will fall under the GPL,
+since Gnu-Readline is GPL software.
+
+If you want to write portable programs and you are not sure if
+GnuReadline/Editline is available on all target machines, use code like
+
+try {
+ Readline.load(ReadlineLibrary.GnuReadline);
+} catch (Exception e) {
+}
+
+
+2. Readline.readline() now additionally throws an IOException
+=============================================================
+
+This is due to the fact that starting from 0.6 the pure Java fallback
+solution is supported. Using the native libraries, you should never
+see this exception, nevertheless you will have to deal with it.
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..b34bf5e
--- /dev/null
+++ b/TODO
@@ -0,0 +1,3 @@
+- Add support for the following readline functions/variables:
+ * rl_initialize
+ * rl_library_version
diff --git a/VERSION b/VERSION
new file mode 100644
index 0000000..faef31a
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+0.7.0
diff --git a/contrib/bsh/BshCompleter.java b/contrib/bsh/BshCompleter.java
new file mode 100644
index 0000000..7a35460
--- /dev/null
+++ b/contrib/bsh/BshCompleter.java
@@ -0,0 +1,38 @@
+package bsh.util;
+
+import org.gnu.readline.ReadlineCompleter;
+
+/**
+ * An adapter for org.gnu.readline's ReadlineCompleter interface to map to
+ * BeanShell's NameCompleter interface.
+ *
+ * @see org.gnu.readline.ReadlineReader
+ * @version $Revision: 1.1 $
+ * @author Shane Celis <shane at terraspring.com>
+ **/
+public class BshCompleter implements ReadlineCompleter {
+
+ private NameCompletion completer;
+
+ /**
+ * Constructs a <code>ReadlineCompleter</code> out of a
+ * <code>NameCompleter</code> object.
+ **/
+ public BshCompleter(NameCompletion completer) {
+ this.completer = completer;
+ }
+
+ /**
+ * Returns String of completion if unambiguous, otherwise null
+ **/
+ public String completer(String text, int state) {
+ // Not sure what state is used for in ReadlineCompleter
+ String[] completions = completer.completeName(text);
+ if (completions.length == 1 && state == 0) {
+ return completions[0];
+ } else {
+ return null; // ambiguous result
+ }
+ }
+
+}
diff --git a/contrib/bsh/Interpreter.java b/contrib/bsh/Interpreter.java
new file mode 100644
index 0000000..928d96e
--- /dev/null
+++ b/contrib/bsh/Interpreter.java
@@ -0,0 +1,1002 @@
+/*****************************************************************************
+ * *
+ * This file is part of the BeanShell Java Scripting distribution. *
+ * Documentation and updates may be found at http://www.beanshell.org/ *
+ * *
+ * Sun Public License Notice: *
+ * *
+ * The contents of this file are subject to the Sun Public License Version *
+ * 1.0 (the "License"); you may not use this file except in compliance with *
+ * the License. A copy of the License is available at http://www.sun.com *
+ * *
+ * The Original Code is BeanShell. The Initial Developer of the Original *
+ * Code is Pat Niemeyer. Portions created by Pat Niemeyer are Copyright *
+ * (C) 2000. All Rights Reserved. *
+ * *
+ * GNU Public License Notice: *
+ * *
+ * Alternatively, the contents of this file may be used under the terms of *
+ * the GNU Lesser General Public License (the "LGPL"), in which case the *
+ * provisions of LGPL are applicable instead of those above. If you wish to *
+ * allow use of your version of this file only under the terms of the LGPL *
+ * and not to allow others to use your version of this file under the SPL, *
+ * indicate your decision by deleting the provisions above and replace *
+ * them with the notice and other provisions required by the LGPL. If you *
+ * do not delete the provisions above, a recipient may use your version of *
+ * this file under either the SPL or the LGPL. *
+ * *
+ * Patrick Niemeyer (pat at pat.net) *
+ * Author of Learning Java, O'Reilly & Associates *
+ * http://www.pat.net/~pat/ *
+ * *
+ *****************************************************************************/
+
+package bsh;
+
+import java.util.Vector;
+import java.io.*;
+import java.io.File; // why? I don't know
+import bsh.util.BshCompleter;
+import bsh.util.NameCompletionTable;
+import bsh.classpath.ClassManagerImpl;
+import org.gnu.readline.Readline;
+import org.gnu.readline.ReadlineReader;
+
+/**
+ The BeanShell script interpreter.
+
+ An instance of Interpreter can be used to source scripts and evaluate
+ statements or expressions.
+ <p>
+ Here are some examples:
+
+ <p><blockquote><pre>
+ Interpeter bsh = new Interpreter();
+
+ // Evaluate statements and expressions
+ bsh.eval("foo=Math.sin(0.5)");
+ bsh.eval("bar=foo*5; bar=Math.cos(bar);");
+ bsh.eval("for(i=0; i<10; i++) { print(\"hello\"); }");
+ // same as above using java syntax and apis only
+ bsh.eval("for(int i=0; i<10; i++) { System.out.println(\"hello\"); }");
+
+ // Source from files or streams
+ bsh.source("myscript.bsh"); // or bsh.eval("source(\"myscript.bsh\")");
+
+ // Use set() and get() to pass objects in and out of variables
+ bsh.set( "date", new Date() );
+ Date date = (Date)bsh.get( "date" );
+ // This would also work:
+ Date date = (Date)bsh.eval( "date" );
+
+ bsh.eval("year = date.getYear()");
+ Integer year = (Integer)bsh.get("year"); // primitives use wrappers
+
+ // With Java1.3+ scripts can implement arbitrary interfaces...
+ // Script an awt event handler (or source it from a file, more likely)
+ bsh.eval( "actionPerformed( e ) { print( e ); }");
+ // Get a reference to the script object (implementing the interface)
+ ActionListener scriptedHandler =
+ (ActionListener)bsh.eval("return (ActionListener)this");
+ // Use the scripted event handler normally...
+ new JButton.addActionListener( script );
+ </pre></blockquote>
+ <p>
+
+ In the above examples we showed a single interpreter instance, however
+ you may wish to use many instances, depending on the application and how
+ you structure your scripts. Interpreter instances are very light weight
+ to create, however if you are going to execute the same script repeatedly
+ and require maximum performance you should consider scripting the code as
+ a method and invoking the scripted method each time on the same interpreter
+ instance (using eval()).
+ <p>
+
+ See the BeanShell User's Manual for more information.
+*/
+public class Interpreter
+ implements Runnable, ConsoleInterface /*,Serializable*/
+{
+ /* --- Begin static stuff --- */
+
+ public static final String VERSION = "1.1a16";
+ /*
+ Debug utils are static so that they are reachable by code that doesn't
+ necessarily have an interpreter reference (e.g. tracing in utils).
+ In the future we may want to allow debug/trace to be turned on on
+ a per interpreter basis, in which case we'll need to use the parent
+ reference in some way to determine the scope of the command that
+ turns it on or off...
+ */
+
+ public static boolean DEBUG, TRACE;
+ // This should be per instance
+ static PrintStream debug;
+ static {
+ staticInit();
+ }
+
+ /** Shared system object visible under bsh.system */
+ static This systemObject;
+
+ /* --- end static stuff --- */
+
+ /* --- Instance data --- */
+
+ Parser parser;
+ NameSpace globalNameSpace;
+ Reader in;
+ PrintStream out;
+ PrintStream err;
+ ConsoleInterface console;
+
+ /** If this interpeter is a child of another, the parent */
+ Interpreter parent;
+
+ /** The name of the file or other source that this interpreter is reading */
+ String sourceFileInfo;
+
+ /**
+ Do we override exit on EOF as normally done in iteractive mode?
+ (This is used by Sessiond)
+ */
+ public boolean noExitOnEOF;
+
+ private boolean
+ evalOnly, // Interpreter has no input stream, use eval() only
+ interactive; // Interpreter has a user, print prompts, etc.
+
+ /* --- End instance data --- */
+
+ /**
+ The main constructor.
+ All constructors should now pass through here.
+
+ @param namespace If namespace is non-null then this interpreter's
+ root namespace will be set to the one provided. If it is null a new
+ one will be created for it.
+ @param parent The parent interpreter if this interpreter is a child
+ of another. May be null.
+ @param sourceFileInfo An informative string holding the filename
+ or other description of the source from which this interpreter is
+ reading... used for debugging. May be null.
+ */
+ public Interpreter(
+ Reader in, PrintStream out, PrintStream err,
+ boolean interactive, NameSpace namespace,
+ Interpreter parent, String sourceFileInfo )
+ {
+ parser = new Parser( in );
+ long t1=System.currentTimeMillis();
+ this.in = in;
+ this.out = out;
+ this.err = err;
+ this.interactive = interactive;
+ debug = err;
+ this.parent = parent;
+ this.sourceFileInfo = sourceFileInfo;
+
+ if ( namespace == null )
+ this.globalNameSpace = new NameSpace("global");
+ else
+ this.globalNameSpace = namespace;
+
+ // The classes which are imported by default
+ globalNameSpace.loadDefaultImports();
+
+ /*
+ Create the root "bsh" system object if it doesn't exist.
+ */
+ if ( ! ( getu("bsh") instanceof bsh.This ) )
+ initRootSystemObject();
+
+ if ( interactive )
+ loadRCFiles();
+
+ long t2=System.currentTimeMillis();
+ Interpreter.debug("Time to initialize interpreter: "+(t2-t1));
+ }
+
+ public Interpreter(
+ Reader in, PrintStream out, PrintStream err,
+ boolean interactive, NameSpace namespace)
+ {
+ this( in, out, err, interactive, namespace, null, null );
+ }
+
+ public Interpreter(
+ Reader in, PrintStream out, PrintStream err, boolean interactive)
+ {
+ this(in, out, err, interactive, null);
+ }
+
+ /**
+ Construct a new interactive interpreter attached to the specified
+ console using the specified parent namespace.
+ */
+ public Interpreter(ConsoleInterface console, NameSpace globalNameSpace) {
+
+ this( console.getIn(), console.getOut(), console.getErr(),
+ true, globalNameSpace );
+
+ setConsole( console );
+ }
+
+ /**
+ Construct a new interactive interpreter attached to the specified
+ console.
+ */
+
+ public Interpreter(ConsoleInterface console) {
+ this(console, null);
+ }
+
+
+ /**
+ Create an interpreter for evaluation only.
+ */
+ public Interpreter()
+ {
+ this( new StringReader(""),
+ System.out, System.err, false, null );
+ evalOnly = true;
+ setu( "bsh.evalOnly", new Primitive(true) );
+ }
+
+ // End constructors
+
+ /**
+ Attach the console thusly... ;)
+ */
+ public void setConsole( ConsoleInterface console ) {
+ this.console = console;
+ setu( "bsh.console", console );
+ }
+
+ private void initRootSystemObject()
+ {
+ // bsh
+ setu("bsh", new NameSpace( "Bsh Object" ).getThis( this ) );
+
+ // init the static shared systemObject if it's not there yet
+ if ( systemObject == null )
+ systemObject = new NameSpace(
+ "Bsh System Object" ).getThis( this );
+ // bsh.system
+ setu( "bsh.system", systemObject );
+
+ // bsh.help
+ This helpText = new NameSpace(
+ "Bsh Command Help Text" ).getThis( this );
+ setu( "bsh.help", helpText );
+
+ // bsh.cwd
+ try {
+ setu( "bsh.cwd", System.getProperty("user.dir") );
+ } catch ( SecurityException e ) {
+ // applets can't see sys props
+ setu( "bsh.cwd", "." );
+ }
+
+ // bsh.interactive
+ setu( "bsh.interactive", new Primitive(interactive) );
+ // bsh.evalOnly
+ setu( "bsh.evalOnly", new Primitive(evalOnly) );
+ }
+
+ /**
+ Set the global namespace for this interpreter.
+ <p>
+
+ Note: This is here for completeness. If you're using this a lot
+ it may be an indication that you are doing more work than you have
+ to. For example, caching the interpreter instance rather than the
+ namespace should not add a significant overhead. No state other
+ than the debug status is stored in the interpreter.
+ <p>
+
+ All features of the namespace can also be accessed using the
+ interpreter via eval() and the script variable 'this.namespace'
+ (or global.namespace as necessary).
+ */
+ public void setNameSpace( NameSpace globalNameSpace ) {
+ this.globalNameSpace = globalNameSpace;
+ }
+
+ /**
+ Get the global namespace of this interpreter.
+ <p>
+
+ Note: This is here for completeness. If you're using this a lot
+ it may be an indication that you are doing more work than you have
+ to. For example, caching the interpreter instance rather than the
+ namespace should not add a significant overhead. No state other than
+ the debug status is stored in the interpreter.
+ <p>
+
+ All features of the namespace can also be accessed using the
+ interpreter via eval() and the script variable 'this.namespace'
+ (or global.namespace as necessary).
+ */
+ public NameSpace getNameSpace() {
+ return globalNameSpace;
+ }
+
+ /**
+ Run the text only interpreter on the command line or specify a file.
+ */
+ public static void main( String [] args )
+ {
+ if ( args.length > 0 ) {
+ String filename = args[0];
+
+ String [] bshArgs;
+ if ( args.length > 1 ) {
+ bshArgs = new String [ args.length -1 ];
+ System.arraycopy( args, 1, bshArgs, 0, args.length-1 );
+ } else
+ bshArgs = new String [0];
+
+ Interpreter interpreter = new Interpreter();
+ interpreter.setu( "bsh.args", bshArgs );
+ try {
+ interpreter.source( filename, interpreter.globalNameSpace );
+ } catch ( FileNotFoundException e ) {
+ System.out.println("File not found: "+e);
+ } catch ( EvalError e ) {
+ System.out.println("Evaluation Error: "+e);
+ } catch ( IOException e ) {
+ System.out.println("I/O Error: "+e);
+ }
+ } else {
+ // Workaround for JDK bug 4071281, where system.in.available()
+ // returns too large a value. This bug has been fixed in JDK 1.2.
+ InputStream src;
+ if ( System.getProperty("os.name").startsWith("Windows")
+ && System.getProperty("java.version").startsWith("1.1."))
+ {
+ src = new FilterInputStream(System.in) {
+ public int available() throws IOException {
+ return 0;
+ }
+ };
+ }
+ else
+ src = System.in;
+
+ Reader in = null;
+ boolean usingReadline = false;
+ try {
+ File history = new File(System.getProperty("user.home") +
+ File.separator + ".bsh_history");
+ if (!history.exists()) {
+ try {
+ history.createNewFile();
+ } catch(IOException ioe) {
+ debug("Unable to create history file: " + history.getAbsolutePath());
+ }
+ }
+ // should I wrap CommandLineReader around it?
+ if (history.canWrite() && history.canRead()) {
+ in = new ReadlineReader("bsh % ", history,ReadlineLibrary.Editline);
+ } else {
+ in = new ReadlineReader("bsh % ",ReadlineLibrary.Editline);
+ debug("Unable to read/write history file: " + history.getAbsolutePath());
+ }
+ } catch (IOException ioe) {
+ System.err.println("Unable to invoke ReadlineReader " +
+ "due to: " + ioe);
+ }
+ if (in == null)
+ in = new CommandLineReader( new InputStreamReader(src));
+ else
+ usingReadline = true;
+ Interpreter interpreter =
+ new Interpreter( in, System.out, System.err, true );
+ if (usingReadline) {
+ NameCompletionTable nct = new NameCompletionTable();
+ nct.add(interpreter.getNameSpace());
+
+ /** ClassManager does a lot of chatting to the stdout,
+ * so this has been commented out for the time being
+ **/
+
+// try {
+// BshClassManager bcm = BshClassManager.getClassManager();
+// if (bcm != null) {
+// nct.add(((ClassManagerImpl)bcm).getClassPath());
+// }
+// } catch(ClassPathException cpe) {
+// debug("classpath exception in name compl:" + cpe);
+// }
+
+ Readline.setCompleter(new BshCompleter(nct));
+ }
+ interpreter.run();
+ }
+ }
+
+ /**
+ Run interactively. (printing prompts, etc.)
+ */
+ public void run() {
+ if(evalOnly)
+ throw new RuntimeException("bsh Interpreter: No stream");
+
+ /*
+ We'll print our banner using eval(String) in order to
+ exercise the parser and get the basic expression classes loaded...
+ This ameliorates the delay after typing the first statement.
+ */
+ if ( interactive )
+ try {
+ eval("printBanner();");
+ } catch ( EvalError e ) {
+ println(
+ "BeanShell "+VERSION+" - by Pat Niemeyer (pat at pat.net)");
+ }
+
+ boolean eof = false;
+
+ // init the callstack.
+ CallStack callstack = new CallStack();
+ callstack.push( globalNameSpace );
+
+ while(!eof)
+ {
+ try
+ {
+ // try to sync up the console
+ System.out.flush();
+ System.err.flush();
+ Thread.yield(); // this helps a little
+ if(interactive && !(in instanceof ReadlineReader))
+ print("bsh % ");
+
+ eof = Line();
+
+ if(get_jjtree().nodeArity() > 0) // number of child nodes
+ {
+ SimpleNode node = (SimpleNode)(get_jjtree().rootNode());
+
+ if(DEBUG)
+ node.dump(">");
+
+ Object ret = node.eval( callstack, this );
+
+ // sanity check during development
+ if ( callstack.depth() > 1 )
+ throw new InterpreterError(
+ "Callstack growing: "+callstack);
+
+ if(ret instanceof ReturnControl)
+ ret = ((ReturnControl)ret).value;
+ if(ret != Primitive.VOID)
+ {
+ setVariable("$_", ret);
+ Object show = getu("bsh.show");
+ if(show instanceof Boolean &&
+ ((Boolean)show).booleanValue() == true)
+ println("<" + ret + ">");
+ }
+ }
+ }
+ catch(ParseException e)
+ {
+ error("Parser Error: " + e.getMessage(DEBUG));
+ if(DEBUG)
+ e.printStackTrace();
+ if(!interactive)
+ eof = true;
+
+ parser.reInitInput(in);
+ }
+ catch(InterpreterError e)
+ {
+ error("Internal Error: " + e.getMessage());
+ e.printStackTrace();
+ if(!interactive)
+ eof = true;
+ }
+ catch(TargetError e)
+ {
+ error("// Uncaught Exception: " + e );
+ if(DEBUG)
+ e.printStackTrace();
+ if(!interactive)
+ eof = true;
+ }
+ catch (EvalError e)
+ {
+ if ( interactive )
+ error( e.toString() );
+ else
+ error( e.getMessage() );
+ if(DEBUG)
+ e.printStackTrace();
+ if(!interactive)
+ eof = true;
+ }
+ catch(Exception e)
+ {
+ error("Unknown error: " + e);
+ e.printStackTrace();
+ if(!interactive)
+ eof = true;
+ }
+ catch(TokenMgrError e)
+ {
+ error("Error parsing input: " + e);
+
+ /*
+ We get stuck in infinite loops here when unicode escapes
+ fail. Must re-init the char stream reader
+ (ASCII_UCodeESC_CharStream.java)
+ */
+ parser.reInitTokenInput( in );
+
+ if(!interactive)
+ eof = true;
+ }
+ finally
+ {
+ get_jjtree().reset();
+ // reinit the callstack
+ callstack.clear();
+ callstack.push( globalNameSpace );
+ }
+ }
+
+ if ( interactive && !noExitOnEOF ) {
+ /* should be done for all streams in general, but this
+ * ensures that the history for readline is flushed */
+ try {
+ in.close();
+ } catch (IOException ioe) {
+ }
+ System.exit(0);
+ }
+ }
+
+ // begin source and eval
+
+ /**
+ Read text from fileName and eval it.
+ */
+ public Object source( String filename, NameSpace nameSpace )
+ throws FileNotFoundException, IOException, EvalError
+ {
+ File file = pathToFile( filename );
+ debug("Sourcing file: "+file);
+ Reader in = new BufferedReader( new FileReader(file) );
+ return eval( in, nameSpace, filename );
+ }
+
+ /**
+ Read text from fileName and eval it.
+ Convenience method. Use the global namespace.
+ */
+ public Object source( String filename )
+ throws FileNotFoundException, IOException, EvalError
+ {
+ return source( filename, globalNameSpace );
+ }
+
+ /**
+ Spawn a non-interactive local interpreter to evaluate text in the
+ specified namespace.
+
+ Return value is the evaluated object (or corresponding primitive
+ wrapper).
+
+ @param sourceFileInfo is for information purposes only. It is used to
+ display error messages (and in the future may be made available to
+ the script).
+ @throws EvalError on script problems
+ @throws TargetError on unhandled exceptions from the script
+ */
+ /*
+ Note: we need a form of eval that passes the callstack through...
+ */
+ /*
+ Can't this be combined with run() ?
+ run seems to have stuff in it for interactive vs. non-interactive...
+ compare them side by side and see what they do differently, aside from the
+ exception handling.
+ */
+
+ public Object eval(
+ Reader in, NameSpace nameSpace, String sourceFileInfo )
+ throws EvalError
+ {
+ Object retVal = null;
+ debug("eval: nameSpace = "+nameSpace);
+
+ /*
+ Create non-interactive local interpreter for this namespace
+ with source from the input stream and out/err same as
+ this interpreter.
+ */
+ Interpreter localInterpreter =
+ new Interpreter(
+ in, out, err, false, nameSpace, this, sourceFileInfo );
+
+ CallStack callstack = new CallStack();
+ callstack.push(
+ new NameSpace("Evaluation global for: "+sourceFileInfo) );
+ callstack.push( nameSpace );
+
+ boolean eof = false;
+ while(!eof)
+ {
+ SimpleNode node = null;
+ try
+ {
+ eof = localInterpreter.Line();
+ if (localInterpreter.get_jjtree().nodeArity() > 0)
+ {
+ node = (SimpleNode)localInterpreter.get_jjtree().rootNode();
+ // nodes remember from where they were sourced
+ node.setSourceFile( sourceFileInfo );
+
+ if ( TRACE )
+ println( "// " +node.getText() );
+
+ retVal = node.eval( callstack, localInterpreter );
+
+ // sanity check during development
+ if ( callstack.depth() > 2 )
+ throw new InterpreterError(
+ "Callstack growing: "+callstack);
+
+ if ( retVal instanceof ReturnControl ) {
+ retVal = ((ReturnControl)retVal).value;
+ break; // non-interactive, return control now
+ }
+ }
+ } catch(ParseException e) {
+ throw new EvalError(
+ "Sourced file: "+sourceFileInfo+" parser Error: "
+ + e.getMessage( DEBUG ), node );
+ } catch(InterpreterError e) {
+ e.printStackTrace();
+ throw new EvalError(
+ "Sourced file: "+sourceFileInfo+" internal Error: "
+ + e.getMessage(), node);
+ } catch( TargetError e ) {
+ if(DEBUG)
+ e.printStackTrace();
+ // failsafe, set the Line as the origin of the error.
+ if ( e.getNode()==null )
+ e.setNode( node );
+ e.reThrow("Sourced file: "+sourceFileInfo);
+ } catch(EvalError e) {
+ if(DEBUG)
+ e.printStackTrace();
+ // failsafe, set the Line as the origin of the error.
+ if ( e.getNode()==null )
+ e.setNode( node );
+ e.reThrow( "Sourced file: "+sourceFileInfo );
+ } catch(Exception e) {
+ e.printStackTrace();
+ throw new EvalError(
+ "Sourced file: "+sourceFileInfo+" unknown error: "
+ + e.getMessage(), node);
+ } catch(TokenMgrError e) {
+ throw new EvalError(
+ "Sourced file: "+sourceFileInfo+" Token Parsing Error: "
+ + e.getMessage(), node );
+ } finally {
+ localInterpreter.get_jjtree().reset();
+ callstack.clear();
+ callstack.push( nameSpace );
+ }
+ }
+ return Primitive.unwrap( retVal );
+ }
+
+ /**
+ Evaluate the inputstream in this interpreter's global namespace.
+ */
+ public Object eval( Reader in ) throws EvalError
+ {
+ return eval( in, globalNameSpace, "eval stream" );
+ }
+
+ /**
+ Evaluate the string in this interpreter's global namespace.
+ */
+ public Object eval( String statement ) throws EvalError {
+ return eval(statement, globalNameSpace);
+ }
+
+ /**
+ Evaluate the string in the specified namespace.
+ */
+ public Object eval( String statement, NameSpace nameSpace )
+ throws EvalError {
+
+ String s = ( statement.endsWith(";") ? statement : statement+";" );
+ return eval(
+ new StringReader(s), nameSpace, "<Inline eval of: "+s+" >" );
+ }
+
+ // end source and eval
+
+ /**
+ Print an error message in a standard format on the output stream
+ associated with this interpreter. On the GUI console this will appear
+ in red, etc.
+ */
+ public final void error(String s) {
+ if ( console != null )
+ console.error( "// Error: " + s +"\n" );
+ else {
+ err.println("// Error: " + s);
+ err.flush();
+ }
+ }
+
+ // ConsoleInterface
+ // The interpreter reflexively implements the console interface that it
+ // uses. Should clean this up by using an inner class to implement the
+ // console for us.
+
+ /**
+ Get the input stream associated with this interpreter.
+ This may be be stdin or the GUI console.
+ */
+ public Reader getIn() { return in; }
+
+ /**
+ Get the outptut stream associated with this interpreter.
+ This may be be stdout or the GUI console.
+ */
+ public PrintStream getOut() { return out; }
+
+ /**
+ Get the error output stream associated with this interpreter.
+ This may be be stderr or the GUI console.
+ */
+ public PrintStream getErr() { return err; }
+
+ public final void println(String s)
+ {
+ print(s + "\n");
+ }
+
+ public final void print(String s)
+ {
+ if (console != null) {
+ console.print(s);
+ } else {
+ out.print(s);
+ out.flush();
+ }
+ }
+
+ // End ConsoleInterface
+
+ /**
+ Print a debug message on debug stream associated with this interpreter
+ only if debugging is turned on.
+ */
+ public final static void debug(String s)
+ {
+ if(DEBUG)
+ debug.println("// Debug: " + s);
+ }
+
+ /*
+ Primary interpreter set and get variable methods
+ Note: These are squeltching errors... should they?
+ */
+
+ /**
+ Get the value of the name.
+ name may be any value. e.g. a variable or field
+ */
+ public Object get( String name ) throws EvalError {
+ Object ret = globalNameSpace.get( name, this );
+ return Primitive.unwrap( ret );
+ }
+
+ /**
+ Unchecked get for internal use
+ */
+ Object getu( String name ) {
+ try {
+ return get( name );
+ } catch ( EvalError e ) {
+ throw new InterpreterError("set: "+e);
+ }
+ }
+
+ /**
+ Assign the value to the name.
+ name may evaluate to anything assignable. e.g. a variable or field.
+ */
+ public void set(String name, Object value) throws EvalError {
+ CallStack callstack = new CallStack();
+ LHS lhs = globalNameSpace.getNameResolver( name ).toLHS(
+ callstack, this );
+ lhs.assign( value );
+ }
+
+ /**
+ Unchecked set for internal use
+ */
+ void setu(String name, Object value) {
+ try {
+ set(name, value);
+ } catch ( EvalError e ) {
+ throw new InterpreterError("set: "+e);
+ }
+ }
+
+ public void set(String name, long value) throws EvalError {
+ set(name, new Primitive(value));
+ }
+ public void set(String name, int value) throws EvalError {
+ set(name, new Primitive(value));
+ }
+ public void set(String name, double value) throws EvalError {
+ set(name, new Primitive(value));
+ }
+ public void set(String name, float value) throws EvalError {
+ set(name, new Primitive(value));
+ }
+ public void set(String name, boolean value) throws EvalError {
+ set(name, new Primitive(value));
+ }
+
+
+
+ /**
+ @deprecated does not properly evaluate compound names
+ */
+ public Object getVariable(String name)
+ {
+ Object obj = globalNameSpace.getVariable(name);
+ return Primitive.unwrap( obj );
+ }
+
+ /**
+ @deprecated does not properly evaluate compound names
+ */
+ public void setVariable(String name, Object value)
+ {
+ try { globalNameSpace.setVariable(name, value); }
+ catch(EvalError e) { error(e.toString()); }
+ }
+
+ /**
+ @deprecated does not properly evaluate compound names
+ */
+ public void setVariable(String name, int value)
+ {
+ try { globalNameSpace.setVariable(name, new Primitive(value)); }
+ catch(EvalError e) { error(e.toString()); }
+ }
+
+ /**
+ @deprecated does not properly evaluate compound names
+ */
+ public void setVariable(String name, float value)
+ {
+ try { globalNameSpace.setVariable(name, new Primitive(value)); }
+ catch(EvalError e) { error(e.toString()); }
+ }
+
+ /**
+ @deprecated does not properly evaluate compound names
+ */
+ public void setVariable(String name, boolean value)
+ {
+ try { globalNameSpace.setVariable(name, new Primitive(value)); }
+ catch(EvalError e) { error(e.toString()); }
+ }
+
+ // end primary set and get methods
+
+ /* Methods for interacting with Parser */
+
+ private JJTParserState get_jjtree() {
+ return parser.jjtree;
+ }
+
+ private ASCII_UCodeESC_CharStream get_jj_input_stream() {
+ return parser.jj_input_stream;
+ }
+
+ private boolean Line() throws ParseException {
+ return parser.Line();
+ }
+
+ /* End methods for interacting with Parser */
+
+ void loadRCFiles() {
+ try {
+ String rcfile =
+ // Default is c:\windows under win98, $HOME under Unix
+ System.getProperty("user.home") + File.separator + ".bshrc";
+ source( rcfile, globalNameSpace );
+ } catch ( Exception e ) {
+ // squeltch security exception, filenotfoundexception
+ debug("Could not find rc file: "+e);
+ }
+ }
+
+ /**
+ Localize a path to the file name based on the bsh.cwd interpreter
+ working directory.
+ */
+ public File pathToFile( String fileName )
+ throws IOException
+ {
+ File file = new File( fileName );
+
+ // if relative, fix up to bsh.cwd
+ if ( !file.isAbsolute() ) {
+ String cwd = (String)getu("bsh.cwd");
+ file = new File( cwd + File.separator + fileName );
+ }
+
+ return new File( file.getCanonicalPath() );
+ }
+
+ public static void redirectOutputToFile( String filename )
+ {
+ try {
+ PrintStream pout = new PrintStream(
+ new FileOutputStream( filename ) );
+ System.setOut( pout );
+ System.setErr( pout );
+ } catch ( IOException e ) {
+ System.err.println("Can't redirect output to file: "+filename );
+ }
+ }
+
+ static void staticInit() {
+ /*
+ Apparently in some environments you can't catch the security exception
+ at all... e.g. as an applet in IE ... will probably have to work
+ around
+ */
+ try {
+ debug = System.err;
+ DEBUG = Boolean.getBoolean("debug");
+ TRACE = Boolean.getBoolean("trace");
+ String outfilename = System.getProperty("outfile");
+ if ( outfilename != null )
+ redirectOutputToFile( outfilename );
+ } catch ( SecurityException e ) {
+ System.err.println("Could not init static:"+e);
+ } catch ( Exception e ) {
+ System.err.println("Could not init static(2):"+e);
+ } catch ( Throwable e ) {
+ System.err.println("Could not init static(3):"+e);
+ }
+ }
+
+ /**
+ Specify the source of the text from which this interpreter is reading.
+ Note: there is a difference between what file the interrpeter is
+ sourcing and from what file a method was originally parsed. One
+ file may call a method sourced from another file. See SimpleNode
+ for origination file info.
+ @see SimpleNode.getSourceFile
+ */
+ public String getSourceFileInfo() {
+ if ( sourceFileInfo != null )
+ return sourceFileInfo;
+ else
+ return "<unknown source>";
+ }
+
+ public Interpreter getParent() {
+ return parent;
+ }
+
+}
+
diff --git a/contrib/bsh/Interpreter.java.diff b/contrib/bsh/Interpreter.java.diff
new file mode 100644
index 0000000..ba6cf31
--- /dev/null
+++ b/contrib/bsh/Interpreter.java.diff
@@ -0,0 +1,79 @@
+37a38,43
+> import java.io.File; // why? I don't know
+> import bsh.util.BshCompleter;
+> import bsh.util.NameCompletionTable;
+> import bsh.classpath.ClassManagerImpl;
+> import org.gnu.readline.Readline;
+> import org.gnu.readline.ReadlineReader;
+104a111
+>
+221a229
+>
+225a234
+>
+358c367,393
+< Reader in = new CommandLineReader( new InputStreamReader(src));
+---
+> Reader in = null;
+> boolean usingReadline = false;
+> try {
+> File history = new File(System.getProperty("user.home") +
+> File.separator + ".bsh_history");
+> if (!history.exists()) {
+> try {
+> history.createNewFile();
+> } catch(IOException ioe) {
+> debug("Unable to create history file: " + history.getAbsolutePath());
+> }
+> }
+> // should I wrap CommandLineReader around it?
+> if (history.canWrite() && history.canRead()) {
+> in = new ReadlineReader("bsh % ", history,ReadlineLibrary.Editline);
+> } else {
+> in = new ReadlineReader("bsh % ",ReadlineLibrary.Editline);
+> debug("Unable to read/write history file: " + history.getAbsolutePath());
+> }
+> } catch (IOException ioe) {
+> System.err.println("Unable to invoke ReadlineReader " +
+> "due to: " + ioe);
+> }
+> if (in == null)
+> in = new CommandLineReader( new InputStreamReader(src));
+> else
+> usingReadline = true;
+360a396,414
+> if (usingReadline) {
+> NameCompletionTable nct = new NameCompletionTable();
+> nct.add(interpreter.getNameSpace());
+>
+> /** ClassManager does a lot of chatting to the stdout,
+> * so this has been commented out for the time being
+> **/
+>
+> // try {
+> // BshClassManager bcm = BshClassManager.getClassManager();
+> // if (bcm != null) {
+> // nct.add(((ClassManagerImpl)bcm).getClassPath());
+> // }
+> // } catch(ClassPathException cpe) {
+> // debug("classpath exception in name compl:" + cpe);
+> // }
+>
+> Readline.setCompleter(new BshCompleter(nct));
+> }
+399c453
+< if(interactive)
+---
+> if(interactive && !(in instanceof ReadlineReader))
+496c550,556
+< if ( interactive && !noExitOnEOF )
+---
+> if ( interactive && !noExitOnEOF ) {
+> /* should be done for all streams in general, but this
+> * ensures that the history for readline is flushed */
+> try {
+> in.close();
+> } catch (IOException ioe) {
+> }
+498a559
+> }
diff --git a/contrib/bsh/README b/contrib/bsh/README
new file mode 100644
index 0000000..84d7a5d
--- /dev/null
+++ b/contrib/bsh/README
@@ -0,0 +1,23 @@
+To use JavaReadline with BeanShell, you must replace one class
+(bsh.Interpreter) in bsh.jar and add another one (bsh.bshCompleter).
+
+The sourcecode for both files is provided in this package. Just
+compile both files and use the jar utility from the JDK. Note that the
+1.2 version has an update flag (this makes things easier). With 1.1
+you have to extract the whole archive, replace the given class files
+and create the archive again.
+
+(This readme was shamelessly stolen and modified with little more than
+substitution tricks from the jpython mod for readline.)
+
+-Shane Celis <shane at terraspring.com>
+
+
+Note: starting from JavaReadline 0.6, you have the choice of various backing
+readline implementations. Since the license of BSH does not conform to the
+GPL, it cannot be used together with GNU-Readline.
+As a consequence, the backing implementation for BeanShell is Editline,
+and I modified ReadlineReader, Interpreter.java and Interpreter.java.diff
+accordingly.
+
+Bernhard
\ No newline at end of file
diff --git a/contrib/jpython/README b/contrib/jpython/README
new file mode 100644
index 0000000..0dd6cb6
--- /dev/null
+++ b/contrib/jpython/README
@@ -0,0 +1,10 @@
+Note: JPython is now Jython, and there have been
+some changes, so the original description of what
+to do to make Jython work with JavaReadline
+does not apply anymore.
+
+However, there has been a posting to the jython-users
+mailing-list describing what to do (see the file
+jython-install.txt). For Debian-users, things should
+be much simpler, because Jython is already packaged
+to use JavaReadline with EditLine as backing library.
diff --git a/contrib/jpython/ReadlineConsole.java b/contrib/jpython/ReadlineConsole.java
new file mode 100644
index 0000000..0ca8fa6
--- /dev/null
+++ b/contrib/jpython/ReadlineConsole.java
@@ -0,0 +1,46 @@
+// Copyright � Corporation for National Research Initiatives
+package org.python.util;
+import org.python.core.*;
+import org.gnu.readline.*;
+
+// Based on CPython-1.5.2's code module
+
+public class ReadlineConsole extends InteractiveConsole {
+ public String filename;
+
+ public ReadlineConsole() {
+ this(null, "<console>");
+ }
+ public ReadlineConsole(PyObject locals) {
+ this(locals, "<console>");
+ }
+ public ReadlineConsole(PyObject locals, String filename) {
+ super(locals,filename);
+ try {
+ Readline.load(ReadlineLibrary.Editline);
+ } catch (Exception e) {
+ }
+ Readline.initReadline("jpython");
+ }
+
+
+ /**
+ * Write a prompt and read a line.
+ *
+ * The returned line does not include the trailing newline. When the
+ * user enters the EOF key sequence, EOFError is raised.
+ *
+ * This subclass implements the functionality using JavaReadline.
+ **/
+ public String raw_input(PyObject prompt) {
+ try {
+ return Readline.readline(prompt==null ? "" : prompt.toString());
+ } catch (java.io.EOFException eofe) {
+ throw new PyException(Py.EOFError);
+ } catch (java.io.IOException ioe) {
+ throw new PyException();
+ } catch (java.io.UnsupportedEncodingException e) {
+ throw new PyException();
+ }
+ }
+}
diff --git a/contrib/jpython/jpython.diff b/contrib/jpython/jpython.diff
new file mode 100644
index 0000000..c2e36a4
--- /dev/null
+++ b/contrib/jpython/jpython.diff
@@ -0,0 +1,22 @@
+*** jpython.java Sun Oct 24 08:54:59 1999
+--- jpython.java.orig Sun Oct 24 08:53:46 1999
+***************
+*** 80,91 ****
+
+ // Now create an interpreter
+! InteractiveConsole interp = null;
+! try {
+! interp = (InteractiveConsole) Class.forName(
+! PySystemState.registry.getProperty("python.console",
+! "org.python.util.InteractiveConsole")).newInstance();
+! } catch (Exception e) {
+! interp = new InteractiveConsole();
+! }
+ //System.err.println("interp");
+ PyModule mod = imp.addModule("__main__");
+--- 80,84 ----
+
+ // Now create an interpreter
+! InteractiveConsole interp = new InteractiveConsole();
+ //System.err.println("interp");
+ PyModule mod = imp.addModule("__main__");
diff --git a/contrib/jpython/jpython.java b/contrib/jpython/jpython.java
new file mode 100644
index 0000000..4a2ab16
--- /dev/null
+++ b/contrib/jpython/jpython.java
@@ -0,0 +1,272 @@
+// Copyright � Corporation for National Research Initiatives
+package org.python.util;
+
+import org.python.core.*;
+import java.util.zip.*;
+import java.io.*;
+
+public class jpython
+{
+ private static String usage =
+ "usage: jpython [options] [-jar jar | -c cmd | file | -] [args]\n"+
+ "Options and arguments:\n"+
+ "-i : inspect interactively after running script, and force\n"+
+ " prompts, even if stdin does not appear to be a terminal\n"+
+ "-S : don't imply `import site' on initialization\n"+
+ "-X : disable class based standard exceptions\n"+
+ "-Dprop=v : Set the property `prop' to value `v'\n"+
+ "-jar jar : program read from __run__.py in jar file\n"+
+ "-c cmd : program passed in as string (terminates option list)\n"+
+ "file : program read from script file\n"+
+ "- : program read from stdin (default; interactive mode if a "+
+ "tty)\n"+
+ "--help : print this usage message and exit\n"+
+ "--version: print JPython version number and exit\n"+
+ "args : arguments passed to program in sys.argv[1:]";
+
+ public static void runJar(String filename) {
+ // TBD: this is kind of gross because a local called `zipfile' just
+ // magically shows up in the module's globals. Either `zipfile'
+ // should be called `__zipfile__' or (preferrably, IMO), __run__.py
+ // should be imported and a main() function extracted. This
+ // function should be called passing zipfile in as an argument.
+ //
+ // Probably have to keep this code around for backwards
+ // compatibility (?)
+ try {
+ ZipFile zip = new ZipFile(filename);
+
+ ZipEntry runit = zip.getEntry("__run__.py");
+ if (runit == null)
+ throw Py.ValueError("jar file missing '__run__.py'");
+
+ PyStringMap locals = new PyStringMap();
+ locals.__setitem__("__name__", new PyString(filename));
+ locals.__setitem__("zipfile", Py.java2py(zip));
+
+ InputStream file = zip.getInputStream(runit);
+ PyCode code;
+ try {
+ code = Py.compile(file, "__run__", "exec");
+ } finally {
+ file.close();
+ }
+ Py.runCode(code, locals, locals);
+ } catch (java.io.IOException e) {
+ throw Py.IOError(e);
+ }
+ }
+
+ public static void main(String[] args) {
+ // Parse the command line options
+ CommandLineOptions opts = new CommandLineOptions();
+ if (!opts.parse(args)) {
+ if (opts.version) {
+ System.err.println(InteractiveConsole.getDefaultBanner());
+ System.exit(0);
+ }
+ System.err.println(usage);
+ int exitcode = opts.help ? 0 : -1;
+ System.exit(exitcode);
+ }
+
+ // Setup the basic python system state from these options
+ PySystemState.initialize(System.getProperties(),
+ opts.properties, opts.argv);
+
+ if (opts.notice) {
+ System.err.println(InteractiveConsole.getDefaultBanner());
+ }
+
+ // Now create an interpreter
+ InteractiveConsole interp = null;
+ try {
+ interp = (InteractiveConsole) Class.forName(
+ PySystemState.registry.getProperty("python.console",
+ "org.python.util.InteractiveConsole")).newInstance();
+ } catch (Exception e) {
+ interp = new InteractiveConsole();
+ }
+ //System.err.println("interp");
+ PyModule mod = imp.addModule("__main__");
+ interp.setLocals(mod.__dict__);
+ //System.err.println("imp");
+
+ if (Options.importSite) {
+ try {
+ imp.load("site");
+ } catch (PyException pye) {
+ if (!Py.matchException(pye, Py.ImportError)) {
+ System.err.println("error importing site");
+ Py.printException(pye);
+ System.exit(-1);
+ }
+ }
+ }
+
+ if (opts.command != null) {
+ try {
+ interp.exec(opts.command);
+ } catch (Throwable t) {
+ Py.printException(t);
+ }
+ }
+
+ // was there a filename on the command line?
+ if (opts.filename != null) {
+ String path = new java.io.File(opts.filename).getParent();
+ if (path == null)
+ path = "";
+ Py.getSystemState().path.insert(0, new PyString(path));
+ if (opts.jar) {
+ runJar(opts.filename);
+ } else if (opts.filename.equals("-")) {
+ try {
+ interp.execfile(System.in, "<stdin>");
+ } catch (Throwable t) {
+ Py.printException(t);
+ }
+ } else {
+ try {
+ interp.execfile(opts.filename);
+ } catch (Throwable t) {
+ Py.printException(t);
+ }
+ }
+ }
+ else {
+ // if there was no file name on the command line, then "" is
+ // the first element on sys.path. This is here because if
+ // there /was/ a filename on the c.l., and say the -i option
+ // was given, sys.path[0] will have gotten filled in with the
+ // dir of the argument filename.
+ Py.getSystemState().path.insert(0, new PyString(""));
+ }
+
+ if (opts.interactive) {
+ try {
+ interp.interact(null);
+ } catch (Throwable t) {
+ Py.printException(t);
+ }
+ }
+ }
+}
+
+
+
+class CommandLineOptions
+{
+ public String filename;
+ public boolean jar, interactive, notice;
+ private boolean fixInteractive;
+ public boolean help, version;
+ public String[] argv;
+ public java.util.Properties properties;
+ public String command;
+
+ public CommandLineOptions() {
+ filename = null;
+ jar = fixInteractive = false;
+ interactive = notice = true;
+ properties = new java.util.Properties();
+ help = version = false;
+ }
+
+ public void setProperty(String key, String value) {
+ properties.put(key, value);
+ // This only works for Java 1.2. There appears to be no portable
+ // way to support this under Java 1.1
+// try {
+// System.setProperty(key, value);
+// }
+// catch (SecurityException e) {}
+ }
+
+ public boolean parse(String[] args) {
+ int index=0;
+ while (index < args.length && args[index].startsWith("-")) {
+ String arg = args[index];
+ if (arg.equals("--help")) {
+ help = true;
+ return false;
+ }
+ else if (arg.equals("--version")) {
+ version = true;
+ return false;
+ }
+ else if (arg.equals("-")) {
+ if (!fixInteractive)
+ interactive = false;
+ filename = "-";
+ }
+ else if (arg.equals("-i")) {
+ fixInteractive = true;
+ interactive = true;
+ }
+ else if (arg.equals("-jar")) {
+ jar = true;
+ if (!fixInteractive)
+ interactive = false;
+ }
+ else if (arg.equals("-X")) {
+ Options.classBasedExceptions = false;
+ }
+ else if (arg.equals("-S")) {
+ Options.importSite = false;
+ }
+ else if (arg.equals("-c")) {
+ command = args[++index];
+ if (!fixInteractive) interactive = false;
+ break;
+ }
+ else if (arg.startsWith("-D")) {
+ String key = null;
+ String value = null;
+ int equals = arg.indexOf("=");
+ if (equals == -1) {
+ String arg2 = args[++index];
+ key = arg.substring(2, arg.length());
+ value = arg2;
+ }
+ else {
+ key = arg.substring(2, equals);
+ value = arg.substring(equals+1, arg.length());
+ }
+ setProperty(key, value);
+ }
+ else {
+ String opt = args[index];
+ if (opt.startsWith("--"))
+ opt = opt.substring(2);
+ else if (opt.startsWith("-"))
+ opt = opt.substring(1);
+ System.err.println("jpython: illegal option -- " + opt);
+ return false;
+ }
+ index += 1;
+ }
+ notice = interactive;
+ if (filename == null && index < args.length && command == null) {
+ filename = args[index++];
+ if (!fixInteractive)
+ interactive = false;
+ notice = false;
+ }
+ if (command != null)
+ notice = false;
+
+ int n = args.length-index+1;
+ argv = new String[n];
+ //new String[args.length-index+1];
+ if (filename != null)
+ argv[0] = filename;
+ else argv[0] = "";
+
+ for(int i=1; i<n; i++, index++) {
+ argv[i] = args[index];
+ }
+
+ return true;
+ }
+}
diff --git a/contrib/jpython/jython-install.txt b/contrib/jpython/jython-install.txt
new file mode 100644
index 0000000..b54702d
--- /dev/null
+++ b/contrib/jpython/jython-install.txt
@@ -0,0 +1,64 @@
+From SteveC at ignitesports.com Sun Dec 30 17:10:46 2001
+
+For about the third time, I have spent a few hours getting the readline
+library worked into jython. (It happens every time I install a new
+jython and it changes a little bit each time.) You would think this
+annoying mess would get documented somewhere, but it hasn't, anywhere,
+correctly, in spite of several halfway attempts to do so. And much of
+the documentation is out of date.
+
+So please, guys, make it a New Year's resolution to get this into the
+official docs, somewhere. Here is a start, it worked for me:
+
+
+What you have to do to get Jython and Readline working (These
+instructions work for GNUReadline on my RedHat Linux system - your
+mileage may vary):
+
+Note: there is another option called Editline but Bernhard Bablok, the
+author of gnu java_readline says he couldn't get it working, so I didn't
+even try. Nonetheless, Editline is the default in jython according to
+the source code in ReadlineConsole.java. (See item #9 below ) If this
+is going to be the case, then the jython docs should give more info
+about it or work it into the standard distribution somehow.
+
+1. Download and install the javacc from
+http://www.webgain.com/products/java_cc/. You can't build jython
+without this.
+
+2. Download the java-readline source from
+http://www.bablokb.de/java/readline.html
+
+3. Make the java_readline jar and backing library using the Makefile
+supplied.
+
+4. Deploy these into your system lib directory. (/usr/lib in my case)
+
+5. Download the latest Jython sources from SourceForge.
+
+6. Create/Modify an ant.properties file in the same directory as the
+build.xml for jython and add the property readline.jar giving it the
+value of a path to the java_readline.jar you deployed in step 3, as
+well as the path to javacc and any other optional jars you wish to
+include.
+
+7. Build jython and deploy it.
+
+8. Modify the jython shell script so as to precede the supplied command
+(java -Dpython.home=...) with 'LD_LIBRARY_PATH="/usr/lib"'
+
+9. Modify your registry file to add the line
+
+ python.console.readlinelib=GnuReadline
+
+As far as I know this one isn't documented anywhere and if you don't put
+it in, the system tries to find Editline and throws an exception if it
+can't. I only pieced it together from reading the source code for
+jython's ReadlineConsole and for the gnu java readline.
+
+After all that, you finally have a console that recognizes the arrow
+keys for history when on the last line. Way too complicated.
+
+So while I thank the Jython developers and Mr. Bablok for their efforts
+and for making this possible at all, please, someone, make this easier
+or at least pull all the documentation into one place.
diff --git a/etc/Makefile b/etc/Makefile
new file mode 100644
index 0000000..4c532b4
--- /dev/null
+++ b/etc/Makefile
@@ -0,0 +1,48 @@
+#**************************************************************************
+#* Makefile for libJavaReadline.so -- load library for JNI wrapper
+#* of GNU readline
+#*
+#* Copyright (c) 1987-1998 Free Software Foundation, Inc.
+#* Java Wrapper Copyright (c) 1998-2001 by Bernhard Bablok (mail at bablokb.de)
+#*
+#* This program is free software; you can redistribute it and/or modify
+#* it under the terms of the GNU Library General Public License as published
+#* by the Free Software Foundation; either version 2 of the License or
+#* (at your option) any later version.
+#*
+#* This 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 Library General Public License for more details.
+#*
+#* You should have received a copy of the GNU Library General Public License
+#* along with this program; see the file COPYING.LIB. If not, write to
+#* the Free Software Foundation Inc., 59 Temple Place - Suite 330,
+#* Boston, MA 02111-1307 USA
+#***************************************************************************
+#
+# $Author: Bablokb $
+# $Revision: 1.2 $
+#
+
+SUBDIRS := $(shell find . -type d -not -name "." -not -name "CVS" -maxdepth 1)
+.PHONY: all clean subdirs $(SUBDIRS)
+
+META-FILES :=
+META_TARGETS := $(META-FILES:%=$(METADIR)/%)
+
+all: subdirs $(META_TARGETS)
+
+subdirs: $(SUBDIRS)
+
+$(SUBDIRS):
+ -mkdir $(METADIR)/$@
+ $(MAKE) -C $@ METADIR=$(METADIR)/$@
+
+$(METADIR)/%: %
+ cp -vu $< $(METADIR)
+
+clean:
+# for dir in $(SUBDIRS); do \
+# $(MAKE) -C $$dir clean; \
+# done
\ No newline at end of file
diff --git a/etc/manifest.stub b/etc/manifest.stub
new file mode 100644
index 0000000..03fae8d
--- /dev/null
+++ b/etc/manifest.stub
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+Main-Class: test.ReadlineTest
diff --git a/src/Makefile b/src/Makefile
new file mode 100644
index 0000000..f7c1228
--- /dev/null
+++ b/src/Makefile
@@ -0,0 +1,41 @@
+#**************************************************************************
+#* Makefile for libJavaReadline.so -- load library for JNI wrapper
+#* of GNU readline
+#*
+#* Copyright (c) 1987-1998 Free Software Foundation, Inc.
+#* Java Wrapper Copyright (c) 1998-2001 by Bernhard Bablok (mail at bablokb.de)
+#*
+#* This program is free software; you can redistribute it and#or modify
+#* it under the terms of the GNU Library General Public License as published
+#* by the Free Software Foundation; either version 2 of the License or
+#* (at your option) any later version.
+#*
+#* This 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 Library General Public License for more details.
+#*
+#* You should have received a copy of the GNU Library General Public License
+#* along with this program; see the file COPYING.LIB. If not, write to
+#* the Free Software Foundation Inc., 59 Temple Place - Suite 330,
+#* Boston, MA 02111-1307 USA
+#***************************************************************************
+#
+# $Author: Bablokb $
+# $Revision: 1.2 $
+#
+
+SUBDIRS := $(shell find . -type d -not -name "." -not -name "CVS" -maxdepth 1)
+export SRCROOT := $(shell pwd)
+
+.PHONY: subdirs $(SUBDIRS) clean
+
+subdirs: $(SUBDIRS)
+
+$(SUBDIRS):
+ $(MAKE) -C $@
+
+clean:
+ for dir in $(SUBDIRS); do \
+ $(MAKE) -C $$dir clean; \
+ done
diff --git a/src/mkrules.inc b/src/mkrules.inc
new file mode 100644
index 0000000..596f610
--- /dev/null
+++ b/src/mkrules.inc
@@ -0,0 +1,56 @@
+#**************************************************************************
+#* Makefile for libJavaReadline.so -- load library for JNI wrapper
+#* of GNU readline
+#*
+#* Copyright (c) 1987-1998 Free Software Foundation, Inc.
+#* Java Wrapper Copyright (c) 1998-2001 by Bernhard Bablok (mail at bablokb.de)
+#*
+#* This program is free software; you can redistribute it and#or modify
+#* it under the terms of the GNU Library General Public License as published
+#* by the Free Software Foundation; either version 2 of the License or
+#* (at your option) any later version.
+#*
+#* This 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 Library General Public License for more details.
+#*
+#* You should have received a copy of the GNU Library General Public License
+#* along with this program; see the file COPYING.LIB. If not, write to
+#* the Free Software Foundation Inc., 59 Temple Place - Suite 330,
+#* Boston, MA 02111-1307 USA
+#***************************************************************************
+#
+# $Author: Bablokb $
+# $Revision: 1.2 $
+#
+
+SUBDIRS := $(shell find . -type d -not -name "." -not -name "CVS" -maxdepth 1)
+PACKDIR := $(CLASSDIR)/$(shell echo `pwd` | sed -e's!.*/src/!!')
+
+.PHONY: all classes subdirs clean $(SUBDIRS)
+
+JAVA_SOURCES := $(wildcard *.java)
+JAVA_TARGETS := $(JAVA_SOURCES:%.java=$(PACKDIR)/%.class)
+
+GIF_SOURCES := $(wildcard *.gif)
+GIF_TARGETS := $(GIF_SOURCES:%=$(PACKDIR)/%)
+
+all: $(PACKDIR) subdirs $(JAVA_TARGETS) $(GIF_TARGETS)
+
+subdirs: $(SUBDIRS)
+
+$(PACKDIR):
+ mkdir $(PACKDIR)
+
+$(SUBDIRS):
+ $(MAKE) -C $@
+
+
+$(PACKDIR)/%.class: %.java
+ $(JAVAC) $(JAVAC_OPT) $< -d $(CLASSDIR)
+
+$(PACKDIR)/%.gif: %.gif
+ cp -vu $< $(PACKDIR)
+
+clean:
diff --git a/src/native/Makefile b/src/native/Makefile
new file mode 100644
index 0000000..14c176f
--- /dev/null
+++ b/src/native/Makefile
@@ -0,0 +1,51 @@
+#**************************************************************************
+#* Makefile for libJava*.so -- load library for JNI wrapper of
+#* of GNU readline
+#*
+#* Copyright (c) 1987-1998 Free Software Foundation, Inc.
+#* Java Wrapper Copyright (c) 1998-2001 by Bernhard Bablok (mail at bablokb.de)
+#*
+#* This program is free software; you can redistribute it and/or modify
+#* it under the terms of the GNU Library General Public License as published
+#* by the Free Software Foundation; either version 2 of the License or
+#* (at your option) any later version.
+#*
+#* This 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 Library General Public License for more details.
+#*
+#* You should have received a copy of the GNU Library General Public License
+#* along with this program; see the file COPYING.LIB. If not, write to
+#* the Free Software Foundation Inc., 59 Temple Place - Suite 330,
+#* Boston, MA 02111-1307 USA
+#***************************************************************************
+#
+# Makefile for JNI-library libJava*.so
+#
+# $Author: Bablokb $
+# $Revision: 1.9 $
+#
+
+.PHONY: all lib clean
+
+SO := $(patsubst %,$(ROOTDIR)/lib%.so,$(T_LIBS))
+
+all: $(T_LIBS)
+
+lib: $(ROOTDIR)/lib$(TG).so
+
+Java%:
+ make TG=$@ lib
+
+$(ROOTDIR)/lib%.so: org_gnu_readline_Readline.c org_gnu_readline_Readline.h
+ $(CC) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -D$(TG) \
+ -c org_gnu_readline_Readline.c
+ gcc -shared $(LIBPATH) $($(TG)_LIBS) org_gnu_readline_Readline.o -o $@
+
+org_gnu_readline_Readline.h: $(BUILDDIR)/org/gnu/readline/Readline.class
+ javah -jni org.gnu.readline.Readline
+ touch org_gnu_readline_Readline.h
+
+clean:
+ -rm -f $(SO) org_gnu_readline_Readline.h org_gnu_readline_Readline.o
\ No newline at end of file
diff --git a/src/native/org_gnu_readline_Readline.c b/src/native/org_gnu_readline_Readline.c
new file mode 100644
index 0000000..3277054
--- /dev/null
+++ b/src/native/org_gnu_readline_Readline.c
@@ -0,0 +1,446 @@
+/**************************************************************************
+ * gnu_readline_Readline.c -- implementation of the Java wrapper
+ * of GNU readline.
+ *
+ * Java Wrapper Copyright (c) 1998-2001 by Bernhard Bablok (mail at bablokb.de)
+ *
+ * This program is free software; you can redistribute it and or modify
+ * it under the terms of the GNU Library General Public License as published
+ * by the Free Software Foundation; either version 2 of the License or
+ * (at your option) any later version.
+ *
+ * This 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 Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this program; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307 USA
+ **************************************************************************/
+
+/*
+ * This file implements the native method interface for class
+ * gnu.readline.Readline
+ *
+ * $Revision: 1.9 $
+ * $Author: Bablokb $
+ */
+
+#include "org_gnu_readline_Readline.h"
+
+#ifdef JavaReadline
+#include <readline/readline.h>
+#include <readline/history.h>
+#endif
+
+#ifdef JavaEditline
+#include <editline/readline.h>
+#endif
+
+#include <string.h>
+#include <errno.h>
+
+#define BUF_LENGTH 1024
+
+static char* utf2ucs(const char *utf8, char *ucs, size_t n);
+static char* ucs2utf(const char *ucs, char *utf8, size_t n);
+
+static jobject jniObject;
+static jmethodID jniMethodId;
+static jclass jniClass;
+static JNIEnv* jniEnv;
+
+/* -------------------------------------------------------------------------- */
+/* Initialize readline and history. Set application name. */
+/* -------------------------------------------------------------------------- */
+
+JNIEXPORT void JNICALL Java_org_gnu_readline_Readline_initReadlineImpl
+ (JNIEnv *env, jclass theClass, jstring jappName) {
+ const char *appName;
+ jboolean is_copy;
+
+ appName = (*env)->GetStringUTFChars(env,jappName,&is_copy);
+ if (appName && strlen(appName))
+ rl_readline_name = strdup(appName);
+ else
+ rl_readline_name = strdup("JAVA");
+ if (is_copy == JNI_TRUE)
+ (*env)->ReleaseStringUTFChars(env, jappName, appName);
+#ifdef JavaReadline
+ rl_catch_signals = 0; // don't install signal handlers in JNI code.
+#endif
+ rl_initialize();
+ using_history();
+}
+
+/* -------------------------------------------------------------------------- */
+/* Reset readline's internal states and terminal.
+/* -------------------------------------------------------------------------- */
+
+JNIEXPORT void JNICALL Java_org_gnu_readline_Readline_cleanupReadlineImpl
+ (JNIEnv *env, jclass theClass) {
+ rl_free_line_state();
+ rl_cleanup_after_signal();
+}
+
+
+/* -------------------------------------------------------------------------- */
+/* Prompt for input. "Main" readline function. . */
+/* -------------------------------------------------------------------------- */
+
+JNIEXPORT jstring JNICALL Java_org_gnu_readline_Readline_readlineImpl
+ (JNIEnv *env, jclass theClass, jstring jprompt) {
+
+ char buffer[BUF_LENGTH];
+ const char *prompt;
+ char *input;
+ jboolean is_copy;
+
+ /* retrieve prompt argument and convert to ucs ---------------------------- */
+
+ prompt = (*env)->GetStringUTFChars(env,jprompt,&is_copy);
+ if (!utf2ucs(prompt,buffer,BUF_LENGTH)) {
+ jclass newExcCls;
+ if (is_copy == JNI_TRUE)
+ (*env)->ReleaseStringUTFChars(env, jprompt, prompt);
+ newExcCls = (*env)->FindClass(env,"java/io/UnsupportedEncodingException");
+ if (newExcCls != NULL)
+ (*env)->ThrowNew(env,newExcCls,"");
+ return NULL;
+ }
+ if (is_copy == JNI_TRUE)
+ (*env)->ReleaseStringUTFChars(env, jprompt, prompt);
+
+ /* use gnu-readline, convert string to utf8 ------------------------------- */
+
+ input = readline(buffer);
+ if (input == NULL) {
+ jclass newExcCls;
+ newExcCls = (*env)->FindClass(env,"java/io/EOFException");
+ if (newExcCls != NULL)
+ (*env)->ThrowNew(env,newExcCls,"");
+ return NULL;
+ } else if (*input) {
+ add_history(input);
+ ucs2utf(input,buffer,BUF_LENGTH);
+ return (*env)->NewStringUTF(env,buffer);
+ } else
+ return NULL;
+}
+
+
+/* -------------------------------------------------------------------------- */
+/* Read keybindings from file. */
+/* -------------------------------------------------------------------------- */
+
+#ifdef JavaReadline
+JNIEXPORT void JNICALL Java_org_gnu_readline_Readline_readInitFileImpl
+ (JNIEnv *env, jclass theClass, jstring jfilename) {
+ char buffer[BUF_LENGTH];
+ const char *filename;
+ jboolean is_copy;
+
+ /* retrieve filename argument and convert to ucs -------------------------- */
+
+ filename = (*env)->GetStringUTFChars(env,jfilename,&is_copy);
+ if (!utf2ucs(filename,buffer,BUF_LENGTH)) {
+ jclass newExcCls;
+ if (is_copy == JNI_TRUE)
+ (*env)->ReleaseStringUTFChars(env,jfilename,filename);
+ newExcCls = (*env)->FindClass(env,"java/io/UnsupportedEncodingException");
+ if (newExcCls != NULL)
+ (*env)->ThrowNew(env,newExcCls,"");
+ return;
+ }
+ if (is_copy == JNI_TRUE)
+ (*env)->ReleaseStringUTFChars(env,jfilename,filename);
+
+ /* pass to readline function ---------------------------------------------- */
+
+ if (rl_read_init_file(buffer)) {
+ jclass newExcCls;
+ newExcCls = (*env)->FindClass(env,"java/io/IOException");
+ if (newExcCls != NULL)
+ (*env)->ThrowNew(env,newExcCls,strerror(errno));
+ return;
+ }
+}
+#endif
+
+/* -------------------------------------------------------------------------- */
+/* Read keybinding from string. */
+/* -------------------------------------------------------------------------- */
+
+#ifdef JavaReadline
+JNIEXPORT jboolean JNICALL Java_org_gnu_readline_Readline_parseAndBindImpl
+ (JNIEnv *env, jclass theClass, jstring jline) {
+ char buffer[BUF_LENGTH];
+ const char *line;
+ jboolean is_copy;
+
+ /* retrieve line argument and convert to ucs -------------------------- */
+
+ line = (*env)->GetStringUTFChars(env,jline,&is_copy);
+ if (!utf2ucs(line,buffer,BUF_LENGTH)) {
+ jclass newExcCls;
+ if (is_copy == JNI_TRUE)
+ (*env)->ReleaseStringUTFChars(env,jline,line);
+ newExcCls = (*env)->FindClass(env,"java/io/UnsupportedEncodingException");
+ if (newExcCls != NULL)
+ (*env)->ThrowNew(env,newExcCls,"");
+ return (jboolean) JNI_FALSE;
+ }
+ if (is_copy == JNI_TRUE)
+ (*env)->ReleaseStringUTFChars(env,jline,line);
+
+ /* pass to readline function ---------------------------------------------- */
+
+ if (rl_parse_and_bind(buffer))
+ return (jboolean) JNI_FALSE;
+ else
+ return (jboolean) JNI_TRUE;
+}
+#endif
+
+/* -------------------------------------------------------------------------- */
+/* Read history file */
+/* -------------------------------------------------------------------------- */
+
+JNIEXPORT void JNICALL Java_org_gnu_readline_Readline_readHistoryFileImpl
+ (JNIEnv *env, jclass theClass, jstring jfilename) {
+ char buffer[BUF_LENGTH];
+ const char *filename;
+ jboolean is_copy;
+
+ /* retrieve filename argument and convert to ucs -------------------------- */
+
+ filename = (*env)->GetStringUTFChars(env,jfilename,&is_copy);
+ if (!utf2ucs(filename,buffer,BUF_LENGTH)) {
+ jclass newExcCls;
+ if (is_copy == JNI_TRUE)
+ (*env)->ReleaseStringUTFChars(env,jfilename,filename);
+ newExcCls = (*env)->FindClass(env,"java/io/UnsupportedEncodingException");
+ if (newExcCls != NULL)
+ (*env)->ThrowNew(env,newExcCls,"");
+ return;
+ }
+ if (is_copy == JNI_TRUE)
+ (*env)->ReleaseStringUTFChars(env,jfilename,filename);
+
+ /* pass to history function ----------------------------------------------- */
+
+ read_history(buffer);
+}
+
+/* -------------------------------------------------------------------------- */
+/* Write history file */
+/* -------------------------------------------------------------------------- */
+
+JNIEXPORT void JNICALL Java_org_gnu_readline_Readline_writeHistoryFileImpl
+ (JNIEnv *env, jclass theClass, jstring jfilename) {
+ char buffer[BUF_LENGTH];
+ const char *filename;
+ jboolean is_copy;
+
+ /* retrieve filename argument and convert to ucs -------------------------- */
+
+ filename = (*env)->GetStringUTFChars(env,jfilename,&is_copy);
+ if (!utf2ucs(filename,buffer,BUF_LENGTH)) {
+ jclass newExcCls;
+ if (is_copy == JNI_TRUE)
+ (*env)->ReleaseStringUTFChars(env,jfilename,filename);
+ newExcCls = (*env)->FindClass(env,"java/io/UnsupportedEncodingException");
+ if (newExcCls != NULL)
+ (*env)->ThrowNew(env,newExcCls,"");
+ return;
+ }
+ if (is_copy == JNI_TRUE)
+ (*env)->ReleaseStringUTFChars(env,jfilename,filename);
+
+ /* pass to history function ----------------------------------------------- */
+
+ write_history(buffer);
+}
+
+
+/* -------------------------------------------------------------------------- */
+/* Completer function, visible to the readline library */
+/* -------------------------------------------------------------------------- */
+
+const char *java_completer(char *text, int state) {
+ jstring jtext;
+ jstring completion;
+ const char *line;
+ jboolean is_copy;
+
+ jtext = (*jniEnv)->NewStringUTF(jniEnv,text);
+
+ if (jniMethodId == 0) {
+ return;
+ }
+
+ completion = (*jniEnv)->CallObjectMethod(jniEnv, jniObject,
+ jniMethodId, jtext, state);
+ if (!completion) {
+ return ((const char *)NULL);
+ }
+
+ line = (*jniEnv)->GetStringUTFChars(jniEnv,completion,&is_copy);
+ return line;
+}
+
+/* -------------------------------------------------------------------------- */
+/* Install completer object */
+/* -------------------------------------------------------------------------- */
+
+JNIEXPORT void JNICALL Java_org_gnu_readline_Readline_setCompleterImpl
+ (JNIEnv *env, jclass class, jobject obj) {
+
+/* completer_cls = (*env)->GetObjectClass(env, compl); */
+/* completer_cls = (*env)->NewGlobalRef(env, completer_cls); */
+
+/* completer = (*env)->GetMethodID(env, completer_cls, */
+/* "completer", */
+/* "(Ljava/lang/String;I)Ljava/lang/String;"); */
+
+/* (*env)->CallVoidMethod(env, completer_cls, completer, "test", 1); */
+ if (obj != NULL) {
+ jniEnv = env;
+ jniObject = obj;
+ jniClass = (*jniEnv)->GetObjectClass(jniEnv, jniObject);
+ jniClass = (*env)->NewGlobalRef(env, jniClass);
+ jniObject = (*env)->NewGlobalRef(env, jniObject);
+ jniMethodId = (*jniEnv)->GetMethodID(jniEnv, jniClass, "completer",
+ "(Ljava/lang/String;I)Ljava/lang/String;");
+ if (jniMethodId == 0) {
+ rl_completion_entry_function = NULL;
+ return;
+ }
+ rl_completion_entry_function = (Function*)java_completer;
+ }
+ else {
+ rl_completion_entry_function = NULL;
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+/* Returns rl_line_buffer
+/* -------------------------------------------------------------------------- */
+
+JNIEXPORT jstring JNICALL
+ Java_org_gnu_readline_Readline_getLineBufferImpl
+ (JNIEnv * env, jclass class) {
+ jniEnv = env;
+ return (*jniEnv)->NewStringUTF(jniEnv, rl_line_buffer);
+}
+
+/* -------------------------------------------------------------------------- */
+/* Returns rl_completer_word_break_characters */
+/* -------------------------------------------------------------------------- */
+
+JNIEXPORT jstring JNICALL
+ Java_org_gnu_readline_Readline_getWordBreakCharactersImpl
+ (JNIEnv * env, jclass class) {
+ jstring word_break_characters;
+
+ jniEnv = env;
+ if (rl_completer_word_break_characters == 0) {
+ word_break_characters =
+ (*jniEnv)->NewStringUTF(jniEnv, rl_basic_word_break_characters);
+
+ } else {
+ word_break_characters =
+ (*jniEnv)->NewStringUTF(jniEnv, rl_completer_word_break_characters);
+ }
+
+ return word_break_characters;
+}
+
+/* -------------------------------------------------------------------------- */
+/* Sets rl_completer_word_break_characters */
+/* -------------------------------------------------------------------------- */
+
+static char word_break_buffer[BUF_LENGTH];
+
+JNIEXPORT void JNICALL
+ Java_org_gnu_readline_Readline_setWordBreakCharactersImpl
+ (JNIEnv * env, jclass class, jstring jword_break_chars) {
+ const char * word_break_chars;
+ jboolean is_copy;
+
+ word_break_chars = (*env)->GetStringUTFChars(env,jword_break_chars,&is_copy);
+ if (!utf2ucs(word_break_chars,word_break_buffer,BUF_LENGTH)) {
+ jclass newExcCls;
+ if (is_copy == JNI_TRUE)
+ (*env)->ReleaseStringUTFChars(env,jword_break_chars,word_break_chars);
+ newExcCls = (*env)->FindClass(env,"java/io/UnsupportedEncodingException");
+ if (newExcCls != NULL)
+ (*env)->ThrowNew(env,newExcCls,"");
+ return;
+ }
+ if (is_copy == JNI_TRUE)
+ (*env)->ReleaseStringUTFChars(env,jword_break_chars,word_break_chars);
+
+ rl_completer_word_break_characters = word_break_buffer;
+}
+
+/* -------------------------------------------------------------------------- */
+/* Convert utf8-string to ucs1-string . */
+/* -------------------------------------------------------------------------- */
+
+char* utf2ucs(const char *utf8, char *ucs, size_t n) {
+ const char *pin;
+ char *pout;
+ unsigned char current, next;
+ int i;
+
+ for (i=0,pin=utf8,pout=ucs; i<n && *pin; i++,pin++,pout++) {
+ current = *pin;
+ if (current >= 0xE0) { /* we support only two-byte utf8 */
+ return NULL;
+ } else if ((current & 0x80) == 0) /* one-byte utf8 */
+ *pout = current;
+ else { /* two-byte utf8 */
+ next = *(++pin);
+ if (next >= 0xC0) { /* illegal coding */
+ return NULL;
+ }
+ *pout = ((current & 3) << 6) + /* first two bits of first byte */
+ (next & 63); /* last six bits of second byte */
+ }
+ }
+ if (i<n)
+ *pout = '\0';
+ return ucs;
+}
+
+/* -------------------------------------------------------------------------- */
+/* Convert ucs1-string to utf8-string . */
+/* -------------------------------------------------------------------------- */
+
+char* ucs2utf(const char *ucs, char *utf8, size_t n) {
+ const char *pin;
+ char *pout;
+ unsigned char current;
+ int i;
+
+ for (i=0,pin=ucs,pout=utf8; i<n && *pin; i++,pin++,pout++) {
+ current = *pin;
+ if (current < 0x80) /* one-byte utf8 */
+ *pout = current;
+ else { /* two-byte utf8 */
+ *pout = 0xC0 + (current>>6); /* first two bits */
+ pout++, i++; /* examine second byte */
+ if (i>=n) { /* cannot convert last byte */
+ *(--pout) = '\0';
+ return utf8;
+ }
+ *pout = 0x80 + (current & 63); /* last six bits */
+ }
+ }
+ if (i<n)
+ *pout = '\0';
+ return utf8;
+}
diff --git a/src/org/Makefile b/src/org/Makefile
new file mode 100644
index 0000000..2aa9a1d
--- /dev/null
+++ b/src/org/Makefile
@@ -0,0 +1,28 @@
+#**************************************************************************
+#* Makefile for libJavaReadline.so -- load library for JNI wrapper
+#* of GNU readline
+#*
+#* Copyright (c) 1987-1998 Free Software Foundation, Inc.
+#* Java Wrapper Copyright (c) 1998-2001 by Bernhard Bablok (mail at bablokb.de)
+#*
+#* This program is free software; you can redistribute it and#or modify
+#* it under the terms of the GNU Library General Public License as published
+#* by the Free Software Foundation; either version 2 of the License or
+#* (at your option) any later version.
+#*
+#* This 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 Library General Public License for more details.
+#*
+#* You should have received a copy of the GNU Library General Public License
+#* along with this program; see the file COPYING.LIB. If not, write to
+#* the Free Software Foundation Inc., 59 Temple Place - Suite 330,
+#* Boston, MA 02111-1307 USA
+#***************************************************************************
+#
+# $Author: Bablokb $
+# $Revision: 1.2 $
+#
+
+include $(SRCROOT)/mkrules.inc
diff --git a/src/org/gnu/Makefile b/src/org/gnu/Makefile
new file mode 100644
index 0000000..e0b5206
--- /dev/null
+++ b/src/org/gnu/Makefile
@@ -0,0 +1,28 @@
+#**************************************************************************
+#* Makefile for libJavaReadline.so -- load library for JNI wrapper
+#* of GNU readline
+#*
+#* Copyright (c) 1987-1998 Free Software Foundation, Inc.
+#* Java Wrapper Copyright (c) 1998-2001 by Bernhard Bablok (mail at bablokb.de)
+#*
+#* This program is free software; you can redistribute it and#or modify
+#* it under the terms of the GNU Library General Public License as published
+#* by the Free Software Foundation; either version 2 of the License or
+#* (at your option) any later version.
+#*
+#* This 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 Library General Public License for more details.
+#*
+#* You should have received a copy of the GNU Library General Public License
+#* along with this program; see the file COPYING.LIB. If not, write to
+#* the Free Software Foundation Inc., 59 Temple Place - Suite 330,
+#* Boston, MA 02111-1307 USA
+#***************************************************************************
+#
+# $Author: Bablokb $
+# $Revision: 1.2 $
+#
+
+include $(SRCROOT)/mkrules.inc
\ No newline at end of file
diff --git a/src/org/gnu/readline/Makefile b/src/org/gnu/readline/Makefile
new file mode 100644
index 0000000..93c32b9
--- /dev/null
+++ b/src/org/gnu/readline/Makefile
@@ -0,0 +1,30 @@
+#**************************************************************************
+#* Makefile for libJavaReadline.so -- load library for JNI wrapper
+#* of GNU readline
+#*
+#* Copyright (c) 1987-1998 Free Software Foundation, Inc.
+#* Java Wrapper Copyright (c) 1998-2001 by Bernhard Bablok (mail at bablokb.de)
+#*
+#* This program is free software; you can redistribute it and/or modify
+#* it under the terms of the GNU Library General Public License as published
+#* by the Free Software Foundation; either version 2 of the License or
+#* (at your option) any later version.
+#*
+#* This 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 Library General Public License for more details.
+#*
+#* You should have received a copy of the GNU Library General Public License
+#* along with this program; see the file COPYING.LIB. If not, write to
+#* the Free Software Foundation Inc., 59 Temple Place - Suite 330,
+#* Boston, MA 02111-1307 USA
+#***************************************************************************
+#
+# $Author: Bablokb $
+# $Revision: 1.5 $
+#
+
+include $(SRCROOT)/mkrules.inc
+
+$(PACKDIR)/Readline.class: $(PACKDIR)/ReadlineLibrary.class
\ No newline at end of file
diff --git a/src/org/gnu/readline/Readline.java b/src/org/gnu/readline/Readline.java
new file mode 100644
index 0000000..4697928
--- /dev/null
+++ b/src/org/gnu/readline/Readline.java
@@ -0,0 +1,475 @@
+/**************************************************************************
+/* Readline.java -- Java wrapper of GNU readline
+/*
+/* Java Wrapper Copyright (c) 1998-2001 by Bernhard Bablok (mail at bablokb.de)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation; either version 2 of the License or
+/* (at your option) any later version.
+/*
+/* This 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 Library General Public License for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; see the file COPYING.LIB. If not, write to
+/* the Free Software Foundation Inc., 59 Temple Place - Suite 330,
+/* Boston, MA 02111-1307 USA
+/**************************************************************************/
+
+package org.gnu.readline;
+
+import java.io.*;
+
+/**
+ This class implements basic functionality of the GNU-readline interface. It
+ uses native method calls if available, otherwise it defaults to normal
+ I/O using a BufferedReader.
+
+ <p>A typical implementation could look like:
+<pre>
+ try {
+ Readline.load(ReadlineLibrary.GnuReadline);
+ }
+ catch (UnsatisfiedLinkError ignore_me) {
+ System.err.println("couldn't load readline lib. Using simple stdin.");
+ }
+
+ Readline.initReadline("myapp");
+
+ Runtime.getRuntime() // if your version supports
+ .addShutdownHook(new Thread() { // addShutdownHook (since 1.3)
+ public void run() {
+ Readline.cleanup();
+ }
+ });
+
+ while (true) {
+ try {
+ line = Readline.readline("myprompt> ");
+ if (line == null)
+ System.out.println("no input");
+ else
+ processLine();
+ }
+ catch (EOFException e) {
+ break;
+ }
+ catch (Exception e) {
+ doSomething();
+ }
+ }
+ Readline.cleanup(); // see note above about addShutdownHook
+
+</pre>
+
+ @version $Revision: 1.18 $
+ @author $Author: Bablokb $
+*/
+
+public class Readline {
+
+ /**
+ The currently defined ReadlineCompleter.
+ */
+
+ private static ReadlineCompleter iCompleter = null;
+
+
+ /**
+ The currently implementing backing library.
+ */
+
+ private static ReadlineLibrary iLib = ReadlineLibrary.PureJava;
+
+ /**
+ The BufferedReader for the fallback solution.
+ */
+
+ private static BufferedReader iReader = null;
+
+ /**
+ Configuration flag: throw an UnsupportedOperationException, if true.
+ This value defaults to false.
+ */
+
+ private static boolean iThrowException = false;
+
+ /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ Load an implementing backing library. This method might throw an
+ UnsatisfiedLinkError in case the native libary is not found in the
+ library path. If you want to have portable program, just catch and
+ ignore that error. JavaReadline will then just use the pure Java fallback
+ solution.
+
+ @param lib An object (constant) of type ReadlineLibrary
+ @throws UnsatisfiedLinkError if the shared library could not be
+ found. Add it to your LD_LIBRARY_PATH.
+ @see org.gnu.readline.ReadlineLibrary
+ */
+
+ public static final void load(ReadlineLibrary lib) throws UnsatisfiedLinkError {
+ if (lib == iLib) // ok, since objects are immutable
+ return;
+ if (lib == ReadlineLibrary.PureJava) {
+ iLib = lib;
+ return;
+ }
+ System.loadLibrary(lib.getName()); // might throw UnsatisfiedLinkError
+ iLib = lib;
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ Initialize the GNU-Readline library. This will also set the
+ application name, which can be used in the initialization files of
+ Readline (usually /etc/inputrc and ~/.inputrc) to define application
+ specific keys. See the file ReadlineTest.java int the test subdir of
+ the distribution for an example.
+
+ @param applicationName Name of application in initialization file
+ */
+
+ public static void initReadline(String applicationName) {
+ if (iLib != ReadlineLibrary.PureJava) {
+ initReadlineImpl(applicationName);
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ Display a prompt on standard output and read a string from
+ standard input. This method returns 'null', if there has
+ been an empty input (user pressed just [RETURN]) and throws
+ an EOFException on end-of-file (C-d).
+
+ @param prompt Prompt to display
+ @return The string the user entered or 'null' if there was no input.
+ @throws EOFException on end-of-file, i.e. CTRL-d input.
+ */
+
+ public static String readline(String prompt) throws EOFException,
+ IOException, UnsupportedEncodingException {
+ if (iLib != ReadlineLibrary.PureJava)
+ return readlineImpl(prompt);
+ else {
+ System.out.print(prompt);
+ if (iReader == null)
+ iReader = new BufferedReader(new InputStreamReader(System.in));
+ String line = iReader.readLine();
+ if (line == null)
+ throw new EOFException("EOF");
+ return (line.length() == 0) ? null : line;
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ Read keybindings and variable assignments from a file. This method is a
+ wrapper to rl_read_init_file(char *filename). Throws IOException if
+ something goes wrong.
+
+ @param filename Name of file to read bindings from
+ @return void
+ */
+
+ public static void readInitFile(String filename) throws IOException {
+ if (iLib == ReadlineLibrary.GnuReadline)
+ readInitFileImpl(filename);
+ else if (iThrowException)
+ throw new UnsupportedOperationException();
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ Parse argument string as if it had been read from `inputrc' file
+ and perform key bindings and variable assignments found.
+
+ @param line Simulated line from inputrc file
+ @return boolean False in case of error
+ */
+
+ public static boolean parseAndBind(String line) {
+ if (iLib == ReadlineLibrary.GnuReadline)
+ return parseAndBindImpl(line);
+ else if (iThrowException)
+ throw new UnsupportedOperationException();
+ else
+ return true;
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ Reads a history file into memory
+ @param filename Name of history file to read
+ */
+
+ public static void readHistoryFile(String filename)
+ throws EOFException, UnsupportedEncodingException {
+ if (iLib != ReadlineLibrary.PureJava)
+ readHistoryFileImpl(filename);
+ else if (iThrowException)
+ throw new UnsupportedOperationException();
+ }
+
+
+ /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ Writes a history file to disc
+
+ @param filename Name of history file to write
+ */
+
+ public static void writeHistoryFile(String filename)
+ throws EOFException, UnsupportedEncodingException {
+ if (iLib != ReadlineLibrary.PureJava)
+ writeHistoryFileImpl(filename);
+ else if (iThrowException)
+ throw new UnsupportedOperationException();
+ }
+
+
+ /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ Set your completer implementation. Setting this to <code>null</code>
+ will result in the default behaviour of readline which is filename
+ completion.
+
+ @param rlc An object implementing the ReadlineCompleter interface
+ */
+
+ public static void setCompleter(ReadlineCompleter rlc) {
+ iCompleter = rlc;
+ if (iLib != ReadlineLibrary.PureJava) {
+ setCompleterImpl(iCompleter);
+ } else if (iThrowException)
+ throw new UnsupportedOperationException();
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ Query current completer function.
+
+ @return Current ReadlineCompleter object
+ */
+
+ public static ReadlineCompleter getCompleter() {
+ return iCompleter;
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ Reset the readline library and with it, the terminal.
+ */
+
+ public static void cleanup() {
+ if (iLib != ReadlineLibrary.PureJava) {
+ cleanupReadlineImpl();
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ Query word break characters.
+ */
+
+ public static String getWordBreakCharacters() {
+ if (iLib != ReadlineLibrary.PureJava)
+ return getWordBreakCharactersImpl();
+ else if (iThrowException)
+ throw new UnsupportedOperationException();
+ else
+ return null;
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ Query the current line buffer. This returns the current content of
+ the internal line buffer. You might need this in a
+ {@link ReadlineCompleter} implementation to access the full text
+ given so far.
+ */
+
+ public static String getLineBuffer() {
+ if (iLib != ReadlineLibrary.PureJava)
+ return getLineBufferImpl();
+ else if (iThrowException)
+ throw new UnsupportedOperationException();
+ else
+ return null;
+ }
+
+
+ /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ Set word break characters.
+
+ @param wordBreakCharacters A string of word break characters
+ */
+
+ public static void
+ setWordBreakCharacters(String wordBreakCharacters)
+ throws UnsupportedEncodingException {
+ if (iLib != ReadlineLibrary.PureJava)
+ setWordBreakCharactersImpl(wordBreakCharacters);
+ else if (iThrowException)
+ throw new UnsupportedOperationException();
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ Configure behavior in case an unsupported method is called. If argument
+ is true, unsupported methods throw an UnsupportedOperationException.
+
+ @param flag configuration flag
+ */
+
+ public static void setThrowExceptionOnUnsupportedMethod(boolean flag) {
+ iThrowException = flag;
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ Query behavior in case an unsupported method is called.
+
+ @return configuration flag
+ */
+
+ public static boolean getThrowExceptionOnUnsupportedMethod() {
+ return iThrowException;
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ Native implementation of initReadline()
+
+ @see org.gnu.readline.Readline#initReadline(String applicationName)
+ */
+
+ private native static void initReadlineImpl(String applicationName);
+
+ /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ cleanup readline; reset terminal.
+ */
+
+ private native static void cleanupReadlineImpl();
+
+ /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ Native implementation of readline()
+
+ @see org.gnu.readline.Readline#readline(String prompt)
+ */
+
+ private native static String readlineImpl(String prompt)
+ throws EOFException, UnsupportedEncodingException;
+
+ /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ Native implementation of readInitFile(String filename)
+
+ @see org.gnu.readline.Readline#readInitFile(String filename)
+ */
+
+ private native static void readInitFileImpl(String filename)
+ throws IOException;
+
+
+ /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ Native implementation of getLineBuffer()
+
+ @see org.gnu.readline.Readline#getLineBuffer()
+ */
+
+ private native static String getLineBufferImpl();
+
+ /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ Native implementation of parseAndBind(String line)
+
+ @see org.gnu.readline.Readline#parseAndBind(String line)
+ */
+
+ private native static boolean parseAndBindImpl(String line);
+
+ /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ Native implementation of readHistoryFile(String filename)
+
+ @see org.gnu.readline.Readline#readHistoryFile(String filename)
+ */
+
+ private native static void readHistoryFileImpl(String filename)
+ throws EOFException, UnsupportedEncodingException;
+
+ /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ Native implementation of writeHistoryFile(String filename)
+
+ @see org.gnu.readline.Readline#writeHistoryFile(String filename)
+ */
+
+ private native static void writeHistoryFileImpl(String filename)
+ throws EOFException, UnsupportedEncodingException;
+
+ /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ Native implementation of setCompleter(ReadlineCompleter rlc)
+
+ @see org.gnu.readline.Readline#setCompleter(ReadlineCompleter rlc)
+ */
+
+ private native static void setCompleterImpl(ReadlineCompleter rlc);
+
+ /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ Native implementation of getWordBreakCharacters()
+
+ @see org.gnu.readline.Readline#getWordBreakCharacters()
+ */
+
+ private native static String getWordBreakCharactersImpl();
+
+ /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ Native implementation of setWordBreakCharacters()
+
+ @see
+ org.gnu.readline.Readline#setWordBreakCharacters(String wordBreakCharacters)
+ */
+
+ private native static void
+ setWordBreakCharactersImpl(String wordBreakCharacters)
+ throws UnsupportedEncodingException;
+}
diff --git a/src/org/gnu/readline/ReadlineCompleter.java b/src/org/gnu/readline/ReadlineCompleter.java
new file mode 100644
index 0000000..55c07b2
--- /dev/null
+++ b/src/org/gnu/readline/ReadlineCompleter.java
@@ -0,0 +1,101 @@
+// File: ReadlineCompleter.java
+// Created: 2001-02-22 15:50:22, erik
+// By: <erik at skiinfo.fr>
+// Time-stamp: <2001-02-23 11:19:11, erik>
+//
+// $Id: ReadlineCompleter.java,v 1.1 2001/12/27 11:08:05 Bablokb Exp $
+//
+// Description:
+
+
+package org.gnu.readline;
+
+/**
+ * Callback interface that implements completion. You've to implement this
+ * interface in order to provide completion in your application. The default
+ * completion mode of the Readline library would otherwise be simple
+ * filename completion.
+ */
+public interface ReadlineCompleter {
+
+ /**
+ * A generator function for filename completion in the general case.
+ * Note that completion in Bash is a little different because of all
+ * the pathnames that must be followed when looking up completions
+ * for a command. The Bash source is a useful reference for writing
+ * custom completion functions.
+ *
+ * <p>The completer method is called with the current text to be
+ * expanded (that is: the string of characters after the last
+ * {@link Readline#getWordBreakCharacters() word break character}) and
+ * an integer. The integer is zero to indicate, that the user just requested
+ * completion (usually by pressing the TAB-key). The completeter method now
+ * can return one possible choice or null to indicate that there is no
+ * choice. If the completer returned a non-null value it is called back by
+ * the readline library with increasing <code>state</code> variable until
+ * it returns null.
+ *
+ * <p>Depending on the state and the return value, the readline library
+ * reacts differently.
+ * <ul>
+ * <li>if the completer returns <code>null</code> for state=0, then
+ * the readline library will beep to indicate that there is no
+ * known completion.</li>
+ * <li>if the completer returns a value for state=0 and
+ * <code>null</code> for state=1, then there was exactly <em>one</em>
+ * possible completion, that is immediately expanded on the command line.</li>
+ * <li>if the completer returns choices for states >= 1, then these
+ * choices are displayed to the user to choose from.</li>
+ * </ul>
+ *
+ * <p><b>Example</b><br>
+ * Consider you have a sorted set (like a TreeSet) of commands:
+ * <hr><pre>
+ * SortedSet commandSet; // SortedSet<String>
+ * ...
+ * commandSet = new TreeSet();
+ * commandSet.add("copy");
+ * commandSet.add("copyme");
+ * commandSet.add("load");
+ * commandSet.add("list");
+ * ...
+ * </pre><hr>
+ * now, you could write a completion method that provides completion for these
+ * commands:
+ * <hr><pre>
+ * private Iterator possibleValues; // iterator for subsequent calls.
+ *
+ * public String completer(String text, int state) {
+ * if (state == 0) {
+ * // first call to completer(): initialize our choices-iterator
+ * possibleValues = commandSet.tailSet(text).iterator();
+ * }
+ * if (possibleValues.hasNext()) {
+ * String nextKey = (String) possibleValues.next();
+ * if (nextKey.startsWith(text))
+ * return nextKey;
+ * }
+ * return null; // we reached the last choice.
+ * }
+ * </pre><hr>
+ *
+ * @param text start of completion text. This is the text since the last
+ * word break character.
+ * @param state 0 or positive int. This state is zero on the first call
+ * for a completion request and increments for each subsequent
+ * call until the end of choices is reached.
+ *
+ * @return String with a completion choice or <code>null</code>, if there
+ * are no more choices.
+ *
+ * @see Readline#getWordBreakCharacters()
+ * @see test.TestCompleter
+ */
+ public String completer(String text, int state);
+}
+
+/*
+ * Local variables:
+ * c-basic-offset: 2
+ * End:
+ */
diff --git a/src/org/gnu/readline/ReadlineLibrary.java b/src/org/gnu/readline/ReadlineLibrary.java
new file mode 100644
index 0000000..29e9295
--- /dev/null
+++ b/src/org/gnu/readline/ReadlineLibrary.java
@@ -0,0 +1,96 @@
+/**************************************************************************
+/* ReadlineLibrary.java -- A typesafe enum class
+/*
+/* Java Wrapper Copyright (c) 1998-2001 by Bernhard Bablok (mail at bablokb.de)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation; either version 2 of the License or
+/* (at your option) any later version.
+/*
+/* This 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 Library General Public License for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; see the file COPYING.LIB. If not, write to
+/* the Free Software Foundation Inc., 59 Temple Place - Suite 330,
+/* Boston, MA 02111-1307 USA
+/**************************************************************************/
+
+package org.gnu.readline;
+
+/**
+ This class implements a typesafe enumeration of the backing libraries.
+
+ @version $Revision: 1.3 $
+ @author $Author: Bablokb $
+*/
+
+public final class ReadlineLibrary {
+
+ /**
+ Constant for fallback, pure Java implementation.
+ */
+
+ public static final ReadlineLibrary PureJava =
+ new ReadlineLibrary("PureJava");
+
+ /**
+ Constant for GNU-Readline implementation.
+ */
+
+ public static final ReadlineLibrary GnuReadline =
+ new ReadlineLibrary("JavaReadline");
+
+ /**
+ Constant for Editline implementation.
+ */
+
+ public static final ReadlineLibrary Editline =
+ new ReadlineLibrary("JavaEditline");
+
+ /**
+ The name of the backing native library.
+ */
+
+ private String iName;
+
+ /**
+ Constructor. The constructor is private, so only the predefined
+ constants are available.
+ */
+
+ private ReadlineLibrary(String name) {
+ iName = name;
+ }
+
+ /**
+ Query name of backing library.
+
+ @return Name of backing library, or "PureJava", in case fallback
+ implementation is used.
+ */
+
+ public String getName() {
+ return iName;
+ }
+
+ /**
+ Return ReadlineLibrary-object with given name.
+
+ @return one of the predefined constants
+ */
+
+ public static ReadlineLibrary byName(String name) {
+ if (name.equals("GnuReadline"))
+ return GnuReadline;
+ else if (name.equals("Editline"))
+ return Editline;
+ else if (name.equals("PureJava"))
+ return PureJava;
+ return null;
+ }
+}
+
diff --git a/src/org/gnu/readline/ReadlineReader.java b/src/org/gnu/readline/ReadlineReader.java
new file mode 100644
index 0000000..b591134
--- /dev/null
+++ b/src/org/gnu/readline/ReadlineReader.java
@@ -0,0 +1,149 @@
+package org.gnu.readline;
+
+import java.io.File;
+import java.io.Reader;
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * A <code>Reader</code> wrapper for the Readline classes. This seems
+ * to work fine in conjunction with such classes as BufferedReader,
+ * but it hasn't been tested well enough to see if this will work well
+ * in all cases.
+ *
+ * This was implemented to make it easier to supplant Readline's
+ * functionality [shrug] anywhere and everywhere, but specifically in
+ * <a href="http://www.beanshell.org">BeanShell</a>.
+ *
+ * @version $Revision: 1.2 $
+ * @author Shane Celis <shane at terrapsring.com>
+ **/
+
+public class ReadlineReader extends Reader {
+
+ public static final String DEFAULT_PROMPT = "";
+ private StringBuffer iBuff;
+ private String iLineSeparator;
+ private String iPrompt;
+ private File iHistoryFile;
+
+ /**
+ * Constructs a ReadlineReader object with the given prompt.
+ **/
+
+ public ReadlineReader(String prompt,ReadlineLibrary lib) {
+ iBuff = new StringBuffer();
+ setPrompt(prompt);
+ Readline.load(lib);
+ Readline.initReadline("ReadlineReader");
+ iLineSeparator = System.getProperty("line.separator", "\n");
+ }
+
+ /**
+ * Constructs a ReadlineReader object with the default prompt.
+ **/
+
+ public ReadlineReader(ReadlineLibrary lib) {
+ this(DEFAULT_PROMPT,lib);
+ }
+
+ /**
+ * Constructs a ReadlineReader object with an associated history
+ * file.
+ **/
+
+ public ReadlineReader(File history,ReadlineLibrary lib) throws IOException {
+ this(DEFAULT_PROMPT,lib);
+ Readline.readHistoryFile(history.getAbsolutePath());
+ iHistoryFile = history; // only set this if we can read the file
+ }
+
+ /**
+ * Constructs a ReadlineReader object with an associated history
+ * file and prompt.
+ **/
+
+ public ReadlineReader(String prompt, File history,ReadlineLibrary lib)
+ throws IOException {
+ this(history,lib);
+ setPrompt(prompt);
+ }
+
+ /**
+ * Returns the current prompt.
+ **/
+
+ public String getPrompt() {
+ return iPrompt;
+ }
+
+ /**
+ * Sets the prompt to the given value.
+ **/
+
+ public void setPrompt(String prompt) {
+ iPrompt = prompt;
+ }
+
+ /**
+ * Reads what's given from <code>readline()</code> into a buffer.
+ * When that buffer is emptied, <code>readline()</code> is called
+ * again to replenish that buffer. This seems to work fine in
+ * conjunction with such classes as BufferedReader, but it hasn't
+ * been tested well enough to see if this will work well in all
+ * cases.
+ **/
+
+ public int read(char[] cbuf, int off, int len)
+ throws IOException {
+ try {
+ if (iBuff.length() == 0) {
+ String line = Readline.readline(iPrompt);
+ iBuff.append((line == null ? "" : line) + iLineSeparator);
+ }
+ if (len > iBuff.length())
+ len = iBuff.length();
+ if (len == 0)
+ return 0;
+ char[] sbuf = iBuff.substring(0, len).toCharArray();
+ System.arraycopy(sbuf, 0, cbuf, off, len);
+ iBuff.delete(0, len);
+ return len;
+ } catch (EOFException eof) {
+ throw eof;
+ } catch (UnsupportedEncodingException uee) {
+ throw uee;
+ }
+ }
+
+ /**
+ * Nullifies all buffers and writes history file if one was given
+ * at construction time.
+ **/
+
+ public void close()
+ throws IOException {
+ iBuff = null;
+ iPrompt = null;
+ if (iHistoryFile != null) {
+ Readline.writeHistoryFile(iHistoryFile.getAbsolutePath());
+ iHistoryFile = null;
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ java.io.BufferedReader rd =
+ new java.io.BufferedReader(new
+ ReadlineReader("hmm ", new File("test"),ReadlineLibrary.GnuReadline));
+ String line;
+ try {
+ while ((line = rd.readLine()) != null) {
+ System.out.println("got: " + line);
+ }
+ } finally {
+ rd.close();
+ }
+ }
+}
+
diff --git a/src/test/Makefile b/src/test/Makefile
new file mode 100644
index 0000000..d564180
--- /dev/null
+++ b/src/test/Makefile
@@ -0,0 +1,30 @@
+#**************************************************************************
+#* Makefile for libJavaReadline.so -- load library for JNI wrapper
+#* of GNU readline
+#*
+#* Copyright (c) 1987-1998 Free Software Foundation, Inc.
+#* Java Wrapper Copyright (c) 1998-2001 by Bernhard Bablok (mail at bablokb.de)
+#*
+#* This program is free software; you can redistribute it and/or modify
+#* it under the terms of the GNU Library General Public License as published
+#* by the Free Software Foundation; either version 2 of the License or
+#* (at your option) any later version.
+#*
+#* This 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 Library General Public License for more details.
+#*
+#* You should have received a copy of the GNU Library General Public License
+#* along with this program; see the file COPYING.LIB. If not, write to
+#* the Free Software Foundation Inc., 59 Temple Place - Suite 330,
+#* Boston, MA 02111-1307 USA
+#***************************************************************************
+#
+# $Author: Bablokb $
+# $Revision: 1.3 $
+#
+
+include $(SRCROOT)/mkrules.inc
+
+$(PACKDIR)/ReadlineTest.class: $(PACKDIR)/TestCompleter.class
\ No newline at end of file
diff --git a/src/test/ReadlineTest.java b/src/test/ReadlineTest.java
new file mode 100644
index 0000000..3d6a342
--- /dev/null
+++ b/src/test/ReadlineTest.java
@@ -0,0 +1,130 @@
+/**************************************************************************
+/* ReadlineTest.java -- Test program for the Java wrapper of GNU readline
+/*
+/* Java Wrapper Copyright (c) 1998-2001 by Bernhard Bablok (mail at bablokb.de)
+/*
+/* This sample program is placed into the public domain and can be
+/* used or modified without any restriction.
+/*
+/* 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.
+/**************************************************************************/
+
+package test;
+
+import java.io.*;
+import org.gnu.readline.*;
+
+/**
+ * ReadlineTest.java
+ *
+ * This class shows the usage of the readline wrapper. It will read lines
+ * from standard input using the GNU-Readline library. You can use the
+ * standard line editing keys. You can also define application specific
+ * keys. Put this into your ~/.inputrc (or into whatever file $INPUTRC
+ * points to) and see what happens if you press function keys F1 to F3:
+ * <pre>
+ *$if ReadlineTest
+ *"\e[11~": "linux is great"
+ *"\e[12~": "jikes is cool"
+ *"\e[13~": "javac is slow"
+ *$endif
+ *</pre>
+ *
+ * If one argument is given to ReadlineTest, a private initialization file
+ * is read. If a second argument is given, the appropriate library is
+ * loaded.
+ *
+ * @author $Author: Bablokb $
+ * @version $Revision: 1.17 $
+ */
+
+public class ReadlineTest {
+
+ public ReadlineTest() {
+
+ }
+
+ /**
+ Main entry point. The first argument can be a filename with an
+ application initialization file.
+ */
+
+ public static void main(String[] args) {
+ String line;
+
+ // Readline.setThrowExceptionOnUnsupportedMethod(true);
+
+ if (args.length > 1)
+ Readline.load(ReadlineLibrary.byName(args[1]));
+ else
+ Readline.load(ReadlineLibrary.GnuReadline);
+
+ System.out.println("initializing Readline...");
+ Readline.initReadline("ReadLineTest"); // init, set app name, read inputrc
+ System.out.println("... done");
+
+ try {
+ if (args.length > 0)
+ Readline.readInitFile(args[0]); // read private inputrc
+ } catch (IOException e) { // this deletes any initialization
+ System.out.println(e.toString()); // from /etc/inputrc and ~/.inputrc
+ System.exit(0);
+ }
+
+ // read history file, if available
+
+ File history = new File(".rltest_history");
+ try {
+ if (history.exists())
+ Readline.readHistoryFile(history.getName());
+ } catch (Exception e) {
+ System.err.println("Error reading history file!");
+ }
+
+ // define some additional function keys
+
+ Readline.parseAndBind("\"\\e[18~\": \"Function key F7\"");
+ Readline.parseAndBind("\"\\e[19~\": \"Function key F8\"");
+
+ // Set word break characters
+ try {
+ Readline.setWordBreakCharacters(" \t;");
+ }
+ catch (UnsupportedEncodingException enc) {
+ System.err.println("Could not set word break characters");
+ System.exit(0);
+ }
+
+ // set test completer
+
+ Readline.setCompleter(new TestCompleter());
+
+ // main input loop
+
+ while (true) {
+ try {
+ line = Readline.readline("linux> ");
+ if (line == null)
+ System.out.println("no input");
+ else
+ System.out.println("line = >" + line + "<");
+ } catch (UnsupportedEncodingException enc) {
+ System.err.println("caught UnsupportedEncodingException");
+ break;
+ } catch (IOException eof) {
+ break;
+ }
+ }
+ try {
+ Readline.writeHistoryFile(history.getName());
+ } catch (Exception e) {
+ System.err.println("Error writing history file!");
+ }
+ System.out.println();
+ Readline.cleanup();
+ System.exit(0);
+ }
+
+}
diff --git a/src/test/TestCompleter.java b/src/test/TestCompleter.java
new file mode 100644
index 0000000..9642404
--- /dev/null
+++ b/src/test/TestCompleter.java
@@ -0,0 +1,55 @@
+/**************************************************************************
+/* TestCompleter.java -- Sample custom completer
+/*
+/* Java Wrapper Copyright (c) 1998-2001 by Bernhard Bablok (mail at bablokb.de)
+/*
+/* This sample program is placed into the public domain and can be
+/* used or modified without any restriction.
+/*
+/* 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.
+/**************************************************************************/
+
+
+package test;
+import org.gnu.readline.*;
+
+/**
+ * This class is a sample custom completer. If you press the TAB-key at
+ * the readline prompt, you will see the two possible completions ("Linux"
+ * and "Tux"). Once you have entered a "L" or a "T", you will only see
+ * the respective single possible completion. In any other case, null is
+ * returned to signal that no (more) completions are available.
+ *
+ * @author $Author: Bablokb $
+ * @version $Revision: 1.1 $
+ */
+
+
+public class TestCompleter implements ReadlineCompleter {
+
+
+ /**
+ Default constructor.
+ */
+
+ public TestCompleter () {
+ }
+
+
+ /**
+ Return possible completion. Implements org.gnu.readline.ReadlineCompleter.
+ */
+
+ public String completer (String t, int s) {
+ if (s == 0) {
+ if (t.equals("") || t.equals("L"))
+ return "Linux";
+ if (t.equals("T"))
+ return "Tux";
+ } else if (s == 1 && t.equals(""))
+ return "Tux";
+ return null;
+ }
+}
diff --git a/src/test/tinputrc b/src/test/tinputrc
new file mode 100644
index 0000000..1a97a76
--- /dev/null
+++ b/src/test/tinputrc
@@ -0,0 +1,5 @@
+$if ReadlineTest
+"\e[14~": "Function key F4"
+"\e[15~": "Function key F5"
+"\e[17~": "Function key F6"
+$endif
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/libreadline-java.git
More information about the pkg-java-commits
mailing list