Thread: [tcljava-dev] PATCH: Jacl
Brought to you by:
mdejong
From: Tom P. <tpo...@ny...> - 2002-08-04 20:06:51
Attachments:
jacl.patch
|
Here are some patches to Jacl, some of these patch are the same as the ones I posted on 6/30/2002. 1. Unified jaclsh/wisk startup, checks $0 to determine if starting jaclsh or wisk. To use this patch, place swank.jar in the same install directory as jacl.jar and tcljava.jar, and 'ln -s jaclsh wisk'. 2. jaclsh: runs 'tty(1)', and checks output if running on a tty device. If so, set 'jacl.tty' property so that the Jacl interpreter can use the appropriate Channel flush behavior. 3. jaclsh: sets 'jacl.tcllibpath' property so that init.tcl can add the installed lib path to auto_path. 4. Interp.java: check jacl.tty property, set interp isTty field. Flush all open channels when exiting. Makes allowExceptions() method public for use by Swank. 5. Shell.java: add processing of ~/.jaclshrc on shell startup, add support for custom tcl_prompt (per Shawn Boyce's earlier patch). 6. StdChannel.java: flush output on write if channel is stderr, or if channel is stdout and connected to a tty device. 7. init.tcl: add contents of system property jacl.tcllibpath to auto_path. 8. TCL.java: change scope of OK to public, for use by Swank. -- Tom Poindexter tpo...@ny... http://www.nyx.net/~tpoindex/ |
From: Mo D. <md...@un...> - 2003-03-13 22:33:00
|
On Sun, 4 Aug 2002 14:06:28 -0600 Tom Poindexter <tpo...@ny...> wrote: ... > 8. TCL.java: change scope of OK to public, for use by Swank. I still don't get why folks keep asking for this change. The TCL.OK value should not be needed outside the Jacl package. ... So, after a bit of poking around it seems that Shell.java should not even be calling updateReturnInfo() or checking to see if the value is TCL.OK since this is already taken care of in interp.eval(). I just checked the following into the CVS, it removes the refs to TCL.OK. Other shells that do the same, like Swank should make this change too. 2003-03-13 Mo DeJong <md...@us...> * extras/GuiShell/GuiShell.java (processCommand): Remove call to interp.updateReturnInfo() and check for TCL.OK. This is already handled by the interp.eval() method. * src/jacl/tcl/lang/Shell.java (processEvent): Remove call to interp.updateReturnInfo() and check for TCL.OK. This is already handled by the interp.eval() method. Index: extras/GuiShell/GuiShell.java =================================================================== RCS file: /cvsroot/tcljava/tcljava/extras/GuiShell/GuiShell.java,v retrieving revision 1.1 diff -u -r1.1 GuiShell.java --- extras/GuiShell/GuiShell.java 8 May 1999 05:19:00 -0000 1.1 +++ extras/GuiShell/GuiShell.java 13 Mar 2003 22:26:05 -0000 @@ -225,16 +225,7 @@ } else { TclException e = evt.evalException; int code = e.getCompletionCode(); - - check_code: { - if (code == TCL.RETURN) { - code = interp.updateReturnInfo(); - if (code == TCL.OK) { - break check_code; - } - } - - switch (code) { + switch (code) { case TCL.ERROR: append(interp.getResult().toString()); append("\n"); @@ -247,7 +238,6 @@ break; default: append("command returned bad code: " + code + "\n"); - } } } Index: src/jacl/tcl/lang/Shell.java =================================================================== RCS file: /cvsroot/tcljava/tcljava/src/jacl/tcl/lang/Shell.java,v retrieving revision 1.12 diff -u -r1.12 Shell.java --- src/jacl/tcl/lang/Shell.java 8 Mar 2003 03:42:44 -0000 1.12 +++ src/jacl/tcl/lang/Shell.java 13 Mar 2003 22:26:07 -0000 @@ -322,16 +322,7 @@ } int code = e.getCompletionCode(); - - check_code: { - if (code == TCL.RETURN) { - code = interp.updateReturnInfo(); - if (code == TCL.OK) { // FIXME : TCL.OK not accessable outside!! - break check_code; - } - } - - switch (code) { + switch (code) { case TCL.ERROR: // This really sucks. The getMessage() call on // a TclException will not always return a msg. @@ -346,7 +337,6 @@ break; default: putLine(err, "command returned bad code: " + code); - } } } finally { commandObj.release(); |
From: Mo D. <md...@un...> - 2003-03-13 22:37:21
|
On Sun, 4 Aug 2002 14:06:28 -0600 Tom Poindexter <tpo...@ny...> wrote: > Here are some patches to Jacl > 3. jaclsh: sets 'jacl.tcllibpath' property so that init.tcl can add the > installed lib path to auto_path. Tom, could you explain why this patch is needed, in ChangeLog format? --- tcljava/src/jacl/tcl/lang/library/init.tcl Sat May 5 16:38:13 2001 +++ tcljava.tp/src/jacl/tcl/lang/library/init.tcl Fri Jul 12 14:28:19 2002 @@ -34,6 +34,12 @@ # } #} +# include jacl/tcljava library path if passed as a system property + +if {[info exists env(jacl.tcllibpath)]} { + lappend auto_path $env(jacl.tcllibpath) +} + if {[lsearch -exact $auto_path [info library]] < 0} { lappend auto_path [info library] } cheers Mo |
From: Tom P. <tpo...@ny...> - 2003-03-14 04:28:50
|
On Thu, Mar 13, 2003 at 02:35:48PM -0800, Mo DeJong wrote: > On Sun, 4 Aug 2002 14:06:28 -0600 > Tom Poindexter <tpo...@ny...> wrote: > > ... > > > 8. TCL.java: change scope of OK to public, for use by Swank. > > I still don't get why folks keep asking for this change. The TCL.OK > value should not be needed outside the Jacl package. > Well, I understand the design principles involved, but for me, it boils down to a choice: being right, or running Swank. I'd rather run Swank. Also required is the patch to src/jacl/tcl/lang/Interp.java, making allowExceptions() public, also used by Swank. I think Swank is too important NOT to make run 'out of the box' with Jacl. Bruce, perhaps you can update us all on any Swank changes that we might be so lucky to see in the near term? Bruce and Mo - perhaps there is another resolution that amiable to all? I confess that I haven't studied Swank internals much, so I can't make suggestions at this point. Here are the few 'trouble' spots I see: TCL.OK: BindCmd.java: return TCL.OK; BindCmd.java: return TCL.OK; SwkCell.java: return TCL.OK; SwkTableModel.java: return TCL.OK; allowExceptions(): BindCmd.java: interp.allowExceptions(); BindCmd.java: interp.allowExceptions(); SwkTableModel.java: interp.allowExceptions(); Mo, *thanks* for all of your hard work in the new IO package, etc. Jacl is certainly due for a release to get it on the minds of users again. There are a few things I been looking at since your announcement, and it boils done to one bug and several convenience factors. First, the bug that I see. This has to to with my Hyde package, still not generally released because I never found a good work around for the binary file IO problem (see my message to the list on 2002-07-24.) It looks like the binary-ness for fconfigure is working to expectation now. The remaining problem seems to be in the actual 'binary' command. Here's some test code: ---- cut here ----------------------------------------------------------------- package require java puts "system encoding is $env(file.encoding)" array set cacheCode [list multtwoCmd [binary format H* cafebabe0000002e000f0a0003000c07000d07000e0100063c696e69743e010003282956010004436f646501000f4c696e654e756d6265725461626c650100076d756c7474776f010005284949294901000a536f7572636546696c6501000f6d756c7474776f436d642e6a6176610c0004000501000f687964652f6d756c7474776f436d640100106a6176612f6c616e672f4f626a656374002100020003000000000002000100040005000100060000001d00010001000000052ab70001b100000001000700000006000100000002000900080009000100060000002200020003000000061a1b683d1cac0000000100070000000a000200000008000400090001000a00000002000b]] set byteCode $cacheCode(multtwoCmd) set defobj [java::defineclass $byteCode] if {[string equal $defobj [java::null]]} { puts "failed defineclass" } else { proc multtwo {a b} {return [java::call hyde.multtwoCmd multtwo $a $b]} puts "int result: multtwo 4 11 = [multtwo 4 11]" } ---- cut here ----------------------------------------------------------------- This bit of code is the basis for my Hyde package. Compile a class on the fly, read the byte codes back in, save in a cache (a Tcl string converted back to binary), use the java::defineclass to give it to the JVM, then a little extra glue to make it look like a Tcl procedure. Here's the code as it looks with hyde: hyde::jproc int multtwo {int x int y} { int result; result = x * y; return result; } puts stderr "int result: multtwo 4 11 = [multtwo 4 11]" To demostrate the bug, try running: $ LANG=en_US jaclsh testbinary.tcl system encoding is ISO-8859-1 int result: multtwo 4 11 = 44 $ LANG=en_US.iso885915 jaclsh testbinary.tcl system encoding is ISO-8859-15 failed defineclass I put some debugging code in src/tcljava/tcl/lang/JavaDefineClassCmd.java: line 47: if (argv.length != 2) { throw new TclNumArgsException(interp, 1, argv, "classbytes"); } classData = argv[1].toString().getBytes(); // print out the bytes codes as ints for (int i = 0; i < classData.length; i++) { Byte b = new Byte(classData[i]); System.out.print( b.intValue() ); System.out.print(" "); if ((i % 16) == 0 && i > 0) { System.out.println(""); } } tclClassLoader = new TclClassLoader(interp, null); result = tclClassLoader.defineClass(null, classData); It turns out the with the LANG=en_US.iso885915, the fourth byte in the class 'cafebabe' signature gets corrupted. If the class file was longer, there would probably be additional mangling. With LANG=en_US, the first 16 bytes are: -54 -2 -70 -66 0 0 0 46 0 15 10 0 3 0 12 7 0 With LANG=en_US.iso885915: -54 -2 -70 63 0 0 0 46 0 15 10 0 3 0 12 7 0 To note, the LANG=en_US.iso885915 was set on some Linux machine, for some version of RedHat. I shorten it to 'en_US' in the /etc/sysconfig/i18n file. Perhaps there is some magic to coerce the bytes to be in the right order with the 'encoding' command, but I haven't found it yet. Ok, on to the nice to haves, it boils down to two patches and a wishlist. The first patch is to jaclsh.in. My version adds the following: -the ability to use some shell parameters set outside the shell -run jaclsh or wisk, by checking the $0 variable, and adding the swank.jar to CLASSPATH and using the correct Shell class. -set a JACL_LIBRARY path to use as the library. -use an alternate JDK/JRE than the one Jacl was built with. -pass additional -D properties to the JVM. The companion patch is to init.tcl to add the JACL_LIBRARY to auto_path. My shell script does several things I find invaluable, the first and foremost is using alternate JDK and Jacl flag settings. I'm doing a lot of EJB testing with Jacl. Running IBM WebSphere is happiest when using the IBM JDK. I also need to pass other -Dxx=yy properties to make Jacl connect as an EJB client, e.g.: # run test script under WebSphere JAVA_HOME=$WAS_HOME/java CLASSPATH=<way long class path omitted> WAS_PROPS="-Dws.ext.dirs=$WAS_HOME/classes:$WAS_HOME/lib/ext:$WAS_HOME/lib:$WAS_ HOME/web/help:$WAS_HOME/properties:$DBDRIVER_PATH:$WAS_USER_DIRS -Dserver.root=$ WAS_HOME" export JACL_FLAGS="-ms5m -mx22m" export JACL_PROPS="$WAS_PROPS" jaclsh blah.tcl My patch file, which also includes the TCL.OK and allowExceptions() patches, is below. Ok, and now for my wish list, three things: 1. fileevent, 2. lset, 3. jacllib. Adding fileevent might be ugly until Jacl is fully converted to use 1.4's NIO package. Lset would be nice, keeping in pace with Tcl 8.4.2. 'Jacllib' should be able to steal much of the same code has tcllib, at least the code that isn't doing socket things with fileevent. I'm also looking for a home for my hyde pacakge, so I have ulterior motives. I might be willing to invest some time to put together some code. My current patch: --- ../tcljava.cvs/jaclsh.in 2002-07-23 09:07:17.000000000 -0600 +++ jaclsh.in 2003-03-12 13:20:08.000000000 -0700 @@ -11,6 +11,13 @@ # Copyright (c) 1998, 1999, 2000 Moses DeJong # All Rights Reserved, see license.terms for license information. +# User environment variables that affect this script: +# JAVA_HOME path to java home, in order to use alternate jvm +# CLASSPATH additional classpaths +# JACL_LIBRARY path to package library dir, defaults to Jacl jar library dir +# JACL_FLAGS java jvm flags for jacl +# JACL_PROPS extra -Dxxx=yyy properties to pass to jvm + # Install prefix for jacl package, defaults to /usr/local prefix=@prefix@ @@ -21,21 +28,43 @@ # includes the .jar files and any .tcl files XP_TCLJAVA_INSTALL_DIR=${prefix}/lib/tcljava${TCLJAVA_VERSION} +# Directory where swank jar lives +XP_SWANK_INSTALL_DIR=${XP_TCLJAVA_INSTALL_DIR} + +# Set jacl.tcllibpath from JACL_LIBRARY or default +JACL_LIBPATH="-Djacl.tcllibpath=${JACL_LIBRARY:-$XP_TCLJAVA_INSTALL_DIR}" + # Add the .jar library files to the CLASSPATH -JACL_CLASSPATH=@JAVA_CLASSPATH@:${XP_TCLJAVA_INSTALL_DIR}/tcljava.jar:${XP_TCLJAVA_INSTALL_DIR}/jacl.jar: +# Check if running jaclsh or wisk, use the corresponding shell and classpath +if [ `basename $0` = "wisk" ] ; then + JACL_SHELL=tcl.lang.SwkShell + JACL_CLASSPATH=@JAVA_CLASSPATH@:${XP_SWANK_INSTALL_DIR}/swank.jar:${XP_TCLJAVA_INSTALL_DIR}/tcljava.jar:${XP_TCLJAVA_INSTALL_DIR}/jacl.jar +else + JACL_SHELL=tcl.lang.Shell + JACL_CLASSPATH=@JAVA_CLASSPATH@:${XP_TCLJAVA_INSTALL_DIR}/tcljava.jar:${XP_TCLJAVA_INSTALL_DIR}/jacl.jar +fi + # Fully qualified path name of JVM executable -JAVA=@JAVA@ +if [ "$JAVA_HOME" -a -x $JAVA_HOME/bin/java ] ; then + JAVA=$JAVA_HOME/bin/java +else + JAVA=@JAVA@ +fi + # The arguments to the JAVA command -JAVA_FLAGS="@JAVA_FLAGS@" +DEFAULT_JACL_FLAGS="@JAVA_FLAGS@" +JACL_FLAGS="${JACL_FLAGS:-$DEFAULT_JACL_FLAGS}" # Run java with the args passed in from the calling environment # We must set the CLASSPATH env var instead of using the -classpath # argument because jacl might want to exec a program that also # depends on the CLASSPATH setting and Java can not export env vars -CLASSPATH=${JACL_CLASSPATH}:${CLASSPATH} +CLASSPATH=${JACL_CLASSPATH}${CLASSPATH:+:${CLASSPATH}} export CLASSPATH -exec ${JAVA} ${JAVA_FLAGS} tcl.lang.Shell ${1+"$@"} +# Allow other user specified properties to be passed via JACL_PROPS env variable + +exec ${JAVA} ${JACL_FLAGS} ${JACL_LIBPATH} ${JACL_PROPS} ${JACL_SHELL} ${1+"$@"} --- ../tcljava.cvs/src/tcljava/tcl/lang/TCL.java 2002-07-23 09:07:17.000000000 -0600 +++ src/tcljava/tcl/lang/TCL.java 2003-03-12 11:47:01.000000000 -0700 @@ -59,7 +59,7 @@ // the completion code TCL.OK. If the desired completion code is TCL.OK, no // exception should be thrown. -static final int OK = 0; +public static final int OK = 0; // The following value is used by the Interp::commandComplete(). It's used // to report that a script is not complete. --- ../tcljava.cvs/src/jacl/tcl/lang/Interp.java 2003-03-10 16:35:39.000000000 -0700 +++ src/jacl/tcl/lang/Interp.java 2003-03-12 11:46:31.000000000 -0700 @@ -3749,7 +3749,7 @@ *---------------------------------------------------------------------- */ -void +public void allowExceptions() { evalFlags |= Parser.TCL_ALLOW_EXCEPTIONS; --- ../tcljava.cvs/src/jacl/tcl/lang/library/init.tcl 2002-07-23 09:07:17.000000000 -0600 +++ src/jacl/tcl/lang/library/init.tcl 2003-03-12 12:04:08.000000000 -0700 @@ -34,6 +34,12 @@ # } #} +# include jacl/tcljava library path if passed as a system property + +if {[info exists env(jacl.tcllibpath)]} { + lappend auto_path $env(jacl.tcllibpath) +} + if {[lsearch -exact $auto_path [info library]] < 0} { lappend auto_path [info library] } -- Tom Poindexter tpo...@ny... http://www.nyx.net/~tpoindex/ |
From: Mo D. <md...@un...> - 2003-04-14 20:14:54
|
On Thu, 13 Mar 2003 21:28:14 -0700 Tom Poindexter <tpo...@ny...> wrote: ... > Mo, *thanks* for all of your hard work in the new IO package, etc. Jacl is > certainly due for a release to get it on the minds of users again. > > There are a few things I been looking at since your announcement, and it boils > done to one bug and several convenience factors. First, the bug that I see. > > This has to to with my Hyde package, still not generally released because I > never found a good work around for the binary file IO problem This problem was fixed by the CVS checkin on 2003-03-18. The fix will be included in the 1.3.1 release. > Ok, on to the nice to haves, it boils down to two patches and a wishlist. > The first patch is to jaclsh.in. My version adds the following: > -the ability to use some shell parameters set outside the shell > -run jaclsh or wisk, by checking the $0 variable, and adding the > swank.jar to CLASSPATH and using the correct Shell class. > -set a JACL_LIBRARY path to use as the library. > -use an alternate JDK/JRE than the one Jacl was built with. > -pass additional -D properties to the JVM. Well, I would rather not try to cram every possible option into the existing jaclsh script. It is provided to get folks "up and running" quickly. No way am I going to add code to launch in multiple JDK/JRE envs. As far as the other options go, can't you just edit the jaclsh script or create your own script to launch with all of these options? > My patch file, which also includes the TCL.OK and allowExceptions() patches, > is below. I have been meaning to ask you to stop doing that. Having to filter out these patches that I have already rejected just makes it harder to evaluate what change you are actually suggesting. > Ok, and now for my wish list, three things: 1. fileevent, 2. lset, 3. jacllib. > > Adding fileevent might be ugly until Jacl is fully converted to use 1.4's > NIO package. Lset would be nice, keeping in pace with Tcl 8.4.2. > 'Jacllib' should be able to steal much of the same code has tcllib, at least > the code that isn't doing socket things with fileevent. I'm also looking for > a home for my hyde pacakge, so I have ulterior motives. I might be willing > to invest some time to put together some code. Someone has to sit down and write the code. The best way to get these wishes implemented is to sit down and start implementing them. The NIO package could make it easier to deal with non-blocking IO, but there is lot of Tcl C code to port even if you just use a thread that blocks. cheers Mo DeJong |
From: Tom P. <tpo...@ny...> - 2003-03-14 16:12:04
|
On Thu, Mar 13, 2003 at 02:39:54PM -0800, Mo DeJong wrote: > On Sun, 4 Aug 2002 14:06:28 -0600 > Tom Poindexter <tpo...@ny...> wrote: > > > Here are some patches to Jacl > > > 3. jaclsh: sets 'jacl.tcllibpath' property so that init.tcl can add the > > installed lib path to auto_path. > > Tom, could you explain why this patch is needed, in ChangeLog format? Without it, Jacl doesn't have a standard directory from which to load external packages, e.g., without patch: % set auto_path resource:/tcl/lang/library with: % set auto_path resource:/tcl/lang/library /usr/local/lib/tcljava1.3.0 This is sort of like TCL_LIBRARY in C based Tcl, but doesn't allow overriding init.tcl as easily. I want a standard place to put Jacl packages like my Hyde and proposed jacllib without requiring each Jacl script lappend'ing to auto_path. In ChangeLog format: * src/jacl/tcl/lang/library/init.tcl: Append to auto_path the value of property jacl.tcllibpath. This allows Jacl to have a standard library directory outside of the internal jar resources. -- Tom Poindexter tpo...@ny... http://www.nyx.net/~tpoindex/ |
From: Mo D. <md...@un...> - 2003-04-14 19:53:50
|
On Fri, 14 Mar 2003 09:11:30 -0700 Tom Poindexter <tpo...@ny...> wrote: > > > Here are some patches to Jacl > > > > > 3. jaclsh: sets 'jacl.tcllibpath' property so that init.tcl can add the > > > installed lib path to auto_path. Just an FYI here, but I rejected this 'jacl.tcllibpath' patch because the TCLLIBPATH property already provides this functionality. Snip from current init.tcl: if {[info exists env(TCLLIBPATH)]} { lappend auto_path $env(TCLLIBPATH) } cheers Mo |