Dünkü mesajımdan sonra tagmanager kodlarını daha dikkatli bir şekilde yeniden incelemeye karar verdim. Neticede şu metoda ulaştım.
Github deposundaki adresi : https://github.com/geany/geany/blob/master/tagmanager/tm_workspace.c#L275
gboolean tm_workspace_create_global_tags(const char *pre_process, const char **includes,
int includes_count, const char *tags_file, int lang)
{
#ifdef HAVE_GLOB_H
glob_t globbuf;
size_t idx_glob;
#endif
int idx_inc;
char *command;
guint i;
FILE *fp;
TMWorkObject *source_file;
GPtrArray *tags_array;
GHashTable *includes_files_hash;
GList *includes_files = NULL;
gchar *temp_file = create_temp_file("tmp_XXXXXX.cpp");
gchar *temp_file2 = create_temp_file("tmp_XXXXXX.cpp");
if (NULL == temp_file || NULL == temp_file2 ||
NULL == theWorkspace || NULL == (fp = g_fopen(temp_file, "w")))
{
g_free(temp_file);
g_free(temp_file2);
return FALSE;
}
includes_files_hash = g_hash_table_new_full (tm_file_inode_hash,
g_direct_equal,
NULL, g_free);
#ifdef HAVE_GLOB_H
globbuf.gl_offs = 0;
if (includes[0][0] == '"') /* leading \" char for glob matching */
for(idx_inc = 0; idx_inc < includes_count; idx_inc++)
{
int dirty_len = strlen(includes[idx_inc]);
char *clean_path = g_malloc(dirty_len - 1);
strncpy(clean_path, includes[idx_inc] + 1, dirty_len - 1);
clean_path[dirty_len - 2] = 0;
#ifdef TM_DEBUG
g_message ("[o][%s]\n", clean_path);
#endif
glob(clean_path, 0, NULL, &globbuf);
#ifdef TM_DEBUG
g_message ("matches: %d\n", globbuf.gl_pathc);
#endif
for(idx_glob = 0; idx_glob < globbuf.gl_pathc; idx_glob++)
{
#ifdef TM_DEBUG
g_message (">>> %s\n", globbuf.gl_pathv[idx_glob]);
#endif
if (!g_hash_table_lookup(includes_files_hash,
globbuf.gl_pathv[idx_glob]))
{
char* file_name_copy = strdup(globbuf.gl_pathv[idx_glob]);
g_hash_table_insert(includes_files_hash, file_name_copy,
file_name_copy);
#ifdef TM_DEBUG
g_message ("Added ...\n");
#endif
}
}
globfree(&globbuf);
g_free(clean_path);
}
else
#endif
/* no glob support or globbing not wanted */
for(idx_inc = 0; idx_inc < includes_count; idx_inc++)
{
if (!g_hash_table_lookup(includes_files_hash,
includes[idx_inc]))
{
char* file_name_copy = strdup(includes[idx_inc]);
g_hash_table_insert(includes_files_hash, file_name_copy,
file_name_copy);
}
}
/* Checks for duplicate file entries which would case trouble */
g_hash_table_foreach(includes_files_hash, tm_move_entries_to_g_list,
&includes_files);
includes_files = g_list_reverse (includes_files);
#ifdef TM_DEBUG
g_message ("writing out files to %s\n", temp_file);
#endif
if (pre_process != NULL)
write_includes_file(fp, includes_files);
else
append_to_temp_file(fp, includes_files);
g_list_free (includes_files);
g_hash_table_destroy(includes_files_hash);
includes_files_hash = NULL;
includes_files = NULL;
fclose(fp);
/* FIXME: The following grep command removes the lines
* G_BEGIN_DECLS and G_END_DECLS from the header files. The reason is
* that in tagmanager, the files are not correctly parsed and the typedefs
* following these lines are incorrectly parsed. The real fix should,
* of course be in tagmanager (c) parser. This is just a temporary fix.
*/
if (pre_process != NULL)
{
command = g_strdup_printf("%s %s | grep -v -E '^\\s*(G_BEGIN_DECLS|G_END_DECLS)\\s*$' > %s",
pre_process, temp_file, temp_file2);
#ifdef TM_DEBUG
g_message("Executing: %s", command);
#endif
system(command);
g_free(command);
g_unlink(temp_file);
g_free(temp_file);
}
else
{
/* no pre-processing needed, so temp_file2 = temp_file */
g_unlink(temp_file2);
g_free(temp_file2);
temp_file2 = temp_file;
temp_file = NULL;
}
source_file = tm_source_file_new(temp_file2, TRUE, tm_source_file_get_lang_name(lang));
if (NULL == source_file)
{
g_unlink(temp_file2);
return FALSE;
}
g_unlink(temp_file2);
g_free(temp_file2);
if ((NULL == source_file->tags_array) || (0 == source_file->tags_array->len))
{
tm_source_file_free(source_file);
return FALSE;
}
tags_array = tm_tags_extract(source_file->tags_array, tm_tag_max_t);
if ((NULL == tags_array) || (0 == tags_array->len))
{
if (tags_array)
g_ptr_array_free(tags_array, TRUE);
tm_source_file_free(source_file);
return FALSE;
}
if (FALSE == tm_tags_sort(tags_array, global_tags_sort_attrs, TRUE))
{
tm_source_file_free(source_file);
return FALSE;
}
if (NULL == (fp = g_fopen(tags_file, "w")))
{
tm_source_file_free(source_file);
return FALSE;
}
fprintf(fp, "# format=tagmanager\n");
for (i = 0; i < tags_array->len; ++i)
{
tm_tag_write(TM_TAG(tags_array->pdata[i]), fp, tm_tag_attr_type_t
| tm_tag_attr_scope_t | tm_tag_attr_arglist_t | tm_tag_attr_vartype_t
| tm_tag_attr_pointer_t);
}
fclose(fp);
tm_source_file_free(source_file);
g_ptr_array_free(tags_array, TRUE);
return TRUE;
}
C++ bilgim çok fazla değil ama yanılmıyorsam Geany bu metodu kullanarak bizim gösterdiğimiz adresteki dosyaların içindeki metodları ayıklayıp bunları bir tag dosyası haline getiriyor. Sende bir ara incelersen memnun olurum eğer aradığımız metod buysa sorunumuzun büyük bir kısmını çözdük demektir :) Sonrasında yapmamız gereken bu metodu anlayıp D ile kodlamak olacak ki sanırım bu işin en keyifli kısmı bu aşamada başlayacak :)
--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]