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