Subversion Repositories pub

Compare Revisions

Ignore whitespace Rev 22 → Rev 23

/nautilus-follow-symlink/trunk/src/follow-symlink.c
33,7 → 33,7
// TODO: what about GnomeVFSFileInfo's is_local ?
gchar * uri_scheme = nautilus_file_info_get_uri_scheme(file_info);
if (strcmp(uri_scheme, "file") != 0) {
FSL_LOG( "Not file scheme" );
FSL_LOG1( "Not file scheme" );
return NULL;
}
g_free(uri_scheme);
49,7 → 49,7
g_assert( (gfi->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_FLAGS) > 0 );
 
if ( (gfi->flags & GNOME_VFS_FILE_FLAGS_SYMLINK) == 0 ) {
FSL_LOG1("GnomeVFS Flags: ! SYMLINK: ", nautilus_file_info_get_uri(file_info));
FSL_LOG("GnomeVFS Flags: ! SYMLINK in %s", nautilus_file_info_get_uri(file_info));
return NULL;
}
 
62,7 → 62,7
}
 
GList *
fsl_get_background_items(NautilusMenuProvider * provider,
fsl_get_background_items(NautilusMenuProvider * provider __unused,
GtkWidget * window,
NautilusFileInfo * current_folder)
{
69,13 → 69,13
TRACE();
 
if (NULL == current_folder) { // XXX: Does this ever happen?
FSL_LOG( "No folder selected" );
FSL_LOG1( "No folder selected");
}
return fsl_get_items_impl(window, current_folder, FALSE, NULL);
}
 
 
gboolean file_is_directory (gpointer file_data)
gboolean file_is_directory (const gpointer const file_data)
{
TRACE();
 
87,11 → 87,14
return gfi->type == GNOME_VFS_FILE_TYPE_DIRECTORY;
}
 
/* Bind to menu if needed */
GList *
fsl_get_file_items (NautilusMenuProvider * provider,
GtkWidget * window,
GList * files)
/*
* Bind to the menu if needed
*
*
*/
GList * fsl_get_file_items (NautilusMenuProvider * provider __unused,
GtkWidget * window,
GList * files)
{
TRACE();
 
98,34 → 101,24
// Number of files = g_list_length(files)
// Directory = nautilus_file_info_is_directory(files->data)
if (NULL == files) {
FSL_LOG("No file selected");
FSL_LOG1("No file selected");
return NULL;
}
 
assert( g_list_length(files) > 0 );
 
if (g_list_length(files) == 1) {
if (!file_is_directory(files->data)) {
FSL_LOG("File is not a directory");
return NULL;
}
return fsl_get_items_impl(window, files->data, TRUE, NULL);
}
FSL_LOG_COND( g_list_length(files) > 1, "More than one file selected (%d)", g_list_length(files) );
 
// More than one selected file
assert( g_list_length(files) > 1 );
 
FSL_LOG( "More than one file selected" );
 
GList * items = NULL;
 
for (int i=0; i<g_list_length(files); ++i) {
const gpointer file_info = g_list_nth_data(files, i);
if (!file_is_directory(file_info)) {
FSL_LOG_SPRINTF1 ( "File %s is not a directory, discarded\n",
nautilus_file_info_get_name(file_info) );
FSL_LOG ( "File %s is not a directory, discarded",
nautilus_file_info_get_name(file_info) );
continue;
}
FSL_LOG_SPRINTF1( "%s is a directory\n", nautilus_file_info_get_name(file_info) );
FSL_LOG( "%s is a directory", nautilus_file_info_get_name(file_info) );
// TODO: Am I loosing memory?
GList * ret = fsl_get_items_impl(window, file_info, TRUE, items);
if (NULL != ret) {
133,13 → 126,15
}
}
 
// TODO: Although items might contain more than one item only the last one is displayed
// why?
 
return items;
}
 
void fsl_callback (NautilusMenuItem * item, NautilusFileInfo * file_info)
/*
* Opens the real path of the symbolic link
*
* file_info: The symbolic link
*/
void fsl_callback (NautilusMenuItem * item __unused, NautilusFileInfo * file_info)
{
TRACE();
 
146,7 → 141,7
gchar ** argv;
const GnomeVFSFileInfo * gfi = nautilus_file_info_get_vfs_file_info(file_info);
// See /usr/include/gnome-vfs-2.0/libgnomevfs/gnome-vfs-file-info.h,
// this one is the "realpath()" (3), also it isn0t urlencoded
// this one is the "realpath()" (3), also it isn't urlencoded
const gchar const * target = gfi->symlink_name;
 
const gchar const * BASE_CMD = "nautilus --no-desktop --no-default-window '%s'";
159,12 → 154,9
 
g_printf("nautilus-follow-symlink: Spawning nautilus with\n '%s'\n", command_line);
 
const gchar * cwd = ".";
// FIXME: const gchar * cwd = nautilus_file_info_get_parent_uri(file_info) + URI_OFFSET;
// TODO: does the cwd used for spawn have any side-effect ?
FSL_LOG_SPRINTF1 ("\tusing pwd=%s\n", cwd );
 
g_spawn_async( cwd,
g_spawn_async( ".",
argv,
NULL,
G_SPAWN_SEARCH_PATH,
173,9 → 165,17
g_free(command_line);
g_strfreev(argv);
}
/* Create the new menu item */
NautilusMenuItem *
fsl_menu_item_new(GdkScreen *screen, gboolean is_file_item, const gchar * base_name)
 
/*
* Creates the new menu item
*
* is_file_item: TRUE if we're working over a (selected) file, FALSE if working
* over a (opened) folder
* base_name: file name, without path, of the given file
*/
NautilusMenuItem * fsl_menu_item_new(GdkScreen *screen __unused,
gboolean is_file_item,
const gchar * base_name)
{
TRACE();
 
205,17 → 205,16
g_sprintf(tooltip, fmt_tooltip, base_name);
}
 
// Trial and error shows that the menu item name must be different
// Trial and error showed that the menu item name must be different
// when various are to be shown, and also that the name should always be
// the same for a given file
static const gchar * ITEM_NAME_FMT = "FsymlinkExtension::follow_symlink_%s";
// TODO: Check g_alloca() error conditions
gchar * unique_name = g_alloca(strlen(ITEM_NAME_FMT) + strlen(base_name)); // 10 = strlen("4294967296"));
static const gchar * const ITEM_NAME_FMT = "FsymlinkExtension::follow_symlink_%s";
gchar * unique_name = g_malloc(strlen(ITEM_NAME_FMT) + strlen(base_name));
g_sprintf(unique_name, ITEM_NAME_FMT, base_name);
// (name, label, tip, icon)
ret = nautilus_menu_item_new(//"FsymlinkExtension::follow_symlink",
unique_name,
name, tooltip, NULL);
ret = nautilus_menu_item_new(unique_name, name, tooltip, FSL_ICON);
 
g_free(unique_name);
g_free(name);
g_free(tooltip);
 
/nautilus-follow-symlink/trunk/src/nautilus-ext-follow-symlink.c
16,7 → 16,10
g_printf("Initializing nautilus-follow-symlink extension (v.%s)\n", VERSION);
 
fsl_register_type(module);
# if 0
provider_types[0] = fsl_get_type();
#endif
provider_types[0] = fsl_type;
}
 
void nautilus_module_shutdown (void)
35,7 → 38,7
*num_types = G_N_ELEMENTS(provider_types);
}
 
void fsl_register_type (GTypeModule *module)
void fsl_register_type (GTypeModule * module)
{
TRACE();
 
43,18 → 46,19
sizeof(FsymlinkExtensionClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) fsl_class_init,
//TODO: Does nullifyng this have side effects?
NULL, //(GClassInitFunc) fsl_class_init,
NULL,
NULL,
sizeof (FsymlinkExtension),
0,
(GInstanceInitFunc) fsl_instance_init,
NULL, //(GInstanceInitFunc) fsl_instance_init,
};
 
fsl_type = g_type_module_register_type (module,
G_TYPE_OBJECT,
"FsymlinkExtension",
&info, 0);
G_TYPE_OBJECT,
"FsymlinkExtension",
&info, 0);
/* Menu provider interface */
static const GInterfaceInfo menu_provider_iface_info = {
(GInterfaceInitFunc)fsl_extension_menu_provider_iface_init,
68,6 → 72,7
/* Other Interfaces */
}
 
