История изменений
Исправление firkax, (текущая версия) :
gchar * su_path_resolve_agent_id_by_path(const char *path, const char *default_id) {
char const *pattern, *s, *end;
gchar *agent_id, *prefix;
if(!path) return g_strdup(default_id);
if(!(_get_res_flags() & RES_AUTODETECTED_DIR)) return g_strdup(default_id);
pattern = "/" AGENT_SPECIFIC_RESOURCE "/";
if(s = g_strstr_len(path, -1, pattern)) {
s += strlen(pattern);
if(end = g_strstr_len(s, -1, "/")) {
agent_id = g_strndup(s, end-s);
prefix = g_strndup(path, end-path);
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);
}
Чего плохого переставить pattern, s, end в начало? Я и agent_id_size и prefix_size собирался, но при ближайшем рассмотрении оказалось что они тавтологические и ненужные, вообще от них избавился. а вот agent_id и prefix перенёс, хотя их и можно было оставить в блоке, но незачем - этот блок по сути основное содержание функции, и его переменные = переменные функции.
А если перед объявлением agent_id_size мне потребуется дописать хоть строчку кода, то и тут тоже придётся переколбашивать всё.
Ну и эта проблема тоже исчезла сама собой.
А теперь сравни исходную простыню, которая у меня даже к экран (15" 768) не влезла и таким образом затруднительно всю её логику оценить одним взглядом (хотя признаюсь не влезло всего несколько строк), и компактный красивый код всего на полстраницы после переделки.
Кстати if(!autodetected_agent_prefix_table) просится сократиться в однострочник но уж слишком длинно получается - перестаёт влезать по горизонтали (да и имя переменной слишком длинное, сократить бы его), не совсем комфортно. Хотя может это потому что я не знаю что он делает. Всякие «залогировать ошибку и вернуть NULL» я спокойно за правую границу экрана отправляю чтобы не засоряли вертикальное пространство экрана с полезной логикой.
Кстати ещё, strstr()+strlen() хорошо бы объединить в единую функцию и тогда нужда в переменной pattern отпадёт. Хотя на самом деле нужды и так нет, это же статическая константа.
Исправление firkax, :
gchar * su_path_resolve_agent_id_by_path(const char *path, const char *default_id) {
char const *pattern, *s, *end;
gchar *agent_id, *prefix;
if(!path) return g_strdup(default_id);
if(!(_get_res_flags() & RES_AUTODETECTED_DIR)) return g_strdup(default_id);
pattern = "/" AGENT_SPECIFIC_RESOURCE "/";
if(s = g_strstr_len(path, -1, pattern)) {
s += strlen(pattern);
if(end = g_strstr_len(s, -1, "/")) {
agent_id = g_strndup(s, end-s);
prefix = g_strndup(path, end-path);
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);
}
Чего плохого переставить pattern, s, end в начало? Я и agent_id_size и prefix_size собирался, но при ближайшем рассмотрении оказалось что они тавтологические и ненужные, вообще от них избавился. а вот agent_id и prefix перенёс, хотя их и можно было оставить в блоке, но незачем - этот блок по сути основное содержание функции, и его переменные = переменные функции.
А если перед объявлением agent_id_size мне потребуется дописать хоть строчку кода, то и тут тоже придётся переколбашивать всё.
Ну и эта проблема тоже исчезла сама собой.
А теперь сравни исходную простыню, которая у меня даже к экран (15" 768) не влезла и таким образом затруднительно всю её логику оценить одним взглядом (хотя признаюсь не влезло всего несколько строк), и компактный красивый код всего на полстраницы после переделки.
Кстати if(!autodetected_agent_prefix_table) просится сократиться в однострочник но уж слишком длинно получается - перестаёт влезать по горизонтали (да и имя переменной слишком длинное, сократить бы его), не совсем комфортно. Хотя может это потому что я не знаю что он делает. Всякие «залогировать ошибку и вернуть NULL» я спокойно за правую границу экрана отправляю чтобы не засоряли вертикальное пространство экрана с полезной логикой.
Исходная версия firkax, :
gchar * su_path_resolve_agent_id_by_path(const char *path, const char *default_id) {
char const *pattern, *s, *end;
gchar *agent_id, *prefix;
if(!path) return g_strdup(default_id);
if(!(_get_res_flags() & RES_AUTODETECTED_DIR)) return g_strdup(default_id);
pattern = "/" AGENT_SPECIFIC_RESOURCE "/";
if(s = g_strstr_len(path, -1, pattern)) {
s += strlen(pattern);
if(end = g_strstr_len(s, -1, "/")) {
agent_id = g_strndup(s, end-s);
prefix = g_strndup(path, end-path);
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);
}
Чего плохого переставить pattern, s, end в начало? Я и agent_id_size и prefix_size собирался, но при ближайшем рассмотрении оказалось что они тавтологические и ненужные, вообще от них избавился. а вот agent_id и prefix перенёс, хотя их и можно было оставить в блоке, но незачем - этот блок по сути основное содержание функции, и его переменные = переменные функции.
А если перед объявлением agent_id_size мне потребуется дописать хоть строчку кода, то и тут тоже придётся переколбашивать всё.
Ну и эта проблема тоже исчезла сама собой.
А теперь сравни исходную простыню, которая у меня даже к экран (15" 768) не влезла и таким образом затруднительно всю её логику оценить одним взглядом (хотя признаюсь не влезло всего несколько строк), и компактный красивый код всего на полстраницы после переделки.
Кстати if(!autodetected_agent_prefix_table) просится сократиться в однострочник но уж слишком длинно получается - перестаёт влезать по горизонтали, не совсем комфортно. Хотя может это потому что я не знаю что он делает. Всякие «залогировать ошибку и вернуть NULL» я спокойно за правую границу экрана отправляю чтобы не засоряли вертикальное пространство экрана с полезной логикой.