Support copying filetype definition file group keys from a system

keyfile with e.g. [styling=C].
Add function utils_make_filename() for building filenames easily.



git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@5596 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
Nick Treleaven 2011-03-17 12:17:04 +00:00
parent 18c1d6c88e
commit a46c2fd899
4 changed files with 131 additions and 17 deletions

View File

@ -1,3 +1,11 @@
2011-03-17 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
* src/utils.c, src/utils.h, src/filetypes.c:
Support copying filetype definition file group keys from a system
keyfile with e.g. [styling=C].
Add function utils_make_filename() for building filenames easily.
2011-03-15 Frank Lanitz <frank(at)frank(dot)uvena(dot)de>
* THANKS, src/about.c:

View File

@ -1155,6 +1155,72 @@ static void load_settings(gint ft_id, GKeyFile *config, GKeyFile *configh)
}
static void add_keys(GKeyFile *dest, const gchar *group, GKeyFile *src)
{
gchar **keys = g_key_file_get_keys(src, group, NULL, NULL);
gchar **ptr;
foreach_strv(ptr, keys)
{
gchar *key = *ptr;
gchar *value = g_key_file_get_value(src, group, key, NULL);
g_key_file_set_value(dest, group, key, value);
g_free(value);
}
g_strfreev(keys);
}
static void add_group_keys(GKeyFile *kf, const gchar *group, GeanyFiletype *ft)
{
GKeyFile *src = g_key_file_new();
gchar *ext = filetypes_get_conf_extension(ft->id);
const gchar *f;
f = utils_make_filename(app->datadir, "filetypes.", ext, NULL);
if (!g_file_test(f, G_FILE_TEST_EXISTS))
f = utils_make_filename(app->configdir,
GEANY_FILEDEFS_SUBDIR G_DIR_SEPARATOR_S, "filetypes.", ext, NULL);
g_free(ext);
if (!g_key_file_load_from_file(src, f, G_KEY_FILE_NONE, NULL))
{
geany_debug("Could not read config file %s for [%s=%s]!", f, group, ft->name);
return;
}
add_keys(kf, group, src);
}
static void copy_ft_groups(GKeyFile *kf)
{
gchar **groups = g_key_file_get_groups(kf, NULL);
gchar **ptr;
foreach_strv(ptr, groups)
{
gchar *group = *ptr;
gchar *name = strstr(*ptr, "=");
GeanyFiletype *ft;
if (!name)
continue;
/* terminate group at '=' */
*name = 0;
name++;
if (!name[0])
continue;
ft = filetypes_lookup_by_name(name);
if (ft)
add_group_keys(kf, group, ft);
}
g_strfreev(groups);
}
/* simple wrapper function to print file errors in DEBUG mode */
static void load_system_keyfile(GKeyFile *key_file, const gchar *file, GKeyFileFlags flags,
GeanyFiletype *ft)
@ -1201,17 +1267,18 @@ void filetypes_load_config(gint ft_id, gboolean reload)
{
/* highlighting uses GEANY_FILETYPES_NONE for common settings */
gchar *ext = filetypes_get_conf_extension(ft_id);
gchar *f0 = g_strconcat(app->datadir, G_DIR_SEPARATOR_S "filetypes.", ext, NULL);
gchar *f = g_strconcat(app->configdir,
G_DIR_SEPARATOR_S GEANY_FILEDEFS_SUBDIR G_DIR_SEPARATOR_S "filetypes.", ext, NULL);
const gchar *f;
load_system_keyfile(config, f0, G_KEY_FILE_KEEP_COMMENTS, ft);
f = utils_make_filename(app->datadir, "filetypes.", ext, NULL);
load_system_keyfile(config, f, G_KEY_FILE_KEEP_COMMENTS, ft);
f = utils_make_filename(app->configdir,
GEANY_FILEDEFS_SUBDIR G_DIR_SEPARATOR_S, "filetypes.", ext, NULL);
g_key_file_load_from_file(config_home, f, G_KEY_FILE_KEEP_COMMENTS, NULL);
g_free(ext);
g_free(f);
g_free(f0);
}
/* Copy keys for any groups with [group=C] from system keyfile */
copy_ft_groups(config);
copy_ft_groups(config_home);
load_settings(ft_id, config, config_home);
highlighting_init_styles(ft_id, config, config_home);

View File

@ -1722,6 +1722,25 @@ gboolean utils_spawn_async(const gchar *dir, gchar **argv, gchar **env, GSpawnFl
}
static gboolean utils_string_vappend(GString *buffer, const gchar *sep, va_list args)
{
const gchar *str = va_arg(args, const gchar *);
if (!str)
return FALSE;
do
{
g_string_append(buffer, str);
str = va_arg(args, const gchar *);
if (str && sep)
g_string_append(buffer, sep);
}
while (str);
return TRUE;
}
/* Similar to g_build_path() but (re)using a fixed buffer, so never free it.
* This assumes a small enough resulting string length to be kept without freeing,
* but this should be the case for filenames.
@ -1730,7 +1749,6 @@ gboolean utils_spawn_async(const gchar *dir, gchar **argv, gchar **env, GSpawnFl
const gchar *utils_build_path(const gchar *first, ...)
{
static GString *buffer = NULL;
const gchar *str;
va_list args;
if (! buffer)
@ -1738,18 +1756,37 @@ const gchar *utils_build_path(const gchar *first, ...)
else
g_string_assign(buffer, first);
g_string_append_c(buffer, G_DIR_SEPARATOR);
va_start(args, first);
while (1)
{
str = va_arg(args, const gchar *);
if (!str)
break;
g_string_append_c(buffer, G_DIR_SEPARATOR);
g_string_append(buffer, str);
}
utils_string_vappend(buffer, G_DIR_SEPARATOR_S, args);
va_end(args);
return buffer->str;
}
/* Concatenates a path with other strings.
* @param path A path, which will have a separator added before the other strings.
* @param ... Strings to concatenate (no directory separators will be
* inserted between them).
* @warning This returns temporary string contents only valid until the next call
* to this function.
* E.g. filename = utils_make_filename(app->datadir, "filetypes.", ext, NULL); */
const gchar *utils_make_filename(const gchar *path, ...)
{
static GString *buffer = NULL;
va_list args;
if (! buffer)
buffer = g_string_new(path);
else
g_string_assign(buffer, path);
g_string_append_c(buffer, G_DIR_SEPARATOR);
va_start(args, path);
utils_string_vappend(buffer, NULL, args);
va_end(args);
return buffer->str;
}

View File

@ -249,6 +249,8 @@ gint utils_str_casecmp(const gchar *s1, const gchar *s2);
const gchar *utils_build_path(const gchar *first, ...) G_GNUC_NULL_TERMINATED;
const gchar *utils_make_filename(const gchar *path, ...) G_GNUC_NULL_TERMINATED;
gchar *utils_get_path_from_uri(const gchar *uri);
gboolean utils_is_uri(const gchar *uri);