#if 0
GType fsl_get_type(void)
{
TRACE();
74,8 → 79,10
 
return fsl_type;
}
#endif
 
void fsl_instance_init(FsymlinkExtension *cvs)
#if 0
void fsl_instance_init(FsymlinkExtension *instance)
{
TRACE();
}
84,5 → 91,6
{
TRACE();
}
#endif
 
/* vim:set ts=4 et ai: */
/nautilus-follow-symlink/trunk/src/follow-symlink.h
19,15 → 19,24
 
static void fsl_callback(NautilusMenuItem *, NautilusFileInfo *);
 
static GList * fsl_get_file_items(NautilusMenuProvider *, GtkWidget *, GList *);
// This signature can't be changed
static GList * fsl_get_file_items(NautilusMenuProvider *,
GtkWidget *,
GList *);
 
static GList * fsl_get_background_items(NautilusMenuProvider *, GtkWidget *, NautilusFileInfo *);
// This signature can't be changed
static GList * fsl_get_background_items(NautilusMenuProvider *,
GtkWidget *,
NautilusFileInfo *);
 
static __inline GList * fsl_get_items_impl(GtkWidget *, NautilusFileInfo *, gboolean,GList*);
static inline GList * fsl_get_items_impl(GtkWidget *,
NautilusFileInfo *,
gboolean,
GList *);
 
