25#include <glib/gstdio.h>
28# define WIN32_LEAN_AND_MEAN
72#define SOURCE_FILE_NEW(S) ((S) = g_slice_new(TMSourceFilePriv))
73#define SOURCE_FILE_FREE(S) g_slice_free(TMSourceFilePriv, (TMSourceFilePriv *) S)
80 int path_max = pathconf(path, _PC_PATH_MAX);
88#if defined(G_OS_WIN32) && !defined(HAVE_REALPATH)
92static char *realpath (
const char *pathname,
char *resolved_path)
96 if (resolved_path !=
NULL)
99 size = GetFullPathNameA (pathname, path_max, resolved_path,
NULL);
103 return resolved_path;
107 size = GetFullPathNameA (pathname, 0,
NULL,
NULL);
108 resolved_path = g_new0 (
char, size);
109 GetFullPathNameA (pathname, size, resolved_path,
NULL);
110 return resolved_path;
129 gchar *path = g_malloc0(len);
131 if (realpath(file_name, path))
141 if ((0 == strcmp(
"virtual",
impl))
142 || (0 == strcmp(
"pure virtual",
impl)))
146 g_warning(
"Unknown implementation %s",
impl);
153 if (0 == strcmp(
"public",
access))
155 else if (0 == strcmp(
"protected",
access))
157 else if (0 == strcmp(
"private",
access))
159 else if (0 == strcmp(
"friend",
access))
161 else if (0 == strcmp(
"default",
access))
165 g_warning(
"Unknown access type %s",
access);
186 if ((
NULL == fgets((gchar*)buf, BUFSIZ, fp)) || (
'\0' == *buf))
188 for (start = end = buf, status = TRUE; (TRUE == status); start = end, ++ end)
190 while ((*end <
TA_NAME) && (*end !=
'\0') && (*end !=
'\n'))
192 if ((
'\0' == *end) || (
'\n' == *end))
198 if (!isprint(*start))
201 tag->
name = g_strdup((gchar*)start);
208 tag->
line = atol((gchar*)start + 1);
211 tag->
local = atoi((gchar*)start + 1);
217 tag->
arglist = g_strdup((gchar*)start + 1);
220 tag->
scope = g_strdup((gchar*)start + 1);
226 tag->
var_type = g_strdup((gchar*)start + 1);
238 tag->
access = (char) *(start + 1);
241 tag->
impl = (char) *(start + 1);
245 g_warning(
"Unknown attribute %s", start + 1);
268 if ((
NULL == fgets((gchar*)buf, BUFSIZ, fp)) || (
'\0' == *buf))
273 for (start = end = buf, status = TRUE; (TRUE == status); start = end, ++ end)
275 while ((*end <
TA_NAME) && (*end !=
'\0') && (*end !=
'\n'))
277 if ((
'\0' == *end) || (
'\n' == *end))
281 if (
NULL == tag->
name && !isprint(*start))
284 fields = g_strsplit((gchar*)start,
"|", -1);
285 field_len = g_strv_length(fields);
287 if (field_len >= 1) tag->
name = g_strdup(fields[0]);
289 if (field_len >= 2 && fields[1] !=
NULL) tag->
var_type = g_strdup(fields[1]);
290 if (field_len >= 3 && fields[2] !=
NULL) tag->
arglist = g_strdup(fields[2]);
314 if ((
NULL == fgets(buf, BUFSIZ, fp)) || (
'\0' == *buf))
317 while (strncmp(buf,
"!_TAG_", 6) == 0);
322 if (! (tab = strchr(p,
'\t')) || p == tab)
324 tag->
name = g_strndup(p, (gsize)(tab - p));
328 if (! (tab = strchr(p,
'\t')))
336 if (*p ==
'/' || *p ==
'?')
339 for (++p; *p && *p != c; p++)
341 if (*p ==
'\\' && p[1])
352 while (*p && *p !=
'\n' && *p !=
'\r')
355 const gchar *key, *value =
NULL;
358 while (*p && *p ==
'\t') p++;
361 while (*end && *end !=
'\t' && *end !=
'\n' && *end !=
'\r')
363 if (*end ==
':' && ! value)
371 p = *end ? end + 1 : end;
374 if (! value || 0 == strcmp(key,
"kind"))
376 const gchar *kind = value ? value : key;
378 if (kind[0] && kind[1])
383 else if (0 == strcmp(key,
"inherits"))
388 else if (0 == strcmp(key,
"implementation"))
390 else if (0 == strcmp(key,
"line"))
391 tag->
line = atol(value);
392 else if (0 == strcmp(key,
"access"))
394 else if (0 == strcmp(key,
"class") ||
395 0 == strcmp(key,
"enum") ||
396 0 == strcmp(key,
"function") ||
397 0 == strcmp(key,
"struct") ||
398 0 == strcmp(key,
"union"))
401 tag->
scope = g_strdup(value);
403 else if (0 == strcmp(key,
"file"))
405 else if (0 == strcmp(key,
"signature"))
408 tag->
arglist = g_strdup(value);
420 gboolean result = FALSE;
453 fprintf(fp,
"%s", tag->
name);
475 if (fprintf(fp,
"\n"))
485 GPtrArray *file_tags;
489 if (
NULL == (fp = g_fopen(tags_file,
"r")))
491 if ((
NULL == fgets((gchar*) buf, BUFSIZ, fp)) || (
'\0' == *buf))
498 if (buf[0] ==
'#' &&
strstr((gchar*) buf,
"format=pipe") !=
NULL)
500 else if (buf[0] ==
'#' &&
strstr((gchar*) buf,
"format=tagmanager") !=
NULL)
502 else if (buf[0] ==
'#' &&
strstr((gchar*) buf,
"format=ctags") !=
NULL)
504 else if (strncmp((gchar*) buf,
"!_TAG_", 6) == 0)
510 guint i, pipe_cnt = 0, tab_cnt = 0;
511 for (i = 0; i < BUFSIZ && buf[i] !=
'\0' && pipe_cnt < 2; i++)
515 else if (buf[i] ==
'\t')
520 else if (tab_cnt > 1)
527 file_tags = g_ptr_array_new();
529 g_ptr_array_add(file_tags, tag);
541 g_return_val_if_fail(tags_array && tags_file, FALSE);
543 fp = g_fopen(tags_file,
"w");
547 fprintf(fp,
"# format=tagmanager\n");
548 for (i = 0; i < tags_array->len; i++)
573 g_message(
"Source File init: %s", file_name);
576 if (file_name !=
NULL)
578 status = g_stat(file_name, &s);
584 if (!S_ISREG(s.st_mode))
586 g_warning(
"%s: Not a regular file", file_name);
600 source_file->
lang = TM_PARSER_NONE;
625 return &
priv->public;
633 g_return_val_if_fail(
NULL != source_file,
NULL);
635 g_atomic_int_inc(&
priv->refcount);
646 g_message(
"Destroying source file: %s", source_file->
file_name);
667 if (
NULL !=
priv && g_atomic_int_dec_and_test(&
priv->refcount))
693 const char *file_name;
694 gboolean retry = TRUE;
698 g_warning(
"Attempt to parse NULL file");
702 if (source_file->
lang == TM_PARSER_NONE)
710 if (use_buffer && (
NULL == text_buf || 0 == buf_size))
720 source_file->
lang, source_file);
static GeanyProjectPrivate priv
char * strstr(const char *str, const char *substr)
The TMSourceFile structure represents the source file and its tags in the tag manager.
GPtrArray * tags_array
Sorted tag array obtained by parsing the object.
char * file_name
Full file name (inc.
char * short_name
Just the name of the file (without the path)
The TMTag structure represents a single tag in the tag manager.
char * scope
Scope of tag.
char * inheritance
Parent classes.
char * var_type
Variable type (maps to struct for typedefs)
char * arglist
Argument list (functions/prototypes/macros)
TMSourceFile * file
These are tag attributes.
gulong line
Line number of the tag.
char access
Access type (public/protected/private/etc.)
char impl
Implementation (e.g.
gboolean local
Is the tag of local scope.
TMTagType tm_parser_get_tag_type(gchar kind, TMParserType lang)
@ tm_tag_function_t
Function definition.
@ tm_tag_prototype_t
Function prototype.
void tm_source_file_free(TMSourceFile *source_file)
Decrements the reference count of source_file.
static TMSourceFile * tm_source_file_dup(TMSourceFile *source_file)
G_DEFINE_BOXED_TYPE(TMSourceFile, tm_source_file, tm_source_file_dup, tm_source_file_free)
static int get_path_max(const char *path)
GPtrArray * tm_source_file_read_tags_file(const gchar *tags_file, TMParserType mode)
TMParserType tm_source_file_get_named_lang(const gchar *name)
gchar tm_source_file_get_tag_access(const gchar *access)
static TMTag * new_tag_from_tags_file(TMSourceFile *file, FILE *fp, TMParserType mode, TMFileFormat format)
TMSourceFile * tm_source_file_new(const char *file_name, const char *name)
Initializes a TMSourceFile structure and returns a pointer to it.
static void tm_source_file_destroy(TMSourceFile *source_file)
@ TM_FILE_FORMAT_TAGMANAGER
static gboolean init_tag_from_file(TMTag *tag, TMSourceFile *file, FILE *fp)
GType tm_source_file_get_type(void)
Gets the GBoxed-derived GType for TMSourceFile.
#define SOURCE_FILE_FREE(S)
#define SOURCE_FILE_NEW(S)
gboolean tm_source_file_write_tags_file(const gchar *tags_file, GPtrArray *tags_array)
static gboolean write_tag(TMTag *tag, FILE *fp, TMTagAttrType attrs)
static gboolean init_tag_from_file_ctags(TMTag *tag, TMSourceFile *file, FILE *fp, TMParserType lang)
static gboolean init_tag_from_file_alt(TMTag *tag, TMSourceFile *file, FILE *fp)
gchar * tm_get_real_path(const gchar *file_name)
Given a file name, returns a newly allocated string containing the realpath() of the file.
gboolean tm_source_file_parse(TMSourceFile *source_file, guchar *text_buf, gsize buf_size, gboolean use_buffer)
const gchar * tm_source_file_get_lang_name(TMParserType lang)
gchar tm_source_file_get_tag_impl(const gchar *impl)
static gboolean tm_source_file_init(TMSourceFile *source_file, const char *file_name, const char *name)
The TMSourceFile structure and associated functions are used to maintain tags for individual files.
void tm_tags_array_free(GPtrArray *tags_array, gboolean free_all)
void tm_tag_unref(TMTag *tag)
#define TAG_ACCESS_FRIEND
Friend members/functions.
#define TAG_ACCESS_PROTECTED
Protected member.
#define TM_TAG(tag)
Use the TM_TAG() macro to cast a pointer to (TMTag *)
#define TAG_IMPL_VIRTUAL
Tag implementation type for functions.
#define TAG_ACCESS_UNKNOWN
Unknown access type.
#define TAG_ACCESS_PRIVATE
Private member.
#define TAG_ACCESS_DEFAULT
Default access (Java)
#define TAG_ACCESS_PUBLIC
Tag access type for C++/Java member functions and variables.
#define TAG_IMPL_UNKNOWN
Unknown implementation.
TMTagAttrType
Tag Attributes.
@ tm_tag_attr_vartype_t
Variable Type.
@ tm_tag_attr_pointer_t
Pointer type.
@ tm_tag_attr_scope_t
Scope of the tag.
@ tm_tag_attr_access_t
Access type (public/protected/private)
@ tm_tag_attr_inheritance_t
Parent classes.
@ tm_tag_attr_impl_t
Implementation (e.g.
@ tm_tag_attr_local_t
If it has local scope.
@ tm_tag_attr_arglist_t
Argument list.
@ tm_tag_attr_line_t
Line number of tag.
@ tm_tag_attr_type_t
Tag Type.