+---------- 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"
        }
    }

Reply via email to