ppCommandFile.cxx 57 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841
  1. // Filename: ppCommandFile.cxx
  2. // Created by: drose (25Sep00)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. #include "ppCommandFile.h"
  6. #include "ppScope.h"
  7. #include "ppNamedScopes.h"
  8. #include "ppSubroutine.h"
  9. #include "tokenize.h"
  10. #ifdef HAVE_UNISTD_H
  11. #include <unistd.h>
  12. #endif
  13. #ifdef HAVE_UTIME_H
  14. #include <utime.h>
  15. #endif
  16. #ifdef HAVE_SYS_UTIME_H
  17. #include <sys/utime.h>
  18. #endif
  19. #include <ctype.h>
  20. #include <stdio.h> // for tempnam()
  21. #include <sys/types.h>
  22. #include <assert.h>
  23. static const string begin_comment(BEGIN_COMMENT);
  24. ////////////////////////////////////////////////////////////////////
  25. // Function: PPCommandFile::IfNesting::Constructor
  26. // Access: Public
  27. // Description:
  28. ////////////////////////////////////////////////////////////////////
  29. PPCommandFile::IfNesting::
  30. IfNesting(IfState state) :
  31. _state(state)
  32. {
  33. _block = (PPCommandFile::BlockNesting *)NULL;
  34. _next = (PPCommandFile::IfNesting *)NULL;
  35. }
  36. ////////////////////////////////////////////////////////////////////
  37. // Function: PPCommandFile::IfNesting::push
  38. // Access: Public
  39. // Description: Adds this IfNesting object to the top of the
  40. // nesting stack.
  41. ////////////////////////////////////////////////////////////////////
  42. void PPCommandFile::IfNesting::
  43. push(PPCommandFile *file) {
  44. _block = file->_block_nesting;
  45. _next = file->_if_nesting;
  46. file->_if_nesting = this;
  47. }
  48. ////////////////////////////////////////////////////////////////////
  49. // Function: PPCommandFile::IfNesting::pop
  50. // Access: Public
  51. // Description: Removes this IfNesting object from the top of the
  52. // nesting stack, and restores the command file's
  53. // nesting state.
  54. ////////////////////////////////////////////////////////////////////
  55. void PPCommandFile::IfNesting::
  56. pop(PPCommandFile *file) {
  57. assert(file->_if_nesting == this);
  58. file->_if_nesting = _next;
  59. }
  60. ////////////////////////////////////////////////////////////////////
  61. // Function: PPCommandFile::WriteState::Constructor
  62. // Access: Public
  63. // Description:
  64. ////////////////////////////////////////////////////////////////////
  65. PPCommandFile::WriteState::
  66. WriteState() {
  67. _out = &cout;
  68. _format = WF_collapse;
  69. _last_blank = true;
  70. }
  71. ////////////////////////////////////////////////////////////////////
  72. // Function: PPCommandFile::WriteState::Copy Constructor
  73. // Access: Public
  74. // Description:
  75. ////////////////////////////////////////////////////////////////////
  76. PPCommandFile::WriteState::
  77. WriteState(const WriteState &copy) :
  78. _out(copy._out),
  79. _format(copy._format),
  80. _last_blank(copy._last_blank)
  81. {
  82. }
  83. ////////////////////////////////////////////////////////////////////
  84. // Function: PPCommandFile::WriteState::write_line
  85. // Access: Public
  86. // Description:
  87. ////////////////////////////////////////////////////////////////////
  88. bool PPCommandFile::WriteState::
  89. write_line(const string &line) {
  90. switch (_format) {
  91. case WF_straight:
  92. (*_out) << line << "\n";
  93. return true;
  94. case WF_collapse:
  95. return write_collapse_line(line);
  96. case WF_makefile:
  97. return write_makefile_line(line);
  98. }
  99. cerr << "Unsupported write format: " << (int)_format << "\n";
  100. return false;
  101. }
  102. ////////////////////////////////////////////////////////////////////
  103. // Function: PPCommandFile::WriteState::write_collapse_line
  104. // Access: Public
  105. // Description:
  106. ////////////////////////////////////////////////////////////////////
  107. bool PPCommandFile::WriteState::
  108. write_collapse_line(const string &line) {
  109. if (line.empty()) {
  110. if (!_last_blank) {
  111. (*_out) << "\n";
  112. _last_blank = true;
  113. }
  114. } else {
  115. _last_blank = false;
  116. (*_out) << line << "\n";
  117. }
  118. return true;
  119. }
  120. ////////////////////////////////////////////////////////////////////
  121. // Function: PPCommandFile::WriteState::write_makefile_line
  122. // Access: Public
  123. // Description:
  124. ////////////////////////////////////////////////////////////////////
  125. bool PPCommandFile::WriteState::
  126. write_makefile_line(const string &line) {
  127. if (line.length() <= 72) {
  128. return write_collapse_line(line);
  129. }
  130. _last_blank = false;
  131. // In makefile mode, long variable assignment lines are folded after
  132. // the assignment.
  133. vector<string> words;
  134. tokenize_whitespace(line, words);
  135. if (words.size() > 2 && (words[1] == "=" || words[1] == ":")) {
  136. // This appears to be a variable assignment or a dependency rule;
  137. // fold it.
  138. (*_out) << words[0] << " " << words[1];
  139. vector<string>::const_iterator wi;
  140. int col = 80;
  141. wi = words.begin() + 2;
  142. while (wi != words.end()) {
  143. col += (*wi).length() + 1;
  144. if (col > 72) {
  145. (*_out) << " \\\n ";
  146. col = 4 + (*wi).length();
  147. }
  148. (*_out) << " " << (*wi);
  149. ++wi;
  150. }
  151. (*_out) << "\n";
  152. } else {
  153. // This is not a variable assignment, so just write it out.
  154. (*_out) << line << "\n";
  155. }
  156. return true;
  157. }
  158. ////////////////////////////////////////////////////////////////////
  159. // Function: PPCommandFile::BlockNesting::Constructor
  160. // Access: Public
  161. // Description:
  162. ////////////////////////////////////////////////////////////////////
  163. PPCommandFile::BlockNesting::
  164. BlockNesting(BlockState state, const string &name) :
  165. _state(state),
  166. _name(name)
  167. {
  168. _if = (PPCommandFile::IfNesting *)NULL;
  169. _write_state = (PPCommandFile::WriteState *)NULL;
  170. _scope = (PPScope *)NULL;
  171. _flags = 0;
  172. _next = (PPCommandFile::BlockNesting *)NULL;
  173. }
  174. ////////////////////////////////////////////////////////////////////
  175. // Function: PPCommandFile::BlockNesting::push
  176. // Access: Public
  177. // Description: Adds this BlockNesting object to the top of the
  178. // nesting stack.
  179. ////////////////////////////////////////////////////////////////////
  180. void PPCommandFile::BlockNesting::
  181. push(PPCommandFile *file) {
  182. _if = file->_if_nesting;
  183. _write_state = file->_write_state;
  184. _scope = file->_scope;
  185. _next = file->_block_nesting;
  186. file->_block_nesting = this;
  187. }
  188. ////////////////////////////////////////////////////////////////////
  189. // Function: PPCommandFile::BlockNesting::pop
  190. // Access: Public
  191. // Description: Removes this BlockNesting object from the top of the
  192. // nesting stack, and restores the command file's
  193. // nesting state.
  194. ////////////////////////////////////////////////////////////////////
  195. void PPCommandFile::BlockNesting::
  196. pop(PPCommandFile *file) {
  197. assert(file->_block_nesting == this);
  198. if (file->_write_state != _write_state) {
  199. delete file->_write_state;
  200. file->_write_state = _write_state;
  201. }
  202. file->_scope = _scope;
  203. file->_block_nesting = _next;
  204. }
  205. ////////////////////////////////////////////////////////////////////
  206. // Function: PPCommandFile::Constructor
  207. // Access: Public
  208. // Description:
  209. ////////////////////////////////////////////////////////////////////
  210. PPCommandFile::
  211. PPCommandFile(PPScope *scope) {
  212. _native_scope = scope;
  213. _scope = scope;
  214. _got_command = false;
  215. _in_for = false;
  216. _if_nesting = (IfNesting *)NULL;
  217. _block_nesting = (BlockNesting *)NULL;
  218. _write_state = new WriteState;
  219. }
  220. ////////////////////////////////////////////////////////////////////
  221. // Function: PPCommandFile::Destructor
  222. // Access: Public, Virtual
  223. // Description:
  224. ////////////////////////////////////////////////////////////////////
  225. PPCommandFile::
  226. ~PPCommandFile() {
  227. delete _write_state;
  228. }
  229. ////////////////////////////////////////////////////////////////////
  230. // Function: PPCommandFile::set_output
  231. // Access: Public
  232. // Description: Changes the main output stream that will be written
  233. // to when text appears outside of a #output .. #end
  234. // block. This is cout by default.
  235. ////////////////////////////////////////////////////////////////////
  236. void PPCommandFile::
  237. set_output(ostream *out) {
  238. _write_state->_out = out;
  239. }
  240. ////////////////////////////////////////////////////////////////////
  241. // Function: PPCommandFile::set_scope
  242. // Access: Public
  243. // Description: Changes the command file to use the indicated scope.
  244. // This scope will *not* be deleted when the command
  245. // file destructs.
  246. ////////////////////////////////////////////////////////////////////
  247. void PPCommandFile::
  248. set_scope(PPScope *scope) {
  249. _scope = scope;
  250. _native_scope = scope;
  251. }
  252. ////////////////////////////////////////////////////////////////////
  253. // Function: PPCommandFile::get_scope
  254. // Access: Public
  255. // Description: Returns the current scope associated with the command
  256. // file. This may change as the command file is
  257. // processed (e.g. between #begin .. #end sequences),
  258. // and it may or may not be tied to the life of the
  259. // PPCommandFile itself.
  260. ////////////////////////////////////////////////////////////////////
  261. PPScope *PPCommandFile::
  262. get_scope() const {
  263. return _scope;
  264. }
  265. ////////////////////////////////////////////////////////////////////
  266. // Function: PPCommandFile::read_file
  267. // Access: Public
  268. // Description: Reads input from the given filename.
  269. ////////////////////////////////////////////////////////////////////
  270. bool PPCommandFile::
  271. read_file(Filename filename) {
  272. filename.set_text();
  273. ifstream in;
  274. if (!filename.open_read(in)) {
  275. cerr << "Unable to open " << filename << ".\n";
  276. return false;
  277. }
  278. return read_stream(in, filename);
  279. }
  280. ////////////////////////////////////////////////////////////////////
  281. // Function: PPCommandFile::read_stream
  282. // Access: Public
  283. // Description: Reads input from the given stream. Each line is
  284. // read, commands are processed, variables are expanded,
  285. // and the resulting output is sent to write_line()
  286. // one line at a time. The return value is true if the
  287. // entire file is read with no errors, false if there is
  288. // some problem.
  289. //
  290. // The filename is just informational; it is used to
  291. // update the variables like THISFILENAME and
  292. // THISDIRPREFIX as appropriate, and to report errors to
  293. // the user.
  294. ////////////////////////////////////////////////////////////////////
  295. bool PPCommandFile::
  296. read_stream(istream &in, const string &filename) {
  297. PushFilename pushed(_scope, filename);
  298. if (!read_stream(in)) {
  299. if (!in.eof()) {
  300. cerr << "Error reading " << filename << ".\n";
  301. }
  302. return false;
  303. }
  304. return true;
  305. }
  306. ////////////////////////////////////////////////////////////////////
  307. // Function: PPCommandFile::read_stream
  308. // Access: Public
  309. // Description: Reads input from the given stream. Each line is
  310. // read, commands are processed, variables are expanded,
  311. // and the resulting output is sent to write_line()
  312. // one line at a time. The return value is true if the
  313. // entire file is read with no errors, false if there is
  314. // some problem.
  315. //
  316. // This flavor of read_stream() does not take a
  317. // filename. It does not, therefore, adjust
  318. // THISFILENAME and THISDIRPREFIX.
  319. ////////////////////////////////////////////////////////////////////
  320. bool PPCommandFile::
  321. read_stream(istream &in) {
  322. string line;
  323. getline(in, line);
  324. begin_read();
  325. while (!in.fail() && !in.eof()) {
  326. if (!read_line(line)) {
  327. return false;
  328. }
  329. getline(in, line);
  330. }
  331. if (!end_read()) {
  332. return false;
  333. }
  334. return true;
  335. }
  336. ////////////////////////////////////////////////////////////////////
  337. // Function: PPCommandFile::begin_read
  338. // Access: Public
  339. // Description: Resets to the beginning-of-the-stream state, in
  340. // preparation for a sequence of read_line() calls.
  341. ////////////////////////////////////////////////////////////////////
  342. void PPCommandFile::
  343. begin_read() {
  344. assert(_if_nesting == (IfNesting *)NULL);
  345. assert(_block_nesting == (BlockNesting *)NULL);
  346. }
  347. ////////////////////////////////////////////////////////////////////
  348. // Function: PPCommandFile::read_line
  349. // Access: Public
  350. // Description: Reads one line at a time, as if from the input
  351. // stream.
  352. ////////////////////////////////////////////////////////////////////
  353. bool PPCommandFile::
  354. read_line(string line) {
  355. // First things first: strip off any comment in the line.
  356. // We only recognize comments that are proceeded by whitespace, or
  357. // that start at the beginning of the line.
  358. size_t comment = line.find(begin_comment);
  359. while (comment != string::npos &&
  360. !(comment == 0 || isspace(line[comment - 1]))) {
  361. comment = line.find(begin_comment, comment + begin_comment.length());
  362. }
  363. if (comment != string::npos) {
  364. // Also strip any whitespace leading up to the comment.
  365. while (comment > 0 && isspace(line[comment - 1])) {
  366. comment--;
  367. }
  368. line = line.substr(0, comment);
  369. }
  370. // If the comment was at the beginning of the line, ignore the whole
  371. // line, including its whitespace.
  372. if (comment != 0) {
  373. // We also strip off whitespace at the end of the line, since this
  374. // is generally invisible and almost always just leads to trouble.
  375. size_t eol = line.length();
  376. while (eol > 0 && (isspace(line[eol - 1]) || line[eol - 1] == '\r')) {
  377. eol--;
  378. }
  379. line = line.substr(0, eol);
  380. if (_in_for) {
  381. // Save up the lines for later execution if we're within a #forscopes.
  382. _saved_lines.push_back(line);
  383. }
  384. if (_got_command) {
  385. return handle_command(line);
  386. } else {
  387. // Find the beginning of the line--skip initial whitespace.
  388. size_t p = 0;
  389. while (p < line.length() && isspace(line[p])) {
  390. p++;
  391. }
  392. if (p == line.length()) {
  393. // The line is empty. Make it truly empty.
  394. line = "";
  395. } else {
  396. if (((p+1) < line.length()) && (line[p] == COMMAND_PREFIX) &&
  397. isalpha(line[p + 1])) {
  398. // This is a special command.
  399. return handle_command(line.substr(p + 1));
  400. }
  401. }
  402. if (!_in_for && !failed_if()) {
  403. if(line[p+1]==COMMAND_PREFIX) {
  404. // double prefix at start of line indicates echo single prefix, like '\\' in C
  405. line.erase(0,1);
  406. }
  407. return _write_state->write_line(_scope->expand_string(line));
  408. }
  409. }
  410. }
  411. return true;
  412. }
  413. ////////////////////////////////////////////////////////////////////
  414. // Function: PPCommandFile::end_read
  415. // Access: Public
  416. // Description: Finishes up the input stream, after a sequence of
  417. // read_line() calls.
  418. ////////////////////////////////////////////////////////////////////
  419. bool PPCommandFile::
  420. end_read() {
  421. bool okflag = true;
  422. if (_if_nesting != (IfNesting *)NULL) {
  423. cerr << "Unclosed if\n";
  424. _if_nesting = (IfNesting *)NULL;
  425. okflag = false;
  426. }
  427. if (_block_nesting != (BlockNesting *)NULL) {
  428. switch (_block_nesting->_state) {
  429. case BS_begin:
  430. cerr << "Unclosed begin " << _block_nesting->_name << "\n";
  431. break;
  432. case BS_forscopes:
  433. case BS_nested_forscopes:
  434. cerr << "Unclosed forscopes " << _block_nesting->_name << "\n";
  435. break;
  436. case BS_foreach:
  437. case BS_nested_foreach:
  438. cerr << "Unclosed foreach " << _block_nesting->_name << "\n";
  439. break;
  440. case BS_formap:
  441. case BS_nested_formap:
  442. cerr << "Unclosed formap " << _block_nesting->_name << "\n";
  443. break;
  444. case BS_defsub:
  445. cerr << "Unclosed defsub " << _block_nesting->_name << "\n";
  446. break;
  447. case BS_defun:
  448. cerr << "Unclosed defun " << _block_nesting->_name << "\n";
  449. break;
  450. case BS_output:
  451. cerr << "Unclosed output " << _block_nesting->_name << "\n";
  452. break;
  453. }
  454. _block_nesting = (BlockNesting *)NULL;
  455. okflag = false;
  456. }
  457. return okflag;
  458. }
  459. ////////////////////////////////////////////////////////////////////
  460. // Function: PPCommandFile::handle_command
  461. // Access: Protected
  462. // Description: Handles a macro command.
  463. ////////////////////////////////////////////////////////////////////
  464. bool PPCommandFile::
  465. handle_command(const string &line) {
  466. if (_got_command) {
  467. // If we were still processing a command from last time, keep
  468. // going; this line is just a continuation. But skip any initial
  469. // whitespace.
  470. size_t p = 0;
  471. while (p < line.length() && isspace(line[p])) {
  472. p++;
  473. }
  474. _params += ' ';
  475. _params += line.substr(p);
  476. } else {
  477. // This is the first line of a new command.
  478. // Pull off the first word and the rest of the line.
  479. size_t p = 0;
  480. while (p < line.length() && !isspace(line[p])) {
  481. p++;
  482. }
  483. _command = line.substr(0, p);
  484. // Skip whitespace between the command and its arguments.
  485. while (p < line.length() && isspace(line[p])) {
  486. p++;
  487. }
  488. _params = line.substr(p);
  489. }
  490. if (!_params.empty() && _params[_params.length() - 1] == '\\') {
  491. // If the line ends with a backslash, there's more to come before
  492. // we can process the command.
  493. _got_command = true;
  494. // Truncate off the backslash, and any whitespace before it.
  495. size_t p = _params.length() - 1;
  496. while (p > 0 && isspace(_params[p - 1])) {
  497. p--;
  498. }
  499. _params = _params.substr(0, p);
  500. return true;
  501. }
  502. // We're completely done scanning the command now.
  503. _got_command = false;
  504. if (_command == "if") {
  505. return handle_if_command();
  506. } else if (_command == "elif") {
  507. return handle_elif_command();
  508. } else if (_command == "else") {
  509. return handle_else_command();
  510. } else if (_command == "endif") {
  511. return handle_endif_command();
  512. } else if (failed_if()) {
  513. // If we're in the middle of a failed #if, we ignore all commands
  514. // except for the if-related commands, above.
  515. return true;
  516. } else if (_command == "begin") {
  517. return handle_begin_command();
  518. } else if (_command == "forscopes") {
  519. return handle_forscopes_command();
  520. } else if (_command == "foreach") {
  521. return handle_foreach_command();
  522. } else if (_command == "formap") {
  523. return handle_formap_command();
  524. } else if (_command == "defsub") {
  525. return handle_defsub_command(true);
  526. } else if (_command == "defun") {
  527. return handle_defsub_command(false);
  528. } else if (_command == "output") {
  529. return handle_output_command();
  530. } else if (_command == "end") {
  531. return handle_end_command();
  532. } else if (_in_for) {
  533. // If we're currently saving up lines within a block sequence, we
  534. // ignore all commands except for the block-related commands,
  535. // above.
  536. return true;
  537. } else if (_command == "format") {
  538. return handle_format_command();
  539. } else if (_command == "print") {
  540. return handle_print_command();
  541. } else if (_command == "include") {
  542. return handle_include_command();
  543. } else if (_command == "sinclude") {
  544. return handle_sinclude_command();
  545. } else if (_command == "call") {
  546. return handle_call_command();
  547. } else if (_command == "error") {
  548. return handle_error_command();
  549. } else if (_command == "defer") {
  550. return handle_defer_command();
  551. } else if (_command == "define") {
  552. return handle_define_command();
  553. } else if (_command == "set") {
  554. return handle_set_command();
  555. } else if (_command == "map") {
  556. return handle_map_command();
  557. } else if (_command == "addmap") {
  558. return handle_addmap_command();
  559. }
  560. cerr << "Invalid command: " << COMMAND_PREFIX << _command << "\n";
  561. return false;
  562. }
  563. ////////////////////////////////////////////////////////////////////
  564. // Function: PPCommandFile::handle_if_command
  565. // Access: Protected
  566. // Description: Handles the #if command: conditionally evaluate the
  567. // following code.
  568. ////////////////////////////////////////////////////////////////////
  569. bool PPCommandFile::
  570. handle_if_command() {
  571. if (failed_if()) {
  572. // If we're *already* inside a failed if, we don't have to
  573. // evaluate this one, but we do need to record the nesting level.
  574. IfNesting *nest = new IfNesting(IS_done);
  575. nest->push(this);
  576. } else {
  577. // If the parameter string evaluates to empty, the case is false.
  578. // Otherwise the case is true. However, if we're currently
  579. // scanning #forscopes or something, we don't evaluate this at
  580. // all, because it doesn't matter.
  581. bool is_empty = true;
  582. if (!_in_for) {
  583. _params = _scope->expand_string(_params);
  584. string::const_iterator si;
  585. for (si = _params.begin(); si != _params.end() && is_empty; ++si) {
  586. is_empty = isspace(*si);
  587. }
  588. }
  589. IfState state = is_empty ? IS_off : IS_on;
  590. IfNesting *nest = new IfNesting(state);
  591. nest->push(this);
  592. }
  593. return true;
  594. }
  595. ////////////////////////////////////////////////////////////////////
  596. // Function: PPCommandFile::handle_elif_command
  597. // Access: Protected
  598. // Description: Handles the #elif command: conditionally evaluate
  599. // the following code, following a failed #if command.
  600. ////////////////////////////////////////////////////////////////////
  601. bool PPCommandFile::
  602. handle_elif_command() {
  603. if (_if_nesting == (IfNesting *)NULL) {
  604. cerr << "elif encountered without if.\n";
  605. return false;
  606. }
  607. if (_if_nesting->_state == IS_else) {
  608. cerr << "elif encountered after else.\n";
  609. return false;
  610. }
  611. if (_if_nesting->_state == IS_on || _if_nesting->_state == IS_done) {
  612. // If we passed the #if above, we don't need to evaluate the #elif.
  613. _if_nesting->_state = IS_done;
  614. return true;
  615. }
  616. // If the parameter string evaluates to empty, the case is false.
  617. // Otherwise the case is true.
  618. bool is_empty = true;
  619. if (!_in_for) {
  620. _params = _scope->expand_string(_params);
  621. string::const_iterator si;
  622. for (si = _params.begin(); si != _params.end() && is_empty; ++si) {
  623. is_empty = isspace(*si);
  624. }
  625. }
  626. _if_nesting->_state = is_empty ? IS_off : IS_on;
  627. return true;
  628. }
  629. ////////////////////////////////////////////////////////////////////
  630. // Function: PPCommandFile::handle_else_command
  631. // Access: Protected
  632. // Description: Handles the #else command: evaluate the following
  633. // code following a failed #if command.
  634. ////////////////////////////////////////////////////////////////////
  635. bool PPCommandFile::
  636. handle_else_command() {
  637. if (_if_nesting == (IfNesting *)NULL) {
  638. cerr << "else encountered without if.\n";
  639. return false;
  640. }
  641. if (_if_nesting->_state == IS_else) {
  642. cerr << "else encountered after else.\n";
  643. return false;
  644. }
  645. if (_if_nesting->_state == IS_on || _if_nesting->_state == IS_done) {
  646. _if_nesting->_state = IS_done;
  647. return true;
  648. }
  649. _if_nesting->_state = IS_else;
  650. return true;
  651. }
  652. ////////////////////////////////////////////////////////////////////
  653. // Function: PPCommandFile::handle_endif_command
  654. // Access: Protected
  655. // Description: Handles the #endif command: close a preceeding #if
  656. // command.
  657. ////////////////////////////////////////////////////////////////////
  658. bool PPCommandFile::
  659. handle_endif_command() {
  660. if (_if_nesting == (IfNesting *)NULL) {
  661. cerr << "endif encountered without if.\n";
  662. return false;
  663. }
  664. IfNesting *nest = _if_nesting;
  665. nest->pop(this);
  666. if (nest->_block != _block_nesting) {
  667. cerr << "If block not closed within scoping block.\n";
  668. return false;
  669. }
  670. delete nest;
  671. return true;
  672. }
  673. ////////////////////////////////////////////////////////////////////
  674. // Function: PPCommandFile::handle_begin_command
  675. // Access: Protected
  676. // Description: Handles the #begin command: begin a named scope
  677. // block. The variables defined between this command
  678. // and the corresponding #end command will be local to
  679. // this named scope.
  680. ////////////////////////////////////////////////////////////////////
  681. bool PPCommandFile::
  682. handle_begin_command() {
  683. string name = trim_blanks(_scope->expand_string(_params));
  684. BlockNesting *nest = new BlockNesting(BS_begin, name);
  685. if (contains_whitespace(name)) {
  686. cerr << "Attempt to define scope named \"" << name
  687. << "\".\nScope names may not contain whitespace.\n";
  688. return false;
  689. }
  690. if (name.find(SCOPE_DIRNAME_SEPARATOR) != string::npos) {
  691. cerr << "Attempt to define scope named \"" << name
  692. << "\".\nScope names may not contain the '"
  693. << SCOPE_DIRNAME_SEPARATOR << "' character.\n";
  694. return false;
  695. }
  696. nest->push(this);
  697. PPScope *named_scope = _scope->get_named_scopes()->make_scope(name);
  698. named_scope->set_parent(_scope);
  699. _scope = named_scope;
  700. return true;
  701. }
  702. ////////////////////////////////////////////////////////////////////
  703. // Function: PPCommandFile::handle_forscopes_command
  704. // Access: Protected
  705. // Description: Handles the #forscopes command: interpret all the lines
  706. // between this command and the corresponding #end
  707. // command once for each occurrence of a named scope
  708. // with the given name.
  709. ////////////////////////////////////////////////////////////////////
  710. bool PPCommandFile::
  711. handle_forscopes_command() {
  712. BlockState state = _in_for ? BS_nested_forscopes : BS_forscopes;
  713. string name = trim_blanks(_scope->expand_string(_params));
  714. BlockNesting *nest = new BlockNesting(state, name);
  715. nest->push(this);
  716. if (!_in_for) {
  717. _in_for = true;
  718. _saved_lines.clear();
  719. }
  720. return true;
  721. }
  722. ////////////////////////////////////////////////////////////////////
  723. // Function: PPCommandFile::handle_foreach_command
  724. // Access: Protected
  725. // Description: Handles the #foreach command: interpret all the lines
  726. // between this command and the corresponding #end
  727. // command once for each word in the argument.
  728. ////////////////////////////////////////////////////////////////////
  729. bool PPCommandFile::
  730. handle_foreach_command() {
  731. // Get the parameters of the foreach command. The first word is the
  732. // name of the variable to substitute in (and which should appear on
  733. // the matching #end command), and the remaining words are the
  734. // values to substitute in.
  735. vector<string> words;
  736. tokenize_whitespace(_scope->expand_string(_params), words);
  737. if (words.empty()) {
  738. cerr << "#foreach requires at least one parameter.\n";
  739. return false;
  740. }
  741. string variable_name = words.front();
  742. BlockState state = _in_for ? BS_nested_foreach : BS_foreach;
  743. BlockNesting *nest = new BlockNesting(state, variable_name);
  744. nest->push(this);
  745. // We insert in all but the first word in the words vector.
  746. nest->_words.insert(nest->_words.end(), words.begin() + 1, words.end());
  747. if (!_in_for) {
  748. _in_for = true;
  749. _saved_lines.clear();
  750. }
  751. return true;
  752. }
  753. ////////////////////////////////////////////////////////////////////
  754. // Function: PPCommandFile::handle_formap_command
  755. // Access: Protected
  756. // Description: Handles the #formap command: interpret all the lines
  757. // between this command and the corresponding #end
  758. // command once for each key in the map, and also within
  759. // the corresponding scope of that particular key.
  760. ////////////////////////////////////////////////////////////////////
  761. bool PPCommandFile::
  762. handle_formap_command() {
  763. // Get the parameters of the formap command. The first word is the
  764. // name of the variable to substitute in (and which should appear on
  765. // the matching #end command), and the second word is the name of
  766. // the map variable.
  767. vector<string> words;
  768. tokenize_whitespace(_scope->expand_string(_params), words);
  769. if (words.size() != 2) {
  770. cerr << "#formap requires exactly two parameters.\n";
  771. return false;
  772. }
  773. string variable_name = words.front();
  774. BlockState state = _in_for ? BS_nested_formap : BS_formap;
  775. BlockNesting *nest = new BlockNesting(state, words[0]);
  776. nest->push(this);
  777. nest->_words.push_back(words[1]);
  778. if (!_in_for) {
  779. _in_for = true;
  780. _saved_lines.clear();
  781. }
  782. return true;
  783. }
  784. ////////////////////////////////////////////////////////////////////
  785. // Function: PPCommandFile::handle_defsub_command
  786. // Access: Protected
  787. // Description: Handles the #defsub (or #defun) command: save all the
  788. // lines between this command and the matching #end as a
  789. // callable subroutine to be invoked by a later #call
  790. // command. If is_defsub is false, it means this
  791. // subroutine was actually defined via a #defun command,
  792. // so it is to be invoked by a later variable reference,
  793. // instead of by a #call command.
  794. ////////////////////////////////////////////////////////////////////
  795. bool PPCommandFile::
  796. handle_defsub_command(bool is_defsub) {
  797. string command = (is_defsub) ? "#defsub" : "#defun";
  798. // The first word of the parameter list is the subroutine name; the
  799. // rest is the comma-separated list of formal parameter names.
  800. // Pull off the first word and the rest of the params.
  801. size_t p = 0;
  802. while (p < _params.length() && !isspace(_params[p])) {
  803. p++;
  804. }
  805. string subroutine_name = trim_blanks(_params.substr(0, p));
  806. if (subroutine_name.empty()) {
  807. cerr << command << " requires at least one parameter.\n";
  808. return false;
  809. }
  810. vector<string> formals;
  811. _scope->tokenize_params(_params.substr(p), formals, false);
  812. vector<string>::const_iterator fi;
  813. for (fi = formals.begin(); fi != formals.end(); ++fi) {
  814. if (!is_valid_formal(*fi)) {
  815. cerr << command << " " << subroutine_name
  816. << ": invalid formal parameter name '" << (*fi) << "'\n";
  817. return false;
  818. }
  819. }
  820. if (_in_for) {
  821. cerr << command << " may not appear within another block scoping command like\n"
  822. << "#forscopes, #foreach, #formap, #defsub, or #defun.\n";
  823. return false;
  824. }
  825. BlockState state = is_defsub ? BS_defsub : BS_defun;
  826. BlockNesting *nest = new BlockNesting(state, subroutine_name);
  827. nest->push(this);
  828. nest->_words.swap(formals);
  829. _in_for = true;
  830. _saved_lines.clear();
  831. return true;
  832. }
  833. ////////////////////////////////////////////////////////////////////
  834. // Function: PPCommandFile::handle_output_command
  835. // Access: Protected
  836. // Description: Handles the #output command: all text between this
  837. // command and the corresponding #end command will be
  838. // sent to the indicated output file.
  839. ////////////////////////////////////////////////////////////////////
  840. bool PPCommandFile::
  841. handle_output_command() {
  842. vector<string> words;
  843. tokenize_whitespace(_scope->expand_string(_params), words);
  844. if (words.empty()) {
  845. cerr << "#output command requires one parameter.\n";
  846. return false;
  847. }
  848. BlockNesting *nest = new BlockNesting(BS_output, words[0]);
  849. // Also check the output flags.
  850. for (int i = 1; i < (int)words.size(); i++) {
  851. if (words[i] == "notouch") {
  852. nest->_flags |= OF_notouch;
  853. } else {
  854. cerr << "Invalid output flag: " << words[i] << "\n";
  855. }
  856. }
  857. nest->push(this);
  858. if (!_in_for) {
  859. string filename = nest->_name;
  860. if (filename.empty()) {
  861. cerr << "Attempt to output to empty filename\n";
  862. return false;
  863. }
  864. string prefix = _scope->expand_variable("DIRPREFIX");
  865. if (filename[0] != '/') {
  866. filename = prefix + filename;
  867. }
  868. nest->_filename = filename;
  869. // Generate an in-memory copy of the file first.
  870. _write_state = new WriteState(*_write_state);
  871. _write_state->_out = &nest->_output;
  872. }
  873. return true;
  874. }
  875. ////////////////////////////////////////////////////////////////////
  876. // Function: PPCommandFile::handle_end_command
  877. // Access: Protected
  878. // Description: Handles the #end command. This closes a number of
  879. // different kinds of blocks, like #begin and #forscopes.
  880. ////////////////////////////////////////////////////////////////////
  881. bool PPCommandFile::
  882. handle_end_command() {
  883. if (_block_nesting == (BlockNesting *)NULL) {
  884. cerr << "Unmatched end " << _params << ".\n";
  885. return false;
  886. }
  887. string name = trim_blanks(_scope->expand_string(_params));
  888. if (name != _block_nesting->_name) {
  889. cerr << "end " << name << " encountered where end "
  890. << _block_nesting->_name << " expected.\n";
  891. return false;
  892. }
  893. BlockNesting *nest = _block_nesting;
  894. nest->pop(this);
  895. if (nest->_if != _if_nesting) {
  896. cerr << "If block not closed within scoping block.\n";
  897. return false;
  898. }
  899. if (nest->_state == BS_forscopes) {
  900. // Now replay all of the saved lines.
  901. _in_for = false;
  902. if (!replay_forscopes(nest->_name)) {
  903. return false;
  904. }
  905. } else if (nest->_state == BS_foreach) {
  906. // Now replay all of the saved lines.
  907. _in_for = false;
  908. if (!replay_foreach(nest->_name, nest->_words)) {
  909. return false;
  910. }
  911. } else if (nest->_state == BS_formap) {
  912. // Now replay all of the saved lines.
  913. _in_for = false;
  914. assert(nest->_words.size() == 1);
  915. if (!replay_formap(nest->_name, nest->_words[0])) {
  916. return false;
  917. }
  918. } else if (nest->_state == BS_defsub || nest->_state == BS_defun) {
  919. // Save all of the saved lines as a named subroutine.
  920. _in_for = false;
  921. PPSubroutine *sub = new PPSubroutine;
  922. sub->_formals.swap(nest->_words);
  923. sub->_lines.swap(_saved_lines);
  924. // Remove the #end command. This will fail if someone makes an
  925. // #end command that spans multiple lines. Don't do that.
  926. assert(!sub->_lines.empty());
  927. sub->_lines.pop_back();
  928. if (nest->_state == BS_defsub) {
  929. PPSubroutine::define_sub(nest->_name, sub);
  930. } else {
  931. PPSubroutine::define_func(nest->_name, sub);
  932. }
  933. } else if (nest->_state == BS_output) {
  934. if (!_in_for) {
  935. if (!nest->_output) {
  936. cerr << "Error while writing " << nest->_filename << "\n";
  937. return false;
  938. }
  939. // Now compare the file we generated to the file that's already
  940. // there, if there is one.
  941. nest->_output << ends;
  942. const char *generated_file = nest->_output.str();
  943. if (!compare_output(generated_file, nest->_filename,
  944. (nest->_flags & OF_notouch) != 0)) {
  945. return false;
  946. }
  947. }
  948. }
  949. delete nest;
  950. return true;
  951. }
  952. ////////////////////////////////////////////////////////////////////
  953. // Function: PPCommandFile::handle_format_command
  954. // Access: Protected
  955. // Description: Handles the #format command: change the formatting
  956. // mode of lines as they are output.
  957. ////////////////////////////////////////////////////////////////////
  958. bool PPCommandFile::
  959. handle_format_command() {
  960. _params = trim_blanks(_scope->expand_string(_params));
  961. if (_params == "straight") {
  962. _write_state->_format = WF_straight;
  963. } else if (_params == "collapse") {
  964. _write_state->_format = WF_collapse;
  965. } else if (_params == "makefile") {
  966. _write_state->_format = WF_makefile;
  967. } else {
  968. cerr << "Ignoring invalid write format: " << _params << "\n";
  969. }
  970. return true;
  971. }
  972. ////////////////////////////////////////////////////////////////////
  973. // Function: PPCommandFile::handle_print_command
  974. // Access: Protected
  975. // Description: Handles the #print command: immediately output the
  976. // arguments to this line to standard error.
  977. ////////////////////////////////////////////////////////////////////
  978. bool PPCommandFile::
  979. handle_print_command() {
  980. cerr << _scope->expand_string(_params) << "\n";
  981. return true;
  982. }
  983. ////////////////////////////////////////////////////////////////////
  984. // Function: PPCommandFile::handle_include_command
  985. // Access: Protected
  986. // Description: Handles the #include command: the indicated file is
  987. // read and processed at this point.
  988. ////////////////////////////////////////////////////////////////////
  989. bool PPCommandFile::
  990. handle_include_command() {
  991. string filename = trim_blanks(_scope->expand_string(_params));
  992. // We allow optional quotation marks around the filename.
  993. if (filename.length() >= 2 &&
  994. filename[0] == '"' &&
  995. filename[filename.length() - 1] == '"') {
  996. filename = filename.substr(1, filename.length() - 2);
  997. }
  998. return include_file(filename);
  999. }
  1000. ////////////////////////////////////////////////////////////////////
  1001. // Function: PPCommandFile::handle_sinclude_command
  1002. // Access: Protected
  1003. // Description: Handles the #sinclude command: the indicated file is
  1004. // read and processed at this point. This is different
  1005. // from #include only in that if the file does not
  1006. // exist, there is no error; instead, nothing happens.
  1007. ////////////////////////////////////////////////////////////////////
  1008. bool PPCommandFile::
  1009. handle_sinclude_command() {
  1010. string filename = trim_blanks(_scope->expand_string(_params));
  1011. // We allow optional quotation marks around the filename.
  1012. if (filename.length() >= 2 &&
  1013. filename[0] == '"' &&
  1014. filename[filename.length() - 1] == '"') {
  1015. filename = filename.substr(1, filename.length() - 2);
  1016. }
  1017. Filename fn(filename);
  1018. if (!fn.exists()) {
  1019. // No such file; no error.
  1020. return true;
  1021. }
  1022. return include_file(filename);
  1023. }
  1024. ////////////////////////////////////////////////////////////////////
  1025. // Function: PPCommandFile::handle_call_command
  1026. // Access: Protected
  1027. // Description: Handles the #call command: the indicated named
  1028. // subroutine is read and processed at this point.
  1029. ////////////////////////////////////////////////////////////////////
  1030. bool PPCommandFile::
  1031. handle_call_command() {
  1032. // The first word is the name of the subroutine; the rest is the
  1033. // comma-separated list of expressions to substitute in for the
  1034. // subroutine's formal parameters.
  1035. // Pull off the first word and the rest of the params.
  1036. size_t p = 0;
  1037. while (p < _params.length() && !isspace(_params[p])) {
  1038. p++;
  1039. }
  1040. string subroutine_name = trim_blanks(_params.substr(0, p));
  1041. string params = _params.substr(p);
  1042. if (subroutine_name.empty()) {
  1043. cerr << "#call requires at least one parameter.\n";
  1044. return false;
  1045. }
  1046. const PPSubroutine *sub = PPSubroutine::get_sub(subroutine_name);
  1047. if (sub == (const PPSubroutine *)NULL) {
  1048. cerr << "Attempt to call undefined subroutine " << subroutine_name << "\n";
  1049. }
  1050. PPScope *old_scope = _scope;
  1051. PPScope::push_scope(_scope);
  1052. PPScope nested_scope(_scope->get_named_scopes());
  1053. _scope = &nested_scope;
  1054. nested_scope.define_formals(subroutine_name, sub->_formals, params);
  1055. vector<string>::const_iterator li;
  1056. for (li = sub->_lines.begin(); li != sub->_lines.end(); ++li) {
  1057. if (!read_line(*li)) {
  1058. PPScope::pop_scope();
  1059. _scope = old_scope;
  1060. return false;
  1061. }
  1062. }
  1063. PPScope::pop_scope();
  1064. _scope = old_scope;
  1065. return true;
  1066. }
  1067. ////////////////////////////////////////////////////////////////////
  1068. // Function: PPCommandFile::handle_error_command
  1069. // Access: Protected
  1070. // Description: Handles the #error command: terminate immediately
  1071. // with the given error message.
  1072. ////////////////////////////////////////////////////////////////////
  1073. bool PPCommandFile::
  1074. handle_error_command() {
  1075. string message = trim_blanks(_scope->expand_string(_params));
  1076. if (!message.empty()) {
  1077. cerr << message << "\n";
  1078. }
  1079. return false;
  1080. }
  1081. ////////////////////////////////////////////////////////////////////
  1082. // Function: PPCommandFile::handle_defer_command
  1083. // Access: Protected
  1084. // Description: Handles the #defer command: define a new variable or
  1085. // change the definition of an existing variable. This
  1086. // is different from #define in that the variable
  1087. // definition is not immediately expanded; it will be
  1088. // expanded when the variable is later used. This
  1089. // allows the definition of variables that depend on
  1090. // other variables whose values have not yet been
  1091. // defined. This is akin to GNU make's = assignment.
  1092. ////////////////////////////////////////////////////////////////////
  1093. bool PPCommandFile::
  1094. handle_defer_command() {
  1095. // Pull off the first word and the rest of the params.
  1096. size_t p = 0;
  1097. while (p < _params.length() && !isspace(_params[p])) {
  1098. p++;
  1099. }
  1100. string varname = _params.substr(0, p);
  1101. if (PPSubroutine::get_func(varname) != (const PPSubroutine *)NULL) {
  1102. cerr << "Warning: variable " << varname
  1103. << " shadowed by function definition.\n";
  1104. }
  1105. // Skip whitespace between the variable name and its definition.
  1106. while (p < _params.length() && isspace(_params[p])) {
  1107. p++;
  1108. }
  1109. string def = _params.substr(p);
  1110. // We don't expand the variable's definition immediately; it will be
  1111. // expanded when the variable is referenced later. However, we
  1112. // should expand any simple self-reference immediately, to allow for
  1113. // recursive definitions.
  1114. def = _scope->expand_self_reference(def, varname);
  1115. _scope->define_variable(varname, def);
  1116. return true;
  1117. }
  1118. ////////////////////////////////////////////////////////////////////
  1119. // Function: PPCommandFile::handle_define_command
  1120. // Access: Protected
  1121. // Description: Handles the #define command: define a new variable or
  1122. // change the definition of an existing variable. The
  1123. // variable definition is immediately expanded. This is
  1124. // akin to GNU make's := assignment.
  1125. ////////////////////////////////////////////////////////////////////
  1126. bool PPCommandFile::
  1127. handle_define_command() {
  1128. // Pull off the first word and the rest of the params.
  1129. size_t p = 0;
  1130. while (p < _params.length() && !isspace(_params[p])) {
  1131. p++;
  1132. }
  1133. string varname = _params.substr(0, p);
  1134. if (PPSubroutine::get_func(varname) != (const PPSubroutine *)NULL) {
  1135. cerr << "Warning: variable " << varname
  1136. << " shadowed by function definition.\n";
  1137. }
  1138. // Skip whitespace between the variable name and its definition.
  1139. while (p < _params.length() && isspace(_params[p])) {
  1140. p++;
  1141. }
  1142. string def = _scope->expand_string(_params.substr(p));
  1143. _scope->define_variable(varname, def);
  1144. return true;
  1145. }
  1146. ////////////////////////////////////////////////////////////////////
  1147. // Function: PPCommandFile::handle_set_command
  1148. // Access: Protected
  1149. // Description: Handles the #set command: change the definition of an
  1150. // existing variable.
  1151. //
  1152. // This is different from #defer in two ways: (1) the
  1153. // variable in question must already have been #defined
  1154. // elsewhere, (2) if the variable was #defined in some
  1155. // parent scope, this will actually change the variable
  1156. // in the parent scope, rather than shadowing it in the
  1157. // local scope. Like #define and unlike #defer, the
  1158. // variable definition is expanded immediately, similar
  1159. // to GNU make's := operator.
  1160. ////////////////////////////////////////////////////////////////////
  1161. bool PPCommandFile::
  1162. handle_set_command() {
  1163. // Pull off the first word and the rest of the params.
  1164. size_t p = 0;
  1165. while (p < _params.length() && !isspace(_params[p])) {
  1166. p++;
  1167. }
  1168. string varname = _params.substr(0, p);
  1169. if (PPSubroutine::get_func(varname) != (const PPSubroutine *)NULL) {
  1170. cerr << "Warning: variable " << varname
  1171. << " shadowed by function definition.\n";
  1172. }
  1173. // Skip whitespace between the variable name and its definition.
  1174. while (p < _params.length() && isspace(_params[p])) {
  1175. p++;
  1176. }
  1177. string def = _scope->expand_string(_params.substr(p));
  1178. if (!_scope->set_variable(varname, def)) {
  1179. cerr << "Attempt to set undefined variable " << varname << "\n";
  1180. return false;
  1181. }
  1182. return true;
  1183. }
  1184. ////////////////////////////////////////////////////////////////////
  1185. // Function: PPCommandFile::handle_map_command
  1186. // Access: Protected
  1187. // Description: Handles the #map command: define a new map variable.
  1188. // This is a special kind of variable declaration that
  1189. // creates a variable that can be used as a function to
  1190. // look up variable expansions within a number of
  1191. // different named scopes, accessed by keyword.
  1192. ////////////////////////////////////////////////////////////////////
  1193. bool PPCommandFile::
  1194. handle_map_command() {
  1195. // Pull off the first word and the rest of the params.
  1196. size_t p = 0;
  1197. while (p < _params.length() && !isspace(_params[p])) {
  1198. p++;
  1199. }
  1200. string varname = _params.substr(0, p);
  1201. // Skip whitespace between the variable name and its definition.
  1202. while (p < _params.length() && isspace(_params[p])) {
  1203. p++;
  1204. }
  1205. string def = trim_blanks(_params.substr(p));
  1206. _scope->define_map_variable(varname, def);
  1207. return true;
  1208. }
  1209. ////////////////////////////////////////////////////////////////////
  1210. // Function: PPCommandFile::handle_addmap_command
  1211. // Access: Protected
  1212. // Description: Handles the #addmap command: add a new key/scope pair
  1213. // to an existing map variable.
  1214. ////////////////////////////////////////////////////////////////////
  1215. bool PPCommandFile::
  1216. handle_addmap_command() {
  1217. // Pull off the first word and the rest of the params.
  1218. size_t p = 0;
  1219. while (p < _params.length() && !isspace(_params[p])) {
  1220. p++;
  1221. }
  1222. string varname = _params.substr(0, p);
  1223. // Skip whitespace between the variable name and the key.
  1224. while (p < _params.length() && isspace(_params[p])) {
  1225. p++;
  1226. }
  1227. string key = trim_blanks(_scope->expand_string(_params.substr(p)));
  1228. _scope->add_to_map_variable(varname, key, _scope);
  1229. return true;
  1230. }
  1231. ////////////////////////////////////////////////////////////////////
  1232. // Function: PPCommandFile::include_file
  1233. // Access: Protected
  1234. // Description: The internal implementation of #include: includes a
  1235. // particular named file at this point.
  1236. ////////////////////////////////////////////////////////////////////
  1237. bool PPCommandFile::
  1238. include_file(Filename filename) {
  1239. filename.set_text();
  1240. ifstream in;
  1241. if (!filename.open_read(in)) {
  1242. cerr << "Unable to open include file " << filename << ".\n";
  1243. return false;
  1244. }
  1245. PushFilename pushed(_scope, filename);
  1246. string line;
  1247. getline(in, line);
  1248. while (!in.fail() && !in.eof()) {
  1249. if (!read_line(line)) {
  1250. return false;
  1251. }
  1252. getline(in, line);
  1253. }
  1254. if (!in.eof()) {
  1255. cerr << "Error reading " << filename << ".\n";
  1256. return false;
  1257. }
  1258. return true;
  1259. }
  1260. ////////////////////////////////////////////////////////////////////
  1261. // Function: PPCommandFile::replay_forscopes
  1262. // Access: Protected
  1263. // Description: Replays all the lines that were saved during a
  1264. // previous #forscopes..#end block.
  1265. ////////////////////////////////////////////////////////////////////
  1266. bool PPCommandFile::
  1267. replay_forscopes(const string &name) {
  1268. assert(!_in_for);
  1269. bool okflag = true;
  1270. vector<string> lines;
  1271. lines.swap(_saved_lines);
  1272. // Remove the #end command. This will fail if someone makes an #end
  1273. // command that spans multiple lines. Don't do that.
  1274. assert(!lines.empty());
  1275. lines.pop_back();
  1276. PPNamedScopes *named_scopes = _scope->get_named_scopes();
  1277. // Extract out the scope names from the #forscopes .. #end name. This
  1278. // is a space-delimited list of scope names.
  1279. vector<string> words;
  1280. tokenize_whitespace(name, words);
  1281. // Now build up the list of scopes with these names.
  1282. PPNamedScopes::Scopes scopes;
  1283. vector<string>::const_iterator wi;
  1284. for (wi = words.begin(); wi != words.end(); ++wi) {
  1285. named_scopes->get_scopes(*wi, scopes);
  1286. }
  1287. PPNamedScopes::sort_by_dependency(scopes);
  1288. // And finally, replay all of the saved lines.
  1289. BlockNesting *saved_block = _block_nesting;
  1290. IfNesting *saved_if = _if_nesting;
  1291. PPNamedScopes::Scopes::const_iterator si;
  1292. for (si = scopes.begin(); si != scopes.end() && okflag; ++si) {
  1293. PPScope::push_scope(_scope);
  1294. _scope = (*si);
  1295. vector<string>::const_iterator li;
  1296. for (li = lines.begin(); li != lines.end() && okflag; ++li) {
  1297. okflag = read_line(*li);
  1298. }
  1299. _scope = PPScope::pop_scope();
  1300. }
  1301. if (saved_block != _block_nesting || saved_if != _if_nesting) {
  1302. cerr << "Misplaced #end or #endif.\n";
  1303. okflag = false;
  1304. }
  1305. return okflag;
  1306. }
  1307. ////////////////////////////////////////////////////////////////////
  1308. // Function: PPCommandFile::replay_foreach
  1309. // Access: Protected
  1310. // Description: Replays all the lines that were saved during a
  1311. // previous #foreach..#end block.
  1312. ////////////////////////////////////////////////////////////////////
  1313. bool PPCommandFile::
  1314. replay_foreach(const string &varname, const vector<string> &words) {
  1315. assert(!_in_for);
  1316. bool okflag = true;
  1317. vector<string> lines;
  1318. lines.swap(_saved_lines);
  1319. // Remove the #end command. This will fail if someone makes an #end
  1320. // command that spans multiple lines. Don't do that.
  1321. assert(!lines.empty());
  1322. lines.pop_back();
  1323. // Now traverse through the saved words.
  1324. BlockNesting *saved_block = _block_nesting;
  1325. IfNesting *saved_if = _if_nesting;
  1326. vector<string>::const_iterator wi;
  1327. for (wi = words.begin(); wi != words.end() && okflag; ++wi) {
  1328. _scope->define_variable(varname, (*wi));
  1329. vector<string>::const_iterator li;
  1330. for (li = lines.begin(); li != lines.end() && okflag; ++li) {
  1331. okflag = read_line(*li);
  1332. }
  1333. }
  1334. if (saved_block != _block_nesting || saved_if != _if_nesting) {
  1335. cerr << "Misplaced #end or #endif.\n";
  1336. okflag = false;
  1337. }
  1338. return okflag;
  1339. }
  1340. ////////////////////////////////////////////////////////////////////
  1341. // Function: PPCommandFile::replay_formap
  1342. // Access: Protected
  1343. // Description: Replays all the lines that were saved during a
  1344. // previous #formap..#end block.
  1345. ////////////////////////////////////////////////////////////////////
  1346. bool PPCommandFile::
  1347. replay_formap(const string &varname, const string &mapvar) {
  1348. assert(!_in_for);
  1349. bool okflag = true;
  1350. vector<string> lines;
  1351. lines.swap(_saved_lines);
  1352. // Remove the #end command. This will fail if someone makes an #end
  1353. // command that spans multiple lines. Don't do that.
  1354. assert(!lines.empty());
  1355. lines.pop_back();
  1356. // Now look up the map variable.
  1357. PPScope::MapVariableDefinition &def = _scope->find_map_variable(mapvar);
  1358. if (&def == &PPScope::_null_map_def) {
  1359. cerr << "Undefined map variable: #formap " << varname << " "
  1360. << mapvar << "\n";
  1361. return false;
  1362. }
  1363. // Now traverse through the map definition.
  1364. BlockNesting *saved_block = _block_nesting;
  1365. IfNesting *saved_if = _if_nesting;
  1366. PPScope::MapVariableDefinition::const_iterator di;
  1367. for (di = def.begin(); di != def.end() && okflag; ++di) {
  1368. _scope->define_variable(varname, (*di).first);
  1369. PPScope::push_scope(_scope);
  1370. _scope = (*di).second;
  1371. vector<string>::const_iterator li;
  1372. for (li = lines.begin(); li != lines.end() && okflag; ++li) {
  1373. okflag = read_line(*li);
  1374. }
  1375. _scope = PPScope::pop_scope();
  1376. }
  1377. if (saved_block != _block_nesting || saved_if != _if_nesting) {
  1378. cerr << "Misplaced #end or #endif.\n";
  1379. okflag = false;
  1380. }
  1381. return okflag;
  1382. }
  1383. ////////////////////////////////////////////////////////////////////
  1384. // Function: PPCommandFile::compare_output
  1385. // Access: Protected
  1386. // Description: After a file has been written to a (potentially
  1387. // large) string via an #output command, compare the
  1388. // results to the original file. If they are different,
  1389. // remove the original file and replace it with the new
  1390. // contents; otherwise, leave the original alone.
  1391. ////////////////////////////////////////////////////////////////////
  1392. bool PPCommandFile::
  1393. compare_output(const string &new_contents, Filename filename,
  1394. bool notouch) {
  1395. filename.set_text();
  1396. bool exists = filename.exists();
  1397. bool differ = false;
  1398. if (exists) {
  1399. size_t len = new_contents.length();
  1400. size_t want_bytes = len + 1;
  1401. char *orig_contents = new char[want_bytes];
  1402. ifstream in;
  1403. if (!filename.open_read(in)) {
  1404. cerr << "Cannot read existing " << filename << ", regenerating.\n";
  1405. differ = true;
  1406. } else {
  1407. in.read(orig_contents, want_bytes);
  1408. if (in.gcount() != len) {
  1409. // The wrong number of bytes.
  1410. differ = true;
  1411. } else {
  1412. differ = !(new_contents == string(orig_contents, len));
  1413. }
  1414. }
  1415. }
  1416. if (differ || !exists) {
  1417. #ifndef WIN32_VC
  1418. if (verbose_dry_run) {
  1419. // Write our new contents to a file so we can run diff on both
  1420. // of them.
  1421. Filename temp_filename = filename.get_fullpath() + string(".ppd");
  1422. temp_filename.set_text();
  1423. ofstream out_b;
  1424. if (!temp_filename.open_write(out_b)) {
  1425. cerr << "Unable to open temporary file " << filename << " for writing.\n";
  1426. return false;
  1427. }
  1428. out_b.write(new_contents.data(), new_contents.length());
  1429. bool diff_ok = true;
  1430. if (!out_b) {
  1431. cerr << "Unable to write to temporary file " << filename << "\n";
  1432. diff_ok = true;
  1433. }
  1434. out_b.close();
  1435. string command = "diff -ub '" + filename.get_fullpath() + "' '" +
  1436. temp_filename.get_fullpath() + "'";
  1437. int sys_result = system(command.c_str());
  1438. if (sys_result < 0) {
  1439. cerr << "Unable to invoke diff\n";
  1440. diff_ok = false;
  1441. }
  1442. out_b.close();
  1443. temp_filename.unlink();
  1444. return diff_ok;
  1445. } else
  1446. #endif
  1447. if (dry_run) {
  1448. cerr << "Would generate " << filename << "\n";
  1449. } else {
  1450. cerr << "Generating " << filename << "\n";
  1451. if (exists) {
  1452. if (!filename.unlink()) {
  1453. cerr << "Unable to remove old " << filename << "\n";
  1454. return false;
  1455. }
  1456. }
  1457. ofstream out_b;
  1458. if (!filename.open_write(out_b)) {
  1459. cerr << "Unable to open file " << filename << " for writing.\n";
  1460. return false;
  1461. }
  1462. out_b.write(new_contents.data(), new_contents.length());
  1463. if (!out_b) {
  1464. cerr << "Unable to write to file " << filename << "\n";
  1465. return false;
  1466. }
  1467. out_b.close();
  1468. }
  1469. } else {
  1470. // Even though the file is unchanged, unless the "notouch" flag is
  1471. // set, we want to update the modification time. This helps the
  1472. // makefiles know we did something.
  1473. if (!notouch && !dry_run) {
  1474. if (!filename.touch()) {
  1475. cerr << "Warning: unable to update timestamp for " << filename << "\n";
  1476. }
  1477. }
  1478. }
  1479. return true;
  1480. }
  1481. ////////////////////////////////////////////////////////////////////
  1482. // Function: PPCommandFile::failed_if
  1483. // Access: Protected
  1484. // Description: Returns true if we are currently within a failed #if
  1485. // block (or in an #else block for a passed #if block),
  1486. // or false otherwise.
  1487. ////////////////////////////////////////////////////////////////////
  1488. bool PPCommandFile::
  1489. failed_if() const {
  1490. return (_if_nesting != (IfNesting *)NULL &&
  1491. (_if_nesting->_state == IS_off || _if_nesting->_state == IS_done));
  1492. }
  1493. ////////////////////////////////////////////////////////////////////
  1494. // Function: PPCommandFile::is_valid_formal_parameter_name
  1495. // Access: Protected
  1496. // Description: Returns true if the indicated name is an acceptable
  1497. // name for a formal parameter. This means it includes
  1498. // no whitespace or crazy punctuation. Mainly this is
  1499. // to protect the user from making some stupid syntax
  1500. // mistake.
  1501. ////////////////////////////////////////////////////////////////////
  1502. bool PPCommandFile::
  1503. is_valid_formal(const string &formal_parameter_name) const {
  1504. if (formal_parameter_name.empty()) {
  1505. return false;
  1506. }
  1507. string::const_iterator si;
  1508. for (si = formal_parameter_name.begin();
  1509. si != formal_parameter_name.end();
  1510. ++si) {
  1511. switch (*si) {
  1512. case ' ':
  1513. case '\n':
  1514. case '\t':
  1515. case '$':
  1516. case '[':
  1517. case ']':
  1518. case ',':
  1519. return false;
  1520. }
  1521. }
  1522. return true;
  1523. }
  1524. ////////////////////////////////////////////////////////////////////
  1525. // Function: PPCommandFile::PushFilename::Constructor
  1526. // Access: Public
  1527. // Description: This special class changes the current filename of
  1528. // the PPCommandFile. The idea is to create one of
  1529. // these when the filename is changed (for instance, to
  1530. // read in a new file via an #include directive); when
  1531. // the variable then goes out of scope, it will restore
  1532. // the previous filename.
  1533. //
  1534. // This updates the scope with the appropriate
  1535. // variables.
  1536. ////////////////////////////////////////////////////////////////////
  1537. PPCommandFile::PushFilename::
  1538. PushFilename(PPScope *scope, const string &filename) {
  1539. _scope = scope;
  1540. _old_thisdirprefix = _scope->get_variable("THISDIRPREFIX");
  1541. _old_thisfilename = _scope->get_variable("THISFILENAME");
  1542. string thisfilename = filename;
  1543. string thisdirprefix;
  1544. size_t slash = filename.rfind('/');
  1545. if (slash == string::npos) {
  1546. thisdirprefix = string();
  1547. } else {
  1548. thisdirprefix = filename.substr(0, slash + 1);
  1549. }
  1550. _scope->define_variable("THISFILENAME", thisfilename);
  1551. _scope->define_variable("THISDIRPREFIX", thisdirprefix);
  1552. }
  1553. ////////////////////////////////////////////////////////////////////
  1554. // Function: PPCommandFile::PushFilename::Destructor
  1555. // Access: Public
  1556. // Description:
  1557. ////////////////////////////////////////////////////////////////////
  1558. PPCommandFile::PushFilename::
  1559. ~PushFilename() {
  1560. _scope->define_variable("THISFILENAME", _old_thisfilename);
  1561. _scope->define_variable("THISDIRPREFIX", _old_thisdirprefix);
  1562. }