#lang scribble/doc @(require "common.ss") @title{Utils} @defmodule[handin-server/utils] @; JBC: have eli verify these contracts? @defproc[(get-conf [key symbol?]) any/c]{ Returns a value from the configuration file (useful for reading things like field names, etc.).} @defproc[(unpack-submission [submission bytes?]) (values (is-a?/c text%) (is-a?/c text%))]{ Returns two @scheme[text%] objects corresponding to the submitted definitions and interactions windows.} @defproc[(make-evaluator/submission [language (or/c module-path? (list/c (one-of/c 'special) symbol?) (list/c (one-of/c 'module) module-path?) (cons/c (one-of/c 'begin) list?))] [require-paths (listof path-string?)] [content bytes?]) (any/c . -> . any)]{ Like @scheme[make-evaluator], but the definitions content is supplied as a submission byte string. The byte string is opened for reading, with line-counting enabled. In addition to the language specification for @scheme[make-evaluator], the @scheme[language] argument can be a list that begins with @scheme['module]. In this case, @scheme[make-module-language] is used to create an evaluator, and the module code must be using the the specified language in its language position. In this case, the @scheme[requires-paths] argument is used only for paths that are allowed to be accessed (the @scheme[_allow-read] argument to @scheme[make-evaluator], since the submission is expected to be a complete submission.)} @defproc[(call-with-evaluator [language (or/c module-path? (list/c (one-of/c 'special) symbol?) (list/c (one-of/c 'module) module-path?) (cons/c (one-of/c 'begin) list?))] [require-paths (listof path-string?)] [input-program any/c] [proc (any/c . -> . any)]) any]{ Calls @scheme[proc] with an evaluator for the given language, teachpack paths, and initial definition content as supplied by @scheme[input-program] (see @scheme[make-evaluator]). It also sets the current error-value print handler to print values in a way suitable for @scheme[language], it initializes @scheme[set-run-status] with @scheme["executing your code"], and it catches all exceptions to re-raise them in a form suitable as a submission error. See @scheme[make-evaluator/submission] for further details.} @defproc[(call-with-evaluator/submission [language (or/c module-path? (list/c (one-of/c 'special) symbol?) (list/c (one-of/c 'module) module-path?) (cons/c (one-of/c 'begin) list?))] [require-paths (listof path-string?)] [submission bytes?] [proc (any/c . -> . any)]) any]{ Like @scheme[call-with-evaluator], but the definitions content is supplied as a byte string. The byte string is opened for reading, with line-counting enabled. See @scheme[call-with-evaluator] and @scheme[make-evaluator/submission] for further details.} @; JBC: this contract is probably wrong @; JBC: does this eval accept an optional namespace? @defproc[(evaluate-all [source any] [input-port port?] [eval (any/c . -> . any)]) any]{ Like @scheme[load] on an input port.} @defproc[(evaluate-submission [submission bytes?] [eval (any/c . -> . any)]) any]{ Like @scheme[load] on a submission byte string.} @defproc[(check-proc [eval (any/c . -> . any)] [expect-v any/c] [compare-proc (any/c any/c . -> . any)] [proc-name symbol?] [arg any/c] ...) any]{ Calls the function named @scheme[proc-name] using the evaluator @scheme[eval], giving it the (unquoted) arguments @scheme[arg ...] Let @scheme[result-v] be the result of the call; unless @scheme[(compare-proc result-v expect-v)] is true, an exception is raised.} Every exception or result mismatch during the call to @scheme[compare-proc] is phrased suitably for the handin client. @defproc[(check-defined [eval (any/c . -> . any)] [name symbol?]) any]{ Checks whether @scheme[name] is defined in the evaluator @scheme[eval], and raises an error if not (suitably phrased for the handin client). If it is defined as non-syntax, its value is returned. Warning: in the beginner language level, procedure definitions are bound as syntax.} @; JBC: returns what? signals error? @defproc[(look-for-tests [text (is-a?/c text%)] [name symbol?] [n number?]) any]{ Inspects the given @scheme[text%] object to determine whether it contains at least @scheme[n] tests for the function @scheme[name]. The tests must be top-level expressions.} @defproc[(user-construct [eval (any/c . -> . any)] [name symbol?] [arg any/c] ...) any]{ Like @scheme[check-proc], but with no result checking. This function is often useful for calling a student-defined constructor.} @defparam[test-history-enabled on? any/c]{ Controls how run-time errors are reported to the handin client. If the parameter's value is true, then the complete sequence of tested expressions is reported to the handin client for any test failure. Set this parameter to true when testing programs that use state.} @defproc*[([(message [string string?]) void?] [(message [string string?] [styles (or/c (symbols 'final) (listof (one-of/c 'ok 'ok-cancel 'yes-no 'caution 'stop)))]) any])]{ If given only a string, this string will be shown on the client's submission dialog; if @scheme[styles] is also given, it can be the symbol @scheme['final], which will be used as the text on the handin dialog after a successful submission instead of ``Handin successful.'' (useful for submissions that were saved, but had problems); finally, @scheme[styles] can be used as a list of styles for a @scheme[message-box] dialog on the client side, and the resulting value is returned as the result of @scheme[message]. You can use this to send warnings to the student or ask confirmation.} @defproc[(set-run-status [status (or/c false? string?)]) void?]{ Registers information about the current actions of the checker, in case the session is terminated due to excessive memory consumption or a timeout. For example, a checker might set the status to indicate which instructor-supplied test was being executed when the session aborted.} @defparam[current-value-printer proc (any/c . -> . string?)]{ Controls how values are printed. The @scheme[proc] must be a procedure that expects a Scheme value and returns a string representation for it. The default value printer uses @scheme[pretty-print], with DrScheme-like settings.} @defproc[(reraise-exn-as-submission-problem [thunk (-> any)]) any]{ Calls @scheme[thunk] in a context that catches exceptions and re-raises them in a form suitable as a submission error. It returns the value returned by @scheme[thunk] if no exception occurs.} @defproc[(log-line [fmt string?] [args any/c] ...) void?]{ Produces a line in the server log file, using the given format string and arguments. This function arranges to print the line fast (to avoid mixing lines from different threads) to the error port, and flush it. (The log port will prefix all lines with a time stamp and a connection identifier.)} @defproc[(timeout-control [msg string?]) void?]{ Controls the timeout for this session. The timeout is initialized by the value of the @scheme[session-timeout] configuration entry, and the checker can use this procedure to further control it: if @scheme[msg] is @scheme['reset] the timeout is reset to @scheme[session-timeout] seconds; if @scheme[msg] is a number the timeout will be set to that many seconds in the future. The timeout can be completely disabled by @scheme[(timeout-control #f)]. (Note that before the checker is used (after the pre-checker, if specified), the timer will be reset to the @scheme['session-timeout] value.)}