示例#1
0
/**
 * parser_cxx_assist_create_member_completion_cache
 * @assist: self
 * @cursor: Current cursor position
 * 
 * Create the completion_cache for member completion if possible
 *
 * Returns: the iter where a completion cache was build, NULL otherwise
 */
static IAnjutaIterable*
parser_cxx_assist_create_member_completion_cache (ParserCxxAssist* assist,
                                                  IAnjutaIterable* cursor)
{
	IAnjutaIterable* symbol = NULL;
	IAnjutaIterable* start_iter = NULL;
	symbol = parser_cxx_assist_parse_expression (assist, cursor, &start_iter);

	if (symbol)
	{
		/* Query symbol children */
		IAnjutaIterable *children = 
			ianjuta_symbol_query_search_members (assist->priv->query_members,
			                                    IANJUTA_SYMBOL(symbol),
			                                    NULL);
			                                    
		g_object_unref (symbol);
		if (children)
		{
			parser_cxx_assist_add_completions_from_symbols (assist, children);

			parser_cxx_assist_populate_real (assist, TRUE);
			g_object_unref (children);
			return start_iter;
		}
	}
	else if (start_iter)
		g_object_unref (start_iter);
	return NULL;
}
示例#2
0
/**
 * parser_cxx_assist_create_calltips:
 * @iter: List of symbols
 * @merge: list of calltips to merge or NULL
 *
 * Create a list of Calltips (string) from a list of symbols
 *
 * A newly allocated GList* with newly allocated strings
 */
