2006-06-10 19:08:23 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
require_once("docutil.php");
|
|
|
|
page_head("Simple validator framework");
|
|
|
|
echo "
|
|
|
|
To create a validator using the simple framework,
|
2007-01-23 21:37:27 +00:00
|
|
|
you must supply four functions:
|
2006-06-10 19:08:23 +00:00
|
|
|
"; block_start(); echo "
|
|
|
|
extern int init_result(RESULT& result, void*& data);
|
|
|
|
"; block_end(); echo "
|
|
|
|
This takes a result, reads its output file(s),
|
|
|
|
parses them into a memory structure,
|
|
|
|
and returns (via the 'data' argument) a pointer to this structure.
|
|
|
|
It returns:
|
|
|
|
<ul>
|
|
|
|
<li> Zero on success,
|
|
|
|
<li> ERR_OPENDIR if there was a transient error,
|
|
|
|
e.g. the output file is on a network volume that is not available.
|
|
|
|
The validator will try this result again later.
|
|
|
|
<li> Any other return value indicates a permanent error.
|
|
|
|
Example: an output file is missing, or has a syntax error.
|
|
|
|
The result will be marked as invalid.
|
|
|
|
</ul>
|
|
|
|
"; block_start(); echo "
|
|
|
|
extern int compare_results(
|
2007-01-04 15:54:10 +00:00
|
|
|
RESULT& r1, void* data1, RESULT& r2, void* data2, bool& match
|
2006-06-10 19:08:23 +00:00
|
|
|
);
|
|
|
|
"; block_end(); echo "
|
|
|
|
This takes two results and their associated memory structures.
|
|
|
|
It returns (via the 'match' argument) true if the two results
|
|
|
|
are equivalent (within the tolerances of the application).
|
|
|
|
"; block_start(); echo "
|
|
|
|
extern int cleanup_result(RESULT& r, void* data);
|
|
|
|
"; block_end(); echo "
|
|
|
|
This frees the structure pointed to by data, if it's non-NULL.
|
2007-01-23 21:37:27 +00:00
|
|
|
"; block_start(); echo "
|
|
|
|
extern double compute_granted_credit(vector<RESULT>& results);
|
|
|
|
"; block_end(); echo "
|
|
|
|
Given a set of results (at least one of which is valid)
|
|
|
|
compute the credit to be granted to all of them.
|
|
|
|
We recommend that this function simply return
|
|
|
|
<code>median_mean_credit(results);</code>
|
2006-06-10 19:08:23 +00:00
|
|
|
<p>
|
|
|
|
You must link these functions with the files
|
|
|
|
validator.C, validate_util.C, and validate_util2.C.
|
|
|
|
The result is your custom validator.
|
|
|
|
|
|
|
|
<h3>Example</h3>
|
|
|
|
Here's an example in which the output file
|
|
|
|
contains an integer and a double.
|
|
|
|
Two results are considered equivalent if the integer is equal
|
|
|
|
and the doubles differ by no more than 0.01.
|
|
|
|
<p>
|
|
|
|
This example uses utility functions
|
|
|
|
get_output_file_path() and try_fopen(),
|
|
|
|
which are documented <a href=backend_util.php>here</a>.
|
|
|
|
"; block_start(); echo "
|
|
|
|
struct DATA {
|
|
|
|
int i;
|
|
|
|
double x;
|
|
|
|
};
|
|
|
|
|
2007-01-23 21:37:27 +00:00
|
|
|
int init_result(RESULT const & result, void*& data) {
|
2006-06-10 19:08:23 +00:00
|
|
|
FILE* f;
|
|
|
|
string path;
|
|
|
|
int i, n, retval;
|
|
|
|
double x;
|
|
|
|
|
|
|
|
retval = get_output_file_path(result, path);
|
|
|
|
if (retval) return retval;
|
|
|
|
retval = try_fopen(path.c_str(), f, \"r\");
|
|
|
|
if (retval) return retval;
|
|
|
|
n = fscanf(f, \"%d %f\", &i, &x);
|
|
|
|
if (n != 2) return ERR_XML_PARSE;
|
|
|
|
DATA* dp = new DATA;
|
|
|
|
dp->i = i;
|
|
|
|
dp->x = x;
|
|
|
|
data = (void*) dp;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-01-23 21:37:27 +00:00
|
|
|
int compare_results(
|
|
|
|
RESULT& r1, void* _data1, RESULT const& r2, void* _data2, bool& match
|
2006-06-10 19:08:23 +00:00
|
|
|
) {
|
|
|
|
DATA* data1 = (DATA*)_data1;
|
|
|
|
DATA* data2 = (DATA*)_data2;
|
|
|
|
match = true;
|
|
|
|
if (data1->i != data2->i) match = false;
|
|
|
|
if (fabs(data1->x - data2->x) > 0.01) match = false;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int cleanup_result(RESULT& r, void* data) {
|
2007-01-23 22:29:19 +00:00
|
|
|
if (data) delete (DATA*) data;
|
2006-06-10 19:08:23 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
"; block_end(); echo "
|
|
|
|
";
|
|
|
|
page_tail();
|
|
|
|
?>
|