[anjuta/newproject: 120/120] Improve AnjutaToken object and update all parsers
- From: Sebastien Granjoux <sgranjoux src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [anjuta/newproject: 120/120] Improve AnjutaToken object and update all parsers
- Date: Sat, 19 Dec 2009 14:47:57 +0000 (UTC)
commit 6ed85240256fd892e9009b6fe9215697a623213f
Author: Sébastien Granjoux <seb sfo free fr>
Date: Sat Dec 19 15:44:32 2009 +0100
Improve AnjutaToken object and update all parsers
libanjuta/Makefile.am | 10 +-
libanjuta/anjuta-project.c | 108 ++-
libanjuta/anjuta-project.h | 11 +-
libanjuta/anjuta-token-file.c | 403 ++++++---
libanjuta/anjuta-token-file.h | 22 +-
libanjuta/anjuta-token-list.c | 756 +++++++++++++++++
libanjuta/anjuta-token-stream.c | 317 +++++++
libanjuta/anjuta-token-stream.h | 44 +
libanjuta/anjuta-token-style.c | 491 -----------
libanjuta/anjuta-token.c | 1220 ++++++++++++++++++++-------
libanjuta/anjuta-token.h | 103 +--
plugins/am-project/Makefile.am | 2 +
plugins/am-project/ac-parser.y | 342 +++++----
plugins/am-project/ac-scanner.h | 19 +-
plugins/am-project/ac-scanner.l | 327 ++------
plugins/am-project/ac-writer.c | 156 +++--
plugins/am-project/am-parser.y | 270 +++----
plugins/am-project/am-project-private.h | 17 +-
plugins/am-project/am-project.c | 1134 +++++++++++++------------
plugins/am-project/am-project.h | 13 +-
plugins/am-project/am-scanner.h | 14 +-
plugins/am-project/am-scanner.l | 404 ++++------
plugins/am-project/am-writer.c | 219 +++++
plugins/am-project/am-writer.h | 39 +
plugins/mk-project/mk-parser.y | 398 +++++-----
plugins/mk-project/mk-project.c | 316 +++-----
plugins/mk-project/mk-project.h | 12 +-
plugins/mk-project/mk-rule.c | 80 +-
plugins/mk-project/mk-rule.h | 4 +-
plugins/mk-project/mk-scanner.h | 18 +-
plugins/mk-project/mk-scanner.l | 222 +++---
plugins/project-manager/gbf-project-model.c | 6 +-
plugins/project-manager/gbf-project-util.c | 46 +
plugins/project-manager/gbf-project-util.h | 8 +-
plugins/project-manager/plugin.c | 4 +-
35 files changed, 4513 insertions(+), 3042 deletions(-)
---
diff --git a/libanjuta/Makefile.am b/libanjuta/Makefile.am
index f7363bf..43d1801 100644
--- a/libanjuta/Makefile.am
+++ b/libanjuta/Makefile.am
@@ -82,12 +82,14 @@ libanjuta_la_SOURCES= \
anjuta-command-queue.h \
anjuta-token.c \
anjuta-token.h \
- anjuta-token-style.c \
- anjuta-token-style.h \
- anjuta-token-file.c \
+ anjuta-token-list.h \
+ anjuta-token-list.c \
anjuta-token-file.h \
+ anjuta-token-file.c \
+ anjuta-project.c \
anjuta-project.h \
- anjuta-project.c
+ anjuta-token-stream.c \
+ anjuta-token-stream.h
if HAVE_PLUGIN_GLADE
diff --git a/libanjuta/anjuta-project.c b/libanjuta/anjuta-project.c
index 75ea98b..4938665 100644
--- a/libanjuta/anjuta-project.c
+++ b/libanjuta/anjuta-project.c
@@ -21,6 +21,31 @@
#include "anjuta-debug.h"
+/**
+ * SECTION:anjuta-project
+ * @title: Anjuta project
+ * @short_description: Anjuta project
+ * @see_also:
+ * @stability: Unstable
+ * @include: libanjuta/anjuta-project.h
+ *
+ * A project in Anjuta is represented by a tree. There are three kinds of node.
+ *
+ * A source node represents a source file. These are lead of the tree, a source
+ * node cannot have children.
+ *
+ * A target node represents an object file defined explicitely.
+ * There are different kinds of target: program, library...
+ * A target have as children all source needed to build it.
+ *
+ * A group node is used to group several target or source, it can represent
+ * a directory by example. The root node of the project is a group node
+ * representing the project directory.
+ *
+ * All these nodes are base objects. They have derived in each project backend
+ * to provide more specific information.
+ */
+
/* convenient shortcut macro the get the AnjutaProjectNode from a GNode */
#define NODE_DATA(node) ((node) != NULL ? (AnjutaProjectNodeData *)((node)->data) : NULL)
#define GROUP_DATA(node) ((node) != NULL ? (AnjutaProjectGroupData *)((node)->data) : NULL)
@@ -66,58 +91,63 @@ AnjutaProjectNode *anjuta_project_node_nth_child (AnjutaProjectNode *node, guint
return g_node_nth_child (node, n);
}
-GList *
-anjuta_project_node_all_child (AnjutaProjectNode *parent, AnjutaProjectNodeType type)
+typedef struct
{
- AnjutaProjectNode *node;
- GList *list = NULL;
-
- for (node = anjuta_project_node_first_child (parent); node != NULL; node = anjuta_project_node_next_sibling (node))
- {
- if (anjuta_project_node_get_type (node) == type)
- {
- list = g_list_prepend (list, node);
- }
- }
+ AnjutaProjectNodeFunc func;
+ gpointer data;
+} AnjutaProjectNodePacket;
- list = g_list_reverse (list);
+static gboolean
+anjuta_project_node_traverse_func (GNode *node, gpointer data)
+{
+ AnjutaProjectNodePacket *pack = (AnjutaProjectNodePacket *)data;
+
+ pack->func ((AnjutaProjectNode *)node, pack->data);
- return list;
+ return FALSE;
}
-GList *
-anjuta_project_node_all (AnjutaProjectNode *parent, AnjutaProjectNodeType type)
+void
+anjuta_project_node_all_foreach (AnjutaProjectNode *node, AnjutaProjectNodeFunc func, gpointer data)
{
- AnjutaProjectNode *node;
- GList *list = NULL;
+ AnjutaProjectNodePacket pack = {func, data};
- for (node = anjuta_project_node_first_child (parent); node != NULL; node = anjuta_project_node_next_sibling (node))
- {
- if (anjuta_project_node_get_type (node) == type)
- {
- list = g_list_prepend (list, node);
- }
- if (anjuta_project_node_get_type (node) == ANJUTA_PROJECT_GROUP)
- {
- GList *child_list;
+ /* POST_ORDER is important when deleting the node, children has to be
+ * deleted first */
+ g_node_traverse (node, G_POST_ORDER, G_TRAVERSE_ALL, -1, anjuta_project_node_traverse_func, &pack);
+}
- child_list = anjuta_project_node_all (node, type);
- child_list = g_list_reverse (child_list);
- list = g_list_concat (child_list, list);
- }
- }
+void
+anjuta_project_node_children_foreach (AnjutaProjectNode *node, AnjutaProjectNodeFunc func, gpointer data)
+{
+ g_node_children_foreach (node, G_TRAVERSE_ALL, func, data);
+}
- list = g_list_reverse (list);
+AnjutaProjectNode *
+anjuta_project_node_append (AnjutaProjectNode *parent, AnjutaProjectNode *node)
+{
+ return g_node_append (parent, node);
+}
- return list;
+AnjutaProjectNode *
+anjuta_project_node_insert_before (AnjutaProjectNode *parent, AnjutaProjectNode *sibling, AnjutaProjectNode *node)
+{
+ return g_node_insert_before (parent, sibling, node);
}
-void
-anjuta_project_node_all_foreach (AnjutaProjectNode *node, AnjutaProjectNodeFunc func, gpointer data)
+AnjutaProjectNode *
+anjuta_project_node_insert_after (AnjutaProjectNode *parent, AnjutaProjectNode *sibling, AnjutaProjectNode *node)
+{
+ return g_node_insert_after (parent, sibling, node);
+}
+
+AnjutaProjectNode *
+anjuta_project_node_prepend (AnjutaProjectNode *parent, AnjutaProjectNode *node)
{
- g_node_traverse (node, G_PRE_ORDER, G_TRAVERSE_ALL, -1, func, data);
+ return g_node_prepend (parent, node);
}
+
AnjutaProjectNodeType
anjuta_project_node_get_type (const AnjutaProjectNode *node)
{
diff --git a/libanjuta/anjuta-project.h b/libanjuta/anjuta-project.h
index 31fbed1..8eec3a2 100644
--- a/libanjuta/anjuta-project.h
+++ b/libanjuta/anjuta-project.h
@@ -83,7 +83,7 @@ typedef GNode AnjutaProjectGroup;
typedef GNode AnjutaProjectTarget;
typedef GNode AnjutaProjectSource;
-typedef GNodeTraverseFunc AnjutaProjectNodeFunc;
+typedef void (*AnjutaProjectNodeFunc) (AnjutaProjectNode *node, gpointer data);
AnjutaProjectNode *anjuta_project_node_parent (AnjutaProjectNode *node);
AnjutaProjectNode *anjuta_project_node_first_child (AnjutaProjectNode *node);
@@ -91,9 +91,14 @@ AnjutaProjectNode *anjuta_project_node_last_child (AnjutaProjectNode *node);
AnjutaProjectNode *anjuta_project_node_next_sibling (AnjutaProjectNode *node);
AnjutaProjectNode *anjuta_project_node_prev_sibling (AnjutaProjectNode *node);
AnjutaProjectNode *anjuta_project_node_nth_child (AnjutaProjectNode *node, guint n);
-GList *anjuta_project_node_all_child (AnjutaProjectNode *node, AnjutaProjectNodeType type);
-GList *anjuta_project_node_all (AnjutaProjectNode *node, AnjutaProjectNodeType type);
+
+AnjutaProjectNode *anjuta_project_node_append (AnjutaProjectNode *parent, AnjutaProjectNode *node);
+AnjutaProjectNode *anjuta_project_node_prepend (AnjutaProjectNode *parent, AnjutaProjectNode *node);
+AnjutaProjectNode *anjuta_project_node_insert_before (AnjutaProjectNode *parent, AnjutaProjectNode *sibling, AnjutaProjectNode *node);
+AnjutaProjectNode *anjuta_project_node_insert_after (AnjutaProjectNode *parent, AnjutaProjectNode *sibling, AnjutaProjectNode *node);
+
void anjuta_project_node_all_foreach (AnjutaProjectNode *node, AnjutaProjectNodeFunc func, gpointer data);
+void anjuta_project_node_children_foreach (AnjutaProjectNode *node, AnjutaProjectNodeFunc func, gpointer data);
AnjutaProjectNodeType anjuta_project_node_get_type (const AnjutaProjectNode *node);
diff --git a/libanjuta/anjuta-token-file.c b/libanjuta/anjuta-token-file.c
index 9fb09a8..7964cff 100644
--- a/libanjuta/anjuta-token-file.c
+++ b/libanjuta/anjuta-token-file.c
@@ -33,15 +33,11 @@ struct _AnjutaTokenFile
{
GObject parent;
- GFile* file;
-
- gsize length;
- gchar *content;
-
- AnjutaToken *first;
- AnjutaToken *last;
+ GFile* file; /* Corresponding GFile */
- guint line_width;
+ AnjutaToken *content; /* Current file content */
+
+ AnjutaToken *save; /* List of memory block used */
};
struct _AnjutaTokenFileClass
@@ -54,118 +50,100 @@ static GObjectClass *parent_class = NULL;
/* Helpers functions
*---------------------------------------------------------------------------*/
-/* Create a directories, including parents if necessary. This function
- * exists in GLIB 2.18, but we need only 2.16 currently.
- * */
+/* Private functions
+ *---------------------------------------------------------------------------*/
-static gboolean
-make_directory_with_parents (GFile *file,
- GCancellable *cancellable,
- GError **error)
+static AnjutaToken*
+anjuta_token_file_find_position (AnjutaTokenFile *file, AnjutaToken *token)
{
- GError *path_error = NULL;
- GList *children = NULL;
+ AnjutaToken *start;
+ const gchar *pos;
+ const gchar *ptr;
+ const gchar *end;
+
+ if (token == NULL) return NULL;
- for (;;)
+ if (anjuta_token_get_length (token) == 0)
{
- if (g_file_make_directory (file, cancellable, &path_error))
- {
- /* Making child directory succeed */
- if (children == NULL)
- {
- /* All directories have been created */
- return TRUE;
- }
- else
- {
- /* Get next child directory */
- g_object_unref (file);
- file = (GFile *)children->data;
- children = g_list_delete_link (children, children);
- }
- }
- else if (g_error_matches (path_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+ AnjutaToken *last = anjuta_token_last (token);
+
+ for (; (token != NULL) && (token != last); token = anjuta_token_next (token))
{
- g_clear_error (&path_error);
- children = g_list_prepend (children, file);
- file = g_file_get_parent (file);
+ if (anjuta_token_get_length (token) != 0) break;
}
- else
- {
- g_object_unref (file);
- g_list_foreach (children, (GFunc)g_object_unref, NULL);
- g_list_free (children);
- g_propagate_error (error, path_error);
+
+ if (anjuta_token_get_length (token) == 0) return NULL;
+ }
+
+ pos = anjuta_token_get_string (token);
+ for (start = file->content; start != NULL; start = anjuta_token_next (start))
+ {
+ guint len = anjuta_token_get_length (start);
- return FALSE;
+ if (len)
+ {
+ ptr = anjuta_token_get_string (start);
+ end = ptr + len;
+
+ if ((pos >= ptr) && (pos < end)) break;
}
- }
+ }
+ if ((start != NULL) && (ptr != pos))
+ {
+ start = anjuta_token_split (start, pos - ptr);
+ start = anjuta_token_next (start);
+ }
+
+ return start;
}
/* Public functions
*---------------------------------------------------------------------------*/
-const gchar *
-anjuta_token_file_get_content (AnjutaTokenFile *file, GError **error)
+AnjutaToken*
+anjuta_token_file_load (AnjutaTokenFile *file, GError **error)
{
- if (file->content == NULL)
- {
- gchar *content;
- gsize length;
+ gchar *content;
+ gsize length;
+
+ anjuta_token_file_unload (file);
- if (g_file_load_contents (file->file, NULL, &content, &length, NULL, error))
- {
- file->content = content;
- file->length = length;
- }
+ file->save = anjuta_token_new_static (ANJUTA_TOKEN_FILE, NULL);
+ file->content = anjuta_token_new_static (ANJUTA_TOKEN_FILE, NULL);
+
+ if (g_file_load_contents (file->file, NULL, &content, &length, NULL, error))
+ {
+ AnjutaToken *token;
+
+ token = anjuta_token_new_with_string (ANJUTA_TOKEN_FILE, content, length);
+ anjuta_token_prepend_child (file->save, token);
+
+ token = anjuta_token_new_static (ANJUTA_TOKEN_FILE, content);
+ anjuta_token_prepend_child (file->content, token);
}
return file->content;
}
-gsize
-anjuta_token_file_get_length (AnjutaTokenFile *file, GError **error)
-{
- anjuta_token_file_get_content (file, error);
-
- return file->length;
-}
-
-typedef struct _AnjutaTokenFileSaveData AnjutaTokenFileSaveData;
-
-struct _AnjutaTokenFileSaveData
-{
- GError **error;
- GFileOutputStream *stream;
- gboolean fail;
-};
-
-static gboolean
-save_node (AnjutaToken *token, AnjutaTokenFileSaveData *data)
+gboolean
+anjuta_token_file_unload (AnjutaTokenFile *file)
{
- if (!(anjuta_token_get_flags (token) & ANJUTA_TOKEN_REMOVED))
- {
- if (!(anjuta_token_get_flags (token) & ANJUTA_TOKEN_REMOVED) && (anjuta_token_get_length (token)))
- {
- if (g_output_stream_write (G_OUTPUT_STREAM (data->stream), anjuta_token_get_string (token), anjuta_token_get_length (token) * sizeof (char), NULL, data->error) < 0)
- {
- data->fail = TRUE;
-
- return TRUE;
- }
- }
- }
+ if (file->content != NULL) anjuta_token_free (file->content);
+ file->content = NULL;
- return FALSE;
+ if (file->save != NULL) anjuta_token_free (file->save);
+ file->save = NULL;
+
+ return TRUE;
}
gboolean
anjuta_token_file_save (AnjutaTokenFile *file, GError **error)
{
GFileOutputStream *stream;
- gboolean ok;
+ gboolean ok = TRUE;
GError *err = NULL;
- AnjutaTokenFileSaveData data;
+ AnjutaToken *token;
stream = g_file_replace (file->file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &err);
if (stream == NULL)
@@ -175,7 +153,7 @@ anjuta_token_file_save (AnjutaTokenFile *file, GError **error)
/* Perhaps parent directory is missing, try to create it */
GFile *parent = g_file_get_parent (file->file);
- if (make_directory_with_parents (parent, NULL, NULL))
+ if (g_file_make_directory_with_parents (parent, NULL, NULL))
{
g_object_unref (parent);
g_clear_error (&err);
@@ -197,14 +175,22 @@ anjuta_token_file_save (AnjutaTokenFile *file, GError **error)
}
}
- data.error = error;
- data.stream = stream;
- data.fail = FALSE;
- g_node_traverse ((GNode *)file->first, G_PRE_ORDER, G_TRAVERSE_ALL, -1, (GNodeTraverseFunc)save_node, &data);
- ok = g_output_stream_close (G_OUTPUT_STREAM (stream), NULL, NULL);
+ for (token = file->content; token != NULL; token = anjuta_token_next (token))
+ {
+ if (!(anjuta_token_get_flags (token) & ANJUTA_TOKEN_REMOVED) && (anjuta_token_get_length (token)))
+ {
+ if (g_output_stream_write (G_OUTPUT_STREAM (stream), anjuta_token_get_string (token), anjuta_token_get_length (token) * sizeof (char), NULL, error) < 0)
+ {
+ ok = FALSE;
+ break;
+ }
+ }
+ }
+
+ ok = ok && g_output_stream_close (G_OUTPUT_STREAM (stream), NULL, NULL);
g_object_unref (stream);
- return !data.fail;
+ return ok;
}
void
@@ -214,44 +200,192 @@ anjuta_token_file_move (AnjutaTokenFile *file, GFile *new_file)
file->file = new_file != NULL ? g_object_ref (new_file) : NULL;
}
-void
-anjuta_token_file_append (AnjutaTokenFile *file, AnjutaToken *token)
+/**
+ * anjuta_token_file_update:
+ * @file: a #AnjutaTokenFile derived class object.
+ * @token: Token to update.
+ *
+ * Update the file with all changed token starting from @token. The function can
+ * return an error if the token is not in the file.
+ *
+ * Return value: TRUE is the update is done without error.
+ */
+gboolean
+anjuta_token_file_update (AnjutaTokenFile *file, AnjutaToken *token)
{
- if (file->last == NULL)
+ AnjutaToken *prev;
+ AnjutaToken *next;
+ AnjutaToken *last;
+ guint added;
+
+ /* Find all token needing an update */
+
+ /* Find following tokens */
+ for (last = token; last != NULL; last = anjuta_token_next (last))
+ {
+ /* Get all tokens in group */
+ last = anjuta_token_last (last);
+
+ gint flags = anjuta_token_get_flags (last);
+ if (!(flags & (ANJUTA_TOKEN_ADDED | ANJUTA_TOKEN_REMOVED))) break;
+ }
+
+ /* Find first modified token */
+ for (;;)
{
- file->first = token;
+ gint flags = anjuta_token_get_flags (token);
+ if (flags & (ANJUTA_TOKEN_ADDED | ANJUTA_TOKEN_REMOVED)) break;
+ if (token == last)
+ {
+ /* No changed */
+ return TRUE;
+ }
+ token = anjuta_token_next (token);
}
- else if (file->last == file->first)
+
+ /* Find previous token */
+ for (prev = token; prev != NULL; prev = anjuta_token_previous (prev))
{
- g_node_insert_after ((GNode *)file->first, NULL, (GNode *)token);
+ gint flags = anjuta_token_get_flags (prev);
+ if ((anjuta_token_get_length (prev) != 0) && !(flags & (ANJUTA_TOKEN_ADDED | ANJUTA_TOKEN_REMOVED))) break;
+ token = prev;
}
- else
+
+ /* Delete removed token and compute length of added token */
+ added = 0;
+ for (next = token; (next != NULL) && (next != last);)
{
- while (((GNode *)file->last)->parent != (GNode *)file->first)
+ gint flags = anjuta_token_get_flags (next);
+
+ if ((flags & ANJUTA_TOKEN_REMOVED) && (anjuta_token_get_length (next) > 0))
{
- file->last = (AnjutaToken *)((GNode *)file->last)->parent;
+ AnjutaToken *pos = anjuta_token_file_find_position (file, next);
+ guint len = anjuta_token_get_length (next);
+
+ if (pos != NULL)
+ {
+ while (len != 0)
+ {
+ guint flen = anjuta_token_get_length (pos);
+ if (len < flen)
+ {
+ pos = anjuta_token_split (pos, len);
+ flen = len;
+ }
+ pos = anjuta_token_free (pos);
+ len -= flen;
+ }
+ next = anjuta_token_free (next);
+ continue;
+ }
+ }
+ else if (flags & ANJUTA_TOKEN_ADDED)
+ {
+ added += anjuta_token_get_length (next);
}
- g_node_insert_after ((GNode *)file->first, (GNode *)file->last, (GNode *)token);
+ next = anjuta_token_next (next);
}
- file->last = token;
-}
-void
-anjuta_token_file_update_line_width (AnjutaTokenFile *file, guint width)
-{
- if (width > file->line_width) file->line_width = width;
-}
+ /* Add new token */
+ if (added != 0)
+ {
+ gchar *value;
+ AnjutaToken *add;
+ AnjutaToken *start = NULL;
+
+ value = g_new (gchar, added);
+ anjuta_token_prepend_child (file->save, anjuta_token_new_with_string (ANJUTA_TOKEN_NAME, value, added));
+
+ /* Find token position */
+ if (prev != NULL)
+ {
+ start = anjuta_token_file_find_position (file, prev);
+ if (start != NULL) start = anjuta_token_split (start, anjuta_token_get_length (prev));
+ }
-AnjutaToken*
-anjuta_token_file_first (AnjutaTokenFile *file)
-{
- return file->first;
+ /* Insert token */
+ add = anjuta_token_new_fragment (ANJUTA_TOKEN_NAME, value, added);
+ if (start == NULL)
+ {
+ anjuta_token_prepend_child (file->content, add);
+ }
+ else
+ {
+ anjuta_token_insert_after (start, add);
+ }
+
+ for (next = token; (next != NULL) && (next != last); next = anjuta_token_next (next))
+ {
+ gint flags = anjuta_token_get_flags (next);
+
+
+ if (flags & ANJUTA_TOKEN_ADDED)
+ {
+ guint len = anjuta_token_get_length (next);
+
+ if (len > 0)
+ {
+ memcpy(value, anjuta_token_get_string (next), len);
+ anjuta_token_set_string (next, value, len);
+ value += len;
+ }
+ }
+ }
+ }
+
+ fprintf (stdout, "Dump config list from file:\n");
+ anjuta_token_dump (file->content);
+
+
+ return TRUE;
}
-AnjutaToken*
-anjuta_token_file_last (AnjutaTokenFile *file)
+gboolean
+anjuta_token_file_get_token_location (AnjutaTokenFile *file, AnjutaTokenFileLocation *location, AnjutaToken *token)
{
- return file->last;
+ AnjutaTokenFileLocation loc = {NULL, 1, 1};
+ AnjutaToken *pos;
+ const gchar *target = anjuta_token_get_string (token);
+
+ for (pos = file->content; pos != NULL; pos = anjuta_token_next (pos))
+ {
+ if (!(anjuta_token_get_flags (pos) & ANJUTA_TOKEN_REMOVED) && (anjuta_token_get_length (pos)))
+ {
+ const gchar *ptr;
+ const gchar *end;
+
+ ptr = anjuta_token_get_string (pos);
+ end = ptr + anjuta_token_get_length (pos);
+
+ for (; ptr != end; ptr++)
+ {
+ if (*ptr == '\n')
+ {
+ /* New line */
+ loc.line++;
+ loc.column = 1;
+ }
+ else
+ {
+ loc.column++;
+ }
+
+ if (ptr == target)
+ {
+ if (location != NULL)
+ {
+ location->filename = file->file == NULL ? NULL : g_file_get_parse_name (file->file);
+ location->line = loc.line;
+ location->column = loc.column;
+ }
+
+ return TRUE;
+ }
+ }
+ }
+ }
+
+ return FALSE;
}
GFile*
@@ -260,10 +394,15 @@ anjuta_token_file_get_file (AnjutaTokenFile *file)
return file->file;
}
-guint
-anjuta_token_file_get_line_width (AnjutaTokenFile *file)
+AnjutaToken*
+anjuta_token_file_get_content (AnjutaTokenFile *file)
{
- return file->line_width;
+ if (file->content == NULL)
+ {
+ anjuta_token_file_load (file, NULL);
+ }
+
+ return file->content;
}
/* GObject functions
@@ -279,10 +418,7 @@ anjuta_token_file_dispose (GObject *object)
{
AnjutaTokenFile *file = ANJUTA_TOKEN_FILE (object);
- anjuta_token_free (file->first);
-
- if (file->content) g_free (file->content);
- file->content = NULL;
+ anjuta_token_file_unload (file);
if (file->file) g_object_unref (file->file);
file->file = NULL;
@@ -297,6 +433,8 @@ static void
anjuta_token_file_instance_init (AnjutaTokenFile *file)
{
file->file = NULL;
+ file->content = NULL;
+ file->save = NULL;
}
/* class_init intialize the class itself not the instance */
@@ -351,12 +489,7 @@ anjuta_token_file_new (GFile *gfile)
{
AnjutaTokenFile *file = g_object_new (ANJUTA_TOKEN_FILE_TYPE, NULL);
- if (gfile)
- {
- file->file = g_object_ref (gfile);
- file->first = anjuta_token_new_static (ANJUTA_TOKEN_FILE, NULL);
- file->last = file->first;
- }
+ if (gfile) file->file = g_object_ref (gfile);
return file;
};
diff --git a/libanjuta/anjuta-token-file.h b/libanjuta/anjuta-token-file.h
index d1053f1..1061d86 100644
--- a/libanjuta/anjuta-token-file.h
+++ b/libanjuta/anjuta-token-file.h
@@ -37,23 +37,29 @@ G_BEGIN_DECLS
typedef struct _AnjutaTokenFile AnjutaTokenFile;
typedef struct _AnjutaTokenFileClass AnjutaTokenFileClass;
+typedef struct
+{
+ gchar *filename;
+ guint line;
+ guint column;
+} AnjutaTokenFileLocation;
+
GType anjuta_token_file_get_type (void);
AnjutaTokenFile *anjuta_token_file_new (GFile *file);
void anjuta_token_file_free (AnjutaTokenFile *file);
-const gchar* anjuta_token_file_get_content (AnjutaTokenFile *file, GError **error);
-gsize anjuta_token_file_get_length (AnjutaTokenFile *file, GError **error);
-void anjuta_token_file_move (AnjutaTokenFile *file, GFile *new_file);
+AnjutaToken* anjuta_token_file_load (AnjutaTokenFile *file, GError **error);
+gboolean anjuta_token_file_unload (AnjutaTokenFile *file);
gboolean anjuta_token_file_save (AnjutaTokenFile *file, GError **error);
+void anjuta_token_file_move (AnjutaTokenFile *file, GFile *new_file);
-void anjuta_token_file_append (AnjutaTokenFile *file, AnjutaToken *token);
-void anjuta_token_file_update_line_width (AnjutaTokenFile *file, guint width);
+gboolean anjuta_token_file_update (AnjutaTokenFile *file, AnjutaToken *token);
-AnjutaToken* anjuta_token_file_first (AnjutaTokenFile *file);
-AnjutaToken* anjuta_token_file_last (AnjutaTokenFile *file);
+gboolean anjuta_token_file_get_token_location (AnjutaTokenFile *file, AnjutaTokenFileLocation *location, AnjutaToken *token);
GFile *anjuta_token_file_get_file (AnjutaTokenFile *file);
-guint anjuta_token_file_get_line_width (AnjutaTokenFile *file);
+AnjutaToken *anjuta_token_file_get_content (AnjutaTokenFile *file);
+
G_END_DECLS
diff --git a/libanjuta/anjuta-token-list.c b/libanjuta/anjuta-token-list.c
new file mode 100644
index 0000000..ba89ea3
--- /dev/null
+++ b/libanjuta/anjuta-token-list.c
@@ -0,0 +1,756 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta-token-list.c
+ * Copyright (C) Sébastien Granjoux 2009 <seb sfo free fr>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "anjuta-token-list.h"
+
+#include "libanjuta/anjuta-debug.h"
+
+#include <string.h>
+
+/* Type definition
+ *---------------------------------------------------------------------------*/
+
+typedef struct _AnjutaTokenStyleSeparator AnjutaTokenStyleSeparator;
+
+struct _AnjutaTokenStyleSeparator
+{
+ guint count;
+ gchar *value;
+ gboolean eol;
+};
+
+struct _AnjutaTokenStyle
+{
+ guint max_width;
+ GHashTable *separator;
+};
+
+/* Private functions
+ *---------------------------------------------------------------------------*/
+
+void free_separator (AnjutaTokenStyleSeparator *sep, gpointer user_data)
+{
+ g_free (sep->value);
+ g_slice_free (AnjutaTokenStyleSeparator, sep);
+}
+
+void free_separator_list (guint key, GList *value, gpointer user_data)
+{
+ /* Free list elements */
+ g_list_foreach (value, (GFunc)free_separator, NULL);
+ g_list_free (value);
+}
+
+AnjutaTokenStyleSeparator*
+anjuta_token_style_insert_separator (AnjutaTokenStyle *style, guint key, const gchar *value)
+{
+ GList *list;
+ GList *last = NULL;
+ GList *sibling = NULL;
+ AnjutaTokenStyleSeparator *sep;
+
+
+ /* Look the separator is already registered */
+ list = (GList *)g_hash_table_lookup (style->separator, GINT_TO_POINTER (key));
+ if (list != NULL)
+ {
+ for (sibling = list; sibling != NULL; sibling = g_list_next(sibling))
+ {
+ sep = (AnjutaTokenStyleSeparator *)sibling->data;
+
+ /* Keep the first separator with count = 1, to insert the new one if
+ * not found */
+ if ((last == NULL) && (sep->count == 1)) last = sibling;
+
+ if (value == NULL)
+ {
+ if (sep->value == NULL)
+ {
+ sep->count++;
+ break;
+ }
+ }
+ else if ((sep->value != NULL) && (strcmp (sep->value, value) == 0))
+ {
+ sep->count++;
+ break;
+ }
+ }
+ }
+
+ if (sibling != NULL)
+ {
+ /* Increment the separator count, Move it if needed */
+ for (last = g_list_previous (sibling); last != NULL; last = g_list_previous (sibling))
+ {
+ if (((AnjutaTokenStyleSeparator *)sibling->data)->count >= ((AnjutaTokenStyleSeparator *)last->data)->count)
+ {
+ last->next = sibling->next;
+ sibling->next = last;
+ sibling->prev = last->prev;
+ last->prev = sibling;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if (last == NULL)
+ {
+ /* Update the list head */
+ list = sibling;
+ g_hash_table_replace (style->separator, GINT_TO_POINTER (key), list);
+ }
+
+ return (AnjutaTokenStyleSeparator *)sibling->data;
+ }
+ else
+ {
+ /* Create a new separator */
+ sep = g_slice_new0 (AnjutaTokenStyleSeparator);
+ sep->count = 1;
+ sep->value = g_strdup (value);
+ sep->eol = value == NULL ? FALSE : strchr (value, '\n') != NULL;
+ list = g_list_insert_before (list, last, sep);
+ g_hash_table_replace (style->separator, GINT_TO_POINTER (key), list);
+
+ return sep;
+ }
+}
+
+AnjutaTokenStyleSeparator*
+anjuta_token_style_insert_separator_between (AnjutaTokenStyle *style, gint next, gint prev, const gchar *value)
+{
+ return anjuta_token_style_insert_separator (style, ((guint)prev & 0xFFFF) | (((guint)next & 0xFFFF) << 16), value);
+}
+
+static AnjutaToken*
+anjuta_token_style_lookup (AnjutaTokenStyle *style, AnjutaTokenType type, gboolean eol)
+{
+ GList *list;
+
+ list = g_hash_table_lookup (style->separator, GINT_TO_POINTER (type));
+
+ return anjuta_token_new_string (ANJUTA_TOKEN_NAME, ((AnjutaTokenStyleSeparator *)list->data)->value);
+}
+
+/* Public style functions
+ *---------------------------------------------------------------------------*/
+
+void
+anjuta_token_style_update (AnjutaTokenStyle *style, AnjutaToken *list)
+{
+ AnjutaToken *token;
+ AnjutaToken *next_token;
+ guint prev = 0;
+ guint next = 0;
+ guint line_width = 0;
+ guint sep_count = 0;
+
+ /* Initialize first line width */
+ for (token = list; token != NULL; token = anjuta_token_previous (token))
+ {
+ gchar *value = anjuta_token_evaluate (token);
+ const gchar *eol = strrchr (value, '\n');
+ gsize len = strlen (value);
+
+ g_free (value);
+
+
+ if (eol != NULL)
+ {
+ line_width = value + len - eol;
+ break;
+ }
+
+ line_width += len;
+ }
+
+ for (token = anjuta_token_first_item (list); token != NULL; token = next_token)
+ {
+ gchar *value = NULL;
+ const gchar *eol;
+ gsize len;
+ gint type;
+
+ next_token = anjuta_token_next_item (token);
+ type = anjuta_token_get_type (token);
+ next = next_token == NULL ? 0 : anjuta_token_get_type (next_token);
+
+ value = anjuta_token_evaluate (token);
+ if (value == NULL) continue;
+
+ len = strlen (value);
+ eol = strrchr (value, '\n');
+ if (eol != NULL) len -= (eol - value);
+ g_free (value);
+
+ line_width += len;
+
+ switch (type)
+ {
+ case ANJUTA_TOKEN_START:
+ case ANJUTA_TOKEN_LAST:
+ case ANJUTA_TOKEN_NEXT:
+ break;
+ default:
+ if (eol != NULL)
+ {
+ line_width = len;
+ sep_count = 0;
+ }
+ continue;
+ }
+
+ value = anjuta_token_evaluate (token);
+ anjuta_token_style_insert_separator_between (style, 0, type, value);
+ if (type == ANJUTA_TOKEN_NEXT)
+ {
+ anjuta_token_style_insert_separator_between (style, next, prev, value);
+ anjuta_token_style_insert_separator_between (style, next, ANJUTA_TOKEN_ANY, value);
+ anjuta_token_style_insert_separator_between (style, ANJUTA_TOKEN_ANY, prev, value);
+ }
+ g_free (value);
+
+ if (eol == NULL)
+ {
+ sep_count++;
+ }
+ else
+ {
+ if ((sep_count > 1) && (line_width > style->max_width))
+ {
+ style->max_width = line_width;
+ }
+ sep_count = 0;
+ line_width = len;
+ }
+ }
+}
+
+void
+anjuta_token_style_format (AnjutaTokenStyle *style, AnjutaToken *list)
+{
+ AnjutaToken *item;
+ AnjutaToken *last;
+ AnjutaToken *text;
+ AnjutaToken *prev;
+
+ /* Find following tokens */
+ for (last = list; last != NULL; last = anjuta_token_next (last))
+ {
+ /* Get all tokens in group */
+ last = anjuta_token_last (last);
+
+ gint flags = anjuta_token_get_flags (last);
+ if (!(flags & (ANJUTA_TOKEN_ADDED | ANJUTA_TOKEN_REMOVED))) break;
+ }
+
+ /* Find previous token */
+ for (prev = list; prev != NULL; prev = anjuta_token_previous (prev))
+ {
+ gint flags = anjuta_token_get_flags (prev);
+ if ((anjuta_token_get_length (prev) != 0) && !(flags & (ANJUTA_TOKEN_ADDED | ANJUTA_TOKEN_REMOVED))) break;
+ list = prev;
+ }
+
+ for (item = list; (item != NULL) && (item != last); item = anjuta_token_next (item))
+ {
+ if (anjuta_token_get_flags (item) & ANJUTA_TOKEN_ADDED)
+ {
+ switch (anjuta_token_get_type (item))
+ {
+ case ANJUTA_TOKEN_START:
+ text = anjuta_token_style_lookup (style, ANJUTA_TOKEN_START, FALSE);
+ anjuta_token_set_flags (text, ANJUTA_TOKEN_ADDED);
+ anjuta_token_insert_after (item, text);
+ anjuta_token_merge (item, text);
+ item = text;
+ break;
+ case ANJUTA_TOKEN_NEXT:
+ text = anjuta_token_style_lookup (style, ANJUTA_TOKEN_NEXT, FALSE);
+ anjuta_token_set_flags (text, ANJUTA_TOKEN_ADDED);
+ anjuta_token_insert_after (item, text);
+ anjuta_token_merge (item, text);
+ item = text;
+ break;
+ case ANJUTA_TOKEN_LAST:
+ text = anjuta_token_style_lookup (style, ANJUTA_TOKEN_LAST, FALSE);
+ anjuta_token_set_flags (text, ANJUTA_TOKEN_ADDED);
+ anjuta_token_insert_after (item, text);
+ anjuta_token_merge (item, text);
+ item = text;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
+
+/* Word functions
+ *---------------------------------------------------------------------------*/
+
+/**
+ * anjuta_token_first_word:
+ * @list: a #AnjutaToken object being a list
+ *
+ * Get the first word of the list. A word is an item in the list which is not
+ * a space or a separator.
+ *
+ * Return value: A #AnjutaToken representing the first word or NULL.
+ */
+AnjutaToken *
+anjuta_token_first_word (AnjutaToken *list)
+{
+ AnjutaToken *item;
+
+ for (item = anjuta_token_first_item (list); item != NULL; item = anjuta_token_next_item (item))
+ {
+ switch (anjuta_token_get_type (item))
+ {
+ case ANJUTA_TOKEN_START:
+ case ANJUTA_TOKEN_NEXT:
+ continue;
+ case ANJUTA_TOKEN_LAST:
+ item = NULL;
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+
+ return item;
+}
+
+AnjutaToken *
+anjuta_token_next_word (AnjutaToken *item)
+{
+ for (item = anjuta_token_next_item (item); item != NULL; item = anjuta_token_next_item (item))
+ {
+ switch (anjuta_token_get_type (item))
+ {
+ case ANJUTA_TOKEN_START:
+ case ANJUTA_TOKEN_NEXT:
+ continue;
+ case ANJUTA_TOKEN_LAST:
+ item = NULL;
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+
+ return item;
+}
+
+AnjutaToken *
+anjuta_token_nth_word (AnjutaToken *list, guint n)
+{
+ AnjutaToken *item;
+ gboolean no_item = TRUE;
+
+ for (item = anjuta_token_first_item (list); item != NULL; item = anjuta_token_next_item (item))
+ {
+ switch (anjuta_token_get_type (item))
+ {
+ case ANJUTA_TOKEN_START:
+ break;
+ case ANJUTA_TOKEN_NEXT:
+ if (no_item)
+ {
+ if (n == 0) return NULL;
+ n--;
+ }
+ no_item = TRUE;
+ break;
+ case ANJUTA_TOKEN_LAST:
+ return NULL;
+ default:
+ if (n == 0) return item;
+ n--;
+ no_item = FALSE;
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+AnjutaToken *
+anjuta_token_replace_nth_word (AnjutaToken *list, guint n, AnjutaToken *item)
+{
+ AnjutaToken *token;
+ gboolean no_item = TRUE;
+
+ token = anjuta_token_first_item (list);
+ if (token == NULL)
+ {
+ token = anjuta_token_insert_after (token, anjuta_token_new_static (ANJUTA_TOKEN_LAST | ANJUTA_TOKEN_ADDED, NULL));
+ anjuta_token_merge (list, token);
+ }
+
+ for (n++;;)
+ {
+ AnjutaToken *next;
+
+ switch (anjuta_token_get_type (token))
+ {
+ case ANJUTA_TOKEN_LAST:
+ if (no_item)
+ {
+ n--;
+ if (n == 0)
+ {
+ token = anjuta_token_insert_before (token, item);
+ return token;
+ }
+ }
+ token = anjuta_token_insert_before (token, anjuta_token_new_static (ANJUTA_TOKEN_NEXT | ANJUTA_TOKEN_ADDED, NULL));
+ no_item = TRUE;
+ break;
+ case ANJUTA_TOKEN_NEXT:
+ if (no_item)
+ {
+ n--;
+ if (n == 0)
+ {
+ token = anjuta_token_insert_before (token, item);
+ return token;
+ }
+ }
+ no_item = TRUE;
+ break;
+ case ANJUTA_TOKEN_ITEM:
+ n--;
+ if (n == 0)
+ {
+ anjuta_token_set_flags (token, ANJUTA_TOKEN_REMOVED);
+ token = anjuta_token_insert_before (token, item);
+ return token;
+ }
+ no_item = FALSE;
+ break;
+ default:
+ break;
+ }
+
+ next = anjuta_token_next_item (token);
+ if (next == NULL)
+ {
+ token = anjuta_token_insert_after (token, anjuta_token_new_static (ANJUTA_TOKEN_LAST | ANJUTA_TOKEN_ADDED, NULL));
+ anjuta_token_merge (list, token);
+ }
+ else
+ {
+ token = next;
+ }
+ }
+}
+
+AnjutaToken *
+anjuta_token_insert_word_before (AnjutaToken *list, AnjutaToken *sibling, AnjutaToken *item)
+{
+ AnjutaToken *token;
+
+ if (list == NULL) list = anjuta_token_list (sibling);
+
+ for (token = anjuta_token_first_item (list); token != NULL;)
+ {
+ AnjutaToken *next;
+
+ switch (anjuta_token_get_type (token))
+ {
+ case ANJUTA_TOKEN_LAST:
+ anjuta_token_insert_before (token, anjuta_token_new_static (ANJUTA_TOKEN_NEXT | ANJUTA_TOKEN_ADDED, NULL));
+ anjuta_token_insert_before (token, item);
+ return item;
+ case ANJUTA_TOKEN_START:
+ if (token == sibling)
+ {
+ anjuta_token_insert_after (token, anjuta_token_new_static (ANJUTA_TOKEN_NEXT | ANJUTA_TOKEN_ADDED, NULL));
+ anjuta_token_insert_after (token, item);
+ return item;
+ }
+ break;
+ case ANJUTA_TOKEN_NEXT:
+ if (token == sibling)
+ {
+ token = anjuta_token_insert_before (token, item);
+ anjuta_token_insert_before (token, anjuta_token_new_static (ANJUTA_TOKEN_NEXT | ANJUTA_TOKEN_ADDED, NULL));
+ return item;
+ }
+ break;
+ default:
+ if (token == sibling)
+ {
+ anjuta_token_insert_before (token, anjuta_token_new_static (ANJUTA_TOKEN_NEXT | ANJUTA_TOKEN_ADDED, NULL));
+ anjuta_token_insert_before (token, item);
+ return item;
+ }
+ break;
+ }
+
+ next = anjuta_token_next_item (token);
+ if (next == NULL)
+ {
+ token = anjuta_token_insert_after (token, anjuta_token_new_static (ANJUTA_TOKEN_NEXT | ANJUTA_TOKEN_ADDED, NULL));
+ anjuta_token_insert_after (token, item);
+ return item;
+ }
+ token = next;
+ }
+
+ anjuta_token_prepend_items (list, item);
+
+ return item;
+}
+
+AnjutaToken *
+anjuta_token_insert_word_after (AnjutaToken *list, AnjutaToken *sibling, AnjutaToken *item)
+{
+ AnjutaToken *token;
+
+ if (list == NULL) list = anjuta_token_list (sibling);
+
+ for (token = anjuta_token_first_item (list); token != NULL;)
+ {
+ AnjutaToken *next;
+
+ switch (anjuta_token_get_type (token))
+ {
+ case ANJUTA_TOKEN_LAST:
+ anjuta_token_insert_before (token, anjuta_token_new_static (ANJUTA_TOKEN_NEXT | ANJUTA_TOKEN_ADDED, NULL));
+ anjuta_token_insert_before (token, item);
+ return item;
+ case ANJUTA_TOKEN_START:
+ if (token == sibling)
+ {
+ anjuta_token_insert_after (token, anjuta_token_new_static (ANJUTA_TOKEN_NEXT | ANJUTA_TOKEN_ADDED, NULL));
+ anjuta_token_insert_after (token, item);
+ return item;
+ }
+ break;
+ case ANJUTA_TOKEN_NEXT:
+ if (token == sibling)
+ {
+ token = anjuta_token_insert_after (token, item);
+ anjuta_token_insert_after (token, anjuta_token_new_static (ANJUTA_TOKEN_NEXT | ANJUTA_TOKEN_ADDED, NULL));
+ return item;
+ }
+ break;
+ default:
+ if (token == sibling)
+ {
+ token = anjuta_token_insert_after (token, anjuta_token_new_static (ANJUTA_TOKEN_NEXT | ANJUTA_TOKEN_ADDED, NULL));
+ anjuta_token_insert_after (token, item);
+ return item;
+ }
+ break;
+ }
+
+ next = anjuta_token_next_item (token);
+ if (next == NULL)
+ {
+ token = anjuta_token_insert_after (token, anjuta_token_new_static (ANJUTA_TOKEN_NEXT | ANJUTA_TOKEN_ADDED, NULL));
+ anjuta_token_insert_after (token, item);
+ return item;
+ }
+ token = next;
+ }
+
+ anjuta_token_prepend_items (list, item);
+
+ return item;
+}
+
+AnjutaToken*
+anjuta_token_remove_word (AnjutaToken *token, AnjutaTokenStyle *user_style)
+{
+ AnjutaTokenStyle *style;
+ AnjutaToken *space;
+
+ style = user_style != NULL ? user_style : anjuta_token_style_new (NULL," ","\n",NULL,0);
+ anjuta_token_style_update (style, anjuta_token_parent (token));
+
+ anjuta_token_set_flags (token, ANJUTA_TOKEN_REMOVED);
+ space = anjuta_token_next_item (token);
+ if (space && (anjuta_token_get_type (space) == ANJUTA_TOKEN_SPACE) && (anjuta_token_next (space) != NULL))
+ {
+ /* Remove following space */
+ anjuta_token_set_flags (space, ANJUTA_TOKEN_REMOVED);
+ }
+ else
+ {
+ space = anjuta_token_previous_item (token);
+ if (space && (anjuta_token_get_type (space) == ANJUTA_TOKEN_SPACE) && (anjuta_token_previous (space) != NULL))
+ {
+ anjuta_token_set_flags (space, ANJUTA_TOKEN_REMOVED);
+ }
+ }
+
+ anjuta_token_style_format (style, anjuta_token_parent (token));
+ if (user_style == NULL) anjuta_token_style_free (style);
+
+ return NULL;
+}
+
+AnjutaToken *
+anjuta_token_insert_token_list (gboolean after, AnjutaToken *pos,...)
+{
+ AnjutaToken *first = NULL;
+ GList *group = NULL;
+ va_list args;
+ gint type;
+
+ va_start (args, pos);
+
+ for (type = va_arg (args, gint); type != 0; type = va_arg (args, gint))
+ {
+ gchar *string = va_arg (args, gchar *);
+ AnjutaToken *token;
+
+ if (after)
+ {
+ pos = token = anjuta_token_insert_after (pos, anjuta_token_new_string (type | ANJUTA_TOKEN_ADDED, string));
+ }
+ else
+ {
+ token = anjuta_token_insert_before (pos, anjuta_token_new_string (type | ANJUTA_TOKEN_ADDED, string));
+ }
+ if (first == NULL) first = token;
+
+ if (group != NULL)
+ {
+ anjuta_token_merge ((AnjutaToken *)group->data, token);
+ }
+
+ if (string == NULL)
+ {
+ switch (type)
+ {
+ case ANJUTA_TOKEN_LIST:
+ break;
+ default:
+ group = g_list_delete_link (group, group);
+ break;
+ }
+ group = g_list_prepend (group, token);
+ }
+ }
+ g_list_free (group);
+
+ va_end (args);
+
+ return first;
+}
+
+AnjutaToken *
+anjuta_token_find_type (AnjutaToken *list, gint flags, AnjutaTokenType* types)
+{
+ AnjutaToken *tok;
+ AnjutaToken *last = NULL;
+
+ for (tok = list; tok != NULL; tok = anjuta_token_next (tok))
+ {
+ AnjutaTokenType *type;
+ for (type = types; *type != 0; type++)
+ {
+ if (anjuta_token_get_type (tok) == *type)
+ {
+ last = tok;
+ if (flags & ANJUTA_TOKEN_SEARCH_NOT) break;
+ if (!(flags & ANJUTA_TOKEN_SEARCH_LAST)) break;
+ }
+ }
+ if ((flags & ANJUTA_TOKEN_SEARCH_NOT) && (*type == 0)) break;
+ }
+
+ return last;
+}
+
+AnjutaToken *
+anjuta_token_skip_comment (AnjutaToken *token)
+{
+ if (token == NULL) return NULL;
+
+ for (;;)
+ {
+ for (;;)
+ {
+ AnjutaToken *next = anjuta_token_next (token);
+
+ if (next == NULL) return token;
+
+ switch (anjuta_token_get_type (token))
+ {
+ case ANJUTA_TOKEN_FILE:
+ case ANJUTA_TOKEN_SPACE:
+ token = next;
+ continue;
+ case ANJUTA_TOKEN_COMMENT:
+ token = next;
+ break;
+ default:
+ return token;
+ }
+ break;
+ }
+
+ for (;;)
+ {
+ AnjutaToken *next = anjuta_token_next (token);
+
+ if (next == NULL) return token;
+ token = next;
+ if (anjuta_token_get_type (token) == ANJUTA_TOKEN_EOL) break;
+ }
+ }
+}
+
+/* Constructor & Destructor
+ *---------------------------------------------------------------------------*/
+
+AnjutaTokenStyle *
+anjuta_token_style_new (const gchar *start, const gchar *next, const gchar *eol, const gchar *last, guint max_width)
+{
+ AnjutaTokenStyle *style;
+
+ style = g_slice_new0 (AnjutaTokenStyle);
+ style->max_width = max_width;
+
+ style->separator = g_hash_table_new (g_direct_hash, NULL);
+ anjuta_token_style_insert_separator (style, ANJUTA_TOKEN_START, start);
+ anjuta_token_style_insert_separator (style, ANJUTA_TOKEN_NEXT, next);
+ anjuta_token_style_insert_separator (style, ANJUTA_TOKEN_NEXT, eol);
+ anjuta_token_style_insert_separator (style, ANJUTA_TOKEN_LAST, last);
+
+ return style;
+}
+
+void
+anjuta_token_style_free (AnjutaTokenStyle *style)
+{
+ g_hash_table_foreach (style->separator, (GHFunc)free_separator_list, NULL);
+ g_hash_table_destroy (style->separator);
+ g_slice_free (AnjutaTokenStyle, style);
+}
diff --git a/libanjuta/anjuta-token-stream.c b/libanjuta/anjuta-token-stream.c
new file mode 100644
index 0000000..7b10f8e
--- /dev/null
+++ b/libanjuta/anjuta-token-stream.c
@@ -0,0 +1,317 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta-token-stream.c
+ * Copyright (C) Sébastien Granjoux 2009 <seb sfo free fr>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "anjuta-token-stream.h"
+
+#include "anjuta-debug.h"
+
+#include <glib-object.h>
+
+#include <stdio.h>
+#include <string.h>
+
+/**
+ * SECTION:anjuta-token-stream
+ * @title: Anjuta token stream
+ * @short_description: Anjuta token stream
+ * @see_also:
+ * @stability: Unstable
+ * @include: libanjuta/anjuta-token-stream.h
+ *
+ * A #AnjutaTokenStream object reads and writes a list of tokens. It uses two
+ * list. The first list is assigned when the object is created. Each token is
+ * read as characters discarding the separation between tokens. The second list
+ * is written using the data of the first list, so no new memory is allocated,
+ * in order to recreate a new list of tokens.
+ *
+ * This is used when the lexer needs several passes. At the beginning the file
+ * is read as a single token containing the whole file content. The first pass
+ * split this content into tokens. Additional passes are done on some parts of
+ * the token list to get a more precise splitting.
+ *
+ * It is important to not allocate new memory and keep the same character
+ * pointers in the additional passes because the token list does not own the
+ * memory. The address of each character is used to find the position of the
+ * changed data in the file.
+ *
+ * Several objects can be linked together to create a stack. It is used for
+ * included file or variable expansion.
+ */
+
+/* Types declarations
+ *---------------------------------------------------------------------------*/
+
+struct _AnjutaTokenStream
+{
+ /* Input stream */
+ AnjutaToken *first;
+ AnjutaToken *last;
+
+ /* Read position in input stream */
+ AnjutaToken *next;
+ gsize pos;
+
+ /* Write position in input stream */
+ AnjutaToken *start;
+ gsize begin;
+
+ /* Output stream */
+ AnjutaToken *root;
+
+ /* Parent stream */
+ AnjutaTokenStream *parent;
+};
+
+/* Helpers functions
+ *---------------------------------------------------------------------------*/
+
+/* Private functions
+ *---------------------------------------------------------------------------*/
+
+/* Public functions
+ *---------------------------------------------------------------------------*/
+
+/**
+ * anjuta_token_stream_append_token:
+ * @stream: a #AnjutaTokenStream object.
+ * @token: a #AnjutaToken object.
+ *
+ * Append an already existing token in the output stream.
+ */
+void
+anjuta_token_stream_append_token (AnjutaTokenStream *stream, AnjutaToken *token)
+{
+ anjuta_token_append_child (stream->root, token);
+}
+
+/**
+ * anjuta_token_stream_tokenize:
+ * @stream: a #AnjutaTokenStream object.
+ * @type: a token type.
+ * @length: the token length in character.
+ *
+ * Create a token of type from the last length characters previously read and
+ * append it in the output stream. The characters are not copied in the output
+ * stream, the new token uses the same characters.
+ *
+ * Return value: The created token.
+ */
+AnjutaToken*
+anjuta_token_stream_tokenize (AnjutaTokenStream *stream, gint type, gsize length)
+{
+ AnjutaToken *frag;
+ AnjutaToken *end;
+
+ frag = anjuta_token_new_fragment (type, NULL, 0);
+
+ for (end = stream->start; end != NULL;)
+ {
+ if (anjuta_token_get_type (end) < ANJUTA_TOKEN_PARSED)
+ {
+ gint toklen = anjuta_token_get_length (end);
+ AnjutaToken *copy = anjuta_token_cut (end, stream->begin, length);
+
+ if (toklen >= (length + stream->begin))
+ {
+
+ if (end == stream->start)
+ {
+ /* Get whole token */
+ anjuta_token_free (frag);
+ anjuta_token_set_type (copy, type);
+ frag = copy;
+ }
+ else
+ {
+ /* Get several token */
+ anjuta_token_append_child (frag, copy);
+ }
+
+ if (toklen == (length + stream->begin))
+ {
+ stream->start = anjuta_token_next (end);
+ stream->begin = 0;
+ }
+ else
+ {
+ stream->start = end;
+ stream->begin += length;
+ }
+ break;
+ }
+ else
+ {
+ anjuta_token_append_child (frag, copy);
+ length -= toklen;
+ end = anjuta_token_next (end);
+ stream->begin = 0;
+ }
+ }
+ else
+ {
+ end = anjuta_token_next (end);
+ stream->begin = 0;
+ }
+ }
+
+ anjuta_token_stream_append_token (stream, frag);
+
+ return frag;
+}
+
+/**
+ * anjuta_token_stream_read:
+ * @stream: a #AnjutaTokenStream object.
+ * @buffer: a character buffer to fill with token data.
+ * @max_size: the size of the buffer.
+ *
+ * Read token from the input stream and write the content as a C string in the
+ * buffer passed as argument.
+ *
+ * Return value: The number of characters written in the buffer.
+ */
+gint
+anjuta_token_stream_read (AnjutaTokenStream *stream, gchar *buffer, gsize max_size)
+{
+ gint result = 0;
+
+ if (stream->next != NULL)
+ {
+ gsize length = anjuta_token_get_length (stream->next);
+
+ if ((anjuta_token_get_type (stream->next) >= ANJUTA_TOKEN_PARSED) || (stream->pos >= length))
+ {
+ for (;;)
+ {
+ /* Last token */
+ if (stream->next == stream->last) return 0;
+
+ if (anjuta_token_get_type (stream->next) >= ANJUTA_TOKEN_PARSED)
+ {
+ stream->next = anjuta_token_next (stream->next);
+ }
+ else
+ {
+ stream->next = anjuta_token_next (stream->next);
+ }
+
+ if ((stream->next == NULL) || (anjuta_token_get_type (stream->next) == 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))
+ {
+ /* Find some data */
+ stream->pos = 0;
+ length = anjuta_token_get_length (stream->next);
+ break;
+ }
+ }
+ }
+
+ if (stream->pos < length)
+ {
+ const gchar *start = anjuta_token_get_string (stream->next);
+
+ length -= stream->pos;
+
+ if (length > max_size) length = max_size;
+ memcpy (buffer, start + stream->pos, length);
+ stream->pos += length;
+ result = length;
+ }
+ }
+
+ return result;
+}
+
+/**
+ * anjuta_token_stream_get_root:
+ * @stream: a #AnjutaTokenStream object.
+ *
+ * Return the root token for the output stream.
+ *
+ * Return value: The output root token.
+ */
+AnjutaToken*
+anjuta_token_stream_get_root (AnjutaTokenStream *stream)
+{
+ g_return_val_if_fail (stream != NULL, NULL);
+
+ return stream->root;
+}
+
+
+
+/* Constructor & Destructor
+ *---------------------------------------------------------------------------*/
+
+/**
+ * anjuta_token_stream_push:
+ * @parent: a parent #AnjutaTokenStream object or NULL.
+ * @token: a token list.
+ *
+ * Create a new stream from a list of tokens. If a parent stream is passed,
+ * the new stream keep a link on it, so we can return it when the new stream
+ * will be destroyed.
+ *
+ * Return value: The newly created stream.
+ */
+AnjutaTokenStream *
+anjuta_token_stream_push (AnjutaTokenStream *parent, AnjutaToken *token)
+{
+ AnjutaTokenStream *child;
+
+ child = g_new (AnjutaTokenStream, 1);
+ child->first = token;
+ child->pos = 0;
+ child->begin = 0;
+ child->parent = parent;
+
+ child->next = anjuta_token_next (token);
+ child->start = child->next;
+ child->last = anjuta_token_last (token);
+ if (child->last == token) child->last = NULL;
+
+ child->root = anjuta_token_new_static (ANJUTA_TOKEN_FILE, NULL);
+
+ return child;
+}
+
+/**
+ * anjuta_token_stream_pop:
+ * @parent: a #AnjutaTokenStream object.
+ *
+ * Destroy the stream object and return the parent stream if it exists.
+ *
+ * Return value: The parent stream or NULL if there is no parent.
+ */
+AnjutaTokenStream *
+anjuta_token_stream_pop (AnjutaTokenStream *stream)
+{
+ AnjutaTokenStream *parent;
+
+ g_return_val_if_fail (stream != NULL, NULL);
+
+ parent = stream->parent;
+ g_free (stream);
+
+ return parent;
+}
diff --git a/libanjuta/anjuta-token-stream.h b/libanjuta/anjuta-token-stream.h
new file mode 100644
index 0000000..c1d4557
--- /dev/null
+++ b/libanjuta/anjuta-token-stream.h
@@ -0,0 +1,44 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta-token-stream.h
+ * Copyright (C) Sébastien Granjoux 2009 <seb sfo free fr>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _ANJUTA_TOKEN_STREAM_H_
+#define _ANJUTA_TOKEN_STREAM_H_
+
+#include <glib.h>
+
+#include <libanjuta/anjuta-token.h>
+
+G_BEGIN_DECLS
+
+typedef struct _AnjutaTokenStream AnjutaTokenStream;
+
+AnjutaTokenStream *anjuta_token_stream_push (AnjutaTokenStream *stream, AnjutaToken *token);
+AnjutaTokenStream *anjuta_token_stream_pop (AnjutaTokenStream *stream);
+
+AnjutaToken* anjuta_token_stream_get_root (AnjutaTokenStream *stream);
+
+AnjutaToken* anjuta_token_stream_tokenize (AnjutaTokenStream *stream, gint type, gsize length);
+gint anjuta_token_stream_read (AnjutaTokenStream *stream, gchar *buffer, gsize max_size);
+
+void anjuta_token_stream_append_token (AnjutaTokenStream *stream, AnjutaToken *token);
+
+
+G_END_DECLS
+
+#endif
diff --git a/libanjuta/anjuta-token.c b/libanjuta/anjuta-token.c
index 088e9f8..7657906 100644
--- a/libanjuta/anjuta-token.c
+++ b/libanjuta/anjuta-token.c
@@ -26,10 +26,52 @@
#include <stdio.h>
#include <string.h>
+/**
+ * SECTION:anjuta-token
+ * @title: Anjuta token
+ * @short_description: Anjuta token
+ * @see_also:
+ * @stability: Unstable
+ * @include: libanjuta/anjuta-token.h
+ *
+ * A #AnjutaToken represents a token. It is a sequence of characters associated
+ * with a type representing its meaning. By example, a token can represent
+ * a keyword, a comment, a variable...
+ *
+ * The token can own the string or has only a pointer on some data allocated
+ * somewhere else with a length.
+ *
+ * A token is linked with other tokens using three double linked lists.
+ *
+ * The first list using next and prev fields is used to keep the token in the
+ * order where there are in the file. The first character of the first token is
+ * the first character in the file.
+ *
+ * A second list is used to represent included
+ * files. Such file is represented by a special token in the first list which
+ * has a pointer, named children to a token list. Each token in this secondary
+ * list has a pointer to its parent, it means the token representing the file
+ * where is the token. It looks like a tree. In fact, every file is represented
+ * by a special token, so the root node is normally a file token and has as
+ * children all the token representing the file content. This parent/child list
+ * is used for expanded variable too.
+ *
+ * A third list is used to group several tokens. A token can have a pointer to
+ * another last token. It means that this token is a group starting from this
+ * token to the one indicated by the last field. In addition each token in this
+ * group has a pointer on the first token of the group. This grouping is
+ * independent of the parent/child list. So a group can start in one file and
+ * end in another included file. The grouping can be nested too. Typically
+ * we can have a group representing a command, a sub group representing the
+ * arguments and then one sub group for each argument.
+ */
+
+
typedef struct _AnjutaTokenData AnjutaTokenData;
struct _AnjutaTokenData
{
+ AnjutaTokenData *data;
AnjutaTokenType type;
gint flags;
gchar *pos;
@@ -38,126 +80,300 @@ struct _AnjutaTokenData
struct _AnjutaToken
{
- AnjutaTokenData *data;
AnjutaToken *next;
AnjutaToken *prev;
AnjutaToken *parent;
+ AnjutaToken *last;
+ AnjutaToken *group;
AnjutaToken *children;
+ AnjutaTokenData data;
};
-
-#define ANJUTA_TOKEN_DATA(node) ((node) != NULL ? (AnjutaTokenData *)((node)->data) : NULL)
-
/* Helpers functions
*---------------------------------------------------------------------------*/
-/* Return true and update end if the token is found.
- * If a close token is found, return FALSE but still update end */
-gboolean
-anjuta_token_match (AnjutaToken *token, gint flags, AnjutaToken *sequence, AnjutaToken **end)
-{
+/* Private functions
+ *---------------------------------------------------------------------------*/
- for (; sequence != NULL; /*sequence = flags & ANJUTA_SEARCH_BACKWARD ? anjuta_token_previous (sequence) : anjuta_token_next (sequence)*/)
+static AnjutaToken *
+anjuta_token_next_child (AnjutaToken *child, AnjutaToken **last)
+{
+ if (child == NULL) return child;
+
+ if (child->children != NULL)
{
- AnjutaToken *toka;
- AnjutaToken *tokb = token;
-
- for (toka = sequence; toka != NULL; toka = anjuta_token_next_sibling (toka))
+ child = child->children;
+ }
+ else
+ {
+ for (;;)
{
- if (anjuta_token_compare (toka, tokb))
+ if ((*last == NULL) || (child == *last))
{
- tokb = anjuta_token_next (tokb);
- if (tokb == NULL)
+ if (child->last == NULL)
{
- if (end) *end = sequence;
- return TRUE;
+ child = NULL;
+ break;
}
+ *last = child->last;
}
- else
+ if (child->next != NULL)
{
+ child = child->next;
break;
}
+ child = child->parent;
}
+ }
+
+ return child;
+}
+
+static AnjutaToken *
+anjuta_token_next_after_children (AnjutaToken *token)
+{
+ if (token->next != NULL)
+ {
+ return token->next;
+ }
+ else if (token->parent != NULL)
+ {
+ return anjuta_token_next_after_children (token->parent);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+AnjutaToken *
+anjuta_token_copy (AnjutaToken *token)
+{
+ AnjutaToken *copy = NULL;
- if (flags & ANJUTA_SEARCH_BACKWARD)
+ if (token != NULL)
+ {
+ copy = g_slice_new0 (AnjutaToken);
+ copy->data.type = token->data.type;
+ copy->data.flags = token->data.flags;
+ if ((copy->data.flags & ANJUTA_TOKEN_STATIC) || (token->data.pos == NULL))
{
- sequence = flags & ANJUTA_SEARCH_INTO ? anjuta_token_previous (sequence) : anjuta_token_previous_sibling (sequence);
+ copy->data.pos = token->data.pos;
}
else
{
- sequence = flags & ANJUTA_SEARCH_INTO ? anjuta_token_next (sequence) : anjuta_token_next_sibling (sequence);
+ copy->data.pos = g_strdup (token->data.pos);
}
+ copy->data.length = token->data.length;
}
- /*g_message ("matched %p %d", sequence, level);*/
-
- if (end) *end = sequence;
-
- return FALSE;
-}
+ return copy;
+}
-gboolean
-anjuta_token_remove (AnjutaToken *token)
+static AnjutaToken *
+anjuta_token_unlink (AnjutaToken *token)
{
- ANJUTA_TOKEN_DATA (token)->flags |= ANJUTA_TOKEN_REMOVED;
- return TRUE;
+ if (token->prev != NULL)
+ {
+ token->prev->next = token->next;
+ }
+ else if ((token->parent != NULL) && (token->parent->children == token))
+ {
+ token->parent->children = token->next;
+ }
+ token->parent = NULL;
+
+ if (token->next != NULL)
+ {
+ token->next->prev = token->prev;
+ token->next = NULL;
+ }
+ token->prev = NULL;
+
+ return token;
}
-gboolean
-anjuta_token_compare (AnjutaToken *toka, AnjutaToken *tokb)
+static void
+anjuta_token_evaluate_token (AnjutaToken *token, GString *value, gboolean raw)
{
- AnjutaTokenData *data = ANJUTA_TOKEN_DATA (toka);
- AnjutaTokenData *datb = ANJUTA_TOKEN_DATA (tokb);
-
- if (datb->type)
+ if ((token != NULL) && (token->data.length != 0))
{
- if (datb->type != data->type) return FALSE;
+ if (!raw)
+ {
+ switch (anjuta_token_get_type (token))
+ {
+ case ANJUTA_TOKEN_COMMENT:
+ case ANJUTA_TOKEN_OPEN_QUOTE:
+ case ANJUTA_TOKEN_CLOSE_QUOTE:
+ case ANJUTA_TOKEN_ESCAPE:
+ case ANJUTA_TOKEN_MACRO:
+ case ANJUTA_TOKEN_EOV:
+ return;
+ default:
+ break;
+ }
+ }
+ g_string_append_len (value, anjuta_token_get_string (token), anjuta_token_get_length (token));
}
+}
+
+static void
+anjuta_token_show (AnjutaToken *token, gint indent)
+{
+ fprintf (stdout, "%*s%p", indent, "", token);
+ fprintf (stdout, ": %d \"%.*s\" %p/%p %s\n",
+ anjuta_token_get_type (token),
+ anjuta_token_get_length (token),
+ anjuta_token_get_string (token),
+ token->last, token->children,
+ anjuta_token_get_flags (token) & ANJUTA_TOKEN_REMOVED ? " (removed)" : "");
+}
+
+static AnjutaToken*
+anjuta_token_dump_child (AnjutaToken *token, gint indent)
+{
+
+ anjuta_token_show (token, indent);
- if (datb != ANJUTA_TOKEN_NONE)
+ if (token->children != NULL)
{
- if (datb->length != 0)
- {
- if (data->length != datb->length) return FALSE;
+ AnjutaToken *child;
+ AnjutaToken *next = NULL;
+ AnjutaToken *last = anjuta_token_next_after_children (token);
- if ((data->flags & ANJUTA_TOKEN_CASE_INSENSITIVE) && (datb->flags & ANJUTA_TOKEN_CASE_INSENSITIVE))
+ for (child = token->children; child != NULL;)
+ {
+ if (child == last)
{
- if (g_ascii_strncasecmp (data->pos, datb->pos, data->length) != 0) return FALSE;
+ return child;
}
- else
+ if (next == NULL)
+ {
+ next = anjuta_token_dump_child (child, indent + 4);
+ }
+ if (child == next)
{
- if (strncmp (data->pos, datb->pos, data->length) != 0) return FALSE;
+ next = NULL;
+
+#if 0
+ /* Look for previous children */
+ for (child = anjuta_token_next (child); child != NULL; child = child->parent)
+ {
+ if (child->parent == token) break;
+ };
+ continue;
+#endif
}
+ child = anjuta_token_next (child);
}
}
-
- if (datb->flags & ANJUTA_TOKEN_PUBLIC_FLAGS)
+
+ if (token->last != NULL)
{
- if ((data->flags & datb->flags & ANJUTA_TOKEN_PUBLIC_FLAGS) == 0)
- return FALSE;
+ AnjutaToken *child;
+ AnjutaToken *next = NULL;
+
+ for (child = anjuta_token_next (token); child != NULL; child = anjuta_token_next (child))
+ {
+ if (next == NULL)
+ {
+ next = anjuta_token_dump_child (child, indent + 4);
+ if (child == token->last)
+ {
+ return child;
+ }
+ }
+ if (child == next) next = NULL;
+ if (child == token->last)
+ {
+ return child;
+ }
+ }
}
- return TRUE;
+ return token;
}
-AnjutaToken *
-anjuta_token_next_after_children (AnjutaToken *token)
+static gboolean
+anjuta_token_check_child (AnjutaToken *token, AnjutaToken *parent)
{
- if (token->next != NULL)
+ if (token->parent != parent)
{
- return token->next;
+ anjuta_token_show (token, 0);
+ fprintf(stderr, "Error: Children has %p as parent instead of %p\n", token->parent, parent);
+ return FALSE;
}
- else if (token->parent != NULL)
+
+ return anjuta_token_check (token);
+}
+
+/* Get and set functions
+ *---------------------------------------------------------------------------*/
+
+void
+anjuta_token_set_type (AnjutaToken *token, gint type)
+{
+ token->data.type = type;
+}
+
+gint
+anjuta_token_get_type (AnjutaToken *token)
+{
+ return token->data.type;
+}
+
+void
+anjuta_token_set_flags (AnjutaToken *token, gint flags)
+{
+ AnjutaToken *child;
+ AnjutaToken *last = token->last;
+
+ for (child = token; child != NULL; child = anjuta_token_next_child (child, &last))
{
- return anjuta_token_next_after_children (token->parent);
+ child->data.flags |= flags;
}
- else
+}
+
+void
+anjuta_token_clear_flags (AnjutaToken *token, gint flags)
+{
+ token->data.flags &= ~flags;
+}
+
+gint
+anjuta_token_get_flags (AnjutaToken *token)
+{
+ return token->data.flags;
+}
+
+void
+anjuta_token_set_string (AnjutaToken *token, const gchar *data, guint length)
+{
+ if (!(token->data.flags & ANJUTA_TOKEN_STATIC))
{
- return NULL;
+ g_free (token->data.pos);
+ token->data.flags |= ANJUTA_TOKEN_STATIC;
}
+ token->data.pos = (gchar *)data;
+ token->data.length = length;
+}
+
+const gchar *
+anjuta_token_get_string (AnjutaToken *token)
+{
+ return token->data.pos;
+}
+
+guint
+anjuta_token_get_length (AnjutaToken *token)
+{
+ return token->data.length;
}
+/* Basic move functions
+ *---------------------------------------------------------------------------*/
+
AnjutaToken *
anjuta_token_next (AnjutaToken *token)
{
@@ -193,31 +409,14 @@ anjuta_token_previous (AnjutaToken *token)
}
AnjutaToken *
-anjuta_token_next_sibling (AnjutaToken *token)
-{
- return token ? token->next : NULL;
-}
-
-AnjutaToken *
-anjuta_token_next_child (AnjutaToken *token)
-{
- return token ? token->children : NULL;
-}
-
-AnjutaToken *
-anjuta_token_previous_sibling (AnjutaToken *token)
-{
- return token->prev;
-}
-
-AnjutaToken *
-anjuta_token_last_child (AnjutaToken *token)
+anjuta_token_last (AnjutaToken *token)
{
- AnjutaToken *last = NULL;
-
- for (; token != NULL; token = (AnjutaToken *)g_node_last_child ((GNode *)last))
+ AnjutaToken *last;
+
+ for (last = token; last->last != NULL; last = last->last);
+ if (last->children != NULL)
{
- last = token;
+ for (last = last->children; last->next != NULL; last = last->next);
}
return last;
@@ -229,401 +428,748 @@ anjuta_token_parent (AnjutaToken *token)
return token->parent;
}
-void
-anjuta_token_set_type (AnjutaToken *token, gint type)
+AnjutaToken *
+anjuta_token_list (AnjutaToken *token)
{
- ANJUTA_TOKEN_DATA (token)->type = type;
+ return token->group;
}
-void
-anjuta_token_set_flags (AnjutaToken *token, gint flags)
+AnjutaToken *
+anjuta_token_parent_group (AnjutaToken *token)
{
- ANJUTA_TOKEN_DATA (token)->flags |= flags;
+ return token->group;
}
-void
-anjuta_token_clear_flags (AnjutaToken *token, gint flags)
-{
- ANJUTA_TOKEN_DATA (token)->flags &= ~flags;
-}
+/* Item move functions
+ *---------------------------------------------------------------------------*/
-gint
-anjuta_token_get_type (AnjutaToken *token)
+AnjutaToken *
+anjuta_token_last_item (AnjutaToken *list)
{
- return ANJUTA_TOKEN_DATA (token)->type;
+ return list->last;
}
-gint
-anjuta_token_get_flags (AnjutaToken *token)
+AnjutaToken *
+anjuta_token_first_item (AnjutaToken *list)
{
- return ANJUTA_TOKEN_DATA (token)->flags;
+ if (list == NULL) return NULL;
+ if (list->children != NULL) return list->children;
+ if (list->last != NULL) return list->next;
+
+ return NULL;
}
-gchar *
-anjuta_token_get_value (AnjutaToken *token)
+AnjutaToken *
+anjuta_token_next_item (AnjutaToken *item)
{
- AnjutaTokenData *data = ANJUTA_TOKEN_DATA (token);
+ AnjutaToken *last;
- return data && (data->pos != NULL) ? g_strndup (data->pos, data->length) : NULL;
-}
+ if (item == NULL) return NULL;
-const gchar *
-anjuta_token_get_string (AnjutaToken *token)
-{
- return ANJUTA_TOKEN_DATA (token)->pos;
+ if ((item->group != NULL) && (item == item->group->last)) return NULL;
+ for (last = item; last->last != NULL; last = last->last);
+
+ return last->next;
}
-guint
-anjuta_token_get_length (AnjutaToken *token)
+AnjutaToken *
+anjuta_token_previous_item (AnjutaToken *item)
{
- return ANJUTA_TOKEN_DATA (token)->length;
+ AnjutaToken *first;
+
+ if (item == NULL) return NULL;
+
+ for (first = item->prev; (first != NULL) && (first->group != item->group); first = first->group);
+
+ return first;
}
-static void
-anjuta_token_evaluate_token (AnjutaToken *token, GString *value, gboolean raw)
+/* Add/Insert/Remove tokens
+ *---------------------------------------------------------------------------*/
+
+/**
+ * anjuta_token_append_child:
+ * @parent: a #AnjutaToken object used as parent.
+ * @children: a #AnjutaToken object.
+ *
+ * Insert all tokens in children as the last children of the given parent.
+ *
+ * Return value: The first token append.
+ */
+AnjutaToken *
+anjuta_token_append_child (AnjutaToken *parent, AnjutaToken *children)
{
- if ((token != NULL) && (ANJUTA_TOKEN_DATA (token)->length != 0))
+ AnjutaToken *token;
+ AnjutaToken *last;
+ AnjutaToken *old_group;
+ AnjutaToken *old_parent;
+
+ g_return_val_if_fail (parent != NULL, NULL);
+ g_return_val_if_fail (children != NULL, NULL);
+
+ old_group = children->group;
+ old_parent = children->parent;
+
+ if (parent->children == NULL)
{
- if (!raw)
+ parent->children = children;
+
+ children->prev = NULL;
+ }
+ else
+ {
+ /* Find last children */
+ for (last = parent->children; last->next != NULL;)
{
- gint type = anjuta_token_get_type (token);
- if ((type == ANJUTA_TOKEN_COMMENT) || (type == ANJUTA_TOKEN_OPEN_QUOTE) || (type == ANJUTA_TOKEN_CLOSE_QUOTE) || (type == ANJUTA_TOKEN_ESCAPE))
+ if ((last->last != NULL) && (last->last->parent == last->parent))
{
- return;
+ last = last->last;
+ }
+ else
+ {
+ last = last->next;
}
}
- g_string_append_len (value, anjuta_token_get_string (token), anjuta_token_get_length (token));
- }
-}
-gchar *
-anjuta_token_evaluate_range (AnjutaToken *start, AnjutaToken *end)
-{
- GString *value = g_string_new (NULL);
+ last->next = children;
+ children->prev = last;
+ }
- for (;;)
+ /* Update each token */
+ for (token = children;;)
{
- if (start == NULL) break;
- anjuta_token_evaluate_token (start, value, FALSE);
- if (start == end) break;
-
- start = anjuta_token_next (start);
+ if (token->parent == old_parent) token->parent = parent;
+ if (token->group == old_group) token->group = parent->group;
+
+ if (token->children != NULL)
+ {
+ token = token->children;
+ }
+ else if (token->next != NULL)
+ {
+ token = token->next;
+ }
+ else
+ {
+ while (token->parent != parent)
+ {
+ token = token->parent;
+ if (token->next != NULL) break;
+ }
+ if (token->next == NULL) break;
+ token = token->next;
+ }
}
-
- return g_string_free (value, FALSE);
+ return children;
}
-static void
-anjuta_token_evaluate_child (AnjutaToken *token, GString *value, gboolean raw)
+/**
+ * anjuta_token_prepend_child:
+ * @parent: a #AnjutaToken object used as parent.
+ * @children: a #AnjutaToken object.
+ *
+ * Insert all tokens in children as the first children of the given parent.
+ *
+ * Return value: The first token append.
+ */
+AnjutaToken *
+anjuta_token_prepend_child (AnjutaToken *parent, AnjutaToken *children)
{
- anjuta_token_evaluate_token (token, value, raw);
+ AnjutaToken *child;
+ AnjutaToken *last = NULL;
- if (token->children) anjuta_token_evaluate_child (token->children, value, raw);
+ g_return_val_if_fail (parent != NULL, NULL);
+ g_return_val_if_fail (children != NULL, NULL);
- if (token->next) anjuta_token_evaluate_child (token->next, value, raw);
+ /* Update each token */
+ for (child = children;;)
+ {
+ AnjutaToken *next;
+
+ if (child->parent == children->parent) child->parent = parent;
+ if (child->group == children->group) child->group = parent->group;
+
+ next = anjuta_token_next_child (child, &last);
+ if (next == NULL) break;
+ child = next;
+ }
+
+ child->next = parent->children;
+ if (child->next) child->next->prev = child;
+ parent->children = children;
+
+ return children;
}
-gchar *
-anjuta_token_evaluate (AnjutaToken *token)
+/**
+ * anjuta_token_prepend_items:
+ * @list: a #AnjutaToken object used as list.
+ * @item: a #AnjutaToken object.
+ *
+ * Insert all tokens in item as item of the given list.
+ *
+ * Return value: The first token append.
+ */
+AnjutaToken *
+anjuta_token_prepend_items (AnjutaToken *list, AnjutaToken *item)
{
- GString *value = g_string_new (NULL);
- gchar *str;
+ AnjutaToken *token;
+ AnjutaToken *old_group;
+ AnjutaToken *old_parent;
- if (token != NULL)
+ g_return_val_if_fail (list != NULL, NULL);
+ g_return_val_if_fail (item != NULL, NULL);
+
+ old_group = item->group;
+ old_parent = item->parent;
+
+ /* Update each token */
+ for (token = item;;)
{
- anjuta_token_evaluate_token (token, value, FALSE);
- if (token->children) anjuta_token_evaluate_child (token->children, value, FALSE);
+ if (token->parent == old_parent) token->parent = list->parent;
+ if (token->group == old_group) token->group = list;
+
+ if (token->children != NULL)
+ {
+ token = token->children;
+ }
+ else if (token->next != NULL)
+ {
+ token = token->next;
+ }
+ else
+ {
+ while (token->parent != list->parent)
+ {
+ token = token->parent;
+ if (token->next != NULL) break;
+ }
+ if (token->next == NULL) break;
+ token = token->next;
+ }
}
- str = g_string_free (value, FALSE);
- return *str == '\0' ? NULL : str;
-}
+ token->next = list->next;
+ if (token->next) token->next->prev = token;
-gchar *
-anjuta_token_value (AnjutaToken *token)
-{
- GString *value = g_string_new (NULL);
- gchar *str;
+ list->next = item;
+ item->prev = list;
- if (token != NULL)
+ if (list->last == NULL)
{
- anjuta_token_evaluate_token (token, value, TRUE);
- if (token->children) anjuta_token_evaluate_child (token->children, value, TRUE);
+ while (token->group != list) token = token->group;
+ list->last = token;
}
- str = g_string_free (value, FALSE);
- return *str == '\0' ? NULL : str;
+ return item;
}
+/**
+ * anjuta_token_insert_after:
+ * @sibling: a #AnjutaToken object.
+ * @item: a #AnjutaToken object.
+ *
+ * Insert all tokens after sibling.
+ *
+ * Return value: The first token inserted.
+ */
AnjutaToken *
-anjuta_token_merge (AnjutaToken *first, AnjutaToken *end)
+anjuta_token_insert_after (AnjutaToken *sibling, AnjutaToken *list)
{
- AnjutaToken *child;
- AnjutaToken *tok;
+ AnjutaToken *last;
+ AnjutaToken *token;
+ AnjutaToken *old_group;
+ AnjutaToken *old_parent;
+
+ g_return_val_if_fail (sibling != NULL, NULL);
+ g_return_val_if_fail (list != NULL, NULL);
- if (first == end) return first;
+ old_group = list->group;
+ old_parent = list->parent;
- child = (AnjutaToken *)g_node_last_child ((GNode *)first);
- do
+ /* Update each token */
+ for (token = list;;)
{
- tok = (AnjutaToken *)g_node_next_sibling ((GNode *)first);
- if (tok == NULL) break;
-
- g_node_unlink ((GNode *)tok);
- child = (AnjutaToken *)g_node_insert_after ((GNode *)first, (GNode *)child, (GNode *)tok);
+ if (token->parent == old_parent) token->parent = sibling->parent;
+ if (token->group == old_group) token->group = sibling->group;
+
+ if (token->children != NULL)
+ {
+ token = token->children;
+ }
+ else if (token->next != NULL)
+ {
+ token = token->next;
+ }
+ else
+ {
+ while (token->parent != sibling->parent)
+ {
+ token = token->parent;
+ if (token->next != NULL) break;
+ }
+ if (token->next == NULL) break;
+ token = token->next;
+ }
+ }
+ for (last = sibling; last->last != NULL; last = last->last);
+
+ token->next = last->next;
+ if (token->next) token->next->prev = token;
+
+ last->next = list;
+ list->prev = last;
+
+ if ((sibling->group != NULL) && (sibling->group->last == sibling))
+ {
+ while (token->group != sibling->group) token = token->group;
+ sibling->group->last = token;
}
- while (tok != end);
- return first;
+ return list;
}
+/**
+ * anjuta_token_insert_before:
+ * @sibling: a #AnjutaToken object.
+ * @item: a #AnjutaToken object.
+ *
+ * Insert all tokens before sibling.
+ *
+ * Return value: The first token inserted.
+ */
AnjutaToken *
-anjuta_token_merge_previous (AnjutaToken *first, AnjutaToken *end)
+anjuta_token_insert_before (AnjutaToken *sibling, AnjutaToken *list)
{
- AnjutaToken *child;
- AnjutaToken *tok;
+ AnjutaToken *last;
+ AnjutaToken *token;
+ AnjutaToken *old_group;
+ AnjutaToken *old_parent;
- if (first == end) return first;
+ g_return_val_if_fail (sibling != NULL, NULL);
+ g_return_val_if_fail (list != NULL, NULL);
- child = (AnjutaToken *)g_node_first_child ((GNode *)first);
- do
+ old_group = list->group;
+ old_parent = list->parent;
+
+ /* Update each token */
+ for (token = list;;)
{
- tok = (AnjutaToken *)g_node_prev_sibling ((GNode *)first);
- if (tok == NULL) break;
-
- g_node_unlink ((GNode *)tok);
- child = (AnjutaToken *)g_node_insert_before ((GNode *)first, (GNode *)child, (GNode *)tok);
+ if (token->parent == old_parent) token->parent = sibling->parent;
+ if (token->group == old_group) token->group = sibling->group;
+ if (token->children != NULL)
+ {
+ token = token->children;
+ }
+ else if (token->next != NULL)
+ {
+ token = token->next;
+ }
+ else
+ {
+ while (token->parent != sibling->parent)
+ {
+ token = token->parent;
+ if (token->next != NULL) break;
+ }
+ if (token->next == NULL) break;
+ token = token->next;
+ }
}
- while (tok != end);
- return first;
+ for (last = sibling; last->last != NULL; last = last->last);
+
+ token->next = sibling;
+ list->prev = sibling->prev;
+ sibling->prev = token;
+
+ if (list->prev) list->prev->next = list;
+
+ if ((list->parent != NULL) && (list->parent->children == sibling)) list->parent->children = list;
+
+ return list;
}
+/**
+ * anjuta_token_delete_parent:
+ * @parent: a #AnjutaToken object used as parent.
+ *
+ * Delete only the parent token.
+ *
+ * Return value: the first children
+ */
AnjutaToken *
-anjuta_token_copy (const AnjutaToken *token)
+anjuta_token_delete_parent (AnjutaToken *parent)
{
- AnjutaToken *copy = NULL;
+ AnjutaToken *token;
- if (token != NULL)
+ g_return_val_if_fail (parent != NULL, NULL);
+
+ if (parent->children == NULL) return NULL;
+
+ /* Update each token */
+ for (token = parent->children;;)
{
- AnjutaTokenData *org = ANJUTA_TOKEN_DATA (token);
- AnjutaTokenData *data = NULL;
- AnjutaToken *child;
- AnjutaToken *last;
+ if (token->parent == parent) token->parent = parent->parent;
- data = g_slice_new0 (AnjutaTokenData);
- data->type =org->type;
- data->flags = org->type;
- if ((data->flags & ANJUTA_TOKEN_STATIC) || (org->pos == NULL))
+ if (token->children != NULL)
{
- data->pos = org->pos;
+ token = token->children;
}
- else
+ else if (token->next != NULL)
{
- data->pos = g_strdup (ANJUTA_TOKEN_DATA (token)->pos);
+ token = token->next;
}
- data->length = org->length;
-
- copy = (AnjutaToken *)g_node_new (data);
-
- last = NULL;
- for (child = anjuta_token_next_child (token); child != NULL; child = anjuta_token_next_sibling (child))
+ else
{
- AnjutaToken *new_child = anjuta_token_copy (child);
- last = last == NULL ? anjuta_token_insert_child (copy, new_child) : anjuta_token_insert_after (last, new_child);
+ while (token->parent != parent->parent)
+ {
+ token = token->parent;
+ if (token->next != NULL) break;
+ }
+ if (token->next == NULL) break;
+ token = token->next;
}
}
- return copy;
+ token->next = parent->next;
+ if (token->next) token->next->prev = token;
+
+ parent->next = parent->children;
+ parent->children->prev = parent;
+ parent->children = NULL;
+
+ return anjuta_token_free (parent);
}
+/* Merge function
+ *---------------------------------------------------------------------------*/
+
AnjutaToken *
-anjuta_token_clear (AnjutaToken *token)
+anjuta_token_merge (AnjutaToken *first, AnjutaToken *end)
{
- AnjutaTokenData *data = ANJUTA_TOKEN_DATA (token);
-
- if (!(data->flags & ANJUTA_TOKEN_STATIC))
+ if ((first == end) || (end == NULL)) return first;
+
+ if (first->parent == NULL)
{
- g_free (data->pos);
+ first->parent = end->parent;
}
- data->length = 0;
- data->pos = NULL;
+ if (first->next == NULL)
+ {
+ anjuta_token_insert_before (end, first);
+ }
+ first->last = end;
+ end->group = first;
- return token;
+ return first;
}
AnjutaToken *
-anjuta_token_delete (AnjutaToken *token)
+anjuta_token_merge_own_children (AnjutaToken *group)
{
- GNode *last;
- GNode *child;
- AnjutaToken *next;
+ AnjutaToken *token;
+ AnjutaToken *next = NULL;
- for (child = g_node_first_child ((GNode *)token); child != NULL; child = g_node_first_child ((GNode *)token))
+ if (group->last != NULL) return group;
+
+ if (group->last->last != NULL) group->last = group->last->last;
+
+ for (token = anjuta_token_next (group); (token != NULL) && (token != group->last); token = anjuta_token_next (token))
{
- g_node_unlink (child);
- last = g_node_insert_after (((GNode *)token)->parent, last, child);
+ if (next == NULL)
+ {
+ if (token->last != NULL)
+ {
+ next = token->last;
+ //token->last = NULL;
+ }
+ token->group = group;
+ }
+ else if (next == token)
+ {
+ next = NULL;
+ }
}
- next = (AnjutaToken *)g_node_next_sibling (token);
- anjuta_token_clear (token);
- g_node_destroy ((GNode *)token);
-
- return next;
+ return group;
}
AnjutaToken *
-anjuta_token_insert_child (AnjutaToken *parent, AnjutaToken *child)
+anjuta_token_merge_children (AnjutaToken *first, AnjutaToken *end)
{
- return (AnjutaToken *)g_node_insert_after ((GNode *)parent, (GNode *)NULL, (GNode *)child);
+ if ((first == end) || (end == NULL))
+ {
+ return first;
+ }
+
+ if (first->parent == NULL)
+ {
+ first->parent = end->parent;
+ }
+ if (first->next == NULL)
+ {
+ anjuta_token_insert_before (end, first);
+ }
+ anjuta_token_unlink (end);
+ if (end->last != NULL)
+ {
+ first->last = end->last;
+ end->last->group = first;
+ }
+ end->group = first;
+ anjuta_token_free (end);
+
+ return first;
}
AnjutaToken *
-anjuta_token_insert_after (AnjutaToken *sibling, AnjutaToken *token)
+anjuta_token_merge_previous (AnjutaToken *first, AnjutaToken *end)
{
- return (AnjutaToken *)g_node_insert_after ((GNode *)sibling->parent, (GNode *)sibling, (GNode *)token);
+ if ((end == NULL) || (first == end)) return first;
+
+ anjuta_token_unlink (first);
+ anjuta_token_insert_before (end, first);
+ end->group = first;
+
+ return first;
}
-AnjutaToken *
-anjuta_token_insert_before (AnjutaToken *sibling, AnjutaToken *baby)
+AnjutaToken *anjuta_token_split (AnjutaToken *token, guint size)
{
- return (AnjutaToken *)g_node_insert_before ((GNode *)sibling->parent, (GNode *)sibling, (GNode *)baby);
-}
+ if (token->data.length > size)
+ {
+ AnjutaToken *copy;
+
+ copy = anjuta_token_copy (token);
+ anjuta_token_insert_before (token, copy);
+
+ copy->data.length = size;
+ if (token->data.flags & ANJUTA_TOKEN_STATIC)
+ {
+ token->data.pos += size;
+ token->data.length -= size;
+ }
+ else
+ {
+ memcpy(token->data.pos, token->data.pos + size, token->data.length - size);
+ }
+
+ return copy;
+ }
+ else
+ {
+ return token;
+ }
+}
-AnjutaToken *anjuta_token_group (AnjutaToken *parent, AnjutaToken *last)
+AnjutaToken *anjuta_token_cut (AnjutaToken *token, guint pos, guint size)
{
- AnjutaToken *child;
- AnjutaToken *tok;
+ AnjutaToken *copy;
- if (parent == last) return parent;
- if (parent->children == last) return parent;
+ copy = anjuta_token_copy (token);
- child = (AnjutaToken *)g_node_last_child ((GNode *)parent);
- do
+ if (pos >= token->data.length)
+ {
+ if (!(copy->data.flags & ANJUTA_TOKEN_STATIC))
+ {
+ g_free (copy->data.pos);
+ }
+ copy->data.pos = NULL;
+ copy->data.length = 0;
+ }
+ if ((pos + size) > token->data.length)
{
- tok = (AnjutaToken *)g_node_next_sibling ((GNode *)parent);
- if (tok == NULL) break;
+ size = token->data.length - pos;
+ }
- g_node_unlink ((GNode *)tok);
- child = (AnjutaToken *)g_node_insert_after ((GNode *)parent, (GNode *)child, (GNode *)tok);
-
+ if (copy->data.flags & ANJUTA_TOKEN_STATIC)
+ {
+ copy->data.pos += pos;
}
- while (tok != last);
+ else
+ {
+ memcpy(copy->data.pos, copy->data.pos + pos, size);
+ }
+ copy->data.length = size;
- return parent;
-
+ return copy;
}
-AnjutaToken *anjuta_token_group_new (AnjutaTokenType type, AnjutaToken* first)
+/* Token evaluation
+ *---------------------------------------------------------------------------*/
+
+gchar *
+anjuta_token_evaluate (AnjutaToken *token)
{
- AnjutaToken *parent = anjuta_token_new_static (type, NULL);
+ GString *value = g_string_new (NULL);
+
+ if (token != NULL)
+ {
+ AnjutaToken *last = token->last;
+ AnjutaToken *child;
+
+ for (child = token; child != NULL; child = anjuta_token_next_child (child, &last))
+ {
+ anjuta_token_evaluate_token (child, value, TRUE);
+ }
+ }
- g_node_insert_before ((GNode *)first->parent, (GNode *)first, (GNode *)parent);
- return anjuta_token_group (parent, first);
+ /* Return NULL and free data for an empty string */
+ return g_string_free (value, *(value->str) == '\0');
}
-AnjutaToken *anjuta_token_ungroup (AnjutaToken *token)
+/* Other functions
+ *---------------------------------------------------------------------------*/
+
+gboolean
+anjuta_token_compare (AnjutaToken *toka, AnjutaToken *tokb)
{
- GNode *last = (GNode *)token;
- GNode *child;
+ if (tokb->data.type)
+ {
+ if (tokb->data.type != toka->data.type) return FALSE;
+ }
- for (child = g_node_first_child ((GNode *)token); child != NULL; child = g_node_first_child ((GNode *)token))
+ if (tokb->data.type != ANJUTA_TOKEN_NONE)
+ {
+ if (tokb->data.length != 0)
+ {
+ if (toka->data.length != tokb->data.length) return FALSE;
+
+ if ((toka->data.flags & ANJUTA_TOKEN_CASE_INSENSITIVE) && (tokb->data.flags & ANJUTA_TOKEN_CASE_INSENSITIVE))
+ {
+ if (g_ascii_strncasecmp (toka->data.pos, tokb->data.pos, toka->data.length) != 0) return FALSE;
+ }
+ else
+ {
+ if (strncmp (toka->data.pos, tokb->data.pos, toka->data.length) != 0) return FALSE;
+ }
+ }
+ }
+
+ if (tokb->data.flags & ANJUTA_TOKEN_PUBLIC_FLAGS)
{
- g_node_unlink (child);
- last = g_node_insert_after (((GNode *)token)->parent, last, child);
+ if ((toka->data.flags & tokb->data.flags & ANJUTA_TOKEN_PUBLIC_FLAGS) == 0)
+ return FALSE;
}
- return token;
+ return TRUE;
}
-AnjutaToken *anjuta_token_split (AnjutaToken *token, guint size)
+void
+anjuta_token_dump (AnjutaToken *token)
{
- if (ANJUTA_TOKEN_DATA (token)->length > size)
- {
- AnjutaToken *copy;
+ if (token == NULL) return;
+
+ anjuta_token_dump_child (token, 0);
+}
- copy = anjuta_token_copy (token);
- g_node_insert_before ((GNode *)token->parent, (GNode *)token, (GNode *)copy);
+void
+anjuta_token_dump_link (AnjutaToken *token)
+{
+ AnjutaToken *last = token;
- ANJUTA_TOKEN_DATA (copy)->length = size;
- if (ANJUTA_TOKEN_DATA (token)->flags & ANJUTA_TOKEN_STATIC)
- {
- ANJUTA_TOKEN_DATA (token)->pos += size;
- ANJUTA_TOKEN_DATA (token)->length -= size;
- }
- else
- {
- memcpy(ANJUTA_TOKEN_DATA (token)->pos, ANJUTA_TOKEN_DATA (token)->pos + size, ANJUTA_TOKEN_DATA (token)->length - size);
- }
+ while (last->last != NULL) last = last->last;
- return copy;
- }
- else
+ for (; token != last; token = anjuta_token_next (token))
{
- return token;
+ anjuta_token_show (token, 0);
}
}
-AnjutaToken *anjuta_token_get_next_arg (AnjutaToken *arg, gchar ** value)
+gboolean
+anjuta_token_check (AnjutaToken *token)
{
- for (;arg != NULL;)
+ if ((token->children != NULL) && (token->last != NULL))
+ {
+ anjuta_token_show (token, 0);
+ fprintf(stderr, "Error: Previous token has both non NULL children and last\n");
+
+ return FALSE;
+ }
+
+ if (token->children != NULL)
{
- switch (anjuta_token_get_type (arg))
+ AnjutaToken *child;
+
+ for (child = token->children; child != NULL; child = child->next)
{
- case ANJUTA_TOKEN_START:
- case ANJUTA_TOKEN_NEXT:
- case ANJUTA_TOKEN_LAST:
- arg = anjuta_token_next_sibling (arg);
- continue;
- default:
- *value = anjuta_token_evaluate (arg);
- arg = anjuta_token_next_sibling (arg);
- break;
+ if (!anjuta_token_check_child (child, token)) return FALSE;
+ }
+ }
+
+ if (token->last != NULL)
+ {
+ AnjutaToken *child;
+
+ for (child = anjuta_token_next (token); child != NULL; child = anjuta_token_next (child))
+ {
+ if (!anjuta_token_check (child)) return FALSE;
+ if (child == token->last) break;
}
- break;
}
- return arg;
+ return TRUE;
}
/* Constructor & Destructor
*---------------------------------------------------------------------------*/
-AnjutaToken *anjuta_token_new_string (AnjutaTokenType type, const char *value)
+AnjutaToken *anjuta_token_new_string (AnjutaTokenType type, const gchar *value)
{
+ AnjutaToken *token;
+
if (value == NULL)
{
- return anjuta_token_new_static (type, NULL);
+ token = anjuta_token_new_static (type, NULL);
}
else
{
- AnjutaTokenData *data;
+ token = g_slice_new0 (AnjutaToken);
+ token->data.type = type & ANJUTA_TOKEN_TYPE;
+ token->data.flags = type & ANJUTA_TOKEN_FLAGS;
+ token->data.pos = g_strdup (value);
+ token->data.length = strlen (value);
+ }
- data = g_slice_new0 (AnjutaTokenData);
- data->type = type & ANJUTA_TOKEN_TYPE;
- data->flags = type & ANJUTA_TOKEN_FLAGS;
- data->pos = g_strdup (value);
- data->length = strlen (value);
+ return token;
+}
- return (AnjutaToken *)g_node_new (data);
+AnjutaToken*
+anjuta_token_new_with_string (AnjutaTokenType type, gchar *value, gsize length)
+{
+ AnjutaToken *token;
+
+ if (value == NULL)
+ {
+ token = anjuta_token_new_static (type, NULL);
}
+ else
+ {
+ token = g_slice_new0 (AnjutaToken);
+ token->data.type = type & ANJUTA_TOKEN_TYPE;
+ token->data.flags = type & ANJUTA_TOKEN_FLAGS;
+ token->data.pos = value;
+ token->data.length = length;
+ }
+
+ return token;
}
-
+
AnjutaToken *
anjuta_token_new_fragment (gint type, const gchar *pos, gsize length)
{
- AnjutaTokenData *data;
+ AnjutaToken *token;
- data = g_slice_new0 (AnjutaTokenData);
- data->type = type & ANJUTA_TOKEN_TYPE;
- data->flags = (type & ANJUTA_TOKEN_FLAGS) | ANJUTA_TOKEN_STATIC;
- data->pos = (gchar *)pos;
- data->length = length;
+ token = g_slice_new0 (AnjutaToken);
+ token->data.type = type & ANJUTA_TOKEN_TYPE;
+ token->data.flags = (type & ANJUTA_TOKEN_FLAGS) | ANJUTA_TOKEN_STATIC;
+ token->data.pos = (gchar *)pos;
+ token->data.length = length;
- return (AnjutaToken *)g_node_new (data);
+ return token;
};
AnjutaToken *anjuta_token_new_static (AnjutaTokenType type, const char *value)
@@ -631,18 +1177,48 @@ AnjutaToken *anjuta_token_new_static (AnjutaTokenType type, const char *value)
return anjuta_token_new_fragment (type, value, value == NULL ? 0 : strlen (value));
}
-
-static void
-free_token_data (GNode *node, gpointer data)
+AnjutaToken*
+anjuta_token_free_children (AnjutaToken *token)
{
- g_slice_free (AnjutaTokenData, node->data);
+ AnjutaToken *child;
+
+ if (token == NULL) return NULL;
+
+ for (child = token->children; child != NULL; child = token->children)
+ {
+ anjuta_token_free (child);
+ }
+ token->children = NULL;
+
+ if (token->last != NULL)
+ {
+ for (child = anjuta_token_next (token); child != NULL; child = anjuta_token_next (token))
+ {
+ anjuta_token_free (child);
+ if (child == token->last) break;
+ }
+ }
+ token->last = NULL;
+
+ return token;
}
-void
+AnjutaToken*
anjuta_token_free (AnjutaToken *token)
{
- if (token == NULL) return;
+ AnjutaToken *next;
+
+ if (token == NULL) return NULL;
- g_node_children_foreach ((GNode *)token, G_TRAVERSE_ALL, free_token_data, NULL);
- g_node_destroy ((GNode *)token);
+ anjuta_token_free_children (token);
+
+ next = anjuta_token_next (token);
+ anjuta_token_unlink (token);
+ if ((token->data.pos != NULL) && !(token->data.flags & ANJUTA_TOKEN_STATIC))
+ {
+ g_free (token->data.pos);
+ }
+ g_slice_free (AnjutaToken, token);
+
+ return next;
}
diff --git a/libanjuta/anjuta-token.h b/libanjuta/anjuta-token.h
index ed6c319..44a0e14 100644
--- a/libanjuta/anjuta-token.h
+++ b/libanjuta/anjuta-token.h
@@ -34,12 +34,16 @@ typedef enum
ANJUTA_TOKEN_TYPE = 0xFFFF,
ANJUTA_TOKEN_FIRST = 16384,
- ANJUTA_TOKEN_FILE = 16384,
+ ANJUTA_TOKEN_FILE,
+ ANJUTA_TOKEN_MACRO,
+ ANJUTA_TOKEN_CONTENT,
+ ANJUTA_TOKEN_ARGUMENT,
+ ANJUTA_TOKEN_VALUE,
+ ANJUTA_TOKEN_EOV,
+ ANJUTA_TOKEN_PARSED,
ANJUTA_TOKEN_KEYWORD,
ANJUTA_TOKEN_OPERATOR,
ANJUTA_TOKEN_NAME,
- ANJUTA_TOKEN_VALUE,
- ANJUTA_TOKEN_MACRO,
ANJUTA_TOKEN_VARIABLE,
ANJUTA_TOKEN_DEFINITION,
ANJUTA_TOKEN_STATEMENT,
@@ -54,7 +58,6 @@ typedef enum
ANJUTA_TOKEN_START,
ANJUTA_TOKEN_NEXT,
ANJUTA_TOKEN_LAST,
- ANJUTA_TOKEN_ARGUMENT,
ANJUTA_TOKEN_ITEM,
ANJUTA_TOKEN_STRING,
ANJUTA_TOKEN_ERROR,
@@ -81,81 +84,57 @@ typedef enum
} AnjutaTokenType;
-//typedef GNode AnjutaToken;
typedef struct _AnjutaToken AnjutaToken;
-typedef struct _AnjutaTokenRange
-{
- AnjutaToken *first;
- AnjutaToken *last;
-} AnjutaTokenRange;
-
-enum AnjutaTokenSearchFlag
-{
- ANJUTA_SEARCH_OVER = 0,
- ANJUTA_SEARCH_INTO = 1 << 0,
- ANJUTA_SEARCH_ALL = 1 << 1,
- ANJUTA_SEARCH_BACKWARD = 1 << 2
-};
-
AnjutaToken *anjuta_token_new_string (AnjutaTokenType type, const gchar *value);
+AnjutaToken *anjuta_token_new_with_string (AnjutaTokenType type, gchar *value, gsize length);
AnjutaToken *anjuta_token_new_static (AnjutaTokenType type, const gchar *value);
AnjutaToken *anjuta_token_new_fragment (gint type, const gchar *pos, gsize length);
-void anjuta_token_free (AnjutaToken *token);
-
-AnjutaToken *anjuta_token_merge (AnjutaToken *first, AnjutaToken *end);
-AnjutaToken *anjuta_token_merge_previous (AnjutaToken *first, AnjutaToken *end);
-AnjutaToken *anjuta_token_copy (const AnjutaToken *token);
-AnjutaToken *anjuta_token_clear (AnjutaToken *token);
-AnjutaToken *anjuta_token_delete (AnjutaToken *token);
-
-AnjutaToken *anjuta_token_group_new (AnjutaTokenType type, AnjutaToken *first);
-AnjutaToken *anjuta_token_group (AnjutaToken *parent, AnjutaToken *last);
-AnjutaToken *anjuta_token_ungroup (AnjutaToken *parent);
-
-AnjutaToken *anjuta_token_split (AnjutaToken *token, guint size);
-
-AnjutaToken * anjuta_token_insert_child (AnjutaToken *parent, AnjutaToken *child);
-AnjutaToken *anjuta_token_insert_after (AnjutaToken *token, AnjutaToken *sibling);
-AnjutaToken *anjuta_token_insert_before (AnjutaToken *token, AnjutaToken *sibling);
-gboolean anjuta_token_match (AnjutaToken *token, gint flags, AnjutaToken *sequence, AnjutaToken **end);
-
-//AnjutaToken *anjuta_token_copy (AnjutaToken *token);
-//AnjutaToken *anjuta_token_copy_include_range (AnjutaToken *token, AnjutaToken *end);
-//AnjutaToken *anjuta_token_copy_exclude_range (AnjutaToken *token, AnjutaToken *end);
-//void anjuta_token_foreach (AnjutaToken *token, GFunc func, gpointer user_data);
-gboolean anjuta_token_remove (AnjutaToken *token);
-//gboolean anjuta_token_free_range (AnjutaToken *token, AnjutaToken *end);
-//GList *anjuta_token_split_list (AnjutaToken *token);
+AnjutaToken* anjuta_token_free_children (AnjutaToken *token);
+AnjutaToken* anjuta_token_free (AnjutaToken *token);
void anjuta_token_set_type (AnjutaToken *token, gint type);
+gint anjuta_token_get_type (AnjutaToken *token);
void anjuta_token_set_flags (AnjutaToken *token, gint flags);
void anjuta_token_clear_flags (AnjutaToken *token, gint flags);
-
-gchar *anjuta_token_evaluate_range (AnjutaToken *start, AnjutaToken *end);
-gchar *anjuta_token_evaluate (AnjutaToken *token);
-gchar *anjuta_token_value (AnjutaToken *token);
+gint anjuta_token_get_flags (AnjutaToken *token);
+const gchar *anjuta_token_get_string (AnjutaToken *token);
+void anjuta_token_set_string (AnjutaToken *token, const char *value, guint length);
+guint anjuta_token_get_length (AnjutaToken *token);
AnjutaToken *anjuta_token_next (AnjutaToken *token);
-AnjutaToken *anjuta_token_next_after_children (AnjutaToken *token);
-AnjutaToken *anjuta_token_next_sibling (AnjutaToken *token);
-AnjutaToken *anjuta_token_next_child (AnjutaToken *token);
AnjutaToken *anjuta_token_previous (AnjutaToken *token);
-AnjutaToken *anjuta_token_previous_sibling (AnjutaToken *token);
-AnjutaToken *anjuta_token_last_child (AnjutaToken *token);
+AnjutaToken *anjuta_token_last (AnjutaToken *token);
AnjutaToken *anjuta_token_parent (AnjutaToken *token);
-gboolean anjuta_token_compare (AnjutaToken *tokena, AnjutaToken *tokenb);
+AnjutaToken *anjuta_token_list (AnjutaToken *token);
-AnjutaToken *anjuta_token_get_next_arg (AnjutaToken *arg, gchar ** value);
+AnjutaToken *anjuta_token_first_item (AnjutaToken *list);
+AnjutaToken *anjuta_token_next_item (AnjutaToken *item);
+AnjutaToken *anjuta_token_previous_item (AnjutaToken *item);
+AnjutaToken *anjuta_token_last_item (AnjutaToken *list);
+AnjutaToken *anjuta_token_append_child (AnjutaToken *parent, AnjutaToken *child);
+AnjutaToken *anjuta_token_prepend_child (AnjutaToken *parent, AnjutaToken *child);
+AnjutaToken *anjuta_token_prepend_items (AnjutaToken *list, AnjutaToken *item);
+AnjutaToken *anjuta_token_insert_after (AnjutaToken *sibling, AnjutaToken *token);
+AnjutaToken *anjuta_token_insert_before (AnjutaToken *sibling, AnjutaToken *token);
+AnjutaToken *anjuta_token_delete_parent (AnjutaToken *parent);
-gint anjuta_token_get_type (AnjutaToken *token);
-gint anjuta_token_get_flags (AnjutaToken *token);
-gchar *anjuta_token_get_value (AnjutaToken *token);
-gchar *anjuta_token_get_value_range (AnjutaToken *token, AnjutaToken *end);
-const gchar *anjuta_token_get_string (AnjutaToken *token);
-guint anjuta_token_get_length (AnjutaToken *token);
+AnjutaToken *anjuta_token_merge (AnjutaToken *first, AnjutaToken *end);
+AnjutaToken *anjuta_token_merge_own_children (AnjutaToken *first);
+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);
+
+gchar *anjuta_token_evaluate (AnjutaToken *token);
+
+void anjuta_token_dump (AnjutaToken *token);
+gboolean anjuta_token_check (AnjutaToken *token);
+void anjuta_token_dump_link (AnjutaToken *token);
+
+gboolean anjuta_token_compare (AnjutaToken *tokena, AnjutaToken *tokenb);
G_END_DECLS
diff --git a/plugins/am-project/Makefile.am b/plugins/am-project/Makefile.am
index 29ee16d..f2a678b 100644
--- a/plugins/am-project/Makefile.am
+++ b/plugins/am-project/Makefile.am
@@ -40,6 +40,8 @@ libam_project_la_SOURCES = \
ac-scanner.h \
ac-writer.h \
ac-writer.c \
+ am-writer.h \
+ am-writer.c \
am-project-private.h \
am-dialogs.h \
am-dialogs.c
diff --git a/plugins/am-project/ac-parser.y b/plugins/am-project/ac-parser.y
index 959675e..b581a2a 100644
--- a/plugins/am-project/ac-parser.y
+++ b/plugins/am-project/ac-parser.y
@@ -18,24 +18,21 @@
*/
%{
-#include <stdlib.h>
#include "ac-scanner.h"
#include "ac-parser.h"
+#include <stdlib.h>
+
//#define YYDEBUG 1
#include "libanjuta/anjuta-debug.h"
-//static void amp_ac_yyerror (YYLTYPE *loc, void *scanner, char const *s);
-
-//amp_ac_yydebug = 1;
+/* Token location is found directly from token value, there is no need to
+ * maintain a separate location variable */
+#define YYLLOC_DEFAULT(Current, Rhs, N) ((Current) = YYRHSLOC(Rhs, (N) ? 1 : 0))
%}
-/*%union {
- AnjutaToken *token;
-}*/
-
%token EOL '\n'
%token SPACE ' '
@@ -51,7 +48,8 @@
%token COMMA ','
%token LOWER '<'
%token GREATER '>'
-
+
+%token COMMENT 256
%token NAME
%token VARIABLE
%token MACRO
@@ -61,9 +59,6 @@
%token START_SPACE_LIST
-%left ARG
-%left EMPTY
-
/* M4 macros */
%token DNL
@@ -81,21 +76,11 @@
%token AC_SUBST
%token AC_INIT
-/*%type pkg_check_modules obsolete_ac_output ac_output ac_config_files
-%type dnl
-%type ac_macro_with_arg ac_macro_without_arg
-%type spaces
-%type separator
-%type arg_string arg arg_list arg_list_body shell_string_body raw_string_body
-
-%type expression comment macro
-%type arg_string_body arg_body expression_body
-
-%type any_space*/
%defines
-%pure_parser
+%define api.pure
+%define api.push_pull "push"
%parse-param {AmpAcScanner* scanner}
%lex-param {AmpAcScanner* scanner}
@@ -108,23 +93,16 @@
%debug
-
-%{
-static void amp_ac_yyerror (YYLTYPE *loc, AmpAcScanner *scanner, char const *s);
-
-%}
-
-
%%
input:
- START_SPACE_LIST space_list
- | file
+ file
+ | START_SPACE_LIST space_list
;
file:
/* empty */
- | file statement
+ | file statement
;
statement:
@@ -187,16 +165,12 @@ operator:
;
name:
- not_operator_token
- | name word_token {
- anjuta_token_group ($1, $2);
+ not_operator_token {
+ $$ = anjuta_token_new_static (ANJUTA_TOKEN_NAME, NULL);
+ anjuta_token_merge ($$, $1);
}
- ;
-
-junks:
- JUNK
- | junks JUNK {
- anjuta_token_group ($1, $2);
+ | name word_token {
+ anjuta_token_merge ($1, $2);
}
;
@@ -204,17 +178,13 @@ junks:
*----------------------------------------------------------------------------*/
dnl:
- DNL not_eol_list EOL {
- anjuta_token_set_type ($1, ANJUTA_TOKEN_COMMENT);
- anjuta_token_group ($1, $3);
- }
+ DNL not_eol_list EOL
;
pkg_check_modules:
PKG_CHECK_MODULES arg_list {
- anjuta_token_set_type ($1, AC_TOKEN_PKG_CHECK_MODULES);
- $$ = anjuta_token_group ($1, $2);
+ amp_ac_scanner_load_module (scanner, $2);
}
;
@@ -228,15 +198,12 @@ optional_arg:
;
ac_macro_with_arg:
- AC_MACRO_WITH_ARG optional_arg RIGHT_PAREN {
- anjuta_token_group ($1, $1);
- }
+ AC_MACRO_WITH_ARG optional_arg RIGHT_PAREN
;
ac_init:
AC_INIT arg_list {
- anjuta_token_set_type ($1, AC_TOKEN_AC_INIT);
- $$ = anjuta_token_group ($1, $2);
+ amp_ac_scanner_load_properties (scanner, $1, $2);
}
ac_output:
@@ -247,15 +214,13 @@ ac_output:
obsolete_ac_output:
OBSOLETE_AC_OUTPUT arg_list {
- anjuta_token_set_type ($1, AC_TOKEN_OBSOLETE_AC_OUTPUT);
- $$ = anjuta_token_group ($1, $2);
+ amp_ac_scanner_load_config (scanner, $2);
}
;
ac_config_files:
AC_CONFIG_FILES arg_list {
- anjuta_token_set_type ($1, AC_TOKEN_AC_CONFIG_FILES);
- $$ = anjuta_token_group ($1, $2);
+ amp_ac_scanner_load_config (scanner, $2);
}
;
@@ -264,26 +229,41 @@ ac_config_files:
arg_list:
arg_list_body RIGHT_PAREN {
- anjuta_token_set_type ($2, ANJUTA_TOKEN_LAST);
- $$ = $2;
+ $$ = anjuta_token_new_static (ANJUTA_TOKEN_LAST, NULL);
+ anjuta_token_merge ($$, $2);
+ anjuta_token_merge ($1, $$);
+ $$ = $1;
}
| spaces arg_list_body RIGHT_PAREN {
- anjuta_token_set_type ($1, ANJUTA_TOKEN_START);
- anjuta_token_set_type ($3, ANJUTA_TOKEN_LAST);
- $$ = $3;
+ $$ = anjuta_token_new_static (ANJUTA_TOKEN_LAST, NULL);
+ anjuta_token_merge ($$, $3);
+ anjuta_token_merge ($1, $$);
+ $$ = $1;
}
;
arg_list_body:
- arg
- | arg_list_body separator arg
+ arg {
+ $$ = anjuta_token_new_static (ANJUTA_TOKEN_LIST, NULL);
+ anjuta_token_merge ($$, $1);
+ fprintf(stdout, "arg_list_body arg\n");
+ anjuta_token_dump ($1);
+ }
+ | arg_list_body separator arg {
+ fprintf(stdout, "arg_list_body body\n");
+ anjuta_token_dump ($1);
+ fprintf(stdout, "arg_list_body separator\n");
+ anjuta_token_dump ($2);
+ fprintf(stdout, "arg_list_body arg\n");
+ anjuta_token_dump ($3);
+ anjuta_token_merge ($1, $3);
+ fprintf(stdout, "arg_list_body merge\n");
+ anjuta_token_dump ($1);
+ }
;
-
+
comment:
- HASH not_eol_list EOL {
- anjuta_token_set_type ($1, ANJUTA_TOKEN_COMMENT);
- anjuta_token_group ($1, $3);
- }
+ HASH not_eol_list EOL
;
not_eol_list:
@@ -294,56 +274,96 @@ not_eol_list:
shell_string:
LEFT_BRACE shell_string_body RIGHT_BRACE {
- anjuta_token_set_type ($1, ANJUTA_TOKEN_STRING);
- anjuta_token_set_type ($3, ANJUTA_TOKEN_LAST);
- $$ = anjuta_token_group ($1, $3);
+ anjuta_token_set_type ($1, ANJUTA_TOKEN_OPEN_QUOTE);
+ anjuta_token_set_type ($3, ANJUTA_TOKEN_CLOSE_QUOTE);
+ $$ = anjuta_token_merge_previous ($2, $1);
+ anjuta_token_merge ($2, $3);
}
;
shell_string_body:
- /* empty */
- | shell_string_body not_brace_token
- | shell_string_body shell_string
+ /* empty */ {
+ $$ = anjuta_token_new_static (ANJUTA_TOKEN_STRING, NULL);
+ }
+ | shell_string_body not_brace_token {
+ anjuta_token_merge ($1, $2);
+ }
+ | shell_string_body shell_string {
+ anjuta_token_merge ($1, $2);
+ }
;
raw_string:
LEFT_BRACE raw_string_body RIGHT_BRACE {
- anjuta_token_set_type ($1, ANJUTA_TOKEN_STRING);
- anjuta_token_set_type ($3, ANJUTA_TOKEN_LAST);
- $$ = anjuta_token_group ($1, $3);
+ anjuta_token_set_type ($1, ANJUTA_TOKEN_OPEN_QUOTE);
+ anjuta_token_set_type ($3, ANJUTA_TOKEN_CLOSE_QUOTE);
+ $$ = anjuta_token_merge_previous ($2, $1);
+ anjuta_token_merge ($2, $3);
}
;
raw_string_body:
- /* empty */
- | raw_string_body not_brace_token
- | raw_string_body raw_string
+ /* empty */ {
+ $$ = anjuta_token_new_static (ANJUTA_TOKEN_STRING, NULL);
+ }
+ | raw_string_body not_brace_token {
+ anjuta_token_merge ($1, $2);
+ }
+ | raw_string_body raw_string {
+ anjuta_token_merge ($1, $2);
+ }
;
arg_string:
LEFT_BRACE arg_string_body RIGHT_BRACE {
- $$ = anjuta_token_group_new (NAME, $1);
anjuta_token_set_type ($1, ANJUTA_TOKEN_OPEN_QUOTE);
anjuta_token_set_type ($3, ANJUTA_TOKEN_CLOSE_QUOTE);
- anjuta_token_group ($$, $3);
+ $$ = anjuta_token_merge_previous ($2, $1);
+ anjuta_token_merge ($2, $3);
}
;
arg_string_body:
- /* empty */
- | arg_string_body space_token
- | arg_string_body HASH
- | arg_string_body LEFT_PAREN
- | arg_string_body RIGHT_PAREN
- | arg_string_body COMMA
- | arg_string_body EQUAL
- | arg_string_body GREATER
- | arg_string_body LOWER
- | arg_string_body NAME
- | arg_string_body VARIABLE
- | arg_string_body WORD
+ /* empty */ {
+ $$ = anjuta_token_new_static (ANJUTA_TOKEN_STRING, NULL);
+ }
+ | arg_string_body space_token {
+ anjuta_token_merge ($1, $2);
+ }
+ | arg_string_body HASH {
+ anjuta_token_merge ($1, $2);
+ }
+ | arg_string_body LEFT_PAREN {
+ anjuta_token_merge ($1, $2);
+ }
+ | arg_string_body RIGHT_PAREN {
+ anjuta_token_merge ($1, $2);
+ }
+ | arg_string_body COMMA {
+ anjuta_token_merge ($1, $2);
+ }
+ | arg_string_body EQUAL {
+ anjuta_token_merge ($1, $2);
+ }
+ | arg_string_body GREATER {
+ anjuta_token_merge ($1, $2);
+ }
+ | arg_string_body LOWER {
+ anjuta_token_merge ($1, $2);
+ }
+ | arg_string_body NAME {
+ anjuta_token_merge ($1, $2);
+ }
+ | arg_string_body VARIABLE {
+ anjuta_token_merge ($1, $2);
+ }
+ | arg_string_body WORD {
+ anjuta_token_merge ($1, $2);
+ }
| arg_string_body macro
- | arg_string_body raw_string
+ | arg_string_body raw_string {
+ anjuta_token_merge ($1, $2);
+ }
;
/* Items
@@ -351,33 +371,48 @@ arg_string_body:
arg:
/* empty */ {
- $$ = NULL;
+ $$ = anjuta_token_new_static (ANJUTA_TOKEN_ITEM, NULL);
}
| arg_part arg_body {
- $$ = anjuta_token_group_new (ANJUTA_TOKEN_ARGUMENT, $1);
- if ($2 != NULL) anjuta_token_group ($$, $2);
+ fprintf(stdout, "arg part\n");
+ anjuta_token_dump ($1);
+ fprintf(stdout, "arg body\n");
+ anjuta_token_dump ($2);
+ anjuta_token_merge_children ($1, $2);
+ fprintf(stdout, "arg merge\n");
+ anjuta_token_dump ($1);
}
;
arg_body:
/* empty */ {
- $$ = NULL;
+ $$ = anjuta_token_new_static (ANJUTA_TOKEN_ITEM, NULL);
}
| arg_body arg_part_or_space {
- $$ = $2;
+ anjuta_token_merge_children ($1, $2);
}
;
arg_part_or_space:
- space_token
+ space_token {
+ $$ = anjuta_token_new_static (ANJUTA_TOKEN_ITEM, NULL);
+ anjuta_token_merge ($$, $1);
+ }
| arg_part
;
arg_part:
arg_string
- | expression
- | macro
- | HASH
+ | expression { $$ = NULL;}
+ | dnl
+ | arg_token {
+ $$ = anjuta_token_new_static (ANJUTA_TOKEN_ITEM, NULL);
+ anjuta_token_merge ($$, $1);
+ }
+ ;
+
+arg_token:
+ HASH
| EQUAL
| LOWER
| GREATER
@@ -388,46 +423,75 @@ arg_part:
separator:
COMMA {
- $$ = anjuta_token_group_new (ANJUTA_TOKEN_NEXT, $1);
+ $$ = anjuta_token_new_static (ANJUTA_TOKEN_NEXT, NULL);
+ anjuta_token_merge ($$, $1);
}
| COMMA spaces {
- $$ = anjuta_token_group_new (ANJUTA_TOKEN_NEXT, $1);
- anjuta_token_group ($$, $2);
+ $$ = anjuta_token_new_static (ANJUTA_TOKEN_NEXT, NULL);
+ fprintf(stdout, "separator spaces\n");
+ anjuta_token_dump ($2);
+ fprintf(stdout, "separator comma\n");
+ anjuta_token_dump ($1);
+ fprintf(stdout, "separator next\n");
+ anjuta_token_dump ($$);
+ anjuta_token_merge ($$, $1);
+ anjuta_token_merge_children ($$, $2);
+ fprintf(stdout, "separator merge\n");
+ anjuta_token_dump ($$);
}
;
expression:
LEFT_PAREN expression_body RIGHT_PAREN {
- anjuta_token_set_type ($1, ANJUTA_TOKEN_STRING);
- anjuta_token_set_type ($3, ANJUTA_TOKEN_LAST);
- $$ = anjuta_token_group ($1, $3);
+ anjuta_token_set_type ($1, ANJUTA_TOKEN_OPEN_QUOTE);
+ anjuta_token_set_type ($3, ANJUTA_TOKEN_CLOSE_QUOTE);
+ $$ = anjuta_token_merge_previous ($2, $1);
+ anjuta_token_merge ($2, $3);
}
;
expression_body:
- /* empty */ {
- $$ = NULL;
+ /* empty */ {
+ $$ = anjuta_token_new_static (ANJUTA_TOKEN_STRING, NULL);
+ }
+ | expression_body space_token {
+ anjuta_token_merge ($1, $2);
}
- | expression_body space_token
| expression_body comment
- | expression_body COMMA
- | expression_body EQUAL
- | expression_body LOWER
- | expression_body GREATER
- | expression_body NAME
- | expression_body VARIABLE
- | expression_body WORD
+ | expression_body COMMA {
+ anjuta_token_merge ($1, $2);
+ }
+ | expression_body EQUAL {
+ anjuta_token_merge ($1, $2);
+ }
+ | expression_body LOWER {
+ anjuta_token_merge ($1, $2);
+ }
+ | expression_body GREATER {
+ anjuta_token_merge ($1, $2);
+ }
+ | expression_body NAME {
+ anjuta_token_merge ($1, $2);
+ }
+ | expression_body VARIABLE {
+ anjuta_token_merge ($1, $2);
+ }
+ | expression_body WORD {
+ anjuta_token_merge ($1, $2);
+ }
| expression_body macro
- | expression_body expression
+ | expression_body expression {
+ anjuta_token_merge ($1, $2);
+ }
;
spaces:
- space_token
+ space_token {
+ $$ = anjuta_token_new_static (ANJUTA_TOKEN_SPACE, NULL);
+ anjuta_token_merge ($$, $1);
+ }
| spaces space_token {
- anjuta_token_group ($$, $2);
- }
- | spaces JUNK {
- anjuta_token_group ($$, $2);
+ anjuta_token_merge ($1, $2);
}
;
@@ -464,12 +528,6 @@ args_token:
| COMMA
;
-operator_token:
- EQUAL
- | LOWER
- | GREATER
- ;
-
not_operator_token:
HASH
| LEFT_BRACE
@@ -508,21 +566,7 @@ any_macro:
| DNL
| OBSOLETE_AC_OUTPUT
| PKG_CHECK_MODULES
+ | AC_INIT
;
%%
-
-static void
-amp_ac_yyerror (YYLTYPE *loc, AmpAcScanner *scanner, char const *s)
-{
- gchar *filename;
-
- g_message ("scanner %p", scanner);
- filename = amp_ac_scanner_get_filename ((AmpAcScanner *)scanner);
- if (filename == NULL) filename = "?";
- g_message ("%s (%d:%d-%d:%d) %s\n", filename, loc->first_line, loc->first_column, loc->last_line, loc->last_column, s);
-}
-
-/* Public functions
- *---------------------------------------------------------------------------*/
-
diff --git a/plugins/am-project/ac-scanner.h b/plugins/am-project/ac-scanner.h
index f3d03a6..48b5f75 100644
--- a/plugins/am-project/ac-scanner.h
+++ b/plugins/am-project/ac-scanner.h
@@ -20,27 +20,31 @@
#ifndef _AC_SCANNER_H_
#define _AC_SCANNER_H_
-#include "libanjuta/anjuta-token.h"
-#include "libanjuta/anjuta-token-file.h"
-
+#include "am-project.h"
#include <glib.h>
#include <gio/gio.h>
G_BEGIN_DECLS
+/* Token location is found directly from token value. We don't maintain a
+ * independent position. */
+#define YYLTYPE AnjutaToken*
#define YYSTYPE AnjutaToken*
typedef struct _AmpAcScanner AmpAcScanner;
-AmpAcScanner *amp_ac_scanner_new (void);
+AmpAcScanner *amp_ac_scanner_new (AmpProject *project);
void amp_ac_scanner_free (AmpAcScanner *scanner);
gboolean amp_ac_scanner_parse (AmpAcScanner *scanner, AnjutaTokenFile *file, GError **error);
-gboolean amp_ac_scanner_parse_token (AmpAcScanner *scanner, AnjutaToken *token, gint start, GError **error);
+AnjutaToken* amp_ac_scanner_parse_token (AmpAcScanner *scanner, AnjutaToken *token, gint start, GError **error);
+void amp_ac_scanner_load_module (AmpAcScanner *scanner, AnjutaToken *module);
+void amp_ac_scanner_load_config (AmpAcScanner *scanner, AnjutaToken *list);
+void amp_ac_scanner_load_properties (AmpAcScanner *scanner, AnjutaToken *macro, AnjutaToken *args);
-const gchar* amp_ac_scanner_get_filename (AmpAcScanner *scanner);
+void amp_ac_yyerror (YYLTYPE *loc, AmpAcScanner *scanner, char const *s);
enum
{
@@ -51,7 +55,8 @@ enum
AC_TOKEN_AC_OUTPUT,
AC_TOKEN_SPACE_LIST,
AC_TOKEN_OPEN_STRING,
- AC_TOKEN_CLOSE_STRING
+ AC_TOKEN_CLOSE_STRING,
+ AC_TOKEN_AC_PREREQ,
};
enum
diff --git a/plugins/am-project/ac-scanner.l b/plugins/am-project/ac-scanner.l
index b1868a2..87afc6c 100644
--- a/plugins/am-project/ac-scanner.l
+++ b/plugins/am-project/ac-scanner.l
@@ -19,20 +19,16 @@
%{
-#include <stdlib.h>
-#include <string.h>
-
#include "ac-scanner.h"
#include "ac-parser.h"
#include "libanjuta/anjuta-debug.h"
+#include "libanjuta/anjuta-token-stream.h"
-/* Eliminate warning */
-#define YY_NO_UNPUT 1
-
-#define YY_INPUT(buf, result, max_size) result = amp_ac_scanner_input (yyextra, buf, max_size)
+#include <stdlib.h>
+#include <string.h>
-#define YY_USER_ACTION amp_update_location(yylloc, yytext, yyleng);
+#define YY_INPUT(buffer, result, max_size) result = anjuta_token_stream_read (yyextra->stream, buffer, max_size)
#define YY_EXTRA_TYPE AmpAcScanner*
@@ -40,40 +36,30 @@
//#define YY_USER_INIT {yy_flex_debug = 1;}
-static AnjutaToken* amp_ac_scanner_append_token (AmpAcScanner *scanner, gint token);
-static void amp_update_location (YYLTYPE *loc, const gchar *text, gint length);
-static gint amp_ac_scanner_input (AmpAcScanner *scanner, gchar *buffer, gsize max_size);
-
-gboolean amp_ac_yyparse (AmpAcScanner *scanner);
-
+static gint amp_ac_scanner_parse_end (AmpAcScanner *scanner);
-#define RETURN(tok) *yylval = amp_ac_scanner_append_token (yyextra, tok); \
+#define RETURN(tok) *yylval = anjuta_token_stream_tokenize (yyextra->stream, tok, yyleng); \
return tok
-
struct _AmpAcScanner
{
yyscan_t scanner;
- AnjutaTokenFile *file;
- gchar *filename;
+ AnjutaTokenStream *stream;
- AnjutaToken *token;
- gint first;
+ AmpProject *project;
- /* Beginning of current token */
- AnjutaToken *start;
- gsize begin;
-
- /* Position in buffer */
- AnjutaToken *next;
- gsize pos;
+ AnjutaToken *parsed;
};
+
%}
%option reentrant stack noyywrap yylineno
+/* Remove some warnings */
+%option nounput noinput noyy_pop_state noyy_top_state
+
%option prefix="amp_ac_yy"
/* Necessary because autotools wrapper always looks for a file named "lex.yy.c",
@@ -150,6 +136,7 @@ AC_CONFIG_FILES\( { RETURN (AC_CONFIG_FILES); }
{OTHER}|\$|\\ { RETURN (WORD); }
+<<EOF>> { if (amp_ac_scanner_parse_end (yyextra) == YY_NULL) return YY_NULL; }
<SPACE_LIST>{
@@ -167,264 +154,132 @@ AC_CONFIG_FILES\( { RETURN (AC_CONFIG_FILES); }
/* Private functions
*---------------------------------------------------------------------------*/
-static AnjutaToken*
-amp_ac_scanner_append_token (AmpAcScanner *scanner, gint token)
+
+static gint
+amp_ac_scanner_parse_end (AmpAcScanner *scanner)
{
- AnjutaToken *frag;
+ scanner->parsed = anjuta_token_stream_get_root (scanner->stream);
+ yypop_buffer_state(scanner->scanner);
+ scanner->stream = anjuta_token_stream_pop (scanner->stream);
- if (scanner->file != NULL)
+ if (scanner->stream == NULL)
{
- const gchar *start = anjuta_token_file_get_content (scanner->file, NULL);
-
- frag = anjuta_token_new_fragment (token, start + scanner->begin, yyget_leng (scanner->scanner));
- anjuta_token_file_append (scanner->file, frag);
- scanner->begin += yyget_leng (scanner->scanner);
+ yyterminate();
}
- else if (scanner->token != NULL)
+ else
{
- gsize length = yyget_leng (scanner->scanner);
- AnjutaToken *end;
-
- for (end = scanner->start; end != NULL; end = anjuta_token_next_sibling (end))
- {
- if (anjuta_token_get_type (end) < ANJUTA_TOKEN_FIRST)
- {
- gint toklen = anjuta_token_get_length (end);
-
- if (toklen >= length)
- {
- if (toklen > length)
- {
- AnjutaToken *start = end;
-
- end = anjuta_token_split (end, length);
- if (start == scanner->start)
- {
- scanner->start = end;
- }
- }
-
- if (end == scanner->start)
- {
- /* Get whole token */
- frag = end;
- anjuta_token_set_type (frag, token);
- scanner->start = anjuta_token_next_sibling (end);
- }
- else
- {
- frag = anjuta_token_new_fragment (token, NULL, 0);
- anjuta_token_insert_before (scanner->start, frag);
- scanner->start = anjuta_token_next_sibling (end);
- anjuta_token_group (frag, end);
- }
- break;
- }
- else
- {
- length -= toklen;
- }
- }
- }
+ return 1;
}
-
- return frag;
}
-static void
-amp_update_location (YYLTYPE *loc, const gchar *text, gint length)
-{
- const gchar *ptr;
- const gchar *end = text + length;
-
- loc->first_line = loc->last_line;
- loc->first_column = loc->last_column + 1;
-
- for (ptr = text; ptr != end; ptr++)
- {
- if (*ptr == '\n')
- {
- loc->last_column = 0;
- loc->last_line++;
- length -= (ptr + 1 - text);
- }
- }
-
- loc->last_column += length;
-}
+/* Parser functions
+ *---------------------------------------------------------------------------*/
-static gint
-amp_ac_scanner_input (AmpAcScanner *scanner, gchar *buffer, gsize max_size)
+void
+amp_ac_yyerror (YYLTYPE *loc, AmpAcScanner *scanner, char const *s)
{
- gint result = YY_NULL;
+ AnjutaTokenFileLocation location;
- if (scanner->file != NULL)
+ if (amp_project_get_token_location (scanner->project, &location, *loc))
{
- gsize length = anjuta_token_file_get_length (scanner->file, NULL);
- if (scanner->pos < length)
- {
- const gchar *start = anjuta_token_file_get_content (scanner->file, NULL);
-
- length -= scanner->pos;
-
- if (length > max_size) length = max_size;
- memcpy (buffer, start + scanner->pos, length);
- scanner->pos += length;
- result = length;
- }
+ g_message ("%s:%d.%d %s\n", location.filename, location.line, location.column, s);
+ g_free (location.filename);
}
- else if (scanner->token != NULL)
+ else
{
- if (scanner->next)
- {
- gsize length = anjuta_token_get_length (scanner->next);
-
- if ((anjuta_token_get_type (scanner->next) >= ANJUTA_TOKEN_FIRST) || (scanner->pos >= length))
- {
- for (;;)
- {
- scanner->next = anjuta_token_next_sibling (scanner->next);
- if (scanner->next == NULL)
- {
- /* Last token */
- break;
- }
- else if ((anjuta_token_get_length (scanner->next) != 0) && (anjuta_token_get_type (scanner->next) < ANJUTA_TOKEN_FIRST))
- {
- /* Find some data */
- scanner->pos = 0;
- length = anjuta_token_get_length (scanner->next);
- break;
- }
- }
- }
-
- if (scanner->pos < length)
- {
- const gchar *start = anjuta_token_get_string (scanner->next);
-
- length -= scanner->pos;
-
- if (length > max_size) length = max_size;
- memcpy (buffer, start + scanner->pos, length);
- scanner->pos += length;
- result = length;
- }
- }
-
+ g_message ("%s \n", s);
}
-
- return result;
}
-/* Public functions
- *---------------------------------------------------------------------------*/
-
-int
-amp_ac_yylex (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,AmpAcScanner *scanner)
+void
+amp_ac_scanner_load_module (AmpAcScanner *scanner, AnjutaToken *module)
{
- /* Return a special start token for bison */
- switch (scanner->first)
- {
- case AC_SPACE_LIST_STATE:
- scanner->first = 0;
- yy_push_state (SPACE_LIST, scanner->scanner);
- return START_SPACE_LIST;
- default:
- break;
- }
+ amp_project_load_module (scanner->project, module);
+}
- /* Parse unknown data */
- return ac_yylex (yylval_param, yylloc_param, scanner->scanner);
+void
+amp_ac_scanner_load_config (AmpAcScanner *scanner, AnjutaToken *list)
+{
+ amp_project_load_config (scanner->project, list);
}
-gboolean
-amp_ac_scanner_parse (AmpAcScanner *scanner, AnjutaTokenFile *file, GError **error)
+void
+amp_ac_scanner_load_properties (AmpAcScanner *scanner, AnjutaToken *macro, AnjutaToken *list)
{
+ amp_project_load_properties (scanner->project, macro, list);
+}
- g_return_val_if_fail (file != NULL, FALSE);
- scanner->file = file;
- scanner->pos = 0;
- scanner->begin = 0;
- scanner->token = NULL;
- scanner->first = 0;
-
- return amp_ac_yyparse (scanner) == 0;
-}
+/* Public functions
+ *---------------------------------------------------------------------------*/
-gboolean
+AnjutaToken *
amp_ac_scanner_parse_token (AmpAcScanner *scanner, AnjutaToken *token, gint start, GError **error)
{
- AnjutaToken *child;
+ AnjutaToken *first;
+ AnjutaTokenStream *stream;
- scanner->token = token;
- scanner->pos = 0;
- scanner->begin = 0;
- scanner->file = NULL;
- scanner->first = start;
+ stream = anjuta_token_stream_push (scanner->stream, token);
+ first = anjuta_token_stream_get_root (stream);
- if (anjuta_token_get_length (token) != 0)
+ if (scanner->stream != NULL)
{
- AnjutaToken *copy = anjuta_token_copy (token);
-
- anjuta_token_insert_child (token, copy);
- anjuta_token_clear (token);
- }
+ /* Parse an included file or a expanded variable */
- /* Move all know data in a list */
- for (child = anjuta_token_next_child (token); child != NULL;)
+ scanner->stream = stream;
+ yypush_buffer_state(yy_create_buffer(NULL, YY_BUF_SIZE, scanner->scanner), scanner->scanner);
+ }
+ else
{
- if (anjuta_token_get_type (child) < ANJUTA_TOKEN_FIRST)
+ amp_ac_yypstate *ps;
+ gint status;
+ YYSTYPE yylval_param;
+ YYLTYPE yylloc_param;
+
+ scanner->stream = stream;
+ ps = amp_ac_yypstate_new ();
+
+ yylval_param = NULL;
+ yylloc_param = NULL;
+ switch (start)
{
- child = anjuta_token_ungroup (child);
- if (anjuta_token_get_length (child) == 0)
- {
- child = anjuta_token_delete (child);
- continue;
- }
+ case AC_SPACE_LIST_STATE:
+ amp_ac_yypush_parse (ps, START_SPACE_LIST, &yylval_param, &yylloc_param, scanner);
+ yy_push_state (SPACE_LIST, scanner->scanner);
+ break;
+ default:
+ break;
}
- child = anjuta_token_next_sibling (child);
- }
-
- scanner->next = anjuta_token_next_child (token);
- scanner->start = scanner->next;
- return amp_ac_yyparse (scanner) == 0;
-}
+ do
+ {
+ gint yychar = ac_yylex (&yylval_param, &yylloc_param, scanner->scanner);
+
+ yylloc_param = yylval_param;
+ status = amp_ac_yypush_parse (ps, yychar, &yylval_param, &yylloc_param, scanner);
-const gchar*
-amp_ac_scanner_get_filename (AmpAcScanner *scanner)
-{
- g_free (scanner->filename);
- scanner->filename = NULL;
- if (scanner->file != NULL)
- {
- scanner->filename = g_file_get_path (anjuta_token_file_get_file (scanner->file));
- }
- else if (scanner->token != NULL)
- {
- scanner->filename = anjuta_token_value (scanner->token);
+ } while (status == YYPUSH_MORE);
+ amp_ac_yypstate_delete (ps);
}
-
- return scanner->filename;
-}
+ return first;
+}
/* Constructor & Destructor
*---------------------------------------------------------------------------*/
AmpAcScanner *
-amp_ac_scanner_new (void)
+amp_ac_scanner_new (AmpProject *project)
{
AmpAcScanner *scanner;
scanner = g_new0 (AmpAcScanner, 1);
yylex_init(&scanner->scanner);
-
yyset_extra (scanner, scanner->scanner);
+ scanner->project = project;
+
return scanner;
};
@@ -433,11 +288,7 @@ amp_ac_scanner_free (AmpAcScanner *scanner)
{
g_return_if_fail (scanner != NULL);
- //if (scanner->buffer != NULL) yy_delete_buffer (scanner->buffer, scanner->scanner);
yylex_destroy(scanner->scanner);
- g_free (scanner->filename);
- scanner->filename = NULL;
-
g_free (scanner);
}
diff --git a/plugins/am-project/ac-writer.c b/plugins/am-project/ac-writer.c
index 71d2bfc..2aa583a 100644
--- a/plugins/am-project/ac-writer.c
+++ b/plugins/am-project/ac-writer.c
@@ -25,6 +25,8 @@
#endif
#include "ac-writer.h"
+#include "ac-scanner.h"
+#include "ac-parser.h"
#include "am-project-private.h"
@@ -41,56 +43,78 @@
/* Private functions
*---------------------------------------------------------------------------*/
-static gboolean
-remove_list_item (AnjutaToken *token, AnjutaTokenStyle *user_style)
+static AnjutaToken*
+find_tokens (AnjutaToken *list, AnjutaTokenType* types)
{
- AnjutaTokenStyle *style;
- AnjutaToken *space;
-
- DEBUG_PRINT ("remove list item");
-
- style = user_style != NULL ? user_style : anjuta_token_style_new (NULL," ","\\n",NULL,0);
- anjuta_token_style_update (style, anjuta_token_parent (token));
+ AnjutaToken *tok;
- anjuta_token_remove (token);
- space = anjuta_token_next_sibling (token);
- if (space && (anjuta_token_get_type (space) == ANJUTA_TOKEN_SPACE) && (anjuta_token_next (space) != NULL))
- {
- /* Remove following space */
- anjuta_token_remove (space);
- }
- else
+ for (tok = list; tok != NULL; tok = anjuta_token_next (tok))
{
- space = anjuta_token_previous_sibling (token);
- if (space && (anjuta_token_get_type (space) == ANJUTA_TOKEN_SPACE) && (anjuta_token_previous (space) != NULL))
+ AnjutaTokenType *type;
+ for (type = types; *type != 0; type++)
{
- anjuta_token_remove (space);
+ if (anjuta_token_get_type (tok) == *type)
+ {
+ return tok;
+ }
}
}
-
- anjuta_token_style_format (style, anjuta_token_parent (token));
- if (user_style == NULL) anjuta_token_style_free (style);
-
- return TRUE;
+
+ return NULL;
}
-static gboolean
-add_list_item (AnjutaToken *list, AnjutaToken *token, AnjutaTokenStyle *user_style)
+static AnjutaToken *
+find_next_eol (AnjutaToken *token)
{
- AnjutaTokenStyle *style;
- AnjutaToken *space;
-
- style = user_style != NULL ? user_style : anjuta_token_style_new (NULL," ","\\n",NULL,0);
- anjuta_token_style_update (style, anjuta_token_parent (list));
+ if (token == NULL) return NULL;
- space = anjuta_token_new_static (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, " ");
- space = anjuta_token_insert_after (list, space);
- anjuta_token_insert_after (space, token);
+ for (;;)
+ {
+ AnjutaToken *next = anjuta_token_next (token);
+
+ if (next == NULL) return token;
+ token = next;
+ if (anjuta_token_get_type (token) == EOL) return token;
+ }
+}
- anjuta_token_style_format (style, anjuta_token_parent (list));
- if (user_style == NULL) anjuta_token_style_free (style);
+static AnjutaToken *
+skip_comment (AnjutaToken *token)
+{
+ if (token == NULL) return NULL;
- return TRUE;
+ for (;;)
+ {
+ for (;;)
+ {
+ AnjutaToken *next = anjuta_token_next (token);
+
+ if (next == NULL) return token;
+
+ switch (anjuta_token_get_type (token))
+ {
+ case ANJUTA_TOKEN_FILE:
+ case SPACE:
+ token = next;
+ continue;
+ case COMMENT:
+ token = next;
+ break;
+ default:
+ return token;
+ }
+ break;
+ }
+
+ for (;;)
+ {
+ AnjutaToken *next = anjuta_token_next (token);
+
+ if (next == NULL) return token;
+ token = next;
+ if (anjuta_token_get_type (token) == EOL) break;
+ }
+ }
}
/* Public functions
@@ -100,18 +124,11 @@ gboolean
amp_project_update_property (AmpProject *project, AmpPropertyType type)
{
AnjutaToken *token;
+ AnjutaToken *arg;
guint pos;
const gchar *value;
-
- if (project->property == NULL)
- {
- return FALSE;
- }
- gchar *name;
- gchar *version;
- gchar *bug_report;
- gchar *tarname;
- gchar *url;
+
+ g_return_val_if_fail (project->property != NULL, FALSE);
switch (type)
{
@@ -137,9 +154,48 @@ amp_project_update_property (AmpProject *project, AmpPropertyType type)
break;
}
+ if (project->property->ac_init == NULL)
+ {
+ gint types[] = {AC_TOKEN_AC_PREREQ, 0};
+ AnjutaToken *group;
+
+ token = find_tokens (project->configure_token, types);
+ if (token == NULL)
+ {
+ token = skip_comment (project->configure_token);
+ if (token == NULL)
+ {
+ token = anjuta_token_append_child (project->configure_token, anjuta_token_new_string (COMMENT | ANJUTA_TOKEN_ADDED, "#"));
+ token = anjuta_token_insert_after (token, anjuta_token_new_string (SPACE | ANJUTA_TOKEN_ADDED, " Created by Anjuta project manager"));
+ token = anjuta_token_insert_after (token, anjuta_token_new_string (EOL | ANJUTA_TOKEN_ADDED, "\n"));
+ token = anjuta_token_insert_after (token, anjuta_token_new_string (EOL | ANJUTA_TOKEN_ADDED, "\n"));
+ }
+ }
+
+ token = anjuta_token_insert_before (token, anjuta_token_new_string (AC_TOKEN_AC_INIT | ANJUTA_TOKEN_ADDED, "AC_INIT("));
+ project->property->ac_init = token;
+ group = anjuta_token_insert_after (token, anjuta_token_new_static (ANJUTA_TOKEN_LIST | ANJUTA_TOKEN_ADDED, NULL));
+ project->property->args = group;
+ token = anjuta_token_insert_after (group, anjuta_token_new_static (ANJUTA_TOKEN_LAST | ANJUTA_TOKEN_ADDED, NULL));
+ anjuta_token_merge (group, token);
+ anjuta_token_insert_after (token, anjuta_token_new_string (EOL | ANJUTA_TOKEN_ADDED, "\n"));
+ fprintf(stdout, "whole file\n");
+ anjuta_token_dump (project->configure_token);
+ }
+ fprintf(stdout, "ac_init before replace\n");
+ anjuta_token_dump (project->property->args);
token = anjuta_token_new_string (ANJUTA_TOKEN_NAME | ANJUTA_TOKEN_ADDED, value);
- anjuta_token_list_replace_nth (project->property->ac_init, pos, token);
- anjuta_token_style_format (project->arg_list, project->property->ac_init);
+ arg = anjuta_token_insert_before (token, anjuta_token_new_static (ANJUTA_TOKEN_ITEM | ANJUTA_TOKEN_ADDED, NULL));
+ anjuta_token_merge (arg, token);
+ anjuta_token_replace_nth_word (project->property->args, pos, arg);
+ fprintf(stdout, "ac_init after replace\n");
+ anjuta_token_dump (project->property->args);
+ fprintf(stdout, "ac_init after replace link\n");
+ anjuta_token_dump_link (project->property->args);
+ anjuta_token_style_format (project->arg_list, project->property->args);
+ fprintf(stdout, "ac_init after update link\n");
+ anjuta_token_dump (project->property->args);
+ anjuta_token_file_update (project->configure_file, token);
return TRUE;
}
diff --git a/plugins/am-project/am-parser.y b/plugins/am-project/am-parser.y
index a6fbcd7..bb8b37e 100644
--- a/plugins/am-project/am-parser.y
+++ b/plugins/am-project/am-parser.y
@@ -18,56 +18,58 @@
*/
%{
-#include <am-scanner.h>
+#include "am-scanner.h"
+#include "am-parser.h"
#include <stdlib.h>
#define YYDEBUG 1
+/* Token location is found directly from token value, there is no need to
+ * maintain a separate location variable */
+#define YYLLOC_DEFAULT(Current, Rhs, N) ((Current) = YYRHSLOC(Rhs, (N) ? 1 : 0))
%}
-/* Defining an union allow to use 2 protocol blocks (enclosed by %{ %}) which
- * is useful when redefining YYSTYPE. */
-%union {
- AnjutaToken *token;
- AnjutaTokenRange range;
-}
-
-%token <token> EOL '\n'
-%token <token> SPACE
-%token <token> TAB '\t'
-%token <token> MACRO
-%token <token> VARIABLE
-%token <token> COLON ':'
-%token <token> DOUBLE_COLON "::"
-%token <token> ORDER '|'
-%token <token> SEMI_COLON ';'
-%token <token> EQUAL '='
-%token <token> IMMEDIATE_EQUAL ":="
-%token <token> CONDITIONAL_EQUAL "?="
-%token <token> APPEND "+="
-%token <token> CHARACTER
-%token <token> NAME
-%token <token> AM_VARIABLE
-%type <token> head_token target_token value_token name_token space_token rule_token equal_token token automake_token prerequisite_token
-%type <token> am_variable
-%type <token> value head space prerequisite target depend rule variable commands head_with_space
-%type <token> value_list strip_value_list prerequisite_list target_list token_list target_list2
-%type <token> optional_space space_list_value
+%token EOL '\n'
+%token SPACE
+%token TAB '\t'
+%token MACRO
+%token VARIABLE
+%token COLON ':'
+%token DOUBLE_COLON "::"
+%token ORDER '|'
+%token SEMI_COLON ';'
+%token EQUAL '='
+%token IMMEDIATE_EQUAL ":="
+%token CONDITIONAL_EQUAL "?="
+%token APPEND "+="
+%token CHARACTER
+%token NAME
+%token AM_VARIABLE
+
+%token SUBDIRS
+%token DIST_SUBDIRS
+%token _DATA
+%token _HEADERS
+%token _LIBRARIES
+%token _LISP
+%token _LTLIBRARIES
+%token _MANS
+%token _PROGRAMS
+%token _PYTHON
+%token _JAVA
+%token _SCRIPTS
+%token _SOURCES
+%token _TEXINFOS
%defines
-%pure_parser
-
-/* Necessary because autotools wrapper always looks for a file named "y.tab.c",
- * not "amp-scanner.c"
-%output="y.tab.c"*/
+%define api.pure
+%define api.push_pull "push"
-%glr-parser
-
-%parse-param {void* scanner}
-%lex-param {void* scanner}
+%parse-param {AmpAmScanner* scanner}
+%lex-param {AmpAmScanner* scanner}
%name-prefix="amp_am_yy"
@@ -79,9 +81,28 @@
%{
-//amp_am_yydebug = 1;
-
-static void amp_am_yyerror (YYLTYPE *loc, AmpAmScanner *scanner, char const *s);
+static gint
+amp_am_automake_variable (AnjutaToken *token)
+{
+ switch (anjuta_token_get_type (token))
+ {
+ case SUBDIRS: return AM_TOKEN_SUBDIRS;
+ case DIST_SUBDIRS: return AM_TOKEN_DIST_SUBDIRS;
+ case _DATA: return AM_TOKEN__DATA;
+ case _HEADERS: return AM_TOKEN__HEADERS;
+ case _LIBRARIES: return AM_TOKEN__LIBRARIES;
+ case _LISP: return AM_TOKEN__LISP;
+ case _LTLIBRARIES: return AM_TOKEN__LTLIBRARIES;
+ case _MANS: return AM_TOKEN__MANS;
+ case _PROGRAMS: return AM_TOKEN__PROGRAMS;
+ case _PYTHON: return AM_TOKEN__PYTHON;
+ case _JAVA: return AM_TOKEN__JAVA;
+ case _SCRIPTS: return AM_TOKEN__SCRIPTS;
+ case _SOURCES: return AM_TOKEN__SOURCES;
+ case _TEXINFOS: return AM_TOKEN__TEXINFOS;
+ default: return ANJUTA_TOKEN_NAME;
+ }
+}
%}
@@ -104,87 +125,48 @@ line:
| line token
;
-variable:
- head_with_space equal_token optional_space value_list optional_space
- | head equal_token optional_space value_list optional_space
- ;
-
-rule:
- depend
- | depend SEMI_COLON commands
- | depend EOL TAB commands
- ;
-
-depend:
- target_list rule_token optional_space prerequisite_list optional_space ORDER optional_space prerequisite_list
- ;
-
-commands:
- token_list
- | commands EOL TAB token_list
- ;
-
am_variable:
- AM_VARIABLE space_list_value {
- $$ = anjuta_token_merge (
- anjuta_token_insert_before ($1,
- anjuta_token_new_static (ANJUTA_TOKEN_STATEMENT, NULL)),
- $2);
+ automake_token space_list_value {
+ $$= anjuta_token_merge_previous ($2, $1);
+ amp_am_scanner_set_am_variable (scanner, amp_am_automake_variable ($1), $1, anjuta_token_last_item ($2));
}
- | AM_VARIABLE optional_space equal_token optional_space
+ | automake_token optional_space equal_token optional_space
+ {
+ $$ = anjuta_token_new_static (ANJUTA_TOKEN_LIST, NULL);
+ anjuta_token_merge ($$, $1);
+ }
;
space_list_value: optional_space equal_token value_list {
- $$ = $3;
+ $$ = anjuta_token_new_static (ANJUTA_TOKEN_LIST, NULL);
+ if ($1 != NULL) anjuta_token_set_type ($1, ANJUTA_TOKEN_START);
+ anjuta_token_merge ($$, $1);
+ anjuta_token_merge ($$, $2);
+ anjuta_token_merge ($$, $3);
}
;
value_list:
optional_space strip_value_list optional_space {
- if ($1) anjuta_token_merge_previous ($2, $1);
- if ($3) anjuta_token_merge ($2, $3);
+ if ($1 != NULL) anjuta_token_set_type ($1, ANJUTA_TOKEN_START);
+ if ($3 != NULL) anjuta_token_set_type ($3, ANJUTA_TOKEN_LAST);
+ anjuta_token_merge_previous ($2, $1);
+ anjuta_token_merge ($2, $3);
$$ = $2;
}
strip_value_list:
value {
- $$ = anjuta_token_merge (
- anjuta_token_insert_before ($1,
- anjuta_token_new_static (ANJUTA_TOKEN_LIST, NULL)),
- $1);
+ $$ = anjuta_token_new_static (ANJUTA_TOKEN_LIST, NULL);
+ anjuta_token_merge ($$, $1);
}
| strip_value_list space value {
+ anjuta_token_set_type ($2, ANJUTA_TOKEN_NEXT);
+ anjuta_token_merge ($1, $2);
anjuta_token_merge ($1, $3);
}
;
-target_list:
- head
- | head_with_space
- | head_with_space target_list2 optional_space
- ;
-
-target_list2:
- target
- | target_list2 space target {
- anjuta_token_merge ($1, $3);
- }
- ;
-
-token_list:
- token
- | token_list token
- ;
-
-prerequisite_list:
- prerequisite
- | prerequisite_list space prerequisite {
- anjuta_token_merge ($1, $3);
- }
- ;
-
-
-
optional_space:
/* empty */ {
$$ = NULL;
@@ -192,41 +174,20 @@ optional_space:
| space
;
-
-head_with_space:
- head space
- ;
-
-head:
- head_token
- | head name_token {
- anjuta_token_merge ($1, $2);
- }
- ;
-
-target:
- head_token
- | target target_token {
- anjuta_token_merge ($1, $2);
- }
- ;
-
value:
- value_token
+ value_token {
+ $$ = anjuta_token_new_static (ANJUTA_TOKEN_ARGUMENT, NULL);
+ anjuta_token_merge ($$, $1);
+ }
| value value_token {
anjuta_token_merge ($1, $2);
}
;
-prerequisite:
- prerequisite_token
- | prerequisite prerequisite_token {
- anjuta_token_merge ($1, $2);
- }
- ;
-
space:
- space_token
+ space_token {
+ $$ = anjuta_token_new_static (ANJUTA_TOKEN_SPACE, NULL);
+ anjuta_token_merge ($$, $1);}
| space space_token {
anjuta_token_merge ($1, $2);
}
@@ -244,21 +205,11 @@ value_token:
| target_token
;
-prerequisite_token:
- equal_token
- | rule_token
- | name_token
- | automake_token
- | ORDER
- | SEMI_COLON
- ;
-
target_token:
head_token
| automake_token
;
-
-
+
space_token:
SPACE
| TAB
@@ -293,28 +244,21 @@ name_token:
;
automake_token:
- AM_VARIABLE
- ;
+ SUBDIRS
+ | DIST_SUBDIRS
+ | _DATA
+ | _HEADERS
+ | _LIBRARIES
+ | _LISP
+ | _LTLIBRARIES
+ | _MANS
+ | _PROGRAMS
+ | _PYTHON
+ | _JAVA
+ | _SCRIPTS
+ | _SOURCES
+ | _TEXINFOS
+ ;
+
%%
-
-static void
-amp_am_yyerror (YYLTYPE *loc, AmpAmScanner *scanner, char const *s)
-{
- gchar *filename;
-
- g_message ("scanner %p", scanner);
- filename = amp_am_scanner_get_filename ((AmpAmScanner *)scanner);
- if (filename == NULL) filename = "?";
- g_message ("%s (%d:%d-%d:%d) %s\n", filename, loc->first_line, loc->first_column, loc->last_line, loc->last_column, s);
-}
-
-/*static void
-amp_am_yyerror (YYLTYPE *loc, void *scanner, char const *s)
-{
- g_message ("(%d:%d-%d:%d) %s\n", loc->first_line, loc->first_column, loc->last_line, loc->last_column, s);
-}*/
-
-/* Public functions
- *---------------------------------------------------------------------------*/
-
diff --git a/plugins/am-project/am-project-private.h b/plugins/am-project/am-project-private.h
index c49c1c3..641a2b9 100644
--- a/plugins/am-project/am-project-private.h
+++ b/plugins/am-project/am-project-private.h
@@ -26,8 +26,19 @@
G_BEGIN_DECLS
+struct _AmpPackage {
+ gchar *name;
+ gchar *version;
+};
+
+struct _AmpModule {
+ GList *packages;
+ AnjutaToken *module;
+};
+
struct _AmpProperty {
AnjutaToken *ac_init; /* AC_INIT macro */
+ AnjutaToken *args;
gchar *name;
gchar *version;
gchar *bug_report;
@@ -44,7 +55,8 @@ struct _AmpProject {
/* project data */
AnjutaTokenFile *configure_file; /* configure.in file */
-
+ AnjutaToken *configure_token;
+
AmpProperty *property;
AmpGroup *root_node; /* tree containing project data;
@@ -63,7 +75,8 @@ struct _AmpProject {
GHashTable *monitors;
/* Keep list style */
- AnjutaTokenStyle *space_list;
+ AnjutaTokenStyle *ac_space_list;
+ AnjutaTokenStyle *am_space_list;
AnjutaTokenStyle *arg_list;
};
diff --git a/plugins/am-project/am-project.c b/plugins/am-project/am-project.c
index 38ba080..3f8129c 100644
--- a/plugins/am-project/am-project.c
+++ b/plugins/am-project/am-project.c
@@ -48,6 +48,7 @@
#include "ac-writer.h"
#include "am-scanner.h"
#include "am-dialogs.h"
+#include "am-writer.h"
//#include "am-config.h"
//#include "am-properties.h"
@@ -67,20 +68,14 @@ static const gchar *valid_am_makefiles[] = {"GNUmakefile.am", "makefile.am", "Ma
#define AMP_TARGET_DATA(node) ((node) != NULL ? (AmpTargetData *)((node)->data) : NULL)
#define AMP_SOURCE_DATA(node) ((node) != NULL ? (AmpSourceData *)((node)->data) : NULL)
-typedef struct _AmpPackage AmpPackage;
+#define STR_REPLACE(target, source) \
+ { g_free (target); target = source == NULL ? NULL : g_strdup (source);}
-struct _AmpPackage {
- gchar *name;
- gchar *version;
-};
+
+typedef struct _AmpPackage AmpPackage;
typedef struct _AmpModule AmpModule;
-struct _AmpModule {
- GList *packages;
- AnjutaToken *module;
-};
-
typedef enum {
AM_GROUP_TOKEN_CONFIGURE,
AM_GROUP_TOKEN_SUBDIRS,
@@ -97,6 +92,7 @@ struct _AmpGroupData {
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;
};
typedef enum _AmpTargetFlag
@@ -341,58 +337,6 @@ file_type (GFile *file, const gchar *filename)
return type;
}
-gboolean
-remove_list_item (AnjutaToken *token, AnjutaTokenStyle *user_style)
-{
- AnjutaTokenStyle *style;
- AnjutaToken *space;
-
- DEBUG_PRINT ("remove list item");
-
- style = user_style != NULL ? user_style : anjuta_token_style_new (NULL," ","\\n",NULL,0);
- anjuta_token_style_update (style, anjuta_token_parent (token));
-
- anjuta_token_remove (token);
- space = anjuta_token_next_sibling (token);
- if (space && (anjuta_token_get_type (space) == ANJUTA_TOKEN_SPACE) && (anjuta_token_next (space) != NULL))
- {
- /* Remove following space */
- anjuta_token_remove (space);
- }
- else
- {
- space = anjuta_token_previous_sibling (token);
- if (space && (anjuta_token_get_type (space) == ANJUTA_TOKEN_SPACE) && (anjuta_token_previous (space) != NULL))
- {
- anjuta_token_remove (space);
- }
- }
-
- anjuta_token_style_format (style, anjuta_token_parent (token));
- if (user_style == NULL) anjuta_token_style_free (style);
-
- return TRUE;
-}
-
-static gboolean
-add_list_item (AnjutaToken *list, AnjutaToken *token, AnjutaTokenStyle *user_style)
-{
- AnjutaTokenStyle *style;
- AnjutaToken *space;
-
- style = user_style != NULL ? user_style : anjuta_token_style_new (NULL," ","\\n",NULL,0);
- anjuta_token_style_update (style, anjuta_token_parent (list));
-
- space = anjuta_token_new_static (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, " ");
- space = anjuta_token_insert_after (list, space);
- anjuta_token_insert_after (space, token);
-
- anjuta_token_style_format (style, anjuta_token_parent (list));
- if (user_style == NULL) anjuta_token_style_free (style);
-
- return TRUE;
-}
-
/* Automake parsing function
*---------------------------------------------------------------------------*/
@@ -501,6 +445,8 @@ ac_init_default_tarname (const gchar *name)
{
gchar *tarname;
+ if (name == NULL) return NULL;
+
/* Remove GNU prefix */
if (strncmp (name, "GNU ", 4) == 0) name += 4;
@@ -522,6 +468,7 @@ amp_config_file_new (const gchar *pathname, GFile *project_root, AnjutaToken *to
config = g_slice_new0(AmpConfigFile);
config->file = g_file_resolve_relative_path (project_root, pathname);
+ g_message ("new config file =%s= token %p group %p", pathname, token, anjuta_token_list (token));
config->token = token;
return config;
@@ -618,20 +565,28 @@ amp_project_free_module_hash (AmpProject *project)
*---------------------------------------------------------------------------*/
static AmpProperty*
-amp_property_new (AnjutaToken *token)
+amp_property_new (AnjutaToken *macro, AnjutaToken *list)
{
AmpProperty *prop;
AnjutaToken *arg;
prop = g_slice_new0(AmpProperty);
- prop->ac_init = token;
+ prop->ac_init = macro;
+ prop->args = list;
- arg = anjuta_token_next_child (token);
- arg = anjuta_token_get_next_arg (arg, &prop->name);
- arg = anjuta_token_get_next_arg (arg, &prop->version);
- arg = anjuta_token_get_next_arg (arg, &prop->bug_report);
- arg = anjuta_token_get_next_arg (arg, &prop->tarname);
- arg = anjuta_token_get_next_arg (arg, &prop->url);
+ if (list != NULL)
+ {
+ arg = anjuta_token_nth_word (list, 0);
+ prop->name = anjuta_token_evaluate (arg);
+ arg = anjuta_token_nth_word (list, 1);
+ prop->version = anjuta_token_evaluate (arg);
+ arg = anjuta_token_nth_word (list, 2);
+ prop->bug_report = anjuta_token_evaluate (arg);
+ arg = anjuta_token_nth_word (list, 3);
+ prop->tarname = anjuta_token_evaluate (arg);
+ arg = anjuta_token_nth_word (list, 4);
+ prop->url = anjuta_token_evaluate (arg);
+ }
return prop;
}
@@ -671,6 +626,17 @@ amp_group_get_token (AmpGroup *node, AmpGroupTokenCategory category)
return group->tokens[category];
}
+static AnjutaToken*
+amp_group_get_first_token (AmpGroup *node, AmpGroupTokenCategory category)
+{
+ GList *list;
+
+ list = amp_group_get_token (node, category);
+ if (list == NULL) return NULL;
+
+ return (AnjutaToken *)list->data;
+}
+
static void
amp_group_set_dist_only (AmpGroup *node, gboolean dist_only)
{
@@ -680,7 +646,7 @@ amp_group_set_dist_only (AmpGroup *node, gboolean dist_only)
}
static AnjutaTokenFile*
-amp_group_set_makefile (AmpGroup *node, GFile *makefile)
+amp_group_set_makefile (AmpGroup *node, GFile *makefile, AmpProject* project)
{
AmpGroupData *group;
@@ -691,13 +657,23 @@ amp_group_set_makefile (AmpGroup *node, GFile *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);
+
+ scanner = amp_am_scanner_new (project, node);
+ group->make_token = amp_am_scanner_parse_token (scanner, token, NULL);
+ amp_am_scanner_free (scanner);
}
else
{
group->makefile = NULL;
group->tfile = NULL;
+ group->make_token = NULL;
}
return group->tfile;
@@ -740,7 +716,7 @@ amp_group_free (AmpGroup *node)
*---------------------------------------------------------------------------*/
static void
-amp_target_add_token (AmpGroup *node, AnjutaToken *token)
+amp_target_add_token (AmpTarget *node, AnjutaToken *token)
{
AmpTargetData *target;
@@ -751,7 +727,7 @@ amp_target_add_token (AmpGroup *node, AnjutaToken *token)
}
static GList *
-amp_target_get_token (AmpGroup *node)
+amp_target_get_token (AmpTarget *node)
{
AmpTargetData *target;
@@ -804,7 +780,7 @@ amp_source_new (GFile *file)
return g_node_new (source);
}
-static void
+void
amp_source_free (AmpSource *node)
{
AmpSourceData *source = AMP_SOURCE_DATA (node);
@@ -923,7 +899,7 @@ monitors_setup (AmpProject *project)
*/
static void
-amp_dump_node (GNode *g_node)
+amp_dump_node (AnjutaProjectNode *g_node)
{
gchar *name = NULL;
@@ -947,8 +923,8 @@ amp_dump_node (GNode *g_node)
g_free (name);
}
-static gboolean
-foreach_node_destroy (GNode *g_node,
+static void
+foreach_node_destroy (AnjutaProjectNode *g_node,
gpointer data)
{
switch (AMP_NODE_DATA (g_node)->type) {
@@ -967,100 +943,85 @@ foreach_node_destroy (GNode *g_node,
g_assert_not_reached ();
break;
}
-
-
- return FALSE;
}
static void
-project_node_destroy (AmpProject *project, GNode *g_node)
+project_node_destroy (AmpProject *project, AnjutaProjectNode *g_node)
{
g_return_if_fail (project != NULL);
g_return_if_fail (AMP_IS_PROJECT (project));
if (g_node) {
/* free each node's data first */
- g_node_traverse (g_node,
- G_POST_ORDER, G_TRAVERSE_ALL, -1,
+ anjuta_project_node_all_foreach (g_node,
foreach_node_destroy, project);
-
+
/* now destroy the tree itself */
//g_node_destroy (g_node);
}
}
-static gboolean
-project_reload_property (AmpProject *project)
+void
+amp_project_load_properties (AmpProject *project, AnjutaToken *macro, AnjutaToken *list)
{
- AnjutaToken *ac_init_tok;
- AnjutaToken *sequence;
- AnjutaToken *init;
-
- ac_init_tok = anjuta_token_new_static (AC_TOKEN_AC_INIT, NULL);
-
- sequence = anjuta_token_file_first (project->configure_file);
- if (anjuta_token_match (ac_init_tok, ANJUTA_SEARCH_INTO, sequence, &init))
- {
- g_message ("find ac_init");
- anjuta_token_style_update (project->arg_list, init);
- project->property = amp_property_new (init);
- }
-
- return TRUE;
+ fprintf (stdout, "property list:\n");
+ anjuta_token_dump (list);
+ project->property = amp_property_new (macro, list);
}
-static void
-project_reload_packages (AmpProject *project)
+void
+amp_project_load_module (AmpProject *project, AnjutaToken *module)
{
- AnjutaToken *pkg_check_tok;
- AnjutaToken *sequence;
AmpAcScanner *scanner = NULL;
-
- pkg_check_tok = anjuta_token_new_static (AC_TOKEN_PKG_CHECK_MODULES, "PKG_CHECK_MODULES(");
-
- sequence = anjuta_token_file_first (project->configure_file);
- for (;;)
+
+ if (module != NULL)
{
- AnjutaToken *module;
AnjutaToken *arg;
+ AnjutaToken *list;
+ AnjutaToken *item;
gchar *value;
AmpModule *mod;
AmpPackage *pack;
gchar *compare;
-
- if (!anjuta_token_match (pkg_check_tok, ANJUTA_SEARCH_INTO, sequence, &module)) break;
- arg = anjuta_token_next_child (module); /* Name */
+ fprintf(stdout, "Load module\n");
+ anjuta_token_dump (module);
+
+ /* Module name */
+ arg = anjuta_token_first_item (module);
value = anjuta_token_evaluate (arg);
mod = amp_module_new (arg);
mod->packages = NULL;
g_hash_table_insert (project->modules, value, mod);
- arg = anjuta_token_next_sibling (arg); /* Separator */
-
- arg = anjuta_token_next_sibling (arg); /* Package list */
- if (scanner == NULL) scanner = amp_ac_scanner_new ();
- amp_ac_scanner_parse_token (scanner, arg, AC_SPACE_LIST_STATE, NULL);
+ /* Package list */
+ arg = anjuta_token_next_word (arg);
+ scanner = amp_ac_scanner_new (project);
+ list = amp_ac_scanner_parse_token (scanner, arg, AC_SPACE_LIST_STATE, NULL);
+ anjuta_token_free_children (arg);
+ list = anjuta_token_delete_parent (list);
+ anjuta_token_prepend_items (arg, list);
+ amp_ac_scanner_free (scanner);
pack = NULL;
compare = NULL;
- for (arg = anjuta_token_next_child (arg); arg != NULL; arg = anjuta_token_next_sibling (arg))
+ for (item = anjuta_token_first_word (arg); item != NULL; item = anjuta_token_next_word (item))
{
- switch (anjuta_token_get_type (arg))
+ value = anjuta_token_evaluate (item);
+ if (value == NULL) continue; /* Empty value, a comment of a quote by example */
+ if (*value == '\0')
+ {
+ g_free (value);
+ continue;
+ }
+ if (strcmp (value, "$VTE_NEW_REQUIRED") == 0)
{
- case ANJUTA_TOKEN_START:
- case ANJUTA_TOKEN_NEXT:
- case ANJUTA_TOKEN_LAST:
- case ANJUTA_TOKEN_JUNK:
- continue;
- default:
- break;
+ int i = 0;
+ i++;
+ i++;
}
- value = anjuta_token_evaluate (arg);
- if (value == NULL) continue; /* Empty value, a comment of a quote by example */
-
if ((pack != NULL) && (compare != NULL))
{
amp_package_set_version (pack, compare, value);
@@ -1069,7 +1030,7 @@ project_reload_packages (AmpProject *project)
pack = NULL;
compare = NULL;
}
- else if ((pack != NULL) && (anjuta_token_get_type (arg) == ANJUTA_TOKEN_OPERATOR))
+ else if ((pack != NULL) && (anjuta_token_get_type (item) == ANJUTA_TOKEN_OPERATOR))
{
compare = value;
}
@@ -1082,100 +1043,55 @@ project_reload_packages (AmpProject *project)
}
}
mod->packages = g_list_reverse (mod->packages);
-
- sequence = anjuta_token_next_sibling (module);
}
- anjuta_token_free (pkg_check_tok);
- if (scanner) amp_ac_scanner_free (scanner);
}
-/* Add a GFile in the list for each makefile in the token list */
void
-amp_project_add_config_files (AmpProject *project, AnjutaToken *list)
+amp_project_load_config (AmpProject *project, AnjutaToken *arg_list)
{
- AnjutaToken* arg;
-
- for (arg = anjuta_token_next_child (list); arg != NULL; arg = anjuta_token_next_sibling (arg))
- {
- gchar *value;
- AmpConfigFile *cfg;
-
- switch (anjuta_token_get_type (arg))
- {
- case ANJUTA_TOKEN_START:
- case ANJUTA_TOKEN_NEXT:
- case ANJUTA_TOKEN_LAST:
- case ANJUTA_TOKEN_JUNK:
- continue;
- default:
- break;
- }
-
- value = anjuta_token_evaluate (arg);
- if (value == NULL) continue;
-
- cfg = amp_config_file_new (value, project->root_file, arg);
- g_hash_table_insert (project->configs, cfg->file, cfg);
- g_free (value);
- }
-}
-
-static gboolean
-project_list_config_files (AmpProject *project)
-{
- AnjutaToken *config_files_tok;
- AnjutaToken *sequence;
AmpAcScanner *scanner = NULL;
- //g_message ("load config project %p root file %p", project, project->root_file);
- /* Search the new AC_CONFIG_FILES macro */
- config_files_tok = anjuta_token_new_static (AC_TOKEN_AC_CONFIG_FILES, NULL);
-
- sequence = anjuta_token_file_first (project->configure_file);
- while (sequence != NULL)
+ if (arg_list != NULL)
{
AnjutaToken *arg;
+ AnjutaToken *list;
+ AnjutaToken *item;
- if (!anjuta_token_match (config_files_tok, ANJUTA_SEARCH_INTO, sequence, &sequence)) break;
- arg = anjuta_token_next_child (sequence); /* List */
- if (scanner == NULL) scanner = amp_ac_scanner_new ();
- amp_ac_scanner_parse_token (scanner, arg, AC_SPACE_LIST_STATE, NULL);
- amp_project_add_config_files (project, arg);
- sequence = anjuta_token_next_sibling (sequence);
- }
-
- /* Search the old AC_OUTPUT macro */
- anjuta_token_free(config_files_tok);
- config_files_tok = anjuta_token_new_static (AC_TOKEN_OBSOLETE_AC_OUTPUT, NULL);
+ /* File list */
+ scanner = amp_ac_scanner_new (project);
+ fprintf (stdout, "\nParse list\n");
- sequence = anjuta_token_file_first (project->configure_file);
- while (sequence != NULL)
- {
- AnjutaToken *arg;
+ arg = anjuta_token_first_item (arg_list);
+ list = amp_ac_scanner_parse_token (scanner, arg, AC_SPACE_LIST_STATE, NULL);
+ anjuta_token_free_children (arg);
+ list = anjuta_token_delete_parent (list);
+ anjuta_token_prepend_items (arg, list);
+ amp_ac_scanner_free (scanner);
+
+ for (item = anjuta_token_first_word (arg); item != NULL; item = anjuta_token_next_word (item))
+ {
+ gchar *value;
+ AmpConfigFile *cfg;
- if (!anjuta_token_match (config_files_tok, ANJUTA_SEARCH_INTO, sequence, &sequence)) break;
- arg = anjuta_token_next_child (sequence); /* List */
- if (scanner == NULL) scanner = amp_ac_scanner_new ();
- amp_ac_scanner_parse_token (scanner, arg, AC_SPACE_LIST_STATE, NULL);
- amp_project_add_config_files (project, arg);
- sequence = anjuta_token_next_sibling (sequence);
+ value = anjuta_token_evaluate (item);
+ if (value == NULL) continue;
+
+ cfg = amp_config_file_new (value, project->root_file, item);
+ g_hash_table_insert (project->configs, cfg->file, cfg);
+ g_free (value);
+ }
}
-
- if (scanner) amp_ac_scanner_free (scanner);
- anjuta_token_free (config_files_tok);
-
- return TRUE;
}
static void
-find_target (GNode *node, gpointer data)
+find_target (AnjutaProjectTarget *node, gpointer data)
{
if (AMP_NODE_DATA (node)->type == ANJUTA_PROJECT_TARGET)
{
if (strcmp (AMP_TARGET_DATA (node)->base.name, *(gchar **)data) == 0)
{
/* Find target, return node value in pointer */
- *(GNode **)data = node;
+ *(AnjutaProjectTarget **)data = node;
return;
}
@@ -1183,7 +1099,7 @@ find_target (GNode *node, gpointer data)
}
static void
-find_canonical_target (GNode *node, gpointer data)
+find_canonical_target (AnjutaProjectTarget *node, gpointer data)
{
if (AMP_NODE_DATA (node)->type == ANJUTA_PROJECT_TARGET)
{
@@ -1192,7 +1108,7 @@ find_canonical_target (GNode *node, gpointer data)
if (strcmp (canon_name, *(gchar **)data) == 0)
{
/* Find target, return node value in pointer */
- *(GNode **)data = node;
+ *(AnjutaProjectTarget **)data = node;
g_free (canon_name);
return;
@@ -1202,19 +1118,19 @@ find_canonical_target (GNode *node, gpointer data)
}
static AnjutaToken*
-project_load_target (AmpProject *project, AnjutaToken *start, GNode *parent, GHashTable *orphan_sources)
+project_load_target (AmpProject *project, AnjutaToken *name, AnjutaToken *list, AnjutaProjectGroup *parent, GHashTable *orphan_sources)
{
AnjutaToken *arg;
AnjutaProjectTargetType type = NULL;
gchar *install;
- gchar *name;
+ gchar *value;
gint flags;
AmpTargetInformation *targets = AmpTargetTypes;
type = (AnjutaProjectTargetType)targets;
while (targets->base.name != NULL)
{
- if (anjuta_token_get_type (start) == targets->token)
+ if (anjuta_token_get_type (name) == targets->token)
{
type = (AnjutaProjectTargetType)targets;
break;
@@ -1222,20 +1138,13 @@ project_load_target (AmpProject *project, AnjutaToken *start, GNode *parent, GHa
targets++;
}
- name = anjuta_token_get_value (start);
- split_automake_variable (name, &flags, &install, NULL);
- g_free (name);
+ value = anjuta_token_evaluate (name);
+ split_automake_variable (value, &flags, &install, NULL);
+ g_free (value);
- amp_group_add_token (parent, start, AM_GROUP_TARGET);
+ amp_group_add_token (parent, name, AM_GROUP_TARGET);
- arg = anjuta_token_next_sibling (start); /* Get variable data */
- if (arg == NULL) return NULL;
- if (anjuta_token_get_type (arg) == ANJUTA_TOKEN_SPACE) arg = anjuta_token_next_sibling (arg); /* Skip space */
- if (arg == NULL) return NULL;
- arg = anjuta_token_next_sibling (arg); /* Skip equal */
- if (arg == NULL) return NULL;
-
- for (arg = anjuta_token_next_child (arg); arg != NULL; arg = anjuta_token_next_sibling (arg))
+ for (arg = anjuta_token_first_word (list); arg != NULL; arg = anjuta_token_next_word (arg))
{
gchar *value;
gchar *canon_id;
@@ -1244,14 +1153,12 @@ project_load_target (AmpProject *project, AnjutaToken *start, GNode *parent, GHa
gchar *orig_key;
gpointer find;
- if ((anjuta_token_get_type (arg) == ANJUTA_TOKEN_SPACE) || (anjuta_token_get_type (arg) == ANJUTA_TOKEN_COMMENT)) continue;
-
value = anjuta_token_evaluate (arg);
canon_id = canonicalize_automake_variable (value);
/* Check if target already exists */
find = value;
- g_node_children_foreach (parent, G_TRAVERSE_ALL, find_target, &find);
+ anjuta_project_node_children_foreach (parent, find_target, &find);
if ((gchar *)find != value)
{
/* Find target */
@@ -1263,7 +1170,7 @@ project_load_target (AmpProject *project, AnjutaToken *start, GNode *parent, GHa
/* Create target */
target = amp_target_new (value, type, install, flags);
amp_target_add_token (target, arg);
- g_node_append (parent, target);
+ anjuta_project_node_append (parent, target);
DEBUG_PRINT ("create target %p name %s", target, value);
/* Check if there are source availables */
@@ -1275,7 +1182,7 @@ project_load_target (AmpProject *project, AnjutaToken *start, GNode *parent, GHa
{
AmpSource *source = src->data;
- g_node_prepend (target, source);
+ anjuta_project_node_prepend (target, source);
}
g_free (orig_key);
g_list_free (sources);
@@ -1289,7 +1196,7 @@ project_load_target (AmpProject *project, AnjutaToken *start, GNode *parent, GHa
}
static AnjutaToken*
-project_load_sources (AmpProject *project, AnjutaToken *start, GNode *parent, GHashTable *orphan_sources)
+project_load_sources (AmpProject *project, AnjutaToken *name, AnjutaToken *list, AnjutaProjectGroup *parent, GHashTable *orphan_sources)
{
AnjutaToken *arg;
AmpGroupData *group = AMP_GROUP_DATA (parent);
@@ -1297,7 +1204,7 @@ project_load_sources (AmpProject *project, AnjutaToken *start, GNode *parent, GH
gchar *target_id = NULL;
GList *orphan = NULL;
- target_id = anjuta_token_get_value (start);
+ target_id = anjuta_token_evaluate (name);
if (target_id)
{
gchar *end = strrchr (target_id, '_');
@@ -1313,24 +1220,15 @@ project_load_sources (AmpProject *project, AnjutaToken *start, GNode *parent, GH
find = target_id;
DEBUG_PRINT ("search for canonical %s", target_id);
- g_node_children_foreach (parent, G_TRAVERSE_ALL, find_canonical_target, &find);
- parent = (gchar *)find != target_id ? (GNode *)find : NULL;
-
- arg = anjuta_token_next_sibling (start); /* Get variable data */
- if (arg == NULL) return NULL;
- if (anjuta_token_get_type (arg) == ANJUTA_TOKEN_SPACE) arg = anjuta_token_next_sibling (arg); /* Skip space */
- if (arg == NULL) return NULL;
- arg = anjuta_token_next_sibling (arg); /* Skip equal */
- if (arg == NULL) return NULL;
+ anjuta_project_node_children_foreach (parent, find_canonical_target, &find);
+ parent = (gchar *)find != target_id ? (AnjutaProjectTarget *)find : NULL;
- for (arg = anjuta_token_next_child (arg); arg != NULL; arg = anjuta_token_next_sibling (arg))
+ for (arg = anjuta_token_first_word (list); arg != NULL; arg = anjuta_token_next_word (arg))
{
gchar *value;
AmpSource *source;
GFile *src_file;
- if ((anjuta_token_get_type (arg) == ANJUTA_TOKEN_SPACE) || (anjuta_token_get_type (arg) == ANJUTA_TOKEN_COMMENT)) continue;
-
value = anjuta_token_evaluate (arg);
/* Create source */
@@ -1348,7 +1246,7 @@ project_load_sources (AmpProject *project, AnjutaToken *start, GNode *parent, GH
{
DEBUG_PRINT ("add target child %p", parent);
/* Add as target child */
- g_node_append (parent, source);
+ anjuta_project_node_append (parent, source);
}
g_free (value);
@@ -1381,23 +1279,14 @@ project_load_sources (AmpProject *project, AnjutaToken *start, GNode *parent, GH
static AmpGroup* project_load_makefile (AmpProject *project, GFile *file, AmpGroup *parent, gboolean dist_only);
static void
-project_load_subdirs (AmpProject *project, AnjutaToken *start, AmpGroup *parent, gboolean dist_only)
+project_load_subdirs (AmpProject *project, AnjutaToken *list, AmpGroup *parent, gboolean dist_only)
{
AnjutaToken *arg;
- arg = anjuta_token_next_sibling (start); /* Get variable data */
- if (arg == NULL) return;
- if (anjuta_token_get_type (arg) == ANJUTA_TOKEN_SPACE) arg = anjuta_token_next_sibling (arg); /* Skip space */
- if (arg == NULL) return;
- arg = anjuta_token_next_sibling (arg); /* Skip equal */
- if (arg == NULL) return;
-
- for (arg = anjuta_token_next_child (arg); arg != NULL; arg = anjuta_token_next_sibling (arg))
+ for (arg = anjuta_token_first_word (list); arg != NULL; arg = anjuta_token_next_word (arg))
{
gchar *value;
- if ((anjuta_token_get_type (arg) == ANJUTA_TOKEN_SPACE) || (anjuta_token_get_type (arg) == ANJUTA_TOKEN_COMMENT)) continue;
-
value = anjuta_token_evaluate (arg);
/* Skip ., it is a special case, used to defined build order */
@@ -1432,13 +1321,6 @@ project_load_subdirs (AmpProject *project, AnjutaToken *start, AmpGroup *parent,
}
static void
-free_source_list (GList *source_list)
-{
- g_list_foreach (source_list, (GFunc)amp_source_free, NULL);
- g_list_free (source_list);
-}
-
-static void
remove_config_file (gpointer data, GObject *object, gboolean is_last_ref)
{
if (is_last_ref)
@@ -1449,17 +1331,16 @@ remove_config_file (gpointer data, GObject *object, gboolean is_last_ref)
}
static AmpGroup*
-project_load_makefile (AmpProject *project, GFile *file, GNode *parent, gboolean dist_only)
+project_load_makefile (AmpProject *project, GFile *file, AnjutaProjectGroup *parent, gboolean dist_only)
{
- GHashTable *orphan_sources = NULL;
+ //GHashTable *orphan_sources = NULL;
const gchar **filename;
AmpAmScanner *scanner;
AmpGroup *group;
- AnjutaToken *significant_tok;
+ //AnjutaToken *significant_tok;
AnjutaToken *arg;
AnjutaTokenFile *tfile;
GFile *makefile = NULL;
- gboolean found;
/* Create group */
group = amp_group_new (file, dist_only);
@@ -1470,7 +1351,7 @@ project_load_makefile (AmpProject *project, GFile *file, GNode *parent, gboolean
}
else
{
- g_node_append (parent, group);
+ anjuta_project_node_append (parent, group);
}
/* Find makefile name
@@ -1494,6 +1375,7 @@ project_load_makefile (AmpProject *project, GFile *file, GNode *parent, gboolean
g_object_unref (final_file);
if (config != NULL)
{
+ g_message ("add group =%s= token %p group %p", *filename, config->token, anjuta_token_list (config->token));
amp_group_add_token (group, config->token, AM_GROUP_TOKEN_CONFIGURE);
break;
}
@@ -1509,57 +1391,44 @@ project_load_makefile (AmpProject *project, GFile *file, GNode *parent, gboolean
/* Parse makefile.am */
DEBUG_PRINT ("Parse: %s", g_file_get_uri (makefile));
- tfile = amp_group_set_makefile (group, makefile);
+ tfile = amp_group_set_makefile (group, makefile, project);
g_hash_table_insert (project->files, makefile, tfile);
g_object_add_toggle_ref (G_OBJECT (tfile), remove_config_file, project);
- scanner = amp_am_scanner_new ();
- amp_am_scanner_parse (scanner, tfile, NULL);
- amp_am_scanner_free (scanner);
-
- /* Find significant token */
- significant_tok = anjuta_token_new_static (ANJUTA_TOKEN_STATEMENT, NULL);
- arg = anjuta_token_file_first (AMP_GROUP_DATA (group)->tfile);
- //anjuta_token_old_dump_range (arg, NULL);
+ return group;
+}
- /* Create hash table for sources list */
- orphan_sources = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)g_free, (GDestroyNotify)free_source_list);
-
- for (found = anjuta_token_match (significant_tok, ANJUTA_SEARCH_INTO, arg, &arg); found; found = anjuta_token_match (significant_tok, ANJUTA_SEARCH_INTO, anjuta_token_next_sibling (arg), &arg))
- {
- AnjutaToken *name = anjuta_token_next_child (arg);
-
- switch (anjuta_token_get_type (name))
- {
- case AM_TOKEN_SUBDIRS:
- project_load_subdirs (project, name, group, FALSE);
- break;
- case AM_TOKEN_DIST_SUBDIRS:
- project_load_subdirs (project, name, group, TRUE);
- break;
- case AM_TOKEN__DATA:
- case AM_TOKEN__HEADERS:
- case AM_TOKEN__LIBRARIES:
- case AM_TOKEN__LISP:
- case AM_TOKEN__LTLIBRARIES:
- case AM_TOKEN__MANS:
- case AM_TOKEN__PROGRAMS:
- case AM_TOKEN__PYTHON:
- case AM_TOKEN__JAVA:
- case AM_TOKEN__SCRIPTS:
- case AM_TOKEN__TEXINFOS:
- project_load_target (project, name, group, orphan_sources);
- break;
- case AM_TOKEN__SOURCES:
- project_load_sources (project, name, group, orphan_sources);
- break;
- }
+void
+amp_project_set_am_variable (AmpProject* project, AmpGroup* group, AnjutaTokenType variable, AnjutaToken *name, AnjutaToken *list, GHashTable *orphan_sources)
+{
+
+ switch (variable)
+ {
+ case AM_TOKEN_SUBDIRS:
+ project_load_subdirs (project, list, group, FALSE);
+ break;
+ case AM_TOKEN_DIST_SUBDIRS:
+ project_load_subdirs (project, list, group, TRUE);
+ break;
+ case AM_TOKEN__DATA:
+ case AM_TOKEN__HEADERS:
+ case AM_TOKEN__LIBRARIES:
+ case AM_TOKEN__LISP:
+ case AM_TOKEN__LTLIBRARIES:
+ case AM_TOKEN__MANS:
+ case AM_TOKEN__PROGRAMS:
+ case AM_TOKEN__PYTHON:
+ case AM_TOKEN__JAVA:
+ case AM_TOKEN__SCRIPTS:
+ case AM_TOKEN__TEXINFOS:
+ project_load_target (project, name, list, group, orphan_sources);
+ break;
+ case AM_TOKEN__SOURCES:
+ project_load_sources (project, name, list, group, orphan_sources);
+ break;
+ default:
+ break;
}
-
- /* Free unused sources files */
- g_hash_table_destroy (orphan_sources);
-
- return group;
}
/* Public functions
@@ -1569,9 +1438,10 @@ gboolean
amp_project_reload (AmpProject *project, GError **error)
{
AmpAcScanner *scanner;
+ AnjutaToken *arg;
GFile *root_file;
GFile *configure_file;
- gboolean ok;
+ gboolean ok = TRUE;
GError *err = NULL;
/* Unload current project */
@@ -1583,11 +1453,13 @@ amp_project_reload (AmpProject *project, GError **error)
/* shortcut hash tables */
project->groups = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
project->files = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal, g_object_unref, g_object_unref);
- project->configs = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal, NULL, amp_config_file_free);
+ project->configs = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal, NULL, (GDestroyNotify)amp_config_file_free);
+ amp_project_new_module_hash (project);
/* Initialize list styles */
- project->space_list = anjuta_token_style_new (NULL, " ", "\\n", NULL, 0);
- project->arg_list = anjuta_token_style_new (NULL, ", ", ",\\n ", ")", 0);
+ project->ac_space_list = anjuta_token_style_new (NULL, " ", "\n", NULL, 0);
+ project->am_space_list = anjuta_token_style_new (NULL, " ", " \\\n", NULL, 0);
+ project->arg_list = anjuta_token_style_new (NULL, ", ", ", ", ")", 0);
/* Find configure file */
if (file_type (root_file, "configure.ac") == G_FILE_TYPE_REGULAR)
@@ -1611,10 +1483,18 @@ amp_project_reload (AmpProject *project, GError **error)
project->configure_file = anjuta_token_file_new (configure_file);
g_hash_table_insert (project->files, configure_file, project->configure_file);
g_object_add_toggle_ref (G_OBJECT (project->configure_file), remove_config_file, project);
- scanner = amp_ac_scanner_new ();
- ok = amp_ac_scanner_parse (scanner, project->configure_file, &err);
+ arg = anjuta_token_file_load (project->configure_file, NULL);
+ fprintf (stdout, "AC file before parsing\n");
+ anjuta_token_dump (arg);
+ fprintf (stdout, "\n");
+ scanner = amp_ac_scanner_new (project);
+ project->configure_token = amp_ac_scanner_parse_token (scanner, arg, 0, &err);
+ fprintf (stdout, "AC file after parsing\n");
+ anjuta_token_check (arg);
+ anjuta_token_dump (project->configure_token);
+ fprintf (stdout, "\n");
amp_ac_scanner_free (scanner);
- if (!ok)
+ if (project->configure_token == NULL)
{
g_set_error (error, IANJUTA_PROJECT_ERROR,
IANJUTA_PROJECT_ERROR_PROJECT_MALFORMED,
@@ -1626,13 +1506,7 @@ amp_project_reload (AmpProject *project, GError **error)
monitors_setup (project);
- project_reload_property (project);
-
- amp_project_new_module_hash (project);
- project_reload_packages (project);
-
/* Load all makefiles recursively */
- project_list_config_files (project);
if (project_load_makefile (project, project->root_file, NULL, FALSE) == NULL)
{
g_set_error (error, IANJUTA_PROJECT_ERROR,
@@ -1673,6 +1547,7 @@ amp_project_unload (AmpProject *project)
if (project->configure_file) g_object_unref (G_OBJECT (project->configure_file));
project->configure_file = NULL;
+ if (project->configure_token) anjuta_token_free (project->configure_token);
if (project->root_file) g_object_unref (project->root_file);
project->root_file = NULL;
@@ -1689,7 +1564,8 @@ amp_project_unload (AmpProject *project)
project->configs = NULL;
/* List styles */
- if (project->space_list) anjuta_token_style_free (project->space_list);
+ if (project->am_space_list) anjuta_token_style_free (project->am_space_list);
+ if (project->ac_space_list) anjuta_token_style_free (project->ac_space_list);
if (project->arg_list) anjuta_token_style_free (project->arg_list);
amp_project_free_module_hash (project);
@@ -1736,19 +1612,38 @@ amp_project_probe (GFile *file,
return probe ? IANJUTA_PROJECT_PROBE_PROJECT_FILES : 0;
}
-AmpGroup*
-amp_project_add_group (AmpProject *project,
- AmpGroup *parent,
- const gchar *name,
- GError **error)
+gboolean
+amp_project_get_token_location (AmpProject *project, AnjutaTokenFileLocation *location, AnjutaToken *token)
+{
+ GHashTableIter iter;
+ gpointer key;
+ gpointer value;
+
+ g_hash_table_iter_init (&iter, project->files);
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ {
+ if (anjuta_token_file_get_token_location ((AnjutaTokenFile *)value, location, token))
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+AmpGroup*
+amp_project_add_sibling_group (AmpProject *project,
+ AmpGroup *parent,
+ const gchar *name,
+ gboolean after,
+ AmpGroup *sibling,
+ GError **error)
{
AmpGroup *last;
AmpGroup *child;
GFile *directory;
GFile *makefile;
- AnjutaToken* token;
- AnjutaToken* prev_token;
- GList *token_list;
+ AnjutaToken *list;
gchar *basename;
gchar *uri;
AnjutaTokenFile* tfile;
@@ -1789,18 +1684,34 @@ amp_project_add_group (AmpProject *project,
_("Group already exists"));
return NULL;
}
+
+ /* If a sibling is used, check that the parent is right */
+ if ((sibling != NULL) && (parent != anjuta_project_node_parent (sibling)))
+ {
+ g_free (uri);
+ error_set (error, IANJUTA_PROJECT_ERROR_VALIDATION_FAILED,
+ _("Sibling group has not the same parent"));
+ return NULL;
+ }
/* Add group node in project tree */
child = amp_group_new (directory, FALSE);
g_hash_table_insert (project->groups, uri, child);
g_object_unref (directory);
- g_node_append (parent, child);
+ if (after)
+ {
+ anjuta_project_node_insert_after (parent, sibling, child);
+ }
+ else
+ {
+ anjuta_project_node_insert_before (parent, sibling, child);
+ }
/* Create directory */
g_file_make_directory (directory, NULL, NULL);
/* Create Makefile.am */
- basename = g_file_get_basename (AMP_GROUP_DATA (parent)->makefile);
+ basename = AMP_GROUP_DATA (parent)->makefile != NULL ? g_file_get_basename (AMP_GROUP_DATA (parent)->makefile) : NULL;
if (basename != NULL)
{
makefile = g_file_get_child (directory, basename);
@@ -1811,19 +1722,56 @@ amp_project_add_group (AmpProject *project,
makefile = g_file_get_child (directory, "Makefile.am");
}
g_file_replace_contents (makefile, "", 0, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL, NULL);
- tfile = amp_group_set_makefile (child, makefile);
+ tfile = amp_group_set_makefile (child, makefile, project);
g_hash_table_insert (project->files, makefile, tfile);
g_object_add_toggle_ref (G_OBJECT (tfile), remove_config_file, project);
+ if (sibling == NULL)
+ {
+ /* Find a sibling before */
+ for (last = anjuta_project_node_prev_sibling (child); (last != NULL) && (AMP_NODE_DATA (last)->type != ANJUTA_PROJECT_GROUP); last = anjuta_project_node_prev_sibling (last));
+ if (last != NULL)
+ {
+ sibling = last;
+ after = TRUE;
+ }
+ else
+ {
+ /* Find a sibling after */
+ for (last = anjuta_project_node_next_sibling (child); (last != NULL) && (AMP_NODE_DATA (last)->type != ANJUTA_PROJECT_GROUP); last = anjuta_project_node_next_sibling (last));
+ if (last != NULL)
+ {
+ sibling = last;
+ after = FALSE;
+ }
+ }
+ }
+
/* Add in configure */
- token_list= amp_group_get_token (parent, AM_GROUP_TOKEN_CONFIGURE);
- if (token_list != NULL)
+ list = NULL;
+ if (sibling) list = amp_group_get_first_token (sibling, AM_GROUP_TOKEN_CONFIGURE);
+ if (list == NULL) list= amp_group_get_first_token (parent, AM_GROUP_TOKEN_CONFIGURE);
+ if (list != NULL) list = anjuta_token_list (list);
+ if (list == NULL)
+ {
+ list = amp_project_write_config_list (project);
+ list = anjuta_token_next (list);
+ }
+ if (list != NULL)
{
gchar *relative_make;
gchar *ext;
- AnjutaTokenStyle *style;
-
- prev_token = (AnjutaToken *)token_list->data;
+ AnjutaToken *prev = NULL;
+
+ if (sibling)
+ {
+ prev = amp_group_get_first_token (sibling, AM_GROUP_TOKEN_CONFIGURE);
+ /*if ((prev != NULL) && after)
+ {
+ prev = anjuta_token_next_word (prev);
+ }*/
+ }
+ //prev_token = (AnjutaToken *)token_list->data;
relative_make = g_file_get_relative_path (project->root_file, makefile);
ext = relative_make + strlen (relative_make) - 3;
@@ -1831,89 +1779,85 @@ amp_project_add_group (AmpProject *project,
{
*ext = '\0';
}
- token = anjuta_token_new_string (ANJUTA_TOKEN_NAME | ANJUTA_TOKEN_ADDED, relative_make);
+ //token = anjuta_token_new_string (ANJUTA_TOKEN_NAME | ANJUTA_TOKEN_ADDED, relative_make);
+ amp_project_write_config_file (project, list, after, prev, relative_make);
g_free (relative_make);
- style = anjuta_token_style_new (NULL," ","\\n",NULL,0);
- add_list_item (prev_token, token, style);
- anjuta_token_style_free (style);
+ //style = anjuta_token_style_new (NULL," ","\n",NULL,0);
+ //anjuta_token_add_word (prev_token, token, style);
+ //anjuta_token_style_free (style);
}
/* Add in Makefile.am */
- for (last = g_node_prev_sibling (child); (last != NULL) && (AMP_NODE_DATA (last)->type != ANJUTA_PROJECT_GROUP); last = g_node_prev_sibling (last));
- if (last == NULL)
+ if (sibling == NULL)
{
- AnjutaToken *prev_token;
- gint space = 0;
- AnjutaToken *list;
-
- /* Skip comment and one space at the beginning */
- for (prev_token = anjuta_token_next_child (anjuta_token_file_first (AMP_GROUP_DATA (parent)->tfile)); prev_token != NULL; prev_token = anjuta_token_next_sibling (prev_token))
+ AnjutaToken *pos;
+ static gint eol_type[] = {ANJUTA_TOKEN_EOL, ANJUTA_TOKEN_SPACE, ANJUTA_TOKEN_COMMENT, 0};
+
+ pos = anjuta_token_find_type (AMP_GROUP_DATA (parent)->make_token, ANJUTA_TOKEN_SEARCH_NOT, eol_type);
+ if (pos == NULL)
{
- switch (anjuta_token_get_type (prev_token))
- {
- case ANJUTA_TOKEN_COMMENT:
- space = 0;
- continue;
- case ANJUTA_TOKEN_SPACE:
- if (space == 0)
- {
- space = 1;
- continue;
- }
- break;
- default:
- break;
- }
- break;
+ pos = anjuta_token_prepend_child (AMP_GROUP_DATA (parent)->make_token, anjuta_token_new_static (ANJUTA_TOKEN_SPACE, "\n"));
}
- if (prev_token == NULL)
- {
- prev_token = anjuta_token_next_child (anjuta_token_file_first (AMP_GROUP_DATA (parent)->tfile));
- if (prev_token)
- {
- prev_token = anjuta_token_file_last (AMP_GROUP_DATA (parent)->tfile);
- }
- }
+ list = anjuta_token_insert_token_list (FALSE, pos,
+ ANJUTA_TOKEN_SPACE, "\n");
+ list = anjuta_token_insert_token_list (FALSE, list,
+ AM_TOKEN_SUBDIRS, "SUBDIRS",
+ ANJUTA_TOKEN_SPACE, " ",
+ ANJUTA_TOKEN_OPERATOR, "=",
+ ANJUTA_TOKEN_LIST, NULL,
+ ANJUTA_TOKEN_LAST, NULL,
+ NULL);
+ list = anjuta_token_next (anjuta_token_next ( anjuta_token_next (list)));
+ }
+ else
+ {
+ AnjutaToken *prev;
+
+ prev = amp_group_get_first_token (sibling, AM_GROUP_TOKEN_SUBDIRS);
+ list = anjuta_token_list (prev);
+ }
+
+ if (list != NULL)
+ {
+ AnjutaToken *token;
+ AnjutaToken *prev;
- token = anjuta_token_new_static (ANJUTA_TOKEN_STATEMENT | ANJUTA_TOKEN_ADDED, NULL);
- if (prev_token == NULL)
+ if (sibling)
+ {
+ prev = amp_group_get_first_token (sibling, AM_GROUP_TOKEN_SUBDIRS);
+ }
+
+ token = anjuta_token_new_string (ANJUTA_TOKEN_NAME | ANJUTA_TOKEN_ADDED, name);
+ if (after)
{
- prev_token = anjuta_token_insert_child (anjuta_token_file_first (AMP_GROUP_DATA (parent)->tfile), token);
+ anjuta_token_insert_word_after (list, prev, token);
}
else
{
- prev_token = anjuta_token_insert_after (prev_token, token);
+ anjuta_token_insert_word_before (list, prev, token);
}
- list = prev_token;
- prev_token = anjuta_token_insert_after (prev_token, anjuta_token_new_string (AM_TOKEN_SUBDIRS | ANJUTA_TOKEN_ADDED, "SUBDIRS"));
- prev_token = anjuta_token_insert_after (prev_token, anjuta_token_new_string (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, " "));
- prev_token = anjuta_token_insert_after (prev_token, anjuta_token_new_string (ANJUTA_TOKEN_OPERATOR | ANJUTA_TOKEN_ADDED, "="));
- prev_token = anjuta_token_insert_after (prev_token, anjuta_token_new_static (ANJUTA_TOKEN_LIST, NULL));
- token = prev_token;
- prev_token = anjuta_token_insert_after (prev_token, anjuta_token_new_string (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, " "));
- prev_token = anjuta_token_insert_after (prev_token, anjuta_token_new_string (ANJUTA_TOKEN_NAME | ANJUTA_TOKEN_ADDED, name));
- anjuta_token_merge (token, prev_token);
- prev_token = anjuta_token_insert_after (prev_token, anjuta_token_new_string (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, "\n"));
- anjuta_token_merge (list, prev_token);
- }
- else
- {
- token_list = amp_group_get_token (parent, AM_GROUP_TOKEN_SUBDIRS);
- if (token_list != NULL)
- {
- prev_token = (AnjutaToken *)token_list->data;
+
+ anjuta_token_style_format (project->am_space_list, list);
+ anjuta_token_file_update (AMP_GROUP_DATA (parent)->tfile, token);
- token = anjuta_token_new_string (ANJUTA_TOKEN_NAME | ANJUTA_TOKEN_ADDED, name);
- add_list_item (prev_token, token, NULL);
- }
+ amp_group_add_token (child, token, AM_GROUP_TOKEN_SUBDIRS);
}
- amp_group_add_token (child, token, AM_GROUP_TOKEN_SUBDIRS);
return child;
}
+
+AmpGroup*
+amp_project_add_group (AmpProject *project,
+ AmpGroup *parent,
+ const gchar *name,
+ GError **error)
+{
+ return amp_project_add_sibling_group (project, parent, name, TRUE, NULL, error);
+}
+
void
amp_project_remove_group (AmpProject *project,
AmpGroup *group,
@@ -1925,31 +1869,28 @@ amp_project_remove_group (AmpProject *project,
for (token_list = amp_group_get_token (group, AM_GROUP_TOKEN_CONFIGURE); token_list != NULL; token_list = g_list_next (token_list))
{
- remove_list_item ((AnjutaToken *)token_list->data, NULL);
+ anjuta_token_remove_word ((AnjutaToken *)token_list->data, NULL);
}
for (token_list = amp_group_get_token (group, AM_GROUP_TOKEN_SUBDIRS); token_list != NULL; token_list = g_list_next (token_list))
{
- remove_list_item ((AnjutaToken *)token_list->data, NULL);
+ anjuta_token_remove_word ((AnjutaToken *)token_list->data, NULL);
}
for (token_list = amp_group_get_token (group, AM_GROUP_TOKEN_DIST_SUBDIRS); token_list != NULL; token_list = g_list_next (token_list))
{
- remove_list_item ((AnjutaToken *)token_list->data, NULL);
+ anjuta_token_remove_word ((AnjutaToken *)token_list->data, NULL);
}
amp_group_free (group);
}
-AmpTarget*
-amp_project_add_target (AmpProject *project,
- AmpGroup *parent,
- const gchar *name,
- AnjutaProjectTargetType type,
- GError **error)
+AmpTarget*
+amp_project_add_sibling_target (AmpProject *project, AmpGroup *parent, const gchar *name, AnjutaProjectTargetType type, gboolean after, AmpTarget *sibling, GError **error)
{
AmpTarget *child;
AnjutaToken* token;
- AnjutaToken* prev_token;
- AnjutaToken *list;
+ AnjutaToken *args;
+ AnjutaToken *var;
+ AnjutaToken *prev;
gchar *targetname;
gchar *find;
GList *last;
@@ -1997,10 +1938,18 @@ amp_project_add_target (AmpProject *project,
return NULL;
}
}
+
+ /* If a sibling is used, check that the parent is right */
+ if ((sibling != NULL) && (parent != anjuta_project_node_parent (sibling)))
+ {
+ error_set (error, IANJUTA_PROJECT_ERROR_VALIDATION_FAILED,
+ _("Sibling target has not the same parent"));
+ return NULL;
+ }
/* Check that the new target doesn't already exist */
find = (gchar *)name;
- g_node_children_foreach (parent, G_TRAVERSE_ALL, find_target, &find);
+ anjuta_project_node_children_foreach (parent, find_target, &find);
if ((gchar *)find != name)
{
error_set (error, IANJUTA_PROJECT_ERROR_DOESNT_EXIST,
@@ -2011,87 +1960,110 @@ amp_project_add_target (AmpProject *project,
/* Add target node in project tree */
child = amp_target_new (name, type, "", 0);
- g_node_append (parent, child);
+ if (after)
+ {
+ anjuta_project_node_insert_after (parent, sibling, child);
+ }
+ else
+ {
+ anjuta_project_node_insert_before (parent, sibling, child);
+ }
+ //anjuta_project_node_append (parent, child);
/* Add in Makefile.am */
targetname = g_strconcat (((AmpTargetInformation *)type)->install, ((AmpTargetInformation *)type)->prefix, NULL);
- for (last = amp_group_get_token (parent, AM_GROUP_TARGET); last != NULL; last = g_list_next (last))
+ // Get token corresponding to sibling and check if the target are compatible
+ args = NULL;
+ var = NULL;
+ if (sibling != NULL)
{
- gchar *value = anjuta_token_evaluate ((AnjutaToken *)last->data);
-
- if ((value != NULL) && (strcmp (targetname, value) == 0))
+ last = amp_target_get_token (sibling);
+
+ if (last != NULL)
{
- g_free (value);
- break;
+ AnjutaToken *token = (AnjutaToken *)last->data;
+
+ token = anjuta_token_list (token);
+ if (token != NULL)
+ {
+ token = anjuta_token_list (token);
+ var = token;
+ if (token != NULL)
+ {
+ token = anjuta_token_first_item (token);
+ if (token != NULL)
+ {
+ gchar *value;
+
+ value = anjuta_token_evaluate (token);
+
+ if ((value != NULL) && (strcmp (targetname, value) == 0))
+ {
+ g_free (value);
+ prev = (AnjutaToken *)last->data;
+ args = anjuta_token_last_item (anjuta_token_list (prev));
+ }
+ }
+ }
+ }
}
- g_free (value);
}
- token = anjuta_token_new_string (((AmpTargetInformation *)type)->token, targetname);
- g_free (targetname);
-
- if (last == NULL)
+ if (args == NULL)
{
- prev_token = anjuta_token_next_child (anjuta_token_file_first (AMP_GROUP_DATA (parent)->tfile));
- if (prev_token != NULL)
+ for (last = amp_group_get_token (parent, AM_GROUP_TARGET); last != NULL; last = g_list_next (last))
{
- /* Add at the end of the file */
- while (anjuta_token_next_sibling (prev_token) != NULL)
+ gchar *value = anjuta_token_evaluate ((AnjutaToken *)last->data);
+
+ if ((value != NULL) && (strcmp (targetname, value) == 0))
{
- prev_token = anjuta_token_next_sibling (prev_token);
+ g_free (value);
+ args = anjuta_token_last_item (anjuta_token_list ((AnjutaToken *)last->data));
+ break;
}
+ g_free (value);
}
+ }
- list = anjuta_token_new_string (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, "\n");
- if (prev_token == NULL)
- {
- prev_token = anjuta_token_insert_child (anjuta_token_file_first (AMP_GROUP_DATA (parent)->tfile), list);
- }
- else
- {
- prev_token = anjuta_token_insert_after (prev_token, list);
- }
- prev_token = anjuta_token_insert_after (prev_token, anjuta_token_new_static (ANJUTA_TOKEN_STATEMENT | ANJUTA_TOKEN_ADDED, NULL));
- list = prev_token;
- prev_token = anjuta_token_insert_after (prev_token, token);
- prev_token = anjuta_token_insert_after (prev_token, anjuta_token_new_string (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, " "));
- prev_token = anjuta_token_insert_after (prev_token, anjuta_token_new_string (ANJUTA_TOKEN_OPERATOR | ANJUTA_TOKEN_ADDED, "="));
- prev_token = anjuta_token_insert_after (prev_token, anjuta_token_new_static (ANJUTA_TOKEN_LIST, NULL));
- token = prev_token;
- prev_token = anjuta_token_insert_after (prev_token, anjuta_token_new_string (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, " "));
- anjuta_token_merge (token, prev_token);
- anjuta_token_merge (list, token);
- anjuta_token_insert_after (token, anjuta_token_new_string (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, "\n"));
- token = prev_token;
+ if (args == NULL)
+ {
+ args = amp_project_write_target (AMP_GROUP_DATA (parent)->make_token, ((AmpTargetInformation *)type)->token, targetname, after, var);
}
- else
+ g_free (targetname);
+
+ if (args != NULL)
{
- for (token = (AnjutaToken *)last->data; anjuta_token_get_type (token) != ANJUTA_TOKEN_LIST; token = anjuta_token_next_sibling (token));
-
- if (anjuta_token_next_child (token) == NULL)
+ token = anjuta_token_new_string (ANJUTA_TOKEN_NAME | ANJUTA_TOKEN_ADDED, name);
+ if (after)
{
- token = anjuta_token_insert_child (token, anjuta_token_new_static (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, " "));
+ anjuta_token_insert_word_after (args, prev, token);
}
else
{
- token = anjuta_token_next_child (token);
+ anjuta_token_insert_word_before (args, prev, token);
}
-
- for (; anjuta_token_next_sibling (token) != NULL; token = anjuta_token_next_sibling (token));
- }
-
- if (anjuta_token_get_type (token) != ANJUTA_TOKEN_SPACE)
- {
- token = anjuta_token_insert_after (token, anjuta_token_new_static (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, " "));
+
+ anjuta_token_style_format (project->am_space_list, args);
+ anjuta_token_file_update (AMP_GROUP_DATA (parent)->tfile, token);
+
+ amp_target_add_token (child, token);
}
- token = anjuta_token_insert_after (token, anjuta_token_new_string (ANJUTA_TOKEN_NAME | ANJUTA_TOKEN_ADDED, name));
- amp_target_add_token (child, token);
return child;
}
+AmpTarget*
+amp_project_add_target (AmpProject *project,
+ AmpGroup *parent,
+ const gchar *name,
+ AnjutaProjectTargetType type,
+ GError **error)
+{
+ return amp_project_add_sibling_target (project, parent, name, type, TRUE, NULL, error);
+}
+
void
amp_project_remove_target (AmpProject *project,
AmpTarget *target,
@@ -2103,82 +2075,112 @@ amp_project_remove_target (AmpProject *project,
for (token_list = amp_target_get_token (target); token_list != NULL; token_list = g_list_next (token_list))
{
- anjuta_token_remove ((AnjutaToken *)token_list->data);
+ anjuta_token_remove_word ((AnjutaToken *)token_list->data, NULL);
}
amp_target_free (target);
}
AmpSource*
-amp_project_add_source (AmpProject *project,
- AmpTarget *target,
- GFile *file,
- GError **error)
+amp_project_add_sibling_source (AmpProject *project, AmpTarget *target, GFile *file, gboolean after, AmpSource *sibling, GError **error)
{
AmpGroup *group;
- AmpSource *last;
AmpSource *source;
- AnjutaToken* token;
+ AnjutaToken *token;
+ AnjutaToken *prev;
+ AnjutaToken *args;
gchar *relative_name;
g_return_val_if_fail (file != NULL, NULL);
g_return_val_if_fail (target != NULL, NULL);
-
- if (AMP_NODE_DATA (target)->type != ANJUTA_PROJECT_TARGET) return NULL;
+ if (AMP_NODE_DATA (target)->type != ANJUTA_PROJECT_TARGET) return NULL;
+
group = (AmpGroup *)(target->parent);
relative_name = g_file_get_relative_path (AMP_GROUP_DATA (group)->base.directory, file);
- /* Add token */
- last = g_node_last_child (target);
- if (last == NULL)
+ /* Add in Makefile.am */
+
+ // Get token corresponding to sibling and check if the target are compatible
+ prev = NULL;
+ args = NULL;
+ if (sibling != NULL)
+ {
+ prev = AMP_SOURCE_DATA (sibling)->token;
+ args = anjuta_token_list (prev);
+ }
+
+ if (args == NULL)
{
- /* First child */
- AnjutaToken *tok;
- AnjutaToken *close_tok;
- AnjutaToken *eol_tok;
gchar *target_var;
gchar *canon_name;
-
- /* Search where the target is declared */
- tok = (AnjutaToken *)amp_target_get_token (target)->data;
- close_tok = anjuta_token_new_static (ANJUTA_TOKEN_CLOSE, NULL);
- eol_tok = anjuta_token_new_static (ANJUTA_TOKEN_EOL, NULL);
- //anjuta_token_match (close_tok, ANJUTA_SEARCH_OVER, tok, &tok);
- anjuta_token_match (eol_tok, ANJUTA_SEARCH_OVER, tok, &tok);
- anjuta_token_free (close_tok);
- anjuta_token_free (eol_tok);
-
- /* Add a _SOURCES variable just after */
+ AnjutaToken *var;
+ GList *list;
+
canon_name = canonicalize_automake_variable (AMP_TARGET_DATA (target)->base.name);
target_var = g_strconcat (canon_name, "_SOURCES", NULL);
- g_free (canon_name);
- tok = anjuta_token_insert_after (tok, anjuta_token_new_string (ANJUTA_TOKEN_NAME | ANJUTA_TOKEN_ADDED, target_var));
+
+ /* Search where the target is declared */
+ var = NULL;
+ list = amp_target_get_token (target);
+ if (list != NULL)
+ {
+ var = (AnjutaToken *)list->data;
+ if (var != NULL)
+ {
+ var = anjuta_token_list (var);
+ if (var != NULL)
+ {
+ var = anjuta_token_list (var);
+ }
+ }
+ }
+
+ args = amp_project_write_source_list (AMP_GROUP_DATA (group)->make_token, target_var, after, var);
g_free (target_var);
- tok = anjuta_token_insert_after (tok, anjuta_token_new_static (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, " "));
- tok = anjuta_token_insert_after (tok, anjuta_token_new_static (ANJUTA_TOKEN_OPERATOR | ANJUTA_TOKEN_ADDED, "="));
- tok = anjuta_token_insert_after (tok, anjuta_token_new_static (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, " "));
- token = anjuta_token_new_static (ANJUTA_TOKEN_SPACE | ANJUTA_TOKEN_ADDED, " ");
- tok = anjuta_token_insert_after (tok, token);
- token = anjuta_token_new_string (ANJUTA_TOKEN_NAME | ANJUTA_TOKEN_ADDED, relative_name);
- tok = anjuta_token_insert_after (tok, token);
- tok = anjuta_token_insert_after (tok, anjuta_token_new_static (ANJUTA_TOKEN_EOL | ANJUTA_TOKEN_ADDED, "\n"));
}
- else
+
+ if (args != NULL)
{
token = anjuta_token_new_string (ANJUTA_TOKEN_NAME | ANJUTA_TOKEN_ADDED, relative_name);
- add_list_item (AMP_SOURCE_DATA (last)->token, token, NULL);
- }
- g_free (relative_name);
+ if (after)
+ {
+ anjuta_token_insert_word_after (args, prev, token);
+ }
+ else
+ {
+ anjuta_token_insert_word_before (args, prev, token);
+ }
+ anjuta_token_style_format (project->am_space_list, args);
+ anjuta_token_file_update (AMP_GROUP_DATA (group)->tfile, token);
+ }
+
/* Add source node in project tree */
source = amp_source_new (file);
AMP_SOURCE_DATA(source)->token = token;
- g_node_append (target, source);
+ if (after)
+ {
+ anjuta_project_node_insert_after (target, sibling, source);
+ }
+ else
+ {
+ anjuta_project_node_insert_before (target, sibling, source);
+ }
return source;
}
+
+AmpSource*
+amp_project_add_source (AmpProject *project,
+ AmpTarget *target,
+ GFile *file,
+ GError **error)
+{
+ return amp_project_add_sibling_source (project, target, file, TRUE, NULL, error);
+}
+
void
amp_project_remove_source (AmpProject *project,
AmpSource *source,
@@ -2187,7 +2189,7 @@ amp_project_remove_source (AmpProject *project,
amp_dump_node (source);
if (AMP_NODE_DATA (source)->type != ANJUTA_PROJECT_SOURCE) return;
- remove_list_item (AMP_SOURCE_DATA (source)->token, NULL);
+ anjuta_token_remove_word (AMP_SOURCE_DATA (source)->token, NULL);
amp_source_free (source);
}
@@ -2267,10 +2269,45 @@ amp_project_save (AmpProject *project, GError **error)
return TRUE;
}
+typedef struct _AmpMovePacket {
+ AmpProject *project;
+ GFile *old_root_file;
+} AmpMovePacket;
+
+static void
+foreach_node_move (AnjutaProjectNode *g_node, gpointer data)
+{
+ AmpProject *project = ((AmpMovePacket *)data)->project;
+ const gchar *old_root_file = ((AmpMovePacket *)data)->old_root_file;
+ GFile *relative;
+ GFile *new_file;
+
+ switch (AMP_NODE_DATA (g_node)->type)
+ {
+ case ANJUTA_PROJECT_GROUP:
+ relative = get_relative_path (old_root_file, AMP_GROUP_DATA (g_node)->base.directory);
+ new_file = g_file_resolve_relative_path (project->root_file, relative);
+ g_free (relative);
+ g_object_unref (AMP_GROUP_DATA (g_node)->base.directory);
+ AMP_GROUP_DATA (g_node)->base.directory = 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);
+ new_file = g_file_resolve_relative_path (project->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;
+ break;
+ default:
+ break;
+ }
+}
+
gboolean
amp_project_move (AmpProject *project, const gchar *path)
{
- GFile *old_root_file;
GFile *new_file;
gchar *relative;
GHashTableIter iter;
@@ -2279,27 +2316,16 @@ amp_project_move (AmpProject *project, const gchar *path)
AnjutaTokenFile *tfile;
AmpConfigFile *cfg;
GHashTable* old_hash;
+ AmpMovePacket packet= {project, NULL};
/* Change project root directory */
- old_root_file = project->root_file;
+ packet.old_root_file = project->root_file;
project->root_file = g_file_new_for_path (path);
/* Change project root directory in groups */
old_hash = project->groups;
project->groups = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
- g_hash_table_iter_init (&iter, old_hash);
- while (g_hash_table_iter_next (&iter, &key, &value))
- {
- AmpGroup *group = (AmpGroup *)value;
-
- relative = get_relative_path (old_root_file, AMP_GROUP_DATA (group)->base.directory);
- new_file = g_file_resolve_relative_path (project->root_file, relative);
- g_free (relative);
- g_object_unref (AMP_GROUP_DATA (group)->base.directory);
- AMP_GROUP_DATA (group)->base.directory = new_file;
-
- g_hash_table_insert (project->groups, g_file_get_uri (new_file), group);
- }
+ anjuta_project_node_all_foreach (project->root_node, foreach_node_move, &packet);
g_hash_table_destroy (old_hash);
/* Change all files */
@@ -2308,7 +2334,7 @@ amp_project_move (AmpProject *project, const gchar *path)
g_hash_table_iter_init (&iter, old_hash);
while (g_hash_table_iter_next (&iter, &key, (gpointer *)&tfile))
{
- relative = get_relative_path (old_root_file, anjuta_token_file_get_file (tfile));
+ relative = get_relative_path (packet.old_root_file, anjuta_token_file_get_file (tfile));
new_file = g_file_resolve_relative_path (project->root_file, relative);
g_free (relative);
anjuta_token_file_move (tfile, new_file);
@@ -2321,11 +2347,11 @@ amp_project_move (AmpProject *project, const gchar *path)
/* Change all configs */
old_hash = project->configs;
- project->configs = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal, NULL, amp_config_file_free);
+ project->configs = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal, NULL, (GDestroyNotify)amp_config_file_free);
g_hash_table_iter_init (&iter, old_hash);
while (g_hash_table_iter_next (&iter, &key, (gpointer *)&cfg))
{
- relative = get_relative_path (old_root_file, cfg->file);
+ relative = get_relative_path (packet.old_root_file, cfg->file);
new_file = g_file_resolve_relative_path (project->root_file, relative);
g_free (relative);
g_object_unref (cfg->file);
@@ -2337,7 +2363,7 @@ amp_project_move (AmpProject *project, const gchar *path)
g_hash_table_destroy (old_hash);
- g_object_unref (old_root_file);
+ g_object_unref (packet.old_root_file);
return TRUE;
}
@@ -2403,7 +2429,7 @@ amp_project_get_source (AmpProject *project, const gchar *id)
gchar *
amp_project_get_node_id (AmpProject *project, const gchar *path)
{
- GNode *node = NULL;
+ AnjutaProjectNode *node = NULL;
if (path != NULL)
{
@@ -2424,7 +2450,7 @@ amp_project_get_node_id (AmpProject *project, const gchar *path)
}
else
{
- node = g_node_nth_child (node, child);
+ node = anjuta_project_node_nth_child (node, child);
}
if (node == NULL)
{
@@ -2499,30 +2525,30 @@ amp_project_get_property (AmpProject *project, AmpPropertyType type)
gboolean
amp_project_set_property (AmpProject *project, AmpPropertyType type, const gchar *value)
{
- if (project->property != NULL)
+ if (project->property == NULL)
{
- switch (type)
- {
- case AMP_PROPERTY_NAME:
- project->property->name = g_strdup (value);
- break;
- case AMP_PROPERTY_VERSION:
- project->property->version = g_strdup (value);
- break;
- case AMP_PROPERTY_BUG_REPORT:
- project->property->bug_report = g_strdup (value);
- break;
- case AMP_PROPERTY_TARNAME:
- project->property->tarname = g_strdup (value);
- break;
- case AMP_PROPERTY_URL:
- project->property->url = g_strdup (value);
- break;
- }
- return amp_project_update_property (project, type);
+ project->property = amp_property_new (NULL, NULL);
+ }
+ switch (type)
+ {
+ case AMP_PROPERTY_NAME:
+ STR_REPLACE (project->property->name, value);
+ break;
+ case AMP_PROPERTY_VERSION:
+ STR_REPLACE (project->property->version, value);
+ break;
+ case AMP_PROPERTY_BUG_REPORT:
+ STR_REPLACE (project->property->bug_report, value);
+ break;
+ case AMP_PROPERTY_TARNAME:
+ STR_REPLACE (project->property->tarname, value);
+ break;
+ case AMP_PROPERTY_URL:
+ STR_REPLACE (project->property->url, value);
+ break;
}
- return TRUE;
+ return amp_project_update_property (project, type);
}
/* Implement IAnjutaProject
@@ -2713,10 +2739,12 @@ amp_project_instance_init (AmpProject *project)
/* project data */
project->root_file = NULL;
project->configure_file = NULL;
+ project->configure_token = NULL;
project->root_node = NULL;
project->property = NULL;
- project->space_list = NULL;
+ project->am_space_list = NULL;
+ project->ac_space_list = NULL;
project->arg_list = NULL;
}
diff --git a/plugins/am-project/am-project.h b/plugins/am-project/am-project.h
index 9298272..cd56897 100644
--- a/plugins/am-project/am-project.h
+++ b/plugins/am-project/am-project.h
@@ -27,7 +27,7 @@
#include <libanjuta/anjuta-project.h>
#include <libanjuta/anjuta-token.h>
#include <libanjuta/anjuta-token-file.h>
-#include <libanjuta/anjuta-token-style.h>
+#include <libanjuta/anjuta-token-list.h>
G_BEGIN_DECLS
@@ -71,11 +71,16 @@ gboolean amp_project_load (AmpProject *project, GFile *directory, GError **error
gboolean amp_project_reload (AmpProject *project, GError **error);
void amp_project_unload (AmpProject *project);
+void amp_project_load_config (AmpProject *project, AnjutaToken *arg_list);
+void amp_project_load_properties (AmpProject *project, AnjutaToken *macro, AnjutaToken *list);
+void amp_project_load_module (AmpProject *project, AnjutaToken *module);
+
+
AmpGroup *amp_project_get_root (AmpProject *project);
AmpGroup *amp_project_get_group (AmpProject *project, const gchar *id);
AmpTarget *amp_project_get_target (AmpProject *project, const gchar *id);
AmpSource *amp_project_get_source (AmpProject *project, const gchar *id);
-
+gboolean amp_project_get_token_location (AmpProject *project, AnjutaTokenFileLocation *location, AnjutaToken *token);
gboolean amp_project_move (AmpProject *project, const gchar *path);
gboolean amp_project_save (AmpProject *project, GError **error);
@@ -84,12 +89,15 @@ gchar * amp_project_get_uri (AmpProject *project);
GFile* amp_project_get_file (AmpProject *project);
AmpGroup* amp_project_add_group (AmpProject *project, AmpGroup *parent, const gchar *name, GError **error);
+AmpGroup* amp_project_add_sibling_group (AmpProject *project, AmpGroup *parent, const gchar *name, gboolean after, AmpGroup *sibling, GError **error);
void amp_project_remove_group (AmpProject *project, AmpGroup *group, GError **error);
AmpTarget* amp_project_add_target (AmpProject *project, AmpGroup *parent, const gchar *name, AnjutaProjectTargetType type, GError **error);
+AmpTarget* amp_project_add_sibling_target (AmpProject *project, AmpGroup *parent, const gchar *name, AnjutaProjectTargetType type, gboolean after, AmpTarget *sibling, GError **error);
void amp_project_remove_target (AmpProject *project, AmpTarget *target, GError **error);
AmpSource* amp_project_add_source (AmpProject *project, AmpTarget *parent, GFile *file, GError **error);
+AmpSource* amp_project_add_sibling_source (AmpProject *project, AmpTarget *parent, GFile *file, gboolean after, AmpSource *sibling, GError **error);
void amp_project_remove_source (AmpProject *project, AmpSource *source, GError **error);
@@ -119,6 +127,7 @@ const gchar *amp_target_get_name (AmpTarget *target);
AnjutaProjectTargetType amp_target_get_type (AmpTarget *target);
gchar *amp_target_get_id (AmpTarget *target);
+void amp_source_free (AmpSource *node);
gchar *amp_source_get_id (AmpSource *source);
GFile *amp_source_get_file (AmpSource *source);
diff --git a/plugins/am-project/am-scanner.h b/plugins/am-project/am-scanner.h
index 70a8a4a..55640a5 100644
--- a/plugins/am-project/am-scanner.h
+++ b/plugins/am-project/am-scanner.h
@@ -20,6 +20,8 @@
#ifndef _AM_SCANNER_H_
#define _AM_SCANNER_H_
+#include "am-project.h"
+
#include "libanjuta/anjuta-token.h"
#include "libanjuta/anjuta-token-file.h"
@@ -28,14 +30,20 @@
G_BEGIN_DECLS
+//#define YYSTYPE AnjutaToken*
+#define YYLTYPE AnjutaToken*
+#define YYSTYPE AnjutaToken*
+
typedef struct _AmpAmScanner AmpAmScanner;
-AmpAmScanner *amp_am_scanner_new (void);
+AmpAmScanner *amp_am_scanner_new (AmpProject *project, AmpGroup *group);
void amp_am_scanner_free (AmpAmScanner *scanner);
-gboolean amp_am_scanner_parse (AmpAmScanner *scanner, AnjutaTokenFile *file, GError **error);
+AnjutaToken *amp_am_scanner_parse_token (AmpAmScanner *scanner, AnjutaToken *token, GError **error);
+
+void amp_am_scanner_set_am_variable (AmpAmScanner *scanner, AnjutaTokenType variable, AnjutaToken *name, AnjutaToken *list);
-const gchar* amp_am_scanner_get_filename (AmpAmScanner *scanner);
+void amp_am_yyerror (YYLTYPE *loc, AmpAmScanner *scanner, char const *s);
typedef enum
{
diff --git a/plugins/am-project/am-scanner.l b/plugins/am-project/am-scanner.l
index fe574c4..4f18edd 100644
--- a/plugins/am-project/am-scanner.l
+++ b/plugins/am-project/am-scanner.l
@@ -19,42 +19,48 @@
%{
-#include <stdlib.h>
-#include <string.h>
#include "am-scanner.h"
#include "am-parser.h"
#include "libanjuta/anjuta-debug.h"
+#include "libanjuta/anjuta-token-stream.h"
+#include <stdlib.h>
+#include <string.h>
-/* Eliminate warning */
-#define YY_NO_UNPUT 1
-#define YY_INPUT(buf,result,the_max_size) \
- result = 0;
+#define YY_INPUT(buffer, result, max_size) result = anjuta_token_stream_read (yyextra->stream, buffer, max_size)
-#define YY_USER_ACTION amp_update_location(yylloc, yytext, yyleng);
-
#define YY_EXTRA_TYPE AmpAmScanner*
+#define YY_DECL static int am_yylex (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner)
+
//#define YY_USER_INIT {yy_flex_debug = 1;}
-
-static AnjutaToken* amp_am_scanner_append_token (AmpAmScanner *scanner, gint token);
-static gint amp_am_scanner_last_token (AmpAmScanner *scanner);
-static gint amp_am_scanner_last_flags (AmpAmScanner *scanner);
-static void amp_am_scanner_update_line_width (AmpAmScanner *scanner, YYLTYPE *loc);
-static void amp_update_location (YYLTYPE *loc, const gchar *text, gint length);
-static int amp_am_parse (yyscan_t scanner);
+
+static int amp_am_scanner_parse_end (AmpAmScanner *scanner);
+
+#define RETURN(tok) *yylval = anjuta_token_stream_tokenize (yyextra->stream, tok, yyleng); \
+ return tok
+
+struct _AmpAmScanner
+{
+ yyscan_t scanner;
+
+ AnjutaTokenStream *stream;
+
+ AmpProject *project;
+ AmpGroup *group;
+ GHashTable *orphan_sources;
+};
%}
-%option reentrant stack noyywrap yylineno
+%option reentrant noyywrap yylineno
-%option prefix="amp_am_yy"
+/* Remove some warnings */
+%option nounput noinput noyy_pop_state noyy_top_state
-/* Necessary because autotools wrapper always looks for a file named "lex.yy.c",
- * not "lex.amp_am_yy.c"
-%option outfile="lex.yy.c"*/
+%option prefix="amp_am_yy"
%option bison-bridge bison-locations
@@ -68,294 +74,213 @@ NAME [^ \t\n\r:#=$"'`&@\\]*
%%
-<INITIAL>\n {
- yylval->token = amp_am_scanner_append_token (yyextra, ANJUTA_TOKEN_EOL);
- return EOL;
-}
+<INITIAL>\n { RETURN (EOL); }
-<INITIAL>([ ]|\\\n)([ \t]|\\\n)* {
- yylval->token = amp_am_scanner_append_token (yyextra, ANJUTA_TOKEN_SPACE);
- return SPACE;
-}
+<INITIAL>([ ]|\\\n)([ \t]|\\\n)* { RETURN (SPACE); }
-<INITIAL>([ \t])*#.*\n {
- yylval->token = amp_am_scanner_append_token (yyextra, ANJUTA_TOKEN_COMMENT);
- return EOL;
-}
+<INITIAL>([ \t])*#.*\n { RETURN (EOL); }
-<INITIAL>\t {
- yylval->token = amp_am_scanner_append_token (yyextra, ANJUTA_TOKEN_SPACE);
- return TAB;
-}
+<INITIAL>\t { RETURN (TAB); }
-<INITIAL>@{NAME}@ {
- yylval->token = amp_am_scanner_append_token (yyextra, ANJUTA_TOKEN_MACRO);
- return MACRO;
-}
+<INITIAL>@{NAME}@ { RETURN (MACRO); }
-<INITIAL>\$\([^ \t\n\r:#=$)]+\) {
- yylval->token = amp_am_scanner_append_token (yyextra, ANJUTA_TOKEN_VARIABLE);
- amp_am_scanner_update_line_width (yyextra, yylloc);
- return VARIABLE;
-}
+<INITIAL>\$\([^ \t\n\r:#=$)]+\) { RETURN (VARIABLE); }
-<INITIAL>\$\{[^ \t\n\r:#=$}]+\} {
- yylval->token = amp_am_scanner_append_token (yyextra, ANJUTA_TOKEN_VARIABLE);
- amp_am_scanner_update_line_width (yyextra, yylloc);
- return VARIABLE;
-}
+<INITIAL>\$\{[^ \t\n\r:#=$}]+\} { RETURN (VARIABLE); }
-<INITIAL>\$[^ \t\n\r\(\{] {
- yylval->token = amp_am_scanner_append_token (yyextra, ANJUTA_TOKEN_VARIABLE);
- amp_am_scanner_update_line_width (yyextra, yylloc);
- return VARIABLE;
-}
+<INITIAL>\$[^ \t\n\r\(\{] { RETURN (VARIABLE); }
-<INITIAL>: {
- yylval->token = amp_am_scanner_append_token (yyextra, ':');
- return COLON;
-}
+<INITIAL>: { RETURN (COLON); }
-<INITIAL>:: {
- yylval->token = amp_am_scanner_append_token (yyextra, ANJUTA_TOKEN_OPERATOR);
- return DOUBLE_COLON;
-}
+<INITIAL>:: { RETURN (DOUBLE_COLON); }
-<INITIAL>; {
- yylval->token = amp_am_scanner_append_token (yyextra, ANJUTA_TOKEN_OPERATOR);
- return SEMI_COLON;
-}
+<INITIAL>; { RETURN (SEMI_COLON); }
-<INITIAL>\| {
- yylval->token = amp_am_scanner_append_token (yyextra, ANJUTA_TOKEN_OPERATOR);
- return ORDER;
-}
+<INITIAL>\| { RETURN (ORDER); }
-<INITIAL>\= {
- yylval->token = amp_am_scanner_append_token (yyextra, ANJUTA_TOKEN_OPERATOR);
- return EQUAL;
-}
+<INITIAL>\= { RETURN (EQUAL); }
-<INITIAL>:= {
- yylval->token = amp_am_scanner_append_token (yyextra, ANJUTA_TOKEN_OPERATOR);
- return IMMEDIATE_EQUAL;
-}
+<INITIAL>:= { RETURN (IMMEDIATE_EQUAL); }
-<INITIAL>\?= {
- yylval->token = amp_am_scanner_append_token (yyextra, ANJUTA_TOKEN_OPERATOR);
- return CONDITIONAL_EQUAL;
-}
+<INITIAL>\?= { RETURN (CONDITIONAL_EQUAL); }
-<INITIAL>\+= {
- yylval->token = amp_am_scanner_append_token (yyextra, ANJUTA_TOKEN_OPERATOR);
- return APPEND;
-}
+<INITIAL>\+= { RETURN (APPEND); }
-<INITIAL>\\[ ] {
- yylval->token = amp_am_scanner_append_token (yyextra, ANJUTA_TOKEN_OPERATOR);
- return CHARACTER;
-}
+<INITIAL>\\[ ] { RETURN (CHARACTER); }
-<INITIAL>\\: {
- yylval->token = amp_am_scanner_append_token (yyextra, ANJUTA_TOKEN_OPERATOR);
- return CHARACTER;
-}
+<INITIAL>\\: { RETURN (CHARACTER); }
-<INITIAL>\\= {
- yylval->token = amp_am_scanner_append_token (yyextra, ANJUTA_TOKEN_OPERATOR);
- return CHARACTER;
-}
+<INITIAL>\\= { RETURN (CHARACTER); }
-<INITIAL>\\# {
- yylval->token = amp_am_scanner_append_token (yyextra, ANJUTA_TOKEN_OPERATOR);
- return CHARACTER;
-}
+<INITIAL>\\# { RETURN (CHARACTER); }
-<INITIAL>SUBDIRS {
- yylval->token = amp_am_scanner_append_token (yyextra, AM_TOKEN_SUBDIRS);
- return AM_VARIABLE;
-}
+<INITIAL>SUBDIRS { RETURN (SUBDIRS); }
-<INITIAL>DIST_SUBDIRS {
- yylval->token = amp_am_scanner_append_token (yyextra, AM_TOKEN_DIST_SUBDIRS);
- return AM_VARIABLE;
-}
+<INITIAL>DIST_SUBDIRS { RETURN (DIST_SUBDIRS); }
-<INITIAL>{NAME}_DATA {
- yylval->token = amp_am_scanner_append_token (yyextra, AM_TOKEN__DATA);
- return AM_VARIABLE;
-}
+<INITIAL>{NAME}_DATA { RETURN (_DATA); }
-<INITIAL>{NAME}_HEADERS {
- yylval->token = amp_am_scanner_append_token (yyextra, AM_TOKEN__HEADERS);
- return AM_VARIABLE;
-}
+<INITIAL>{NAME}_HEADERS { RETURN (_HEADERS); }
-<INITIAL>{NAME}_LIBRARIES {
- yylval->token = amp_am_scanner_append_token (yyextra, AM_TOKEN__LIBRARIES);
- return AM_VARIABLE;
-}
+<INITIAL>{NAME}_LIBRARIES { RETURN (_LIBRARIES); }
-<INITIAL>{NAME}_LISP {
- yylval->token = amp_am_scanner_append_token (yyextra, AM_TOKEN__LISP);
- return AM_VARIABLE;
-}
+<INITIAL>{NAME}_LISP { RETURN (_LISP); }
-<INITIAL>{NAME}_LTLIBRARIES {
- yylval->token = amp_am_scanner_append_token (yyextra, AM_TOKEN__LTLIBRARIES);
- return AM_VARIABLE;
-}
+<INITIAL>{NAME}_LTLIBRARIES { RETURN (_LTLIBRARIES); }
-<INITIAL>{NAME}_MANS {
- yylval->token = amp_am_scanner_append_token (yyextra, AM_TOKEN__MANS);
- return AM_VARIABLE;
-}
+<INITIAL>{NAME}_MANS { RETURN (_MANS); }
-<INITIAL>{NAME}_PROGRAMS {
- yylval->token = amp_am_scanner_append_token (yyextra, AM_TOKEN__PROGRAMS);
- return AM_VARIABLE;
-}
+<INITIAL>{NAME}_PROGRAMS { RETURN (_PROGRAMS); }
-<INITIAL>{NAME}_PYTHON {
- yylval->token = amp_am_scanner_append_token (yyextra, AM_TOKEN__PYTHON);
- return AM_VARIABLE;
-}
+<INITIAL>{NAME}_PYTHON { RETURN (_PYTHON); }
-<INITIAL>{NAME}_JAVA {
- yylval->token = amp_am_scanner_append_token (yyextra, AM_TOKEN__JAVA);
- return AM_VARIABLE;
-}
+<INITIAL>{NAME}_JAVA { RETURN (_JAVA); }
-<INITIAL>{NAME}_SCRIPTS {
- yylval->token = amp_am_scanner_append_token (yyextra, AM_TOKEN__SCRIPTS);
- return AM_VARIABLE;
-}
+<INITIAL>{NAME}_SCRIPTS { RETURN (_SCRIPTS); }
-<INITIAL>{NAME}_SOURCES {
- yylval->token = amp_am_scanner_append_token (yyextra, AM_TOKEN__SOURCES);
- return AM_VARIABLE;
-}
+<INITIAL>{NAME}_SOURCES { RETURN (_SOURCES); }
-<INITIAL>{NAME}_TEXINFOS {
- yylval->token = amp_am_scanner_append_token (yyextra, AM_TOKEN__TEXINFOS);
- return AM_VARIABLE;
-}
+<INITIAL>{NAME}_TEXINFOS { RETURN (_TEXINFOS); }
-<INITIAL>{NAME} {
- yylval->token = amp_am_scanner_append_token (yyextra, ANJUTA_TOKEN_NAME);
- amp_am_scanner_update_line_width (yyextra, yylloc);
- return NAME;
-}
+<INITIAL>{NAME} { RETURN (NAME); }
-<INITIAL>. {
- yylval->token = amp_am_scanner_append_token (yyextra, *yytext);
- return CHARACTER;
-}
+<INITIAL>. { RETURN (CHARACTER); }
%%
-
-struct _AmpAmScanner
+
+typedef struct _AmpAmBuffer AmpAmBuffer;
+
+struct _AmpAmBuffer
{
- const gchar *pos;
- yyscan_t scanner;
- YY_BUFFER_STATE buffer;
+ AnjutaToken *token;
- AnjutaTokenFile *file;
- gchar *filename;
+ /* Beginning of current token */
+ AnjutaToken *start;
+ gsize begin;
- guint line_width;
-};
+ AnjutaToken *end; /* Last token */
+ /* Next data read buffer */
+ AnjutaToken *next;
+ gsize pos;
+
+ /* Place to put new token */
+ AnjutaToken *first;
+ AnjutaToken *last;
+
+ AmpAmBuffer *parent;
+};
+
/* Private functions
*---------------------------------------------------------------------------*/
-static AnjutaToken*
-amp_am_scanner_append_token (AmpAmScanner *scanner, gint token)
+static gint
+amp_am_scanner_parse_end (AmpAmScanner *scanner)
{
- AnjutaToken *frag;
-
- frag = anjuta_token_new_fragment (token, scanner->pos, yyget_leng (scanner->scanner));
- anjuta_token_file_append (scanner->file, frag);
- scanner->pos += yyget_leng (scanner->scanner);
- //anjuta_token_old_dump (frag);
-
- return frag;
+ yypop_buffer_state(scanner->scanner);
+ scanner->stream = anjuta_token_stream_pop (scanner->stream);
+
+ if (scanner->stream == NULL)
+ {
+ yyterminate();
+ }
+ else
+ {
+ return 1;
+ }
}
-static void
-amp_am_scanner_update_line_width (AmpAmScanner *scanner, YYLTYPE *loc)
+/* Parser functions
+ *---------------------------------------------------------------------------*/
+
+void
+amp_am_yyerror (YYLTYPE *loc, AmpAmScanner *scanner, char const *s)
{
- anjuta_token_file_update_line_width (scanner->file, loc->last_column);
+ AnjutaTokenFileLocation location;
+
+ if (amp_project_get_token_location (scanner->project, &location, *loc))
+ {
+ g_message ("%s:%d.%d %s\n", location.filename, location.line, location.column, s);
+ g_free (location.filename);
+ }
+ else
+ {
+ g_message ("%s \n", s);
+ }
}
-static void
-amp_update_location (YYLTYPE *loc, const gchar *text, gint length)
+void
+amp_am_scanner_set_am_variable (AmpAmScanner *scanner, AnjutaTokenType variable, AnjutaToken *name, AnjutaToken *list)
{
- const gchar *ptr;
- const gchar *end = text + length;
-
- loc->first_line = loc->last_line;
- loc->first_column = loc->last_column + 1;
-
- for (ptr = text; ptr != end; ptr++)
- {
- if (*ptr == '\n')
- {
- loc->last_column = 0;
- loc->last_line++;
- length -= (ptr + 1 - text);
- }
- }
-
- loc->last_column += length;
+ amp_project_set_am_variable (scanner->project, scanner->group, variable, name, list, scanner->orphan_sources);
}
/* Public functions
*---------------------------------------------------------------------------*/
-gboolean
-amp_am_scanner_parse (AmpAmScanner *scanner, AnjutaTokenFile *file, GError **error)
+AnjutaToken *
+amp_am_scanner_parse_token (AmpAmScanner *scanner, AnjutaToken *token, GError **error)
{
- if (scanner->buffer != NULL) yy_delete_buffer (scanner->buffer, scanner->scanner);
-
- scanner->file = file;
- if (scanner->file== NULL) return FALSE;
+ AnjutaToken *first;
+ AnjutaTokenStream *stream;
+
+ stream = anjuta_token_stream_push (scanner->stream, token);
+ first = anjuta_token_stream_get_root (stream);
+
+ if (scanner->stream != NULL)
+ {
+ /* Parse an included file or a expanded variable */
+
+ scanner->stream = stream;
+ yypush_buffer_state(yy_create_buffer(NULL, YY_BUF_SIZE, scanner->scanner), scanner->scanner);
+ }
+ else
+ {
+ amp_am_yypstate *ps;
+ gint status;
+
+ scanner->stream = stream;
+ ps = amp_am_yypstate_new ();
+ do
+ {
+ YYSTYPE yylval_param;
+ YYLTYPE yylloc_param;
+ gint yychar = am_yylex (&yylval_param, &yylloc_param, scanner->scanner);
+
+ yylloc_param = yylval_param;
+ status = amp_am_yypush_parse (ps, yychar, &yylval_param, &yylloc_param, scanner);
+
+ } while (status == YYPUSH_MORE);
+ amp_am_yypstate_delete (ps);
- scanner->pos = anjuta_token_file_get_content (scanner->file, error);
- if (scanner->pos == NULL) return FALSE;
+ }
- scanner->buffer = yy_scan_string (scanner->pos, scanner->scanner);
-
- return amp_am_yyparse (scanner->scanner) == 0;
+ return first;
}
-guint
-amp_am_scanner_get_line_width (AmpAmScanner *scanner)
-{
- return scanner->line_width;
-}
+/* Constructor & Destructor
+ *---------------------------------------------------------------------------*/
-const gchar*
-amp_am_scanner_get_filename (AmpAmScanner *scanner)
+static void
+free_source_list (GList *source_list)
{
- g_free (scanner->filename);
- scanner->filename = NULL;
- if (scanner->file) scanner->filename = g_file_get_path (anjuta_token_file_get_file (scanner->file));
-
- return scanner->filename;
+ g_list_foreach (source_list, (GFunc)amp_source_free, NULL);
+ g_list_free (source_list);
}
-
-/* Constructor & Destructor
- *---------------------------------------------------------------------------*/
-
AmpAmScanner *
-amp_am_scanner_new (void)
+amp_am_scanner_new (AmpProject *project, AmpGroup *group)
{
AmpAmScanner *scanner;
scanner = g_new0 (AmpAmScanner, 1);
+ scanner->project = project;
+ scanner->group = group;
+
+ /* Create hash table for sources list */
+ scanner->orphan_sources = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)g_free, (GDestroyNotify)free_source_list);
+
yylex_init(&scanner->scanner);
yyset_extra (scanner, scanner->scanner);
@@ -367,11 +292,10 @@ amp_am_scanner_free (AmpAmScanner *scanner)
{
g_return_if_fail (scanner != NULL);
- if (scanner->buffer != NULL) yy_delete_buffer (scanner->buffer, scanner->scanner);
yylex_destroy(scanner->scanner);
- g_free (scanner->filename);
- scanner->filename = NULL;
+ /* Free unused sources files */
+ g_hash_table_destroy (scanner->orphan_sources);
g_free (scanner);
}
diff --git a/plugins/am-project/am-writer.c b/plugins/am-project/am-writer.c
new file mode 100644
index 0000000..a68f534
--- /dev/null
+++ b/plugins/am-project/am-writer.c
@@ -0,0 +1,219 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* am-writer.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 "am-writer.h"
+#include "ac-scanner.h"
+#include "ac-parser.h"
+
+#include "am-project-private.h"
+
+#include <libanjuta/anjuta-debug.h>
+#include <libanjuta/anjuta-utils.h>
+
+/* Types
+ *---------------------------------------------------------------------------*/
+
+
+/* Helper functions
+ *---------------------------------------------------------------------------*/
+
+/* Private functions
+ *---------------------------------------------------------------------------*/
+
+/* Public functions
+ *---------------------------------------------------------------------------*/
+
+AnjutaToken *
+amp_project_write_config_list (AmpProject *project)
+{
+ AnjutaToken *pos;
+ AnjutaToken *token;
+ static gint output_type[] = {AC_TOKEN_AC_OUTPUT, 0};
+ static gint eol_type[] = {ANJUTA_TOKEN_EOL, ANJUTA_TOKEN_SPACE, ANJUTA_TOKEN_COMMENT, 0};
+
+ pos = anjuta_token_find_type (project->configure_token, 0, output_type);
+ if (pos == NULL)
+ {
+ gint other_type[] = {AC_TOKEN_AC_INIT,
+ AC_TOKEN_PKG_CHECK_MODULES,
+ AC_TOKEN_AC_CONFIG_FILES,
+ AC_TOKEN_OBSOLETE_AC_OUTPUT,
+ AC_TOKEN_AC_PREREQ,
+ 0};
+
+ pos = anjuta_token_find_type (project->configure_token, ANJUTA_TOKEN_SEARCH_LAST, other_type);
+ if (pos == NULL)
+ {
+ pos = anjuta_token_skip_comment (project->configure_token);
+ }
+ else
+ {
+ AnjutaToken* next;
+
+ next = anjuta_token_find_type (pos, ANJUTA_TOKEN_SEARCH_NOT, eol_type);
+ }
+
+ }
+
+ token = anjuta_token_insert_token_list (FALSE, pos,
+ AC_TOKEN_AC_CONFIG_FILES, "AC_CONFIG_FILES(",
+ ANJUTA_TOKEN_LIST, NULL,
+ ANJUTA_TOKEN_LAST, NULL,
+ RIGHT_PAREN, ")",
+ NULL);
+
+ return token;
+}
+
+AnjutaToken *
+amp_project_write_subdirs_list (AmpGroup *project)
+{
+ AnjutaToken *pos;
+ AnjutaToken *token;
+ static gint eol_type[] = {ANJUTA_TOKEN_EOL, ANJUTA_TOKEN_SPACE, ANJUTA_TOKEN_COMMENT, 0};
+
+ pos = anjuta_token_find_type (pos, ANJUTA_TOKEN_SEARCH_NOT, eol_type);
+
+ token = anjuta_token_insert_token_list (FALSE, pos,
+ AC_TOKEN_AC_CONFIG_FILES, "AC_CONFIG_FILES(",
+ ANJUTA_TOKEN_LIST, NULL,
+ ANJUTA_TOKEN_LAST, NULL,
+ RIGHT_PAREN, ")",
+ NULL);
+
+ return token;
+}
+
+AnjutaToken *
+amp_project_write_config_file (AmpProject *project, AnjutaToken *list, gboolean after, AnjutaToken *sibling, const gchar *filename)
+{
+ AnjutaToken *token;
+
+ token = anjuta_token_new_string (ANJUTA_TOKEN_NAME | ANJUTA_TOKEN_ADDED, filename);
+ fprintf (stdout, "Dump config list:\n");
+ anjuta_token_dump (list);
+ if (after)
+ {
+ anjuta_token_insert_word_after (list, sibling, token);
+ }
+ else
+ {
+ anjuta_token_insert_word_before (list, sibling, token);
+ }
+ fprintf (stdout, "Dump config list after insertion:\n");
+ anjuta_token_dump (list);
+
+ anjuta_token_style_format (project->ac_space_list, list);
+
+ fprintf (stdout, "Dump config list after format:\n");
+ anjuta_token_dump (list);
+
+ anjuta_token_file_update (project->configure_file, list);
+
+ return token;
+}
+
+AnjutaToken *
+amp_project_write_target (AnjutaToken *makefile, gint type, const gchar *name, gboolean after, AnjutaToken* sibling)
+{
+ AnjutaToken *pos;
+ AnjutaToken *token;
+
+ if (sibling == NULL)
+ {
+ pos = anjuta_token_first_item (makefile);
+
+ /* Add at the end of the file */
+ while (anjuta_token_next_item (pos) != NULL)
+ {
+ pos = anjuta_token_next_item (pos);
+ }
+ }
+ else
+ {
+ pos = sibling;
+ }
+
+ token = anjuta_token_insert_token_list (after, pos,
+ ANJUTA_TOKEN_LIST, NULL,
+ type, name,
+ ANJUTA_TOKEN_SPACE, " ",
+ ANJUTA_TOKEN_OPERATOR, "=",
+ ANJUTA_TOKEN_LIST, NULL,
+ ANJUTA_TOKEN_START, NULL,
+ NULL);
+
+ return anjuta_token_last_item (token);
+}
+
+AnjutaToken *
+amp_project_write_source_list (AnjutaToken *makefile, const gchar *name, gboolean after, AnjutaToken* sibling)
+{
+ AnjutaToken *pos;
+ AnjutaToken *token;
+ static gint eol_type[] = {ANJUTA_TOKEN_EOL, 0};
+
+ if (sibling == NULL)
+ {
+ pos = anjuta_token_first_item (makefile);
+
+ /* Add at the end of the file */
+ while (anjuta_token_next_item (pos) != NULL)
+ {
+ pos = anjuta_token_next_item (pos);
+ }
+ }
+ else
+ {
+ pos = sibling;
+ }
+
+ if (after && (pos != NULL))
+ {
+ token = anjuta_token_find_type (pos, 0, eol_type);
+ if (token != NULL)
+ {
+ pos = token;
+ }
+ else
+ {
+ pos = anjuta_token_insert_token_list (after, pos,
+ ANJUTA_TOKEN_EOL, "\n",
+ NULL);
+ }
+ }
+
+ token = anjuta_token_insert_token_list (after, pos,
+ ANJUTA_TOKEN_LIST, NULL,
+ ANJUTA_TOKEN_NAME, name,
+ ANJUTA_TOKEN_SPACE, " ",
+ ANJUTA_TOKEN_OPERATOR, "=",
+ ANJUTA_TOKEN_LIST, NULL,
+ ANJUTA_TOKEN_START, NULL,
+ NULL);
+
+ return anjuta_token_last_item (token);
+}
diff --git a/plugins/am-project/am-writer.h b/plugins/am-project/am-writer.h
new file mode 100644
index 0000000..290f4df
--- /dev/null
+++ b/plugins/am-project/am-writer.h
@@ -0,0 +1,39 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* am-writer.h
+ *
+ * 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.
+ */
+
+#ifndef _AM_WRITER_H_
+#define _AM_WRITER_H_
+
+#include "am-project.h"
+
+#include <glib.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+AnjutaToken *amp_project_write_config_list (AmpProject *project);
+AnjutaToken *amp_project_write_config_file (AmpProject *project, AnjutaToken *list, gboolean after, AnjutaToken *sibling, const gchar *filename);
+AnjutaToken *amp_project_write_target (AnjutaToken *makefile, gint type, const gchar *name, gboolean after, AnjutaToken* sibling);
+AnjutaToken *amp_project_write_source_list (AnjutaToken *makefile, const gchar *name, gboolean after, AnjutaToken* sibling);
+
+G_END_DECLS
+
+#endif /* _AM_WRITER_H_ */
diff --git a/plugins/mk-project/mk-parser.y b/plugins/mk-project/mk-parser.y
index 31d1da0..ecf5289 100644
--- a/plugins/mk-project/mk-parser.y
+++ b/plugins/mk-project/mk-parser.y
@@ -25,10 +25,14 @@
#define YYDEBUG 1
+/* Token location is found directly from token value, there is no need to
+ * maintain a separate location variable */
+#define YYLLOC_DEFAULT(Current, Rhs, N) ((Current) = YYRHSLOC(Rhs, (N) ? 1 : 0))
+
%}
-%token EOL '\n'
-%token SPACE
+%token EOL '\n'
+%token SPACE ' '
%token TAB '\t'
%token HASH '#'
%token MACRO
@@ -59,14 +63,10 @@
%token _EXPORT_ALL_VARIABLES
%token _NOTPARALLEL
-
%defines
-%pure_parser
-
-/* Necessary because autotools wrapper always looks for a file named "y.tab.c",
- * not "amp-scanner.c"
-%output="y.tab.c"*/
+%define api.pure
+%define api.push_pull "push"
/*%glr-parser*/
@@ -87,12 +87,84 @@
//mkp_yydebug = 1;
-static void mkp_yyerror (YYLTYPE *loc, MkpScanner *scanner, char const *s);
-static gint mkp_special_target (AnjutaToken *list);
-static gint mkp_special_prerequisite (AnjutaToken *token);
+static gint
+mkp_special_prerequisite (AnjutaToken *token)
+{
+ switch (anjuta_token_get_type (token))
+ {
+ case ORDER:
+ return MK_TOKEN_ORDER;
+ default:
+ return ANJUTA_TOKEN_NAME;
+ }
+}
-%}
+static void
+mkp_special_target (AnjutaToken *list)
+{
+ AnjutaToken *arg = anjuta_token_first_item (list);
+ AnjutaToken *target = arg != NULL ? anjuta_token_first_item (arg) : NULL;
+ if ((target != NULL) && (anjuta_token_next_item (target) == NULL))
+ {
+ gint mk_token = 0;
+
+ switch (anjuta_token_get_type (target))
+ {
+ case _PHONY:
+ mk_token = MK_TOKEN__PHONY;
+ break;
+ case _SUFFIXES:
+ mk_token = MK_TOKEN__SUFFIXES;
+ break;
+ case _DEFAULT:
+ mk_token = MK_TOKEN__DEFAULT;
+ break;
+ case _PRECIOUS:
+ mk_token = MK_TOKEN__PRECIOUS;
+ break;
+ case _INTERMEDIATE:
+ mk_token = MK_TOKEN__INTERMEDIATE;
+ break;
+ case _SECONDARY:
+ mk_token = MK_TOKEN__SECONDARY;
+ break;
+ case _SECONDEXPANSION:
+ mk_token = MK_TOKEN__SECONDEXPANSION;
+ break;
+ case _DELETE_ON_ERROR:
+ mk_token = MK_TOKEN__DELETE_ON_ERROR;
+ break;
+ case _IGNORE:
+ mk_token = MK_TOKEN__IGNORE;
+ break;
+ case _LOW_RESOLUTION_TIME:
+ mk_token = MK_TOKEN__LOW_RESOLUTION_TIME;
+ break;
+ case _SILENT:
+ mk_token = MK_TOKEN__SILENT;
+ break;
+ case _EXPORT_ALL_VARIABLES:
+ mk_token = MK_TOKEN__EXPORT_ALL_VARIABLES;
+ break;
+ case _NOTPARALLEL:
+ mk_token = MK_TOKEN__NOTPARALLEL;
+ break;
+ case ORDER:
+ mk_token = MK_TOKEN_ORDER;
+ break;
+ default:
+ break;
+ }
+
+ if (mk_token)
+ {
+ anjuta_token_set_type (arg, mk_token);
+ }
+ }
+}
+
+%}
%%
@@ -106,34 +178,44 @@ statement:
| space end_of_line
| definition end_of_line
| rule command_list {
- if ($2 != NULL) $$ = anjuta_token_group ($1, $2);
- mkp_scanner_add_rule (scanner, $$);
+ anjuta_token_merge_children ($1, $2);
+ mkp_scanner_add_rule (scanner, $1);
}
;
definition:
- head_list equal_token value_list {
- $$ = anjuta_token_merge (
- anjuta_token_insert_before ($1,
- anjuta_token_new_static (ANJUTA_TOKEN_DEFINITION, NULL)),
- $3 != NULL ? $3 : $2);
+ head_list equal_group value {
+ $$ = anjuta_token_new_static (ANJUTA_TOKEN_DEFINITION, NULL);
+ anjuta_token_merge_own_children ($1);
+ anjuta_token_merge ($$, $1);
+ anjuta_token_merge ($$, $2);
+ anjuta_token_merge ($$, $3);
+ mkp_scanner_update_variable (scanner, $$);
+ }
+ | head_list equal_group {
+ $$ = anjuta_token_new_static (ANJUTA_TOKEN_DEFINITION, NULL);
+ anjuta_token_merge_own_children ($1);
+ anjuta_token_merge ($$, $1);
+ anjuta_token_merge ($$, $2);
mkp_scanner_update_variable (scanner, $$);
- }
+ }
;
rule:
depend_list end_of_line {
- $$ = anjuta_token_group ($1, $2);
+ anjuta_token_merge ($1, $2);
}
| depend_list SEMI_COLON command_line EOL {
- $$ = anjuta_token_group ($1, $4);
+ anjuta_token_merge ($1, $2);
+ anjuta_token_merge ($1, $3);
+ anjuta_token_merge ($1, $4);
}
;
depend_list:
head_list rule_token prerequisite_list {
- $$ = anjuta_token_group_new (MK_TOKEN_RULE, $1);
- anjuta_token_set_type ($1, MK_TOKEN_TARGET);
+ $$ = anjuta_token_new_static (MK_TOKEN_RULE, NULL);
+ anjuta_token_merge ($$, $1);
mkp_special_target ($1);
switch (anjuta_token_get_type ($2))
{
@@ -146,16 +228,19 @@ depend_list:
default:
break;
}
- anjuta_token_group ($$, $3 != NULL ? $3 : $2);
+ anjuta_token_merge ($$, $2);
+ anjuta_token_merge ($$, $3);
}
;
command_list:
/* empty */ {
- $$ = NULL;
+ $$ = anjuta_token_new_static (MK_TOKEN_COMMANDS, NULL);
}
| command_list TAB command_line EOL {
- $$ = $4;
+ anjuta_token_merge ($1, $2);
+ anjuta_token_merge ($1, $3);
+ anjuta_token_merge ($1, $4);
}
;
@@ -164,15 +249,16 @@ command_list:
*----------------------------------------------------------------------------*/
end_of_line:
- EOL
- | comment
+ EOL {
+ $$ = NULL;
+ }
+ | comment {
+ $$ = NULL;
+ }
;
comment:
- HASH not_eol_list EOL {
- anjuta_token_set_type ($1, ANJUTA_TOKEN_COMMENT);
- anjuta_token_group ($1, $3);
- }
+ HASH not_eol_list EOL
;
not_eol_list:
@@ -180,69 +266,59 @@ not_eol_list:
| not_eol_list not_eol_token
;
-value_list:
+prerequisite_list:
/* empty */ {
- $$ = NULL;
+ $$ = anjuta_token_new_static (MK_TOKEN_PREREQUISITE, NULL);
}
| space {
- $$ = $1;
- }
- | optional_space value_list_body optional_space {
- $$ = anjuta_token_group_new (ANJUTA_TOKEN_VALUE, $1 != NULL ? $1 : $2);
- if ($1) anjuta_token_set_type ($1, ANJUTA_TOKEN_START);
- if ($3) anjuta_token_set_type ($1, ANJUTA_TOKEN_LAST);
- anjuta_token_group ($$, $3 != NULL ? $3 : $2);
- }
- ;
-
-value_list_body:
- value
- | value_list_body space value {
- anjuta_token_set_type ($2, ANJUTA_TOKEN_NEXT);
- $$ = $3;
- }
- ;
-
-prerequisite_list:
- /* empty */ {
- $$ = NULL;
+ $$ = anjuta_token_new_static (MK_TOKEN_PREREQUISITE, NULL);
}
| optional_space prerequisite_list_body optional_space {
- $$ = anjuta_token_group_new (MK_TOKEN_PREREQUISITE, $1 != NULL ? $1 : $2);
if ($1) anjuta_token_set_type ($1, ANJUTA_TOKEN_START);
if ($3) anjuta_token_set_type ($3, ANJUTA_TOKEN_LAST);
- anjuta_token_group ($$, $3 != NULL ? $3 : $2);
+ anjuta_token_merge_previous ($2, $1);
+ anjuta_token_merge ($2, $3);
+ $$ = $2;
}
;
prerequisite_list_body:
- prerequisite
+ prerequisite {
+ $$ = anjuta_token_new_static (MK_TOKEN_PREREQUISITE, NULL);
+ anjuta_token_merge ($$, $1);
+ }
| prerequisite_list_body space prerequisite {
anjuta_token_set_type ($2, ANJUTA_TOKEN_NEXT);
- $$ = $3;
+ anjuta_token_merge ($1, $2);
+ anjuta_token_merge ($1, $3);
}
;
head_list:
optional_space head_list_body optional_space {
- $$ = anjuta_token_group_new (ANJUTA_TOKEN_NAME, $1 != NULL ? $1 : $2);
- if ($1) anjuta_token_set_type ($1, ANJUTA_TOKEN_START);
- if ($3) anjuta_token_set_type ($3, ANJUTA_TOKEN_LAST);
- anjuta_token_group ($$, $3 != NULL ? $3 : $2);
+ $$ = anjuta_token_merge_previous ($2, $1);
+ anjuta_token_merge ($$, $3);
}
;
head_list_body:
- head
+ head {
+ $$ = anjuta_token_new_static (ANJUTA_TOKEN_NAME, NULL);
+ anjuta_token_merge ($$, $1);
+ }
| head_list_body space head {
- anjuta_token_set_type ($2, ANJUTA_TOKEN_NEXT);
- $$ = $3;
+ anjuta_token_merge ($1, $2);
+ anjuta_token_merge ($1, $3);
}
;
command_line:
- /* empty */
- | command_line command_token
+ /* empty */ {
+ $$ = anjuta_token_new_static (MK_TOKEN_COMMAND, NULL);
+ }
+ | command_line command_token {
+ anjuta_token_merge ($1, $2);
+ }
;
/* Items
@@ -256,43 +332,82 @@ optional_space:
;
space:
- space_token
+ space_token {
+ $$ = anjuta_token_new_static (ANJUTA_TOKEN_SPACE, NULL);
+ anjuta_token_merge ($$, $1);
+ }
| space space_token {
- anjuta_token_merge ($1, $2);
+ anjuta_token_merge ($1, $2);
}
+ | space variable_token
;
head:
head_token {
- $$ = anjuta_token_group_new (ANJUTA_TOKEN_NAME, $1);
+ $$ = anjuta_token_new_static (ANJUTA_TOKEN_NAME, NULL);
+ anjuta_token_merge ($$, $1);
}
| head head_token {
- anjuta_token_group ($$, $2);
+ anjuta_token_merge ($1, $2);
}
+ | head variable_token
;
value:
value_token {
- $$ = anjuta_token_group_new (ANJUTA_TOKEN_VALUE, $1);
+ $$ = anjuta_token_new_static (ANJUTA_TOKEN_VALUE, NULL);
+ anjuta_token_merge ($$, $1);
+ }
+ | space_token {
+ $$ = anjuta_token_new_static (ANJUTA_TOKEN_VALUE, NULL);
+ anjuta_token_merge ($$, $1);
}
| value value_token {
- anjuta_token_group ($$, $2);
+ anjuta_token_merge ($1, $2);
+ }
+ | value space_token {
+ anjuta_token_merge ($1, $2);
}
;
prerequisite:
+ name_prerequisite
+ ;
+
+name_prerequisite:
prerequisite_token {
- $$ = anjuta_token_group_new (mkp_special_prerequisite ($$), $1);
+ $$ = anjuta_token_new_static (mkp_special_prerequisite ($1), NULL);
+ anjuta_token_merge ($$, $1);
}
- | prerequisite prerequisite_token {
- $$ = anjuta_token_group ($1, $2);
- anjuta_token_set_type ($$, ANJUTA_TOKEN_VALUE);
+ | name_prerequisite prerequisite_token {
+ anjuta_token_merge ($1, $2);
}
+ | name_prerequisite variable_token
;
+equal_group:
+ EQUAL {
+ $$ = anjuta_token_new_static (MK_TOKEN_EQUAL, NULL);
+ anjuta_token_merge ($$, $1);
+ }
+ | IMMEDIATE_EQUAL {
+ $$ = anjuta_token_new_static (MK_TOKEN_IMMEDIATE_EQUAL, NULL);
+ anjuta_token_merge ($$, $1);
+ }
+ | CONDITIONAL_EQUAL {
+ $$ = anjuta_token_new_static (MK_TOKEN_CONDITIONAL_EQUAL, NULL);
+ anjuta_token_merge ($$, $1);
+ }
+ | APPEND {
+ $$ = anjuta_token_new_static (MK_TOKEN_APPEND, NULL);
+ anjuta_token_merge ($$, $1);
+ }
+ ;
+
+
/* Tokens
*----------------------------------------------------------------------------*/
-
+
not_eol_token:
word_token
| space_token
@@ -306,6 +421,7 @@ prerequisite_token:
command_token:
name_token
+ | variable_token
| equal_token
| rule_token
| depend_token
@@ -314,6 +430,7 @@ command_token:
value_token:
name_token
+ | variable_token
| equal_token
| rule_token
| depend_token
@@ -324,11 +441,14 @@ head_token:
| depend_token
;
-name_token:
+variable_token:
VARIABLE {
- anjuta_token_set_type ($$, MK_TOKEN_VARIABLE);
+ mkp_scanner_parse_variable (scanner, $$);
}
- | NAME
+ ;
+
+name_token:
+ NAME
| CHARACTER
| COMMA
| ORDER
@@ -391,114 +511,10 @@ space_token:
;
equal_token:
- EQUAL {
- anjuta_token_set_type ($$, MK_TOKEN_EQUAL);
- }
- | IMMEDIATE_EQUAL {
- anjuta_token_set_type ($$, MK_TOKEN_IMMEDIATE_EQUAL);
- }
- | CONDITIONAL_EQUAL {
- anjuta_token_set_type ($$, MK_TOKEN_CONDITIONAL_EQUAL);
- }
- | APPEND {
- anjuta_token_set_type ($$, MK_TOKEN_APPEND);
- }
+ EQUAL
+ | IMMEDIATE_EQUAL
+ | CONDITIONAL_EQUAL
+ | APPEND
;
%%
-
-static void
-mkp_yyerror (YYLTYPE *loc, MkpScanner *scanner, char const *s)
-{
- gchar *filename;
-
- g_message ("scanner %p", scanner);
- filename = mkp_scanner_get_filename ((MkpScanner *)scanner);
- if (filename == NULL) filename = "?";
- g_message ("%s (%d:%d-%d:%d) %s\n", filename, loc->first_line, loc->first_column, loc->last_line, loc->last_column, s);
-}
-
-static gint
-mkp_special_prerequisite (AnjutaToken *token)
-{
- switch (anjuta_token_get_type (token))
- {
- case ORDER:
- return MK_TOKEN_ORDER;
- default:
- return ANJUTA_TOKEN_NAME;
- }
-}
-
-static gint
-mkp_special_target (AnjutaToken *list)
-{
- AnjutaToken *arg;
-
- for (arg = anjuta_token_list_first (list); arg != NULL; arg = anjuta_token_list_next (arg))
- {
- AnjutaToken *child = anjuta_token_next_child (arg);
-
- if ((child != NULL) && (anjuta_token_next_sibling (child) == NULL))
- {
- gint mk_token = 0;
-
- switch (anjuta_token_get_type (child))
- {
- case _PHONY:
- mk_token = MK_TOKEN__PHONY;
- break;
- case _SUFFIXES:
- mk_token = MK_TOKEN__SUFFIXES;
- break;
- case _DEFAULT:
- mk_token = MK_TOKEN__DEFAULT;
- break;
- case _PRECIOUS:
- mk_token = MK_TOKEN__PRECIOUS;
- break;
- case _INTERMEDIATE:
- mk_token = MK_TOKEN__INTERMEDIATE;
- break;
- case _SECONDARY:
- mk_token = MK_TOKEN__SECONDARY;
- break;
- case _SECONDEXPANSION:
- mk_token = MK_TOKEN__SECONDEXPANSION;
- break;
- case _DELETE_ON_ERROR:
- mk_token = MK_TOKEN__DELETE_ON_ERROR;
- break;
- case _IGNORE:
- mk_token = MK_TOKEN__IGNORE;
- break;
- case _LOW_RESOLUTION_TIME:
- mk_token = MK_TOKEN__LOW_RESOLUTION_TIME;
- break;
- case _SILENT:
- mk_token = MK_TOKEN__SILENT;
- break;
- case _EXPORT_ALL_VARIABLES:
- mk_token = MK_TOKEN__EXPORT_ALL_VARIABLES;
- break;
- case _NOTPARALLEL:
- mk_token = MK_TOKEN__NOTPARALLEL;
- break;
- case ORDER:
- mk_token = MK_TOKEN_ORDER;
- break;
- default:
- break;
- }
-
- if (mk_token)
- {
- anjuta_token_set_type (arg, mk_token);
- }
- }
- }
-}
-
-/* Public functions
- *---------------------------------------------------------------------------*/
-
diff --git a/plugins/mk-project/mk-project.c b/plugins/mk-project/mk-project.c
index d3e48cc..d0d9c9d 100644
--- a/plugins/mk-project/mk-project.c
+++ b/plugins/mk-project/mk-project.c
@@ -25,6 +25,7 @@
#endif
#include "mk-project.h"
+#include "mk-rule.h"
#include "mk-project-private.h"
@@ -522,7 +523,7 @@ monitors_setup (MkpProject *project)
*/
static void
-mkp_dump_node (GNode *g_node)
+mkp_dump_node (AnjutaProjectNode *g_node)
{
gchar *name = NULL;
@@ -546,8 +547,8 @@ mkp_dump_node (GNode *g_node)
g_free (name);
}
-static gboolean
-foreach_node_destroy (GNode *g_node,
+static void
+foreach_node_destroy (AnjutaProjectNode *g_node,
gpointer data)
{
switch (MKP_NODE_DATA (g_node)->type) {
@@ -566,21 +567,17 @@ foreach_node_destroy (GNode *g_node,
g_assert_not_reached ();
break;
}
-
-
- return FALSE;
}
static void
-project_node_destroy (MkpProject *project, GNode *g_node)
+project_node_destroy (MkpProject *project, AnjutaProjectNode *g_node)
{
g_return_if_fail (project != NULL);
g_return_if_fail (MKP_IS_PROJECT (project));
if (g_node) {
/* free each node's data first */
- g_node_traverse (g_node,
- G_POST_ORDER, G_TRAVERSE_ALL, -1,
+ anjuta_project_node_all_foreach (g_node,
foreach_node_destroy, project);
/* now destroy the tree itself */
@@ -589,79 +586,20 @@ project_node_destroy (MkpProject *project, GNode *g_node)
}
static void
-find_target (GNode *node, gpointer data)
+find_target (AnjutaProjectTarget *node, gpointer data)
{
if (MKP_NODE_DATA (node)->type == ANJUTA_PROJECT_TARGET)
{
if (strcmp (MKP_TARGET_DATA (node)->base.name, *(gchar **)data) == 0)
{
/* Find target, return node value in pointer */
- *(GNode **)data = node;
+ *(AnjutaProjectTarget **)data = node;
return;
}
}
}
-static AnjutaToken*
-project_load_rule (MkpProject *project, AnjutaToken *rule, GNode *parent)
-{
- AnjutaToken *arg;
- AnjutaToken *prerequisite;
-
- /* Search for prerequisite */
- prerequisite = NULL;
- for (arg = anjuta_token_list_first (rule); arg != NULL; arg = anjuta_token_list_next (arg))
- {
- if (anjuta_token_get_type (arg) == MK_TOKEN_PREREQUISITE)
- {
- prerequisite = anjuta_token_list_next (arg);
- }
- }
-
- for (arg = anjuta_token_list_first (rule); arg != NULL; arg = anjuta_token_list_next (arg))
- {
- gchar *value;
- gpointer find;
- MkpTarget *target;
-
- value = anjuta_token_evaluate (arg);
-
- /* Check if target already exists */
- find = value;
- g_node_children_foreach (parent, G_TRAVERSE_ALL, find_target, &find);
- if ((gchar *)find != value)
- {
- /* Find target */
- target = (MkpTarget *)find;
- }
- else
- {
- /* Create target */
- target = mkp_target_new (value, (AnjutaProjectTargetType)&MkpTargetTypes[0]);
- mkp_target_add_token (target, arg);
- g_node_append (parent, target);
- }
-
- g_free (value);
-
- /* Add prerequisite */
- for (arg = prerequisite; arg != NULL; arg = anjuta_token_list_next (arg))
- {
- MkpSource *source;
- GFile *src_file;
-
- value = anjuta_token_evaluate (arg);
- src_file = g_file_get_child (project->root_file, value);
- source = mkp_source_new (src_file);
- g_object_unref (src_file);
- g_node_append (target, source);
- }
- }
-
- return NULL;
-}
-
static void
remove_make_file (gpointer data, GObject *object, gboolean is_last_ref)
{
@@ -676,10 +614,9 @@ static MkpGroup*
project_load_makefile (MkpProject *project, GFile *file, MkpGroup *parent, GError **error)
{
MkpScanner *scanner;
- AnjutaToken *rule_tok;
AnjutaToken *arg;
AnjutaTokenFile *tfile;
- gboolean found;
+ AnjutaToken *parse;
gboolean ok;
GError *err = NULL;
@@ -688,8 +625,10 @@ project_load_makefile (MkpProject *project, GFile *file, MkpGroup *parent, GErro
tfile = mkp_group_set_makefile (parent, file);
g_hash_table_insert (project->files, g_object_ref (file), g_object_ref (tfile));
// g_object_add_toggle_ref (G_OBJECT (project->make_file), remove_make_file, project);
+ arg = anjuta_token_file_load (tfile, NULL);
scanner = mkp_scanner_new (project);
- ok = mkp_scanner_parse (scanner, tfile, &err);
+ parse = mkp_scanner_parse_token (scanner, arg, &err);
+ ok = parse != NULL;
mkp_scanner_free (scanner);
if (!ok)
{
@@ -703,14 +642,6 @@ project_load_makefile (MkpProject *project, GFile *file, MkpGroup *parent, GErro
/* Load target */
mkp_project_enumerate_targets (project, parent);
-
- /*rule_tok = anjuta_token_new_static (MK_TOKEN_RULE, NULL);
-
- arg = anjuta_token_file_first (tfile);
- for (found = anjuta_token_match (rule_tok, ANJUTA_SEARCH_INTO, arg, &arg); found; found = anjuta_token_match (rule_tok, ANJUTA_SEARCH_INTO, anjuta_token_next_sibling (arg), &arg))
- {
- project_load_rule (project, arg, parent);
- }*/
return parent;
}
@@ -786,7 +717,7 @@ mkp_project_get_source (MkpProject *project, const gchar *id)
gchar *
mkp_project_get_node_id (MkpProject *project, const gchar *path)
{
- GNode *node = NULL;
+ AnjutaProjectNode *node = NULL;
if (path != NULL)
{
@@ -807,7 +738,7 @@ mkp_project_get_node_id (MkpProject *project, const gchar *path)
}
else
{
- node = g_node_nth_child (node, child);
+ node = anjuta_project_node_nth_child (node, child);
}
if (node == NULL)
{
@@ -864,6 +795,25 @@ mkp_project_get_target_types (MkpProject *project, GError **error)
return types;
}
+gboolean
+mkp_project_get_token_location (MkpProject *project, AnjutaTokenFileLocation *location, AnjutaToken *token)
+{
+ GHashTableIter iter;
+ gpointer key;
+ gpointer value;
+
+ g_hash_table_iter_init (&iter, project->files);
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ {
+ if (anjuta_token_file_get_token_location ((AnjutaTokenFile *)value, location, token))
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
/* Group access functions
*---------------------------------------------------------------------------*/
@@ -931,7 +881,7 @@ mkp_variable_get_name (MkpVariable *variable)
}
gchar *
-mkp_variable_evaluate (MkpVariable *variable, AnjutaProjectNode *context)
+mkp_variable_evaluate (MkpVariable *variable, MkpProject *project)
{
return anjuta_token_evaluate (variable->value);
}
@@ -962,81 +912,82 @@ mkp_variable_free (MkpVariable *variable)
/* Public functions
*---------------------------------------------------------------------------*/
-static void
-mkp_project_token_evaluate_token (MkpProject *project, AnjutaToken *token, GString *value)
+void
+mkp_project_update_variable (MkpProject *project, AnjutaToken *variable)
{
- if ((token != NULL) && (anjuta_token_get_length (token) != 0))
+ AnjutaToken *arg;
+ char *name = NULL;
+ MakeTokenType assign = 0;
+ AnjutaToken *value = NULL;
+
+ fprintf(stdout, "update variable");
+ anjuta_token_dump (variable);
+
+ arg = anjuta_token_first_item (variable);
+ name = g_strstrip (anjuta_token_evaluate (arg));
+ arg = anjuta_token_next_item (arg);
+
+ g_message ("new variable %s", name);
+ switch (anjuta_token_get_type (arg))
+ {
+ case MK_TOKEN_EQUAL:
+ case MK_TOKEN_IMMEDIATE_EQUAL:
+ case MK_TOKEN_CONDITIONAL_EQUAL:
+ case MK_TOKEN_APPEND:
+ assign = anjuta_token_get_type (arg);
+ break;
+ default:
+ break;
+ }
+
+ value = anjuta_token_next_item (arg);
+
+ if (assign != 0)
{
- gint type = anjuta_token_get_type (token);
- guint length;
- const gchar *string;
- gchar *name;
MkpVariable *var;
-
- switch (type)
+
+ g_message ("assign %d name %s value %s\n", assign, name, anjuta_token_evaluate (value));
+ var = (MkpVariable *)g_hash_table_lookup (project->variables, name);
+ if (var != NULL)
{
- case ANJUTA_TOKEN_COMMENT:
- case ANJUTA_TOKEN_OPEN_QUOTE:
- case ANJUTA_TOKEN_CLOSE_QUOTE:
- case ANJUTA_TOKEN_ESCAPE:
- break;
- case MK_TOKEN_VARIABLE:
- length = anjuta_token_get_length (token);
- string = anjuta_token_get_string (token);
- if (string[1] == '(')
- {
- name = g_strndup (string + 2, length - 3);
- }
- else
- {
- name = g_strndup (string + 1, 1);
- }
- var = g_hash_table_lookup (project->variables, name);
- g_free (name);
- if (var != NULL)
- {
- name = mkp_variable_evaluate (var, NULL);
- g_string_append (value, name);
- g_free (name);
- }
- break;
- default:
- g_string_append_len (value, anjuta_token_get_string (token), anjuta_token_get_length (token));
+ var->assign = assign;
+ var->value = value;
+ }
+ else
+ {
+ var = mkp_variable_new (name, assign, value);
+ g_hash_table_insert (project->variables, var->name, var);
}
+
}
-}
-static void
-mkp_project_token_evaluate_child (MkpProject *project, AnjutaToken *token, GString *value)
-{
- AnjutaToken *child;
+ g_message ("update variable %s", name);
- mkp_project_token_evaluate_token (project, token, value);
-
- child = anjuta_token_next_child (token);
- if (child) mkp_project_token_evaluate_child (project, child, value);
-
- child = anjuta_token_next_sibling (token);
- if (child) mkp_project_token_evaluate_child (project, child, value);
+ if (name) g_free (name);
}
-gchar *mkp_project_token_evaluate (MkpProject *project, AnjutaToken *token)
+AnjutaToken*
+mkp_project_get_variable_token (MkpProject *project, AnjutaToken *variable)
{
- GString *value = g_string_new (NULL);
- gchar *str;
-
- if (token != NULL)
- {
- AnjutaToken *child;
+ guint length;
+ const gchar *string;
+ gchar *name;
+ MkpVariable *var;
- mkp_project_token_evaluate_token (project, token, value);
-
- child = anjuta_token_next_child (token);
- if (child != NULL) mkp_project_token_evaluate_child (project, child, value);
+ 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 (project->variables, name);
+ g_free (name);
- str = g_string_free (value, FALSE);
- return *str == '\0' ? NULL : str;
+ return var != NULL ? var->value : NULL;
}
gboolean
@@ -1057,14 +1008,14 @@ mkp_project_reload (MkpProject *project, GError **error)
/* shortcut hash tables */
project->groups = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
project->files = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal, g_object_unref, g_object_unref);
- project->variables = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, mkp_variable_free);
+ project->variables = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)mkp_variable_free);
/* Initialize rules data */
mkp_project_init_rules (project);
/* Initialize list styles */
- project->space_list = anjuta_token_style_new (NULL, " ", "\\n", NULL, 0);
- project->arg_list = anjuta_token_style_new (NULL, ", ", ",\\n ", ")", 0);
+ project->space_list = anjuta_token_style_new (NULL, " ", "\n", NULL, 0);
+ project->arg_list = anjuta_token_style_new (NULL, ", ", ",\n ", ")", 0);
/* Find make file */
for (makefile = valid_makefiles; *makefile != NULL; makefile++)
@@ -1179,72 +1130,6 @@ mkp_project_probe (GFile *directory,
return probe ? IANJUTA_PROJECT_PROBE_MAKE_FILES : 0;
}
-void
-mkp_project_update_variable (MkpProject *project, AnjutaToken *variable)
-{
- AnjutaToken *arg;
- char *name = NULL;
- MakeTokenType assign = 0;
- AnjutaToken *value = NULL;
-
- for (arg = anjuta_token_next_child (variable); arg != NULL; arg = anjuta_token_next_sibling (arg))
- {
- if (anjuta_token_get_type (arg) == ANJUTA_TOKEN_NAME)
- {
- name = g_strstrip (anjuta_token_evaluate (arg));
- break;
- }
- }
- for (; arg != NULL; arg = anjuta_token_next_sibling (arg))
- {
- switch (anjuta_token_get_type (arg))
- {
- case MK_TOKEN_EQUAL:
- case MK_TOKEN_IMMEDIATE_EQUAL:
- case MK_TOKEN_CONDITIONAL_EQUAL:
- case MK_TOKEN_APPEND:
- assign = anjuta_token_get_type (arg);
- break;
- default:
- continue;
- }
- break;
- }
- for (; arg != NULL; arg = anjuta_token_next_sibling (arg))
- {
- if (anjuta_token_get_type (arg) == ANJUTA_TOKEN_VALUE)
- {
- value = arg;
- break;
- }
- }
-
- if (assign != 0)
- {
- MkpVariable *var;
-
- var = (MkpVariable *)g_hash_table_lookup (project->variables, name);
- if (var != NULL)
- {
- var->assign = assign;
- var->value = value;
- }
- else
- {
- var = mkp_variable_new (name, assign, value);
- g_hash_table_insert (project->variables, var->name, var);
- }
-
- }
-
- g_message ("update variable %s", name);
-
- if (name) g_free (name);
-}
-
-/* Public functions
- *---------------------------------------------------------------------------*/
-
gboolean
mkp_project_save (MkpProject *project, GError **error)
{
@@ -1413,7 +1298,7 @@ iproject_iface_init(IAnjutaProjectIface* iface)
iface->remove_node = iproject_remove_node;
}
-/* GbfProject implementation
+/* GObject implementation
*---------------------------------------------------------------------------*/
static void
@@ -1457,4 +1342,3 @@ mkp_project_class_init (MkpProjectClass *klass)
ANJUTA_TYPE_BEGIN(MkpProject, mkp_project, G_TYPE_OBJECT);
ANJUTA_TYPE_ADD_INTERFACE(iproject, IANJUTA_TYPE_PROJECT);
ANJUTA_TYPE_END;
-//GBF_BACKEND_BOILERPLATE (MkpProject, mkp_project);
diff --git a/plugins/mk-project/mk-project.h b/plugins/mk-project/mk-project.h
index 22c2fc0..b1d4b88 100644
--- a/plugins/mk-project/mk-project.h
+++ b/plugins/mk-project/mk-project.h
@@ -27,11 +27,11 @@
#include <libanjuta/anjuta-project.h>
#include <libanjuta/anjuta-token.h>
#include <libanjuta/anjuta-token-file.h>
-#include <libanjuta/anjuta-token-style.h>
+#include <libanjuta/anjuta-token-list.h>
G_BEGIN_DECLS
-#define YYSTYPE AnjutaToken*
+//#define YYSTYPE AnjutaToken*
#define MKP_TYPE_PROJECT (mkp_project_get_type ())
#define MKP_PROJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MKP_TYPE_PROJECT, MkpProject))
@@ -78,6 +78,10 @@ void mkp_project_unload (MkpProject *project);
MkpGroup *mkp_project_get_root (MkpProject *project);
MkpVariable *mkp_project_get_variable (MkpProject *project, const gchar *name);
GList *mkp_project_list_variable (MkpProject *project);
+AnjutaToken* mkp_project_get_variable_token (MkpProject *project, AnjutaToken *variable);
+
+void mkp_project_update_variable (MkpProject *project, AnjutaToken *variable);
+void mkp_project_add_rule (MkpProject *project, AnjutaToken *rule);
MkpGroup *mkp_project_get_group (MkpProject *project, const gchar *id);
MkpTarget *mkp_project_get_target (MkpProject *project, const gchar *id);
@@ -88,6 +92,7 @@ gboolean mkp_project_save (MkpProject *project, GError **error);
gchar * mkp_project_get_uri (MkpProject *project);
GFile* mkp_project_get_file (MkpProject *project);
+gboolean mkp_project_get_token_location (MkpProject *project, AnjutaTokenFileLocation *location, AnjutaToken *token);
MkpGroup* mkp_project_add_group (MkpProject *project, MkpGroup *parent, const gchar *name, GError **error);
void mkp_project_remove_group (MkpProject *project, MkpGroup *group, GError **error);
@@ -111,9 +116,10 @@ gchar *mkp_target_get_id (MkpTarget *target);
gchar *mkp_source_get_id (MkpSource *source);
GFile *mkp_source_get_file (MkpSource *source);
-gchar *mkp_variable_evaluate (MkpVariable *variable, AnjutaProjectNode *context);
+gchar *mkp_variable_evaluate (MkpVariable *variable, MkpProject *project);
const gchar* mkp_variable_get_name (MkpVariable *variable);
+
G_END_DECLS
#endif /* _MK_PROJECT_H_ */
diff --git a/plugins/mk-project/mk-rule.c b/plugins/mk-project/mk-rule.c
index 39422ad..cbad543 100644
--- a/plugins/mk-project/mk-rule.c
+++ b/plugins/mk-project/mk-rule.c
@@ -30,6 +30,7 @@
#include "mk-scanner.h"
#include <string.h>
+#include <stdio.h>
/* Rule object
*---------------------------------------------------------------------------*/
@@ -141,22 +142,25 @@ mkp_project_find_source (MkpProject *project, gchar *target, AnjutaProjectGroup
}
-/* Public functions
+/* Parser functions
*---------------------------------------------------------------------------*/
void
-mkp_project_add_rule (MkpProject *project, AnjutaToken *token)
+mkp_project_add_rule (MkpProject *project, AnjutaToken *group)
{
AnjutaToken *targ;
AnjutaToken *dep;
AnjutaToken *arg;
gboolean double_colon = FALSE;
- targ = anjuta_token_list_first (token);
- arg = anjuta_token_list_next (targ);
+ fprintf(stdout, "add rule\n");
+ anjuta_token_dump (group);
+
+ targ = anjuta_token_first_item (group);
+ arg = anjuta_token_next_word (targ);
if (anjuta_token_get_type (arg) == MK_TOKEN_DOUBLE_COLON) double_colon = TRUE;
- dep = anjuta_token_list_next (arg);
- for (arg = anjuta_token_list_first (targ); arg != NULL; arg = anjuta_token_list_next (arg))
+ dep = anjuta_token_next_word (arg);
+ for (arg = anjuta_token_first_word (targ); arg != NULL; arg = anjuta_token_next_word (arg))
{
AnjutaToken *src;
gchar *target;
@@ -167,11 +171,11 @@ mkp_project_add_rule (MkpProject *project, AnjutaToken *token)
switch (anjuta_token_get_type (arg))
{
case MK_TOKEN__PHONY:
- for (src = anjuta_token_list_first (dep); src != NULL; src = anjuta_token_list_next (src))
+ for (src = anjuta_token_first_word (dep); src != NULL; src = anjuta_token_next_word (src))
{
if (anjuta_token_get_type (src) != MK_TOKEN_ORDER)
{
- target = mkp_project_token_evaluate (project, src);
+ target = anjuta_token_evaluate (src);
rule = g_hash_table_lookup (project->rules, target);
if (rule == NULL)
@@ -187,13 +191,13 @@ mkp_project_add_rule (MkpProject *project, AnjutaToken *token)
}
break;
case MK_TOKEN__SUFFIXES:
- for (src = anjuta_token_list_first (dep); src != NULL; src = anjuta_token_list_next (src))
+ for (src = anjuta_token_first_word (dep); src != NULL; src = anjuta_token_next_word (src))
{
if (anjuta_token_get_type (src) != MK_TOKEN_ORDER)
{
gchar *suffix;
- suffix = mkp_project_token_evaluate (project, src);
+ suffix = anjuta_token_evaluate (src);
/* The pointer value must only be not NULL, it does not matter if it is
* invalid */
g_hash_table_replace (project->suffix, suffix, suffix);
@@ -221,31 +225,34 @@ mkp_project_add_rule (MkpProject *project, AnjutaToken *token)
/* Do nothing with these targets, just ignore them */
break;
default:
- target = g_strstrip (mkp_project_token_evaluate (project, arg));
+ target = g_strstrip (anjuta_token_evaluate (arg));
if (*target == '\0') break;
g_message ("add rule =%s=", target);
-
+
rule = g_hash_table_lookup (project->rules, target);
if (rule == NULL)
{
- rule = mkp_rule_new (target, token);
+ rule = mkp_rule_new (target, group);
g_hash_table_insert (project->rules, rule->name, rule);
}
else
{
- rule->rule = arg;
+ rule->rule = group;
}
- for (src = anjuta_token_list_first (dep); src != NULL; src = anjuta_token_list_next (src))
+ for (src = anjuta_token_first_word (dep); src != NULL; src = anjuta_token_next_word (src))
{
- gchar *src_name = mkp_project_token_evaluate (project, src);
-
- g_message (" with source %s", src_name);
- if (anjuta_token_get_type (src) == MK_TOKEN_ORDER)
+ gchar *src_name = anjuta_token_evaluate (src);
+
+ if (src_name != NULL)
{
- order = TRUE;
+ g_message (" with source %s", src_name);
+ if (anjuta_token_get_type (src) == MK_TOKEN_ORDER)
+ {
+ order = TRUE;
+ }
+ rule->prerequisite = g_list_prepend (rule->prerequisite, src_name);
}
- rule->prerequisite = g_list_prepend (rule->prerequisite, src_name);
}
if (target != NULL) g_free (target);
@@ -253,6 +260,9 @@ mkp_project_add_rule (MkpProject *project, AnjutaToken *token)
}
}
+/* Public functions
+ *---------------------------------------------------------------------------*/
+
void
mkp_project_enumerate_targets (MkpProject *project, AnjutaProjectGroup *parent)
{
@@ -317,35 +327,33 @@ mkp_project_enumerate_targets (MkpProject *project, AnjutaProjectGroup *parent)
/* Create target */
target = mkp_target_new (rule->name, NULL);
mkp_target_add_token (target, rule->rule);
- g_node_append (parent, target);
+ anjuta_project_node_append (parent, target);
- /* Search for prerequisite */
- prerequisite = NULL;
- for (arg = anjuta_token_list_first (rule->rule); arg != NULL; arg = anjuta_token_list_next (arg))
- {
- if (anjuta_token_get_type (arg) == MK_TOKEN_PREREQUISITE)
- {
- prerequisite = arg;
- break;
- }
- }
+ /* Get prerequisite */
+ prerequisite = anjuta_token_first_word (rule->rule);
+ if (prerequisite != NULL) prerequisite = anjuta_token_next_word (prerequisite);
+ if (prerequisite != NULL) prerequisite = anjuta_token_next_word (prerequisite);
/* Add prerequisite */
- for (arg = anjuta_token_list_first (prerequisite); arg != NULL; arg = anjuta_token_list_next (arg))
+ for (arg = anjuta_token_first_word (prerequisite); arg != NULL; arg = anjuta_token_next_word (arg))
{
MkpSource *source;
GFile *src_file;
gchar *name;
- name = g_strstrip (mkp_project_token_evaluate (project, arg));
- name = mkp_project_find_source (project, name, parent, 0);
+ name = anjuta_token_evaluate (arg);
+ if (name != NULL)
+ {
+ name = g_strstrip (name);
+ name = mkp_project_find_source (project, name, parent, 0);
+ }
if (name != NULL)
{
src_file = g_file_get_child (project->root_file, name);
source = mkp_source_new (src_file);
g_object_unref (src_file);
- g_node_append (target, source);
+ anjuta_project_node_append (target, source);
g_free (name);
}
diff --git a/plugins/mk-project/mk-rule.h b/plugins/mk-project/mk-rule.h
index e02db66..88a29cd 100644
--- a/plugins/mk-project/mk-rule.h
+++ b/plugins/mk-project/mk-rule.h
@@ -31,7 +31,9 @@ G_BEGIN_DECLS
void mkp_project_init_rules (MkpProject *project);
void mkp_project_free_rules (MkpProject *project);
-void mkp_project_enumerate_targets (MkpProject *project, AnjutaProjectGroup *parent);
+void mkp_project_enumerate_targets (MkpProject *project, MkpGroup *parent);
+void mkp_project_add_rule (MkpProject *project, AnjutaToken *group);
+
G_END_DECLS
diff --git a/plugins/mk-project/mk-scanner.h b/plugins/mk-project/mk-scanner.h
index dd5ec57..83d64bc 100644
--- a/plugins/mk-project/mk-scanner.h
+++ b/plugins/mk-project/mk-scanner.h
@@ -20,32 +20,34 @@
#ifndef _MK_SCANNER_H_
#define _MK_SCANNER_H_
+#include "mk-project.h"
+
#include "libanjuta/anjuta-token.h"
#include "libanjuta/anjuta-token-file.h"
-#include "libanjuta/anjuta-token-style.h"
+#include "libanjuta/anjuta-token-list.h"
#include <glib.h>
#include <gio/gio.h>
G_BEGIN_DECLS
+/* Token location is found directly from token value. We don't maintain a
+ * independent position. */
+#define YYLTYPE AnjutaToken*
#define YYSTYPE AnjutaToken*
-#ifndef _MK_PROJECT_H_
-typedef struct _MkpProject MkpProject;
-#endif
-
typedef struct _MkpScanner MkpScanner;
MkpScanner *mkp_scanner_new (MkpProject *project);
void mkp_scanner_free (MkpScanner *scanner);
-gboolean mkp_scanner_parse (MkpScanner *scanner, AnjutaTokenFile *file, GError **error);
+AnjutaToken *mkp_scanner_parse_token (MkpScanner *scanner, AnjutaToken *token, GError **error);
void mkp_scanner_update_variable (MkpScanner *scanner, AnjutaToken *variable);
+void mkp_scanner_parse_variable (MkpScanner *scanner, AnjutaToken *variable);
void mkp_scanner_add_rule (MkpScanner *scanner, AnjutaToken *rule);
-const gchar* mkp_scanner_get_filename (MkpScanner *scanner);
+void mkp_yyerror (YYLTYPE *loc, MkpScanner *scanner, char const *s);
typedef enum
{
@@ -58,6 +60,8 @@ typedef enum
MK_TOKEN_PREREQUISITE,
MK_TOKEN_ORDER_PREREQUISITE,
MK_TOKEN_ORDER,
+ MK_TOKEN_COMMAND,
+ MK_TOKEN_COMMANDS,
MK_TOKEN_COLON,
MK_TOKEN_DOUBLE_COLON,
MK_TOKEN_VARIABLE,
diff --git a/plugins/mk-project/mk-scanner.l b/plugins/mk-project/mk-scanner.l
index 972069d..03ff3d3 100644
--- a/plugins/mk-project/mk-scanner.l
+++ b/plugins/mk-project/mk-scanner.l
@@ -19,49 +19,44 @@
%{
-#include <stdlib.h>
-#include <string.h>
#include "mk-scanner.h"
#include "mk-parser.h"
+#include "mk-rule.h"
#include "libanjuta/anjuta-debug.h"
+#include "libanjuta/anjuta-token-stream.h"
+#include <stdlib.h>
+#include <string.h>
-/* Eliminate warning */
-#define YY_NO_UNPUT 1
-
-#define YY_INPUT(buf,result,the_max_size) \
- result = 0;
+#define YY_INPUT(buffer, result, max_size) result = anjuta_token_stream_read (yyextra->stream, buffer, max_size)
-#define YY_USER_ACTION mkp_update_location(yylloc, yytext, yyleng);
-
#define YY_EXTRA_TYPE MkpScanner*
//#define YY_USER_INIT {yy_flex_debug = 1;}
-
-static AnjutaToken* mkp_scanner_append_token (MkpScanner *scanner, gint token);
-static gint mkp_scanner_last_token (MkpScanner *scanner);
-static gint mkp_scanner_last_flags (MkpScanner *scanner);
-static void mkp_scanner_update_line_width (MkpScanner *scanner, YYLTYPE *loc);
-static void mkp_update_location (YYLTYPE *loc, const gchar *text, gint length);
-static int mkp_parse (yyscan_t scanner);
-
-void mkp_project_update_variable (MkpProject *project, AnjutaToken *variable);
-void mkp_project_add_rule (MkpProject *project, AnjutaToken *rule);
+static gint mkp_scanner_parse_end (MkpScanner *scanner);
-#define RETURN(tok) *yylval = mkp_scanner_append_token (yyextra, tok); \
+#define RETURN(tok) *yylval = anjuta_token_stream_tokenize (yyextra->stream, tok, yyleng); \
return tok
+struct _MkpScanner
+{
+ yyscan_t scanner;
+
+ AnjutaTokenStream *stream;
+
+ MkpProject *project;
+};
+
%}
-%option reentrant stack noyywrap yylineno
+%option reentrant noyywrap yylineno
-%option prefix="mkp_mk_yy"
+/* Remove some warnings */
+%option nounput noinput
-/* Necessary because autotools wrapper always looks for a file named "lex.yy.c",
- * not "lex.mkp_yy.c"
-%option outfile="lex.yy.c"*/
+%option prefix="mkp_mk_yy"
%option bison-bridge bison-locations
@@ -146,42 +141,48 @@ NAME [^ \t\n\r:#=$"'`&@\\]*
. { RETURN (CHARACTER); }
-%%
-
-struct _MkpScanner
-{
- const gchar *pos;
- yyscan_t scanner;
- YY_BUFFER_STATE buffer;
-
- AnjutaTokenFile *file;
- gchar *filename;
+<<EOF>> { if (mkp_scanner_parse_end (yyextra) == YY_NULL) return YY_NULL; }
- MkpProject *project;
- guint line_width;
-};
+%%
/* Private functions
*---------------------------------------------------------------------------*/
-static AnjutaToken*
-mkp_scanner_append_token (MkpScanner *scanner, gint token)
+static gint
+mkp_scanner_parse_end (MkpScanner *scanner)
{
- AnjutaToken *frag;
-
- frag = anjuta_token_new_fragment (token, scanner->pos, yyget_leng (scanner->scanner));
- anjuta_token_file_append (scanner->file, frag);
- scanner->pos += yyget_leng (scanner->scanner);
- //anjuta_token_old_dump (frag);
-
- return frag;
+ yypop_buffer_state(scanner->scanner);
+ scanner->stream = anjuta_token_stream_pop (scanner->stream);
+
+ if (scanner->stream == NULL)
+ {
+ yyterminate();
+ }
+ else
+ {
+ return 1;
+ }
}
-static void
-mkp_scanner_update_line_width (MkpScanner *scanner, YYLTYPE *loc)
+/* Parser functions
+ *---------------------------------------------------------------------------*/
+
+void
+mkp_yyerror (YYLTYPE *loc, MkpScanner *scanner, char const *s)
{
- anjuta_token_file_update_line_width (scanner->file, loc->last_column);
+ AnjutaTokenFileLocation location;
+
+ //g_message ("error at %d error at * %d string \"%s\"", anjuta_token_get_type((AnjutaToken *)loc), anjuta_token_get_type(*loc), anjuta_token_get_string ((AnjutaToken *loc));
+ if (mkp_project_get_token_location (scanner->project, &location, *loc))
+ {
+ g_message ("%s:%d.%d %s\n", location.filename, location.line, location.column, s);
+ g_free (location.filename);
+ }
+ else
+ {
+ g_message ("%s \n", s);
+ }
}
void
@@ -196,71 +197,74 @@ mkp_scanner_add_rule (MkpScanner *scanner, AnjutaToken *rule)
mkp_project_add_rule (scanner->project, rule);
}
-static void
-mkp_update_location (YYLTYPE *loc, const gchar *text, gint length)
+void
+mkp_scanner_parse_variable (MkpScanner *scanner, AnjutaToken *variable)
{
- const gchar *ptr;
- const gchar *end = text + length;
-
- loc->first_line = loc->last_line;
- loc->first_column = loc->last_column + 1;
-
- for (ptr = text; ptr != end; ptr++)
- {
- if (*ptr == '\n')
- {
- loc->last_column = 0;
- loc->last_line++;
- length -= (ptr + 1 - text);
- }
- }
-
- loc->last_column += length;
+ AnjutaToken *group;
+ AnjutaToken *content;
+
+ anjuta_token_set_type (variable, ANJUTA_TOKEN_VARIABLE);
+ content = anjuta_token_new_static (ANJUTA_TOKEN_CONTENT, NULL);
+ anjuta_token_stream_append_token (scanner->stream, content);
+
+ group = mkp_project_get_variable_token (scanner->project, variable);
+ fprintf(stdout, "get variable %s is %p\n", anjuta_token_evaluate (variable), group);
+ if (group != NULL)
+ {
+ //AnjutaToken *token;
+
+ //anjuta_token_dump (group);
+ //token = anjuta_token_group_into_token (group);
+ //anjuta_token_set_type (token, ANJUTA_TOKEN_CONTENT);
+ //anjuta_token_dump (token);
+ fprintf (stdout,"variable %s\n", anjuta_token_get_string (variable));
+ anjuta_token_dump (group);
+ mkp_scanner_parse_token (scanner, group, NULL);
+ //anjuta_token_free (token);
+ }
}
/* Public functions
*---------------------------------------------------------------------------*/
-int
-mkp_yylex (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,MkpScanner *scanner)
+AnjutaToken *
+mkp_scanner_parse_token (MkpScanner *scanner, AnjutaToken *token, GError **error)
{
- return mkp_mk_yylex (yylval_param, yylloc_param, scanner->scanner);
+ AnjutaToken *first;
+ AnjutaTokenStream *stream;
+
+ stream = anjuta_token_stream_push (scanner->stream, token);
+ first = anjuta_token_stream_get_root (stream);
+
+ if (scanner->stream != NULL)
+ {
+ /* Parse an included file or a expanded variable */
+
+ scanner->stream = stream;
+ yypush_buffer_state(yy_create_buffer(NULL, YY_BUF_SIZE, scanner->scanner), scanner->scanner);
+ }
+ else
+ {
+ mkp_yypstate *ps;
+ gint status;
+
+ scanner->stream = stream;
+ ps = mkp_yypstate_new ();
+ do
+ {
+ YYSTYPE yylval_param;
+ YYLTYPE yylloc_param;
+ gint yychar = mkp_mk_yylex (&yylval_param, &yylloc_param, scanner->scanner);
+
+ yylloc_param = yylval_param;
+ status = mkp_yypush_parse (ps, yychar, &yylval_param, &yylloc_param, scanner);
+ } while (status == YYPUSH_MORE);
+ mkp_yypstate_delete (ps);
+ }
+
+ return first;
}
-
-gboolean
-mkp_scanner_parse (MkpScanner *scanner, AnjutaTokenFile *file, GError **error)
-{
- if (scanner->buffer != NULL) yy_delete_buffer (scanner->buffer, scanner->scanner);
-
- scanner->file = file;
- if (scanner->file== NULL) return FALSE;
-
- scanner->pos = anjuta_token_file_get_content (scanner->file, error);
- if (scanner->pos == NULL) return FALSE;
-
- scanner->buffer = yy_scan_string (scanner->pos, scanner->scanner);
-
- return mkp_yyparse (scanner) == 0;
-}
-
-guint
-mkp_scanner_get_line_width (MkpScanner *scanner)
-{
- return scanner->line_width;
-}
-
-const gchar*
-mkp_scanner_get_filename (MkpScanner *scanner)
-{
- g_free (scanner->filename);
- scanner->filename = NULL;
- if (scanner->file) scanner->filename = g_file_get_path (anjuta_token_file_get_file (scanner->file));
-
- return scanner->filename;
-}
-
-
/* Constructor & Destructor
*---------------------------------------------------------------------------*/
@@ -284,11 +288,7 @@ mkp_scanner_free (MkpScanner *scanner)
{
g_return_if_fail (scanner != NULL);
- if (scanner->buffer != NULL) yy_delete_buffer (scanner->buffer, scanner->scanner);
yylex_destroy(scanner->scanner);
- g_free (scanner->filename);
- scanner->filename = NULL;
-
g_free (scanner);
}
diff --git a/plugins/project-manager/gbf-project-model.c b/plugins/project-manager/gbf-project-model.c
index d9ede16..6b6569a 100644
--- a/plugins/project-manager/gbf-project-model.c
+++ b/plugins/project-manager/gbf-project-model.c
@@ -486,7 +486,7 @@ update_target (GbfProjectModel *model, AnjutaProjectTarget *target, GtkTreeIter
return;
/* update target data here */
- sources = anjuta_project_node_all_child (target, ANJUTA_PROJECT_SOURCE);
+ sources = gbf_project_util_all_child (target, ANJUTA_PROJECT_SOURCE);
/* walk the tree target */
if (gtk_tree_model_iter_children (tree_model, &child, iter)) {
@@ -572,8 +572,8 @@ update_group (GbfProjectModel *model, AnjutaProjectGroup *group, GtkTreeIter *it
tree_model = GTK_TREE_MODEL (model);
/* update group data. nothing to do here */
- groups = anjuta_project_node_all_child (group, ANJUTA_PROJECT_GROUP);
- targets = anjuta_project_node_all_child (group, ANJUTA_PROJECT_TARGET);
+ groups = gbf_project_util_all_child (group, ANJUTA_PROJECT_GROUP);
+ targets = gbf_project_util_all_child (group, ANJUTA_PROJECT_TARGET);
/* walk the tree group */
/* group can be NULL, but we iterate anyway to remove any
diff --git a/plugins/project-manager/gbf-project-util.c b/plugins/project-manager/gbf-project-util.c
index 8cb178b..651b68a 100644
--- a/plugins/project-manager/gbf-project-util.c
+++ b/plugins/project-manager/gbf-project-util.c
@@ -794,3 +794,49 @@ gbf_project_util_add_source_multi (GbfProjectModel *model,
g_object_unref (gui);
return new_sources;
}
+
+GList *
+gbf_project_util_all_child (AnjutaProjectNode *parent, AnjutaProjectNodeType type)
+{
+ AnjutaProjectNode *node;
+ GList *list = NULL;
+
+ for (node = anjuta_project_node_first_child (parent); node != NULL; node = anjuta_project_node_next_sibling (node))
+ {
+ if (anjuta_project_node_get_type (node) == type)
+ {
+ list = g_list_prepend (list, node);
+ }
+ }
+
+ list = g_list_reverse (list);
+
+ return list;
+}
+
+GList *
+gbf_project_util_node_all (AnjutaProjectNode *parent, AnjutaProjectNodeType type)
+{
+ AnjutaProjectNode *node;
+ GList *list = NULL;
+
+ for (node = anjuta_project_node_first_child (parent); node != NULL; node = anjuta_project_node_next_sibling (node))
+ {
+ if (anjuta_project_node_get_type (node) == type)
+ {
+ list = g_list_prepend (list, node);
+ }
+ if (anjuta_project_node_get_type (node) == ANJUTA_PROJECT_GROUP)
+ {
+ GList *child_list;
+
+ child_list = gbf_project_util_node_all (node, type);
+ child_list = g_list_reverse (child_list);
+ list = g_list_concat (child_list, list);
+ }
+ }
+
+ list = g_list_reverse (list);
+
+ return list;
+}
diff --git a/plugins/project-manager/gbf-project-util.h b/plugins/project-manager/gbf-project-util.h
index 55f6a77..602f13a 100644
--- a/plugins/project-manager/gbf-project-util.h
+++ b/plugins/project-manager/gbf-project-util.h
@@ -52,7 +52,13 @@ GList* gbf_project_util_add_source_multi (GbfProjectModel *model,
AnjutaProjectGroup *default_group,
GList *uris_to_add);
-
+
+GList * gbf_project_util_all_child (AnjutaProjectNode *parent,
+ AnjutaProjectNodeType type);
+
+GList * gbf_project_util_node_all (AnjutaProjectNode *parent,
+ AnjutaProjectNodeType type);
+
G_END_DECLS
diff --git a/plugins/project-manager/plugin.c b/plugins/project-manager/plugin.c
index 0ccb9cc..8360ec5 100644
--- a/plugins/project-manager/plugin.c
+++ b/plugins/project-manager/plugin.c
@@ -1928,7 +1928,7 @@ iproject_manager_get_elements (IAnjutaProjectManager *project_manager,
plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
g_return_val_if_fail (IANJUTA_IS_PROJECT (plugin->project), NULL);
- return anjuta_project_node_all (ianjuta_project_get_root (plugin->project, NULL), element_type);
+ return gbf_project_util_node_all (ianjuta_project_get_root (plugin->project, NULL), element_type);
}
static AnjutaProjectTargetClass
@@ -1977,7 +1977,7 @@ iproject_manager_get_targets (IAnjutaProjectManager *project_manager,
g_return_val_if_fail (IANJUTA_IS_PROJECT (plugin->project), NULL);
/* Get all targets */
- targets = anjuta_project_node_all (ianjuta_project_get_root (plugin->project, NULL), ANJUTA_PROJECT_TARGET);
+ targets = gbf_project_util_node_all (ianjuta_project_get_root (plugin->project, NULL), ANJUTA_PROJECT_TARGET);
/* Remove all targets not in specified class */
for (node = g_list_first (targets); node != NULL;)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]