Skip to content

Commit 8ce9ff1

Browse files
committed
Improve commands on windows.
1 parent 0f1209f commit 8ce9ff1

File tree

8 files changed

+358
-68
lines changed

8 files changed

+358
-68
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,7 @@ cmake-*
1313
*.json
1414
a.out
1515
packages
16-
*.bat
16+
*.bat
17+
18+
build
19+
.cache

src/sw/command/command.h

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -392,8 +392,12 @@ if [ $E -ne 0 ]; then echo "Error code: $E"; fi
392392
base::operator>(p);
393393
outputs.insert(p);
394394
}
395+
396+
// this operator will run commands
395397
void operator|(auto &c) {
396-
{
398+
out.s = &c.in;
399+
c.in.s = &out;
400+
/*{
397401
command_pointer_holder ch;
398402
ch.r = &c;
399403
ch.io = &c;
@@ -404,7 +408,12 @@ if [ $E -ne 0 ]; then echo "Error code: $E"; fi
404408
ch.r = this;
405409
ch.io = this;
406410
c.in = ch;
407-
}
411+
}*/
412+
}
413+
// this operator will make a pipe between commands
414+
void operator|=(auto &c) {
415+
out.s = &c.in;
416+
c.in.s = &out;
408417
}
409418

410419
string name() const {
@@ -421,14 +430,12 @@ if [ $E -ne 0 ]; then echo "Error code: $E"; fi
421430
}
422431
return print();
423432
}
424-
425433
string get_error_message() {
426434
if (ok()) {
427435
return {};
428436
}
429437
return "command failed: " + name() + ":\n" + raw_command::get_error_message();
430438
}
431-
432439
void save(const path &dir, shell_type t = detect_shell()) {
433440
auto fn = dir / std::to_string(hash()) += visit(t,[](auto &&v){return v.extension;});
434441
string s;
@@ -491,6 +498,21 @@ if [ $E -ne 0 ]; then echo "Error code: $E"; fi
491498
return io_command::shell::sh{};
492499
#endif
493500
}
501+
502+
/*struct command_result {
503+
bool success{};
504+
505+
command_result() = default;
506+
command_result(const decltype(exit_code) &e) : success{e ? *e == 0 : false} {}
507+
508+
operator bool() const {return success;}
509+
};*/
510+
bool operator()(this auto &&self) {
511+
executor ex;
512+
self.run(ex, []{});
513+
ex.run();
514+
return self.exit_code ? *self.exit_code == 0 : false;
515+
}
494516
};
495517

