Search the web
Sign In
New User? Sign Up
tcljava
? Already a member? Sign in to Yahoo!

Yahoo! Groups Tips

Did you know...
Want to share photos of your group with the world? Add a group photo to Flickr.

Best of Y! Groups

   Check them out and nominate your group.
Having problems with message search? Fill out this form to ensure your group is one of the first to be migrated to the new message search system.

Messages

  Messages Help
Advanced
Messages 1 - 30 of 1276   Newest  |  < Newer  |  Older >  |  Oldest
Messages: Show Message Summaries   (Group by Topic) Sort by Date v  
#30 From: Moses DeJong <dejong@...>
Date: Tue Jan 5, 1999 8:53 pm
Subject: [Tcl Java] Re: BUG: Jacl1.1a1 Input handling on Windows...
dejong@...
Send Email Send Email
 
Your patch looks like a good start. To really fix things we need to have a
complete implementation of the fconfigure command. I am planning on
looking into this once I get more free time.

Mo DeJong
dejong@...
gimme multimedia group

On Mon, 4 Jan 1999, Christian Krone wrote:

> Hello,
>
> first I wrote:
> > - When reading from a file, the handling of a backslash at the end of a
> >   line is wrong. (Only on Windows and only from a file!)
> >   An example session follows:
> >   % exec type test.jacl
> >   puts \
> >   -nonewline Hello
> >   % source test.jacl
> >   can not find channel named " -nonewline"
> >   % puts \
> >   -nonewline Hello
> >   Hello% exit
>
> Then Moses DeJong answered:
> > Yes, this is a known problem. Only Unix style input is currently
> > accepted (\n at end of line). This problem also makes the Mac port
> > of jacl very hard to use. This is something that needs to be fixed
> > but I have not had time start on it yet. I did some funky junk
> > with the exec command to get it working under windows and I think it
> > does the \r\n conversion correctly but I would not bet my life on that.
>
> I don't know, if I hit all places, but with the attached patch applied to
> .../jacl1.1a1/src/jacl/tcl/lang/Interp.java all my tcl files run smoothly.
>
> I hope this helps, Krischan
> --
> Christian Krone, SQL Datenbanksysteme GmbH
> Mail mailto:krischan@...
>
> P.S. If you receive this mail three times (due to my full disk), sorry for
that.

----------------------------------------------------------------
The TclJava mailing list is sponsored by WebNet Technologies.
To subscribe:    send mail to TclJava-request@...
                  with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to TclJava-request@...
                  with the word UNSUBSCRIBE as the subject.
To send to the list, send email to 'TclJava@...'.
A list archive is at: http://www.findmail.com/listsaver/tcldallas/

#29 From: Philip Chu <philipchu@...>
Date: Tue Jan 5, 1999 7:50 pm
Subject: [Tcl Java] Re: modal Swing dialogs
philipchu@...
Send Email Send Email
 
By the way, I ran the second script below (Swing frame with tcl callback
that brings up a modal dialog) with Jacl 1.1a on the same platform and got
the same result - when invoking the callback, the modal dialog froze after
coming up.

However, what I neglected to state explicitly in the original report was
that changing the modal dialog to a non-modal dialog or another frame seems
to work, both in TclBlend and Jacl. Is this related to reported problems
about threading with TclBlend? Actually, I expect bringing up non-modal
dialogs or new frames would increase the number of threads, if anything.
Also, some of my coworkers told me that a combination of Swing and Tk is
not expected to work, but there appear to be at least a few exceptions to
that - are there any known reasons why Swing should not work with Tcl/Tk?


At 01:03 AM 12/29/98 -0800, Philip Chu wrote:
>I'm having problems using modal Swing dialogs with TclBlend 1.1a, JDK 1.2
>on NT.
>
>The first script below creates a tk button that pops up a Swing confirm
>dialog. The confirm dialog comes up OK, but if you drag it over the tk
>button, the latter does not repaint.
>
>A more serious problem is shown in the second script below, which creates a
>Swing frame and button, which has a tcl callback script that brings up a
>Swing confirm dialog. In this case, the whole app freezes when the confirm
>dialog pops up.
>
># test swing modal dialogs
>package require java
>set frame [java::new javax.swing.JFrame]
>button .b -text "Test" -command "java::call javax.swing.JOptionPane
>showConfirmDialog $frame Message"
>pack .b
>
># show JDialog from JFrame
>package require java
>set frame [java::new javax.swing.JFrame]
>set pane [$frame getContentPane]
>set button [java::new javax.swing.JButton "hello"]
>$pane add $button
>java::bind $button java.awt.event.ActionListener.actionPerformed \
>"java::call javax.swing.JOptionPane showConfirmDialog $frame hello"
>$frame setSize 200 200
>$frame show
>
>
>--
>Phil Chu
>philipchu@... http://www.technicat.com/
>
>----------------------------------------------------------------
>The TclJava mailing list is sponsored by WebNet Technologies.
>To subscribe:    send mail to TclJava-request@...
>                 with the word SUBSCRIBE as the subject.
>To unsubscribe:  send mail to TclJava-request@...
>                 with the word UNSUBSCRIBE as the subject.
>To send to the list, send email to 'TclJava@...'.
>A list archive is at: http://www.findmail.com/listsaver/tcldallas/
>
--
Phil Chu
philipchu@... http://www.technicat.com/

----------------------------------------------------------------
The TclJava mailing list is sponsored by WebNet Technologies.
To subscribe:    send mail to TclJava-request@...
                  with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to TclJava-request@...
                  with the word UNSUBSCRIBE as the subject.
To send to the list, send email to 'TclJava@...'.
A list archive is at: http://www.findmail.com/listsaver/tcldallas/

#28 From: Christian Krone <krischan@...>
Date: Mon Jan 4, 1999 10:09 am
Subject: [Tcl Java] Re: BUG: Jacl1.1a1 Input handling on Windows...
krischan@...
Send Email Send Email
 
Hello,

first I wrote:
> - When reading from a file, the handling of a backslash at the end of a
>   line is wrong. (Only on Windows and only from a file!)
>   An example session follows:
>   % exec type test.jacl
>   puts \
>   -nonewline Hello
>   % source test.jacl
>   can not find channel named " -nonewline"
>   % puts \
>   -nonewline Hello
>   Hello% exit

Then Moses DeJong answered:
> Yes, this is a known problem. Only Unix style input is currently
> accepted (\n at end of line). This problem also makes the Mac port
> of jacl very hard to use. This is something that needs to be fixed
> but I have not had time start on it yet. I did some funky junk
> with the exec command to get it working under windows and I think it
> does the \r\n conversion correctly but I would not bet my life on that.

I don't know, if I hit all places, but with the attached patch applied to
.../jacl1.1a1/src/jacl/tcl/lang/Interp.java all my tcl files run smoothly.

I hope this helps, Krischan
--
Christian Krone, SQL Datenbanksysteme GmbH
Mail mailto:krischan@...

