[anjuta] am: Implement adding and removing package to targets (missing dialog)



commit 7e53dbc4496e5441f4aab99629ebe36bddcc4421
Author: Sébastien Granjoux <seb sfo free fr>
Date:   Sat Nov 27 21:48:24 2010 +0100

    am: Implement adding and removing package to targets (missing dialog)

 libanjuta/anjuta-project.c                |    2 +-
 plugins/am-project/am-project.c           |  148 +++++++++++++++++++++++++++--
 plugins/am-project/am-properties.c        |  108 +++++++++++++++++++++-
 plugins/am-project/am-properties.h        |    4 +
 plugins/am-project/am-writer.c            |    6 +-
 plugins/am-project/tests/Makefile.am      |    3 +-
 plugins/am-project/tests/target_module.at |  102 ++++++++++++++++++++
 plugins/am-project/tests/testsuite.at     |    2 +
 8 files changed, 359 insertions(+), 16 deletions(-)
---
diff --git a/libanjuta/anjuta-project.c b/libanjuta/anjuta-project.c
index 9f85934..b5b5cbe 100644
--- a/libanjuta/anjuta-project.c
+++ b/libanjuta/anjuta-project.c
@@ -599,7 +599,7 @@ anjuta_project_node_get_property (AnjutaProjectNode *node, AnjutaProjectProperty
 	if (found == NULL)
 	{
 		/* Search in native properties */
-		found = g_list_find_custom (node->custom_properties, property, find_property);
+		found = g_list_find_custom (node->native_properties, property, find_property);
 	}
 
 	return found != NULL ? (AnjutaProjectProperty *)found->data : NULL;
diff --git a/plugins/am-project/am-project.c b/plugins/am-project/am-project.c
index b073b6b..e78fe4d 100644
--- a/plugins/am-project/am-project.c
+++ b/plugins/am-project/am-project.c
@@ -1364,7 +1364,7 @@ project_load_group_module (AmpProject *project, AnjutaAmGroupNode *group)
 	gchar **group_cpp = NULL;
 
 	prop = amp_node_get_property_from_token (ANJUTA_PROJECT_NODE (group), AM_TOKEN__CPPFLAGS);
-	if (prop) group_cpp = g_strsplit_set (prop->value, " \t", 0);
+	if (prop && (prop->value != NULL)) group_cpp = g_strsplit_set (prop->value, " \t", 0);
 	
 	/* Check all targets */
 	for (target = anjuta_project_node_first_child (ANJUTA_PROJECT_NODE (group)); target != NULL; target = anjuta_project_node_next_sibling (target))
@@ -1386,7 +1386,7 @@ project_load_group_module (AmpProject *project, AnjutaAmGroupNode *group)
 		default:
 			break;
 		}
-		if (prop) target_lib = g_strsplit_set (prop->value, " \t", 0);
+		if (prop && (prop->value != NULL)) target_lib = g_strsplit_set (prop->value, " \t", 0);
 
 		/* Check if targets use libraries */
 		if (target_lib != NULL)
@@ -1394,8 +1394,8 @@ project_load_group_module (AmpProject *project, AnjutaAmGroupNode *group)
 			AnjutaProjectNode *module;
 
 			prop = amp_node_get_property_from_token (target, AM_TOKEN_TARGET_CPPFLAGS);
