PageRenderTime 58ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 1ms

/structural/supporting_matl_misc_and_old/support/matrixTypeGenerator/ver_2/BLAS_LAPACK/generator/src/laFortRead.cpp

https://bitbucket.org/slawton/windturbinemdo-stevebitb
C++ | 6229 lines | 4928 code | 739 blank | 562 comment | 858 complexity | c5e787dc7056794a46af21b0c488ee4a MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause
  1. #include <fstream>
  2. #include <ostream>
  3. #include <iostream>
  4. #include <vector>
  5. #include <list>
  6. #include <string>
  7. #include <cctype>
  8. #include <cstdlib>
  9. #include <sstream>
  10. #include <sys/types.h>
  11. #include <sys/stat.h>
  12. #include <unistd.h>
  13. #include "eMsg.h"
  14. using namespace std;
  15. #define LINE_SIZE 1024
  16. // this is a list of all the globals
  17. // objList<fortranType> fTypes;
  18. // objList<cppType_basic> bTypes;
  19. // objList<cppType_template> tTypes;
  20. // list<fortranFunction> fortranFunctionList;
  21. // objList<mapText> textMaps;
  22. // objList<cppFunctionName> cppFuncs;
  23. // cppType* voidType;
  24. // sourceFile fortranSource;
  25. // sourceFile cppPrototype;
  26. // sourceFile cppDefinition;
  27. // commandSource_recording recorder;
  28. char* copyLine(const char* ln)
  29. {
  30. unsigned long L=0;
  31. if(ln==NULL)
  32. throw eMsg("fortranFunction: the input array is NULL");
  33. while(ln[L]!=0)
  34. L++;
  35. L++;
  36. char* retVal=new char[L];
  37. if(retVal==NULL)
  38. throw eMsg("copyLine(): Failed to allocate memory");
  39. for(unsigned long i=0;i<L;i++)
  40. retVal[i]=ln[i];
  41. return retVal;
  42. }
  43. bool strEqual(const char* lhs, const char* rhs)
  44. {
  45. if(lhs==NULL || rhs==NULL)
  46. {
  47. if(lhs==rhs)
  48. return true;
  49. return false;
  50. }
  51. unsigned long i=0;
  52. while(lhs[i]!=0 && rhs!=0)
  53. {
  54. if(lhs[i]!=rhs[i])
  55. return false;
  56. i++;
  57. }
  58. if(rhs[i]!=lhs[i])
  59. return false;
  60. return true;
  61. }
  62. bool strFilterEqual(const char* fltr, const char* test)
  63. {
  64. unsigned long at=0;
  65. unsigned long atFlt=0;
  66. // Null filter means everything matches automatically
  67. if(fltr[atFlt]==0)
  68. return true;
  69. while(fltr[atFlt]!=0 && test[at]!=0)
  70. {
  71. // Are we matching tokens?
  72. if(fltr[atFlt]=='*')
  73. {
  74. atFlt++;
  75. // test to see if there is a trailing token, otherwise we return true
  76. if(fltr[atFlt]==0)
  77. return true;
  78. // The function of a '**' is undefined
  79. if(fltr[atFlt]=='*')
  80. throw eMsg("strFilterEqual(): '**' type filter not allowed");
  81. // There is a token and thus we need to find a match
  82. bool seekMatch=true;
  83. while(seekMatch)
  84. {
  85. // seek forward until a possible match
  86. while(test[at]!=0 && test[at]!=fltr[atFlt])
  87. at++;
  88. if(test[at]==0)
  89. return false;
  90. unsigned long cnt=0;
  91. while(test[at+cnt]!=0 && fltr[atFlt+cnt]!=0 && fltr[atFlt+cnt]!='*' && test[at+cnt]==fltr[atFlt+cnt])
  92. cnt++;
  93. // test to see if the test string ran out
  94. if( test[at+cnt]==0 )
  95. // this is ok only if we are at the end of the filter
  96. return fltr[atFlt+cnt]==0 || (fltr[atFlt+cnt]=='*' && fltr[atFlt+cnt+1]==0);
  97. // string didn;t run out test to see if the token was matched
  98. if( fltr[atFlt+cnt]=='*' || fltr[atFlt+cnt]==0 )
  99. {
  100. at+=cnt;
  101. atFlt+=cnt;
  102. // Test if the filter has ended, if so then we can complete the test
  103. if( fltr[atFlt]==0 )
  104. return test[at]==0;
  105. // everything matched and nothing has ended so we keep searching
  106. seekMatch=false;
  107. }
  108. else
  109. {
  110. // could not find token match, try again starting from the next character
  111. at++;
  112. }
  113. }
  114. }
  115. else
  116. {
  117. // no '*' has been found so a simple search
  118. if(test[at]!=fltr[atFlt])
  119. return false;
  120. at++;
  121. atFlt++;
  122. }
  123. }
  124. // reached the end of test or filter thus only successful if both at the end
  125. return test[at]==fltr[atFlt];
  126. }
  127. class wordList
  128. {
  129. private:
  130. unsigned long sz;
  131. vector<unsigned long> start;
  132. vector<unsigned long> end;
  133. char* line;
  134. public:
  135. wordList& setLine(const char* line_in)
  136. {
  137. if(line_in==NULL)
  138. {
  139. sz=0;
  140. return *this;
  141. }
  142. unsigned long at=0;
  143. sz=0;
  144. while(line_in[at]!=0)
  145. {
  146. while(line_in[at]!=0 && isspace(line_in[at]))
  147. at++;
  148. if(line_in[at]!=0)
  149. sz++;
  150. while(line_in[at]!=0 && !isspace(line_in[at]))
  151. at++;
  152. }
  153. start.resize(sz);
  154. end.resize(sz);
  155. if(line!=NULL)
  156. delete[] line;
  157. line=new char[at+1];
  158. at=0;
  159. unsigned long atWrd=0;
  160. while(line_in[at]!=0)
  161. {
  162. while(line_in[at]!=0 && isspace(line_in[at]))
  163. {
  164. line[at]=line_in[at];
  165. at++;
  166. }
  167. if(line_in[at]!=0)
  168. start[atWrd]=at;
  169. while(line_in[at]!=0 && !isspace(line_in[at]))
  170. {
  171. end[atWrd]=at;
  172. line[at]=line_in[at];
  173. at++;
  174. }
  175. atWrd++;
  176. }
  177. line[at]=0;
  178. return *this;
  179. }
  180. wordList(const char* line_in=NULL) : sz(0) , start(0) , end(0) , line(NULL)
  181. {
  182. setLine(line_in);
  183. }
  184. ~wordList()
  185. {
  186. if(line!=NULL)
  187. delete[] line;
  188. }
  189. wordList& getWord(unsigned long at, char* word, unsigned long bfSz)
  190. {
  191. if(at>=sz)
  192. throw eMsg("wordList: The argument does not exist");
  193. unsigned long wSz=end[at]-start[at]+1;
  194. if(wSz>bfSz+1)
  195. throw eMsg("wordList: the buffer provided is not big enough");
  196. unsigned long i;
  197. for(i=0;i<wSz;i++)
  198. word[i]=line[start[at]+i];
  199. word[i]=0;
  200. return *this;
  201. }
  202. unsigned long size()
  203. {
  204. return sz;
  205. }
  206. unsigned long getStart(unsigned long at)
  207. {
  208. if(at>=sz)
  209. throw eMsg("wordList: the requested start does not exist");
  210. return start[at];
  211. }
  212. unsigned long getEnd(unsigned long at)
  213. {
  214. if(at>=sz)
  215. throw eMsg("wordList: the requested end does not exist");
  216. return end[at];
  217. }
  218. };
  219. class cppType
  220. {
  221. protected:
  222. static int typeID;
  223. int myID;
  224. friend class cppType_template;
  225. virtual void addMyID(list<int>& idList) const
  226. {
  227. idList.push_back(myID);
  228. }
  229. public:
  230. cppType()
  231. {
  232. myID=typeID++;
  233. }
  234. cppType(const cppType& rhs)
  235. {
  236. this->myID=rhs.myID;
  237. }
  238. virtual ~cppType()
  239. {}
  240. // virtual const char* getName()=0;
  241. virtual void printType(ostream& out)=0;
  242. virtual void printDescription(ostream& out)=0;
  243. virtual cppType* copyType()=0;
  244. bool operator==(const cppType& rhs)
  245. {
  246. list<int> lhsType;
  247. list<int> rhsType;
  248. this->addMyID(lhsType);
  249. rhs.addMyID(rhsType);
  250. unsigned long tpCount=lhsType.size();
  251. if(tpCount!=rhsType.size())
  252. return false;
  253. list<int>::iterator itLhs=lhsType.begin();
  254. list<int>::iterator itRhs=rhsType.begin();
  255. for(unsigned long i=0;i<tpCount;i++)
  256. {
  257. if(*itLhs!=*itRhs)
  258. return false;
  259. itLhs++;
  260. itRhs++;
  261. }
  262. return true;
  263. }
  264. bool operator!=(const cppType& rhs)
  265. {
  266. return !(*this==rhs);
  267. }
  268. };
  269. int cppType::typeID=0;
  270. class cppType_basic : public cppType
  271. {
  272. private:
  273. char* name;
  274. char* description;
  275. public:
  276. cppType_basic& setName(const char* name_in)
  277. {
  278. unsigned long i=0;
  279. while(name_in[i]!=0)
  280. i++;
  281. i++;
  282. if(name!=NULL)
  283. delete[] name;
  284. name=new char[i];
  285. if(name==NULL)
  286. throw eMsg("cppType_basic::setName(): Failed to allocate memory");
  287. for(unsigned long j=0;j<i;j++)
  288. name[j]=name_in[j];
  289. return *this;
  290. }
  291. cppType_basic& setDescription(const char* desc_in)
  292. {
  293. unsigned long i=0;
  294. while(desc_in[i]!=0)
  295. i++;
  296. i++;
  297. if(description!=NULL)
  298. delete[] description;
  299. description=new char[i];
  300. if(description==NULL)
  301. throw eMsg("cppType_basic::setDescription(): Failed to allocate memory");
  302. for(unsigned long j=0;j<i;j++)
  303. description[j]=desc_in[j];
  304. return *this;
  305. }
  306. cppType_basic() : name(NULL) , description(NULL)
  307. {}
  308. cppType_basic(const char* name_in, const char* desc_in) : name(NULL) , description(NULL)
  309. {
  310. setName(name_in);
  311. setDescription(desc_in);
  312. }
  313. cppType_basic(const cppType_basic& rhs) : cppType(rhs) , name(NULL) , description(NULL)
  314. {
  315. if(rhs.name!=NULL)
  316. this->setName(rhs.name);
  317. if(rhs.description)
  318. this->setDescription(rhs.description);
  319. }
  320. virtual ~cppType_basic()
  321. {
  322. if(name!=NULL)
  323. delete[] name;
  324. if(description!=NULL)
  325. delete[] description;
  326. }
  327. virtual void printType(ostream& out)
  328. {
  329. if(name==NULL)
  330. return;
  331. out << name;
  332. }
  333. virtual void printDescription(ostream& out)
  334. {
  335. if(description==NULL)
  336. return;
  337. out << name << ": " << description;
  338. }
  339. virtual cppType* copyType()
  340. {
  341. return new cppType_basic(*this);
  342. }
  343. const char* getName()
  344. {
  345. return name;
  346. }
  347. };
  348. class cppType_template : public cppType_basic
  349. {
  350. private:
  351. vector<bool> isType;
  352. vector<cppType*> args;
  353. vector<int> vals;
  354. vector<bool> canDelete;
  355. void addMyID(list<int>& idList) const
  356. {
  357. this->cppType::addMyID(idList);
  358. for(unsigned long i=0;i<args.size();i++)
  359. {
  360. if(isType[i])
  361. {
  362. if(args[i]==NULL)
  363. throw eMsg("cppType_template: template parameter has not been set");
  364. args[i]->addMyID(idList);
  365. }
  366. else
  367. {
  368. idList.push_back(vals[i]);
  369. }
  370. }
  371. }
  372. public:
  373. cppType_template(const char* name_in,const char* desc_in,unsigned long size_in) : cppType_basic(name_in,desc_in) , isType(size_in,true) , args(size_in,NULL) , vals(size_in,0) , canDelete(size_in,false)
  374. {}
  375. cppType_template(unsigned long size_in=0) : isType(size_in,true) , args(size_in,NULL) , vals(size_in,0) , canDelete(size_in,false)
  376. {}
  377. cppType_template(const cppType_template& rhs) : cppType_basic(rhs) , isType(rhs.isType) , args(rhs.args) , vals(rhs.vals) , canDelete(rhs.isType.size(),false)
  378. {}
  379. virtual ~cppType_template()
  380. {
  381. for(unsigned long i=0;i<args.size();i++)
  382. {
  383. if(canDelete[i] && args[i]!=NULL)
  384. delete args[i];
  385. }
  386. }
  387. cppType_template& resize(unsigned long size_in=0)
  388. {
  389. isType.resize(size_in,true);
  390. args.resize(size_in,NULL);
  391. vals.resize(size_in,0);
  392. canDelete.resize(size_in,false);
  393. return *this;
  394. }
  395. unsigned long size()
  396. {
  397. return isType.size();
  398. }
  399. cppType_template& clearTypes()
  400. {
  401. for(unsigned long i=0;i<isType.size();i++)
  402. {
  403. if(isType[i])
  404. args[i]=NULL;
  405. }
  406. return *this;
  407. }
  408. cppType_template& setArgType(unsigned long at, cppType* arg, bool canDelete_in)
  409. {
  410. if(at>=isType.size())
  411. throw eMsg("cppType_template: The argument does not exist");
  412. if(args[at]!=NULL && args[at]!=arg && canDelete[at])
  413. delete args[at];
  414. isType[at]=true;
  415. args[at]=arg;
  416. canDelete[at]=canDelete_in;
  417. return *this;
  418. }
  419. cppType_template& setArgType(unsigned long at, int val)
  420. {
  421. if(at>=isType.size())
  422. throw eMsg("cppType_template: The argument does not exist");
  423. isType[at]=true;
  424. vals[at]=val;
  425. return *this;
  426. }
  427. virtual void printType(ostream& out)
  428. {
  429. this->cppType_basic::printType(out);
  430. out << '<';
  431. for(unsigned long i=0;i<isType.size();i++)
  432. {
  433. if(i>0)
  434. out << ',';
  435. out << ' ';
  436. if(isType[i] && args[i]!=NULL)
  437. args[i]->printType(out);
  438. else if(!isType[i])
  439. out << vals[i];
  440. else
  441. throw eMsg("cppType_template: the template type has not been set");
  442. out << ' ';
  443. }
  444. out << '>';
  445. }
  446. virtual void printDescription(ostream& out)
  447. {
  448. this->cppType_basic::printDescription(out);
  449. }
  450. virtual cppType* copyType()
  451. {
  452. return new cppType_template(*this);
  453. }
  454. };
  455. class fortranType
  456. {
  457. private:
  458. vector<vector<const char*> > fTypeName;
  459. cppType* cType;
  460. public:
  461. fortranType(unsigned long sz_in) : fTypeName(sz_in,vector<const char*>(0,NULL))
  462. {}
  463. fortranType& setSize(unsigned long sz_in)
  464. {
  465. fTypeName.resize(sz_in);
  466. return *this;
  467. }
  468. fortranType& setTypeSize(unsigned long typeAt, unsigned long wordCnt)
  469. {
  470. if(typeAt>=fTypeName.size())
  471. throw eMsg("fortranType: the requested type does not exist");
  472. fTypeName[typeAt].resize(wordCnt);
  473. return *this;
  474. }
  475. fortranType& setText(unsigned long typeAt,unsigned long at, const char* wrd)
  476. {
  477. if(typeAt>=fTypeName.size())
  478. throw eMsg("fortranType: the requested type does not exist");
  479. if(at>=fTypeName[typeAt].size())
  480. throw eMsg("fortranType: the word in the type does not exist");
  481. fTypeName[typeAt][at]=wrd;
  482. return *this;
  483. }
  484. fortranType& setType(cppType* cType_in)
  485. {
  486. if(cType_in==NULL)
  487. throw eMsg("fortranType: the type is NULL");
  488. cType=cType_in;
  489. return *this;
  490. }
  491. bool isType(wordList& line,unsigned long& end)
  492. {
  493. char word[LINE_SIZE];
  494. for(unsigned long i=0;i<fTypeName.size();i++)
  495. {
  496. bool fail=false;
  497. unsigned long j;
  498. for(j=0; j<fTypeName[i].size();j++)
  499. {
  500. line.getWord(j,word,LINE_SIZE);
  501. if(!strEqual(word,fTypeName[i][j]))
  502. fail=true;
  503. else
  504. end=line.getEnd(j);
  505. }
  506. if(!fail)
  507. {
  508. return true;
  509. }
  510. }
  511. return false;
  512. }
  513. bool isType(wordList& line)
  514. {
  515. unsigned long end;
  516. return this->isType(line,end);
  517. }
  518. cppType* getType()
  519. {
  520. return cType;
  521. }
  522. };
  523. template<class oType>
  524. class objList
  525. {
  526. private:
  527. list<oType*> typeObjs;
  528. bool own;
  529. vector<oType*> vct;
  530. bool vctGood;
  531. public:
  532. objList(bool own_in=true) : own(own_in) , vctGood(false)
  533. {}
  534. ~objList()
  535. {
  536. if(own)
  537. {
  538. for(typename list<oType*>::iterator it=typeObjs.begin();it!=typeObjs.end();it++)
  539. delete *it;
  540. }
  541. }
  542. unsigned long size()
  543. {
  544. return typeObjs.size();
  545. }
  546. objList& addObj(oType* newType)
  547. {
  548. if(newType==NULL)
  549. throw eMsg("objList: the new type is NULL");
  550. typeObjs.push_back(newType);
  551. vctGood=false;
  552. return *this;
  553. }
  554. oType* getObj(unsigned long at)
  555. {
  556. if(at>=typeObjs.size())
  557. throw eMsg("objList: The requested type does not exist");
  558. if(!vctGood)
  559. {
  560. vct.resize(typeObjs.size(),NULL);
  561. typename list<oType*>::iterator it=typeObjs.begin();
  562. for(unsigned long i=0;i<typeObjs.size();i++)
  563. {
  564. vct[i]=*it;
  565. it++;
  566. }
  567. vctGood=true;
  568. }
  569. return vct[at];
  570. }
  571. objList& deleteBack(unsigned long cnt=1)
  572. {
  573. if(cnt>typeObjs.size())
  574. cnt=typeObjs.size();
  575. for(unsigned long i=0;i<cnt;i++)
  576. {
  577. if(own)
  578. delete typeObjs.back();
  579. typeObjs.pop_back();
  580. }
  581. return *this;
  582. }
  583. };
  584. objList<fortranType> fTypes;
  585. objList<cppType_basic> bTypes;
  586. objList<cppType_template> tTypes;
  587. cppType* voidType;
  588. cppType* readType(wordList& line, unsigned long& end)
  589. {
  590. for(unsigned long i=0;i<fTypes.size();i++)
  591. {
  592. fortranType* fTp=fTypes.getObj(i);
  593. if(fTp->isType(line,end))
  594. {
  595. end++;
  596. return fTp->getType();
  597. }
  598. }
  599. return NULL;
  600. }
  601. cppType* readType(wordList& line)
  602. {
  603. unsigned long end;
  604. return readType(line,end);
  605. }
  606. class variable
  607. {
  608. private:
  609. char* name;
  610. cppType* type;
  611. bool deleteType;
  612. unsigned long pointerLevel;
  613. bool isReference;
  614. bool isConst;
  615. public:
  616. variable& setName(const char* name_in)
  617. {
  618. if(name!=NULL)
  619. delete[] name;
  620. if(name_in==NULL)
  621. {
  622. name=NULL;
  623. return *this;
  624. }
  625. unsigned long L=0;
  626. while(name_in[L]!=0)
  627. L++;
  628. L++;
  629. name=new char[L];
  630. if(name==NULL)
  631. throw eMsg("variable: Failed to allocate memory");
  632. for(unsigned long i=0;i<L;i++)
  633. name[i]=name_in[i];
  634. return *this;
  635. }
  636. variable& setType(cppType* type_in,bool deleteType_in=false)
  637. {
  638. if(type!=NULL && type!=type_in && deleteType)
  639. delete type;
  640. type=type_in;
  641. deleteType=deleteType_in;
  642. return *this;
  643. }
  644. variable& setPointerLevel(unsigned long lvl_in)
  645. {
  646. pointerLevel=lvl_in;
  647. return *this;
  648. }
  649. variable& setReference(bool isRef_in)
  650. {
  651. isReference=isRef_in;
  652. return *this;
  653. }
  654. variable& setConst(bool isConst_in)
  655. {
  656. isConst=isConst_in;
  657. return *this;
  658. }
  659. variable(cppType* type_in=NULL,const char* name_in=NULL,long pntrLevel=0,bool isReference_in=false,bool isConst_in=false,bool deleteType_in=false) : name(NULL) , type(type_in) , deleteType(false) , pointerLevel(pntrLevel) , isReference(isReference_in) , isConst(isConst_in)
  660. {
  661. setType(type_in,deleteType_in);
  662. setName(name_in);
  663. }
  664. variable(const variable& asg) : name(NULL) , type(NULL) , deleteType(false) , pointerLevel(0) , isReference(false) , isConst(false)
  665. {
  666. *this=asg;
  667. }
  668. ~variable()
  669. {
  670. if(name!=NULL)
  671. delete[] name;
  672. if(deleteType && type!=NULL)
  673. delete type;
  674. }
  675. variable& operator=(const variable& asg)
  676. {
  677. if(name!=NULL)
  678. delete[] name;
  679. if(asg.name==NULL)
  680. this->name=NULL;
  681. else
  682. {
  683. this->name=copyLine(asg.name);
  684. if(this->name==NULL)
  685. throw eMsg("variable::operator=(): Failed to allocate memory");
  686. }
  687. if(this->deleteType && this->type!=NULL)
  688. delete this->type;
  689. if(asg.deleteType)
  690. {
  691. if(asg.type==NULL)
  692. {
  693. this->type=NULL;
  694. this->deleteType=false;
  695. }
  696. else
  697. {
  698. this->type=asg.type->copyType();
  699. if(this->type==NULL)
  700. throw eMsg("variable::operator=(): Failed to allocate memory");
  701. this->deleteType=asg.deleteType;
  702. }
  703. }
  704. else
  705. {
  706. this->deleteType=false;
  707. this->type=asg.type;
  708. }
  709. this->pointerLevel=asg.pointerLevel;
  710. this->isReference=asg.isReference;
  711. this->isConst=asg.isConst;
  712. return *this;
  713. }
  714. variable& printName(ostream& out)
  715. {
  716. if(name==NULL)
  717. throw eMsg("variable: Name has not been set");
  718. out << name;
  719. return *this;
  720. }
  721. variable& printDecl(ostream& out)
  722. {
  723. if(type==NULL)
  724. throw eMsg("variable: type has not been set");
  725. if(isConst)
  726. out << "const ";
  727. type->printType(out);
  728. for(unsigned long i=0;i<pointerLevel;i++)
  729. out << '*';
  730. if(isReference)
  731. out << '&';
  732. out << ' ';
  733. this->printName(out);
  734. return *this;
  735. }
  736. cppType* getType()
  737. {
  738. return type;
  739. }
  740. const char* getName()
  741. {
  742. return name;
  743. }
  744. };
  745. struct comment
  746. {
  747. char* line;
  748. bool tagged;
  749. comment() : line(NULL)
  750. {}
  751. ~comment()
  752. {
  753. if(line!=NULL)
  754. delete[] line;
  755. }
  756. comment(const comment& asg)
  757. {
  758. if(asg.line!=NULL)
  759. {
  760. unsigned long i=0;
  761. while(asg.line[i]!=0)
  762. i++;
  763. this->line=new char[i+1];
  764. if(this->line==NULL)
  765. throw eMsg("comment: Failed to allocate memory");
  766. i=0;
  767. while(asg.line[i]!=0)
  768. {
  769. this->line[i]=asg.line[i];
  770. i++;
  771. }
  772. this->line[i]=0;
  773. }
  774. else
  775. {
  776. this->line=NULL;
  777. }
  778. this->tagged=asg.tagged;
  779. }
  780. comment& operator=(const comment& asg)
  781. {
  782. if(this->line!=NULL)
  783. delete[] this->line;
  784. if(asg.line!=NULL)
  785. {
  786. unsigned long i=0;
  787. while(asg.line[i]!=0)
  788. i++;
  789. this->line=new char[i+1];
  790. if(this->line==NULL)
  791. throw eMsg("comment: Failed to allocate memory");
  792. i=0;
  793. while(asg.line[i]!=0)
  794. {
  795. this->line[i]=asg.line[i];
  796. i++;
  797. }
  798. }
  799. else
  800. {
  801. this->line=NULL;
  802. }
  803. this->tagged=asg.tagged;
  804. }
  805. };
  806. class nameSource
  807. {
  808. protected:
  809. vector<bool> sourceIsSunk;
  810. void setSourceSize(unsigned long sz_in)
  811. {
  812. sourceIsSunk.resize(sz_in,false);
  813. }
  814. public:
  815. nameSource() : sourceIsSunk(0,false)
  816. {}
  817. virtual ~nameSource()
  818. {}
  819. virtual unsigned long sourceSize()
  820. {
  821. return sourceIsSunk.size();
  822. }
  823. virtual const char* getSourceName(unsigned long at)=0;
  824. virtual const char* getSourceDescription()=0;
  825. virtual const char* getSourceTermDescription(unsigned long at)=0;
  826. virtual bool isSunk(unsigned long at)
  827. {
  828. if(at>=sourceIsSunk.size())
  829. throw eMsg("nameSource::isSunk(): The source does not exist");
  830. return sourceIsSunk[at];
  831. }
  832. virtual void setSunk(unsigned long at,bool isSunk=true)
  833. {
  834. if(at>=sourceIsSunk.size())
  835. throw eMsg("nameSource::setSunk(): The source does not exist");
  836. sourceIsSunk[at]=isSunk;
  837. }
  838. };
  839. class nameSink
  840. {
  841. protected:
  842. vector<nameSource*> sources;
  843. vector<unsigned long> atSources;
  844. void setSinkSize(unsigned long sz)
  845. {
  846. sources.resize(sz);
  847. atSources.resize(sz);
  848. }
  849. public:
  850. nameSink()
  851. {}
  852. virtual ~nameSink()
  853. {}
  854. unsigned long sinkSize()
  855. {
  856. return sources.size();
  857. }
  858. void setSource(unsigned long atSnk,nameSource* src,unsigned long atSrc)
  859. {
  860. if(atSnk>=sources.size())
  861. throw eMsg("nameSink: The sink does not exist");
  862. sources[atSnk]=src;
  863. atSources[atSnk]=atSrc;
  864. }
  865. bool sinkSet(unsigned long at)
  866. {
  867. if(at>=sources.size())
  868. throw eMsg("nameSink: The sink does not exist");
  869. if(sources[at]!=NULL)
  870. return true;
  871. return false;
  872. }
  873. virtual const char* getSinkDescription()=0;
  874. virtual const char* getSinkTermDescription(unsigned long at)=0;
  875. };
  876. class declaration
  877. {
  878. public:
  879. virtual void printDecl(ostream& out)=0;
  880. };
  881. class code
  882. {
  883. public:
  884. code()
  885. {}
  886. virtual ~code()
  887. {}
  888. virtual void writeCode(ostream& out)=0;
  889. };
  890. class function
  891. {
  892. public:
  893. virtual const char* getFunctionName()=0;
  894. virtual unsigned long getFunctionArgumentCount()=0;
  895. // virtual const char* getArgName(unsigned long at)=0;
  896. virtual const char* getArgumentDescription(unsigned long at)=0;
  897. };
  898. class nameMap : virtual public nameSource , virtual public nameSink
  899. {
  900. public:
  901. nameMap()
  902. {}
  903. virtual ~nameMap()
  904. {}
  905. };
  906. class mappingCode : public nameMap , public code
  907. {
  908. public:
  909. mappingCode()
  910. {}
  911. virtual ~mappingCode()
  912. {}
  913. };
  914. enum txtTYPE
  915. {
  916. ttINPUT,
  917. ttOUTPUT,
  918. ttTYPE,
  919. ttCUSTOM
  920. };
  921. class mapText
  922. {
  923. private:
  924. char* txt;
  925. unsigned long inCnt;
  926. unsigned long outCnt;
  927. unsigned long typeCnt;
  928. unsigned long custCnt;
  929. char* desc;
  930. char** inDesc;
  931. char** outDesc;
  932. char** tpDesc;
  933. char** cstDesc;
  934. void clearText()
  935. {
  936. if(txt!=NULL)
  937. delete[] txt;
  938. txt=NULL;
  939. if(desc!=NULL)
  940. delete[] desc;
  941. desc=NULL;
  942. if(inDesc!=NULL)
  943. {
  944. for(unsigned long i=0;i<inCnt;i++)
  945. {
  946. if(inDesc[i])
  947. delete[] inDesc[i];
  948. }
  949. delete[] inDesc;
  950. inDesc=NULL;
  951. }
  952. inCnt=0;
  953. if(outDesc!=NULL)
  954. {
  955. for(unsigned long i=0;i<outCnt;i++)
  956. {
  957. if(outDesc[i])
  958. delete[] outDesc[i];
  959. }
  960. delete[] outDesc;
  961. outDesc=NULL;
  962. }
  963. outCnt=0;
  964. if(tpDesc!=NULL)
  965. {
  966. for(unsigned long i=0;i<typeCnt;i++)
  967. {
  968. if(tpDesc[i])
  969. delete[] tpDesc[i];
  970. }
  971. delete[] tpDesc;
  972. tpDesc=NULL;
  973. }
  974. typeCnt=0;
  975. if(cstDesc!=NULL)
  976. {
  977. for(unsigned long i=0;i<custCnt;i++)
  978. {
  979. if(cstDesc[i])
  980. delete[] cstDesc[i];
  981. }
  982. delete[] cstDesc;
  983. cstDesc=NULL;
  984. }
  985. custCnt=0;
  986. }
  987. public:
  988. bool setText(const char* text)
  989. {
  990. clearText();
  991. if(text==NULL)
  992. {
  993. txt=NULL;
  994. return false;
  995. }
  996. else
  997. {
  998. txt=copyLine(text);
  999. if(txt==NULL)
  1000. throw eMsg("mapText: Failed to allocate text");
  1001. }
  1002. unsigned long at=0;
  1003. inCnt=0;
  1004. outCnt=0;
  1005. typeCnt=0;
  1006. custCnt=0;
  1007. while(txt[at]!=0)
  1008. {
  1009. if(txt[at]=='@')
  1010. {
  1011. char number[24];
  1012. at++;
  1013. if(txt[at]!='(')
  1014. return false;
  1015. at++;
  1016. txtTYPE tt=ttINPUT;
  1017. if(txt[at]=='o')
  1018. tt=ttOUTPUT;
  1019. else if(txt[at]=='i')
  1020. tt=ttINPUT;
  1021. else if(txt[at]=='t')
  1022. tt=ttTYPE;
  1023. else if(txt[at]=='c')
  1024. tt=ttCUSTOM;
  1025. else
  1026. return false;
  1027. at++;
  1028. unsigned long i=0;
  1029. while(txt[at]!=')' && txt[at]!=0)
  1030. {
  1031. if(!isdigit(txt[at]))
  1032. return false;
  1033. number[i++]=txt[at++];
  1034. }
  1035. number[i]=0;
  1036. if(txt[at]==0)
  1037. return false;
  1038. if(txt[at]!=')')
  1039. return false;
  1040. unsigned long atTerm=atoi(number);
  1041. switch(tt)
  1042. {
  1043. case ttOUTPUT:
  1044. if(outCnt<(atTerm+1))
  1045. outCnt=atTerm+1;
  1046. break;
  1047. case ttINPUT:
  1048. if(inCnt<(atTerm+1))
  1049. inCnt=atTerm+1;
  1050. break;
  1051. case ttTYPE:
  1052. if(typeCnt<(atTerm+1))
  1053. typeCnt=atTerm+1;
  1054. break;
  1055. case ttCUSTOM:
  1056. if(custCnt<(atTerm+1))
  1057. custCnt=atTerm+1;
  1058. break;
  1059. default:
  1060. throw eMsg("mapText: An unexpected error occured");
  1061. }
  1062. }
  1063. at++;
  1064. }
  1065. if(inCnt>0)
  1066. {
  1067. inDesc=new char*[inCnt];
  1068. if(inDesc==NULL)
  1069. throw eMsg("mapText::setText(): Failed to allocate memory");
  1070. for(unsigned long i=0;i<inCnt;i++)
  1071. inDesc[i]=NULL;
  1072. }
  1073. if(outCnt>0)
  1074. {
  1075. outDesc=new char*[outCnt];
  1076. if(outDesc==NULL)
  1077. throw eMsg("mapText::setText(): Failed to allocate memory");
  1078. for(unsigned long i=0;i<outCnt;i++)
  1079. outDesc[i]=NULL;
  1080. }
  1081. if(typeCnt>0)
  1082. {
  1083. tpDesc=new char*[typeCnt];
  1084. if(tpDesc==NULL)
  1085. throw eMsg("mapText::setText(): Failed to allocate memory");
  1086. for(unsigned long i=0;i<typeCnt;i++)
  1087. tpDesc[i]=NULL;
  1088. }
  1089. if(custCnt>0)
  1090. {
  1091. cstDesc=new char*[custCnt];
  1092. if(cstDesc==NULL)
  1093. throw eMsg("mapText::setText(): Failed to allocate memory");
  1094. for(unsigned long i=0;i<custCnt;i++)
  1095. cstDesc[i]=NULL;
  1096. }
  1097. return true;
  1098. };
  1099. mapText(const char* txt_in=NULL) : txt(NULL) , inCnt(0) , outCnt(0) , typeCnt(0) , custCnt(0) , desc(NULL) , inDesc(NULL) , outDesc(NULL) , tpDesc(NULL) , cstDesc(NULL)
  1100. {
  1101. if(txt_in!=NULL)
  1102. {
  1103. if(!setText(txt_in))
  1104. throw eMsg("mapText::mapText(): Cannot create mapText with malformed text");
  1105. }
  1106. }
  1107. ~mapText()
  1108. {
  1109. clearText();
  1110. }
  1111. mapText& setDescription(const char* dsc_in)
  1112. {
  1113. if(desc!=NULL)
  1114. delete[] desc;
  1115. if(dsc_in==NULL)
  1116. desc=NULL;
  1117. else
  1118. {
  1119. desc=copyLine(dsc_in);
  1120. if(desc==NULL)
  1121. throw eMsg("mapText::setDescription(): Failed to allocate memory");
  1122. }
  1123. return *this;
  1124. }
  1125. mapText& setInputDescription(unsigned long at, const char* dsc_in)
  1126. {
  1127. if(at>=inCnt)
  1128. throw eMsg("mapText::setInputDescription(): The input description does not exist");
  1129. if(inDesc==NULL)
  1130. throw eMsg("mapText::setInputDescription(): The container for the input description has not been set");
  1131. if(inDesc[at]!=NULL)
  1132. delete[] inDesc[at];
  1133. if(dsc_in==NULL)
  1134. inDesc[at]=NULL;
  1135. else
  1136. {
  1137. inDesc[at]=copyLine(dsc_in);
  1138. if(inDesc[at]==NULL)
  1139. throw eMsg("mapText::setInputDescription(): Failed to allocate memory");
  1140. }
  1141. return *this;
  1142. }
  1143. mapText& setOutputDescription(unsigned long at, const char* dsc_in)
  1144. {
  1145. if(at>=outCnt)
  1146. throw eMsg("mapText::setOutputDescription(): The input description does not exist");
  1147. if(outDesc==NULL)
  1148. throw eMsg("mapText::setOutputDescription(): The container for the input description has not been set");
  1149. if(outDesc[at]!=NULL)
  1150. delete[] outDesc[at];
  1151. if(dsc_in==NULL)
  1152. outDesc[at]=NULL;
  1153. else
  1154. {
  1155. outDesc[at]=copyLine(dsc_in);
  1156. if(outDesc[at]==NULL)
  1157. throw eMsg("mapText::setOutputDescription(): Failed to allocate memory");
  1158. }
  1159. return *this;
  1160. }
  1161. mapText& setTypeDescription(unsigned long at, const char* dsc_in)
  1162. {
  1163. if(at>=typeCnt)
  1164. throw eMsg("mapText::setTypeDescription(): The input description does not exist");
  1165. if(tpDesc==NULL)
  1166. throw eMsg("mapText::setTypeDescription(): The container for the input description has not been set");
  1167. if(tpDesc[at]!=NULL)
  1168. delete[] tpDesc[at];
  1169. if(dsc_in==NULL)
  1170. tpDesc[at]=NULL;
  1171. else
  1172. {
  1173. tpDesc[at]=copyLine(dsc_in);
  1174. if(tpDesc[at]==NULL)
  1175. throw eMsg("mapText::setTypeDescription(): Failed to allocate memory");
  1176. }
  1177. return *this;
  1178. }
  1179. mapText& setCustomDescription(unsigned long at, const char* dsc_in)
  1180. {
  1181. if(at>=custCnt)
  1182. throw eMsg("mapText::setCustomDescription(): The input description does not exist");
  1183. if(cstDesc==NULL)
  1184. throw eMsg("mapText::setCustomDescription(): The container for the input description has not been set");
  1185. if(cstDesc[at]!=NULL)
  1186. delete[] cstDesc[at];
  1187. if(dsc_in==NULL)
  1188. cstDesc[at]=NULL;
  1189. else
  1190. {
  1191. cstDesc[at]=copyLine(dsc_in);
  1192. if(cstDesc[at]==NULL)
  1193. throw eMsg("mapText::setCustomDescription(): Failed to allocate memory");
  1194. }
  1195. return *this;
  1196. }
  1197. const char* getTxt() const
  1198. {
  1199. return txt;
  1200. }
  1201. unsigned long getInCnt() const
  1202. {
  1203. return inCnt;
  1204. }
  1205. unsigned long getOutCnt() const
  1206. {
  1207. return outCnt;
  1208. }
  1209. unsigned long getTypeCnt() const
  1210. {
  1211. return typeCnt;
  1212. }
  1213. unsigned long getCustCnt() const
  1214. {
  1215. return custCnt;
  1216. }
  1217. const char* getDescription() const
  1218. {
  1219. return desc;
  1220. }
  1221. const char* getInputDescription(unsigned long at) const
  1222. {
  1223. if(at>=inCnt)
  1224. throw eMsg("mapText::getInputDescription(): The requested description does not exist");
  1225. return inDesc[at];
  1226. }
  1227. const char* getOutputDescription(unsigned long at) const
  1228. {
  1229. if(at>=outCnt)
  1230. throw eMsg("mapText::getOutputDescription(): The description does not exist");
  1231. return outDesc[at];
  1232. }
  1233. const char* getTypeDescription(unsigned long at) const
  1234. {
  1235. if(at>=typeCnt)
  1236. throw eMsg("mapText::getTypeDescription(): The description does not exist");
  1237. return tpDesc[at];
  1238. }
  1239. const char* getCustomDescription(unsigned long at) const
  1240. {
  1241. if(at>=custCnt)
  1242. throw eMsg("mapText::getCustomDescription(): The description does not exist");
  1243. return cstDesc[at];
  1244. }
  1245. };
  1246. objList<mapText> textMaps;
  1247. class nameMap_text : public mappingCode
  1248. {
  1249. private:
  1250. const mapText* mpTxt;
  1251. const char* txt;
  1252. unsigned long outCnt;
  1253. unsigned long typeCnt;
  1254. unsigned long custCnt;
  1255. vector<cppType*> types;
  1256. vector<bool> canDelete;
  1257. vector<char*> outNames;
  1258. vector<char*> custNames;
  1259. public:
  1260. nameMap_text& setText(const mapText& mpTxt_in)
  1261. {
  1262. mpTxt=&mpTxt_in;
  1263. this->txt=mpTxt->getTxt();
  1264. this->outCnt=mpTxt->getOutCnt();
  1265. this->typeCnt=mpTxt->getTypeCnt();
  1266. this->custCnt=mpTxt->getCustCnt();
  1267. types.resize(typeCnt,NULL);
  1268. canDelete.resize(typeCnt,false);
  1269. outNames.resize(outCnt,NULL);
  1270. custNames.resize(custCnt,NULL);
  1271. this->setSinkSize(mpTxt->getInCnt());
  1272. this->setSourceSize(outCnt);
  1273. return *this;
  1274. }
  1275. nameMap_text() : mpTxt(NULL) , txt(NULL) , outCnt(0) , typeCnt(0) , custCnt(0) , types(0,NULL) , canDelete(0,false) , outNames(0,NULL) , custNames(0,NULL)
  1276. {}
  1277. nameMap_text(const mapText& mpTxt_in) : mpTxt(NULL) , txt(NULL) , outCnt(0) , typeCnt(0) , custCnt(0) , types(0,NULL) , canDelete(0,false) , outNames(0,NULL) , custNames(0,NULL)
  1278. {
  1279. this->setText(mpTxt_in);
  1280. }
  1281. ~nameMap_text()
  1282. {
  1283. for(unsigned long i=0;i<types.size();i++)
  1284. {
  1285. if(types[i]!=NULL && canDelete[i])
  1286. delete types[i];
  1287. }
  1288. for(unsigned long i=0;i<outNames.size();i++)
  1289. {
  1290. if(outNames[i]!=NULL)
  1291. delete[] outNames[i];
  1292. }
  1293. for(unsigned long i=0;i<custNames.size();i++)
  1294. {
  1295. if(custNames[i]!=NULL)
  1296. delete[] custNames[i];
  1297. }
  1298. }
  1299. nameMap_text& setOutName(unsigned long at,const char* name)
  1300. {
  1301. if(at>=outNames.size())
  1302. throw eMsg("nameMap_text: The nameMap does not have those outputs");
  1303. if(outNames[at]!=NULL)
  1304. delete[] outNames[at];
  1305. outNames[at]=NULL;
  1306. if(name==NULL)
  1307. return *this;
  1308. outNames[at]=copyLine(name);
  1309. if(outNames[at]==NULL)
  1310. throw eMsg("nameMap_text: failed to allocate memory");
  1311. return *this;
  1312. }
  1313. const char* getOutName(unsigned long at)
  1314. {
  1315. if(at>=outNames.size())
  1316. throw eMsg("nameMap_text: The output does not exist");
  1317. return outNames[at];
  1318. }
  1319. unsigned long outNameCount()
  1320. {
  1321. return outNames.size();
  1322. }
  1323. nameMap_text& setCustName(unsigned long at,const char* name)
  1324. {
  1325. if(at>=custNames.size())
  1326. throw eMsg("nameMap_text: The nameMap does not have those customs");
  1327. if(custNames[at]!=NULL)
  1328. delete[] custNames[at];
  1329. custNames[at]=NULL;
  1330. if(name==NULL)
  1331. return *this;
  1332. custNames[at]=copyLine(name);
  1333. if(custNames[at]==NULL)
  1334. throw eMsg("nameMap_text: failed to allocate memory");
  1335. return *this;
  1336. }
  1337. const char* getCustName(unsigned long at)
  1338. {
  1339. if(at>=custNames.size())
  1340. throw eMsg("nameMap_text: The custom does not exist");
  1341. return custNames[at];
  1342. }
  1343. unsigned long custNameCount()
  1344. {
  1345. return custNames.size();
  1346. }
  1347. nameMap_text& setCppType(unsigned long at, cppType* type_in,bool canDelete_in=false)
  1348. {
  1349. if(at>=types.size())
  1350. throw eMsg("nameMap_text: The type does not exist");
  1351. if(types[at]!=NULL && types[at]!=type_in && canDelete[at])
  1352. delete types[at];
  1353. types[at]=type_in;
  1354. canDelete[at]=canDelete_in;
  1355. return *this;
  1356. }
  1357. cppType* getCppType(unsigned long at)
  1358. {
  1359. if(at>=types.size())
  1360. throw eMsg("nameMap_text: The type does not exist");
  1361. return types[at];
  1362. }
  1363. unsigned long getTypeCount()
  1364. {
  1365. return types.size();
  1366. }
  1367. void writeCode(ostream& out)
  1368. {
  1369. if(txt==NULL)
  1370. return;
  1371. unsigned long at=0;
  1372. while(txt[at]!=0)
  1373. {
  1374. if(txt[at]=='@')
  1375. {
  1376. char number[24];
  1377. at++;
  1378. if(txt[at]!='(')
  1379. throw eMsg("nameMap_text: malformed text");
  1380. at++;
  1381. txtTYPE tt=ttINPUT;
  1382. if(txt[at]=='o')
  1383. tt=ttOUTPUT;
  1384. else if(txt[at]=='i')
  1385. tt=ttINPUT;
  1386. else if(txt[at]=='t')
  1387. tt=ttTYPE;
  1388. else if(txt[at]=='c')
  1389. tt=ttCUSTOM;
  1390. else
  1391. throw eMsg("nameMap_text: The text is malformed");
  1392. at++;
  1393. unsigned long i=0;
  1394. while(txt[at]!=')' && txt[at]!=0)
  1395. {
  1396. if(!isdigit(txt[at]))
  1397. throw eMsg("nameMap_text: malformed text");
  1398. number[i++]=txt[at++];
  1399. }
  1400. if(txt[at]==0)
  1401. throw eMsg("nameMap_text: malformed text");
  1402. if(txt[at]!=')')
  1403. throw eMsg("nameMap_text: malformed text");
  1404. number[i]=0;
  1405. unsigned long atTerm=atoi(number);
  1406. switch(tt)
  1407. {
  1408. case ttOUTPUT:
  1409. if(atTerm>=outCnt)
  1410. throw eMsg("nameMap_text: specified an output that does not exist");
  1411. if(outNames[atTerm]==NULL)
  1412. throw eMsg("nameMap_text: not all the outputs have been specified");
  1413. out << outNames[atTerm];
  1414. break;
  1415. case ttINPUT:
  1416. if(atTerm>=this->sinkSize())
  1417. throw eMsg("nameMap_text: specified and input that does not exist");
  1418. if(this->sources[atTerm]==NULL)
  1419. throw eMsg("nameMap_text: the input data has not been specified");
  1420. out << this->sources[atTerm]->getSourceName(this->atSources[atTerm]);
  1421. break;
  1422. case ttTYPE:
  1423. if(atTerm>=typeCnt)
  1424. throw eMsg("nameMap_text: The requested type does not exist");
  1425. if(types[atTerm]==NULL)
  1426. throw eMsg("nameMap_text: The requested type has not been specified");
  1427. types[atTerm]->printType(out);
  1428. break;
  1429. case ttCUSTOM:
  1430. if(atTerm>=custCnt)
  1431. throw eMsg("nameMap_text: The requested custom does not exist");
  1432. if(custNames[atTerm]==NULL)
  1433. throw eMsg("nameMap_text: The requested custom has not been specified");
  1434. out << custNames[atTerm];
  1435. break;
  1436. default:
  1437. throw eMsg("nameMap_text: There was an error trying to fill in a custom item");
  1438. }
  1439. }
  1440. else
  1441. {
  1442. out << txt[at];
  1443. }
  1444. at++;
  1445. }
  1446. out << endl;
  1447. }
  1448. const char* getSinkDescription()
  1449. {
  1450. if(mpTxt==NULL)
  1451. throw eMsg("nameMap_text::getSinkDescription(): The text does not exist");
  1452. return mpTxt->getDescription();
  1453. }
  1454. const char* getSinkTermDescription(unsigned long at)
  1455. {
  1456. if(mpTxt==NULL)
  1457. throw eMsg("nameMap_text::getSinkTermDescription(): The text does not exist");
  1458. return mpTxt->getInputDescription(at);
  1459. }
  1460. const char* getSourceName(unsigned long at)
  1461. {
  1462. if(at>=outCnt)
  1463. throw eMsg("nameMap_text::getSourceName(): The source name does not exist");
  1464. return outNames[at];
  1465. }
  1466. const char* getSourceDescription()
  1467. {
  1468. if(mpTxt==NULL)
  1469. throw eMsg("nameMap_text::getSourceDescription(): The text has not been set");
  1470. return mpTxt->getDescription();
  1471. }
  1472. const char* getSourceTermDescription(unsigned long at)
  1473. {
  1474. if(mpTxt==NULL)
  1475. throw eMsg("nameMap_text::getSourceTermDescription(): The text source has not been set");
  1476. return mpTxt->getOutputDescription(at);
  1477. }
  1478. };
  1479. class returnSink : public mappingCode
  1480. {
  1481. public:
  1482. returnSink()
  1483. {
  1484. this->setSourceSize(0);
  1485. this->setSinkSize(1);
  1486. }
  1487. const char* getSinkDescription()
  1488. {
  1489. return "Returns a varible";
  1490. }
  1491. const char* getSinkTermDescription(unsigned long at)
  1492. {
  1493. return "The variable to be sunk";
  1494. }
  1495. const char* getSourceName(unsigned long at)
  1496. {
  1497. throw eMsg("returnSink::getSourceName(): This object is not meant to return any source information");
  1498. }
  1499. const char* getSourceDescription()
  1500. {
  1501. return "This is an empty source that merely returns a variable";
  1502. }
  1503. const char* getSourceTermDescription(unsigned long at)
  1504. {
  1505. throw eMsg("returnSink::getSourceTermDescription(): This object has not sources");
  1506. }
  1507. void writeCode(ostream& out)
  1508. {
  1509. out << "\treturn " << this->sources[0]->getSourceName(this->atSources[0]) << ';' << endl;
  1510. }
  1511. };
  1512. class returnValue : public mappingCode
  1513. {
  1514. private:
  1515. char* value;
  1516. public:
  1517. returnValue(const char* val=NULL) : value(NULL)
  1518. {
  1519. this->setSourceSize(0);
  1520. this->setSinkSize(0);
  1521. if(val!=NULL)
  1522. {
  1523. value=copyLine(val);
  1524. if(value==NULL)
  1525. throw eMsg("returnValue::returnValue(): Failed to allocate memory");
  1526. }
  1527. }
  1528. ~returnValue()
  1529. {
  1530. if(value!=NULL)
  1531. delete[] value;
  1532. }
  1533. returnValue& setValue(const char* val)
  1534. {
  1535. if(value!=NULL)
  1536. delete[] value;
  1537. if(val==NULL)
  1538. {
  1539. value=NULL;
  1540. return *this;
  1541. }
  1542. value=copyLine(val);
  1543. if(value==NULL)
  1544. throw eMsg("returnValue::setValue(): Failed to allocate memory");
  1545. return *this;
  1546. }
  1547. const char* getSinkDescription()
  1548. {
  1549. return "This is an empty sink that returns a value";
  1550. }
  1551. const char* getSinkTermDescription(unsigned long at)
  1552. {
  1553. throw eMsg("returnValue::getSinkTermDescription(): This is an empty sink");
  1554. }
  1555. const char* getSourceName(unsigned long at)
  1556. {
  1557. throw eMsg("returnValue::getSourceName(): This is an empty source");
  1558. }
  1559. const char* getSourceDescription()
  1560. {
  1561. return "This is an empty source that return a value";
  1562. }
  1563. const char* getSourceTermDescription(unsigned long at)
  1564. {
  1565. throw eMsg("returnValue::getSourceTermDescription(): This is an empty source");
  1566. }
  1567. void writeCode(ostream& out)
  1568. {
  1569. if(value==NULL)
  1570. throw eMsg("returnValue::writeCode(): The value has not been set");
  1571. out << "\treturn " << value << ';' << endl;
  1572. }
  1573. };
  1574. class callingCode : public mappingCode
  1575. {
  1576. protected:
  1577. function* func;
  1578. bool canDelete;
  1579. unsigned long inExtra;
  1580. void printCall(ostream& out)
  1581. {
  1582. if(func==NULL)
  1583. throw eMsg("callingCode::printCall(): The calling code does not have a function to call");
  1584. out << func->getFunctionName() << "( ";
  1585. bool isFirst=true;
  1586. for(unsigned long i=0;i<func->getFunctionArgumentCount();i++)
  1587. {
  1588. if(!isFirst)
  1589. out << " , ";
  1590. out << this->sources[i]->getSourceName(this->atSources[i]);
  1591. isFirst=false;
  1592. }
  1593. out << " )";
  1594. }
  1595. callingCode(unsigned long outCnt,function* func_in=NULL,bool canDelete_in=false, unsigned long inExtra_in=0) : func(func_in) , canDelete(canDelete_in) , inExtra(inExtra_in)
  1596. {
  1597. if(func_in!=NULL)
  1598. this->setSinkSize(func_in->getFunctionArgumentCount());
  1599. this->setSourceSize(outCnt);
  1600. }
  1601. public:
  1602. callingCode(function* func_in=NULL,bool canDelete_in=false) : func(func_in) , canDelete(canDelete_in) , inExtra(0)
  1603. {
  1604. if(func_in!=NULL)
  1605. this->setSinkSize(func_in->getFunctionArgumentCount());
  1606. this->setSourceSize(0);
  1607. }
  1608. virtual ~callingCode()
  1609. {
  1610. if(func!=NULL && canDelete)
  1611. delete func;
  1612. }
  1613. virtual void setFunction(function* func_in,bool canDelete_in=false)
  1614. {
  1615. if(func!=NULL && func!=func_in && canDelete)
  1616. delete func;
  1617. func=func_in;
  1618. canDelete=canDelete_in;
  1619. if(func!=NULL)
  1620. this->setSinkSize(func->getFunctionArgumentCount()+inExtra);
  1621. }
  1622. virtual void writeCode(ostream& out)
  1623. {
  1624. out << '\t';
  1625. this->printCall(out);
  1626. out << ';' << endl;
  1627. }
  1628. virtual const char* getSourceName(unsigned long at)
  1629. {
  1630. throw eMsg("callingCode::getSourceName(): This code provides no sources");
  1631. }
  1632. virtual const char* getSourceDescription()
  1633. {
  1634. return "This calls a function, no new variables are created";
  1635. }
  1636. virtual const char* getSourceTermDescription(unsigned long at)
  1637. {
  1638. throw eMsg("callingCode::getSourceDescription(): This code provides no sources");
  1639. }
  1640. virtual const char* getSinkDescription()
  1641. {
  1642. return "This calls a function where each argument is an input to this code segment";
  1643. }
  1644. virtual const char* getSinkTermDescription(unsigned long at)
  1645. {
  1646. if(func==NULL)
  1647. throw eMsg("callingCode::getSinkTermDescription(): The function has not been set");
  1648. if(at>=this->sinkSize())
  1649. throw eMsg("callingCode::getSinkTermDescription(): The sink does not exist");
  1650. return func->getArgumentDescription(at);
  1651. }
  1652. };
  1653. class callingCode_return : public callingCode
  1654. {
  1655. public:
  1656. callingCode_return(function* func_in=NULL,bool canDelete_in=false) : callingCode(func_in,canDelete_in)
  1657. {}
  1658. void writeCode(ostream& out)
  1659. {
  1660. out << "\treturn ";
  1661. this->printCall(out);
  1662. out << ';' << endl;
  1663. }
  1664. const char* getSinkDescription()
  1665. {
  1666. return "return a function call where each argument is an input to this code segment";
  1667. }
  1668. const char* getSourceDescription()
  1669. {
  1670. return "This calls a function, no new variables are created because it returns";
  1671. }
  1672. };
  1673. class callingCode_assignNew : public callingCode
  1674. {
  1675. private:
  1676. cppType* retType;
  1677. char* retVar;
  1678. bool deleteRet;
  1679. public:
  1680. callingCode_assignNew(function* func_in=NULL,bool canDelete_in=false, cppType* retType_in=NULL, const char* retVar_in=NULL, bool deleteRet_in=false) : callingCode(1,func_in,canDelete_in) , retType(retType_in) , retVar(NULL) , deleteRet(deleteRet_in)
  1681. {
  1682. if(retVar_in!=NULL)
  1683. {
  1684. retVar=copyLine(retVar_in);
  1685. if(retVar==NULL)
  1686. throw eMsg("callingCode_assignNew::callingCode_assignNew(): Failed to allocate memory");
  1687. }
  1688. }
  1689. ~callingCode_assignNew()
  1690. {
  1691. if(retType!=NULL && deleteRet)
  1692. delete retType;
  1693. if(retVar!=NULL)
  1694. delete[] retVar;
  1695. }
  1696. callingCode_assignNew& setVariable(cppType* retType_in,const char* retVar_in,bool deleteRet=false)
  1697. {
  1698. if(retType!=NULL && deleteRet)
  1699. delete retType;
  1700. if(retVar!=NULL)
  1701. delete[] retVar;
  1702. retType=retType_in;
  1703. if(retVar_in==NULL)
  1704. {
  1705. retVar=NULL;
  1706. }
  1707. else
  1708. {
  1709. retVar=copyLine(retVar_in);
  1710. if(retVar==NULL)
  1711. throw eMsg("callingCode_assignNew::setVariable(): Failed to allocate memory");
  1712. }
  1713. return *this;
  1714. }
  1715. void writeCode(ostream& out)
  1716. {
  1717. if(retType==NULL || retVar==NULL)
  1718. throw eMsg("callingCode_assignNew::writeCode(): Not all the inputs have been specified");
  1719. out << '\t';
  1720. retType->printType(out);
  1721. out << ' ' << retVar << '=';
  1722. this->printCall(out);
  1723. out << ';' << endl;
  1724. }
  1725. const char* getSinkDescription()
  1726. {
  1727. return "return a function call where each argument is an input to this code segment";
  1728. }
  1729. const char* getSourceName(unsigned long at)
  1730. {
  1731. if(at!=0)
  1732. throw eMsg("callingCode_assignNew::getSourceName(): The output does not exist");
  1733. if(retVar==NULL)
  1734. throw eMsg("callingCode_assignNew::getSourceName(): The output has not been specified");
  1735. return retVar;
  1736. }
  1737. const char* getSourceDescription()
  1738. {
  1739. return "The calls a function, the return value is assigned to this code segments output variable";
  1740. }
  1741. const char* getSourceTermDescription(unsigned long at)
  1742. {
  1743. if(at!=0)
  1744. throw eMsg("callingCode_assignNew::getSourceTermDescription(): The output does not exist");
  1745. return "The variable return value is assigned to";
  1746. }
  1747. };
  1748. class callingCode_assignOld : public callingCode
  1749. {
  1750. public:
  1751. callingCode_assignOld(function* func_in=NULL,bool canDelete_in=false) : callingCode(0,func_in,canDelete_in,1)
  1752. {}
  1753. void writeCode(ostream& out)
  1754. {
  1755. unsigned long atSink=this->sinkSize()-1;
  1756. out << '\t' << this->sources[atSink]->getSourceName(this->atSources[atSink]) << '=';
  1757. this->printCall(out);
  1758. out << ';' << endl;
  1759. }
  1760. const char* getSinkDescription()
  1761. {
  1762. return "return a function call where each argument is an input to this code segment, the return value is assigned to an old variable";
  1763. }
  1764. const char* getSourceDescription()
  1765. {
  1766. return "This calls a function, no new variables are created because it returns";
  1767. }
  1768. const char* getSinkTermDescription(unsigned long at)
  1769. {
  1770. if(at>=this->sinkSize())
  1771. throw eMsg("callingCode_assignOld::getSinkTermDescription(): THe sink does not exist");
  1772. if(at<(this->sinkSize()-1))
  1773. return callingCode::getSinkTermDescription(at);
  1774. return "The variable where the return value is assigned";
  1775. }
  1776. };
  1777. class cppFunctionCode : public declaration
  1778. {
  1779. public:
  1780. virtual void writeDefinition(ostream& out)=0;
  1781. };
  1782. class cppFunctionName;
  1783. class cppFunctionInstance;
  1784. class cppFunctionName
  1785. {
  1786. private:
  1787. char* name;
  1788. list<cppFunctionInstance*> funcList;
  1789. bool isEqual(cppFunctionInstance* rhs,cppFunctionInstance* lhs);
  1790. public:
  1791. cppFunctionName(const char* fName=NULL);
  1792. virtual ~cppFunctionName();
  1793. const char* getName();
  1794. bool isUnique(cppFunctionInstance* fnc_test);
  1795. unsigned long getFunctionCount();
  1796. cppFunctionInstance* getFunctionInstance(unsigned long at);
  1797. cppFunctionInstance* createFunctionInstance();
  1798. void deleteLastInstance();
  1799. };
  1800. class cppFunctionInstance : public cppFunctionCode , public nameSource
  1801. {
  1802. private:
  1803. cppFunctionName* funcNameSource;
  1804. list<mappingCode*> mapCodePointers;
  1805. list<bool> delMapCode;
  1806. callingCode* myCall;
  1807. bool deleteCall;
  1808. list<code*> defnCode;
  1809. list<nameSource*> sources;
  1810. list<nameSink*> sinks;
  1811. vector<variable*> args;
  1812. vector<bool> deleteVar;
  1813. vector<char*> argDesc;
  1814. vector<bool> sunk;
  1815. cppType* retType;
  1816. bool callAdded;
  1817. bool retCalled;
  1818. bool areSinksClosed();
  1819. void printFunctionDecl(ostream& out);
  1820. public:
  1821. cppFunctionInstance(cppFunctionName* funcNameSource_in);
  1822. ~cppFunctionInstance();
  1823. unsigned long getArgumentCount();
  1824. cppFunctionInstance& setArgumentCount(unsigned long argCnt);
  1825. cppFunctionInstance& addArgument(unsigned long at, variable* arg,const char* desc,bool canDelete_in=false);
  1826. cppFunctionInstance& defineReturn(cppType* retType_in);
  1827. variable* getVariable(unsigned long at);
  1828. bool checkSinks();
  1829. bool canWrite();
  1830. bool canAdd();
  1831. bool canAddCall();
  1832. cppFunctionInstance& addMap(mappingCode* mpCd_in,bool retCall=false,bool canDelete_in=false);
  1833. cppFunctionInstance& addCall(callingCode* clCd_in,bool retCall=false,bool canDelete_in=false);
  1834. unsigned long sourceObjectCount();
  1835. unsigned long sinkObjectCount();
  1836. nameSource* getSource(unsigned long at);
  1837. nameSink* getSink(); // returns the most recently added sink
  1838. nameSink* getSink(unsigned long at);
  1839. // this is inherited from nameSource
  1840. unsigned long sourceSize();
  1841. const char* getSourceName(unsigned long at);
  1842. const char* getSourceDescription();
  1843. const char* getSourceTermDescription(unsigned long at);
  1844. bool isSunk(unsigned long at);
  1845. void setSunk(unsigned long at,bool isSunk=true);
  1846. void writeDefinition(ostream& out);
  1847. void printDecl(ostream& out);
  1848. };
  1849. bool cppFunctionName::isEqual(cppFunctionInstance* rhs,cppFunctionInstance* lhs)
  1850. {
  1851. if(rhs->getArgumentCount()!=lhs->getArgumentCount())
  1852. return false;
  1853. for(unsigned long i=0;i<rhs->getArgumentCount();i++)
  1854. {
  1855. if((*(rhs->getVariable(i)->getType()))!=(*(lhs->getVariable(i)->getType())))
  1856. return false;
  1857. }
  1858. return true;
  1859. }
  1860. cppFunctionName::cppFunctionName(const char* fName) : name(NULL)
  1861. {
  1862. if(fName!=NULL)
  1863. {
  1864. name=copyLine(fName);
  1865. if(name==NULL)
  1866. throw eMsg("cppFunctionName: Failed to allocate memory");
  1867. }
  1868. }
  1869. cppFunctionName::~cppFunctionName()
  1870. {
  1871. if(name!=NULL)
  1872. delete[] name;
  1873. for(list<cppFunctionInstance*>::iterator it=funcList.begin();it!=funcList.end();it++)
  1874. {
  1875. if((*it)!=NULL)
  1876. delete *it;
  1877. }
  1878. }
  1879. const char* cppFunctionName::getName()
  1880. {
  1881. if(name==NULL)
  1882. throw eMsg("cppFunctionName: The function name has not been specified");
  1883. return name;
  1884. }
  1885. bool cppFunctionName::isUnique(cppFunctionInstance* fnc_test)
  1886. {
  1887. for(list<cppFunctionInstance*>::iterator it=funcList.begin();it!=funcList.end();it++)
  1888. {
  1889. if(fnc_test!=*it)
  1890. {
  1891. if(isEqual(fnc_test,*it))
  1892. return false;
  1893. }
  1894. }
  1895. return true;
  1896. }
  1897. unsigned long cppFunctionName::getFunctionCount()
  1898. {
  1899. return funcList.size();
  1900. }
  1901. cppFunctionInstance* cppFunctionName::getFunctionInstance(unsigned long at)
  1902. {
  1903. if(at>=funcList.size())
  1904. throw eMsg("cppFunctionName::getFunctionInstance(): The function instance does not exist");
  1905. list<cppFunctionInstance*>::iterator it=funcList.begin();
  1906. for(unsigned long i=0;i<at;i++)
  1907. it++;
  1908. return *it;
  1909. }
  1910. cppFunctionInstance* cppFunctionName::createFunctionInstance()
  1911. {
  1912. funcList.push_back(new cppFunctionInstance(this));
  1913. if(funcList.back()==NULL)
  1914. throw eMsg("cppFunctionName::createFunctionInstance(): Failed to allocate memory");
  1915. return funcList.back();
  1916. }
  1917. void cppFunctionName::deleteLastInstance()
  1918. {
  1919. if(funcList.size()==0)
  1920. return;
  1921. delete funcList.back();
  1922. funcList.pop_back();
  1923. }
  1924. bool cppFunctionInstance::areSinksClosed()
  1925. {
  1926. if(sinks.size()>0)
  1927. {
  1928. nameSink* lstSnk=sinks.back();
  1929. for(unsigned long i=0;i<lstSnk->sinkSize();i++)
  1930. {
  1931. if(!lstSnk->sinkSet(i))
  1932. return false;
  1933. }
  1934. }
  1935. return true;
  1936. }
  1937. void cppFunctionInstance::printFunctionDecl(ostream& out)
  1938. {
  1939. if(retType==NULL || funcNameSource==NULL)
  1940. throw eMsg("cppFunctionInstance::printFunctionDecl(): Not all the inputs have been set");
  1941. if(!funcNameSource->isUnique(this))
  1942. throw eMsg("cppFunctionInstance::printFunctionDecl(): This function instance is not unique");
  1943. for(unsigned long i=0;i<args.size();i++)
  1944. {
  1945. if(args[i]==NULL)
  1946. throw eMsg("cppFunctionInstance::printFunctionDecl(): Not all the inputs have been set");
  1947. }
  1948. retType->printType(out);
  1949. out << ' ';
  1950. out << funcNameSource->getName();
  1951. out << "( ";
  1952. bool isFirst=true;
  1953. for(unsigned long i=0;i<args.size();i++)
  1954. {
  1955. if(!isFirst)
  1956. out << " , ";
  1957. args[i]->printDecl(out);
  1958. isFirst=false;
  1959. }
  1960. out << " )";
  1961. }
  1962. cppFunctionInstance::cppFunctionInstance(cppFunctionName* funcNameSource_in) : funcNameSource(funcNameSource_in) , callAdded(false) , retCalled(false)
  1963. {
  1964. sources.push_back(this);
  1965. }
  1966. cppFunctionInstance::~cppFunctionInstance()
  1967. {
  1968. for(unsigned long i=0;i<argDesc.size();i++)
  1969. {
  1970. if(argDesc[i]!=NULL)
  1971. delete[] argDesc[i];
  1972. }
  1973. for(unsigned long i=0;i<args.size();i++)
  1974. {
  1975. if(args[i]!=NULL && deleteVar[i])
  1976. delete args[i];
  1977. }
  1978. typename list<mappingCode*>::iterator itPntr=mapCodePointers.begin();
  1979. for(typename list<bool>::iterator itDel=delMapCode.begin();itDel!=delMapCode.end();itDel++)
  1980. {
  1981. if((*itPntr)!=NULL && (*itDel))
  1982. delete (*itPntr);
  1983. itPntr++;
  1984. }
  1985. }
  1986. unsigned long cppFunctionInstance::getArgumentCount()
  1987. {
  1988. return args.size();
  1989. }
  1990. cppFunctionInstance& cppFunctionInstance::setArgumentCount(unsigned long argCnt)
  1991. {
  1992. for(unsigned long i=argCnt;i<argDesc.size();i++)
  1993. {
  1994. if(deleteVar[i])
  1995. delete args[i];
  1996. delete[] argDesc[i];
  1997. argDesc[i]=NULL;
  1998. }
  1999. args.resize(argCnt,NULL);
  2000. argDesc.resize(argCnt,NULL);
  2001. deleteVar.resize(argCnt,false);
  2002. sunk.resize(argCnt,false);
  2003. return *this;
  2004. }
  2005. cppFunctionInstance& cppFunctionInstance::addArgument(unsigned long at, variable* arg,const char* desc,bool canDelete_in)
  2006. {
  2007. if(at>=args.size())
  2008. throw eMsg("cppFunctionInstance::addArgument(): The argument does not exist");
  2009. if(args[at]!=NULL && args[at]!=arg && deleteVar[at])
  2010. delete args[at];
  2011. args[at]=arg;
  2012. deleteVar[at]=canDelete_in;
  2013. if(argDesc[at]!=NULL)
  2014. delete[] argDesc[at];
  2015. argDesc[at]=copyLine(desc);
  2016. if(argDesc[at]==NULL)
  2017. throw eMsg("cppFunctionInstance::addArgument(): Failed to allocate memory");
  2018. return *this;
  2019. }
  2020. cppFunctionInstance& cppFunctionInstance::defineReturn(cppType* retType_in)
  2021. {
  2022. if(retType_in==NULL)
  2023. throw eMsg("The return type is not valid");
  2024. retType=retType_in;
  2025. return *this;
  2026. }
  2027. variable* cppFunctionInstance::getVariable(unsigned long at)
  2028. {
  2029. if(at>=args.size())
  2030. throw eMsg("The requested variable does not exist");
  2031. return args[at];
  2032. }
  2033. bool cppFunctionInstance::checkSinks()
  2034. {
  2035. return areSinksClosed();
  2036. }
  2037. bool cppFunctionInstance::canWrite()
  2038. {
  2039. if(retType==NULL)
  2040. return false;
  2041. if(retCalled)
  2042. return funcNameSource->isUnique(this);
  2043. if((*retType)!=(*voidType))
  2044. return false;
  2045. if(!checkSinks())
  2046. return false;
  2047. if(!callAdded)
  2048. return false;
  2049. return funcNameSource->isUnique(this);
  2050. }
  2051. bool cppFunctionInstance::canAdd()
  2052. {
  2053. return (retType==voidType || !retCalled);
  2054. }
  2055. bool cppFunctionInstance::canAddCall()
  2056. {
  2057. return !callAdded;
  2058. }
  2059. cppFunctionInstance& cppFunctionInstance::addMap(mappingCode* mpCd_in,bool retCall,bool canDelete_in)
  2060. {
  2061. if(retCalled)
  2062. throw eMsg("cppFunctionInstance: Cannot add more code to a function that is complete");
  2063. if(!areSinksClosed())
  2064. throw eMsg("cppFunctionInstance: Cannot add another sink until all the sinks are closed");
  2065. if(retCall)
  2066. {
  2067. if(retType==voidType || retType==NULL)
  2068. throw eMsg("cppFunctionInstance: Cannot have a return statement in a function returning void");
  2069. if(!callAdded)
  2070. throw eMsg("cppFunctionInstance: Cannot call return without the fortran function being called");
  2071. retCalled=true;
  2072. }
  2073. mapCodePointers.push_back(mpCd_in);
  2074. delMapCode.push_back(canDelete_in);
  2075. defnCode.push_back(mpCd_in);
  2076. sources.push_back(mpCd_in);
  2077. sinks.push_back(mpCd_in);
  2078. return *this;
  2079. }
  2080. cppFunctionInstance& cppFunctionInstance::addCall(callingCode* clCd_in,bool retCall,bool canDelete_in)
  2081. {
  2082. if(retCalled)
  2083. throw eMsg("cppFunctionInstance: The function has returned cannot add more code");
  2084. if(callAdded)
  2085. throw eMsg("cppFunctionInstance: Cannot have more than one instance of fortran function calls");
  2086. callAdded=true;
  2087. this->addMap(clCd_in,retCall,canDelete_in);
  2088. return *this;
  2089. }
  2090. unsigned long cppFunctionInstance::sourceObjectCount()
  2091. {
  2092. return sources.size();
  2093. }
  2094. unsigned long cppFunctionInstance::sinkObjectCount()
  2095. {
  2096. return sinks.size();
  2097. }
  2098. nameSource* cppFunctionInstance::getSource(unsigned long at)
  2099. {
  2100. if(at>=sources.size())
  2101. throw eMsg("cppFunctionInstance: The source does not exist");
  2102. list<nameSource*>::iterator it=sources.begin();
  2103. for(unsigned long i=0;i<at;i++)
  2104. it++;
  2105. return *it;
  2106. }
  2107. nameSink* cppFunctionInstance::getSink()
  2108. {
  2109. if(sinks.size()==0)
  2110. return NULL;
  2111. return sinks.back();
  2112. }
  2113. nameSink* cppFunctionInstance::getSink(unsigned long at)
  2114. {
  2115. if(at>=sinks.size())
  2116. throw eMsg("cppFunctionInstance: The sink does not exist");
  2117. list<nameSink*>::iterator it=sinks.begin();
  2118. for(unsigned long i=0;i<at;i++)
  2119. it++;
  2120. return *it;
  2121. }
  2122. // this is inherited from nameSource
  2123. unsigned long cppFunctionInstance::sourceSize()
  2124. {
  2125. return args.size();
  2126. }
  2127. const char* cppFunctionInstance::getSourceName(unsigned long at)
  2128. {
  2129. if(at>=args.size())
  2130. throw eMsg("cppFunctionInstance: The argument (aka source) does not exist");
  2131. return args[at]->getName();
  2132. }
  2133. const char* cppFunctionInstance::getSourceDescription()
  2134. {
  2135. return "The cpp function arguments";
  2136. }
  2137. const char* cppFunctionInstance::getSourceTermDescription(unsigned long at)
  2138. {
  2139. if(at>=args.size())
  2140. throw eMsg("cppFunctionInstance: The argument (aka source) does not exist");
  2141. return argDesc[at];
  2142. }
  2143. bool cppFunctionInstance::isSunk(unsigned long at)
  2144. {
  2145. if(at>=sunk.size())
  2146. throw eMsg("cppFunctionInstance: The argument (aka source) does not exist");
  2147. return sunk[at];
  2148. }
  2149. void cppFunctionInstance::setSunk(unsigned long at,bool isSunk)
  2150. {
  2151. if(at>=sunk.size())
  2152. throw eMsg("cppFunctionInstance: The argument (aka source) does not exist");
  2153. sunk[at]=isSunk;
  2154. }
  2155. void cppFunctionInstance::writeDefinition(ostream& out)
  2156. {
  2157. if(!canWrite())
  2158. throw eMsg("cppFunctionInstance: The function is not ready to be written yet");
  2159. this->printFunctionDecl(out);
  2160. out << endl << '{' << endl;
  2161. bool isFirst=true;
  2162. for(list<code*>::iterator it=defnCode.begin();it!=defnCode.end();it++)
  2163. {
  2164. if(!isFirst)
  2165. out << endl;
  2166. (*it)->writeCode(out);
  2167. isFirst=false;
  2168. }
  2169. out << '}' << endl << endl;
  2170. }
  2171. void cppFunctionInstance::printDecl(ostream& out)
  2172. {
  2173. this->printFunctionDecl(out);
  2174. out << ';' << endl;
  2175. }
  2176. objList<cppFunctionName> cppFuncs;
  2177. enum argIO
  2178. {
  2179. argUNKNOWN,
  2180. argINPUT,
  2181. argOUTPUT
  2182. };
  2183. // class fileReader
  2184. // {
  2185. // protected:
  2186. //
  2187. // list<comment> comments;
  2188. // bool funcSet;
  2189. // cppType* retType;
  2190. // char* name;
  2191. // list<variable*> args;
  2192. // vector<argIO> ioStat;
  2193. //
  2194. // virtual bool read(const char* file)=0;
  2195. //
  2196. // public:
  2197. //
  2198. // fileReader() : funcSet(false) , retType(NULL) , name(NULL) , ioStat(0,argUNKNOWN)
  2199. // {}
  2200. //
  2201. // ~fileReader()
  2202. // {}
  2203. // };
  2204. class fortranFunction : public declaration , public function
  2205. {
  2206. private:
  2207. list<comment> comments;
  2208. bool funcSet;
  2209. cppType* retType;
  2210. bool deleteRet;
  2211. char* name;
  2212. list<variable*> args;
  2213. vector<argIO> ioStat;
  2214. vector<const char*> argDesc;
  2215. bool read(const char* file)
  2216. {
  2217. fstream fin;
  2218. fin.open(file,fstream::in);
  2219. if(!fin.is_open())
  2220. throw eMsg("fortranFunction: failed to read file");
  2221. char line[LINE_SIZE];
  2222. vector<bool> isFnd;
  2223. bool argsRead=false;
  2224. cppType* varType;
  2225. bool inDecl=false;
  2226. while(!fin.eof())
  2227. {
  2228. fin.getline(line,LINE_SIZE);
  2229. char* ln=copyLine(line);
  2230. if(ln[0]=='*')
  2231. {
  2232. comment newComm;
  2233. newComm.line=ln;
  2234. if(ln[1]=='>')
  2235. newComm.tagged=true;
  2236. else
  2237. newComm.tagged=false;
  2238. comments.push_back(newComm);
  2239. }
  2240. else
  2241. {
  2242. wordList words(ln);
  2243. char word[LINE_SIZE];
  2244. if(!funcSet)
  2245. {
  2246. unsigned long strt;
  2247. for(unsigned long i=0;i<words.size();i++)
  2248. {
  2249. words.getWord(i,word,LINE_SIZE);
  2250. if(strEqual(word,"SUBROUTINE"))
  2251. {
  2252. funcSet=true;
  2253. retType=voidType;
  2254. strt=words.getStart(i+1);
  2255. break;
  2256. }
  2257. if(strEqual(word,"FUNCTION"))
  2258. {
  2259. funcSet=true;
  2260. retType=readType(words);
  2261. if(retType==NULL)
  2262. {
  2263. cout << "Failed to read the type in " << ln << endl;
  2264. throw eMsg("fortranFunction: Failed to read type");
  2265. }
  2266. strt=words.getStart(i+1);
  2267. break;
  2268. }
  2269. }
  2270. if(funcSet)
  2271. {
  2272. unsigned long j=strt;
  2273. char var[LINE_SIZE];
  2274. while(ln[j]!='(' && !isspace(ln[j]) && ln[j]!=0)
  2275. j++;
  2276. if(ln[j]==0)
  2277. throw eMsg("fortranFunction: Premature end to the line");
  2278. j+=2;
  2279. name=new char[j-strt];
  2280. if(name==NULL)
  2281. throw eMsg("fortranFunction: failed to allcate memory");
  2282. j=strt;
  2283. while(ln[j]!='(' && !isspace(ln[j]))
  2284. {
  2285. name[j-strt]=tolower(ln[j]);
  2286. j++;
  2287. }
  2288. name[j-strt]='_';
  2289. name[j+1-strt]=0;
  2290. bool isVars=true;
  2291. while(ln[j]!='(' && ln[j]!=0)
  2292. j++;
  2293. j++;
  2294. while(isspace(ln[j]) && ln[j]!=')' && ln[j]!=0)
  2295. j++;
  2296. if(ln[j]==0)
  2297. throw eMsg("fortranFunction: unexpected end to the line");
  2298. if(ln[j]==')')
  2299. isVars=false;
  2300. while(isVars)
  2301. {
  2302. if(ln[j]==',')
  2303. throw eMsg("fortranFunction: the argument list is malformed");
  2304. unsigned long k=j;
  2305. while(!isspace(ln[k]) && ln[k]!=0 && ln[k]!=')' && ln[k]!=',')
  2306. k++;
  2307. if(ln[k]==')')
  2308. isVars=false;
  2309. if(ln[k]==0)
  2310. throw eMsg("fortranFunction: the declaration is malformed");
  2311. unsigned long l=0;
  2312. for(j=j;j<k;j++)
  2313. var[l++]=ln[j];
  2314. var[l]=0;
  2315. variable* pVar=new variable(NULL,var,0,true);
  2316. if(pVar==NULL)
  2317. throw eMsg("fortranFunction: Failed to allocate memory");
  2318. args.push_back(pVar);
  2319. if(isVars)
  2320. {
  2321. while(ln[j]!=',' && ln[j]!=')' && ln[j]!=0)
  2322. j++;
  2323. if(ln[j]==0)
  2324. throw eMsg("fortranFunction: The declaration seems malformed");
  2325. if(ln[j]==')')
  2326. {
  2327. isVars=false;
  2328. }
  2329. else
  2330. {
  2331. j++;
  2332. while(isspace(ln[j]) && ln[j]!=0 && ln[j]!=')' && ln[j]!=',')
  2333. j++;
  2334. if(ln[j]==0 || ln[j]==')' || ln[j]==',')
  2335. throw eMsg("fortranFunction: The declration is messed up");
  2336. }
  2337. }
  2338. }
  2339. if(args.size()==0)
  2340. argsRead=true;
  2341. isFnd.resize(args.size(),false);
  2342. ioStat.resize(args.size(),argUNKNOWN);
  2343. argDesc.resize(args.size(),NULL);
  2344. }
  2345. }
  2346. else if(!argsRead)
  2347. {
  2348. unsigned long i=0;
  2349. if(inDecl)
  2350. {
  2351. while(isspace(ln[i]) && ln[i]!=0)
  2352. i++;
  2353. if(ln[i]!='&')
  2354. inDecl=false;
  2355. else
  2356. i++;
  2357. }
  2358. if(!inDecl)
  2359. varType=readType(words,i);
  2360. if(varType!=NULL)
  2361. {
  2362. char tmpVar[LINE_SIZE];
  2363. unsigned long j;
  2364. while(ln[i]!=0)
  2365. {
  2366. bool isArray=false;
  2367. while(isspace(ln[i]))
  2368. i++;
  2369. if(ln[i]!=0)
  2370. {
  2371. j=0;
  2372. while(ln[i]!='(' && !isspace(ln[i]) && ln[i]!=',' && ln[i]!=0)
  2373. tmpVar[j++]=ln[i++];
  2374. tmpVar[j]=0;
  2375. if(ln[i]!=0)
  2376. {
  2377. while(isspace(ln[i]) && ln[i]!=0)
  2378. i++;
  2379. if(ln[i]!=0)
  2380. {
  2381. if(ln[i]=='(')
  2382. {
  2383. isArray=true;
  2384. while(ln[i]!=')' && ln[i]!=0)
  2385. i++;
  2386. if(ln[i]==0)
  2387. throw eMsg("fortranFunction: the fortran type declaration is malformed");
  2388. i++;
  2389. while(isspace(ln[i]) && ln[i]!=0)
  2390. i++;
  2391. }
  2392. if(ln[i]==',')
  2393. i++;
  2394. }
  2395. }
  2396. }
  2397. j=0;
  2398. for(list<variable*>::iterator it=args.begin();it!=args.end();it++)
  2399. {
  2400. if(!isFnd[j])
  2401. {
  2402. if(strEqual(tmpVar,(*it)->getName()))
  2403. {
  2404. (*it)->setType(varType);
  2405. if(isArray)
  2406. (*it)->setPointerLevel(1);
  2407. isFnd[j]=true;
  2408. argsRead=true;
  2409. for(unsigned long k=0;k<isFnd.size();k++)
  2410. {
  2411. if(!isFnd[k])
  2412. {
  2413. argsRead=false;
  2414. break;
  2415. }
  2416. }
  2417. break;
  2418. }
  2419. }
  2420. j++;
  2421. }
  2422. }
  2423. }
  2424. else
  2425. {
  2426. inDecl=false;
  2427. }
  2428. }
  2429. delete[] ln;
  2430. }
  2431. }
  2432. for(list<comment>::iterator it=comments.begin();it!=comments.end();it++)
  2433. {
  2434. if(it->tagged)
  2435. {
  2436. unsigned long i=0;
  2437. const char* cLn=it->line;
  2438. while(cLn[i]!='\\' && cLn[i]!=0)
  2439. i++;
  2440. if(cLn[i]!=0)
  2441. {
  2442. i++;
  2443. char param[6];
  2444. unsigned long j=0;
  2445. while(j<5 && cLn[i]!=0)
  2446. param[j++]=cLn[i++];
  2447. if(cLn[i]!=0)
  2448. {
  2449. param[j]=0;
  2450. if(strEqual("param",param))
  2451. {
  2452. while(cLn[i]!='[' && cLn[i]!=0)
  2453. i++;
  2454. if(cLn[i]!=0)
  2455. {
  2456. argIO thisArg=argUNKNOWN;
  2457. while(cLn[i]!=']' && cLn[i]!=0)
  2458. {
  2459. if(cLn[i]=='i' && thisArg==argUNKNOWN)
  2460. thisArg=argINPUT;
  2461. if(cLn[i]=='o')
  2462. thisArg=argOUTPUT;
  2463. i++;
  2464. }
  2465. if(cLn[i]!=0)
  2466. {
  2467. i++;
  2468. char tmpVar[LINE_SIZE];
  2469. while(isspace(cLn[i]) && cLn[i]!=0)
  2470. i++;
  2471. if(cLn[i]!=0)
  2472. {
  2473. unsigned long j=0;
  2474. while(cLn[i]!=0 && !isspace(cLn[i]))
  2475. tmpVar[j++]=cLn[i++];
  2476. tmpVar[j]=0;
  2477. j=0;
  2478. for(list<variable*>::iterator itArg=args.begin();itArg!=args.end();itArg++)
  2479. {
  2480. if(strEqual((*itArg)->getName(),tmpVar))
  2481. {
  2482. ioStat[j]=thisArg;
  2483. argDesc[j]=copyLine(cLn);
  2484. if(argDesc[j]==NULL)
  2485. throw eMsg("fortranFunction::read(): Failed to allocate memory");
  2486. }
  2487. j++;
  2488. }
  2489. }
  2490. }
  2491. }
  2492. }
  2493. }
  2494. }
  2495. }
  2496. }
  2497. fin.close();
  2498. return true;
  2499. }
  2500. public:
  2501. fortranFunction(const char* fn=NULL) : funcSet(false) , retType(NULL) , deleteRet(false) , name(NULL) , ioStat(0,argUNKNOWN)
  2502. {
  2503. if(fn!=NULL)
  2504. read(fn);
  2505. }
  2506. fortranFunction(const fortranFunction& asg)
  2507. {
  2508. for(typename list<comment>::const_iterator it=asg.comments.begin();it!=asg.comments.end();it++)
  2509. this->comments.push_back(*it);
  2510. this->funcSet=asg.funcSet;
  2511. retType=asg.retType;
  2512. if(asg.name!=NULL)
  2513. {
  2514. this->name=copyLine(asg.name);
  2515. if(this->name==NULL)
  2516. throw eMsg("fortranFunction::fortranFunction(): Failed to allocate memory");
  2517. }
  2518. else
  2519. {
  2520. this->name=NULL;
  2521. }
  2522. for(typename list<variable*>::const_iterator it=asg.args.begin();it!=asg.args.end();it++)
  2523. {
  2524. variable* tmpVar=new variable(*(*it));
  2525. if(tmpVar==NULL)
  2526. throw eMsg("fortranFunction::fortranFunction(): Failed to allocate memory");
  2527. this->args.push_back(tmpVar);
  2528. }
  2529. this->ioStat.resize(asg.ioStat.size(),argUNKNOWN);
  2530. for(unsigned long i=0;i<this->ioStat.size();i++)
  2531. this->ioStat[i]=asg.ioStat[i];
  2532. this->argDesc.resize(asg.argDesc.size(),NULL);
  2533. for(unsigned long i=0;i<this->argDesc.size();i++)
  2534. {
  2535. if(asg.argDesc[i]!=NULL)
  2536. this->argDesc[i]=copyLine(asg.argDesc[i]);
  2537. }
  2538. }
  2539. ~fortranFunction()
  2540. {
  2541. if(name!=NULL)
  2542. delete[] name;
  2543. for(typename list<variable*>::iterator it=args.begin();it!=args.end();it++)
  2544. delete *it;
  2545. for(unsigned long i=0;i<argDesc.size();i++)
  2546. {
  2547. if(argDesc[i]!=NULL)
  2548. delete[] argDesc[i];
  2549. }
  2550. }
  2551. fortranFunction& operator=(const fortranFunction& asg)
  2552. {
  2553. // delete this data
  2554. if(name!=NULL)
  2555. delete[] name;
  2556. for(typename list<variable*>::iterator it=args.begin();it!=args.end();it++)
  2557. delete *it;
  2558. for(unsigned long i=0;i<argDesc.size();i++)
  2559. {
  2560. if(argDesc[i]!=NULL)
  2561. delete[] argDesc[i];
  2562. }
  2563. // copy over the other data
  2564. for(typename list<comment>::const_iterator it=asg.comments.begin();it!=asg.comments.end();it++)
  2565. this->comments.push_back(*it);
  2566. this->funcSet=asg.funcSet;
  2567. retType=asg.retType;
  2568. if(asg.name!=NULL)
  2569. {
  2570. this->name=copyLine(asg.name);
  2571. if(this->name==NULL)
  2572. throw eMsg("fortranFunction::fortranFunction(): Failed to allocate memory");
  2573. }
  2574. else
  2575. this->name=NULL;
  2576. for(typename list<variable*>::const_iterator it=asg.args.begin();it!=asg.args.end();it++)
  2577. {
  2578. variable* tmpVar=new variable(*(*it));
  2579. if(tmpVar==NULL)
  2580. throw eMsg("fortranFunction::fortranFunction(): Failed to allocate memory");
  2581. this->args.push_back(tmpVar);
  2582. }
  2583. this->ioStat.resize(asg.ioStat.size(),argUNKNOWN);
  2584. for(unsigned long i=0;i<this->ioStat.size();i++)
  2585. this->ioStat[i]=asg.ioStat[i];
  2586. this->argDesc.resize(asg.argDesc.size(),NULL);
  2587. for(unsigned long i=0;i<this->argDesc.size();i++)
  2588. {
  2589. if(asg.argDesc[i]!=NULL)
  2590. this->argDesc[i]=copyLine(asg.argDesc[i]);
  2591. }
  2592. return *this;
  2593. }
  2594. unsigned long argCount()
  2595. {
  2596. return args.size();
  2597. }
  2598. argIO getArgStat(unsigned long at)
  2599. {
  2600. if(at>=ioStat.size())
  2601. throw eMsg("fortranFunction: The argument does not exist");
  2602. return ioStat[at];
  2603. }
  2604. void setArgStat(unsigned long at, argIO argStat_in, const char* description=NULL)
  2605. {
  2606. if(at>=ioStat.size())
  2607. throw eMsg("fortranFunction: The argument does not exist");
  2608. ioStat[at]=argStat_in;
  2609. if(argDesc[at]!=NULL && argDesc[at]!=description)
  2610. delete[] argDesc[at];
  2611. if(argDesc[at]!=description)
  2612. {
  2613. if(description!=NULL)
  2614. {
  2615. argDesc[at]=copyLine(description);
  2616. if(argDesc[at]==NULL)
  2617. throw eMsg("fortranFunction::setArgStat(): Failed to allocate memory");
  2618. }
  2619. else
  2620. {
  2621. argDesc[at]=NULL;
  2622. }
  2623. }
  2624. }
  2625. void printDecl(ostream& out)
  2626. {
  2627. if(retType!=NULL)
  2628. retType->printType(out);
  2629. out << ' ' << name << "( ";
  2630. unsigned long at=0;
  2631. bool first=true;
  2632. for(list<variable*>::iterator it=args.begin();it!=args.end();it++)
  2633. {
  2634. if((*it)!=NULL)
  2635. {
  2636. if(!first)
  2637. out << " , ";
  2638. if(ioStat[at++]==argINPUT)
  2639. out << "const ";
  2640. (*it)->printDecl(out);
  2641. first=false;
  2642. }
  2643. }
  2644. out << " );" << endl;
  2645. }
  2646. const char* getFunctionName()
  2647. {
  2648. return this->name;
  2649. }
  2650. unsigned long getFunctionArgumentCount()
  2651. {
  2652. return args.size();
  2653. }
  2654. const char* getArgumentDescription(unsigned long at)
  2655. {
  2656. static stringstream tmpDesc;
  2657. if(at>=args.size())
  2658. throw eMsg("fortranFunction::getArgumentDescription(): The description does not exist");
  2659. if(argDesc[at]==NULL)
  2660. {
  2661. tmpDesc.str("");
  2662. tmpDesc << "Function argument " << at;
  2663. return tmpDesc.str().c_str();
  2664. }
  2665. return argDesc[at];
  2666. }
  2667. const char* getArgumentName(unsigned long at)
  2668. {
  2669. if(at>=args.size())
  2670. throw eMsg("fortranFunction::getArgumentName(): The argument does not exist");
  2671. typename list<variable*>::iterator it=args.begin();
  2672. for(unsigned long i=0;i<at;i++)
  2673. it++;
  2674. if((*it)==NULL)
  2675. throw eMsg("fortranFunction::getArgumentName(): The argument is NULL");
  2676. return (*it)->getName();
  2677. }
  2678. };
  2679. // read the fortran file
  2680. // get the input output if needed
  2681. // write the prototype
  2682. // select/define cpp function name
  2683. // define the arguments and return value for the name
  2684. // check that the arguments are unique
  2685. // each argument is a source
  2686. // the return value is a sink
  2687. // write the cpp function declaration
  2688. // introduce the fortran function as a code segment
  2689. // each argument is a sink
  2690. // the return value is a source
  2691. // OPTIONAL define/select maps for the code
  2692. // the maps are really blocks of text with special formating to insert custom keywords
  2693. // Link the sources with sinks until all sinks are full (outstanding sources are ignored)
  2694. // When everything is linked the cpp definition can be written
  2695. // void setCppFuncCnt(unsigned long funcCnt)
  2696. // {
  2697. // }
  2698. //
  2699. // unsigned long getCppFuncCnt()
  2700. // {
  2701. // }
  2702. //
  2703. // void addCppFunc(unsigned long at, cppFunctionInstance* func)
  2704. // {
  2705. // }
  2706. // class commandSource
  2707. // {
  2708. // public:
  2709. //
  2710. // virtual ~commandSource()
  2711. // {}
  2712. //
  2713. // virtual char getCharacter()=0;
  2714. // virtual void getLine(string& str)=0;
  2715. // virtual long getInteger()=0;
  2716. // virtual double getFloat()=0;
  2717. // virtual bool isOver()=0;
  2718. // };
  2719. // class function
  2720. // {
  2721. // public:
  2722. //
  2723. // virtual void printDecl(ostream& out)=0;
  2724. // virtual void printCall(ostream& out)=0;
  2725. // virtual bool overloaded()=0;
  2726. // virtual unsigned long size()=0;
  2727. // virtual variable* getVariable(unsigned long at)=0;
  2728. // };
  2729. //
  2730. // class function_fortran
  2731. // {
  2732. // private:
  2733. //
  2734. // unsigned long sz;
  2735. //
  2736. //
  2737. // public:
  2738. //
  2739. // bool overloaded()
  2740. // {
  2741. // return false;
  2742. // }
  2743. // }
  2744. //
  2745. //
  2746. //
  2747. // class program
  2748. // {
  2749. // private:
  2750. //
  2751. //
  2752. // fstream* pOut;
  2753. // fstream* dOut;
  2754. // ostream* scrn;
  2755. //
  2756. // public:
  2757. //
  2758. // virtual bool runComms(commandSource* comms_in,ostream* scrn_in=NULL)=NULL;
  2759. //
  2760. // };
  2761. class commentSink
  2762. {
  2763. public:
  2764. commentSink()
  2765. {}
  2766. ~commentSink()
  2767. {}
  2768. virtual void sinkComment(const char* comment)
  2769. {}
  2770. };
  2771. class commandSource
  2772. {
  2773. public:
  2774. commandSource()
  2775. {}
  2776. virtual ~commandSource()
  2777. {}
  2778. virtual char getChar()=0;
  2779. virtual long getInt()=0;
  2780. virtual const char* getToken()=0; // a word
  2781. virtual const char* getLine()=0;
  2782. virtual const char* getText()=0;
  2783. virtual unsigned long getLineCount()=0;
  2784. // if recording and an error is made this is called so the erroneous command is not recorded
  2785. virtual void clearRecord()
  2786. {}
  2787. // check to see if there is any more input or tells the program that a new batch is coming and to flush the buffer
  2788. virtual bool startRecord()
  2789. {
  2790. return true;
  2791. }
  2792. virtual void flushRecord()
  2793. {}
  2794. virtual void flushErrorToStream(ostream& out)
  2795. {}
  2796. virtual void flushErrorToFile(ostream& out, const char* fn)
  2797. {}
  2798. // tells the console that it is all over
  2799. virtual void exitRecord()
  2800. {}
  2801. virtual void setCommentSink(commentSink* cSnk)
  2802. {}
  2803. };
  2804. class commandSource_basic : public commandSource
  2805. {
  2806. private:
  2807. commentSink* cmntSink;
  2808. protected:
  2809. istream& in;
  2810. unsigned long cnt;
  2811. char line[LINE_SIZE*10];
  2812. void getRealLine(char* gtLine=NULL,unsigned long lnSize=0)
  2813. {
  2814. bool needLine=true;
  2815. if(gtLine==NULL)
  2816. {
  2817. gtLine=line;
  2818. lnSize=LINE_SIZE*10;
  2819. }
  2820. else
  2821. {
  2822. if(lnSize==0)
  2823. throw eMsg("commandSource_basic::getRealLine(): Invalid Line Size");
  2824. }
  2825. while(needLine && !in.eof())
  2826. {
  2827. in.getline(gtLine,lnSize);
  2828. if(line[0]!='%')
  2829. {
  2830. needLine=false;
  2831. }
  2832. else
  2833. {
  2834. if(cmntSink!=NULL)
  2835. cmntSink->sinkComment(line);
  2836. }
  2837. }
  2838. if(needLine)
  2839. throw eMsg("commandSource_basic(): Pre-mature eof, failed to retrieve a real line");
  2840. }
  2841. public:
  2842. commandSource_basic(istream& input) : cmntSink(NULL) , in(input) , cnt(0)
  2843. {}
  2844. ~commandSource_basic()
  2845. {}
  2846. char getChar()
  2847. {
  2848. char retVal;
  2849. this->getRealLine();
  2850. retVal=line[0];
  2851. return retVal;
  2852. }
  2853. long getInt()
  2854. {
  2855. long value;
  2856. stringstream ss;
  2857. this->getRealLine();
  2858. ss << line;
  2859. ss >> value;
  2860. return value;
  2861. }
  2862. const char* getToken() // a word
  2863. {
  2864. char* retVal=line;
  2865. unsigned long at=0;
  2866. this->getRealLine();
  2867. while(isspace(retVal[0]) && retVal[0]!=0)
  2868. retVal++;
  2869. while(!isspace(retVal[at]) && retVal[at]!=0)
  2870. at++;
  2871. retVal[at]=0;
  2872. return retVal;
  2873. }
  2874. const char* getLine()
  2875. {
  2876. this->getRealLine();
  2877. return line;
  2878. }
  2879. virtual const char* getText()
  2880. {
  2881. char* atLine=line;
  2882. unsigned long read=0;
  2883. cnt=0;
  2884. while(!in.eof() && ((10*LINE_SIZE-read)>0))
  2885. {
  2886. this->getRealLine(atLine,10*LINE_SIZE-read);
  2887. // in.getline(atLine,10*LINE_SIZE-read);
  2888. if(!in.eof())
  2889. {
  2890. read+=in.gcount();
  2891. atLine=&(line[read]);
  2892. if(read>0)
  2893. line[read-1]='\n';
  2894. cnt++;
  2895. }
  2896. }
  2897. line[read-1]=0;
  2898. in.clear();
  2899. return line;
  2900. }
  2901. unsigned long getLineCount()
  2902. {
  2903. return cnt;
  2904. }
  2905. void setCommentSink(commentSink* cSnk)
  2906. {
  2907. cmntSink=cSnk;
  2908. }
  2909. };
  2910. class commandSource_file : public commandSource_basic
  2911. {
  2912. private:
  2913. ostream* out;
  2914. public:
  2915. commandSource_file(fstream& fin, ostream* out_in=NULL) : commandSource_basic(fin) , out(out_in)
  2916. {
  2917. }
  2918. ~commandSource_file()
  2919. {
  2920. }
  2921. char getChar()
  2922. {
  2923. char c=this->commandSource_basic::getChar();
  2924. if(out!=NULL)
  2925. *out << c << endl;
  2926. return c;
  2927. }
  2928. long getInt()
  2929. {
  2930. long val=this->commandSource_basic::getInt();
  2931. if(out!=NULL)
  2932. *out << val << endl;
  2933. return val;
  2934. }
  2935. const char* getToken()
  2936. {
  2937. const char* val=this->commandSource_basic::getToken();
  2938. if(out!=NULL)
  2939. *out << val << endl;
  2940. return val;
  2941. }
  2942. const char* getLine()
  2943. {
  2944. const char* val=this->commandSource_basic::getLine();
  2945. if(out!=NULL)
  2946. *out << val << endl;
  2947. return val;
  2948. }
  2949. const char* getText()
  2950. {
  2951. char* atLine=line;
  2952. unsigned long read=0;
  2953. cnt=this->commandSource_basic::getInt();
  2954. for(unsigned long i=0;i<cnt;i++)
  2955. {
  2956. this->getRealLine(atLine,10*LINE_SIZE-read);
  2957. // in.getline(atLine,10*LINE_SIZE-read);
  2958. read+=in.gcount();
  2959. atLine=&(line[read]);
  2960. if(read>0)
  2961. line[read-1]='\n';
  2962. }
  2963. line[read-1]=0;
  2964. in.clear();
  2965. if(out!=NULL)
  2966. *out << line << endl;
  2967. return line;
  2968. }
  2969. bool startRecord()
  2970. {
  2971. in.peek();
  2972. if(in.eof())
  2973. return false;
  2974. else
  2975. return true;
  2976. }
  2977. };
  2978. class commandSource_recording : public commandSource , private commentSink
  2979. {
  2980. private:
  2981. commandSource* comm;
  2982. bool deleteComm;
  2983. char* recFile;
  2984. bool append;
  2985. bool rec;
  2986. fstream fout;
  2987. stringstream sout;
  2988. commentSink* cmntSink;
  2989. void sinkComment(const char* comment)
  2990. {
  2991. sout << comment << '\n';
  2992. if(cmntSink!=NULL)
  2993. cmntSink->sinkComment(comment);
  2994. }
  2995. public:
  2996. commandSource_recording(commandSource* comm_in=NULL, bool canDelete_in=false, const char* recFile_in=NULL, bool append_in=false) : comm(comm_in) , deleteComm(canDelete_in) , recFile(NULL) , append(append_in) , rec(false) , cmntSink(NULL)
  2997. {
  2998. if(comm!=NULL)
  2999. comm->setCommentSink(this);
  3000. if(recFile_in!=NULL)
  3001. {
  3002. recFile=copyLine(recFile_in);
  3003. if(recFile==NULL)
  3004. throw eMsg("commandSource_recording::commandSource_recording(): Failed to allocate memory");
  3005. }
  3006. }
  3007. ~commandSource_recording()
  3008. {
  3009. if(comm!=NULL && deleteComm)
  3010. delete comm;
  3011. if(recFile!=NULL)
  3012. delete[] recFile;
  3013. }
  3014. commandSource_recording& setCommandSource(commandSource* comm_in=NULL, bool canDelete_in=false)
  3015. {
  3016. if(comm!=NULL && comm!=comm_in && deleteComm)
  3017. delete comm;
  3018. comm=comm_in;
  3019. if(comm!=NULL)
  3020. comm->setCommentSink(this);
  3021. deleteComm=canDelete_in;
  3022. return *this;
  3023. }
  3024. const char* getRecordFile()
  3025. {
  3026. return recFile;
  3027. }
  3028. bool recording()
  3029. {
  3030. return rec;
  3031. }
  3032. commandSource_recording& start()
  3033. {
  3034. if(rec)
  3035. return *this;
  3036. if(recFile==NULL)
  3037. throw eMsg("commandSource_recording::start(): The recording file has not been set");
  3038. if(append)
  3039. fout.open(recFile,fstream::out|fstream::app);
  3040. else
  3041. fout.open(recFile,fstream::out);
  3042. if(!fout.is_open())
  3043. throw eMsg("commandSource_recording::start(): Filed to open the file");
  3044. rec=true;
  3045. return *this;
  3046. }
  3047. commandSource_recording& stop()
  3048. {
  3049. if(!rec)
  3050. return *this;
  3051. fout.close();
  3052. fout.clear();
  3053. rec=false;
  3054. return *this;
  3055. }
  3056. bool getAppendState()
  3057. {
  3058. return append;
  3059. }
  3060. commandSource_recording& setAppendState(bool append_in)
  3061. {
  3062. append=append_in;
  3063. return *this;
  3064. }
  3065. commandSource_recording& setRecordFile(const char* recFile_in,bool append_in=false)
  3066. {
  3067. bool wasRec=rec;
  3068. if(rec)
  3069. this->stop();
  3070. if(recFile!=NULL)
  3071. {
  3072. delete[] recFile;
  3073. recFile=NULL;
  3074. }
  3075. if(recFile_in!=NULL)
  3076. {
  3077. recFile=copyLine(recFile_in);
  3078. if(recFile==NULL)
  3079. throw eMsg("commandSource_recording::commandSource_recording(): Failed to allocate memory");
  3080. }
  3081. append=append_in;
  3082. if(wasRec && recFile!=NULL)
  3083. this->start();
  3084. return *this;
  3085. }
  3086. char getChar()
  3087. {
  3088. if(comm==NULL)
  3089. throw eMsg("commandSource_recording::getChar(): The command source has not been set");
  3090. char c=comm->getChar();
  3091. if(rec)
  3092. {
  3093. if(c==0)
  3094. sout << '\n';
  3095. else
  3096. sout << c << '\n';
  3097. }
  3098. return c;
  3099. }
  3100. long getInt()
  3101. {
  3102. if(comm==NULL)
  3103. throw eMsg("commandSource_recording::getInt(): The command source has not been set");
  3104. long val=comm->getInt();
  3105. if(rec)
  3106. {
  3107. sout << val << '\n';
  3108. }
  3109. return val;
  3110. }
  3111. const char* getToken()
  3112. {
  3113. if(comm==NULL)
  3114. throw eMsg("commandSource_recording::getToken(): The command source has not been set");
  3115. const char* tok=comm->getToken();
  3116. if(rec)
  3117. {
  3118. sout << tok << '\n';
  3119. }
  3120. return tok;
  3121. }
  3122. const char* getLine()
  3123. {
  3124. if(comm==NULL)
  3125. throw eMsg("commandSource_recording::getLine(): The command source has not been set");
  3126. const char* ln=comm->getLine();
  3127. if(rec)
  3128. {
  3129. sout << ln << '\n';
  3130. }
  3131. return ln;
  3132. }
  3133. const char* getText()
  3134. {
  3135. if(comm==NULL)
  3136. throw eMsg("commandSource_recording::getText(): The command source has not been set");
  3137. const char* txt=comm->getText();
  3138. sout << comm->getLineCount() << '\n';
  3139. if(rec)
  3140. {
  3141. sout << txt << '\n';
  3142. }
  3143. return txt;
  3144. }
  3145. unsigned long getLineCount()
  3146. {
  3147. if(comm==NULL)
  3148. throw eMsg("commandSource_recording::getLineCount(): The command source has not been set");
  3149. return comm->getLineCount();
  3150. }
  3151. // if recording and an error is made this is called so the erroneous command is not recorded
  3152. void clearRecord()
  3153. {
  3154. if(comm==NULL)
  3155. throw eMsg("commandSource_recording::clearRecord(): The command source has not been set");
  3156. sout.str("");
  3157. comm->clearRecord();
  3158. }
  3159. // check to see if there is any more input or tells the program that a new batch is coming and to flush the buffer
  3160. bool startRecord()
  3161. {
  3162. if(comm==NULL)
  3163. throw eMsg("commandSource_recording::startRecord(): The command source has not been set");
  3164. if(rec)
  3165. this->clearRecord();
  3166. else
  3167. this->start();
  3168. return comm->startRecord();
  3169. }
  3170. void flushRecord()
  3171. {
  3172. if(comm==NULL)
  3173. throw eMsg("commandSource_recording::exitRecord(): The command source has not been set");
  3174. if(rec)
  3175. fout << sout.str();
  3176. this->clearRecord();
  3177. comm->flushRecord();
  3178. }
  3179. void flushErrorToStream(ostream& out)
  3180. {
  3181. out << "Error producing command sequence recorded by commandSource_recording:" << endl;
  3182. out << sout.str();
  3183. this->clearRecord();
  3184. if(comm!=NULL)
  3185. comm->flushErrorToStream(out);
  3186. }
  3187. void flushErrorToFile(ostream& out,const char* fn)
  3188. {
  3189. fstream fout;
  3190. fout.open(fn,fstream::out);
  3191. if(!fout.is_open())
  3192. {
  3193. out << "Failed to open file " << fn << endl;
  3194. }
  3195. else
  3196. {
  3197. out << "Printing erroneous command sequence to " << fn << endl;
  3198. this->flushErrorToStream(fout);
  3199. fout.flush();
  3200. fout.close();
  3201. fout.clear();
  3202. }
  3203. }
  3204. // tells the console that it is all over
  3205. void exitRecord()
  3206. {
  3207. if(comm==NULL)
  3208. throw eMsg("commandSource_recording::exitRecord(): The command source has not been set");
  3209. this->clearRecord();
  3210. if(rec)
  3211. {
  3212. this->stop();
  3213. this->setAppendState(true);
  3214. }
  3215. comm->exitRecord();
  3216. }
  3217. void setCommentSink(commentSink* cSnk)
  3218. {
  3219. cmntSink=cSnk;
  3220. }
  3221. };
  3222. bool basicMenu(const char* title, vector<const char*>& options, vector<bool>& canDelete, ostream& out, commandSource& in, unsigned long& select, unsigned long permCnt=0)
  3223. {
  3224. unsigned long at=permCnt;
  3225. unsigned long sz=options.size();
  3226. if(permCnt>9 && options.size()>10)
  3227. throw eMsg("basicMenu(): Cannot display menu too many permanent options");
  3228. bool retVal=true;
  3229. while(true)
  3230. {
  3231. cout << "\n\n" << endl;
  3232. cout << title << endl;
  3233. for(unsigned long i=0;i<permCnt;i++)
  3234. out << i << '\t' << options[i] << endl;
  3235. for(unsigned long i=0;(i<(10-permCnt) && (i+at)<sz);i++)
  3236. out << i+permCnt << '\t' << options[i+at] << endl;
  3237. if(sz<10)
  3238. cout << "Make selection or [q]uit: ";
  3239. else if(at==permCnt)
  3240. cout << "Make selection, [n]ext or [q]uit: ";
  3241. else if(sz+permCnt-at<=10)
  3242. cout << "Make selection, [b]ack or [q]uit: ";
  3243. else
  3244. cout << "Make selection, [n]ext, [b]ack or [q]uit: ";
  3245. cout.flush();
  3246. char answer=tolower(in.getChar());
  3247. select=10;
  3248. switch(answer)
  3249. {
  3250. case 'n':
  3251. at+=10-permCnt;
  3252. if(at>=sz)
  3253. at-=10-permCnt;
  3254. break;
  3255. case 'b':
  3256. if(at>permCnt)
  3257. at-=10-permCnt;
  3258. break;
  3259. case '0':
  3260. select=0;
  3261. break;
  3262. case '1':
  3263. select=1;
  3264. break;
  3265. case '2':
  3266. select=2;
  3267. break;
  3268. case '3':
  3269. select=3;
  3270. break;
  3271. case '4':
  3272. select=4;
  3273. break;
  3274. case '5':
  3275. select=5;
  3276. break;
  3277. case '6':
  3278. select=6;
  3279. break;
  3280. case '7':
  3281. select=7;
  3282. break;
  3283. case '8':
  3284. select=8;
  3285. break;
  3286. case '9':
  3287. select=9;
  3288. break;
  3289. case 'q':
  3290. select=11;
  3291. break;
  3292. }
  3293. if(select<10)
  3294. {
  3295. if(select<permCnt)
  3296. break;
  3297. select+=at-permCnt;
  3298. if(select<sz)
  3299. break;
  3300. }
  3301. else if(select>10)
  3302. {
  3303. retVal=false;
  3304. break;
  3305. }
  3306. }
  3307. for(unsigned long i=0;i<sz;i++)
  3308. {
  3309. if(options[i]!=NULL && canDelete[i])
  3310. delete[] options[i];
  3311. }
  3312. return retVal;
  3313. }
  3314. bool nestedMenu(const char* title, vector<const char*>& pageHeader, vector< vector<const char*> >& options, vector<bool>& delHead, vector< vector<bool> >& canDelete, ostream& out, commandSource& in, unsigned long& major, unsigned long& minor, vector<unsigned long>& permCnt)
  3315. {
  3316. if(pageHeader.size()!=options.size() || delHead.size()!=pageHeader.size())
  3317. throw eMsg("nestedMenu(): The input data is inconsistent");
  3318. for(unsigned long i=0;i<options.size();i++)
  3319. {
  3320. if(options[i].size()!=canDelete[i].size())
  3321. throw eMsg("nestedMenu(): The input data is inconsistent");
  3322. }
  3323. bool majorRun=true;
  3324. bool retVal=true;
  3325. unsigned long maj=0;
  3326. unsigned long pgCnt=0;
  3327. unsigned long atPage=0;
  3328. for(unsigned long i=0;i<options.size();i++)
  3329. {
  3330. if(options[i].size()>0)
  3331. pgCnt++;
  3332. }
  3333. if(pgCnt==0)
  3334. {
  3335. retVal=false;
  3336. majorRun=false;
  3337. }
  3338. while(majorRun)
  3339. {
  3340. bool minorRun=true;
  3341. unsigned long at=permCnt[maj];
  3342. unsigned long sz=options[maj].size();
  3343. if(permCnt[maj]>9 && options[maj].size()>10)
  3344. throw eMsg("basicMenu(): Cannot display menu too many permanent options");
  3345. while(minorRun)
  3346. {
  3347. vector<const char*>& opt=options[maj];
  3348. unsigned long pmCnt=permCnt[maj];
  3349. cout << "\n\n" << endl;
  3350. cout << title << endl;
  3351. cout << pageHeader[maj] << endl;
  3352. for(unsigned long i=0;i<pmCnt;i++)
  3353. out << i << '\t' << opt[i] << endl;
  3354. for(unsigned long i=0;(i<(10-pmCnt) && (i+at)<sz);i++)
  3355. out << i+pmCnt << '\t' << opt[i+pmCnt] << endl;
  3356. if(atPage==0 && pgCnt==1)
  3357. {
  3358. if(sz<10)
  3359. cout << "Make selection or [q]uit: ";
  3360. else if(at==pmCnt)
  3361. cout << "Make selection, [n]ext or [q]uit: ";
  3362. else if(sz+pmCnt-at<=10)
  3363. cout << "Make selection, [b]ack or [q]uit: ";
  3364. else
  3365. cout << "Make selection, [n]ext, [b]ack or [q]uit: ";
  3366. }
  3367. else if(atPage==0)
  3368. {
  3369. // if(sz<10)
  3370. // cout << "Make selection, [N]ext page or [q]uit: ";
  3371. // else if(at==pmCnt)
  3372. // cout << "Make selection, [n]ext, [N]ext page or [q]uit: ";
  3373. // else if(sz+pmCnt-at<=10)
  3374. // cout << "Make selection, [b]ack, [N]ext page, or [q]uit: ";
  3375. // else
  3376. // cout << "Make selection, [n]ext, [b]ack, [N]ext page, or [q]uit: ";
  3377. if(at==pmCnt)
  3378. cout << "Make selection, [n]ext, [N]ext page or [q]uit: ";
  3379. else
  3380. cout << "Make selection, [n]ext, [b]ack, [N]ext page, or [q]uit: ";
  3381. }
  3382. else if(atPage==(pgCnt-1))
  3383. {
  3384. // if(sz<10)
  3385. // cout << "Make selection, [B]ack page or [q]uit: ";
  3386. // else if(at==pmCnt)
  3387. // cout << "Make selection, [n]ext, [B]ack page or [q]uit: ";
  3388. // else if(sz+pmCnt-at<=10)
  3389. // cout << "Make selection, [b]ack, [B]ack page or [q]uit: ";
  3390. // else
  3391. // cout << "Make selection, [n]ext, [b]ack, [B]ack page or [q]uit: ";
  3392. if(sz+pmCnt-at<=10)
  3393. cout << "Make selection, [b]ack, [B]ack page or [q]uit: ";
  3394. else
  3395. cout << "Make selection, [n]ext, [b]ack, [B]ack page or [q]uit: ";
  3396. }
  3397. else
  3398. {
  3399. // if(sz<10)
  3400. // cout << "Make selection, [N]ext page, [B]ack page or [q]uit: ";
  3401. // else if(at==pmCnt)
  3402. // cout << "Make selection, [n]ext, [N]ext page, [B]ack page or [q]uit: ";
  3403. // else if(sz+pmCnt-at<=10)
  3404. // cout << "Make selection, [b]ack, [N]ext page, [B]ack page or [q]uit: ";
  3405. // else
  3406. cout << "Make selection, [n]ext, [b]ack, [N]ext page, [B]ack page or [q]uit: ";
  3407. }
  3408. cout.flush();
  3409. char answer=in.getChar();
  3410. minor=10;
  3411. switch(answer)
  3412. {
  3413. case 'n':
  3414. at+=10-pmCnt;
  3415. if(at<sz)
  3416. break;
  3417. at-=10-pmCnt;
  3418. case 'N':
  3419. if(atPage<(pgCnt-1))
  3420. {
  3421. atPage++;
  3422. maj++;
  3423. while(options[maj].size()==0)
  3424. maj++;
  3425. minorRun=false;
  3426. }
  3427. break;
  3428. case 'b':
  3429. if(at>pmCnt)
  3430. {
  3431. at-=10-pmCnt;
  3432. break;
  3433. }
  3434. case 'B':
  3435. if(atPage>0)
  3436. {
  3437. atPage--;
  3438. maj--;
  3439. while(options[maj].size()==0)
  3440. maj--;
  3441. minorRun=false;
  3442. }
  3443. break;
  3444. case '0':
  3445. minor=0;
  3446. break;
  3447. case '1':
  3448. minor=1;
  3449. break;
  3450. case '2':
  3451. minor=2;
  3452. break;
  3453. case '3':
  3454. minor=3;
  3455. break;
  3456. case '4':
  3457. minor=4;
  3458. break;
  3459. case '5':
  3460. minor=5;
  3461. break;
  3462. case '6':
  3463. minor=6;
  3464. break;
  3465. case '7':
  3466. minor=7;
  3467. break;
  3468. case '8':
  3469. minor=8;
  3470. break;
  3471. case '9':
  3472. minor=9;
  3473. break;
  3474. case 'q':
  3475. minor=11;
  3476. break;
  3477. case 'Q':
  3478. minor=11;
  3479. break;
  3480. }
  3481. if(minor<10)
  3482. {
  3483. major=maj;
  3484. if(minor<pmCnt)
  3485. break;
  3486. minor+=at-pmCnt;
  3487. if(minor<sz)
  3488. {
  3489. majorRun=false;
  3490. minorRun=false;
  3491. }
  3492. }
  3493. else if(minor>10)
  3494. {
  3495. majorRun=false;
  3496. minorRun=false;
  3497. retVal=false;
  3498. }
  3499. }
  3500. }
  3501. for(unsigned long i=0;i<pageHeader.size();i++)
  3502. {
  3503. if(pageHeader[i]!=NULL && delHead[i])
  3504. delete[] pageHeader[i];
  3505. }
  3506. for(unsigned long i=0;i<options.size();i++)
  3507. {
  3508. for(unsigned long j=0;j<options[i].size();j++)
  3509. {
  3510. if(options[i][j]!=NULL && canDelete[i][j])
  3511. delete[] options[i][j];
  3512. }
  3513. }
  3514. return retVal;
  3515. }
  3516. class sourceFile
  3517. {
  3518. private:
  3519. list<declaration*> decls;
  3520. list<cppFunctionCode*> defns;
  3521. char* fn;
  3522. sourceFile& writeFile(ostream& out)
  3523. {
  3524. out << endl;
  3525. for(typename list<declaration*>::iterator it=decls.begin();it!=decls.end();it++)
  3526. (*it)->printDecl(out);
  3527. out << endl;
  3528. for(typename list<cppFunctionCode*>::iterator it=defns.begin();it!=defns.end();it++)
  3529. (*it)->writeDefinition(out);
  3530. out << endl;
  3531. return *this;
  3532. }
  3533. public:
  3534. sourceFile(const char* file_in=NULL) : fn(NULL)
  3535. {
  3536. if(file_in!=NULL)
  3537. {
  3538. fn=copyLine(file_in);
  3539. if(fn==NULL)
  3540. throw eMsg("sourceFile::sourceFile(): Failed to allocate memory");
  3541. }
  3542. }
  3543. ~sourceFile()
  3544. {
  3545. if(fn!=NULL)
  3546. delete[] fn;
  3547. }
  3548. const char* getFileName()
  3549. {
  3550. return fn;
  3551. }
  3552. sourceFile& setFileName(const char* file_in)
  3553. {
  3554. if(fn!=NULL)
  3555. {
  3556. delete[] fn;
  3557. fn=NULL;
  3558. }
  3559. if(file_in==NULL)
  3560. {
  3561. fn=NULL;
  3562. return *this;
  3563. }
  3564. fn=copyLine(file_in);
  3565. if(fn==NULL)
  3566. throw eMsg("sourceFile::setFileName(): Failed to allocate memory");
  3567. return *this;
  3568. }
  3569. sourceFile& addDeclaration(declaration* dec)
  3570. {
  3571. if(dec==NULL)
  3572. throw eMsg("sourceFile::addDeclaration(): The declaration is NULL");
  3573. decls.push_back(dec);
  3574. return *this;
  3575. }
  3576. sourceFile& addDefinition(cppFunctionCode* def)
  3577. {
  3578. if(def==NULL)
  3579. throw eMsg("sourceFile::addDefinition(): Cannot accept a NULL argument");
  3580. defns.push_back(def);
  3581. return *this;
  3582. }
  3583. sourceFile& writeFile(bool append=true)
  3584. {
  3585. if(fn==NULL)
  3586. return writeFile(cout);
  3587. fstream fout;
  3588. if(append)
  3589. fout.open(fn,fstream::out | fstream::app);
  3590. else
  3591. fout.open(fn,fstream::out);
  3592. if(!fout.is_open())
  3593. throw eMsg("sourceFile::writeFile(): Failed to open file");
  3594. return writeFile(fout);
  3595. }
  3596. };
  3597. sourceFile fortranSource;
  3598. sourceFile cppPrototype;
  3599. sourceFile cppDefinition;
  3600. commandSource_recording recorder;
  3601. vector<const char*> fileArguments;
  3602. vector<bool> fileArgumentProcessed;
  3603. list<fortranFunction> fortranFunctionList;
  3604. // DEFINE CPP TYPE
  3605. bool createCPPType(commandSource& comm, ostream& out, cppType*& newType,bool makeCopy=true)
  3606. {
  3607. // ask if it is a basic type or template
  3608. bool typeCreated=false;
  3609. if(makeCopy)
  3610. newType=NULL;
  3611. vector<const char*> opt(2,NULL);
  3612. vector<bool> del(2,false);
  3613. opt[0]="basic type";
  3614. opt[1]="template type";
  3615. unsigned long ans;
  3616. if(basicMenu("What kind of C++ type?",opt,del,out,comm,ans,0))
  3617. {
  3618. cppType_basic* bTp;
  3619. cppType_template* tTp;
  3620. const char* name;
  3621. const char* desc;
  3622. long argCnt=0;
  3623. unsigned long uCnt=0;
  3624. char ansYN;
  3625. bool getCnt=true;
  3626. bool failed=false;
  3627. switch(ans)
  3628. {
  3629. case 0:
  3630. out << "Specify the name: ";
  3631. out.flush();
  3632. name=copyLine(comm.getToken());
  3633. if(name==NULL)
  3634. throw eMsg("createCPPType(): Failed to allocate memory");
  3635. out << "Give a description for this type: ";
  3636. out.flush();
  3637. desc=copyLine(comm.getLine());
  3638. if(desc==NULL)
  3639. {
  3640. delete[] name;
  3641. throw eMsg("createCPPType(): Failed to allocate memory");
  3642. }
  3643. out << "About to create a basic type with name " << name << " continue? [y]: ";
  3644. out.flush();
  3645. ansYN=comm.getChar();
  3646. if(ansYN!='n' && ansYN!='N')
  3647. {
  3648. bTp=new cppType_basic(name,desc);
  3649. if(bTp==NULL)
  3650. {
  3651. delete[] name;
  3652. delete[] desc;
  3653. throw eMsg("createCPPType(): Failed to allocate memory");
  3654. throw eMsg("createCPPType(): Failed to allocate memory");
  3655. }
  3656. bTypes.addObj(bTp);
  3657. if(makeCopy)
  3658. {
  3659. newType=new cppType_basic(*bTp);
  3660. if(newType==NULL)
  3661. {
  3662. delete[] name;
  3663. delete[] desc;
  3664. throw eMsg("createCPPType(): Failed to allocate memory");
  3665. }
  3666. }
  3667. }
  3668. delete[] name;
  3669. delete[] desc;
  3670. break;
  3671. case 1:
  3672. out << "Specify the name: ";
  3673. out.flush();
  3674. name=copyLine(comm.getToken());
  3675. if(name==NULL)
  3676. throw eMsg("createCPPType(): Failed to allocate memory");
  3677. out << "Give a description for this type: ";
  3678. out.flush();
  3679. desc=copyLine(comm.getLine());
  3680. if(desc==NULL)
  3681. {
  3682. delete[] name;
  3683. throw eMsg("createCPPType(): Failed to allocate memory");
  3684. }
  3685. getCnt=true;
  3686. failed=false;
  3687. while(getCnt)
  3688. {
  3689. out << "How many template arguments? ";
  3690. out.flush();
  3691. argCnt=comm.getInt();
  3692. if(argCnt<0)
  3693. {
  3694. out << "Cannot accept a negative, do you want to try again [y]: ";
  3695. out.flush();
  3696. ansYN=comm.getChar();
  3697. if(ansYN=='n' || ansYN=='N')
  3698. {
  3699. getCnt=false;
  3700. failed=true;
  3701. }
  3702. }
  3703. else
  3704. {
  3705. getCnt=false;
  3706. }
  3707. }
  3708. if(!failed)
  3709. {
  3710. uCnt=argCnt;
  3711. out << "About to create a template type with name " << name << " with " << uCnt << " arguments" << endl;
  3712. out << "Described as " << desc << endl;
  3713. out << "Continue? [y]: ";
  3714. out.flush();
  3715. ansYN=comm.getChar();
  3716. if(ansYN!='n' && ansYN!='N')
  3717. {
  3718. tTp=new cppType_template(name,desc,uCnt);
  3719. if(tTp==NULL)
  3720. {
  3721. delete[] name;
  3722. delete[] desc;
  3723. throw eMsg("createCPPType(): Failed to allocate memory");
  3724. }
  3725. tTypes.addObj(tTp);
  3726. typeCreated=true;
  3727. if(makeCopy)
  3728. {
  3729. newType=new cppType_template(*tTp);
  3730. if(newType==NULL)
  3731. {
  3732. delete[] name;
  3733. delete[] desc;
  3734. throw eMsg("createCPPType(): Failed to allocate memory");
  3735. }
  3736. }
  3737. }
  3738. }
  3739. delete[] name;
  3740. delete[] desc;
  3741. break;
  3742. }
  3743. }
  3744. return typeCreated;
  3745. }
  3746. bool createCPPType(commandSource& comm, ostream& out)
  3747. {
  3748. cppType* dummy=NULL;
  3749. return createCPPType(comm, out, dummy, false);
  3750. }
  3751. bool createTextMap(commandSource& comm, ostream& out, mapText*& txtMp)
  3752. {
  3753. bool getText=true;
  3754. bool exit=false;
  3755. char ansYN;
  3756. txtMp=new mapText();
  3757. const char* txt=NULL;
  3758. // get text
  3759. while(getText)
  3760. {
  3761. out << "Give the code for the new map:" << endl;
  3762. txt=copyLine(comm.getText());
  3763. if(txt==NULL)
  3764. {
  3765. delete txtMp;
  3766. throw eMsg("createTextMap(): Failed to allocate memory");
  3767. }
  3768. if(txtMp->setText(txt))
  3769. {
  3770. getText=false;
  3771. }
  3772. else
  3773. {
  3774. out << "The text given is malformed, try again? [y]: ";
  3775. out.flush();
  3776. ansYN=comm.getChar();
  3777. if(ansYN=='n' || ansYN=='N')
  3778. {
  3779. exit=true;
  3780. getText=false;
  3781. }
  3782. }
  3783. delete[] txt;
  3784. }
  3785. if(exit)
  3786. {
  3787. delete txtMp;
  3788. txtMp=NULL;
  3789. return false;
  3790. }
  3791. // get description
  3792. out << "Give a brief description: ";
  3793. out.flush();
  3794. txt=copyLine(comm.getLine());
  3795. if(txt==NULL)
  3796. {
  3797. delete txtMp;
  3798. throw eMsg("createTextMap(): Failed to allocate memory");
  3799. }
  3800. txtMp->setDescription(txt);
  3801. delete[] txt;
  3802. // get inputs
  3803. for(unsigned long i=0;i<txtMp->getInCnt();i++)
  3804. {
  3805. out << "Give a brief description of input " << i+1 << ": ";
  3806. out.flush();
  3807. txt=copyLine(comm.getLine());
  3808. if(txt==NULL)
  3809. {
  3810. delete txtMp;
  3811. throw eMsg("createTextMap(): Failed to allocate memory");
  3812. }
  3813. txtMp->setInputDescription(i,txt);
  3814. delete[] txt;
  3815. }
  3816. // get outputs
  3817. for(unsigned long i=0;i<txtMp->getOutCnt();i++)
  3818. {
  3819. out << "Give a brief description of output " << i+1 << ": ";
  3820. out.flush();
  3821. txt=copyLine(comm.getLine());
  3822. if(txt==NULL)
  3823. {
  3824. delete txtMp;
  3825. throw eMsg("createTextMap(): Failed to allocate memory");
  3826. }
  3827. txtMp->setOutputDescription(i,txt);
  3828. delete[] txt;
  3829. }
  3830. // get types
  3831. for(unsigned long i=0;i<txtMp->getTypeCnt();i++)
  3832. {
  3833. out << "Give a brief description of type " << i+1 << ": ";
  3834. out.flush();
  3835. txt=copyLine(comm.getLine());
  3836. if(txt==NULL)
  3837. {
  3838. delete txtMp;
  3839. throw eMsg("createTextMap(): Failed to allocate memory");
  3840. }
  3841. txtMp->setTypeDescription(i,txt);
  3842. delete[] txt;
  3843. }
  3844. // get customs
  3845. for(unsigned long i=0;i<txtMp->getCustCnt();i++)
  3846. {
  3847. out << "Give a brief description of custom field " << i+1 << ": ";
  3848. out.flush();
  3849. txt=copyLine(comm.getLine());
  3850. if(txt==NULL)
  3851. {
  3852. delete txtMp;
  3853. throw eMsg("createTextMap(): Failed to allocate memory");
  3854. }
  3855. txtMp->setCustomDescription(i,txt);
  3856. delete[] txt;
  3857. }
  3858. // ask for confirmation
  3859. out << "About to submit mapText:" << endl;
  3860. out << txtMp->getTxt() << endl;
  3861. out << "Described as " << txtMp->getDescription() << endl;
  3862. bool prntSpace=false;
  3863. for(unsigned long i=0;i<txtMp->getInCnt();i++)
  3864. {
  3865. if(prntSpace)
  3866. out << ", ";
  3867. out << "Input " << i+1 << " is '" << txtMp->getInputDescription(i) << '\'';
  3868. prntSpace=true;
  3869. }
  3870. for(unsigned long i=0;i<txtMp->getOutCnt();i++)
  3871. {
  3872. if(prntSpace)
  3873. out << ", ";
  3874. out << "Output " << i+1 << " is '" << txtMp->getOutputDescription(i) << '\'';
  3875. prntSpace=true;
  3876. }
  3877. for(unsigned long i=0;i<txtMp->getTypeCnt();i++)
  3878. {
  3879. if(prntSpace)
  3880. out << ", ";
  3881. out << "Type " << i+1 << " is '" << txtMp->getTypeDescription(i) << '\'';
  3882. prntSpace=true;
  3883. }
  3884. for(unsigned long i=0;i<txtMp->getCustCnt();i++)
  3885. {
  3886. if(prntSpace)
  3887. out << ", ";
  3888. out << "Custom field " << i+1 << " is '" << txtMp->getCustomDescription(i) << '\'';
  3889. prntSpace=true;
  3890. }
  3891. out << endl << "Do you want to submit this? [y]: ";
  3892. out.flush();
  3893. ansYN=comm.getChar();
  3894. if(ansYN=='n' || ansYN=='N')
  3895. {
  3896. delete txtMp;
  3897. txtMp=NULL;
  3898. return false;
  3899. }
  3900. textMaps.addObj(txtMp);
  3901. return true;
  3902. }
  3903. bool createTextMap(commandSource& comm, ostream& out)
  3904. {
  3905. mapText* tmp;
  3906. return createTextMap(comm,out,tmp);
  3907. }
  3908. bool createCppFunctionName(commandSource& comm, ostream& out, cppFunctionName*& func)
  3909. {
  3910. out << "What name do you want for the function name: ";
  3911. out.flush();
  3912. const char* name=copyLine(comm.getToken());
  3913. if(name==NULL)
  3914. throw eMsg("createCppFunctionName(): Failed to allocate memory");
  3915. out << "Are you sure you want a function called " << name << "? [y] ";
  3916. out.flush();
  3917. char ansYN=comm.getChar();
  3918. if(ansYN=='n' || ansYN=='N')
  3919. {
  3920. delete[] name;
  3921. return false;
  3922. }
  3923. func=new cppFunctionName(name);
  3924. delete[] name;
  3925. cppFuncs.addObj(func);
  3926. return true;
  3927. }
  3928. bool createCppFunctionName(commandSource& comm, ostream& out)
  3929. {
  3930. cppFunctionName* func;
  3931. return createCppFunctionName(comm, out, func);
  3932. }
  3933. bool readFortranFunction(commandSource& comm, ostream& out)
  3934. {
  3935. bool getList=true;
  3936. bool retry=true;
  3937. unsigned long fileCnt=0;
  3938. unsigned long openFile=0;
  3939. const char* fltr=NULL;
  3940. char ansYN;
  3941. unsigned long ans;
  3942. unsigned long atFile;
  3943. while(retry)
  3944. {
  3945. retry=false;
  3946. while(getList)
  3947. {
  3948. if(fltr!=NULL)
  3949. delete[] fltr;
  3950. out << "Please specify a search filter: ";
  3951. out.flush();
  3952. fltr=copyLine(comm.getLine());
  3953. for(unsigned long i=0;i<fileArgumentProcessed.size();i++)
  3954. {
  3955. if(!fileArgumentProcessed[i])
  3956. {
  3957. openFile++;
  3958. if(strFilterEqual(fltr,fileArguments[i]))
  3959. fileCnt++;
  3960. }
  3961. }
  3962. if(openFile==0)
  3963. {
  3964. out << "There are no more fortran files to process" << endl;
  3965. delete[] fltr;
  3966. return false;
  3967. }
  3968. if(fileCnt==0)
  3969. {
  3970. out << "The filter provided does not match any of the open files, try another? [y]: ";
  3971. out.flush();
  3972. ansYN=comm.getChar();
  3973. if(ansYN=='n' || ansYN=='N')
  3974. getList=false;
  3975. }
  3976. else
  3977. {
  3978. getList=false;
  3979. }
  3980. }
  3981. if(fileCnt==0)
  3982. {
  3983. delete[] fltr;
  3984. return false;
  3985. }
  3986. if(fileCnt>1)
  3987. {
  3988. vector<const char*> opt(fileCnt,NULL);
  3989. vector<unsigned long> fileIndex(fileCnt,0);
  3990. vector<bool> del(fileCnt,false);
  3991. atFile=0;
  3992. for(unsigned long i=0;i<fileArgumentProcessed.size();i++)
  3993. {
  3994. if(!fileArgumentProcessed[i] && strFilterEqual(fltr,fileArguments[i]))
  3995. {
  3996. opt[atFile]=fileArguments[i];
  3997. fileIndex[atFile]=i;
  3998. atFile++;
  3999. }
  4000. }
  4001. if(!basicMenu("What file would you like to process?",opt,del,out,comm,ans,0))
  4002. {
  4003. delete[] fltr;
  4004. return false;
  4005. }
  4006. atFile=fileIndex[ans];
  4007. }
  4008. else
  4009. {
  4010. for(unsigned long i=0;i<fileArgumentProcessed.size();i++)
  4011. {
  4012. if(!fileArgumentProcessed[i] && strFilterEqual(fltr,fileArguments[i]))
  4013. {
  4014. atFile=i;
  4015. break;
  4016. }
  4017. }
  4018. out << "Going to process " << fileArguments[atFile] << " is this correct [y]? ";
  4019. out.flush();
  4020. ansYN=comm.getChar();
  4021. if(ansYN=='n' || ansYN=='N')
  4022. retry=true;
  4023. }
  4024. }
  4025. delete[] fltr;
  4026. // read a fortran function
  4027. fortranFunction test(fileArguments[atFile]);
  4028. out << "The prototype for the function is ";
  4029. test.printDecl(out);
  4030. out << endl;
  4031. // now lets make sure all the arguments are set
  4032. for(unsigned long i=0;i<test.argCount();i++)
  4033. {
  4034. bool isOut;
  4035. const char* argDesc;
  4036. bool overRide=false;
  4037. if(test.getArgStat(i)==argUNKNOWN)
  4038. {
  4039. out << "Is argument " << test.getArgumentName(i) << " in position " << i+1 << " of the argument list an output? [n]: ";
  4040. out.flush();
  4041. ansYN=comm.getChar();
  4042. if(ansYN=='y' || ansYN=='Y')
  4043. isOut=true;
  4044. else
  4045. isOut=false;
  4046. }
  4047. else
  4048. {
  4049. if(test.getArgStat(i)==argOUTPUT)
  4050. isOut=true;
  4051. else
  4052. isOut=false;
  4053. out << "Argument " << test.getArgumentName(i) << " in position " << i+1 << " of the argument list is an ";
  4054. if(isOut)
  4055. out << " output ";
  4056. else
  4057. out << " input ";
  4058. out << "is this correct? [y]: ";
  4059. out.flush();
  4060. ansYN=comm.getChar();
  4061. if(ansYN=='n' || ansYN=='N')
  4062. {
  4063. isOut=!isOut;
  4064. overRide=true;
  4065. }
  4066. }
  4067. if(test.getArgStat(i)==argUNKNOWN)
  4068. {
  4069. out << "Give a brief description of the argument: ";
  4070. out.flush();
  4071. argDesc=comm.getLine();
  4072. if(isOut)
  4073. test.setArgStat(i,argOUTPUT,argDesc);
  4074. else
  4075. test.setArgStat(i,argINPUT,argDesc);
  4076. }
  4077. else
  4078. {
  4079. bool newDesc=false;
  4080. out << "Give a brief description of the argument: [" << test.getArgumentDescription(i) << "] ";
  4081. out.flush();
  4082. argDesc=comm.getLine();
  4083. if(argDesc[0]!=0)
  4084. newDesc=true;
  4085. else
  4086. argDesc=test.getArgumentDescription(i);
  4087. if(newDesc || overRide)
  4088. {
  4089. if(isOut)
  4090. test.setArgStat(i,argOUTPUT,argDesc);
  4091. else
  4092. test.setArgStat(i,argINPUT,argDesc);
  4093. }
  4094. }
  4095. }
  4096. out << "\nAbout to add the fortran function defined in file:" << endl;
  4097. out << '\t' << fileArguments[atFile] << endl;
  4098. out << "That defines the function" << endl;
  4099. out << '\t';
  4100. test.printDecl(out);
  4101. out << endl << endl << "With the following argument descriptions:" << endl;
  4102. for(unsigned long i=0;i<test.argCount();i++)
  4103. {
  4104. out << '\t' << test.getArgumentName(i) << '\t';
  4105. if(test.getArgStat(i)==argOUTPUT)
  4106. out << "out\t";
  4107. else
  4108. out << "in\t";
  4109. out << test.getArgumentDescription(i) << endl;
  4110. }
  4111. out << "Do you want to submit this? [y]: ";
  4112. out.flush();
  4113. ansYN=comm.getChar();
  4114. if(ansYN=='n' || ansYN=='N')
  4115. return false;
  4116. fortranFunctionList.push_back(test);
  4117. fileArgumentProcessed[atFile]=true;
  4118. fortranSource.addDeclaration(&(fortranFunctionList.back()));
  4119. return true;
  4120. }
  4121. // Retrieve cpp function name
  4122. bool getCppFunctionName(commandSource& comm, ostream& out, cppFunctionName*& func)
  4123. {
  4124. // populate menu with all the available cpp function names
  4125. unsigned long cnt=cppFuncs.size();
  4126. unsigned long ans;
  4127. out << "Creating function name for ";
  4128. fortranFunctionList.back().printDecl(out);
  4129. out << endl;
  4130. if(cnt==0)
  4131. return createCppFunctionName(comm,out,func);
  4132. vector<const char*> opt(cnt+1,NULL);
  4133. vector<bool> del(cnt+1,false);
  4134. opt[0]="Create new function name";
  4135. for(unsigned long i=0;i<cnt;i++)
  4136. opt[i+1]=cppFuncs.getObj(i)->getName();
  4137. // note that an option to define new type will always be present
  4138. // wait for selection
  4139. stringstream ss;
  4140. ss.str("");
  4141. ss << "Retrieve function name for ";
  4142. fortranFunctionList.back().printDecl(ss);
  4143. if(basicMenu(ss.str().c_str(),opt,del,out,comm,ans,1))
  4144. {
  4145. if(ans==0)
  4146. {
  4147. out << "Creating function name for ";
  4148. fortranFunctionList.back().printDecl(out);
  4149. out << endl;
  4150. return createCppFunctionName(comm,out,func);
  4151. }
  4152. func=cppFuncs.getObj(ans-1);
  4153. return true;
  4154. }
  4155. return false;
  4156. }
  4157. // RETRIEVE CPP TYPE
  4158. bool getCppType(commandSource& comm,ostream& out,cppType*& type)
  4159. {
  4160. unsigned long bCnt=bTypes.size();
  4161. unsigned long tCnt=tTypes.size();
  4162. unsigned long cnt=bCnt+tCnt+1;
  4163. char ansYN;
  4164. vector<const char*> opt(cnt,NULL);
  4165. vector<bool> del(cnt,NULL);
  4166. opt[0]="Define new C++ Type";
  4167. stringstream ss;
  4168. for(unsigned long i=0;i<bCnt;i++)
  4169. {
  4170. ss.str("");
  4171. ss << bTypes.getObj(i)->getName() << " \t";
  4172. bTypes.getObj(i)->printDescription(ss);
  4173. opt[i+1]=copyLine(ss.str().c_str());
  4174. if(opt[i+1]==NULL)
  4175. {
  4176. for(unsigned long j=1;j<(i+1);j++)
  4177. delete[] opt[j];
  4178. throw eMsg("getCppType(): Failed to allocate memory");
  4179. }
  4180. del[i+1]=true;
  4181. }
  4182. for(unsigned long i=0;i<tCnt;i++)
  4183. {
  4184. ss.str("");
  4185. ss << tTypes.getObj(i)->getName() << " \t";
  4186. tTypes.getObj(i)->printDescription(ss);
  4187. opt[i+bCnt+1]=copyLine(ss.str().c_str());
  4188. if(opt[i+bCnt+1]==NULL)
  4189. {
  4190. for(unsigned long j=1;j<(i+bCnt+1);j++)
  4191. delete[] opt[j];
  4192. throw eMsg("getCppType(): Failed to allocate memory");
  4193. }
  4194. del[i+bCnt+1]=true;
  4195. }
  4196. unsigned long ans;
  4197. if(!basicMenu("Select an option for a C++ type:",opt,del,out,comm,ans,1))
  4198. return false;
  4199. if(ans==0)
  4200. return createCPPType(comm,out,type,true);
  4201. if(ans<=bCnt)
  4202. {
  4203. type=new cppType_basic(*(bTypes.getObj(ans-1)));
  4204. if(type==NULL)
  4205. throw eMsg("getCppType(): Failed to allocate memory");
  4206. return true;
  4207. }
  4208. cppType_template* tmpType=new cppType_template(*(tTypes.getObj(ans-1-bCnt)));
  4209. if(tmpType==NULL)
  4210. throw eMsg("getCppType(): Failed to allocate memory");
  4211. for(unsigned long i=0;i<tmpType->size();i++)
  4212. {
  4213. bool getType=true;
  4214. while(getType)
  4215. {
  4216. out << "Need to retrieve information for template argument " << i+1 << endl;
  4217. out << "Is the argument a type [y]: ";
  4218. out.flush();
  4219. ansYN=comm.getChar();
  4220. if(ansYN=='n' || ansYN=='N')
  4221. {
  4222. out << "Please specify the value for the argument: ";
  4223. out.flush();
  4224. long val=comm.getInt();
  4225. tmpType->setArgType(i,val);
  4226. getType=false;
  4227. }
  4228. else
  4229. {
  4230. out << "About to retrieve a type for the template argument " << i+1 << "..." << endl;
  4231. cppType* arg;
  4232. if(!getCppType(comm,out,arg))
  4233. {
  4234. out << "Failed to retrieve a type, do you want to exit to the previous menu [n]: ";
  4235. out.flush();
  4236. ansYN=comm.getChar();
  4237. if(ansYN=='y' || ansYN=='Y')
  4238. {
  4239. delete tmpType;
  4240. return false;
  4241. }
  4242. }
  4243. else
  4244. {
  4245. getType=false;
  4246. tmpType->setArgType(i,arg,true);
  4247. }
  4248. }
  4249. }
  4250. }
  4251. type=tmpType;
  4252. return true;
  4253. }
  4254. // GET THE MAP TEXT
  4255. bool getCodeSegment(commandSource& comm, ostream& out, bool funcCalled, bool needReturn, mappingCode*& mapCode, callingCode*& callCode, bool& isReturn)
  4256. {
  4257. mapCode=NULL;
  4258. callCode=NULL;
  4259. isReturn=false;
  4260. // callingCode
  4261. // callingCode_assignNew
  4262. // callingCode_assignOld
  4263. // callingCode_return
  4264. // returnValue
  4265. // returnSink
  4266. // nameMap_text...
  4267. // objList<mapText> textMaps;
  4268. unsigned long mpCnt=textMaps.size();
  4269. unsigned long cnt;
  4270. bool getCode=true;
  4271. char ansYN;
  4272. if(!funcCalled)
  4273. {
  4274. if(needReturn)
  4275. cnt=mpCnt+5;
  4276. else
  4277. cnt=mpCnt+4;
  4278. }
  4279. else if(needReturn)
  4280. {
  4281. cnt=mpCnt+3;
  4282. }
  4283. else
  4284. {
  4285. cnt=mpCnt+1;
  4286. }
  4287. mapText* txtMp=NULL;
  4288. while(getCode)
  4289. {
  4290. vector<const char*> opt(cnt,NULL);
  4291. vector<bool> del(cnt,false);
  4292. unsigned long atIndex=0;
  4293. opt[atIndex++]="Define a new text map";
  4294. if(!funcCalled)
  4295. {
  4296. opt[atIndex++]="Basic function call";
  4297. opt[atIndex++]="Function call that assigns the return value to a new variable";
  4298. opt[atIndex++]="Function call that assigns the return value to an existing variable";
  4299. if(needReturn)
  4300. opt[atIndex++]="Function call that return the return value of the function";
  4301. }
  4302. else if(needReturn)
  4303. {
  4304. opt[atIndex++]="Return a value";
  4305. opt[atIndex++]="Return a variable";
  4306. }
  4307. for(unsigned long i=0;i<mpCnt;i++)
  4308. opt[atIndex++]=textMaps.getObj(i)->getDescription();
  4309. unsigned long ans;
  4310. if(!basicMenu("What code segment do you want to add?",opt,del,out,comm,ans,1))
  4311. return false;
  4312. if(ans!=0)
  4313. {
  4314. if(!funcCalled)
  4315. {
  4316. if(needReturn)
  4317. {
  4318. if(ans>4)
  4319. ans+=2;
  4320. }
  4321. else
  4322. {
  4323. if(ans>3)
  4324. ans+=3;
  4325. }
  4326. }
  4327. else
  4328. {
  4329. if(needReturn)
  4330. {
  4331. ans+=4;
  4332. }
  4333. else
  4334. {
  4335. ans+=6;
  4336. }
  4337. }
  4338. }
  4339. cppType* tp=NULL;
  4340. const char* txt;
  4341. switch(ans)
  4342. {
  4343. case 0:
  4344. if(!createTextMap(comm,out,txtMp))
  4345. {
  4346. out << "Do you want to return to the main menu [n]? ";
  4347. out.flush();
  4348. ansYN=comm.getChar();
  4349. if(ansYN=='y' || ansYN=='Y')
  4350. return false;
  4351. else
  4352. break;
  4353. }
  4354. getCode=false;
  4355. break;
  4356. case 1:
  4357. out << "Are you sure you want to submit a simple function call [y]? ";
  4358. out.flush();
  4359. ansYN=comm.getChar();
  4360. if(ansYN!='n' && ansYN!='N')
  4361. {
  4362. callCode=new callingCode(&(fortranFunctionList.back()),false);
  4363. if(callCode==NULL)
  4364. throw eMsg("getCodeSegment(): Failed to allocate memory");
  4365. return true;
  4366. }
  4367. out << "Do you want to return to the main menu [n]? ";
  4368. out.flush();
  4369. ansYN=comm.getChar();
  4370. if(ansYN=='y' || ansYN=='Y')
  4371. return false;
  4372. break;
  4373. case 2:
  4374. out << "Need the type for the new variable" << endl;
  4375. if(!getCppType(comm,out,tp))
  4376. {
  4377. out << "Do you want to return to the main menu [n]? ";
  4378. out.flush();
  4379. ansYN=comm.getChar();
  4380. if(ansYN=='y' || ansYN=='Y')
  4381. return false;
  4382. break;
  4383. }
  4384. out << "What name do you want for this variable: ";
  4385. out.flush();
  4386. txt=copyLine(comm.getToken());
  4387. out << "Are you sure you want to submit a function call that assigns to a variable of type ";
  4388. tp->printType(out);
  4389. out << " with the name " << txt << " [y] ? ";
  4390. out.flush();
  4391. ansYN=comm.getChar();
  4392. if(ansYN!='n' && ansYN!='N')
  4393. {
  4394. callCode=new callingCode_assignNew(&(fortranFunctionList.back()),false,tp,txt,true);
  4395. delete[] txt;
  4396. if(callCode==NULL)
  4397. throw eMsg("getCodeSegment(): Failed to allocate memory");
  4398. return true;
  4399. }
  4400. delete[] txt;
  4401. out << "Do you want to return to the main menu [n]? ";
  4402. out.flush();
  4403. ansYN=comm.getChar();
  4404. if(ansYN=='y' || ansYN=='Y')
  4405. return false;
  4406. break;
  4407. case 3:
  4408. out << "Are you sure you want to submit a function call that assigns to an existing variable [y]? ";
  4409. out.flush();
  4410. ansYN=comm.getChar();
  4411. if(ansYN!='n' && ansYN!='N')
  4412. {
  4413. callCode=new callingCode_assignOld(&(fortranFunctionList.back()),false);
  4414. if(callCode==NULL)
  4415. throw eMsg("getCodeSegment(): Failed to allocate memory");
  4416. return true;
  4417. }
  4418. out << "Do you want to return to the main menu [n]? ";
  4419. out.flush();
  4420. ansYN=comm.getChar();
  4421. if(ansYN=='y' || ansYN=='Y')
  4422. return false;
  4423. break;
  4424. case 4:
  4425. out << "Are you sure you want to submit a function call where the result is the return value [y]? ";
  4426. out.flush();
  4427. ansYN=comm.getChar();
  4428. if(ansYN!='n' && ansYN!='N')
  4429. {
  4430. callCode=new callingCode_return(&(fortranFunctionList.back()),false);
  4431. if(callCode==NULL)
  4432. throw eMsg("getCodeSegment(): Failed to allocate memory");
  4433. isReturn=true;
  4434. return true;
  4435. }
  4436. out << "Do you want to return to the main menu [n]? ";
  4437. out.flush();
  4438. ansYN=comm.getChar();
  4439. if(ansYN=='y' || ansYN=='Y')
  4440. return false;
  4441. break;
  4442. case 5:
  4443. out << "What value to you want to return: ";
  4444. out.flush();
  4445. txt=copyLine(comm.getToken());
  4446. out << "Do you want to submit a return the value " << txt << " statement [y]? ";
  4447. out.flush();
  4448. ansYN=comm.getChar();
  4449. if(ansYN!='n' && ansYN!='N')
  4450. {
  4451. mapCode=new returnValue(txt);
  4452. delete[] txt;
  4453. isReturn=true;
  4454. return true;
  4455. }
  4456. delete[] txt;
  4457. out << "Do you want to return to the main menu [n]? ";
  4458. out.flush();
  4459. ansYN=comm.getChar();
  4460. if(ansYN=='y' || ansYN=='Y')
  4461. return false;
  4462. break;
  4463. case 6:
  4464. out << "Do you want to submit a return a variable statement [y]? ";
  4465. out.flush();
  4466. ansYN=comm.getChar();
  4467. if(ansYN!='n' && ansYN!='N')
  4468. {
  4469. mapCode=new returnSink();
  4470. isReturn=true;
  4471. return true;
  4472. }
  4473. out << "Do you want to return to the main menu [n]? ";
  4474. out.flush();
  4475. ansYN=comm.getChar();
  4476. if(ansYN=='y' || ansYN=='Y')
  4477. return false;
  4478. break;
  4479. default:
  4480. txtMp=textMaps.getObj(ans-7);
  4481. getCode=false;
  4482. break;
  4483. }
  4484. }
  4485. nameMap_text* map=new nameMap_text(*txtMp);
  4486. if(map==NULL)
  4487. throw eMsg("getCodeSegment(): Failed to allocate memory");
  4488. const char* tok;
  4489. cppType* tmpType;
  4490. for(unsigned long i=0;i<txtMp->getOutCnt();i++)
  4491. {
  4492. out << "Specify the name for output " << i+1 << " described by " << txtMp->getOutputDescription(i) << ": ";
  4493. out.flush();
  4494. tok=comm.getToken();
  4495. map->setOutName(i,tok);
  4496. }
  4497. for(unsigned long i=0;i<txtMp->getCustCnt();i++)
  4498. {
  4499. out << "Specify the token for the custom field " << i+1 << " described by " << txtMp->getCustomDescription(i) << ": ";
  4500. out.flush();
  4501. tok=comm.getToken();
  4502. map->setCustName(i,tok);
  4503. }
  4504. for(unsigned long i=0;i<txtMp->getTypeCnt();i++)
  4505. {
  4506. bool getType=true;
  4507. while(getType)
  4508. {
  4509. out << "Specify the type for type " << i+1 << " described as " << txtMp->getTypeDescription(i) << endl;
  4510. if(!getCppType(comm,out,tmpType))
  4511. {
  4512. out << "Do you want to return to the main menu [n] ? ";
  4513. out.flush();
  4514. ansYN=comm.getChar();
  4515. if(ansYN=='y' || ansYN=='Y')
  4516. {
  4517. delete map;
  4518. return false;
  4519. }
  4520. }
  4521. else
  4522. {
  4523. getType=false;
  4524. }
  4525. }
  4526. map->setCppType(i,tmpType,true);
  4527. }
  4528. out << "About to submit the text map described as " << txtMp->getDescription() << " and written as " << endl;
  4529. out << txtMp->getTxt() << endl;
  4530. for(unsigned long i=0;i<txtMp->getOutCnt();i++)
  4531. out << "With output " << i+1 << ": " << map->getOutName(i) << endl;
  4532. for(unsigned long i=0;i<txtMp->getCustCnt();i++)
  4533. out << "With custom field " << i+1 << ": " << map->getCustName(i) << endl;
  4534. for(unsigned long i=0;i<txtMp->getTypeCnt();i++)
  4535. {
  4536. out << "With type " << i+1 << ": ";
  4537. map->getCppType(i)->printType(out);
  4538. out << endl;
  4539. }
  4540. out << "Are you sure everything is correct [y]? ";
  4541. out.flush();
  4542. ansYN=comm.getChar();
  4543. if(ansYN=='n' || ansYN=='N')
  4544. {
  4545. delete map;
  4546. return false;
  4547. }
  4548. mapCode=map;
  4549. return true;
  4550. }
  4551. // CPP FUNCTION INSTANCE
  4552. bool createCppFunctionInstance(commandSource& comm, ostream& out, cppFunctionInstance*& fncInst)
  4553. {
  4554. fncInst=NULL;
  4555. char ansYN;
  4556. if(fortranFunctionList.size()==0)
  4557. {
  4558. out << "Cannot define a C++ function until a fortran function has been defined" << endl;
  4559. return false;
  4560. }
  4561. cppFunctionName* funcName;
  4562. // Call Retrieve Cpp function Name
  4563. if(!getCppFunctionName(comm,out,funcName))
  4564. return false;
  4565. cppFunctionInstance* fnc=funcName->createFunctionInstance();
  4566. if(fnc==NULL)
  4567. throw eMsg("createCppFunctionInstance(): Failed to allocate memory");
  4568. unsigned long argCnt;
  4569. out << "Defining function for ";
  4570. fortranFunctionList.back().printDecl(out);
  4571. out << endl;
  4572. out << "How many arguments for this function? ";
  4573. out.flush();
  4574. argCnt=comm.getInt();
  4575. fnc->setArgumentCount(argCnt);
  4576. for(unsigned long i=0;i<argCnt;i++)
  4577. {
  4578. cppType* argType;
  4579. // get the cpp type
  4580. if(!getCppType(comm,out,argType))
  4581. {
  4582. funcName->deleteLastInstance();
  4583. return false;
  4584. }
  4585. // ask if it is a reference
  4586. out << "Is this const? [n] ";
  4587. out.flush();
  4588. ansYN=comm.getChar();
  4589. bool isCnst=false;
  4590. if(ansYN=='y' || ansYN=='Y')
  4591. isCnst=true;
  4592. // get the pointer level
  4593. bool getLevel=true;
  4594. bool fail=false;
  4595. long pntrCnt=0;
  4596. while(getLevel && !fail)
  4597. {
  4598. out << "How many pointer levels is this argument? ";
  4599. out.flush();
  4600. pntrCnt=comm.getInt();
  4601. if(pntrCnt<0)
  4602. {
  4603. out << "Cannot accept a negative value, try again? [y]:";
  4604. out.flush();
  4605. ansYN=comm.getChar();
  4606. if(ansYN=='n' || ansYN=='N')
  4607. {
  4608. fail=true;
  4609. getLevel=false;
  4610. }
  4611. }
  4612. else
  4613. {
  4614. getLevel=false;
  4615. }
  4616. }
  4617. if(fail)
  4618. {
  4619. funcName->deleteLastInstance();
  4620. delete argType;
  4621. return false;
  4622. }
  4623. // ask if it is a reference
  4624. out << "Is this a reference? [n] ";
  4625. out.flush();
  4626. ansYN=comm.getChar();
  4627. bool isRef=false;
  4628. if(ansYN=='y' || ansYN=='Y')
  4629. isRef=true;
  4630. // ask for the name of the variable
  4631. out << "What name do you want to give to this variable? ";
  4632. out.flush();
  4633. const char* name=comm.getToken();
  4634. variable* var=new variable(argType,name,pntrCnt,isRef,isCnst,true);
  4635. if(var==NULL)
  4636. {
  4637. delete argType;
  4638. throw eMsg("createCppFunctionInstance(): Failed to allocate memory");
  4639. }
  4640. out << "Describe the variable: ";
  4641. out.flush();
  4642. const char* desc=comm.getLine();
  4643. fnc->addArgument(i,var,desc,true);
  4644. }
  4645. // Retrieve the return tyoe
  4646. out << "\n\n\nRetrieve the return type for this function" << endl;
  4647. cppType* retType;
  4648. if(!getCppType(comm,out,retType))
  4649. {
  4650. funcName->deleteLastInstance();
  4651. return false;
  4652. }
  4653. fnc->defineReturn(retType);
  4654. bool addingMaps=true;
  4655. bool funcCalled=false;
  4656. mappingCode* mapCode;
  4657. callingCode* callCode;
  4658. bool isReturn;
  4659. bool needReturn=((*retType)!=(*voidType));
  4660. while(addingMaps)
  4661. {
  4662. if(funcCalled && !needReturn)
  4663. {
  4664. out << "Note the function call has occured and no return statement is needed, do you want to add any more code segments [n]? ";
  4665. out.flush();
  4666. ansYN=comm.getChar();
  4667. if(ansYN!='y' && ansYN!='Y')
  4668. addingMaps=false;
  4669. }
  4670. if(addingMaps)
  4671. {
  4672. if(!getCodeSegment(comm, out, funcCalled, needReturn, mapCode, callCode, isReturn))
  4673. {
  4674. funcName->deleteLastInstance();
  4675. return false;
  4676. }
  4677. if(mapCode==NULL && callCode==NULL)
  4678. {
  4679. out << "An error occurred trying to get the map" << endl;
  4680. funcName->deleteLastInstance();
  4681. return false;
  4682. }
  4683. if(mapCode!=NULL)
  4684. fnc->addMap(mapCode,isReturn,true);
  4685. if(callCode!=NULL)
  4686. {
  4687. fnc->addCall(callCode,isReturn,true);
  4688. funcCalled=true;
  4689. }
  4690. // connect all the sinks with a source
  4691. nameSink* snk=fnc->getSink();
  4692. if(snk==NULL)
  4693. throw eMsg("createCppFunctionInstance(): Unexplained error");
  4694. for(unsigned long i=0;i<snk->sinkSize();i++)
  4695. {
  4696. stringstream ss;
  4697. ss.str("");
  4698. ss << "Select the source for sink term " << i+1 << " of the last code segment described as " << snk->getSinkTermDescription(i);
  4699. unsigned long srcCnt=fnc->sourceObjectCount()-1;
  4700. vector<bool> delHead(srcCnt,false);
  4701. unsigned long major=0;
  4702. unsigned long minor=0;
  4703. vector<unsigned long> permCnt(srcCnt,0);
  4704. vector<const char*> pageHeader(srcCnt,NULL);
  4705. vector< vector<const char*> > options(srcCnt);
  4706. vector< vector<bool> > canDelete(srcCnt);
  4707. unsigned long srcTrmCnt=0;
  4708. for(unsigned long j=0;j<srcCnt;j++)
  4709. {
  4710. nameSource* src=fnc->getSource(j);
  4711. pageHeader[j]=src->getSourceDescription();
  4712. options[j].resize(src->sourceSize(),NULL);
  4713. canDelete[j].resize(src->sourceSize(),true);
  4714. for(unsigned long k=0;k<src->sourceSize();k++)
  4715. {
  4716. srcTrmCnt++;
  4717. stringstream srcTrm;
  4718. srcTrm.str("");
  4719. srcTrm << "Variable '" << src->getSourceName(k) << "' as described as '" << src->getSourceTermDescription(k) << "'";
  4720. options[j][k]=copyLine(srcTrm.str().c_str());
  4721. }
  4722. }
  4723. if(srcTrmCnt==0)
  4724. {
  4725. out << "\n\nFailed to add code segment because there are no sources for the sink\n\n" << endl;
  4726. funcName->deleteLastInstance();
  4727. return false;
  4728. }
  4729. if(!nestedMenu(ss.str().c_str(), pageHeader, options, delHead, canDelete, out, comm, major, minor, permCnt))
  4730. {
  4731. funcName->deleteLastInstance();
  4732. return false;
  4733. }
  4734. fnc->getSink()->setSource(i,fnc->getSource(major),minor); // INFO
  4735. }
  4736. // adjust to any changes in state
  4737. if(isReturn)
  4738. {
  4739. if(!funcCalled || !fnc->canWrite())
  4740. {
  4741. out << "The sequence of code is invalid" << endl;
  4742. funcName->deleteLastInstance();
  4743. }
  4744. else
  4745. {
  4746. addingMaps=false;
  4747. }
  4748. }
  4749. }
  4750. }
  4751. out << "The C++ function is " << endl;
  4752. fnc->writeDefinition(out);
  4753. out << '\n' << endl;
  4754. out << "Do you want to submit this [y]? ";
  4755. out.flush();
  4756. ansYN=comm.getChar();
  4757. if(ansYN=='n' || ansYN=='N')
  4758. {
  4759. funcName->deleteLastInstance();
  4760. return false;
  4761. }
  4762. fncInst=fnc;
  4763. cppPrototype.addDeclaration(fnc);
  4764. cppDefinition.addDefinition(fnc);
  4765. return true;
  4766. // while(addingArgs)
  4767. // {
  4768. // Ask "Do you want to add an argument?"
  4769. // if( no )
  4770. // break;
  4771. // Call retrieve cpp function type
  4772. // Get var name
  4773. // Get the variable description
  4774. // add variable to the instance
  4775. // }
  4776. // Ask "Is there a return value"?
  4777. // If yes
  4778. // Retrieve cpp Type
  4779. // set retType accordingly
  4780. // else
  4781. // set return type to void
  4782. // while ( adding maps )
  4783. // {
  4784. // permanent entry is new map selection
  4785. // populate menu entries with map descriptions
  4786. // // Note that if call has been added do not list calling maps
  4787. // wait for selection
  4788. // if( new map selected )
  4789. // define new map
  4790. // else
  4791. // with response retrieve entry
  4792. // for all outputs
  4793. // display description
  4794. // get token
  4795. // for all types
  4796. // display description
  4797. // retrieve cpp type
  4798. // for all customs
  4799. // display description
  4800. // get token
  4801. // for all sink terms
  4802. // set major title to "retrieving source for <sink description>: <insert sink term description>"
  4803. // for each non-empty source
  4804. // set minor title to "<insert source description>"
  4805. // populate menue with each source term description
  4806. // wait for selection
  4807. // set sink term
  4808. // if !canAdd
  4809. // break;
  4810. // if canWrite
  4811. // Ask "do you want to add another map?"
  4812. // if no
  4813. // break
  4814. // }
  4815. // return instance
  4816. }
  4817. bool createCppFunctionInstance(commandSource& comm, ostream& out)
  4818. {
  4819. cppFunctionInstance* fncInst=NULL;
  4820. return createCppFunctionInstance(comm,out,fncInst);
  4821. }
  4822. // RUN COMMANDS
  4823. void runCommands(commandSource& comm, ostream& out)
  4824. {
  4825. bool canExit=false;
  4826. while(!canExit && comm.startRecord())
  4827. {
  4828. vector<const char*> opt;
  4829. vector<bool> del;
  4830. if(fortranFunctionList.size()>0)
  4831. {
  4832. opt.resize(6);
  4833. del.resize(6,false);
  4834. }
  4835. else
  4836. {
  4837. opt.resize(5);
  4838. del.resize(5,false);
  4839. }
  4840. opt[0]="Define a new C++ type";
  4841. opt[1]="Define a new code map";
  4842. opt[2]="Define a new C++ function name";
  4843. opt[3]="Define a fortran function";
  4844. if(fortranFunctionList.size()>0)
  4845. {
  4846. opt[4]="Define a new C++ function instance";
  4847. opt[5]="Return to the main menu";
  4848. }
  4849. else
  4850. {
  4851. opt[4]="Return to the main menu";
  4852. }
  4853. stringstream ss;
  4854. ss << "What object do you want to define?";
  4855. if(fortranFunctionList.size()>0)
  4856. {
  4857. ss << " [";
  4858. fortranFunctionList.back().printDecl(ss);
  4859. ss << "]";
  4860. }
  4861. unsigned long ans;
  4862. if(basicMenu(ss.str().c_str(), opt, del, out, comm, ans, 0))
  4863. {
  4864. if(fortranFunctionList.size()==0 && ans==4)
  4865. ans=5;
  4866. switch(ans)
  4867. {
  4868. case 0:
  4869. out << "About to define a new C++ type" << endl;
  4870. try
  4871. {
  4872. if(createCPPType(comm,out))
  4873. comm.flushRecord();
  4874. else
  4875. comm.clearRecord();
  4876. }
  4877. catch(eMsg e)
  4878. {
  4879. comm.flushErrorToFile(out,"error.err");
  4880. throw e;
  4881. }
  4882. break;
  4883. case 1:
  4884. out << "About to define a new code map" << endl;
  4885. try
  4886. {
  4887. if(createTextMap(comm, out))
  4888. comm.flushRecord();
  4889. else
  4890. comm.clearRecord();
  4891. }
  4892. catch(eMsg e)
  4893. {
  4894. comm.flushErrorToFile(out,"error.err");
  4895. throw e;
  4896. }
  4897. break;
  4898. case 2:
  4899. out << "About to define a new C++ function name" << endl;
  4900. try
  4901. {
  4902. if(createCppFunctionName(comm,out))
  4903. comm.flushRecord();
  4904. else
  4905. comm.clearRecord();
  4906. }
  4907. catch(eMsg e)
  4908. {
  4909. comm.flushErrorToFile(out,"error.err");
  4910. throw e;
  4911. }
  4912. break;
  4913. case 3:
  4914. out << "About to read a new fortran function" << endl;
  4915. try
  4916. {
  4917. if(readFortranFunction(comm,out))
  4918. comm.flushRecord();
  4919. else
  4920. comm.clearRecord();
  4921. }
  4922. catch(eMsg e)
  4923. {
  4924. comm.flushErrorToFile(out,"error.err");
  4925. throw e;
  4926. }
  4927. break;
  4928. case 4:
  4929. out << "About to define a new instance of a C++ function" << endl;
  4930. try
  4931. {
  4932. if(createCppFunctionInstance(comm,out))
  4933. comm.flushRecord();
  4934. else
  4935. comm.clearRecord();
  4936. }
  4937. catch(eMsg e)
  4938. {
  4939. comm.flushErrorToFile(out,"error.err");
  4940. throw e;
  4941. }
  4942. break;
  4943. case 5:
  4944. out << "Returning to the main menu..." << endl;
  4945. canExit=true;
  4946. break;
  4947. }
  4948. }
  4949. else
  4950. {
  4951. canExit=true;
  4952. }
  4953. }
  4954. comm.exitRecord();
  4955. // while ( not exit )
  4956. // populate entries (with if statement to check if fortran file is loaded)
  4957. // wait for selection
  4958. // switch selection
  4959. // case define new type
  4960. // define new type
  4961. // break
  4962. // case define new map
  4963. // define new map
  4964. // break;
  4965. // case define new cpp function name
  4966. // cpp function name
  4967. // break;
  4968. // case select fortran function
  4969. // populate menue entries for fortran functions (from argument list)
  4970. // wait for selection
  4971. // set fortran function type
  4972. // add fortran type to the fortran code file
  4973. // note that there is no break here
  4974. // case retrieve C++ function instance
  4975. // retrieve C++ function instance
  4976. // add C++ function instance to both the definition and declaration C++ source files
  4977. // }
  4978. }
  4979. // MAIN
  4980. int mainMenu(commandSource& comm, ostream& out)
  4981. {
  4982. // while ( not exit )
  4983. bool exit=false;
  4984. while(!exit)
  4985. {
  4986. //
  4987. // populate menu entries
  4988. unsigned long ans;
  4989. vector<const char*> opt(8,NULL);
  4990. stringstream ss;
  4991. ss.str("");
  4992. ss << "Define FORTRAN prototype file [" << fortranSource.getFileName() << ']';
  4993. opt[0]=copyLine(ss.str().c_str());
  4994. if(opt[0]==NULL)
  4995. throw eMsg("mainMenu(): Failed to allocate memory");
  4996. ss.str("");
  4997. ss << "Define C++ prototype file [" << cppPrototype.getFileName() << ']';
  4998. opt[1]=copyLine(ss.str().c_str());
  4999. if(opt[1]==NULL)
  5000. throw eMsg("mainMenu(): Failed to allocate memory");
  5001. ss.str("");
  5002. ss << "Define C++ definition file [" << cppDefinition.getFileName() << ']';
  5003. opt[2]=copyLine(ss.str().c_str());
  5004. if(opt[2]==NULL)
  5005. throw eMsg("mainMenu(): Failed to allocate memory");
  5006. ss.str("");
  5007. ss << "Define command history file [" << recorder.getRecordFile() << ']';
  5008. if(recorder.getAppendState())
  5009. ss << " appending output";
  5010. else
  5011. ss << " writing new output";
  5012. opt[3]=copyLine(ss.str().c_str());
  5013. if(opt[3]==NULL)
  5014. throw eMsg("mainMenu(): Failed to allocate memory");
  5015. opt[4]="Run recorded commands";
  5016. opt[5]="Execute new commands";
  5017. opt[6]="Write Code";
  5018. opt[7]="Quit";
  5019. vector<bool> del(8,false);
  5020. del[0]=true;
  5021. del[1]=true;
  5022. del[2]=true;
  5023. del[3]=true;
  5024. if(basicMenu("Main Menu: What would you like to do?", opt, del, out, comm, ans, 0))
  5025. {
  5026. if(ans==7)
  5027. exit=true;
  5028. }
  5029. else
  5030. {
  5031. exit=true;
  5032. }
  5033. if(!exit)
  5034. {
  5035. const char* fn;
  5036. char ansYN;
  5037. bool appendFile;
  5038. fstream fin;
  5039. commandSource_file commFile(fin,&cout);
  5040. commandSource* commAuto;
  5041. bool switchAppState=false;
  5042. switch(ans)
  5043. {
  5044. case 0:
  5045. out << "Defining the FORTRAN prototype file..." << endl;
  5046. out << "Specify the output file: ";
  5047. out.flush();
  5048. fortranSource.setFileName(comm.getLine());
  5049. out << endl;
  5050. break;
  5051. case 1:
  5052. out << "Defining the C++ prototype file..." << endl;
  5053. out << "Specify the output file: ";
  5054. out.flush();
  5055. cppPrototype.setFileName(comm.getLine());
  5056. out << endl;
  5057. break;
  5058. case 2:
  5059. out << "Defining the C++ definition file..." << endl;
  5060. out << "Specify the output file: ";
  5061. out.flush();
  5062. cppDefinition.setFileName(comm.getLine());
  5063. out << endl;
  5064. break;
  5065. case 3:
  5066. out << "Defining the command history file" << endl;
  5067. out << "Specify the output file [" << recorder.getRecordFile() << "]: ";
  5068. out.flush();
  5069. fn=copyLine(comm.getLine());
  5070. out << "Do you want to overwrite the file y/n [n]: ";
  5071. out.flush();
  5072. ansYN=comm.getChar();
  5073. appendFile=true;
  5074. if(ansYN=='y' || ansYN=='Y')
  5075. appendFile=false;
  5076. if(fn[0]==0)
  5077. recorder.setAppendState(appendFile);
  5078. else
  5079. recorder.setRecordFile(fn,appendFile);
  5080. delete[] fn;
  5081. break;
  5082. case 4:
  5083. out << "Do you want to run the commands already recorded in " << recorder.getRecordFile() << "? [y]: ";
  5084. out.flush();
  5085. ansYN=comm.getChar();
  5086. commAuto=&commFile;
  5087. if(ansYN=='n' || ansYN=='N')
  5088. {
  5089. out << "Specify what command file: ";
  5090. out.flush();
  5091. fn=copyLine(comm.getLine());
  5092. if(!strEqual(fn,recorder.getRecordFile()))
  5093. {
  5094. out << "Do you want to append these recorded commands to the current command record? [n]: ";
  5095. out.flush();
  5096. ansYN=comm.getChar();
  5097. if(ansYN=='y' || ansYN=='Y')
  5098. {
  5099. commAuto=&recorder;
  5100. recorder.setCommandSource(&commFile);
  5101. }
  5102. }
  5103. }
  5104. else
  5105. {
  5106. fn=copyLine(recorder.getRecordFile());
  5107. switchAppState=true;
  5108. }
  5109. fin.open(fn,fstream::in);
  5110. delete[] fn;
  5111. if(!fin.is_open())
  5112. throw eMsg("mainMenu(): Failed to open file");
  5113. out << "running recorded input now..." << endl;
  5114. runCommands(*commAuto,out);
  5115. fin.close();
  5116. fin.clear();
  5117. if(switchAppState)
  5118. recorder.setAppendState(true);
  5119. out << endl << endl << "We have completed running the recorded commands" << endl;
  5120. break;
  5121. case 5:
  5122. recorder.setCommandSource(&comm);
  5123. out << "executing commands now..." << endl;
  5124. runCommands(recorder,out);
  5125. break;
  5126. case 6:
  5127. out << "Will write code now..." << endl;
  5128. fortranSource.writeFile(false);
  5129. if(strEqual(cppPrototype.getFileName(),fortranSource.getFileName()))
  5130. cppPrototype.writeFile(true);
  5131. else
  5132. cppPrototype.writeFile(false);
  5133. if(strEqual(cppDefinition.getFileName(),fortranSource.getFileName()) || strEqual(cppDefinition.getFileName(),cppPrototype.getFileName()))
  5134. cppDefinition.writeFile(true);
  5135. else
  5136. cppDefinition.writeFile(false);
  5137. break;
  5138. }
  5139. }
  5140. // wait for selection(terminal command sourc)
  5141. // switch selection
  5142. // case get file X
  5143. // get file X
  5144. // case exit
  5145. // set exit
  5146. // break
  5147. // case write code
  5148. // write code
  5149. // break
  5150. // case run recorded commands
  5151. // create new file based command source
  5152. // runCommands ( file command source )
  5153. // ask if new commands should be appended to this file
  5154. // break
  5155. // case run terminal commands
  5156. // runCommands ( terminal cammand source )
  5157. // break
  5158. }
  5159. return 0;
  5160. }
  5161. /*
  5162. RETRIEVE CPP FUNCTION NAME
  5163. populate menu with all the available cpp function names
  5164. // note that an option to define new type will always be present
  5165. wait for selection
  5166. switch selection
  5167. case define new cpp name
  5168. define new cpp name
  5169. return result
  5170. case old name
  5171. return the selection
  5172. RETRIEVE CPP TYPE
  5173. populate menu with all the available cpp types (with description)
  5174. // note and option to define a new type will always be present
  5175. if define a new type
  5176. define new cpp type
  5177. return result
  5178. else
  5179. {
  5180. with selection retrieve the cpp type
  5181. if template type
  5182. {
  5183. for each template argument
  5184. {
  5185. ask "is type?"
  5186. if yes
  5187. Retrieve CPP Type
  5188. else
  5189. command getLong
  5190. }
  5191. }
  5192. }
  5193. */
  5194. int main(int argc,char** argv)
  5195. {
  5196. if(argc<6)
  5197. {
  5198. cout << "laFortRead fortran_prototype c++_prototype c++_definition command_history input_1 input_2 ... input_n" << endl;
  5199. return 1;
  5200. }
  5201. fortranSource.setFileName(argv[1]);
  5202. cppPrototype.setFileName(argv[2]);
  5203. cppDefinition.setFileName(argv[3]);
  5204. // define some basic C++ types
  5205. cppType_basic* bTp;
  5206. bTp=new cppType_basic("void","This is nothing");
  5207. bTypes.addObj(bTp);
  5208. voidType=bTp;
  5209. bTp=new cppType_basic("bool","This is a boolean");
  5210. bTypes.addObj(bTp);
  5211. bTp=new cppType_basic("char","This is a simple character");
  5212. bTypes.addObj(bTp);
  5213. bTp=new cppType_basic("long","This is an integer");
  5214. bTypes.addObj(bTp);
  5215. bTp=new cppType_basic("float","This is a single precision float");
  5216. bTypes.addObj(bTp);
  5217. bTp=new cppType_basic("double","This is a double precision float");
  5218. bTypes.addObj(bTp);
  5219. bTp=new cppType_basic("complex<float>","This is the single precision complex number");
  5220. bTypes.addObj(bTp);
  5221. bTp=new cppType_basic("complex<double>","This is the double precision complex number");
  5222. bTypes.addObj(bTp);
  5223. // define the analogous fortran types
  5224. fortranType* fTp;
  5225. fTp=new fortranType(1);
  5226. fTp->setTypeSize(0,1).setText(0,0,"LOGICAL").setType(bTypes.getObj(1));
  5227. fTypes.addObj(fTp);
  5228. fTp=new fortranType(2);
  5229. fTp->setTypeSize(0,1).setText(0,0,"BYTE").setTypeSize(1,1).setText(1,0,"CHARACTER").setType(bTypes.getObj(2));
  5230. fTypes.addObj(fTp);
  5231. fTp=new fortranType(1);
  5232. fTp->setTypeSize(0,1).setText(0,0,"INTEGER").setType(bTypes.getObj(3));
  5233. fTypes.addObj(fTp);
  5234. fTp=new fortranType(1);
  5235. fTp->setTypeSize(0,1).setText(0,0,"REAL").setType(bTypes.getObj(4));
  5236. fTypes.addObj(fTp);
  5237. fTp=new fortranType(2);
  5238. fTp->setTypeSize(0,1).setText(0,0,"REAL*8").setTypeSize(1,2).setText(1,0,"DOUBLE").setText(1,1,"PRECISION").setType(bTypes.getObj(5));
  5239. fTypes.addObj(fTp);
  5240. fTp=new fortranType(1);
  5241. fTp->setTypeSize(0,1).setText(0,0,"COMPLEX").setType(bTypes.getObj(6));
  5242. fTypes.addObj(fTp);
  5243. fTp=new fortranType(2);
  5244. fTp->setTypeSize(0,1).setText(0,0,"COMPLEX*16").setTypeSize(1,2).setText(1,0,"DOUBLE").setText(1,1,"COMPLEX").setType(bTypes.getObj(7));
  5245. fTypes.addObj(fTp);
  5246. fortranSource.setFileName(argv[1]);
  5247. cppPrototype.setFileName(argv[2]);
  5248. cppDefinition.setFileName(argv[3]);
  5249. recorder.setRecordFile(argv[4],false);
  5250. fileArguments.resize(argc-5,NULL);
  5251. fileArgumentProcessed.resize(argc-5,NULL);
  5252. for(unsigned long i=0;i<fileArguments.size();i++)
  5253. {
  5254. fileArguments[i]=argv[i+5];
  5255. fileArgumentProcessed[i]=false;
  5256. }
  5257. commandSource_basic comm(cin);
  5258. return mainMenu(comm, cout);
  5259. /*
  5260. fstream pOut;
  5261. fstream dOut;
  5262. fstream cOut;
  5263. fstream fin;
  5264. // temporary variables for creating variables
  5265. cppType_template* tmpTType;
  5266. cppType_basic* tmpBType;
  5267. // read a fortran function
  5268. fortranFunction test(argv[1]);
  5269. // now lets make sure all the arguments are set
  5270. for(unsigned long i=0;i<test.argCount();i++)
  5271. {
  5272. if(test.getArgStat(i)==argUNKNOWN)
  5273. test.setArgStat(i,argOUTPUT);
  5274. }
  5275. cout << endl << "About to print the prototype for the fortran function" << endl;
  5276. test.printDecl(cout);
  5277. cout << ';' << endl;
  5278. // define a new template type
  5279. cppType_template* tTp;
  5280. tTp=new cppType_template(1);
  5281. if(tTp==NULL)
  5282. throw eMsg("main(): Failed to allocate memory");
  5283. tTp->setName("matrixRdWt_GenCol");
  5284. tTp->setDescription("General Matrix");
  5285. tTypes.addObj(tTp);
  5286. tTp=new cppType_template(1);
  5287. if(tTp==NULL)
  5288. throw eMsg("main(): Failed to allocate memory");
  5289. tTp->setName("matrixRdWtSqr_GenCol");
  5290. tTp->setDescription("General Square Matrix");
  5291. tTypes.addObj(tTp);
  5292. // define/select a function name
  5293. cppFunctionName* fncName;
  5294. fncName=new cppFunctionName("solveMatrix");
  5295. cppFuncs.addObj(fncName);
  5296. // create instance
  5297. cppFunctionInstance* fnc=fncName->createFunctionInstance();
  5298. // retrieve the types
  5299. tmpBType=bTypes.getObj(5);
  5300. tmpTType=tTypes.getObj(0);
  5301. cppType_template* bMtxType;
  5302. bMtxType=new cppType_template(*tmpTType);
  5303. bMtxType->setArgType(0,tmpBType,false);
  5304. tmpTType=tTypes.getObj(1);
  5305. cppType_template* aMtxType;
  5306. aMtxType=new cppType_template(*tmpTType);
  5307. aMtxType->setArgType(0,tmpBType,false);
  5308. // add the arguments
  5309. fnc->setArgumentCount(3);
  5310. variable* varA=new variable(aMtxType,"A",0,true,true);
  5311. variable* varB=new variable(bMtxType,"B",0,true,true);
  5312. tmpBType=bTypes.getObj(3);
  5313. variable* varPivot=new variable(tmpBType,"pivot",1,true);
  5314. fnc->defineReturn(tmpBType);
  5315. fnc->addArgument(0,varA,"The A Matrix", true);
  5316. fnc->addArgument(1,varB,"The B Matrix", true);
  5317. fnc->addArgument(2,varPivot,"The pivot array", true);
  5318. // print the C++ declaration
  5319. cout << endl << "About to print the prototype for the cpp function instance" << endl;
  5320. fnc->printDecl(cout);
  5321. // =====================
  5322. // this section is devoted to writing code
  5323. // =====================
  5324. mapText* tmpMpTxt;
  5325. nameMap_text* tmpNameMap;
  5326. // create the simple variable declaration statement
  5327. tmpMpTxt=new mapText("\t@(t0) @(o0)=@(c0);");
  5328. if(tmpMpTxt==NULL)
  5329. throw eMsg("main(): Failed to allocate memory");
  5330. tmpMpTxt->setDescription("Declares a new variable with an initialized value");
  5331. tmpMpTxt->setOutputDescription(0,"The variable name");
  5332. tmpMpTxt->setTypeDescription(0,"The variable type");
  5333. tmpMpTxt->setCustomDescription(0,"The initialized value");
  5334. textMaps.addObj(tmpMpTxt);
  5335. // add the variable declaration to the code
  5336. tmpNameMap=new nameMap_text(*tmpMpTxt);
  5337. if(tmpNameMap==NULL)
  5338. throw eMsg("main(): Failed to allocate memory");
  5339. tmpNameMap->setOutName(0,"info");
  5340. tmpNameMap->setCustName(0,"0");
  5341. tmpNameMap->setCppType(0,new cppType_basic(*(bTypes.getObj(3))),true);
  5342. fnc->addMap(tmpNameMap,false,true);
  5343. // create the matrix info extraction statements
  5344. tmpMpTxt=new mapText("\tunsigned long @(o1), @(o2);\n\t@(o0)=@(i0).array();\n\t@(i0).size(@(o1),@(o2));\n\t@(o3)=@(i0).leadDim();");
  5345. if(tmpMpTxt==NULL)
  5346. throw eMsg("main(): Failed to allocate memory");
  5347. tmpMpTxt->setDescription("Extracts all the information from a matrix to make a call to LAPACK");
  5348. tmpMpTxt->setInputDescription(0,"The matrix that will be used in a future LAPACK call");
  5349. tmpMpTxt->setOutputDescription(0, "The matrix array");
  5350. tmpMpTxt->setOutputDescription(1, "Number of rows in the matrix");
  5351. tmpMpTxt->setOutputDescription(2, "Number of columns in the matrix");
  5352. tmpMpTxt->setOutputDescription(3, "The leading dimension in the matrix");
  5353. textMaps.addObj(tmpMpTxt);
  5354. // add the array extraction for the A matrix
  5355. tmpNameMap=new nameMap_text(*tmpMpTxt);
  5356. if(tmpNameMap==NULL)
  5357. throw eMsg("main(): Failed to allocate memory");
  5358. tmpNameMap->setOutName(0,"arrayA");
  5359. tmpNameMap->setOutName(1,"rowsA");
  5360. tmpNameMap->setOutName(2,"colsA");
  5361. tmpNameMap->setOutName(3,"ldA");
  5362. fnc->addMap(tmpNameMap,false,true);
  5363. // set the argument to this segments input
  5364. fnc->getSink()->setSource(0,fnc->getSource(0),0);
  5365. // the the array extraction for the B matrix
  5366. tmpNameMap=new nameMap_text(*tmpMpTxt);
  5367. if(tmpNameMap==NULL)
  5368. throw eMsg("main(): Failed to allocate memory");
  5369. tmpNameMap->setOutName(0,"arrayB");
  5370. tmpNameMap->setOutName(1,"rowsB");
  5371. tmpNameMap->setOutName(2,"colsB");
  5372. tmpNameMap->setOutName(3,"ldB");
  5373. fnc->addMap(tmpNameMap,false,true);
  5374. // link the function argument to this statement
  5375. fnc->getSink()->setSource(0,fnc->getSource(0),1);
  5376. // add the fortran function call to the code
  5377. callingCode* clCd=new callingCode(&test);
  5378. if(clCd==NULL)
  5379. throw eMsg("main(): failed to allocate memory");
  5380. fnc->addCall(clCd,false,true);
  5381. // link all the inputs to the arguments
  5382. fnc->getSink()->setSource(0,fnc->getSource(2),1); // N
  5383. fnc->getSink()->setSource(1,fnc->getSource(3),2); // NRHS
  5384. fnc->getSink()->setSource(2,fnc->getSource(2),0); // A
  5385. fnc->getSink()->setSource(3,fnc->getSource(2),3); // LDA
  5386. fnc->getSink()->setSource(4,fnc->getSource(0),2); // IPIV
  5387. fnc->getSink()->setSource(5,fnc->getSource(3),0); // B
  5388. fnc->getSink()->setSource(6,fnc->getSource(3),3); // LDB
  5389. fnc->getSink()->setSource(7,fnc->getSource(1),0); // INFO
  5390. // create and add the return sink
  5391. returnSink* retSnk;
  5392. retSnk=new returnSink();
  5393. if(retSnk==NULL)
  5394. throw eMsg("main(): failed to allocate memory");
  5395. fnc->addMap(retSnk,true,true);
  5396. fnc->getSink()->setSource(0,fnc->getSource(1),0);
  5397. cout << endl;
  5398. cout << "About to write the cpp function definition" << endl;
  5399. fnc->writeDefinition(cout);
  5400. cout << endl;
  5401. commandSource_basic comm(cin);
  5402. vector<const char*> opts(15,"option");
  5403. opts[0]="option 0";
  5404. opts[1]="option 1";
  5405. opts[2]="option 2";
  5406. opts[3]="option 3";
  5407. opts[4]="option 4";
  5408. opts[5]="option 5";
  5409. opts[6]="option 6";
  5410. opts[7]="option 7";
  5411. opts[8]="option 8";
  5412. opts[9]="option 9";
  5413. opts[10]="option 10";
  5414. opts[11]="option 11";
  5415. opts[12]="option 12";
  5416. opts[13]="option 13";
  5417. opts[14]="option 14";
  5418. vector<bool> del(15,false);
  5419. unsigned long ans;
  5420. if(basicMenu("Pick and option", opts, del, cout, comm, ans, 7))
  5421. cout << "You selected " << ans << endl;
  5422. else
  5423. cout << "You exited" << endl;
  5424. return mainMenu(comm, cout);
  5425. */
  5426. // delete data
  5427. // delete bMtxType;
  5428. // delete aMtxType;
  5429. // delete varA;
  5430. // delete varB;
  5431. // delete varPivot;
  5432. // open the prototype file
  5433. // pOut.open(argv[1],fstream::out);
  5434. // if(!pOut.is_open())
  5435. // throw eMsg("Failed to open the prototype");
  5436. //
  5437. // // open the derived file
  5438. // dOut.open(argv[2],fstream::out);
  5439. // if(!dOut.is_open())
  5440. // {
  5441. // pOut.close();
  5442. // throw eMsg("Failed to open the derived");
  5443. // }
  5444. //
  5445. // // test to see if there are some existing commands
  5446. // {
  5447. // stat sb;
  5448. // if(stat(argv[3],&sb)==0)
  5449. // {
  5450. // cOut.open(argv[3],fstream::in);
  5451. // if(!dOut.is_open())
  5452. // {
  5453. // pOut.close();
  5454. // throw eMsg("Failed to open the derived");
  5455. // }
  5456. //
  5457. // }
  5458. // }
  5459. return 0;
  5460. }