cmCommandArgumentParserHelper.cxx 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  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 "cmCommandArgumentParserHelper.h"
  14. #include "cmSystemTools.h"
  15. #include "cmCommandArgumentLexer.h"
  16. #include "cmMakefile.h"
  17. int cmCommandArgument_yyparse( yyscan_t yyscanner );
  18. cmCommandArgumentParserHelper::cmCommandArgumentParserHelper()
  19. {
  20. m_FileLine = -1;
  21. m_FileName = 0;
  22. m_EmptyVariable[0] = 0;
  23. strcpy(m_DCURLYVariable, "${");
  24. strcpy(m_RCURLYVariable, "}");
  25. strcpy(m_ATVariable, "@");
  26. strcpy(m_DOLLARVariable, "$");
  27. strcpy(m_LCURLYVariable, "{");
  28. strcpy(m_BSLASHVariable, "\\");
  29. }
  30. cmCommandArgumentParserHelper::~cmCommandArgumentParserHelper()
  31. {
  32. this->CleanupParser();
  33. }
  34. void cmCommandArgumentParserHelper::SetLineFile(long line, const char* file)
  35. {
  36. m_FileLine = line;
  37. m_FileName = file;
  38. }
  39. char* cmCommandArgumentParserHelper::AddString(const char* str)
  40. {
  41. if ( !str || !*str )
  42. {
  43. return m_EmptyVariable;
  44. }
  45. char* stVal = new char[strlen(str)+1];
  46. strcpy(stVal, str);
  47. return *(m_Variables.insert(stVal).first);
  48. }
  49. char* cmCommandArgumentParserHelper::ExpandSpecialVariable(const char* key, const char* var)
  50. {
  51. if ( !key )
  52. {
  53. return this->ExpandVariable(var);
  54. }
  55. if ( strcmp(key, "ENV") == 0 )
  56. {
  57. char *ptr = getenv(var);
  58. if (ptr)
  59. {
  60. if (m_EscapeQuotes)
  61. {
  62. return this->AddString(cmSystemTools::EscapeQuotes(ptr).c_str());
  63. }
  64. else
  65. {
  66. return ptr;
  67. }
  68. }
  69. return m_EmptyVariable;
  70. }
  71. cmSystemTools::Error("Key ", key, " is not used yet. For now only $ENV{..} is allowed");
  72. return 0;
  73. }
  74. char* cmCommandArgumentParserHelper::ExpandVariable(const char* var)
  75. {
  76. if(m_FileName && strcmp(var, "CMAKE_CURRENT_LIST_FILE") == 0)
  77. {
  78. return this->AddString(m_FileName);
  79. }
  80. else if(m_FileLine >= 0 && strcmp(var, "CMAKE_CURRENT_LIST_LINE") == 0)
  81. {
  82. cmOStringStream ostr;
  83. ostr << m_FileLine;
  84. return this->AddString(ostr.str().c_str());
  85. }
  86. const char* value = m_Makefile->GetDefinition(var);
  87. if (m_EscapeQuotes)
  88. {
  89. return this->AddString(cmSystemTools::EscapeQuotes(value).c_str());
  90. }
  91. return this->AddString(value);
  92. }
  93. void cmCommandArgumentParserHelper::DeallocateParserType(char** pt)
  94. {
  95. if (!pt)
  96. {
  97. return;
  98. }
  99. if (!*pt)
  100. {
  101. //*pt = 0;
  102. return;
  103. }
  104. // std::cout << (void*) *pt << " " << *pt << " this->DeallocateParserType" << std::endl;
  105. //delete [] *pt;
  106. *pt = 0;
  107. this->UnionsAvailable --;
  108. }
  109. void cmCommandArgumentParserHelper::SafePrintMissing(const char* str, int line, int cnt)
  110. {
  111. if ( this->Verbose )
  112. {
  113. if ( str )
  114. {
  115. //std::cout << (void*) str << " JPSafePrintMissing" << std::endl;
  116. std::cout << line << " String " << cnt << " exists: ";
  117. unsigned int cc;
  118. for ( cc = 0; cc < strlen(str); cc ++ )
  119. {
  120. unsigned char ch = str[cc];
  121. if ( ch >= 32 && ch <= 126 )
  122. {
  123. std::cout << (char)ch;
  124. }
  125. else
  126. {
  127. std::cout << "<" << (int)ch << ">";
  128. break;
  129. }
  130. }
  131. std::cout << "- " << strlen(str) << std::endl;
  132. }
  133. }
  134. }
  135. void cmCommandArgumentParserHelper::Print(const char* place, const char* str)
  136. {
  137. if ( this->Verbose )
  138. {
  139. std::cout << "[" << place << "=" << str << "]" << std::endl;
  140. }
  141. }
  142. char* cmCommandArgumentParserHelper::CombineUnions(char* in1, char* in2)
  143. {
  144. if ( !in1 )
  145. {
  146. return in2;
  147. }
  148. else if ( !in2 )
  149. {
  150. return in1;
  151. }
  152. int len = strlen(in1) + strlen(in2) + 1;
  153. char* out = new char [ len ];
  154. strcpy(out, in1);
  155. strcat(out, in2);
  156. return *(m_Variables.insert(out).first);
  157. }
  158. void cmCommandArgumentParserHelper::CheckEmpty(int line, int cnt, cmCommandArgumentParserHelper::ParserType* pt)
  159. {
  160. int cc;
  161. int kk = -cnt + 1;
  162. for ( cc = 1; cc <= cnt; cc ++)
  163. {
  164. cmCommandArgumentParserHelper::ParserType* cpt = pt + kk;
  165. this->SafePrintMissing(cpt->str, line, cc);
  166. kk ++;
  167. }
  168. }
  169. void cmCommandArgumentParserHelper::PrepareElement(cmCommandArgumentParserHelper::ParserType* me)
  170. {
  171. // Inititalize self
  172. me->str = 0;
  173. }
  174. void cmCommandArgumentParserHelper::AllocateParserType(cmCommandArgumentParserHelper::ParserType* pt,
  175. const char* str, int len)
  176. {
  177. pt->str = 0;
  178. if ( len == 0 )
  179. {
  180. len = strlen(str);
  181. }
  182. if ( len == 0 )
  183. {
  184. return;
  185. }
  186. this->UnionsAvailable ++;
  187. pt->str = new char[ len + 1 ];
  188. strncpy(pt->str, str, len);
  189. pt->str[len] = 0;
  190. this->Allocates.push_back(pt->str);
  191. // std::cout << (void*) pt->str << " " << pt->str << " JPAllocateParserType" << std::endl;
  192. }
  193. int cmCommandArgumentParserHelper::ParseString(const char* str, int verb)
  194. {
  195. if ( !str)
  196. {
  197. return 0;
  198. }
  199. //printf("Do some parsing: %s\n", str);
  200. this->Verbose = verb;
  201. this->InputBuffer = str;
  202. this->InputBufferPos = 0;
  203. this->CurrentLine = 0;
  204. m_Result = "";
  205. yyscan_t yyscanner;
  206. cmCommandArgument_yylex_init(&yyscanner);
  207. cmCommandArgument_yyset_extra(this, yyscanner);
  208. int res = cmCommandArgument_yyparse(yyscanner);
  209. cmCommandArgument_yylex_destroy(yyscanner);
  210. if ( res != 0 )
  211. {
  212. //str << "CAL_Parser returned: " << res << std::endl;
  213. //std::cerr << "When parsing: [" << str << "]" << std::endl;
  214. return 0;
  215. }
  216. this->CleanupParser();
  217. if ( Verbose )
  218. {
  219. std::cerr << "Expanding [" << str << "] produced: [" << m_Result.c_str() << "]" << std::endl;
  220. }
  221. return 1;
  222. }
  223. void cmCommandArgumentParserHelper::CleanupParser()
  224. {
  225. std::vector<char*>::iterator it;
  226. for ( it = this->Allocates.begin();
  227. it != this->Allocates.end();
  228. ++ it )
  229. {
  230. delete [] *it;
  231. }
  232. std::set<char*>::iterator sit;
  233. for ( sit = m_Variables.begin();
  234. sit != m_Variables.end();
  235. ++ sit )
  236. {
  237. delete [] *sit;
  238. }
  239. this->Allocates.erase(this->Allocates.begin(),
  240. this->Allocates.end());
  241. m_Variables.erase(m_Variables.begin(), m_Variables.end());
  242. }
  243. int cmCommandArgumentParserHelper::LexInput(char* buf, int maxlen)
  244. {
  245. //std::cout << "JPLexInput ";
  246. //std::cout.write(buf, maxlen);
  247. //std::cout << std::endl;
  248. if ( maxlen < 1 )
  249. {
  250. return 0;
  251. }
  252. if ( this->InputBufferPos < this->InputBuffer.size() )
  253. {
  254. buf[0] = this->InputBuffer[ this->InputBufferPos++ ];
  255. if ( buf[0] == '\n' )
  256. {
  257. this->CurrentLine ++;
  258. }
  259. return(1);
  260. }
  261. else
  262. {
  263. buf[0] = '\n';
  264. return( 0 );
  265. }
  266. }
  267. void cmCommandArgumentParserHelper::Error(const char* str)
  268. {
  269. unsigned long pos = static_cast<unsigned long>(this->InputBufferPos);
  270. //fprintf(stderr, "Argument Parser Error: %s (%lu / Line: %d)\n", str, pos, this->CurrentLine);
  271. cmOStringStream ostr;
  272. ostr << str << " (" << pos << ")";
  273. /*
  274. int cc;
  275. std::cerr << "String: [";
  276. for ( cc = 0; cc < 30 && *(this->InputBuffer.c_str() + this->InputBufferPos + cc);
  277. cc ++ )
  278. {
  279. std::cerr << *(this->InputBuffer.c_str() + this->InputBufferPos + cc);
  280. }
  281. std::cerr << "]" << std::endl;
  282. */
  283. m_Error = ostr.str();
  284. }
  285. void cmCommandArgumentParserHelper::UpdateCombine(const char* str1, const char* str2)
  286. {
  287. if ( this->CurrentCombine == "" && str1 != 0)
  288. {
  289. this->CurrentCombine = str1;
  290. }
  291. this->CurrentCombine += ".";
  292. this->CurrentCombine += str2;
  293. }
  294. int cmCommandArgumentParserHelper::ParseFile(const char* file)
  295. {
  296. if ( !cmSystemTools::FileExists(file))
  297. {
  298. return 0;
  299. }
  300. std::ifstream ifs(file);
  301. if ( !ifs )
  302. {
  303. return 0;
  304. }
  305. cmStdString fullfile = "";
  306. cmStdString line;
  307. while ( cmSystemTools::GetLineFromStream(ifs, line) )
  308. {
  309. fullfile += line + "\n";
  310. }
  311. return this->ParseString(fullfile.c_str(), 0);
  312. }
  313. void cmCommandArgumentParserHelper::Append(const char* str)
  314. {
  315. std::cout << "Append[" << str << "]" << std::endl;
  316. }
  317. void cmCommandArgumentParserHelper::SetMakefile(const cmMakefile* mf)
  318. {
  319. m_Makefile = mf;
  320. }
  321. void cmCommandArgumentParserHelper::SetResult(const char* value)
  322. {
  323. if ( !value )
  324. {
  325. m_Result = "";
  326. return;
  327. }
  328. m_Result = value;
  329. }