Vcsn  2.2
Be Rational
stream.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <sstream>
4 #include <stdexcept>
5 #include <iostream> // cin
6 #include <memory> // shared_ptr
7 
8 #include <vcsn/misc/escape.hh>
9 #include <vcsn/misc/export.hh>
10 #include <vcsn/misc/raise.hh>
11 
12 namespace vcsn LIBVCSN_API
13 {
15  extern std::ostream cnull;
16 
18  extern std::wostream wcnull;
19 
22  std::string
23  bracketed(std::istream& i, char lbracket, char rbracket);
24 
26  template <typename ValueSet, typename... Args>
27  inline auto
28  conv(const ValueSet& vs, const std::string& str, Args&&... args)
29  -> decltype(vs.conv(std::declval<std::istream&>(),
30  std::forward<Args>(args)...))
31  {
32  std::istringstream i{str};
33  auto res = vs.conv(i, std::forward<Args>(args)...);
34  VCSN_REQUIRE(i.peek() == EOF,
35  vs.sname(), ": invalid value: ", str,
36  ", unexpected ", str_escape(i.peek()));
37  return res;
38  }
39 
45  char eat(std::istream& is, char c);
46 
52  const std::string& eat(std::istream& is, const std::string& s);
53 
59  template <typename... Args>
60  ATTRIBUTE_NORETURN
61  inline
62  void fail_reading(std::istream& is, Args&&... args)
63  {
64  is.clear();
65  std::string buf;
66  std::getline(is, buf, '\n');
67  if (!is.good())
68  // This shouldn't really happen; however it's best to fail cleanly.
69  is.clear();
70  if (buf.empty())
71  raise(std::forward<Args>(args)...);
72  else
73  raise(std::forward<Args>(args)..., ": ", str_escape(buf));
74  }
75 
78  inline char get_char(std::istream& i)
79  {
80  int res = i.get();
81  if (res == '\\')
82  {
83  int c = i.peek();
84  // \(, \) and \- are used in setalpha::make, e.g.,
85  // char_letters(\(\-\)), so strip the backslash. Otherwise,
86  // return the backslash itself.
87  if (c == 'x')
88  {
89  i.ignore();
90  // Handle hexadecimal escape.
91  int c1 = i.get();
92  require(c1 != EOF,
93  "get_char: unexpected end-of-file"
94  " after: \\x");
95  require(isxdigit(c1),
96  "get_char: invalid escape: \\x", char(c1));
97  int c2 = i.get();
98  require(c2 != EOF,
99  "get_char: unexpected end-of-file"
100  " after: \\x", char(c1));
101  require(isxdigit(c2),
102  "get_char: invalid escape: \\x",
103  char(c1), char(c2));
104  res = std::stoi(std::string{char(c1), char(c2)}, nullptr, 16);
105  }
106  else if (std::isalnum(c))
107  raise("get_char: invalid escape: \\", char(c), " in \\", i);
108  else
109  res = i.get();
110  }
111  require(res != EOF,
112  "get_char: unexpected end-of-file");
113  return res;
114  }
115 
117  template <typename ValueSet, typename Value = typename ValueSet::value_t,
118  typename... Args>
119  inline auto
120  to_string(const ValueSet& vs, const Value& v, Args&&... args)
121  -> std::string
122  {
123  std::ostringstream o;
124  vs.print(v, o, std::forward<Args>(args)...);
125  return o.str();
126  }
127 
129  std::string get_file_contents(const std::string& file);
130 
133  std::shared_ptr<std::istream> open_input_file(const std::string& file);
134 
137  std::shared_ptr<std::ostream> open_output_file(const std::string& file);
138 
139 }
std::shared_ptr< std::istream > open_input_file(const std::string &file)
Open file for reading and return its autoclosing stream.
Definition: stream.cc:81
#define VCSN_REQUIRE(Cond,...)
A macro similar to require.
Definition: raise.hh:89
char get_char(std::istream &i)
Read a single char, with possible -escape support.
Definition: stream.hh:78
Definition: a-star.hh:8
void require(Bool b, Args &&...args)
If b is not verified, raise an error with args as message.
Definition: raise.hh:78
std::string to_string(direction d)
Conversion to string.
Definition: direction.cc:7
std::ostream & str_escape(std::ostream &os, const std::string &str, const char *special=nullptr)
Output a string, escaping special characters.
Definition: escape.cc:54
std::shared_ptr< std::ostream > open_output_file(const std::string &file)
Open file for writing and return its autoclosing stream.
Definition: stream.cc:96
char eat(std::istream &is, char c)
Check lookahead character and advance.
Definition: stream.cc:37
std::string bracketed(std::istream &i, char lbracket, char rbracket)
Extract the string which is here between lbracket and rbracket.
Definition: stream.cc:17
#define LIBVCSN_API
Definition: export.hh:8
ATTRIBUTE_NORETURN void fail_reading(std::istream &is, Args &&...args)
Throw an exception after failing to read from is.
Definition: stream.hh:62
std::string get_file_contents(const std::string &file)
Return the contents of file.
Definition: stream.cc:66
std::istringstream is
The input stream: the specification to translate.
Definition: translate.cc:380
std::ostream cnull
An narrow-char stream that discards the output.
Definition: stream.cc:13
std::wostream wcnull
An wide-char stream that discards the output.
Definition: stream.cc:14
auto conv(const ValueSet &vs, const std::string &str, Args &&...args) -> decltype(vs.conv(std::declval< std::istream & >(), std::forward< Args >(args)...))
Parse str via vs.conv.
Definition: stream.hh:28