blc_array.cpp 20.1 KB
Newer Older
Arnaud Blanchard's avatar
Arnaud Blanchard committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* Basic Library for C/C++ (blclib)
 Copyright  ETIS — ENSEA, Université de Cergy-Pontoise, CNRS (2011 - 2014)
 Author: A. Blanchard
 This software is a computer program whose purpose is to simulate neural networks and control robots or simulations.
 This software is governed by the CeCILL v2.1 license under French law and abiding by the rules of distribution of free software.
 You can use, modify and/ or redistribute the software under the terms of the CeCILL v2.1 license as circulated by CEA, CNRS and INRIA at the following URL "http://www.cecill.info".
 As a counterpart to the access to the source code and  rights to copy, modify and redistribute granted by the license,
  users are provided only with a limited warranty and the software's author, the holder of the economic rights,  and the successive licensors have only limited liability.
  In this respect, the user's attention is drawn to the risks associated with loading, using, modifying and/or developing or reproducing the software by the user in light of its specific status of free software,
  that may mean  that it is complicated to manipulate, and that also therefore means that it is reserved for developers and experienced professionals having in-depth computer knowledge.
 Users are therefore encouraged to load and test the software's suitability as regards their requirements in conditions enabling the security of their systems and/or data to be ensured
  and, more generally, to use and operate it in the same conditions as regards security.
  The fact that you are presently reading this means that you have had knowledge of the CeCILL v2.1 license and that you accept its terms. */

//
//  Created by Arnaud Blanchard on 17/06/2014.
//

#include "blc_array.h"
#include "blc_text.h"

22
#include <signal.h> //raise
23
#include <stdio.h> //fopen
Arnaud Blanchard's avatar
Arnaud Blanchard committed
24

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
START_EXTERN_C
blc_dim *vcreate_blc_dims(size_t *size, uint32_t type, int dims_nb, int length, va_list arguments){
    blc_dim *dim, *dims;
    
    dims=MANY_ALLOCATIONS(dims_nb, blc_dim);
    *size=blc_get_type_size(type);
    
    FOR_EACH(dim, dims, dims_nb){
        dim->step=*size;
        (*size)*=length;
        dim->length=length;
        length=va_arg(arguments, int);
    }
    return dims;
}

blc_dim *create_blc_dims(size_t *size, uint32_t type, int dims_nb, int length0, ...){
    blc_dim *dims;
    va_list arguments;
    va_start(arguments, length0);
    
    dims=vcreate_blc_dims(size, type, dims_nb, length0, arguments);
    
    va_end(arguments);
    return dims;
}
END_EXTERN_C

53
blc_array::blc_array():type('NDEF'), format('NDEF'), dims(NULL), dims_nb(0), total_length(0){}
54

55
blc_array::blc_array(uint32_t type, uint32_t format, int dims_nb, int length0, ...){
56
57
58
59
60
61
    va_list arguments;
    
    va_start(arguments, length0);
    vdef_array( type,  format,  dims_nb,  length0, arguments);
    allocate();
    va_end(arguments);
62
63
}

64
blc_array::~blc_array(){
65
    if (dims) FREE(dims);
66
67
}

Arnaud Blanchard's avatar
Arnaud Blanchard committed
68
void blc_array::vdef_array(uint32_t type, uint32_t format, int dims_nb, int length, va_list arguments){
69
70
71
72
73
74
    total_length=1;
    this->dims_nb=dims_nb;
    this->type=type;
    this->format=format;
    dims=vcreate_blc_dims(&size, type, dims_nb, length, arguments);
    total_length=size/get_type_size();
Arnaud Blanchard's avatar
Arnaud Blanchard committed
75
76
77
}

void blc_array::def_array(uint32_t type, uint32_t format, int dims_nb, int length, ...){
78
79
80
81
82
83
    va_list arguments;
    
    va_start(arguments, length);
    vdef_array(type, format, dims_nb, length, arguments);
    va_end(arguments);
    
Arnaud Blanchard's avatar
Arnaud Blanchard committed
84
85
}