P.S. If you receive this mail three times (due to my full disk), sorry for that.
*** Interp.java.org Mon Dec 28 13:33:25 1998
--- Interp.java Sat Jan  2 13:33:16 1999
***************
*** 1965,1971 ****
       try {
  	 byte charArray[] = new byte[fs.available()];
  	 fs.read(charArray);
!  return new String(charArray);
       } catch (IOException e) {
  	 return null;
       } finally {
--- 1964,1998 ----
       try {
  	 byte charArray[] = new byte[fs.available()];
  	 fs.read(charArray);
!
!  String sep = System.getProperty("line.separator");
!  if (sep.equals("\n")) {
! 	    return new String(charArray);
!  }
!
!  /*
! 	 * If we come to this place, a translation from "\r\n" (on Windows)
! 	 * or "\r" (on Mac?) into "\n" is needed.
! 	 */
!
!  int sepLength = sep.length();
!  String str = new String(charArray);
!  char tmpArray[] = new char[charArray.length];
!  int srcPos = 0;
!  int dstPos = 0;
!  int srcEnd;
!  while ((srcEnd = str.indexOf(sep, srcPos)) >= 0) {
! 	    str.getChars(srcPos, srcEnd, tmpArray, dstPos);
! 	    dstPos += srcEnd-srcPos;
! 	    tmpArray[dstPos++] = '\n';
! 	    srcPos = srcEnd+sepLength;
!  }
!  srcEnd = str.length();
!  str.getChars(srcPos, srcEnd, tmpArray, dstPos);
!  dstPos += srcEnd-srcPos;
!
!  return new String(tmpArray, 0, dstPos);
!
       } catch (IOException e) {
  	 return null;
       } finally {

#27 From: krischan@...
Date: Mon Jan 4, 1999 9:57 am
Subject: [Tcl Java] Unidentified subject!
krischan@...
Send Email Send Email
 
----------------------------------------------------------------
The TclJava mailing list is sponsored by WebNet Technologies.
To subscribe:    send mail to TclJava-request@...
                  with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to TclJava-request@...
                  with the word UNSUBSCRIBE as the subject.
To send to the list, send email to 'TclJava@...'.
A list archive is at: http://www.findmail.com/listsaver/tcldallas/

#26 From: krischan@...
Date: Mon Jan 4, 1999 10:02 am
Subject: [Tcl Java] Unidentified subject!
krischan@...
Send Email Send Email
 
----------------------------------------------------------------
The TclJava mailing list is sponsored by WebNet Technologies.
To subscribe:    send mail to TclJava-request@...
                  with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to TclJava-request@...
                  with the word UNSUBSCRIBE as the subject.
To send to the list, send email to 'TclJava@...'.
A list archive is at: http://www.findmail.com/listsaver/tcldallas/

#25 From: Moses DeJong <dejong@...>
Date: Fri Jan 1, 1999 12:56 am
Subject: [Tcl Java] Re: Tcl Blend 1.1a1 JDK1.1.7 WinNT: Java threads freeze Application?
dejong@...
Send Email Send Email
 
Hi steve.

Three other people have reported bugs like yours so I think this now
counts as a "known problem". If you have the time you might want to
post a small example that shows the freeze you are running into. You
do not have to, but it will make it much easier to find out if changes
to TclBlend fix the problem you are running into. One other thing that
could help is if you could try your program in Jacl and see if it breaks
there too. If you can create an example that freezes in Jacl it is much
easier to track down the problem because multiple threads in Java are
a lot easier to debug then a combo of Tcl + JNI + Java.

later
mo

> I am creating a Java object that draws a graphical chart.  This Java object
> uses a thread
> to update the data on the chart.  The chart comes up fine, but as soon as a
> thread is created the
> application freezes.  Is there a problem with using Java threads?
>
> I can run the Java application stand alone just fine,  but not from tcl
> blend.
>
> Thanks,
>
> Steve

----------------------------------------------------------------
The TclJava mailing list is sponsored by WebNet Technologies.
To subscribe:    send mail to TclJava-request@...
                  with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to TclJava-request@...
                  with the word UNSUBSCRIBE as the subject.
To send to the list, send email to 'TclJava@...'.
A list archive is at: http://www.findmail.com/listsaver/tcldallas/

#24 From: Moses DeJong <dejong@...>
Date: Fri Jan 1, 1999 12:48 am
Subject: [Tcl Java] Re: java::import
dejong@...
Send Email Send Email
 
On Wed, 30 Dec 1998, Christian Krone wrote:

> Hello,
>
> > > over christmas I started to implement java::import
> > I thought about implementing this command but I decided not to
> > because I was not really sure how much help it would be.
>
> Let me cite the Tutorial given at the Tcl/Tk conference, 9/16/98
>   "Tcl and Java Programming: Practice and Pitfalls"
> <cite
href="http://ptolemy.eecs.berkeley.edu/~johnr/tutorials/tcljava98/notes/swing.ht\
ml">
>  The first few line sets a variable to the package path, to save some typing:
>          set swing com.sun.java.swing
>  (Wouldn't it be nice if Tcl Blend could "import" Java packages?)
> </cite>
> This paper was my first contact with TclJava, and I always thought, that
> everybody would like to have java::import.
>
> > > - Is there a chance, that this implementation will become
> > >   part of Jacl and TclBlend?
> > There is always a chance. I guess it depened on how much help
> > this command will be and how much of the system it changes.
> > I really have no problems with changing tons of code but
> > christopher just hates "lots of changes".
>
> There are two small new classes (JavaImport and JavaImportCmd)
> and a really small patch to JavaInvoke (one else part will be modified).
>
> Since every command uses JavaInvoke to convert a classname from String
> into the corresponding class, I found no java::* command which doesn't
> react to java::import.
>
> > There is also an issue of "caching" names and how you will tell is
> > two packages has a class with the exact same name.
>
> JavaImport has a hitCache, so that every class is searched only once.
> The search doesn't stop after a class is found, but walks through all
> imported packages, so that another class with the same name leads to an
> error.

Right, this was impression of the main problem with the java::import
command. Perhaps a "java::import -remove com.myorg.*" would be in opder?

> *But*
> I think, one problem remains (which simply doesn't exist in Java):
> The import directive in Java is effective only during compilation and ends
> at the end of the compilation unit. In TclJava it works during execution,
> and so the "lifetime" is different: The sourcing of any tcl script may
> change the imported packages.
>
> I wonder if it is a good idea to integerate the
> java::import statements into the current namespace.
> If all library scripts only use java::import in their own namespace,
> the global one doesn't get filled with unwanted packages...
> Example: (Assume there exists a com.myorg.Date class...)
>
> File main.tcl:
> java::import com.myorg.*
> # The following will print methods of com.myorg.Date
> puts [java::methods Date]
> source datelib.tcl
> # The following will print methods of com.myorg.Date,
> # if java::import works just for the current namespace,
> # else it will work or fail dependend of the content of datelib.tcl
> puts [java::methods Date]
>
> File datelib.tcl:
> namespace eval datelib {java::import java.util.*}
> proc datelib::test {} {java::new Date} ;# Will find java.util.Date

You hit the nail on the head. The whole namespace thing is a problem in
jacl. I am still not sure if jacl really needs namespaces (people seemed
to be able to code in Tcl 7.X just fine without them). At any rate,
implementing namespaces in jacl might be a little much for this release.

> There is at least one problem with this approach:
> Jacl ignores the namespace command!
> So the java::import command of datelib.tcl will never be executed!
>
>
> *And now to something completely different*

That whole troff to HTML thing is a mess. When Tcl was at Sun they used
a nroff parsing script to generate the HTML for the docs. Once Tcl moved
over to scriptics they no longer had access to these tools. I think the
best approach is to just create the man pages in HTML and forget about
the unix man pages. Windows and Mac people can not read unix man pages
(without a lot of work). Everyone should be able to read HTML.

> Two more questions regarding TclJava documentation:
> - Is the html file in jacl1.1a1/doc/html/TclJava/java.htm the master
>   or is it generated out of a xml/cgi/tcl/troff/whatever file, that isn't
>   part of jacl1.1a1Src.tar.gz?

As long as we could also produce "regular" HTML for the webpages. Are you
interested in doing this? I would be willing to help out as much as I
could but to be honest I am a little more concerned with fixing some of
the bugs in Tcl Blend and Jacl right now.

> - Wouldn't it be a nice idea to convert the html into XML like Dr. Hipp
>   did it for Tcl/Tk (See http://www.hwaci.com/sw/tcldoc)?
>
> Greetings, Krischan
> --
> Christian Krone, SQL Datenbanksysteme GmbH


later
mo

----------------------------------------------------------------
The TclJava mailing list is sponsored by WebNet Technologies.
To subscribe:    send mail to TclJava-request@...
                  with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to TclJava-request@...
                  with the word UNSUBSCRIBE as the subject.
To send to the list, send email to 'TclJava@...'.
A list archive is at: http://www.findmail.com/listsaver/tcldallas/

#23 From: "Eisenreich, Steve" <sje@...>
Date: Wed Dec 30, 1998 3:14 pm
Subject: [Tcl Java] Re: Tcl Blend 1.1a1 JDK1.1.7 WinNT: Java threads freeze Ap plication?
sje@...
Send Email Send Email
 
I am creating a Java object that draws a graphical chart.  This Java object
uses a thread
to update the data on the chart.  The chart comes up fine, but as soon as a
thread is created the
application freezes.  Is there a problem with using Java threads?

I can run the Java application stand alone just fine,  but not from tcl
blend.

Thanks,

Steve

----------------------------------------------------------------
The TclJava mailing list is sponsored by WebNet Technologies.
To subscribe:    send mail to TclJava-request@...
                  with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to TclJava-request@...
                  with the word UNSUBSCRIBE as the subject.
To send to the list, send email to 'TclJava@...'.
A list archive is at: http://www.findmail.com/listsaver/tcldallas/

#22 From: Christian Krone <krischan@...>
Date: Wed Dec 30, 1998 11:32 am
Subject: [Tcl Java] Re: java::import
krischan@...
Send Email Send Email
 
Hello,

> > over christmas I started to implement java::import
> I thought about implementing this command but I decided not to
> because I was not really sure how much help it would be.

Let me cite the Tutorial given at the Tcl/Tk conference, 9/16/98
   "Tcl and Java Programming: Practice and Pitfalls"
<cite
href="http://ptolemy.eecs.berkeley.edu/~johnr/tutorials/tcljava98/notes/swing.ht\
ml">
  The first few line sets a variable to the package path, to save some typing:
          set swing com.sun.java.swing
  (Wouldn't it be nice if Tcl Blend could "import" Java packages?)
</cite>
This paper was my first contact with TclJava, and I always thought, that
everybody would like to have java::import.

> > - Is there a chance, that this implementation will become
> >   part of Jacl and TclBlend?
> There is always a chance. I guess it depened on how much help
> this command will be and how much of the system it changes.
> I really have no problems with changing tons of code but
> christopher just hates "lots of changes".

There are two small new classes (JavaImport and JavaImportCmd)
and a really small patch to JavaInvoke (one else part will be modified).

Since every command uses JavaInvoke to convert a classname from String
into the corresponding class, I found no java::* command which doesn't
react to java::import.

> There is also an issue of "caching" names and how you will tell is
> two packages has a class with the exact same name.

JavaImport has a hitCache, so that every class is searched only once.
The search doesn't stop after a class is found, but walks through all
imported packages, so that another class with the same name leads to an
error.

*But*
I think, one problem remains (which simply doesn't exist in Java):
The import directive in Java is effective only during compilation and ends
at the end of the compilation unit. In TclJava it works during execution,
and so the "lifetime" is different: The sourcing of any tcl script may
change the imported packages.

I wonder if it is a good idea to integerate the
java::import statements into the current namespace.
If all library scripts only use java::import in their own namespace,
the global one doesn't get filled with unwanted packages...
Example: (Assume there exists a com.myorg.Date class...)

File main.tcl:
java::import com.myorg.*
# The following will print methods of com.myorg.Date
puts [java::methods Date]
source datelib.tcl
# The following will print methods of com.myorg.Date,
# if java::import works just for the current namespace,
# else it will work or fail dependend of the content of datelib.tcl
puts [java::methods Date]

File datelib.tcl:
namespace eval datelib {java::import java.util.*}
proc datelib::test {} {java::new Date} ;# Will find java.util.Date

There is at least one problem with this approach:
Jacl ignores the namespace command!
So the java::import command of datelib.tcl will never be executed!


*And now to something completely different*

Two more questions regarding TclJava documentation:
- Is the html file in jacl1.1a1/doc/html/TclJava/java.htm the master
   or is it generated out of a xml/cgi/tcl/troff/whatever file, that isn't
   part of jacl1.1a1Src.tar.gz?
- Wouldn't it be a nice idea to convert the html into XML like Dr. Hipp
   did it for Tcl/Tk (See http://www.hwaci.com/sw/tcldoc)?

Greetings, Krischan
--
Christian Krone, SQL Datenbanksysteme GmbH

----------------------------------------------------------------
The TclJava mailing list is sponsored by WebNet Technologies.
To subscribe:    send mail to TclJava-request@...
                  with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to TclJava-request@...
                  with the word UNSUBSCRIBE as the subject.
To send to the list, send email to 'TclJava@...'.
A list archive is at: http://www.findmail.com/listsaver/tcldallas/

#21 From: Moses DeJong <dejong@...>
Date: Tue Dec 29, 1998 8:41 pm
Subject: [Tcl Java] Re: classpath problem on Windows 98
dejong@...
Send Email Send Email
 
On Tue, 29 Dec 1998, Philip Chu wrote:

> At 02:11 PM 12/28/98 -0600, Moses DeJong wrote:
> >You might be the first person to run tcl blend on windows 98. When you
> >get the "could not find class tcl/lang/Interp" message that means there is
> >something wrong with the CLASSPATH such that the JVM can not find the
> >tclblend.jar file. Try this.
> >
> >%javap tcl.lang.Interp
> >
> >If your CLASSPATH is set correctly you should see the public interface
> >of tcl.lang.Interp printed to your screen. If you get a message like
> >"can't find tcl.lang.Interp" then you need to make sure your CLASSPATH
> >includes the tclblend.jar file.
> >
> >Try that and tell us if it worked.

The "Classpath gets longer" thing is a minor bug that I have already fixed
in my tree. It will not break anything. Did you compile tcl from the
tcl8.0.4 and tclblend1.1a1 source releases or did you use the binary
releases? If you used the binary releases then you might want to try
and compile both tcl and tclblend from the source. Of course this means
you will have to own Visual C++. I remember there was some problem
with using tcl blend on a system that did not have a scriptics registry
key. I do not have access to a windows 98 box so I can not really test
your problem for myself. One other thing you might want to try is to
do the package require java and then run both of these commands from
the tcl shell.

exec javap -classpath $env(CLASSPATH) tcl.lanng.Interp

exec javap -classpath $env(CLASSPATH) tcl.lang.JavaNewCmd

This will make sure that both tclblend.jar and tcljava.jar are getting
found on the CLASSPATH. Email your results back to the list and we will
see what we can do.


> I performed "package require java", got the error, then "javap
> tcl.lang.Interp", and that worked. A subsequent "package require java"
> still didn't work (although each time I invoke it, the CLASSPATH gets longer!)

You will not need to set the CLASSPATH in autoexec.bat.

> Note that I've tried this with and without setting CLASSPATH myself
> explicitly in autoexec.bat.
>
> --
> Phil Chu
> philipchu@... http://www.technicat.com/
>


later
mo

----------------------------------------------------------------
The TclJava mailing list is sponsored by WebNet Technologies.
To subscribe:    send mail to TclJava-request@...
                  with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to TclJava-request@...
                  with the word UNSUBSCRIBE as the subject.
To send to the list, send email to 'TclJava@...'.
A list archive is at: http://www.findmail.com/listsaver/tcldallas/

#20 From: Christian Krone <krischan@...>
Date: Tue Dec 29, 1998 4:30 pm
Subject: [Tcl Java] Re: BUG: Jacl1.1a1 Input handling on Windows...
krischan@...
Send Email Send Email
 
Hello,

> > - During an interactive session of jaclsh the input isn't echoed,
> >   until a newline is entered. I already saw a report of this bug
> >   in clt. It is indeed very strange to type something without echo...
>
> I think this is actually a java bug and not a jacl bug. The report
> I read on this was on a windows system that was not configured for
> us/english output (I think it was french or something). When I run
> jacl on my NT machine it works as expected. If it does not work on
> your machine then try this simple program and see what it prints.
>
> public class echo {
>     public static void main(String[] argv) throws Exception {
>         System.out.println("Please begin typing");
>         while (true) {
>             int avail = System.in.available();
>             if (avail == 0) {
>                 Thread.currentThread().sleep(100);
>             } else {
>                 byte[] buff = new byte[avail];
>                 System.in.read(buff);
>
>                 //echo back what was just typed
>                 System.out.println("-----ECHO BEGIN-----");
>                 System.out.write(buff);
>                 System.out.println("-----ECHO END-----");
>             }
>         }
>     }
> }

I compiled it for JDK1.1.6 on different Windows and Linux systems and
with JDK1.2beta4 on a german Windows and there the echo program has the
expected output (comment is added by me):

Please begin typing
Hallo                  /* <== Characters appeared while I'm typing... */
-----ECHO BEGIN-----
Hallo
-----ECHO END-----

But when I used JDK1.2fcs (a rather new version) on a german and on an
english Windows system, echo worked like this:

Please begin typing
Hallo                  /* <== Characters appeared after hitting Return... */
-----ECHO BEGIN-----
-----ECHO END-----
-----ECHO BEGIN-----

-----ECHO END-----

So it is indeed a problem with Java1.2 on Windows and not with Jacl.
But it doesn't seem to depend on the language of NT.

For me the workaround is to use TclBlend on Windows (it's also faster...)

Thanks, Krischan
--
Christian Krone, SQL Datenbanksysteme GmbH

----------------------------------------------------------------
The TclJava mailing list is sponsored by WebNet Technologies.
To subscribe:    send mail to TclJava-request@...
                  with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to TclJava-request@...
                  with the word UNSUBSCRIBE as the subject.
To send to the list, send email to 'TclJava@...'.
A list archive is at: http://www.findmail.com/listsaver/tcldallas/

#19 From: Philip Chu <philipchu@...>
Date: Tue Dec 29, 1998 9:03 am
Subject: [Tcl Java] modal Swing dialogs
philipchu@...
Send Email Send Email
 
I'm having problems using modal Swing dialogs with TclBlend 1.1a, JDK 1.2
on NT.

The first script below creates a tk button that pops up a Swing confirm
dialog. The confirm dialog comes up OK, but if you drag it over the tk
button, the latter does not repaint.

A more serious problem is shown in the second script below, which creates a
Swing frame and button, which has a tcl callback script that brings up a
Swing confirm dialog. In this case, the whole app freezes when the confirm
dialog pops up.

# test swing modal dialogs
package require java
set frame [java::new javax.swing.JFrame]
button .b -text "Test" -command "java::call javax.swing.JOptionPane
showConfirmDialog $frame Message"
pack .b

# show JDialog from JFrame
package require java
set frame [java::new javax.swing.JFrame]
set pane [$frame getContentPane]
set button [java::new javax.swing.JButton "hello"]
$pane add $button
java::bind $button java.awt.event.ActionListener.actionPerformed \
"java::call javax.swing.JOptionPane showConfirmDialog $frame hello"
$frame setSize 200 200
$frame show


--
Phil Chu
philipchu@... http://www.technicat.com/

----------------------------------------------------------------
The TclJava mailing list is sponsored by WebNet Technologies.
To subscribe:    send mail to TclJava-request@...
                  with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to TclJava-request@...
                  with the word UNSUBSCRIBE as the subject.
To send to the list, send email to 'TclJava@...'.
A list archive is at: http://www.findmail.com/listsaver/tcldallas/

#18 From: Philip Chu <philipchu@...>
Date: Tue Dec 29, 1998 8:52 am
Subject: [Tcl Java] Re: classpath problem on Windows 98
philipchu@...
Send Email Send Email
 
At 02:11 PM 12/28/98 -0600, Moses DeJong wrote:
>You might be the first person to run tcl blend on windows 98. When you
>get the "could not find class tcl/lang/Interp" message that means there is
>something wrong with the CLASSPATH such that the JVM can not find the
>tclblend.jar file. Try this.
>
>%javap tcl.lang.Interp
>
>If your CLASSPATH is set correctly you should see the public interface
>of tcl.lang.Interp printed to your screen. If you get a message like
>"can't find tcl.lang.Interp" then you need to make sure your CLASSPATH
>includes the tclblend.jar file.
>
>Try that and tell us if it worked.

I performed "package require java", got the error, then "javap
tcl.lang.Interp", and that worked. A subsequent "package require java"
still didn't work (although each time I invoke it, the CLASSPATH gets longer!)

Note that I've tried this with and without setting CLASSPATH myself
explicitly in autoexec.bat.

--
Phil Chu
philipchu@... http://www.technicat.com/

----------------------------------------------------------------
The TclJava mailing list is sponsored by WebNet Technologies.
To subscribe:    send mail to TclJava-request@...
                  with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to TclJava-request@...
                  with the word UNSUBSCRIBE as the subject.
To send to the list, send email to 'TclJava@...'.
A list archive is at: http://www.findmail.com/listsaver/tcldallas/

#17 From: Moses DeJong <dejong@...>
Date: Tue Dec 29, 1998 1:46 am
Subject: [Tcl Java] could you provide feedback on a new command?
dejong@...
Send Email Send Email
 
Hello.

I am looking for feedback on the new java::try command that
I am working on. The java::try command is needed because there
is no way to manage multiple exception types in Jacl or Tcl Blend.

Here is the command usage.
   java::try script ?catch exception_pair script? ?finally script?



Lets assume we have a Tcl proc called "bad" that raises an
exceptional condition. We could place a catch around an
invocation of bad to protect the script from errors.

if {[catch {bad} err]} {
     puts "error in procedure bad: $err"
}

If we wanted to do the same thing using the java::try command
we could use the following code.

java::try {
     bad
} catch {TclException err} {
     puts "error in procedure bad: $err"
}



Now lets assume we wanted to handle multiple error conditions.
Suppose we wanted to call a Tcl command that was implemented with
a combination of Tcl and Java commands. For this example we assume
this "jcombo" command already exists in the interpreter. We could
then use the java::try command to manage exceptional conditions
that could be raised while processing the "jcombo" command.


java::try {
     jcombo
} catch {TclException e} {
     puts "a Tcl error occured"
} catch {IOException e} {
     puts "a Java IOException occured"
} catch {NumberFormatException e} {
     puts "a Java NumberFormatException occured"
}




You could also use a finally clause.

java::try {
     set i 1
} finally {
     set j 2
}


A couple of things to note.

1) the return value of the command would be the results of the last
command in the body script or the last command in a catch script but
the results would not be changed by a finally script.


The TclException type would be a "special" type that would be used
to catch all exceptional conditions generated by Tcl. The value of
the variable for a TclException catch block like catch {TclException err}
would be the error condition (just like catch {...} err). If the
catch block is set for a Java Exception like catch {NumberFormatException e}
then the error variable e would be set to java0x? which would be the
reflected Java exception object. This means that you could query the
exception object about its error message of do something and rethrow
the error.

java::try {
     #some java code
} catch {Exception e} {
     puts "caught Java error [$e getMessage]"
     java::throw $e
} catch {TclException e} {
     puts "caught Tcl error $e"
}


Also note that unlike the java try-catch-finally command the special
keyword TclException would not be a subclass of java.lang.Exception
so Tcl exceptions and Java exceptions can be handled differently.



Well, does that raise any red flags with anyone? I think this approach
will give us all the power of the Java's try-catch-finally construct
without losing the Tcl's dynamic scripting ability. Any comments?



thanks a bunch
mo dejong
dejong at cs.umn.edu

----------------------------------------------------------------
The TclJava mailing list is sponsored by WebNet Technologies.
To subscribe:    send mail to TclJava-request@...
                  with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to TclJava-request@...
                  with the word UNSUBSCRIBE as the subject.
To send to the list, send email to 'TclJava@...'.
A list archive is at: http://www.findmail.com/listsaver/tcldallas/

#16 From: Moses DeJong <dejong@...>
Date: Tue Dec 29, 1998 12:33 am
Subject: [Tcl Java] is anyone using the binary releases of jacl or tcl blend?
dejong@...
Send Email Send Email
 
I have been thinking about the binary releases of jacl and tcl blend
for a bit now and I am really starting to think that we should get
rid of them. I am NOT talking about the binary release for Windows
or Mac, just the solaris-binary of Tcl Blend and the binary release
of jacl for unix systems. Here are a couple of reasons I think the
binary release should go.

1) they REALLY make life hard for the developers of jacl and tcl blend
    because a ton of nasty makefile rules need to be kept up to date.

2) the binary only releases do not use ./configure and have no way to
    check for problems with the installed JDK tools.

3) the source releases will install wrapper scripts on unix systems
    so that people can type jaclsh or jtclsh instead of something
    nasty like "java tcl.lang.Shell ...".

4) the source releases come with the regression test that people can
    run by typing "make test". If there is something wrong with the
    JVM or Tcl then these tests should show the problem.

5) the only unix binary for tcl blend we support is for solaris with
    JDK1.1. If people wanted to use the JDK1.2 they would be out of
    luck because the 1.1 binary will not work with 1.2.


I really can not think of any reasons why we should keep the binary
releases. Is there anyone out there that uses the binary releases or
thinks that they should stay? If you think the binary releases should
stay please post your arguments so we know what jacl and tcl blend
users think about this issue.


later
mo dejong
dejong at cs.umn.edu

----------------------------------------------------------------
The TclJava mailing list is sponsored by WebNet Technologies.
To subscribe:    send mail to TclJava-request@...
                  with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to TclJava-request@...
                  with the word UNSUBSCRIBE as the subject.
To send to the list, send email to 'TclJava@...'.
A list archive is at: http://www.findmail.com/listsaver/tcldallas/

#15 From: Moses DeJong <dejong@...>
Date: Tue Dec 29, 1998 12:07 am
Subject: [Tcl Java] ORO inc found.
dejong@...
Send Email Send Email
 
ORO inc went under but the code seems to be back up on this site.

http://www.savarese.org

I don't think this really changes anything for jacl but I have no idea
what the binary license said so I could be wrong. We really should replace
the regexp stuff with a library like the gnu regexp package but I do not
know if there will be time before 1.1 goes final.

gnu regexp stuff should be at.

www.gnu.org/software/java/java.html

later
mo

----------------------------------------------------------------
The TclJava mailing list is sponsored by WebNet Technologies.
To subscribe:    send mail to TclJava-request@...
                  with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to TclJava-request@...
                  with the word UNSUBSCRIBE as the subject.
To send to the list, send email to 'TclJava@...'.
A list archive is at: http://www.findmail.com/listsaver/tcldallas/

#14 From: Moses DeJong <dejong@...>
Date: Mon Dec 28, 1998 11:02 pm
Subject: [Tcl Java] Re: java::import
dejong@...
Send Email Send Email
 
On Mon, 28 Dec 1998, Christian Krone wrote:

> Hello,
>
> over christmas I started to implement java::import.
> Right now it looks fine, but there is still a test file
> and a man page to write...

There is always a chance. I guess it depened on how much help
this command will be and how much of the system it changes.
I really have no problems with changing tons of code but
christopher just hates "lots of changes".

> So before I continue to work on this, I have some questions:
> - Is there a chance, that this implementation will become
>   part of Jacl and TclBlend?

I thought about implementing this command but I decided not to
because I was not really sure how much help it would be. Do you
intend to only change the java::new command so that short names
outside of the java.lang package can be provided?

> - Is there any other person currently working on the same topic?

Well, the "problem" is the need to be really clear about where
the short names will be accepted instead of the long names. It can
get really ugly if one is not careful and there are a bunch of
commands that could require changes. There is also an issue of
"caching" names and how you will tell is two packages has a class with
the exact same name.

> - Is there some known problem with java::import, which I don't see,
>   but which is the reason for the fact, that it isn't implemented yet?

Not really. The way it has worked so far is that each person works
on a private tree. Then where we are ready for a "release" the trees
are merged to produce an "official" tree. Of course this merging takes
a long time and christopher and I get into long silly arguments over
little things like error output of commands. Then after a bunch or
these email arguments and name calling we settle on something and
"ship" it over to the folks at scriptics.

> - Is there a "standard" way to incorporate changes into TclJava, or
>   should I send the sources to this mailing list?
>
> Thanks in advance for your answers,
> Krischan
> --
> Christian Krone, SQL Datenbanksysteme GmbH


later
mo

----------------------------------------------------------------
The TclJava mailing list is sponsored by WebNet Technologies.
To subscribe:    send mail to TclJava-request@...
                  with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to TclJava-request@...
                  with the word UNSUBSCRIBE as the subject.
To send to the list, send email to 'TclJava@...'.
A list archive is at: http://www.findmail.com/listsaver/tcldallas/

#13 From: Moses DeJong <dejong@...>
Date: Mon Dec 28, 1998 10:37 pm
Subject: [Tcl Java] Re: clock Jacl command
dejong@...
Send Email Send Email
 
On Mon, 28 Dec 1998, Christian Krone wrote:

> Hello,

Yup, you came to the right place.

> I hope, this mailing list is the correct place for something like this:

Cool, I just tested your code under JDK1.1 and JDK1.2 and it works great!
I have already added it to my beta tree. Of course, I can not promise that
everything in my tree will get into the "official" beta release.

> In the attachment there is an implementation of the clock command
> based on the sources of Jacl1.1a1:
> There are:
>   - ClockCmd.java (a new file belonging into .../jacl1.1a1/src/jacl/tcl/lang)
>   - Interp.java.patch (a patch for
.../jacl1.1a1/src/jacl/tcl/lang/Interp.java)
>   - all.patch (a patch for .../jacl1.1a1/tests/all)

I used the 8.0.4 clock.test. The 8.1b1 clock.test has some issues but
we will not worry about that as Tcl Blend does not work with tcl8.1b1 yet.
You might want to glance at the settimezone test if you have time.

> The modified jacl shell will NOT pass the clock.test, as it is found
> in .../jacl1.1a1/tests/tcl, since this doesn't seem to be up to date.
> It will pass the .../tcl8.0/tests/clock.test, which is attached also.
>
> I hope, this files will find their way into jacl1.1a2, jacl1.1b1 or
whatever...
>
> Have fun, Krischan
> --
> Christian Krone, SQL Datenbanksysteme GmbH


later
mo

----------------------------------------------------------------
The TclJava mailing list is sponsored by WebNet Technologies.
To subscribe:    send mail to TclJava-request@...
                  with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to TclJava-request@...
                  with the word UNSUBSCRIBE as the subject.
To send to the list, send email to 'TclJava@...'.
A list archive is at: http://www.findmail.com/listsaver/tcldallas/

#12 From: Moses DeJong <dejong@...>
Date: Mon Dec 28, 1998 8:49 pm
Subject: [Tcl Java] Re: BUG: Jacl1.1a1 Input handling on Windows...
dejong@...
Send Email Send Email
 
On Mon, 28 Dec 1998, Christian Krone wrote:

> Hello,
>
> there are two bugs in the input handling of the jacl Shell,
> which only occur on Windows:

I think this is actually a java bug and not a jacl bug. The report
I read on this was on a windows system that was not configured for
us/english output (I think it was french or something). When I run
jacl on my NT machine it works as expected. If it does not work on
your machine then try this simple program and see what it prints.

public class echo {
     public static void main(String[] argv) throws Exception {
	 System.out.println("Please begin typing");
	 while (true) {
	     int avail = System.in.available();
	     if (avail == 0) {
		 Thread.currentThread().sleep(100);
	     } else {
		 byte[] buff = new byte[avail];
		 System.in.read(buff);

		 //echo back what was just typed
		 System.out.println("-----ECHO BEGIN-----");
		 System.out.write(buff);
		 System.out.println("-----ECHO END-----");
	     }
	 }
     }
}

> - During an interactive session of jaclsh the input isn't echoed,
>   until a newline is entered. I already saw a report of this bug
>   in clt. It is indeed very strange to type something without echo...


Yes, this is a known problem. Only Unix style input is currently
accepted (\n at end of line). This problem also makes the Mac port
of jacl very hard to use. This is something that needs to be fixed
but I have not had time start on it yet. I did some funky junk
with the exec command to get it working under windows and I think it
does the \r\n conversion correctly but I would not bet my life on that.


> - When reading from a file, the handling of a backslash at the end of a
>   line is wrong. (Only on Windows and only from a file!)
>   An example session follows:
>   % exec type test.jacl
>   puts \
>   -nonewline Hello
>   % source test.jacl
>   can not find channel named " -nonewline"
>   % puts \
>   -nonewline Hello
>   Hello% exit
>
> I hope, this helps to improve jacl,
> Krischan
> --
> Christian Krone, SQL Datenbanksysteme GmbH
>
> ----------------------------------------------------------------
> The TclJava mailing list is sponsored by WebNet Technologies.
> To subscribe:    send mail to TclJava-request@...
>                  with the word SUBSCRIBE as the subject.
> To unsubscribe:  send mail to TclJava-request@...
>                  with the word UNSUBSCRIBE as the subject.
> To send to the list, send email to 'TclJava@...'.
> A list archive is at: http://www.findmail.com/listsaver/tcldallas/
>

----------------------------------------------------------------
The TclJava mailing list is sponsored by WebNet Technologies.
To subscribe:    send mail to TclJava-request@...
                  with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to TclJava-request@...
                  with the word UNSUBSCRIBE as the subject.
To send to the list, send email to 'TclJava@...'.
A list archive is at: http://www.findmail.com/listsaver/tcldallas/

#11 From: Moses DeJong <dejong@...>
Date: Mon Dec 28, 1998 8:11 pm
Subject: [Tcl Java] Re: classpath problem on Windows 98
dejong@...
Send Email Send Email
 
You might be the first person to run tcl blend on windows 98. When you
get the "could not find class tcl/lang/Interp" message that means there is
something wrong with the CLASSPATH such that the JVM can not find the
tclblend.jar file. Try this.

%javap tcl.lang.Interp

If your CLASSPATH is set correctly you should see the public interface
of tcl.lang.Interp printed to your screen. If you get a message like
"can't find tcl.lang.Interp" then you need to make sure your CLASSPATH
includes the tclblend.jar file.

Try that and tell us if it worked.

Mo DeJong
dejong@...
gimme multimedia group

On Mon, 28 Dec 1998, Philip Chu wrote:

> On my Windows 98 laptop (with JRE 1.2) I get the following message after
> "package require java". The CLASSPATH looks correct to me, but it seems the
> jvm is ignoring CLASSPATH. Is this a Windows 98 problem?
>
> Loading 'C:/Program Files/Tcl/lib/tcl8.0/../tclblend1.1/tclblend.dll' failed:
>  could not find class tcl/lang/Interp.
> Check that your path includes the directory where tclblend.dll resides.
> Try looking in the directories under the value of tcl_library,
> currently: C:/PROGRA~1/TCL/lib/tcl8.0
> Currently, the CLASSPATH environment variable is set to:
> C:\Program Files\Tcl\lib\tcl8.0\..\tclblend1.1\tcljava.jar;C:\Program
> Files\Tcl\lib\tcl8.0\..\tclblend1.1\tclblend.jar;
> The JVM currently is using the following classpath:C:\PROGRAM
> FILES\JAVASOFT\JRE\1.2\lib\rt.jar;C:\PROGRAM
> FILES\JAVASOFT\JRE\1.2\lib\i18n.jar;C:\PROGRAM FILES\JAVASOFT\JRE\1.2\classes
>
> --
> Phil Chu
> philipchu@... http://www.technicat.com/
>
> ----------------------------------------------------------------
> The TclJava mailing list is sponsored by WebNet Technologies.
> To subscribe:    send mail to TclJava-request@...
>                  with the word SUBSCRIBE as the subject.
> To unsubscribe:  send mail to TclJava-request@...
>                  with the word UNSUBSCRIBE as the subject.
> To send to the list, send email to 'TclJava@...'.
> A list archive is at: http://www.findmail.com/listsaver/tcldallas/
>

----------------------------------------------------------------
The TclJava mailing list is sponsored by WebNet Technologies.
To subscribe:    send mail to TclJava-request@...
                  with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to TclJava-request@...
                  with the word UNSUBSCRIBE as the subject.
To send to the list, send email to 'TclJava@...'.
A list archive is at: http://www.findmail.com/listsaver/tcldallas/

#10 From: Philip Chu <philipchu@...>
Date: Mon Dec 28, 1998 8:05 pm
Subject: [Tcl Java] classpath problem on Windows 98
philipchu@...
Send Email Send Email
 
On my Windows 98 laptop (with JRE 1.2) I get the following message after
"package require java". The CLASSPATH looks correct to me, but it seems the
jvm is ignoring CLASSPATH. Is this a Windows 98 problem?

Loading 'C:/Program Files/Tcl/lib/tcl8.0/../tclblend1.1/tclblend.dll' failed:
  could not find class tcl/lang/Interp.
Check that your path includes the directory where tclblend.dll resides.
Try looking in the directories under the value of tcl_library,
currently: C:/PROGRA~1/TCL/lib/tcl8.0
Currently, the CLASSPATH environment variable is set to:
C:\Program Files\Tcl\lib\tcl8.0\..\tclblend1.1\tcljava.jar;C:\Program
Files\Tcl\lib\tcl8.0\..\tclblend1.1\tclblend.jar;
The JVM currently is using the following classpath:C:\PROGRAM
FILES\JAVASOFT\JRE\1.2\lib\rt.jar;C:\PROGRAM
FILES\JAVASOFT\JRE\1.2\lib\i18n.jar;C:\PROGRAM FILES\JAVASOFT\JRE\1.2\classes

--
Phil Chu
philipchu@... http://www.technicat.com/

----------------------------------------------------------------
The TclJava mailing list is sponsored by WebNet Technologies.
To subscribe:    send mail to TclJava-request@...
                  with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to TclJava-request@...
                  with the word UNSUBSCRIBE as the subject.
To send to the list, send email to 'TclJava@...'.
A list archive is at: http://www.findmail.com/listsaver/tcldallas/

#9 From: Christian Krone <krischan@...>
Date: Mon Dec 28, 1998 5:54 pm
Subject: [Tcl Java] java::import
krischan@...
Send Email Send Email
 
Hello,

over christmas I started to implement java::import.
Right now it looks fine, but there is still a test file
and a man page to write...

So before I continue to work on this, I have some questions:
- Is there a chance, that this implementation will become
   part of Jacl and TclBlend?
- Is there any other person currently working on the same topic?
- Is there some known problem with java::import, which I don't see,
   but which is the reason for the fact, that it isn't implemented yet?
- Is there a "standard" way to incorporate changes into TclJava, or
   should I send the sources to this mailing list?

Thanks in advance for your answers,
Krischan
--
Christian Krone, SQL Datenbanksysteme GmbH

----------------------------------------------------------------
The TclJava mailing list is sponsored by WebNet Technologies.
To subscribe:    send mail to TclJava-request@...
                  with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to TclJava-request@...
                  with the word UNSUBSCRIBE as the subject.
To send to the list, send email to 'TclJava@...'.
A list archive is at: http://www.findmail.com/listsaver/tcldallas/

#8 From: Christian Krone <krischan@...>
Date: Mon Dec 28, 1998 5:46 pm
Subject: [Tcl Java] BUG: Jacl1.1a1 Input handling on Windows...
krischan@...
Send Email Send Email
 
Hello,

there are two bugs in the input handling of the jacl Shell,
which only occur on Windows:

- During an interactive session of jaclsh the input isn't echoed,
   until a newline is entered. I already saw a report of this bug
   in clt. It is indeed very strange to type something without echo...

- When reading from a file, the handling of a backslash at the end of a
   line is wrong. (Only on Windows and only from a file!)
   An example session follows:
   % exec type test.jacl
   puts \
   -nonewline Hello
   % source test.jacl
   can not find channel named " -nonewline"
   % puts \
   -nonewline Hello
   Hello% exit

I hope, this helps to improve jacl,
Krischan
--
Christian Krone, SQL Datenbanksysteme GmbH

----------------------------------------------------------------
The TclJava mailing list is sponsored by WebNet Technologies.
To subscribe:    send mail to TclJava-request@...
                  with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to TclJava-request@...
                  with the word UNSUBSCRIBE as the subject.
To send to the list, send email to 'TclJava@...'.
A list archive is at: http://www.findmail.com/listsaver/tcldallas/

#7 From: Christian Krone <krischan@...>
Date: Mon Dec 28, 1998 12:59 pm
Subject: [Tcl Java] clock Jacl command
krischan@...
Send Email Send Email
 
Hello,

I hope, this mailing list is the correct place for something like this:

In the attachment there is an implementation of the clock command
based on the sources of Jacl1.1a1:
There are:
   - ClockCmd.java (a new file belonging into .../jacl1.1a1/src/jacl/tcl/lang)
   - Interp.java.patch (a patch for .../jacl1.1a1/src/jacl/tcl/lang/Interp.java)
   - all.patch (a patch for .../jacl1.1a1/tests/all)

The modified jacl shell will NOT pass the clock.test, as it is found
in .../jacl1.1a1/tests/tcl, since this doesn't seem to be up to date.
It will pass the .../tcl8.0/tests/clock.test, which is attached also.

I hope, this files will find their way into jacl1.1a2, jacl1.1b1 or whatever...

Have fun, Krischan
--
Christian Krone, SQL Datenbanksysteme GmbH
/*
  * ClockCmd.java --
  *
  * Implements the built-in "clock" Tcl command.
  *
  * Copyright (c) 1998 Christian Krone.
  * Copyright (c) 1997 Cornell University.
  * Copyright (c) 1995-1997 Sun Microsystems, Inc.
  * Copyright (c) 1992-1995 Karl Lehenbauer and Mark Diekhans.
  *
  * See the file "license.terms" for information on usage and
  * redistribution of this file, and for a DISCLAIMER OF ALL
  * WARRANTIES.
  *
  * RCS: @(#) $Id$
  *
  */

package tcl.lang;

import java.util.*;
import java.text.*;

/**
  * This class implements the built-in "clock" command in Tcl.
  */

class ClockCmd implements Command {

     static final private String validCmds[] = {
	 "clicks",
	 "format",
	 "scan",
	 "seconds"
     };

     static final private int CMD_CLICKS  = 0;
     static final private int CMD_FORMAT   = 1;
     static final private int CMD_SCAN  = 2;
     static final private int CMD_SECONDS = 3;

     static final private String formatOpts[] = {
	 "-format",
	 "-gmt"
     };

     static final private int OPT_FORMAT_FORMAT  = 0;
     static final private int OPT_FORMAT_GMT = 1;

     static final private String scanOpts[] = {
	 "-base",
	 "-gmt"
     };

     static final private int OPT_SCAN_BASE  = 0;
     static final private int OPT_SCAN_GMT = 1;

     static final int EPOCH_YEAR = 1970;

/**
  *----------------------------------------------------------------------
  *
  * cmdProc --
  *
  * This procedure is invoked as part of the Command interface to
  * process the "clock" Tcl command.  See the user documentation
  * for details on what it does.
  *
  * Results:
  * None.
  *
  * Side effects:
  * See the user documentation.
  *
  *----------------------------------------------------------------------
  */

public void
cmdProc(
     Interp interp,  // Current interpreter.
     TclObject argv[])  // Argument list.
throws
     TclException 	 // A standard Tcl exception.
{
     int clockVal;  // Time value as seconds of epoch.
     String dateString;  // Time value as string.
     int argIx; 	 // Counter over arguments.
     String format = null; // User specified format string.
     boolean useGmt = false; // User specified flag to use gmt.
     TclObject baseObj = null; // User specified raw value of baseClock.
     Date baseClock;  // User specified time value.
     Date date; 	 // Parsed date value.

     if (argv.length < 2) {
	 throw new TclNumArgsException(interp, 1, argv, "option ?arg ...?");
     }
     int cmd = TclIndex.get(interp, argv[1], validCmds, "option", 0);

     switch (cmd) {
	 case CMD_CLICKS: {
	     if (argv.length != 2) {
		 throw new TclNumArgsException(interp, 2, argv, null);
	     }
	     long millis = new java.util.Date().getTime();
	     int clicks = (int)(millis%Integer.MAX_VALUE);
	     interp.setResult(clicks);
	     break;
	 }

	 case CMD_FORMAT: {
	     if ((argv.length < 3) || (argv.length > 7)) {
		 throw new TclNumArgsException(interp, 2, argv,
		     "clockval ?-format string? ?-gmt boolean?");
	     }
	     clockVal = TclInteger.get(interp, argv[2]);

	     for (argIx = 3; argIx+1 < argv.length; argIx += 2) {
	         int formatOpt = TclIndex.get(interp, argv[argIx],
				     formatOpts, "switch", 0);
	         switch (formatOpt) {
		     case OPT_FORMAT_FORMAT: {
		         format = argv[argIx+1].toString();
		         break;
		     }
		     case OPT_FORMAT_GMT: {
		         useGmt = TclBoolean.get(interp, argv[argIx+1]);
		         break;
		     }
		 }
	     }
	     if (argIx < argv.length) {
		 throw new TclNumArgsException(interp, 2, argv,
		     "clockval ?-format string? ?-gmt boolean?");
	     }
	     FormatClock(interp, clockVal, useGmt, format);
	     break;
	 }

	 case CMD_SCAN: {
	     if ((argv.length < 3) || (argv.length > 7)) {
		 throw new TclNumArgsException(interp, 2, argv,
		     "dateString ?-base clockValue? ?-gmt boolean?");
	     }
	     dateString = argv[2].toString();

	     for (argIx = 3; argIx+1 < argv.length; argIx += 2) {
	         int scanOpt = TclIndex.get(interp, argv[argIx],
				   scanOpts, "switch", 0);
	         switch (scanOpt) {
		     case OPT_SCAN_BASE: {
		         baseObj = argv[argIx+1];
		         break;
		     }
		     case OPT_SCAN_GMT: {
		         useGmt = TclBoolean.get(interp, argv[argIx+1]);
		         break;
		     }
		 }
	     }
	     if (argIx < argv.length) {
		 throw new TclNumArgsException(interp, 2, argv,
		     "clockval ?-format string? ?-gmt boolean?");
	     }
	     if (baseObj != null) {
	         baseClock = new Date(TclInteger.get(interp, baseObj)*1000);
	     } else {
	         baseClock = new Date();
	     }

	     date = GetDate(dateString, baseClock, useGmt);
	     if (date == null) {
	         throw new TclException(interp,
			       "unable to convert date-time string \"" +
			       dateString + "\"");
	     }

	     int seconds = (int)(date.getTime()/1000);
	     interp.setResult(seconds);
	     break;
	 }

	 case CMD_SECONDS: {
	     if (argv.length != 2) {
		 throw new TclNumArgsException(interp, 2, argv, null);
	     }
	     long millis = new java.util.Date().getTime();
	     int seconds = (int)(millis/1000);
	     interp.setResult(seconds);
	     break;
	 }
     }
}

/**
  *-----------------------------------------------------------------------------
  *
  * FormatClock --
  *
  *      Formats a time value based on seconds into a human readable
  * string.
  *
  * Results:
  *      None.
  *
  * Side effects:
  *      The interpreter will contain the formatted string as result.
  *
  *-----------------------------------------------------------------------------
  */

private void
FormatClock(
     Interp interp,  // Current interpreter.
     int clockVal,         // Time in seconds.
     boolean useGMT,  // Boolean
     String format)  // Format string
throws
     TclException 	 // A standard Tcl exception.
{
     Date date = new Date((long)clockVal*1000);
     Calendar calendar = Calendar.getInstance();
     SimpleDateFormat fmt, locFmt;
     FieldPosition fp = new FieldPosition(0);

     if (format == null) {
	 format = new String ("%a %b %d %H:%M:%S %Z %Y");
     }

     calendar.setTime(date);
     if (useGMT) {
         calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
     }
     fmt = new SimpleDateFormat("mm.dd.yy", Locale.US);
     fmt.setCalendar(calendar);

     StringBuffer result = new StringBuffer();
     for (int ix = 0; ix < format.length(); ix++) {
         if (format.charAt(ix) == '%' && ix+1 < format.length()) {
	     switch (format.charAt(++ix)) {
	         case '%': // Insert a %.
		     result.append('%');
		     break;
	         case 'a': // Abbreviated weekday name (Mon, Tue, etc.).
		     fmt.applyPattern("EEE");
		     fmt.format(date, result, fp);
		     break;
	         case 'A': // Full weekday name (Monday, Tuesday, etc.).
		     fmt.applyPattern("EEEE");
		     fmt.format(date, result, fp);
		     break;
	         case 'b': case 'h': // Abbreviated month name (Jan,Feb,etc.).
		     fmt.applyPattern("MMM");
		     fmt.format(date, result, fp);
		     break;
	         case 'B': // Full month name.
		     fmt.applyPattern("MMMM");
		     fmt.format(date, result, fp);
		     break;
	         case 'c': // Locale specific date and time.
		     locFmt = (SimpleDateFormat)DateFormat.getDateTimeInstance(
			           DateFormat.SHORT, DateFormat.SHORT);
		     locFmt.setCalendar(calendar);
		     locFmt.format(date, result, fp);
		     break;
	         case 'C': // Century (00 - 99).
		     int century = calendar.get(Calendar.YEAR)/100;
		     result.append((century < 10 ? "0" : "") + century);
		     break;
	         case 'd': // Day of month (01 - 31).
		     fmt.applyPattern("dd");
		     fmt.format(date, result, fp);
		     break;
	         case 'D': // Date as %m/%d/%y.
		     fmt.applyPattern("MM/dd/yy");
		     fmt.format(date, result, fp);
		     break;
	         case 'e': // Day of month (1 - 31), no leading zeros.
		     fmt.applyPattern("d");
		     String day = fmt.format(date);
		     result.append((day.length() < 2 ? " " : "") + day);
		     break;
	         case 'H': // Hour in 24-hour format (00 - 23).
		     fmt.applyPattern("HH");
		     fmt.format(date, result, fp);
		     break;
	         case 'I': // Hour in 12-hour format (01 - 12).
		     fmt.applyPattern("hh");
		     fmt.format(date, result, fp);
		     break;
	         case 'j': // Day of year (001 - 366).
		     fmt.applyPattern("DDD");
		     fmt.format(date, result, fp);
		     break;
	         case 'k': // Hour in 24-hour format (0 - 23), no leading zeros.
		     fmt.applyPattern("H");
		     String h24 = fmt.format(date);
		     result.append((h24.length() < 2 ? " " : "") + h24);
		     break;
	         case 'l': // Hour in 12-hour format (1 - 12), no leading zeros.
		     fmt.applyPattern("h");
		     String h12 = fmt.format(date);
		     result.append((h12.length() < 2 ? " " : "") + h12);
		     break;
	         case 'm': // Month number (01 - 12).
		     fmt.applyPattern("MM");
		     fmt.format(date, result, fp);
		     break;
	         case 'M': // Minute (00 - 59).
		     fmt.applyPattern("mm");
		     fmt.format(date, result, fp);
		     break;
	         case 'n': // Insert a newline.
		     result.append('\n');
		     break;
	         case 'p': // AM/PM indicator.
		     fmt.applyPattern("aa");
		     fmt.format(date, result, fp);
		     break;
	         case 'r': // Time as %I:%M:%S %p.
		     fmt.applyPattern("KK:mm:ss aaaa");
		     fmt.format(date, result, fp);
		     break;
	         case 'R': // Time as %H:%M.
		     fmt.applyPattern("hh:mm");
		     fmt.format(date, result, fp);
		     break;
	         case 's': // seconds since epoch.
		     long millis = calendar.getTime().getTime();
		     if (useGMT) {
		         Calendar localCalendar = Calendar.getInstance();
			 localCalendar.setTime(calendar.getTime());
			 millis -= localCalendar.get(Calendar.ZONE_OFFSET)
			  	 + localCalendar.get(Calendar.DST_OFFSET);
		     }
		     result.append((int)(millis/1000));
		     break;
	         case 'S': // Seconds (00 - 59).
		     fmt.applyPattern("ss");
		     fmt.format(date, result, fp);
		     break;
	         case 't': // Insert a tab.
		     result.append('\t');
		     break;
	         case 'T': // Time as %H:%M:%S.
		     fmt.applyPattern("hh:mm:ss");
		     fmt.format(date, result, fp);
		     break;
	         case 'u': // Weekday number (1 - 7) Sunday = 7.
		     int dayOfWeek17 = calendar.get(Calendar.DAY_OF_WEEK);
		     if (dayOfWeek17 == calendar.SUNDAY) {
		         result.append(7);
		     } else {
		         result.append(dayOfWeek17 - Calendar.SUNDAY);
		     }
		     break;
	         case 'U': // Week of year (01-52), Sunday is first day.
		     int weekS = GetWeek(calendar, Calendar.SUNDAY, false);
		     result.append((weekS < 10 ? "0" : "") + weekS);
		     break;
	         case 'V': // ISO 8601 Week Of Year (01 - 53).
		     int isoWeek = GetWeek(calendar, Calendar.MONDAY, true);
		     result.append((isoWeek < 10 ? "0" : "") + isoWeek);
		     break;
	         case 'w': // Weekday number (0 - 6) Sunday = 0.
		     int dayOfWeek06 = calendar.get(Calendar.DAY_OF_WEEK);
		     result.append(dayOfWeek06-calendar.SUNDAY);
		     break;
	         case 'W': // Week of year (01-52), Monday is first day.
		     int weekM = GetWeek(calendar, Calendar.MONDAY, false);
		     result.append((weekM < 10 ? "0" : "") + weekM);
		     break;
	         case 'x': // Locale specific date format.
		     locFmt = (SimpleDateFormat)DateFormat.getDateInstance(
						    DateFormat.SHORT);
		     locFmt.setCalendar(calendar);
		     locFmt.format(date, result, fp);
		     break;
	         case 'X': // Locale specific time format.
		     locFmt = (SimpleDateFormat)DateFormat.getTimeInstance(
						    DateFormat.SHORT);
		     locFmt.setCalendar(calendar);
		     locFmt.format(date, result, fp);
		     break;
	         case 'y': // Year without century (00 - 99).
		     fmt.applyPattern("yy");
		     fmt.format(date, result, fp);
		     break;
	         case 'Y': // Year with century (e.g. 1990)
		     fmt.applyPattern("yyyy");
		     fmt.format(date, result, fp);
		     break;
	         case 'Z': // Time zone name.
		     fmt.applyPattern("zzz");
		     fmt.format(date, result, fp);
		     break;
	         default:
		     result.append(format.charAt(ix));
		     break;
	     }
	 } else {
	   result.append(format.charAt(ix));
	 }
     }
     interp.setResult(result.toString());
}

/**
  *-----------------------------------------------------------------------------
  *
  * GetWeek --
  *
  *      Returns the week_of_year of the given date.
  * The weekday considered as start of the week is given as argument.
  * Specify iso as true to get the week_of_year accourding to ISO.
  *
  * Results:
  *      Day of the week .
  *
  * Side effects:
  *      The interpreter will contain the formatted string as result.
  *
  *-----------------------------------------------------------------------------
  */

private int
GetWeek(
     Calendar calendar,  // Calendar containing Date.
     int firstDayOfWeek,  // this day starts a week (MONDAY/SUNDAY).
     boolean iso 	 // evaluate according to ISO?
)
{
     if (iso) {
         firstDayOfWeek = Calendar.MONDAY;
     }

     /*
      * After changing the firstDayOfWeek, we have to set the time value anew,
      * so that the fields of the calendar are recalculated.
      */

     calendar.setFirstDayOfWeek(firstDayOfWeek);
     calendar.setMinimalDaysInFirstWeek(iso ? 4 : 7);
     calendar.setTime(calendar.getTime());
     int week = calendar.get(Calendar.WEEK_OF_YEAR);

     if (!iso) {
	 /*
	  * The week for the first days of the year may be 52 or 53.
	  * But here we have to return 0, if we don't compute ISO week.
	  * So any bigger than 50th week in January will become 00.
	  */
	 if (calendar.get(Calendar.MONTH) == Calendar.JANUARY && week > 50) {
	     week = 0;
	 }
     }

     return week;
}

/**
  *-----------------------------------------------------------------------------
  *
  * GetDate --
  *
  *      Scan a human readable date string and construct a Date.
  *
  * Results:
  *      The scanned date (or null, if an error occured).
  *
  * Side effects:
  *      None.
  *
  *-----------------------------------------------------------------------------
  */

private Date
GetDate(
     String dateString,  // Date string to scan
     Date baseDate,  // Date to use as base
     boolean useGMT)  // Boolean
{
     Calendar calendar = Calendar.getInstance();
     Calendar now = Calendar.getInstance();
     now.setTime(baseDate);
     calendar.set(now.get(Calendar.YEAR), now.get(Calendar.MONTH),
	 now.get(Calendar.DAY_OF_MONTH), 0, 0 ,0);
     if (useGMT) {
         calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
     }

     ClockToken[] dt = GetTokens(dateString, false);

     ParsePosition parsePos = new ParsePosition(0);
     ClockRelTimespan diff = new ClockRelTimespan();
     int hasTime = 0;
     int hasZone = 0;
     int hasDate = 0;
     int hasDay = 0;
     int hasRel = 0;

     while (parsePos.getIndex() < dt.length) {
         if (ParseTime(dt, parsePos, calendar)) {
	     hasTime++;
	 } else if (ParseZone(dt, parsePos, calendar)) {
	     hasZone++;
	 } else if (ParseDate(dt, parsePos, calendar)) {
	     hasDate++;
	 } else if (ParseDay(dt, parsePos, calendar)) {
	     hasDay++;
	 } else if (ParseRel(dt, parsePos, diff)) {
	     hasRel++;
	 } else if (ParseNumber(dt, parsePos, calendar,
			        hasDate > 0 && hasTime > 0 && hasRel == 0)) {
	     if (hasDate == 0 || hasTime == 0 || hasRel > 0) {
	         hasTime++;
	     }
	 } else {
	     return null;
	 }
     }

     if (hasTime > 1 || hasZone > 1 || hasDate > 1 || hasDay > 1) {
         return null;
     }

     /*
      * The following line handles years that are specified using
      * only two digits.  The line of code below implements a policy
      * defined by the X/Open workgroup on the millinium rollover.
      * Note: some of those dates may not actually be valid on some
      * platforms.  The POSIX standard startes that the dates 70-99
      * shall refer to 1970-1999 and 00-38 shall refer to 2000-2038.
      * This later definition should work on all platforms.
      */
     int thisYear = calendar.get(Calendar.YEAR);
     if (thisYear < 100) {
         if (thisYear >= 69) {
	     calendar.set(Calendar.YEAR, thisYear+1900);
	 } else {
	     calendar.set(Calendar.YEAR, thisYear+2000);
	 }
     }

     if (hasRel > 0) {
         if (hasTime == 0 && hasDate == 0 && hasDay == 0) {
	     calendar.setTime(baseDate);
	 }
	 calendar.add(Calendar.SECOND, diff.getSeconds());
	 calendar.add(Calendar.MONTH, diff.getMonths());
     }

     return calendar.getTime();
}

/**
  *-----------------------------------------------------------------------------
  *
  * ParseTime --
  *
  *      Parse a time string and sets the Calendar.
  * A time string is valid, if it confirms to the following yacc rule:
  * time    : tUNUMBER tMERIDIAN
  *         | tUNUMBER ':' tUNUMBER o_merid
  *         | tUNUMBER ':' tUNUMBER tSNUMBER
  *         | tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid
  *         | tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER
  *         ;
  *
  * Results:
  *      True, if a time was read (parsePos was incremented and calendar
  * was set according to the read time); false otherwise.
  *
  * Side effects:
  *      None.
  *
  *-----------------------------------------------------------------------------
  */

private boolean
ParseTime (
     ClockToken[] dt,  // Input as scanned array of tokens
     ParsePosition parsePos, // Current position in input
     Calendar calendar  // calendar object to set
)
{
     int pos = parsePos.getIndex();

     if (pos+5 < dt.length &&
	 dt[pos].isUNumber() &&
	 dt[pos+1].is(':') &&
	 dt[pos+2].isUNumber() &&
	 dt[pos+3].is(':') &&
	 dt[pos+4].isUNumber() &&
	 dt[pos+5].isSNumber()) {
	 calendar.set(Calendar.HOUR, dt[pos].getInt());
	 calendar.set(Calendar.MINUTE, dt[pos+2].getInt());
	 calendar.set(Calendar.SECOND, dt[pos+4].getInt());
         parsePos.setIndex(pos+6);
         return true;
     }
     if (pos+4 < dt.length &&
	 dt[pos].isUNumber() &&
	 dt[pos+1].is(':') &&
	 dt[pos+2].isUNumber() &&
	 dt[pos+3].is(':') &&
	 dt[pos+4].isUNumber()) {
         parsePos.setIndex(pos+5);
	 ParseMeridianAndSetHour(dt, parsePos, calendar, dt[pos].getInt());
	 calendar.set(Calendar.MINUTE, dt[pos+2].getInt());
	 calendar.set(Calendar.SECOND, dt[pos+4].getInt());
         return true;
     }
     if (pos+3 < dt.length &&
	 dt[pos].isUNumber() &&
	 dt[pos+1].is(':') &&
	 dt[pos+2].isUNumber() &&
	 dt[pos+3].isSNumber()) {
	 calendar.set(Calendar.HOUR, dt[pos].getInt());
	 calendar.set(Calendar.MINUTE, dt[pos+2].getInt());
         parsePos.setIndex(pos+4);
         return true;
     }
     if (pos+2 < dt.length &&
	 dt[pos].isUNumber() &&
	 dt[pos+1].is(':') &&
	 dt[pos+2].isUNumber()) {
         parsePos.setIndex(pos+3);
	 ParseMeridianAndSetHour(dt, parsePos, calendar, dt[pos].getInt());
	 calendar.set(Calendar.MINUTE, dt[pos+2].getInt());
         return true;
     }
     if (pos+1 < dt.length &&
	 dt[pos].isUNumber() &&
	 dt[pos+1].is(ClockToken.MERIDIAN)) {
         parsePos.setIndex(pos+1);
	 ParseMeridianAndSetHour(dt, parsePos, calendar, dt[pos].getInt());
         return true;
     }
     return false;
}

/**
  *-----------------------------------------------------------------------------
  *
  * ParseZone --
  *
  *      Parse a timezone string and sets the Calendar.
  * A timezone string is valid, if it confirms to the following yacc rule:
  * zone    : tZONE tDST
  *         | tZONE
  *         | tDAYZONE
  *         ;
  *
  * Results:
  *      True, if a timezone was read (parsePos was incremented and calendar
  * was set according to the read timezone); false otherwise.
  *
  * Side effects:
  *      None.
  *
  *-----------------------------------------------------------------------------
  */

private boolean
ParseZone (
     ClockToken[] dt,  // Input as scanned array of tokens
     ParsePosition parsePos, // Current position in input
     Calendar calendar  // calendar object to set
)
{
     int pos = parsePos.getIndex();

     if (pos+1 < dt.length &&
	 dt[pos].is(ClockToken.ZONE) &&
	 dt[pos+1].is(ClockToken.DST)) {
         calendar.setTimeZone(dt[pos].getZone());
         parsePos.setIndex(pos+2);
         return true;
     }
     if (pos < dt.length &&
	 dt[pos].is(ClockToken.ZONE)) {
         calendar.setTimeZone(dt[pos].getZone());
         parsePos.setIndex(pos+1);
         return true;
     }
     if (pos < dt.length &&
	 dt[pos].is(ClockToken.DAYZONE)) {
         calendar.setTimeZone(dt[pos].getZone());
         parsePos.setIndex(pos+1);
         return true;
     }
     return false;
}

/**
  *-----------------------------------------------------------------------------
  *
  * ParseDay --
  *
  *      Parse a day string and sets the Calendar.
  * A day string is valid, if it confirms to the following yacc rule:
  * day     : tDAY
  *         | tDAY ','
  *         | tUNUMBER tDAY
  *         ;
  *
  * Results:
  *      True, if a day was read (parsePos was incremented and calendar
  * was set according to the read day); false otherwise.
  *
  * Side effects:
  *      None.
  *
  *-----------------------------------------------------------------------------
  */

private boolean
ParseDay (
     ClockToken[] dt,  // Input as scanned array of tokens
     ParsePosition parsePos, // Current position in input
     Calendar calendar  // calendar object to set
)
{
     int pos = parsePos.getIndex();

     if (pos+1 < dt.length &&
	 dt[pos].is(ClockToken.DAY) &&
	 dt[pos+1].is(',')) {
	 calendar.set(Calendar.DAY_OF_MONTH, dt[pos].getInt());
         parsePos.setIndex(pos+2);
         return true;
     }
     if (pos+1 < dt.length &&
	 dt[pos].isUNumber() &&
	 dt[pos+1].is(ClockToken.DAY)) {
	 calendar.set(Calendar.DAY_OF_MONTH, dt[pos+1].getInt());
         parsePos.setIndex(pos+2);
         return true;
     }
     if (pos < dt.length &&
	 dt[pos].is(ClockToken.DAY)) {
	 calendar.set(Calendar.DAY_OF_MONTH, dt[pos].getInt());
         parsePos.setIndex(pos+1);
         return true;
     }
     return false;
}

/**
  *-----------------------------------------------------------------------------
  *
  * ParseDate --
  *
  *      Parse a date string and sets the Calendar.
  * A date string is valid, if it confirms to the following yacc rule:
  * date : tUNUMBER '/' tUNUMBER
  *  | tUNUMBER '/' tUNUMBER '/' tUNUMBER
  *  | tMONTH tUNUMBER
  *  | tMONTH tUNUMBER ',' tUNUMBER
  *  | tUNUMBER tMONTH
  *  | tEPOCH
  *  | tUNUMBER tMONTH tUNUMBER
  *  ;
  *
  * Results:
  *      True, if a date was read (parsePos was incremented and calendar
  * was set according to the read day); false otherwise.
  *
  * Side effects:
  *      None.
  *
  *-----------------------------------------------------------------------------
  */

private boolean
ParseDate (
     ClockToken[] dt,  // Input as scanned array of tokens
     ParsePosition parsePos, // Current position in input
     Calendar calendar  // calendar object to set
)
{
     int pos = parsePos.getIndex();

     if (pos+4 < dt.length &&
	 dt[pos].isUNumber() &&
	 dt[pos+1].is('/') &&
	 dt[pos+2].isUNumber() &&
	 dt[pos+3].is('/') &&
	 dt[pos+4].isUNumber()) {
	 calendar.set(Calendar.DAY_OF_MONTH, dt[pos+2].getInt());
	 calendar.set(Calendar.MONTH, dt[pos].getInt()-1);
	 calendar.set(Calendar.YEAR, dt[pos+4].getInt());
         parsePos.setIndex(pos+5);
         return true;
     }
     if (pos+3 < dt.length &&
	 dt[pos].is(ClockToken.MONTH) &&
	 dt[pos+1].isUNumber() &&
	 dt[pos+2].is(',') &&
	 dt[pos+3].isUNumber()) {
	 calendar.set(Calendar.DAY_OF_MONTH, dt[pos+1].getInt());
	 calendar.set(Calendar.MONTH, dt[pos].getInt());
	 calendar.set(Calendar.YEAR, dt[pos+3].getInt());
         parsePos.setIndex(pos+4);
         return true;
     }
     if (pos+2 < dt.length &&
	 dt[pos].isUNumber() &&
	 dt[pos+1].is('/') &&
	 dt[pos+2].isUNumber()) {
	 calendar.set(Calendar.DAY_OF_MONTH, dt[pos+2].getInt());
	 calendar.set(Calendar.MONTH, dt[pos].getInt()-1);
         parsePos.setIndex(pos+3);
         return true;
     }
     if (pos+2 < dt.length &&
	 dt[pos].isUNumber() &&
	 dt[pos+1].is(ClockToken.MONTH) &&
	 dt[pos+2].isUNumber()) {
	 calendar.set(Calendar.DAY_OF_MONTH, dt[pos].getInt());
	 calendar.set(Calendar.MONTH, dt[pos+1].getInt());
	 calendar.set(Calendar.YEAR, dt[pos+2].getInt());
         parsePos.setIndex(pos+3);
         return true;
     }
     if (pos+1 < dt.length &&
	 dt[pos].is(ClockToken.MONTH) &&
	 dt[pos+1].isUNumber()) {
	 calendar.set(Calendar.DAY_OF_MONTH, dt[pos+1].getInt());
	 calendar.set(Calendar.MONTH, dt[pos].getInt());
         parsePos.setIndex(pos+2);
         return true;
     }
     if (pos+1 < dt.length &&
	 dt[pos].isUNumber() &&
	 dt[pos+1].is(ClockToken.MONTH)) {
	 calendar.set(Calendar.DAY_OF_MONTH, dt[pos].getInt());
	 calendar.set(Calendar.MONTH, dt[pos+1].getInt());
         parsePos.setIndex(pos+2);
         return true;
     }
     if (pos < dt.length &&
	 dt[pos].is(ClockToken.EPOCH)) {
	 calendar.set(Calendar.DAY_OF_MONTH, 1);
	 calendar.set(Calendar.MONTH, 0);
	 calendar.set(Calendar.YEAR, EPOCH_YEAR);
         parsePos.setIndex(pos+1);
         return true;
     }
     return false;
}

/**
  *-----------------------------------------------------------------------------
  *
  * ParseNumber --
  *
  *      Parse a number and sets the Calendar.
  * If argument mayBeYear is true, this number is conidered as year,
  * otherwise it is date and time in the form HHMM.
  *
  * Results:
  *      True, if a number was read (parsePos was incremented and calendar
  * was set according to the read day); false otherwise.
  *
  * Side effects:
  *      None.
  *
  *-----------------------------------------------------------------------------
  */

private boolean
ParseNumber (
     ClockToken[] dt,  // Input as scanned array of tokens
     ParsePosition parsePos, // Current position in input
     Calendar calendar,  // calendar object to set
     boolean mayBeYear  // number is considered to be year?
)
{
     int pos = parsePos.getIndex();

     if (pos < dt.length &&
	 dt[pos].isUNumber()) {
         parsePos.setIndex(pos+1);
         if (mayBeYear) {
	     calendar.set(Calendar.YEAR, dt[pos].getInt());
	 } else {
	   calendar.set(Calendar.HOUR_OF_DAY, dt[pos].getInt()/100);
	   calendar.set(Calendar.MINUTE, dt[pos].getInt()%100);
	   calendar.set(Calendar.SECOND, 0);
	 }
         return true;
     }
     return false;
}

/**
  *-----------------------------------------------------------------------------
  *
  * ParseRel --
  *
  *      Parse a relative time specification and sets the time difference.
  * A relative time specification is valid, if it confirms to the
  * following yacc rule:
  * rel : relunit tAGO
  *  | relunit
  *  ;
  *
  * Results:
  *      True, if a relative time specification was read (parsePos was
  * incremented and the time difference was set according to the read
  * relative time specification); false otherwise.
  *
  * Side effects:
  *      None.
  *
  *-----------------------------------------------------------------------------
  */

private boolean
ParseRel (
     ClockToken[] dt,  // Input as scanned array of tokens
     ParsePosition parsePos, // Current position in input
     ClockRelTimespan diff // time difference to evaluate
)
{
     if (ParseRelUnit(dt, parsePos, diff)) {
         int pos = parsePos.getIndex();
         if (pos < dt.length &&
	     dt[pos].is(ClockToken.AGO)) {
	     diff.negate();
	     parsePos.setIndex(pos+1);
	 }
         return true;
     }
     return false;
}

/**
  *-----------------------------------------------------------------------------
  *
  * ParseRelUnit --
  *
  *      Parse a relative time unit and sets the time difference.
  * A relative time unit is valid, if it confirms to the
  * following yacc rule:
  * relunit : tUNUMBER tMINUTE_UNIT
  *  | tSNUMBER tMINUTE_UNIT
  *  | tMINUTE_UNIT
  *  | tSNUMBER tSEC_UNIT
  *  | tUNUMBER tSEC_UNIT
  *  | tSEC_UNIT
  *  | tSNUMBER tMONTH_UNIT
  *  | tUNUMBER tMONTH_UNIT
  *  | tMONTH_UNIT
  *  ;
  *
  * Results:
  *      True, if a relative time unit was read (parsePos was incremented and
  * the time difference was set according to the read relative time unit);
  * false otherwise.
  *
  * Side effects:
  *      None.
  *
  *-----------------------------------------------------------------------------
  */

private boolean
ParseRelUnit (
     ClockToken[] dt,  // Input as scanned array of tokens
     ParsePosition parsePos, // Current position in input
     ClockRelTimespan diff // time difference to evaluate
)
{
     int pos = parsePos.getIndex();

     if (pos+1 < dt.length &&
	 (dt[pos].isUNumber() || dt[pos].isSNumber()) &&
	 dt[pos+1].is(ClockToken.MINUTE_UNIT)) {
         diff.addSeconds(dt[pos].getInt()*dt[pos+1].getInt()*60);
         parsePos.setIndex(pos+2);
         return true;
     } else if (pos+1 < dt.length &&
	 (dt[pos].isUNumber() || dt[pos].isSNumber()) &&
	 dt[pos+1].is(ClockToken.SEC_UNIT)) {
         diff.addSeconds(dt[pos].getInt());
         parsePos.setIndex(pos+2);
         return true;
     } else if (pos+1 < dt.length &&
	 (dt[pos].isUNumber() || dt[pos].isSNumber()) &&
	 dt[pos+1].is(ClockToken.MONTH_UNIT)) {
         diff.addMonths(dt[pos].getInt()*dt[pos+1].getInt());
         parsePos.setIndex(pos+2);
         return true;
     } else if (pos < dt.length &&
	 dt[pos].is(ClockToken.MINUTE_UNIT)) {
         diff.addSeconds(dt[pos].getInt()*60);
         parsePos.setIndex(pos+1);
         return true;
     } else if (pos < dt.length &&
	 dt[pos].is(ClockToken.SEC_UNIT)) {
         diff.addSeconds(1);
         parsePos.setIndex(pos+1);
         return true;
     } else if (pos < dt.length &&
	 dt[pos].is(ClockToken.MONTH_UNIT)) {
         diff.addMonths(dt[pos].getInt());
         parsePos.setIndex(pos+1);
         return true;
     }
     return false;
}

/**
  *-----------------------------------------------------------------------------
  *
  * ParseMeridianAndSetHour --
  *
  *      Parse a meridian and sets the hour field of the calendar.
  * A meridian is valid, if it confirms to the following yacc rule:
  * o_merid : // NULL
  *  | tMERIDIAN
  *  ;
  *
  * Results:
  *      None; parsePos was incremented and the claendar was set according
  * to the read meridian.
  *
  * Side effects:
  *      None.
  *
  *-----------------------------------------------------------------------------
  */

private void
ParseMeridianAndSetHour(
     ClockToken[] dt,  // Input as scanned array of tokens
     ParsePosition parsePos, // Current position in input
     Calendar calendar,  // calendar object to set
     int hour 	 // hour value (1-12 or 0-23) to set.
)
{
     int pos = parsePos.getIndex();
     int hourField;

     if (pos < dt.length &&
	 dt[pos].is(ClockToken.MERIDIAN)) {
         calendar.set(Calendar.AM_PM, dt[pos].getInt());
         parsePos.setIndex(pos+1);
	 hourField = Calendar.HOUR;
     } else {
	 hourField = Calendar.HOUR_OF_DAY;
     }

     if (hourField == Calendar.HOUR && hour == 12) {
         hour = 0;
     }
     calendar.set(hourField, hour);
}

/**
  *-----------------------------------------------------------------------------
  *
  * GetTokens --
  *
  *      Lexical analysis of the input string.
  *
  * Results:
  *      An array of ClockToken, representing the input string.
  *
  * Side effects:
  *      None.
  *
  *-----------------------------------------------------------------------------
  */

private ClockToken[]
GetTokens (
     String in,  // String to parse
     boolean debug // Send the generated token list to stderr?
)
{
     ParsePosition parsePos = new ParsePosition(0);
     ClockToken dt;
     Vector tokenVector = new Vector(in.length());

     while ((dt = GetNextToken(in, parsePos)) != null) {
         tokenVector.addElement(dt);
     }

     ClockToken[] tokenArray = new ClockToken[tokenVector.size()];
     tokenVector.copyInto(tokenArray);

     if (debug) {
         for (int ix = 0; ix < tokenArray.length; ix++) {
	     if (ix != 0) {
	         System.err.print(",");
	     }
	     System.err.print(tokenArray[ix].toString());
	 }
	 System.err.println("");
     }

     return tokenArray;
}

/**
  *-----------------------------------------------------------------------------
  *
  * GetNextToken --
  *
  *      Lexical analysis of the next token of input string.
  *
  * Results:
  *      A ClockToken representing the next token of the input string,
  * (parsePos was incremented accordingly), if one was found.
  * null otherwise (e.g. at end of input).
  *
  * Side effects:
  *      None.
  *
  *-----------------------------------------------------------------------------
  */

private ClockToken
GetNextToken (
     String in, 	 // String to parse
     ParsePosition parsePos // Current position in input
)
{
     int pos = parsePos.getIndex();
     int sign;

     while (true) {
         while (pos < in.length() && Character.isSpaceChar(in.charAt(pos))) {
	     pos++;
	 }
	 if (pos >= in.length()) {
	     break;
	 }

	 char c = in.charAt(pos);
	 if (Character.isDigit(c) || c == '-' || c == '+') {
	     if (c == '-' || c == '+') {
	         sign = c == '-' ? -1 : 1;
		 if (!Character.isDigit(in.charAt(++pos))) {
		     /*
		      * skip the '-' sign
		      */
		   continue;
		 }
	     } else {
	         sign = 0;
	     }
	     int number = 0;
	     while (pos < in.length()
		    && Character.isDigit(c = in.charAt(pos))) {
	         number = 10 * number + c - '0';
		 pos++;
	     }
	     if (sign < 0) {
	         number = -number;
	     }
	     parsePos.setIndex(pos);
	     return new ClockToken(number, sign != 0);
	 }
	 if (Character.isLetter(c)) {
	     int beginPos = pos;
	     while (++pos < in.length()) {
	         c = in.charAt(pos);
		 if (!Character.isLetter(c) && c != '.') {
		     break;
		 }
	     }
	     parsePos.setIndex(pos);
	     return LookupWord(in.substring(beginPos, pos));
	 }
	 parsePos.setIndex(pos+1);
	 return new ClockToken(in.charAt(pos));
     }
     parsePos.setIndex(pos+1);
     return null;
}

/**
  *-----------------------------------------------------------------------------
  *
  * LookupWord --
  *
  *      Construct a ClockToken for the given word.
  *
  * Results:
  *      A ClockToken representing the given word.
  *
  * Side effects:
  *      None.
  *
  *-----------------------------------------------------------------------------
  */

private ClockToken LookupWord(
     String word 	 // word to lookup
)
{
     int ix;
     String names[];
     String zones[][];

     if (word.equalsIgnoreCase("am") || word.equalsIgnoreCase("a.m.")) {
         return new ClockToken(ClockToken.MERIDIAN, Calendar.AM);
     }
     if (word.equalsIgnoreCase("pm") || word.equalsIgnoreCase("p.m.")) {
         return new ClockToken(ClockToken.MERIDIAN, Calendar.PM);
     }

     /*
      * See if we have an abbreviation for a day or month.
      */
     boolean abbrev;
     if (word.length() == 3) {
         abbrev = true;
     } else if (word.length() == 4 && word.charAt(3) == '.') {
         abbrev = true;
         word = word.substring(0, 3);
     } else {
         abbrev = false;
     }

     DateFormatSymbols symbols = new DateFormatSymbols(Locale.US);
     if (abbrev) {
         names = symbols.getShortMonths();
     } else {
         names = symbols.getMonths();
     }
     for (ix = 0; ix < names.length; ix++) {
         if (word.equalsIgnoreCase(names[ix])) {
	     return new ClockToken(ClockToken.MONTH, ix);
	 }
     }
     if (abbrev) {
         names = symbols.getShortWeekdays();
     } else {
         names = symbols.getWeekdays();
     }
     for (ix = 0; ix < names.length; ix++) {
         if (word.equalsIgnoreCase(names[ix])) {
	     return new ClockToken(ClockToken.DAY, ix);
	 }
     }

     /*
      * Drop out any periods and try the timezone table.
      */
     StringBuffer withoutDotsBuf = new StringBuffer(word.length());
     for (ix = 0; ix < word.length(); ix++) {
         if (word.charAt(ix) != '.') {
	     withoutDotsBuf.append(word.charAt(ix));
	 }
     }

     String withoutDots = new String(withoutDotsBuf);
     zones = symbols.getZoneStrings();

     for (ix = 0; ix < zones.length; ix++) {
         if (withoutDots.equalsIgnoreCase(zones[ix][2]) ||
	     withoutDots.equalsIgnoreCase(zones[ix][4])) {
 	     TimeZone zone = TimeZone.getTimeZone(zones[ix][0]);
	     return new ClockToken(ClockToken.ZONE, zone);
	 }
     }
     if (withoutDots.equalsIgnoreCase("dst")) {
	 return new ClockToken(ClockToken.DST, null);
     }

     /*
      * Strip off any plural and try the units.
      */
     String singular;
     if (word.endsWith("s")) {
         singular = word.substring(0, word.length()-1);
     } else {
         singular = word;
     }
     if (singular.equalsIgnoreCase("year")) {
	 return new ClockToken(ClockToken.MONTH_UNIT, 12);
     } else if (singular.equalsIgnoreCase("month")) {
	 return new ClockToken(ClockToken.MONTH_UNIT, 1);
     } else if (singular.equalsIgnoreCase("fortnight")) {
	 return new ClockToken(ClockToken.MINUTE_UNIT, 14*24*60);
     } else if (singular.equalsIgnoreCase("week")) {
	 return new ClockToken(ClockToken.MINUTE_UNIT, 7*24*60);
     } else if (singular.equalsIgnoreCase("day")) {
	 return new ClockToken(ClockToken.MINUTE_UNIT, 24*60);
     } else if (singular.equalsIgnoreCase("hour")) {
	 return new ClockToken(ClockToken.MINUTE_UNIT, 60);
     } else if (singular.equalsIgnoreCase("minute")) {
	 return new ClockToken(ClockToken.MINUTE_UNIT, 1);
     } else if (singular.equalsIgnoreCase("min")) {
	 return new ClockToken(ClockToken.MINUTE_UNIT, 1);
     } else if (singular.equalsIgnoreCase("second")) {
	 return new ClockToken(ClockToken.SEC_UNIT, 1);
     } else if (singular.equalsIgnoreCase("sec")) {
	 return new ClockToken(ClockToken.SEC_UNIT, 1);
     }

     if (singular.equalsIgnoreCase("tomorrow")) {
	 return new ClockToken(ClockToken.MINUTE_UNIT, 1*24*60);
     } else if (singular.equalsIgnoreCase("yesterday")) {
	 return new ClockToken(ClockToken.MINUTE_UNIT, -1*24*60);
     } else if (singular.equalsIgnoreCase("today")) {
	 return new ClockToken(ClockToken.MINUTE_UNIT, 0);
     } else if (singular.equalsIgnoreCase("now")) {
	 return new ClockToken(ClockToken.MINUTE_UNIT, 0);
     } else if (singular.equalsIgnoreCase("last")) {
	 return new ClockToken(-1, false);
     } else if (singular.equalsIgnoreCase("this")) {
	 return new ClockToken(ClockToken.MINUTE_UNIT, 0);
     } else if (singular.equalsIgnoreCase("next")) {
	 return new ClockToken(2, false);
     } else if (singular.equalsIgnoreCase("ago")) {
	 return new ClockToken(ClockToken.AGO, 1);
     } else if (singular.equalsIgnoreCase("epoch")) {
	 return new ClockToken(ClockToken.EPOCH, 0);
     }

     /*
      * Ignore military timezones.
      */

     return new ClockToken(word);
}

} // end ClockCmd

/**
  *-----------------------------------------------------------------------------
  *
  * CLASS ClockToken --
  *
  *      An object of this class represents a lexical unit of the human
  * readable date string. It can be one of the following variants:
  *
  * - signed number,
  *   = occurence can be asked by isSNumber(),
  *   = value can be retrieved by means of getInt();
  * - unsigned number,
  *   = occurence can be asked by isUNumber(),
  *   = value can be retrieved by means of getInt();
  * - a single character (delimiters like ':' or '/'),
  *   = occurence can be asked by is(), e.g. is('/');
  * - a word (like "January" or "DST")
  *   = occurence can be asked by is(), e.g. is(ClockToken.AGO);
  *   = value can be retrieved by means of getInt() or getZone().
  *
  *-----------------------------------------------------------------------------
  */

class ClockToken {
     final static int SNUMBER     = 1;
     final static int UNUMBER     = 2;
     final static int WORD        = 3;
     final static int CHAR        = 4;
     final static int MONTH       = 5;
     final static int DAY         = 6;
     final static int MONTH_UNIT  = 7;
     final static int MINUTE_UNIT = 8;
     final static int SEC_UNIT    = 9;
     final static int AGO         = 10;
     final static int EPOCH       = 11;
     final static int ZONE        = 12;
     final static int DAYZONE     = 13;
     final static int DST         = 14;
     final static int MERIDIAN    = 15;

     ClockToken(int number, boolean signed) {
         this.kind = signed ? SNUMBER : UNUMBER;
	 this.number = number;
     }
     ClockToken(int kind, int number) {
         this.kind = kind;
	 this.number = number;
     }
     ClockToken(int kind, TimeZone zone) {
         this.kind = kind;
	 this.zone = zone;
     }
     ClockToken(String word) {
         this.kind = WORD;
	 this.word = word;
     }
     ClockToken(char c) {
         this.kind = CHAR;
	 this.c = c;
     }

     public boolean isSNumber() {
         return kind == SNUMBER;
     }
     public boolean isUNumber() {
         return kind == UNUMBER;
     }
     public boolean is(char c) {
         return this.kind == CHAR && this.c == c;
     }
     public boolean is(int kind) {
         return this.kind == kind;
     }

     int getInt() {
         return number;
     }
     TimeZone getZone() {
         return zone;
     }

     public String toString() {
         if (isSNumber()) {
	     return "S"+Integer.toString(getInt());
	 } else if (isUNumber()) {
	     return "U"+Integer.toString(getInt());
	 } else if (kind == WORD) {
	     return word;
	 } else if (kind == CHAR) {
	     return new Character(c).toString();
	 } else if (kind == ZONE || kind == DAYZONE) {
	     return zone.getID();
	 } else {
	     return "("+kind+","+getInt()+")";
	 }
     }

     private int kind;
     private int number;
     private String word;
     private char c;
     private TimeZone zone;
} // end ClockToken

/**
  *-----------------------------------------------------------------------------
  *
  * CLASS ClockRelTimespan --
  *
  *      An object of this class can be used to track the time difference during
  * the analysis of a relative time specification.
  *
  * It has two read only properties 'seconds' and 'months', which are set
  * to 0 during initialization and which can be modified by means of the
  * addSeconds(), addMonths() and negate() methods.
  *
  *-----------------------------------------------------------------------------
  */

class ClockRelTimespan {
     ClockRelTimespan() {
         seconds = 0;
	 months = 0;
     }
     void addSeconds(int s) {
         seconds += s;
     }
     void addMonths(int m) {
         months += m;
     }
     void negate() {
         seconds = -seconds;
         months = -months;
     }
     int getSeconds() {
         return seconds;
     }
     int getMonths() {
         return months;
     }
     private int seconds;
     private int months;
}
*** Interp.java.org Fri Nov  6 23:38:15 1998
--- Interp.java Mon Dec 28 13:33:25 1998
***************
*** 647,652 ****
--- 647,653 ----
       Extension.loadOnDemand(this, "case",   "tcl.lang.CaseCmd");
       Extension.loadOnDemand(this, "catch",   "tcl.lang.CatchCmd");
       Extension.loadOnDemand(this, "cd",   	  "tcl.lang.CdCmd");
+     Extension.loadOnDemand(this, "clock",   "tcl.lang.ClockCmd");
       Extension.loadOnDemand(this, "close",   "tcl.lang.CloseCmd");
       Extension.loadOnDemand(this, "continue",  	  "tcl.lang.ContinueCmd");
       Extension.loadOnDemand(this, "concat",   "tcl.lang.ConcatCmd");
*** all.org Wed Nov 11 01:52:53 1998
--- all Mon Dec 28 13:35:42 1998
***************
*** 16,22 ****
       # These are currently the tests that Jacl can pass comfortably.
       # (ToDo) Add others!

!     set fileList {append assocd case concat error eval expr
  	 fileName for format get
           if incr info join lindex linsert list llength lrange
  	 lreplace lsort parse parseOld pkg proc regexp rename scan set split
--- 16,22 ----
       # These are currently the tests that Jacl can pass comfortably.
       # (ToDo) Add others!

!     set fileList {append assocd case clock concat error eval expr
  	 fileName for format get
           if incr info join lindex linsert list llength lrange
  	 lreplace lsort parse parseOld pkg proc regexp rename scan set split
# Commands covered:  clock
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright (c) 1995-1997 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# SCCS: @(#) clock.test 1.17 97/11/24 15:05:38

if {[string compare test [info procs test]] == 1} then {source defs}

test clock-1.1 {clock tests} {
     list [catch {clock} msg] $msg
} {1 {wrong # args: should be "clock option ?arg ...?"}}
test clock-1.2 {clock tests} {
     list [catch {clock foo} msg] $msg
} {1 {bad option "foo": must be clicks, format, scan, or seconds}}

# clock clicks
test clock-2.1 {clock clicks tests} {
     expr [clock clicks]+1
     concat {}
} {}
test clock-2.2 {clock clicks tests} {
     list [catch {clock clicks foo} msg] $msg
} {1 {wrong # args: should be "clock clicks"}}
test clock-2.3 {clock clicks tests} {
     set start [clock clicks]
     after 10
     set end [clock clicks]
     expr "$end > $start"
} {1}

# clock format
test clock-3.1 {clock format tests} {unixOnly} {
     set clockval 657687766
     clock format $clockval -format {%a %b %d %I:%M:%S %p %Y} -gmt true
} {Sun Nov 04 03:02:46 AM 1990}
test clock-3.2 {clock format tests} {
     list [catch {clock format} msg] $msg
} {1 {wrong # args: should be "clock format clockval ?-format string? ?-gmt
boolean?"}}
test clock-3.3 {clock format tests} {
     list [catch {clock format foo} msg] $msg
} {1 {expected integer but got "foo"}}
test clock-3.4 {clock format tests} {unixOrPc} {
     set clockval 657687766
     clock format $clockval -format "%a %b %d %I:%M:%S %p %Y" -gmt true
} "Sun Nov 04 03:02:46 AM 1990"
test clock-3.5 {clock format tests} {
     list [catch {clock format a b c d e g} msg] $msg
} {1 {wrong # args: should be "clock format clockval ?-format string? ?-gmt
boolean?"}}
test clock-3.6 {clock format tests} {unixOrPc nonPortable} {
     set clockval -1
     clock format $clockval -format "%a %b %d %I:%M:%S %p %Y" -gmt true
} "Wed Dec 31 11:59:59 PM 1969"
test clock-3.7 {clock format tests} {
     list [catch {clock format 123 -bad arg} msg] $msg
} {1 {bad switch "-bad": must be -format, or -gmt}}
test clock-3.8 {clock format tests} {
     clock format 123 -format "x"
} x
test clock-3.9 {clock format tests} {
     clock format 123 -format ""
} ""

# clock scan
test clock-4.1 {clock scan tests} {
     list [catch {clock scan} msg] $msg
} {1 {wrong # args: should be "clock scan dateString ?-base clockValue? ?-gmt
boolean?"}}
test clock-4.2 {clock scan tests} {
     list [catch {clock scan "bad-string"} msg] $msg
} {1 {unable to convert date-time string "bad-string"}}
test clock-4.3 {clock scan tests} {
     clock format [clock scan "14 Feb 92" -gmt true] \
       -format {%m/%d/%y %I:%M:%S %p} -gmt true
} {02/14/92 12:00:00 AM}
test clock-4.4 {clock scan tests} {
     clock format [clock scan "Feb 14, 1992 12:20 PM" -gmt true] \
       -format {%m/%d/%y %I:%M:%S %p} -gmt true
} {02/14/92 12:20:00 PM}
test clock-4.5 {clock scan tests} {
     clock format \
       [clock scan "Feb 14, 1992 12:20 PM" -base 319363200 -gmt true] \
       -format {%m/%d/%y %I:%M:%S %p} -gmt true
} {02/14/92 12:20:00 PM}
test clock-4.6 {clock scan tests} {
     set time [clock scan "Oct 23,1992 15:00"]
     clock format $time -format {%b %d,%Y %H:%M}
} {Oct 23,1992 15:00}
test clock-4.7 {clock scan tests} {
     set time [clock scan "Oct 23,1992 15:00 GMT"]
     clock format $time -format {%b %d,%Y %H:%M GMT} -gmt true
} {Oct 23,1992 15:00 GMT}
test clock-4.8 {clock scan tests} {
     set time [clock scan "Oct 23,1992 15:00" -gmt true]
     clock format $time -format {%b %d,%Y %H:%M GMT} -gmt true
} {Oct 23,1992 15:00 GMT}
test clock-4.9 {clock scan tests} {
     list [catch {clock scan "Jan 12" -bad arg} msg] $msg
} {1 {bad switch "-bad": must be -base, or -gmt}}
# The following two two tests test the two year date policy
test clock-4.10 {clock scan tests} {
     set time [clock scan "1/1/71" -gmt true]
     clock format $time -format {%b %d,%Y %H:%M GMT} -gmt true
} {Jan 01,1971 00:00 GMT}
test clock-4.11 {clock scan tests} {
     set time [clock scan "1/1/37" -gmt true]
     clock format $time -format {%b %d,%Y %H:%M GMT} -gmt true
} {Jan 01,2037 00:00 GMT}

# clock seconds
test clock-5.1 {clock seconds tests} {
     expr [clock seconds]+1
     concat {}
} {}
test clock-5.2 {clock seconds tests} {
     list [catch {clock seconds foo} msg] $msg
} {1 {wrong # args: should be "clock seconds"}}
test clock-5.3 {clock seconds tests} {
     set start [clock seconds]
     after 2000
     set end [clock seconds]
     expr "$end > $start"
} {1}

# The following dates check certain roll over dates
set day [expr 24 * 60 * 60]
test clock-6.1 {clock roll over dates} {
     set time [clock scan "12/31/1998" -gmt true]
     clock format [expr $time + $day] -format {%b %d,%Y %H:%M GMT} -gmt true
} {Jan 01,1999 00:00 GMT}
test clock-6.2 {clock roll over dates} {
     set time [clock scan "12/31/1999" -gmt true]
     clock format [expr $time + $day] -format {%b %d,%Y %H:%M GMT} -gmt true
} {Jan 01,2000 00:00 GMT}
test clock-6.3 {clock roll over dates} {
     set time [clock scan "2/28/2000" -gmt true]
     clock format [expr $time + $day] -format {%b %d,%Y %H:%M GMT} -gmt true
} {Feb 29,2000 00:00 GMT}
test clock-6.4 {clock roll over dates} {
     set time [clock scan "2/29/2000" -gmt true]
     clock format [expr $time + $day] -format {%b %d,%Y %H:%M GMT} -gmt true
} {Mar 01,2000 00:00 GMT}
test clock-6.5 {clock roll over dates} {
     set time [clock scan "January 1, 2000" -gmt true]
     clock format $time -format %A -gmt true
} {Saturday}
test clock-6.6 {clock roll over dates} {
     set time [clock scan "January 1, 2000" -gmt true]
     clock format $time -format %j -gmt true
} {001}
test clock-6.7 {clock roll over dates} {
     set time [clock scan "February 29, 2000" -gmt true]
     clock format $time -format %A -gmt true
} {Tuesday}
test clock-6.8 {clock roll over dates} {
     set time [clock scan "February 29, 2000" -gmt true]
     clock format $time -format %j -gmt true
} {060}
test clock-6.9 {clock roll over dates} {
     set time [clock scan "March 1, 2000" -gmt true]
     clock format $time -format %A -gmt true
} {Wednesday}
test clock-6.10 {clock roll over dates} {
     set time [clock scan "March 1, 2000" -gmt true]
     clock format $time -format %j -gmt true
} {061}
test clock-6.11 {clock roll over dates} {
     set time [clock scan "March 1, 2001" -gmt true]
     clock format $time -format %j -gmt true
} {060}

#6 From: Moses DeJong <dejong@...>
Date: Wed Dec 23, 1998 9:52 pm
Subject: [Tcl Java] Re: release schedule
dejong@...
Send Email Send Email
 
Well, Tcl Blend and Jacl are not really commercial products so they do not
have a "release schedule". I am currently working on a number of features
and bug fixes that will be going into the beta release. Once the beta
release is done no "new features" will be going in and only bug fixes
(and perhaps unimplemented commands) will be worked on. The only real
answer I can give you is that the 1.1 final will be released
"when it is done".

Mo DeJong
dejong@...
gimme multimedia group

On Tue, 22 Dec 1998, Philip Chu wrote:

> I just joined this list, so forgive me if this has been answered recently:
> What is the release schedule for TclBlend? In particular, when will
> TclBlend 1.1 final be released? I would like to use it in a commercial
> product.
>
> --
> Phil Chu
> philipchu@... http://www.technicat.com/
>
> ----------------------------------------------------------------
> The TclJava mailing list is sponsored by WebNet Technologies.
> To subscribe:    send mail to TclJava-request@...
>                  with the word SUBSCRIBE as the subject.
> To unsubscribe:  send mail to TclJava-request@...
>                  with the word UNSUBSCRIBE as the subject.
> To send to the list, send email to 'TclJava@...'.
> A list archive is at: http://www.findmail.com/listsaver/tcldallas/
>

----------------------------------------------------------------
The TclJava mailing list is sponsored by WebNet Technologies.
To subscribe:    send mail to TclJava-request@...
                  with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to TclJava-request@...
                  with the word UNSUBSCRIBE as the subject.
To send to the list, send email to 'TclJava@...'.
A list archive is at: http://www.findmail.com/listsaver/tcldallas/

#5 From: Philip Chu <philipchu@...>
Date: Wed Dec 23, 1998 7:14 am
Subject: [Tcl Java] release schedule
philipchu@...
Send Email Send Email
 
I just joined this list, so forgive me if this has been answered recently:
What is the release schedule for TclBlend? In particular, when will
TclBlend 1.1 final be released? I would like to use it in a commercial
product.

--
Phil Chu
philipchu@... http://www.technicat.com/

----------------------------------------------------------------
The TclJava mailing list is sponsored by WebNet Technologies.
To subscribe:    send mail to TclJava-request@...
                  with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to TclJava-request@...
                  with the word UNSUBSCRIBE as the subject.
To send to the list, send email to 'TclJava@...'.
A list archive is at: http://www.findmail.com/listsaver/tcldallas/

#4 From: Christopher Hylands <cxh@...>
Date: Tue Dec 15, 1998 10:26 pm
Subject: [Tcl Java] Re: [Request Jacl ] Applet support
cxh@...
Send Email Send Email
 
Jacl works in applets, with limitations.
Check out:
http://ptolemy.eecs.berkeley.edu/~cxh/java/jaclapplet/index.html

The biggest limitation is that commands like 'java::new' does not
work.   If you are not interfacing directly to java, then Jacl might
provide enough functionality for you.


-Christopher

--------

     Jacl  Request

     Name:  Howard Jess
     email:  howard@...
     Synopsis:  Applet support

     DesiredBehavior:
     Mostly interested in web-based applications: we have a largish system that
    uses TCL scripts for CGI; we'd like to leverage our TCL knowledge in buildin
    g browser-based applications.  So far, JACL doesn't support applets, but JPy
    thon does. We'd rather stick with TCL, if JACL support were possible.
--------

----------------------------------------------------------------
The TclJava mailing list is sponsored by WebNet Technologies.
To subscribe:    send mail to TclJava-request@...
                  with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to TclJava-request@...
                  with the word UNSUBSCRIBE as the subject.
To send to the list, send email to 'TclJava@...'.
A list archive is at: http://www.findmail.com/listsaver/tcldallas/

#3 From: Christian Krone <krischan@...>
Date: Wed Dec 2, 1998 2:11 pm
Subject: [Tcl Java] BUG: TclJava1.1a1 JDK1.2 WinNT: JOptionPane freezes Application
krischan@...
Send Email Send Email
 
Hello,

I'm working with TclBlend 1.1a1 and JDK1.2 on WinNT for two weeks now
and most of the time I'm really happy: Good work, Chris+Mo!

But meanwhile I found some -mostly small- bugs (buggies?),
which I will report here on this mailinglist (one after the other).

Usage of javax.swing.JOptionPane freezes the whole application!
May be, there is something wrong in thread control?
It must be a problem of TclJava, since the corresponding program in
pure Java is working fine, but it fails with Jacl and TclBlend.

Here are the two programs, first the tcl one, then the Java stuff:

--------------------------------------------------------------------------------

package require java

proc keyPressed {} {
     java::call javax.swing.JOptionPane showMessageDialog \
	     [java::null] "This is a very important message" "Wow!" \
	     [java::field javax.swing.JOptionPane INFORMATION_MESSAGE]
}

set this [java::new javax.swing.JFrame "Dialog-Test"]
java::bind $this keyPressed keyPressed
$this setSize 400 200
[$this getContentPane] add [java::new javax.swing.JLabel \
	 "Press any key, then wait and see..."]
$this show

# The funny lines below will go into the event loop,
# if we are running under a tclsh, wish or jaclsh...
if {[info globals tk_version] != ""} {
     wm withdraw .
     catch {console hide}
} else {
     vwait forever
}

--------------------------------------------------------------------------------

import javax.swing.*;
import java.awt.event.*;

public class Dialog extends KeyAdapter implements KeyListener {

public void keyPressed (KeyEvent e) {
   JOptionPane.showMessageDialog (null, "This is a very important message",
				  "Wow!", JOptionPane.INFORMATION_MESSAGE);
}

public Dialog () {
   JFrame f = new JFrame ("Dialog-Test");
   f.setSize (400, 200);
   f.addKeyListener (this);
   f.getContentPane ().add (new JLabel ("Press any key, then wait and see..."));
   f.show ();
}

public static void main(String args[]) {
   Dialog f = new Dialog ();
}
}

--------------------------------------------------------------------------------

Thanks for listening, Krischan
--
Christian Krone, SQL Datenbanksysteme GmbH
Mail mailto:krischan@...

----------------------------------------------------------------
The TclJava mailing list is sponsored by WebNet Technologies.
To subscribe:    send mail to TclJava-request@...
                  with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to TclJava-request@...
                  with the word UNSUBSCRIBE as the subject.
To send to the list, send email to 'TclJava@...'.
A list archive is at: http://www.findmail.com/listsaver/tcldallas/

#2 From: Bryan Surles <surles@...>
Date: Tue Dec 1, 1998 9:47 pm
Subject: [Tcl Java] Java/Perl Tool Available As Open Source Software
surles@...
Send Email Send Email
 
>FOR IMMEDIATE RELEASE
>December 1, 1998
>
>FURTHER INFORMATION CONTACT
>Ellen Maremont Silver
>(707)829-0515 ext. 322  silver@...
>http://www.oreilly.com/
>
>JAVA/PERL TOOL AVAILABLE AS OPEN SOURCE SOFTWARE
>Programmers Can Use Strengths of Two Popular Languages in the Same
>Environment
>
>Sebastopol, CA--Java/Perl Lingo (JPL), software which enables
>programmers to use the use the strengths of both Java and Perl in the
>same environment, is now freely available as open source software.
>Until now, the tool has been available exclusively in O'Reilly &
>Associates' Perl Resource Kit-UNIX Edition, a commercial product. JPL
>was developed by Larry Wall, creator of Perl and Senior Software
>Developer at O'Reilly & Associates.
>
>JPL, available since November, 1997, is a unique project whose goal is
>to seamlessly unite the two popular languages in a way which lets them
>complement each other's strengths. Java excels at helping computers
>across a network or the Internet communicate and share data; Perl is
>used especially for system administration and interactive Web sites.
>JPL enables programmers to implement Java methods with Perl, and for
>Perl code to access Java via the Java Native Interface (JNI). It
>includes a translator and build system that make it easy to create JPL
>applications.
>
>The JPL tool and its source code are available as part of the latest
>development release of Perl (version 5.005_54) and can be obtained at
>http://www.perl.com/. Subscription information for the JPL mailing list
>is available at http://www.perl.org/maillist.html/.
>
>"O'Reilly has been a strong supporter of open source software, so
>releasing JPL as open source matches our company values," said Gina
>Blaber, Director of O'Reilly's Software Products. "JPL will benefit
>from the attention of the broader development community. Further, our
>Perl books and software are an important part of the O'Reilly business,
>so we want to thank and support the open source community by making the
>JPL source available."
>
>O'Reilly first released the Perl Resource Kit-UNIX in November, 1997,
>and followed it in August with the Perl Resource Kit-Win32 Edition.
>
>#  #  #

----------------------------------------------------------------
The TclJava mailing list is sponsored by WebNet Technologies.
To subscribe:    send mail to TclJava-request@...
                  with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to TclJava-request@...
                  with the word UNSUBSCRIBE as the subject.
To send to the list, send email to 'TclJava@...'.
A list archive is at: http://www.findmail.com/listsaver/tcldallas/

#1 From: Moses DeJong <dejong@...>
Date: Tue Dec 1, 1998 3:54 am
Subject: [Tcl Java] Re: Problem with Cast
dejong@...
Send Email Send Email
 
Hey John!

> Hey Mo!
>
> > > Now I need to go
> >
> > Did you set that tcl_platform(javaCastNeeded) variable yourself? I have
> > never seen that before.
>
> I set it myself, because I needed a flag to test for
> whether I needed the cast...
>
>
> > This depends on what types the Java objects are returned as
> > in the methods.
> >
> > > 1. I have to do extra work to cast most of the objects
> > > I get back from Java methods.
>
> I said "most." I understand how it works, my point
> is that *most* of the time in *real* code I seem to
> be calling methods that are overridden, which means
> that I have to downcast the result. I already explained
> why this is bogus.

To be honest, I do not see how it would be easy to explain the
1.0 behavior to anyone that has worked with any OO system. I
did not invent this OO stuff so I am not going to defend it
but at the very least the interface between tcl and jacl should
respect the OO "rules of the road".

> > True, the docs need some work before the beta is released.
> >
> > > 3. It's going to be hard to explain and teach to
> > > Tcl programmers.
>
> I didn't say hard to document, I said hard to explain.
> They're not the same thing. Writing documentation
> isn't going to fix the problem.

This really is a feature that "can not be removed". It is not
just a matter of adding a command of something. This behavior
is at the lowest level of the interaction between tcl and java.
If it were possible to add a "no typing" feature we might do it,
but it is not so there is no reason to argue about it.

> > That is not possible. This is not a "feature" that was
> > added on to anything. This is now the "behavior" and
> > the only way to not use it is by using the 1.0 version.
> > There were so many changes needed to get this to work
> > that removing the "feature" is no longer an option.
> >
> > > Anyway, I'm reverting to 1.0 so I can get some work
> > > done. I think the 1.1 team should seriously consider
> > > removing this feature.
>
> "That is not possible"? Come off it, Mo, it's code,
> not Mt Rushmore... What I'm telling you is that this
> "feature" is just not working. At the least, consider
> an option to allow it to be turned off. Please?


I know, I know, Tcl is not typed and Java is. My point is
that when you use the two together you have to respect the
rules for both languages as much as possible. All things
being equal, I would vote for the thing that was easy to
code. In this situation the "easy to code" argument
falls flat on its face because in 1.0 you were able to do
things to Java objects from Tcl code that would not be
allowed in Java code. I have also attempted to ignore
the role of object types in method invocations in this
thread. This handy new feature in 1.1 would be very
difficult to implement properly if the reflected objects
were not typed (like in 1.0).


> > Ok, the main point I want to make about this "new feature"
> > is that it is not really a feature as much as it is a bug
> > fix. The 1.0 version did not keep track of the type of
> > Java objects. This means that in some instances (like the
> > situation you describe where Java objects were typed as
> > java.lang.Object) it would be "easier" to use because
> > the upcast from Object to whatever could be avoided, but
> > there are other situations where this "behavior" would
> > lead to voilations of the Java language specification.
> > I am not going to try to rehash this with an example
> > or anything but I can point you to the HTML version of my
> > paper from the Tcl conference (of course if you have the
> > proceedings you could just look at that). Section 5 has
> > a number of examples of why the behavior in 1.0 was bad
> > and why the new 1.1 behavior is good.
> >
> > http://www.cs.umn.edu/~dejong/tcl/paper.html
>
> This example doesn't say WHY the 1.1 behaviour is
> good. It just says it is "consistent with object-oriented
> principles", much as above you talk about "violating
> the Java language specification." But that's irrelevant
> here -- we are coding in Tcl, which is neither typed
> nor object-oriented. Give me ONE decent example that
> says WHY it is better.


Example at bottom of email.


> > I know that is "seems" like a little more work to use
> > the java::cast command but it really is better in the
> > long run. Another nice feature that 1.1 gives you
> > is the ability to use Java interface classes which
> > were not accessable in 1.0. Yet another nice feature that
> > is not described in my paper or the docs is the fact
> > that Java array objects are typed and the elements of
> > the arrays are typed in 1.1.
>
> Can you give us an example of using interface classes?
>
> > I hope that helps
>
> No, not really.
>
> JohnR
>
> > Mo DeJong
> > dejong@...
> >
>
>



Ok, here is attempt #2 at why the new system is better. The class
could be saved as simple.java and the commands at the bottom can
be run inside jacl or tclblend.


public class simple implements simple.inter {

     public static interface inter {
	 public void allowed();
     }

     public void allowed() {
	 System.out.println("allowed");
     }

     public void not_allowed() {
	 System.out.println("NOT allowed");
	 System.exit(-1);
     }

     public static Object getAsObject() {
	 return new simple();
     }

     public static inter getAsInterface() {
	 return new simple();
     }

}


/*

Example of regular object use.

%set o [java::call simple getAsObject]

%java::info class $o

1.0 returns "simple"
1.1 returns "java.lang.Object"


%$o allowed

This would print "allowed" in 1.0
This would fail in 1.1 because type is "Object" not "simple" (this is the
correct behavior)



Example of interface use (new in 1.1).

%set i [java::call simple getAsInterface]

%java::info class $i

1.0 would think the object type is "simple"
1.1 would see the object as an interface called "inter"
(ignore the fact that inter is an inner class, that is just so
that you only have to save this as a single simple.java file).


%$i allowed

This would work in 1.0 and 1.1

%$i not_allowed

1.0 this INCORRECT invocation would be allowed because 1.0 did not
understand Java interfaces.

1.1 this method would be rejected because the method "not_allowed"
is not defined for the interface "inter".

*/



I hope that helps
mo dejong
dejong at cs.umn.edu

----------------------------------------------------------------
The TclJava mailing list is sponsored by WebNet Technologies.
To subscribe:    send mail to TclJava-request@...
                  with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to TclJava-request@...
                  with the word UNSUBSCRIBE as the subject.
To send to the list, send email to 'TclJava@...'.
A list archive is at: http://www.findmail.com/listsaver/tcldallas/

Messages 1 - 30 of 1276   Newest  |  < Newer  |  Older >  |  Oldest
Advanced
Add to My Yahoo!      XML What's This?

Copyright © 2009 Yahoo! Inc. All rights reserved.
Privacy Policy - Terms of Service - Guidelines - Help