@@ -67,31 +67,72 @@ BT::Expected<Any> ParseScriptAndExecute(Ast::Environment& env, const std::string
67
67
}
68
68
}
69
69
70
- Result ValidateScript ( const std::string& script)
70
+ class SafeErrorReport
71
71
{
72
- char error_msgs_buffer[2048 ];
72
+ mutable std::string error_buffer;
73
+ mutable std::size_t count = 0 ;
73
74
74
- auto input = lexy::string_input<lexy::utf8_encoding>(script);
75
- auto result =
76
- lexy::parse<BT::Grammar::stmt>(input, ErrorReport ().to (error_msgs_buffer));
77
- if (result.has_value () && result.error_count () == 0 )
75
+ struct _sink
78
76
{
79
- try
77
+ std::string* buffer;
78
+ std::size_t * count;
79
+ using return_type = std::size_t ;
80
+
81
+ template <typename Input, typename Reader, typename Tag>
82
+ void operator ()(const lexy::error_context<Input>& context,
83
+ const lexy::error<Reader, Tag>& error)
80
84
{
81
- std::vector<BT::Ast::ExprBase::Ptr> exprs = LEXY_MOV (result).value ();
82
- if (exprs.empty ())
83
- {
84
- return nonstd::make_unexpected (" Empty Script" );
85
- }
86
- // valid script
87
- return {};
85
+ *buffer += " error: while parsing " ;
86
+ *buffer += context.production ();
87
+ *buffer += " \n " ;
88
+ (*count)++;
88
89
}
89
- catch (std::runtime_error& err)
90
+
91
+ std::size_t finish () &&
90
92
{
91
- return nonstd::make_unexpected (err.what ());
93
+ return *count;
94
+ }
95
+ };
96
+
97
+ public:
98
+ using return_type = std::size_t ;
99
+
100
+ constexpr auto sink () const
101
+ {
102
+ return _sink{ &error_buffer, &count };
103
+ }
104
+ const std::string& get_errors () const
105
+ {
106
+ return error_buffer;
107
+ }
108
+ };
109
+
110
+ Result ValidateScript (const std::string& script)
111
+ {
112
+ auto input = lexy::string_input<lexy::utf8_encoding>(script);
113
+ SafeErrorReport error_report; // Replace char buffer with our safe handler
114
+
115
+ auto result = lexy::parse<BT::Grammar::stmt>(input, error_report);
116
+
117
+ if (!result.has_value () || result.error_count () != 0 )
118
+ {
119
+ return nonstd::make_unexpected (error_report.get_errors ());
120
+ }
121
+
122
+ try
123
+ {
124
+ std::vector<BT::Ast::ExprBase::Ptr> exprs = LEXY_MOV (result).value ();
125
+ if (exprs.empty ())
126
+ {
127
+ return nonstd::make_unexpected (" Empty Script" );
92
128
}
129
+ // valid script
130
+ return {};
131
+ }
132
+ catch (std::runtime_error& err)
133
+ {
134
+ return nonstd::make_unexpected (err.what ());
93
135
}
94
- return nonstd::make_unexpected (error_msgs_buffer);
95
136
}
96
137
97
138
} // namespace BT
0 commit comments