ppDirectory.cxx 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961
  1. // Filename: ppDirectory.cxx
  2. // Created by: drose (28Sep00)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. #include "ppDirectory.h"
  6. #include "ppDirectoryTree.h"
  7. #include "ppScope.h"
  8. #include "ppNamedScopes.h"
  9. #include "ppCommandFile.h"
  10. #include "ppDependableFile.h"
  11. #include "tokenize.h"
  12. #include "ppremake.h"
  13. #ifdef HAVE_DIRENT_H
  14. #include <dirent.h>
  15. #endif
  16. #ifdef HAVE_UNISTD_H
  17. #include <unistd.h>
  18. #endif
  19. #ifdef HAVE_SYS_TYPES_H
  20. #include <sys/types.h>
  21. #endif
  22. #include <sys/stat.h>
  23. #include <algorithm>
  24. #include <assert.h>
  25. #ifdef WIN32_VC
  26. #include <direct.h>
  27. #include <windows.h>
  28. #endif
  29. // How new must a pp.dep cache file be before we will believe it?
  30. static const int max_cache_minutes = 60;
  31. PPDirectory *current_output_directory = (PPDirectory *)NULL;
  32. // An STL object to sort directories in order by dependency and then
  33. // by name, used in get_child_dirnames().
  34. class SortDirectoriesByDependencyAndName {
  35. public:
  36. bool operator () (const PPDirectory *a, const PPDirectory *b) const {
  37. if (a->get_depends_index() != b->get_depends_index()) {
  38. return a->get_depends_index() < b->get_depends_index();
  39. }
  40. return a->get_dirname() < b->get_dirname();
  41. }
  42. };
  43. ////////////////////////////////////////////////////////////////////
  44. // Function: PPDirectory::Constructor
  45. // Access: Public
  46. // Description: Creates the root directory.
  47. ////////////////////////////////////////////////////////////////////
  48. PPDirectory::
  49. PPDirectory(PPDirectoryTree *tree) {
  50. _scope = (PPScope *)NULL;
  51. _source = (PPCommandFile *)NULL;
  52. _parent = (PPDirectory *)NULL;
  53. _tree = tree;
  54. _depth = 0;
  55. _depends_index = 0;
  56. _computing_depends_index = false;
  57. _dirname = "top";
  58. _tree->_dirnames.insert(PPDirectoryTree::Dirnames::value_type(_dirname, this));
  59. }
  60. ////////////////////////////////////////////////////////////////////
  61. // Function: PPDirectory::Constructor
  62. // Access: Public
  63. // Description: Creates a new directory level that automatically adds
  64. // itself to its parent's children list.
  65. ////////////////////////////////////////////////////////////////////
  66. PPDirectory::
  67. PPDirectory(const string &dirname, PPDirectory *parent) :
  68. _dirname(dirname),
  69. _parent(parent)
  70. {
  71. assert(_parent != (PPDirectory *)NULL);
  72. _scope = (PPScope *)NULL;
  73. _source = (PPCommandFile *)NULL;
  74. _parent->_children.push_back(this);
  75. _tree = _parent->_tree;
  76. _depth = _parent->_depth + 1;
  77. _depends_index = 0;
  78. _computing_depends_index = false;
  79. bool inserted =
  80. _tree->_dirnames.insert(PPDirectoryTree::Dirnames::value_type(_dirname, this)).second;
  81. if (!inserted) {
  82. cerr << "Warning: multiple directories encountered named "
  83. << _dirname << "\n";
  84. }
  85. }
  86. ////////////////////////////////////////////////////////////////////
  87. // Function: PPDirectory::Destructor
  88. // Access: Public
  89. // Description: When a tree root destructs, all of its children are
  90. // also destroyed.
  91. ////////////////////////////////////////////////////////////////////
  92. PPDirectory::
  93. ~PPDirectory() {
  94. Children::iterator ci;
  95. for (ci = _children.begin(); ci != _children.end(); ++ci) {
  96. delete (*ci);
  97. }
  98. }
  99. ////////////////////////////////////////////////////////////////////
  100. // Function: PPDirectory::get_tree
  101. // Access: Public
  102. // Description: Returns the PPDirectoryTree object corresponding to
  103. // the source tree that this directory is a part of.
  104. ////////////////////////////////////////////////////////////////////
  105. PPDirectoryTree *PPDirectory::
  106. get_tree() const {
  107. return _tree;
  108. }
  109. ////////////////////////////////////////////////////////////////////
  110. // Function: PPDirectory::count_source_files
  111. // Access: Public
  112. // Description: Returns the number of directories within the tree
  113. // that actually have a Sources.pp file that was read.
  114. ////////////////////////////////////////////////////////////////////
  115. int PPDirectory::
  116. count_source_files() const {
  117. int count = 0;
  118. if (_source != (PPCommandFile *)NULL) {
  119. count++;
  120. }
  121. Children::const_iterator ci;
  122. for (ci = _children.begin(); ci != _children.end(); ++ci) {
  123. count += (*ci)->count_source_files();
  124. }
  125. return count;
  126. }
  127. ////////////////////////////////////////////////////////////////////
  128. // Function: PPDirectory::get_dirname
  129. // Access: Public
  130. // Description: Returns the name of this particular directory level.
  131. ////////////////////////////////////////////////////////////////////
  132. const string &PPDirectory::
  133. get_dirname() const {
  134. return _dirname;
  135. }
  136. ////////////////////////////////////////////////////////////////////
  137. // Function: PPDirectory::get_depends_index
  138. // Access: Public
  139. // Description: Returns the dependency index associated with this
  140. // directory. It is generally true that if directory A
  141. // depends on B, then A.get_depends_index() >
  142. // B.get_depends_index().
  143. ////////////////////////////////////////////////////////////////////
  144. int PPDirectory::
  145. get_depends_index() const {
  146. return _depends_index;
  147. }
  148. ////////////////////////////////////////////////////////////////////
  149. // Function: PPDirectory::get_path
  150. // Access: Public
  151. // Description: Returns the relative path from the root to this
  152. // particular directory. This does not include the root
  153. // name itself, and does not include a trailing slash.
  154. ////////////////////////////////////////////////////////////////////
  155. string PPDirectory::
  156. get_path() const {
  157. if (_parent == (PPDirectory *)NULL) {
  158. return ".";
  159. }
  160. if (_parent->_parent == (PPDirectory *)NULL) {
  161. return _dirname;
  162. }
  163. return _parent->get_path() + "/" + _dirname;
  164. }
  165. ////////////////////////////////////////////////////////////////////
  166. // Function: PPDirectory::get_fullpath
  167. // Access: Public
  168. // Description: Returns the full path to this particular directory.
  169. // This does not include a trailing slash.
  170. ////////////////////////////////////////////////////////////////////
  171. string PPDirectory::
  172. get_fullpath() const {
  173. if (_parent == (PPDirectory *)NULL) {
  174. return _tree->get_fullpath();
  175. }
  176. return _tree->get_fullpath() + "/" + get_path();
  177. }
  178. ////////////////////////////////////////////////////////////////////
  179. // Function: PPDirectory::get_rel_to
  180. // Access: Public
  181. // Description: Returns the relative path to the other directory from
  182. // this one. This does not include a trailing slash.
  183. ////////////////////////////////////////////////////////////////////
  184. string PPDirectory::
  185. get_rel_to(const PPDirectory *other) const {
  186. const PPDirectory *a = this;
  187. const PPDirectory *b = other;
  188. if (a == b) {
  189. return ".";
  190. }
  191. if (a->_tree != b->_tree) {
  192. // If they're in different trees, just return the full path to b.
  193. return b->get_fullpath();
  194. }
  195. string prefix, postfix;
  196. while (a->_depth > b->_depth) {
  197. prefix += "../";
  198. a = a->_parent;
  199. assert(a != (PPDirectory *)NULL);
  200. }
  201. while (b->_depth > a->_depth) {
  202. postfix = b->_dirname + "/" + postfix;
  203. b = b->_parent;
  204. assert(b != (PPDirectory *)NULL);
  205. }
  206. while (a != b) {
  207. prefix += "../";
  208. postfix = b->_dirname + "/" + postfix;
  209. a = a->_parent;
  210. b = b->_parent;
  211. assert(a != (PPDirectory *)NULL);
  212. assert(b != (PPDirectory *)NULL);
  213. }
  214. string result = prefix + postfix;
  215. assert(!result.empty());
  216. return result.substr(0, result.length() - 1);
  217. }
  218. ////////////////////////////////////////////////////////////////////
  219. // Function: PPDirectory::get_source
  220. // Access: Public
  221. // Description: Returns the source file associated with this level
  222. // of the directory hierarchy. This *might* be NULL.
  223. ////////////////////////////////////////////////////////////////////
  224. PPCommandFile *PPDirectory::
  225. get_source() const {
  226. return _source;
  227. }
  228. ////////////////////////////////////////////////////////////////////
  229. // Function: PPDirectory::get_num_children
  230. // Access: Public
  231. // Description: Returns the number of subdirectories below this
  232. // level.
  233. ////////////////////////////////////////////////////////////////////
  234. int PPDirectory::
  235. get_num_children() const {
  236. return _children.size();
  237. }
  238. ////////////////////////////////////////////////////////////////////
  239. // Function: PPDirectory::get_child
  240. // Access: Public
  241. // Description: Returns the nth subdirectory below this level.
  242. ////////////////////////////////////////////////////////////////////
  243. PPDirectory *PPDirectory::
  244. get_child(int n) const {
  245. assert(n >= 0 && n < (int)_children.size());
  246. return _children[n];
  247. }
  248. ////////////////////////////////////////////////////////////////////
  249. // Function: PPDirectory::get_child_dirnames
  250. // Access: Public
  251. // Description: Returns a single string listing the names of all the
  252. // subdirectories of this level, delimited by spaces.
  253. //
  254. // The list is sorted in dependency order such that a
  255. // directory is listed after the other directories it
  256. // might depend on.
  257. ////////////////////////////////////////////////////////////////////
  258. string PPDirectory::
  259. get_child_dirnames() const {
  260. Children copy_children = _children;
  261. sort(copy_children.begin(), copy_children.end(),
  262. SortDirectoriesByDependencyAndName());
  263. vector<string> words;
  264. Children::const_iterator ci;
  265. for (ci = copy_children.begin(); ci != copy_children.end(); ++ci) {
  266. words.push_back((*ci)->get_dirname());
  267. }
  268. string result = repaste(words, " ");
  269. return result;
  270. }
  271. ////////////////////////////////////////////////////////////////////
  272. // Function: PPDirectory::get_complete_subtree
  273. // Access: Public
  274. // Description: Returns a single string listing the relative path
  275. // from the source root to each source directory at this
  276. // level and below, delimited by spaces.
  277. ////////////////////////////////////////////////////////////////////
  278. string PPDirectory::
  279. get_complete_subtree() const {
  280. Children copy_children = _children;
  281. sort(copy_children.begin(), copy_children.end(),
  282. SortDirectoriesByDependencyAndName());
  283. vector<string> words;
  284. words.push_back(get_path());
  285. Children::const_iterator ci;
  286. for (ci = copy_children.begin(); ci != copy_children.end(); ++ci) {
  287. words.push_back((*ci)->get_complete_subtree());
  288. }
  289. string result = repaste(words, " ");
  290. return result;
  291. }
  292. ////////////////////////////////////////////////////////////////////
  293. // Function: PPDirectory::get_dependable_file
  294. // Access: Public
  295. // Description: Returns a PPDependableFile object corresponding to
  296. // the named filename, creating one if it does not
  297. // already exist. This can be used to determine the
  298. // inter-file dependencies between source files.
  299. //
  300. // If is_header is true, then the file will be added to
  301. // the index at the top of the directory tree, so that
  302. // other directories may include this file. In this
  303. // case, if the filename is not unique, a warning
  304. // message will be issued.
  305. ////////////////////////////////////////////////////////////////////
  306. PPDependableFile *PPDirectory::
  307. get_dependable_file(const string &filename, bool is_header) {
  308. Dependables::iterator di;
  309. di = _dependables.find(filename);
  310. if (di != _dependables.end()) {
  311. return (*di).second;
  312. }
  313. // No such file found; create a new definition.
  314. PPDependableFile *dependable = new PPDependableFile(this, filename);
  315. _dependables.insert(Dependables::value_type(filename, dependable));
  316. if (is_header) {
  317. PPDirectoryTree *main_tree = _tree->get_main_tree();
  318. bool unique = main_tree->_dependables.insert
  319. (PPDirectoryTree::Dependables::value_type(filename, dependable)).second;
  320. if (!unique) {
  321. PPDependableFile *other = main_tree->find_dependable_file(filename);
  322. if (_tree != main_tree &&
  323. other->get_directory()->get_tree() != main_tree) {
  324. // Both files are in external dependable trees.
  325. cerr << "Error: header file " << dependable->get_fullpath()
  326. << " may be confused with " << other->get_fullpath()
  327. << ".\n";
  328. errors_occurred = true;
  329. } else if (other->get_directory()->get_tree() != _tree) {
  330. // This file is a source file in this tree, while the other
  331. // one is an external file. This is not a warning condition,
  332. // since maybe we've already installed the source file to the
  333. // global install directory on some previous build.
  334. } else {
  335. // Both files are within the same source tree.
  336. cerr << "Error: source file " << dependable->get_pathname()
  337. << " may be confused with " << other->get_pathname()
  338. << ".\n";
  339. errors_occurred = true;
  340. }
  341. }
  342. }
  343. return dependable;
  344. }
  345. ////////////////////////////////////////////////////////////////////
  346. // Function: PPDirectory::report_depends
  347. // Access: Public
  348. // Description: Reports all the directories that the current
  349. // directory depends on.
  350. ////////////////////////////////////////////////////////////////////
  351. void PPDirectory::
  352. report_depends() const {
  353. if (_i_depend_on.empty()) {
  354. cerr << _dirname << " depends on no other directories.\n";
  355. } else {
  356. // Get the complete set of directories we depend on.
  357. Depends dep;
  358. get_complete_i_depend_on(dep);
  359. cerr << _dirname << " depends directly on the following directories:";
  360. show_directories(_i_depend_on);
  361. cerr << "and directly or indirectly on the following directories:";
  362. show_directories(dep);
  363. }
  364. }
  365. ////////////////////////////////////////////////////////////////////
  366. // Function: PPDirectory::report_reverse_depends
  367. // Access: Public
  368. // Description: Reports all the directories that depend on the
  369. // current directory.
  370. ////////////////////////////////////////////////////////////////////
  371. void PPDirectory::
  372. report_reverse_depends() const {
  373. if (_depends_on_me.empty()) {
  374. cerr << _dirname << " is needed by no other directories.\n";
  375. } else {
  376. // Get the complete set of directories we depend on.
  377. Depends dep;
  378. get_complete_depends_on_me(dep);
  379. cerr << _dirname << " is needed directly by the following directories:";
  380. show_directories(_depends_on_me);
  381. cerr << "and directly or indirectly by the following directories:";
  382. show_directories(dep);
  383. }
  384. }
  385. ////////////////////////////////////////////////////////////////////
  386. // Function: PPDirectory::r_scan
  387. // Access: Private
  388. // Description: The recursive implementation of
  389. // PPDirectoryTree::scan_source().
  390. ////////////////////////////////////////////////////////////////////
  391. bool PPDirectory::
  392. r_scan(const string &prefix) {
  393. Filename root_name = ".";
  394. if (!prefix.empty()) {
  395. root_name = prefix.substr(0, prefix.length() - 1);
  396. }
  397. // Collect all the filenames in the directory in this vector first.
  398. vector<string> filenames;
  399. if (!root_name.scan_directory(filenames)) {
  400. cerr << "Unable to scan directory " << root_name << "\n";
  401. return false;
  402. }
  403. vector<string>::const_iterator fi;
  404. for (fi = filenames.begin(); fi != filenames.end(); ++fi) {
  405. string filename = (*fi);
  406. if (!filename.empty() && filename[0] != '.') {
  407. // Is this possibly a subdirectory with its own Sources.pp
  408. // within it?
  409. string next_prefix = prefix + filename + "/";
  410. Filename source_filename = next_prefix + SOURCE_FILENAME;
  411. if (source_filename.exists()) {
  412. PPDirectory *subtree = new PPDirectory(filename, this);
  413. if (!subtree->r_scan(next_prefix)) {
  414. return false;
  415. }
  416. }
  417. }
  418. }
  419. return true;
  420. }
  421. ////////////////////////////////////////////////////////////////////
  422. // Function: PPDirectory::scan_extra_depends
  423. // Access: Private
  424. // Description: The recursive implementation of
  425. // PPDirectoryTree::scan_extra_depends(). This simply
  426. // adds each *.h or *.I file in the directory as a
  427. // dependable file. It is assumed to be called for an
  428. // external directory named by DEPENDABLE_HEADER_DIRS.
  429. ////////////////////////////////////////////////////////////////////
  430. bool PPDirectory::
  431. scan_extra_depends(const string &cache_filename) {
  432. Filename root_name = get_fullpath();
  433. vector<string> filenames;
  434. if (!root_name.scan_directory(filenames)) {
  435. cerr << "Unable to scan directory " << root_name << "\n";
  436. return false;
  437. }
  438. if (verbose) {
  439. cerr << "Scanning external directory " << get_fullpath() << "\n";
  440. }
  441. vector<string>::const_iterator fi;
  442. for (fi = filenames.begin(); fi != filenames.end(); ++fi) {
  443. string filename = (*fi);
  444. if (!filename.empty() && filename[0] != '.' &&
  445. filename != string("CVS") &&
  446. filename != cache_filename) {
  447. get_dependable_file(filename, true);
  448. }
  449. }
  450. return true;
  451. }
  452. ////////////////////////////////////////////////////////////////////
  453. // Function: PPDirectory::read_source_file
  454. // Access: Private
  455. // Description: Recursively reads in the source file at each level,
  456. // if defined.
  457. ////////////////////////////////////////////////////////////////////
  458. bool PPDirectory::
  459. read_source_file(const string &prefix, PPNamedScopes *named_scopes) {
  460. Filename source_filename = prefix + SOURCE_FILENAME;
  461. source_filename.set_text();
  462. ifstream in;
  463. if (source_filename.open_read(in)) {
  464. if (verbose) {
  465. cerr << "Reading (dir) \"" << source_filename << "\"\n";
  466. }
  467. named_scopes->set_current(_dirname);
  468. _scope = named_scopes->make_scope("");
  469. _scope->define_variable("SOURCEFILE", SOURCE_FILENAME);
  470. _scope->define_variable("DIRNAME", _dirname);
  471. _scope->define_variable("DIRPREFIX", prefix);
  472. _scope->define_variable("PATH", get_path());
  473. _scope->define_variable("SUBDIRS", get_child_dirnames());
  474. _scope->define_variable("SUBTREE", get_complete_subtree());
  475. _scope->set_directory(this);
  476. _source = new PPCommandFile(_scope);
  477. if (!_source->read_stream(in, source_filename)) {
  478. return false;
  479. }
  480. }
  481. Children::iterator ci;
  482. for (ci = _children.begin(); ci != _children.end(); ++ci) {
  483. if (!(*ci)->read_source_file(prefix + (*ci)->get_dirname() + "/",
  484. named_scopes)) {
  485. return false;
  486. }
  487. }
  488. return true;
  489. }
  490. ////////////////////////////////////////////////////////////////////
  491. // Function: PPDirectory::read_depends_file
  492. // Access: Private
  493. // Description: Recursively reads in the dependency definition file
  494. // for each source file.
  495. ////////////////////////////////////////////////////////////////////
  496. bool PPDirectory::
  497. read_depends_file(PPNamedScopes *named_scopes) {
  498. if (_scope != (PPScope *)NULL) {
  499. // Read the depends file, so we can determine the relationship
  500. // between this source file and all of the other source files.
  501. string depends_filename = _scope->expand_variable("DEPENDS_FILE");
  502. if (depends_filename.empty()) {
  503. cerr << "No definition given for $[DEPENDS_FILE], cannot process.\n";
  504. return false;
  505. }
  506. named_scopes->set_current(_dirname);
  507. current_output_directory = this;
  508. PPCommandFile depends(_scope);
  509. if (!depends.read_file(depends_filename)) {
  510. cerr << "Error reading dependency definition file "
  511. << depends_filename << ".\n";
  512. return false;
  513. }
  514. // This should have defined the variable DEPEND_DIRS, which lists
  515. // the various dirnames this source file depends on.
  516. vector<string> dirnames;
  517. tokenize_whitespace(_scope->expand_variable("DEPEND_DIRS"), dirnames);
  518. vector<string>::const_iterator ni;
  519. for (ni = dirnames.begin(); ni != dirnames.end(); ++ni) {
  520. const string &dirname = (*ni);
  521. PPDirectory *dir = _tree->find_dirname(dirname);
  522. if (dir == (PPDirectory *)NULL) {
  523. cerr << "Could not find dependent dirname " << dirname << "\n";
  524. } else {
  525. if (dir != this) {
  526. _i_depend_on.insert(dir);
  527. dir->_depends_on_me.insert(this);
  528. }
  529. }
  530. }
  531. // This may also have defined the variable DEPENDABLE_HEADERS,
  532. // which lists the header files in this directory that C/C++
  533. // source files in this and other directories might be including
  534. // (and will therefore depend on).
  535. vector<string> headers;
  536. tokenize_whitespace(_scope->expand_variable("DEPENDABLE_HEADERS"), headers);
  537. for (ni = headers.begin(); ni != headers.end(); ++ni) {
  538. get_dependable_file(*ni, true);
  539. }
  540. }
  541. Children::iterator ci;
  542. for (ci = _children.begin(); ci != _children.end(); ++ci) {
  543. if (!(*ci)->read_depends_file(named_scopes)) {
  544. return false;
  545. }
  546. }
  547. return true;
  548. }
  549. ////////////////////////////////////////////////////////////////////
  550. // Function: PPDirectory::resolve_dependencies
  551. // Access: Private
  552. // Description: Visits each directory and assigns a correct
  553. // _depends_index to each one, such that if directory A
  554. // depends on directory B then A._depends_index >
  555. // B._depends_index.
  556. //
  557. // This also detects cycles in the directory dependency
  558. // graph.
  559. ////////////////////////////////////////////////////////////////////
  560. bool PPDirectory::
  561. resolve_dependencies() {
  562. if (!compute_depends_index()) {
  563. return false;
  564. }
  565. Children::iterator ci;
  566. for (ci = _children.begin(); ci != _children.end(); ++ci) {
  567. if (!(*ci)->resolve_dependencies()) {
  568. return false;
  569. }
  570. }
  571. // Now that we've resolved all of our children's dependencies,
  572. // redefine our SUBDIRS and SUBTREE variables to put things in the
  573. // right order.
  574. if (_scope != (PPScope *)NULL) {
  575. _scope->define_variable("SUBDIRS", get_child_dirnames());
  576. _scope->define_variable("SUBTREE", get_complete_subtree());
  577. }
  578. return true;
  579. }
  580. ////////////////////////////////////////////////////////////////////
  581. // Function: PPDirectory::compute_depends_index
  582. // Access: Private
  583. // Description: Computes the dependency score for a particular
  584. // directory. See resolve_dependencies().
  585. ////////////////////////////////////////////////////////////////////
  586. bool PPDirectory::
  587. compute_depends_index() {
  588. if (_depends_index != 0) {
  589. return true;
  590. }
  591. if (_i_depend_on.empty()) {
  592. _depends_index = 1;
  593. return true;
  594. }
  595. _computing_depends_index = true;
  596. int max_index = 0;
  597. Depends::iterator di;
  598. for (di = _i_depend_on.begin(); di != _i_depend_on.end(); ++di) {
  599. if ((*di)->_computing_depends_index) {
  600. // Oops, we have a cycle!
  601. cerr << "Cycle detected in inter-directory dependencies!\n"
  602. << _dirname << " depends on " << (*di)->_dirname << "\n";
  603. return false;
  604. }
  605. if (!(*di)->compute_depends_index()) {
  606. // Keep reporting the cycle as we unroll the recursion.
  607. cerr << _dirname << " depends on " << (*di)->_dirname << "\n";
  608. return false;
  609. }
  610. max_index = max(max_index, (*di)->_depends_index);
  611. }
  612. _computing_depends_index = false;
  613. _depends_index = max_index + 1;
  614. return true;
  615. }
  616. ////////////////////////////////////////////////////////////////////
  617. // Function: PPDirectory::read_file_dependencies
  618. // Access: Private
  619. // Description: Before processing the source files, makes a pass and
  620. // reads in all of the dependency cache files so we'll
  621. // have a heads-up on which files depend on the others.
  622. ////////////////////////////////////////////////////////////////////
  623. void PPDirectory::
  624. read_file_dependencies(const string &cache_filename) {
  625. // Open up the dependency cache file in the directory.
  626. Filename cache_pathname(get_fullpath(), cache_filename);
  627. cache_pathname.set_text();
  628. ifstream in;
  629. // Does the cache file exist, and is it recent enough? We don't
  630. // trust old cache files on principle.
  631. string os_specific = cache_pathname.to_os_specific();
  632. time_t now = time(NULL);
  633. #ifdef WIN32_VC
  634. struct _stat this_buf;
  635. bool this_exists = false;
  636. if (_stat(os_specific.c_str(), &this_buf) == 0) {
  637. this_exists = true;
  638. }
  639. #else // WIN32_VC
  640. struct stat this_buf;
  641. bool this_exists = false;
  642. if (stat(os_specific.c_str(), &this_buf) == 0) {
  643. this_exists = true;
  644. }
  645. #endif
  646. if (!this_exists) {
  647. // The cache file doesn't exist. That's OK.
  648. if (verbose) {
  649. cerr << "No cache file: \"" << cache_pathname << "\"\n";
  650. }
  651. } else if (this_buf.st_mtime < now - 60 * max_cache_minutes) {
  652. // It exists, but it's too old.
  653. if (verbose) {
  654. cerr << "Cache file too old: \"" << cache_pathname << "\"\n";
  655. }
  656. } else {
  657. // It exists and is new enough; use it.
  658. if (!cache_pathname.open_read(in)) {
  659. cerr << "Couldn't read \"" << cache_pathname << "\"\n";
  660. } else {
  661. if (verbose) {
  662. cerr << "Loading cache \"" << cache_pathname << "\"\n";
  663. }
  664. bool okcache = true;
  665. string line;
  666. getline(in, line);
  667. while (!in.fail() && !in.eof()) {
  668. vector<string> words;
  669. tokenize_whitespace(line, words);
  670. if (words.size() >= 2) {
  671. PPDependableFile *file = get_dependable_file(words[0], false);
  672. if (!file->update_from_cache(words)) {
  673. // Hey, we asked for an invalid or absent file. Phooey.
  674. // Invalidate the cache, and also make sure that this
  675. // particular file (which maybe doesn't even exist) isn't
  676. // mentioned in the cache file any more.
  677. Dependables::iterator di;
  678. di = _dependables.find(words[0]);
  679. if (di != _dependables.end()) {
  680. _dependables.erase(di);
  681. }
  682. okcache = false;
  683. break;
  684. }
  685. }
  686. getline(in, line);
  687. }
  688. if (!okcache) {
  689. if (verbose) {
  690. cerr << "Cache \"" << cache_pathname << "\" is stale.\n";
  691. }
  692. Dependables::iterator di;
  693. for (di = _dependables.begin(); di != _dependables.end(); ++di) {
  694. (*di).second->clear_cache();
  695. }
  696. }
  697. }
  698. }
  699. Children::iterator ci;
  700. for (ci = _children.begin(); ci != _children.end(); ++ci) {
  701. (*ci)->read_file_dependencies(cache_filename);
  702. }
  703. }
  704. ////////////////////////////////////////////////////////////////////
  705. // Function: PPDirectory::update_file_dependencies
  706. // Access: Private
  707. // Description: After all source processing has completed, makes one
  708. // more pass through the directory hierarchy and writes
  709. // out the inter-file dependency cache.
  710. ////////////////////////////////////////////////////////////////////
  711. void PPDirectory::
  712. update_file_dependencies(const string &cache_filename) {
  713. if (dry_run) {
  714. // If this is just a dry run, just report circularities.
  715. Dependables::const_iterator di;
  716. for (di = _dependables.begin(); di != _dependables.end(); ++di) {
  717. PPDependableFile *file = (*di).second;
  718. if (file->was_examined()) {
  719. if (file->is_circularity()) {
  720. cerr << "Warning: circular #include directives:\n"
  721. << " " << file->get_circularity() << "\n";
  722. }
  723. }
  724. }
  725. } else {
  726. // Open up the dependency cache file in the directory.
  727. Filename cache_pathname(get_fullpath(), cache_filename);
  728. cache_pathname.set_text();
  729. cache_pathname.unlink();
  730. // If we have no files, don't bother writing the cache.
  731. bool wrote_anything = false;
  732. if (!_dependables.empty()) {
  733. ofstream out;
  734. if (!cache_pathname.open_write(out)) {
  735. cerr << "Cannot update cache dependency file " << cache_pathname << "\n";
  736. return;
  737. }
  738. if (verbose) {
  739. cerr << "Rewriting cache " << cache_pathname << "\n";
  740. }
  741. // Walk through our list of dependable files, writing them out the
  742. // the cache file.
  743. bool external_tree = (_tree->get_main_tree() != _tree);
  744. Dependables::const_iterator di;
  745. for (di = _dependables.begin(); di != _dependables.end(); ++di) {
  746. PPDependableFile *file = (*di).second;
  747. if (file->was_examined() || (external_tree && file->was_cached())) {
  748. if (file->is_circularity()) {
  749. cerr << "Warning: circular #include directives:\n"
  750. << " " << file->get_circularity() << "\n";
  751. }
  752. file->write_cache(out);
  753. wrote_anything = true;
  754. }
  755. }
  756. out.close();
  757. }
  758. if (!wrote_anything) {
  759. // Well, if we didn't write anything, remove the cache file
  760. // after all.
  761. cache_pathname.unlink();
  762. }
  763. }
  764. Children::iterator ci;
  765. for (ci = _children.begin(); ci != _children.end(); ++ci) {
  766. (*ci)->update_file_dependencies(cache_filename);
  767. }
  768. }
  769. ////////////////////////////////////////////////////////////////////
  770. // Function: PPDirectory::get_complete_i_depend_on
  771. // Access: Private
  772. // Description: Gets the transitive closure of i_depend_on. This
  773. // fills the given set (which must have been empty
  774. // before this call) with the complete set of all
  775. // directories this directory depends on, directly or
  776. // indirectly.
  777. ////////////////////////////////////////////////////////////////////
  778. void PPDirectory::
  779. get_complete_i_depend_on(Depends &dep) const {
  780. Depends::const_iterator di;
  781. for (di = _i_depend_on.begin(); di != _i_depend_on.end(); ++di) {
  782. PPDirectory *dir = (*di);
  783. bool inserted = dep.insert(dir).second;
  784. if (inserted) {
  785. dir->get_complete_i_depend_on(dep);
  786. }
  787. }
  788. }
  789. ////////////////////////////////////////////////////////////////////
  790. // Function: PPDirectory::get_complete_depends_on_me
  791. // Access: Private
  792. // Description: Gets the transitive closure of depends_on_me. This
  793. // fills the given set (which must have been empty
  794. // before this call) with the complete set of all
  795. // directories this that depend on this directory,
  796. // directly or indirectly.
  797. ////////////////////////////////////////////////////////////////////
  798. void PPDirectory::
  799. get_complete_depends_on_me(Depends &dep) const {
  800. Depends::const_iterator di;
  801. for (di = _depends_on_me.begin(); di != _depends_on_me.end(); ++di) {
  802. PPDirectory *dir = (*di);
  803. bool inserted = dep.insert(dir).second;
  804. if (inserted) {
  805. dir->get_complete_depends_on_me(dep);
  806. }
  807. }
  808. }
  809. ////////////////////////////////////////////////////////////////////
  810. // Function: PPDirectory::show_directories
  811. // Access: Private
  812. // Description: Writes a set of dependency directory names to
  813. // standard error. The output begins with a newline.
  814. ////////////////////////////////////////////////////////////////////
  815. void PPDirectory::
  816. show_directories(const PPDirectory::Depends &dep) const {
  817. // Copy the set into a vector, so we can sort it into a nice order
  818. // for the user's pleasure.
  819. vector<PPDirectory *> dirs;
  820. copy(dep.begin(), dep.end(),
  821. back_insert_iterator<vector<PPDirectory *> >(dirs));
  822. sort(dirs.begin(), dirs.end(), SortDirectoriesByDependencyAndName());
  823. static const int max_col = 72;
  824. int col = max_col;
  825. vector<PPDirectory *>::const_iterator di;
  826. for (di = dirs.begin(); di != dirs.end(); ++di) {
  827. const string &dirname = (*di)->_dirname;
  828. col += dirname.length() + 1;
  829. if (col >= max_col) {
  830. col = dirname.length() + 2;
  831. cerr << "\n " << dirname;
  832. } else {
  833. cerr << " " << dirname;
  834. }
  835. }
  836. cerr << "\n";
  837. }