Branch data Line data Source code
1 : : /* GObject - GLib Type, Object, Parameter and Signal Library
2 : : * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc.
3 : : *
4 : : * SPDX-License-Identifier: LGPL-2.1-or-later
5 : : *
6 : : * This library is free software; you can redistribute it and/or
7 : : * modify it under the terms of the GNU Lesser General Public
8 : : * License as published by the Free Software Foundation; either
9 : : * version 2.1 of the License, or (at your option) any later version.
10 : : *
11 : : * This library is distributed in the hope that it will be useful,
12 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : : * Lesser General Public License for more details.
15 : : *
16 : : * You should have received a copy of the GNU Lesser General
17 : : * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 : : */
19 : :
20 : : #include "config.h"
21 : :
22 : : #include <stdlib.h>
23 : : #include <string.h>
24 : : #include <sys/stat.h>
25 : : #include <fcntl.h>
26 : :
27 : : #include <glib-object.h>
28 : : #include <glib/gprintf.h>
29 : :
30 : :
31 : : static gchar *indent_inc = NULL;
32 : : static guint spacing = 1;
33 : : static FILE *f_out = NULL;
34 : : static GType root = 0;
35 : : static gboolean recursion = TRUE;
36 : :
37 : : #define O_SPACE " "
38 : : #define O_ESPACE ""
39 : : #define O_BRANCH "├"
40 : : #define O_VLINE "│"
41 : : #define O_LLEAF "└"
42 : : #define O_KEY_FILL "_"
43 : :
44 : : static void
45 : 48 : show_nodes (GType type,
46 : : GType sibling,
47 : : const gchar *indent)
48 : : {
49 : : GType *children;
50 : : size_t i;
51 : :
52 : 48 : if (!type)
53 : 0 : return;
54 : :
55 : 48 : children = g_type_children (type, NULL);
56 : :
57 : 54 : g_fprintf (f_out, "%s%s%s%s",
58 : : indent,
59 : 6 : sibling ? O_BRANCH : (type != root ? O_LLEAF : O_SPACE),
60 : : O_ESPACE,
61 : : g_type_name (type));
62 : :
63 : 48 : for (i = strlen (g_type_name (type)); i <= strlen (indent_inc); i++)
64 : 0 : fputs (O_KEY_FILL, f_out);
65 : :
66 : 48 : fputc ('\n', f_out);
67 : :
68 : 48 : if (children && recursion)
69 : : {
70 : : gchar *new_indent;
71 : : GType *child;
72 : :
73 : 48 : if (sibling)
74 : 42 : new_indent = g_strconcat (indent, O_VLINE, indent_inc, NULL);
75 : : else
76 : 6 : new_indent = g_strconcat (indent, O_SPACE, indent_inc, NULL);
77 : :
78 : 74 : for (child = children; *child; child++)
79 : 26 : show_nodes (child[0], child[1], new_indent);
80 : :
81 : 48 : g_free (new_indent);
82 : : }
83 : :
84 : 48 : g_free (children);
85 : : }
86 : :
87 : : static gint
88 : 1 : help (const gchar *arg)
89 : : {
90 : 1 : g_fprintf (stdout, "usage: gobject-query <qualifier> [-r <type>] [-{i|b} \"\"] [-s #] [-{h|x|y}]\n");
91 : 1 : g_fprintf (stdout, " -r specify root type\n");
92 : 1 : g_fprintf (stdout, " -n don't descend type tree\n");
93 : 1 : g_fprintf (stdout, " -h show help\n");
94 : 1 : g_fprintf (stdout, " -b specify indent string\n");
95 : 1 : g_fprintf (stdout, " -i specify incremental indent string\n");
96 : 1 : g_fprintf (stdout, " -s specify line spacing\n");
97 : 1 : g_fprintf (stdout, "qualifiers:\n");
98 : 1 : g_fprintf (stdout, " froots iterate over fundamental roots\n");
99 : 1 : g_fprintf (stdout, " tree print type tree\n");
100 : :
101 : 1 : return arg != NULL;
102 : : }
103 : :
104 : : int
105 : 4 : main (gint argc,
106 : : gchar *argv[])
107 : : {
108 : : GLogLevelFlags fatal_mask;
109 : 4 : gboolean gen_froots = 0;
110 : 4 : gboolean gen_tree = 0;
111 : : gint i;
112 : 4 : const gchar *iindent = "";
113 : :
114 : 4 : f_out = stdout;
115 : :
116 : 4 : fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
117 : 4 : fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
118 : 4 : g_log_set_always_fatal (fatal_mask);
119 : :
120 : 4 : root = G_TYPE_OBJECT;
121 : :
122 : 6 : for (i = 1; i < argc; i++)
123 : : {
124 : 4 : if (strcmp ("-s", argv[i]) == 0)
125 : : {
126 : 0 : i++;
127 : 0 : if (i < argc)
128 : 0 : spacing = atoi (argv[i]);
129 : : }
130 : 4 : else if (strcmp ("-i", argv[i]) == 0)
131 : : {
132 : 0 : i++;
133 : 0 : if (i < argc)
134 : : {
135 : : char *p;
136 : : guint n;
137 : :
138 : 0 : p = argv[i];
139 : 0 : while (*p)
140 : 0 : p++;
141 : 0 : n = p - argv[i];
142 : 0 : indent_inc = g_new (gchar, n * strlen (O_SPACE) + 1);
143 : 0 : *indent_inc = 0;
144 : 0 : while (n)
145 : : {
146 : 0 : n--;
147 : 0 : strcpy (indent_inc, O_SPACE);
148 : : }
149 : : }
150 : : }
151 : 4 : else if (strcmp ("-b", argv[i]) == 0)
152 : : {
153 : 0 : i++;
154 : 0 : if (i < argc)
155 : 0 : iindent = argv[i];
156 : : }
157 : 4 : else if (strcmp ("-r", argv[i]) == 0)
158 : : {
159 : 0 : i++;
160 : 0 : if (i < argc)
161 : 0 : root = g_type_from_name (argv[i]);
162 : : }
163 : 4 : else if (strcmp ("-n", argv[i]) == 0)
164 : : {
165 : 0 : recursion = FALSE;
166 : : }
167 : 4 : else if (strcmp ("froots", argv[i]) == 0)
168 : : {
169 : 1 : gen_froots = 1;
170 : : }
171 : 3 : else if (strcmp ("tree", argv[i]) == 0)
172 : : {
173 : 1 : gen_tree = 1;
174 : : }
175 : 2 : else if (strcmp ("--version", argv[i]) == 0)
176 : : {
177 : 1 : g_print (PACKAGE_VERSION "\n");
178 : 1 : return 0;
179 : : }
180 : 1 : else if (strcmp ("-h", argv[i]) == 0 ||
181 : 1 : strcmp ("--help", argv[i]) == 0)
182 : : {
183 : 1 : return help (NULL);
184 : : }
185 : : else
186 : 0 : return help (argv[i]);
187 : : }
188 : :
189 : 2 : if (!gen_froots && !gen_tree)
190 : 0 : return help ((argc > 0) ? argv[i-1] : NULL);
191 : :
192 : 2 : if (!indent_inc)
193 : : {
194 : 2 : indent_inc = g_new (gchar, strlen (O_SPACE) + 1);
195 : 2 : *indent_inc = 0;
196 : 2 : strcpy (indent_inc, O_SPACE);
197 : : }
198 : :
199 : 2 : if (gen_tree)
200 : 1 : show_nodes (root, 0, iindent);
201 : 2 : if (gen_froots)
202 : : {
203 : 1 : root = ~0;
204 : 257 : for (i = 0; i <= G_TYPE_FUNDAMENTAL_MAX; i += G_TYPE_MAKE_FUNDAMENTAL (1))
205 : : {
206 : 256 : const gchar *name = g_type_name (i);
207 : 256 : GType sibling = i + G_TYPE_MAKE_FUNDAMENTAL (1);
208 : :
209 : 256 : if (sibling > G_TYPE_FUNDAMENTAL_MAX || g_type_name (sibling) == NULL)
210 : 235 : sibling = 0;
211 : :
212 : 256 : if (name)
213 : 21 : show_nodes (i, sibling, iindent);
214 : : }
215 : : }
216 : :
217 : 2 : return 0;
218 : : }
|