[anjuta] am-project: Move all node objects in different files



commit 395b6c3701924983260c5b73b3b5d6c461d6ba4a
Author: Sébastien Granjoux <seb sfo free fr>
Date:   Sun Dec 26 18:10:15 2010 +0100

    am-project: Move all node objects in different files

 plugins/am-project/Makefile.am          |   14 +-
 plugins/am-project/ac-writer.c          |   14 +-
 plugins/am-project/am-node.c            |  948 -------------------------------
 plugins/am-project/am-node.h            |  104 ----
 plugins/am-project/am-project-private.h |   81 ---
 plugins/am-project/am-project.c         |  158 ++----
 plugins/am-project/am-project.h         |    7 +-
 plugins/am-project/am-scanner.l         |    3 +-
 plugins/am-project/am-writer.c          |   11 +-
 plugins/am-project/amp-group.c          |  479 ++++++++++++++++
 plugins/am-project/amp-group.h          |   84 +++
 plugins/am-project/amp-module.c         |  148 +++++
 plugins/am-project/amp-module.h         |   54 ++
 plugins/am-project/amp-node.c           |   82 +++
 plugins/am-project/amp-node.h           |   69 +++
 plugins/am-project/amp-package.c        |  156 +++++
 plugins/am-project/amp-package.h        |   55 ++
 plugins/am-project/amp-source.c         |  150 +++++
 plugins/am-project/amp-source.h         |   58 ++
 plugins/am-project/amp-target.c         |  355 ++++++++++++
 plugins/am-project/amp-target.h         |   75 +++
 21 files changed, 1835 insertions(+), 1270 deletions(-)
---
diff --git a/plugins/am-project/Makefile.am b/plugins/am-project/Makefile.am
index 13321b1..d6ea914 100644
--- a/plugins/am-project/Makefile.am
+++ b/plugins/am-project/Makefile.am
@@ -47,8 +47,18 @@ libam_project_la_SOURCES = \
 	am-project-private.h \
 	am-properties.c \
 	am-properties.h \
-	am-node.c \
-	am-node.h \
+	amp-node.c \
+	amp-node.h \
+	amp-module.h \
+	amp-module.c \
+	amp-package.h \
+	amp-package.c \
+	amp-group.h \
+	amp-group.c \
+	amp-target.h \
+	amp-target.c \
+	amp-source.h \
+	amp-source.c \
 	command-queue.c \
 	command-queue.h
 
diff --git a/plugins/am-project/ac-writer.c b/plugins/am-project/ac-writer.c
index f8eca90..d179096 100644
--- a/plugins/am-project/ac-writer.c
+++ b/plugins/am-project/ac-writer.c
@@ -27,7 +27,10 @@
 #include "ac-writer.h"
 #include "ac-scanner.h"
 #include "ac-parser.h"
-#include "am-node.h"
+#include "amp-node.h"
+#include "amp-module.h"
+#include "amp-package.h"
+
 
 #include "am-project-private.h"
 
