Skip to content

Commit 683b7f2

Browse files
committed
Add message callback to cprover API
In order to report status updates and success / failure messages.
1 parent 8c18ecd commit 683b7f2

File tree

4 files changed

+102
-0
lines changed

4 files changed

+102
-0
lines changed

regression/libcprover-cpp/call_bmc.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@
99
#include <iostream>
1010
#include <vector>
1111

12+
void print_messages_to_stdout(
13+
const api_messaget &message,
14+
api_call_back_contextt)
15+
{
16+
std::cout << api_message_get_string(message) << std::endl;
17+
}
18+
1219
int main(int argc, char *argv[])
1320
{
1421
try
@@ -25,6 +32,7 @@ int main(int argc, char *argv[])
2532
api_sessiont api(api_options);
2633

2734
// Demonstrate the loading of a goto-model from the command line arguments
35+
api.set_message_callback(print_messages_to_stdout, nullptr);
2836
api.load_model_from_files(arguments);
2937

3038
std::cout << "Successfully initialised goto_model" << std::endl;

regression/libcprover-cpp/model_loading/load_basic_c_file/test.desc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ test.c
33

44
^EXIT=0$
55
^SIGNAL=0$
6+
Parsing test.c
7+
Converting
8+
Type\-checking test
9+
Generating GOTO Program
610
Successfully initialised goto_model
711
--
812
--

src/libcprover-cpp/api.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,60 @@ api_sessiont::api_sessiont(const api_optionst &options)
4646

4747
api_sessiont::~api_sessiont() = default;
4848

49+
struct api_messaget
50+
{
51+
std::string string;
52+
};
53+
54+
const char *api_message_get_string(const api_messaget &message)
55+
{
56+
return message.string.c_str();
57+
}
58+
59+
class api_message_handlert : public message_handlert
60+
{
61+
public:
62+
explicit api_message_handlert(
63+
api_message_callbackt callback,
64+
api_call_back_contextt context);
65+
66+
void print(unsigned level, const std::string &message) override;
67+
68+
// Unimplemented for now. We may need to implement these as string conversions
69+
// or something later.
70+
void print(unsigned level, const xmlt &xml) override{};
71+
void print(unsigned level, const jsont &json) override{};
72+
73+
void flush(unsigned) override{};
74+
75+
private:
76+
api_call_back_contextt context;
77+
api_message_callbackt callback;
78+
};
79+
80+
api_message_handlert::api_message_handlert(
81+
api_message_callbackt callback,
82+
api_call_back_contextt context)
83+
: message_handlert{}, context{context}, callback{callback}
84+
{
85+
}
86+
87+
void api_message_handlert::print(unsigned level, const std::string &message)
88+
{
89+
if(!callback)
90+
return;
91+
api_messaget api_message{message};
92+
callback(api_message, context);
93+
}
94+
95+
void api_sessiont::set_message_callback(
96+
api_message_callbackt callback,
97+
api_call_back_contextt context)
98+
{
99+
implementation->message_handler =
100+
util_make_unique<api_message_handlert>(callback, context);
101+
}
102+
49103
void api_sessiont::load_model_from_files(const std::vector<std::string> &files)
50104
{
51105
implementation->model = util_make_unique<goto_modelt>(initialize_goto_model(

src/libcprover-cpp/api.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,34 @@ struct api_session_implementationt;
1919

2020
#include "options.h" // IWYU pragma: keep
2121

22+
/// Opaque message type. Properties of messages to be fetched through further
23+
/// api calls.
24+
struct api_messaget;
25+
26+
/// Given a \p api_message, this function returns that message expressed as a
27+
/// C language string.
28+
/// \note The memory for the returned string is owned by the message and as such
29+
/// does not need to be freed by users of the API.
30+
const char *api_message_get_string(const api_messaget &message);
31+
32+
/// The type of pointers to contextual data passed to the api_message_callback
33+
/// functions. These pointers point to api consumer data and are just passed
34+
/// through to the callback verbatim. These support users of the api to avoid
35+
/// using global variables.
36+
using api_call_back_contextt = void *;
37+
38+
/// The type of call back for feedback of status information and results.
39+
/// \param message: A structured message object. The lifetime of this object is
40+
/// the duration of the call to the callback. So if any data from it is
41+
/// required to persist, then this data must be copied into the API consumers
42+
/// memory.
43+
/// \param call_back_context: A pointer to the context for the function. This
44+
/// is passed through the API to the function and is for use like a capture
45+
/// group. Memory for this object is owned by the consumer of the API.
46+
using api_message_callbackt = void (*)(
47+
const api_messaget &message,
48+
api_call_back_contextt call_back_context);
49+
2250
// An object in the pattern of Session Facade - owning all of the memory
2351
// the API is using and being responsible for the management of that.
2452
struct api_sessiont
@@ -28,6 +56,14 @@ struct api_sessiont
2856
explicit api_sessiont(const api_optionst &options);
2957
~api_sessiont(); // default constructed in the .cpp file
3058

59+
/// \param callback: A call back function to receive progress updates and
60+
/// success/failure statuses.
61+
/// \param context: A context pointer passed through to the callback function.
62+
/// This is used similarly to a capture in a lambda function.
63+
void set_message_callback(
64+
api_message_callbackt callback,
65+
api_call_back_contextt context);
66+
3167
/// Load a goto_model from a given vector of filenames.
3268
/// \param files: A vector<string> containing the filenames to be loaded
3369
void load_model_from_files(const std::vector<std::string> &files);

0 commit comments

Comments
 (0)