+---------- On Jan 20, Jim Davidson said:
> No, it doesn't. Each "chunk" of ADP must be a valid Tcl script as they're
> all executed independently. A parser which could handle the above would
> basically convert the whole page into a single script. Downside with that
> solution is an error anywhere in the page would generally result in no output
> which is why it's not done that way. Perhaps it could be a config option,
> maybe mapped to specfic files when the single-script approach would be
> useful?
You could combine the two features. Accumulate enough alternating
code/text blocks to get a complete set of Tcl commands (as defined by
"info complete" or Tcl_CommandComplete). Wrap that up as one chunk
of error-protected script. Sometimes the chunk will contain just one
<%...%> block, and sometimes it will be several (with interspersed
raw text blocks). This approach is completely compatible with all ADP
scripts supported by the existing system.
Here's the algorithm expressed as a Tcl script. (It could easily be done
in C too.) Suppose the ADP has been parsed into a list of alternating
chunks of raw text and Tcl code, stored in variable `chunks'. Let the
first chunk always be raw text. This code creates a Tcl program in
variable `script' that represents the entire ADP.
set script ""
set partial_script ""
foreach {text code} $chunks {
# First, handle the raw text chunk. If we have no partial
# script accumulated, we'll just append a print command
# to the full script. If we do have a partial script
# accumulated, we append the print command to the partial
# script.
set svar [expr {$partial_script == "" ? script : partial_script}]
append $svar [list ns_adp_puts -nonewline $text] "\n"
# Now handle the code chunk. Append it to the (possibly empty)
# partial script.
append partial_script $code
# Now see if the partial_script is complete and non-empty.
# If so, append it to the full script.
if {[info complete $partial_script] && $partial_script != ""} {
append script [list _ns_adp_eval_code $partial_script] "\n"
set partial_script ""
}
}
if {$partial_script != ""} {
# We expect that _ns_adp_eval_code will always get an
# error on this partial script, but oh well...
append script [list _ns_adp_eval_code $partial_script] "\n"
}
You need one new run-time command, _ns_adp_eval_code. It's pretty
simple:
proc _ns_adp_eval_code {script} {
set code [catch {uplevel 1 $script} result]
if {$code != 0} {
ns_log Error "[ns_conn url]: ADP script evaluation error: code $code,
result [list $result], traceback:\n$::errorInfo"
}
}