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