diff --git a/HACKING b/HACKING index 50971e64c6..531f0748f4 100644 --- a/HACKING +++ b/HACKING @@ -214,11 +214,15 @@ Coding to will not be mutated within the function. * Don't let variable names shadow outer variables - use gcc's -Wshadow option. -* Use the strictest possible data type where practical. For example - for an enumeration, use the actual enum type rather than just a +* Use the strictest possible data type where practical. + Avoid using untyped pointers (e.g. gpointer) where practical. + For an enumeration, use the actual enum type rather than just a ``gint``, use a ``gchar`` for individual (ASCII/UTF-8) string characters rather than ``gint``, and use a ``guint`` for integers which cannot be negative rather than ``gint``. +* Prefer loops to calling ``some_type_foreach()`` with a ``user_data`` + argument. (Note: Some containers don't support external iteration, + e.g. for tree structures, so *_foreach is fine for those). * Do not use G_LIKELY or G_UNLIKELY (except in critical loops). These add noise to the code with little real benefit. diff --git a/src/build.c b/src/build.c index 2774d88694..4badf9a410 100644 --- a/src/build.c +++ b/src/build.c @@ -2510,41 +2510,29 @@ static guint build_save_menu_grp(GKeyFile *config, GeanyBuildCommand *src, gint } -typedef struct ForEachData +static gboolean save_project_filetype(GeanyFiletype *ft, GKeyFile *config) { - GKeyFile *config; - GPtrArray *ft_names; -} ForEachData; - - -static void foreach_project_filetype(gpointer data, gpointer user_data) -{ - GeanyFiletype *ft = data; - ForEachData *d = user_data; guint i = 0; gchar *regkey = g_strdup_printf("%serror_regex", ft->name); - i += build_save_menu_grp(d->config, ft->priv->projfilecmds, GEANY_GBG_FT, ft->name); - i += build_save_menu_grp(d->config, ft->priv->projexeccmds, GEANY_GBG_EXEC, ft->name); + i += build_save_menu_grp(config, ft->priv->projfilecmds, GEANY_GBG_FT, ft->name); + i += build_save_menu_grp(config, ft->priv->projexeccmds, GEANY_GBG_EXEC, ft->name); if (!EMPTY(ft->priv->projerror_regex_string)) { - g_key_file_set_string(d->config, build_grp_name, regkey, ft->priv->projerror_regex_string); + g_key_file_set_string(config, build_grp_name, regkey, ft->priv->projerror_regex_string); i++; } else - g_key_file_remove_key(d->config, build_grp_name, regkey, NULL); + g_key_file_remove_key(config, build_grp_name, regkey, NULL); g_free(regkey); - if (i > 0) - g_ptr_array_add(d->ft_names, ft->name); + return (i > 0); } - /* TODO: untyped ptr is too ugly (also for build_load_menu) */ void build_save_menu(GKeyFile *config, gpointer ptr, GeanyBuildSource src) { GeanyFiletype *ft; GeanyProject *pj; - ForEachData data; switch (src) { @@ -2577,15 +2565,21 @@ void build_save_menu(GKeyFile *config, gpointer ptr, GeanyBuildSource src) g_key_file_remove_key(config, build_grp_name, "error_regex", NULL); if (pj->priv->build_filetypes_list != NULL) { - data.config = config; - data.ft_names = g_ptr_array_new(); - g_ptr_array_foreach(pj->priv->build_filetypes_list, foreach_project_filetype, (gpointer)(&data)); - if (data.ft_names->pdata != NULL) + GPtrArray *ft_names = g_ptr_array_new(); + const GPtrArray *build_fts = pj->priv->build_filetypes_list; + + for (guint i = 0; i < build_fts->len; i++) + { + ft = build_fts->pdata[i]; + if (save_project_filetype(ft, config)) + g_ptr_array_add(ft_names, ft->name); + } + if (ft_names->pdata != NULL) g_key_file_set_string_list(config, build_grp_name, "filetypes", - (const gchar**)(data.ft_names->pdata), data.ft_names->len); + (const gchar**)ft_names->pdata, ft_names->len); else g_key_file_remove_key(config, build_grp_name, "filetypes", NULL); - g_ptr_array_free(data.ft_names, TRUE); + g_ptr_array_free(ft_names, TRUE); } break; default: /* defaults and GEANY_BCS_FT can't save */