static GList*
parser_cxx_assist_create_calltips (IAnjutaIterable* iter, GList* merge)
{
	GList* tips = merge;
	if (iter)
	{
		do
		{
			IAnjutaSymbol* symbol = IANJUTA_SYMBOL (iter);
			const gchar* name = ianjuta_symbol_get_string (
			                            symbol,IANJUTA_SYMBOL_FIELD_NAME, NULL);
			if (name != NULL)
			{
				const gchar* args = ianjuta_symbol_get_string (
				                                symbol,
				                                IANJUTA_SYMBOL_FIELD_SIGNATURE,
				                                NULL);
				const gchar* rettype = ianjuta_symbol_get_string (
				                               symbol,
				                               IANJUTA_SYMBOL_FIELD_RETURNTYPE,
				                               NULL);
				gchar* print_args;
				gchar* separator;
				gchar* white_name;
				gint white_count = 0;

				if (!rettype)
					rettype = "";
				else
					white_count += strlen(rettype) + 1;
				
				white_count += strlen(name) + 1;
				
				white_name = g_strnfill (white_count, ' ');
				separator = g_strjoin (NULL, ", \n", white_name, NULL);
				gchar** argv;
				if (!args)
					args = "()";
				
				argv = g_strsplit (args, ",", -1);
				print_args = g_strjoinv (separator, argv);
				gchar* tip = g_strdup_printf ("%s %s %s", rettype, name,
				                              print_args);
				
				if (!g_list_find_custom (tips, tip, (GCompareFunc) strcmp))
					tips = g_list_append (tips, tip);
				
				g_strfreev (argv);
				g_free (print_args);
				g_free (separator);
				g_free (white_name);
			}
			else
				break;
		}
		while (ianjuta_iterable_next (iter, NULL));
	}
	return tips;
}
示例#3
0
文件: plugin.c 项目: VujinovM/anjuta
static gboolean
glade_widget_already_in_scope (IAnjutaEditor* editor, gchar* widget_name,
                               gchar* mark, CppJavaPlugin* lang_plugin)
{
       gboolean ret = FALSE;
       IAnjutaIterable *mark_position;
       IAnjutaSymbolQuery *query_scope;
       IAnjutaIterable *scope;
       IAnjutaSymbolQuery *query_members;
       mark_position = language_support_get_mark_position (editor, mark);

       if (!mark_position)
              return FALSE;

       int line = ianjuta_editor_get_line_from_position (editor, mark_position, NULL);
       g_object_unref(mark_position);


       IAnjutaSymbolManager *symbol_manager =
              anjuta_shell_get_interface (ANJUTA_PLUGIN (lang_plugin)->shell, IAnjutaSymbolManager, NULL);

       query_scope = ianjuta_symbol_manager_create_query (symbol_manager,
                                                          IANJUTA_SYMBOL_QUERY_SEARCH_SCOPE,
                                                          IANJUTA_SYMBOL_QUERY_DB_PROJECT, NULL);
       if (!query_scope)
              return FALSE;

       GFile *file = ianjuta_file_get_file (IANJUTA_FILE(editor), NULL);
       gchar* path = g_file_get_path (file);

       scope = ianjuta_symbol_query_search_scope (query_scope, path, line, NULL);
       g_object_unref(query_scope);

       if (!scope)
              return FALSE;

       query_members = ianjuta_symbol_manager_create_query (symbol_manager,
                                                            IANJUTA_SYMBOL_QUERY_SEARCH_MEMBERS,
                                                            IANJUTA_SYMBOL_QUERY_DB_PROJECT,
                                                            NULL);

       if (query_members)
       {
              IAnjutaIterable *members = ianjuta_symbol_query_search_members (
                                                   query_members,
                                                   IANJUTA_SYMBOL(scope), NULL);
              g_object_unref(query_members);

              if (members)
              {
                     ret = glade_widget_member_of_scope (widget_name, members);
                     g_object_unref(members);
              }
       }

       g_object_unref(scope);

       return ret;
}
示例#4
0
static void
update_type_list (AnjutaShell *shell, IAnjutaIterable *iter, const gchar *name)
{
	gchar *list = NULL;
	GValue value = {0,};
	
	if (iter)
	{
		ianjuta_iterable_first (iter, NULL);
		if (ianjuta_iterable_get_length (iter, NULL) > 0)
		{
			GString *s = g_string_sized_new(ianjuta_iterable_get_length (iter, NULL) * 10);
			do {
				IAnjutaSymbol *symbol = IANJUTA_SYMBOL (iter);
				const gchar *sname = ianjuta_symbol_get_string (symbol, IANJUTA_SYMBOL_FIELD_NAME, NULL);
				g_string_append(s, sname);
				g_string_append_c(s, ' ');
			} while (ianjuta_iterable_next (iter, NULL));
			list =  g_string_free(s, FALSE);
		}
	}
	
	anjuta_shell_get_value (shell, name, &value, NULL);
	if (G_VALUE_HOLDS_STRING(&value))
	{
		const gchar *value_list = g_value_get_string (&value);
		
		if (list == NULL)
		{
			anjuta_shell_remove_value (shell, name, NULL);
		}
		else if (strcmp (list, value_list) == 0)
		{
			g_free (list);
		}
		else
		{
			g_value_take_string (&value, list);
			anjuta_shell_add_value (shell, name, &value, NULL);
		}
	}
	else
	{
		if (list != NULL)
		{
			g_value_init (&value, G_TYPE_STRING);
			g_value_take_string (&value, list);
			anjuta_shell_add_value (shell, name, &value, NULL);
		}
	}
	if (G_IS_VALUE (&value))
		g_value_unset (&value);
}
示例#5
0
文件: plugin.c 项目: VujinovM/anjuta
static gboolean
glade_widget_member_of_scope (gchar *widget_name, IAnjutaIterable *members)
{
       do {
              IAnjutaSymbol *symbol = IANJUTA_SYMBOL (members);
              gchar *member_name = ianjuta_symbol_get_string (symbol, IANJUTA_SYMBOL_FIELD_NAME, NULL);
              /* Checks if member already exists... */
              if (g_strcmp0 (member_name, widget_name) == 0) {
                     return TRUE;
              }
       } while (ianjuta_iterable_next (members, NULL));

       return FALSE;
}
示例#6
0
/**
 * parser_cxx_assist_add_completions_from_symbols:
 * @assist: self
 * @symbols: Symbol iteration
 *
 * Add completions to the completions cache from @symbols.
 *
 */
