| 530 | } |
| 531 | |
| 532 | static PyObject* SolveTask(PyObject *self, PyObject *args) { |
| 533 | if (__z3_parser == nullptr) { |
| 534 | PyErr_SetString(PyExc_RuntimeError, "parser not initialized"); |
| 535 | return NULL; |
| 536 | } |
| 537 | |
| 538 | uint64_t id = 0; |
| 539 | unsigned timeout = 5000; |
| 540 | if (!PyArg_ParseTuple(args, "K|I", &id, &timeout)) { |
| 541 | return NULL; |
| 542 | } |
| 543 | |
| 544 | symsan::Z3ParserSolver::solution_t solutions; |
| 545 | int status = __z3_parser->solve_task(id, timeout, solutions); |
| 546 | |
| 547 | PyObject *sols = PyList_New(solutions.size()); |
| 548 | for (size_t i = 0; i < solutions.size(); i++) { |
| 549 | auto &val = solutions[i]; |
| 550 | PyObject *sol = PyDict_New(); |
| 551 | |
| 552 | // Common fields for all operations |
| 553 | PyDict_SetItemString(sol, "op", PyLong_FromLong((int)val.op)); |
| 554 | PyDict_SetItemString(sol, "id", PyLong_FromUnsignedLong(val.id)); |
| 555 | PyDict_SetItemString(sol, "offset", PyLong_FromLong(val.offset)); |
| 556 | |
| 557 | // Operation-specific fields |
| 558 | using op_t = symsan::Z3ParserSolver::solution_op_t; |
| 559 | switch (val.op) { |
| 560 | case op_t::SET: |
| 561 | PyDict_SetItemString(sol, "val", PyLong_FromUnsignedLong(val.val)); |
| 562 | break; |
| 563 | case op_t::INSERT: |
| 564 | PyDict_SetItemString(sol, "data", |
| 565 | PyBytes_FromStringAndSize((char*)val.data.data(), val.data.size())); |
| 566 | break; |
| 567 | case op_t::DELETE: |
| 568 | PyDict_SetItemString(sol, "len", PyLong_FromUnsignedLong(val.len)); |
| 569 | break; |
| 570 | } |
| 571 | |
| 572 | PyList_SetItem(sols, i, sol); |
| 573 | } |
| 574 | |
| 575 | PyObject *ret = PyTuple_New(2); |
| 576 | PyTuple_SetItem(ret, 0, PyLong_FromLong(status)); |
| 577 | PyTuple_SetItem(ret, 1, sols); |
| 578 | |
| 579 | return ret; |
| 580 | } |
| 581 | |
| 582 | static PyObject* ExportTaskSMT2(PyObject *self, PyObject *args) { |
| 583 | if (__z3_parser == nullptr) { |
nothing calls this directly
no test coverage detected