am-project: Expand variables in source names
[anjuta.git] / plugins / am-project / amp-group.c
blobe5b71ffc9dcd28a25d7b03418418cda44ffc8ffc
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
2 /* amp-group.c
4 * Copyright (C) 2010 Sébastien Granjoux
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
11 * This program 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 * General Public License for more details.
16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
27 #include "amp-group.h"
29 #include "amp-node.h"
30 #include "am-scanner.h"
31 #include "am-properties.h"
32 #include "am-writer.h"
35 #include <libanjuta/interfaces/ianjuta-project.h>
37 #include <libanjuta/anjuta-debug.h>
39 #include <glib/gi18n.h>
41 #include <memory.h>
42 #include <string.h>
43 #include <ctype.h>
46 /* Helper functions
47 *---------------------------------------------------------------------------*/
49 static void
50 error_set (GError **error, gint code, const gchar *message)
52 if (error != NULL) {
53 if (*error != NULL) {
54 gchar *tmp;
56 /* error already created, just change the code
57 * and prepend the string */
58 (*error)->code = code;
59 tmp = (*error)->message;
60 (*error)->message = g_strconcat (message, "\n\n", tmp, NULL);
61 g_free (tmp);
63 } else {
64 *error = g_error_new_literal (IANJUTA_PROJECT_ERROR,
65 code,
66 message);
71 /* Private functions
72 *---------------------------------------------------------------------------*/
74 /* Find if pkg-config modules are used in group targets */
75 static gboolean
76 project_load_group_module (AmpProject *project, AmpGroupNode *group)
78 AnjutaProjectNode *target;
79 AnjutaProjectProperty *prop;
80 gchar **group_cpp = NULL;
82 prop = amp_node_get_property_from_token (ANJUTA_PROJECT_NODE (group), AM_TOKEN__CPPFLAGS, 0);
83 if (prop && (prop->value != NULL)) group_cpp = g_strsplit_set (prop->value, " \t", 0);
85 /* Check all targets */
86 for (target = anjuta_project_node_first_child (ANJUTA_PROJECT_NODE (group)); target != NULL; target = anjuta_project_node_next_sibling (target))
88 gint type = anjuta_project_node_get_full_type (target) & (ANJUTA_PROJECT_ID_MASK | ANJUTA_PROJECT_TYPE_MASK);
89 gchar **target_lib = NULL;
90 gchar **target_cpp = NULL;
92 prop = NULL;
93 switch (type)
95 case ANJUTA_PROJECT_TARGET | ANJUTA_PROJECT_PROGRAM:
96 prop = amp_node_get_property_from_token (target, AM_TOKEN_TARGET_LDADD, 0);
97 break;
98 case ANJUTA_PROJECT_TARGET | ANJUTA_PROJECT_STATICLIB:
99 case ANJUTA_PROJECT_TARGET | ANJUTA_PROJECT_SHAREDLIB:
100 case ANJUTA_PROJECT_TARGET | ANJUTA_PROJECT_LT_MODULE:
101 prop = amp_node_get_property_from_token (target, AM_TOKEN_TARGET_LIBADD, 0);
102 break;
103 default:
104 break;
106 if (prop && (prop->value != NULL)) target_lib = g_strsplit_set (prop->value, " \t", 0);
108 /* Check if targets use libraries */
109 if (target_lib != NULL)
111 AnjutaProjectNode *module;
113 prop = amp_node_get_property_from_token (target, AM_TOKEN_TARGET_CPPFLAGS, 0);
114 if (prop && (prop->value != NULL)) target_cpp = g_strsplit_set (prop->value, " \t", 0);
116 for (module = anjuta_project_node_first_child (ANJUTA_PROJECT_NODE (project)); module != NULL; module = anjuta_project_node_next_sibling (module))
118 if (anjuta_project_node_get_node_type (module) == ANJUTA_PROJECT_MODULE)
120 const gchar *name = anjuta_project_node_get_name (module);
121 gchar *lib_flags = g_strconcat ("$(", name, "_LIBS)", NULL);
122 gchar **flags;
124 for (flags = target_lib; *flags != NULL; flags++)
127 if (strcmp (*flags, lib_flags) == 0)
129 gchar *cpp_flags = g_strconcat ("$(", name, "_CFLAGS)", NULL);
130 gchar **cflags;
131 gboolean found = FALSE;
133 if (group_cpp != NULL)
135 for (cflags = group_cpp; *cflags != NULL; cflags++)
137 if (strcmp (*cflags, cpp_flags) == 0)
139 found = TRUE;
140 break;
144 if ((target_cpp != NULL) && !found)
146 for (cflags = target_cpp; *cflags != NULL; cflags++)
148 if (strcmp (*cflags, cpp_flags) == 0)
150 found = TRUE;
151 break;
155 if (found)
157 /* Add new module */
158 AnjutaProjectNode *new_module;
160 new_module = amp_node_new_valid (target, ANJUTA_PROJECT_MODULE, NULL, name, NULL);
161 anjuta_project_node_append (target, new_module);
163 g_free (cpp_flags);
166 g_free (lib_flags);
169 g_strfreev (target_cpp);
170 g_strfreev (target_lib);
173 g_strfreev (group_cpp);
175 return TRUE;
179 extern const gchar *valid_am_makefiles[];
181 static AmpGroupNode*
182 project_load_makefile (AmpProject *project, AmpGroupNode *group)
184 const gchar **filename;
185 AnjutaTokenFile *tfile;
186 GFile *makefile = NULL;
187 GFile *file = anjuta_project_node_get_file ((AnjutaProjectNode *)group);
189 /* Find makefile name
190 * It has to be in the config_files list with .am extension */
191 for (filename = valid_am_makefiles; *filename != NULL; filename++)
193 makefile = g_file_get_child (file, *filename);
194 if (file_type (file, *filename) == G_FILE_TYPE_REGULAR)
196 gchar *final_filename = g_strdup (*filename);
197 gchar *ptr;
198 GFile *final_file;
199 AnjutaToken *token;
201 ptr = g_strrstr (final_filename,".am");
202 if (ptr != NULL) *ptr = '\0';
203 final_file = g_file_get_child (file, final_filename);
204 g_free (final_filename);
206 token = amp_project_get_config_token (project, final_file);
207 g_object_unref (final_file);
208 if (token != NULL)
210 amp_group_node_add_token (group, token, AM_GROUP_TOKEN_CONFIGURE);
211 break;
214 g_object_unref (makefile);
217 if (*filename == NULL)
219 /* Unable to find automake file */
220 return group;
223 /* Parse makefile.am */
224 DEBUG_PRINT ("Parse: %s", g_file_get_uri (makefile));
225 tfile = amp_group_node_set_makefile (group, makefile, project);
227 project_load_group_module (project, group);
229 return group;
233 /* Variable object
234 *---------------------------------------------------------------------------*/
236 AmpVariable*
237 amp_variable_new (gchar *name, AnjutaTokenType assign, AnjutaToken *value)
239 AmpVariable *variable = NULL;
241 g_return_val_if_fail (name != NULL, NULL);
243 variable = g_slice_new0(AmpVariable);
244 variable->name = g_strdup (name);
245 variable->assign = assign;
246 variable->value = value;
248 return variable;
251 static void
252 amp_variable_free (AmpVariable *variable)
254 g_free (variable->name);
256 g_slice_free (AmpVariable, variable);
261 /* Group objects
262 *---------------------------------------------------------------------------*/
265 void
266 amp_group_node_add_token (AmpGroupNode *group, AnjutaToken *token, AmpGroupNodeTokenCategory category)
268 if (token != NULL) group->tokens[category] = g_list_prepend (group->tokens[category], token);
271 void
272 amp_group_node_remove_token (AmpGroupNode *group, AnjutaToken *token)
274 gint i;
276 for (i = 0; i < AM_GROUP_TOKEN_LAST; i++)
278 group->tokens[i] = g_list_remove (group->tokens[i], token);
282 GList *
283 amp_group_node_get_token (AmpGroupNode *group, AmpGroupNodeTokenCategory category)
285 return group->tokens[category];
288 GList *
289 amp_group_node_get_all_token (AmpGroupNode *group)
291 gint i;
292 GList *tokens = NULL;
294 for (i = 0; i < AM_GROUP_TOKEN_LAST; i++)
296 tokens = g_list_concat (tokens, g_list_copy (group->tokens[i]));
299 return tokens;
302 AnjutaToken*
303 amp_group_node_get_first_token (AmpGroupNode *group, AmpGroupNodeTokenCategory category)
305 GList *list;
307 list = amp_group_node_get_token (group, category);
308 if (list == NULL) return NULL;
310 return (AnjutaToken *)list->data;
313 void
314 amp_group_node_set_dist_only (AmpGroupNode *group, gboolean dist_only)
316 group->dist_only = dist_only;
319 static void
320 on_group_monitor_changed (GFileMonitor *monitor,
321 GFile *file,
322 GFile *other_file,
323 GFileMonitorEvent event_type,
324 gpointer data)
326 AnjutaProjectNode *node = ANJUTA_PROJECT_NODE (data);
327 AnjutaProjectNode *root;
329 switch (event_type) {
330 case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
331 case G_FILE_MONITOR_EVENT_CHANGED:
332 case G_FILE_MONITOR_EVENT_DELETED:
333 /* project can be NULL, if the node is dummy node because the
334 * original one is reloaded. */
335 root = anjuta_project_node_root (node);
336 if (root != NULL) g_signal_emit_by_name (G_OBJECT (root), "file-changed", data);
337 break;
338 default:
339 break;
343 void
344 amp_group_node_update_preset_variable (AmpGroupNode *group)
346 gchar *path;
347 AnjutaToken *value;
348 AmpVariable *var;
349 GFile *root;
350 GFile *file;
351 AnjutaProjectNode *node;
353 if (group->preset_token != NULL) anjuta_token_free (group->preset_token);
354 group->preset_token = anjuta_token_new_static (ANJUTA_TOKEN_FILE, NULL);
356 /* Get project root */
357 for (node = ANJUTA_PROJECT_NODE (group); anjuta_project_node_parent (node) != NULL; node = anjuta_project_node_parent (node));
358 root = anjuta_project_node_get_file (node);
360 /* Set source directory variables */
361 file = anjuta_project_node_get_file (group);
362 value = anjuta_token_insert_token_list (FALSE, NULL,
363 ANJUTA_TOKEN_LIST, NULL,
364 ANJUTA_TOKEN_ARGUMENT, NULL,
365 ANJUTA_TOKEN_CONTENT, ".",
366 NULL);
367 anjuta_token_append_child (group->preset_token, value);
368 var = amp_variable_new ("srcdir", 0, value);
369 g_hash_table_insert (group->variables, var->name, var);
370 var = amp_variable_new ("builddir", 0, value);
371 g_hash_table_insert (group->variables, var->name, var);
373 path = g_file_get_path (file);
374 value = anjuta_token_insert_token_list (FALSE, NULL,
375 ANJUTA_TOKEN_LIST, NULL,
376 ANJUTA_TOKEN_ARGUMENT, NULL,
377 ANJUTA_TOKEN_CONTENT, path,
378 NULL);
379 g_free (path);
380 anjuta_token_append_child (group->preset_token, value);
381 var = amp_variable_new ("abs_srcdir", 0, value);
382 g_hash_table_insert (group->variables, var->name, var);
383 var = amp_variable_new ("abs_builddir", 0, value);
384 g_hash_table_insert (group->variables, var->name, var);
386 path = get_relative_path (file, root);
387 value = anjuta_token_insert_token_list (FALSE, NULL,
388 ANJUTA_TOKEN_LIST, NULL,
389 ANJUTA_TOKEN_ARGUMENT, NULL,
390 ANJUTA_TOKEN_CONTENT, path,
391 NULL);
392 g_free (path);
393 anjuta_token_append_child (group->preset_token, value);
394 var = amp_variable_new ("top_srcdir", 0, value);
395 g_hash_table_insert (group->variables, var->name, var);
396 var = amp_variable_new ("top_builddir", 0, value);
397 g_hash_table_insert (group->variables, var->name, var);
399 path = g_file_get_path (root);
400 value = anjuta_token_insert_token_list (FALSE, NULL,
401 ANJUTA_TOKEN_LIST, NULL,
402 ANJUTA_TOKEN_ARGUMENT, NULL,
403 ANJUTA_TOKEN_CONTENT, path,
404 NULL);
405 g_free (path);
406 anjuta_token_append_child (group->preset_token, value);
407 var = amp_variable_new ("abs_top_srcdir", 0, value);
408 g_hash_table_insert (group->variables, var->name, var);
409 var = amp_variable_new ("abs_top_builddir", 0, value);
410 g_hash_table_insert (group->variables, var->name, var);
413 AnjutaTokenFile*
414 amp_group_node_set_makefile (AmpGroupNode *group, GFile *makefile, AmpProject *project)
416 if (group->makefile != NULL) g_object_unref (group->makefile);
417 if (group->tfile != NULL) anjuta_token_file_free (group->tfile);
418 if (makefile != NULL)
420 AnjutaToken *token;
421 AmpAmScanner *scanner;
422 AnjutaProjectNode *source;
424 group->makefile = g_object_ref (makefile);
425 group->tfile = anjuta_token_file_new (makefile);
426 source = amp_source_node_new (makefile, ANJUTA_PROJECT_PROJECT | ANJUTA_PROJECT_FRAME | ANJUTA_PROJECT_READ_ONLY);
427 anjuta_project_node_append (ANJUTA_PROJECT_NODE (group), source);
429 token = anjuta_token_file_load (group->tfile, NULL);
430 amp_project_add_file (project, makefile, group->tfile);
432 amp_group_node_update_preset_variable (group);
434 scanner = amp_am_scanner_new (project, group);
435 group->make_token = amp_am_scanner_parse_token (scanner, anjuta_token_new_static (ANJUTA_TOKEN_FILE, NULL), token, makefile, NULL);
436 amp_am_scanner_free (scanner);
438 group->monitor = g_file_monitor_file (makefile,
439 G_FILE_MONITOR_NONE,
440 NULL,
441 NULL);
442 if (group->monitor != NULL)
444 g_signal_connect (G_OBJECT (group->monitor),
445 "changed",
446 G_CALLBACK (on_group_monitor_changed),
447 group);
450 else
452 group->makefile = NULL;
453 group->tfile = NULL;
454 group->make_token = NULL;
455 if (group->monitor) g_object_unref (group->monitor);
456 group->monitor = NULL;
459 return group->tfile;
462 AnjutaToken*
463 amp_group_node_get_makefile_token (AmpGroupNode *group)
465 return group->make_token;
468 AnjutaTokenFile *
469 amp_group_node_get_make_token_file (AmpGroupNode *group)
471 return group->tfile;
474 gboolean
475 amp_group_node_update_makefile (AmpGroupNode *group, AnjutaToken *token)
477 return anjuta_token_file_update (group->tfile, token);
480 gchar *
481 amp_group_node_get_makefile_name (AmpGroupNode *group)
483 gchar *basename = NULL;
485 if (group->makefile != NULL)
487 basename = g_file_get_basename (group->makefile);
490 return basename;
493 void
494 amp_group_node_update_node (AmpGroupNode *group, AmpGroupNode *new_group)
496 gint i;
497 GHashTable *hash;
499 if (group->monitor != NULL)
501 g_object_unref (group->monitor);
502 group->monitor = NULL;
504 if (group->makefile != NULL)
506 g_object_unref (group->makefile);
507 group->monitor = NULL;
509 if (group->preset_token != NULL)
511 anjuta_token_free (group->preset_token);
512 group->preset_token = NULL;
514 if (group->tfile) anjuta_token_file_free (group->tfile);
515 for (i = 0; i < AM_GROUP_TOKEN_LAST; i++)
517 if (group->tokens[i] != NULL) g_list_free (group->tokens[i]);
519 if (group->variables) g_hash_table_remove_all (group->variables);
521 group->dist_only = new_group->dist_only;
522 group->makefile = new_group->makefile;
523 new_group->makefile = NULL;
524 group->tfile = new_group->tfile;
525 new_group->tfile = NULL;
526 group->make_token = new_group->make_token;
527 new_group->make_token = NULL;
528 group->preset_token = new_group->preset_token;
529 new_group->preset_token = NULL;
530 memcpy (group->tokens, new_group->tokens, sizeof (group->tokens));
531 memset (new_group->tokens, 0, sizeof (new_group->tokens));
532 hash = group->variables;
533 group->variables = new_group->variables;
534 new_group->variables = hash;
536 if (group->makefile != NULL)
538 group->monitor = g_file_monitor_file (group->makefile,
539 G_FILE_MONITOR_NONE,
540 NULL,
541 NULL);
542 if (group->monitor != NULL)
544 g_signal_connect (G_OBJECT (group->monitor),
545 "changed",
546 G_CALLBACK (on_group_monitor_changed),
547 group);
552 void
553 amp_group_node_update_variable (AmpGroupNode *group, AnjutaToken *variable)
555 AnjutaToken *arg;
556 char *name = NULL;
557 AnjutaToken *value = NULL;
558 AmpVariable *var;
560 arg = anjuta_token_first_item (variable);
561 name = g_strstrip (anjuta_token_evaluate (arg));
562 value = anjuta_token_last_item (variable);
564 var = (AmpVariable *)g_hash_table_lookup (group->variables, name);
565 if (var != NULL)
567 var->value = value;
569 else
571 var = amp_variable_new (name, 0, value);
572 g_hash_table_insert (group->variables, var->name, var);
575 if (name) g_free (name);
578 AnjutaToken*
579 amp_group_node_get_variable_token (AmpGroupNode *group, const gchar *name)
581 AmpVariable *var;
583 var = g_hash_table_lookup (group->variables, name);
585 return var != NULL ? var->value : NULL;
588 gboolean
589 amp_group_node_set_file (AmpGroupNode *group, GFile *new_file)
591 if (group->base.file != NULL) g_object_unref (group->base.file);
592 g_free (group->base.name);
593 group->base.name = NULL;
594 group->base.file = g_object_ref (new_file);
596 return TRUE;
599 AmpGroupNode*
600 amp_group_node_new (GFile *file, const gchar *name, gboolean dist_only)
602 AmpGroupNode *node = NULL;
604 node = g_object_new (AMP_TYPE_GROUP_NODE, NULL);
605 node->base.file = g_object_ref (file);
606 node->base.name = g_strdup (name);
607 node->dist_only = dist_only;
608 memset (node->tokens, 0, sizeof (node->tokens));
610 return node;
613 AmpGroupNode*
614 amp_group_node_new_valid (GFile *file, const gchar *name, gboolean dist_only, GError **error)
616 /* Validate group name */
617 if (!name || strlen (name) <= 0)
619 g_free (name);
620 error_set (error, IANJUTA_PROJECT_ERROR_VALIDATION_FAILED,
621 _("Please specify group name"));
622 return NULL;
625 gboolean failed = FALSE;
626 const gchar *ptr = name;
627 while (*ptr) {
628 if (!isalnum (*ptr) && (strchr ("#$:%+,-.=@^_`~/", *ptr) == NULL))
629 failed = TRUE;
630 ptr++;
632 if (failed) {
633 g_free (name);
634 error_set (error, IANJUTA_PROJECT_ERROR_VALIDATION_FAILED,
635 _("Group name can only contain alphanumeric or \"#$:%+,-.=@^_`~/\" characters"));
636 return NULL;
640 return amp_group_node_new (file, name, dist_only);
643 void
644 amp_group_node_free (AmpGroupNode *node)
646 g_object_unref (G_OBJECT (node));
649 /* AmpNode implementation
650 *---------------------------------------------------------------------------*/
652 static gboolean
653 amp_group_node_load (AmpNode *group, AmpNode *parent, AmpProject *project, GError **error)
655 if (project_load_makefile (project, AMP_GROUP_NODE (group)) == NULL)
657 g_set_error (error, IANJUTA_PROJECT_ERROR,
658 IANJUTA_PROJECT_ERROR_DOESNT_EXIST,
659 _("Project doesn't exist or invalid path"));
661 return FALSE;
664 return TRUE;
667 static gboolean
668 amp_group_node_save (AmpNode *group, AmpNode *parent, AmpProject *project, GError **error)
670 AnjutaTokenFile *tfile;
671 AnjutaProjectNode *child;
672 gboolean ok = TRUE;
673 GFile *directory;
675 /* Create directory */
676 directory = g_file_get_parent (AMP_GROUP_NODE (group)->makefile);
677 g_file_make_directory (directory, NULL, NULL);
678 g_object_unref (directory);
680 /* Save group */
681 tfile = AMP_GROUP_NODE (group)->tfile;
682 if (tfile == NULL)
684 /* Create an empty makefile */
685 g_file_replace_contents (AMP_GROUP_NODE (group)->makefile, "", 0, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL, NULL);
687 return TRUE;
690 if (anjuta_token_file_is_dirty (tfile))
692 if (!anjuta_token_file_save (tfile, error)) return FALSE;
695 /* Save all children */
696 for (child = anjuta_project_node_first_child (ANJUTA_PROJECT_NODE (group)); child != NULL; child = anjuta_project_node_next_sibling (child))
698 /* Try to save all children even if some fail */
699 if (!amp_node_save (AMP_NODE (child), group, project, error)) ok = FALSE;
702 return ok;
705 static gboolean
706 amp_group_node_update (AmpNode *node, AmpNode *new_node)
708 amp_group_node_update_node (AMP_GROUP_NODE (node), AMP_GROUP_NODE (new_node));
710 return TRUE;
713 static gboolean
714 amp_group_node_write (AmpNode *node, AmpNode *parent, AmpProject *project, GError **error)
716 return amp_group_node_create_token (project, AMP_GROUP_NODE (node), error);
719 static gboolean
720 amp_group_node_erase (AmpNode *node, AmpNode *parent, AmpProject *project, GError **error)
722 return amp_group_node_delete_token (project, AMP_GROUP_NODE (node), error);
727 /* GObjet implementation
728 *---------------------------------------------------------------------------*/
731 G_DEFINE_DYNAMIC_TYPE (AmpGroupNode, amp_group_node, AMP_TYPE_NODE);
733 static void
734 amp_group_node_init (AmpGroupNode *node)
736 node->base.type = ANJUTA_PROJECT_GROUP;
737 node->base.properties_info = amp_get_group_property_list();
738 node->base.state = ANJUTA_PROJECT_CAN_ADD_GROUP |
739 ANJUTA_PROJECT_CAN_ADD_TARGET |
740 ANJUTA_PROJECT_CAN_REMOVE |
741 ANJUTA_PROJECT_CAN_SAVE;
742 node->dist_only = FALSE;
743 node->variables = NULL;
744 node->makefile = NULL;
745 node->variables = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)amp_variable_free);
746 node->monitor = NULL;
747 memset (node->tokens, 0, sizeof (node->tokens));
748 node->preset_token = NULL;
751 static void
752 amp_group_node_dispose (GObject *object)
754 AmpGroupNode *node = AMP_GROUP_NODE (object);
756 if (node->monitor) g_object_unref (node->monitor);
757 node->monitor = NULL;
759 if (node->preset_token) anjuta_token_free (node->preset_token);
760 node->preset_token = NULL;
762 G_OBJECT_CLASS (amp_group_node_parent_class)->dispose (object);
765 static void
766 amp_group_node_finalize (GObject *object)
768 AmpGroupNode *node = AMP_GROUP_NODE (object);
769 gint i;
771 if (node->tfile) anjuta_token_file_free (node->tfile);
772 if (node->makefile) g_object_unref (node->makefile);
774 for (i = 0; i < AM_GROUP_TOKEN_LAST; i++)
776 if (node->tokens[i] != NULL) g_list_free (node->tokens[i]);
778 if (node->variables) g_hash_table_destroy (node->variables);
780 G_OBJECT_CLASS (amp_group_node_parent_class)->finalize (object);
783 static void
784 amp_group_node_class_init (AmpGroupNodeClass *klass)
786 GObjectClass* object_class = G_OBJECT_CLASS (klass);
787 AmpNodeClass* node_class;
789 object_class->finalize = amp_group_node_finalize;
790 object_class->dispose = amp_group_node_dispose;
792 node_class = AMP_NODE_CLASS (klass);
793 node_class->load = amp_group_node_load;
794 node_class->save = amp_group_node_save;
795 node_class->update = amp_group_node_update;
796 node_class->write = amp_group_node_write;
797 node_class->erase = amp_group_node_erase;
800 static void
801 amp_group_node_class_finalize (AmpGroupNodeClass *klass)
805 void
806 amp_group_node_register (GTypeModule *module)
808 amp_group_node_register_type (module);