static NautilusMenuItem * fsl_menu_item_new(GdkScreen *, gboolean, const gchar *);
 
static __inline gboolean file_is_directory(gpointer);
static inline __pure gboolean file_is_directory(const gpointer const);
 
/* Exported Prototypes
* Here the namespace is a bit more explicit just in case
/nautilus-follow-symlink/trunk/src/nautilus-ext-follow-symlink.h
26,7 → 26,9
 
static void fsl_register_type(GTypeModule *);
 
static GType fsl_get_type(void);
#if 0
static __constfn GType fsl_get_type(void);
#endif
 
/* Data Types */
 
42,10 → 44,12
 
typedef struct _FsymlinkExtension FsymlinkExtension;
 
/* Data initializers */
/* Data initializers, not really needed */
#if 0
static void fsl_class_init (FsymlinkExtensionClass *class);
 
static void fsl_instance_init (FsymlinkExtension *cvs);
#endif
 
/* Defined in the private interface */
extern void fsl_extension_menu_provider_iface_init(NautilusMenuProviderIface *iface);
/nautilus-follow-symlink/trunk/src/common.h
12,6 → 12,10
#include <stdlib.h> /* getenv() (3) */
#include <string.h> /* strcmp() (3) */
 
#ifdef _DEBUG
#include <stdarg.h> /* va_list, va_start ... */
#endif
 
#include "libintl.h"
#define _(STR) gettext(STR)
 
26,49 → 30,174
#define __inline
#endif
 
#if !defined(__fsl_unused)
// Xref: http://rlove.org/log/2005102601
#if __GNUC__ >= 3
#define __fsl_unused __attribute__ ((unused))
#else
#define __fsl_unused
#endif
// Based on : http://rlove.org/log/2005102601
#if __GNUC__ >= 3
#define inline inline __attribute__((always_inline))
#define __pure __attribute__((pure))
//#define __const __attribute__((const)) // fails
#define __constfn __attribute__((const))
#define __noreturn __attribute__((noreturn))
#define __malloc __attribute__((malloc))
#define __must_check __attribute__((warn_unused_result))
#define __deprecated __attribute__((deprecated))
#define __used __attribute__((used))
#define __unused __attribute__((unused))
#define __packed __attribute__((packed))
#define likely(x) __builtin_expect (!!(x), 1)
#define unlikely(x) __builtin_expect (!!(x), 0)
 
/* These are mine: used to hint the compiler in variadic printf-like
* functions, this way it will warn if format/arguments are incorrect */
/* printf-like variadic arguments (format is first, args from second) */
#define __va_printf __attribute__((format(printf, 1, 2)))
/* fprintf-like variadic arguments (format is second, args from third */
#define __va_fprintf __attribute__((format(printf, 2, 3)))
#else
#define inline /* no inline */
#define __pure /* no pure */
#define __constfn /* no const */
#define __noreturn /* no noreturn */
#define __malloc /* no malloc */
#define __must_check /* no warn_unused_result */
#define __deprecated /* no deprecated */
#define __used /* no used */
#define __unused /* no unused */
#define __packed /* no packed */
#define likely(x) (x)
#define unlikely(x) (x)
 
#define __va_printf
#define __va_fprintf
#endif
 
/*
* Uber-anal glib usage: disallow stdlib's functions where glib provides
* their own
*/
#if 0 && __GNUC__
#pragma GCC poison printf sprintf
#endif
 
#ifdef _DEBUG
/* Debugging facilities */
 
/* Prefix for messages */
#define FSL_ "nautilus-follow-symlink: "
/* Environment variable, set to 1 to enable verbosity */
#define DBGENV_ (getenv("FSL_DBG"))
/* Check on runtime the environment variable's value */
#define DEBUG_ON_() (DBGENV_ != NULL && 0 == strcmp(DBGENV_,"1"))
 