Arnaud Blanchard's avatar
Arnaud Blanchard committed
86
void blc_array::def_array(uint32_t type, uint32_t format, int dims_nb, blc_dim const *dims){
87
88
89
90
91
92
93
94
95
96
97
    
    this->type=type;
    this->format=format;
    this->dims_nb=dims_nb;
    
    size=get_type_size();
    this->dims=MANY_ALLOCATIONS(dims_nb, blc_dim);
    memcpy(this->dims, dims, sizeof(blc_dim)*dims_nb);
    
    size =dims[dims_nb-1].length*dims[dims_nb-1].step;
    total_length=size/get_type_size();
Arnaud Blanchard's avatar
Arnaud Blanchard committed
98
99
}

100
void blc_array::def_array(uint32_t type, uint32_t format, char const *dims_string){
101
102
103
    this->type=type;
    this->format=format;
    sscan_dims(dims_string);
104
105
}

106
void blc_array::init(char const *properties){
107
108
    sscan_properties(properties);
    allocate();
109
110
111
}

void blc_array::vinit(uint32_t type, uint32_t format, int dims_nb, int length, va_list arguments){
112
113
    vdef_array(type, format, dims_nb, length, arguments);
    allocate();
114
115
116
}

void blc_array::init(uint32_t type, uint32_t format, int dims_nb, int length, ...){
117
118
119
120
121
122
    va_list arguments;
    
    va_start(arguments, length);
    vinit(type, format, dims_nb, length, arguments);
    va_end(arguments);
    
123
124
}

Arnaud Blanchard's avatar
Arnaud Blanchard committed
125
void blc_array::add_dim(int length, int step){
126
127
128
129
130
131
132
133
    blc_dim dim;
    
    dim.length=length;
    dim.step=step;
    
    APPEND_ITEM(&dims, &dims_nb, &dim);
    size=step*length; //Check if it always true ??
    total_length=size/get_type_size();
Arnaud Blanchard's avatar
Arnaud Blanchard committed
134
135
136
}

void blc_array::add_dim(int length){
137
138
    if (dims_nb==0) add_dim(length, get_type_size());
    else add_dim(length, dims[dims_nb-1].length*dims[dims_nb-1].step);
Arnaud Blanchard's avatar
Arnaud Blanchard committed
139
140
141
}

void blc_array::set_dims(int dims_nb, int length, ...){
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
    blc_dim *dim;
    va_list args;
    
    if (dims) FREE(dims);
    
    this->dims_nb=dims_nb;
    dims=MANY_ALLOCATIONS(dims_nb, blc_dim);
    
    size=get_type_size();
    va_start(args, length);
    FOR_EACH(dim, dims,  dims_nb)
    {
        size*=length;
        dim->step=1;
        dim->length=length;
        length=va_arg(args, int);
    }
    va_end(args);
    total_length=size/get_type_size();
Arnaud Blanchard's avatar
Arnaud Blanchard committed
161
162
163
}

int blc_array::get_type_size(){
164
    return blc_get_type_size(type);
Arnaud Blanchard's avatar
Arnaud Blanchard committed
165
166
167
}

int blc_array::sprint_dims(char *string, int string_size){
168
169
170
171
172
173
174
175
176
    int i, width=0;
    
    if (dims_nb==0)  width=snprintf(string, string_size,  "0");
    else {
        width=snprintf(string, string_size, "%lu", dims[0].length);
        for(i=1; i<dims_nb; i++) width+=snprintf(string+width, string_size-width, "x%lu", dims[i].length);
    }
    if (width >= string_size) EXIT_ON_ERROR("The reserved size '%d' is too small to store the '%d' dims.",size, dims_nb);
    return width;
Arnaud Blanchard's avatar
Arnaud Blanchard committed
177
178
179
}

int blc_array::fprint_dims(FILE *file)const {
180
181
182
183
184
185
186
187
    int i, width;
    
    if (dims_nb==0)  width=fprintf(file, "0");
    else {
        width=fprintf(file, "%lu", dims[0].length);
        for(i=1; i<dims_nb; i++) width+=fprintf(file, "x%lu", dims[i].length);
    }
    return width;
Arnaud Blanchard's avatar
Arnaud Blanchard committed
188
189
190
}

void blc_array::fscan_dims(FILE *file){
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
    blc_dim *dim;
    size_t length;
    
    size=get_type_size();
    
    FSCANF(1, file, "%lu", &length);
    if (dims) FREE(dims);
    dims_nb=0;
    
    if (length != 0){
        do{
            dim=APPEND_ALLOCATION(&dims, &dims_nb, blc_dim);
            dim->length=length;
            dim->step=size;
            size*=dim->length;
        }while(fscanf(file, "x%lu", &length)==1);
    }
    total_length=size/get_type_size();
Arnaud Blanchard's avatar
Arnaud Blanchard committed
209
210
}