-			if (prop) target_cpp = g_strsplit_set (prop->value, " \t", 0);
-						
+			if (prop && (prop->value != NULL)) target_cpp = g_strsplit_set (prop->value, " \t", 0);
+
 			for (module = anjuta_project_node_first_child (ANJUTA_PROJECT_NODE (project)); module != NULL; module = anjuta_project_node_next_sibling (module))
 			{
 				if (anjuta_project_node_get_node_type (module) == ANJUTA_PROJECT_MODULE)
@@ -2543,7 +2543,58 @@ amp_add_work (PmJob *job)
 			amp_source_create_token (AMP_PROJECT (job->user_data), ANJUTA_AM_SOURCE_NODE (job->node), &job->error);
 			break;
 		case ANJUTA_PROJECT_MODULE:
-			amp_module_create_token (AMP_PROJECT (job->user_data), ANJUTA_AM_MODULE_NODE (job->node), &job->error);
+			if ((job->parent != NULL) && (anjuta_project_node_get_node_type (job->parent) == ANJUTA_PROJECT_TARGET))
+			{
+				AnjutaProjectNode *group = anjuta_project_node_parent (job->parent);
+				AnjutaProjectProperty *group_cpp;
+				AnjutaProjectProperty *target_cpp;
+				AnjutaProjectProperty *target_lib;
+				gchar *lib_flags;
+				gchar *cpp_flags;
+				gint type;
+				
+				group_cpp = amp_node_get_property_from_token (group, AM_TOKEN__CPPFLAGS); 
+					
+				type = anjuta_project_node_get_full_type (job->parent) & (ANJUTA_PROJECT_ID_MASK | ANJUTA_PROJECT_TYPE_MASK);
+				switch (type)
+				{
+				case ANJUTA_PROJECT_TARGET | ANJUTA_PROJECT_PROGRAM:
+					target_lib = amp_node_get_property_from_token (job->parent, AM_TOKEN_TARGET_LDADD);
+					break;
+				case ANJUTA_PROJECT_TARGET | ANJUTA_PROJECT_STATICLIB:
+				case ANJUTA_PROJECT_TARGET | ANJUTA_PROJECT_SHAREDLIB:
+					target_lib = amp_node_get_property_from_token (job->parent, AM_TOKEN_TARGET_LIBADD);
+					break;
+				default:
+					break;
+				}
+				target_cpp = amp_node_get_property_from_token (job->parent, AM_TOKEN_TARGET_CPPFLAGS);
+
+				lib_flags = g_strconcat ("$(", anjuta_project_node_get_name (job->node), "_LIBS)", NULL);
+				cpp_flags = g_strconcat ("$(", anjuta_project_node_get_name (job->node), "_CFLAGS)", NULL);
+
+				if (!amp_node_property_has_flags (group, group_cpp, cpp_flags) && !amp_node_property_has_flags (job->parent, target_cpp, cpp_flags))
+				{
+					AnjutaProjectProperty *prop;
+					prop = amp_node_property_add_flags (group, group_cpp, cpp_flags);
+					amp_project_update_am_property (AMP_PROJECT (job->user_data), group, prop);				
+				}
+					
+				if (!amp_node_property_has_flags (job->parent, target_lib, lib_flags))
+				{
+					AnjutaProjectProperty *prop;
+					prop = amp_node_property_add_flags (job->parent, target_lib, lib_flags);
+					amp_project_update_am_property (AMP_PROJECT (job->user_data), job->parent, prop);				
+				}
+
+				g_free (lib_flags);
+				g_free (cpp_flags);
+				job->parent = group;
+			}
+			else
+			{
+				amp_module_create_token (AMP_PROJECT (job->user_data), ANJUTA_AM_MODULE_NODE (job->node), &job->error);
+			}
 			break;
 		case ANJUTA_PROJECT_PACKAGE:
 			amp_package_create_token (AMP_PROJECT (job->user_data), ANJUTA_AM_PACKAGE_NODE (job->node), &job->error);
@@ -2570,6 +2621,8 @@ static PmCommandWork amp_add_after_job = {amp_add_after_setup, amp_add_work, amp
 static gboolean
 amp_remove_setup (PmJob *job)
 {
+	job->parent = anjuta_project_node_parent (job->node);
+	if (job->parent == NULL) job->parent = job->node;
 	anjuta_project_node_set_state (job->node, ANJUTA_PROJECT_REMOVED);
 	
 	return TRUE;
@@ -2590,7 +2643,84 @@ amp_remove_work (PmJob *job)
 			amp_source_delete_token (AMP_PROJECT (job->user_data), ANJUTA_AM_SOURCE_NODE (job->node), &job->error);
 			break;
 		case ANJUTA_PROJECT_MODULE:
-			amp_module_delete_token (AMP_PROJECT (job->user_data), ANJUTA_AM_MODULE_NODE (job->node), &job->error);
+			if ((job->parent != NULL) && (anjuta_project_node_get_node_type (job->parent) == ANJUTA_PROJECT_TARGET))
+			{
+				AnjutaProjectNode *group = anjuta_project_node_parent (job->parent);
+				AnjutaProjectProperty *prop;
+				AnjutaProjectProperty *group_cpp;
+				AnjutaProjectProperty *target_cpp;
+				AnjutaProjectProperty *target_lib;
+				gchar *lib_flags;
+				gchar *cpp_flags;
+				gint type;
+
+				lib_flags = g_strconcat ("$(", anjuta_project_node_get_name (job->node), "_LIBS)", NULL);
+				cpp_flags = g_strconcat ("$(", anjuta_project_node_get_name (job->node), "_CFLAGS)", NULL);
+				
+				group_cpp = amp_node_get_property_from_token (group, AM_TOKEN__CPPFLAGS); 
+				if (amp_node_property_has_flags (group, group_cpp, cpp_flags))
+				{
+					/* Remove flags in group variable if not more target has this module */
+					gboolean used = FALSE;
+					AnjutaProjectNode *target;
+					
+					for (target = anjuta_project_node_first_child (ANJUTA_PROJECT_NODE (group)); target != NULL; target = anjuta_project_node_next_sibling (target))
+					{
+						if (anjuta_project_node_get_node_type (target) == ANJUTA_PROJECT_TARGET)
+						{
+							AnjutaProjectNode *module;
+
+							for (module = anjuta_project_node_first_child (target); module != NULL; module = anjuta_project_node_next_sibling (module))
+							{
+								if ((anjuta_project_node_get_node_type (module) == ANJUTA_PROJECT_MODULE) &&
+								    (module != job->node) &&
+								    (strcmp (anjuta_project_node_get_name (module), anjuta_project_node_get_name (job->node)) == 0))
+								{
+									used = TRUE;
+									break;
+								}
+							}
+						}
+						if (used) break;
+					}
+
+					if (!used)
+					{
+						AnjutaProjectProperty *prop;
+
+						prop = amp_node_property_remove_flags (group, group_cpp, cpp_flags);
+						if (prop != NULL) amp_project_update_am_property (AMP_PROJECT (job->user_data), group, prop);
+					}
+				}
+					
+				type = anjuta_project_node_get_full_type (job->parent) & (ANJUTA_PROJECT_ID_MASK | ANJUTA_PROJECT_TYPE_MASK);
+				switch (type)
+				{
+				case ANJUTA_PROJECT_TARGET | ANJUTA_PROJECT_PROGRAM:
+					target_lib = amp_node_get_property_from_token (job->parent, AM_TOKEN_TARGET_LDADD);
+					break;
+				case ANJUTA_PROJECT_TARGET | ANJUTA_PROJECT_STATICLIB:
+				case ANJUTA_PROJECT_TARGET | ANJUTA_PROJECT_SHAREDLIB:
+					target_lib = amp_node_get_property_from_token (job->parent, AM_TOKEN_TARGET_LIBADD);
+					break;
+				default:
+					break;
+				}
+				target_cpp = amp_node_get_property_from_token (job->parent, AM_TOKEN_TARGET_CPPFLAGS);
+
+				prop = amp_node_property_remove_flags (job->parent, target_cpp, cpp_flags);
+				if (prop != NULL) amp_project_update_am_property (AMP_PROJECT (job->user_data), job->parent, prop);
+				prop = amp_node_property_remove_flags (job->parent, target_lib, lib_flags);
+				if (prop != NULL) amp_project_update_am_property (AMP_PROJECT (job->user_data), job->parent, prop);
+
+				g_free (lib_flags);
+				g_free (cpp_flags);
+				job->parent = group;	
+			}
+			else
+			{
+				amp_module_delete_token (AMP_PROJECT (job->user_data), ANJUTA_AM_MODULE_NODE (job->node), &job->error);
+			}
 			break;
 		case ANJUTA_PROJECT_PACKAGE:
 			amp_package_delete_token (AMP_PROJECT (job->user_data), ANJUTA_AM_PACKAGE_NODE (job->node), &job->error);
@@ -2605,9 +2735,7 @@ amp_remove_work (PmJob *job)
 static gboolean
 amp_remove_complete (PmJob *job)
 {
-	AnjutaProjectNode *parent = anjuta_project_node_parent (job->node);
-
-	g_signal_emit_by_name (AMP_PROJECT (job->user_data), "node-changed", parent != NULL ? parent : job->node,  job->error);
+	g_signal_emit_by_name (AMP_PROJECT (job->user_data), "node-changed", job->parent,  job->error);
 
 	return TRUE;
 }
@@ -2719,7 +2847,7 @@ static gboolean
 iproject_save_node (IAnjutaProject *obj, AnjutaProjectNode *node, GError **error)
 {
 	PmJob *save_job;
-	
+
 	if (node == NULL) node = ANJUTA_PROJECT_NODE (obj);
 	if (AMP_PROJECT (obj)->queue == NULL) AMP_PROJECT (obj)->queue = pm_command_queue_new ();
 
diff --git a/plugins/am-project/am-properties.c b/plugins/am-project/am-properties.c
index 7ec49b2..b1c9562 100644
--- a/plugins/am-project/am-properties.c
+++ b/plugins/am-project/am-properties.c
@@ -34,6 +34,7 @@
 
 #include <glib/gi18n.h>
 
+#include <ctype.h>
 
 /* Types
   *---------------------------------------------------------------------------*/
@@ -314,7 +315,7 @@ AnjutaProjectProperty *
 amp_node_property_set (AnjutaProjectNode *node, AnjutaProjectProperty *prop, const gchar* value)
 {
 	AnjutaProjectProperty *new_prop;
-		
+
 	new_prop = anjuta_project_node_get_property (node, prop);
 	if ((new_prop != NULL) && (new_prop->native != NULL))
 	{
@@ -348,6 +349,111 @@ amp_node_get_property_from_token (AnjutaProjectNode *node, gint token)
 	return NULL;
 }
 
+
+
+/* Modify flags value
+ *---------------------------------------------------------------------------*/
+
+static const gchar *
+am_node_property_find_flags (AnjutaProjectProperty *prop, const gchar *value, gsize len)
+{
+	const gchar *found;
+	
+	for (found = prop->value; found != NULL;)
+	{
+		found = strstr (found, value);
+		if (found != NULL)
+		{
+			/* Check that flags is alone */
+			if (((found == prop->value) || isspace (*(found - 1))) &&
+			     ((*(found + len) == '\0') || isspace (*(found + len))))
+			{
+				return found;
+			}
+			found += len;
+		}
+	}
+
+	return NULL;
+}
+
+gboolean
+amp_node_property_has_flags (AnjutaProjectNode *node, AnjutaProjectProperty *prop, const gchar *value)
+{
+	return am_node_property_find_flags (prop, value, strlen (value)) != NULL ? TRUE : FALSE;
+}
+
+AnjutaProjectProperty *
+amp_node_property_remove_flags (AnjutaProjectNode *node, AnjutaProjectProperty *prop, const gchar *value)
+{
+	AnjutaProjectProperty *new_prop = NULL;
+	const gchar *found;
+	gsize len = strlen (value);
+	
+	found = am_node_property_find_flags (prop, value, len);
+
+	if (found != NULL)
+	{
+		gsize new_len;
+		
+		if (found == prop->value)
+		{
+			while (isspace (*(found + len))) len++;
+		}
+		else if (*(found + len) == '\0')
+		{
+			while ((found != prop->value) && isspace(*(found - 1))) found--;
+		}
+		else
+		{
+			while (isspace (*(found + len))) len++;
+		}
+
+		new_len = strlen (prop->value) - len;
+
+		if (new_len == 0)
+		{
+			new_prop = amp_node_property_set (node, prop, NULL);			
+		}
+		else
+		{
+			gchar *new_value;
+
+			new_value = g_new(gchar, new_len + 1);
+
+			if (found != prop->value) memcpy (new_value, prop->value, found - prop->value);
+			memcpy (new_value + (found - prop->value), found + len, new_len + 1 - (found - prop->value)); 
+			new_prop = amp_node_property_set (node, prop, new_value);
+			g_free (new_value);
+		}
+	}
+
+	return new_prop;
+}
+
+AnjutaProjectProperty *
+amp_node_property_add_flags (AnjutaProjectNode *node, AnjutaProjectProperty *prop, const gchar *value)
+{
+	AnjutaProjectProperty *new_prop;
+	
+	if (prop->value == NULL)
+	{
+		new_prop = amp_node_property_set (node, prop, value);
+	}
+	else
+	{
+		gchar *new_value;
+
+		new_value = g_strconcat (prop->value, " ", value, NULL);
+		new_prop = amp_node_property_set (node, prop, new_value);
+		g_free (new_value);
+	}
+
+	return new_prop;
+}
+
+
+
 /* Get property list
  *---------------------------------------------------------------------------*/
 
diff --git a/plugins/am-project/am-properties.h b/plugins/am-project/am-properties.h
index 8322bb5..d98da2e 100644
--- a/plugins/am-project/am-properties.h
+++ b/plugins/am-project/am-properties.h
@@ -36,6 +36,10 @@ gboolean amp_node_property_add (AnjutaProjectNode *node, AnjutaProjectProperty *
 AnjutaProjectProperty *amp_node_property_set (AnjutaProjectNode *node, AnjutaProjectProperty *prop, const gchar* value);
 AnjutaProjectProperty *amp_node_get_property_from_token (AnjutaProjectNode *node, gint token);
 
+gboolean amp_node_property_has_flags (AnjutaProjectNode *node, AnjutaProjectProperty *prop, const gchar *value);
+AnjutaProjectProperty *amp_node_property_remove_flags (AnjutaProjectNode *node, AnjutaProjectProperty *prop, const gchar *value);
+AnjutaProjectProperty *amp_node_property_add_flags (AnjutaProjectNode *node, AnjutaProjectProperty *prop, const gchar *value);
+
 GList* amp_get_project_property_list (void);
 GList* amp_get_group_property_list (void);
 GList* amp_get_target_property_list (AnjutaProjectNodeType type);
diff --git a/plugins/am-project/am-writer.c b/plugins/am-project/am-writer.c
index 2e51ab7..1e6578d 100644
--- a/plugins/am-project/am-writer.c
+++ b/plugins/am-project/am-writer.c
@@ -285,7 +285,7 @@ amp_group_create_token (AmpProject  *project, AnjutaAmGroupNode *group, GError *
 		amp_group_add_token (group, token, AM_GROUP_TOKEN_SUBDIRS);
 	}
 
-	tfile = amp_group_set_makefile (group, makefile, G_OBJECT (project));
+	tfile = amp_group_set_makefile (group, makefile, project);
 	amp_project_add_file (project, makefile, tfile);
 	
 	return TRUE;
@@ -837,7 +837,6 @@ gboolean amp_project_update_am_property (AmpProject *project, AnjutaProjectNode
 	AnjutaProjectNode *group;
 	AnjutaToken *args;
 
-
 	/* Find group  of the property */
 	if (anjuta_project_node_get_node_type (node) == ANJUTA_PROJECT_GROUP)
 	{
@@ -847,6 +846,7 @@ gboolean amp_project_update_am_property (AmpProject *project, AnjutaProjectNode
 	{
 		group = anjuta_project_node_parent (node);
 	}
+	
 
 	if ((property->value == NULL) || (*property->value == '\0'))
 	{
@@ -887,7 +887,7 @@ gboolean amp_project_update_am_property (AmpProject *project, AnjutaProjectNode
 			g_free (canon_name);
 			g_free (prop_name);
 		}
-		
+
 		switch (property->native->type)
 		{
 		case ANJUTA_PROJECT_PROPERTY_LIST:
diff --git a/plugins/am-project/tests/Makefile.am b/plugins/am-project/tests/Makefile.am
index d1918fb..6c8e6b1 100644
--- a/plugins/am-project/tests/Makefile.am
+++ b/plugins/am-project/tests/Makefile.am
@@ -26,7 +26,8 @@ TESTSUITE_AT = \
 	$(srcdir)/variable.at \
 	$(srcdir)/properties.at \
 	$(srcdir)/module.at \
-	$(srcdir)/package.at
+	$(srcdir)/package.at \
+	$(srcdir)/target_module.at
 
 TESTSUITE = $(srcdir)/testsuite
 
diff --git a/plugins/am-project/tests/target_module.at b/plugins/am-project/tests/target_module.at
new file mode 100644
index 0000000..f371db5
--- /dev/null
+++ b/plugins/am-project/tests/target_module.at
@@ -0,0 +1,102 @@
+AT_SETUP([Add target module])
+AS_MKDIR_P([simple])
+AT_DATA([simple/configure.ac],
+[[PKG_CHECK_MODULES(MODULE1, module1)
+AC_CONFIG_FILES(Makefile)
+]])
+AT_DATA([simple/Makefile.am],
+[[lib_LTLIBRARIES = library.la
+
+noinst_PROGRAMS = program
+]])
+
+
+
+AT_DATA([expect],
+[[    MODULE (): MODULE1
+        PACKAGE (): module1
+    GROUP (): simple1
+        PROPERTY (C preprocessor flags): $(MODULE1_CFLAGS)
+        TARGET (): library.la
+            PROPERTY (Libraries): $(MODULE1_LIBS)
+            MODULE (): MODULE1
+        TARGET (): program
+]])
+AT_PARSER_CHECK([load simple \
+		 move simple1 \
+		 add module 1:0 MODULE1 \
+		 list \
+		 save])
+AT_CHECK([[sed 's/^\(\s*\w\+\s*(\)[0-9:]\+\()\)/\1\2/' output | diff - expect]])
+AT_PARSER_CHECK([load simple1 \
+		 list])
+AT_CHECK([[sed 's/^\(\s*\w\+\s*(\)[0-9:]\+\()\)/\1\2/' output | diff - expect]])
+
+
+
+AT_DATA([expect],
+[[    MODULE (): MODULE1
+        PACKAGE (): module1
+    GROUP (): simple2
+        PROPERTY (C preprocessor flags): $(MODULE1_CFLAGS)
+        TARGET (): library.la
+            PROPERTY (Libraries): $(MODULE1_LIBS)
+            MODULE (): MODULE1
+        TARGET (): program
+            PROPERTY (Libraries): $(MODULE1_LIBS)
+            MODULE (): MODULE1
+]])
+AT_PARSER_CHECK([load simple1 \
+		 move simple2 \
+		 add module 1:1 MODULE1 \
+		 list \
+		 save])
+AT_CHECK([[sed 's/^\(\s*\w\+\s*(\)[0-9:]\+\()\)/\1\2/' output | diff - expect]])
+AT_PARSER_CHECK([load simple2 \
+		 list])
+AT_CHECK([[sed 's/^\(\s*\w\+\s*(\)[0-9:]\+\()\)/\1\2/' output | diff - expect]])
+
+
+
+AT_DATA([expect],
+[[    MODULE (): MODULE1
+        PACKAGE (): module1
+    GROUP (): simple3
+        PROPERTY (C preprocessor flags): $(MODULE1_CFLAGS)
+        TARGET (): library.la
+        TARGET (): program
+            PROPERTY (Libraries): $(MODULE1_LIBS)
+            MODULE (): MODULE1
+]])
+AT_PARSER_CHECK([load simple2 \
+		 move simple3 \
+		 remove 1:0:0 \
+		 list \
+		 save])
+AT_CHECK([[sed 's/^\(\s*\w\+\s*(\)[0-9:]\+\()\)/\1\2/' output | diff - expect]])
+AT_PARSER_CHECK([load simple3 \
+		 list])
+AT_CHECK([[sed 's/^\(\s*\w\+\s*(\)[0-9:]\+\()\)/\1\2/' output | diff - expect]])
+
+
+
+AT_DATA([expect],
+[[    MODULE (): MODULE1
+        PACKAGE (): module1
+    GROUP (): simple4
+        TARGET (): library.la
+        TARGET (): program
+]])
+AT_PARSER_CHECK([load simple3 \
+		 move simple4 \
+		 remove 1:1:0 \
+		 list \
+		 save])
+AT_CHECK([[sed 's/^\(\s*\w\+\s*(\)[0-9:]\+\()\)/\1\2/' output | diff - expect]])
+AT_PARSER_CHECK([load simple4 \
+		 list])
+AT_CHECK([[sed 's/^\(\s*\w\+\s*(\)[0-9:]\+\()\)/\1\2/' output | diff - expect]])
+
+
+
+AT_CLEANUP
diff --git a/plugins/am-project/tests/testsuite.at b/plugins/am-project/tests/testsuite.at
index eef2513..d2037e8 100644
--- a/plugins/am-project/tests/testsuite.at
+++ b/plugins/am-project/tests/testsuite.at
@@ -10,3 +10,5 @@ m4_include([variable.at])
 m4_include([properties.at])
 m4_include([module.at])
 m4_include([package.at])
+m4_include([target_module.at])
+



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