1 #include <string.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <errno.h>
5 #include <glib-object.h>
6
7 extern GType dee_analyzer_get_type (void);
8 extern GType dee_client_get_type (void);
9 extern GType dee_file_resource_manager_get_type (void);
10 extern GType dee_filter_model_get_type (void);
11 extern GType dee_glist_result_set_get_type (void);
12 extern GType dee_hash_index_get_type (void);
13 extern GType dee_index_get_type (void);
14 extern GType dee_model_get_type (void);
15 extern GType dee_peer_get_type (void);
16 extern GType dee_proxy_model_get_type (void);
17 extern GType dee_resource_manager_get_type (void);
18 extern GType dee_result_set_get_type (void);
19 extern GType dee_sequence_model_get_type (void);
20 extern GType dee_serializable_get_type (void);
21 extern GType dee_serializable_model_get_type (void);
22 extern GType dee_server_get_type (void);
23 extern GType dee_shared_model_get_type (void);
24 extern GType dee_term_list_get_type (void);
25 extern GType dee_text_analyzer_get_type (void);
26 extern GType dee_transaction_get_type (void);
27 extern GType dee_tree_index_get_type (void);
28
29 #ifdef GTK_IS_WIDGET_CLASS
30 #include <gtk/gtk.h>
31 #endif
32 GType object_types[22];
33
34 static GType *
35 get_object_types (void)
36 {
37 gpointer g_object_class;
38 gint i = 0;
39 object_types[i++] = dee_analyzer_get_type ();
40 object_types[i++] = dee_client_get_type ();
41 object_types[i++] = dee_file_resource_manager_get_type ();
42 object_types[i++] = dee_filter_model_get_type ();
43 object_types[i++] = dee_glist_result_set_get_type ();
44 object_types[i++] = dee_hash_index_get_type ();
45 object_types[i++] = dee_index_get_type ();
46 object_types[i++] = dee_model_get_type ();
47 object_types[i++] = dee_peer_get_type ();
48 object_types[i++] = dee_proxy_model_get_type ();
49 object_types[i++] = dee_resource_manager_get_type ();
50 object_types[i++] = dee_result_set_get_type ();
51 object_types[i++] = dee_sequence_model_get_type ();
52 object_types[i++] = dee_serializable_get_type ();
53 object_types[i++] = dee_serializable_model_get_type ();
54 object_types[i++] = dee_server_get_type ();
55 object_types[i++] = dee_shared_model_get_type ();
56 object_types[i++] = dee_term_list_get_type ();
57 object_types[i++] = dee_text_analyzer_get_type ();
58 object_types[i++] = dee_transaction_get_type ();
59 object_types[i++] = dee_tree_index_get_type ();
60 object_types[i] = 0;
61
62 /* reference the GObjectClass to initialize the param spec pool
63 * potentially needed by interfaces. See http://bugs.gnome.org/571820 */
64 g_object_class = g_type_class_ref (G_TYPE_OBJECT);
65
66 /* Need to make sure all the types are loaded in and initialize
67 * their signals and properties.
68 */
69 for (i=0; object_types[i]; i++)
70 {
71 if (G_TYPE_IS_CLASSED (object_types[i]))
72 g_type_class_ref (object_types[i]);
73 if (G_TYPE_IS_INTERFACE (object_types[i]))
74 g_type_default_interface_ref (object_types[i]);
75 }
76
77 g_type_class_unref (g_object_class);
78
79 return object_types;
80 }
81
82 /*
83 * This uses GObject type functions to output signal prototypes and the object
84 * hierarchy.
85 */
86
87 /* The output files */
88 const gchar *signals_filename = "./dee-1.0.signals.new";
89 const gchar *hierarchy_filename = "./dee-1.0.hierarchy.new";
90 const gchar *interfaces_filename = "./dee-1.0.interfaces.new";
91 const gchar *prerequisites_filename = "./dee-1.0.prerequisites.new";
92 const gchar *args_filename = "./dee-1.0.args.new";
93
94
95 static void output_signals (void);
96 static void output_object_signals (FILE *fp,
97 GType object_type);
98 static void output_object_signal (FILE *fp,
99 const gchar *object_class_name,
100 guint signal_id);
101 static const gchar * get_type_name (GType type,
102 gboolean * is_pointer);
103 static void output_object_hierarchy (void);
104 static void output_hierarchy (FILE *fp,
105 GType type,
106 guint level);
107
108 static void output_object_interfaces (void);
109 static void output_interfaces (FILE *fp,
110 GType type);
111
112 static void output_interface_prerequisites (void);
113 static void output_prerequisites (FILE *fp,
114 GType type);
115
116 static void output_args (void);
117 static void output_object_args (FILE *fp, GType object_type);
118
119 int
120 main (int argc, char *argv[])
121 {
122 g_type_init(); g_type_class_ref(G_TYPE_OBJECT);
123
124 get_object_types ();
125
126 output_signals ();
127 output_object_hierarchy ();
128 output_object_interfaces ();
129 output_interface_prerequisites ();
130 output_args ();
131
132 return 0;
133 }
134
135
136 static void
137 output_signals (void)
138 {
139 FILE *fp;
140 gint i;
141
142 fp = fopen (signals_filename, "w");
143 if (fp == NULL)
144 {
145 g_warning ("Couldn't open output file: %s : %s", signals_filename, g_strerror(errno));
146 return;
147 }
148
149 for (i = 0; object_types[i]; i++)
150 output_object_signals (fp, object_types[i]);
151
152 fclose (fp);
153 }
154
155 static gint
156 compare_signals (const void *a, const void *b)
157 {
158 const guint *signal_a = a;
159 const guint *signal_b = b;
160
161 return strcmp (g_signal_name (*signal_a), g_signal_name (*signal_b));
162 }
163
164 /* This outputs all the signals of one object. */
165 static void
166 output_object_signals (FILE *fp, GType object_type)
167 {
168 const gchar *object_class_name;
169 guint *signals, n_signals;
170 guint sig;
171
172 if (G_TYPE_IS_INSTANTIATABLE (object_type) ||
173 G_TYPE_IS_INTERFACE (object_type))
174 {
175
176 object_class_name = g_type_name (object_type);
177
178 signals = g_signal_list_ids (object_type, &n_signals);
179 qsort (signals, n_signals, sizeof (guint), compare_signals);
180
181 for (sig = 0; sig < n_signals; sig++)
182 {
183 output_object_signal (fp, object_class_name, signals[sig]);
184 }
185 g_free (signals);
186 }
187 }
188
189
190 /* This outputs one signal. */
191 static void
192 output_object_signal (FILE *fp,
193 const gchar *object_name,
194 guint signal_id)
195 {
196 GSignalQuery query_info;
197 const gchar *type_name, *ret_type, *object_arg, *arg_name;
198 gchar *pos, *object_arg_lower;
199 gboolean is_pointer;
200 gchar buffer[1024];
201 guint i, param;
202 gint param_num, widget_num, event_num, callback_num;
203 gint *arg_num;
204 gchar signal_name[128];
205 gchar flags[16];
206
207 /* g_print ("Object: %s Signal: %u\n", object_name, signal_id);*/
208
209 param_num = 1;
210 widget_num = event_num = callback_num = 0;
211
212 g_signal_query (signal_id, &query_info);
213
214 /* Output the signal object type and the argument name. We assume the
215 type is a pointer - I think that is OK. We remove "Gtk" or "Gnome" and
216 convert to lower case for the argument name. */
217 pos = buffer;
218 sprintf (pos, "%s ", object_name);
219 pos += strlen (pos);
220
221 /* Try to come up with a sensible variable name for the first arg
222 * It chops off 2 know prefixes :/ and makes the name lowercase
223 * It should replace lowercase -> uppercase with '_'
224 * GFileMonitor -> file_monitor
225 * GIOExtensionPoint -> extension_point
226 * GtkTreeView -> tree_view
227 * if 2nd char is upper case too
228 * search for first lower case and go back one char
229 * else
230 * search for next upper case
231 */
232 if (!strncmp (object_name, "Gtk", 3))
233 object_arg = object_name + 3;
234 else if (!strncmp (object_name, "Gnome", 5))
235 object_arg = object_name + 5;
236 else
237 object_arg = object_name;
238
239 object_arg_lower = g_ascii_strdown (object_arg, -1);
240 sprintf (pos, "*%s\n", object_arg_lower);
241 pos += strlen (pos);
242 if (!strncmp (object_arg_lower, "widget", 6))
243 widget_num = 2;
244 g_free(object_arg_lower);
245
246 /* Convert signal name to use underscores rather than dashes '-'. */
247 strncpy (signal_name, query_info.signal_name, 127);
248 signal_name[127] = '\0';
249 for (i = 0; signal_name[i]; i++)
250 {
251 if (signal_name[i] == '-')
252 signal_name[i] = '_';
253 }
254
255 /* Output the signal parameters. */
256 for (param = 0; param < query_info.n_params; param++)
257 {
258 type_name = get_type_name (query_info.param_types[param] & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
259
260 /* Most arguments to the callback are called "arg1", "arg2", etc.
261 GtkWidgets are called "widget", "widget2", ...
262 GtkCallbacks are called "callback", "callback2", ... */
263 if (!strcmp (type_name, "GtkWidget"))
264 {
265 arg_name = "widget";
266 arg_num = &widget_num;
267 }
268 else if (!strcmp (type_name, "GtkCallback")
269 || !strcmp (type_name, "GtkCCallback"))
270 {
271 arg_name = "callback";
272 arg_num = &callback_num;
273 }
274 else
275 {
276 arg_name = "arg";
277 arg_num = ¶m_num;
278 }
279 sprintf (pos, "%s ", type_name);
280 pos += strlen (pos);
281
282 if (!arg_num || *arg_num == 0)
283 sprintf (pos, "%s%s\n", is_pointer ? "*" : " ", arg_name);
284 else
285 sprintf (pos, "%s%s%i\n", is_pointer ? "*" : " ", arg_name,
286 *arg_num);
287 pos += strlen (pos);
288
289 if (arg_num)
290 {
291 if (*arg_num == 0)
292 *arg_num = 2;
293 else
294 *arg_num += 1;
295 }
296 }
297
298 pos = flags;
299 /* We use one-character flags for simplicity. */
300 if (query_info.signal_flags & G_SIGNAL_RUN_FIRST)
301 *pos++ = 'f';
302 if (query_info.signal_flags & G_SIGNAL_RUN_LAST)
303 *pos++ = 'l';
304 if (query_info.signal_flags & G_SIGNAL_RUN_CLEANUP)
305 *pos++ = 'c';
306 if (query_info.signal_flags & G_SIGNAL_NO_RECURSE)
307 *pos++ = 'r';
308 if (query_info.signal_flags & G_SIGNAL_DETAILED)
309 *pos++ = 'd';
310 if (query_info.signal_flags & G_SIGNAL_ACTION)
311 *pos++ = 'a';
312 if (query_info.signal_flags & G_SIGNAL_NO_HOOKS)
313 *pos++ = 'h';
314 *pos = 0;
315
316 /* Output the return type and function name. */
317 ret_type = get_type_name (query_info.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
318
319 fprintf (fp,
320 "<SIGNAL>\n<NAME>%s::%s</NAME>\n<RETURNS>%s%s</RETURNS>\n<FLAGS>%s</FLAGS>\n%s</SIGNAL>\n\n",
321 object_name, query_info.signal_name, ret_type, is_pointer ? "*" : "", flags, buffer);
322 }
323
324
325 /* Returns the type name to use for a signal argument or return value, given
326 the GtkType from the signal info. It also sets is_pointer to TRUE if the
327 argument needs a '*' since it is a pointer. */
328 static const gchar *
329 get_type_name (GType type, gboolean * is_pointer)
330 {
331 const gchar *type_name;
332
333 *is_pointer = FALSE;
334 type_name = g_type_name (type);
335
336 switch (type) {
337 case G_TYPE_NONE:
338 case G_TYPE_CHAR:
339 case G_TYPE_UCHAR:
340 case G_TYPE_BOOLEAN:
341 case G_TYPE_INT:
342 case G_TYPE_UINT:
343 case G_TYPE_LONG:
344 case G_TYPE_ULONG:
345 case G_TYPE_FLOAT:
346 case G_TYPE_DOUBLE:
347 case G_TYPE_POINTER:
348 /* These all have normal C type names so they are OK. */
349 return type_name;
350
351 case G_TYPE_STRING:
352 /* A GtkString is really a gchar*. */
353 *is_pointer = TRUE;
354 return "gchar";
355
356 case G_TYPE_ENUM:
357 case G_TYPE_FLAGS:
358 /* We use a gint for both of these. Hopefully a subtype with a decent
359 name will be registered and used instead, as GTK+ does itself. */
360 return "gint";
361
362 case G_TYPE_BOXED:
363 /* The boxed type shouldn't be used itself, only subtypes. Though we
364 return 'gpointer' just in case. */
365 return "gpointer";
366
367 case G_TYPE_PARAM:
368 /* A GParam is really a GParamSpec*. */
369 *is_pointer = TRUE;
370 return "GParamSpec";
371
372 #if GLIB_CHECK_VERSION (2, 25, 9)
373 case G_TYPE_VARIANT:
374 *is_pointer = TRUE;
375 return "GVariant";
376 #endif
377
378 default:
379 break;
380 }
381
382 /* For all GObject subclasses we can use the class name with a "*",
383 e.g. 'GtkWidget *'. */
384 if (g_type_is_a (type, G_TYPE_OBJECT))
385 *is_pointer = TRUE;
386
387 /* Also catch non GObject root types */
388 if (G_TYPE_IS_CLASSED (type))
389 *is_pointer = TRUE;
390
391 /* All boxed subtypes will be pointers as well. */
392 /* Exception: GStrv */
393 if (g_type_is_a (type, G_TYPE_BOXED) &&
394 !g_type_is_a (type, G_TYPE_STRV))
395 *is_pointer = TRUE;
396
397 /* All pointer subtypes will be pointers as well. */
398 if (g_type_is_a (type, G_TYPE_POINTER))
399 *is_pointer = TRUE;
400
401 /* But enums are not */
402 if (g_type_is_a (type, G_TYPE_ENUM) ||
403 g_type_is_a (type, G_TYPE_FLAGS))
404 *is_pointer = FALSE;
405
406 return type_name;
407 }
408
409
410 /* This outputs the hierarchy of all objects which have been initialized,
411 i.e. by calling their XXX_get_type() initialization function. */
412 static void
413 output_object_hierarchy (void)
414 {
415 FILE *fp;
416 gint i,j;
417 GType root, type;
418 GType root_types[22] = { G_TYPE_INVALID, };
419
420 fp = fopen (hierarchy_filename, "w");
421 if (fp == NULL)
422 {
423 g_warning ("Couldn't open output file: %s : %s", hierarchy_filename, g_strerror(errno));
424 return;
425 }
426 output_hierarchy (fp, G_TYPE_OBJECT, 0);
427 output_hierarchy (fp, G_TYPE_INTERFACE, 0);
428
429 for (i=0; object_types[i]; i++) {
430 root = object_types[i];
431 while ((type = g_type_parent (root))) {
432 root = type;
433 }
434 if ((root != G_TYPE_OBJECT) && (root != G_TYPE_INTERFACE)) {
435 for (j=0; root_types[j]; j++) {
436 if (root == root_types[j]) {
437 root = G_TYPE_INVALID; break;
438 }
439 }
440 if(root) {
441 root_types[j] = root;
442 output_hierarchy (fp, root, 0);
443 }
444 }
445 }
446
447 fclose (fp);
448 }
449
450 /* This is called recursively to output the hierarchy of a object. */
451 static void
452 output_hierarchy (FILE *fp,
453 GType type,
454 guint level)
455 {
456 guint i;
457 GType *children;
458 guint n_children;
459
460 if (!type)
461 return;
462
463 for (i = 0; i < level; i++)
464 fprintf (fp, " ");
465 fprintf (fp, "%s\n", g_type_name (type));
466
467 children = g_type_children (type, &n_children);
468
469 for (i=0; i < n_children; i++)
470 output_hierarchy (fp, children[i], level + 1);
471
472 g_free (children);
473 }
474
475 static void output_object_interfaces (void)
476 {
477 guint i;
478 FILE *fp;
479
480 fp = fopen (interfaces_filename, "w");
481 if (fp == NULL)
482 {
483 g_warning ("Couldn't open output file: %s : %s", interfaces_filename, g_strerror(errno));
484 return;
485 }
486 output_interfaces (fp, G_TYPE_OBJECT);
487
488 for (i = 0; object_types[i]; i++)
489 {
490 if (!g_type_parent (object_types[i]) &&
491 (object_types[i] != G_TYPE_OBJECT) &&
492 G_TYPE_IS_INSTANTIATABLE (object_types[i]))
493 {
494 output_interfaces (fp, object_types[i]);
495 }
496 }
497 fclose (fp);
498 }
499
500 static void
501 output_interfaces (FILE *fp,
502 GType type)
503 {
504 guint i;
505 GType *children, *interfaces;
506 guint n_children, n_interfaces;
507
508 if (!type)
509 return;
510
511 interfaces = g_type_interfaces (type, &n_interfaces);
512
513 if (n_interfaces > 0)
514 {
515 fprintf (fp, "%s", g_type_name (type));
516 for (i=0; i < n_interfaces; i++)
517 fprintf (fp, " %s", g_type_name (interfaces[i]));
518 fprintf (fp, "\n");
519 }
520 g_free (interfaces);
521
522 children = g_type_children (type, &n_children);
523
524 for (i=0; i < n_children; i++)
525 output_interfaces (fp, children[i]);
526
527 g_free (children);
528 }
529
530 static void output_interface_prerequisites (void)
531 {
532 FILE *fp;
533
534 fp = fopen (prerequisites_filename, "w");
535 if (fp == NULL)
536 {
537 g_warning ("Couldn't open output file: %s : %s", prerequisites_filename, g_strerror(errno));
538 return;
539 }
540 output_prerequisites (fp, G_TYPE_INTERFACE);
541 fclose (fp);
542 }
543
544 static void
545 output_prerequisites (FILE *fp,
546 GType type)
547 {
548 #if GLIB_CHECK_VERSION(2,1,0)
549 guint i;
550 GType *children, *prerequisites;
551 guint n_children, n_prerequisites;
552
553 if (!type)
554 return;
555
556 prerequisites = g_type_interface_prerequisites (type, &n_prerequisites);
557
558 if (n_prerequisites > 0)
559 {
560 fprintf (fp, "%s", g_type_name (type));
561 for (i=0; i < n_prerequisites; i++)
562 fprintf (fp, " %s", g_type_name (prerequisites[i]));
563 fprintf (fp, "\n");
564 }
565 g_free (prerequisites);
566
567 children = g_type_children (type, &n_children);
568
569 for (i=0; i < n_children; i++)
570 output_prerequisites (fp, children[i]);
571
572 g_free (children);
573 #endif
574 }
575
576 static void
577 output_args (void)
578 {
579 FILE *fp;
580 gint i;
581
582 fp = fopen (args_filename, "w");
583 if (fp == NULL)
584 {
585 g_warning ("Couldn't open output file: %s : %s", args_filename, g_strerror(errno));
586 return;
587 }
588
589 for (i = 0; object_types[i]; i++) {
590 output_object_args (fp, object_types[i]);
591 }
592
593 fclose (fp);
594 }
595
596 static gint
597 compare_param_specs (const void *a, const void *b)
598 {
599 GParamSpec *spec_a = *(GParamSpec **)a;
600 GParamSpec *spec_b = *(GParamSpec **)b;
601
602 return strcmp (g_param_spec_get_name (spec_a), g_param_spec_get_name (spec_b));
603 }
604
605 /* Its common to have unsigned properties restricted
606 * to the signed range. Therefore we make this look
607 * a bit nicer by spelling out the max constants.
608 */
609
610 /* Don't use "==" with floats, it might trigger a gcc warning. */
611 #define GTKDOC_COMPARE_FLOAT(x, y) (x <= y && x >= y)
612
613 static gchar*
614 describe_double_constant (gdouble value)
615 {
616 gchar *desc;
617
618 if (GTKDOC_COMPARE_FLOAT (value, G_MAXDOUBLE))
619 desc = g_strdup ("G_MAXDOUBLE");
620 else if (GTKDOC_COMPARE_FLOAT (value, G_MINDOUBLE))
621 desc = g_strdup ("G_MINDOUBLE");
622 else if (GTKDOC_COMPARE_FLOAT (value, -G_MAXDOUBLE))
623 desc = g_strdup ("-G_MAXDOUBLE");
624 else if (GTKDOC_COMPARE_FLOAT (value, G_MAXFLOAT))
625 desc = g_strdup ("G_MAXFLOAT");
626 else if (GTKDOC_COMPARE_FLOAT (value, G_MINFLOAT))
627 desc = g_strdup ("G_MINFLOAT");
628 else if (GTKDOC_COMPARE_FLOAT (value, -G_MAXFLOAT))
629 desc = g_strdup ("-G_MAXFLOAT");
630 else{
631 /* make sure floats are output with a decimal dot irrespective of
632 * current locale. Use formatd since we want human-readable numbers
633 * and do not need the exact same bit representation when deserialising */
634 desc = g_malloc0 (G_ASCII_DTOSTR_BUF_SIZE);
635 g_ascii_formatd (desc, G_ASCII_DTOSTR_BUF_SIZE, "%g", value);
636 }
637
638 return desc;
639 }
640
641 static gchar*
642 describe_signed_constant (gsize size, gint64 value)
643 {
644 gchar *desc = NULL;
645
646 switch (size) {
647 case 2:
648 if (sizeof (int) == 2) {
649 if (value == G_MAXINT)
650 desc = g_strdup ("G_MAXINT");
651 else if (value == G_MININT)
652 desc = g_strdup ("G_MININT");
653 else if (value == (gint64)G_MAXUINT)
654 desc = g_strdup ("G_MAXUINT");
655 }
656 break;
657 case 4:
658 if (sizeof (int) == 4) {
659 if (value == G_MAXINT)
660 desc = g_strdup ("G_MAXINT");
661 else if (value == G_MININT)
662 desc = g_strdup ("G_MININT");
663 else if (value == (gint64)G_MAXUINT)
664 desc = g_strdup ("G_MAXUINT");
665 }
666 if (value == G_MAXLONG)
667 desc = g_strdup ("G_MAXLONG");
668 else if (value == G_MINLONG)
669 desc = g_strdup ("G_MINLONG");
670 else if (value == (gint64)G_MAXULONG)
671 desc = g_strdup ("G_MAXULONG");
672 break;
673 case 8:
674 if (value == G_MAXINT64)
675 desc = g_strdup ("G_MAXINT64");
676 else if (value == G_MININT64)
677 desc = g_strdup ("G_MININT64");
678 break;
679 default:
680 break;
681 }
682 if (!desc)
683 desc = g_strdup_printf ("%" G_GINT64_FORMAT, value);
684
685 return desc;
686 }
687
688 static gchar*
689 describe_unsigned_constant (gsize size, guint64 value)
690 {
691 gchar *desc = NULL;
692
693 switch (size) {
694 case 2:
695 if (sizeof (int) == 2) {
696 if (value == (guint64)G_MAXINT)
697 desc = g_strdup ("G_MAXINT");
698 else if (value == G_MAXUINT)
699 desc = g_strdup ("G_MAXUINT");
700 }
701 break;
702 case 4:
703 if (sizeof (int) == 4) {
704 if (value == (guint64)G_MAXINT)
705 desc = g_strdup ("G_MAXINT");
706 else if (value == G_MAXUINT)
707 desc = g_strdup ("G_MAXUINT");
708 }
709 if (value == (guint64)G_MAXLONG)
710 desc = g_strdup ("G_MAXLONG");
711 else if (value == G_MAXULONG)
712 desc = g_strdup ("G_MAXULONG");
713 break;
714 case 8:
715 if (value == G_MAXINT64)
716 desc = g_strdup ("G_MAXINT64");
717 else if (value == G_MAXUINT64)
718 desc = g_strdup ("G_MAXUINT64");
719 break;
720 default:
721 break;
722 }
723 if (!desc)
724 desc = g_strdup_printf ("%" G_GUINT64_FORMAT, value);
725
726 return desc;
727 }
728
729 static gchar*
730 describe_type (GParamSpec *spec)
731 {
732 gchar *desc;
733 gchar *lower;
734 gchar *upper;
735
736 if (G_IS_PARAM_SPEC_CHAR (spec))
737 {
738 GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec);
739
740 lower = describe_signed_constant (sizeof(gchar), pspec->minimum);
741 upper = describe_signed_constant (sizeof(gchar), pspec->maximum);
742 if (pspec->minimum == G_MININT8 && pspec->maximum == G_MAXINT8)
743 desc = g_strdup ("");
744 else if (pspec->minimum == G_MININT8)
745 desc = g_strdup_printf ("<= %s", upper);
746 else if (pspec->maximum == G_MAXINT8)
747 desc = g_strdup_printf (">= %s", lower);
748 else
749 desc = g_strdup_printf ("[%s,%s]", lower, upper);
750 g_free (lower);
751 g_free (upper);
752 }
753 else if (G_IS_PARAM_SPEC_UCHAR (spec))
754 {
755 GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec);
756
757 lower = describe_unsigned_constant (sizeof(guchar), pspec->minimum);
758 upper = describe_unsigned_constant (sizeof(guchar), pspec->maximum);
759 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT8)
760 desc = g_strdup ("");
761 else if (pspec->minimum == 0)
762 desc = g_strdup_printf ("<= %s", upper);
763 else if (pspec->maximum == G_MAXUINT8)
764 desc = g_strdup_printf (">= %s", lower);
765 else
766 desc = g_strdup_printf ("[%s,%s]", lower, upper);
767 g_free (lower);
768 g_free (upper);
769 }
770 else if (G_IS_PARAM_SPEC_INT (spec))
771 {
772 GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec);
773
774 lower = describe_signed_constant (sizeof(gint), pspec->minimum);
775 upper = describe_signed_constant (sizeof(gint), pspec->maximum);
776 if (pspec->minimum == G_MININT && pspec->maximum == G_MAXINT)
777 desc = g_strdup ("");
778 else if (pspec->minimum == G_MININT)
779 desc = g_strdup_printf ("<= %s", upper);
780 else if (pspec->maximum == G_MAXINT)
781 desc = g_strdup_printf (">= %s", lower);
782 else
783 desc = g_strdup_printf ("[%s,%s]", lower, upper);
784 g_free (lower);
785 g_free (upper);
786 }
787 else if (G_IS_PARAM_SPEC_UINT (spec))
788 {
789 GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec);
790
791 lower = describe_unsigned_constant (sizeof(guint), pspec->minimum);
792 upper = describe_unsigned_constant (sizeof(guint), pspec->maximum);
793 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT)
794 desc = g_strdup ("");
795 else if (pspec->minimum == 0)
796 desc = g_strdup_printf ("<= %s", upper);
797 else if (pspec->maximum == G_MAXUINT)
798 desc = g_strdup_printf (">= %s", lower);
799 else
800 desc = g_strdup_printf ("[%s,%s]", lower, upper);
801 g_free (lower);
802 g_free (upper);
803 }
804 else if (G_IS_PARAM_SPEC_LONG (spec))
805 {
806 GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec);
807
808 lower = describe_signed_constant (sizeof(glong), pspec->minimum);
809 upper = describe_signed_constant (sizeof(glong), pspec->maximum);
810 if (pspec->minimum == G_MINLONG && pspec->maximum == G_MAXLONG)
811 desc = g_strdup ("");
812 else if (pspec->minimum == G_MINLONG)
813 desc = g_strdup_printf ("<= %s", upper);
814 else if (pspec->maximum == G_MAXLONG)
815 desc = g_strdup_printf (">= %s", lower);
816 else
817 desc = g_strdup_printf ("[%s,%s]", lower, upper);
818 g_free (lower);
819 g_free (upper);
820 }
821 else if (G_IS_PARAM_SPEC_ULONG (spec))
822 {
823 GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec);
824
825 lower = describe_unsigned_constant (sizeof(gulong), pspec->minimum);
826 upper = describe_unsigned_constant (sizeof(gulong), pspec->maximum);
827 if (pspec->minimum == 0 && pspec->maximum == G_MAXULONG)
828 desc = g_strdup ("");
829 else if (pspec->minimum == 0)
830 desc = g_strdup_printf ("<= %s", upper);
831 else if (pspec->maximum == G_MAXULONG)
832 desc = g_strdup_printf (">= %s", lower);
833 else
834 desc = g_strdup_printf ("[%s,%s]", lower, upper);
835 g_free (lower);
836 g_free (upper);
837 }
838 else if (G_IS_PARAM_SPEC_INT64 (spec))
839 {
840 GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec);
841
842 lower = describe_signed_constant (sizeof(gint64), pspec->minimum);
843 upper = describe_signed_constant (sizeof(gint64), pspec->maximum);
844 if (pspec->minimum == G_MININT64 && pspec->maximum == G_MAXINT64)
845 desc = g_strdup ("");
846 else if (pspec->minimum == G_MININT64)
847 desc = g_strdup_printf ("<= %s", upper);
848 else if (pspec->maximum == G_MAXINT64)
849 desc = g_strdup_printf (">= %s", lower);
850 else
851 desc = g_strdup_printf ("[%s,%s]", lower, upper);
852 g_free (lower);
853 g_free (upper);
854 }
855 else if (G_IS_PARAM_SPEC_UINT64 (spec))
856 {
857 GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec);
858
859 lower = describe_unsigned_constant (sizeof(guint64), pspec->minimum);
860 upper = describe_unsigned_constant (sizeof(guint64), pspec->maximum);
861 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT64)
862 desc = g_strdup ("");
863 else if (pspec->minimum == 0)
864 desc = g_strdup_printf ("<= %s", upper);
865 else if (pspec->maximum == G_MAXUINT64)
866 desc = g_strdup_printf (">= %s", lower);
867 else
868 desc = g_strdup_printf ("[%s,%s]", lower, upper);
869 g_free (lower);
870 g_free (upper);
871 }
872 else if (G_IS_PARAM_SPEC_FLOAT (spec))
873 {
874 GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec);
875
876 lower = describe_double_constant (pspec->minimum);
877 upper = describe_double_constant (pspec->maximum);
878 if (GTKDOC_COMPARE_FLOAT (pspec->minimum, -G_MAXFLOAT))
879 {
880 if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXFLOAT))
881 desc = g_strdup ("");
882 else
883 desc = g_strdup_printf ("<= %s", upper);
884 }
885 else if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXFLOAT))
886 desc = g_strdup_printf (">= %s", lower);
887 else
888 desc = g_strdup_printf ("[%s,%s]", lower, upper);
889 g_free (lower);
890 g_free (upper);
891 }
892 else if (G_IS_PARAM_SPEC_DOUBLE (spec))
893 {
894 GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec);
895
896 lower = describe_double_constant (pspec->minimum);
897 upper = describe_double_constant (pspec->maximum);
898 if (GTKDOC_COMPARE_FLOAT (pspec->minimum, -G_MAXDOUBLE))
899 {
900 if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXDOUBLE))
901 desc = g_strdup ("");
902 else
903 desc = g_strdup_printf ("<= %s", upper);
904 }
905 else if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXDOUBLE))
906 desc = g_strdup_printf (">= %s", lower);
907 else
908 desc = g_strdup_printf ("[%s,%s]", lower, upper);
909 g_free (lower);
910 g_free (upper);
911 }
912 #if GLIB_CHECK_VERSION (2, 12, 0)
913 else if (G_IS_PARAM_SPEC_GTYPE (spec))
914 {
915 GParamSpecGType *pspec = G_PARAM_SPEC_GTYPE (spec);
916 gboolean is_pointer;
917
918 desc = g_strdup (get_type_name (pspec->is_a_type, &is_pointer));
919 }
920 #endif
921 #if GLIB_CHECK_VERSION (2, 25, 9)
922 else if (G_IS_PARAM_SPEC_VARIANT (spec))
923 {
924 GParamSpecVariant *pspec = G_PARAM_SPEC_VARIANT (spec);
925 gchar *variant_type;
926
927 variant_type = g_variant_type_dup_string (pspec->type);
928 desc = g_strdup_printf ("GVariant<%s>", variant_type);
929 g_free (variant_type);
930 }
931 #endif
932 else
933 {
934 desc = g_strdup ("");
935 }
936
937 return desc;
938 }
939
940 static gchar*
941 describe_default (GParamSpec *spec)
942 {
943 gchar *desc;
944
945 if (G_IS_PARAM_SPEC_CHAR (spec))
946 {
947 GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec);
948
949 desc = g_strdup_printf ("%d", pspec->default_value);
950 }
951 else if (G_IS_PARAM_SPEC_UCHAR (spec))
952 {
953 GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec);
954
955 desc = g_strdup_printf ("%u", pspec->default_value);
956 }
957 else if (G_IS_PARAM_SPEC_BOOLEAN (spec))
958 {
959 GParamSpecBoolean *pspec = G_PARAM_SPEC_BOOLEAN (spec);
960
961 desc = g_strdup_printf ("%s", pspec->default_value ? "TRUE" : "FALSE");
962 }
963 else if (G_IS_PARAM_SPEC_INT (spec))
964 {
965 GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec);
966
967 desc = g_strdup_printf ("%d", pspec->default_value);
968 }
969 else if (G_IS_PARAM_SPEC_UINT (spec))
970 {
971 GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec);
972
973 desc = g_strdup_printf ("%u", pspec->default_value);
974 }
975 else if (G_IS_PARAM_SPEC_LONG (spec))
976 {
977 GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec);
978
979 desc = g_strdup_printf ("%ld", pspec->default_value);
980 }
981 else if (G_IS_PARAM_SPEC_LONG (spec))
982 {
983 GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec);
984
985 desc = g_strdup_printf ("%lu", pspec->default_value);
986 }
987 else if (G_IS_PARAM_SPEC_INT64 (spec))
988 {
989 GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec);
990
991 desc = g_strdup_printf ("%" G_GINT64_FORMAT, pspec->default_value);
992 }
993 else if (G_IS_PARAM_SPEC_UINT64 (spec))
994 {
995 GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec);
996
997 desc = g_strdup_printf ("%" G_GUINT64_FORMAT, pspec->default_value);
998 }
999 else if (G_IS_PARAM_SPEC_UNICHAR (spec))
1000 {
1001 GParamSpecUnichar *pspec = G_PARAM_SPEC_UNICHAR (spec);
1002
1003 if (g_unichar_isprint (pspec->default_value))
1004 desc = g_strdup_printf ("'%c'", pspec->default_value);
1005 else
1006 desc = g_strdup_printf ("%u", pspec->default_value);
1007 }
1008 else if (G_IS_PARAM_SPEC_ENUM (spec))
1009 {
1010 GParamSpecEnum *pspec = G_PARAM_SPEC_ENUM (spec);
1011
1012 GEnumValue *value = g_enum_get_value (pspec->enum_class, pspec->default_value);
1013 if (value)
1014 desc = g_strdup_printf ("%s", value->value_name);
1015 else
1016 desc = g_strdup_printf ("%d", pspec->default_value);
1017 }
1018 else if (G_IS_PARAM_SPEC_FLAGS (spec))
1019 {
1020 GParamSpecFlags *pspec = G_PARAM_SPEC_FLAGS (spec);
1021 guint default_value;
1022 GString *acc;
1023
1024 default_value = pspec->default_value;
1025 acc = g_string_new ("");
1026
1027 while (default_value)
1028 {
1029 GFlagsValue *value = g_flags_get_first_value (pspec->flags_class, default_value);
1030
1031 if (!value)
1032 break;
1033
1034 if (acc->len > 0)
1035 g_string_append (acc, "|");
1036 g_string_append (acc, value->value_name);
1037
1038 default_value &= ~value->value;
1039 }
1040
1041 if (default_value == 0)
1042 desc = g_string_free (acc, FALSE);
1043 else
1044 {
1045 desc = g_strdup_printf ("%d", pspec->default_value);
1046 g_string_free (acc, TRUE);
1047 }
1048 }
1049 else if (G_IS_PARAM_SPEC_FLOAT (spec))
1050 {
1051 GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec);
1052
1053 /* make sure floats are output with a decimal dot irrespective of
1054 * current locale. Use formatd since we want human-readable numbers
1055 * and do not need the exact same bit representation when deserialising */
1056 desc = g_malloc0 (G_ASCII_DTOSTR_BUF_SIZE);
1057 g_ascii_formatd (desc, G_ASCII_DTOSTR_BUF_SIZE, "%g",
1058 pspec->default_value);
1059 }
1060 else if (G_IS_PARAM_SPEC_DOUBLE (spec))
1061 {
1062 GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec);
1063
1064 /* make sure floats are output with a decimal dot irrespective of
1065 * current locale. Use formatd since we want human-readable numbers
1066 * and do not need the exact same bit representation when deserialising */
1067 desc = g_malloc0 (G_ASCII_DTOSTR_BUF_SIZE);
1068 g_ascii_formatd (desc, G_ASCII_DTOSTR_BUF_SIZE, "%g",
1069 pspec->default_value);
1070 }
1071 else if (G_IS_PARAM_SPEC_STRING (spec))
1072 {
1073 GParamSpecString *pspec = G_PARAM_SPEC_STRING (spec);
1074
1075 if (pspec->default_value)
1076 {
1077 gchar *esc = g_strescape (pspec->default_value, NULL);
1078
1079 desc = g_strdup_printf ("\"%s\"", esc);
1080
1081 g_free (esc);
1082 }
1083 else
1084 desc = g_strdup_printf ("NULL");
1085 }
1086 #if GLIB_CHECK_VERSION (2, 25, 9)
1087 else if (G_IS_PARAM_SPEC_VARIANT (spec))
1088 {
1089 GParamSpecVariant *pspec = G_PARAM_SPEC_VARIANT (spec);
1090
1091 if (pspec->default_value)
1092 desc = g_variant_print (pspec->default_value, TRUE);
1093 else
1094 desc = g_strdup ("NULL");
1095 }
1096 #endif
1097 else
1098 {
1099 desc = g_strdup ("");
1100 }
1101
1102 return desc;
1103 }
1104
1105
1106 static void
1107 output_object_args (FILE *fp, GType object_type)
1108 {
1109 gpointer class;
1110 const gchar *object_class_name;
1111 guint arg;
1112 gchar flags[16], *pos;
1113 GParamSpec **properties;
1114 guint n_properties;
1115 gboolean child_prop;
1116 gboolean style_prop;
1117 gboolean is_pointer;
1118 const gchar *type_name;
1119 gchar *type_desc;
1120 gchar *default_value;
1121
1122 if (G_TYPE_IS_OBJECT (object_type))
1123 {
1124 class = g_type_class_peek (object_type);
1125 if (!class)
1126 return;
1127
1128 properties = g_object_class_list_properties (class, &n_properties);
1129 }
1130 #if GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 3)
1131 else if (G_TYPE_IS_INTERFACE (object_type))
1132 {
1133 class = g_type_default_interface_ref (object_type);
1134
1135 if (!class)
1136 return;
1137
1138 properties = g_object_interface_list_properties (class, &n_properties);
1139 }
1140 #endif
1141 else
1142 return;
1143
1144 object_class_name = g_type_name (object_type);
1145
1146 child_prop = FALSE;
CID 10034 - DEADCODE
After this line, the value of "style_prop" is equal to 0.
Assigning: "style_prop" = "0".
1147 style_prop = FALSE;
1148
1149 while (TRUE) {
1150 qsort (properties, n_properties, sizeof (GParamSpec *), compare_param_specs);
1151 for (arg = 0; arg < n_properties; arg++)
1152 {
1153 GParamSpec *spec = properties[arg];
1154 const gchar *nick, *blurb, *dot;
1155
1156 if (spec->owner_type != object_type)
1157 continue;
1158
1159 pos = flags;
1160 /* We use one-character flags for simplicity. */
1161 if (child_prop && !style_prop)
1162 *pos++ = 'c';
CID 10034 - DEADCODE
On this path, the condition "style_prop" cannot be true.
After this line, the value of "style_prop" is equal to 0.
Noticing condition "style_prop".
1163 if (style_prop)
CID 10034 - DEADCODE
Execution cannot reach this statement "*pos++ = 's';".
1164 *pos++ = 's';
1165 if (spec->flags & G_PARAM_READABLE)
1166 *pos++ = 'r';
1167 if (spec->flags & G_PARAM_WRITABLE)
1168 *pos++ = 'w';
1169 if (spec->flags & G_PARAM_CONSTRUCT)
1170 *pos++ = 'x';
1171 if (spec->flags & G_PARAM_CONSTRUCT_ONLY)
1172 *pos++ = 'X';
1173 *pos = 0;
1174
1175 nick = g_param_spec_get_nick (spec);
1176 blurb = g_param_spec_get_blurb (spec);
1177
1178 dot = "";
1179 if (blurb) {
1180 int str_len = strlen (blurb);
1181 if (str_len > 0 && blurb[str_len - 1] != '.')
1182 dot = ".";
1183 }
1184
1185 type_desc = describe_type (spec);
1186 default_value = describe_default (spec);
1187 type_name = get_type_name (spec->value_type, &is_pointer);
1188 fprintf (fp, "<ARG>\n<NAME>%s::%s</NAME>\n<TYPE>%s%s</TYPE>\n<RANGE>%s</RANGE>\n<FLAGS>%s</FLAGS>\n<NICK>%s</NICK>\n<BLURB>%s%s</BLURB>\n<DEFAULT>%s</DEFAULT>\n</ARG>\n\n",
1189 object_class_name, g_param_spec_get_name (spec), type_name, is_pointer ? "*" : "", type_desc, flags, nick ? nick : "(null)", blurb ? blurb : "(null)", dot, default_value);
1190 g_free (type_desc);
1191 g_free (default_value);
1192 }
1193
1194 g_free (properties);
1195
1196 #ifdef GTK_IS_CONTAINER_CLASS
1197 if (!child_prop && GTK_IS_CONTAINER_CLASS (class)) {
1198 properties = gtk_container_class_list_child_properties (class, &n_properties);
1199 child_prop = TRUE;
1200 continue;
1201 }
1202 #endif
1203
1204 #ifdef GTK_IS_CELL_AREA_CLASS
1205 if (!child_prop && GTK_IS_CELL_AREA_CLASS (class)) {
1206 properties = gtk_cell_area_class_list_cell_properties (class, &n_properties);
1207 child_prop = TRUE;
1208 continue;
1209 }
1210 #endif
1211
1212 #ifdef GTK_IS_WIDGET_CLASS
1213 #if GTK_CHECK_VERSION(2,1,0)
1214 if (!style_prop && GTK_IS_WIDGET_CLASS (class)) {
1215 properties = gtk_widget_class_list_style_properties (GTK_WIDGET_CLASS (class), &n_properties);
1216 style_prop = TRUE;
1217 continue;
1218 }
1219 #endif
1220 #endif
1221
1222 break;
1223 }
1224 }