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) && !(anjuta_token_get_flags (item) & ANJUTA_TOKEN_REMOVED)) { 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; } } } }
/** * 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->token != NULL) { gsize length = anjuta_token_get_length (stream->token); if ((anjuta_token_get_type (stream->token) >= ANJUTA_TOKEN_PARSED) || (stream->pos >= length)) { for (;;) { /* Last token */ if (stream->token== stream->last) return 0; if (anjuta_token_get_type (stream->token) >= ANJUTA_TOKEN_PARSED) { stream->token = anjuta_token_next (stream->token); } else { stream->token = anjuta_token_next (stream->token); } if ((stream->token == NULL) || (anjuta_token_get_type (stream->token) == ANJUTA_TOKEN_EOV)) { /* Last token */ return 0; } else if ((anjuta_token_get_length (stream->token) != 0) && (anjuta_token_get_type (stream->token) < ANJUTA_TOKEN_PARSED)) { /* Find some data */ stream->pos = 0; length = anjuta_token_get_length (stream->token); break; } } } if (stream->pos < length) { const gchar *start = anjuta_token_get_string (stream->token); length -= stream->pos; if (length > max_size) length = max_size; memcpy (buffer, start + stream->pos, length); stream->pos += length; result = length; } } return result; }
gboolean amp_module_node_create_token (AmpProject *project, AmpModuleNode *module, GError **error) { gboolean after; AnjutaToken *token; AnjutaToken *prev; AnjutaToken *next; AnjutaProjectNode *sibling; /* Add in configure.ac */ /* Find a sibling if possible */ prev = NULL; after = TRUE; for (sibling = anjuta_project_node_prev_sibling (ANJUTA_PROJECT_NODE (module)); sibling != NULL; sibling = anjuta_project_node_prev_sibling (sibling)) { if (anjuta_project_node_get_node_type (sibling) == ANJUTA_PROJECT_MODULE) { prev = amp_module_node_get_token (AMP_MODULE_NODE (sibling)); if (prev != NULL) { prev = anjuta_token_list (prev); break; } } } if (prev == NULL) { after = FALSE; for (sibling = anjuta_project_node_next_sibling (ANJUTA_PROJECT_NODE (module)); sibling != NULL; sibling = anjuta_project_node_next_sibling (sibling)) { if (anjuta_project_node_get_node_type (sibling) == ANJUTA_PROJECT_MODULE) { prev = amp_module_node_get_token (AMP_MODULE_NODE (sibling)); if (prev != NULL) { prev = anjuta_token_list (prev); break; } } } } token = amp_project_write_module_list (project, anjuta_project_node_get_name (ANJUTA_PROJECT_NODE (module)), after, prev); next = anjuta_token_next (token); next = anjuta_token_next (next); next = anjuta_token_next (next); amp_module_node_add_token (module, next); amp_project_update_configure (project, token); return TRUE; }
/** * anjuta_token_stream_push: * @parent: a parent #AnjutaTokenStream object or NULL. * @root: a token or NULL * @content: 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 *root, AnjutaToken *content, GFile *file) { AnjutaTokenStream *child; child = g_new (AnjutaTokenStream, 1); child->first = content; child->pos = 0; child->begin = 0; child->parent = parent; child->next = anjuta_token_next (content); child->start = child->next; child->last = anjuta_token_last (content); if (child->last == content) child->last = NULL; child->root = root == NULL ? anjuta_token_new_static (ANJUTA_TOKEN_FILE, NULL) : root; if (file == NULL) { child->current_directory = parent == NULL ? NULL : (parent->current_directory == NULL ? NULL : g_object_ref (parent->current_directory)); child->current_file = NULL; } else { child->current_directory = g_file_get_parent (file); child->current_file = g_object_ref (file); } return child; }
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; } } }
static AnjutaToken* find_tokens (AnjutaToken *list, AnjutaTokenType* types) { AnjutaToken *tok; 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) { return tok; } } } return NULL; }
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; }
/** * 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_static (type, NULL); for (end = stream->start; end != NULL;) { if ((anjuta_token_get_type (end) < ANJUTA_TOKEN_PARSED) || (anjuta_token_get_length (end) == 0)) { gint toklen = anjuta_token_get_length (end); AnjutaToken *copy = anjuta_token_cut (end, stream->begin, length); if (toklen >= (length + stream->begin)) { 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_insert_after (frag, copy); anjuta_token_merge (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_insert_after (frag, copy); anjuta_token_merge (frag, copy); length -= toklen - stream->begin; 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; }
static AnjutaToken * anjuta_token_find_target_property_position (AmpTargetNode *target, AnjutaTokenType type) { AnjutaToken *pos = NULL; gboolean after = FALSE; GList *list; AmpGroupNode *group; AnjutaToken *makefile; group = AMP_GROUP_NODE (anjuta_project_node_parent_type (ANJUTA_PROJECT_NODE (target), ANJUTA_PROJECT_GROUP)); /* Try to find a better position */ /* 1. With the other properties of the target */ list = amp_target_node_get_all_token (target); if (list != NULL) { GList *link; AnjutaTokenType best = 0; for (link = list; link != NULL; link = g_list_next (link)) { AnjutaToken *token = (AnjutaToken *)link->data; AnjutaTokenType existing = anjuta_token_get_type (token); if ((existing < AM_TOKEN_FIRST_ORDERED_TARGET_MACRO) || (existing > AM_TOKEN_LAST_ORDERED_TARGET_MACRO)) { token = anjuta_token_list (token); if (token != NULL) existing = anjuta_token_get_type (token); } if ((existing >= AM_TOKEN_FIRST_ORDERED_TARGET_MACRO) && (existing <= AM_TOKEN_LAST_ORDERED_TARGET_MACRO)) { if (existing > type) { if ((best == 0) || ((existing - type) < best)) { best = existing - type; pos = token; after = FALSE; } } else { if ((best == 0) || ((type -existing) < best)) { best = type - existing; pos = token; after = TRUE; } } } } g_list_free (list); } /* 2. With properties of sibling targets */ if (pos == NULL) { AnjutaProjectNode *prev = ANJUTA_PROJECT_NODE (target); AnjutaProjectNode *next = ANJUTA_PROJECT_NODE (target); AmpTargetNode *sibling; AnjutaTokenFile *makefile; AnjutaToken *target_list = NULL; GList *link; link = amp_target_node_get_token (target, ANJUTA_TOKEN_ARGUMENT); if ((link != NULL) && (link->data != NULL)) { target_list = anjuta_token_list ((AnjutaToken *)link->data); } makefile = amp_group_node_get_make_token_file (group); if (makefile != NULL) { after = TRUE; while ((prev != NULL) || (next != NULL)) { /* Find sibling */ if (after) { while (prev != NULL) { prev = anjuta_project_node_prev_sibling (prev); if (anjuta_project_node_get_node_type (prev) == ANJUTA_PROJECT_TARGET) break; } sibling = AMP_TARGET_NODE (prev); } else { while (next != NULL) { next = anjuta_project_node_next_sibling (next); if (anjuta_project_node_get_node_type (next) == ANJUTA_PROJECT_TARGET) break; } sibling = AMP_TARGET_NODE (next); } list = sibling == NULL ? NULL : amp_target_node_get_all_token (sibling); /* Check that the target is in the same list */ if ((list != NULL) && (target_list != NULL)) { AnjutaToken *token; link = amp_target_node_get_token (sibling, ANJUTA_TOKEN_ARGUMENT); if ((link != NULL) && (link->data != NULL)) { token = anjuta_token_list ((AnjutaToken *)link->data); } if ((token != NULL) && (target_list != token)) { /* Target is in another list, do not use it, nor following ones */ list = NULL; if (after) { prev = NULL; } else { next = NULL; } } } if (list != NULL) { gsize best = 0; for (link = list; link != NULL; link = g_list_next (link)) { AnjutaToken *token = (AnjutaToken *)link->data; AnjutaTokenType existing = anjuta_token_get_type (token); if ((existing < AM_TOKEN_FIRST_ORDERED_TARGET_MACRO) || (existing > AM_TOKEN_LAST_ORDERED_TARGET_MACRO)) { token = anjuta_token_list (token); if (token != NULL) existing = anjuta_token_get_type (token); } if ((existing >= AM_TOKEN_FIRST_ORDERED_TARGET_MACRO) && (existing <= AM_TOKEN_LAST_ORDERED_TARGET_MACRO)) { gsize tpos; tpos = anjuta_token_file_get_token_position (makefile, token); if ((best == 0) || (after && (tpos > best)) || (!after && (tpos < best))) { pos = token; best = tpos; } } } g_list_free (list); list = NULL; if (best != 0) break; } after = after ? FALSE : TRUE; } } } /* 3. After target declaration */ if (pos == NULL) { list = amp_target_node_get_token (AMP_TARGET_NODE (target), ANJUTA_TOKEN_ARGUMENT); if (list != NULL) { pos = (AnjutaToken *)list->data; if (pos != NULL) { pos = anjuta_token_list (pos); if (pos != NULL) { pos = anjuta_token_list (pos); } } } after = TRUE; } /* 4. At the end of the file */ if (pos == NULL) { makefile = amp_group_node_get_makefile_token (group); for (pos = anjuta_token_first_item (makefile); (pos != NULL) && (anjuta_token_next_item (pos) != NULL); pos = anjuta_token_next_item (pos)); after = TRUE; } /* 5. Create new file */ if (pos == NULL) { /* Empty file */ pos = anjuta_token_new_string (ANJUTA_TOKEN_COMMENT | ANJUTA_TOKEN_ADDED, "## Process this file with automake to produce Makefile.in\n"); anjuta_token_append_child (makefile, pos); amp_group_node_update_makefile (group, pos); } /* Find end of line */ if (after) { while (pos != NULL) { if (anjuta_token_get_type (pos) == ANJUTA_TOKEN_EOL) break; if (anjuta_token_next (pos) == NULL) { pos = anjuta_token_insert_token_list (after, pos, ANJUTA_TOKEN_EOL, "\n", NULL); break; } pos = anjuta_token_next (pos); } } pos = anjuta_token_insert_token_list (after, pos, ANJUTA_TOKEN_EOL, "\n", NULL); pos = anjuta_token_insert_token_list (after, pos, ANJUTA_TOKEN_EOL, "\n", NULL); amp_group_node_update_makefile (group, pos); return pos; }
gboolean amp_group_node_create_token (AmpProject *project, AmpGroupNode *group, GError **error) { GFile *directory; GFile *makefile; AnjutaToken *list; gchar *basename; AnjutaTokenFile* tfile; AnjutaProjectNode *sibling; AmpGroupNode *parent; gboolean after; const gchar *name; /* Get parent target */ name = anjuta_project_node_get_name (ANJUTA_PROJECT_NODE (group)); parent = AMP_GROUP_NODE (anjuta_project_node_parent_type(ANJUTA_PROJECT_NODE (group), ANJUTA_PROJECT_GROUP)); if (parent != NULL) { directory = g_file_get_child (anjuta_project_node_get_file (ANJUTA_PROJECT_NODE (parent)), name); } else { /* Used only when adding root group (a group named . in an empty project) */ parent = group; directory = g_object_ref (anjuta_project_node_get_file (ANJUTA_PROJECT_NODE (parent))); } /* Find a sibling if possible */ after = TRUE; for (sibling = anjuta_project_node_prev_sibling (ANJUTA_PROJECT_NODE (group)); sibling != NULL; sibling = anjuta_project_node_prev_sibling (sibling)) { if (anjuta_project_node_get_node_type (sibling) == ANJUTA_PROJECT_GROUP) break; } if (sibling == NULL) { after = FALSE; for (sibling = anjuta_project_node_next_sibling (ANJUTA_PROJECT_NODE (group)); sibling != NULL; sibling = anjuta_project_node_next_sibling (sibling)) { if (anjuta_project_node_get_node_type (sibling) == ANJUTA_PROJECT_GROUP) break; } } if (sibling == NULL) after = TRUE; /* Create Makefile.am */ basename = amp_group_node_get_makefile_name (parent); if (basename != NULL) { makefile = g_file_get_child (directory, basename); g_free (basename); } else { makefile = g_file_get_child (directory, "Makefile.am"); } /* Add in configure */ list = NULL; if (sibling) list = amp_group_node_get_first_token (AMP_GROUP_NODE (sibling), AM_GROUP_TOKEN_CONFIGURE); if (list == NULL) list= amp_group_node_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; AnjutaToken *prev = NULL; AnjutaToken *token; if (sibling) { prev = amp_group_node_get_first_token (AMP_GROUP_NODE (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 (anjuta_project_node_get_file (ANJUTA_PROJECT_NODE (project)), makefile); ext = relative_make + strlen (relative_make) - 3; if (strcmp (ext, ".am") == 0) { *ext = '\0'; } token = amp_project_write_config_file (project, list, after, prev, relative_make); amp_group_node_add_token (AMP_GROUP_NODE (group), token, AM_GROUP_TOKEN_CONFIGURE); g_free (relative_make); } /* Add in Makefile.am */ if (sibling == NULL) { list = anjuta_token_find_group_property_position (parent, AM_TOKEN_SUBDIRS); if (list != NULL) { 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_node_get_first_token (AMP_GROUP_NODE (sibling), AM_GROUP_TOKEN_SUBDIRS); list = anjuta_token_list (prev); } if (list != NULL) { AnjutaToken *token; AnjutaToken *prev; AnjutaTokenStyle *style; style = anjuta_token_style_new_from_base (project->am_space_list); anjuta_token_style_update (style, list); if (sibling) { prev = amp_group_node_get_first_token (AMP_GROUP_NODE (sibling), AM_GROUP_TOKEN_SUBDIRS); } token = anjuta_token_new_string (ANJUTA_TOKEN_NAME | ANJUTA_TOKEN_ADDED, name); if (after) { anjuta_token_insert_word_after (list, prev, token); } else { anjuta_token_insert_word_before (list, prev, token); } /* Try to use the same style than the current group list */ anjuta_token_style_format (style, list); anjuta_token_style_free (style); amp_group_node_update_makefile (parent, token); amp_group_node_add_token (group, token, AM_GROUP_TOKEN_SUBDIRS); } tfile = amp_group_node_set_makefile (group, makefile, project); amp_project_add_file (project, makefile, tfile); return TRUE; }
static AnjutaToken * anjuta_token_find_group_property_position (AmpGroupNode *group, AnjutaTokenType type) { AnjutaToken *pos = NULL; gboolean after = FALSE; GList *list; AnjutaToken *makefile; /* Try to find a better position */ /* 1. With the other properties of the group */ list = amp_group_node_get_all_token (group); if (list != NULL) { GList *link; AnjutaTokenType best = 0; for (link = list; link != NULL; link = g_list_next (link)) { AnjutaToken *token = (AnjutaToken *)link->data; AnjutaTokenType existing = anjuta_token_get_type (token); if ((existing < AM_TOKEN_FIRST_ORDERED_TARGET_MACRO) || (existing > AM_TOKEN_LAST_ORDERED_TARGET_MACRO)) { token = anjuta_token_list (token); if (token != NULL) existing = anjuta_token_get_type (token); } if ((existing >= AM_TOKEN_FIRST_ORDERED_TARGET_MACRO) && (existing <= AM_TOKEN_LAST_ORDERED_TARGET_MACRO)) { if (existing > type) { if ((best == 0) || ((existing - type) < best)) { best = existing - type; pos = token; after = FALSE; } } else { if ((best == 0) || ((type -existing) < best)) { best = type - existing; pos = token; after = TRUE; } } } } g_list_free (list); } /* 2. At the end of the file */ if (pos == NULL) { makefile = amp_group_node_get_makefile_token (group); for (pos = anjuta_token_first_item (makefile); (pos != NULL) && (anjuta_token_next_item (pos) != NULL); pos = anjuta_token_next_item (pos)); after = TRUE; } /* makefile can be NULL for the root node if there isn't any corresponding Makefile.am */ if (makefile != NULL) { /* 3. Create new file */ if (pos == NULL) { /* Empty file */ pos = anjuta_token_new_string (ANJUTA_TOKEN_COMMENT | ANJUTA_TOKEN_ADDED, "## Process this file with automake to produce Makefile.in\n"); anjuta_token_append_child (makefile, pos); amp_group_node_update_makefile (group, pos); } /* Find end of line */ if (after) { while (pos != NULL) { if (anjuta_token_get_type (pos) == ANJUTA_TOKEN_EOL) break; if (anjuta_token_next (pos) == NULL) { pos = anjuta_token_insert_token_list (after, pos, ANJUTA_TOKEN_EOL, "\n", NULL); break; } pos = anjuta_token_next (pos); } } pos = anjuta_token_insert_token_list (after, pos, ANJUTA_TOKEN_EOL, "\n", NULL); pos = anjuta_token_insert_token_list (after, pos, ANJUTA_TOKEN_EOL, "\n", NULL); amp_group_node_update_makefile (group, pos); } return pos; }
static AnjutaToken * anjuta_token_find_position (AnjutaToken *list, gboolean after, AnjutaTokenType type, AnjutaToken *sibling) { AnjutaToken *tok; AnjutaToken *pos = sibling; if (sibling == NULL) { AnjutaToken *last = NULL; gboolean found = FALSE; for (tok = list; tok != NULL; tok = anjuta_token_next (tok)) { AnjutaTokenType current = anjuta_token_get_type (tok); if ((current >= AC_TOKEN_FIRST_ORDERED_MACRO) && (current <= AC_TOKEN_LAST_ORDERED_MACRO)) { /* Find a valid position */ if (after) { /* 1. After the last similar macro * 2. After the last macro with a higher priority * 3. At the end of the file */ if (current == type) { pos = tok; found = TRUE; } else if (!found && (current < type)) { pos = tok; } } else { /* 1. Before the first similar macro * 2. Before the first macro with an lower priority * 3. At the beginning of the file */ if (current == type) { pos = tok; break; } else if (!found && (current > type)) { pos = tok; found = TRUE; } } } last = tok; } if (after && (pos == NULL)) pos = last; } if (after) { for (; pos != NULL; pos = anjuta_token_next (pos)) { AnjutaTokenType current = anjuta_token_get_type (pos); if (current == ANJUTA_TOKEN_EOL) break; } } return pos; }