R
Roedy Green
If you look at my website, mindprod.com, you will see that a large
part of it is generated by various computer programs.
If I run the output through HTMLValidator, or eyeball it, or view it
in a browser, it is generally pretty easy to find errors. The hard
part is figuring out where that error was generated in the
corresponding code.
I had an idea years ago for a tool to solve that problem, but no one
was interested. It worked like this:
In debug mode there is a hook in the text-output functions to,
whenever you write a line, makes a log entry including the offset in
the file and where in the program it called the io that wrote it.
The log entry would be in compact binary (something like serialized
ObjectStream), but in essence it would look something like this:
at com.mindprod.prices.Prices.emitDetailsAndManual line:1059
The output is perfectly normal and you can do anything you would
normally do with it. However, there a magic viewer for the file.
When you right click on any character, it will tell you the program
and line number that wrote it. It looks the filename and offset up in
the log file, which is massaged to make finding fast.
I needed such a tool tonight, but I had too many things on my plate
and did not have time. Further I did not know how to insert the hook
without changing the names of the io methods.
So I cooked up something a little more primitive.
/**
* tell you where in the code you are, class/method/line
*
* @param depth Set to 1 if you call youAreHere directly.
* Set to 2 if you call it indirectly via a piece of
code that
* does something with the String it generates, and
you
* really want the location of its caller.
*/
public static String youAreHere( int depth )
{
final Throwable t = new Throwable();
final StackTraceElement[] es = t.getStackTrace();
final StackTraceElement e = es[ depth ];
return "at "
+ e.getClassName()
+ "."
+ e.getMethodName()
+ " line:"
+ e.getLineNumber();
}
I then peppered my code with calls to this method. I inserted the
String it gives back into the output stream inline, as an HTML
comment.
<!-- at com.mindprod.prices.Prices.emitDetailsAndManual line:1059 -->
By turning a debug switch on and off I could control
whether these comments were inserted.
There is a problem. You can't just insert <!-- ... --> ANYWHERE in
HTML. So I had to manually back off and suppress the insertion in
spots where the comment could confuse an HTML parser, e.g. inside
comments or inside macros which are officially comments. If I had a
tool such as above, that would not be a problem. The generated stream
would be intact no matter where I made my log entries.
part of it is generated by various computer programs.
If I run the output through HTMLValidator, or eyeball it, or view it
in a browser, it is generally pretty easy to find errors. The hard
part is figuring out where that error was generated in the
corresponding code.
I had an idea years ago for a tool to solve that problem, but no one
was interested. It worked like this:
In debug mode there is a hook in the text-output functions to,
whenever you write a line, makes a log entry including the offset in
the file and where in the program it called the io that wrote it.
The log entry would be in compact binary (something like serialized
ObjectStream), but in essence it would look something like this:
at com.mindprod.prices.Prices.emitDetailsAndManual line:1059
The output is perfectly normal and you can do anything you would
normally do with it. However, there a magic viewer for the file.
When you right click on any character, it will tell you the program
and line number that wrote it. It looks the filename and offset up in
the log file, which is massaged to make finding fast.
I needed such a tool tonight, but I had too many things on my plate
and did not have time. Further I did not know how to insert the hook
without changing the names of the io methods.
So I cooked up something a little more primitive.
/**
* tell you where in the code you are, class/method/line
*
* @param depth Set to 1 if you call youAreHere directly.
* Set to 2 if you call it indirectly via a piece of
code that
* does something with the String it generates, and
you
* really want the location of its caller.
*/
public static String youAreHere( int depth )
{
final Throwable t = new Throwable();
final StackTraceElement[] es = t.getStackTrace();
final StackTraceElement e = es[ depth ];
return "at "
+ e.getClassName()
+ "."
+ e.getMethodName()
+ " line:"
+ e.getLineNumber();
}
I then peppered my code with calls to this method. I inserted the
String it gives back into the output stream inline, as an HTML
comment.
<!-- at com.mindprod.prices.Prices.emitDetailsAndManual line:1059 -->
By turning a debug switch on and off I could control
whether these comments were inserted.
There is a problem. You can't just insert <!-- ... --> ANYWHERE in
HTML. So I had to manually back off and suppress the insertion in
spots where the comment could confuse an HTML parser, e.g. inside
comments or inside macros which are officially comments. If I had a
tool such as above, that would not be a problem. The generated stream
would be intact no matter where I made my log entries.