static void
parser_cxx_assist_add_completions_from_symbols (ParserCxxAssist* assist,
                                                IAnjutaIterable* symbols)
{
	if (!symbols)
		return;
	do
	{
		IAnjutaSymbol* symbol = IANJUTA_SYMBOL (symbols);
		IAnjutaEditorAssistProposal* proposal = parser_cxx_assist_proposal_new (symbol);	

		anjuta_completion_add_item (assist->priv->completion_cache, proposal);
	}
	while (ianjuta_iterable_next (symbols, NULL));
}
示例#7
0
文件: plugin.c 项目: VujinovM/anjuta
static void
on_glade_drop (IAnjutaEditor* editor,
               IAnjutaIterable* iterator,
               const gchar* signal_data,
               CppJavaPlugin* lang_plugin)
{
    GStrv split_signal_data = g_strsplit(signal_data, ":", 5);
    char *handler = split_signal_data[2];
    /**
     * Split signal data format:
     * widget = split_signaldata[0];
     * signal = split_signaldata[1];
     * handler = split_signaldata[2];
     * user_data = split_signaldata[3];
     * swapped = g_str_equal (split_signaldata[4], "1");
     */

    IAnjutaIterable *iter;
    iter = language_support_find_symbol (lang_plugin,
                                         IANJUTA_EDITOR (editor),
                                         handler);
    if (iter == NULL)
    {
        GFile *file = ianjuta_file_get_file (IANJUTA_FILE (editor), NULL);
        CppFileType filetype = get_filetype (file);
        language_support_add_c_callback (lang_plugin, editor, iterator, split_signal_data, filetype);
    } else {
        /* Symbol found, going there */
        ianjuta_editor_goto_line (editor, ianjuta_symbol_get_int (
                                                            IANJUTA_SYMBOL (iter),
                                                            IANJUTA_SYMBOL_FIELD_FILE_POS,
                                                            NULL), NULL);
        g_object_unref (iter);
    }
    g_strfreev (split_signal_data);
}
示例#8
0
IAnjutaSymbol*
isymbol_manager_get_symbol_by_id (IAnjutaSymbolManager *sm,
								  gint symbol_id, 
								  IAnjutaSymbolField info_fields,
								  GError **err)
{
	SymbolDBEngineIteratorNode *node;
	SymbolDBPlugin *sdb_plugin;
	SymbolDBEngine *dbe;
	SymbolDBEngineIterator *iterator;

	g_return_val_if_fail (symbol_id > 0, NULL);
	sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (sm);
	dbe = SYMBOL_DB_ENGINE (sdb_plugin->sdbe_project);

	iterator = symbol_db_engine_get_symbol_info_by_id (dbe, symbol_id, 
													   info_fields);	
	
	if (iterator == NULL)
		return NULL;
	
	node = SYMBOL_DB_ENGINE_ITERATOR_NODE (iterator);
	return IANJUTA_SYMBOL (node);
}
示例#9
0
static void
on_cls_inherit_update (IAnjutaSymbolQuery *query, IAnjutaIterable *iter,
                       AnjutaClassInheritance *plugin)
{
	IAnjutaSymbol *symbol;
	ClsNode *cls_node;
	GError *err = NULL;
	
	/* Mark all nodes for deletion. Selectively, they will be unmarked below */
	g_hash_table_foreach (plugin->nodes,
	                      (GHFunc) on_cls_node_mark_for_deletion,
	                      NULL);
	if (!iter)
	{
		DEBUG_PRINT ("%s", "cls_inherit_update_graph (): search returned no items.");
		goto cleanup;
	}
	
	ianjuta_iterable_first (iter, NULL);
	if (ianjuta_iterable_get_length (iter, NULL) <= 0)
	{
		g_object_unref (iter);
		goto cleanup;
	}
	do 
	{
		gint klass_id;
		IAnjutaIterable *parents;
     
		/* a symbol representing a class */
		symbol = IANJUTA_SYMBOL (iter);

		/* get parents of the current class */
		parents =
			ianjuta_symbol_query_search_class_parents (plugin->query_parents,
			                                           symbol, &err);

		if (err)
		{
			g_warning ("Class parents query failed: %s", err->message);
			g_error_free (err);
			err = NULL;
		}
		/* if no parents are found then continue */
		if (parents == NULL || ianjuta_iterable_get_length (parents, NULL) <= 0)
		{
			/*DEBUG_PRINT ("ClassInheritance: no parents found for class %s",
						 ianjuta_symbol_get_name (symbol, NULL));*/
			continue;
		}

		if ((klass_id = ianjuta_symbol_get_int (symbol,
		                                        IANJUTA_SYMBOL_FIELD_ID,
		                                        NULL)) <= 0)
		{
			/*DEBUG_PRINT ("%s", "ClassInheritance: klass_id cannot be <= 0");*/
			continue;
		}
		
		cls_node = g_hash_table_lookup (plugin->nodes, GINT_TO_POINTER (klass_id));
		if (!cls_node)
		{
			cls_node = cls_inherit_create_node (plugin, symbol);
			g_hash_table_insert (plugin->nodes, GINT_TO_POINTER (klass_id), cls_node);
		}
		cls_node->marked_for_deletion = FALSE;

		/* Get parents */
		do 
		{
			gint parent_id;
			ClsNode *parent_node;
			IAnjutaSymbol *parent_symbol;
			parent_symbol = IANJUTA_SYMBOL (parents);
			parent_id = ianjuta_symbol_get_int (parent_symbol,
			                                    IANJUTA_SYMBOL_FIELD_ID,
			                                    NULL);
			
			parent_node = g_hash_table_lookup (plugin->nodes,
			                                   GINT_TO_POINTER (parent_id));
			if (!parent_node)
			{
				parent_node = cls_inherit_create_node (plugin, parent_symbol);
				g_hash_table_insert (plugin->nodes, GINT_TO_POINTER (parent_id),
				                     parent_node);
			}
			parent_node->marked_for_deletion = FALSE;
			cls_node_add_edge (parent_node, cls_node);
		} while (ianjuta_iterable_next (parents, NULL) == TRUE);
		g_object_unref (parents);

	} while (ianjuta_iterable_next (iter, NULL) == TRUE);

cleanup:
	
	/* Delete all marked nodes that did not get unmarked above. */
	g_hash_table_foreach_remove (plugin->nodes,
	                             (GHRFunc) on_cls_node_delete_marked,
	                             NULL);

	cls_inherit_draw (plugin);
}
示例#10
0
gboolean
cls_node_expand (ClsNode *cls_node, ClsNodeExpansionType expansion_type)
{
	Agsym_t *sym;
	GString *label;
	gint max_label_items = 0;
	gint real_items_length = 0;
	gint var_order = -1000;
	gint method_order = 0;
	IAnjutaSymbol *node_sym;
	IAnjutaIterable *iter;
	GError *err = NULL;
	
	if (cls_node->expansion_status == expansion_type ||
	    expansion_type == CLS_NODE_COLLAPSED)
		return FALSE;

	node_sym =
		IANJUTA_SYMBOL (ianjuta_symbol_query_search_id (cls_node->plugin->query_id,
		                                                cls_node->klass_id,
		                                                &err));
	if (err)
	{
		g_warning ("Symbol ID query failed: %s", err->message);
		g_error_free (err);
		err = NULL;
	}
	if (!node_sym)
		return FALSE;
	
	if (!(sym = agfindattr(cls_node->graph->proto->n, "shape")))
		sym = agnodeattr(cls_node->graph, "shape", "");
	agxset (cls_node->agnode, sym->index, "record");
	
	if (!(sym = agfindattr(cls_node->graph->proto->n, "label")))
		sym = agnodeattr(cls_node->graph, "label", "");
	
	label = g_string_new ("");
	g_string_printf (label, "{%s", cls_node->sym_name);
	
	/* get members from the passed symbol node */
	iter = ianjuta_symbol_query_search_members (cls_node->plugin->query_members,
	                                            node_sym, &err);
	if (err)
	{
		g_warning ("Class members query failed: %s", err->message);
		g_error_free (err);
		err = NULL;
	}

	real_items_length = ianjuta_iterable_get_length (iter, NULL);
	
	/* set the max number of items to draw */
	if (real_items_length <= NODE_HALF_DISPLAY_ELEM_NUM || 
	    expansion_type == CLS_NODE_FULL_EXPANDED) 
	{
		max_label_items = real_items_length;
		cls_node->expansion_status = CLS_NODE_FULL_EXPANDED;
	}
	else
	{
		max_label_items = NODE_HALF_DISPLAY_ELEM_NUM;
		cls_node->expansion_status = CLS_NODE_SEMI_EXPANDED;
	}

	g_hash_table_remove_all (cls_node->members);
	if (iter && real_items_length > 0)
	{
		gint i = 0;

		/* First member variables */
		do
		{
			const gchar *name, *args, *type_name;
			IAnjutaSymbol *symbol;
			GdkPixbuf *icon;
			
			symbol = IANJUTA_SYMBOL (iter);
			name = g_strdup (ianjuta_symbol_get_string (symbol,
			                                            IANJUTA_SYMBOL_FIELD_NAME,
			                                            NULL));
			args = ianjuta_symbol_get_string (symbol,
			                                  IANJUTA_SYMBOL_FIELD_SIGNATURE,
			                                  NULL);
			icon = (GdkPixbuf*) ianjuta_symbol_get_icon (symbol, NULL);
			
			if (!args) /* Member variables */
			{
				ClsNodeItem *cls_item = g_new0 (ClsNodeItem, 1);

				type_name = ianjuta_symbol_get_string (symbol, IANJUTA_SYMBOL_FIELD_TYPE_NAME, NULL);
				cls_item->cls_node = cls_node;
				cls_item->label = g_strconcat (name, " : ", type_name, NULL);
				cls_item->order = var_order++;
				if (icon)
					g_object_ref (icon);
				cls_item->icon = icon;
				
				g_hash_table_insert (cls_node->members,
				                     g_strdup (cls_item->label),
				                     cls_item);
				g_string_append_printf (label, "|%s", cls_item->label);

				/* Setup file and line */
				cls_item->type_name = g_strdup (type_name);
				cls_item->line = ianjuta_symbol_get_int (symbol,
				                                         IANJUTA_SYMBOL_FIELD_FILE_POS,
				                                         NULL);
				cls_item->file = ianjuta_symbol_get_file (symbol, NULL);
			}
			else /* Member methods */
			{
				ClsNodeItem *cls_item;
				gchar *method_key = g_strconcat (name, args, NULL);
				cls_item = g_hash_table_lookup (cls_node->members, method_key);

				if (cls_item) /* We found an entry for this method */
				{
					IAnjutaSymbolType sym_type
						= ianjuta_symbol_get_sym_type (symbol, NULL);
					if (!(sym_type & IANJUTA_SYMBOL_TYPE_PROTOTYPE))
					{
						/* This one is method, so take this one instead */
						g_free (cls_item->args);
						cls_item->args = g_strdup (args);

						if (cls_item->file) g_object_unref (cls_item->file);
						cls_item->file = NULL;

						/* Setup file and line */
						cls_item->line = ianjuta_symbol_get_int (symbol,
						                                         IANJUTA_SYMBOL_FIELD_FILE_POS,
						                                         NULL);
						cls_item->file = ianjuta_symbol_get_file (symbol, NULL);
					}
				}
				else /* We did not find a member entry, create a new one */
				{
					ClsNodeItem *cls_item = g_new0 (ClsNodeItem, 1);
					type_name = ianjuta_symbol_get_string (symbol,
					                                       IANJUTA_SYMBOL_FIELD_RETURNTYPE,
					                                       NULL);

					cls_item->cls_node = cls_node;
					if (type_name)
					{
						if (strlen (args) > 2)
							cls_item->label = g_strconcat (name, "(...)",
							                               " : ", type_name,
							                               NULL);
						else
							cls_item->label = g_strconcat (name, "()", " : ",
							                               type_name, NULL);
					}
					else
					{
						if (strlen (args) > 2)
							cls_item->label = g_strconcat (name, "(...)", NULL);
						else
							cls_item->label = g_strconcat (name, "()", NULL);
					}
					cls_item->args = g_strdup (args);
					cls_item->type_name = g_strdup (type_name);
					cls_item->order = method_order++;
					if (icon)
						g_object_ref (icon);
					cls_item->icon = icon;
					
					g_string_append_printf (label, "|%s", cls_item->label);
					g_hash_table_insert (cls_node->members, method_key,
					                     cls_item);
					
					/* Setup file and line */
					cls_item->line = ianjuta_symbol_get_int (symbol,
					                                         IANJUTA_SYMBOL_FIELD_FILE_POS,
					                                         NULL);
					cls_item->file = ianjuta_symbol_get_file (symbol, NULL);
				}
			}
			i++;
		}
		while (ianjuta_iterable_next (iter, NULL) && i < max_label_items);
	}
	if (iter)
		g_object_unref (iter);
	
	if (cls_node->expansion_status == CLS_NODE_SEMI_EXPANDED &&
	    real_items_length > NODE_HALF_DISPLAY_ELEM_NUM)
	{
		g_string_append_printf (label, "|%s", NODE_SHOW_ALL_MEMBERS_STR);
	}
	
	g_string_append_printf (label, "}");
	agxset(cls_node->agnode, sym->index, label->str);
	
	/* set the margin for icons */
	if (!(sym = agfindattr(cls_node->graph->proto->n, "margin")))
		sym = agnodeattr(cls_node->graph, "margin", "0.11,0.055");
	agxset(cls_node->agnode, sym->index, "0.3,0.03");

	g_string_free (label, TRUE);

	return TRUE;
}
示例#11
0
/*----------------------------------------------------------------------------
 * add a node to an Agraph. Check also if the node is yet in the hash_table so 
 * that we can build the label of the node with the class-data.
 */
