File: test_exceptions_convert.cpp

package info (click to toggle)
emscripten 2.0.12~dfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 108,440 kB
  • sloc: ansic: 510,324; cpp: 384,763; javascript: 84,341; python: 51,362; sh: 50,019; pascal: 4,159; makefile: 3,409; asm: 2,150; lisp: 1,869; ruby: 488; cs: 142
file content (137 lines) | stat: -rw-r--r-- 3,656 bytes parent folder | download | duplicates (4)
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
125
126
127
128
129
130
131
132
133
134
135
136
137
// Copyright 2014 The Emscripten Authors.  All rights reserved.
// Emscripten is available under two separate licenses, the MIT license and the
// University of Illinois/NCSA Open Source License.  Both these licenses can be
// found in the LICENSE file.

#include <ios>
#include <iostream>
#include <sstream>
#include <stdexcept>

namespace
{
  struct TestEnum
  {
    enum type
    {
      Zero,
      One
    };
  };

  // An input operator a-la-boost date_time.  This input operator will catch
  // anything and rethrow if the exception mask for the input stream is set to
  // throw on failure.
  std::istream& operator>>(std::istream& in, TestEnum::type& value)
  {
    try {
      std::string raw;
      if (not (in >> raw)) { return in; }
      if (raw == "Zero")  { value = TestEnum::Zero; return in; }
      if (raw == "One")   { value = TestEnum::One; return in; }

      // The boost input operator uses it's own facet for input which can
      // throw, so we simulate something failing by just throwing an exception
      // directly.
      throw std::exception();
    }
    catch (...) {
      const std::ios_base::iostate exception_mask = in.exceptions();
      if (std::ios_base::failbit & exception_mask) {
        try { in.setstate(std::ios_base::failbit); }
        catch(std::ios_base::failure&) {}
        throw; // rethrow original exception
      }
      else {
        in.setstate(std::ios_base::failbit);
      }
    }
    return in;
  }
}

int main()
{
  try {
    // Show that the input operator works.
    std::istringstream iss("One");
    TestEnum::type value = TestEnum::Zero;

    // We expect this to work.
    iss >> value;
    if (iss.fail()) {
      std::cout
        << "Failed to convert 'One' to TestEnum::type... fail"
        << std::endl;
    }
    else {
      std::cout
        << "Successfully converted 'One' to TestEnum::type: " << value
        << "... ok" << std::endl;
    }
  }
  catch (...) {
    std::cout
      << "Unknown exception caught converting 'One' to TestEnum... fail"
      << std::endl;
  }

  try {
    // Show that invalid input set the fail bit on the input stream and no
    // exception is thrown, since we did not enable them on the stream.
    std::istringstream iss("Two");
    TestEnum::type value = TestEnum::Zero;

    // We expect this to fail.
    iss >> value;
    if (iss.fail()) {
      std::cout
        << "Failed to convert 'Two' to TestEnum::type... ok"
        << std::endl;
    }
    else {
      std::cout
        << "Successfully converted 'Two' to TestEnum::type: " << value
        << "... fail" << std::endl;
    }
  }
  catch (...) {
    std::cout
      << "Unknown exception caught converting 'Two' to TestEnum... fail"
      << std::endl;
  }

  try {
    // Show that setting the input stream to throw on failure currently
    // results in a JS exception being emitted.
    std::istringstream iss("Three");
    TestEnum::type value = TestEnum::Zero;

    // Tell the stream to throw on failure.
    iss.exceptions(std::ios_base::failbit);

    // We expect this to fail.
    iss >> value;
    if (iss.fail()) {
      std::cout
        << "No exception thrown; Failed to convert 'Three' to TestEnum::type..."
        "fail" << std::endl;
    }
    else {
      std::cout
        << "Successfully converted 'Three' to TestEnum::type: " << value
        << "... fail" << std::endl;
    }
  }
  catch(const std::ios_base::failure& ex) {
    std::cout << "Caught exception: " << ex.what() << "... ok" << std::endl;
  }
  catch (...) {
    std::cout
      << "Unknown exception caught converting 'Three' to TestEnum... fail"
      << std::endl;
  }

  return 0;
}