Merge remote-tracking branch 'remotes/origin/upstream'
[framework/uifw/eet.git] / src / examples / eet-data-file_descriptor_02.c
1 /*
2  * build: gcc -o eet_data_file_descriptor_02 eet-data-file_descriptor_02.c `pkg-config --cflags --libs eet eina`
3  */
4
5 #include <Eina.h>
6 #include <Eet.h>
7 #include <stdio.h>
8 #include <limits.h>
9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #include <unistd.h>
12
13 typedef enum _Example_Data_Type      Example_Data_Type;
14 typedef struct _Example_Variant_Type Example_Variant_Type;
15 typedef struct _Example_Variant      Example_Variant;
16 typedef struct _Example_Union        Example_Union;
17 typedef struct _Example_Struct1      Example_Struct1;
18 typedef struct _Example_Struct2      Example_Struct2;
19 typedef struct _Example_Struct3      Example_Struct3;
20 typedef struct _Example_Lists        Example_Lists;
21
22 enum _Example_Data_Type
23 {
24    EET_UNKNOWN = 0,
25    EET_STRUCT1,
26    EET_STRUCT2,
27    EET_STRUCT3
28 };
29
30 struct
31 {
32    Example_Data_Type u;
33    const char       *name;
34 } eet_mapping[] = {
35    { EET_STRUCT1, "ST1" },
36    { EET_STRUCT2, "ST2" },
37    { EET_STRUCT3, "ST3" },
38    { EET_UNKNOWN, NULL }
39 };
40
41 struct _Example_Struct1
42 {
43    double      val1;
44    int         stuff;
45    const char *s1;
46 };
47
48 struct _Example_Struct2
49 {
50    Eina_Bool          b1;
51    unsigned long long v1;
52 };
53
54 struct _Example_Struct3
55 {
56    int body;
57 };
58
59 struct _Example_Union
60 {
61    Example_Data_Type type;
62
63    union {
64       Example_Struct1 st1;
65       Example_Struct2 st2;
66       Example_Struct3 st3;
67    } u;
68 };
69
70 struct _Example_Variant_Type
71 {
72    const char *type;
73    Eina_Bool   unknow : 1;
74 };
75
76 struct _Example_Variant
77 {
78    Example_Variant_Type t;
79
80    void                *data; /* differently than the union type, we
81                                * don't need to pre-allocate the memory
82                                * for the field*/
83 };
84
85 struct _Example_Lists
86 {
87    Eina_List *union_list;
88    Eina_List *variant_list;
89 };
90
91 static void
92 _st1_set(Example_Struct1 *st1,
93          double           v1,
94          int              v2,
95          const char      *v3)
96 {
97    st1->val1 = v1;
98    st1->stuff = v2;
99    st1->s1 = v3;
100 } /* _st1_set */
101
102 static void
103 _st2_set(Example_Struct2   *st2,
104          Eina_Bool          v1,
105          unsigned long long v2)
106 {
107    st2->b1 = v1;
108    st2->v1 = v2;
109 } /* _st2_set */
110
111 static void
112 _st3_set(Example_Struct3 *st3,
113          int              v1)
114 {
115    st3->body = v1;
116 } /* _st3_set */
117
118 static const char *
119 /* union
120    type_get() */
121 _union_type_get(const void *data,
122                 Eina_Bool  *unknow)
123 {
124    const Example_Data_Type *u = data;
125    int i;
126
127    if (unknow)
128      *unknow = EINA_FALSE;
129
130    for (i = 0; eet_mapping[i].name != NULL; ++i)
131      if (*u == eet_mapping[i].u)
132        return eet_mapping[i].name;
133
134    if (unknow)
135      *unknow = EINA_TRUE;
136
137    return NULL;
138 } /* _union_type_get */
139
140 static Eina_Bool
141 _union_type_set(const char *type,
142                 void       *data,
143                 Eina_Bool   unknow)
144 {
145    Example_Data_Type *u = data;
146    int i;
147
148    if (unknow)
149      return EINA_FALSE;
150
151    for (i = 0; eet_mapping[i].name != NULL; ++i)
152      if (strcmp(eet_mapping[i].name, type) == 0)
153        {
154           *u = eet_mapping[i].u;
155           return EINA_TRUE;
156        }
157
158    return EINA_FALSE;
159 } /* _union_type_set */
160
161 static const char *
162 _variant_type_get(const void *data,
163                   Eina_Bool  *unknow)
164 {
165    const Example_Variant_Type *type = data;
166    int i;
167
168    if (unknow)
169      *unknow = type->unknow;
170
171    for (i = 0; eet_mapping[i].name != NULL; ++i)
172      if (strcmp(type->type, eet_mapping[i].name) == 0)
173        return eet_mapping[i].name;
174
175    if (unknow)
176      *unknow = EINA_FALSE;
177
178    return type->type;
179 } /* _variant_type_get */
180
181 static Eina_Bool
182 _variant_type_set(const char *type,
183                   void       *data,
184                   Eina_Bool   unknow)
185 {
186    Example_Variant_Type *vt = data;
187
188    vt->type = type;
189    vt->unknow = unknow;
190    return EINA_TRUE;
191 } /* _variant_type_set */
192
193 static Eet_Data_Descriptor *
194 _st1_dd(void)
195 {
196    Eet_Data_Descriptor_Class eddc;
197    Eet_Data_Descriptor *res;
198
199    EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Struct1);
200    res = eet_data_descriptor_file_new(&eddc);
201    EET_DATA_DESCRIPTOR_ADD_BASIC(
202      res, Example_Struct1, "val1", val1, EET_T_DOUBLE);
203    EET_DATA_DESCRIPTOR_ADD_BASIC(
204      res, Example_Struct1, "stuff", stuff, EET_T_INT);
205    EET_DATA_DESCRIPTOR_ADD_BASIC(
206      res, Example_Struct1, "s1", s1, EET_T_STRING);
207
208    return res;
209 } /* _st1_dd */
210
211 static Eet_Data_Descriptor *
212 _st2_dd(void)
213 {
214    Eet_Data_Descriptor_Class eddc;
215    Eet_Data_Descriptor *res;
216
217    EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Struct2);
218    res = eet_data_descriptor_file_new(&eddc);
219    EET_DATA_DESCRIPTOR_ADD_BASIC(
220      res, Example_Struct2, "b1", b1, EET_T_UCHAR);
221    EET_DATA_DESCRIPTOR_ADD_BASIC(
222      res, Example_Struct2, "v1", v1, EET_T_ULONG_LONG);
223
224    return res;
225 } /* _st2_dd */
226
227 static Eet_Data_Descriptor *
228 _st3_dd(void)
229 {
230    Eet_Data_Descriptor_Class eddc;
231    Eet_Data_Descriptor *res;
232
233    EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Struct3);
234    res = eet_data_descriptor_file_new(&eddc);
235    EET_DATA_DESCRIPTOR_ADD_BASIC(
236      res, Example_Struct3, "body", body, EET_T_INT);
237
238    return res;
239 } /* _st3_dd */
240
241 /* string that represents the entry in the eet file. you might like to
242  * have different profiles or so in the same file, this is possible
243  * with different strings
244  */
245 static const char CACHE_FILE_ENTRY[] = "cache";
246
247 /* keep the descriptor static global, so it can be shared by different
248  * functions (load/save) of this and only this file.
249  */
250 static Eet_Data_Descriptor *_lists_descriptor;
251 static Eet_Data_Descriptor *_struct_1_descriptor;
252 static Eet_Data_Descriptor *_struct_2_descriptor;
253 static Eet_Data_Descriptor *_struct_3_descriptor;
254 static Eet_Data_Descriptor *_union_descriptor;
255 static Eet_Data_Descriptor *_variant_descriptor;
256 static Eet_Data_Descriptor *_union_unified_descriptor;
257 static Eet_Data_Descriptor *_variant_unified_descriptor;
258
259 /* keep file handle alive, so mmap()ed strings are all alive as
260  * well */
261 static Eet_File *_cache_file = NULL;
262 static Eet_Dictionary *_cache_dict = NULL;
263
264 static void
265 /* declaring types */
266 _data_descriptors_init(void)
267 {
268    Eet_Data_Descriptor_Class eddc;
269
270    EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Lists);
271    _lists_descriptor = eet_data_descriptor_file_new(&eddc);
272
273    _struct_1_descriptor = _st1_dd();
274    _struct_2_descriptor = _st2_dd();
275    _struct_3_descriptor = _st3_dd();
276
277    /* for union */
278    EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Union);
279    _union_descriptor = eet_data_descriptor_file_new(&eddc);
280
281    eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
282    eddc.func.type_get = _union_type_get;
283    eddc.func.type_set = _union_type_set;
284    _union_unified_descriptor = eet_data_descriptor_file_new(&eddc);
285
286    EET_DATA_DESCRIPTOR_ADD_MAPPING(
287      _union_unified_descriptor, "ST1", _struct_1_descriptor);
288    EET_DATA_DESCRIPTOR_ADD_MAPPING(
289      _union_unified_descriptor, "ST2", _struct_2_descriptor);
290    EET_DATA_DESCRIPTOR_ADD_MAPPING(
291      _union_unified_descriptor, "ST3", _struct_3_descriptor);
292
293    EET_DATA_DESCRIPTOR_ADD_UNION(
294      _union_descriptor, Example_Union, "u", u, type,
295      _union_unified_descriptor);
296
297    EET_DATA_DESCRIPTOR_ADD_LIST(
298      _lists_descriptor, Example_Lists, "union_list", union_list,
299      _union_descriptor);
300
301    /* for variant */
302    EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Variant);
303    _variant_descriptor = eet_data_descriptor_file_new(&eddc);
304
305    eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
306    eddc.func.type_get = _variant_type_get;
307    eddc.func.type_set = _variant_type_set;
308    _variant_unified_descriptor = eet_data_descriptor_stream_new(&eddc);
309
310    EET_DATA_DESCRIPTOR_ADD_MAPPING(
311      _variant_unified_descriptor, "ST1", _struct_1_descriptor);
312    EET_DATA_DESCRIPTOR_ADD_MAPPING(
313      _variant_unified_descriptor, "ST2", _struct_2_descriptor);
314    EET_DATA_DESCRIPTOR_ADD_MAPPING(
315      _variant_unified_descriptor, "ST3", _struct_3_descriptor);
316
317    EET_DATA_DESCRIPTOR_ADD_VARIANT(
318      _variant_descriptor, Example_Variant, "data", data, t,
319      _variant_unified_descriptor);
320
321    EET_DATA_DESCRIPTOR_ADD_LIST(
322      _lists_descriptor, Example_Lists, "variant_list", variant_list,
323      _variant_descriptor);
324 } /* _data_descriptors_init */
325
326 static void
327 _data_descriptors_shutdown(void)
328 {
329    eet_data_descriptor_free(_lists_descriptor);
330    eet_data_descriptor_free(_struct_1_descriptor);
331    eet_data_descriptor_free(_struct_2_descriptor);
332    eet_data_descriptor_free(_struct_3_descriptor);
333    eet_data_descriptor_free(_union_descriptor);
334    eet_data_descriptor_free(_variant_descriptor);
335    eet_data_descriptor_free(_union_unified_descriptor);
336    eet_data_descriptor_free(_variant_unified_descriptor);
337 } /* _data_descriptors_shutdown */
338
339 /* need to check if the pointer came from mmap()ed area in
340  * eet_dictionary or it was allocated with eina_stringshare_add()
341  */
342 static void
343 _string_free(const char *str)
344 {
345    if (!str)
346      return;
347
348    if ((_cache_dict) && (eet_dictionary_string_check(_cache_dict, str)))
349      return;
350
351    eina_stringshare_del(str);
352 } /* _string_free */
353
354 static Example_Union *
355 _union_1_new(const char *v1,
356              const char *v2,
357              const char *v3)
358 {
359    Example_Union *un = calloc(1, sizeof(Example_Union));
360    if (!un)
361      {
362         fprintf(
363           stderr, "ERROR: could not allocate an Example_Union struct.\n");
364         return NULL;
365      }
366
367    un->type = EET_STRUCT1;
368    _st1_set(&(un->u.st1), atof(v1), atoi(v2), eina_stringshare_add(v3));
369
370    return un;
371 }
372
373 static Example_Union *
374 _union_2_new(const char *v1,
375              const char *v2)
376 {
377    Example_Union *un = calloc(1, sizeof(Example_Union));
378    if (!un)
379      {
380         fprintf(
381           stderr, "ERROR: could not allocate an Example_Union struct.\n");
382         return NULL;
383      }
384
385    un->type = EET_STRUCT2;
386    _st2_set(&(un->u.st2), atoi(v1), atoi(v2));
387
388    return un;
389 }
390
391 static Example_Union *
392 _union_3_new(const char *v1)
393 {
394    Example_Union *un = calloc(1, sizeof(Example_Union));
395    if (!un)
396      {
397         fprintf(
398           stderr, "ERROR: could not allocate an Example_Union struct.\n");
399         return NULL;
400      }
401
402    un->type = EET_STRUCT3;
403    _st3_set(&(un->u.st3), atoi(v1));
404
405    return un;
406 }
407
408 static Example_Variant *
409 _variant_1_new(const char *v1,
410                const char *v2,
411                const char *v3)
412 {
413    Example_Struct1 *st1;
414    Example_Variant *va = calloc(1, sizeof(Example_Variant));
415    if (!va)
416      {
417         fprintf(
418           stderr, "ERROR: could not allocate an Example_Variant struct.\n");
419         return NULL;
420      }
421
422    va = calloc(1, sizeof (Example_Variant));
423    va->t.type = eet_mapping[0].name;
424    st1 = calloc(1, sizeof (Example_Struct1));
425    _st1_set(st1, atof(v1), atoi(v2), eina_stringshare_add(v3));
426    va->data = st1;
427
428    return va;
429 }
430
431 static Example_Variant *
432 _variant_2_new(const char *v1,
433                const char *v2)
434 {
435    printf("varinant 2 new\n");
436
437    Example_Struct2 *st2;
438    Example_Variant *va = calloc(1, sizeof(Example_Variant));
439    if (!va)
440      {
441         fprintf(
442           stderr, "ERROR: could not allocate an Example_Variant struct.\n");
443         return NULL;
444      }
445
446    va = calloc(1, sizeof (Example_Variant));
447
448    va->t.type = eet_mapping[1].name;
449
450    printf("type gets %s\n", va->t.type);
451
452    st2 = calloc(1, sizeof (Example_Struct2));
453    _st2_set(st2, atoi(v1), atoi(v2));
454    va->data = st2;
455
456    return va;
457 }
458
459 static Example_Variant *
460 _variant_3_new(const char *v1)
461 {
462    Example_Struct3 *st3;
463    Example_Variant *va = calloc(1, sizeof(Example_Variant));
464    if (!va)
465      {
466         fprintf(
467           stderr, "ERROR: could not allocate an Example_Variant struct.\n");
468         return NULL;
469      }
470
471    va = calloc(1, sizeof (Example_Variant));
472    va->t.type = eet_mapping[2].name;
473    st3 = calloc(1, sizeof (Example_Struct3));
474    _st3_set(st3, atoi(v1));
475    va->data = st3;
476
477    return va;
478 }
479
480 static Example_Lists *
481 _data_new(void)
482 {
483    Example_Lists *example_lists = calloc(1, sizeof(Example_Lists));
484    if (!example_lists)
485      {
486         fprintf(stderr, "ERROR: could not allocate a Example_Lists struct.\n");
487         return NULL;
488      }
489
490    return example_lists;
491 } /* _data_new */
492
493 static void
494 _union_free(Example_Union *un)
495 {
496    if (un->type == EET_STRUCT1)
497      {
498         Example_Struct1 *st1 = &(un->u.st1);
499         _string_free(st1->s1);
500      }
501
502    free(un);
503 }
504
505 static void
506 _variant_free(Example_Variant *va)
507 {
508    if (!strcmp(va->t.type, eet_mapping[0].name))
509      {
510         Example_Struct1 *st1 = va->data;
511         _string_free(st1->s1);
512      }
513
514    free(va->data);
515    free(va);
516 }
517
518 static void
519 _data_free(Example_Lists *cache)
520 {
521    Example_Union *un;
522    Example_Variant *va;
523
524    EINA_LIST_FREE(cache->union_list, un)
525      _union_free(un);
526
527    EINA_LIST_FREE(cache->variant_list, va)
528      _variant_free(va);
529
530    free(cache);
531 } /* _data_free */
532
533 static Example_Lists *
534 _data_load(const char *filename)
535 {
536    Example_Lists *data;
537    Eet_File *ef = eet_open(filename, EET_FILE_MODE_READ);
538    if (!ef)
539      {
540         fprintf(stderr, "ERROR: could not open '%s' for read\n", filename);
541         return NULL;
542      }
543
544    data = eet_data_read(ef, _lists_descriptor, CACHE_FILE_ENTRY);
545    if (!data)
546      {
547         eet_close(ef);
548         return NULL;
549      }
550
551    if (_cache_file)
552      eet_close(_cache_file);
553
554    _cache_file = ef;
555    _cache_dict = eet_dictionary_get(ef);
556
557    return data;
558 } /* _data_load */
559
560 static Eina_Bool
561 _data_save(const Example_Lists *cache,
562            const char          *filename)
563 {
564    char tmp[PATH_MAX];
565    Eet_File *ef;
566    Eina_Bool ret;
567    unsigned int i, len;
568    struct stat st;
569
570    len = eina_strlcpy(tmp, filename, sizeof(tmp));
571    if (len + 12 >= (int)sizeof(tmp))
572      {
573         fprintf(stderr, "ERROR: file name is too big: %s\n", filename);
574         return EINA_FALSE;
575      }
576
577    i = 0;
578    do
579      {
580         snprintf(tmp + len, 12, ".%u", i);
581         i++;
582      }
583    while (stat(tmp, &st) == 0);
584
585    ef = eet_open(tmp, EET_FILE_MODE_WRITE);
586    if (!ef)
587      {
588         fprintf(stderr, "ERROR: could not open '%s' for write\n", tmp);
589         return EINA_FALSE;
590      }
591
592    ret = eet_data_write
593        (ef, _lists_descriptor, CACHE_FILE_ENTRY, cache, EINA_TRUE);
594
595    eet_close(ef);
596
597    if (ret)
598      {
599         unlink(filename);
600         rename(tmp, filename);
601      }
602
603    return ret;
604 } /* _data_save */
605
606 static void
607 _print_union(const Example_Union *un)
608 {
609    printf("\t  |   type: %s'\n", eet_mapping[un->type - 1].name);
610
611    switch (un->type)
612      {
613       case EET_STRUCT1:
614         printf("\t\t  val1: %f\n", un->u.st1.val1);
615         printf("\t\t  stuff: %d\n", un->u.st1.stuff);
616         printf("\t\t  s1: %s\n", un->u.st1.s1);
617         break;
618
619       case EET_STRUCT2:
620         printf("\t\t  val1: %i\n", un->u.st2.b1);
621         printf("\t\t  stuff: %lli\n", un->u.st2.v1);
622         break;
623
624       case EET_STRUCT3:
625         printf("\t\t  val1: %i\n", un->u.st3.body);
626         break;
627
628       default:
629         return;
630      }
631 }
632
633 static void
634 _print_variant(const Example_Variant *va)
635 {
636    printf("\t  |   type: %s'\n", va->t.type);
637
638    switch (va->t.type[2])
639      {
640       case '1':
641       {
642          Example_Struct1 *st1 = va->data;
643
644          printf("\t\t  val1: %f\n", st1->val1);
645          printf("\t\t  stuff: %d\n", st1->stuff);
646          printf("\t\t  s1: %s\n", st1->s1);
647       }
648       break;
649
650       case '2':
651       {
652          Example_Struct2 *st2 = va->data;
653
654          printf("\t\t  val1: %i\n", st2->b1);
655          printf("\t\t  stuff: %lli\n", st2->v1);
656       }
657       break;
658
659       case '3':
660       {
661          Example_Struct3 *st3 = va->data;
662
663          printf("\t\t  val1: %i\n", st3->body);
664       }
665       break;
666
667       default:
668         return;
669      }
670 }
671
672 int
673 main(int   argc,
674      char *argv[])
675 {
676    Example_Lists *data_lists;
677    int ret = 0;
678
679    if (argc < 3)
680      {
681         fprintf(stderr,
682                 "Usage:\n\t%s <input> <output> [action action-params]\n\n"
683                 "where actions and their parameters are:\n"
684                 "\tunion <type> [fields]\n"
685                 "\tvariant <type> [fields]\n"
686                 "\n",
687                 argv[0]);
688         return -1;
689      }
690
691    eina_init();
692    eet_init();
693    _data_descriptors_init();
694
695    data_lists = _data_load(argv[1]);
696    if (!data_lists)
697      {
698         printf("Creating new data lists.\n");
699         data_lists = _data_new();
700         if (!data_lists)
701           {
702              ret = -2;
703              goto end;
704           }
705      }
706
707    if (argc > 3)
708      {
709         if (strcmp(argv[3], "union") == 0)
710           {
711              if (argc > 4)
712                {
713                   int type = atoi(argv[4]);
714                   Example_Union *un;
715
716                   if (type < EET_STRUCT1 || type > EET_STRUCT3)
717                     {
718                        fprintf(stderr,
719                                "ERROR: invalid type parameter (%s).\n",
720                                argv[4]);
721                        goto cont;
722                     }
723
724                   switch (type)
725                     {
726                      case 1:
727                        if (argc != 8)
728                          {
729                             fprintf(
730                               stderr, "ERROR: wrong number of parameters"
731                                       " (%d).\n", argc);
732                             goto cont;
733                          }
734
735                        un = _union_1_new(
736                            argv[5], argv[6], argv[7]);
737                        if (!un)
738                          {
739                             fprintf(
740                               stderr, "ERROR: could not create the "
741                                       "requested union.\n");
742                             goto cont;
743                          }
744                        data_lists->union_list =
745                          eina_list_append(data_lists->union_list, un);
746                        break;
747
748                      case 2:
749                        if (argc != 7)
750                          {
751                             fprintf(
752                               stderr, "ERROR: wrong number of parameters"
753                                       " (%d).\n", argc);
754                             goto cont;
755                          }
756
757                        un = _union_2_new(argv[5], argv[6]);
758                        if (!un)
759                          {
760                             fprintf(
761                               stderr, "ERROR: could not create the "
762                                       "requested union.\n");
763                             goto cont;
764                          }
765                        data_lists->union_list =
766                          eina_list_append(data_lists->union_list, un);
767                        break;
768
769                      case 3:
770                        if (argc != 6)
771                          {
772                             fprintf(
773                               stderr, "ERROR: wrong number of parameters"
774                                       " (%d).\n", argc);
775                             goto cont;
776                          }
777
778                        un = _union_3_new(argv[5]);
779                        if (!un)
780                          {
781                             fprintf(
782                               stderr, "ERROR: could not create the "
783                                       "requested union.\n");
784                             goto cont;
785                          }
786                        data_lists->union_list =
787                          eina_list_append(data_lists->union_list, un);
788                        break;
789
790                      default:
791                        fprintf(
792                          stderr, "ERROR: bad type of of struct passed\n");
793                        goto cont;
794                     }
795                }
796              else
797                fprintf(stderr,
798                        "ERROR: wrong number of parameters (%d).\n",
799                        argc);
800           }
801         else if (strcmp(argv[3], "variant") == 0)
802           {
803              if (argc > 4)
804                {
805                   int type = atoi(argv[4]);
806                   Example_Variant *va;
807
808                   if (type < EET_STRUCT1 || type > EET_STRUCT3)
809                     {
810                        fprintf(stderr,
811                                "ERROR: invalid type parameter (%s).\n",
812                                argv[4]);
813                        goto cont;
814                     }
815
816                   switch (type)
817                     {
818                      case 1:
819                        if (argc != 8)
820                          {
821                             fprintf(
822                               stderr, "ERROR: wrong number of parameters"
823                                       " (%d).\n", argc);
824                             goto cont;
825                          }
826
827                        va = _variant_1_new(
828                            argv[5], argv[6], argv[7]);
829                        if (!va)
830                          {
831                             fprintf(
832                               stderr, "ERROR: could not create the "
833                                       "requested variant.\n");
834                             goto cont;
835                          }
836                        data_lists->variant_list =
837                          eina_list_append(data_lists->variant_list, va);
838                        break;
839
840                      case 2:
841                        if (argc != 7)
842                          {
843                             fprintf(
844                               stderr, "ERROR: wrong number of parameters"
845                                       " (%d).\n", argc);
846                             goto cont;
847                          }
848
849                        va = _variant_2_new(argv[5], argv[6]);
850                        if (!va)
851                          {
852                             fprintf(
853                               stderr, "ERROR: could not create the "
854                                       "requested variant.\n");
855                             goto cont;
856                          }
857                        data_lists->variant_list =
858                          eina_list_append(data_lists->variant_list, va);
859                        break;
860
861                      case 3:
862                        if (argc != 6)
863                          {
864                             fprintf(
865                               stderr, "ERROR: wrong number of parameters"
866                                       " (%d).\n", argc);
867                             goto cont;
868                          }
869
870                        va = _variant_3_new(argv[5]);
871                        if (!va)
872                          {
873                             fprintf(
874                               stderr, "ERROR: could not create the "
875                                       "requested variant.\n");
876                             goto cont;
877                          }
878                        data_lists->variant_list =
879                          eina_list_append(data_lists->variant_list, va);
880                        break;
881
882                      default:
883                        fprintf(
884                          stderr, "ERROR: bad type of of struct passed\n");
885                        goto cont;
886                     }
887                }
888              else
889                fprintf(stderr,
890                        "ERROR: wrong number of parameters (%d).\n",
891                        argc);
892           }
893         else
894           fprintf(stderr, "ERROR: unknown action '%s'\n", argv[3]);
895      }
896
897 cont:
898    printf("Cached data:\n");
899
900    printf("\tstats: unions=%u, variants=%u\n",
901           eina_list_count(data_lists->union_list),
902           eina_list_count(data_lists->variant_list));
903
904    if (eina_list_count(data_lists->union_list))
905      {
906         const Eina_List *l;
907         const Example_Union *un;
908         printf("\t  * union list:\n");
909
910         EINA_LIST_FOREACH(data_lists->union_list, l, un)
911           {
912              _print_union(un);
913           }
914      }
915
916    if (eina_list_count(data_lists->variant_list))
917      {
918         const Eina_List *l;
919         const Example_Variant *un;
920         printf("\t  * variant list:\n");
921
922         EINA_LIST_FOREACH(data_lists->variant_list, l, un)
923           {
924              _print_variant(un);
925           }
926      }
927
928    printf("\n");
929
930    if (!_data_save(data_lists, argv[2]))
931      ret = -3;
932
933    _data_free(data_lists);
934
935 end:
936    if (_cache_file)
937      eet_close(_cache_file);
938    _data_descriptors_shutdown();
939    eet_shutdown();
940    eina_shutdown();
941
942    return ret;
943 } /* main */
944