1 ///
2 /// @file   api-c.cpp
3 /// @brief  primesieve C API.
4 ///         Contains the implementations of the functions declared
5 ///         in the primesieve.h header file.
6 ///
7 /// Copyright (C) 2021 Kim Walisch, <kim.walisch@gmail.com>
8 ///
9 /// This file is distributed under the BSD License. See the COPYING
10 /// file in the top level directory.
11 ///
12 
13 #include <primesieve.h>
14 #include <primesieve.hpp>
15 #include <primesieve/malloc_vector.hpp>
16 
17 #include <stdint.h>
18 #include <cstdlib>
19 #include <cstddef>
20 #include <cerrno>
21 #include <exception>
22 #include <iostream>
23 
24 using std::size_t;
25 using namespace primesieve;
26 
27 namespace {
28 
29 template <typename T>
get_primes(uint64_t start,uint64_t stop,size_t * size)30 void* get_primes(uint64_t start, uint64_t stop, size_t* size)
31 {
32   try
33   {
34     malloc_vector<T> primes;
35     store_primes(start, stop, primes);
36 
37     if (size)
38       *size = primes.size();
39 
40     primes.disable_free();
41     return primes.data();
42   }
43   catch (const std::exception& e)
44   {
45     if (size)
46       *size = 0;
47 
48     std::cerr << "primesieve_generate_primes: " << e.what() << std::endl;
49     errno = EDOM;
50     return nullptr;
51   }
52 }
53 
54 template <typename T>
get_n_primes(uint64_t n,uint64_t start)55 void* get_n_primes(uint64_t n, uint64_t start)
56 {
57   try
58   {
59     malloc_vector<T> primes;
60     store_n_primes(n, start, primes);
61     primes.disable_free();
62     return primes.data();
63   }
64   catch (const std::exception& e)
65   {
66     std::cerr << "primesieve_generate_n_primes: " << e.what() << std::endl;
67     errno = EDOM;
68     return nullptr;
69   }
70 }
71 
72 } // namespace
73 
primesieve_generate_primes(uint64_t start,uint64_t stop,size_t * size,int type)74 void* primesieve_generate_primes(uint64_t start, uint64_t stop, size_t* size, int type)
75 {
76   switch (type)
77   {
78     case SHORT_PRIMES:     return get_primes<short>(start, stop, size);
79     case USHORT_PRIMES:    return get_primes<unsigned short>(start, stop, size);
80     case INT_PRIMES:       return get_primes<int>(start, stop, size);
81     case UINT_PRIMES:      return get_primes<unsigned int>(start, stop, size);
82     case LONG_PRIMES:      return get_primes<long>(start, stop, size);
83     case ULONG_PRIMES:     return get_primes<unsigned long>(start, stop, size);
84     case LONGLONG_PRIMES:  return get_primes<long long>(start, stop, size);
85     case ULONGLONG_PRIMES: return get_primes<unsigned long long>(start, stop, size);
86     case INT16_PRIMES:     return get_primes<int16_t>(start, stop, size);
87     case UINT16_PRIMES:    return get_primes<uint16_t>(start, stop, size);
88     case INT32_PRIMES:     return get_primes<int32_t>(start, stop, size);
89     case UINT32_PRIMES:    return get_primes<uint32_t>(start, stop, size);
90     case INT64_PRIMES:     return get_primes<int64_t>(start, stop, size);
91     case UINT64_PRIMES:    return get_primes<uint64_t>(start, stop, size);
92   }
93 
94   if (size)
95     *size = 0;
96 
97   std::cerr << "primesieve_generate_primes: Invalid type parameter!" << std::endl;
98   errno = EDOM;
99   return nullptr;
100 }
101 
primesieve_generate_n_primes(uint64_t n,uint64_t start,int type)102 void* primesieve_generate_n_primes(uint64_t n, uint64_t start, int type)
103 {
104   switch (type)
105   {
106     case SHORT_PRIMES:     return get_n_primes<short>(n, start);
107     case USHORT_PRIMES:    return get_n_primes<unsigned short>(n, start);
108     case INT_PRIMES:       return get_n_primes<int>(n, start);
109     case UINT_PRIMES:      return get_n_primes<unsigned int>(n, start);
110     case LONG_PRIMES:      return get_n_primes<long>(n, start);
111     case ULONG_PRIMES:     return get_n_primes<unsigned long>(n, start);
112     case LONGLONG_PRIMES:  return get_n_primes<long long>(n, start);
113     case ULONGLONG_PRIMES: return get_n_primes<unsigned long long>(n, start);
114     case INT16_PRIMES:     return get_n_primes<int16_t>(n, start);
115     case UINT16_PRIMES:    return get_n_primes<uint16_t>(n, start);
116     case INT32_PRIMES:     return get_n_primes<int32_t>(n, start);
117     case UINT32_PRIMES:    return get_n_primes<uint32_t>(n, start);
118     case INT64_PRIMES:     return get_n_primes<int64_t>(n, start);
119     case UINT64_PRIMES:    return get_n_primes<uint64_t>(n, start);
120   }
121 
122   std::cerr << "primesieve_generate_n_primes: Invalid type parameter!" << std::endl;
123   errno = EDOM;
124   return nullptr;
125 }
126 
primesieve_free(void * primes)127 void primesieve_free(void* primes)
128 {
129   free(primes);
130 }
131 
primesieve_nth_prime(int64_t n,uint64_t start)132 uint64_t primesieve_nth_prime(int64_t n, uint64_t start)
133 {
134   try
135   {
136     return nth_prime(n, start);
137   }
138   catch (const std::exception& e)
139   {
140     std::cerr << "primesieve_nth_prime: " << e.what() << std::endl;
141     errno = EDOM;
142     return PRIMESIEVE_ERROR;
143   }
144 }
145 
primesieve_count_primes(uint64_t start,uint64_t stop)146 uint64_t primesieve_count_primes(uint64_t start, uint64_t stop)
147 {
148   try
149   {
150     return count_primes(start, stop);
151   }
152   catch (const std::exception& e)
153   {
154     std::cerr << "primesieve_count_primes: " << e.what() << std::endl;
155     errno = EDOM;
156     return PRIMESIEVE_ERROR;
157   }
158 }
159 
primesieve_count_twins(uint64_t start,uint64_t stop)160 uint64_t primesieve_count_twins(uint64_t start, uint64_t stop)
161 {
162   try
163   {
164     return count_twins(start, stop);
165   }
166   catch (const std::exception& e)
167   {
168     std::cerr << "primesieve_count_twins: " << e.what() << std::endl;
169     errno = EDOM;
170     return PRIMESIEVE_ERROR;
171   }
172 }
173 
primesieve_count_triplets(uint64_t start,uint64_t stop)174 uint64_t primesieve_count_triplets(uint64_t start, uint64_t stop)
175 {
176   try
177   {
178     return count_triplets(start, stop);
179   }
180   catch (const std::exception& e)
181   {
182     std::cerr << "primesieve_count_triplets: " << e.what() << std::endl;
183     errno = EDOM;
184     return PRIMESIEVE_ERROR;
185   }
186 }
187 
primesieve_count_quadruplets(uint64_t start,uint64_t stop)188 uint64_t primesieve_count_quadruplets(uint64_t start, uint64_t stop)
189 {
190   try
191   {
192     return count_quadruplets(start, stop);
193   }
194   catch (const std::exception& e)
195   {
196     std::cerr << "primesieve_count_quadruplets: " << e.what() << std::endl;
197     errno = EDOM;
198     return PRIMESIEVE_ERROR;
199   }
200 }
201 
primesieve_count_quintuplets(uint64_t start,uint64_t stop)202 uint64_t primesieve_count_quintuplets(uint64_t start, uint64_t stop)
203 {
204   try
205   {
206     return count_quintuplets(start, stop);
207   }
208   catch (const std::exception& e)
209   {
210     std::cerr << "primesieve_count_quintuplets: " << e.what() << std::endl;
211     errno = EDOM;
212     return PRIMESIEVE_ERROR;
213   }
214 }
215 
primesieve_count_sextuplets(uint64_t start,uint64_t stop)216 uint64_t primesieve_count_sextuplets(uint64_t start, uint64_t stop)
217 {
218   try
219   {
220     return count_sextuplets(start, stop);
221   }
222   catch (const std::exception& e)
223   {
224     std::cerr << "primesieve_count_sextuplets: " << e.what() << std::endl;
225     errno = EDOM;
226     return PRIMESIEVE_ERROR;
227   }
228 }
229 
primesieve_print_primes(uint64_t start,uint64_t stop)230 void primesieve_print_primes(uint64_t start, uint64_t stop)
231 {
232   try
233   {
234     print_primes(start, stop);
235   }
236   catch (const std::exception& e)
237   {
238     std::cerr << "primesieve_print_primes: " << e.what() << std::endl;
239     errno = EDOM;
240   }
241 }
242 
primesieve_print_twins(uint64_t start,uint64_t stop)243 void primesieve_print_twins(uint64_t start, uint64_t stop)
244 {
245   try
246   {
247     print_twins(start, stop);
248   }
249   catch (const std::exception& e)
250   {
251     std::cerr << "primesieve_print_twins: " << e.what() << std::endl;
252     errno = EDOM;
253   }
254 }
255 
primesieve_print_triplets(uint64_t start,uint64_t stop)256 void primesieve_print_triplets(uint64_t start, uint64_t stop)
257 {
258   try
259   {
260     print_triplets(start, stop);
261   }
262   catch (const std::exception& e)
263   {
264     std::cerr << "primesieve_print_triplets: " << e.what() << std::endl;
265     errno = EDOM;
266   }
267 }
268 
primesieve_print_quadruplets(uint64_t start,uint64_t stop)269 void primesieve_print_quadruplets(uint64_t start, uint64_t stop)
270 {
271   try
272   {
273     print_quadruplets(start, stop);
274   }
275   catch (const std::exception& e)
276   {
277     std::cerr << "primesieve_print_quadruplets: " << e.what() << std::endl;
278     errno = EDOM;
279   }
280 }
281 
primesieve_print_quintuplets(uint64_t start,uint64_t stop)282 void primesieve_print_quintuplets(uint64_t start, uint64_t stop)
283 {
284   try
285   {
286     print_quintuplets(start, stop);
287   }
288   catch (const std::exception& e)
289   {
290     std::cerr << "primesieve_print_quintuplets: " << e.what() << std::endl;
291     errno = EDOM;
292   }
293 }
294 
primesieve_print_sextuplets(uint64_t start,uint64_t stop)295 void primesieve_print_sextuplets(uint64_t start, uint64_t stop)
296 {
297   try
298   {
299     print_sextuplets(start, stop);
300   }
301   catch (const std::exception& e)
302   {
303     std::cerr << "primesieve_print_sextuplets: " << e.what() << std::endl;
304     errno = EDOM;
305   }
306 }
307 
primesieve_get_sieve_size()308 int primesieve_get_sieve_size()
309 {
310   return get_sieve_size();
311 }
312 
primesieve_get_num_threads()313 int primesieve_get_num_threads()
314 {
315   return get_num_threads();
316 }
317 
primesieve_set_sieve_size(int sieve_size)318 void primesieve_set_sieve_size(int sieve_size)
319 {
320   set_sieve_size(sieve_size);
321 }
322 
primesieve_set_num_threads(int num_threads)323 void primesieve_set_num_threads(int num_threads)
324 {
325   set_num_threads(num_threads);
326 }
327 
primesieve_get_max_stop()328 uint64_t primesieve_get_max_stop()
329 {
330   return get_max_stop();
331 }
332 
primesieve_version()333 const char* primesieve_version()
334 {
335   return PRIMESIEVE_VERSION;
336 }
337