25#define XNAME_LENGTH 256
71 pp = (
char *) pattern;
97void strsubst(
char *
string,
int size,
const char *pattern,
const char *
subst)
114 s = size - (p - string);
129 snprintf(buf,
sizeof(buf),
"%d", v);
134 std::string buf =
"l=\"" + std::to_string(line) +
"\"";
135 buf +=
" fn=\"" + filename +
"\"";
137 buf +=
" lvl=\"" + std::to_string(
level) +
"\"";
141static std::string
q(
const char *s) {
142 return "\"" + std::string(s) +
"\"";
149 std::stringstream
ss;
155 else if (
num == 0 && s[0] !=
'0')
169 seq.error_line =
seq.current_line_number;
170 seq.serror_line =
seq.scurrent_line_number;
181 cm_msg(
MTALK,
"sequencer",
"Sequencer has stopped with error.");
201 for (
i = 0; *p &&
i < size;
i++) {
208 if (*p ==
'"' && *(p + 1) ==
'"') {
211 }
else if (*p ==
'"') {
263extern char *
stristr(
const char *
str,
const char *pattern);
280 while ((
i1 = (
int)result.find(
"$")) != (
int)std::string::npos) {
281 std::string s = result.substr(
i1 + 1);
282 if (std::isdigit(s[0])) {
284 for (
i2 =
i1 + 1; std::isdigit(result[
i2]);)
289 if (
seq.stack_index > 0) {
290 std::istringstream f(
seq.subroutine_param[
seq.stack_index - 1]);
291 std::vector<std::string>
param;
293 while (std::getline(f,
sp,
','))
296 throw "Parameter \"$" + std::to_string(
index) +
"\" not valid";
301 throw "Parameter \"$" + std::to_string(
index) +
"\" not valid";
304 for (
i2 =
i1 + 1; std::isalnum(result[
i2]) || result[
i2] ==
'_';)
306 s = s.substr(0,
i2 -
i1 - 1);
307 if (result[
i2] ==
'[') {
311 if (
i == (
int)std::string::npos)
312 throw "Variable \"" + result +
"\" does not contain ']'";
319 throw "Variable \"" + s +
"\" has invalid index";
324 std::vector<std::string>
sv =
o;
327 throw "Variable \"" + s +
"\" not found";
329 while (result[
i2] && result[
i2] !=
']')
332 throw "Variable \"" + result +
"\" does not contain ']'";
333 if (result[
i2] ==
']')
338 throw "Variable \"" + s +
"\" not found";
342 throw "Variable \"" + s +
"\" not found";
347 result = result.substr(0,
i1) +
vsubst + result.substr(
i2);
353 if (result.find(
",") != std::string::npos)
358 double r =
te_interp(result.c_str(), &error);
361 if (!std::isdigit(result[0]) && result[0] !=
'-')
364 throw "Error in expression \"" + result +
"\" position " + std::to_string(error - 1);
368 return std::to_string((
int) r);
370 return std::to_string(r);
382 for (
i = 0;
i <
n;
i++) {
399 p = (
char *)condition;
431 for (
i++;
str[
i] ==
' ';
i++);
476 if (((
unsigned int)
value1 & (
unsigned int)
value2) > 0)
486 std::ifstream
file(filename);
490 std::vector<std::string>
lines;
494 while (std::getline(
file, line))
495 lines.push_back(line);
498 o->WSA(
"Script/Lines",
lines, 0);
506 char *error,
int error_size,
int *error_line) {
510 std::string
xml, path, fn;
516 snprintf(error,
error_size,
"More than 10 nested INCLUDE statements exceeded in file \"%s\"", filename);
521 path = std::string(
cpath);
522 if (path.length() > 0 && path.back() !=
'/')
561 char* buf = (
char *)
malloc(size + 1);
585 if (*(
pe - 1) ==
'\r') {
596 xml +=
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n";
597 xml +=
"<!DOCTYPE RunSequence [\n";
614 if (
list[1][0] ==
'/') {
616 p +=
"userfiles/sequencer";
620 if (!p.empty() && p.back() !=
'/')
632 size = p.length() + 1 + 4;
645 path +=
"userfiles/sequencer/";
659 xml +=
"<Library name=\"";
668 xml +=
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n";
673 xml +=
"<RunSequence xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"\">\n";
676 std::vector<std::string>
slines;
677 for (line = 0; line <
n_lines; line++) {
681 c->odbs->WSA(
"Script/Lines",
slines, 0);
684 std::string p =
"/" +
c->odb_path +
"/Param/Value";
691 c->odbs->Delete(
"Variables");
692 c->odbs->Delete(
"Param");
695 for (line = 0; line <
n_lines; line++) {
696 char *p =
lines[line];
706 for (
i = 0;
i <
n;
i++) {
707 if (
list[
i][0] ==
'#') {
708 for (
j =
i;
j <
n;
j++)
715 for (
i = 0;
i <
n;
i++) {
721 for (
i = 0;
i <
n;
i++) {
733 nq = (
nq == 0 ? 1 : 0);
734 if (
eq[
i] ==
'=' &&
nq == 0 &&
735 (
i > 0 && (
eq[
i - 1] !=
'!') &&
eq[
i - 1] !=
'<' &&
eq[
i - 1] !=
'>'))
738 if (
n == 1 &&
eq[0] !=
'=') {
772 for (
i = 2;
i < 100 &&
list[
i][0];
i++) {
782 for (
i = 2;
i < 100 &&
list[
i][0];
i++) {
828 if (
list[2][0] == 0) {
830 }
else if (
list[3][0] == 0) {
835 for (
i = 2;
i < 100 &&
list[
i][0];
i++) {
851 if (
list[2][0] ==
'1')
852 xml +=
" wait=\"1\"";
855 xml +=
"</Message>\n";
872 q(
list[2]) +
"></ODBCreate>\n";
884 list[2] +
"</ODBSet>\n";
901 " string=" +
q(
list[2]) +
">" +
list[3] +
"</ODBLookup>\n";
913 xml +=
"</ODBSubdir>\n";
918 *error_line = line + 1;
924 c->odbs->RB((std::string(
"Param/Value/") +
list[1]).
c_str(), &v,
true);
925 c->odbs->WS((std::string(
"Param/Comment/") +
list[1]).
c_str(),
list[2]);
929 bool v(
def ==
"1" ||
def ==
"true" ||
def ==
"TRUE");
930 c->odbs->RB((std::string(
"Param/Value/") +
list[1]).
c_str(), &v,
true);
931 c->odbs->WS((std::string(
"Param/Comment/") +
list[1]).
c_str(),
list[2]);
932 c->odbs->WS((std::string(
"Param/Defaults/") +
list[1]).
c_str(),
list[3]);
934 }
else if (!
list[3][0]) {
937 c->odbs->RS((std::string(
"Param/Value/") +
list[1]).
c_str(), &v,
true);
938 c->odbs->WS((std::string(
"Param/Comment/") +
list[1]).
c_str(),
list[2]);
939 }
else if (!
list[4][0]) {
941 std::string v(
list[3]);
942 c->odbs->RS((std::string(
"Param/Value/") +
list[1]).
c_str(), &v,
true);
943 c->odbs->WS((std::string(
"Param/Comment/") +
list[1]).
c_str(),
list[2]);
944 c->odbs->WS((std::string(
"Param/Defaults/") +
list[1]).
c_str(),
list[3]);
950 c->odbs->RS((std::string(
"Param/Value/") +
list[1]).
c_str(), &v,
true);
951 c->odbs->WS((std::string(
"Param/Comment/") +
list[1]).
c_str(),
list[2]);
952 std::vector<std::string>
options;
953 for (
i = 3;
i < 100 &&
list[
i][0];
i++) {
967 c->odbs->WS((std::string(
"Param/Value/") +
list[1]).c_str(),
ov.c_str());
974 if (
list[2][0] == 0) {
978 for (
i = 2;
i < 100 &&
list[
i][0];
i++) {
986 xml +=
"</Script>\n";
996 xml +=
"</Subroutine>\n";
1004 }
else if (!
list[3][0]) {
1008 q(
list[3]) +
">" +
list[4] +
"</Wait>\n";
1011 }
else if (
list[0][0] == 0 ||
list[0][0] ==
'#') {
1015 *error_line = line + 1;
1023 xml +=
"\n</Library>\n";
1025 xml +=
"</RunSequence>\n";
1043 cm_msg(
MERROR,
"seq_read",
"Cannot find /Sequencer/State in ODB, db_find_key() status %d",
status);
1050 cm_msg(
MERROR,
"seq_read",
"Cannot get /Sequencer/State from ODB, db_get_record1() status %d",
status);
1061 cm_msg(
MERROR,
"seq_write",
"Cannot find /Sequencer/State in ODB, db_find_key() status %d",
status);
1066 cm_msg(
MERROR,
"seq_write",
"Cannot write to ODB /Sequencer/State, db_set_record() status %d",
status);
1081 seq.wait_type[0] = 0;
1082 seq.wait_odb[0] = 0;
1084 seq.loop_start_line[
i] = 0;
1085 seq.sloop_start_line[
i] = 0;
1086 seq.loop_end_line[
i] = 0;
1087 seq.sloop_end_line[
i] = 0;
1088 seq.loop_counter[
i] = 0;
1092 seq.if_else_line[
i] = 0;
1093 seq.if_endif_line[
i] = 0;
1096 seq.subroutine_end_line[
i] = 0;
1097 seq.subroutine_return_line[
i] = 0;
1098 seq.subroutine_call_line[
i] = 0;
1099 seq.ssubroutine_call_line[
i] = 0;
1100 seq.subroutine_param[
i][0] = 0;
1102 seq.current_line_number = 0;
1103 seq.scurrent_line_number = 0;
1104 seq.sfilename[0] = 0;
1106 seq.stack_index = 0;
1109 seq.serror_line = 0;
1111 seq.subdir_end_line = 0;
1112 seq.subdir_not_notify = 0;
1128 midas::odb vars(std::string(
"/") +
c->odb_path +
"/Variables");
1132 if (!
param.is_subkey(
d.get_name())) {
1133 mstrlcpy(
seq.error,
"Cannot start script because /Sequencer/Param/Value is incomplete",
sizeof(
seq.error));
1135 cm_msg(
MERROR,
"sequencer",
"Cannot start script because /Sequencer/Param/Value is incomplete");
1141 vars[p.get_name()] = p.
s();
1144 mstrlcpy(
seq.error,
"Cannot start script, no script loaded",
sizeof(
seq.error));
1152 seq.current_line_number = 1;
1153 seq.scurrent_line_number = 1;
1158 cm_msg(
MTALK,
"sequencer",
"Sequencer started with script \"%s\" in debugging mode.",
seq.filename);
1160 cm_msg(
MTALK,
"sequencer",
"Sequencer started with script \"%s\".",
seq.filename);
1168 if (
seq.follow_libraries) {
1170 path +=
"userfiles/sequencer/";
1172 path +=
seq.filename;
1186 seq.stop_after_run =
true;
1194 seq.stop_after_run =
false;
1228 seq.subroutine_return_line[
seq.stack_index] = -1;
1266 seq.serror_line = 0;
1271 c->odbs->WS(
"Script/Lines",
"");
1281 path +=
"userfiles/sequencer/";
1285 path = path.substr(0, path.find_last_of(
'/') + 1);
1293 std::string fn(path);
1294 if (!fn.empty() && fn.back() !=
'/')
1312 if (
seq.next_filename[0][0]) {
1314 for (
int i=0 ;
i<9 ;
i++)
1316 seq.next_filename[9][0] = 0;
1333 if (
c->seqp->new_file) {
1357 bool stop_after_run =
false;
1367 c->odbs->RB(
"Command/Stop after run", &stop_after_run);
1372 c->odbs->RB(
"Command/Step over", &
step_over);
1376 std::string filename;
1377 c->odbs->RS(
"State/Filename", &filename);
1381 if (filename.find(
"..") != std::string::npos) {
1384 mstrlcat(seqp->
error,
"\": file names with \"..\" is not permitted",
sizeof(seqp->
error));
1386 }
else if (filename.find(
".msl") == std::string::npos) {
1389 mstrlcat(seqp->
error,
"\": file name should end with \".msl\"",
sizeof(seqp->
error));
1394 if (path.length() > 0 && path.back() !=
'/') {
1405 c->odbs->WB(
"Command/Load new file",
false);
1411 c->odbs->WB(
"Command/Start script",
false);
1419 cm_msg(
MTALK,
"sequencer",
"Sequencer is already running");
1425 c->odbs->WB(
"Command/Stop immediately",
false);
1427 cm_msg(
MTALK,
"sequencer",
"Sequencer is finished by \"stop immediately\".");
1429 c->odbs->WB(
"Command/Stop immediately",
false);
1430 cm_msg(
MTALK,
"sequencer",
"Sequencer received \"stop immediately\". Executing ATEXIT.");
1434 if (stop_after_run) {
1435 c->odbs->WB(
"Command/Stop after run",
false);
1440 c->odbs->WB(
"Command/Cancel stop after run",
false);
1446 c->odbs->WB(
"Command/Pause script",
false);
1447 cm_msg(
MTALK,
"sequencer",
"Sequencer is paused.");
1452 c->odbs->WB(
"Command/Resume script",
false);
1453 cm_msg(
MTALK,
"sequencer",
"Sequencer is resumed.");
1457 c->odbs->WB(
"Command/Debug script",
false);
1465 cm_msg(
MTALK,
"sequencer",
"Sequencer is already running");
1471 c->odbs->WB(
"Command/Step over",
false);
1507 std::vector<HNDLE> keys;
1515 size =
sizeof(
data);
1555 int i,
j, l,
n,
status, size,
index1,
index2,
state,
run_number,
cont;
1561 if (!
seq.running ||
seq.paused) {
1566 if (
c->pnseq ==
NULL) {
1581 strcpy(
seq.last_msg,
str+11);
1585 seq_error(
seq,
c,
"Cannot find <RunSequence> tag in XML file");
1592 if (
seq.stack_index > 0 &&
seq.current_line_number ==
seq.subroutine_end_line[
seq.stack_index - 1]) {
1594 seq.subroutine_end_line[
seq.stack_index - 1] = 0;
1596 if (
seq.subroutine_return_line[
seq.stack_index - 1] == -1) {
1599 cm_msg(
MTALK,
"sequencer",
"Sequencer is finished.");
1605 seq.current_line_number =
seq.subroutine_return_line[
seq.stack_index - 1];
1606 seq.subroutine_return_line[
seq.stack_index - 1] = 0;
1607 seq.subroutine_call_line[
seq.stack_index - 1] = 0;
1608 seq.ssubroutine_call_line[
seq.stack_index - 1] = 0;
1619 cm_msg(
MTALK,
"sequencer",
"Sequencer is finished.");
1628 if (
seq.loop_start_line[
i] > 0)
1631 if (
seq.current_line_number ==
seq.loop_end_line[
i]) {
1635 if (
seq.loop_counter[
i] ==
seq.loop_n[
i]) {
1636 seq.loop_counter[
i] = 0;
1637 seq.loop_start_line[
i] = 0;
1638 seq.sloop_start_line[
i] = 0;
1639 seq.loop_end_line[
i] = 0;
1640 seq.sloop_end_line[
i] = 0;
1642 seq.current_line_number++;
1652 value = std::to_string(
seq.loop_counter[
i] + 1);
1655 size =
value.length() + 1;
1660 seq.loop_counter[
i]++;
1661 seq.current_line_number =
seq.loop_start_line[
i] + 1;
1669 if (
seq.if_index > 0 &&
seq.current_line_number ==
seq.if_endif_line[
seq.if_index - 1]) {
1673 seq.if_line[
seq.if_index] = 0;
1674 seq.if_else_line[
seq.if_index] = 0;
1675 seq.if_endif_line[
seq.if_index] = 0;
1676 seq.current_line_number++;
1682 if (
seq.current_line_number ==
seq.subdir_end_line) {
1685 seq.subdir_end_line = 0;
1697 seq.current_line_number++;
1705 if (
seq.follow_libraries) {
1712 if (filename != std::string(
seq.sfilename)) {
1714 mstrlcpy(
seq.sfilename, filename.c_str(),
sizeof(
seq.sfilename));
1726 if (
seq.scurrent_line_number >= 0) {
1728 std::string s =
o[
seq.scurrent_line_number - 1];
1729 printf(
"%3d: %s\n",
seq.scurrent_line_number, s.c_str());
1736 seq.current_line_number++;
1747 if (s.find(
'$') != std::string::npos)
1754 seq.current_line_number++;
1772 std::string
s1 = s.substr(0, s.find(
'['));
1773 std::string
s2 = s.substr(s.find(
'['));
1786 if (
seq.subdir_not_notify)
1801 seq.current_line_number++;
1820 path +=
"userfiles/sequencer/";
1826 path +=
"userfiles/sequencer/";
1829 if (
value.back() !=
'/')
1834 if (
value.find(
'$') != std::string::npos)
1866 seq.current_line_number++;
1882 path +=
"userfiles/sequencer/";
1888 path +=
"userfiles/sequencer/";
1892 size_t pos =
value.find_last_of(
'/');
1893 if (pos != std::string::npos)
1898 if (
value.find(
'$') != std::string::npos)
1932 seq_error(
seq,
c,
"No ODB path specified in ODBSAVE command");
1939 seq.current_line_number++;
1963 std::string
s1 = s.substr(0, s.find(
'['));
1964 std::string
s2 = s.substr(s.find(
'['));
1987 size =
sizeof(
data);
1991 value = *((
int *)
data) > 0 ?
"1" :
"0";
1996 size =
value.length() + 1;
2024 std::string
s1 = s.substr(0, s.find(
'['));
2025 std::string
s2 = s.substr(s.find(
'['));
2051 size =
sizeof(
data);
2064 size =
value.length() + 1;
2090 std::string
s1 = s.substr(0, s.find(
'['));
2091 std::string
s2 = s.substr(s.find(
'['));
2113 size =
sizeof(
data);
2119 size =
sizeof(
data);
2123 if (
seq.subdir_not_notify)
2129 seq.current_line_number++;
2155 seq.current_line_number++;
2179 for (tid = 0; tid <
TID_LAST; tid++) {
2185 seq_error(
seq,
c,
"Type must be one of UINT8,INT8,UINT16,INT16,UINT32,INT32,BOOL,FLOAT,DOUBLE,STRING");
2212 seq.current_line_number++;
2221 seq.current_line_number++;
2231 for (
i = 0;
i <
n;
i++) {
2242 std::string r =
ss_execs(s.c_str());
2247 seq.current_line_number++;
2253 if (!
seq.transition_request) {
2254 seq.transition_request =
TRUE;
2255 size =
sizeof(
state);
2267 size =
sizeof(
state);
2271 seq.current_line_number++;
2275 if (!
seq.transition_request) {
2276 seq.transition_request =
TRUE;
2277 size =
sizeof(
state);
2289 size =
sizeof(
state);
2297 if (
seq.stop_after_run) {
2304 cm_msg(
MTALK,
"sequencer",
"Sequencer is finished by \"stop after current run\".");
2306 cm_msg(
MTALK,
"sequencer",
"Sequencer is going to finish by \"stop after current run\". Executing ATEXIT.");
2309 seq.current_line_number++;
2326 strcpy(
seq.wait_type,
"Events");
2334 seq.wait_type[0] = 0;
2335 seq.wait_odb[0] = 0;
2352 std::string
s1 = s.substr(0, s.find(
'['));
2353 std::string
s2 = s.substr(s.find(
'['));
2379 size =
sizeof(
data);
2382 value = *((
int *)
data) > 0 ?
"1" :
"0";
2408 seq.wait_type[0] = 0;
2409 seq.wait_odb[0] = 0;
2415 strcpy(
seq.wait_type,
"Seconds");
2416 if (
seq.start_time == 0) {
2421 if (
seq.wait_value >
seq.wait_limit)
2422 seq.wait_value =
seq.wait_limit;
2425 seq.current_line_number++;
2429 seq.wait_type[0] = 0;
2430 seq.wait_odb[0] = 0;
2443 if (
seq.loop_start_line[
i] == 0)
2449 seq.loop_start_line[
i] =
seq.current_line_number;
2455 seq.loop_counter[
i] = 1;
2476 size =
value.length() + 1;
2482 seq.current_line_number++;
2489 while (
seq.if_index > 0 &&
2490 seq.current_line_number >
seq.if_line[
seq.if_index - 1] &&
2491 seq.current_line_number <
seq.if_endif_line[
seq.if_index-1]) {
2495 seq.if_line[
seq.if_index] = 0;
2496 seq.if_else_line[
seq.if_index] = 0;
2497 seq.if_endif_line[
seq.if_index] = 0;
2498 seq.current_line_number++;
2504 if (
seq.loop_start_line[
i] == 0)
2512 seq.current_line_number =
seq.loop_end_line[
i-1];
2513 seq.loop_counter[
i-1] =
seq.loop_n[
i-1];
2520 seq_error(
seq,
c,
"Maximum number of nested if..endif exceeded");
2525 seq.if_line[
seq.if_index] =
seq.current_line_number;
2529 seq.if_else_line[
seq.if_index] = 0;
2541 seq.if_else_line[
seq.if_index] =
j;
2554 seq.current_line_number++;
2555 else if (
seq.if_else_line[
seq.if_index])
2556 seq.current_line_number =
seq.if_else_line[
seq.if_index] + 1;
2558 seq.current_line_number =
seq.if_endif_line[
seq.if_index];
2566 if (
seq.if_index == 0) {
2570 seq.current_line_number =
seq.if_endif_line[
seq.if_index - 1];
2576 cm_msg(
MTALK,
"sequencer",
"Sequencer is finished.");
2596 seq.current_line_number =
i;
2644 size =
value.length() + 1;
2650 size =
value.length() + 1;
2658 if (
seq.loop_start_line[
i] > 0) {
2689 if (!
seq.message_wait) {
2699 if (
seq.message[0] != 0) {
2705 seq.message_wait =
false;
2718 std::string
type =
"INFO";
2722 if (
type ==
"ERROR")
2724 else if (
type ==
"DEBUG")
2726 else if (
type ==
"LOG")
2728 else if (
type ==
"TALK")
2805 size =
sizeof(
seq1);
2811 seq.stop_after_run =
seq1.stop_after_run;
2828 c->odbs =
gOdb->Chdir(
c->odb_path.c_str(),
true);
2833 cm_msg(
MERROR,
"init_sequencer",
"Sequencer error: Cannot find /Sequencer, db_find_key() status %d",
status);
2839 cm_msg(
MERROR,
"init_sequencer",
"Sequencer error: mismatching /Sequencer/State structure, db_check_record() status %d",
status);
2845 cm_msg(
MERROR,
"init_sequencer",
"Sequencer error: Cannot find /Sequencer/State, db_find_key() status %d",
status);
2849 int size =
sizeof(
seq);
2852 cm_msg(
MERROR,
"init_sequencer",
"Sequencer error: Cannot get /Sequencer/State, db_get_record1() status %d",
status);
2860 if (
seq.filename[0])
2869 cm_msg(
MERROR,
"init_sequencer",
"Sequencer error: Cannot watch /Sequencer/State, db_watch() status %d",
status);
2874 c->odbs->RB(
"Command/Start script", &b,
true);
2876 c->odbs->RB(
"Command/Stop immediately", &b,
true);
2878 c->odbs->RB(
"Command/Stop after run", &b,
true);
2880 c->odbs->RB(
"Command/Cancel stop after run", &b,
true);
2882 c->odbs->RB(
"Command/Pause script", &b,
true);
2884 c->odbs->RB(
"Command/Resume script", &b,
true);
2886 c->odbs->RB(
"Command/Debug script", &b,
true);
2888 c->odbs->RB(
"Command/Step over", &b,
true);
2890 c->odbs->RB(
"Command/Load new file", &b,
true);
2894 cm_msg(
MERROR,
"init_sequencer",
"Sequencer error: Cannot find /Sequencer/Command, db_find_key() status %d",
status);
2900 cm_msg(
MERROR,
"init_sequencer",
"Sequencer error: Cannot watch /Sequencer/Command, db_watch() status %d",
status);
2912 std::string seq_name =
"";
2925 for (
int i = 1;
i <
argc;
i++) {
2926 if (
argv[
i][0] ==
'-' &&
argv[
i][1] ==
'D') {
2928 }
else if (
argv[
i][0] ==
'-') {
2931 if (
argv[
i][1] ==
'h')
2933 else if (
argv[
i][1] ==
'e')
2935 else if (
argv[
i][1] ==
'c')
2936 seq_name =
argv[++
i];
2939 printf(
"usage: %s [-h Hostname[:port]] [-e Experiment] [-c Name] [-D]\n\n",
argv[0]);
2940 printf(
" -e experiment to connect to\n");
2941 printf(
" -c Name of additional sequencer, i.e. \'Test\'\n");
2942 printf(
" -h connect to midas server (mserver) on given host\n");
2943 printf(
" -D become a daemon\n");
2949 printf(
"Becoming a daemon...\n");
2953 std::string prg_name =
"Sequencer";
2954 std::string odb_path =
"Sequencer";
2956 if (!seq_name.empty()) {
2957 prg_name = std::string(
"Sequencer") + seq_name;
2958 odb_path = std::string(
"Sequencer") + seq_name;
2990 printf(
"%s runs already.\n", prg_name.c_str());
3004 c.seq_name = seq_name;
3005 c.prg_name = prg_name;
3006 c.odb_path = odb_path;
3010 if (seq_name.empty()) {
3011 printf(
"Sequencer started. Stop with \"!\"\n");
3013 printf(
"%s started.\n", prg_name.c_str());
3014 printf(
"Set ODB String \"/Alias/Sequencer%s\" to URL \"?cmd=sequencer&seq_name=%s\"\n", seq_name.c_str(), seq_name.c_str());
3015 printf(
"Stop with \"!\"\n");
3028 }
catch (std::string &msg) {
3030 }
catch (
const char *msg) {
3042 if ((
char)
ch ==
'!')
static bool exists(const std::string &name)
INT cm_yield(INT millisec)
INT cm_get_experiment_database(HNDLE *hDB, HNDLE *hKeyClient)
INT cm_transition(INT transition, INT run_number, char *errstr, INT errstr_size, INT async_flag, INT debug_flag)
INT cm_connect_experiment1(const char *host_name, const char *default_exp_name, const char *client_name, void(*func)(char *), INT odb_size, DWORD watchdog_timeout)
std::string cm_expand_env(const char *str)
INT cm_disconnect_experiment(void)
std::string cm_get_path()
INT cm_get_environment(char *host_name, int host_name_size, char *exp_name, int exp_name_size)
INT cm_exist(const char *name, BOOL bUnique)
#define CM_DEFERRED_TRANSITION
#define CM_WRONG_PASSWORD
#define DB_STRUCT_MISMATCH
#define DB_INVALID_HANDLE
INT ss_getchar(BOOL reset)
std::string ss_execs(const char *cmd)
std::string ss_replace_env_variables(const std::string &inputPath)
INT ss_daemon_init(BOOL keep_stdout)
INT ss_sleep(INT millisec)
std::string cm_get_error(INT code)
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
INT cm_msg_retrieve(INT n_message, char *message, INT buf_size)
BOOL equal_ustring(const char *str1, const char *str2)
INT db_get_data_index(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT idx, DWORD type)
INT db_delete_key(HNDLE hDB, HNDLE hKey, BOOL follow_links)
INT db_get_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, void *data, INT *buf_size, DWORD type, BOOL create)
INT db_save_json(HNDLE hDB, HNDLE hKey, const char *filename, int flags)
std::string strcomb1(const char **list)
INT db_save_xml(HNDLE hDB, HNDLE hKey, const char *filename)
INT db_get_record1(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT align, const char *rec_str)
INT db_create_key(HNDLE hDB, HNDLE hKey, const char *key_name, DWORD type)
INT db_check_record(HNDLE hDB, HNDLE hKey, const char *keyname, const char *rec_str, BOOL correct)
INT db_get_record(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT align)
INT db_save(HNDLE hDB, HNDLE hKey, const char *filename, BOOL bRemote)
INT db_get_key(HNDLE hDB, HNDLE hKey, KEY *key)
INT db_load(HNDLE hDB, HNDLE hKeyRoot, const char *filename, BOOL bRemote)
INT db_set_data_index(HNDLE hDB, HNDLE hKey, const void *data, INT data_size, INT idx, DWORD type)
INT db_find_keys(HNDLE hDB, HNDLE hKeyRoot, char *odbpath, std::vector< HNDLE > &hKeyVector)
INT db_watch(HNDLE hDB, HNDLE hKey, void(*dispatcher)(INT, INT, INT, void *), void *info)
INT db_set_data(HNDLE hDB, HNDLE hKey, const void *data, INT buf_size, INT num_values, DWORD type)
INT db_sprintf(char *string, const void *data, INT data_size, INT idx, DWORD type)
void strarrayindex(char *odbpath, int *index1, int *index2)
INT db_set_data1(HNDLE hDB, HNDLE hKey, const void *data, INT buf_size, INT num_values, DWORD type)
INT db_set_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, const void *data, INT data_size, INT num_values, DWORD type)
INT db_find_key(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
INT db_set_record(HNDLE hDB, HNDLE hKey, void *data, INT buf_size, INT align)
INT db_set_data_index1(HNDLE hDB, HNDLE hKey, const void *data, INT data_size, INT idx, DWORD type, BOOL bNotify)
INT db_sscanf(const char *data_str, void *data, INT *data_size, INT i, DWORD tid)
INT db_set_num_values(HNDLE hDB, HNDLE hKey, INT num_values)
const char * rpc_tid_name(INT id)
static void seq_watch(HNDLE hDB, HNDLE hKeyChanged, int index, void *info)
void seq_array_index(SEQUENCER &seq, SeqCon *c, char *odbpath, int *index1, int *index2)
int concatenate(SEQUENCER &seq, SeqCon *c, char *result, int size, char *value)
int set_all_matching(HNDLE hDB, HNDLE hBaseKey, char *odbpath, char *value, int index1, int index2, int notify)
static void seq_stop_after_run(SEQUENCER &seq, SeqCon *c)
static void seq_start_next(SEQUENCER &seq, SeqCon *c)
static void seq_stop(SEQUENCER &seq, SeqCon *c)
void seq_write(const SEQUENCER &seq, SeqCon *c)
int strbreak(char *str, char list[][XNAME_LENGTH], int size, const char *brk, BOOL ignore_quotes)
void strsubst(char *string, int size, const char *pattern, const char *subst)
static std::string qtoString(std::string filename, int line, int level)
static void seq_watch_command(HNDLE hDB, HNDLE hKeyChanged, int index, void *info)
char * stristr(const char *str, const char *pattern)
static BOOL goto_at_exit(SEQUENCER &seq, SeqCon *c)
void seq_read(SEQUENCER *seq, SeqCon *c)
static BOOL msl_parse(SEQUENCER &seq, SeqCon *c, int level, const char *cpath, const char *filename, const char *xml_filename, char *error, int error_size, int *error_line)
void init_sequencer(SEQUENCER &seq, SeqCon *c)
static void seq_step_over(SEQUENCER &seq, SeqCon *c)
static void seq_cancel_stop_after_run(SEQUENCER &seq, SeqCon *c)
static void seq_pause(SEQUENCER &seq, SeqCon *c, bool flag)
void sequencer(SEQUENCER &seq, SeqCon *c)
static std::string toString(int v)
void seq_error(SEQUENCER &seq, SeqCon *c, const char *str)
static std::string q(const char *s)
std::string eval_var(SEQUENCER &seq, SeqCon *c, std::string value)
bool loadMSL(MVOdb *o, const std::string &filename)
int eval_condition(SEQUENCER &seq, SeqCon *c, const char *condition)
static void seq_start(SEQUENCER &seq, SeqCon *c, bool debug)
bool is_valid_number(const char *str)
void seq_clear(SEQUENCER &seq)
static void seq_open_file(const char *str, SEQUENCER &seq, SeqCon *c)
BOOL debug
debug printouts
std::string msprintf(const char *format,...)
#define DIR_SEPARATOR_STR
#define DEFAULT_WATCHDOG_TIMEOUT
#define JSFLAG_FOLLOW_LINKS
#define JSFLAG_OMIT_LAST_WRITTEN
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
#define SEQ_NEST_LEVEL_IF
#define SEQUENCER_STR(_name)
#define SEQ_NEST_LEVEL_LOOP
#define SEQ_NEST_LEVEL_SUB
double te_interp(const char *expression, int *error)
static void pn(const te_expr *n, int depth)
static te_expr * list(state *s)