PageRenderTime 74ms CodeModel.GetById 5ms RepoModel.GetById 0ms app.codeStats 1ms

/structural/supporting_matl_misc_and_old/support/fortranPrototypeGenerator/fullReader/laFortRead.cpp

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