ppCommandFile.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. // Filename: ppCommandFile.h
  2. // Created by: drose (25Sep00)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. #ifndef PPCOMMANDFILE_H
  6. #define PPCOMMANDFILE_H
  7. #include "ppremake.h"
  8. #include "filename.h"
  9. #include <map>
  10. #include <vector>
  11. class PPScope;
  12. ///////////////////////////////////////////////////////////////////
  13. // Class : PPCommandFile
  14. // Description : This encapsulates a file that contains #commands to
  15. // execute (like #define, #if, #begin .. #end),
  16. // $[variables] to expand, and plain text to output.
  17. ////////////////////////////////////////////////////////////////////
  18. class PPCommandFile {
  19. public:
  20. PPCommandFile(PPScope *scope);
  21. ~PPCommandFile();
  22. void set_output(ostream *out);
  23. void set_scope(PPScope *scope);
  24. PPScope *get_scope() const;
  25. bool read_file(Filename filename);
  26. bool read_stream(istream &in, const string &filename);
  27. bool read_stream(istream &in);
  28. void begin_read();
  29. bool read_line(string line);
  30. bool end_read();
  31. protected:
  32. bool handle_command(const string &line);
  33. bool handle_if_command();
  34. bool handle_elif_command();
  35. bool handle_else_command();
  36. bool handle_endif_command();
  37. bool handle_begin_command();
  38. bool handle_while_command();
  39. bool handle_for_command();
  40. bool handle_forscopes_command();
  41. bool handle_foreach_command();
  42. bool handle_formap_command();
  43. bool handle_defsub_command(bool is_defsub);
  44. bool handle_output_command();
  45. bool handle_end_command();
  46. bool handle_format_command();
  47. bool handle_print_command();
  48. bool handle_printvar_command();
  49. bool handle_include_command();
  50. bool handle_sinclude_command();
  51. bool handle_copy_command();
  52. bool handle_call_command();
  53. bool handle_error_command();
  54. bool handle_mkdir_command();
  55. bool handle_defer_command();
  56. bool handle_define_command();
  57. bool handle_set_command();
  58. bool handle_map_command();
  59. bool handle_addmap_command();
  60. bool handle_push_command();
  61. bool include_file(Filename filename);
  62. bool replay_while(const string &name);
  63. bool replay_for(const string &name, const vector<string> &words);
  64. bool replay_forscopes(const string &name);
  65. bool replay_foreach(const string &varname, const vector<string> &words);
  66. bool replay_formap(const string &varname, const string &mapvar);
  67. bool compare_output(const string &new_contents, Filename filename,
  68. bool notouch, bool binary);
  69. bool failed_if() const;
  70. bool is_valid_formal(const string &formal_parameter_name) const;
  71. private:
  72. class PushFilename {
  73. public:
  74. PushFilename(PPScope *scope, const string &filename);
  75. ~PushFilename();
  76. PPScope *_scope;
  77. string _old_thisdirprefix;
  78. string _old_thisfilename;
  79. };
  80. private:
  81. class BlockNesting;
  82. enum IfState {
  83. IS_on, // e.g. a passed #if
  84. IS_else, // after matching an #else
  85. IS_off, // e.g. a failed #if
  86. IS_done // e.g. after reaching an #else or #elif for a passed #if.
  87. };
  88. class IfNesting {
  89. public:
  90. IfNesting(IfState state);
  91. void push(PPCommandFile *file);
  92. void pop(PPCommandFile *file);
  93. IfState _state;
  94. BlockNesting *_block;
  95. IfNesting *_next;
  96. };
  97. enum BlockState {
  98. BS_begin,
  99. BS_while,
  100. BS_nested_while,
  101. BS_for,
  102. BS_nested_for,
  103. BS_forscopes,
  104. BS_nested_forscopes,
  105. BS_foreach,
  106. BS_nested_foreach,
  107. BS_formap,
  108. BS_nested_formap,
  109. BS_defsub,
  110. BS_defun,
  111. BS_output
  112. };
  113. enum WriteFormat {
  114. WF_error, // anything other than whitespace is an error.
  115. WF_straight, // write lines directly as they come in
  116. WF_collapse, // collapse out consecutive blank lines
  117. WF_makefile // fancy makefile formatting
  118. };
  119. class WriteState {
  120. public:
  121. WriteState();
  122. WriteState(const WriteState &copy);
  123. bool write_line(const string &line);
  124. bool write_collapse_line(const string &line);
  125. bool write_makefile_line(const string &line);
  126. ostream *_out;
  127. WriteFormat _format;
  128. bool _last_blank;
  129. };
  130. enum OutputFlags {
  131. OF_notouch = 0x001,
  132. OF_binary = 0x002,
  133. };
  134. class BlockNesting {
  135. public:
  136. BlockNesting(BlockState state, const string &name);
  137. void push(PPCommandFile *file);
  138. void pop(PPCommandFile *file);
  139. BlockState _state;
  140. string _name;
  141. IfNesting *_if;
  142. WriteState *_write_state;
  143. PPScope *_scope;
  144. string _params;
  145. #ifdef HAVE_SSTREAM
  146. ostringstream _output;
  147. #else
  148. ostrstream _output;
  149. #endif
  150. vector<string> _words;
  151. int _flags;
  152. BlockNesting *_next;
  153. };
  154. PPScope *_native_scope;
  155. PPScope *_scope;
  156. bool _got_command;
  157. bool _in_for;
  158. IfNesting *_if_nesting;
  159. BlockNesting *_block_nesting;
  160. string _command;
  161. string _params;
  162. WriteState *_write_state;
  163. vector<string> _saved_lines;
  164. friend class PPCommandFile::IfNesting;
  165. friend class PPCommandFile::WriteState;
  166. friend class PPCommandFile::BlockNesting;
  167. };
  168. #endif