static ClsNode*
cls_inherit_create_node (AnjutaClassInheritance *plugin,
                         const IAnjutaSymbol *node_sym)
{
	ClsNode *cls_node;
	Agsym_t *sym;
	gint font_size;
	const gchar *font_name;
	
#define FONT_SIZE_STR_LEN 16
	gchar font_size_str[FONT_SIZE_STR_LEN];

	cls_node = g_new0 (ClsNode, 1);
	cls_node->graph = plugin->graph;
	cls_node->canvas = plugin->canvas;
	cls_node->plugin = plugin;
	cls_node->sym_manager =
			anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin)->shell,
			                            IAnjutaSymbolManager, NULL);

	cls_node->sym_name =
		g_strdup (ianjuta_symbol_get_string (IANJUTA_SYMBOL (node_sym),
		                                     IANJUTA_SYMBOL_FIELD_NAME,
		                                     NULL));
	cls_node->klass_id =
		ianjuta_symbol_get_int (IANJUTA_SYMBOL (node_sym),
		                        IANJUTA_SYMBOL_FIELD_ID,
		                        NULL);
	cls_node->members =
		g_hash_table_new_full (g_str_hash, g_str_equal,
		                       (GDestroyNotify) g_free,
		                       (GDestroyNotify) cls_node_item_free);
	cls_node->expansion_status = CLS_NODE_COLLAPSED;
	cls_node->drawn_expansion_status = CLS_NODE_COLLAPSED;
	cls_node->edges_to =
		g_hash_table_new_full (g_direct_hash, g_direct_equal,
		                       NULL, (GDestroyNotify)cls_node_edge_free);
	cls_node->edges_from = g_hash_table_new (g_direct_hash, g_direct_equal);
	
	/* let's add the node to the graph */
	if ((cls_node->agnode = agnode (cls_node->graph,
	                                cls_node->sym_name)) == NULL)
	{
		cls_node_free (cls_node);
		return NULL;
	}
	
	/* set the font */
	if (!(sym = agfindattr(plugin->graph->proto->n, "fontname")))
		sym = agnodeattr(plugin->graph, "fontname", "");
	font_name =
		pango_font_description_get_family (plugin->canvas->style->font_desc);
	agxset(cls_node->agnode, sym->index, (char*)font_name);

	/* set the font-size */	
	if (!(sym = agfindattr(plugin->graph->proto->n, "fontsize")))
		sym = agnodeattr(plugin->graph, "fontsize", "");

	font_size =
		pango_font_description_get_size (plugin->canvas->style->font_desc)/
			PANGO_SCALE;

	/* The above font size in points is with real screen DPI, but graphviz
	 * rendering is done at fixed INCH_TO_PIXELS_CONVERSION_FACTOR dpi. So
	 * convert to the right font size points for graphviz.
	 */
	font_size =
		font_size * gdk_screen_get_resolution (gdk_screen_get_default ())
					/ INCH_TO_PIXELS_CONVERSION_FACTOR;
	
	snprintf (font_size_str, FONT_SIZE_STR_LEN, "%d", font_size);
	agxset(cls_node->agnode, sym->index, font_size_str);

	if (!(sym = agfindattr(plugin->graph->proto->n, "ratio")))
		sym = agnodeattr(plugin->graph, "ratio", "");
	agxset(cls_node->agnode, sym->index, "expand");	

	/* Set an attribute - in this case one that affects the visible rendering */
	if (!(sym = agfindattr(plugin->graph->proto->n, "shape")))
		sym = agnodeattr(plugin->graph, "shape", "");
	agxset(cls_node->agnode, sym->index, "box");
	
	if (!(sym = agfindattr(plugin->graph->proto->n, "label")))
		sym = agnodeattr(plugin->graph, "label", "");
	agxset(cls_node->agnode, sym->index, cls_node->sym_name);

	return cls_node;
}