211
int blc_array::sscan_dims(char const *string){
Arnaud Blanchard's avatar
Arnaud Blanchard committed
212
    blc_dim *dim;
213
    int pos, total_pos;
214
    size_t length;
215
    
Arnaud Blanchard's avatar
Arnaud Blanchard committed
216
217
    size=get_type_size();
    
218
    SSCANF(1, string, "%lu%n", &length, &pos);
219
    total_pos=0;
Arnaud Blanchard's avatar
Arnaud Blanchard committed
220
    dims_nb=0;
Arnaud Blanchard's avatar
Arnaud Blanchard committed
221
    if (dims) FREE(dims);
Arnaud Blanchard's avatar
Arnaud Blanchard committed
222
223
    if (length != 0){
        do{
224
            total_pos+=pos;
Arnaud Blanchard's avatar
Arnaud Blanchard committed
225
226
227
228
            dim=APPEND_ALLOCATION(&dims, &dims_nb, blc_dim);
            dim->length=length;
            dim->step=size;
            size*=dim->length;
Arnaud Blanchard's avatar
Arnaud Blanchard committed
229
        }while(sscanf(string+total_pos, "x%lu%n", &length, &pos)==1);
Arnaud Blanchard's avatar
Arnaud Blanchard committed
230
    }
231
    total_length=size/get_type_size();
232
233
234
235
236
237
    return total_pos;
}


//Should use code in common with fprint_info
void blc_array::sprint_properties(char *buffer, size_t buffer_size){
238
239
240
241
242
243
244
245
246
    int width;
    uint32_t str_type;
    uint32_t str_format;
    
    if (type==0) EXIT_ON_ERROR("The type should not be NULL. Use 'NDEF' by default.");
    if (format==0) EXIT_ON_ERROR("The format should not be NULL. Use 'NDEF' by default.");
    
    width=snprintf(buffer, buffer_size, "%.4s %.4s ", UINT32_TO_STRING(str_type, type),  UINT32_TO_STRING(str_format, format));
    width+=sprint_dims(buffer+width,buffer_size-width);
247
248
249
}

void blc_array::fprint_properties(FILE *file){
250
251
252
253
254
255
256
257
258
259
    int width;
    uint32_t net_type = htonl(type);
    uint32_t net_format = htonl(format);
    
    if (type==0) EXIT_ON_ERROR("The type should not be NULL. Use 'NDEF' by default.");
    if (format==0) EXIT_ON_ERROR("The format should not be NULL. Use 'NDEF' by default.");
    
    
    fprintf(file, "%.4s %.4s ", (char*)&net_type, (char*)&net_format);
    width=fprint_dims(file);
260
261
262
263
}

//Should use code in common with fscan_info
void blc_array::sscan_properties(char const *string){
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
    int ret, pos;
    
    dims_nb=0;
    data=NULL;
    size=0;
    
    ret = sscanf(string, "%4c %4c%n", (char*)&type, (char*)&format, &pos);
    if (ret == EOF) EXIT_ON_ERROR("End of FILE");
    else if (ret!=2) EXIT_ON_ERROR("%d parameters have been read instead of 2 in '%s'.", ret,  string);
    
    string+=pos;
    
    NTOHL(type);
    NTOHL(format);
    
    string+=sscan_dims(string);
280
281
282
}

void blc_array::fscan_properties(FILE *file){
283
284
285
286
287
288
289
290
291
292
293
294
295
    int ret;
    dims_nb=0;
    data=NULL;
    size=0;
    
    ret = fscanf(file, "%4c %4c ", (char*)&type, (char*)&format);
    if (ret == EOF) EXIT_ON_ERROR("End of FILE");
    else if (ret!=2) EXIT_ON_ERROR("%d parameters have been read instead of 2", ret);
    
    NTOHL(type);
    NTOHL(format);
    
    fscan_dims(file);
Arnaud Blanchard's avatar
Arnaud Blanchard committed
296
297
}