@@ -334,6 +337,7 @@ gboolean
 amp_package_create_token (AmpProject  *project, AnjutaAmPackageNode *package, GError **error)
 {
 	AnjutaAmModuleNode *module;
+	AnjutaProjectNode *sibling;
 	gboolean after;
 	AnjutaToken *token;
 	AnjutaToken *prev;
@@ -347,15 +351,15 @@ amp_package_create_token (AmpProject  *project, AnjutaAmPackageNode *package, GE
 
 	/* Add in configure.ac */
 	/* Find a sibling if possible */
-	if (package->base.prev != NULL)
+	if ((sibling = anjuta_project_node_prev_sibling (ANJUTA_PROJECT_NODE (package))) != NULL)
 	{
-		prev = ANJUTA_AM_PACKAGE_NODE (package->base.prev)->token;
+		prev = amp_package_get_token (ANJUTA_AM_PACKAGE_NODE (sibling));
 		after = TRUE;
 		args = anjuta_token_list (prev);
 	}
-	else if (package->base.next != NULL)
+	else if ((sibling = anjuta_project_node_next_sibling (ANJUTA_PROJECT_NODE (package))) != NULL)
 	{
-		prev = ANJUTA_AM_PACKAGE_NODE (package->base.next)->token;
+		prev = amp_package_get_token (ANJUTA_AM_PACKAGE_NODE (sibling));
 		after = FALSE;
 		args = anjuta_token_list (prev);
 	}
diff --git a/plugins/am-project/am-project-private.h b/plugins/am-project/am-project-private.h
index 8e1fa5a..eaaf6e0 100644
--- a/plugins/am-project/am-project-private.h
+++ b/plugins/am-project/am-project-private.h
@@ -85,87 +85,6 @@ struct _AmpNodeInfo {
 };
 
 
-#define ANJUTA_TYPE_AM_MODULE_NODE			(anjuta_am_module_node_get_type ())
-#define ANJUTA_AM_MODULE_NODE(obj)				(G_TYPE_CHECK_INSTANCE_CAST ((obj), ANJUTA_TYPE_AM_MODULE_NODE, AnjutaAmModuleNode))
-
-GType anjuta_am_module_node_get_type (void) G_GNUC_CONST;
-
-struct _AnjutaAmModuleNode {
-	AnjutaProjectNode base;
-	AnjutaToken *module;
-};
-
-
-#define ANJUTA_TYPE_AM_PACKAGE_NODE			(anjuta_am_package_node_get_type ())
-#define ANJUTA_AM_PACKAGE_NODE(obj)				(G_TYPE_CHECK_INSTANCE_CAST ((obj), ANJUTA_TYPE_AM_PACKAGE_NODE, AnjutaAmPackageNode))
-
-GType anjuta_am_package_node_get_type (void) G_GNUC_CONST;
-
-struct _AnjutaAmPackageNode {
-	AnjutaProjectNode base;
-	gchar *version;
-	AnjutaToken *token;
-};
-
-
-#define ANJUTA_TYPE_AM_GROUP_NODE			(anjuta_am_group_node_get_type ())
-#define ANJUTA_AM_GROUP_NODE(obj)				(G_TYPE_CHECK_INSTANCE_CAST ((obj), ANJUTA_TYPE_AM_GROUP_NODE, AnjutaAmGroupNode))
-
-GType anjuta_am_group_node_get_type (void) G_GNUC_CONST;
-
-typedef enum {
-	AM_GROUP_TOKEN_CONFIGURE,
-	AM_GROUP_TOKEN_SUBDIRS,
-	AM_GROUP_TOKEN_DIST_SUBDIRS,
-	AM_GROUP_TARGET,
-	AM_GROUP_TOKEN_LAST
-} AmpGroupTokenCategory;
-
-struct _AnjutaAmGroupNode {
-	AnjutaProjectNode base;
-	gboolean dist_only;										/* TRUE if the group is distributed but not built */
-	GFile *makefile;												/* GFile corresponding to group makefile */
-	AnjutaTokenFile *tfile;										/* Corresponding Makefile */
-	GList *tokens[AM_GROUP_TOKEN_LAST];			/* List of token used by this group */
-	AnjutaToken *make_token;
-	GHashTable *variables;
-	GFileMonitor *monitor;									/* File monitor */
-};
-
-
-
-#define ANJUTA_TYPE_AM_TARGET_NODE			(anjuta_am_target_node_get_type ())
-#define ANJUTA_AM_TARGET_NODE(obj)				(G_TYPE_CHECK_INSTANCE_CAST ((obj), ANJUTA_TYPE_AM_TARGET_NODE, AnjutaAmTargetNode))
-
-GType anjuta_am_target_node_get_type (void) G_GNUC_CONST;
-
-typedef enum {
-	AM_TARGET_TOKEN_TARGET,
-	AM_TARGET_TOKEN_SOURCES,
-	AM_TARGET_TOKEN_LAST
-} AmpTargetTokenCategory;
-
-struct _AnjutaAmTargetNode {
-	AnjutaProjectNode base;
-	gchar *install;
-	gint flags;
-	GList* tokens;	
-};
-
-
-
-#define ANJUTA_TYPE_AM_SOURCE_NODE			(anjuta_am_source_node_get_type ())
-#define ANJUTA_AM_SOURCE_NODE(obj)			(G_TYPE_CHECK_INSTANCE_CAST ((obj), ANJUTA_TYPE_AM_SOURCE_NODE, AnjutaAmSourceNode))
-
-GType anjuta_am_source_node_get_type (void) G_GNUC_CONST;
-
-struct _AnjutaAmSourceNode {
-	AnjutaProjectNode base;
-	AnjutaToken* token;	
-};
-
-
-
 G_END_DECLS
 
 #endif /* _AM_PROJECT_PRIVATE_H_ */
diff --git a/plugins/am-project/am-project.c b/plugins/am-project/am-project.c
index dc1bafd..83ac031 100644
--- a/plugins/am-project/am-project.c
+++ b/plugins/am-project/am-project.c
@@ -27,7 +27,12 @@
 #include "am-project.h"
 
 #include "am-project-private.h"
-#include "am-node.h"
+#include "amp-node.h"
+#include "amp-module.h"
+#include "amp-package.h"
+#include "amp-group.h"
+#include "amp-target.h"
+#include "amp-source.h"
 #include "command-queue.h"
 
 #include <libanjuta/interfaces/ianjuta-project.h>
@@ -305,7 +310,7 @@ file_type (GFile *file, const gchar *filename)
 
 /* Remove invalid character according to automake rules */
 gchar*
-canonicalize_automake_variable (gchar *name)
+canonicalize_automake_variable (const gchar *name)
 {
 	gchar *canon_name = g_strdup (name);
 	gchar *ptr;
@@ -622,7 +627,7 @@ find_target (AnjutaProjectNode *node, gpointer data)
 {
 	if ((AMP_NODE_DATA (node)->type  & ANJUTA_PROJECT_TYPE_MASK) == ANJUTA_PROJECT_TARGET)
 	{
-		if (strcmp (AMP_TARGET_DATA (node)->base.name, *(gchar **)data) == 0)
+		if (strcmp (anjuta_project_node_get_name (node), *(gchar **)data) == 0)
 		{
 			/* Find target, return node value in pointer */
 			*(AnjutaProjectNode **)data = node;
@@ -639,7 +644,7 @@ find_canonical_target (AnjutaProjectNode *node, gpointer data)
 {
 	if ((AMP_NODE_DATA (node)->type  & ANJUTA_PROJECT_TYPE_MASK) == ANJUTA_PROJECT_TARGET)
 	{
-		gchar *canon_name = canonicalize_automake_variable (AMP_TARGET_DATA (node)->base.name);	
+		gchar *canon_name = canonicalize_automake_variable (anjuta_project_node_get_name (node));	
 		DEBUG_PRINT ("compare canon %s vs %s node %p", canon_name, *(gchar **)data, node);
 		if (strcmp (canon_name, *(gchar **)data) == 0)
 		{
@@ -655,9 +660,6 @@ find_canonical_target (AnjutaProjectNode *node, gpointer data)
 	return FALSE;
 }
 
-/* Source objects
- *---------------------------------------------------------------------------*/
-
 /*
  * ---------------- Data structures managment
  */
@@ -669,15 +671,15 @@ amp_dump_node (AnjutaProjectNode *g_node)
 	
 	switch (AMP_NODE_DATA (g_node)->type & ANJUTA_PROJECT_TYPE_MASK) {
 		case ANJUTA_PROJECT_GROUP:
-			name = g_file_get_uri (AMP_GROUP_DATA (g_node)->base.file);
+			name = g_file_get_uri (anjuta_project_node_get_file (g_node));
 			DEBUG_PRINT ("GROUP: %s", name);
 			break;
 		case ANJUTA_PROJECT_TARGET:
-			name = g_strdup (AMP_TARGET_DATA (g_node)->base.name);
+			name = g_strdup (anjuta_project_node_get_name (g_node));
 			DEBUG_PRINT ("TARGET: %s", name);
 			break;
 		case ANJUTA_PROJECT_SOURCE:
-			name = g_file_get_uri (AMP_SOURCE_DATA (g_node)->base.file);
+			name = g_file_get_uri (anjuta_project_node_get_file (g_node));
 			DEBUG_PRINT ("SOURCE: %s", name);
 			break;
 		default:
@@ -744,7 +746,7 @@ project_node_new (AmpProject *project, AnjutaProjectNode *parent, AnjutaProjectN
 		case ANJUTA_PROJECT_GROUP:
 			if ((file == NULL) && (name != NULL))
 			{
-				file = g_file_get_child (AMP_GROUP_DATA (parent)->base.file, name);
+				file = g_file_get_child (anjuta_project_node_get_file (parent), name);
 				node = ANJUTA_PROJECT_NODE (amp_group_new (file, FALSE, error));
 				g_object_unref (file);
 			}
@@ -816,13 +818,13 @@ project_node_save (AmpProject *project, AnjutaProjectNode *node, GError **error)
 	
 	switch (AMP_NODE_DATA (node)->type & ANJUTA_PROJECT_TYPE_MASK) {
 		case ANJUTA_PROJECT_GROUP:
-			g_hash_table_insert (files, AMP_GROUP_DATA (node)->tfile, NULL);
+			g_hash_table_insert (files, amp_group_get_make_token_file (ANJUTA_AM_GROUP_NODE (node)), NULL);
 			g_hash_table_insert (files, project->configure_file, NULL);
 			break;
 		case ANJUTA_PROJECT_TARGET:
 		case ANJUTA_PROJECT_SOURCE:
 			for (parent = node; anjuta_project_node_get_node_type (parent) != ANJUTA_PROJECT_GROUP; parent = anjuta_project_node_parent (parent));
-			g_hash_table_insert (files, AMP_GROUP_DATA (parent)->tfile, NULL);
+			g_hash_table_insert (files, amp_group_get_make_token_file (ANJUTA_AM_GROUP_NODE (parent)), NULL);
 			break;
 		case ANJUTA_PROJECT_MODULE:
 		case ANJUTA_PROJECT_PACKAGE:
@@ -1196,7 +1198,7 @@ project_load_sources (AmpProject *project, AnjutaToken *name, AnjutaToken *list,
 			src_file = g_file_get_child (parent_file, value);
 			source = project_node_new (project, NULL, ANJUTA_PROJECT_SOURCE | ANJUTA_PROJECT_PROJECT, src_file, NULL, NULL);
 			g_object_unref (src_file);
-			AMP_SOURCE_DATA(source)->token = arg;
+			amp_source_add_token (ANJUTA_AM_SOURCE_NODE(source), arg);
 	
 			DEBUG_PRINT ("add target child %p", parent);
 			/* Add as target child */
@@ -1261,7 +1263,7 @@ project_load_data (AmpProject *project, AnjutaToken *name, AnjutaToken *list, An
 
 	if (target != NULL)
 	{
-		GFile *parent_file = g_object_ref (AMP_GROUP_DATA (parent)->base.file);
+		GFile *parent_file = g_object_ref (anjuta_project_node_get_file (parent));
 		
 		for (arg = anjuta_token_first_word (list); arg != NULL; arg = anjuta_token_next_word (arg))
 		{
@@ -1276,7 +1278,7 @@ project_load_data (AmpProject *project, AnjutaToken *name, AnjutaToken *list, An
 			src_file = g_file_get_child (parent_file, value);
 			source = project_node_new (project, NULL, ANJUTA_PROJECT_SOURCE | ANJUTA_PROJECT_PROJECT, src_file, NULL, NULL);
 			g_object_unref (src_file);
-			AMP_SOURCE_DATA(source)->token = arg;
+			amp_source_add_token (ANJUTA_AM_SOURCE_NODE(source), arg);
 
 			/* Add as target child */
 			DEBUG_PRINT ("add target child %p", target);
@@ -1532,7 +1534,7 @@ project_load_subdirs (AmpProject *project, AnjutaToken *list, AnjutaProjectNode
 			GFile *subdir;
 			AnjutaAmGroupNode *group;
 
-			subdir = g_file_resolve_relative_path (AMP_GROUP_DATA (parent)->base.file, value);
+			subdir = g_file_resolve_relative_path (anjuta_project_node_get_file (parent), value);
 			
 			/* Look for already existing group */
 			group = ANJUTA_AM_GROUP_NODE (anjuta_project_node_children_traverse (parent, find_group, subdir));
@@ -2206,7 +2208,7 @@ amp_project_remove_source (AmpProject  *project,
 {
 	if (anjuta_project_node_get_node_type (ANJUTA_PROJECT_NODE (source)) != ANJUTA_PROJECT_SOURCE) return;
 	
-	anjuta_token_remove_word (AMP_SOURCE_DATA (source)->token);
+	anjuta_token_remove_word (amp_source_get_token (source));
 
 	amp_source_free (source);
 }
@@ -2269,20 +2271,20 @@ foreach_node_move (AnjutaProjectNode *g_node, gpointer data)
 	switch (anjuta_project_node_get_node_type (g_node))
 	{
 	case ANJUTA_PROJECT_GROUP:
-		relative = get_relative_path (old_root_file, AMP_GROUP_DATA (g_node)->base.file);
+		relative = get_relative_path (old_root_file, anjuta_project_node_get_file (g_node));
 		new_file = g_file_resolve_relative_path (root_file, relative);
 		g_free (relative);
-		g_object_unref (AMP_GROUP_DATA (g_node)->base.file);
-		AMP_GROUP_DATA (g_node)->base.file = new_file;
-
+		amp_group_set_file (ANJUTA_AM_GROUP_NODE (g_node), new_file);
+		g_object_unref (new_file);	
+			
 		g_hash_table_insert (project->groups, g_file_get_uri (new_file), g_node);
 		break;
 	case ANJUTA_PROJECT_SOURCE:
-		relative = get_relative_path (old_root_file, AMP_SOURCE_DATA (g_node)->base.file);
+		relative = get_relative_path (old_root_file, anjuta_project_node_get_file (g_node));
 		new_file = g_file_resolve_relative_path (root_file, relative);
 		g_free (relative);
-		g_object_unref (AMP_SOURCE_DATA (g_node)->base.file);
-		AMP_SOURCE_DATA (g_node)->base.file = new_file;
+		amp_source_set_file (ANJUTA_AM_SOURCE_NODE (g_node), new_file);
+		g_object_unref (new_file);	
 		break;
 	default:
 		break;
@@ -2358,7 +2360,7 @@ amp_project_dump (AmpProject *project, AnjutaProjectNode *node)
 	switch (anjuta_project_node_get_node_type (node))
 	{
 	case ANJUTA_PROJECT_GROUP:
-		anjuta_token_dump (AMP_GROUP_DATA (node)->make_token);
+		anjuta_token_dump (amp_group_get_makefile_token (ANJUTA_AM_GROUP_NODE (node)));
 		break;
 	case ANJUTA_PROJECT_ROOT:
 		anjuta_token_dump (AMP_PROJECT (node)->configure_token);
@@ -2465,7 +2467,7 @@ amp_project_get_node_id (AmpProject *project, const gchar *path)
 	switch (anjuta_project_node_get_node_type (node))
 	{
 		case ANJUTA_PROJECT_GROUP:
-			return g_file_get_uri (AMP_GROUP_DATA (node)->base.file);
+			return g_file_get_uri (anjuta_project_node_get_file (node));
 		case ANJUTA_PROJECT_TARGET:
 		case ANJUTA_PROJECT_SOURCE:
 			return g_base64_encode ((guchar *)&node, sizeof (node));
@@ -3056,99 +3058,6 @@ iproject_iface_init(IAnjutaProjectIface* iface)
 /* Group access functions
  *---------------------------------------------------------------------------*/
 
-GFile*
-amp_group_get_directory (AnjutaAmGroupNode *group)
-{
-	return AMP_GROUP_DATA (group)->base.file;
-}
-
-gchar *
-amp_group_get_id (AnjutaAmGroupNode *group)
-{
-	return g_file_get_uri (AMP_GROUP_DATA (group)->base.file);
-}
-
-void
-amp_group_update_variable (AnjutaAmGroupNode *group, AnjutaToken *variable)
-{
-	AnjutaToken *arg;
-	char *name = NULL;
-	AnjutaToken *value = NULL;
-	AmpVariable *var;
-
-	arg = anjuta_token_first_item (variable);
-	name = g_strstrip (anjuta_token_evaluate (arg));
-	arg = anjuta_token_next_item (arg);
-	value = anjuta_token_next_item (arg);
-
-	var = (AmpVariable *)g_hash_table_lookup (AMP_GROUP_DATA (group)->variables, name);
-	if (var != NULL)
-	{
-		var->value = value;
-	}
-	else
-	{
-		var = amp_variable_new (name, 0, value);
-		g_hash_table_insert (AMP_GROUP_DATA (group)->variables, var->name, var);
-	}
-
-	if (name) g_free (name);
-}
-
-AnjutaToken*
-amp_group_get_variable_token (AnjutaAmGroupNode *group, AnjutaToken *variable)
-{
-	guint length;
-	const gchar *string;
-	gchar *name;
-	AmpVariable *var;
-		
-	length = anjuta_token_get_length (variable);
-	string = anjuta_token_get_string (variable);
-	if (string[1] == '(')
-	{
-		name = g_strndup (string + 2, length - 3);
-	}
-	else
-	{
-		name = g_strndup (string + 1, 1);
-	}
-	var = g_hash_table_lookup (AMP_GROUP_DATA (group)->variables, name);
-	g_free (name);
-
-	return var != NULL ? var->value : NULL;
-}
-
-/* Target access functions
- *---------------------------------------------------------------------------*/
-
-const gchar *
-amp_target_get_name (AnjutaAmTargetNode *target)
-{
-	return AMP_TARGET_DATA (target)->base.name;
-}
-
-gchar *
-amp_target_get_id (AnjutaAmTargetNode *target)
-{
-	return g_base64_encode ((guchar *)&target, sizeof (target));
-}
-
-/* Source access functions
- *---------------------------------------------------------------------------*/
-
-gchar *
-amp_source_get_id (AnjutaAmSourceNode *source)
-{
-	return g_base64_encode ((guchar *)&source, sizeof (source));
-}
-
-GFile*
-amp_source_get_file (AnjutaAmSourceNode *source)
-{
-	return AMP_SOURCE_DATA (source)->base.file;
-}
-
 /* GbfProject implementation
  *---------------------------------------------------------------------------*/
 
@@ -3229,7 +3138,7 @@ amp_project_class_finalize (AmpProjectClass *klass)
 
 G_DEFINE_DYNAMIC_TYPE_EXTENDED (AmpProject,
                                 amp_project,
-                                ANJUTA_TYPE_PROJECT_NODE,
+                                AMP_TYPE_NODE,
                                 0,
                                 G_IMPLEMENT_INTERFACE_DYNAMIC (IANJUTA_TYPE_PROJECT,
                                                                iproject_iface_init));
@@ -3237,6 +3146,11 @@ G_DEFINE_DYNAMIC_TYPE_EXTENDED (AmpProject,
 void
 amp_project_register_project (GTypeModule *module)
 {
-	amp_project_register_nodes (module);
+	amp_node_register (module);
+	anjuta_am_module_node_register (module);
+	anjuta_am_package_node_register (module);
+	anjuta_am_group_node_register (module);
+	anjuta_am_target_node_register (module);
+	anjuta_am_source_node_register (module);
 	amp_project_register_type (module);
 }
diff --git a/plugins/am-project/am-project.h b/plugins/am-project/am-project.h
index 1960474..28e07f8 100644
--- a/plugins/am-project/am-project.h
+++ b/plugins/am-project/am-project.h
@@ -24,6 +24,8 @@
 
 #include <glib-object.h>
 
+#include "amp-node.h"
+
 #include <libanjuta/anjuta-project.h>
 #include <libanjuta/anjuta-token.h>
 #include <libanjuta/anjuta-token-file.h>
@@ -41,7 +43,7 @@ typedef struct _AmpProject        AmpProject;
 typedef struct _AmpProjectClass   AmpProjectClass;
 
 struct _AmpProjectClass {
-	AnjutaProjectNodeClass parent_class;
+	AmpNodeClass parent_class;
 };
 
 typedef struct _AnjutaAmRootNode AnjutaAmRootNode;
@@ -120,7 +122,6 @@ AnjutaProjectNode *amp_node_first_child (AnjutaProjectNode *node);
 AnjutaProjectNode *amp_node_last_child (AnjutaProjectNode *node);
 AnjutaProjectNode *amp_node_next_sibling (AnjutaProjectNode *node);
 AnjutaProjectNode *amp_node_prev_sibling (AnjutaProjectNode *node);
-AnjutaProjectNodeType amp_node_get_type (AnjutaProjectNode *node);
 //void amp_node_all_foreach (AnjutaProjectNode *node, AnjutaProjectNodeFunc func, gpointer data);
 
 GFile *amp_group_get_directory (AnjutaAmGroupNode *group);
@@ -135,7 +136,7 @@ void amp_source_free (AnjutaAmSourceNode *node);
 gchar *amp_source_get_id (AnjutaAmSourceNode *source);
 GFile *amp_source_get_file (AnjutaAmSourceNode *source);
 
-gchar* canonicalize_automake_variable (gchar *name);
+gchar* canonicalize_automake_variable (const gchar *name);
 
 
 
diff --git a/plugins/am-project/am-scanner.l b/plugins/am-project/am-scanner.l
index 78864f5..5d17bd4 100644
--- a/plugins/am-project/am-scanner.l
+++ b/plugins/am-project/am-scanner.l
@@ -21,7 +21,8 @@
 
 #include "am-scanner.h"
 #include "am-parser.h"
-#include "am-node.h"
+#include "amp-node.h"
+#include "amp-target.h"
 
 #include "libanjuta/anjuta-debug.h"
 #include "libanjuta/anjuta-token-stream.h"
diff --git a/plugins/am-project/am-writer.c b/plugins/am-project/am-writer.c
index 1e6578d..e161f8d 100644
--- a/plugins/am-project/am-writer.c
+++ b/plugins/am-project/am-writer.c
@@ -29,7 +29,10 @@
 #include "ac-parser.h"
 
 #include "am-project-private.h"
-#include "am-node.h"
+#include "amp-node.h"
+#include "amp-group.h"
+#include "amp-target.h"
+#include "amp-source.h"
 #include "am-scanner.h"
 
 #include <libanjuta/anjuta-debug.h>
@@ -670,7 +673,7 @@ amp_source_create_token (AmpProject  *project, AnjutaAmSourceNode *source, GErro
 	}
 	else
 	{
-		prev = ANJUTA_AM_SOURCE_NODE (sibling)->token;
+		prev = amp_source_get_token (ANJUTA_AM_SOURCE_NODE (sibling));
 		args = anjuta_token_list (prev);
 	}
 
@@ -692,7 +695,7 @@ amp_source_create_token (AmpProject  *project, AnjutaAmSourceNode *source, GErro
 		AnjutaToken *var;
 		GList *list;
 		
-		canon_name = canonicalize_automake_variable (ANJUTA_AM_TARGET_NODE (target)->base.name);
+		canon_name = canonicalize_automake_variable (anjuta_project_node_get_name (ANJUTA_PROJECT_NODE (target)));
 		target_var = g_strconcat (canon_name,  "_SOURCES", NULL);
 
 		/* Search where the target is declared */
@@ -879,7 +882,7 @@ gboolean amp_project_update_am_property (AmpProject *project, AnjutaProjectNode
 			else
 			{
 				/* Target property */
-				canon_name = canonicalize_automake_variable (ANJUTA_AM_TARGET_NODE (node)->base.name);
+				canon_name = canonicalize_automake_variable (anjuta_project_node_get_name (ANJUTA_PROJECT_NODE (node)));
 				prop_name = g_strconcat (canon_name, ((AmpProperty *)property->native)->suffix, NULL);
 			}
 			args = amp_project_write_property_list (ANJUTA_AM_GROUP_NODE (group), node, prop_name);
diff --git a/plugins/am-project/amp-group.c b/plugins/am-project/amp-group.c
new file mode 100644
index 0000000..55ea058
--- /dev/null
+++ b/plugins/am-project/amp-group.c
@@ -0,0 +1,479 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* amp-group.c
+ *
+ * Copyright (C) 2010  Sébastien Granjoux
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "amp-group.h"
+
+#include "amp-node.h"
+#include "am-scanner.h"
+#include "am-properties.h"
+
+
+#include <libanjuta/interfaces/ianjuta-project.h>
+
+#include <libanjuta/anjuta-debug.h>
+
+#include <glib/gi18n.h>
+
+#include <memory.h>
+#include <string.h>
+#include <ctype.h>
+
+/* Types
+ *---------------------------------------------------------------------------*/
+
+struct _AnjutaAmGroupNode {
+	AnjutaProjectNode base;
+	gboolean dist_only;										/* TRUE if the group is distributed but not built */
+	GFile *makefile;												/* GFile corresponding to group makefile */
+	AnjutaTokenFile *tfile;										/* Corresponding Makefile */
+	GList *tokens[AM_GROUP_TOKEN_LAST];			/* List of token used by this group */
+	AnjutaToken *make_token;
+	GHashTable *variables;
+	GFileMonitor *monitor;									/* File monitor */
+};
+
+
+/* Helper functions
+ *---------------------------------------------------------------------------*/
+
+static void
+error_set (GError **error, gint code, const gchar *message)
+{
+        if (error != NULL) {
+                if (*error != NULL) {
+                        gchar *tmp;
+
+                        /* error already created, just change the code
+                         * and prepend the string */
+                        (*error)->code = code;
+                        tmp = (*error)->message;
+                        (*error)->message = g_strconcat (message, "\n\n", tmp, NULL);
+                        g_free (tmp);
+
+                } else {
+                        *error = g_error_new_literal (IANJUTA_PROJECT_ERROR,
+                                                      code,
+                                                      message);
+                }
+        }
+}
+                                                      
+
+/* Variable object
+ *---------------------------------------------------------------------------*/
+
+AmpVariable*
+amp_variable_new (gchar *name, AnjutaTokenType assign, AnjutaToken *value)
+{
+    AmpVariable *variable = NULL;
+
+	g_return_val_if_fail (name != NULL, NULL);
+	
+	variable = g_slice_new0(AmpVariable); 
+	variable->name = g_strdup (name);
+	variable->assign = assign;
+	variable->value = value;
+
+	return variable;
+}
+
+static void
+amp_variable_free (AmpVariable *variable)
+{
+	g_free (variable->name);
+	
+    g_slice_free (AmpVariable, variable);
+}
+
+
+
+/* Group objects
+ *---------------------------------------------------------------------------*/
+
+
+void
+amp_group_add_token (AnjutaAmGroupNode *group, AnjutaToken *token, AmpGroupTokenCategory category)
+{
+	group->tokens[category] = g_list_prepend (group->tokens[category], token);
+}
+
+GList *
+amp_group_get_token (AnjutaAmGroupNode *group, AmpGroupTokenCategory category)
+{
+	return group->tokens[category];
+}
+
+AnjutaToken*
+amp_group_get_first_token (AnjutaAmGroupNode *group, AmpGroupTokenCategory category)
+{
+	GList *list;
+	
+	list = amp_group_get_token (group, category);
+	if (list == NULL) return NULL;
+
+	return (AnjutaToken *)list->data;
+}
+
+void
+amp_group_set_dist_only (AnjutaAmGroupNode *group, gboolean dist_only)
+{
+ 	group->dist_only = dist_only;
+}
+
+static void
+on_group_monitor_changed (GFileMonitor *monitor,
+											GFile *file,
+											GFile *other_file,
+											GFileMonitorEvent event_type,
+											gpointer data)
+{
+	AnjutaProjectNode *node = ANJUTA_PROJECT_NODE (data);
+	AnjutaProjectNode *root;
+
+	switch (event_type) {
+		case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
+		case G_FILE_MONITOR_EVENT_CHANGED:
+		case G_FILE_MONITOR_EVENT_DELETED:
+			/* project can be NULL, if the node is dummy node because the
+			 * original one is reloaded. */
+			root = anjuta_project_node_root (node);
+			if (root != NULL) g_signal_emit_by_name (G_OBJECT (root), "file-changed", data);
+			break;
+		default:
+			break;
+	}
+}
+
+AnjutaTokenFile*
+amp_group_set_makefile (AnjutaAmGroupNode *group, GFile *makefile, AmpProject *project)
+{
+	if (group->makefile != NULL) g_object_unref (group->makefile);
+	if (group->tfile != NULL) anjuta_token_file_free (group->tfile);
+	if (makefile != NULL)
+	{
+		AnjutaToken *token;
+		AmpAmScanner *scanner;
+		
+		group->makefile = g_object_ref (makefile);
+		group->tfile = anjuta_token_file_new (makefile);
+
+		token = anjuta_token_file_load (group->tfile, NULL);
+		amp_project_add_file (project, makefile, group->tfile);
+			
+		scanner = amp_am_scanner_new (project, group);
+		group->make_token = amp_am_scanner_parse_token (scanner, anjuta_token_new_static (ANJUTA_TOKEN_FILE, NULL), token, makefile, NULL);
+		amp_am_scanner_free (scanner);
+
+		group->monitor = g_file_monitor_file (makefile, 
+						      									G_FILE_MONITOR_NONE,
+						       									NULL,
+						       									NULL);
+		if (group->monitor != NULL)
+		{
+			g_signal_connect (G_OBJECT (group->monitor),
+					  "changed",
+					  G_CALLBACK (on_group_monitor_changed),
+					  group);
+		}
+	}
+	else
+	{
+		group->makefile = NULL;
+		group->tfile = NULL;
+		group->make_token = NULL;
+		if (group->monitor) g_object_unref (group->monitor);
+		group->monitor = NULL;
+	}
+
+	return group->tfile;
+}
+
+AnjutaToken*
+amp_group_get_makefile_token (AnjutaAmGroupNode *group)
+{
+	return group->make_token;
+}
+
+AnjutaTokenFile *
+amp_group_get_make_token_file (AnjutaAmGroupNode *group)
+{
+	return group->tfile;
+}
+
+gboolean
+amp_group_update_makefile (AnjutaAmGroupNode *group, AnjutaToken *token)
+{
+	return anjuta_token_file_update (group->tfile, token);
+}
+
+gchar *
+amp_group_get_makefile_name (AnjutaAmGroupNode *group)
+{
+	gchar *basename = NULL;
+	
+	if (group->makefile != NULL) 
+	{
+		basename = g_file_get_basename (group->makefile);
+	}
+
+	return basename;
+}
+
+void
+amp_group_update_node (AnjutaAmGroupNode *group, AnjutaAmGroupNode *new_group)
+{
+	gint i;
+	GHashTable *hash;
+
+	if (group->monitor != NULL)
+	{
+		g_object_unref (group->monitor);
+		group->monitor = NULL;
+	}
+	if (group->makefile != NULL)	
+	{
+		g_object_unref (group->makefile);
+		group->monitor = NULL;
+	}
+	if (group->tfile) anjuta_token_file_free (group->tfile);
+	for (i = 0; i < AM_GROUP_TOKEN_LAST; i++)
+	{
+		if (group->tokens[i] != NULL) g_list_free (group->tokens[i]);
+	}
+	if (group->variables) g_hash_table_remove_all (group->variables);
+
+	group->dist_only = new_group->dist_only;
+	group->makefile = new_group->makefile;
+	new_group->makefile = NULL;
+	group->tfile = new_group->tfile;
+	new_group->tfile = NULL;
+	memcpy (group->tokens, new_group->tokens, sizeof (group->tokens));
+	memset (new_group->tokens, 0, sizeof (new_group->tokens));
+	hash = group->variables;
+	group->variables = new_group->variables;
+	new_group->variables = hash;
+	
+	if (group->makefile != NULL)
+	{
+		group->monitor = g_file_monitor_file (group->makefile, 
+					      									G_FILE_MONITOR_NONE,
+					       									NULL,
+					       									NULL);
+		if (group->monitor != NULL)
+		{
+			g_signal_connect (G_OBJECT (group->monitor),
+					  "changed",
+					  G_CALLBACK (on_group_monitor_changed),
+					  group);
+		}
+	}
+}
+
+void
+amp_group_update_variable (AnjutaAmGroupNode *group, AnjutaToken *variable)
+{
+	AnjutaToken *arg;
+	char *name = NULL;
+	AnjutaToken *value = NULL;
+	AmpVariable *var;
+
+	arg = anjuta_token_first_item (variable);
+	name = g_strstrip (anjuta_token_evaluate (arg));
+	arg = anjuta_token_next_item (arg);
+	value = anjuta_token_next_item (arg);
+
+	var = (AmpVariable *)g_hash_table_lookup (group->variables, name);
+	if (var != NULL)
+	{
+		var->value = value;
+	}
+	else
+	{
+		var = amp_variable_new (name, 0, value);
+		g_hash_table_insert (group->variables, var->name, var);
+	}
+
+	if (name) g_free (name);
+}
+
+AnjutaToken*
+amp_group_get_variable_token (AnjutaAmGroupNode *group, AnjutaToken *variable)
+{
+	guint length;
+	const gchar *string;
+	gchar *name;
+	AmpVariable *var;
+		
+	length = anjuta_token_get_length (variable);
+	string = anjuta_token_get_string (variable);
+	if (string[1] == '(')
+	{
+		name = g_strndup (string + 2, length - 3);
+	}
+	else
+	{
+		name = g_strndup (string + 1, 1);
+	}
+	var = g_hash_table_lookup (group->variables, name);
+	g_free (name);
+
+	return var != NULL ? var->value : NULL;
+}
+
+gboolean
+amp_group_set_file (AnjutaAmGroupNode *group, GFile *new_file)
+{
+	g_object_unref (group->base.file);
+	group->base.file = g_object_ref (new_file);
+
+	return TRUE;
+}
+
+AnjutaAmGroupNode*
+amp_group_new (GFile *file, gboolean dist_only, GError **error)
+{
+	AnjutaAmGroupNode *node = NULL;
+	gchar *name;
+
+	/* Validate group name */
+	name = g_file_get_basename (file);
+	if (!name || strlen (name) <= 0)
+	{
+		g_free (name);
+		error_set (error, IANJUTA_PROJECT_ERROR_VALIDATION_FAILED,
+			   _("Please specify group name"));
+		return NULL;
+	}
+	{
+		gboolean failed = FALSE;
+		const gchar *ptr = name;
+		while (*ptr) {
+			if (!isalnum (*ptr) && (strchr ("#$:%+,- = ^_`~", *ptr) == NULL))
+				failed = TRUE;
+			ptr++;
+		}
+		if (failed) {
+			g_free (name);
+			error_set (error, IANJUTA_PROJECT_ERROR_VALIDATION_FAILED,
+				   _("Group name can only contain alphanumeric or \"#$:%+,- = ^_`~\" characters"));
+			return NULL;
+		}
+	}
+	g_free (name);
+	
+	node = g_object_new (ANJUTA_TYPE_AM_GROUP_NODE, NULL);
+	node->base.file = g_object_ref (file);
+	node->dist_only = dist_only;
+
+    return node;	
+}
+
+void
+amp_group_free (AnjutaAmGroupNode *node)
+{
+	g_object_unref (G_OBJECT (node));
+}
+
+
+/* GObjet implementation
+ *---------------------------------------------------------------------------*/
+
+
+typedef struct _AnjutaAmGroupNodeClass AnjutaAmGroupNodeClass;
+
+struct _AnjutaAmGroupNodeClass {
+	AmpNodeClass parent_class;
+};
+
+G_DEFINE_DYNAMIC_TYPE (AnjutaAmGroupNode, anjuta_am_group_node, AMP_TYPE_NODE);
+
+static void
+anjuta_am_group_node_init (AnjutaAmGroupNode *node)
+{
+	node->base.type = ANJUTA_PROJECT_GROUP;
+	node->base.native_properties = amp_get_group_property_list();
+	node->base.state = ANJUTA_PROJECT_CAN_ADD_GROUP |
+						ANJUTA_PROJECT_CAN_ADD_TARGET |
+						ANJUTA_PROJECT_CAN_ADD_SOURCE |
+						ANJUTA_PROJECT_CAN_REMOVE |
+						ANJUTA_PROJECT_CAN_SAVE;
+	node->dist_only = FALSE;
+	node->variables = NULL;
+	node->makefile = NULL;
+	node->variables = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)amp_variable_free);
+	node->monitor = NULL;
+	memset (node->tokens, 0, sizeof (node->tokens));
+}
+
+static void
+anjuta_am_group_node_dispose (GObject *object)
+{
+	AnjutaAmGroupNode *node = ANJUTA_AM_GROUP_NODE (object);
+
+	if (node->monitor) g_object_unref (node->monitor);
+	node->monitor = NULL;
+	
+	G_OBJECT_CLASS (anjuta_am_group_node_parent_class)->dispose (object);
+}
+
+static void
+anjuta_am_group_node_finalize (GObject *object)
+{
+	AnjutaAmGroupNode *node = ANJUTA_AM_GROUP_NODE (object);
+	gint i;
+	
+	g_list_foreach (node->base.custom_properties, (GFunc)amp_property_free, NULL);
+	if (node->tfile) anjuta_token_file_free (node->tfile);
+	if (node->makefile) g_object_unref (node->makefile);
+
+	for (i = 0; i < AM_GROUP_TOKEN_LAST; i++)
+	{
+		if (node->tokens[i] != NULL) g_list_free (node->tokens[i]);
+	}
+	if (node->variables) g_hash_table_destroy (node->variables);
+
+	G_OBJECT_CLASS (anjuta_am_group_node_parent_class)->finalize (object);
+}
+
+static void
+anjuta_am_group_node_class_init (AnjutaAmGroupNodeClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+	
+	object_class->finalize = anjuta_am_group_node_finalize;
+	object_class->dispose = anjuta_am_group_node_dispose;
+}
+
+static void
+anjuta_am_group_node_class_finalize (AnjutaAmGroupNodeClass *klass)
+{
+}
+
+void
+anjuta_am_group_node_register (GTypeModule *module)
+{
+	anjuta_am_group_node_register_type (module);
+}
diff --git a/plugins/am-project/amp-group.h b/plugins/am-project/amp-group.h
new file mode 100644
index 0000000..2889320
--- /dev/null
+++ b/plugins/am-project/amp-group.h
@@ -0,0 +1,84 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* amp-group.h
+ *
+ * Copyright (C) 2010  Sébastien Granjoux
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _AMP_GROUP_H_
+#define _AMP_GROUP_H_
+
+#include "am-project-private.h"
+#include "am-scanner.h"
+
+#include <glib-object.h>
+
+#include <libanjuta/anjuta-project.h>
+#include <libanjuta/anjuta-token.h>
+#include <libanjuta/anjuta-token-file.h>
+
+G_BEGIN_DECLS
+
+/* Type macros
+ *---------------------------------------------------------------------------*/
+
+#define ANJUTA_TYPE_AM_GROUP_NODE			(anjuta_am_group_node_get_type ())
+#define ANJUTA_AM_GROUP_NODE(obj)				(G_TYPE_CHECK_INSTANCE_CAST ((obj), ANJUTA_TYPE_AM_GROUP_NODE, AnjutaAmGroupNode))
+
+GType anjuta_am_group_node_get_type (void) G_GNUC_CONST;
+
+typedef enum {
+	AM_GROUP_TOKEN_CONFIGURE,
+	AM_GROUP_TOKEN_SUBDIRS,
+	AM_GROUP_TOKEN_DIST_SUBDIRS,
+	AM_GROUP_TARGET,
+	AM_GROUP_TOKEN_LAST
+} AmpGroupTokenCategory;
+
+typedef struct _AmpVariable AmpVariable;
+
+struct _AmpVariable {
+	gchar *name;
+	AnjutaTokenType assign;
+	AnjutaToken *value;
+};
+
+void anjuta_am_group_node_register (GTypeModule *module);
+
+AmpVariable* amp_variable_new (gchar *name, AnjutaTokenType assign, AnjutaToken *value);
+
+
+void amp_group_add_token (AnjutaAmGroupNode *group, AnjutaToken *token, AmpGroupTokenCategory category);
+GList * amp_group_get_token (AnjutaAmGroupNode *group, AmpGroupTokenCategory category);
+AnjutaToken* amp_group_get_first_token (AnjutaAmGroupNode *group, AmpGroupTokenCategory category);
+void amp_group_set_dist_only (AnjutaAmGroupNode *group, gboolean dist_only);
+AnjutaTokenFile* amp_group_set_makefile (AnjutaAmGroupNode *group, GFile *makefile, AmpProject *project);
+AnjutaToken* amp_group_get_makefile_token (AnjutaAmGroupNode *group);
+AnjutaTokenFile *amp_group_get_make_token_file (AnjutaAmGroupNode *group);
+gchar *amp_group_get_makefile_name (AnjutaAmGroupNode *group);
+gboolean amp_group_update_makefile (AnjutaAmGroupNode *group, AnjutaToken *token);
+void amp_group_update_variable (AnjutaAmGroupNode *group, AnjutaToken *variable);
+AnjutaToken* amp_group_get_variable_token (AnjutaAmGroupNode *group, AnjutaToken *variable);
+AnjutaAmGroupNode* amp_group_new (GFile *file, gboolean dist_only, GError **error);
+void amp_group_free (AnjutaAmGroupNode *node);
+void amp_group_update_node (AnjutaAmGroupNode *node, AnjutaAmGroupNode *new_node);
+gboolean amp_group_set_file (AnjutaAmGroupNode *group, GFile *new_file);
+
+
+G_END_DECLS
+
+#endif /* _AMP_GROUP_H_ */
diff --git a/plugins/am-project/amp-module.c b/plugins/am-project/amp-module.c
new file mode 100644
index 0000000..a9b1274
--- /dev/null
+++ b/plugins/am-project/amp-module.c
@@ -0,0 +1,148 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* amp-module.c
+ *
+ * Copyright (C) 2009  Sébastien Granjoux
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "amp-module.h"
+
+#include "amp-node.h"
+#include "am-scanner.h"
+#include "am-properties.h"
+
+
+#include <libanjuta/interfaces/ianjuta-project.h>
+
+#include <libanjuta/anjuta-debug.h>
+
+#include <glib/gi18n.h>
+
+#include <memory.h>
+#include <string.h>
+#include <ctype.h>
+
+/* Types
+ *---------------------------------------------------------------------------*/
+
+struct _AnjutaAmModuleNode {
+	AnjutaProjectNode base;
+	AnjutaToken *module;
+};
+
+
+/* Module objects
+ *---------------------------------------------------------------------------*/
+
+void
+amp_module_add_token (AnjutaAmModuleNode *module, AnjutaToken *token)
+{
+	gchar *name;
+	
+	module->module = token;
+	name = anjuta_token_evaluate (anjuta_token_first_item (token));
+	if (name != NULL)
+	{
+		g_free (module->base.name);
+		module->base.name = name;
+	}
+}
+
+AnjutaToken *
+amp_module_get_token (AnjutaAmModuleNode *node)
+{
+	return node->module;
+}
+
+void
+amp_module_update_node (AnjutaAmModuleNode *node, AnjutaAmModuleNode *new_node)
+{
+	node->module = new_node->module;
+}
+
+AnjutaAmModuleNode*
+amp_module_new (const gchar *name, GError **error)
+{
+	AnjutaAmModuleNode *module = NULL;
+
+	module = g_object_new (ANJUTA_TYPE_AM_MODULE_NODE, NULL);
+	module->base.name = g_strdup (name);;
+
+	return module;
+}
+
+void
+amp_module_free (AnjutaAmModuleNode *node)
+{
+	g_object_unref (G_OBJECT (node));
+}
+
+
+/* GObjet implementation
+ *---------------------------------------------------------------------------*/
+
+typedef struct _AnjutaAmModuleNodeClass AnjutaAmModuleNodeClass;
+
+struct _AnjutaAmModuleNodeClass {
+	AmpNodeClass parent_class;
+};
+
+G_DEFINE_DYNAMIC_TYPE (AnjutaAmModuleNode, anjuta_am_module_node, AMP_TYPE_NODE);
+
+static void
+anjuta_am_module_node_init (AnjutaAmModuleNode *node)
+{
+	node->base.type = ANJUTA_PROJECT_MODULE;
+	node->base.native_properties = amp_get_module_property_list();
+	node->base.state = ANJUTA_PROJECT_CAN_ADD_PACKAGE |
+						ANJUTA_PROJECT_CAN_REMOVE;
+	node->module = NULL;
+}
+
+static void
+anjuta_am_module_node_finalize (GObject *object)
+{
+	AnjutaAmModuleNode *module = ANJUTA_AM_MODULE_NODE (object);
+
+	g_list_foreach (module->base.custom_properties, (GFunc)amp_property_free, NULL);
+	
+	G_OBJECT_CLASS (anjuta_am_module_node_parent_class)->finalize (object);
+}
+
+static void
+anjuta_am_module_node_class_init (AnjutaAmModuleNodeClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+	
+	object_class->finalize = anjuta_am_module_node_finalize;
+}
+
+static void
+anjuta_am_module_node_class_finalize (AnjutaAmModuleNodeClass *klass)
+{
+}
+
+void
+anjuta_am_module_node_register (GTypeModule *module)
+{
+	anjuta_am_module_node_register_type (module);
+}
diff --git a/plugins/am-project/amp-module.h b/plugins/am-project/amp-module.h
new file mode 100644
index 0000000..f819663
--- /dev/null
+++ b/plugins/am-project/amp-module.h
@@ -0,0 +1,54 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* amp-module.h
+ *
+ * Copyright (C) 2010  Sébastien Granjoux
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _AMP_MODULE_H_
+#define _AMP_MODULE_H_
+
+#include "am-project.h"
+
+#include <glib-object.h>
+
+#include <libanjuta/anjuta-project.h>
+#include <libanjuta/anjuta-token.h>
+#include <libanjuta/anjuta-token-file.h>
+
+G_BEGIN_DECLS
+
+/* Type macros
+ *---------------------------------------------------------------------------*/
+
+#define ANJUTA_TYPE_AM_MODULE_NODE			(anjuta_am_module_node_get_type ())
+#define ANJUTA_AM_MODULE_NODE(obj)				(G_TYPE_CHECK_INSTANCE_CAST ((obj), ANJUTA_TYPE_AM_MODULE_NODE, AnjutaAmModuleNode))
+
+GType anjuta_am_module_node_get_type (void) G_GNUC_CONST;
+
+
+void anjuta_am_module_node_register (GTypeModule *module);
+
+AnjutaAmModuleNode* amp_module_new (const gchar *name, GError **error);
+void amp_module_free (AnjutaAmModuleNode *node);
+AnjutaToken *amp_module_get_token (AnjutaAmModuleNode *node);
+void amp_module_add_token (AnjutaAmModuleNode *group, AnjutaToken *token);
+void amp_module_update_node (AnjutaAmModuleNode *node, AnjutaAmModuleNode *new_node);
+
+G_END_DECLS
+
+#endif /* _AMP_MODULE_H_ */
diff --git a/plugins/am-project/amp-node.c b/plugins/am-project/amp-node.c
new file mode 100644
index 0000000..36fa3f7
--- /dev/null
+++ b/plugins/am-project/amp-node.c
@@ -0,0 +1,82 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* amp-node.c
+ *
+ * Copyright (C) 2009  Sébastien Granjoux
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "amp-node.h"
+#include "am-scanner.h"
+#include "am-properties.h"
+
+
+#include <libanjuta/interfaces/ianjuta-project.h>
+
+#include <libanjuta/anjuta-debug.h>
+
+#include <glib/gi18n.h>
+
+#include <memory.h>
+#include <string.h>
+#include <ctype.h>
+
+
+
+/* GObjet implementation
+ *---------------------------------------------------------------------------*/
+
+G_DEFINE_DYNAMIC_TYPE (AmpNode, amp_node, ANJUTA_TYPE_PROJECT_NODE);
+
+static void
+amp_node_init (AmpNode *node)
+{
+}
+
+static void
+amp_node_finalize (GObject *object)
+{
+	AmpNode *node = AMP_NODE (object);
+
+	//g_list_foreach (node->parent.custom_properties, (GFunc)amp_property_free, NULL);
+	
+	G_OBJECT_CLASS (amp_node_parent_class)->finalize (object);
+}
+
+static void
+amp_node_class_init (AmpNodeClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+	
+	object_class->finalize = amp_node_finalize;
+}
+
+static void
+amp_node_class_finalize (AmpNodeClass *klass)
+{
+}
+
+
+void
+amp_node_register (GTypeModule *module)
+{
+	amp_node_register_type (module);
+}
diff --git a/plugins/am-project/amp-node.h b/plugins/am-project/amp-node.h
new file mode 100644
index 0000000..2db8852
--- /dev/null
+++ b/plugins/am-project/amp-node.h
@@ -0,0 +1,69 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* amp-node.h
+ *
+ * Copyright (C) 2010  Sébastien Granjoux
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _AMP_NODE_H_
+#define _AMP_NODE_H_
+
+#include <glib-object.h>
+
+#include <libanjuta/anjuta-project.h>
+#include <libanjuta/anjuta-token.h>
+#include <libanjuta/anjuta-token-file.h>
+
+G_BEGIN_DECLS
+
+/* Type macros
+ *---------------------------------------------------------------------------*/
+
+#define AMP_TYPE_NODE                   (amp_node_get_type ())
+#define AMP_NODE(object)                (G_TYPE_CHECK_INSTANCE_CAST ((object), AMP_TYPE_NODE, AmpNode))
+#define AMP_NODE_CLASS(klass)           (G_TYPE_CHECK_CLASS_CAST ((klass), AMP_TYPE_NODE, AmpNodeClass))
+#define AMP_IS_NODE(object)             (G_TYPE_CHECK_INSTANCE_TYPE ((object), AMP_TYPE_NODE))
+#define AMP_IS_NODE_CLASS(klass)        (G_TYPE_CHECK_CLASS_TYPE ((klass), AMP_TYPE_NODE))
+#define AMP_NODE_GET_CLASS(obj)         (G_TYPE_INSTANCE_GET_CLASS ((obj), AMP_TYPE_NODE, AmpNodeClass))
+
+
+typedef struct _AmpNode                 AmpNode;
+typedef struct _AmpNodeClass            AmpNodeClass;
+
+
+/**
+ * AmpNode:
+ *
+ * An object representing a autotool project node, by example a directory, a target or a source file.
+ */
+struct _AmpNode
+{
+	AnjutaProjectNode   parent;
+};
+
+struct _AmpNodeClass
+{
+	AnjutaProjectNodeClass  parent_class;
+};
+
+GType amp_node_get_type (void) G_GNUC_CONST;
+
+void amp_node_register (GTypeModule *module);
+
+G_END_DECLS
+
+#endif /* _AMP_NODE_H_ */
diff --git a/plugins/am-project/amp-package.c b/plugins/am-project/amp-package.c
new file mode 100644
index 0000000..41abd10
--- /dev/null
+++ b/plugins/am-project/amp-package.c
@@ -0,0 +1,156 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* am-package.c
+ *
+ * Copyright (C) 2009  Sébastien Granjoux
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "amp-package.h"
+
+#include "amp-node.h"
+#include "am-scanner.h"
+#include "am-properties.h"
+
+
+#include <libanjuta/interfaces/ianjuta-project.h>
+
+#include <libanjuta/anjuta-debug.h>
+
+#include <glib/gi18n.h>
+
+#include <memory.h>
+#include <string.h>
+#include <ctype.h>
+
+/* Types
+ *---------------------------------------------------------------------------*/
+
+struct _AnjutaAmPackageNode {
+	AnjutaProjectNode base;
+	gchar *version;
+	AnjutaToken *token;
+};
+
+
+
+/* Package objects
+ *---------------------------------------------------------------------------*/
+
+AnjutaAmPackageNode*
+amp_package_new (const gchar *name, GError **error)
+{
+	AnjutaAmPackageNode *node = NULL;
+
+	node = g_object_new (ANJUTA_TYPE_AM_PACKAGE_NODE, NULL);
+	node->base.name = g_strdup (name);
+
+	return node;
+}
+
+void
+amp_package_free (AnjutaAmPackageNode *node)
+{
+	g_object_unref (G_OBJECT (node));
+}
+
+void
+amp_package_set_version (AnjutaAmPackageNode *node, const gchar *compare, const gchar *version)
+{
+	g_return_if_fail (node != NULL);
+	g_return_if_fail ((version == NULL) || (compare != NULL));
+
+	g_free (node->version);
+	node->version = version != NULL ? g_strconcat (compare, version, NULL) : NULL;
+}
+
+AnjutaToken *
+amp_package_get_token (AnjutaAmPackageNode *node)
+{
+	return node->token;
+}
+
+void
+amp_package_add_token (AnjutaAmPackageNode *node, AnjutaToken *token)
+{
+	node->token = token;
+}
+
+void
+amp_package_update_node (AnjutaAmPackageNode *node, AnjutaAmPackageNode *new_node)
+{
+	g_return_if_fail (new_node != NULL);	
+
+	node->token = new_node->token;
+	g_free (node->version);
+	node->version = new_node->version;
+	new_node->version = NULL;
+}
+
+
+/* GObjet implementation
+ *---------------------------------------------------------------------------*/
+
+typedef struct _AnjutaAmPackageNodeClass AnjutaAmPackageNodeClass;
+
+struct _AnjutaAmPackageNodeClass {
+	AmpNodeClass parent_class;
+};
+
+G_DEFINE_DYNAMIC_TYPE (AnjutaAmPackageNode, anjuta_am_package_node, AMP_TYPE_NODE);
+
+static void
+anjuta_am_package_node_init (AnjutaAmPackageNode *node)
+{
+	node->base.type = ANJUTA_PROJECT_PACKAGE;
+	node->base.native_properties = amp_get_package_property_list();
+	node->base.state =  ANJUTA_PROJECT_CAN_REMOVE;
+	node->version = NULL;
+}
+
+static void
+anjuta_am_package_node_finalize (GObject *object)
+{
+	AnjutaAmPackageNode *node = ANJUTA_AM_PACKAGE_NODE (object);
+
+	g_list_foreach (node->base.custom_properties, (GFunc)amp_property_free, NULL);
+	
+	G_OBJECT_CLASS (anjuta_am_package_node_parent_class)->finalize (object);
+}
+
+static void
+anjuta_am_package_node_class_init (AnjutaAmPackageNodeClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+	
+	object_class->finalize = anjuta_am_package_node_finalize;
+}
+
+static void
+anjuta_am_package_node_class_finalize (AnjutaAmPackageNodeClass *klass)
+{
+}
+
+void
+anjuta_am_package_node_register (GTypeModule *module)
+{
+	anjuta_am_package_node_register_type (module);
+}
diff --git a/plugins/am-project/amp-package.h b/plugins/am-project/amp-package.h
new file mode 100644
index 0000000..bcaa624
--- /dev/null
+++ b/plugins/am-project/amp-package.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* amp-package.h
+ *
+ * Copyright (C) 2010  Sébastien Granjoux
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _AMP_PACKAGE_H_
+#define _AMP_PACKAGE_H_
+
+#include "am-project.h"
+
+#include <glib-object.h>
+
+#include <libanjuta/anjuta-project.h>
+#include <libanjuta/anjuta-token.h>
+#include <libanjuta/anjuta-token-file.h>
+
+G_BEGIN_DECLS
+
+/* Type macros
+ *---------------------------------------------------------------------------*/
+
+#define ANJUTA_TYPE_AM_PACKAGE_NODE			(anjuta_am_package_node_get_type ())
+#define ANJUTA_AM_PACKAGE_NODE(obj)				(G_TYPE_CHECK_INSTANCE_CAST ((obj), ANJUTA_TYPE_AM_PACKAGE_NODE, AnjutaAmPackageNode))
+
+GType anjuta_am_package_node_get_type (void) G_GNUC_CONST;
+
+
+void anjuta_am_package_node_register (GTypeModule *module);
+
+AnjutaAmPackageNode* amp_package_new (const gchar *name, GError **error);
+void amp_package_free (AnjutaAmPackageNode *node);
+void amp_package_set_version (AnjutaAmPackageNode *node, const gchar *compare, const gchar *version);
+AnjutaToken *amp_package_get_token (AnjutaAmPackageNode *node);
+void amp_package_add_token (AnjutaAmPackageNode *node, AnjutaToken *token);
+void amp_package_update_node (AnjutaAmPackageNode *node, AnjutaAmPackageNode *new_node);
+
+G_END_DECLS
+
+#endif /* _AMP_PACKAGE_H_ */
diff --git a/plugins/am-project/amp-source.c b/plugins/am-project/amp-source.c
new file mode 100644
index 0000000..69859b7
--- /dev/null
+++ b/plugins/am-project/amp-source.c
@@ -0,0 +1,150 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* am-source.c
+ *
+ * Copyright (C) 2009  Sébastien Granjoux
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "amp-source.h"
+
+#include "amp-node.h"
+#include "am-scanner.h"
+#include "am-properties.h"
+
+
+#include <libanjuta/interfaces/ianjuta-project.h>
+
+#include <libanjuta/anjuta-debug.h>
+
+#include <glib/gi18n.h>
+
+#include <memory.h>
+#include <string.h>
+#include <ctype.h>
+
+/* Types
+ *---------------------------------------------------------------------------*/
+
+struct _AnjutaAmSourceNode {
+	AnjutaProjectNode base;
+	AnjutaToken* token;	
+};
+
+
+
+
+/* Source object
+ *---------------------------------------------------------------------------*/
+
+AnjutaToken *
+amp_source_get_token (AnjutaAmSourceNode *node)
+{
+	return node->token;
+}
+
+void
+amp_source_add_token (AnjutaAmSourceNode *node, AnjutaToken *token)
+{
+	node->token = token;
+}
+
+void
+amp_source_update_node (AnjutaAmSourceNode *node, AnjutaAmSourceNode *new_node)
+{
+	node->token = new_node->token;
+}
+
+AnjutaProjectNode*
+amp_source_new (GFile *file, GError **error)
+{
+	AnjutaAmSourceNode *node = NULL;
+
+	node = g_object_new (ANJUTA_TYPE_AM_SOURCE_NODE, NULL);
+	node->base.file = g_object_ref (file);
+
+	return ANJUTA_PROJECT_NODE (node);
+}
+
+gboolean
+amp_source_set_file (AnjutaAmSourceNode *source, GFile *new_file)
+{
+	g_object_unref (source->base.file);
+	source->base.file = g_object_ref (new_file);
+
+	return TRUE;
+}
+
+void
+amp_source_free (AnjutaAmSourceNode *node)
+{
+	g_object_unref (G_OBJECT (node));
+}
+
+
+/* GObjet implementation
+ *---------------------------------------------------------------------------*/
+
+typedef struct _AnjutaAmSourceNodeClass AnjutaAmSourceNodeClass;
+
+struct _AnjutaAmSourceNodeClass {
+	AmpNodeClass parent_class;
+};
+
+G_DEFINE_DYNAMIC_TYPE (AnjutaAmSourceNode, anjuta_am_source_node, AMP_TYPE_NODE);
+
+static void
+anjuta_am_source_node_init (AnjutaAmSourceNode *node)
+{
+	node->base.type = ANJUTA_PROJECT_SOURCE;
+	node->base.native_properties = amp_get_source_property_list();
+	node->base.state = ANJUTA_PROJECT_CAN_REMOVE;
+	node->token = NULL;
+}
+
+static void
+anjuta_am_source_node_finalize (GObject *object)
+{
+	AnjutaAmSourceNode *node = ANJUTA_AM_SOURCE_NODE (object);
+
+	g_list_foreach (node->base.custom_properties, (GFunc)amp_property_free, NULL);
+	G_OBJECT_CLASS (anjuta_am_source_node_parent_class)->finalize (object);
+}
+
+static void
+anjuta_am_source_node_class_init (AnjutaAmSourceNodeClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+	
+	object_class->finalize = anjuta_am_source_node_finalize;
+}
+
+static void
+anjuta_am_source_node_class_finalize (AnjutaAmSourceNodeClass *klass)
+{
+}
+
+void
+anjuta_am_source_node_register (GTypeModule *module)
+{
+	anjuta_am_source_node_register_type (module);
+}
+
diff --git a/plugins/am-project/amp-source.h b/plugins/am-project/amp-source.h
new file mode 100644
index 0000000..d50b954
--- /dev/null
+++ b/plugins/am-project/amp-source.h
@@ -0,0 +1,58 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* amp-source.h
+ *
+ * Copyright (C) 2010  Sébastien Granjoux
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _AMP_SOURCE_H_
+#define _AMP_SOURCE_H_
+
+#include "am-project-private.h"
+#include "am-scanner.h"
+
+#include <glib-object.h>
+
+#include <libanjuta/anjuta-project.h>
+#include <libanjuta/anjuta-token.h>
+#include <libanjuta/anjuta-token-file.h>
+
+G_BEGIN_DECLS
+
+/* Type macros
+ *---------------------------------------------------------------------------*/
+
+#define ANJUTA_TYPE_AM_SOURCE_NODE			(anjuta_am_source_node_get_type ())
+#define ANJUTA_AM_SOURCE_NODE(obj)			(G_TYPE_CHECK_INSTANCE_CAST ((obj), ANJUTA_TYPE_AM_SOURCE_NODE, AnjutaAmSourceNode))
+
+GType anjuta_am_source_node_get_type (void) G_GNUC_CONST;
+
+
+
+void anjuta_am_source_node_register (GTypeModule *module);
+
+AnjutaProjectNode* amp_source_new (GFile *file, GError **error);
+void amp_source_free (AnjutaAmSourceNode *node);
+AnjutaToken *amp_source_get_token (AnjutaAmSourceNode *node);
+void amp_source_add_token (AnjutaAmSourceNode *node, AnjutaToken *token);
+void amp_source_update_node (AnjutaAmSourceNode *node, AnjutaAmSourceNode *new_node);
+gboolean amp_source_set_file (AnjutaAmSourceNode *source, GFile *new_file);
+
+
+G_END_DECLS
+
+#endif /* _AMP_SOURCE_H_ */
diff --git a/plugins/am-project/amp-target.c b/plugins/am-project/amp-target.c
new file mode 100644
index 0000000..eea355e
--- /dev/null
+++ b/plugins/am-project/amp-target.c
@@ -0,0 +1,355 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* amp-target.c
+ *
+ * Copyright (C) 2010  Sébastien Granjoux
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "amp-target.h"
+
+#include "amp-node.h"
+#include "am-scanner.h"
+#include "am-properties.h"
+
+
+#include <libanjuta/interfaces/ianjuta-project.h>
+
+#include <libanjuta/anjuta-debug.h>
+
+#include <glib/gi18n.h>
+
+#include <memory.h>
+#include <string.h>
+#include <ctype.h>
+
+
+/* Types
+ *---------------------------------------------------------------------------*/
+
+struct _AnjutaAmTargetNode {
+	AnjutaProjectNode base;
+	gchar *install;
+	gint flags;
+	GList* tokens;	
+};
+
+
+
+/* Helper functions
+ *---------------------------------------------------------------------------*/
+
+static void
+error_set (GError **error, gint code, const gchar *message)
+{
+        if (error != NULL) {
+                if (*error != NULL) {
+                        gchar *tmp;
+
+                        /* error already created, just change the code
+                         * and prepend the string */
+                        (*error)->code = code;
+                        tmp = (*error)->message;
+                        (*error)->message = g_strconcat (message, "\n\n", tmp, NULL);
+                        g_free (tmp);
+
+                } else {
+                        *error = g_error_new_literal (IANJUTA_PROJECT_ERROR,
+                                                      code,
+                                                      message);
+                }
+        }
+}
+
+
+/* Tagged token list
+ *
+ * This structure is used to keep a list of useful tokens in each
+ * node. It is a two levels list. The level lists all kinds of token
+ * and has a pointer of another list of token of  this kind.
+ *---------------------------------------------------------------------------*/
+
+typedef struct _TaggedTokenItem {
+	AmTokenType type;
+	GList *tokens;
+} TaggedTokenItem;
+
+
+static TaggedTokenItem *
+tagged_token_item_new (AmTokenType type)
+{
+    TaggedTokenItem *item;
+
+	item = g_slice_new0(TaggedTokenItem); 
+
+	item->type = type;
+
+	return item;
+}
+
+static void
+tagged_token_item_free (TaggedTokenItem* item)
+{
+	g_list_free (item->tokens);
+    g_slice_free (TaggedTokenItem, item);
+}
+
+static gint
+tagged_token_item_compare (gconstpointer a, gconstpointer b)
+{
+	return ((TaggedTokenItem *)a)->type - (GPOINTER_TO_INT(b));
+}
+
+static GList*
+tagged_token_list_insert (GList *list, AmTokenType type, AnjutaToken *token)
+{
+	GList *existing;
+	
+	existing = g_list_find_custom (list, GINT_TO_POINTER (type), tagged_token_item_compare);
+	if (existing == NULL)
+	{
+		/* Add a new item */
+		TaggedTokenItem *item;
+
+		item = tagged_token_item_new (type);
+		list = g_list_prepend (list, item);
+		existing = list;
+	}
+
+	((TaggedTokenItem *)(existing->data))->tokens = g_list_prepend (((TaggedTokenItem *)(existing->data))->tokens, token);
+
+	return list;
+}
+
+static GList*
+tagged_token_list_get (GList *list, AmTokenType type)
+{
+	GList *existing;
+	GList *tokens = NULL;
+	
+	existing = g_list_find_custom (list, GINT_TO_POINTER (type), tagged_token_item_compare);
+	if (existing != NULL)
+	{
+		tokens = ((TaggedTokenItem *)(existing->data))->tokens;
+	}
+	
+	return tokens;
+}
+
+static AnjutaTokenType
+tagged_token_list_next (GList *list, AmTokenType type)
+{
+	AnjutaTokenType best = 0;
+	
+	for (list = g_list_first (list); list != NULL; list = g_list_next (list))
+	{
+		TaggedTokenItem *item = (TaggedTokenItem *)list->data;
+
+		if ((item->type > type) && ((best == 0) || (item->type < best)))
+		{
+			best = item->type;
+		}
+	}
+
+	return best;
+}
+
+static GList*
+tagged_token_list_free (GList *list)
+{
+	g_list_foreach (list, (GFunc)tagged_token_item_free, NULL);
+	g_list_free (list);
+
+	return NULL;
+}
+
+
+
+
+/* Target object
+ *---------------------------------------------------------------------------*/
+
+void
+amp_target_set_type (AnjutaAmTargetNode *target, AmTokenType type)
+{
+	target->base.type = ANJUTA_PROJECT_TARGET | type;
+	target->base.native_properties = amp_get_target_property_list(type);
+}
+
+void
+amp_target_add_token (AnjutaAmTargetNode *target, AmTokenType type, AnjutaToken *token)
+{
+	target->tokens = tagged_token_list_insert (target->tokens, type, token);
+}
+
+GList *
+amp_target_get_token (AnjutaAmTargetNode *target, AmTokenType type)
+{
+	return tagged_token_list_get	(target->tokens, type);
+}
+
+AnjutaTokenType
+amp_target_get_first_token_type (AnjutaAmTargetNode *target)
+{
+	return tagged_token_list_next (target->tokens, 0);
+}
+
+AnjutaTokenType
+amp_target_get_next_token_type (AnjutaAmTargetNode *target, AnjutaTokenType type)
+{
+	return tagged_token_list_next (target->tokens, type);
+}
+
+void
+amp_target_update_node (AnjutaAmTargetNode *node, AnjutaAmTargetNode *new_node)
+{
+	g_free (node->install);
+	g_list_free (node->tokens);
+
+	node->install = new_node->install;
+	new_node->install = NULL;
+	node->flags = new_node->flags;
+	node->tokens = new_node->tokens;
+	new_node->tokens = NULL;
+}
+
+AnjutaAmTargetNode*
+amp_target_new (const gchar *name, AnjutaProjectNodeType type, const gchar *install, gint flags, GError **error)
+{
+	AnjutaAmTargetNode *node = NULL;
+	const gchar *basename;
+
+	/* Validate target name */
+	if (!name || strlen (name) <= 0)
+	{
+		error_set (error, IANJUTA_PROJECT_ERROR_VALIDATION_FAILED,
+			   _("Please specify target name"));
+		return NULL;
+	}
+	{
+		gboolean failed = FALSE;
+		const gchar *ptr = name;
+		while (*ptr) {
+			if (!isalnum (*ptr) && *ptr != '.' && *ptr != '-' &&
+			    *ptr != '_' && *ptr != '/')
+				failed = TRUE;
+			ptr++;
+		}
+		if (failed) {
+			error_set (error, IANJUTA_PROJECT_ERROR_VALIDATION_FAILED,
+				   _("Target name can only contain alphanumeric, '_', '-', '/' or '.' characters"));
+			return NULL;
+		}
+	}
+
+	/* Skip eventual directory name */
+	basename = strrchr (name, '/');
+	basename = basename == NULL ? name : basename + 1;
+		
+	
+	if ((type & ANJUTA_PROJECT_ID_MASK) == ANJUTA_PROJECT_SHAREDLIB) {
+		if (strlen (basename) < 7 ||
+		    strncmp (basename, "lib", strlen("lib")) != 0 ||
+		    strcmp (&basename[strlen(basename) - 3], ".la") != 0) {
+			error_set (error, IANJUTA_PROJECT_ERROR_VALIDATION_FAILED,
+				   _("Shared library target name must be of the form 'libxxx.la'"));
+			return NULL;
+		}
+	}
+	else if ((type & ANJUTA_PROJECT_ID_MASK) == ANJUTA_PROJECT_STATICLIB) {
+		if (strlen (basename) < 6 ||
+		    strncmp (basename, "lib", strlen("lib")) != 0 ||
+		    strcmp (&basename[strlen(basename) - 2], ".a") != 0) {
+			error_set (error, IANJUTA_PROJECT_ERROR_VALIDATION_FAILED,
+				   _("Static library target name must be of the form 'libxxx.a'"));
+			return NULL;
+		}
+	}
+	
+	node = g_object_new (ANJUTA_TYPE_AM_TARGET_NODE, NULL);
+	amp_target_set_type (node, type);
+	node->base.name = g_strdup (name);
+	node->install = g_strdup (install);
+	node->flags = flags;
+	
+	return node;
+}
+
+void
+amp_target_free (AnjutaAmTargetNode *node)
+{
+	g_object_unref (G_OBJECT (node));
+}
+
+
+/* GObjet implementation
+ *---------------------------------------------------------------------------*/
+
+typedef struct _AnjutaAmTargetNodeClass AnjutaAmTargetNodeClass;
+
+struct _AnjutaAmTargetNodeClass {
+	AmpNodeClass parent_class;
+};
+
+G_DEFINE_DYNAMIC_TYPE (AnjutaAmTargetNode, anjuta_am_target_node, AMP_TYPE_NODE);
+
+static void
+anjuta_am_target_node_init (AnjutaAmTargetNode *node)
+{
+	node->base.type = ANJUTA_PROJECT_TARGET;
+	node->base.state = ANJUTA_PROJECT_CAN_ADD_SOURCE |
+						ANJUTA_PROJECT_CAN_ADD_MODULE |
+						ANJUTA_PROJECT_CAN_REMOVE;
+	node->install = NULL;
+	node->flags = 0;
+	node->tokens = NULL;
+}
+
+static void
+anjuta_am_target_node_finalize (GObject *object)
+{
+	AnjutaAmTargetNode *node = ANJUTA_AM_TARGET_NODE (object);
+
+	g_list_foreach (node->base.custom_properties, (GFunc)amp_property_free, NULL);
+	tagged_token_list_free (node->tokens);
+	node->tokens = NULL;
+	
+	G_OBJECT_CLASS (anjuta_am_target_node_parent_class)->finalize (object);
+}
+
+static void
+anjuta_am_target_node_class_init (AnjutaAmTargetNodeClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+	
+	object_class->finalize = anjuta_am_target_node_finalize;
+}
+
+static void
+anjuta_am_target_node_class_finalize (AnjutaAmTargetNodeClass *klass)
+{
+}
+
+void
+anjuta_am_target_node_register (GTypeModule *module)
+{
+	anjuta_am_target_node_register_type (module);
+}
diff --git a/plugins/am-project/amp-target.h b/plugins/am-project/amp-target.h
new file mode 100644
index 0000000..5dd739e
--- /dev/null
+++ b/plugins/am-project/amp-target.h
@@ -0,0 +1,75 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* amp-target.h
+ *
+ * Copyright (C) 2010  Sébastien Granjoux
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _AMP_TARGET_H_
+#define _AMP_TARGET_H_
+
+#include "am-project-private.h"
+#include "am-scanner.h"
+
+#include <glib-object.h>
+
+#include <libanjuta/anjuta-project.h>
+#include <libanjuta/anjuta-token.h>
+#include <libanjuta/anjuta-token-file.h>
+
+G_BEGIN_DECLS
+
+/* Type macros
+ *---------------------------------------------------------------------------*/
+
+#define ANJUTA_TYPE_AM_TARGET_NODE			(anjuta_am_target_node_get_type ())
+#define ANJUTA_AM_TARGET_NODE(obj)				(G_TYPE_CHECK_INSTANCE_CAST ((obj), ANJUTA_TYPE_AM_TARGET_NODE, AnjutaAmTargetNode))
+
+GType anjuta_am_target_node_get_type (void) G_GNUC_CONST;
+
+typedef enum {
+	AM_TARGET_TOKEN_TARGET,
+	AM_TARGET_TOKEN_SOURCES,
+	AM_TARGET_TOKEN_LAST
+} AmpTargetTokenCategory;
+
+typedef enum _AmpTargetFlag
+{
+	AM_TARGET_CHECK = 1 << 0,
+	AM_TARGET_NOINST = 1 << 1,
+	AM_TARGET_DIST = 1 << 2,
+	AM_TARGET_NODIST = 1 << 3,
+	AM_TARGET_NOBASE = 1 << 4,
+	AM_TARGET_NOTRANS = 1 << 5,
+	AM_TARGET_MAN = 1 << 6,
+	AM_TARGET_MAN_SECTION = 31 << 7
+} AmpTargetFlag;
+
+void anjuta_am_target_node_register (GTypeModule *module);
+
+void amp_target_add_token (AnjutaAmTargetNode *target, AmTokenType type, AnjutaToken *token);
+GList * amp_target_get_token (AnjutaAmTargetNode *target, AmTokenType type);
+void amp_target_set_type (AnjutaAmTargetNode *target, AmTokenType type);
+AnjutaTokenType amp_target_get_first_token_type (AnjutaAmTargetNode *target);
+AnjutaTokenType amp_target_get_next_token_type (AnjutaAmTargetNode *target, AnjutaTokenType type);
+AnjutaAmTargetNode* amp_target_new (const gchar *name, AnjutaProjectNodeType type, const gchar *install, gint flags, GError **error);
+void amp_target_free (AnjutaAmTargetNode *node);
+void amp_target_update_node (AnjutaAmTargetNode *node, AnjutaAmTargetNode *new_node);
+
+G_END_DECLS
+
+#endif /* _AM_TARGET_H_ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]