diff --git a/libanjuta/anjuta-token-style.c b/libanjuta/anjuta-token-style.c index 14b7d15..77cd6bd 100644 --- a/libanjuta/anjuta-token-style.c +++ b/libanjuta/anjuta-token-style.c @@ -463,25 +463,56 @@ anjuta_token_list_replace_nth (AnjutaToken *list, guint n, AnjutaToken *item) } AnjutaToken * -anjuta_token_list_insert_after (AnjutaToken *sibling, AnjutaToken *baby) +anjuta_token_list_insert_after (AnjutaToken *list, AnjutaToken *sibling, AnjutaToken *item) { - AnjutaToken *token = sibling; - AnjutaToken *separator; + AnjutaToken *token; - if (anjuta_token_get_type (token) == ANJUTA_TOKEN_LAST) + token = anjuta_token_list_first (list); + if (token == NULL) { - token = anjuta_token_previous_sibling (token); + token = anjuta_token_insert_child (list, anjuta_token_new_static (ANJUTA_TOKEN_START | ANJUTA_TOKEN_ADDED, NULL)); + token = anjuta_token_insert_after (token, anjuta_token_new_static (ANJUTA_TOKEN_LAST | ANJUTA_TOKEN_ADDED, NULL)); } - else if ((anjuta_token_get_type (token) != ANJUTA_TOKEN_NEXT) && (anjuta_token_next_sibling (token) != NULL)) + + for (;;) { - token = anjuta_token_next_sibling (token); - } - - separator = anjuta_token_new_static (ANJUTA_TOKEN_NEXT | ANJUTA_TOKEN_ADDED, NULL); - token = anjuta_token_insert_after (token, separator); - token = anjuta_token_insert_after (token, baby); + AnjutaToken *next; - return token; + 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 token; + case ANJUTA_TOKEN_START: + case ANJUTA_TOKEN_NEXT: + if (token == sibling) + { + anjuta_token_insert_after (token, item); + anjuta_token_insert_after (token, anjuta_token_new_static (ANJUTA_TOKEN_NEXT | ANJUTA_TOKEN_ADDED, NULL)); + return token; + } + break; + default: + 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 token; + } + break; + } + + next = anjuta_token_next (token); + if (next == NULL) + { + token = anjuta_token_insert_after (token, anjuta_token_new_static (ANJUTA_TOKEN_LAST | ANJUTA_TOKEN_ADDED, NULL)); + } + else + { + token = next; + } + } } void diff --git a/libanjuta/anjuta-token-style.h b/libanjuta/anjuta-token-style.h index 55a8859..aa14baf 100644 --- a/libanjuta/anjuta-token-style.h +++ b/libanjuta/anjuta-token-style.h @@ -39,7 +39,7 @@ AnjutaToken *anjuta_token_list_last (AnjutaToken *list); AnjutaToken *anjuta_token_list_next (AnjutaToken *sibling); AnjutaToken *anjuta_token_list_replace (AnjutaToken *sibling, AnjutaToken *baby); AnjutaToken *anjuta_token_list_replace_nth (AnjutaToken *list, guint n, AnjutaToken *baby); -AnjutaToken *anjuta_token_list_insert_after (AnjutaToken *sibling, AnjutaToken *baby); +AnjutaToken *anjuta_token_list_insert_after (AnjutaToken *list, AnjutaToken *sibling, AnjutaToken *baby); void anjuta_token_list_delete (AnjutaToken *sibling); G_END_DECLS diff --git a/libanjuta/anjuta-token.c b/libanjuta/anjuta-token.c index a5506a0..695105c 100644 --- a/libanjuta/anjuta-token.c +++ b/libanjuta/anjuta-token.c @@ -747,9 +747,6 @@ anjuta_token_merge_children (AnjutaToken *first, AnjutaToken *end) AnjutaToken * anjuta_token_merge_previous (AnjutaToken *first, AnjutaToken *end) { - AnjutaToken *child; - AnjutaToken *tok; - if ((end == NULL) || (first == end)) return first; anjuta_token_unlink (first); @@ -1172,8 +1169,6 @@ anjuta_token_check_child (AnjutaToken *token, AnjutaToken *parent) gboolean anjuta_token_check (AnjutaToken *token) { - AnjutaToken *next = token; - if ((token->children != NULL) && (token->last != NULL)) { anjuta_token_show (token, 0); @@ -1241,6 +1236,116 @@ AnjutaToken *anjuta_token_group_children (AnjutaToken *token) return token; } +/* Additional public functions + *---------------------------------------------------------------------------*/ + +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; + } + } +} + +AnjutaToken * +anjuta_token_insert_token_before (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; + + 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; +} + + /* Constructor & Destructor *---------------------------------------------------------------------------*/ diff --git a/libanjuta/anjuta-token.h b/libanjuta/anjuta-token.h index 7527041..6400524 100644 --- a/libanjuta/anjuta-token.h +++ b/libanjuta/anjuta-token.h @@ -97,7 +97,9 @@ enum AnjutaTokenSearchFlag ANJUTA_SEARCH_OVER = 0, ANJUTA_SEARCH_INTO = 1 << 0, ANJUTA_SEARCH_ALL = 1 << 1, - ANJUTA_SEARCH_BACKWARD = 1 << 2 + ANJUTA_SEARCH_BACKWARD = 1 << 2, + ANJUTA_TOKEN_SEARCH_LAST = 1 << 3, + ANJUTA_TOKEN_SEARCH_NOT = 1 << 4, }; typedef gboolean (*AnjutaTokenTraverseFunc) (AnjutaToken* token, gpointer data); @@ -192,6 +194,10 @@ 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_find_type (AnjutaToken *list, gint flags, AnjutaTokenType* types); +AnjutaToken *anjuta_token_skip_comment (AnjutaToken *list); +AnjutaToken *anjuta_token_insert_token_before (AnjutaToken *list,...); + G_END_DECLS #endif diff --git a/src/Makefile.am b/src/Makefile.am index 022aa8b..257363f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -34,6 +34,8 @@ projectparser_SOURCES = \ ac-scanner.h \ ac-writer.h \ ac-writer.c \ + am-writer.h \ + am-writer.c \ am-dialogs.c \ am-dialogs.h \ mk-project.c \ diff --git a/src/ac-parser.y b/src/ac-parser.y index 37be7e7..b581a2a 100644 --- a/src/ac-parser.y +++ b/src/ac-parser.y @@ -49,7 +49,7 @@ %token LOWER '<' %token GREATER '>' -%token COMMENT +%token COMMENT 256 %token NAME %token VARIABLE %token MACRO diff --git a/src/am-project.c b/src/am-project.c index cb33ce6..75474c5 100644 --- a/src/am-project.c +++ b/src/am-project.c @@ -1772,14 +1772,21 @@ amp_project_add_sibling_group (AmpProject *project, g_object_add_toggle_ref (G_OBJECT (tfile), remove_config_file, project); /* Add in configure */ - token_list= amp_group_get_token (parent, AM_GROUP_TOKEN_CONFIGURE); + token_list = NULL; + if (sibling) amp_group_get_token (sibling, AM_GROUP_TOKEN_CONFIGURE); + if (token_list == NULL) token_list= amp_group_get_token (parent, AM_GROUP_TOKEN_CONFIGURE); + if (token_list == NULL) + { + token_list = amp_project_write_config_list (project); + token_list = anjuta_token_next (token_list); + } if (token_list != NULL) { gchar *relative_make; gchar *ext; - AnjutaTokenStyle *style; + //AnjutaTokenStyle *style; - prev_token = (AnjutaToken *)token_list->data; + //prev_token = (AnjutaToken *)token_list->data; relative_make = g_file_get_relative_path (project->root_file, makefile); ext = relative_make + strlen (relative_make) - 3; @@ -1787,12 +1794,13 @@ amp_project_add_sibling_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_before (project, token_list, sibling, 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); + //add_list_item (prev_token, token, style); + //anjuta_token_style_free (style); } /* Add in Makefile.am */ diff --git a/src/am-writer.c b/src/am-writer.c new file mode 100644 index 0000000..14d7bab --- /dev/null +++ b/src/am-writer.c @@ -0,0 +1,103 @@ +/* -*- 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 +#endif + +#include "am-writer.h" +#include "ac-scanner.h" +#include "ac-parser.h" + +#include "am-project-private.h" + +#include +#include + +/* 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_before (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_before (AmpProject *project, AnjutaToken *list, AnjutaToken *sibling, const gchar *filename) +{ + AnjutaToken *token; + + token = anjuta_token_new_string (ANJUTA_TOKEN_NAME | ANJUTA_TOKEN_ADDED, filename); + anjuta_token_list_insert_after (list, sibling, token); + + anjuta_token_style_format (list, project->space_list); + + anjuta_token_file_update (project->configure_file, list); + + return token; +} diff --git a/src/am-writer.h b/src/am-writer.h new file mode 100644 index 0000000..e0aeeb1 --- /dev/null +++ b/src/am-writer.h @@ -0,0 +1,37 @@ +/* -*- 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 +#include + +G_BEGIN_DECLS + +AnjutaToken *amp_project_write_config_list (AmpProject *project); +AnjutaToken *amp_project_write_config_file_before (AmpProject *project, AnjutaToken *list, AnjutaToken *sibling, const gchar *filename); + +G_END_DECLS + +#endif /* _AM_WRITER_H_ */ diff --git a/src/mk-parser.y b/src/mk-parser.y index 6c2f4c3..d28d642 100644 --- a/src/mk-parser.y +++ b/src/mk-parser.y @@ -32,7 +32,7 @@ %} %token EOL '\n' -%token SPACE +%token SPACE ' ' %token TAB '\t' %token HASH '#' %token MACRO diff --git a/tests/group.at b/tests/group.at index eeedce8..e9f28c8 100644 --- a/tests/group.at +++ b/tests/group.at @@ -19,4 +19,18 @@ AT_CHECK([diff output expect]) AT_PARSER_CHECK([load empty2 \ list]) AT_CHECK([diff output expect]) +AT_DATA([expect], +[[ GROUP (0): empty2 + GROUP (0:0): group1 + GROUP (0:1): group2 +]]) +AT_PARSER_CHECK([load empty \ + move empty2 \ + add group 0 group2 after 0:0\ + list \ + save]) +AT_CHECK([diff output expect]) +AT_PARSER_CHECK([load empty2 \ + list]) +AT_CHECK([diff output expect]) AT_CLEANUP