298
//is it usefull ??
299
/*
300
301
302
303
304
305
306
307
308
309
 size_t blc_array::get_minimum_size(){
 blc_dim *dim;
 size_t size = get_type_size();
 
 FOR_EACH(dim, dims, dims_nb) {
 if (dim->length==0) EXIT_ON_ERROR("Length must not be 0 on dim '%d'");
 size*=dim->length;
 }
 return size;
 }*/
Arnaud Blanchard's avatar
Arnaud Blanchard committed
310
311

void blc_array::fprint_debug (FILE *file) const{
312
313
314
315
316
317
    uint32_t type_str, format_str;
    
    fprintf(file, "\nblc_array:\n type:%.4s, format:%.4s, dims_nb:%d, size:%ld \n", UINT32_TO_STRING(type_str, type), UINT32_TO_STRING(format_str, format),  dims_nb, size);
    fprint_dims(file);
    fprintf(file, "\n");
    if (data==NULL) fprintf(file, "data is null\n");
Arnaud Blanchard's avatar
Arnaud Blanchard committed
318
319
}

320
void blc_array::def_with_blc_file(char const *filename){
321
322
323
324
325
326
327
328
329
330
331
    FILE *file;
    const char *ext;
    
    ext=blc_get_filename_extension(filename);
    if (strcmp(ext, "blc")!=0)  EXIT_ON_ERROR("'%s' does not .blc extension but '%s'", filename, ext);
    
    SYSTEM_ERROR_CHECK(file=fopen(filename, "r"), NULL, "Opening filename '%s'.", filename);
    
    fscan_properties(file);
    fscanf(file, "\n");
    fclose(file);
332
333
334
}

void blc_array::init_with_blc_file(char const *filename){
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
    FILE *file;
    ssize_t ret;
    const char *ext;
    
    ext=blc_get_filename_extension(filename);
    if (strcmp(ext, "blc")!=0)  EXIT_ON_ERROR("'%s' does not .blc extension but '%s'", filename, ext);
    
    SYSTEM_ERROR_CHECK(file=fopen(filename, "r"), NULL, "Opening filename '%s'.", filename);
    
    fscan_properties(file);
    fscanf(file, "\n");
    allocate();
    SYSTEM_ERROR_CHECK(ret=fread(data, 1, size, file), -1, "Reading the blc_array data for '%s'", filename);
    if (ret!=size) EXIT_ON_ARRAY_ERROR(this, "Reading only '%ld' bytes for file '%s'", ret, filename);
    fclose(file);
350
}
Arnaud Blanchard's avatar
Arnaud Blanchard committed
351

352
void blc_array::update_with_blc_file(char const *filename){
353
354
355
356
357
358
359
360
361
362
363
364
365
366
    FILE *file;
    ssize_t ret;
    char const *ext;
    
    ext=blc_get_filename_extension(filename);
    if (strcmp(ext, "blc")!=0)  EXIT_ON_ERROR("'%s' does not .blc extension but '%s'", filename, ext);
    
    SYSTEM_ERROR_CHECK(file=fopen(filename, "r"), NULL, "Opening filename '%s'.", filename);
    
    fscan_properties(file);
    fscanf(file, "\n");
    SYSTEM_ERROR_CHECK(ret=fread(data, size, 1, file), -1, "Reading the blc_array data for '%s'", filename);
    if (ret!=size) EXIT_ON_ARRAY_ERROR(this, "Reading only '%l' bytes for file '%s'", ret, filename);
    fclose(file);
367
368
369
}

void blc_array::save_blc_file(char const *filename){
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
    FILE *file;
    ssize_t ret;
    char const *ext;
    
    ext=blc_get_filename_extension(filename);
    
    //This test is mainly useful to avoid to accidently erase files.
    if (strcmp(ext, "blc")!=0)  EXIT_ON_ERROR("'%s' does not .blc extension but '%s'", filename, ext);
    
    SYSTEM_ERROR_CHECK(file=fopen(filename, "w"), NULL, "Opening filename '%s'.", filename);
    
    fprint_properties(file);
    fprintf(file, "\n");
    
    SYSTEM_ERROR_CHECK(ret=fwrite(data, 1, size, file), -1, "Writing the blc_array data for '%s'", filename);
    if (ret!=size) EXIT_ON_ARRAY_ERROR(this, "Writing only '%ld' bytes for file '%s'", ret, filename);
    fclose(file);
387
388
389
390
}


