1 #include "otsdaq-utilities/MacroMaker/MacroMakerSupervisor.h"
9 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
12 #include "otsdaq-core/FECore/FEVInterface.h"
14 #include "otsdaq-core/CodeEditor/CodeEditor.h"
27 #include "otsdaq-core/TableCore/TableGroupKey.h"
29 #define MACROS_DB_PATH std::string(getenv("SERVICE_DATA_PATH")) + "/MacroData/"
30 #define MACROS_HIST_PATH std::string(getenv("SERVICE_DATA_PATH")) + "/MacroHistory/"
31 #define MACROS_EXPORT_PATH std::string(getenv("SERVICE_DATA_PATH")) + "/MacroExport/"
36 #define __MF_SUBJECT__ "MacroMaker"
42 : CoreSupervisorBase(stub)
44 INIT_MF(
"MacroMaker");
47 mkdir(((std::string)MACROS_DB_PATH).c_str(), 0755);
48 mkdir(((std::string)MACROS_HIST_PATH).c_str(), 0755);
49 mkdir(((std::string)MACROS_EXPORT_PATH).c_str(), 0755);
52 &MacroMakerSupervisor::frontEndCommunicationRequest,
60 MacroMakerSupervisor::~MacroMakerSupervisor(
void) { destroy(); }
63 void MacroMakerSupervisor::init(
void)
68 allFESupervisorInfo_ = allSupervisorInfo_.getAllFETypeSupervisorInfo();
72 void MacroMakerSupervisor::destroy(
void)
80 void MacroMakerSupervisor::forceSupervisorPropertyValues()
87 void MacroMakerSupervisor::request(
const std::string& requestType,
89 HttpXmlDocument& xmlOut,
90 const WebUsers::RequestUserInfo& userInfo)
try
92 __SUP_COUT__ <<
"User name is " << userInfo.username_ <<
"." << __E__;
93 __SUP_COUT__ <<
"User permission level for request '" << requestType <<
"' is "
94 << unsigned(userInfo.permissionLevel_) <<
"." << __E__;
97 if(requestType ==
"getPermission")
99 xmlOut.addTextElementToData(
"Permission",
100 std::to_string(
unsigned(userInfo.permissionLevel_)));
104 std::string macroPath = (std::string)MACROS_DB_PATH + userInfo.username_ +
"/";
105 mkdir(macroPath.c_str(), 0755);
106 std::string histPath = (std::string)MACROS_HIST_PATH + userInfo.username_ +
"/";
107 mkdir(histPath.c_str(), 0755);
108 std::string publicPath = (std::string)MACROS_DB_PATH +
"publicMacros/";
109 mkdir(publicPath.c_str(), 0755);
110 std::string exportPath =
111 (std::string)MACROS_EXPORT_PATH + userInfo.username_ +
"/";
112 mkdir(exportPath.c_str(), 0755);
115 handleRequest(requestType, xmlOut, cgiIn, userInfo.username_);
117 catch(
const std::runtime_error& e)
119 __SS__ <<
"Error occurred handling request '" << requestType <<
"': " << e.what()
121 __SUP_COUT__ << ss.str();
122 xmlOut.addTextElementToData(
"Error", ss.str());
126 __SS__ <<
"Unknown error occurred handling request '" << requestType <<
"!'" << __E__;
127 __SUP_COUT__ << ss.str();
128 xmlOut.addTextElementToData(
"Error", ss.str());
132 void MacroMakerSupervisor::handleRequest(
const std::string Command,
133 HttpXmlDocument& xmldoc,
135 const std::string& username)
137 if(Command ==
"FElist")
139 else if(Command ==
"writeData")
140 writeData(xmldoc, cgi, username);
141 else if(Command ==
"readData")
142 readData(xmldoc, cgi, username);
143 else if(Command ==
"createMacro")
144 createMacro(xmldoc, cgi, username);
145 else if(Command ==
"loadMacros")
146 loadMacros(xmldoc, username);
147 else if(Command ==
"loadHistory")
148 loadHistory(xmldoc, username);
149 else if(Command ==
"deleteMacro")
150 deleteMacro(xmldoc, cgi, username);
151 else if(Command ==
"editMacro")
152 editMacro(xmldoc, cgi, username);
153 else if(Command ==
"clearHistory")
154 clearHistory(username);
155 else if(Command ==
"exportMacro")
156 exportMacro(xmldoc, cgi, username);
157 else if(Command ==
"exportFEMacro")
158 exportFEMacro(xmldoc, cgi, username);
159 else if(Command ==
"getFEMacroList")
160 getFEMacroList(xmldoc, username);
161 else if(Command ==
"runFEMacro")
162 runFEMacro(xmldoc, cgi, username);
164 xmldoc.addTextElementToData(
"Error",
"Unrecognized command '" + Command +
"'");
168 xoap::MessageReference MacroMakerSupervisor::frontEndCommunicationRequest(
169 xoap::MessageReference message)
try
171 __SUP_COUT__ <<
"FE Request received: " << SOAPUtilities::translate(message) << __E__;
173 SOAPParameters typeParameter, rxParameters;
174 typeParameter.addParameter(
"type");
175 SOAPUtilities::receive(message, typeParameter);
177 std::string type = typeParameter.getValue(
"type");
179 std::string error =
"";
181 if(type ==
"initFElist")
185 rxParameters.addParameter(
"groupName");
186 rxParameters.addParameter(
"groupKey");
187 SOAPUtilities::receive(message, rxParameters);
189 std::string groupName = rxParameters.getValue(
"groupName");
190 std::string groupKey = rxParameters.getValue(
"groupKey");
192 __SUP_COUTV__(groupName);
193 __SUP_COUTV__(groupKey);
195 ConfigurationManager cfgMgr;
196 cfgMgr.loadTableGroup(groupName, TableGroupKey(groupKey),
true);
201 const SupervisorInfoMap& feTypeSupervisors =
202 CorePropertySupervisorBase::allSupervisorInfo_.getAllFETypeSupervisorInfo();
204 ConfigurationTree appsNode = cfgMgr.getNode(ConfigurationManager::XDAQ_APPLICATION_TABLE_NAME);
206 __SUP_COUT__ <<
"Number of FE Supervisors found = " <<
207 feTypeSupervisors.size() << __E__;
209 FEPluginTypetoFEsMap_.clear();
210 FEtoSupervisorMap_.clear();
211 FEtoPluginTypeMap_.clear();
212 for(
auto& feApp : feTypeSupervisors)
214 __SUP_COUT__ <<
"FEs for app " << feApp.first <<
":" << feApp.second.getName()
217 auto feChildren = appsNode.getNode(feApp.second.getName())
218 .getNode(
"LinkToSupervisorTable")
219 .getNode(
"LinkToFEInterfaceTable")
222 for(
auto& fe : feChildren)
224 __SUP_COUTV__(fe.first);
225 FEtoSupervisorMap_[fe.first] = feApp.first;
227 std::string pluginType =
228 fe.second.getNode(
"FEInterfacePluginName").getValue();
229 FEPluginTypetoFEsMap_[pluginType].emplace(fe.first);
230 FEtoPluginTypeMap_[fe.first] = pluginType;
234 __SUP_COUTV__(StringMacros::mapToString(FEtoSupervisorMap_));
235 __SUP_COUTV__(StringMacros::mapToString(FEPluginTypetoFEsMap_));
236 __SUP_COUTV__(StringMacros::mapToString(FEtoPluginTypeMap_));
238 else if(type ==
"feSend" ||
240 type ==
"feMacroMultiDimensionalStart" ||
241 type ==
"feMacroMultiDimensionalCheck" ||
242 type ==
"macroMultiDimensionalStart" ||
243 type ==
"macroMultiDimensionalCheck")
247 rxParameters.addParameter(
"targetInterfaceID");
248 SOAPUtilities::receive(message, rxParameters);
250 std::string targetInterfaceID = rxParameters.getValue(
"targetInterfaceID");
252 __SUP_COUTV__(targetInterfaceID);
254 auto feIt = FEtoSupervisorMap_.find(targetInterfaceID);
255 if(feIt == FEtoSupervisorMap_.end())
257 __SUP_SS__ <<
"Destination front end interface ID '" << targetInterfaceID
258 <<
"' was not found in the list of front ends." << __E__;
262 unsigned int FESupervisorIndex = feIt->second;
263 __SUP_COUT__ <<
"Found supervisor index: " << FESupervisorIndex << __E__;
265 SupervisorInfoMap::iterator it = allFESupervisorInfo_.find(FESupervisorIndex);
266 if(it == allFESupervisorInfo_.end())
268 __SUP_SS__ <<
"Error transmitting request to FE Supervisor '"
269 << targetInterfaceID <<
":" << FESupervisorIndex <<
".' \n\n"
270 <<
"The FE Supervisor Index does not exist. Have you configured "
271 "the state machine properly?"
276 if(type ==
"macroMultiDimensionalStart")
280 SOAPParameters rxParameters;
281 rxParameters.addParameter(
"macroName");
282 SOAPUtilities::receive(message, rxParameters);
283 std::string macroName = rxParameters.getValue(
"macroName");
284 __SUP_COUTV__(macroName);
286 std::string macroString;
287 loadMacro(macroName, macroString);
289 SOAPParameters parameters;
290 parameters.addParameter(
"macroString", macroString);
291 SOAPUtilities::addParameters(message, parameters);
296 __SUP_COUT__ <<
"Forwarding request: " << SOAPUtilities::translate(message)
299 xoap::MessageReference replyMessage =
300 SOAPMessenger::sendWithSOAPReply(it->second.getDescriptor(), message);
304 __SUP_COUT__ <<
"Forwarding FE Macro response: "
305 << SOAPUtilities::translate(replyMessage) << __E__;
310 catch(
const xdaq::exception::Exception& e)
312 __SUP_SS__ <<
"Error forwarding FE Communication request to FE Supervisor '"
313 << targetInterfaceID <<
":" << FESupervisorIndex <<
".' "
314 <<
"Have you configured the state machine properly?\n\n"
315 << e.what() << __E__;
321 __SUP_SS__ <<
"Unrecognized FE Communication type: " << type << __E__;
325 return SOAPUtilities::makeSOAPMessageReference(
"Received");
327 catch(
const std::runtime_error& e)
329 __SUP_SS__ <<
"Error processing FE communication request: " << e.what() << __E__;
330 __SUP_COUT_ERR__ << ss.str();
332 xoap::MessageReference returnMessage =
333 SOAPUtilities::makeSOAPMessageReference(
"Error");
335 SOAPParameters parameters;
336 parameters.addParameter(
"Error", ss.str());
337 SOAPUtilities::addParameters(returnMessage, parameters);
338 return returnMessage;
342 xoap::MessageReference returnMessage =
343 SOAPUtilities::makeSOAPMessageReference(
"Error");
345 __SUP_SS__ <<
"Unknown error processing FE communication request." << __E__;
346 __SUP_COUT_ERR__ << ss.str();
348 SOAPParameters parameters;
349 parameters.addParameter(
"Error", ss.str());
350 SOAPUtilities::addParameters(returnMessage, parameters);
351 return returnMessage;
355 void MacroMakerSupervisor::getFElist(HttpXmlDocument& xmldoc)
357 __SUP_COUT__ <<
"Getting FE list!!!!!!!!!" << __E__;
359 SOAPParameters txParameters;
360 txParameters.addParameter(
"Request",
"GetInterfaces");
362 SOAPParameters rxParameters;
363 rxParameters.addParameter(
"FEList");
365 SupervisorInfoMap::const_iterator it;
366 std::string oneInterface;
367 std::string rxFEList;
369 size_t lastColonIndex;
373 for(
auto& appInfo : allFESupervisorInfo_)
381 __SUP_COUT__ <<
"FESupervisor LID = " << appInfo.second.getId()
382 <<
" name = " << appInfo.second.getName() << __E__;
386 xoap::MessageReference retMsg =
387 SOAPMessenger::sendWithSOAPReply(appInfo.second.getDescriptor(),
388 "MacroMakerSupervisorRequest",
390 SOAPUtilities::receive(retMsg, rxParameters);
392 catch(
const xdaq::exception::Exception& e)
394 __SS__ <<
"Error transmitting request to FE Supervisor LID = "
395 << appInfo.second.getId() <<
" name = " << appInfo.second.getName()
397 << e.what() << __E__;
398 __SUP_COUT_ERR__ << ss.str();
402 rxFEList = rxParameters.getValue(
"FEList");
404 __SUP_COUT__ <<
"FE List received: \n" << rxFEList << __E__;
406 std::istringstream allInterfaces(rxFEList);
407 while(std::getline(allInterfaces, oneInterface))
409 __SUP_COUTV__(oneInterface);
410 xmldoc.addTextElementToData(
"FE", oneInterface);
412 lastColonIndex = oneInterface.rfind(
':');
413 if(lastColonIndex == std::string::npos)
415 __SUP_SS__ <<
"Last colon could not be found in " << oneInterface
419 oneInterface = oneInterface.substr(lastColonIndex);
421 __SUP_COUTV__(oneInterface);
429 void MacroMakerSupervisor::writeData(HttpXmlDocument& xmldoc,
431 const std::string& username)
433 __SUP_COUT__ <<
"MacroMaker writing..." << __E__;
435 std::string Address = CgiDataUtilities::getData(cgi,
"Address");
436 std::string Data = CgiDataUtilities::getData(cgi,
"Data");
437 std::string interfaceIndexArray = CgiDataUtilities::getData(cgi,
"interfaceIndex");
438 std::string supervisorIndexArray = CgiDataUtilities::getData(cgi,
"supervisorIndex");
440 CgiDataUtilities::decodeURIComponent(CgiDataUtilities::getData(cgi,
"time"));
441 std::string addressFormatStr = CgiDataUtilities::getData(cgi,
"addressFormatStr");
442 std::string dataFormatStr = CgiDataUtilities::getData(cgi,
"dataFormatStr");
444 std::string interfaces = CgiDataUtilities::postData(cgi,
"interfaces");
446 __SUP_COUT__ <<
"Write Address: " << Address <<
" Data: " << Data << __E__;
447 __SUP_COUTV__(interfaces);
449 std::string command =
"w:" + Address +
":" + Data;
450 std::string format = addressFormatStr +
":" + dataFormatStr;
451 appendCommandToHistory(command, format, time, interfaces, username);
453 SOAPParameters txParameters;
454 txParameters.addParameter(
"Request",
"UniversalWrite");
455 txParameters.addParameter(
"Address", Address);
456 txParameters.addParameter(
"Data", Data);
458 __SUP_COUT__ <<
"Here comes the array from multiselect box for WRITE, behold: \n"
459 << supervisorIndexArray <<
"\n"
460 << interfaceIndexArray << __E__;
464 std::vector<std::string> interfaceIndices;
465 std::istringstream f(interfaceIndexArray);
467 while(getline(f, s,
','))
468 interfaceIndices.push_back(s);
469 std::vector<int> supervisorIndices;
470 std::istringstream g(supervisorIndexArray);
472 while(getline(g, t,
','))
473 supervisorIndices.push_back(std::stoi(t));
475 for(
unsigned int i = 0; i < supervisorIndices.size(); i++)
477 unsigned int FESupervisorIndex = supervisorIndices[i];
478 std::string interfaceIndex = interfaceIndices[i];
480 txParameters.addParameter(
"InterfaceID", interfaceIndex);
482 __SUP_COUT__ <<
"The index of the supervisor instance is: " << FESupervisorIndex
484 __SUP_COUT__ <<
"...and the interface ID is: " << interfaceIndex << __E__;
486 SupervisorInfoMap::iterator it = allFESupervisorInfo_.find(FESupervisorIndex);
487 if(it == allFESupervisorInfo_.end())
489 __SUP_SS__ <<
"Error transmitting request to FE Supervisor '"
490 << interfaceIndex <<
":" << FESupervisorIndex <<
".' \n\n"
491 <<
"The FE Index doesn't exist. Have you configured the state "
499 xoap::MessageReference replyMessage = SOAPMessenger::sendWithSOAPReply(
500 it->second.getDescriptor(),
"MacroMakerSupervisorRequest", txParameters);
502 __SUP_COUT__ <<
"Response received: "
503 << SOAPUtilities::translate(replyMessage) << __E__;
505 SOAPParameters rxParameters;
506 rxParameters.addParameter(
"Error");
507 SOAPUtilities::receive(replyMessage, rxParameters);
509 std::string error = rxParameters.getValue(
"Error");
510 __SUP_COUTV__(error);
515 __SUP_SS__ <<
"Error transmitting request to FE Supervisor '"
516 << interfaceIndex <<
":" << FESupervisorIndex <<
".' "
517 <<
"Have you configured the state machine properly?\n\n"
522 catch(
const xdaq::exception::Exception& e)
524 __SUP_SS__ <<
"Error transmitting request to FE Supervisor '"
525 << interfaceIndex <<
":" << FESupervisorIndex <<
".' "
526 <<
"Have you configured the state machine properly?\n\n"
527 << e.what() << __E__;
535 void MacroMakerSupervisor::readData(HttpXmlDocument& xmldoc,
537 const std::string& username)
539 __SUP_COUT__ <<
"@@@@@@@ MacroMaker wants to read data @@@@@@@@" << __E__;
540 std::string Address = CgiDataUtilities::getData(cgi,
"Address");
541 std::string interfaceIndexArray = CgiDataUtilities::getData(cgi,
"interfaceIndex");
542 std::string supervisorIndexArray = CgiDataUtilities::getData(cgi,
"supervisorIndex");
544 CgiDataUtilities::decodeURIComponent(CgiDataUtilities::getData(cgi,
"time"));
545 std::string addressFormatStr = CgiDataUtilities::getData(cgi,
"addressFormatStr");
546 std::string dataFormatStr = CgiDataUtilities::getData(cgi,
"dataFormatStr");
548 std::string interfaces = CgiDataUtilities::postData(cgi,
"interfaces");
550 __SUP_COUT__ <<
"Read Address: " << Address << __E__;
551 __SUP_COUTV__(interfaces);
553 SOAPParameters txParameters;
554 txParameters.addParameter(
"Request",
"UniversalRead");
555 txParameters.addParameter(
"Address", Address);
557 SOAPParameters rxParameters;
558 rxParameters.addParameter(
"dataResult");
559 rxParameters.addParameter(
"Error");
560 __SUP_COUT__ <<
"Here comes the array from multiselect box for READ, behold: "
561 << supervisorIndexArray <<
"," << interfaceIndexArray << __E__;
565 std::vector<std::string> interfaceIndices;
566 std::istringstream f(interfaceIndexArray);
568 while(getline(f, s,
','))
569 interfaceIndices.push_back(s);
570 std::vector<int> supervisorIndices;
571 std::istringstream g(supervisorIndexArray);
573 while(getline(g, t,
','))
574 supervisorIndices.push_back(std::stoi(t));
576 for(
unsigned int i = 0; i < supervisorIndices.size(); i++)
578 unsigned int FESupervisorIndex = supervisorIndices[i];
579 std::string interfaceIndex = interfaceIndices[i];
581 txParameters.addParameter(
"InterfaceID", interfaceIndex);
583 __SUP_COUT__ <<
"The index of the supervisor instance is: " << FESupervisorIndex
585 __SUP_COUT__ <<
"...and the interface ID is: " << interfaceIndex << __E__;
587 SupervisorInfoMap::iterator it = allFESupervisorInfo_.find(FESupervisorIndex);
588 if(it == allFESupervisorInfo_.end())
590 __SUP_SS__ <<
"Error transmitting request to FE Supervisor '"
591 << interfaceIndex <<
":" << FESupervisorIndex <<
".' \n\n"
592 <<
"The FE Index doesn't exist. Have you configured the state "
600 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
601 it->second.getDescriptor(),
"MacroMakerSupervisorRequest", txParameters);
603 __SUP_COUT__ <<
"Response received: " << SOAPUtilities::translate(retMsg)
608 SOAPUtilities::receive(retMsg, rxParameters);
610 std::string error = rxParameters.getValue(
"Error");
611 __SUP_COUTV__(error);
616 __SUP_SS__ <<
"Error transmitting request to FE Supervisor '"
617 << interfaceIndex <<
":" << FESupervisorIndex <<
".' "
618 <<
"Have you configured the state machine properly?\n\n"
623 catch(
const xdaq::exception::Exception& e)
625 __SUP_SS__ <<
"Error transmitting request to FE Supervisor '"
626 << interfaceIndex <<
":" << FESupervisorIndex <<
".' "
627 <<
"Have you configured the state machine properly?\n\n"
628 << e.what() << __E__;
632 std::string dataReadResult = rxParameters.getValue(
"dataResult");
633 __SUP_COUT__ <<
"Data reading result received: " << dataReadResult << __E__;
634 xmldoc.addTextElementToData(
"readData", dataReadResult);
635 std::string command =
"r:" + Address +
":" + dataReadResult;
636 std::string format = addressFormatStr +
":" + dataFormatStr;
637 appendCommandToHistory(command, format, time, interfaces, username);
642 void MacroMakerSupervisor::createMacro(HttpXmlDocument& xmldoc,
644 const std::string& username)
646 __SUP_COUT__ <<
"MacroMaker wants to create a macro!!!!!!!!!" << __E__;
647 std::string Name = CgiDataUtilities::postData(cgi,
"Name");
648 std::string Sequence = CgiDataUtilities::postData(cgi,
"Sequence");
649 std::string Time = CgiDataUtilities::postData(cgi,
"Time");
651 CgiDataUtilities::decodeURIComponent(CgiDataUtilities::postData(cgi,
"Notes"));
652 std::string isMacroPublic = CgiDataUtilities::getData(cgi,
"isPublic");
653 std::string isMacroLSBF = CgiDataUtilities::getData(cgi,
"isLSBF");
656 __SUP_COUTV__(Sequence);
657 __SUP_COUTV__(Notes);
659 __SUP_COUTV__(isMacroPublic);
660 __SUP_COUTV__(isMacroLSBF);
662 __SUP_COUTV__(MACROS_DB_PATH);
664 std::string fileName = Name +
".dat";
665 std::string fullPath;
666 if(isMacroPublic ==
"true")
667 fullPath = (std::string)MACROS_DB_PATH +
"publicMacros/" + fileName;
669 fullPath = (std::string)MACROS_DB_PATH + username +
"/" + fileName;
671 __SUP_COUTV__(fullPath);
673 std::ofstream macrofile(fullPath.c_str());
674 if(macrofile.is_open())
677 macrofile <<
"\"name\":\"" << Name <<
"\",\n";
678 macrofile <<
"\"sequence\":\"" << Sequence <<
"\",\n";
679 macrofile <<
"\"time\":\"" << Time <<
"\",\n";
680 macrofile <<
"\"notes\":\"" << Notes <<
"\",\n";
681 macrofile <<
"\"LSBF\":\"" << isMacroLSBF <<
"\"\n";
682 macrofile <<
"}@" << __E__;
686 __SUP_COUT__ <<
"Unable to open file" << __E__;
697 void MacroMakerSupervisor::loadMacro(
const std::string& macroName,
698 std::string& macroString,
699 const std::string& username )
701 __SUP_COUTV__(macroName);
704 std::string fullPath, line;
706 for(
unsigned int i = 0; i < 2; ++i)
709 fullPath = (std::string)MACROS_DB_PATH + username +
"/";
711 fullPath = (std::string)MACROS_DB_PATH +
"publicMacros/";
713 fullPath += macroName;
714 if(macroName.find(
".dat") != macroName.size() - 4)
716 __SUP_COUTV__(fullPath);
718 std::ifstream read(fullPath.c_str());
731 __SUP_COUT__ <<
"Unable to open file: " << fullPath << __E__;
735 if(macroString !=
"")
739 if(macroString ==
"")
741 __SUP_SS__ <<
"Unable to locate file for macro '" << macroName
742 <<
"'... does it exist?" << __E__;
744 ss <<
" Attempted username was '" << username <<
".'" << __E__;
748 __SUP_COUTV__(macroString);
752 void MacroMakerSupervisor::loadMacroNames(
753 const std::string& username,
754 std::pair<std::vector<std::string> ,
755 std::vector<std::string> >& returnMacroNames)
759 std::string fullPath = (std::string)MACROS_DB_PATH + username +
"/";
760 if((dir = opendir(fullPath.c_str())) != NULL)
763 while((ent = readdir(dir)) != NULL)
766 if((
unsigned)strlen(ent->d_name) > 4)
770 ((fullPath + (std::string)ent->d_name)).c_str());
775 returnMacroNames.second.push_back(ent->d_name);
778 __SUP_COUT__ <<
"Unable to open file" << __E__;
785 __SUP_COUT__ <<
"Looping through privateMacros folder failed! Wrong directory"
788 fullPath = (std::string)MACROS_DB_PATH +
"publicMacros/";
789 if((dir = opendir(fullPath.c_str())) != NULL)
792 while((ent = readdir(dir)) != NULL)
795 if((
unsigned)strlen(ent->d_name) > 4)
799 ((fullPath + (std::string)ent->d_name)).c_str());
803 returnMacroNames.first.push_back(ent->d_name);
807 __SUP_COUT__ <<
"Unable to open file" << __E__;
814 __SUP_COUT__ << fullPath << __E__;
815 __SUP_COUT__ <<
"Looping through MacroData folder failed! Wrong directory"
822 void MacroMakerSupervisor::loadMacros(HttpXmlDocument& xmldoc,
823 const std::string& username)
827 std::string returnStr =
"";
828 std::string fullPath = (std::string)MACROS_DB_PATH + username +
"/";
829 if((dir = opendir(fullPath.c_str())) != NULL)
832 while((ent = readdir(dir)) != NULL)
835 if((
unsigned)strlen(ent->d_name) > 4)
839 ((fullPath + (std::string)ent->d_name)).c_str());
842 std::stringstream buffer;
849 returnStr += buffer.str();
854 __SUP_COUT__ <<
"Unable to open file" << __E__;
857 std::string returnMacroStr = returnStr.substr(0, returnStr.size() - 1);
859 __SUP_COUT__ <<
"Loading existing macros! " << returnMacroStr << __E__;
862 xmldoc.addTextElementToData(
"returnMacroStr", returnMacroStr);
866 __SUP_COUT__ <<
"Looping through privateMacros folder failed! Wrong directory"
869 fullPath = (std::string)MACROS_DB_PATH +
"publicMacros/";
871 if((dir = opendir(fullPath.c_str())) != NULL)
874 while((ent = readdir(dir)) != NULL)
877 if((
unsigned)strlen(ent->d_name) > 4)
881 ((fullPath + (std::string)ent->d_name)).c_str());
884 std::stringstream buffer;
891 returnStr += buffer.str();
895 __SUP_COUT__ <<
"Unable to open file" << __E__;
898 std::string returnPublicStr = returnStr.substr(0, returnStr.size() - 1);
899 __SUP_COUT__ <<
"Loading existing public macros: " << returnPublicStr << __E__;
901 xmldoc.addTextElementToData(
"returnPublicStr", returnPublicStr);
905 __SUP_COUT__ << fullPath << __E__;
906 __SUP_COUT__ <<
"Looping through MacroData folder failed! Wrong directory"
912 void MacroMakerSupervisor::appendCommandToHistory(std::string Command,
915 std::string Interfaces,
916 const std::string& username)
918 std::string fileName =
"history.hist";
919 std::string fullPath = (std::string)MACROS_HIST_PATH + username +
"/" + fileName;
920 __SUP_COUT__ << fullPath << __E__;
921 std::ofstream histfile(fullPath.c_str(), std::ios::app);
922 if(histfile.is_open())
925 histfile <<
"\"Command\":\"" << Command <<
"\",\n";
926 histfile <<
"\"Format\":\"" << Format <<
"\",\n";
927 histfile <<
"\"Time\":\"" << Time <<
"\",\n";
928 histfile <<
"\"Interfaces\":\"" << Interfaces <<
"\"\n";
929 histfile <<
"}#" << __E__;
933 __SUP_COUT__ <<
"Unable to open history.hist" << __E__;
937 void MacroMakerSupervisor::loadHistory(HttpXmlDocument& xmldoc,
938 const std::string& username)
940 std::string fileName = MACROS_HIST_PATH + username +
"/" +
"history.hist";
942 std::ifstream read(fileName.c_str());
943 __SUP_COUT__ << fileName << __E__;
949 unsigned long long fileSz, i = 0, MAX_HISTORY_SIZE = 100000;
953 read.seekg(0, std::ios::end);
954 fileSz = read.tellg();
955 returnStr =
new char[fileSz + 1];
956 returnStr[fileSz] =
'\0';
957 read.seekg(0, std::ios::beg);
960 read.read(returnStr, fileSz);
964 if(fileSz > MAX_HISTORY_SIZE)
966 i = fileSz - MAX_HISTORY_SIZE;
967 for(; i < fileSz; ++i)
968 if(returnStr[i] ==
'#')
977 FILE* fp = fopen(fileName.c_str(),
"w");
980 __SS__ <<
"Big problem with macromaker history file: " << fileName
984 fwrite(&returnStr[i], fileSz - i, 1, fp);
988 __SUP_COUT__ <<
"Loading user history! " << __E__;
991 returnStr[fileSz - 2] =
'\0';
993 xmldoc.addTextElementToData(
"returnHistStr", &returnStr[i]);
999 __SUP_COUT__ <<
"Unable to open history.hist" << __E__;
1003 void MacroMakerSupervisor::deleteMacro(HttpXmlDocument& xmldoc,
1005 const std::string& username)
1007 std::string MacroName = CgiDataUtilities::getData(cgi,
"MacroName");
1008 std::string isMacroPublic = CgiDataUtilities::getData(cgi,
"isPublic");
1010 std::string fileName = MacroName +
".dat";
1011 std::string fullPath;
1012 if(isMacroPublic ==
"true")
1013 fullPath = (std::string)MACROS_DB_PATH +
"publicMacros/" + fileName;
1015 fullPath = (std::string)MACROS_DB_PATH + username +
"/" + fileName;
1017 __SUP_COUT__ << fullPath << __E__;
1019 std::remove(fullPath.c_str());
1020 __SUP_COUT__ <<
"Successfully deleted " << MacroName;
1021 xmldoc.addTextElementToData(
"deletedMacroName", MacroName);
1025 void MacroMakerSupervisor::editMacro(HttpXmlDocument& xmldoc,
1027 const std::string& username)
1029 std::string oldMacroName = CgiDataUtilities::postData(cgi,
"oldMacroName");
1030 std::string newMacroName = CgiDataUtilities::postData(cgi,
"newMacroName");
1031 std::string Sequence = CgiDataUtilities::postData(cgi,
"Sequence");
1032 std::string Time = CgiDataUtilities::postData(cgi,
"Time");
1034 CgiDataUtilities::decodeURIComponent(CgiDataUtilities::postData(cgi,
"Notes"));
1036 std::string isMacroPublic = CgiDataUtilities::getData(cgi,
"isPublic");
1037 std::string isMacroLSBF = CgiDataUtilities::getData(cgi,
"isLSBF");
1039 __SUP_COUTV__(oldMacroName);
1040 __SUP_COUTV__(newMacroName);
1041 __SUP_COUTV__(Sequence);
1042 __SUP_COUTV__(Notes);
1043 __SUP_COUTV__(Time);
1044 __SUP_COUTV__(isMacroPublic);
1045 __SUP_COUTV__(isMacroLSBF);
1047 __SUP_COUTV__(MACROS_DB_PATH);
1049 std::string fileName = oldMacroName +
".dat";
1050 std::string fullPath;
1051 if(isMacroPublic ==
"true")
1052 fullPath = (std::string)MACROS_DB_PATH +
"publicMacros/" + fileName;
1054 fullPath = (std::string)MACROS_DB_PATH + username +
"/" + fileName;
1056 __SUP_COUTV__(fullPath);
1058 std::ofstream macrofile(fullPath.c_str());
1059 if(macrofile.is_open())
1062 macrofile <<
"\"name\":\"" << newMacroName <<
"\",\n";
1063 macrofile <<
"\"sequence\":\"" << Sequence <<
"\",\n";
1064 macrofile <<
"\"time\":\"" << Time <<
"\",\n";
1065 macrofile <<
"\"notes\":\"" << Notes <<
"\",\n";
1066 macrofile <<
"\"LSBF\":\"" << isMacroLSBF <<
"\"\n";
1067 macrofile <<
"}@" << __E__;
1071 __SUP_COUT__ <<
"Unable to open file" << __E__;
1073 if(oldMacroName != newMacroName)
1077 rename((MACROS_DB_PATH + username +
"/" + oldMacroName +
".dat").c_str(),
1078 (MACROS_DB_PATH + username +
"/" + newMacroName +
".dat").c_str());
1080 xmldoc.addTextElementToData(
"newMacroName", newMacroName);
1082 xmldoc.addTextElementToData(
"newMacroName",
"ERROR");
1087 void MacroMakerSupervisor::clearHistory(
const std::string& username)
1089 std::string fileName =
"history.hist";
1090 std::string fullPath = (std::string)MACROS_HIST_PATH + username +
"/" + fileName;
1092 std::remove(fullPath.c_str());
1093 __SUP_COUT__ <<
"Successfully deleted " << fullPath;
1097 void MacroMakerSupervisor::exportFEMacro(HttpXmlDocument& xmldoc,
1099 const std::string& username)
1101 std::string macroName = CgiDataUtilities::getData(cgi,
"MacroName");
1102 std::string pluginName = CgiDataUtilities::getData(cgi,
"PluginName");
1103 std::string macroSequence = CgiDataUtilities::postData(cgi,
"MacroSequence");
1104 std::string macroNotes = CgiDataUtilities::decodeURIComponent(
1105 CgiDataUtilities::postData(cgi,
"MacroNotes"));
1107 __SUP_COUTV__(pluginName);
1108 __SUP_COUTV__(macroName);
1109 __SUP_COUTV__(macroSequence);
1112 for(
unsigned int i = 0; i < macroNotes.length(); ++i)
1113 if(macroNotes[i] ==
'\r' || macroNotes[i] ==
'\n')
1114 macroNotes[i] =
' ';
1115 __SUP_COUTV__(macroNotes);
1117 std::stringstream ss(macroSequence);
1118 std::string command;
1119 std::vector<std::string> commands;
1121 while(getline(ss, command,
','))
1122 commands.push_back(command);
1124 __SUP_COUTV__(StringMacros::vectorToString(commands));
1126 std::map<std::string , std::set<std::string> >
1127 specialsCodeMap = CodeEditor::getSpecialsMap();
1130 auto specialsCodeMapIt = specialsCodeMap.find(CodeEditor::SPECIAL_TYPE_FEInterface);
1131 if(specialsCodeMapIt == specialsCodeMap.end())
1134 <<
"Could not find any FE Interface plugins in source code. Does MacroMaker "
1135 <<
"have access to the source code? Check that the Supervisor context places "
1137 <<
"location with access to the source code." << __E__;
1142 std::string headerFile = pluginName +
".h";
1143 std::string sourceFile = pluginName +
"_interface.cc";
1144 bool foundHeaderFile =
false;
1145 bool foundSourceFile =
false;
1146 for(
const auto& filePath : specialsCodeMapIt->second)
1148 if(!foundHeaderFile && filePath.find(headerFile) != std::string::npos)
1150 foundHeaderFile =
true;
1151 headerFile = filePath;
1152 __SUP_COUT__ <<
"found headerFile=" << filePath << __E__;
1154 if(!foundSourceFile && filePath.find(sourceFile) != std::string::npos)
1156 foundSourceFile =
true;
1157 sourceFile = filePath;
1158 __SUP_COUT__ <<
"found sourceFile=" << filePath << __E__;
1161 if(foundSourceFile && foundHeaderFile)
1165 if(!foundHeaderFile)
1167 __SS__ <<
"Could not find the header file for the FE Interface plugins at '"
1168 << headerFile <<
".' Does MacroMaker "
1169 <<
"have access to the source code? Check that the Supervisor context "
1170 "places MacroMaker in a "
1171 <<
"location with access to the source code." << __E__;
1174 if(!foundSourceFile)
1176 __SS__ <<
"Could not find the source file for the FE Interface plugins at '"
1177 << sourceFile <<
".' Does MacroMaker "
1178 <<
"have access to the source code? Check that the Supervisor context "
1179 "places MacroMaker in a "
1180 <<
"location with access to the source code." << __E__;
1193 char timeBuffer[100];
1196 struct tm* timeinfo;
1199 timeinfo = localtime(&rawtime);
1201 strftime(timeBuffer, 100,
"%b-%d-%Y %I:%M:%S", timeinfo);
1204 std::string contents;
1209 CodeEditor::readFile(CodeEditor::SOURCE_BASE_PATH,sourceFile, contents);
1213 xmldoc.addTextElementToData(
"sourceFile", sourceFile);
1214 xmldoc.addTextElementToData(
"headerFile", headerFile);
1217 if(contents.find(pluginName +
"::" + macroName) != std::string::npos)
1219 __SS__ <<
"The function definition '" << (pluginName +
"::" + macroName)
1220 <<
"(...)' already exists in the source file '" << sourceFile
1221 <<
".' Duplicate functions are not allowed - please rename the macro or "
1222 "modify the source file."
1227 std::stringstream codess;
1228 std::set<std::string> inArgNames, outArgNames;
1235 __SUP_COUTV__(StringMacros::setToString(inArgNames));
1236 __SUP_COUTV__(StringMacros::setToString(outArgNames));
1240 auto insertPos = contents.find(pluginName +
"::" + pluginName);
1241 if(insertPos == std::string::npos)
1243 __SS__ <<
"Could not find the code insert position in the source file '"
1244 << sourceFile <<
".' The FE plugin class constructor must be '"
1245 << pluginName <<
":" << pluginName <<
"' - is this the case?" << __E__;
1248 __SUP_COUTV__(insertPos);
1250 insertPos = contents.find(
"{", insertPos);
1251 if(insertPos == std::string::npos)
1253 __SS__ <<
"Could not find the code insert position in the source file '"
1255 <<
".' The FE plugin class constructor must begin with '{"
1256 <<
"' - is this the case?" << __E__;
1260 __SUP_COUTV__(insertPos);
1262 insert =
"\n\t//registration of FEMacro '" + macroName +
"' generated, " +
1263 timeBuffer +
", by '" + username +
"' using MacroMaker.\n\t" +
1264 "FEVInterface::registerFEMacroFunction(\"" + macroName +
1265 "\",//feMacroName \n\t\t" +
1266 "static_cast<FEVInterface::frontEndMacroFunction_t>(&" + pluginName +
1267 "::" + macroName +
"), //feMacroFunction \n\t\t" +
1268 "std::vector<std::string>{";
1271 for(
const auto& inArg : inArgNames)
1277 insert +=
"\"" + inArg +
"\"";
1280 insert +=
"}, //namesOfInputArgs \n\t\t";
1281 insert +=
"std::vector<std::string>{";
1284 for(
const auto& outArg : outArgNames)
1290 insert +=
"\"" + outArg +
"\"";
1293 insert +=
"}, //namesOfOutputArgs \n\t\t";
1294 insert +=
"1); //requiredUserPermissions \n\n";
1296 __SUP_COUTV__(insert);
1297 contents = contents.substr(0, insertPos) + insert + contents.substr(insertPos);
1302 auto insertPos = contents.rfind(
"DEFINE_OTS_INTERFACE");
1303 if(insertPos == std::string::npos)
1305 __SS__ <<
"Could not find the code insert position in the source file '"
1307 <<
".' The FE plugin class must end with a 'DEFINE_OTS_INTERFACE("
1308 << pluginName <<
")' - is this the case?" << __E__;
1311 __SUP_COUTV__(insertPos);
1315 "============================================================================"
1316 "============================================\n//" +
1317 macroName +
"\n" +
"//\tFEMacro '" + macroName +
"' generated, " +
1318 timeBuffer +
", by '" + username +
"' using MacroMaker.\n" +
1319 "//\tMacro Notes: " + macroNotes +
"\n" +
"void " + pluginName +
1320 "::" + macroName +
"(__ARGS__)\n{\n\t" +
1321 "__CFG_COUT__ << \"# of input args = \" << argsIn.size() << __E__; \n\t" +
1322 "__CFG_COUT__ << \"# of output args = \" << argsOut.size() << __E__; \n\t" +
1323 "for(auto &argIn:argsIn) \n\t\t" +
1324 "__CFG_COUT__ << argIn.first << \": \" << argIn.second << __E__; \n\n\t" +
1325 "//macro commands section \n" + codess.str() +
"\n\n\t" +
1326 "for(auto &argOut:argsOut) \n\t\t" +
1327 "__CFG_COUT__ << argOut.first << \": \" << argOut.second << __E__; \n\n" +
1328 "} //end " + macroName +
"()\n\n";
1331 CodeEditor::writeFile(CodeEditor::SOURCE_BASE_PATH,
1332 sourceFile, contents,
"MacroMaker-" + username, insertPos, insert);
1337 CodeEditor::readFile(CodeEditor::SOURCE_BASE_PATH, headerFile, contents);
1342 auto insertPos = contents.rfind(
"};");
1343 if(insertPos == std::string::npos)
1345 __SS__ <<
"Could not find the code insert position in the header file '"
1347 <<
".' The FE plugin class must end with a '};' - is this the case?"
1352 __SUP_COUTV__(insertPos);
1354 insert =
"\npublic: // FEMacro '" + macroName +
"' generated, " + timeBuffer +
1355 ", by '" + username +
"' using MacroMaker.\n\t" +
"void " + macroName +
1358 __SUP_COUTV__(insert);
1359 CodeEditor::writeFile(CodeEditor::SOURCE_BASE_PATH,
1360 headerFile, contents,
"MacroMaker-" + username, insertPos, insert);
1366 void MacroMakerSupervisor::exportMacro(HttpXmlDocument& xmldoc,
1368 const std::string& username)
1370 std::string macroName = CgiDataUtilities::getData(cgi,
"MacroName");
1371 std::string macroSequence = CgiDataUtilities::postData(cgi,
"MacroSequence");
1372 std::string macroNotes = CgiDataUtilities::decodeURIComponent(
1373 CgiDataUtilities::postData(cgi,
"MacroNotes"));
1375 __SUP_COUTV__(macroName);
1376 __SUP_COUTV__(macroSequence);
1379 for(
unsigned int i = 0; i < macroNotes.length(); ++i)
1380 if(macroNotes[i] ==
'\r' || macroNotes[i] ==
'\n')
1381 macroNotes[i] =
' ';
1382 __SUP_COUTV__(macroNotes);
1384 std::stringstream ss(macroSequence);
1385 std::string command;
1386 std::vector<std::string> commands;
1388 while(getline(ss, command,
','))
1389 commands.push_back(command);
1391 std::string fileName = macroName +
".cc";
1393 std::string fullPath = (std::string)MACROS_EXPORT_PATH + username +
"/" + fileName;
1394 __SUP_COUT__ << fullPath << __E__;
1395 std::ofstream exportFile(fullPath.c_str(), std::ios::trunc);
1396 if(exportFile.is_open())
1398 exportFile <<
"//Generated Macro Name:\t" << macroName <<
"\n";
1399 exportFile <<
"//Macro Notes: " << macroNotes <<
"\n";
1403 struct tm* timeinfo;
1407 timeinfo = localtime(&rawtime);
1409 strftime(buffer, 100,
"%b-%d-%Y %I:%M:%S", timeinfo);
1410 exportFile <<
"//Generated Time: \t\t" << buffer <<
"\n";
1413 exportFile <<
"//Paste this whole file into an interface to transfer Macro "
1416 createCode(exportFile, commands);
1420 xmldoc.addTextElementToData(
"ExportFile", fullPath);
1423 __SUP_COUT__ <<
"Unable to open file" << __E__;
1428 void MacroMakerSupervisor::createCode(std::ostream& out,
1429 const std::vector<std::string>& commands,
1430 const std::string& tabOffset,
1432 std::set<std::string>* inArgNames,
1433 std::set<std::string>* outArgNames)
1436 std::set<std::string > argInHasBeenInitializedSet;
1437 bool addressIsVariable, dataIsVariable;
1439 out << tabOffset <<
"{";
1442 << tabOffset <<
"\t"
1443 <<
"char *address \t= new char[universalAddressSize_]{0}; //create address "
1444 "buffer of interface size and init to all 0";
1446 << tabOffset <<
"\t"
1447 <<
"char *data \t\t= new char[universalDataSize_]{0}; //create data buffer "
1448 "of interface size and init to all 0";
1451 << tabOffset <<
"\t"
1452 <<
"uint64_t macroAddress; //create macro address buffer (size 8 bytes)";
1454 << tabOffset <<
"\t"
1455 <<
"uint64_t macroData; //create macro address buffer (size 8 bytes)";
1458 << tabOffset <<
"\t"
1459 <<
"std::map<std::string /*arg name*/,uint64_t /*arg val*/> macroArgs; //create "
1460 "map from arg name to 64-bit number";
1463 for(
unsigned int i = 0; i < commands.size(); i++)
1465 std::stringstream sst(commands[i]);
1467 std::vector<std::string>
1469 while(getline(sst, tokens,
':'))
1470 oneCommand.push_back(tokens);
1471 while(oneCommand.size() < 4)
1472 oneCommand.push_back(
"");
1474 __SUP_COUTV__(StringMacros::vectorToString(oneCommand));
1500 addressIsVariable = isArgumentVariable(oneCommand[2]);
1501 dataIsVariable = isArgumentVariable(oneCommand[3]);
1503 __SUP_COUTV__(addressIsVariable);
1504 __SUP_COUTV__(dataIsVariable);
1506 out <<
"\n\n" << tabOffset <<
"\t// command-#" << i <<
": ";
1508 if(oneCommand[1][0] ==
'w' || oneCommand[1][0] ==
'r')
1510 if(oneCommand[1][0] ==
'w')
1512 else if(oneCommand[1][0] ==
'r')
1515 if(addressIsVariable)
1516 out << oneCommand[2];
1518 out <<
"0x" << oneCommand[2];
1519 out <<
" /*address*/,";
1523 out << oneCommand[3] <<
" /*data*/";
1524 else if(oneCommand[1][0] ==
'w')
1525 out <<
"0x" << oneCommand[3] <<
" /*data*/";
1526 else if(oneCommand[1][0] ==
'r')
1530 else if(oneCommand[1][0] ==
'd')
1532 out <<
"delay(" << oneCommand[2] <<
");\n";
1533 out << tabOffset <<
"\t"
1534 <<
"__CFG_COUT__ << \"Sleeping for... \" << " << oneCommand[2]
1535 <<
" << \" milliseconds \" << __E__;\n";
1536 out << tabOffset <<
"\t"
1537 <<
"usleep(" << oneCommand[2] <<
"*1000 /* microseconds */);\n";
1542 __SS__ <<
"FATAL ERROR: Unknown command '" << oneCommand[1]
1543 <<
"'... command is not w, r or d" << __E__;
1549 if(addressIsVariable)
1551 if(argInHasBeenInitializedSet.find(oneCommand[2]) ==
1552 argInHasBeenInitializedSet.end())
1554 argInHasBeenInitializedSet.emplace(oneCommand[2]);
1559 out << tabOffset <<
"\t"
1560 <<
"macroArgs[\"" << oneCommand[2]
1562 "theXDAQContextConfigTree_.getNode(theConfigurationPath_)."
1565 << tabOffset <<
"\t\t\"" << oneCommand[2]
1566 <<
"\").getValue<uint64_t>();";
1571 inArgNames->emplace(oneCommand[2]);
1574 out << tabOffset <<
"\t"
1575 <<
"macroArgs[\"" << oneCommand[2] <<
"\"] = __GET_ARG_IN__(\""
1576 << oneCommand[2] <<
"\", uint64_t);";
1579 out <<
"\t//get macro address argument";
1581 << tabOffset <<
"\tmemcpy(address,¯oArgs[\"" << oneCommand[2]
1582 <<
"\"],8); //copy macro address argument to buffer";
1586 out << tabOffset <<
"\t"
1587 <<
"macroAddress = 0x" << oneCommand[2]
1588 <<
"; memcpy(address,¯oAddress,8);"
1589 <<
"\t//copy macro address to buffer";
1594 if(oneCommand[1] ==
"w")
1598 if(argInHasBeenInitializedSet.find(oneCommand[3]) ==
1599 argInHasBeenInitializedSet
1602 argInHasBeenInitializedSet.emplace(oneCommand[3]);
1607 inArgNames->emplace(oneCommand[3]);
1611 << tabOffset <<
"\t"
1612 <<
"macroArgs[\"" << oneCommand[3]
1613 <<
"\"] = __GET_ARG_IN__(\"" << oneCommand[3]
1614 <<
"\", uint64_t); //initialize from input arguments";
1620 << tabOffset <<
"\t"
1621 <<
"macroArgs[\"" << oneCommand[3]
1623 "theXDAQContextConfigTree_.getNode(theConfigurationPath_)."
1626 << tabOffset <<
"\t\t\"" << oneCommand[3]
1627 <<
"\").getValue<uint64_t>(); //initialize from "
1628 "configuration tree";
1631 out <<
"\t//get macro data argument";
1633 << tabOffset <<
"\tmemcpy(data,¯oArgs[\"" << oneCommand[3]
1634 <<
"\"],8); //copy macro data argument to buffer";
1639 << tabOffset <<
"\t"
1640 <<
"macroData = 0x" << oneCommand[3] <<
"; memcpy(data,¯oData,8);"
1641 <<
"\t//copy macro data to buffer";
1644 << tabOffset <<
"\t"
1645 <<
"universalWrite(address,data);";
1650 << tabOffset <<
"\t"
1651 <<
"universalRead(address,data);";
1653 std::string outputArgName;
1656 outputArgName = oneCommand[3];
1660 sprintf(str,
"outArg%d", i);
1661 outputArgName = str;
1663 __SUP_COUTV__(outputArgName);
1665 out << tabOffset <<
"\t"
1666 <<
"memcpy(¯oArgs[\"" << outputArgName
1667 <<
"\"],data,8); //copy buffer to argument map";
1672 << tabOffset <<
"\t"
1673 <<
"__SET_ARG_OUT__(\"" << outputArgName <<
"\",macroArgs[\""
1674 << outputArgName <<
"\"]); //update output argument result";
1677 outArgNames->emplace(outputArgName);
1678 argInHasBeenInitializedSet.emplace(
1683 out <<
"\n\n" << tabOffset <<
"\tdelete[] address; //free the memory";
1684 out <<
"\n" << tabOffset <<
"\tdelete[] data; //free the memory";
1685 out <<
"\n" << tabOffset <<
"}";
1687 __SUP_COUT__ <<
"Done with code generation." << __E__;
1693 bool MacroMakerSupervisor::isArgumentVariable(
const std::string& argumentString)
1695 for(
unsigned int i = 0; i < argumentString.length(); ++i)
1698 if(!((argumentString[i] >=
'0' && argumentString[i] <=
'9') ||
1699 (argumentString[i] >=
'a' && argumentString[i] <=
'f') ||
1700 (argumentString[i] >=
'A' && argumentString[i] <=
'F')))
1715 std::string MacroMakerSupervisor::generateHexArray(
const std::string& sourceHexString,
1718 std::stringstream retSs;
1720 std::string srcHexStr = sourceHexString;
1721 __SUP_COUT__ <<
"Translating: \n";
1722 __SUP_COUT__ << srcHexStr << __E__;
1724 if(srcHexStr.size() % 2)
1725 srcHexStr =
"0" + srcHexStr;
1727 numOfBytes = srcHexStr.size() / 2;
1728 retSs <<
"[" << numOfBytes <<
"] = {";
1730 for(
int i = 0; i < numOfBytes * 2; i += 2)
1733 if(!((srcHexStr[i] >=
'0' && srcHexStr[i] <=
'9') ||
1734 (srcHexStr[i] >=
'a' && srcHexStr[i] <=
'f') ||
1735 (srcHexStr[i] >=
'A' && srcHexStr[i] <=
'F')) ||
1736 !((srcHexStr[i + 1] >=
'0' && srcHexStr[i + 1] <=
'9') ||
1737 (srcHexStr[i + 1] >=
'a' && srcHexStr[i + 1] <=
'f') ||
1738 (srcHexStr[i + 1] >=
'A' && srcHexStr[i + 1] <=
'F')))
1746 retSs <<
"0x" << srcHexStr[srcHexStr.size() - 1 - i - 1]
1747 << srcHexStr[srcHexStr.size() - 1 - i];
1751 __SUP_COUT__ << retSs.str() << __E__;
1757 void MacroMakerSupervisor::runFEMacro(HttpXmlDocument& xmldoc, cgicc::Cgicc& cgi,
1758 const std::string& username)
1761 __SUP_COUT__ << __E__;
1764 std::string feClassSelected= CgiDataUtilities::getData(cgi,
"feClassSelected");
1765 std::string feUIDSelected = CgiDataUtilities::getData(cgi,
"feUIDSelected");
1766 std::string macroType = CgiDataUtilities::getData(cgi,
"macroType");
1767 std::string macroName = CgiDataUtilities::getData(cgi,
"macroName");
1768 std::string inputArgs = CgiDataUtilities::postData(cgi,
"inputArgs");
1769 std::string outputArgs = CgiDataUtilities::postData(cgi,
"outputArgs");
1770 bool saveOutputs = CgiDataUtilities::getDataAsInt(cgi,
"saveOutputs")==1;
1773 __SUP_COUTV__(feClassSelected);
1774 __SUP_COUTV__(feUIDSelected);
1775 __SUP_COUTV__(macroType);
1776 __SUP_COUTV__(macroName);
1777 __SUP_COUTV__(inputArgs);
1778 __SUP_COUTV__(outputArgs);
1779 __SUP_COUTV__(saveOutputs);
1781 std::set<std::string > feUIDs;
1783 if(feUIDSelected ==
"") feUIDSelected =
"*";
1784 if(feClassSelected ==
"") feClassSelected =
"*";
1786 if(feClassSelected ==
"" || feUIDSelected ==
"" || macroType ==
"" ||
1789 __SUP_SS__ <<
"Illegal empty front-end parameter." << __E__;
1792 else if(feUIDSelected !=
"*")
1793 feUIDs.emplace(feUIDSelected);
1797 if(feClassSelected ==
"*")
1799 for(
auto& feTypePair:FEPluginTypetoFEsMap_)
1800 for(
auto& feUID:feTypePair.second)
1801 feUIDs.emplace(feUID);
1805 auto typeIt = FEPluginTypetoFEsMap_.find(feClassSelected);
1806 if(typeIt == FEPluginTypetoFEsMap_.end())
1808 __SUP_SS__ <<
"Illegal front-end type parameter '" <<
1809 feClassSelected <<
"' not in list of types." << __E__;
1813 for(
auto& feUID:typeIt->second)
1814 feUIDs.emplace(feUID);
1818 __SUP_COUTV__(StringMacros::setToString(feUIDs));
1820 std::string macroString;
1821 if(macroType ==
"public")
1822 loadMacro(macroName,macroString);
1823 else if(macroType ==
"private")
1824 loadMacro(macroName,macroString,username);
1826 __SUP_COUTV__(macroString);
1833 std::string filename =
"/macroOutput_" +
1834 std::to_string(time(0)) +
"_" + std::to_string(clock()) +
".txt";
1836 __SUP_COUTV__(filename);
1837 fp = fopen((CodeEditor::OTSDAQ_DATA_PATH + filename).c_str(),
"w");
1840 __SUP_SS__ <<
"Failed to open file to save macro output '" <<
1841 CodeEditor::OTSDAQ_DATA_PATH <<
1842 filename <<
"'..." << __E__;
1846 fprintf(fp,
"############################\n");
1847 fprintf(fp,
"### Running '%s' at time %s\n",macroName.c_str(),
1848 StringMacros::getTimestampString().c_str());
1849 fprintf(fp,
"### \t Target front-ends (count=%lu): %s\n",
1850 feUIDs.size(),StringMacros::setToString(feUIDs).c_str());
1851 fprintf(fp,
"### \t\t Inputs: %s\n",inputArgs.c_str());
1852 fprintf(fp,
"############################\n\n\n");
1855 xmldoc.addTextElementToData(
"outputArgs_name",
"Filename");
1856 xmldoc.addTextElementToData(
"outputArgs_value",
1857 "$OTSDAQ_DATA/" + filename);
1862 for(
auto& feUID:feUIDs)
1864 auto feIt = FEtoSupervisorMap_.find(feUID);
1865 if(feIt == FEtoSupervisorMap_.end())
1867 __SUP_SS__ <<
"Destination front end interface ID '" << feUID
1868 <<
"' was not found in the list of front ends." << __E__;
1869 ss <<
"\n\nHere is the map:\n\n" << StringMacros::mapToString(FEtoSupervisorMap_) << __E__;
1873 unsigned int FESupervisorIndex = feIt->second;
1874 __SUP_COUT__ <<
"Found supervisor index: " << FESupervisorIndex << __E__;
1876 SupervisorInfoMap::iterator it = allFESupervisorInfo_.find(FESupervisorIndex);
1877 if(it == allFESupervisorInfo_.end())
1879 __SUP_SS__ <<
"Error transmitting request to FE Supervisor '"
1880 << feUID <<
":" << FESupervisorIndex <<
".' \n\n"
1881 <<
"The FE Supervisor Index does not exist. Have you configured "
1882 "the state machine properly?"
1888 SOAPParameters txParameters;
1889 if(macroType ==
"fe")
1890 txParameters.addParameter(
"Request",
"RunInterfaceMacro");
1892 txParameters.addParameter(
"Request",
"RunMacroMakerMacro");
1893 txParameters.addParameter(
"InterfaceID", feUID);
1894 if(macroType ==
"fe")
1895 txParameters.addParameter(
"feMacroName", macroName);
1898 txParameters.addParameter(
"macroName", macroName);
1899 txParameters.addParameter(
"macroString", macroString);
1901 txParameters.addParameter(
"inputArgs", inputArgs);
1902 txParameters.addParameter(
"outputArgs", outputArgs);
1904 SOAPParameters rxParameters;
1906 rxParameters.addParameter(
"outputArgs");
1907 rxParameters.addParameter(
"Error");
1911 fprintf(fp,
"Running '%s' at time %s\n",macroName.c_str(),
1912 StringMacros::getTimestampString().c_str());
1913 fprintf(fp,
"\t Target front-end: '%s::%s'\n",
1914 FEtoPluginTypeMap_[feUID].c_str(),feUID.c_str());
1915 fprintf(fp,
"\t\t Inputs: %s\n",inputArgs.c_str());
1919 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
1920 it->second.getDescriptor(),
1921 "MacroMakerSupervisorRequest",
1925 __SUP_COUT__ <<
"Received response message: "
1926 << SOAPUtilities::translate(retMsg) << __E__;
1928 SOAPUtilities::receive(retMsg, rxParameters);
1930 __SUP_COUT__ <<
"Received it " << __E__;
1933 std::string outputResults = rxParameters.getValue(
"outputArgs");
1934 std::string error = rxParameters.getValue(
"Error");
1937 __SUP_COUT__ <<
"outputArgs = " << outputResults << __E__;
1941 __SS__ <<
"Attempted FE Macro Failed. Attempted target "
1942 <<
"was UID=" << feUID <<
" at feSupervisorID=" << FESupervisorIndex <<
"."
1944 ss <<
"\n\n The error was:\n\n" << error << __E__;
1945 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1946 xmldoc.addTextElementToData(
"Error", ss.str());
1954 std::istringstream inputStream(outputResults);
1955 std::string splitVal, argName, argValue;
1956 while(getline(inputStream, splitVal,
';'))
1958 std::istringstream pairInputStream(splitVal);
1959 getline(pairInputStream, argName,
',');
1960 getline(pairInputStream, argValue,
',');
1964 fprintf(fp,
"\t\t Output '%s' = %s\n",
1965 argName.c_str(),argValue.c_str());
1969 xmldoc.addTextElementToData(
"outputArgs_name", argName);
1970 xmldoc.addTextElementToData(
"outputArgs_value", argValue);
1972 __SUP_COUT__ << argName <<
": " << argValue << __E__;
1986 catch(
const std::runtime_error& e)
1988 __SUP_SS__ <<
"Error processing FE communication request: " <<
1990 __SUP_COUT_ERR__ << ss.str();
1991 xmldoc.addTextElementToData(
"Error", ss.str());
1995 __SUP_SS__ <<
"Unknown error processing FE communication request." << __E__;
1996 __SUP_COUT_ERR__ << ss.str();
1998 xmldoc.addTextElementToData(
"Error", ss.str());
2002 void MacroMakerSupervisor::getFEMacroList(HttpXmlDocument& xmldoc,
2003 const std::string& username)
2005 __SUP_COUT__ <<
"Getting FE Macro list" << __E__;
2007 SOAPParameters txParameters;
2008 txParameters.addParameter(
"Request",
"GetInterfaceMacros");
2010 SOAPParameters rxParameters;
2011 rxParameters.addParameter(
"FEMacros");
2013 std::string oneInterface;
2014 std::string rxFEMacros;
2018 for(
auto& appInfo : allFESupervisorInfo_)
2020 __SUP_COUT__ <<
"FESupervisor LID = " << appInfo.second.getId()
2021 <<
" name = " << appInfo.second.getName() << __E__;
2023 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
2024 appInfo.second.getDescriptor(),
"MacroMakerSupervisorRequest", txParameters);
2025 SOAPUtilities::receive(retMsg, rxParameters);
2027 rxFEMacros = rxParameters.getValue(
"FEMacros");
2029 __SUP_COUT__ <<
"FE Macros received: \n" << rxFEMacros << __E__;
2031 std::istringstream allInterfaces(rxFEMacros);
2032 while(std::getline(allInterfaces, oneInterface))
2036 xmldoc.addTextElementToData(
"FEMacros", oneInterface);
2042 std::pair<std::vector<std::string> ,
2043 std::vector<std::string> > macroNames;
2044 loadMacroNames(username,macroNames);
2046 __SUP_COUT__ <<
"Public macro count: " << macroNames.first.size() << __E__;
2047 __SUP_COUT__ <<
"Private macro count: " << macroNames.second.size() << __E__;
2049 std::string macroString;
2059 for(
int i=0;i<2;++i)
2060 for(
auto& macroName:(i?macroNames.second:macroNames.first))
2063 loadMacro(macroName,macroString,username);
2066 FEVInterface::macroStruct_t macro(macroString);
2068 std::stringstream xmlMacroStream;
2069 xmlMacroStream << macro.macroName_;
2070 xmlMacroStream <<
":" <<
"1";
2071 xmlMacroStream <<
":" << macro.namesOfInputArguments_.size();
2072 for(
auto& inputArg:macro.namesOfInputArguments_)
2073 xmlMacroStream <<
":" << inputArg;
2074 xmlMacroStream <<
":" << macro.namesOfOutputArguments_.size();
2075 for(
auto& inputArg:macro.namesOfOutputArguments_)
2076 xmlMacroStream <<
":" << inputArg;
2078 xmldoc.addTextElementToData(i?
"PrivateMacro":
"PublicMacro", xmlMacroStream.str());