cmDependsJavaParserHelper.cxx 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. /*=========================================================================
  2. Program: CMake - Cross-Platform Makefile Generator
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
  8. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
  9. This software is distributed WITHOUT ANY WARRANTY; without even
  10. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  11. PURPOSE. See the above copyright notices for more information.
  12. =========================================================================*/
  13. #include "cmDependsJavaParserHelper.h"
  14. #include "cmSystemTools.h"
  15. #include "cmDependsJavaLexer.h"
  16. int cmDependsJava_yyparse( yyscan_t yyscanner );
  17. cmDependsJavaParserHelper::cmDependsJavaParserHelper()
  18. {
  19. this->CurrentDepth = 0;
  20. this->UnionsAvailable = 0;
  21. this->LastClassId = 0;
  22. CurrentClass tl;
  23. tl.Name = "*";
  24. this->ClassStack.push_back(tl);
  25. }
  26. cmDependsJavaParserHelper::~cmDependsJavaParserHelper()
  27. {
  28. this->CleanupParser();
  29. }
  30. void cmDependsJavaParserHelper::CurrentClass::AddFileNamesForPrinting(std::vector<cmStdString> *files, const char* prefix, const char* sep)
  31. {
  32. cmStdString rname = "";
  33. if ( prefix )
  34. {
  35. rname += prefix;
  36. rname += sep;
  37. }
  38. rname += this->Name;
  39. files->push_back(rname);
  40. std::vector<CurrentClass>::iterator it;
  41. for ( it = this->NestedClasses.begin();
  42. it != this->NestedClasses.end();
  43. ++ it )
  44. {
  45. it->AddFileNamesForPrinting(files, rname.c_str(), sep);
  46. }
  47. }
  48. void cmDependsJavaParserHelper::DeallocateParserType(char** pt)
  49. {
  50. if (!pt)
  51. {
  52. return;
  53. }
  54. if (!*pt)
  55. {
  56. //*pt = 0;
  57. return;
  58. }
  59. // std::cout << (void*) *pt << " " << *pt << " this->DeallocateParserType" << std::endl;
  60. //delete [] *pt;
  61. *pt = 0;
  62. this->UnionsAvailable --;
  63. }
  64. void cmDependsJavaParserHelper::AddClassFound(const char* sclass)
  65. {
  66. if( ! sclass )
  67. {
  68. return;
  69. }
  70. std::vector<cmStdString>::iterator it;
  71. for ( it = this->ClassesFound.begin();
  72. it != this->ClassesFound.end();
  73. it ++ )
  74. {
  75. if ( *it == sclass )
  76. {
  77. return;
  78. }
  79. }
  80. this->ClassesFound.push_back(sclass);
  81. }
  82. void cmDependsJavaParserHelper::AddPackagesImport(const char* sclass)
  83. {
  84. std::vector<cmStdString>::iterator it;
  85. for ( it = this->PackagesImport.begin();
  86. it != this->PackagesImport.end();
  87. it ++ )
  88. {
  89. if ( *it == sclass )
  90. {
  91. return;
  92. }
  93. }
  94. this->PackagesImport.push_back(sclass);
  95. }
  96. void cmDependsJavaParserHelper::SafePrintMissing(const char* str, int line, int cnt)
  97. {
  98. if ( str )
  99. {
  100. //std::cout << (void*) str << " JPSafePrintMissing" << std::endl;
  101. std::cout << line << " String " << cnt << " exists: ";
  102. unsigned int cc;
  103. for ( cc = 0; cc < strlen(str); cc ++ )
  104. {
  105. unsigned char ch = str[cc];
  106. if ( ch >= 32 && ch <= 126 )
  107. {
  108. std::cout << (char)ch;
  109. }
  110. else
  111. {
  112. std::cout << "<" << (int)ch << ">";
  113. break;
  114. }
  115. }
  116. std::cout << "- " << strlen(str) << std::endl;
  117. }
  118. }
  119. void cmDependsJavaParserHelper::Print(const char* place, const char* str)
  120. {
  121. if ( this->Verbose )
  122. {
  123. std::cout << "[" << place << "=" << str << "]" << std::endl;
  124. }
  125. }
  126. void cmDependsJavaParserHelper::CombineUnions(char** out, const char* in1, char** in2,
  127. const char* sep)
  128. {
  129. int len = 1;
  130. if ( in1 )
  131. {
  132. len += strlen(in1);
  133. }
  134. if ( *in2 )
  135. {
  136. len += strlen(*in2);
  137. }
  138. if ( sep )
  139. {
  140. len += strlen(sep);
  141. }
  142. *out = new char [ len ];
  143. *out[0] = 0;
  144. if ( in1 )
  145. {
  146. strcat(*out, in1);
  147. }
  148. if ( sep )
  149. {
  150. strcat(*out, sep);
  151. }
  152. if ( *in2 )
  153. {
  154. strcat(*out, *in2);
  155. }
  156. if ( *in2 )
  157. {
  158. this->DeallocateParserType(in2);
  159. }
  160. // std::cout << (void*) *out << " " << *out << " JPAllocateParserType" << std::endl;
  161. this->UnionsAvailable ++;
  162. }
  163. void cmDependsJavaParserHelper::CheckEmpty(int line, int cnt, cmDependsJavaParserHelper::ParserType* pt)
  164. {
  165. int cc;
  166. int kk = -cnt + 1;
  167. for ( cc = 1; cc <= cnt; cc ++)
  168. {
  169. cmDependsJavaParserHelper::ParserType* cpt = pt + kk;
  170. this->SafePrintMissing(cpt->str, line, cc);
  171. kk ++;
  172. }
  173. }
  174. void cmDependsJavaParserHelper::PrepareElement(cmDependsJavaParserHelper::ParserType* me)
  175. {
  176. // Inititalize self
  177. me->str = 0;
  178. }
  179. void cmDependsJavaParserHelper::AllocateParserType(cmDependsJavaParserHelper::ParserType* pt,
  180. const char* str, int len = 0)
  181. {
  182. pt->str = 0;
  183. if ( len == 0 )
  184. {
  185. len = strlen(str);
  186. }
  187. if ( len == 0 )
  188. {
  189. return;
  190. }
  191. this->UnionsAvailable ++;
  192. pt->str = new char[ len + 1 ];
  193. strncpy(pt->str, str, len);
  194. pt->str[len] = 0;
  195. this->Allocates.push_back(pt->str);
  196. // std::cout << (void*) pt->str << " " << pt->str << " JPAllocateParserType" << std::endl;
  197. }
  198. void cmDependsJavaParserHelper::StartClass(const char* cls)
  199. {
  200. CurrentClass cl;
  201. cl.Name = cls;
  202. this->ClassStack.push_back(cl);
  203. this->CurrentDepth ++;
  204. }
  205. void cmDependsJavaParserHelper::EndClass()
  206. {
  207. CurrentClass* parent = 0;
  208. CurrentClass* current = 0;
  209. if ( this->ClassStack.size() > 0 )
  210. {
  211. current = &(*(this->ClassStack.end() - 1));
  212. if ( this->ClassStack.size() > 1 )
  213. {
  214. parent = &(*(this->ClassStack.end() - 2));
  215. }
  216. }
  217. if ( current == 0 )
  218. {
  219. std::cerr << "Error when parsing. Current class is null" << std::endl;
  220. abort();
  221. }
  222. if ( parent == 0 )
  223. {
  224. std::cerr << "Error when parsing. Parent class is null" << std::endl;
  225. abort();
  226. }
  227. this->CurrentDepth --;
  228. parent->NestedClasses.push_back(*current);
  229. this->ClassStack.erase(this->ClassStack.end()-1, this->ClassStack.end());
  230. }
  231. void cmDependsJavaParserHelper::PrintClasses()
  232. {
  233. if ( this->ClassStack.size() == 0 )
  234. {
  235. std::cerr << "Error when parsing. No classes on class stack" << std::endl;
  236. abort();
  237. }
  238. std::vector<cmStdString> files = this->GetFilesProduced();
  239. std::vector<cmStdString>::iterator sit;
  240. for ( sit = files.begin();
  241. sit != files.end();
  242. ++ sit )
  243. {
  244. std::cout << " " << sit->c_str() << ".class" << std::endl;
  245. }
  246. }
  247. std::vector<cmStdString> cmDependsJavaParserHelper::GetFilesProduced()
  248. {
  249. std::vector<cmStdString> files;
  250. CurrentClass* toplevel = &(*(this->ClassStack.begin()));
  251. std::vector<CurrentClass>::iterator it;
  252. for ( it = toplevel->NestedClasses.begin();
  253. it != toplevel->NestedClasses.end();
  254. ++ it )
  255. {
  256. it->AddFileNamesForPrinting(&files, 0, "$");
  257. }
  258. return files;
  259. }
  260. int cmDependsJavaParserHelper::ParseString(const char* str, int verb)
  261. {
  262. if ( !str)
  263. {
  264. return 0;
  265. }
  266. //printf("Do some parsing: %s\n", str);
  267. this->Verbose = verb;
  268. this->InputBuffer = str;
  269. this->InputBufferPos = 0;
  270. this->CurrentLine = 0;
  271. yyscan_t yyscanner;
  272. cmDependsJava_yylex_init(&yyscanner);
  273. cmDependsJava_yyset_extra(this, yyscanner);
  274. int res = cmDependsJava_yyparse(yyscanner);
  275. cmDependsJava_yylex_destroy(yyscanner);
  276. if ( res != 0 )
  277. {
  278. std::cout << "JP_Parse returned: " << res << std::endl;
  279. return 0;
  280. }
  281. if ( verb )
  282. {
  283. if ( this->CurrentPackage.size() > 0 )
  284. {
  285. std::cout << "Current package is: " << this->CurrentPackage.c_str() << std::endl;
  286. }
  287. std::cout << "Imports packages:";
  288. if ( this->PackagesImport.size() > 0 )
  289. {
  290. std::vector<cmStdString>::iterator it;
  291. for ( it = this->PackagesImport.begin();
  292. it != this->PackagesImport.end();
  293. ++ it )
  294. {
  295. std::cout << " " << it->c_str();
  296. }
  297. }
  298. std::cout << std::endl;
  299. std::cout << "Depends on:";
  300. if ( this->ClassesFound.size() > 0 )
  301. {
  302. std::vector<cmStdString>::iterator it;
  303. for ( it = this->ClassesFound.begin();
  304. it != this->ClassesFound.end();
  305. ++ it )
  306. {
  307. std::cout << " " << it->c_str();
  308. }
  309. }
  310. std::cout << std::endl;
  311. std::cout << "Generated files:" << std::endl;
  312. this->PrintClasses();
  313. if ( this->UnionsAvailable != 0 )
  314. {
  315. std::cout << "There are still " << this->UnionsAvailable << " unions available" << std::endl;
  316. //return 0;
  317. }
  318. }
  319. this->CleanupParser();
  320. return 1;
  321. }
  322. void cmDependsJavaParserHelper::CleanupParser()
  323. {
  324. std::vector<char*>::iterator it;
  325. for ( it = this->Allocates.begin();
  326. it != this->Allocates.end();
  327. ++ it )
  328. {
  329. delete [] *it;
  330. }
  331. this->Allocates.erase(this->Allocates.begin(),
  332. this->Allocates.end());
  333. }
  334. int cmDependsJavaParserHelper::LexInput(char* buf, int maxlen)
  335. {
  336. //std::cout << "JPLexInput ";
  337. //std::cout.write(buf, maxlen);
  338. //std::cout << std::endl;
  339. if ( maxlen < 1 )
  340. {
  341. return 0;
  342. }
  343. if ( this->InputBufferPos < this->InputBuffer.size() )
  344. {
  345. buf[0] = this->InputBuffer[ this->InputBufferPos++ ];
  346. if ( buf[0] == '\n' )
  347. {
  348. this->CurrentLine ++;
  349. }
  350. return(1);
  351. }
  352. else
  353. {
  354. buf[0] = '\n';
  355. return( 0 );
  356. }
  357. }
  358. void cmDependsJavaParserHelper::Error(const char* str)
  359. {
  360. fprintf(stderr, "JPError: %s (%d / Line: %d)\n", str, this->InputBufferPos, this->CurrentLine);
  361. int cc;
  362. std::cerr << "String: [";
  363. for ( cc = 0; cc < 30 && *(this->InputBuffer.c_str() + this->InputBufferPos + cc);
  364. cc ++ )
  365. {
  366. std::cerr << *(this->InputBuffer.c_str() + this->InputBufferPos + cc);
  367. }
  368. std::cerr << "]" << std::endl;
  369. }
  370. void cmDependsJavaParserHelper::UpdateCombine(const char* str1, const char* str2)
  371. {
  372. if ( this->CurrentCombine == "" && str1 != 0)
  373. {
  374. this->CurrentCombine = str1;
  375. }
  376. this->CurrentCombine += ".";
  377. this->CurrentCombine += str2;
  378. }
  379. int cmDependsJavaParserHelper::ParseFile(const char* file)
  380. {
  381. if ( !cmSystemTools::FileExists(file))
  382. {
  383. return 0;
  384. }
  385. std::ifstream ifs(file);
  386. if ( !ifs )
  387. {
  388. return 0;
  389. }
  390. cmStdString fullfile = "";
  391. cmStdString line;
  392. while ( cmSystemTools::GetLineFromStream(ifs, line) )
  393. {
  394. fullfile += line + "\n";
  395. }
  396. return this->ParseString(fullfile.c_str(), 0);
  397. }