LINUX.ORG.RU

История изменений

Исправление 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);
    }