/* Informational message shown on initialisation */
#define FSL_DEBUG_INIT() { \
const int ENABLED = DEBUG_ON_(); \
g_print( FSL_ "DEBUG mode is available, and "); \
g_print( (ENABLED) ? "enabled.\n" : "disabled.\n"); \
g_print( FSL_ "set the environment variable FSL_DBG to \n" \
FSL_ "1 to enable it or to any other value to disable it.\n"); \
enum {
FINE = 1,
FINER,
 
TRACE = FINER,
};
 
/* Check on runtime the environment variable's value
*
* (set to 1 to enable verbosity, to 2 for extra verbosity)
*/
static inline int VERBOSITY_LEVEL(void)
{
const char * const DBGENV = getenv("FSL_DBG");
if (NULL == DBGENV || 0 == strcmp(DBGENV, "0")) {
return 0;
}
else if (0 == strcmp(DBGENV, "2")) {
return 2;
}
return 1;
}
 
/* Informational message shown on initialisation */
static inline void FSL_DEBUG_INIT(void)
{
g_print( FSL_ "DEBUG mode is available, and ");
g_printf(" set to %d.\n", VERBOSITY_LEVEL());
g_print( FSL_ "set the environment variable FSL_DBG to \n"
FSL_ "1 to enable it or to any other value to disable it.\n");
}
 
/* Display the name of the current function name */
#define TRACE() if (DEBUG_ON_())\
g_printf("nautilus-follow-symlink trace: %s()\n", __FUNCTION__);
/* Display a message */
#define FSL_LOG(str) if (DEBUG_ON_()) g_printf("%s\n", (str));
/* Display a formatted message with one string argument */
#define FSL_LOG1(str1, str2) if (DEBUG_ON_()) g_printf("%s %s\n", (str1), (str2));
#define FSL_LOG_SPRINTF1(s1, s2) if (DEBUG_ON_()) g_printf((s1), (s2));
#define TRACE() FSL_LOG_WITH_LEVEL(TRACE, FSL_ "trace: %s()", __func__);
 
/*
* Display a log message with a given log level if the level
* is at least VERBOSITY_LEVEL().
* Same as FSL_LOG_WITH_LEVEL but taking a va_list, this function
* provides the implementation used by the other FSL_LOG_*'s
*/
static inline void __unused FSL_LOG_WITH_LEVEL_IMPL(int level,
gchar * const format,
va_list ap)
{
if (VERBOSITY_LEVEL() >= level) {
g_vprintf(format, ap);
g_print("\n");
}
}
 
/*
* Display a log message with a given log level if the level
* is at least VERBOSITY_LEVEL().
*/
static void __unused __va_fprintf FSL_LOG_WITH_LEVEL(int level,
gchar * const format,
...)
{
va_list ap;
va_start(ap, format);
 
FSL_LOG_WITH_LEVEL_IMPL(level, format, ap);
 
va_end(ap);
}
 
/* Display a message
*
* NOTE: Variadic functions can't be inlined
*/
static void __unused __va_printf FSL_LOG(gchar * const format, ...)
{
va_list ap;
va_start(ap, format);
 
FSL_LOG_WITH_LEVEL_IMPL(FINE, format, ap);
 
va_end(ap);
}
 
/* Display a message if a condition is true
*
* NOTE: Variadic functions can't be inlined
*/
static void __unused __va_fprintf FSL_LOG_COND(int cond, gchar * const format, ...)
{
if (cond) {
va_list ap;
va_start(ap, format);
 
FSL_LOG_WITH_LEVEL_IMPL(FINE, format, ap);
 
va_end(ap);
}
}
 
/* see below for an explanation */
#define FSL_LOG1(s) FSL_LOG(s)
#else
/* Debugging facilities disabled */
#define FINE
#define FINER
#define TRACE()
#define FSL_LOG(a)
#define FSL_LOG1(a,b)
#define FSL_DEBUG_INIT()
#define FSL_LOG_SPRINTF1(a,b)
/* With variadic functions there's no way (AFAIK) to provide empty
* alternative macros that won't raise a compiler error if no variable
* arguments are given, hence this hackish FSL_LOG1, for the cases
* in which just an argument is used
*/
#define FSL_LOG1(s)
#define FSL_LOG(f, ...)
///* Unneeded for the time being */ #define FSL_LOG_WITH_LEVEL(l,f,rest...)
#define FSL_LOG_COND(c,f,...)
#endif
 
#endif /* FOLLOW_SYMLINK_COMMON_H */