[anjuta] am-project: Evaluate all autotools variables at the end
- From: Sebastien Granjoux <sgranjoux src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [anjuta] am-project: Evaluate all autotools variables at the end
- Date: Sat, 21 May 2011 15:52:03 +0000 (UTC)
commit 0dbbbc39e3e417456aad3e5fbb1d89c63e38d16e
Author: Sébastien Granjoux <seb sfo free fr>
Date: Sat May 21 17:20:09 2011 +0200
am-project: Evaluate all autotools variables at the end
libanjuta/anjuta-token-stream.c | 67 ++++++++++++-----------
libanjuta/anjuta-token-stream.h | 1 +
libanjuta/anjuta-token.c | 101 +++++++++++++++++++++++++++++++++-
libanjuta/anjuta-token.h | 2 +
libanjuta/anjuta-utils.c | 2 +-
plugins/am-project/am-scanner.l | 78 +++++++++++++++++++++++++-
plugins/am-project/amp-group.c | 16 +++--
plugins/am-project/tests/variable.at | 47 ++++++++++++++++
8 files changed, 269 insertions(+), 45 deletions(-)
---
diff --git a/libanjuta/anjuta-token-stream.c b/libanjuta/anjuta-token-stream.c
index aa58203..60e0ee5 100644
--- a/libanjuta/anjuta-token-stream.c
+++ b/libanjuta/anjuta-token-stream.c
@@ -64,7 +64,7 @@ struct _AnjutaTokenStream
AnjutaToken *last;
/* Read position in input stream */
- AnjutaToken *next;
+ AnjutaToken *token;
gsize pos;
/* Write position in input stream */
@@ -128,11 +128,11 @@ anjuta_token_stream_tokenize (AnjutaTokenStream *stream, gint type, gsize length
for (end = stream->start; end != NULL;)
{
- if (anjuta_token_get_type (end) < ANJUTA_TOKEN_PARSED)
+ if ((anjuta_token_get_type (end) < ANJUTA_TOKEN_PARSED) || (anjuta_token_get_length (end) == 0))
{
gint toklen = anjuta_token_get_length (end);
AnjutaToken *copy = anjuta_token_cut (end, stream->begin, length);
-
+
if (toklen >= (length + stream->begin))
{
@@ -177,7 +177,7 @@ anjuta_token_stream_tokenize (AnjutaTokenStream *stream, gint type, gsize length
stream->begin = 0;
}
}
-
+
anjuta_token_stream_append_token (stream, frag);
return frag;
@@ -199,36 +199,36 @@ anjuta_token_stream_read (AnjutaTokenStream *stream, gchar *buffer, gsize max_si
{
gint result = 0;
- if (stream->next != NULL)
+ if (stream->token != NULL)
{
- gsize length = anjuta_token_get_length (stream->next);
+ gsize length = anjuta_token_get_length (stream->token);
- if ((anjuta_token_get_type (stream->next) >= ANJUTA_TOKEN_PARSED) || (stream->pos >= length))
+ if ((anjuta_token_get_type (stream->token) >= ANJUTA_TOKEN_PARSED) || (stream->pos >= length))
{
for (;;)
{
/* Last token */
- if (stream->next == stream->last) return 0;
+ if (stream->token== stream->last) return 0;
- if (anjuta_token_get_type (stream->next) >= ANJUTA_TOKEN_PARSED)
+ if (anjuta_token_get_type (stream->token) >= ANJUTA_TOKEN_PARSED)
{
- stream->next = anjuta_token_next (stream->next);
+ stream->token = anjuta_token_next (stream->token);
}
else
{
- stream->next = anjuta_token_next (stream->next);
+ stream->token = anjuta_token_next (stream->token);
}
- if ((stream->next == NULL) || (anjuta_token_get_type (stream->next) == ANJUTA_TOKEN_EOV))
+ if ((stream->token == NULL) || (anjuta_token_get_type (stream->token) == ANJUTA_TOKEN_EOV))
{
/* Last token */
return 0;
}
- else if ((anjuta_token_get_length (stream->next) != 0) && (anjuta_token_get_type (stream->next) < ANJUTA_TOKEN_PARSED))
+ else if ((anjuta_token_get_length (stream->token) != 0) && (anjuta_token_get_type (stream->token) < ANJUTA_TOKEN_PARSED))
{
/* Find some data */
stream->pos = 0;
- length = anjuta_token_get_length (stream->next);
+ length = anjuta_token_get_length (stream->token);
break;
}
}
@@ -236,7 +236,7 @@ anjuta_token_stream_read (AnjutaTokenStream *stream, gchar *buffer, gsize max_si
if (stream->pos < length)
{
- const gchar *start = anjuta_token_get_string (stream->next);
+ const gchar *start = anjuta_token_get_string (stream->token);
length -= stream->pos;
@@ -324,22 +324,9 @@ anjuta_token_stream_push (AnjutaTokenStream *parent, AnjutaToken *root, AnjutaTo
child->pos = 0;
child->begin = 0;
child->parent = parent;
-
- /* If content is empty, anjuta_token_next returns following token which is
- * wrong */
- if (anjuta_token_is_empty (content))
- {
- child->next = NULL;
- child->start = NULL;
- child->last = NULL;
- }
- else
- {
- child->next = anjuta_token_next (content);
- child->start = child->next;
- child->last = anjuta_token_last (content);
- if (child->last == content) child->last = NULL;
- }
+ child->token = content;
+ child->start = child->token;
+ child->last = anjuta_token_last (content);
child->root = root == NULL ? anjuta_token_new_static (ANJUTA_TOKEN_FILE, NULL) : root;
if (file == NULL)
@@ -358,7 +345,7 @@ anjuta_token_stream_push (AnjutaTokenStream *parent, AnjutaToken *root, AnjutaTo
/**
* anjuta_token_stream_pop:
- * @parent: a #AnjutaTokenStream object.
+ * @stream: a #AnjutaTokenStream object.
*
* Destroy the stream object and return the parent stream if it exists.
*
@@ -378,3 +365,19 @@ anjuta_token_stream_pop (AnjutaTokenStream *stream)
return parent;
}
+
+/**
+ * anjuta_token_stream_get_parent:
+ * @stream: a #AnjutaTokenStream object.
+ *
+ * Return the parent stream
+ *
+ * Return value: The parent stream or NULL if there is no parent.
+ */
+AnjutaTokenStream *
+anjuta_token_stream_get_parent (AnjutaTokenStream *stream)
+{
+ g_return_val_if_fail (stream != NULL, NULL);
+
+ return stream->parent;
+}
diff --git a/libanjuta/anjuta-token-stream.h b/libanjuta/anjuta-token-stream.h
index bfeb38f..35bf389 100644
--- a/libanjuta/anjuta-token-stream.h
+++ b/libanjuta/anjuta-token-stream.h
@@ -30,6 +30,7 @@ typedef struct _AnjutaTokenStream AnjutaTokenStream;
AnjutaTokenStream *anjuta_token_stream_push (AnjutaTokenStream *stream, AnjutaToken *root, AnjutaToken *content, GFile *filename);
AnjutaTokenStream *anjuta_token_stream_pop (AnjutaTokenStream *stream);
+AnjutaTokenStream *anjuta_token_stream_get_parent (AnjutaTokenStream *stream);
AnjutaToken* anjuta_token_stream_get_root (AnjutaTokenStream *stream);
GFile* anjuta_token_stream_get_current_directory (AnjutaTokenStream *stream);
diff --git a/libanjuta/anjuta-token.c b/libanjuta/anjuta-token.c
index e069f70..04c9737 100644
--- a/libanjuta/anjuta-token.c
+++ b/libanjuta/anjuta-token.c
@@ -1132,7 +1132,8 @@ AnjutaToken *anjuta_token_split (AnjutaToken *token, guint size)
}
}
-AnjutaToken *anjuta_token_cut (AnjutaToken *token, guint pos, guint size)
+AnjutaToken *
+anjuta_token_cut (AnjutaToken *token, guint pos, guint size)
{
AnjutaToken *copy;
@@ -1165,10 +1166,108 @@ AnjutaToken *anjuta_token_cut (AnjutaToken *token, guint pos, guint size)
return copy;
}
+static void
+concat_token (AnjutaToken *token, gpointer user_data)
+{
+ AnjutaToken *first = (AnjutaToken *)user_data;
+
+ if (anjuta_token_get_length (token) > 0)
+ {
+ if (anjuta_token_get_string (first) == NULL)
+ {
+ anjuta_token_set_string (first, anjuta_token_get_string (token), anjuta_token_get_length (token));
+ }
+ else if ((first != NULL) && ((anjuta_token_get_string(first) + anjuta_token_get_length (first)) == anjuta_token_get_string (token)))
+ {
+ anjuta_token_set_string (first, anjuta_token_get_string (first), anjuta_token_get_length (first) + anjuta_token_get_length (token));
+ }
+ else
+ {
+ AnjutaToken *new;
+
+ new = anjuta_token_new_static_len (ANJUTA_TOKEN_CONTENT, anjuta_token_get_string (token), anjuta_token_get_length (token));
+ anjuta_token_insert_after (first, new);
+ anjuta_token_merge (first, new);
+ }
+ }
+}
+
+
+AnjutaToken *
+anjuta_token_concat(AnjutaToken *token)
+{
+ AnjutaToken *new;
+
+ new = anjuta_token_new_static (ANJUTA_TOKEN_CONTENT, NULL);
+ anjuta_token_foreach_token (token, concat_token, new);
+
+ anjuta_token_insert_token_before (token, new);
+ anjuta_token_free (token);
+
+ return new;
+}
+
/* Token foreach
*---------------------------------------------------------------------------*/
void
+anjuta_token_foreach_token (AnjutaToken *token, AnjutaTokenForeachFunc func, gpointer user_data)
+{
+ if (token != NULL)
+ {
+ AnjutaToken *last_token;
+ gint child = 0;
+
+ last_token = token->last == NULL ? token : token->last;
+ while (token != NULL)
+ {
+ if (child == 0) func (token, user_data);
+
+ /* Check if we have found the last token */
+ if (token == last_token)
+ {
+ /* Find last token */
+ if (token->last == NULL)
+ {
+ break;
+ }
+ /* Last token still include additional tokens */
+ last_token = token->last;
+ }
+
+ if (token->children != NULL)
+ {
+ /* Check children, only for last token */
+ child++;
+ token = token->children;
+ }
+ else if (token->next != NULL)
+ {
+ /* Get next sibling */
+ token = token->next;
+ }
+ else
+ {
+ /* Get parent */
+ for (;;)
+ {
+ child--;
+ token = token->parent;
+ if (token == NULL) break;
+ if (token->next != NULL)
+ {
+ token = token->next;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return;
+}
+
+void
anjuta_token_foreach_content (AnjutaToken *token, AnjutaTokenForeachFunc func, gpointer user_data)
{
if (token != NULL)
diff --git a/libanjuta/anjuta-token.h b/libanjuta/anjuta-token.h
index 920268a..d20efdc 100644
--- a/libanjuta/anjuta-token.h
+++ b/libanjuta/anjuta-token.h
@@ -114,6 +114,7 @@ AnjutaToken *anjuta_token_parent (AnjutaToken *token);
AnjutaToken *anjuta_token_list (AnjutaToken *token);
AnjutaToken *anjuta_token_next_after_children (AnjutaToken *token);
void anjuta_token_foreach_content (AnjutaToken *token, AnjutaTokenForeachFunc func, gpointer user_data);
+void anjuta_token_foreach_token (AnjutaToken *token, AnjutaTokenForeachFunc func, gpointer user_data);
AnjutaToken *anjuta_token_foreach_post_order (AnjutaToken *token, AnjutaTokenForeachFunc func, gpointer user_data);
AnjutaToken *anjuta_token_first_item (AnjutaToken *list);
@@ -135,6 +136,7 @@ AnjutaToken *anjuta_token_merge_children (AnjutaToken *first, AnjutaToken *end);
AnjutaToken *anjuta_token_merge_previous (AnjutaToken *first, AnjutaToken *end);
AnjutaToken *anjuta_token_split (AnjutaToken *token, guint size);
AnjutaToken *anjuta_token_cut (AnjutaToken *token, guint pos, guint size);
+AnjutaToken *anjuta_token_concat(AnjutaToken *token);
gchar *anjuta_token_evaluate (AnjutaToken *token);
gboolean anjuta_token_is_empty (AnjutaToken *token);
diff --git a/libanjuta/anjuta-utils.c b/libanjuta/anjuta-utils.c
index 33b1294..73552ec 100644
--- a/libanjuta/anjuta-utils.c
+++ b/libanjuta/anjuta-utils.c
@@ -400,7 +400,7 @@ anjuta_util_dialog_boolean_question (GtkWindow *parent, const gchar *mesg, ...)
{
real_parent = NULL;
}
-
+
dialog = gtk_message_dialog_new (real_parent,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_QUESTION,
diff --git a/plugins/am-project/am-scanner.l b/plugins/am-project/am-scanner.l
index c5dad7f..de2130e 100644
--- a/plugins/am-project/am-scanner.l
+++ b/plugins/am-project/am-scanner.l
@@ -53,7 +53,9 @@ struct _AmpAmScanner
AmpProject *project;
AmpGroupNode *group;
GHashTable *orphan_properties;
+ GList *am_variables;
gboolean eof; /* TRUE to emit EOF at the end */
+ gboolean expansion; /* Expand variables */
};
%}
@@ -208,6 +210,26 @@ NAME [^ \t\n\r:#=$"'`&@\\]*
/* Private functions
*---------------------------------------------------------------------------*/
+static void
+amp_am_scanner_reparse_token (AmpAmScanner *scanner, AnjutaToken *token, GFile *filename)
+{
+ AnjutaToken *root;
+ AnjutaToken *list;
+
+ if (token == NULL) return;
+
+ token = anjuta_token_concat (token);
+
+ yylex_init(&scanner->scanner);
+ yyset_extra (scanner, scanner->scanner);
+
+ root = anjuta_token_new_static (ANJUTA_TOKEN_FILE, NULL);
+ list = amp_am_scanner_parse_token (scanner, root, token, filename, NULL);
+ list = anjuta_token_delete_parent (list);
+ anjuta_token_insert_before (token, list);
+ anjuta_token_free (token);
+}
+
static gint
amp_am_scanner_parse_end (AmpAmScanner *scanner)
{
@@ -223,8 +245,9 @@ amp_am_scanner_parse_end (AmpAmScanner *scanner)
scanner->eof = FALSE;
return END_OF_FILE;
}
- yypop_buffer_state(scanner->scanner);
- scanner->stream = anjuta_token_stream_pop (scanner->stream);
+
+ yypop_buffer_state(scanner->scanner);
+ scanner->stream = anjuta_token_stream_pop (scanner->stream);
if (scanner->stream == NULL)
{
@@ -240,6 +263,27 @@ amp_am_scanner_parse_end (AmpAmScanner *scanner)
}
}
+static GList *
+list_used_variable (AnjutaToken *token)
+{
+ AnjutaToken *last = anjuta_token_last (token);
+ GList *list = NULL;
+
+ for (;;)
+ {
+ if (anjuta_token_get_type (token) == ANJUTA_TOKEN_VARIABLE)
+ {
+ list = g_list_prepend (list, token);
+ }
+ if (token == last) break;
+ token = anjuta_token_next (token);
+ }
+ list = g_list_reverse (list);
+
+ return list;
+}
+
+
/* Parser functions
*---------------------------------------------------------------------------*/
@@ -262,7 +306,15 @@ amp_am_yyerror (YYLTYPE *loc, AmpAmScanner *scanner, char const *s)
void
amp_am_scanner_set_am_variable (AmpAmScanner *scanner, AnjutaToken *variable)
{
- amp_project_set_am_variable (scanner->project, scanner->group, variable, scanner->orphan_properties);
+ if (!scanner->expansion)
+ {
+ /* Keep variable token to expand them at the end */
+ scanner->am_variables = g_list_prepend (scanner->am_variables, variable);
+ }
+ else
+ {
+ amp_project_set_am_variable (scanner->project, scanner->group, variable, scanner->orphan_properties);
+ }
}
void
@@ -299,7 +351,7 @@ amp_am_scanner_parse_variable (AmpAmScanner *scanner, AnjutaToken *variable)
AnjutaToken *value;
anjuta_token_set_type (variable, ANJUTA_TOKEN_VARIABLE);
-
+
value = amp_group_node_get_variable_token (scanner->group, variable);
if (value != NULL)
{
@@ -316,6 +368,7 @@ amp_am_scanner_parse_token (AmpAmScanner *scanner, AnjutaToken *root, AnjutaToke
{
AnjutaToken *first;
AnjutaTokenStream *stream;
+ GList *variable;
stream = anjuta_token_stream_push (scanner->stream, root, content, filename);
first = anjuta_token_stream_get_root (stream);
@@ -348,6 +401,18 @@ amp_am_scanner_parse_token (AmpAmScanner *scanner, AnjutaToken *root, AnjutaToke
} while (status == YYPUSH_MORE);
amp_am_yypstate_delete (ps);
+ /* Evaluate autotools variable at the end */
+ if (scanner->expansion == FALSE)
+ {
+ scanner->expansion = TRUE;
+ scanner->am_variables = g_list_reverse (scanner->am_variables);
+ for (variable = g_list_first (scanner->am_variables); variable != NULL; variable = g_list_next (variable))
+ {
+ AnjutaToken *token = (AnjutaToken *)variable->data;
+
+ amp_am_scanner_reparse_token (scanner, token, filename);
+ }
+ }
}
return first;
@@ -370,6 +435,10 @@ amp_am_scanner_new (AmpProject *project, AmpGroupNode *group)
/* Create hash table for sources list */
scanner->orphan_properties = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)g_free, (GDestroyNotify)amp_target_node_free);
+ /* Create hash table for variable */
+ scanner->am_variables = NULL;
+ scanner->expansion = FALSE;
+
yylex_init(&scanner->scanner);
yyset_extra (scanner, scanner->scanner);
@@ -385,6 +454,7 @@ amp_am_scanner_free (AmpAmScanner *scanner)
/* Free unused sources files */
g_hash_table_destroy (scanner->orphan_properties);
+ g_list_free (scanner->am_variables);
g_free (scanner);
}
diff --git a/plugins/am-project/amp-group.c b/plugins/am-project/amp-group.c
index e8f9fa7..10c8a78 100644
--- a/plugins/am-project/amp-group.c
+++ b/plugins/am-project/amp-group.c
@@ -508,22 +508,24 @@ AnjutaToken*
amp_group_node_get_variable_token (AmpGroupNode *group, AnjutaToken *variable)
{
guint length;
- const gchar *string;
- gchar *name;
+ gchar *string;
+ const gchar *name;
AmpVariable *var;
- length = anjuta_token_get_length (variable);
- string = anjuta_token_get_string (variable);
+ string = anjuta_token_evaluate(variable);
+ length = strlen (string);
if (string[1] == '(')
{
- name = g_strndup (string + 2, length - 3);
+ string[length - 1] = '\0';
+ name = string + 2;
}
else
{
- name = g_strndup (string + 1, 1);
+ string[2] = '\0';
+ name = string + 1;
}
var = g_hash_table_lookup (group->variables, name);
- g_free (name);
+ g_free (string);
return var != NULL ? var->value : NULL;
}
diff --git a/plugins/am-project/tests/variable.at b/plugins/am-project/tests/variable.at
index a682aae..2c27076 100644
--- a/plugins/am-project/tests/variable.at
+++ b/plugins/am-project/tests/variable.at
@@ -1,4 +1,7 @@
AT_SETUP([Variable in Makefile.am])
+
+
+
AS_MKDIR_P([variable])
AT_DATA([variable/configure.ac],
[[AC_CONFIG_FILES(Makefile)
@@ -16,4 +19,48 @@ AT_DATA([expect],
AT_PARSER_CHECK([load variable \
list])
AT_CHECK([diff -b output expect])
+
+
+
+AS_MKDIR_P([variable2])
+AT_DATA([variable2/configure.ac],
+[[AC_CONFIG_FILES(Makefile)
+]])
+AT_DATA([variable2/Makefile.am],
+[[
+bin_PROGRAMS = $(TARGETS)
+TARGETS = target1
+]])
+AT_DATA([expect],
+[[ GROUP (): variable2
+ TARGET (): target1
+ PROPERTY (Installation directory): bindir
+]])
+AT_PARSER_CHECK([load variable2 \
+ list])
+AT_CHECK([diff -b output expect])
+
+
+
+AS_MKDIR_P([variable3])
+AT_DATA([variable3/configure.ac],
+[[AC_CONFIG_FILES(Makefile)
+]])
+AT_DATA([variable3/Makefile.am],
+[[
+bin_PROGRAMS = $(TARGETS)
+TARGETS1 = target1
+TARGETS = $(TARGETS1)
+]])
+AT_DATA([expect],
+[[ GROUP (): variable3
+ TARGET (): target1
+ PROPERTY (Installation directory): bindir
+]])
+AT_PARSER_CHECK([load variable3 \
+ list])
+AT_CHECK([diff -b output expect])
+
+
+
AT_CLEANUP
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]