Commit 37d2649e authored by Leigh B. Stoller's avatar Leigh B. Stoller

Convert all of the new template code to PHP "classes." This was not as

much "fun" as the Perl conversion, but nothing about PHP is as much
fun as it is in perl.
parent 7e219a4a
...@@ -34,7 +34,7 @@ sub usage() ...@@ -34,7 +34,7 @@ sub usage()
"-E <str> - A pithy sentence describing the template\n". "-E <str> - A pithy sentence describing the template\n".
"-g <gid> - The group in which to create the experiment\n". "-g <gid> - The group in which to create the experiment\n".
"<pid> - The project in which to create the experiment\n". "<pid> - The project in which to create the experiment\n".
"<tid> - The template name (unique, alphanumeric, no blanks)\n". "<tid> - The template name (alphanumeric, no blanks)\n".
"<input> - Input file for experiment.\n"); "<input> - Input file for experiment.\n");
exit(-1); exit(-1);
} }
...@@ -305,6 +305,9 @@ system("$makegraph $guid"); ...@@ -305,6 +305,9 @@ system("$makegraph $guid");
fatal(-1, "Error generating template graph.") fatal(-1, "Error generating template graph.")
if ($?); if ($?);
# Web interface depends on this line. Bad; need another way to send
# back the newly generated guid/version.
print "Template $guid/$vers has been created\n";
exit(0); exit(0);
# #
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
# All rights reserved. # All rights reserved.
# #
include("defs.php3"); include("defs.php3");
include("template_defs.php"); include_once("template_defs.php");
# #
# Only known and logged in users ... # Only known and logged in users ...
...@@ -52,28 +52,26 @@ if (!TBvalid_integer($runidx)) { ...@@ -52,28 +52,26 @@ if (!TBvalid_integer($runidx)) {
PAGEHEADER("Experiment Run"); PAGEHEADER("Experiment Run");
# #
# Check to make sure this is a valid template. # Check to make sure this is a valid template and user has permission.
# #
if (! TBValidExperimentTemplate($guid, $version)) { $template = Template::Lookup($guid, $version);
if (!$template) {
USERERROR("The experiment template $guid/$version is not a valid ". USERERROR("The experiment template $guid/$version is not a valid ".
"experiment template!", 1); "experiment template!", 1);
} }
if (! TBIsTemplateInstanceExperiment($exptidx)) { if (! $template->AccessCheck($uid, $TB_EXPT_READINFO)) {
USERERROR("You do not have permission to view experiment template ".
"$guid/$version!", 1);
}
$instance = TemplateInstance::LookupByExptidx($exptidx);
if (!$instance) {
USERERROR("The instance $exptidx is not a valid instance in ". USERERROR("The instance $exptidx is not a valid instance in ".
"template $guid/$version!", 1); "template $guid/$version!", 1);
} }
if (! TBValidExperimentRun($exptidx, $runidx)) { if (! $instance->ValidRun($runidx)) {
USERERROR("The run $runidx is not a valid experiment run!", 1); USERERROR("The run $runidx is not a valid experiment run!", 1);
} }
#
# Verify Permission.
#
if (! TBExptTemplateAccessCheck($uid, $guid, $TB_EXPT_READINFO)) {
USERERROR("You do not have permission to view experiment template ".
"$guid/$version!", 1);
}
echo "<font size=+2>Experiment Run<b> " . echo "<font size=+2>Experiment Run<b> " .
MakeLink("instance", MakeLink("instance",
"guid=$guid&version=$version&exptidx=$exptidx", "guid=$guid&version=$version&exptidx=$exptidx",
...@@ -82,7 +80,7 @@ echo "<font size=+2>Experiment Run<b> " . ...@@ -82,7 +80,7 @@ echo "<font size=+2>Experiment Run<b> " .
echo "<br><br>\n"; echo "<br><br>\n";
SHOWEXPERIMENTRUN($exptidx, $runidx); $instance->ShowRun($runidx);
# #
# Standard Testbed Footer # Standard Testbed Footer
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
# All rights reserved. # All rights reserved.
# #
include("defs.php3"); include("defs.php3");
include("template_defs.php"); include_once("template_defs.php");
# #
# Only known and logged in users ... # Only known and logged in users ...
...@@ -45,24 +45,22 @@ if (!TBvalid_integer($exptidx)) { ...@@ -45,24 +45,22 @@ if (!TBvalid_integer($exptidx)) {
PAGEHEADER("Template Instance"); PAGEHEADER("Template Instance");
# #
# Check to make sure this is a valid template. # Check to make sure this is a valid template and user has permission.
# #
if (! TBValidExperimentTemplate($guid, $version)) { $template = Template::Lookup($guid, $version);
if (!$template) {
USERERROR("The experiment template $guid/$version is not a valid ". USERERROR("The experiment template $guid/$version is not a valid ".
"experiment template!", 1); "experiment template!", 1);
} }
if (! TBIsTemplateInstanceExperiment($exptidx)) { if (! $template->AccessCheck($uid, $TB_EXPT_READINFO)) {
USERERROR("The instance $exptidx is not a valid instance in ".
"template $guid/$version!", 1);
}
#
# Verify Permission.
#
if (! TBExptTemplateAccessCheck($uid, $guid, $TB_EXPT_READINFO)) {
USERERROR("You do not have permission to view experiment template ". USERERROR("You do not have permission to view experiment template ".
"$guid/$version!", 1); "$guid/$version!", 1);
} }
$instance = TemplateInstance::LookupByExptidx($exptidx);
if (!$instance) {
USERERROR("The instance $exptidx is not a valid instance in ".
"template $guid/$version!", 1);
}
echo "<font size=+2>Template Instance <b>" . echo "<font size=+2>Template Instance <b>" .
MakeLink("template", MakeLink("template",
...@@ -70,7 +68,7 @@ echo "<font size=+2>Template Instance <b>" . ...@@ -70,7 +68,7 @@ echo "<font size=+2>Template Instance <b>" .
"</b></font>\n"; "</b></font>\n";
echo "<br><br>\n"; echo "<br><br>\n";
SHOWTEMPLATEINSTANCE($guid, $version, $exptidx, 1); $instance->Show(1);
# #
# Standard Testbed Footer # Standard Testbed Footer
......
...@@ -72,7 +72,7 @@ sajax_handle_client_request(); ...@@ -72,7 +72,7 @@ sajax_handle_client_request();
# Faster to do this after the sajax stuff # Faster to do this after the sajax stuff
include("showstuff.php3"); include("showstuff.php3");
include("template_defs.php"); include_once("template_defs.php");
# #
# Need some DB info. # Need some DB info.
...@@ -97,11 +97,15 @@ $panic_date = $row["panic_date"]; ...@@ -97,11 +97,15 @@ $panic_date = $row["panic_date"];
$lockdown = $row["lockdown"]; $lockdown = $row["lockdown"];
# Template Instance Experiments get special treatment in this page. # Template Instance Experiments get special treatment in this page.
$isinstance = ($EXPOSETEMPLATES && $instance = NULL;
TBIsTemplateInstanceExperiment($expindex) ? 1 : 0); if ($EXPOSETEMPLATES) {
if ($isinstance) { $instance = TemplateInstance::LookupByExptidx($expindex);
$tag = "Template Instance";
TBPidEid2Template($pid, $eid, $guid, $version, $instance_idx); if (! is_null($instance)) {
$tag = "Template Instance";
$guid = $instance->guid();
$vers = $instance->vers();
}
} }
# #
...@@ -189,7 +193,7 @@ if ($expstate) { ...@@ -189,7 +193,7 @@ if ($expstate) {
} }
elseif ($expstate == $TB_EXPTSTATE_ACTIVE || elseif ($expstate == $TB_EXPTSTATE_ACTIVE ||
($expstate == $TB_EXPTSTATE_PANICED && $isadmin)) { ($expstate == $TB_EXPTSTATE_PANICED && $isadmin)) {
WRITESUBMENUBUTTON(($isinstance ? WRITESUBMENUBUTTON(($instance ?
"Terminate Instance" : "Terminate Instance" :
"Swap Experiment Out"), "Swap Experiment Out"),
"swapexp.php3?inout=out&pid=$exp_pid&eid=$exp_eid"); "swapexp.php3?inout=out&pid=$exp_pid&eid=$exp_eid");
...@@ -201,23 +205,23 @@ if ($expstate) { ...@@ -201,23 +205,23 @@ if ($expstate) {
} }
} }
if (!$isinstance && $expstate != $TB_EXPTSTATE_PANICED) { if (!$instance && $expstate != $TB_EXPTSTATE_PANICED) {
WRITESUBMENUBUTTON("Terminate Experiment", WRITESUBMENUBUTTON("Terminate Experiment",
"endexp.php3?pid=$exp_pid&eid=$exp_eid"); "endexp.php3?pid=$exp_pid&eid=$exp_eid");
} }
# Batch experiments can be modifed only when paused. # Batch experiments can be modifed only when paused.
if (!$isinstance && ($expstate == $TB_EXPTSTATE_SWAPPED || if (!$instance && ($expstate == $TB_EXPTSTATE_SWAPPED ||
(!$isbatch && $expstate == $TB_EXPTSTATE_ACTIVE))) { (!$isbatch && $expstate == $TB_EXPTSTATE_ACTIVE))) {
WRITESUBMENUBUTTON("Modify Experiment", WRITESUBMENUBUTTON("Modify Experiment",
"modifyexp.php3?pid=$exp_pid&eid=$exp_eid"); "modifyexp.php3?pid=$exp_pid&eid=$exp_eid");
} }
} }
if ($isinstance && $expstate == $TB_EXPTSTATE_ACTIVE) { if ($instance && $expstate == $TB_EXPTSTATE_ACTIVE) {
WRITESUBMENUBUTTON("Start New Experiment Run", WRITESUBMENUBUTTON("Start New Experiment Run",
"template_exprun.php?action=start&guid=$guid". "template_exprun.php?action=start&guid=$guid".
"&version=$version&eid=$exp_eid"); "&version=$vers&eid=$exp_eid");
} }
if ($expstate == $TB_EXPTSTATE_ACTIVE) { if ($expstate == $TB_EXPTSTATE_ACTIVE) {
...@@ -293,7 +297,7 @@ WRITESUBMENUDIVIDER(); ...@@ -293,7 +297,7 @@ WRITESUBMENUDIVIDER();
WRITESUBMENUBUTTON("Show History", WRITESUBMENUBUTTON("Show History",
"showstats.php3?showby=expt&which=$expindex"); "showstats.php3?showby=expt&which=$expindex");
if (!$isinstance && STUDLY()) { if (!$instance && STUDLY()) {
WRITESUBMENUBUTTON("Duplicate Experiment", WRITESUBMENUBUTTON("Duplicate Experiment",
"beginexp_html.php3?copyid=${exp_pid},${exp_eid}"); "beginexp_html.php3?copyid=${exp_pid},${exp_eid}");
} }
...@@ -408,11 +412,11 @@ if (TBExptFirewall($exp_pid, $exp_eid) && ...@@ -408,11 +412,11 @@ if (TBExptFirewall($exp_pid, $exp_eid) &&
} }
SUBPAGEEND(); SUBPAGEEND();
if ($isinstance && if ($instance &&
($expstate == $TB_EXPTSTATE_ACTIVE || ($expstate == $TB_EXPTSTATE_ACTIVE ||
$expstate == $TB_EXPTSTATE_PANICED || $expstate == $TB_EXPTSTATE_PANICED ||
$expstate == $TB_EXPTSTATE_ACTIVATING)) { $expstate == $TB_EXPTSTATE_ACTIVATING)) {
SHOWTEMPLATEINSTANCEBINDINGS($guid, $version, $instance_idx); $instance->ShowBindings();
} }
# #
......
...@@ -129,7 +129,10 @@ function STARTLOG($pid, $eid) ...@@ -129,7 +129,10 @@ function STARTLOG($pid, $eid)
</script>\n"; </script>\n";
echo "<br>\n"; echo "<br>\n";
echo "<img id='busy' src='busy.gif'><span id='loading'> Loading...</span>"; echo "<center>\n";
echo "<img id='busy' src='busy.gif'>
<span id='loading'> Working ...</span>";
echo "</center>\n";
echo "<br>\n"; echo "<br>\n";
echo "<div><iframe id='outputframe' src='busy.gif' ". echo "<div><iframe id='outputframe' src='busy.gif' ".
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
# #
# Functions to dump out various things. # Functions to dump out various things.
# #
include_once("template_defs.php");
# #
# A project # A project
...@@ -863,16 +864,17 @@ function SHOWEXP($pid, $eid, $short = 0, $sortby = "") { ...@@ -863,16 +864,17 @@ function SHOWEXP($pid, $eid, $short = 0, $sortby = "") {
</tr>\n"; </tr>\n";
if (!$short) { if (!$short) {
$isinstance = (TBIsTemplateInstanceExperiment($exptidx) ? 1 : 0); $instance = TemplateInstance::LookupByExptidx($exptidx);
if ($isinstance) { if (! is_null($instance)) {
TBPidEid2Template($pid, $eid, $guid, $version, $instance_idx); $guid = $instance->guid();
$vers = $instance->vers();
echo "<tr> echo "<tr>
<td>Template: </td> <td>Template: </td>
<td class=\"left\"> <td class=\"left\">
<a href='template_show.php?guid=$guid&version=$version'> <a href='template_show.php?guid=$guid&version=$vers'>
$guid/$version</a></td> $guid/$vers</a></td>
</tr>\n"; </tr>\n";
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
# #
include("defs.php3"); include("defs.php3");
include("showstuff.php3"); include("showstuff.php3");
include("template_defs.php"); include_once("template_defs.php");
# #
# Only known and logged in users can do this. # Only known and logged in users can do this.
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
# All rights reserved. # All rights reserved.
# #
include("defs.php3"); include("defs.php3");
include("template_defs.php"); include_once("template_defs.php");
# #
# Only known and logged in users can begin experiments. # Only known and logged in users can begin experiments.
...@@ -109,19 +109,17 @@ if (isset($guid) && isset($version)) { ...@@ -109,19 +109,17 @@ if (isset($guid) && isset($version)) {
if (!TBvalid_tinyint($version)) { if (!TBvalid_tinyint($version)) {
PAGEARGERROR("Invalid GUID version"); PAGEARGERROR("Invalid GUID version");
} }
# #
# Check to make sure this is a valid template. # Check to make sure this is a valid template and user has permission.
# #
if (! TBValidExperimentTemplate($guid, $version)) { $template = Template::Lookup($guid, $version);
if (!$template) {
USERERROR("The experiment template $guid/$version is not a valid ". USERERROR("The experiment template $guid/$version is not a valid ".
"experiment template!", 1); "experiment template!", 1);
} }
if (! $template->AccessCheck($uid, $TB_EXPT_READINFO)) {
# USERERROR("You do not have permission to modify experiment template ".
# Verify Permission.
#
if (! TBExptTemplateAccessCheck($uid, $guid, $TB_EXPT_READINFO)) {
USERERROR("You do not have permission to view experiment template ".
"$guid/$version!", 1); "$guid/$version!", 1);
} }
header("Content-Type: text/plain"); header("Content-Type: text/plain");
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
# #
include("defs.php3"); include("defs.php3");
include("showstuff.php3"); include("showstuff.php3");
include("template_defs.php"); include_once("template_defs.php");
# #
# Only known and logged in users can end experiments. # Only known and logged in users can end experiments.
...@@ -100,9 +100,13 @@ if (! TBExptAccessCheck($uid, $exp_pid, $exp_eid, $TB_EXPT_MODIFY)) { ...@@ -100,9 +100,13 @@ if (! TBExptAccessCheck($uid, $exp_pid, $exp_eid, $TB_EXPT_MODIFY)) {
} }
# Template Instance Experiments get special treatment in this page. # Template Instance Experiments get special treatment in this page.
$isinstance = $EXPOSETEMPLATES && TBIsTemplateInstanceExperiment($exptidx); $instance = NULL;
if ($isinstance && $inout != "out") { if ($EXPOSETEMPLATES) {
PAGEARGERROR("Invalid action for template instance"); $instance = TemplateInstance::LookupByExptidx($exptidx);
if (! is_null($instance) && $inout != "out") {
PAGEARGERROR("Invalid action for template instance");
}
} }
# Convert inout to informative text. # Convert inout to informative text.
...@@ -133,7 +137,7 @@ elseif (!strcmp($inout, "restart")) { ...@@ -133,7 +137,7 @@ elseif (!strcmp($inout, "restart")) {
$action = "restart"; $action = "restart";
} }
if ($isinstance) { if ($instance) {
echo "<font size=+2>Template Instance <b>"; echo "<font size=+2>Template Instance <b>";
} }
else { else {
...@@ -162,7 +166,7 @@ if (!$confirmed) { ...@@ -162,7 +166,7 @@ if (!$confirmed) {
if ($force) { if ($force) {
echo "<font color=red><br>forcibly</br></font> "; echo "<font color=red><br>forcibly</br></font> ";
} }
if ($isinstance) { if ($instance) {
echo "terminate template instance"; echo "terminate template instance";
} }
else { else {
...@@ -226,10 +230,10 @@ if (!$confirmed) { ...@@ -226,10 +230,10 @@ if (!$confirmed) {
# #
TBGroupUnixInfo($exp_pid, $exp_gid, $unix_gid, $unix_name); TBGroupUnixInfo($exp_pid, $exp_gid, $unix_gid, $unix_name);
if ($isinstance) { if ($instance) {
if (! TBPidEid2Template($exp_pid, $exp_eid, $guid, $version, $instidx)) { $guid = $instance->guid();
TBERROR("Could not map $pid/$eid to its template!", 1); $version = $instance->vers();
}
echo "<br>\n"; echo "<br>\n";
echo "<b>Terminating template instance!</b> ... "; echo "<b>Terminating template instance!</b> ... ";
echo "this will take a few minutes; please be patient."; echo "this will take a few minutes; please be patient.";
...@@ -253,7 +257,7 @@ $args = ($idleswap ? "-i" : ($autoswap ? "-a" : "")); ...@@ -253,7 +257,7 @@ $args = ($idleswap ? "-i" : ($autoswap ? "-a" : ""));
$retval = SUEXEC($uid, "$exp_pid,$unix_gid", $retval = SUEXEC($uid, "$exp_pid,$unix_gid",
($force ? ($force ?
"webidleswap $args $exp_pid $exp_eid" : "webidleswap $args $exp_pid $exp_eid" :
($isinstance ? ($instance ?
"webtemplate_swapout -e $exp_eid $guid/$version" : "webtemplate_swapout -e $exp_eid $guid/$version" :
"webswapexp -s $inout $exp_pid $exp_eid")), "webswapexp -s $inout $exp_pid $exp_eid")),
SUEXEC_ACTION_IGNORE); SUEXEC_ACTION_IGNORE);
...@@ -279,7 +283,7 @@ if ($retval) { ...@@ -279,7 +283,7 @@ if ($retval) {
echo "<blockquote><pre>$suexec_output<pre></blockquote>"; echo "<blockquote><pre>$suexec_output<pre></blockquote>";
} }
else { else {
if ($isinstance) { if ($instance) {
STARTLOG($pid, $eid); STARTLOG($pid, $eid);
} }
elseif ($isbatch) { elseif ($isbatch) {
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
# All rights reserved. # All rights reserved.
# #
include("defs.php3"); include("defs.php3");
include("template_defs.php"); include_once("template_defs.php");
# #
# No PAGEHEADER since we spit out a Location header later. See below. # No PAGEHEADER since we spit out a Location header later. See below.
...@@ -310,9 +310,6 @@ if (!isset($formfields[tid]) || $formfields[tid] == "") { ...@@ -310,9 +310,6 @@ if (!isset($formfields[tid]) || $formfields[tid] == "") {
elseif (!TBvalid_eid($formfields[tid])) { elseif (!TBvalid_eid($formfields[tid])) {
$errors["Template ID"] = TBFieldErrorString(); $errors["Template ID"] = TBFieldErrorString();
} }
elseif (TBValidExperimentTemplate($formfields[pid], $formfields[tid])) {
$errors["Template ID"] = "Already in use";
}
# #
# Description: # Description:
...@@ -507,23 +504,26 @@ if ($retval) { ...@@ -507,23 +504,26 @@ if ($retval) {
return; return;
} }
unset($guid); #
if (TBPidTid2Template($pid, $tid, $guid, $version)) { # Parse the last line of output. Ick.
#
if (preg_match("/^Template\s+(\w+)\/(\w+)\s+/",
$suexec_output_array[count($suexec_output_array)-1],
$matches)) {
$guid = $matches[1];
$vers = $matches[2];
echo "<script type='text/javascript' language='javascript'>\n"; echo "<script type='text/javascript' language='javascript'>\n";
echo "PageReplace('template_show.php?guid=$guid&version=$version');\n"; echo "PageReplace('template_show.php?guid=$guid&version=$vers');\n";
echo "</script>\n"; echo "</script>\n";
} }
# #
# In case the above fails. # In case the above fails.
# #
echo "Done!"; echo "<center><b>Done!</b></center>";
echo "<br><br>\n"; echo "<br><br>\n";
if (isset($guid)) {
SHOWTEMPLATE($guid, $version);
}
# #
# Standard Testbed Footer # Standard Testbed Footer
# #
......
This diff is collapsed.
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
# All rights reserved. # All rights reserved.
# #
include("defs.php3"); include("defs.php3");
include("template_defs.php"); include_once("template_defs.php");
# #
# No PAGEHEADER since we spit out a Location header later. See below. # No PAGEHEADER since we spit out a Location header later. See below.
...@@ -28,7 +28,7 @@ $deletexmlfile = 0; ...@@ -28,7 +28,7 @@ $deletexmlfile = 0;
# #
# Spit the form out using the array of data. # Spit the form out using the array of data.
# #
function SPITFORM($formfields, $parameters, $errors) function SPITFORM($instance, $formfields, $parameters, $errors)
{ {
global $TBDB_EIDLEN; global $TBDB_EIDLEN;
global $guid, $version, $eid; global $guid, $version, $eid;
...@@ -36,7 +36,8 @@ function SPITFORM($formfields, $parameters, $errors) ...@@ -36,7 +36,8 @@ function SPITFORM($formfields, $parameters, $errors)
PAGEHEADER("Start an Experiment Run"); PAGEHEADER("Start an Experiment Run");
echo "<center>\n"; echo "<center>\n";
SHOWTEMPLATE($guid, $version); $template = $instance->template();
$template->Show();
echo "</center>\n"; echo "</center>\n";
echo "<br><br>\n"; echo "<br><br>\n";
...@@ -171,38 +172,33 @@ if (!TBvalid_eid($eid)) { ...@@ -171,38 +172,33 @@ if (!TBvalid_eid($eid)) {
} }
# #
# Check to make sure this is a valid template. # Check to make sure this is a valid template and user has permission.
# #
if (! TBValidExperimentTemplate($guid, $version)) { $template = Template::Lookup($guid, $version);
if (!$template) {
USERERROR("The experiment template $guid/$version is not a valid ". USERERROR("The experiment template $guid/$version is not a valid ".
"experiment template!", 1); "experiment template!", 1);
} }
if (! $template->AccessCheck($uid, $TB_EXPT_MODIFY)) {
# Need this below. USERERROR("You do not have permission to modify experiment template ".
if (! TBGuid2PidGid($guid, $pid, $gid)) { "$guid/$version!", 1);
TBERROR("Could not get template pid,gid for template $guid", 1);
} }
# Need these below.
$pid = $template->pid();
$gid = $template->gid();
if (($exptidx = TBExptIndex($pid, $eid)) < 0) { if (($exptidx = TBExptIndex($pid, $eid)) < 0) {
TBERROR("Could not instance IDX for template instance $guid/$eid", 1); TBERROR("No such experiment '$eid' for template $guid/$version/$eid", 1);
} }
# #
# Check to make sure and a valid instance that is actually swapped in. # Check to make sure and a valid instance that is actually swapped in.
# #
if (! TBValidExperimentTemplateInstance($guid, $version, $exptidx)) { $instance = TemplateInstance::LookupByExptidx($exptidx);
USERERROR("Experiment Template Instance $guid/$version/$exptidx is not ". if (!$instance) {
"a valid experiment template instance!", 1); TBERROR("Template Instance $guid/$version/$exptidx is not ".
}