1 /* Implementation of the C interface: declarations.
2    Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it>
3    Copyright (C) 2010-2016 BUGSENG srl (http://bugseng.com)
4 
5 This file is part of the Parma Polyhedra Library (PPL).
6 
7 The PPL is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 The PPL is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA.
20 
21 For the most up-to-date information see the Parma Polyhedra Library
22 site: http://bugseng.com/products/ppl/ . */
23 
24 #ifndef PPL_ppl_c_implementation_common_defs_hh
25 #define PPL_ppl_c_implementation_common_defs_hh 1
26 
27 #define PPL_NO_AUTOMATIC_INITIALIZATION
28 #include "ppl.hh"
29 #include "ppl_c.h"
30 #include <stdexcept>
31 
32 namespace Parma_Polyhedra_Library {
33 
34 namespace Interfaces {
35 
36 namespace C {
37 
38 extern "C" typedef void
39 (*error_handler_type)(enum ppl_enum_error_code code, const char* description);
40 
41 extern error_handler_type user_error_handler;
42 
43 void notify_error(enum ppl_enum_error_code code, const char* description);
44 
45 Relation_Symbol relation_symbol(enum ppl_enum_Constraint_Type t);
46 
47 Bounded_Integer_Type_Width
48 bounded_integer_type_width(enum ppl_enum_Bounded_Integer_Type_Width w);
49 
50 Bounded_Integer_Type_Representation
51 bounded_integer_type_representation(enum ppl_enum_Bounded_Integer_Type_Representation r);
52 
53 /*! \brief
54   A class to wrap an array of fixed length into a partial function interface
55   suitable for the map_space_dimension() methods.
56 */
57 class Array_Partial_Function_Wrapper {
58 public:
59   /*! \brief
60     Construct a partial function wrapping the first \p n positions of
61     \p v.
62   */
63   Array_Partial_Function_Wrapper(dimension_type* v, size_t n);
64 
65   /*! \brief
66     Returns <CODE>true</CODE> if and only if the represented partial
67     function has an empty codomain (i.e., it is always undefined).
68   */
69   bool has_empty_codomain() const;
70 
71   /*! \brief
72     Returns the maximum value that belongs to the codomain
73     of the partial function.
74   */
75   dimension_type max_in_codomain() const;
76 
77   /*! \brief
78     Assigns to \p j the value associated to \p i by \p *this, if any.
79 
80     Let \f$f\f$ be the function represented by \p *this and \f$k\f$ be
81     the value of \p i.  If \f$f\f$ is defined in \f$k\f$, then
82     \f$f(k)\f$ is assigned to \p j and <CODE>true</CODE> is returned.
83     If \f$f\f$ is undefined in \f$k\f$, then <CODE>false</CODE> is
84     returned.
85   */
86   bool maps(dimension_type i, dimension_type& j) const;
87 
88 private:
89   //! Holds the vector implementing the map.
90   dimension_type* vec;
91 
92   //! Holds the size of \p vec.
93   size_t vec_size;
94 
95   //! Cache for computing the maximum dimension in the codomain.
96   mutable dimension_type max_in_codomain_;
97 
98   //! Cache for computing emptiness:
99   //! -1 if we still don't know, 0 if not empty, 1 if empty.
100   mutable int empty;
101 };
102 
103 class timeout_exception : public Parma_Polyhedra_Library::Throwable {
104 public:
throw_me() const105   void throw_me() const {
106     throw *this;
107   }
priority() const108   int priority() const {
109     return 0;
110   }
111 };
112 
113 void reset_timeout();
114 
115 class deterministic_timeout_exception
116   : public Parma_Polyhedra_Library::Throwable {
117 public:
throw_me() const118   void throw_me() const {
119     throw *this;
120   }
priority() const121   int priority() const {
122     return 0;
123   }
124 };
125 
126 void reset_deterministic_timeout();
127 
128 } // namespace C
129 
130 } // namespace Interfaces
131 
132 } // namespace Parma_Polyhedra_Library
133 
134 
135 #define CATCH_STD_EXCEPTION(exception, code) \
136 catch (const std::exception& e) {            \
137   notify_error(code, e.what()); \
138   return code; \
139 }
140 
141 #define CATCH_ALL \
142 CATCH_STD_EXCEPTION(bad_alloc, PPL_ERROR_OUT_OF_MEMORY) \
143 CATCH_STD_EXCEPTION(invalid_argument, PPL_ERROR_INVALID_ARGUMENT) \
144 CATCH_STD_EXCEPTION(domain_error, PPL_ERROR_DOMAIN_ERROR) \
145 CATCH_STD_EXCEPTION(length_error, PPL_ERROR_LENGTH_ERROR) \
146 CATCH_STD_EXCEPTION(logic_error, PPL_ERROR_LOGIC_ERROR) \
147 CATCH_STD_EXCEPTION(overflow_error, PPL_ARITHMETIC_OVERFLOW) \
148 CATCH_STD_EXCEPTION(runtime_error, PPL_ERROR_INTERNAL_ERROR) \
149 CATCH_STD_EXCEPTION(exception, PPL_ERROR_UNKNOWN_STANDARD_EXCEPTION) \
150 catch (timeout_exception&) { \
151   reset_timeout(); \
152   notify_error(PPL_TIMEOUT_EXCEPTION, "PPL timeout expired"); \
153   return PPL_TIMEOUT_EXCEPTION; \
154 } \
155 catch (deterministic_timeout_exception&) { \
156   reset_deterministic_timeout(); \
157   notify_error(PPL_TIMEOUT_EXCEPTION, "PPL deterministic timeout expired"); \
158   return PPL_TIMEOUT_EXCEPTION; \
159 } \
160 catch (...) { \
161   notify_error(PPL_ERROR_UNEXPECTED_ERROR, \
162                "completely unexpected error: a bug in the PPL"); \
163   return PPL_ERROR_UNEXPECTED_ERROR; \
164 }
165 
166 #define DECLARE_CONVERSIONS(Type, CPP_Type)             \
167   inline const CPP_Type*                                \
168   to_const(ppl_const_##Type##_t x) {                    \
169     return reinterpret_cast<const CPP_Type*>(x);        \
170   }                                                     \
171                                                         \
172   inline CPP_Type*                                      \
173   to_nonconst(ppl_##Type##_t x) {                       \
174     return reinterpret_cast<CPP_Type*>(x);              \
175   }                                                     \
176                                                         \
177   inline ppl_const_##Type##_t                           \
178   to_const(const CPP_Type* x) {                         \
179     return reinterpret_cast<ppl_const_##Type##_t>(x);   \
180   }                                                     \
181                                                         \
182   inline ppl_##Type##_t                                 \
183   to_nonconst(CPP_Type* x) {                            \
184     return reinterpret_cast<ppl_##Type##_t>(x);         \
185   }
186 
187 #define DEFINE_PRINT_FUNCTIONS(Type)                                    \
188   int                                                                   \
189   ppl_io_print_##Type(ppl_const_##Type##_t x) try {                     \
190     using namespace IO_Operators;                                       \
191     stdiobuf sb(stdout);                                                \
192     std::ostream os(&sb);                                               \
193     os << *to_const(x);                                                 \
194     if (!os)                                                            \
195       return PPL_STDIO_ERROR;                                           \
196     return 0;                                                           \
197   }                                                                     \
198   CATCH_ALL                                                             \
199                                                                         \
200   int                                                                   \
201   ppl_io_fprint_##Type(FILE* file, ppl_const_##Type##_t x) try {        \
202     using namespace IO_Operators;                                       \
203     stdiobuf sb(file);                                                  \
204     std::ostream os(&sb);                                               \
205     os << *to_const(x);                                                 \
206     if (!os)                                                            \
207       return PPL_STDIO_ERROR;                                           \
208     return 0;                                                           \
209   }                                                                     \
210   CATCH_ALL                                                             \
211                                                                         \
212   int                                                                   \
213   ppl_io_asprint_##Type(char** strp, ppl_const_##Type##_t x) try {      \
214     using namespace IO_Operators;                                       \
215     std::ostringstream os;                                              \
216     os << *to_const(x);                                                 \
217     if (!os)                                                            \
218       return PPL_STDIO_ERROR;                                           \
219     *strp = strdup(os.str().c_str());                                   \
220     if (*strp == 0)                                                     \
221       return PPL_ERROR_OUT_OF_MEMORY;                                   \
222     return 0;                                                           \
223   }                                                                     \
224   CATCH_ALL
225 
226 #define DEFINE_ASCII_DUMP_FUNCTIONS(Type)                               \
227   int                                                                   \
228   ppl_##Type##_ascii_dump(ppl_const_##Type##_t x, FILE* file) try {     \
229     stdiobuf sb(file);                                                  \
230     std::ostream os(&sb);                                               \
231     to_const(x)->ascii_dump(os);                                        \
232     if (!os)                                                            \
233       return PPL_STDIO_ERROR;                                           \
234     return 0;                                                           \
235   }                                                                     \
236   CATCH_ALL
237 
238 #define DEFINE_ASCII_LOAD_FUNCTIONS(Type)                               \
239   int                                                                   \
240   ppl_##Type##_ascii_load(ppl_##Type##_t x, FILE* file) try {           \
241     stdiobuf sb(file);                                                  \
242     std::istream is(&sb);                                               \
243     if (!to_nonconst(x)->ascii_load(is))                                \
244       return PPL_STDIO_ERROR;                                           \
245     return 0;                                                           \
246   }                                                                     \
247   CATCH_ALL
248 
249 #define DEFINE_ASCII_DUMP_LOAD_FUNCTIONS(Type)  \
250   DEFINE_ASCII_DUMP_FUNCTIONS(Type)             \
251   DEFINE_ASCII_LOAD_FUNCTIONS(Type)
252 
253 #define DEFINE_OUTPUT_FUNCTIONS(Type)           \
254   DEFINE_PRINT_FUNCTIONS(Type)                  \
255   DEFINE_ASCII_DUMP_LOAD_FUNCTIONS(Type)
256 
257 #include "ppl_c_implementation_common_inlines.hh"
258 
259 #endif // !defined(PPL_ppl_c_implementation_common_defs_hh)
260