void blc_array::fprint_tsv(FILE *file){
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
    int dim, length, i, j;
    uint32_t type_str;
    blc_dim *tmp_dims;
    
    dim = 0;
    j = 0;
    
    tmp_dims = MANY_ALLOCATIONS(dims_nb, blc_dim);
    memcpy(tmp_dims, dims, dims_nb * sizeof(blc_dim));
    
    while (dim != dims_nb)
    {
        if (dim == 0)
        {
            length = tmp_dims[0].length;
            switch (type)
            {
                case 'INT8': if (format=='TEXT')fprintf(file, "%-*s ", length, chars);
                else FOR(i, length) fprintf(file, "%4d\nt", chars[i + j]);
                    break;
                case 'UIN8':
                    FOR(i, length){
                        fprintf(file, "%3u", uchars[i + j]);
                        if (i != length-1) fputc('\t', file);
                    }
                    break;
                case 'IN16':
                    FOR(i, length){
                        fprintf(file, "%6d", ints16[i + j]);
                        if (i != length-1) fputc('\t', file);
                    }
                    break;
                case 'UI16':
                    FOR(i, length){
                        fprintf(file, "%5u", uints16[i + j]);
                        if (i != length-1) fputc('\t', file);
                    }
                    break;
                case 'IN32':
                    FOR(i, length){
                        fprintf(file, "%d", uints32[i + j]);
                        if (i != length-1) fputc('\t', file);
                    }
                    break;
                case 'UI32':
                    FOR(i, length){
                        fprintf(file, "%u", uints32[i + j]);
                        if (i != length-1) fputc('\t', file);
                    }
                    break;
                case 'FL32':
                    FOR(i, length){
                        fprintf(file, "%f", floats[i + j]);
                        if (i != length-1) fputc('\t', file);
                    }
                    break;
                case 'FL64':
                    FOR(i, length){
                        fprintf(file, "%lf", doubles[i + j]);
                        if (i != length-1) fputc('\t', file);
                    }
                    break;
                default:
                    EXIT_ON_ARRAY_ERROR(this, "You cannot display type: '%.4s'", UINT32_TO_STRING(type_str, type));
            }
            //I increment what I have just done
            j+=length;
            dim++;
        }
        else
        {
            tmp_dims[dim].length--;
            if (tmp_dims[dim].length == 0)
            {
                tmp_dims[dim].length = dims[dim].length;
                dim++;
            }
            else dim--;
            
            if (dim==dims_nb-2 ) fprintf(file, "\n");
            else fprintf(file, "\t");
        }
    }
    fprintf(file, "\n");
    FREE(tmp_dims);
476
477
478
}

void blc_array::def_with_tsv_file(char const *filename){
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
    FILE *file;
    const char *ext;
    float value;
    int tmp_length, ret,  pos;
    
    ext=blc_get_filename_extension(filename);
    if (strcmp(ext, "tsv")!=0)  EXIT_ON_ERROR("'%s' does not .tsv extension but '%s'", filename, ext);
    
    SYSTEM_ERROR_CHECK(file=fopen(filename, "r"), NULL, "Opening filename '%s'.", filename);
    
    dims_nb=0;
    do{
        tmp_length=0;
        do{
            SYSTEM_ERROR_CHECK(ret=fscanf(file, "%f", &value), -1, "Scanning file '%s'", filename);
            tmp_length++;
        }
        while(ret==1);
        this->add_dim(tmp_length);
        SYSTEM_ERROR_CHECK(ret=fscanf(file, "\n%n", &pos), -1, "Scanning file '%s'", filename);
    }while(pos==1);
    fclose(file);
Arnaud Blanchard's avatar
Arnaud Blanchard committed
501
502
}

