/* * * Copyright (c) 2001-2002, Biswapesh Chattopadhyay * * This source code is released for free distribution under the terms of the * GNU General Public License. * */ /** * @file tm_source_file.h The TMSourceFile structure and associated functions are used to maintain tags for individual files. */ #include <stdio.h> #include <limits.h> #include <stdlib.h> #include <string.h> #include "general.h" #include "entry.h" #include "parse.h" #include "read.h" #define LIBCTAGS_DEFINED #include "tm_work_object.h" #include "tm_source_file.h" #include "tm_tag.h" guint source_file_class_id = 0; static TMSourceFile *current_source_file = NULL; gboolean tm_source_file_init(TMSourceFile *source_file, const char *file_name , gboolean update, const char* name) { if (0 == source_file_class_id) source_file_class_id = tm_work_object_register(tm_source_file_free , tm_source_file_update, NULL); #ifdef TM_DEBUG g_message("Source File init: %s", file_name); #endif if (FALSE == tm_work_object_init(&(source_file->work_object), source_file_class_id, file_name, FALSE)) return FALSE; source_file->inactive = FALSE; if (NULL == LanguageTable) { initializeParsing(); installLanguageMapDefaults(); if (NULL == TagEntryFunction) TagEntryFunction = tm_source_file_tags; if (NULL == TagEntrySetArglistFunction) TagEntrySetArglistFunction = tm_source_file_set_tag_arglist; } if (name == NULL) source_file->lang = LANG_AUTO; else source_file->lang = getNamedLanguage(name); if (update) tm_source_file_update(TM_WORK_OBJECT(source_file), TRUE, FALSE, FALSE); return TRUE; } TMWorkObject *tm_source_file_new(const char *file_name, gboolean update, const char *name) { TMSourceFile *source_file = g_new(TMSourceFile, 1); if (TRUE != tm_source_file_init(source_file, file_name, update, name)) { g_free(source_file); return NULL; } return (TMWorkObject *) source_file; } void tm_source_file_destroy(TMSourceFile *source_file) { #ifdef TM_DEBUG g_message("Destroying source file: %s", source_file->work_object.file_name); #endif if (NULL != TM_WORK_OBJECT(source_file)->tags_array) { tm_tags_array_free(TM_WORK_OBJECT(source_file)->tags_array, TRUE); TM_WORK_OBJECT(source_file)->tags_array = NULL; } tm_work_object_destroy(&(source_file->work_object)); } void tm_source_file_free(gpointer source_file) { if (NULL != source_file) { tm_source_file_destroy(source_file); g_free(source_file); } } gboolean tm_source_file_parse(TMSourceFile *source_file) { const char *file_name; gboolean status = TRUE; int passCount = 0; if ((NULL == source_file) || (NULL == source_file->work_object.file_name)) { g_warning("Attempt to parse NULL file"); return FALSE; } file_name = source_file->work_object.file_name; if (NULL == LanguageTable) { initializeParsing(); installLanguageMapDefaults(); if (NULL == TagEntryFunction) TagEntryFunction = tm_source_file_tags; if (NULL == TagEntrySetArglistFunction) TagEntrySetArglistFunction = tm_source_file_set_tag_arglist; } current_source_file = source_file; if (LANG_AUTO == source_file->lang) source_file->lang = getFileLanguage (file_name); if (source_file->lang < 0 || ! LanguageTable [source_file->lang]->enabled) return status; while ((TRUE == status) && (passCount < 3)) { if (source_file->work_object.tags_array) tm_tags_array_free(source_file->work_object.tags_array, FALSE); if (fileOpen (file_name, source_file->lang)) { if (LanguageTable [source_file->lang]->parser != NULL) { LanguageTable [source_file->lang]->parser (); fileClose (); break; } else if (LanguageTable [source_file->lang]->parser2 != NULL) status = LanguageTable [source_file->lang]->parser2 (passCount); fileClose (); } else { g_warning("%s: Unable to open %s", G_STRFUNC, file_name); return FALSE; } ++ passCount; } return status; } gboolean tm_source_file_buffer_parse(TMSourceFile *source_file, guchar* text_buf, gint buf_size) { const char *file_name; gboolean status = TRUE; if ((NULL == source_file) || (NULL == source_file->work_object.file_name)) { g_warning("Attempt to parse NULL file"); return FALSE; } if ((NULL == text_buf) || (0 == buf_size)) { g_warning("Attempt to parse a NULL text buffer"); } file_name = source_file->work_object.file_name; if (NULL == LanguageTable) { initializeParsing(); installLanguageMapDefaults(); if (NULL == TagEntryFunction) TagEntryFunction = tm_source_file_tags; if (NULL == TagEntrySetArglistFunction) TagEntrySetArglistFunction = tm_source_file_set_tag_arglist; } current_source_file = source_file; if (LANG_AUTO == source_file->lang) source_file->lang = getFileLanguage (file_name); if (source_file->lang == LANG_IGNORE) { #ifdef TM_DEBUG g_warning("ignoring %s (unknown language)\n", file_name); #endif } else if (! LanguageTable [source_file->lang]->enabled) { #ifdef TM_DEBUG g_warning("ignoring %s (language disabled)\n", file_name); #endif } else { int passCount = 0; while ((TRUE == status) && (passCount < 3)) { if (source_file->work_object.tags_array) tm_tags_array_free(source_file->work_object.tags_array, FALSE); if (bufferOpen (text_buf, buf_size, file_name, source_file->lang)) { if (LanguageTable [source_file->lang]->parser != NULL) { LanguageTable [source_file->lang]->parser (); bufferClose (); break; } else if (LanguageTable [source_file->lang]->parser2 != NULL) status = LanguageTable [source_file->lang]->parser2 (passCount); bufferClose (); } else { g_warning("Unable to open %s", file_name); return FALSE; } ++ passCount; } return TRUE; } return status; } void tm_source_file_set_tag_arglist(const char *tag_name, const char *arglist) { int count; TMTag **tags, *tag; if (NULL == arglist || NULL == tag_name || NULL == current_source_file || NULL == current_source_file->work_object.tags_array) { return; } tags = tm_tags_find(current_source_file->work_object.tags_array, tag_name, FALSE, &count); if (tags != NULL && count == 1) { tag = tags[0]; g_free(tag->atts.entry.arglist); tag->atts.entry.arglist = g_strdup(arglist); } } int tm_source_file_tags(const tagEntryInfo *tag) { if (NULL == current_source_file) return 0; if (NULL == current_source_file->work_object.tags_array) current_source_file->work_object.tags_array = g_ptr_array_new(); g_ptr_array_add(current_source_file->work_object.tags_array, tm_tag_new(current_source_file, tag)); return TRUE; } gboolean tm_source_file_update(TMWorkObject *source_file, gboolean force , gboolean __unused__ recurse, gboolean update_parent) { if (force) { tm_source_file_parse(TM_SOURCE_FILE(source_file)); tm_tags_sort(source_file->tags_array, NULL, FALSE); /* source_file->analyze_time = tm_get_file_timestamp(source_file->file_name); */ if ((source_file->parent) && update_parent) { tm_work_object_update(source_file->parent, TRUE, FALSE, TRUE); } return TRUE; } else { #ifdef TM_DEBUG g_message ("no parsing of %s has been done", source_file->file_name); #endif return FALSE; } } gboolean tm_source_file_buffer_update(TMWorkObject *source_file, guchar* text_buf, gint buf_size, gboolean update_parent) { #ifdef TM_DEBUG g_message("Buffer updating based on source file %s", source_file->file_name); #endif tm_source_file_buffer_parse (TM_SOURCE_FILE(source_file), text_buf, buf_size); tm_tags_sort(source_file->tags_array, NULL, FALSE); /* source_file->analyze_time = time(NULL); */ if ((source_file->parent) && update_parent) { #ifdef TM_DEBUG g_message("Updating parent [project] from buffer.."); #endif tm_work_object_update(source_file->parent, TRUE, FALSE, TRUE); } #ifdef TM_DEBUG else g_message("Skipping parent update because parent is %s and update_parent is %s" , source_file->parent?"NOT NULL":"NULL", update_parent?"TRUE":"FALSE"); #endif return TRUE; } gboolean tm_source_file_write(TMWorkObject *source_file, FILE *fp, guint attrs) { TMTag *tag; guint i; if (NULL != source_file) { if (NULL != (tag = tm_tag_new(TM_SOURCE_FILE(source_file), NULL))) { tm_tag_write(tag, fp, tm_tag_attr_max_t); tm_tag_unref(tag); if (NULL != source_file->tags_array) { for (i=0; i < source_file->tags_array->len; ++i) { tag = TM_TAG(source_file->tags_array->pdata[i]); if (TRUE != tm_tag_write(tag, fp, attrs)) return FALSE; } } } } return TRUE; } const gchar *tm_source_file_get_lang_name(gint lang) { if (NULL == LanguageTable) { initializeParsing(); installLanguageMapDefaults(); if (NULL == TagEntryFunction) TagEntryFunction = tm_source_file_tags; if (NULL == TagEntrySetArglistFunction) TagEntrySetArglistFunction = tm_source_file_set_tag_arglist; } return getLanguageName(lang); } gint tm_source_file_get_named_lang(const gchar *name) { if (NULL == LanguageTable) { initializeParsing(); installLanguageMapDefaults(); if (NULL == TagEntryFunction) TagEntryFunction = tm_source_file_tags; if (NULL == TagEntrySetArglistFunction) TagEntrySetArglistFunction = tm_source_file_set_tag_arglist; } return getNamedLanguage(name); }