protoc-input-output-file.patch 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. --- a/src/google/protobuf/compiler/command_line_interface.cc
  2. +++ b/src/google/protobuf/compiler/command_line_interface.cc
  3. @@ -1579,6 +1579,13 @@ CommandLineInterface::ParseArgumentStatus CommandLineInterface::ParseArguments(
  4. << std::endl;
  5. return PARSE_ARGUMENT_FAIL;
  6. }
  7. + if (mode_ != MODE_DECODE && mode_ != MODE_ENCODE &&
  8. + (!encode_decode_input_.empty() || !encode_decode_output_.empty())) {
  9. + std::cerr << "--encode-decode-input and --encode-decode-output are used "
  10. + << "only together with --encode or --decode modes."
  11. + << std::endl;
  12. + return PARSE_ARGUMENT_FAIL;
  13. + }
  14. if (!dependency_out_name_.empty() && input_files_.size() > 1) {
  15. std::cerr
  16. << "Can only process one input file when using --dependency_out=FILE."
  17. @@ -1889,6 +1896,35 @@ CommandLineInterface::InterpretArgument(const TProtoStringType& name,
  18. codec_type_ = value;
  19. + } else if (name == "--encode-decode-input") {
  20. + if (!encode_decode_input_.empty()) {
  21. + std::cerr << name << " may only be passed once." << std::endl;
  22. + return PARSE_ARGUMENT_FAIL;
  23. + }
  24. + if (value.empty()) {
  25. + std::cerr << name << " requires a non-empty value." << std::endl;
  26. + return PARSE_ARGUMENT_FAIL;
  27. + }
  28. + if (access(value.c_str(), F_OK) < 0) {
  29. + std::cerr << value << ": encode/decode input file does not exist."
  30. + << std::endl;
  31. + return PARSE_ARGUMENT_FAIL;
  32. + }
  33. +
  34. + encode_decode_input_ = value;
  35. +
  36. + } else if (name == "--encode-decode-output") {
  37. + if (!encode_decode_output_.empty()) {
  38. + std::cerr << name << " may only be passed once." << std::endl;
  39. + return PARSE_ARGUMENT_FAIL;
  40. + }
  41. + if (value.empty()) {
  42. + std::cerr << name << " requires a non-empty value." << std::endl;
  43. + return PARSE_ARGUMENT_FAIL;
  44. + }
  45. +
  46. + encode_decode_output_ = value;
  47. +
  48. } else if (name == "--deterministic_output") {
  49. deterministic_output_ = true;
  50. @@ -2035,6 +2071,10 @@ Parse PROTO_FILES and generate output based on the options given:
  51. pairs in text format to standard output. No
  52. PROTO_FILES should be given when using this
  53. flag.
  54. + --encode-decode-input=FILE Read text/binary message from FILE instead of
  55. + reading it from standard input.
  56. + --encode-decode-output=FILE Write text/binary message to FILE instead of
  57. + writing it to standard output.
  58. --descriptor_set_in=FILES Specifies a delimited list of FILES
  59. each containing a FileDescriptorSet (a
  60. protocol buffer defined in descriptor.proto).
  61. @@ -2352,16 +2392,40 @@ bool CommandLineInterface::EncodeOrDecode(const DescriptorPool* pool) {
  62. DynamicMessageFactory dynamic_factory(pool);
  63. std::unique_ptr<Message> message(dynamic_factory.GetPrototype(type)->New());
  64. + int in_fd = STDIN_FILENO;
  65. + if (!encode_decode_input_.empty()) {
  66. + do {
  67. + in_fd = open(encode_decode_input_.c_str(), O_RDONLY | O_BINARY);
  68. + } while (in_fd < 0 && errno == EINTR);
  69. + if (in_fd < 0) {
  70. + int error = errno;
  71. + std::cerr << encode_decode_input_ << ": " << strerror(error) << std::endl;
  72. + return false;
  73. + }
  74. + }
  75. +
  76. + int out_fd = STDOUT_FILENO;
  77. + if (!encode_decode_output_.empty()) {
  78. + do {
  79. + out_fd = open(encode_decode_output_.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
  80. + } while (out_fd < 0 && errno == EINTR);
  81. + if (out_fd < 0) {
  82. + int error = errno;
  83. + std::cerr << encode_decode_output_ << ": " << strerror(error) << std::endl;;
  84. + return false;
  85. + }
  86. + }
  87. +
  88. if (mode_ == MODE_ENCODE) {
  89. - SetFdToTextMode(STDIN_FILENO);
  90. - SetFdToBinaryMode(STDOUT_FILENO);
  91. + SetFdToTextMode(in_fd);
  92. + SetFdToBinaryMode(out_fd);
  93. } else {
  94. - SetFdToBinaryMode(STDIN_FILENO);
  95. - SetFdToTextMode(STDOUT_FILENO);
  96. + SetFdToBinaryMode(in_fd);
  97. + SetFdToTextMode(out_fd);
  98. }
  99. - io::FileInputStream in(STDIN_FILENO);
  100. - io::FileOutputStream out(STDOUT_FILENO);
  101. + io::FileInputStream in(in_fd);
  102. + io::FileOutputStream out(out_fd);
  103. if (mode_ == MODE_ENCODE) {
  104. // Input is text.
  105. --- a/src/google/protobuf/compiler/command_line_interface.h
  106. +++ b/src/google/protobuf/compiler/command_line_interface.h
  107. @@ -383,6 +383,11 @@ class PROTOC_EXPORT CommandLineInterface {
  108. Mode mode_ = MODE_COMPILE;
  109. + // For encode end decode modes only: read from input and write to output
  110. + // instead of stdin and stdout.
  111. + TProtoStringType encode_decode_input_;
  112. + TProtoStringType encode_decode_output_;
  113. +
  114. enum PrintMode {
  115. PRINT_NONE, // Not in MODE_PRINT
  116. PRINT_FREE_FIELDS, // --print_free_fields