503
void blc_array::update_with_tsv_file(char const *filename){
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
    FILE *file;
    char const *ext;
    int dim, length, j;
    blc_dim *tmp_dims;
    
    ext=blc_get_filename_extension(filename);
    if (strcmp(ext, "tsv")!=0)  EXIT_ON_ERROR("'%s' has not .tsv extension but '%s'", filename, ext);
    
    SYSTEM_ERROR_CHECK(file=fopen(filename, "r"), NULL, "Opening filename '%s'.", filename);
    
    dim = 0;
    j = 0;
    
    tmp_dims = MANY_ALLOCATIONS(dims_nb, blc_dim);
    memcpy(tmp_dims, dims, dims_nb * sizeof(blc_dim));
    
    
    ///TODO find a simpler way.
    switch (type){
            
        case 'FL32':
            while (dim != dims_nb)
            {
                if (dim == 0){
                    length = tmp_dims[0].length;
                    fscan_tsv_floats(file, &floats[j], length);
                    //I increment what I have just done
                    j+=length;
                    dim++;
                }
                else{
                    tmp_dims[dim].length--;
                    if (tmp_dims[dim].length == 0){
                        tmp_dims[dim].length = dims[dim].length;
                        dim++;
                    }
                    else dim--;
                    
                    if (dim==dims_nb-2 )fscanf(file, "\n");
                    else fscanf(file, "\t");
                }
            }
            break;
        case 'UIN8':
            while (dim != dims_nb)
            {
                if (dim == 0){
                    length = tmp_dims[0].length;
                    fscan_tsv_uchars(file, &uchars[j], length);
                    //I increment what I have just done
                    j+=length;
                    dim++;
                }
                else{
                    tmp_dims[dim].length--;
                    if (tmp_dims[dim].length == 0){
                        tmp_dims[dim].length = dims[dim].length;
                        dim++;
                    }
                    else dim--;
                    
                    if (dim==dims_nb-2 )fscanf(file, "\n");
                    else fscanf(file, "\t");
                }
            }
            break;
        default:
            EXIT_ON_ARRAY_ERROR(this, "This type is not working with this function. Only 'UIN8' and 'FL32' work for naw.");
            
    }
    FREE(tmp_dims);
    fclose(file);
576
577
}

578
void blc_array::save_tsv_file(char const *filename){
579
580
581
582
583
584
585
586
587
588
589
590
    FILE *file;
    char const *ext;
    
    ext=blc_get_filename_extension(filename);
    
    //This test is mainly useful to avoid to accidently erase files. At least it is a .tsv
    if (strcmp(ext, "tsv")!=0)  EXIT_ON_ERROR("'%s' has not tsv extension but '%s'", filename, ext);
    
    SYSTEM_ERROR_CHECK(file=fopen(filename, "w"), NULL, "Opening filename '%s' for writing.", filename);
    this->fprint_tsv(file);
    
    fclose(file);
Arnaud Blanchard's avatar
Arnaud Blanchard committed
591
}
592

593
void blc_array::fprint_surface_uchars(FILE *file, int ansi_terminal){
594
    blc_fprint_3Darray(file, this->uchars, this->size, 0, 1, 1, dims[0].step, dims[0].length, dims[1].step, dims[1].length, ansi_terminal);
595
596
597
598
}

/* C wrapper */
START_EXTERN_C
599
600
601
602




603
void blc_array_def(blc_array *array,  uint32_t type, uint32_t format, int dims_nb, int length0, ...){
604
605
606
607
608
    va_list arguments;
    
    va_start(arguments, length0);
    array->def_array(type, format, dims_nb, length0, arguments);
    va_end(arguments);
609
610
611
}

void blc_array_init(blc_array *array,  uint32_t type, uint32_t format, int dims_nb, int length0, ...){
612
613
614
615
616
    va_list arguments;
    
    va_start(arguments, length0);
    array->init(type, format, dims_nb, length0, arguments);
    va_end(arguments);
617
618
}

619
620
// Envoie un message d'erreur avec name_of_file, name_of_function, number_of_line et affiche le message formate avec les parametres variables. Puis exit le programme avec le parametre EXIT_FAILURE. To be used with EXIT_ON_ERROR.
void blc_array_fatal_error(blc_array const *array, const char *name_of_file, const char* name_of_function, int numero_of_line, const char *message, ...){
621
622
623
624
625
626
627
628
629
630
    va_list arguments;
    va_start(arguments, message);
    fprintf(stderr, "\n%s: %s \t %s \t %i :\nError: ", blc_program_name, name_of_file, name_of_function, numero_of_line);
    color_vfprintf(BLC_BRIGHT_RED, stderr, message, arguments);
    va_end(arguments);
    array->fprint_debug(stderr);
    fprintf(stderr, "\n\n");
    fflush(stderr);
    raise(SIGABRT);
    exit(EXIT_FAILURE);
631
632
633
}

void blc_array_destroy(blc_array *array){
634
    array->~blc_array();
635
}
636
END_EXTERN_C