ppCommandFile.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  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_call_command();
  52. bool handle_error_command();
  53. bool handle_mkdir_command();
  54. bool handle_defer_command();
  55. bool handle_define_command();
  56. bool handle_set_command();
  57. bool handle_map_command();
  58. bool handle_addmap_command();
  59. bool handle_push_command();
  60. bool include_file(Filename filename);
  61. bool replay_while(const string &name);
  62. bool replay_for(const string &name, const vector<string> &words);
  63. bool replay_forscopes(const string &name);
  64. bool replay_foreach(const string &varname, const vector<string> &words);
  65. bool replay_formap(const string &varname, const string &mapvar);
  66. bool compare_output(const string &new_contents, Filename filename,
  67. bool notouch);
  68. bool failed_if() const;
  69. bool is_valid_formal(const string &formal_parameter_name) const;
  70. private:
  71. class PushFilename {
  72. public:
  73. PushFilename(PPScope *scope, const string &filename);
  74. ~PushFilename();
  75. PPScope *_scope;
  76. string _old_thisdirprefix;
  77. string _old_thisfilename;
  78. };
  79. private:
  80. class BlockNesting;
  81. enum IfState {
  82. IS_on, // e.g. a passed #if
  83. IS_else, // after matching an #else
  84. IS_off, // e.g. a failed #if
  85. IS_done // e.g. after reaching an #else or #elif for a passed #if.
  86. };
  87. class IfNesting {
  88. public:
  89. IfNesting(IfState state);
  90. void push(PPCommandFile *file);
  91. void pop(PPCommandFile *file);
  92. IfState _state;
  93. BlockNesting *_block;
  94. IfNesting *_next;
  95. };
  96. enum BlockState {
  97. BS_begin,
  98. BS_while,
  99. BS_nested_while,
  100. BS_for,
  101. BS_nested_for,
  102. BS_forscopes,
  103. BS_nested_forscopes,
  104. BS_foreach,
  105. BS_nested_foreach,
  106. BS_formap,
  107. BS_nested_formap,
  108. BS_defsub,
  109. BS_defun,
  110. BS_output
  111. };
  112. enum WriteFormat {
  113. WF_error, // anything other than whitespace is an error.
  114. WF_straight, // write lines directly as they come in
  115. WF_collapse, // collapse out consecutive blank lines
  116. WF_makefile // fancy makefile formatting
  117. };
  118. class WriteState {
  119. public:
  120. WriteState();
  121. WriteState(const WriteState &copy);
  122. bool write_line(const string &line);
  123. bool write_collapse_line(const string &line);
  124. bool write_makefile_line(const string &line);
  125. ostream *_out;
  126. WriteFormat _format;
  127. bool _last_blank;
  128. };
  129. enum OutputFlags {
  130. OF_notouch = 0x001,
  131. };
  132. class BlockNesting {
  133. public:
  134. BlockNesting(BlockState state, const string &name);
  135. void push(PPCommandFile *file);
  136. void pop(PPCommandFile *file);
  137. BlockState _state;
  138. string _name;
  139. IfNesting *_if;
  140. WriteState *_write_state;
  141. PPScope *_scope;
  142. string _params;
  143. #ifdef HAVE_SSTREAM
  144. ostringstream _output;
  145. #else
  146. ostrstream _output;
  147. #endif
  148. vector<string> _words;
  149. int _flags;
  150. BlockNesting *_next;
  151. };
  152. PPScope *_native_scope;
  153. PPScope *_scope;
  154. bool _got_command;
  155. bool _in_for;
  156. IfNesting *_if_nesting;
  157. BlockNesting *_block_nesting;
  158. string _command;
  159. string _params;
  160. WriteState *_write_state;
  161. vector<string> _saved_lines;
  162. friend class PPCommandFile::IfNesting;
  163. friend class PPCommandFile::WriteState;
  164. friend class PPCommandFile::BlockNesting;
  165. };
  166. #endif