(root)/
glib-2.79.0/
gobject/
gobject-query.c
       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  show_nodes (GType        type,
      46  	    GType        sibling,
      47  	    const gchar *indent)
      48  {
      49    GType   *children;
      50    guint i;
      51    
      52    if (!type)
      53      return;
      54    
      55    children = g_type_children (type, NULL);
      56    
      57    g_fprintf (f_out, "%s%s%s%s",
      58  	   indent,
      59  	   sibling ? O_BRANCH : (type != root ? O_LLEAF : O_SPACE),
      60  	   O_ESPACE,
      61  	   g_type_name (type));
      62    
      63    for (i = strlen (g_type_name (type)); i <= strlen (indent_inc); i++)
      64      fputs (O_KEY_FILL, f_out);
      65    
      66    fputc ('\n', f_out);
      67    
      68    if (children && recursion)
      69      {
      70        gchar *new_indent;
      71        GType   *child;
      72        
      73        if (sibling)
      74  	new_indent = g_strconcat (indent, O_VLINE, indent_inc, NULL);
      75        else
      76  	new_indent = g_strconcat (indent, O_SPACE, indent_inc, NULL);
      77        
      78        for (child = children; *child; child++)
      79  	show_nodes (child[0], child[1], new_indent);
      80        
      81        g_free (new_indent);
      82      }
      83    
      84    g_free (children);
      85  }
      86  
      87  static gint
      88  help (const gchar *arg)
      89  {
      90    g_fprintf (stdout, "usage: gobject-query <qualifier> [-r <type>] [-{i|b} \"\"] [-s #] [-{h|x|y}]\n");
      91    g_fprintf (stdout, "       -r       specify root type\n");
      92    g_fprintf (stdout, "       -n       don't descend type tree\n");
      93    g_fprintf (stdout, "       -h       show help\n");
      94    g_fprintf (stdout, "       -b       specify indent string\n");
      95    g_fprintf (stdout, "       -i       specify incremental indent string\n");
      96    g_fprintf (stdout, "       -s       specify line spacing\n");
      97    g_fprintf (stdout, "qualifiers:\n");
      98    g_fprintf (stdout, "       froots   iterate over fundamental roots\n");
      99    g_fprintf (stdout, "       tree     print type tree\n");
     100    
     101    return arg != NULL;
     102  }
     103  
     104  int
     105  main (gint   argc,
     106        gchar *argv[])
     107  {
     108    GLogLevelFlags fatal_mask;
     109    gboolean gen_froots = 0;
     110    gboolean gen_tree = 0;
     111    gint i;
     112    const gchar *iindent = "";
     113  
     114    f_out = stdout;
     115    
     116    fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
     117    fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
     118    g_log_set_always_fatal (fatal_mask);
     119    
     120    root = G_TYPE_OBJECT;
     121  
     122    for (i = 1; i < argc; i++)
     123      {
     124        if (strcmp ("-s", argv[i]) == 0)
     125  	{
     126  	  i++;
     127  	  if (i < argc)
     128  	    spacing = atoi (argv[i]);
     129  	}
     130        else if (strcmp ("-i", argv[i]) == 0)
     131  	{
     132  	  i++;
     133  	  if (i < argc)
     134  	    {
     135  	      char *p;
     136  	      guint n;
     137  	      
     138  	      p = argv[i];
     139  	      while (*p)
     140  		p++;
     141  	      n = p - argv[i];
     142  	      indent_inc = g_new (gchar, n * strlen (O_SPACE) + 1);
     143  	      *indent_inc = 0;
     144  	      while (n)
     145  		{
     146  		  n--;
     147  		  strcpy (indent_inc, O_SPACE);
     148  		}
     149  	    }
     150  	}
     151        else if (strcmp ("-b", argv[i]) == 0)
     152  	{
     153  	  i++;
     154  	  if (i < argc)
     155  	    iindent = argv[i];
     156  	}
     157        else if (strcmp ("-r", argv[i]) == 0)
     158  	{
     159  	  i++;
     160  	  if (i < argc)
     161  	    root = g_type_from_name (argv[i]);
     162  	}
     163        else if (strcmp ("-n", argv[i]) == 0)
     164  	{
     165  	  recursion = FALSE;
     166  	}
     167        else if (strcmp ("froots", argv[i]) == 0)
     168  	{
     169  	  gen_froots = 1;
     170  	}
     171        else if (strcmp ("tree", argv[i]) == 0)
     172  	{
     173  	  gen_tree = 1;
     174  	}
     175        else if (strcmp ("--version", argv[i]) == 0)
     176          {
     177            g_print (PACKAGE_VERSION "\n");
     178            return 0;
     179          }
     180        else if (strcmp ("-h", argv[i]) == 0 ||
     181                 strcmp ("--help", argv[i]) == 0)
     182  	{
     183  	  return help (NULL);
     184  	}
     185        else
     186  	return help (argv[i]);
     187      }
     188    
     189    if (!gen_froots && !gen_tree)
     190      return help ((argc > 0) ? argv[i-1] : NULL);
     191    
     192    if (!indent_inc)
     193      {
     194        indent_inc = g_new (gchar, strlen (O_SPACE) + 1);
     195        *indent_inc = 0;
     196        strcpy (indent_inc, O_SPACE);
     197      }
     198    
     199    if (gen_tree)
     200      show_nodes (root, 0, iindent);
     201    if (gen_froots)
     202      {
     203        root = ~0;
     204        for (i = 0; i <= G_TYPE_FUNDAMENTAL_MAX; i += G_TYPE_MAKE_FUNDAMENTAL (1))
     205  	{
     206  	  const gchar *name = g_type_name (i);
     207            GType sibling = i + G_TYPE_MAKE_FUNDAMENTAL (1);
     208  
     209            if (sibling > G_TYPE_FUNDAMENTAL_MAX || g_type_name (sibling) == NULL)
     210              sibling = 0;
     211  	  
     212  	  if (name)
     213  	    show_nodes (i, sibling, iindent);
     214  	}
     215      }
     216    
     217    return 0;
     218  }