История изменений
Исправление wandrien, (текущая версия) :
Или вот пример:
gchar * su_path_resolve_agent_id_by_path(const char * path, const char * default_id)
{
if (!path)
return g_strdup(default_id);
if (!(_get_res_flags() & RES_AUTODETECTED_DIR))
return g_strdup(default_id);
const char * pattern = "/" AGENT_SPECIFIC_RESOURCE "/";
const char * s = g_strstr_len(path, -1, pattern);
if (s)
{
s = s + strlen(pattern);
const char * end = g_strstr_len(s, -1, "/");
if (end)
{
size_t agent_id_size = end - s;
size_t prefix_size = end - path;
gchar * agent_id = g_strndup(s, agent_id_size);
gchar * prefix = g_strndup(path, prefix_size);
if (!autodetected_agent_prefix_table)
{
autodetected_agent_prefix_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
}
g_hash_table_insert(autodetected_agent_prefix_table, agent_id, prefix);
su_log_debug("path %s autodetected as agent %s with prefix %s\n", path, agent_id, prefix);
return g_strdup(agent_id);
}
}
return g_strdup(default_id);
}
Здесь если писать по правилам C89, то переменные pattern
, s
и end
(да-да), должны быть объявлены в начале функции. Ну или другой вариант - заворачивать всё в многоэтажные блоки, но так никто в здравом уме не делает, понятно.
А если перед объявлением agent_id_size
мне потребуется дописать хоть строчку кода, то и тут тоже придётся переколбашивать всё.
А вот пример, где действительно полезно деление функции на блоки:
/* overall history */
{
overall_nav_history_initialize();
GtkWidget* mi = gtk_ui_manager_get_widget(ui, "/menubar/GoMenu/RecentlyVisitedMenu");
win->overall_nav_history_menu = GTK_WIDGET(gtk_menu_item_get_submenu(GTK_MENU_ITEM(mi)));
}
/* load bookmarks menu */
load_bookmarks(win, ui);
/* file menu */
{
GtkWidget * mi = gtk_ui_manager_get_widget(ui, "/menubar/EditMenu/FileMenu");
win->file_menu_item = GTK_MENU_ITEM(mi);
GtkWidget * ancestor_menu_item = gtk_ui_manager_get_widget(ui, "/menubar/EditMenu");
g_signal_connect(ancestor_menu_item, "select", G_CALLBACK(on_file_menu_item_ancestor_select), win);
}
Исходная версия wandrien, :
Или вот пример:
gchar * su_path_resolve_agent_id_by_path(const char * path, const char * default_id)
{
if (!path)
return g_strdup(default_id);
if (!(_get_res_flags() & RES_AUTODETECTED_DIR))
return g_strdup(default_id);
const char * pattern = "/" AGENT_SPECIFIC_RESOURCE "/";
const char * s = g_strstr_len(path, -1, pattern);
if (s)
{
s = s + strlen(pattern);
const char * end = g_strstr_len(s, -1, "/");
if (end)
{
size_t agent_id_size = end - s;
size_t prefix_size = end - path;
gchar * agent_id = g_strndup(s, agent_id_size);
gchar * prefix = g_strndup(path, prefix_size);
if (!autodetected_agent_prefix_table)
{
autodetected_agent_prefix_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
}
g_hash_table_insert(autodetected_agent_prefix_table, agent_id, prefix);
su_log_debug("path %s autodetected as agent %s with prefix %s\n", path, agent_id, prefix);
return g_strdup(agent_id);
}
}
return g_strdup(default_id);
}
Здесь если писать по правилам C89, то переменные pattern
, s
и end
(да-да), должны быть объявлены в начали функции. Ну или другой вариант - заворачивать всё в многоэтажные блоки, но так никто в здравом уме не делает, понятно.
А если перед объявлением agent_id_size
мне потребуется дописать хоть строчку кода, то и тут тоже придётся переколбашивать всё.
А вот пример, где действительно полезно деление функции на блоки:
/* overall history */
{
overall_nav_history_initialize();
GtkWidget* mi = gtk_ui_manager_get_widget(ui, "/menubar/GoMenu/RecentlyVisitedMenu");
win->overall_nav_history_menu = GTK_WIDGET(gtk_menu_item_get_submenu(GTK_MENU_ITEM(mi)));
}
/* load bookmarks menu */
load_bookmarks(win, ui);
/* file menu */
{
GtkWidget * mi = gtk_ui_manager_get_widget(ui, "/menubar/EditMenu/FileMenu");
win->file_menu_item = GTK_MENU_ITEM(mi);
GtkWidget * ancestor_menu_item = gtk_ui_manager_get_widget(ui, "/menubar/EditMenu");
g_signal_connect(ancestor_menu_item, "select", G_CALLBACK(on_file_menu_item_ancestor_select), win);
}