Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
7cc9fd27776eb4d0defa5d822a642b7283cae9cf
[simgrid.git] / src / gras / gs / type.c
1 /* gs_type.c */
2
3 #include "gs/gs_private.h"
4 GRAS_LOG_NEW_DEFAULT_SUBCATEGORY(NDR_type_creation,NDR);
5
6 /*......................................................................
7  * Type
8  */
9
10 /* alloc/free */
11 static
12 struct s_gs_type *
13 _gs_type_alloc(void) {
14         struct s_gs_type        *p_type = NULL;
15         p_type = malloc(sizeof(struct s_gs_type));
16         return p_type;
17 }
18
19 static
20 struct s_gs_type *
21 _gs_type_new(struct s_gs_type_bag       *p_bag,
22              struct s_gs_connection     *p_connection,
23              const char                 *name) {
24
25         struct s_gs_type_bag_ops        *bag_ops = p_bag->bag_ops;
26         struct s_gs_type                *p_type  = NULL;
27
28         p_type = _gs_type_alloc();
29
30         p_type->code = -1;
31         p_type->name = strdup(name);
32
33         p_type->size                    = 0;
34         p_type->alignment               = 0;
35         p_type->aligned_size            = 0;
36         p_type->category_code           = e_gs_type_cat_undefined;
37         p_type->category.undefined_data = NULL;
38         p_type->before_callback         = NULL;
39         p_type->after_callback          = NULL;
40
41         bag_ops->store_type(p_bag, p_connection, p_type);
42
43         return p_type;
44 }
45
46
47
48
49
50 /*......................................................................
51  * Elemental
52  */
53 static
54 struct s_gs_cat_elemental *
55 _gs_elemental_cat_alloc(void) {
56         struct s_gs_cat_elemental       *p_elemental    = NULL;
57
58         p_elemental = malloc(sizeof (struct s_gs_cat_elemental));
59
60         return p_elemental;
61 }
62
63 static
64 struct s_gs_cat_elemental *
65 _gs_elemental_cat_new(void) {
66         struct s_gs_cat_elemental       *p_elemental    = NULL;
67
68         p_elemental = _gs_elemental_cat_alloc();
69         p_elemental->encoding = e_gs_elemental_encoding_undefined;
70
71         return p_elemental;
72 }
73
74 struct s_gs_type *
75 gs_type_new_elemental_with_callback(struct s_gs_type_bag        *p_bag,
76                                     struct s_gs_connection      *p_connection,
77                                     const char                         *name,
78                                     enum e_gs_elemental_encoding  encoding,
79                                     long int                      size,
80
81                                     void (*callback)(void               *vars,
82                                                      struct s_gs_type   *p_type,
83                                                      void               *data)) {
84
85         struct s_gs_type                *p_type         = NULL;
86         struct s_gs_cat_elemental       *p_elemental    = NULL;
87
88         if (callback)
89           DEBUG1("%s",__FUNCTION__);
90         p_elemental = _gs_elemental_cat_new();
91         p_elemental->encoding = encoding;
92
93         p_type = _gs_type_new(p_bag, p_connection, name);
94
95         p_type->size = size > 0?size:0;
96
97         if (size > 0) {
98                 long int sz   = size;
99                 long int mask = sz;
100
101                 while ((sz >>= 1)) {
102                         mask |= sz;
103                 }
104
105                 if (size & (mask >> 1)) {
106                         long int alignment      = 0;
107                         long int aligned_size   = 0;
108
109                         alignment       = (size & ~(mask >> 1)) << 1;
110                         if (alignment < 0)
111                                 GS_FAILURE("elemental type is too large");
112
113                         aligned_size    = aligned(size, alignment);
114                         if (aligned_size < 0)
115                                 GS_FAILURE("elemental type is too large");
116
117                         p_type->alignment       = alignment;
118                         p_type->aligned_size    = aligned_size;
119
120                 } else {
121                         long int alignment      = size & ~(mask >> 1);
122                         long int aligned_size   = aligned(size, alignment);
123
124                         p_type->alignment       = alignment;
125                         p_type->aligned_size    = aligned_size;
126                 }
127
128         } else {
129                 p_type->alignment       = 0;
130                 p_type->aligned_size    = 0;
131         }
132
133         p_type->category_code           = e_gs_type_cat_elemental;
134         p_type->category.elemental_data = p_elemental;
135
136         p_type->before_callback         = callback;
137
138         return p_type;
139 }
140
141 struct s_gs_type *
142 gs_type_new_elemental(struct s_gs_type_bag      *p_bag,
143                       struct s_gs_connection    *p_connection,
144                       const char                         *name,
145                       enum e_gs_elemental_encoding  encoding,
146                       long int                      size) {
147         DEBUG1("%s",__FUNCTION__);
148         return gs_type_new_elemental_with_callback(p_bag, p_connection, name, encoding, size, NULL);
149 }
150
151
152 struct s_gs_type *
153 gs_type_new_unsigned_integer_elemental_with_callback(struct s_gs_type_bag       *p_bag,
154                                                      struct s_gs_connection     *p_connection,
155                                                      const char *name,
156                                                      long int    size,
157
158                                                      void (*callback)(void              *vars,
159                                                                       struct s_gs_type  *p_type,
160                                                                       void              *data)) {
161         if (callback)
162           DEBUG1("%s",__FUNCTION__);
163         return gs_type_new_elemental_with_callback(p_bag, p_connection, name,
164                                                    e_gs_elemental_encoding_unsigned_integer,
165                                                    size,
166                                                    callback);
167 }
168
169 struct s_gs_type *
170 gs_type_new_unsigned_integer_elemental(struct s_gs_type_bag     *p_bag,
171                                        struct s_gs_connection   *p_connection,
172                                        const char *name,
173                                        long int size) {
174         DEBUG1("%s",__FUNCTION__);
175         return gs_type_new_unsigned_integer_elemental_with_callback(p_bag, p_connection, name, size, NULL);
176 }
177
178
179 struct s_gs_type *
180 gs_type_new_signed_integer_elemental_with_callback(struct s_gs_type_bag *p_bag,
181                                                    struct s_gs_connection       *p_connection,
182                                                    const char           *name,
183                                                    long int      size,
184
185                                                    void (*callback)(void                *vars,
186                                                                     struct s_gs_type    *p_type,
187                                                                     void                *data)) {
188         if (callback)
189           DEBUG1("%s",__FUNCTION__);
190         return gs_type_new_elemental_with_callback(p_bag, p_connection, name,
191                                                    e_gs_elemental_encoding_signed_integer,
192                                                    size,
193                                                    callback);
194 }
195
196 struct s_gs_type *
197 gs_type_new_signed_integer_elemental(struct s_gs_type_bag       *p_bag,
198                                      struct s_gs_connection     *p_connection,
199                                      const char *name,
200                                      long int    size) {
201         DEBUG1("%s",__FUNCTION__);
202         return gs_type_new_signed_integer_elemental_with_callback(p_bag, p_connection, name, size, NULL);
203 }
204
205
206 struct s_gs_type *
207 gs_type_new_floating_point_elemental_with_callback(struct s_gs_type_bag *p_bag,
208                                                    struct s_gs_connection       *p_connection,
209                                                    const char           *name,
210                                                    long int      size,
211
212                                                    void (*callback)(void                *vars,
213                                                                     struct s_gs_type    *p_type,
214                                                                     void                *data)) {
215         DEBUG1("%s",__FUNCTION__);
216         return gs_type_new_elemental_with_callback(p_bag, p_connection, name,
217                                                    e_gs_elemental_encoding_floating_point,
218                                                    size,
219                                                    callback);
220
221 }
222
223 struct s_gs_type *
224 gs_type_new_floating_point_elemental(struct s_gs_type_bag       *p_bag,
225                                      struct s_gs_connection     *p_connection,
226                                      const char         *name,
227                                      long int   size) {
228         DEBUG1("%s",__FUNCTION__);
229         return gs_type_new_floating_point_elemental_with_callback(p_bag, p_connection, name, size, NULL);
230 }
231
232
233
234
235
236 /*......................................................................
237  * Struct
238  */
239 static
240 struct s_gs_cat_struct *
241 _gs_struct_cat_alloc(void) {
242         struct s_gs_cat_struct  *p_struct       = NULL;
243         p_struct = malloc(sizeof (struct s_gs_cat_struct));
244         return p_struct;
245 }
246
247 static
248 struct s_gs_cat_struct *
249 _gs_struct_cat_new(void) {
250         struct s_gs_cat_struct  *p_struct       = NULL;
251
252         p_struct = _gs_struct_cat_alloc();
253
254         p_struct->nb_fields     = 0;
255         p_struct->field_array   = NULL;
256
257         return p_struct;
258 }
259
260 struct s_gs_type *
261 gs_type_new_struct_with_callback(struct s_gs_type_bag   *p_bag,
262                                  struct s_gs_connection *p_connection,
263                                  const char *name,
264
265                                  void (*before_callback)(void           *vars,
266                                                          struct s_gs_type       *p_type,
267                                                          void           *data),
268
269                                  void (*after_callback)(void            *vars,
270                                                         struct s_gs_type        *p_type,
271                                                         void            *data)) {
272         struct s_gs_type                *p_type         = NULL;
273         struct s_gs_cat_struct          *p_struct       = NULL;
274
275         if (before_callback || after_callback) 
276         DEBUG1("%s",__FUNCTION__);
277         p_struct = _gs_struct_cat_new();
278
279         p_type   = _gs_type_new(p_bag, p_connection, name);
280
281         p_type->size                    = 0;
282         p_type->alignment               = 0;
283         p_type->aligned_size            = 0;
284         p_type->category_code           = e_gs_type_cat_struct;
285         p_type->category.struct_data    = p_struct;
286         p_type->before_callback         = before_callback;
287         p_type->after_callback          = after_callback;
288
289         return p_type;
290 }
291
292 struct s_gs_type *
293 gs_type_new_struct(struct s_gs_type_bag *p_bag,
294                    struct s_gs_connection       *p_connection,
295                    const char *name) {
296         DEBUG2("%s(%s)",__FUNCTION__,name);
297         return gs_type_new_struct_with_callback(p_bag, p_connection, name, NULL, NULL);
298 }
299
300
301 static
302 struct s_gs_cat_struct_field *
303 _gs_struct_field_cat_alloc(void) {
304         struct s_gs_cat_struct_field    *p_struct_field = NULL;
305         p_struct_field = malloc(sizeof (struct s_gs_cat_struct_field));
306         return p_struct_field;
307 }
308
309 static
310 struct s_gs_cat_struct_field *
311 _gs_struct_field_cat_new(const char             *name,
312                          long int          offset,
313                          struct s_gs_type *p_field_type,
314
315                          void (*before_callback)(void                   *vars,
316                                                  struct s_gs_type       *p_type,
317                                                  void                   *data),
318
319                          void (*after_callback)(void                    *vars,
320                                                 struct s_gs_type        *p_type,
321                                                 void                    *data)) {
322
323         struct s_gs_cat_struct_field    *p_struct_field = NULL;
324
325         if (p_field_type->size < 0)
326                 GS_FAILURE("variable length field not allowed in structure");
327
328         p_struct_field = _gs_struct_field_cat_alloc();
329
330         p_struct_field->name            = strdup(name);
331         p_struct_field->offset          = aligned(offset, p_field_type->alignment);
332         p_struct_field->code            = p_field_type->code;
333         p_struct_field->before_callback = before_callback;
334         p_struct_field->after_callback  = after_callback;
335
336         return p_struct_field;
337 }
338
339 void
340 gs_type_struct_append_field_with_callback(struct s_gs_type      *p_struct_type,
341                                           const char                    *name,
342                                           struct s_gs_type      *p_field_type,
343
344                                           void (*before_callback)(void                  *vars,
345                                                                   struct s_gs_type      *p_type,
346                                                                   void                  *data),
347
348                                           void (*after_callback)(void                   *vars,
349                                                                  struct s_gs_type       *p_type,
350                                                                  void                   *data)) {
351
352         struct s_gs_cat_struct          *p_struct       = NULL;
353         int                              field_num      =   -1;
354         struct s_gs_cat_struct_field    *p_field        = NULL;
355
356         if (before_callback || after_callback) 
357           DEBUG1("%s",__FUNCTION__);
358
359         if (p_field_type->size < 0)
360                 GS_FAILURE("field size must be statically known");
361
362         p_struct = p_struct_type->category.struct_data;
363
364         if ((field_num = p_struct->nb_fields++)) {
365                 p_struct->field_array   = realloc(p_struct->field_array, p_struct->nb_fields * sizeof (struct s_gs_cat_struct_field *));
366         } else {
367                 p_struct->field_array   = malloc(sizeof (struct s_gs_cat_struct_field *));
368         }
369
370         p_field = _gs_struct_field_cat_new(name, p_struct_type->size, p_field_type, before_callback, after_callback);
371         p_struct->field_array[field_num]        = p_field;
372
373         p_struct_type->size             = p_field->offset + p_field_type->size;
374         p_struct_type->alignment        = max(p_struct_type->alignment, p_field_type->alignment);
375         p_struct_type->aligned_size     = aligned(p_struct_type->size, p_struct_type->alignment);
376 }
377
378 void
379 gs_type_struct_append_field(struct s_gs_type    *p_struct_type,
380                             const char          *name,
381                             struct s_gs_type    *p_field_type) {
382         DEBUG1("%s",__FUNCTION__);
383         gs_type_struct_append_field_with_callback(p_struct_type, name, p_field_type, NULL, NULL);
384 }
385
386
387
388
389 /*......................................................................
390  * Union
391  */
392 static
393 struct s_gs_cat_union *
394 _gs_union_cat_alloc(void) {
395         struct s_gs_cat_union   *p_union        = NULL;
396         p_union = malloc(sizeof (struct s_gs_cat_union));
397         return p_union;
398 }
399
400 static
401 struct s_gs_cat_union *
402 _gs_union_cat_new(void) {
403         struct s_gs_cat_union   *p_union        = NULL;
404
405         p_union = _gs_union_cat_alloc();
406
407         p_union->nb_fields      = 0;
408         p_union->field_array    = NULL;
409
410         return p_union;
411 }
412
413 struct s_gs_type *
414 gs_type_new_union_with_callback(struct s_gs_type_bag    *p_bag,
415                                 struct s_gs_connection  *p_connection,
416                                 const char *name,
417
418                                 int (*field_callback)(void              *vars,
419                                                        struct s_gs_type *p_type,
420                                                        void             *data),
421
422                                 void (*after_callback)(void             *vars,
423                                                        struct s_gs_type *p_type,
424                                                        void             *data)) {
425         struct s_gs_type                *p_type         = NULL;
426         struct s_gs_cat_union           *p_union        = NULL;
427
428         if (!field_callback
429             &&
430             (!p_connection||p_connection->direction != e_gs_connection_direction_incoming))
431                 GS_FAILURE("attempt to create a union type without discriminant");
432
433         p_union = _gs_union_cat_new();
434
435         p_type  = _gs_type_new(p_bag, p_connection, name);
436
437         p_type->size                    = 0;
438         p_type->alignment               = 0;
439         p_type->aligned_size            = 0;
440         p_type->category_code           = e_gs_type_cat_union;
441         p_type->category.union_data     = p_union;
442         p_type->before_callback         = NULL;
443
444         p_union->callback               = field_callback;
445         p_type->after_callback          = after_callback;
446
447         return p_type;
448 }
449
450 struct s_gs_type *
451 gs_type_new_union(struct s_gs_type_bag  *p_bag,
452                   struct s_gs_connection        *p_connection,
453                   const char *name,
454
455                   int (*field_callback)(void                    *vars,
456                                          struct s_gs_type       *p_type,
457                                          void                   *data)) {
458         return gs_type_new_union_with_callback(p_bag, p_connection, name, field_callback, NULL);
459 }
460
461
462 static
463 struct s_gs_cat_union_field *
464 _gs_union_field_cat_alloc(void) {
465         struct s_gs_cat_union_field     *p_union_field  = NULL;
466         p_union_field = malloc(sizeof (struct s_gs_cat_union_field));
467         return p_union_field;
468 }
469
470 static
471 struct s_gs_cat_union_field *
472 _gs_union_field_cat_new(const char                      *name,
473                         struct s_gs_type        *p_field_type,
474
475                         void (*before_callback)(void                    *vars,
476                                                 struct s_gs_type        *p_type,
477                                                 void                    *data),
478
479                         void (*after_callback)(void                     *vars,
480                                                struct s_gs_type *p_type,
481                                                void                     *data)) {
482
483         struct s_gs_cat_union_field     *p_union_field  = NULL;
484
485         if (p_field_type->size < 0)
486                 GS_FAILURE("variable length field not allowed in structure");
487
488         p_union_field = _gs_union_field_cat_alloc();
489
490         p_union_field->name             = strdup(name);
491         p_union_field->code             = p_field_type->code;
492         p_union_field->before_callback  = before_callback;
493         p_union_field->after_callback   = after_callback;
494
495         return p_union_field;
496 }
497
498 void
499 gs_type_union_append_field_with_callback(struct s_gs_type       *p_union_type,
500                                          const char                     *name,
501                                          struct s_gs_type       *p_field_type,
502
503                                          void (*before_callback)(void                   *vars,
504                                                                  struct s_gs_type       *p_type,
505                                                                  void                   *data),
506
507                                          void (*after_callback)(void                    *vars,
508                                                                 struct s_gs_type        *p_type,
509                                                                 void                    *data)) {
510
511         struct s_gs_cat_union           *p_union        = NULL;
512         int                              field_num      =   -1;
513         struct s_gs_cat_union_field    *p_field        = NULL;
514
515         if (p_field_type->size < 0)
516                 GS_FAILURE("field size must be statically known");
517
518         p_union = p_union_type->category.union_data;
519
520         if ((field_num = p_union->nb_fields++)) {
521                 p_union->field_array    = realloc(p_union->field_array, p_union->nb_fields * sizeof (struct s_gs_cat_union_field *));
522         } else {
523                 p_union->field_array    = malloc(sizeof (struct s_gs_cat_union_field *));
524         }
525
526         p_field = _gs_union_field_cat_new(name, p_field_type, before_callback, after_callback);
527         p_union->field_array[field_num] = p_field;
528
529         p_union_type->size              = max(p_union_type->size, p_field_type->size);
530         p_union_type->alignment         = max(p_union_type->alignment, p_field_type->alignment);
531         p_union_type->aligned_size      = aligned(p_union_type->size, p_union_type->alignment);
532 }
533
534 void
535 gs_type_union_append_field(struct s_gs_type     *p_union_type,
536                            const char           *name,
537                            struct s_gs_type     *p_field_type) {
538         gs_type_union_append_field_with_callback(p_union_type, name, p_field_type, NULL, NULL);
539 }
540
541
542
543
544 /*......................................................................
545  * Ref
546  */
547 static
548 struct s_gs_cat_ref *
549 _gs_ref_cat_alloc(void) {
550         struct s_gs_cat_ref     *p_ref  = NULL;
551         p_ref = malloc(sizeof (struct s_gs_cat_ref));
552         return p_ref;
553 }
554
555 static
556 struct s_gs_cat_ref *
557 _gs_ref_cat_new(void) {
558         struct s_gs_cat_ref     *p_ref  = NULL;
559
560         p_ref           = _gs_ref_cat_alloc();
561         p_ref->code     = 0;
562         p_ref->callback = NULL;
563
564         return p_ref;
565 }
566
567 struct s_gs_type *
568 gs_type_new_ref_with_callback(struct s_gs_type_bag      *p_bag,
569                               struct s_gs_connection    *p_connection,
570                               const char                *name,
571                               struct s_gs_type  *p_referenced_type,
572
573                               int (*type_callback)(void         *vars,
574                                                    struct s_gs_type     *p_type,
575                                                    void         *data),
576
577                               void (*after_callback)(void               *vars,
578                                                      struct s_gs_type   *p_type,
579                                                      void               *data)) {
580         struct s_gs_type                *p_type         = NULL;
581         struct s_gs_cat_ref             *p_ref          = NULL;
582
583         p_ref           = _gs_ref_cat_new();
584
585         if (!p_referenced_type
586             &&
587             !type_callback
588             &&
589             (!p_connection||p_connection->direction != e_gs_connection_direction_incoming))
590                 GS_FAILURE("attempt to declare a generic ref without discriminant");
591
592         p_ref->code     = p_referenced_type?p_referenced_type->code:-1;
593         p_ref->callback = type_callback;
594
595         p_type          = _gs_type_new(p_bag, p_connection, name);
596
597         {
598                 struct s_gs_type_bag_ops        *bag_ops        = p_bag->bag_ops;
599                 struct s_gs_type                *p_pointer_type = NULL;
600
601                 p_pointer_type = bag_ops->get_type_by_name(p_bag, p_connection, "data pointer");
602                 p_type->size            = p_pointer_type->size;
603                 p_type->alignment       = p_pointer_type->alignment;
604                 p_type->aligned_size    = p_pointer_type->aligned_size;
605         }
606
607         p_type->category_code           = e_gs_type_cat_ref;
608         p_type->category.ref_data       = p_ref;
609
610         p_type->before_callback = NULL;
611         p_type->after_callback  = after_callback;
612
613         return p_type;
614 }
615
616 struct s_gs_type *
617 gs_type_new_ref(struct s_gs_type_bag    *p_bag,
618                 struct s_gs_connection  *p_connection,
619                 const char               *name,
620                 struct s_gs_type *p_referenced_type) {
621         return gs_type_new_ref_with_callback(p_bag, p_connection, name, p_referenced_type, NULL, NULL);
622 }
623
624
625
626
627 /*......................................................................
628  * Array
629  */
630 static
631 struct s_gs_cat_array *
632 _gs_array_cat_alloc(void) {
633         struct s_gs_cat_array   *p_array        = NULL;
634         p_array = malloc(sizeof (struct s_gs_cat_array));
635         return p_array;
636 }
637
638 static
639 struct s_gs_cat_array *
640 _gs_array_cat_new(void) {
641         struct s_gs_cat_array   *p_array        = NULL;
642
643         p_array                 = _gs_array_cat_alloc();
644         p_array->code           =    0;
645         p_array->element_count  =    0;
646
647         return p_array;
648 }
649
650 struct s_gs_type *
651 gs_type_new_array_with_callback(struct s_gs_type_bag    *p_bag,
652                                 struct s_gs_connection  *p_connection,
653                                 const char                 *name,
654                                 long int            size,
655                                 struct s_gs_type *p_array_element_type,
656
657                                 long int (*size_callback)(void          *vars,
658                                                           struct s_gs_type      *p_type,
659                                                           void          *data),
660
661                                 void (*after_callback)(void             *vars,
662                                                        struct s_gs_type *p_type,
663                                                        void             *data)) {
664
665         struct s_gs_type                *p_type         = NULL;
666         struct s_gs_cat_array           *p_array        = NULL;
667
668         p_array                 = _gs_array_cat_new();
669         p_array->code           = p_array_element_type->code;
670         p_array->element_count  = size;
671
672         p_type = _gs_type_new(p_bag, p_connection, name);
673
674         if (size <= 0) {
675                 if (size < 0 && !size_callback
676                     &&
677                     (!p_connection||p_connection->direction != e_gs_connection_direction_incoming))
678                         GS_FAILURE("attempt to construct a variable sized array with no callback");
679
680                 p_type->size = size;
681         } else {
682                 p_type->size = size * p_array_element_type->aligned_size;
683         }
684
685         p_type->alignment    = p_array_element_type->alignment;
686         p_type->aligned_size = size;
687
688         p_type->category_code     = e_gs_type_cat_array;
689         p_type->category.array_data = p_array;
690
691         p_array->callback = size_callback;
692
693         p_type->before_callback = NULL;
694         p_type->after_callback  = after_callback;
695
696         return p_type;
697 }
698
699 struct s_gs_type *
700 gs_type_new_array(struct s_gs_type_bag  *p_bag,
701                   struct s_gs_connection        *p_connection,
702                   const char               *name,
703                   long int          size,
704                   struct s_gs_type *p_array_element_type) {
705         return gs_type_new_array_with_callback(p_bag, p_connection, name, size, p_array_element_type, NULL, NULL);
706 }
707
708
709
710
711
712 /*......................................................................
713  * Type structure bootstrap
714  */
715 static
716 long int
717 _strlen_cb(void                 *p_vars,
718            struct s_gs_type     *p_type,
719            void                 *data) {
720
721         (void)p_vars;
722         (void)p_type;
723
724         return 1+(long int)strlen(data);
725 }
726
727 static
728 void
729 _category_code_push_cb(void             *p_vars,
730                        struct s_gs_type *p_type,
731                        void             *data) {
732         gs_vars_push(p_vars, p_type, "_category_code", data);
733 }
734
735 static
736 int
737 _category_code_pop_cb(void              *p_vars,
738                       struct s_gs_type  *p_type,
739                       void              *data) {
740         int *p_cat = NULL;
741
742         (void)p_type;
743         (void)data;
744
745         p_cat = gs_vars_pop(p_vars, "_category_code", NULL);
746
747         if (!p_cat)
748                 GS_FAILURE("categoy code not found");
749
750         return *p_cat;
751 }
752
753 static
754 void
755 _field_count_push_cb(void               *p_vars,
756                        struct s_gs_type *p_type,
757                        void             *data) {
758         gs_vars_push(p_vars, p_type, "_field_count", data);
759 }
760
761 static
762 long
763 int
764 _field_count_pop_cb(void                *p_vars,
765                       struct s_gs_type  *p_type,
766                       void              *data) {
767         long int *p_cat = NULL;
768
769         (void)p_type;
770         (void)data;
771
772         p_cat = gs_vars_pop(p_vars, "_field_count", NULL);
773
774         if (!p_cat)
775                 GS_FAILURE("categoy code not found");
776
777         return *p_cat;
778 }
779
780 void
781 gs_bootstrap_type_bag(struct s_gs_type_bag *p_bag) {
782   DEBUG0("###################### BEGIN OF TYPE BOOTSTRAPING");
783   gs_bootstrap_incoming_connection(p_bag, NULL);
784   DEBUG0("###################### END OF TYPE BOOTSTRAPING");
785 }
786
787 void
788 gs_bootstrap_incoming_connection(struct s_gs_type_bag   *p_bag,
789                                  struct s_gs_connection *p_cnx) {
790
791         /* basic types */
792         struct s_gs_type *signed_char                           = NULL;
793         struct s_gs_type *unsigned_char                         = NULL;
794         struct s_gs_type *signed_short_int                      = NULL;
795         struct s_gs_type *unsigned_short_int                    = NULL;
796         struct s_gs_type *signed_int                            = NULL;
797         struct s_gs_type *unsigned_int                          = NULL;
798         struct s_gs_type *signed_long_int                       = NULL;
799         struct s_gs_type *unsigned_long_int                     = NULL;
800         struct s_gs_type *signed_long_long_int                  = NULL;
801         struct s_gs_type *unsigned_long_long_int                = NULL;
802         struct s_gs_type *data_pointer                          = NULL;
803         struct s_gs_type *function_pointer                      = NULL;
804         struct s_gs_type *char_array                            = NULL;
805         struct s_gs_type *string                                = NULL;
806
807         /* categories */
808         struct s_gs_type *s_gs_cat_elemental                    = NULL;         /* Elemental    */
809
810         struct s_gs_type *s_gs_cat_struct_field                 = NULL;         /* Struct       */
811         struct s_gs_type *ref_s_gs_cat_struct_field             = NULL;
812         struct s_gs_type *tab_ref_s_gs_cat_struct_field         = NULL;
813         struct s_gs_type *ref_tab_ref_s_gs_cat_struct_field     = NULL;
814         struct s_gs_type *s_gs_cat_struct                       = NULL;
815
816         struct s_gs_type *s_gs_cat_union_field                  = NULL;         /* Union        */
817         struct s_gs_type *ref_s_gs_cat_union_field              = NULL;
818         struct s_gs_type *tab_ref_s_gs_cat_union_field          = NULL;
819         struct s_gs_type *ref_tab_ref_s_gs_cat_union_field      = NULL;
820         struct s_gs_type *s_gs_cat_union                        = NULL;
821
822         struct s_gs_type *s_gs_cat_ref                          = NULL;         /* Ref          */
823
824         struct s_gs_type *s_gs_cat_array                        = NULL;         /* Array        */
825
826         struct s_gs_type *s_gs_cat_ignored                      = NULL;         /* Ignored      */
827
828         /* type */
829         struct s_gs_type *ref_s_gs_cat_elemental                = NULL;
830         struct s_gs_type *ref_s_gs_cat_struct                   = NULL;
831         struct s_gs_type *ref_s_gs_cat_union                    = NULL;
832         struct s_gs_type *ref_s_gs_cat_ref                      = NULL;
833         struct s_gs_type *ref_s_gs_cat_array                    = NULL;
834         struct s_gs_type *ref_s_gs_cat_ignored                  = NULL;
835
836         struct s_gs_type *u_gs_category                         = NULL;
837         struct s_gs_type *s_gs_type                             = NULL;
838
839         /* message */
840         struct s_gs_type *s_gs_sequence                         = NULL;
841         struct s_gs_type *s_gs_message                          = NULL;
842
843         struct s_gs_type *ref_s_gs_sequence                     = NULL;
844         struct s_gs_type *ref_s_gs_message                      = NULL;
845
846
847         /*
848          * connection boostrap sequence
849          */
850
851         signed_char   = gs_type_new_signed_integer_elemental  (p_bag, p_cnx, "signed char",   1);
852         unsigned_char = gs_type_new_unsigned_integer_elemental(p_bag, p_cnx, "unsigned char", 1);
853
854
855         if (p_cnx) {
856                 struct s_gs_connection_ops      *cops   = p_cnx->connection_ops;
857                 unsigned char                    a      = 0;
858                 unsigned char                    b      = 0;
859
860                 if (p_cnx->direction != e_gs_connection_direction_incoming)
861                 GS_FAILURE("invalid connection");
862
863                 cops->read(p_cnx, &b, 1);
864                 signed_short_int        = gs_type_new_signed_integer_elemental  (p_bag, p_cnx, "signed short int",       b);
865
866                 cops->read(p_cnx, &b, 1);
867                 unsigned_short_int      = gs_type_new_unsigned_integer_elemental(p_bag, p_cnx, "unsigned short int",     b);
868
869
870                 cops->read(p_cnx, &b, 1);
871                 signed_int              = gs_type_new_signed_integer_elemental  (p_bag, p_cnx, "signed int",             b);
872
873                 cops->read(p_cnx, &b, 1);
874                 unsigned_int            = gs_type_new_unsigned_integer_elemental(p_bag, p_cnx, "unsigned int",           b);
875
876
877                 cops->read(p_cnx, &b, 1);
878                 signed_long_int         = gs_type_new_signed_integer_elemental  (p_bag, p_cnx, "signed long int",        b);
879
880                 cops->read(p_cnx, &b, 1);
881                 unsigned_long_int       = gs_type_new_unsigned_integer_elemental(p_bag, p_cnx, "unsigned long int",      b);
882
883
884                 cops->read(p_cnx, &b, 1);
885                 signed_long_long_int    = gs_type_new_signed_integer_elemental  (p_bag, p_cnx, "signed long long int",   b);
886
887                 cops->read(p_cnx, &b, 1);
888                 unsigned_long_long_int  = gs_type_new_unsigned_integer_elemental(p_bag, p_cnx, "unsigned long long int", b);
889
890                 cops->read(p_cnx, &b, 1);
891                 cops->read(p_cnx, &a, 1);
892                 data_pointer            = gs_type_new_ignored(p_bag, p_cnx, "data pointer",     b, a, NULL);
893
894                 cops->read(p_cnx, &b, 1);
895                 cops->read(p_cnx, &a, 1);
896                 function_pointer        = gs_type_new_ignored(p_bag, p_cnx, "function pointer", b, a, NULL);
897         } else {
898                 signed_short_int        = gs_type_new_signed_integer_elemental  (p_bag, NULL, "signed short int",               sizeof (signed    short      int));
899                 unsigned_short_int      = gs_type_new_unsigned_integer_elemental(p_bag, NULL, "unsigned short int",             sizeof (unsigned  short      int));
900
901                 signed_int              = gs_type_new_signed_integer_elemental  (p_bag, NULL, "signed int",                     sizeof (signed               int));
902                 unsigned_int            = gs_type_new_unsigned_integer_elemental(p_bag, NULL, "unsigned int",                   sizeof (unsigned             int));
903
904                 signed_long_int         = gs_type_new_signed_integer_elemental  (p_bag, NULL, "signed long int",                sizeof (signed    long       int));
905                 unsigned_long_int       = gs_type_new_unsigned_integer_elemental(p_bag, NULL, "unsigned long int",              sizeof (unsigned  long       int));
906
907                 signed_long_long_int    = gs_type_new_signed_integer_elemental  (p_bag, NULL, "signed long long int",           sizeof (signed    long long  int));
908                 unsigned_long_long_int  = gs_type_new_unsigned_integer_elemental(p_bag, NULL, "unsigned long long int", sizeof (unsigned  long long  int));
909
910                 data_pointer            = gs_type_new_ignored(p_bag, NULL, "data pointer",      sizeof (void *),          sizeof (void *),          NULL);
911                 function_pointer        = gs_type_new_ignored(p_bag, NULL, "function pointer", sizeof (void (*) (void)), sizeof (void (*) (void)), NULL);
912         }
913
914         char_array = gs_type_new_array_with_callback(p_bag, p_cnx, "_char_array", -1, signed_char, _strlen_cb, NULL);
915         string     = gs_type_new_ref(p_bag, p_cnx, "_string", char_array);
916
917         /* Elemental cat */
918         s_gs_cat_elemental = gs_type_new_struct(p_bag, p_cnx, "_s_gs_cat_elemental");
919         gs_type_struct_append_field(s_gs_cat_elemental, "encoding", signed_int);
920
921         /* Struct cat */
922         s_gs_cat_struct_field = gs_type_new_struct(p_bag, p_cnx, "_s_gs_cat_struct_field");
923         gs_type_struct_append_field(s_gs_cat_struct_field, "name",            string);
924         gs_type_struct_append_field(s_gs_cat_struct_field, "offset",          signed_long_int);
925         gs_type_struct_append_field(s_gs_cat_struct_field, "code",            signed_int);
926         gs_type_struct_append_field(s_gs_cat_struct_field, "before_callback", function_pointer);
927         gs_type_struct_append_field(s_gs_cat_struct_field, "after_callback",  function_pointer);
928
929         ref_s_gs_cat_struct_field         = gs_type_new_ref                (p_bag, p_cnx, "_ps_gs_cat_struct_field",   s_gs_cat_struct_field);
930         tab_ref_s_gs_cat_struct_field     = gs_type_new_array_with_callback(p_bag, p_cnx, "_aps_gs_cat_struct_field", -1, ref_s_gs_cat_struct_field, _field_count_pop_cb, NULL);
931         ref_tab_ref_s_gs_cat_struct_field = gs_type_new_ref                (p_bag, p_cnx, "_paps_gs_cat_struct_field", tab_ref_s_gs_cat_struct_field);
932
933         s_gs_cat_struct = gs_type_new_struct(p_bag, p_cnx, "_s_gs_cat_struct");
934         gs_type_struct_append_field_with_callback(s_gs_cat_struct, "nb_fields", signed_int, _field_count_push_cb, NULL);
935         gs_type_struct_append_field(s_gs_cat_struct, "field_array", ref_tab_ref_s_gs_cat_struct_field);
936
937         /* Union cat */
938         s_gs_cat_union_field = gs_type_new_struct(p_bag, p_cnx, "_s_gs_cat_union_field");
939         gs_type_struct_append_field(s_gs_cat_union_field, "name",          string);
940         gs_type_struct_append_field(s_gs_cat_union_field, "code",                  signed_int);
941         gs_type_struct_append_field(s_gs_cat_union_field, "before_callback", function_pointer);
942         gs_type_struct_append_field(s_gs_cat_union_field, "after_callback",  function_pointer);
943
944         ref_s_gs_cat_union_field         = gs_type_new_ref                (p_bag, p_cnx, "_ps_gs_cat_union_field",   s_gs_cat_union_field);
945         tab_ref_s_gs_cat_union_field     = gs_type_new_array_with_callback(p_bag, p_cnx, "_aps_gs_cat_union_field", -1, ref_s_gs_cat_union_field, _field_count_pop_cb, NULL);
946         ref_tab_ref_s_gs_cat_union_field = gs_type_new_ref                (p_bag, p_cnx, "_paps_gs_cat_union_field", tab_ref_s_gs_cat_union_field);
947
948         s_gs_cat_union = gs_type_new_struct(p_bag, p_cnx, "_s_gs_cat_union");
949         gs_type_struct_append_field_with_callback(s_gs_cat_union, "nb_fields", signed_int, _field_count_push_cb, NULL);
950         gs_type_struct_append_field(s_gs_cat_union, "field_array", ref_tab_ref_s_gs_cat_union_field);
951         gs_type_struct_append_field(s_gs_cat_union, "callback",  function_pointer);
952
953         /* Ref cat */
954         s_gs_cat_ref = gs_type_new_struct(p_bag, p_cnx, "_s_gs_cat_ref");
955         gs_type_struct_append_field(s_gs_cat_ref, "code",           signed_int);
956         gs_type_struct_append_field(s_gs_cat_ref, "callback", function_pointer);
957
958         /* Array cat */
959         s_gs_cat_array = gs_type_new_struct(p_bag, p_cnx, "_s_gs_cat_array");
960         gs_type_struct_append_field(s_gs_cat_array, "code",        signed_int);
961         gs_type_struct_append_field(s_gs_cat_array, "element_count", signed_long_int);
962         gs_type_struct_append_field(s_gs_cat_array, "callback",    function_pointer);
963
964         /* Ignored cat */
965         s_gs_cat_ignored = gs_type_new_struct(p_bag, p_cnx, "_s_gs_cat_ignored");
966         gs_type_struct_append_field(s_gs_cat_ignored, "default_value", data_pointer);
967
968         /* refs to categories */
969         ref_s_gs_cat_elemental  = gs_type_new_ref(p_bag, p_cnx, "_ref_s_gs_cat_elemental", s_gs_cat_elemental);
970         ref_s_gs_cat_struct     = gs_type_new_ref(p_bag, p_cnx, "_ref_s_gs_cat_struct",    s_gs_cat_struct   );
971         ref_s_gs_cat_union      = gs_type_new_ref(p_bag, p_cnx, "_ref_s_gs_cat_union",     s_gs_cat_union    );
972         ref_s_gs_cat_ref        = gs_type_new_ref(p_bag, p_cnx, "_ref_s_gs_cat_ref",       s_gs_cat_ref      );
973         ref_s_gs_cat_array      = gs_type_new_ref(p_bag, p_cnx, "_ref_s_gs_cat_array",     s_gs_cat_array    );
974         ref_s_gs_cat_ignored    = gs_type_new_ref(p_bag, p_cnx, "_ref_s_gs_cat_ignored",   s_gs_cat_ignored  );
975
976         /* union of categories */
977         u_gs_category = gs_type_new_union(p_bag, p_cnx, "_u_gs_category", _category_code_pop_cb);
978         gs_type_union_append_field(u_gs_category, "undefined_data", data_pointer);
979         gs_type_union_append_field(u_gs_category, "elemental_data", ref_s_gs_cat_elemental);
980         gs_type_union_append_field(u_gs_category, "struct_data",    ref_s_gs_cat_struct);
981         gs_type_union_append_field(u_gs_category, "union_data",     ref_s_gs_cat_union);
982         gs_type_union_append_field(u_gs_category, "ref_data",       ref_s_gs_cat_ref);
983         gs_type_union_append_field(u_gs_category, "array_data",     ref_s_gs_cat_array);
984         gs_type_union_append_field(u_gs_category, "ignored_data",   ref_s_gs_cat_ignored);
985
986         /* type */
987         s_gs_type = gs_type_new_struct(p_bag, p_cnx, "_s_gs_type");
988         gs_type_struct_append_field              (s_gs_type, "code",            signed_int);
989         gs_type_struct_append_field              (s_gs_type, "name",            string);
990         gs_type_struct_append_field              (s_gs_type, "size",            signed_long_int);
991         gs_type_struct_append_field              (s_gs_type, "alignment",               signed_long_int);
992         gs_type_struct_append_field              (s_gs_type, "aligned_size",    signed_long_int);
993         gs_type_struct_append_field_with_callback(s_gs_type, "category_code",   signed_int, _category_code_push_cb, NULL);
994         gs_type_struct_append_field              (s_gs_type, "category",                u_gs_category);
995         gs_type_struct_append_field              (s_gs_type, "before_callback", function_pointer);
996         gs_type_struct_append_field              (s_gs_type, "after_callback",  function_pointer);
997
998         /* message */
999         s_gs_sequence = gs_type_new_struct(p_bag, p_cnx, "_s_gs_sequence");
1000         s_gs_message  = gs_type_new_struct(p_bag, p_cnx, "_s_gs_message");
1001
1002         ref_s_gs_sequence = gs_type_new_ref(p_bag, p_cnx, "_ref_s_gs_sequence", s_gs_sequence);
1003         ref_s_gs_message  = gs_type_new_ref(p_bag, p_cnx, "_ref_s_gs_message",  s_gs_message);
1004
1005         gs_type_struct_append_field(s_gs_sequence, "message", ref_s_gs_message);
1006         gs_type_struct_append_field(s_gs_sequence, "code",    signed_int);
1007         gs_type_struct_append_field(s_gs_sequence, "next",    ref_s_gs_sequence);
1008
1009         gs_type_struct_append_field(s_gs_message, "code",  signed_int);
1010         gs_type_struct_append_field(s_gs_message, "name",  string);
1011         gs_type_struct_append_field(s_gs_message, "first", ref_s_gs_sequence);
1012         gs_type_struct_append_field(s_gs_message, "next",        ref_s_gs_sequence);
1013 }
1014
1015 void
1016 gs_bootstrap_outgoing_connection(struct s_gs_type_bag   *p_bag,
1017                                  struct s_gs_connection *p_cnx) {
1018         struct s_gs_type_bag_ops        *bops   = p_bag->bag_ops;
1019         struct s_gs_connection_ops      *cops   = p_cnx->connection_ops;
1020         unsigned char                    b      = 0;
1021
1022         if (p_cnx->direction != e_gs_connection_direction_outgoing)
1023                 GS_FAILURE("invalid connection");
1024
1025         bops->mark_type(p_bag, p_cnx, "signed char");
1026         bops->mark_type(p_bag, p_cnx, "unsigned char");
1027
1028         b = sizeof(signed short int);
1029         cops->write(p_cnx, &b, 1);
1030         bops->mark_type(p_bag, p_cnx, "signed short int");
1031
1032         b = sizeof(unsigned short int);
1033         cops->write(p_cnx, &b, 1);
1034         bops->mark_type(p_bag, p_cnx, "unsigned short int");
1035
1036         b = sizeof(signed int);
1037         cops->write(p_cnx, &b, 1);
1038         bops->mark_type(p_bag, p_cnx, "signed int");
1039
1040         b = sizeof(unsigned int);
1041         cops->write(p_cnx, &b, 1);
1042         bops->mark_type(p_bag, p_cnx, "unsigned in");
1043
1044         b = sizeof(signed long int);
1045         cops->write(p_cnx, &b, 1);
1046         bops->mark_type(p_bag, p_cnx, "signed long int");
1047
1048         b = sizeof(unsigned long int);
1049         cops->write(p_cnx, &b, 1);
1050         bops->mark_type(p_bag, p_cnx, "unsigned long int");
1051
1052         b = sizeof(signed long long int);
1053         cops->write(p_cnx, &b, 1);
1054         bops->mark_type(p_bag, p_cnx, "signed long long int");
1055
1056         b = sizeof(unsigned long long int);
1057         cops->write(p_cnx, &b, 1);
1058         bops->mark_type(p_bag, p_cnx, "unsigned long long int");
1059
1060         b = sizeof(void *);
1061         cops->write(p_cnx, &b, 1); /* size      */
1062         cops->write(p_cnx, &b, 1); /* alignment */
1063         bops->mark_type(p_bag, p_cnx, "data pointer");
1064
1065         b = sizeof(void (*) (void));
1066         cops->write(p_cnx, &b, 1); /* size      */
1067         cops->write(p_cnx, &b, 1); /* alignment */
1068         bops->mark_type(p_bag, p_cnx, "function pointer");
1069
1070         bops->mark_type(p_bag, p_cnx, "_char_array");
1071         bops->mark_type(p_bag, p_cnx, "_string");
1072
1073         bops->mark_type(p_bag, p_cnx, "_s_gs_cat_elemental");
1074
1075         bops->mark_type(p_bag, p_cnx, "_s_gs_cat_struct_field");
1076         bops->mark_type(p_bag, p_cnx, "_ps_gs_cat_struct_field");
1077         bops->mark_type(p_bag, p_cnx, "_aps_gs_cat_struct_field");
1078         bops->mark_type(p_bag, p_cnx, "_paps_gs_cat_struct_field");
1079         bops->mark_type(p_bag, p_cnx, "_s_gs_cat_struct");
1080
1081         bops->mark_type(p_bag, p_cnx, "_s_gs_cat_union_field");
1082         bops->mark_type(p_bag, p_cnx, "_ps_gs_cat_union_field");
1083         bops->mark_type(p_bag, p_cnx, "_aps_gs_cat_union_field");
1084         bops->mark_type(p_bag, p_cnx, "_paps_gs_cat_union_field");
1085         bops->mark_type(p_bag, p_cnx, "_s_gs_cat_union");
1086
1087         bops->mark_type(p_bag, p_cnx, "_s_gs_cat_ref");
1088
1089         bops->mark_type(p_bag, p_cnx, "_s_gs_cat_array");
1090
1091         bops->mark_type(p_bag, p_cnx, "_s_gs_cat_ignored");
1092
1093         bops->mark_type(p_bag, p_cnx, "_ref_s_gs_cat_elemental");
1094         bops->mark_type(p_bag, p_cnx, "_ref_s_gs_cat_struct");
1095         bops->mark_type(p_bag, p_cnx, "_ref_s_gs_cat_union");
1096         bops->mark_type(p_bag, p_cnx, "_ref_s_gs_cat_ref");
1097         bops->mark_type(p_bag, p_cnx, "_ref_s_gs_cat_array");
1098         bops->mark_type(p_bag, p_cnx, "_ref_s_gs_cat_ignored");
1099
1100         bops->mark_type(p_bag, p_cnx, "_u_gs_category");
1101         bops->mark_type(p_bag, p_cnx, "_s_gs_type");
1102
1103         bops->mark_type(p_bag, p_cnx, "_s_gs_sequence");
1104         bops->mark_type(p_bag, p_cnx, "_s_gs_message" );
1105
1106         bops->mark_type(p_bag, p_cnx, "_ref_s_gs_sequence");
1107         bops->mark_type(p_bag, p_cnx, "_ref_s_gs_message");
1108 }
1109
1110
1111 /*......................................................................
1112  * Ignored
1113  */
1114 static
1115 struct s_gs_cat_ignored *
1116 _gs_ignored_cat_alloc(void) {
1117         struct s_gs_cat_ignored *p_ignored      = NULL;
1118
1119         p_ignored = malloc(sizeof (struct s_gs_cat_ignored));
1120
1121         return p_ignored;
1122 }
1123
1124 static
1125 struct s_gs_cat_ignored *
1126 _gs_ignored_cat_new(void) {
1127         struct s_gs_cat_ignored *p_ignored      = NULL;
1128
1129         p_ignored                       = _gs_ignored_cat_alloc();
1130         p_ignored->default_value        = NULL;
1131
1132         return p_ignored;
1133 }
1134
1135
1136 struct s_gs_type *
1137 gs_type_new_ignored_with_callback(struct s_gs_type_bag  *p_bag,
1138                                   struct s_gs_connection        *p_connection,
1139                                   const char                          *name,
1140                                   long int                       size,
1141                                   long int                       alignment,
1142                                   void                          *default_value,
1143                                   void (*callback)(void         *vars,
1144                                                    struct s_gs_type     *p_type,
1145                                                    void         *data)) {
1146
1147         struct s_gs_type                *p_type         = NULL;
1148         struct s_gs_cat_ignored         *p_ignored      = NULL;
1149
1150         p_ignored       = _gs_ignored_cat_new();
1151         p_type          = _gs_type_new(p_bag, p_connection, name);
1152
1153         p_type->size            = size > 0?size:0;
1154         p_type->alignment       = alignment;
1155
1156         if (size > 0) {
1157                 long int aligned_size   = aligned(size, alignment);
1158
1159                 p_type->aligned_size    = aligned_size;
1160         } else {
1161                 p_type->aligned_size    = 0;
1162         }
1163
1164         if (default_value && p_type->size) {
1165                 p_ignored->default_value = gs_memdup(default_value, (size_t)size);
1166         }
1167
1168         p_type->category_code           = e_gs_type_cat_ignored;
1169         p_type->category.ignored_data   = p_ignored;
1170
1171         p_type->before_callback         = callback;
1172
1173         return p_type;
1174 }
1175
1176 struct s_gs_type *
1177 gs_type_new_ignored(struct s_gs_type_bag        *p_bag,
1178                     struct s_gs_connection      *p_connection,
1179                     const char                        *name,
1180                     long int                     size,
1181                     long int                     alignment,
1182                     void                        *default_value) {
1183         return gs_type_new_ignored_with_callback(p_bag, p_connection, name, size, alignment, default_value, NULL);
1184 }