496518
struct cl_exe_command : io_command {
@@ -627,12 +649,16 @@ struct cl_exe_command : io_command {
627649
struct gcc_command : io_command {
628650
path deps_file;
629651

630-
void run(auto &&ex, auto &&cb) {
652+
gcc_command() {
631653
err = ""s;
632654
out = ""s;
633-
655+
}
656+
void run(auto &&ex, auto &&cb) {
634657
io_command::run(ex, cb);
635658
}
659+
void run(auto &&ex) {
660+
run(ex, [&]{process_deps();});
661+
}
636662
void process_deps() {
637663
auto is_space = [](auto c) {
638664
return c == ' ' || c == '\n' || c == '\r' || c == '\t';

src/sw/command/win32.h

Lines changed: 56 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ namespace sw {
1313
template <bool Output>
1414
struct command_stream {
1515
static constexpr auto Input = !Output;
16+
static constexpr HANDLE default_handle_value = 0; // or INVALID_HANDLE_VALUE?
1617

1718
using second_end_of_pipe = command_stream<!Output>*;
1819
using stream_callback = std::function<void(string_view)>;
@@ -31,7 +32,7 @@ struct command_stream {
3132
};*/
3233

3334
stream s;
34-
HANDLE h = 0;
35+
HANDLE h{default_handle_value};
3536
win32::pipe pipe;
3637

3738
command_stream() = default;
@@ -78,8 +79,6 @@ struct command_stream {
7879
Output ? CREATE_ALWAYS : OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0));
7980
},
8081
[&](second_end_of_pipe &e) {
81-
SW_UNIMPLEMENTED;
82-
// ok, but verify
8382
if constexpr (Input) {
8483
h = e->pipe.r;
8584
} else {
@@ -88,11 +87,12 @@ struct command_stream {
8887
}
8988
},
9089
[&](auto &) {
91-
pipe.init(true);
9290
if constexpr (Input) {
91+
pipe.init(true, false, false, true);
9392
ex.register_handle(pipe.w);
9493
h = pipe.r;
9594
} else {
95+
pipe.init(false, true, true, false);
9696
ex.register_handle(pipe.r);
9797
h = pipe.w;
9898
}
@@ -110,30 +110,36 @@ struct command_stream {
110110
},
111111
[&](string &s) {
112112
if constexpr (Input) {
113-
SW_UNIMPLEMENTED;
114-
/*pipe.r.reset();
115-
ex.write_async(pipe.w, [&](auto &&f, auto &&buf, auto &&ec) mutable {
113+
pipe.r.reset();
114+
h = default_handle_value;
115+
ex.write_async(pipe.w, s.data(), s.size(), [&, pos = 0uz](auto &&cb, auto &&ec) mutable {
116116
if (!ec) {
117-
s += buf;
118-
ex.write_async(pipe.w, std::move(f));
117+
pos += cb->datasize;
118+
ex.write_async(pipe.w, cb, s.data() + pos, s.size() - pos);
119+
} else {
120+
pipe.w.reset();
119121
}
120-
});*/
122+
});
121123
} else {
122124
pipe.w.reset();
123-
ex.read_async(pipe.r, [&](auto &&f, auto &&buf, auto &&ec) mutable {
125+
h = default_handle_value;
126+
ex.read_async(pipe.r, [&](auto &&cb, auto &&ec) mutable {
124127
if (!ec) {
125-
s += buf;
126-
ex.read_async(pipe.r, std::move(f));
128+
s.append((char *)cb->buf, cb->datasize);
129+
ex.read_async(pipe.r, cb);
130+
} else {
131+
pipe.r.reset();
127132
}
128133
});
129134
}
130135
},
131-
[&](second_end_of_pipe &) {
132-
SW_UNIMPLEMENTED;
136+
[&](second_end_of_pipe &e) {
133137
if constexpr (Input) {
134-
//CloseHandle(d.si.StartupInfo.hStdInput);
138+
e->pipe.r.reset();
139+
h = default_handle_value;
135140
} else {
136-
//CloseHandle(h);
141+
pipe.w.reset();
142+
h = default_handle_value;
137143
}
138144
},
139145
[&](stream_callback &cb) {
@@ -153,21 +159,25 @@ struct command_stream {
153159
});*/
154160
} else {
155161
pipe.w.reset();
156-
ex.read_async(pipe.r, [&, cb, s = string{}](auto &&f, auto &&buf, auto &&ec) mutable {
162+
ex.read_async(pipe.r, [&, scb = cb, s = string{}](auto &&cb, auto &&ec) mutable {
157163
if (!ec) {
158-
s += buf;
164+
s.append((char *)cb->buf, cb->datasize);
159165
if (auto p = s.find_first_of("\r\n"); p != -1) {
160-
cb(string_view(s.data(), p));
166+
scb(string_view(s.data(), p));
161167
p = s.find("\n", p);
162168
s = s.substr(p + 1);
163169
}
164-
ex.read_async(pipe.r, std::move(f));
170+
ex.read_async(pipe.r, cb);
171+
} else {
172+
pipe.r.reset();
173+
h = default_handle_value;
165174
}
166175
});
167176
}
168177
},
169178
[&](path &fn) {
170179
CloseHandle(h);
180+
h = default_handle_value;
171181
});
172182
}
173183
void inside_fork(int fd) {
@@ -198,7 +208,27 @@ struct command_stream {
198208
);
199209
}
200210
void finish() {
201-
pipe = decltype(pipe){};
211+
//pipe = decltype(pipe){};
212+
visit(
213+
s,
214+
[&](inherit) {
215+
h = default_handle_value;
216+
},
217+
[&](close_) {
218+
// empty
219+
},
220+
[&](string &s) {
221+
// empty
222+
},
223+
[&](second_end_of_pipe &) {
224+
// empty
225+
},
226+
[&](stream_callback &cb) {
227+
// empty
228+
},
229+
[&](path &fn) {
230+
// empty
231+
});
202232
}
203233
void close() {
204234
s = close_{};
@@ -242,7 +272,7 @@ struct raw_command {
242272
process_data d;
243273
//
244274
bool detach{};
245-
bool exec{};
275+
bool exec{}; // replace current process
246276
std::chrono::seconds time_limit{};
247277

248278
// sync()
@@ -318,6 +348,8 @@ struct raw_command {
318348
flags |= CREATE_UNICODE_ENVIRONMENT;
319349
flags |= EXTENDED_STARTUPINFO_PRESENT;
320350
// flags |= CREATE_NO_WINDOW;
351+
flags |= CREATE_SUSPENDED;
352+
// CREATE_BREAKAWAY_FROM_JOB for detached?
321353

322354
d.si.StartupInfo.dwFlags = STARTF_USESTDHANDLES;
323355
if (detach) {
@@ -432,6 +464,7 @@ struct raw_command {
432464
}
433465
cb();
434466
});
467+
WINAPI_CALL(ResumeThread(d.thread));
435468
/*visit(
436469
out.s,
437470
[&](command_pointer_holder &ch) {

src/sw/helpers/common.h

Lines changed: 104 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -254,13 +254,26 @@ struct special_variant : variant<any_setting, Types...> {
254254
};
255255

256256
struct cpp_emitter {
257-
struct ns {
257+
struct scope {
258258
cpp_emitter &e;
259-
ns(cpp_emitter &e, auto &&name) : e{e} {
260-
e += "namespace "s + name + " {";
259+
string tail;
260+
261+
scope(cpp_emitter &e, auto &&kv, auto &&name, auto &&tail) : e{e}, tail{tail} {
262+
e += kv + " "s + name + " {";
263+
}
264+
scope(cpp_emitter &e) : e{e} {
265+
e += "{";
266+
}
267+
~scope() {
268+
e += "}" + tail;
269+
}
270+
};
271+
struct ns : scope {
272+
ns(cpp_emitter &e, auto &&name) : scope{e, "namespace", name, ""} {
261273
}
262-
~ns() {
263-
e += "}";
274+
};
275+
struct stru : scope {
276+
stru(cpp_emitter &e, auto &&name) : scope{e, "struct", name, ";"} {
264277
}
265278
};
266279

@@ -281,6 +294,92 @@ struct cpp_emitter {
281294
auto namespace_(auto &&name) {
282295
return ns{*this, name};
283296
}
297+
auto struct_(auto &&name) {
298+
return stru{*this, name};
299+
}
300+
operator const string &() const {return s;}
301+
};
302+
303+
struct cpp_emitter2 {
304+
struct line {
305+
using other = std::unique_ptr<cpp_emitter2>;
306+
std::variant<string, other> s;
307+
int indent{};
308+
309+
line() : s{std::make_unique<cpp_emitter2>()} {
310+
}
311+
line(const string &s) : s{s} {
312+
}
313+
template <auto N>
314+
line(const char (&s)[N]) : line{string{s}} {
315+
}
316+
auto ptr() { return std::get<other>(s).get(); }
317+
auto text(int parent_indent, const string &delim) const {
318+
string t;
319+
auto pi = parent_indent;
320+
while (pi--) {
321+
t += delim;
322+
}
323+
return t + visit(s, [](const string &s) {
324+
return s;
325+
}, [&](const auto &e) {
326+
return e->text(parent_indent, delim);
327+
});
328+
}
329+
};
330+
331+
struct scope {
332+
cpp_emitter2 &e;
333+
string tail;
334+
335+
scope(cpp_emitter2 &e, auto &&kv, auto &&name, auto &&tail) : e{e}, tail{tail} {
336+
e += kv + " "s + name + " {";
337+
}
338+
scope(cpp_emitter2 &e) : e{e} {
339+
e += "{";
340+
}
341+
~scope() {
342+
e += "}" + tail;
343+
}
344+
};
345+
struct ns : scope {
346+
ns(cpp_emitter2 &e, auto &&name) : scope{e, "namespace", name, ""} {
347+
}
348+
};
349+
struct stru : scope {
350+
stru(cpp_emitter2 &e, auto &&name) : scope{e, "struct", name, ";"} {
351+
}
352+
};
353+
354+
std::vector<line> lines;
355+
int current_indent{};
356+
357+
cpp_emitter2 &operator+=(auto &&s) {
358+
add_line(s);
359+
return *this;
360+
}
361+
void add_line(auto &&s) {
362+
lines.push_back(s);
363+
}
364+
void include(const path &p) {
365+
auto fn = normalize_path_and_drive(p);
366+
add_line("#include \"" + fn + "\"\n");
367+
}
368+
auto namespace_(auto &&name) {
369+
auto &l = lines.emplace_back();
370+
return ns{*l.ptr(), name};
371+
}
372+
auto struct_(auto &&name) {
373+
auto &l = lines.emplace_back();
374+
return stru{*l.ptr(), name};
375+
}
376+
string text(int parent_indent = 0, const string &delim = " "s) const {
377+
string s;
378+
for (auto &&line : lines) {
379+
s += line.text(parent_indent, delim) + "\n"s;
380+
}
381+
return s;
382+
}
284383
};
285384

286385
// refine

0 commit comments

Comments
 (0)