3 * Copyright (c) 2001-2002, Biswapesh Chattopadhyay
5 * This source code is released for free distribution under the terms of the
6 * GNU General Public License.
11 * @file tm_work_object.h
12 * A TMWorkObject structure is the base class for TMSourceFile and TMProject.
15 #include "general.h" /* must always come first */
22 #include <glib/gstdio.h>
25 # define WIN32_LEAN_AND_MEAN
26 # include <windows.h> /* for GetFullPathName */
30 #include "tm_work_object.h"
32 static GPtrArray
*s_work_object_subclasses
= NULL
;
35 static int get_path_max(const char *path
)
40 int path_max
= pathconf(path
, _PC_PATH_MAX
);
49 /* realpath implementation for Windows found at http://bugzilla.gnome.org/show_bug.cgi?id=342926
50 * this one is better than e.g. liberty's lrealpath because this one uses Win32 API and works
51 * with special chars within the filename */
52 static char *realpath (const char *pathname
, char *resolved_path
)
56 if (resolved_path
!= NULL
)
58 int path_max
= get_path_max(pathname
);
59 size
= GetFullPathNameA (pathname
, path_max
, resolved_path
, NULL
);
67 size
= GetFullPathNameA (pathname
, 0, NULL
, NULL
);
68 resolved_path
= g_new0 (char, size
);
69 GetFullPathNameA (pathname
, size
, resolved_path
, NULL
);
75 gchar
*tm_get_real_path(const gchar
*file_name
)
79 gsize len
= get_path_max(file_name
) + 1;
80 gchar
*path
= g_malloc0(len
);
82 if (realpath(file_name
, path
))
90 guint
tm_work_object_register(GFreeFunc free_func
, TMUpdateFunc update_func
, TMFindFunc find_func
)
92 TMWorkObjectClass
*object_class
;
93 if (NULL
== s_work_object_subclasses
)
95 s_work_object_subclasses
= g_ptr_array_new();
96 object_class
= g_new(TMWorkObjectClass
, 1);
97 object_class
->free_func
= tm_work_object_free
;
98 object_class
->update_func
= NULL
;
99 object_class
->find_func
= NULL
;
100 g_ptr_array_add(s_work_object_subclasses
, object_class
);
102 object_class
= g_new(TMWorkObjectClass
, 1);
103 object_class
->free_func
= free_func
;
104 object_class
->update_func
= update_func
;
105 object_class
->find_func
= find_func
;
106 g_ptr_array_add(s_work_object_subclasses
, object_class
);
107 return (s_work_object_subclasses
->len
- 1);
110 gboolean
tm_work_object_init(TMWorkObject
*work_object
, guint type
, const char *file_name
116 if (file_name
!= NULL
)
118 if (0 != (status
= g_stat(file_name
, &s
)))
123 if (NULL
== (f
= g_fopen(file_name
, "a+")))
125 g_warning("Unable to create file %s", file_name
);
129 status
= g_stat(file_name
, &s
);
134 /* g_warning("Unable to stat %s", file_name);*/
137 if (!S_ISREG(s
.st_mode
))
139 g_warning("%s: Not a regular file", file_name
);
142 work_object
->file_name
= tm_get_real_path(file_name
);
143 work_object
->short_name
= strrchr(work_object
->file_name
, '/');
144 if (work_object
->short_name
)
145 ++ work_object
->short_name
;
147 work_object
->short_name
= work_object
->file_name
;
151 work_object
->file_name
= NULL
;
152 work_object
->short_name
= NULL
;
154 work_object
->type
= type
;
155 work_object
->parent
= NULL
;
156 work_object
->analyze_time
= 0;
157 work_object
->tags_array
= NULL
;
162 time_t tm_get_file_timestamp(const char *file_name)
166 g_return_val_if_fail(file_name, 0);
168 if (0 != g_stat(file_name, &s))
176 gboolean tm_work_object_is_changed(TMWorkObject *work_object)
178 return (gboolean) (work_object->analyze_time < tm_get_file_timestamp(work_object->file_name));
182 TMWorkObject
*tm_work_object_new(guint type
, const char *file_name
, gboolean create
)
184 TMWorkObject
*work_object
= g_new(TMWorkObject
, 1);
185 if (!tm_work_object_init(work_object
, type
, file_name
, create
))
193 void tm_work_object_destroy(TMWorkObject
*work_object
)
197 g_free(work_object
->file_name
);
198 if (work_object
->tags_array
)
199 g_ptr_array_free(work_object
->tags_array
, TRUE
);
203 void tm_work_object_free(gpointer work_object
)
205 if (NULL
!= work_object
)
207 TMWorkObject
*w
= (TMWorkObject
*) work_object
;
208 if ((w
->type
> 0) && (w
->type
< s_work_object_subclasses
->len
) &&
209 (s_work_object_subclasses
->pdata
[w
->type
] != NULL
))
211 GFreeFunc free_func
=
212 ((TMWorkObjectClass
*)s_work_object_subclasses
->pdata
[w
->type
])->free_func
;
213 if (NULL
!= free_func
)
214 free_func(work_object
);
217 tm_work_object_destroy(w
);
222 void tm_work_object_write_tags(TMWorkObject
*work_object
, FILE *file
, guint attrs
)
224 if (NULL
!= work_object
->tags_array
)
227 for (i
=0; i
< work_object
->tags_array
->len
; ++i
)
228 tm_tag_write((TMTag
*) g_ptr_array_index(work_object
->tags_array
, i
)
229 , file
, (TMTagAttrType
) attrs
);
233 gboolean
tm_work_object_update(TMWorkObject
*work_object
, gboolean force
234 , gboolean recurse
, gboolean update_parent
)
236 if ((NULL
!= work_object
) && (work_object
->type
> 0) &&
237 (work_object
->type
< s_work_object_subclasses
->len
) &&
238 (s_work_object_subclasses
->pdata
[work_object
->type
] != NULL
))
240 TMUpdateFunc update_func
=
241 ((TMWorkObjectClass
*)s_work_object_subclasses
->pdata
[work_object
->type
])->update_func
;
242 if (NULL
!= update_func
)
243 return update_func(work_object
, force
, recurse
, update_parent
);
248 TMWorkObject
*tm_work_object_find(TMWorkObject
*work_object
, const char *file_name
249 , gboolean name_only
)
251 if ((NULL
!= work_object
) && (work_object
->type
> 0) &&
252 (work_object
->type
< s_work_object_subclasses
->len
) &&
253 (s_work_object_subclasses
->pdata
[work_object
->type
] != NULL
))
255 TMFindFunc find_func
=
256 ((TMWorkObjectClass
*)s_work_object_subclasses
->pdata
[work_object
->type
])->find_func
;
257 if (NULL
== find_func
)
261 const char *short_name
= strrchr(file_name
, '/');
265 short_name
= file_name
;
266 if (0 == strcmp(work_object
->short_name
, short_name
))
273 char *path
= tm_get_real_path(file_name
);
274 int cmp
= strcmp(work_object
->file_name
, file_name
);
283 return find_func(work_object
, file_name
, name_only
);
288 void tm_work_object_dump(const TMWorkObject
*w
)
292 fprintf(stderr
, "%s", w
->file_name
);
294 fprintf(stderr
, " <- %s\n", w
->parent
->file_name
);
296 fprintf(stderr
, " <- NULL\n");