/* GObject - GLib Type, Object, Parameter and Signal Library * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc. * * SPDX-License-Identifier: LGPL-2.1-or-later * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General * Public License along with this library; if not, see . */ #include "config.h" #include #include #include #include #include #include static gchar *indent_inc = NULL; static guint spacing = 1; static FILE *f_out = NULL; static GType root = 0; static gboolean recursion = TRUE; #define O_SPACE " " #define O_ESPACE "" #define O_BRANCH "├" #define O_VLINE "│" #define O_LLEAF "└" #define O_KEY_FILL "_" static void show_nodes (GType type, GType sibling, const gchar *indent) { GType *children; size_t i; if (!type) return; children = g_type_children (type, NULL); g_fprintf (f_out, "%s%s%s%s", indent, sibling ? O_BRANCH : (type != root ? O_LLEAF : O_SPACE), O_ESPACE, g_type_name (type)); for (i = strlen (g_type_name (type)); i <= strlen (indent_inc); i++) fputs (O_KEY_FILL, f_out); fputc ('\n', f_out); if (children && recursion) { gchar *new_indent; GType *child; if (sibling) new_indent = g_strconcat (indent, O_VLINE, indent_inc, NULL); else new_indent = g_strconcat (indent, O_SPACE, indent_inc, NULL); for (child = children; *child; child++) show_nodes (child[0], child[1], new_indent); g_free (new_indent); } g_free (children); } static gint help (const gchar *arg) { g_fprintf (stdout, "usage: gobject-query [-r ] [-{i|b} \"\"] [-s #] [-{h|x|y}]\n"); g_fprintf (stdout, " -r specify root type\n"); g_fprintf (stdout, " -n don't descend type tree\n"); g_fprintf (stdout, " -h show help\n"); g_fprintf (stdout, " -b specify indent string\n"); g_fprintf (stdout, " -i specify incremental indent string\n"); g_fprintf (stdout, " -s specify line spacing\n"); g_fprintf (stdout, "qualifiers:\n"); g_fprintf (stdout, " froots iterate over fundamental roots\n"); g_fprintf (stdout, " tree print type tree\n"); return arg != NULL; } int main (gint argc, gchar *argv[]) { GLogLevelFlags fatal_mask; gboolean gen_froots = 0; gboolean gen_tree = 0; gint i; const gchar *iindent = ""; f_out = stdout; fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK); fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL; g_log_set_always_fatal (fatal_mask); root = G_TYPE_OBJECT; for (i = 1; i < argc; i++) { if (strcmp ("-s", argv[i]) == 0) { i++; if (i < argc) spacing = atoi (argv[i]); } else if (strcmp ("-i", argv[i]) == 0) { i++; if (i < argc) { char *p; guint n; p = argv[i]; while (*p) p++; n = p - argv[i]; indent_inc = g_new (gchar, n * strlen (O_SPACE) + 1); *indent_inc = 0; while (n) { n--; strcpy (indent_inc, O_SPACE); } } } else if (strcmp ("-b", argv[i]) == 0) { i++; if (i < argc) iindent = argv[i]; } else if (strcmp ("-r", argv[i]) == 0) { i++; if (i < argc) root = g_type_from_name (argv[i]); } else if (strcmp ("-n", argv[i]) == 0) { recursion = FALSE; } else if (strcmp ("froots", argv[i]) == 0) { gen_froots = 1; } else if (strcmp ("tree", argv[i]) == 0) { gen_tree = 1; } else if (strcmp ("--version", argv[i]) == 0) { g_print (PACKAGE_VERSION "\n"); return 0; } else if (strcmp ("-h", argv[i]) == 0 || strcmp ("--help", argv[i]) == 0) { return help (NULL); } else return help (argv[i]); } if (!gen_froots && !gen_tree) return help ((argc > 0) ? argv[i-1] : NULL); if (!indent_inc) { indent_inc = g_new (gchar, strlen (O_SPACE) + 1); *indent_inc = 0; strcpy (indent_inc, O_SPACE); } if (gen_tree) show_nodes (root, 0, iindent); if (gen_froots) { root = ~0; for (i = 0; i <= G_TYPE_FUNDAMENTAL_MAX; i += G_TYPE_MAKE_FUNDAMENTAL (1)) { const gchar *name = g_type_name (i); GType sibling = i + G_TYPE_MAKE_FUNDAMENTAL (1); if (sibling > G_TYPE_FUNDAMENTAL_MAX || g_type_name (sibling) == NULL) sibling = 0; if (name) show_nodes (i, sibling, iindent); } } return 0; }