/
command_stream.cc
73 lines (66 loc) · 2.59 KB
/
command_stream.cc
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
// The definition of the Command_stream class. It is constructed from a
// standard stream and defines an input operator for Argm objects. It also
// handles the calling of .prompt.
//
// Copyright (C) 2005-2018 Samuel Newbold
#include <iostream>
#include <list>
#include <map>
#include <string>
#include <set>
#include <sstream>
#include <sys/time.h>
#include <vector>
#include "arg_spec.h"
#include "rwsh_stream.h"
#include "variable_map.h"
#include "argm.h"
#include "arg_script.h"
#include "call_stack.h"
#include "clock.h"
#include "command_stream.h"
#include "executable.h"
#include "executable_map.h"
#include "prototype.h"
#include "function.h"
Command_stream::Command_stream(Rwsh_istream_p& s, bool subprompt_i) :
src(s), subprompt(subprompt_i) {}
// write the next command to dest. run .prompt as appropriate
Command_stream& Command_stream::getline(Command_block& dest,
Error_list& errors) {
if (this->fail()) return *this;
std::string cmd;
for (bool cmd_is_incomplete=true; cmd_is_incomplete;) {
errors.reset(); // If this is the first execution of the loop, then errors
// should be empty, if a subsequent execution, then we will regenerate all
// the errors again. Obviously this should go away when this gets fixed to
// be single-pass.
std::string line;
struct timeval before_input, after_input;
gettimeofday(&before_input, rwsh_clock.no_timezone);
src.getline(line);
gettimeofday(&after_input, rwsh_clock.no_timezone);
rwsh_clock.user_wait(before_input, after_input);
std::string::size_type point = 0;
if (fail()) {
if (cmd.size()) { // EOF without a complete command
Exception raw_command(Argm::Raw_command, cmd);
executable_map.run_handling_exceptions(raw_command, errors);
Command_block(cmd, point, 0, errors);} // will throw the right exception
return *this;}
else cmd += line;
dest = Command_block(cmd, point, 0, errors);
if (global_stack.remove_exceptions(".unclosed_brace", errors) ||
global_stack.remove_exceptions(".unclosed_parenthesis", errors))
cmd += '\n';
else if (global_stack.unwind_stack()) {
Exception raw_command(Argm::Raw_command, cmd);
global_stack.catch_one(raw_command, errors);
return *this;}
else cmd_is_incomplete = false;}
Exception raw_command(Argm::Raw_command, cmd);
executable_map.run_handling_exceptions(raw_command, errors);
return *this;}
// returns true if the last command could not be read
bool Command_stream::fail() const {
return global_stack.exit_requested || src.fail();}