command_builder.h 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #pragma once
  2. #include <iostream>
  3. #include <sstream>
  4. #include <string>
  5. #include "types.h"
  6. namespace build {
  7. class command_builder {
  8. private:
  9. indent_t indent_;
  10. std::stringstream buffer_;
  11. public:
  12. command_builder(std::string const & cmd, int indent = 0);
  13. template <typename T> command_builder && operator<<(T const & value) &&;
  14. template <typename T> command_builder & operator<<(T const & value) &;
  15. template <typename T>
  16. command_builder & operator<<(std::vector<T> const & value) &;
  17. int execute() const;
  18. private:
  19. template <typename T> void write(T const & value) { buffer_ << value; }
  20. void write(version const & vers);
  21. void write(source_file const & file);
  22. void write(output_file const & file);
  23. };
  24. command_builder::command_builder(std::string const & cmd, int indent)
  25. : indent_{indent}, buffer_() {
  26. buffer_ << cmd;
  27. }
  28. template <typename T>
  29. command_builder && command_builder::operator<<(T const & value) && {
  30. return std::move((*this) << value);
  31. }
  32. template <typename T>
  33. command_builder & command_builder::operator<<(T const & value) & {
  34. buffer_ << ' ';
  35. write(value);
  36. return *this;
  37. }
  38. template <typename T>
  39. command_builder &
  40. command_builder::operator<<(std::vector<T> const & value) & {
  41. for (T const & v : value) {
  42. (*this) << v;
  43. }
  44. return *this;
  45. }
  46. void command_builder::write(version const & vers) {
  47. switch (vers) {
  48. case version::cxx11:
  49. buffer_ << ' ' << "-std=c++11";
  50. break;
  51. case version::cxx14:
  52. buffer_ << ' ' << "-std=c++14";
  53. break;
  54. case version::cxx17:
  55. buffer_ << ' ' << "-std=c++17";
  56. break;
  57. case none:
  58. break;
  59. }
  60. }
  61. void command_builder::write(source_file const & file) {
  62. buffer_ << " -c " << file.get();
  63. }
  64. void command_builder::write(output_file const & file) {
  65. buffer_ << " -o " << file.get();
  66. }
  67. std::ostream & operator<<(std::ostream & os, indent_t const & value) {
  68. for (int i = 0; i < value.value; ++i) {
  69. os << " ";
  70. }
  71. return os;
  72. }
  73. int command_builder::execute() const {
  74. std::string cmdstr = buffer_.str();
  75. // TODO(samjaffe): Not sure this belongs here, so much as command_builder
  76. // should take a formatter object (including things like color config)
  77. std::cout << indent_ << cmdstr << std::endl;
  78. return std::system(cmdstr.c_str());
  79. }
  80. }