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