aboutsummaryrefslogtreecommitdiff
path: root/src/solvers/h48
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2024-10-12 16:23:05 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2024-10-12 16:23:05 +0200
commit182e2d45678d0487be71370c37b88daca3d2c54b (patch)
tree3987ecd9bade082a7b41901c2376daa73401e548 /src/solvers/h48
parentda8fdd4955fd24666643915a6728678e9965a0d3 (diff)
downloadnissy-core-182e2d45678d0487be71370c37b88daca3d2c54b.tar.gz
nissy-core-182e2d45678d0487be71370c37b88daca3d2c54b.zip
Make gendata and co safer by checking buffer size
Diffstat (limited to 'src/solvers/h48')
-rw-r--r--src/solvers/h48/gendata_cocsep.h11
-rw-r--r--src/solvers/h48/gendata_h48.h120
-rw-r--r--src/solvers/h48/gendata_types_macros.h1
-rw-r--r--src/solvers/h48/solve.h9
-rw-r--r--src/solvers/h48/solve_multithread.h12
5 files changed, 84 insertions, 69 deletions
diff --git a/src/solvers/h48/gendata_cocsep.h b/src/solvers/h48/gendata_cocsep.h
index 18bfc38..b46bcf3 100644
--- a/src/solvers/h48/gendata_cocsep.h
+++ b/src/solvers/h48/gendata_cocsep.h
@@ -1,7 +1,8 @@
1STATIC_INLINE bool get_visited(const uint8_t *, int64_t); 1STATIC_INLINE bool get_visited(const uint8_t *, int64_t);
2STATIC_INLINE void set_visited(uint8_t *, int64_t); 2STATIC_INLINE void set_visited(uint8_t *, int64_t);
3 3
4STATIC size_t gendata_cocsep(void *, uint64_t *, cube_t *); 4STATIC size_t gendata_cocsep(
5 char [static COCSEP_FULLSIZE+INFOSIZE], uint64_t *, cube_t *);
5STATIC uint32_t gendata_cocsep_dfs(cocsep_dfs_arg_t *); 6STATIC uint32_t gendata_cocsep_dfs(cocsep_dfs_arg_t *);
6STATIC void getdistribution_cocsep(const uint32_t *, uint64_t [static 21]); 7STATIC void getdistribution_cocsep(const uint32_t *, uint64_t [static 21]);
7 8
@@ -19,7 +20,11 @@ After the data as described above, more auxiliary information is appended:
19 of positions having that pruning value. 20 of positions having that pruning value.
20*/ 21*/
21STATIC size_t 22STATIC size_t
22gendata_cocsep(void *buf, uint64_t *selfsim, cube_t *rep) 23gendata_cocsep(
24 char buf[static COCSEP_FULLSIZE+INFOSIZE],
25 uint64_t *selfsim,
26 cube_t *rep
27)
23{ 28{
24 uint32_t *buf32, cc; 29 uint32_t *buf32, cc;
25 uint16_t n; 30 uint16_t n;
@@ -64,7 +69,7 @@ gendata_cocsep(void *buf, uint64_t *selfsim, cube_t *rep)
64 info.distribution[i] = cc; 69 info.distribution[i] = cc;
65 } 70 }
66 71
67 writetableinfo(&info, buf); 72 writetableinfo(&info, COCSEP_FULLSIZE+INFOSIZE, buf);
68 73
69 DBG_ASSERT(n == COCSEP_CLASSES, 0, 74 DBG_ASSERT(n == COCSEP_CLASSES, 0,
70 "cocsep: computed %" PRIu16 " symmetry classes, " 75 "cocsep: computed %" PRIu16 " symmetry classes, "
diff --git a/src/solvers/h48/gendata_h48.h b/src/solvers/h48/gendata_h48.h
index 50ab01c..2a4469f 100644
--- a/src/solvers/h48/gendata_h48.h
+++ b/src/solvers/h48/gendata_h48.h
@@ -1,14 +1,16 @@
1STATIC uint64_t gendata_h48short(gendata_h48short_arg_t *); 1STATIC uint64_t gendata_h48short(gendata_h48short_arg_t *);
2STATIC size_t gendata_h48(gendata_h48_arg_t *); 2STATIC int64_t gendata_h48(gendata_h48_arg_t *);
3STATIC size_t gendata_h48h0k4(gendata_h48_arg_t *); 3STATIC void gendata_h48h0k4(gendata_h48_arg_t *);
4STATIC size_t gendata_h48k2(gendata_h48_arg_t *); 4STATIC void gendata_h48k2(gendata_h48_arg_t *);
5STATIC void gendata_h48k2_realcoord(gendata_h48_arg_t *);
6
5STATIC void * gendata_h48h0k4_runthread(void *); 7STATIC void * gendata_h48h0k4_runthread(void *);
8STATIC void * gendata_h48k2_runthread(void *);
9
6STATIC_INLINE void gendata_h48_mark_atomic(gendata_h48_mark_t *); 10STATIC_INLINE void gendata_h48_mark_atomic(gendata_h48_mark_t *);
7STATIC_INLINE void gendata_h48_mark(gendata_h48_mark_t *); 11STATIC_INLINE void gendata_h48_mark(gendata_h48_mark_t *);
8STATIC_INLINE bool gendata_h48k2_dfs_stop(cube_t, int8_t, h48k2_dfs_arg_t *); 12STATIC_INLINE bool gendata_h48k2_dfs_stop(cube_t, int8_t, h48k2_dfs_arg_t *);
9STATIC size_t gendata_h48k2_realcoord(gendata_h48_arg_t *);
10STATIC void gendata_h48k2_dfs(h48k2_dfs_arg_t *arg); 13STATIC void gendata_h48k2_dfs(h48k2_dfs_arg_t *arg);
11STATIC void * gendata_h48k2_runthread(void *);
12STATIC tableinfo_t makeinfo_h48k2(gendata_h48_arg_t *); 14STATIC tableinfo_t makeinfo_h48k2(gendata_h48_arg_t *);
13STATIC void getdistribution_h48(const uint8_t *, 15STATIC void getdistribution_h48(const uint8_t *,
14 uint64_t [static INFO_DISTRIBUTION_LEN], uint8_t, uint8_t); 16 uint64_t [static INFO_DISTRIBUTION_LEN], uint8_t, uint8_t);
@@ -62,75 +64,77 @@ gendata_h48short(gendata_h48short_arg_t *arg)
62} 64}
63 65
64/* Generic function that dispatches to the data generators */ 66/* Generic function that dispatches to the data generators */
65STATIC size_t 67STATIC int64_t
66gendata_h48(gendata_h48_arg_t *arg) 68gendata_h48(gendata_h48_arg_t *arg)
67{ 69{
70 uint64_t size;
68 void *cocsepdata_offset; 71 void *cocsepdata_offset;
69 size_t cocsepsize, h48size; 72 size_t cocsepsize;
70 tableinfo_t cocsepinfo; 73 tableinfo_t cocsepinfo;
71 74
72 cocsepsize = gendata_cocsep(arg->buf, arg->selfsim, arg->crep); 75 if (arg == NULL) {
76 LOG("Error computing H48 data: arg is NULL.\n");
77 return NISSY_ERROR_UNKNOWN;
78 }
73 79
74 if (arg->buf == NULL) { 80 size = 2*INFOSIZE + COCSEP_FULLSIZE + H48_TABLESIZE(arg->h, arg->k);
75 cocsepdata_offset = NULL; 81
76 arg->cocsepdata = NULL; 82 if (arg->buf == NULL)
77 arg->h48buf = NULL; 83 return size; /* Dry-run */
78 } else { 84
79 cocsepdata_offset = (char *)arg->buf + INFOSIZE; 85 if (arg->buf_size < size) {
80 arg->cocsepdata = (uint32_t *)cocsepdata_offset; 86 LOG("Error computing H48 data: buffer is too small "
81 arg->h48buf = (char *)arg->buf + cocsepsize; 87 "(needed %" PRId64 " bytes but received %" PRId64 ")\n",
88 size, arg->buf_size);
89 return NISSY_ERROR_BUFFER_SIZE;
82 } 90 }
83 91
84 arg->base = 99; // TODO: set this somewhere else 92 cocsepsize = gendata_cocsep(arg->buf, arg->selfsim, arg->crep);
93
94 cocsepdata_offset = (char *)arg->buf + INFOSIZE;
95 arg->cocsepdata = (uint32_t *)cocsepdata_offset;
96 arg->h48buf = (char *)arg->buf + cocsepsize;
97
98 arg->base = 99; /* TODO: set this somewhere else */
85 99
86 if (arg->h == 0 && arg->k == 4) { 100 if (arg->h == 0 && arg->k == 4) {
87 h48size = gendata_h48h0k4(arg); 101 gendata_h48h0k4(arg);
88 } else if ((arg->h == 0 || arg->h == 11) && arg->k == 2) { 102 } else if ((arg->h == 0 || arg->h == 11) && arg->k == 2) {
89 h48size = gendata_h48k2_realcoord(arg); 103 gendata_h48k2_realcoord(arg);
90 } else if (arg->k == 2) { 104 } else if (arg->k == 2) {
91 h48size = gendata_h48k2(arg); 105 gendata_h48k2(arg);
92 } else { 106 } else {
93 LOG("Cannot generate data for h = %" PRIu8 " and k = %" PRIu8 107 LOG("Cannot generate data for h = %" PRIu8 " and k = %" PRIu8
94 " (not implemented yet)\n", arg->h, arg->k); 108 " (not implemented yet)\n", arg->h, arg->k);
95 goto gendata_h48_error; 109 return NISSY_ERROR_INVALID_SOLVER;
96 } 110 }
97 111
98 if (arg->buf == NULL) 112 if (readtableinfo(arg->buf_size, arg->buf, &cocsepinfo) != NISSY_OK) {
99 goto gendata_h48_return_size;
100
101 if (!readtableinfo(arg->buf, &cocsepinfo)) {
102 LOG("gendata_h48: could not read info for cocsep table\n"); 113 LOG("gendata_h48: could not read info for cocsep table\n");
103 goto gendata_h48_error; 114 return NISSY_ERROR_UNKNOWN;
104 } 115 }
105 116
106 cocsepinfo.next = cocsepsize; 117 cocsepinfo.next = cocsepsize;
107 if (!writetableinfo(&cocsepinfo, arg->buf)) { 118 if (writetableinfo(&cocsepinfo, arg->buf_size, arg->buf) != NISSY_OK) {
108 LOG("gendata_h48: could not write info for cocsep table" 119 LOG("gendata_h48: could not write info for cocsep table"
109 " with updated 'next' value\n"); 120 " with updated 'next' value\n");
110 goto gendata_h48_error; 121 return NISSY_ERROR_UNKNOWN;
111 } 122 }
112 123
113gendata_h48_return_size: 124 return size;
114 return cocsepsize + h48size;
115
116gendata_h48_error:
117 return 0;
118} 125}
119 126
120STATIC size_t 127STATIC void
121gendata_h48h0k4(gendata_h48_arg_t *arg) 128gendata_h48h0k4(gendata_h48_arg_t *arg)
122{ 129{
123 _Atomic uint8_t *table; 130 _Atomic uint8_t *table;
124 uint8_t val; 131 uint8_t val;
125 int64_t i, sc, done, d, h48max; 132 int64_t i, sc, done, d, h48max;
126 uint64_t t, tt, isize, cc; 133 uint64_t t, tt, isize, cc, bufsize;
127 h48h0k4_bfs_arg_t bfsarg[THREADS]; 134 h48h0k4_bfs_arg_t bfsarg[THREADS];
128 pthread_t thread[THREADS]; 135 pthread_t thread[THREADS];
129 pthread_mutex_t table_mutex[CHUNKS]; 136 pthread_mutex_t table_mutex[CHUNKS];
130 137
131 if (arg->buf == NULL)
132 goto gendata_h48h0k4_return_size;
133
134 arg->info = (tableinfo_t) { 138 arg->info = (tableinfo_t) {
135 .solver = "h48 solver h = 0, k = 4", 139 .solver = "h48 solver h = 0, k = 4",
136 .type = TABLETYPE_PRUNING, 140 .type = TABLETYPE_PRUNING,
@@ -194,10 +198,8 @@ gendata_h48h0k4(gendata_h48_arg_t *arg)
194 } 198 }
195 199
196 arg->info.maxvalue = d - 1; 200 arg->info.maxvalue = d - 1;
197 writetableinfo(&arg->info, arg->h48buf); 201 bufsize = arg->buf_size - COCSEP_FULLSIZE - INFOSIZE;
198 202 writetableinfo(&arg->info, bufsize, arg->h48buf);
199gendata_h48h0k4_return_size:
200 return H48_TABLESIZE(0, 4) + INFOSIZE;
201} 203}
202 204
203STATIC void * 205STATIC void *
@@ -258,7 +260,7 @@ gendata_h48h0k4_runthread(void *arg)
258 return NULL; 260 return NULL;
259} 261}
260 262
261STATIC size_t 263STATIC void
262gendata_h48k2(gendata_h48_arg_t *arg) 264gendata_h48k2(gendata_h48_arg_t *arg)
263{ 265{
264 static const uint8_t shortdepth = 8; 266 static const uint8_t shortdepth = 8;
@@ -313,19 +315,15 @@ gendata_h48k2(gendata_h48_arg_t *arg)
313 uint8_t t; 315 uint8_t t;
314 uint8_t *table; 316 uint8_t *table;
315 int64_t j; 317 int64_t j;
316 uint64_t i, ii, inext, count; 318 uint64_t i, ii, inext, count, bufsize;
317 h48map_t shortcubes; 319 h48map_t shortcubes;
318 gendata_h48short_arg_t shortarg; 320 gendata_h48short_arg_t shortarg;
319 h48k2_dfs_arg_t dfsarg[THREADS]; 321 h48k2_dfs_arg_t dfsarg[THREADS];
320 pthread_t thread[THREADS]; 322 pthread_t thread[THREADS];
321 pthread_mutex_t shortcubes_mutex, table_mutex[CHUNKS]; 323 pthread_mutex_t shortcubes_mutex, table_mutex[CHUNKS];
322 324
323 if (arg->buf == NULL)
324 goto gendata_h48k2_return_size;
325
326 table = (uint8_t *)arg->h48buf + INFOSIZE; 325 table = (uint8_t *)arg->h48buf + INFOSIZE;
327 if (arg->buf != NULL) 326 memset(table, 0xFF, H48_TABLESIZE(arg->h, arg->k));
328 memset(table, 0xFF, H48_TABLESIZE(arg->h, arg->k));
329 327
330 LOG("Computing depth <=%" PRIu8 "\n", shortdepth) 328 LOG("Computing depth <=%" PRIu8 "\n", shortdepth)
331 h48map_create(&shortcubes, capacity, randomizer); 329 h48map_create(&shortcubes, capacity, randomizer);
@@ -379,10 +377,8 @@ gendata_h48k2(gendata_h48_arg_t *arg)
379 arg->info.distribution[t]++; 377 arg->info.distribution[t]++;
380 } 378 }
381 379
382 writetableinfo(&arg->info, arg->h48buf); 380 bufsize = arg->buf_size - COCSEP_FULLSIZE - INFOSIZE;
383 381 writetableinfo(&arg->info, bufsize, arg->h48buf);
384gendata_h48k2_return_size:
385 return H48_TABLESIZE(arg->h, 2) + INFOSIZE;
386} 382}
387 383
388STATIC void * 384STATIC void *
@@ -565,11 +561,11 @@ gendata_h48k2_dfs_stop(cube_t cube, int8_t depth, h48k2_dfs_arg_t *arg)
565 } 561 }
566} 562}
567 563
568STATIC size_t 564STATIC void
569gendata_h48k2_realcoord(gendata_h48_arg_t *arg) 565gendata_h48k2_realcoord(gendata_h48_arg_t *arg)
570{ 566{
571 /* TODO */ 567 /* TODO */
572 return gendata_h48k2(arg); 568 gendata_h48k2(arg);
573} 569}
574 570
575STATIC void * 571STATIC void *
@@ -684,6 +680,7 @@ gendata_h48_derive(uint8_t h, const void *fulltable, void *buf)
684 const uint8_t *h48full; 680 const uint8_t *h48full;
685 uint8_t *h48derive; 681 uint8_t *h48derive;
686 int64_t i, j, h48max; 682 int64_t i, j, h48max;
683 uint64_t bufsize;
687 gendata_h48_arg_t arg; 684 gendata_h48_arg_t arg;
688 tableinfo_t cocsepinfo, fulltableinfo; 685 tableinfo_t cocsepinfo, fulltableinfo;
689 686
@@ -693,7 +690,9 @@ gendata_h48_derive(uint8_t h, const void *fulltable, void *buf)
693 fulltableinfo.bits = 2; 690 fulltableinfo.bits = 2;
694 fulltableinfo.base = 8; 691 fulltableinfo.base = 8;
695 692
696 readtableinfo_n(fulltable, 2, &fulltableinfo); 693 int64_t TODOlarge = 999999999999; /* TODO: cleanup here */
694
695 readtableinfo_n(TODOlarge, fulltable, 2, &fulltableinfo);
697 arg.h = h; 696 arg.h = h;
698 arg.k = fulltableinfo.bits; 697 arg.k = fulltableinfo.bits;
699 arg.maxdepth = 20; 698 arg.maxdepth = 20;
@@ -711,13 +710,15 @@ gendata_h48_derive(uint8_t h, const void *fulltable, void *buf)
711 if (buf == NULL) 710 if (buf == NULL)
712 goto gendata_h48_derive_return_size; 711 goto gendata_h48_derive_return_size;
713 712
714 if (!readtableinfo(buf, &cocsepinfo)) { 713 bufsize = COCSEP_FULLSIZE + INFOSIZE;
714 if (readtableinfo(bufsize, buf, &cocsepinfo) != NISSY_OK) {
715 LOG("gendata_h48: could not read info for cocsep table\n"); 715 LOG("gendata_h48: could not read info for cocsep table\n");
716 goto gendata_h48_derive_error; 716 goto gendata_h48_derive_error;
717 } 717 }
718 718
719 cocsepinfo.next = cocsepsize; 719 cocsepinfo.next = cocsepsize;
720 if (!writetableinfo(&cocsepinfo, buf)) { 720 bufsize = COCSEP_FULLSIZE + INFOSIZE;
721 if (writetableinfo(&cocsepinfo, bufsize, buf) != NISSY_OK) {
721 LOG("gendata_h48_derive: could not write info for cocsep table" 722 LOG("gendata_h48_derive: could not write info for cocsep table"
722 " with updated 'next' value\n"); 723 " with updated 'next' value\n");
723 goto gendata_h48_derive_error; 724 goto gendata_h48_derive_error;
@@ -742,7 +743,8 @@ gendata_h48_derive(uint8_t h, const void *fulltable, void *buf)
742 743
743 getdistribution_h48(h48derive, arg.info.distribution, h, arg.k); 744 getdistribution_h48(h48derive, arg.info.distribution, h, arg.k);
744 745
745 if (!writetableinfo(&arg.info, arg.h48buf)) { 746 bufsize = arg.buf_size - COCSEP_FULLSIZE - INFOSIZE;
747 if (writetableinfo(&arg.info, bufsize, arg.h48buf) != NISSY_OK) {
746 LOG("gendata_h48_derive: could not write info for table\n"); 748 LOG("gendata_h48_derive: could not write info for table\n");
747 goto gendata_h48_derive_error; 749 goto gendata_h48_derive_error;
748 } 750 }
diff --git a/src/solvers/h48/gendata_types_macros.h b/src/solvers/h48/gendata_types_macros.h
index e0e4df7..73a46ff 100644
--- a/src/solvers/h48/gendata_types_macros.h
+++ b/src/solvers/h48/gendata_types_macros.h
@@ -58,6 +58,7 @@ typedef struct {
58 uint8_t base; 58 uint8_t base;
59 uint8_t maxdepth; 59 uint8_t maxdepth;
60 tableinfo_t info; 60 tableinfo_t info;
61 uint64_t buf_size;
61 void *buf; 62 void *buf;
62 void *h48buf; 63 void *h48buf;
63 uint32_t *cocsepdata; 64 uint32_t *cocsepdata;
diff --git a/src/solvers/h48/solve.h b/src/solvers/h48/solve.h
index 3948b15..f2babdf 100644
--- a/src/solvers/h48/solve.h
+++ b/src/solvers/h48/solve.h
@@ -21,7 +21,8 @@ STATIC uint32_t allowednextmove_h48(uint8_t *, uint8_t, uint32_t);
21STATIC void solve_h48_appendsolution(dfsarg_solveh48_t *); 21STATIC void solve_h48_appendsolution(dfsarg_solveh48_t *);
22STATIC_INLINE bool solve_h48_stop(dfsarg_solveh48_t *); 22STATIC_INLINE bool solve_h48_stop(dfsarg_solveh48_t *);
23STATIC int64_t solve_h48_dfs(dfsarg_solveh48_t *); 23STATIC int64_t solve_h48_dfs(dfsarg_solveh48_t *);
24STATIC int64_t solve_h48(cube_t, int8_t, int8_t, int8_t, const void *, char *); 24STATIC int64_t solve_h48(cube_t, int8_t, int8_t,
25 int8_t, uint64_t, const void *, uint64_t, char *);
25 26
26STATIC uint32_t 27STATIC uint32_t
27allowednextmove_h48(uint8_t *moves, uint8_t n, uint32_t h48branch) 28allowednextmove_h48(uint8_t *moves, uint8_t n, uint32_t h48branch)
@@ -163,7 +164,9 @@ solve_h48(
163 int8_t minmoves, 164 int8_t minmoves,
164 int8_t maxmoves, 165 int8_t maxmoves,
165 int8_t maxsolutions, 166 int8_t maxsolutions,
167 uint64_t data_size,
166 const void *data, 168 const void *data,
169 uint64_t solutions_size,
167 char *solutions 170 char *solutions
168) 171)
169{ 172{
@@ -171,9 +174,9 @@ solve_h48(
171 dfsarg_solveh48_t arg; 174 dfsarg_solveh48_t arg;
172 tableinfo_t info; 175 tableinfo_t info;
173 176
174 if(!readtableinfo_n(data, 2, &info)) { 177 if(readtableinfo_n(data_size, data, 2, &info) != NISSY_OK) {
175 LOG("solve_h48: error reading table\n"); 178 LOG("solve_h48: error reading table\n");
176 return 0; 179 return NISSY_ERROR_DATA;
177 } 180 }
178 181
179 arg = (dfsarg_solveh48_t) { 182 arg = (dfsarg_solveh48_t) {
diff --git a/src/solvers/h48/solve_multithread.h b/src/solvers/h48/solve_multithread.h
index 766d84a..3ba914a 100644
--- a/src/solvers/h48/solve_multithread.h
+++ b/src/solvers/h48/solve_multithread.h
@@ -20,7 +20,8 @@ STATIC void copy_queue(task_queue_t *, task_queue_t *, int, _Atomic int64_t *);
20STATIC void *start_thread(void *); 20STATIC void *start_thread(void *);
21STATIC int64_t solve_h48_bfs(dfsarg_solveh48_t *, task_queue_t *, int8_t); 21STATIC int64_t solve_h48_bfs(dfsarg_solveh48_t *, task_queue_t *, int8_t);
22STATIC int64_t solve_h48_single(dfsarg_solveh48_t *, task_queue_t *); 22STATIC int64_t solve_h48_single(dfsarg_solveh48_t *, task_queue_t *);
23STATIC int64_t solve_h48_multithread(cube_t, int8_t, int8_t, int8_t, const void *, char *); 23STATIC int64_t solve_h48_multithread(cube_t, int8_t, int8_t, int8_t,
24 uint64_t, const void *, uint64_t, char *);
24 25
25STATIC void 26STATIC void
26solve_h48_appendsolution_thread(dfsarg_solveh48_t *arg, task_queue_t *tq) 27solve_h48_appendsolution_thread(dfsarg_solveh48_t *arg, task_queue_t *tq)
@@ -236,8 +237,11 @@ solve_h48_multithread(
236 int8_t minmoves, 237 int8_t minmoves,
237 int8_t maxmoves, 238 int8_t maxmoves,
238 int8_t maxsolutions, 239 int8_t maxsolutions,
240 uint64_t data_size,
239 const void *data, 241 const void *data,
240 char *solutions) 242 uint64_t solutions_size,
243 char *solutions
244)
241{ 245{
242 _Atomic int64_t nsols = 0; 246 _Atomic int64_t nsols = 0;
243 int p_depth = 0; 247 int p_depth = 0;
@@ -245,9 +249,9 @@ solve_h48_multithread(
245 tableinfo_t info; 249 tableinfo_t info;
246 pthread_t threads[THREADS]; 250 pthread_t threads[THREADS];
247 251
248 if (!readtableinfo_n(data, 2, &info)){ 252 if (readtableinfo_n(data_size, data, 2, &info) != NISSY_OK) {
249 LOG("solve_h48: error reading table\n"); 253 LOG("solve_h48: error reading table\n");
250 return 0; 254 return NISSY_ERROR_DATA;
251 } 255 }
252 256
253 arg = (dfsarg_solveh48_t){ 257 arg = (dfsarg_solveh48_t){

Generated with cgit - Back to sebastiano.tronto.net