1 /*   EXTRAITS DE LA LICENCE
2 	Copyright CEA, contributeurs : Luc BILLARD et Damien
3 	CALISTE, laboratoire L_Sim, (2001-2005)
4 
5 	Adresse mèl :
6 	BILLARD, non joignable par mèl ;
7 	CALISTE, damien P caliste AT cea P fr.
8 
9 	Ce logiciel est un programme informatique servant à visualiser des
10 	structures atomiques dans un rendu pseudo-3D.
11 
12 	Ce logiciel est régi par la licence CeCILL soumise au droit français et
13 	respectant les principes de diffusion des logiciels libres. Vous pouvez
14 	utiliser, modifier et/ou redistribuer ce programme sous les conditions
15 	de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
16 	sur le site "http://www.cecill.info".
17 
18 	Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
19 	pris connaissance de la licence CeCILL, et que vous en avez accepté les
20 	termes (cf. le fichier Documentation/licence.fr.txt fourni avec ce logiciel).
21 */
22 
23 /*   LICENCE SUM UP
24 	Copyright CEA, contributors : Luc BILLARD et Damien
25 	CALISTE, laboratoire L_Sim, (2001-2005)
26 
27 	E-mail address:
28 	BILLARD, not reachable any more ;
29 	CALISTE, damien P caliste AT cea P fr.
30 
31 	This software is a computer program whose purpose is to visualize atomic
32 	configurations in 3D.
33 
34 	This software is governed by the CeCILL  license under French law and
35 	abiding by the rules of distribution of free software.  You can  use,
36 	modify and/ or redistribute the software under the terms of the CeCILL
37 	license as circulated by CEA, CNRS and INRIA at the following URL
38 	"http://www.cecill.info".
39 
40 	The fact that you are presently reading this means that you have had
41 	knowledge of the CeCILL license and that you accept its terms. You can
42 	find a copy of this licence shipped with this software at Documentation/licence.en.txt.
43 */
44 
45 #include "toolFileFormat.h"
46 
47 #include <visu_tools.h>
48 #include <visu_commandLine.h>
49 #include <string.h>
50 #include <stdlib.h>
51 
52 /**
53  * SECTION:toolFileFormat
54  * @short_description: Describes file format objects (name patterns,
55  * description, properties...).
56  *
57  * <para>When dealing with files, it is convenient to class then by
58  * formats, one format for JPEG files, one other for
59  * postscript... Such file formats are characterized by their
60  * description, explaining what they are, one or more name pattern
61  * (e.g. "*.jpg") and some properties (e.g. compression level for JPEG
62  * file).</para>
63  * <para>This module describes objects that can store all these
64  * informations and deals with them. To create a new file format, use
65  * tool_file_format_new(). A #ToolFileFormat object can be used in a
66  * GtkFileChooser object, using a GtkFileFilter. tool_file_format_getLabel()
67  * will return directly the label to give to the GtkFileFilter and the
68  * name patterns can be passed to it also.</para>
69  * <para>A file format property is a #ToolOption value. There are some
70  * convenient routines to add common boolean or integer
71  * properties. For instance, use tool_file_format_addPropertyBoolean()
72  * to add a boolean property to a given #ToolFileFormat object. Then the stored
73  * properties can be iterated on using a #ToolFileFormatIter iterator.</para>
74  */
75 
76 /**
77  * ToolFileFormatIter:
78  * @lst: internal pointer.
79  * @name: name of the current iterated property (read only).
80  * @label: label of the current iterated property (read only).
81  * @val: its value (read only).
82  *
83  * Iterator on #ToolFileFormat object properties. See
84  * tool_file_format_iterNextProperty().
85  *
86  * Since: 3.6
87  */
88 
tool_file_format_getQuark(void)89 GQuark tool_file_format_getQuark(void)
90 {
91   return g_quark_from_static_string("ToolFileFormat");
92 }
93 
94 /**
95  * ToolFileFormatPrivate:
96  *
97  * Private attributes of #ToolFileFormat objects.
98  **/
99 struct _ToolFileFormatPrivate
100 {
101   /* This is the list of file patterns, for example (*.jpg; *.jpeg; *.jpe). */
102   GList *fileType;
103   GList *fileMatchers;
104   gboolean ignoreFileType;
105 
106   /* This is a short text to describe this file format.
107      It should not be bigger than 30 characters. */
108   gchar *name;
109   /* This is a private field, it is a concatenation
110      of "name ({patterns},)". */
111   gchar *labelString;
112 
113   /* A validating routine for this file format. */
114   ToolFileFormatValidate validate;
115 
116   /* This is a private field. It enables to add some properties
117      to a file format. See fileFormatAdd_property*() and tool_file_format_property_get*()
118      to control them. */
119   GList *properties;
120 };
121 
122 enum {
123     PROP_0,
124     NAME_PROP,
125     LABEL_PROP,
126     IGNORE_PROP
127 };
128 
129 static void tool_file_format_finalize(GObject *obj);
130 static void tool_file_format_get_property(GObject* obj, guint property_id,
131                                           GValue *value, GParamSpec *pspec);
132 static void tool_file_format_set_property(GObject* obj, guint property_id,
133                                           const GValue *value, GParamSpec *pspec);
134 
135 static ToolOption* _getProperty(const ToolFileFormat *format, const gchar *name);
136 
G_DEFINE_TYPE_WITH_CODE(ToolFileFormat,tool_file_format,VISU_TYPE_OBJECT,G_ADD_PRIVATE (ToolFileFormat))137 G_DEFINE_TYPE_WITH_CODE(ToolFileFormat, tool_file_format, VISU_TYPE_OBJECT,
138                         G_ADD_PRIVATE(ToolFileFormat))
139 
140 static void tool_file_format_class_init(ToolFileFormatClass *klass)
141 {
142   DBG_fprintf(stderr, "Tool FileFormat: creating the class of the object.\n");
143 
144   G_OBJECT_CLASS(klass)->finalize     = tool_file_format_finalize;
145   G_OBJECT_CLASS(klass)->set_property = tool_file_format_set_property;
146   G_OBJECT_CLASS(klass)->get_property = tool_file_format_get_property;
147 
148   /**
149    * ToolFileFormat::name:
150    *
151    * The name identifying one file format, can be translate and used in a UI.
152    *
153    * Since: 3.7
154    */
155   g_object_class_install_property
156     (G_OBJECT_CLASS(klass), NAME_PROP,
157      g_param_spec_string("name", _("Name"), _("File format description."), "",
158                          G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
159   /**
160    * ToolFileFormat::label:
161    *
162    * The label giving the file pattern, can be translate and used in a UI.
163    *
164    * Since: 3.7
165    */
166   g_object_class_install_property
167     (G_OBJECT_CLASS(klass), LABEL_PROP,
168      g_param_spec_string("label", _("Label"), _("Label used to show the file pattern."), "",
169                          G_PARAM_READABLE));
170   /**
171    * ToolFileFormat::ignore-type:
172    *
173    * Store if the patterns of format descibes all possible patterns
174    * for the file format.
175    *
176    * Since: 3.7
177    */
178   g_object_class_install_property
179     (G_OBJECT_CLASS(klass), IGNORE_PROP,
180      g_param_spec_boolean("ignore-type", _("Ignore file patterns"),
181                           _("Don't restrict file matching to the given patterns."),
182                           FALSE, G_PARAM_READWRITE));
183 }
184 
tool_file_format_init(ToolFileFormat * fmt)185 static void tool_file_format_init(ToolFileFormat *fmt)
186 {
187   DBG_fprintf(stderr, "Tool FileFormat: initializing new object (%p).\n",
188 	      (gpointer)fmt);
189 
190   fmt->priv = tool_file_format_get_instance_private(fmt);
191   fmt->priv->name           = (gchar*)0;
192   fmt->priv->fileType       = (GList*)0;
193   fmt->priv->fileMatchers   = (GList*)0;
194   fmt->priv->labelString    = (gchar*)0;
195   fmt->priv->validate       = (ToolFileFormatValidate)0;
196   fmt->priv->properties     = (GList*)0;
197   fmt->priv->ignoreFileType = FALSE;
198 }
199 
tool_file_format_finalize(GObject * obj)200 static void tool_file_format_finalize(GObject *obj)
201 {
202   ToolFileFormatPrivate *format;
203 
204   DBG_fprintf(stderr, "Tool FileFormat: finalize object %p.\n", (gpointer)obj);
205 
206   format = TOOL_FILE_FORMAT(obj)->priv;
207 
208   g_free(format->name);
209   g_free(format->labelString);
210 
211   g_list_free_full(format->fileType, g_free);
212   g_list_free_full(format->fileMatchers, (GDestroyNotify)g_pattern_spec_free);
213   g_list_free_full(format->properties, (GDestroyNotify)tool_option_free);
214 
215   /* Chain up to the parent class */
216   G_OBJECT_CLASS(tool_file_format_parent_class)->finalize(obj);
217 
218   DBG_fprintf(stderr, "Tool FileFormat: freeing ... OK.\n");
219 }
tool_file_format_get_property(GObject * obj,guint property_id,GValue * value,GParamSpec * pspec)220 static void tool_file_format_get_property(GObject* obj, guint property_id,
221                                           GValue *value, GParamSpec *pspec)
222 {
223   ToolFileFormatPrivate *self = TOOL_FILE_FORMAT(obj)->priv;
224 
225   DBG_fprintf(stderr, "Tool FileFormat: get property '%s' -> ",
226 	      g_param_spec_get_name(pspec));
227   switch (property_id)
228     {
229     case NAME_PROP:
230       g_value_set_string(value, self->name); DBG_fprintf(stderr, "%s.\n", self->name); break;
231     case LABEL_PROP:
232       g_value_set_string(value, self->labelString);
233       DBG_fprintf(stderr, "%s.\n", self->labelString); break;
234     case IGNORE_PROP:
235       g_value_set_boolean(value, self->ignoreFileType);
236       DBG_fprintf(stderr, "%d.\n", self->ignoreFileType); break;
237     default:
238       /* We don't have any other property... */
239       G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
240       break;
241     }
242 }
tool_file_format_set_property(GObject * obj,guint property_id,const GValue * value,GParamSpec * pspec)243 static void tool_file_format_set_property(GObject* obj, guint property_id,
244                                           const GValue *value, GParamSpec *pspec)
245 {
246   ToolFileFormatPrivate *self = TOOL_FILE_FORMAT(obj)->priv;
247   gint nbCharacterMax = 45, lg;
248 
249   DBG_fprintf(stderr, "Tool FileFormat: set property '%s' -> ",
250 	      g_param_spec_get_name(pspec));
251   switch (property_id)
252     {
253     case NAME_PROP:
254       lg = strlen(g_value_get_string(value));
255       if (lg > nbCharacterMax)
256         {
257           g_warning("The label property is bigger than"
258                     " %d characters and it will be truncated.", nbCharacterMax);
259           lg = nbCharacterMax;
260         }
261       self->name = g_strndup(g_value_get_string(value), lg);
262       DBG_fprintf(stderr, "%s.\n", self->name); break;
263     case IGNORE_PROP:
264       self->ignoreFileType = g_value_get_boolean(value);
265       DBG_fprintf(stderr, "%d.\n", self->ignoreFileType); break;
266     default:
267       /* We don't have any other property... */
268       G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
269       break;
270     }
271 }
272 
_buildLabel(ToolFileFormat * format)273 static void _buildLabel(ToolFileFormat *format)
274 {
275   GList *lst;
276   GString *tmpStr;
277 
278   tmpStr = g_string_new(format->priv->name);
279   g_string_append_printf(tmpStr, " (");
280   for (lst = format->priv->fileType; lst; lst = g_list_next(lst))
281     {
282       g_string_append_printf(tmpStr, "%s", (gchar*) lst->data);
283       if (lst->next)
284 	g_string_append_printf(tmpStr, ", ");
285     }
286   if (!format->priv->fileType)
287     g_string_append_printf(tmpStr, "no filter");
288   if (format->priv->fileType && format->priv->ignoreFileType)
289     g_string_append_printf(tmpStr, ", ...");
290   g_string_append_printf(tmpStr, ")");
291   if (format->priv->labelString)
292     g_free(format->priv->labelString);
293   format->priv->labelString = tmpStr->str;
294   g_string_free(tmpStr, FALSE);
295 }
296 
297 /**
298  * tool_file_format_newRestricted:
299  * @descr: a short string to label a new file format.
300  * @patterns: a set of patterns to identify files of this format.
301  *
302  * Allocate a new #ToolFileFormat. The @patterns argument is copied in
303  * the #ToolFileFormat object and can be freed safely after the call to this method.
304  * The @patterns list is not all the patterns supported by the format.
305  *
306  * Returns: (transfer none): a newly allocated ToolFileFormat,
307  * or NULL if something goes wrong.
308  */
tool_file_format_newRestricted(const gchar * descr,const gchar ** patterns)309 ToolFileFormat* tool_file_format_newRestricted(const gchar* descr, const gchar** patterns)
310 {
311   ToolFileFormat *format;
312 
313   g_return_val_if_fail(descr && descr[0] && patterns, (ToolFileFormat*)0);
314 
315   format = TOOL_FILE_FORMAT(g_object_new(TOOL_TYPE_FILE_FORMAT,
316                                          "name", descr, "ignore-type", TRUE, NULL));
317   tool_file_format_addPatterns(format, patterns);
318 
319   return format;
320 }
321 
322 /**
323  * tool_file_format_new:
324  * @descr: a short string to label a new file format.
325  * @patterns: (array zero-terminated=1) (element-type utf8): a set of patterns to identify files of this format.
326  *
327  * Allocate a new #ToolFileFormat. The @patterns argument is copied in
328  * the #ToolFileFormat object and can be freed safely after the call to this method.
329  *
330  * Returns: (transfer none): a newly allocated ToolFileFormat,
331  * or NULL if something goes wrong.
332  */
tool_file_format_new(const gchar * descr,const gchar ** patterns)333 ToolFileFormat* tool_file_format_new(const gchar* descr, const gchar** patterns)
334 {
335   ToolFileFormat *format;
336 
337   g_return_val_if_fail(descr && descr[0] && patterns, (ToolFileFormat*)0);
338 
339   format = TOOL_FILE_FORMAT(g_object_new(TOOL_TYPE_FILE_FORMAT,
340                                          "name", descr, "ignore-type", FALSE, NULL));
341   tool_file_format_addPatterns(format, patterns);
342 
343   return format;
344 }
345 /**
346  * tool_file_format_addPatterns:
347  * @fmt: a #ToolFileFormat object.
348  * @patterns: (array zero-terminated=1): a list of matching patterns.
349  *
350  * A file format may have pattern for the naming scheme of files, like
351  * "*.jpg" and "*.jpeg" for JPEG files. It's not mandatory for a file
352  * format to match its own pattern anyway.
353  *
354  * Since: 3.7
355  **/
tool_file_format_addPatterns(ToolFileFormat * fmt,const gchar ** patterns)356 void tool_file_format_addPatterns(ToolFileFormat *fmt, const gchar **patterns)
357 {
358   gint n;
359 
360   g_return_if_fail(TOOL_IS_FILE_FORMAT(fmt));
361 
362   for (n = 0; patterns[n]; n++)
363     fmt->priv->fileType = g_list_append(fmt->priv->fileType, g_strdup(patterns[n]));
364   g_list_free_full(fmt->priv->fileMatchers, (GDestroyNotify)g_pattern_spec_free);
365   fmt->priv->fileMatchers = (GList*)0;
366   _buildLabel(fmt);
367 }
368 /**
369  * tool_file_format_copy:
370  * @from: a #ToolFileFormat object.
371  *
372  * Copy the given file format @from a create a new one.
373  *
374  * Since: 3.6
375  *
376  * Returns: (transfer full): a newly created #ToolFileFormat. Should
377  * be freed with g_object_unref().
378  */
tool_file_format_copy(const ToolFileFormat * from)379 ToolFileFormat* tool_file_format_copy(const ToolFileFormat *from)
380 {
381   ToolFileFormat *to;
382   GList *lst;
383 
384   g_return_val_if_fail(from, (ToolFileFormat*)0);
385 
386   to = TOOL_FILE_FORMAT(g_object_new(TOOL_TYPE_FILE_FORMAT,
387                                      "name", from->priv->name,
388                                      "ignore-type", from->priv->ignoreFileType, NULL));
389   DBG_fprintf(stderr, "Tool ToolFileFormat: copy to file format %p.\n", (gpointer)to);
390   to->priv->fileType       = (GList*)0;
391   for (lst = from->priv->fileType; lst; lst = g_list_next(lst))
392     to->priv->fileType = g_list_append(to->priv->fileType, g_strdup((gchar*)lst->data));
393   _buildLabel(to);
394   to->priv->properties     = (GList*)0;
395   for (lst = from->priv->properties; lst; lst = g_list_next(lst))
396     to->priv->properties = g_list_append(to->priv->properties,
397                                          tool_option_copy((ToolOption*)lst->data));
398 
399   return to;
400 }
401 /**
402  * tool_file_format_getName:
403  * @format: a #ToolFileFormat.
404  *
405  * This method gives the name describing the file format.
406  *
407  * Returns: (transfer none): a string with the name. This string
408  * should not be freed.
409  */
tool_file_format_getName(ToolFileFormat * format)410 const gchar* tool_file_format_getName(ToolFileFormat *format)
411 {
412   DBG_fprintf(stderr, "Tool ToolFileFormat: get the name of format '%p'.\n",
413 	      (gpointer)format);
414   g_return_val_if_fail(format, (gchar*)0);
415   return format->priv->name;
416 }
417 /**
418  * tool_file_format_getLabel:
419  * @format: a #ToolFileFormat.
420  *
421  * This method gives a label describing the file format.
422  *
423  * Returns: (transfer none): a string made by the name and all
424  * the paterns of the given format, given in parentethis. This string
425  * should not be freed.
426  */
tool_file_format_getLabel(ToolFileFormat * format)427 const gchar* tool_file_format_getLabel(ToolFileFormat *format)
428 {
429   DBG_fprintf(stderr, "Tool ToolFileFormat: get the label of format '%p'.\n",
430 	      (gpointer)format);
431   g_return_val_if_fail(format, (gchar*)0);
432   return format->priv->labelString;
433 }
434 /**
435  * tool_file_format_getFilePatterns:
436  * @format: a #ToolFileFormat.
437  *
438  * This method gives a list with the file patterns.
439  *
440  * Returns: (transfer none) (element-type utf8): a list with the file
441  * patterns. This list should not be freed.
442  *
443  * Since: 3.6
444  */
tool_file_format_getFilePatterns(ToolFileFormat * format)445 const GList* tool_file_format_getFilePatterns(ToolFileFormat *format)
446 {
447   DBG_fprintf(stderr, "Tool ToolFileFormat: get the file patterns of format '%p'.\n",
448 	      (gpointer)format);
449   g_return_val_if_fail(format, (GList*)0);
450   return format->priv->fileType;
451 }
452 
453 /**
454  * tool_file_format_canMatch:
455  * @format: a #ToolFileFormat.
456  *
457  * This method is used to know if the file pattern list can be used
458  * to match a given filename with tool_file_format_match().
459  *
460  * Returns: TRUE if a call to tool_file_format_match() is safe.
461  *
462  * Since: 3.6
463  */
tool_file_format_canMatch(ToolFileFormat * format)464 gboolean tool_file_format_canMatch(ToolFileFormat* format)
465 {
466   g_return_val_if_fail(format, FALSE);
467 
468   return !format->priv->ignoreFileType;
469 }
470 /**
471  * tool_file_format_match:
472  * @format: a #ToolFileFormat ;
473  * @filename: a string to match.
474  *
475  * This method try to match the given string to one of the patterns of
476  * the #ToolFileFormat @format.
477  *
478  * Returns: the matching pattern, if any.
479  */
tool_file_format_match(ToolFileFormat * format,const gchar * filename)480 const gchar* tool_file_format_match(ToolFileFormat *format, const gchar *filename)
481 {
482   GList *tmpLst;
483 
484   g_return_val_if_fail(format, FALSE);
485 
486   DBG_fprintf(stderr, "Tool FileFormat: try to match '%s' with '%s' -> ",
487               filename, format->priv->name);
488   tmpLst = format->priv->fileType;
489   while(tmpLst && !g_pattern_match_simple(tmpLst->data, filename))
490     tmpLst = g_list_next(tmpLst);
491   DBG_fprintf(stderr, "%d.\n", (tmpLst != (GList*)0));
492   return (tmpLst)?(const gchar*)tmpLst->data:(const gchar*)0;
493 }
_validate(ToolFileFormat * format,const gchar * filename)494 static gboolean _validate(ToolFileFormat *format, const gchar *filename)
495 {
496   gboolean passed;
497   GList *lst;
498 
499   if (!format->priv->fileMatchers)
500     for (lst = format->priv->fileType; lst; lst = g_list_next(lst))
501       format->priv->fileMatchers = g_list_prepend(format->priv->fileMatchers,
502                                                   g_pattern_spec_new((char*)lst->data));
503 
504   passed = FALSE;
505   for (lst = format->priv->fileMatchers; lst && !passed; lst = g_list_next(lst))
506     passed = g_pattern_match_string((GPatternSpec*)lst->data, filename);
507   return passed;
508 }
509 /**
510  * tool_file_format_validate:
511  * @format: a #ToolFileFormat ;
512  * @filename: a string to match.
513  *
514  * This method runs a minimal parsing routine set with
515  * tool_file_format_setValidator() to check if the provided filename
516  * correspond to this file format.
517  *
518  * Since: 3.7
519  *
520  * Returns: TRUE, if the file (after minimal parsing) is of this file
521  * format. If there is no validator routine, it is using a built-in
522  * one, based on pattern matching with file types, see
523  * tool_file_format_addPatterns().
524  */
tool_file_format_validate(ToolFileFormat * format,const gchar * filename)525 gboolean tool_file_format_validate(ToolFileFormat *format, const gchar *filename)
526 {
527   gboolean res;
528 
529   g_return_val_if_fail(format, FALSE);
530 
531   DBG_fprintf(stderr, "Tool FileFormat: try to validate '%s' with '%s' -> ",
532               filename, format->priv->name);
533   if (format->priv->validate)
534     res = format->priv->validate(filename);
535   else
536     res = _validate(format, filename);
537   DBG_fprintf(stderr, "%d.\n", res);
538   return res;
539 }
540 /**
541  * tool_file_format_setValidator:
542  * @format: a #ToolFileFormat ;
543  * @validate: (scope call) (allow-none): a pointer to a validator routine.
544  *
545  * Set up a validating routine that do a minimal parsing to check that
546  * a provided file corresponds to this file format.
547  *
548  * Since: 3.7
549  */
tool_file_format_setValidator(ToolFileFormat * format,ToolFileFormatValidate validate)550 void tool_file_format_setValidator(ToolFileFormat *format,
551                                    ToolFileFormatValidate validate)
552 {
553   g_return_if_fail(format);
554   format->priv->validate = validate;
555 }
556 
557 /**
558  * tool_file_format_addOption:
559  * @format: a #ToolFileFormat object.
560  * @opt: a #ToolOption object.
561  *
562  * File format may have options, like pseudo-potential pparameters in
563  * case of BigDFT calculations.
564  *
565  * Since: 3.7
566  **/
tool_file_format_addOption(ToolFileFormat * format,ToolOption * opt)567 void tool_file_format_addOption(ToolFileFormat *format, ToolOption *opt)
568 {
569   g_return_if_fail(TOOL_IS_FILE_FORMAT(format));
570 
571   format->priv->properties = g_list_append(format->priv->properties, (gpointer)opt);
572 }
573 
574 /**
575  * tool_file_format_addPropertyBoolean:
576  * @format: the #ToolFileFormat object.
577  * @name: a name ;
578  * @label: a description ;
579  * @defaultVal: a default value.
580  *
581  * Add a new boolean property to the file format @format.
582  *
583  * Returns: (transfer none): a newly created #ToolOption, free with tool_option_free().
584  */
tool_file_format_addPropertyBoolean(ToolFileFormat * format,const gchar * name,const gchar * label,gboolean defaultVal)585 ToolOption* tool_file_format_addPropertyBoolean(ToolFileFormat *format,
586                                                 const gchar *name, const gchar *label,
587                                                 gboolean defaultVal)
588 {
589   ToolOption *opt;
590   GValue *val;
591 
592   opt = _getProperty(format, name);
593   if (!opt)
594     {
595       opt = tool_option_new(name, label, G_TYPE_BOOLEAN);
596       format->priv->properties = g_list_append(format->priv->properties, (gpointer)opt);
597     }
598   val = tool_option_getValue(opt);
599   g_value_set_boolean(val, defaultVal);
600   return opt;
601 }
602 /**
603  * tool_file_format_addPropertyInt:
604  * @format: the #ToolFileFormat object.
605  * @name: a name ;
606  * @label: a description ;
607  * @defaultVal: a default value.
608  *
609  * Add a new integer property to the file format @format.
610  *
611  * Returns: (transfer none): a newly created #ToolOption, free with tool_option_free().
612  */
tool_file_format_addPropertyInt(ToolFileFormat * format,const gchar * name,const gchar * label,gint defaultVal)613 ToolOption* tool_file_format_addPropertyInt(ToolFileFormat *format,
614                                             const gchar *name, const gchar *label,
615                                             gint defaultVal)
616 {
617   ToolOption *opt;
618   GValue *val;
619 
620   opt = _getProperty(format, name);
621   if (!opt)
622     {
623       opt = tool_option_new(name, label, G_TYPE_INT);
624       format->priv->properties = g_list_append(format->priv->properties, (gpointer)opt);
625     }
626   val = tool_option_getValue(opt);
627   g_value_set_int(val, defaultVal);
628   return opt;
629 }
630 /**
631  * tool_file_format_addPropertyDouble:
632  * @format: the #ToolFileFormat object.
633  * @name: a name ;
634  * @label: a description ;
635  * @defaultVal: a default value.
636  *
637  * Add a new integer property to the file format @format.
638  *
639  * Since: 3.7
640  *
641  * Returns: (transfer none): a newly created #ToolOption, free with tool_option_free().
642  */
tool_file_format_addPropertyDouble(ToolFileFormat * format,const gchar * name,const gchar * label,gdouble defaultVal)643 ToolOption* tool_file_format_addPropertyDouble(ToolFileFormat *format,
644                                                const gchar *name, const gchar *label,
645                                                gdouble defaultVal)
646 {
647   ToolOption *opt;
648   GValue *val;
649 
650   opt = _getProperty(format, name);
651   if (!opt)
652     {
653       opt = tool_option_new(name, label, G_TYPE_DOUBLE);
654       format->priv->properties = g_list_append(format->priv->properties, (gpointer)opt);
655     }
656   val = tool_option_getValue(opt);
657   g_value_set_double(val, defaultVal);
658   return opt;
659 }
660 
661 /**
662  * tool_file_format_iterNextProperty:
663  * @format: a #ToolFileFormat object.
664  * @iter: an iterator.
665  *
666  * Run to the next property of the file format @format. The iterator
667  * attributes are updated so it's convenient to access the property
668  * values and details, see #ToolFileFormatIter.
669  *
670  * Since: 3.6
671  *
672  * Returns: TRUE if any.
673  */
tool_file_format_iterNextProperty(ToolFileFormat * format,ToolFileFormatIter * iter)674 gboolean tool_file_format_iterNextProperty(ToolFileFormat *format,
675                                            ToolFileFormatIter *iter)
676 {
677   if (!iter->lst)
678     iter->lst = format->priv->properties;
679   else
680     iter->lst = g_list_next(iter->lst);
681 
682   if (!iter->lst)
683     return FALSE;
684 
685   iter->name  = (gchar*)tool_option_getName ((ToolOption*)iter->lst->data);
686   iter->label = (gchar*)tool_option_getLabel((ToolOption*)iter->lst->data);
687   iter->val   = tool_option_getValue((ToolOption*)iter->lst->data);
688 
689   return TRUE;
690 }
691 
_getProperty(const ToolFileFormat * format,const gchar * name)692 static ToolOption* _getProperty(const ToolFileFormat *format, const gchar *name)
693 {
694   GList *lst;
695 
696   g_return_val_if_fail(format && name, (ToolOption*)0);
697 
698   DBG_fprintf(stderr, "Tool FileFormat: grep property '%s' from file format %p.\n",
699               name, (gpointer)format);
700   for (lst = format->priv->properties; lst; lst = g_list_next(lst))
701     if (!strcmp(name, tool_option_getName((ToolOption*)lst->data)))
702       return (ToolOption*)lst->data;
703   return (ToolOption*)0;
704 }
705 
706 /**
707  * tool_file_format_setPropertiesFromCLI:
708  * @format: A #ToolFileFormat object.
709  *
710  * Scan all options from command line and affects values.
711  *
712  * Since: 3.8
713  **/
tool_file_format_setPropertiesFromCLI(ToolFileFormat * format)714 void tool_file_format_setPropertiesFromCLI(ToolFileFormat *format)
715 {
716   GHashTable *opts;
717   GHashTableIter iter;
718   gpointer key, value;
719   ToolOption *prop;
720 
721   opts = commandLineGet_options();
722   if (!opts)
723     return;
724 
725   g_hash_table_iter_init(&iter, opts);
726   while(g_hash_table_iter_next(&iter, &key, &value))
727     {
728       prop = _getProperty(format, (const gchar*)key);
729       if (prop)
730         g_value_copy(tool_option_getValue((ToolOption*)value),
731                      tool_option_getValue(prop));
732     }
733 }
734 
735 /**
736  * tool_file_format_getPropertyBoolean:
737  * @format: a #ToolFileFormat object.
738  * @name: a property name.
739  *
740  * Retrieves the value of property @prop.
741  *
742  * Since: 3.8
743  *
744  * Returns: the property value if exists, FALSE otherwise.
745  **/
tool_file_format_getPropertyBoolean(const ToolFileFormat * format,const gchar * name)746 gboolean tool_file_format_getPropertyBoolean(const ToolFileFormat *format,
747                                              const gchar *name)
748 {
749   ToolOption *prop;
750 
751   g_return_val_if_fail(TOOL_IS_FILE_FORMAT(format), FALSE);
752 
753   prop = _getProperty(format, name);
754   if (!prop)
755     return FALSE;
756 
757   return g_value_get_boolean(tool_option_getValue(prop));
758 }
759 
760 /**
761  * tool_file_format_getPropertyInt:
762  * @format: a #ToolFileFormat object.
763  * @name: a property name.
764  *
765  * Retrieves the value of property @prop.
766  *
767  * Since: 3.8
768  *
769  * Returns: the property value if exists, -1 otherwise.
770  **/
tool_file_format_getPropertyInt(const ToolFileFormat * format,const gchar * name)771 gint tool_file_format_getPropertyInt(const ToolFileFormat *format,
772                                      const gchar *name)
773 {
774   ToolOption *prop;
775 
776   g_return_val_if_fail(TOOL_IS_FILE_FORMAT(format), -1);
777 
778   prop = _getProperty(format, name);
779   if (!prop)
780     return -1;
781 
782   return g_value_get_int(tool_option_getValue(prop));
783 }
784