Merge branch '3066_dir_list'

* 3066_dir_list:
  Rename type file_entry to the file_entry_t.
  Concretize an usage of file_entry type.
  Rename functions:
  Rename macros related to dir_list::size.
  (dir_list_append): add new dir_list API and use it.
  (clean_dir): try minimize memory usage.
  Add dir_list::len member to keep number of items in list.
  (handle_path): don't check list size here.
  (dir_list_grow): new public API of dir_list.
  Rename panel_sort_info_t to dir_sort_options_t
  Move sort_field member out from panel_sort_info_t structure.
  Ticket #3066: refactoring of dir_list class and related code.
This commit is contained in:
Andrew Borodin 2013-09-19 16:23:53 +04:00
commit cc980f3c50
22 changed files with 548 additions and 522 deletions

View File

@ -25,7 +25,7 @@ typedef struct mc_fhl_struct
mc_fhl_t *mc_fhl_new (gboolean);
void mc_fhl_free (mc_fhl_t **);
int mc_fhl_get_color (mc_fhl_t *, file_entry *);
int mc_fhl_get_color (mc_fhl_t *, file_entry_t *);
gboolean mc_fhl_read_ini_file (mc_fhl_t *, const gchar *);
gboolean mc_fhl_parse_ini_file (mc_fhl_t *);

View File

@ -47,7 +47,7 @@
/*inline functions */
inline static gboolean
mc_fhl_is_file (file_entry * fe)
mc_fhl_is_file (file_entry_t * fe)
{
#if S_ISREG == 0
(void) fe;
@ -56,13 +56,13 @@ mc_fhl_is_file (file_entry * fe)
}
inline static gboolean
mc_fhl_is_file_exec (file_entry * fe)
mc_fhl_is_file_exec (file_entry_t * fe)
{
return is_exe (fe->st.st_mode);
}
inline static gboolean
mc_fhl_is_dir (file_entry * fe)
mc_fhl_is_dir (file_entry_t * fe)
{
#if S_ISDIR == 0
(void) fe;
@ -71,7 +71,7 @@ mc_fhl_is_dir (file_entry * fe)
}
inline static gboolean
mc_fhl_is_link (file_entry * fe)
mc_fhl_is_link (file_entry_t * fe)
{
#if S_ISLNK == 0
(void) fe;
@ -80,25 +80,25 @@ mc_fhl_is_link (file_entry * fe)
}
inline static gboolean
mc_fhl_is_hlink (file_entry * fe)
mc_fhl_is_hlink (file_entry_t * fe)
{
return (fe->st.st_nlink > 1);
}
inline static gboolean
mc_fhl_is_link_to_dir (file_entry * fe)
mc_fhl_is_link_to_dir (file_entry_t * fe)
{
return mc_fhl_is_link (fe) && (fe->f.link_to_dir);
}
inline static gboolean
mc_fhl_is_stale_link (file_entry * fe)
mc_fhl_is_stale_link (file_entry_t * fe)
{
return mc_fhl_is_link (fe) ? fe->f.stale_link : !mc_fhl_is_file (fe);
}
inline static gboolean
mc_fhl_is_device_char (file_entry * fe)
mc_fhl_is_device_char (file_entry_t * fe)
{
#if S_ISCHR == 0
(void) fe;
@ -107,7 +107,7 @@ mc_fhl_is_device_char (file_entry * fe)
}
inline static gboolean
mc_fhl_is_device_block (file_entry * fe)
mc_fhl_is_device_block (file_entry_t * fe)
{
#if S_ISBLK == 0
(void) fe;
@ -116,7 +116,7 @@ mc_fhl_is_device_block (file_entry * fe)
}
inline static gboolean
mc_fhl_is_special_socket (file_entry * fe)
mc_fhl_is_special_socket (file_entry_t * fe)
{
#if S_ISSOCK == 0
(void) fe;
@ -125,7 +125,7 @@ mc_fhl_is_special_socket (file_entry * fe)
}
inline static gboolean
mc_fhl_is_special_fifo (file_entry * fe)
mc_fhl_is_special_fifo (file_entry_t * fe)
{
#if S_ISFIFO == 0
(void) fe;
@ -134,7 +134,7 @@ mc_fhl_is_special_fifo (file_entry * fe)
}
inline static gboolean
mc_fhl_is_special_door (file_entry * fe)
mc_fhl_is_special_door (file_entry_t * fe)
{
#if S_ISDOOR == 0
(void) fe;
@ -145,7 +145,7 @@ mc_fhl_is_special_door (file_entry * fe)
inline static gboolean
mc_fhl_is_special (file_entry * fe)
mc_fhl_is_special (file_entry_t * fe)
{
return
(mc_fhl_is_special_socket (fe) || mc_fhl_is_special_fifo (fe)
@ -156,7 +156,7 @@ mc_fhl_is_special (file_entry * fe)
/* --------------------------------------------------------------------------------------------- */
static int
mc_fhl_get_color_filetype (mc_fhl_filter_t * mc_filter, mc_fhl_t * fhl, file_entry * fe)
mc_fhl_get_color_filetype (mc_fhl_filter_t * mc_filter, mc_fhl_t * fhl, file_entry_t * fe)
{
gboolean my_color = FALSE;
(void) fhl;
@ -231,7 +231,7 @@ mc_fhl_get_color_filetype (mc_fhl_filter_t * mc_filter, mc_fhl_t * fhl, file_ent
/* --------------------------------------------------------------------------------------------- */
static int
mc_fhl_get_color_regexp (mc_fhl_filter_t * mc_filter, mc_fhl_t * fhl, file_entry * fe)
mc_fhl_get_color_regexp (mc_fhl_filter_t * mc_filter, mc_fhl_t * fhl, file_entry_t * fe)
{
(void) fhl;
if (mc_filter->search_condition == NULL)
@ -250,7 +250,7 @@ mc_fhl_get_color_regexp (mc_fhl_filter_t * mc_filter, mc_fhl_t * fhl, file_entry
/* --------------------------------------------------------------------------------------------- */
int
mc_fhl_get_color (mc_fhl_t * fhl, file_entry * fe)
mc_fhl_get_color (mc_fhl_t * fhl, file_entry_t * fe)
{
guint i;
mc_fhl_filter_t *mc_filter;

View File

@ -69,7 +69,7 @@ typedef struct
unsigned int stale_link:1; /* If this is a symlink and points to Charon's land */
unsigned int dir_size_computed:1; /* Size of directory was computed with dirsizes_cmd */
} f;
} file_entry;
} file_entry_t;
/*** global variables defined in .c file *********************************************************/

View File

@ -703,17 +703,17 @@ panel_listing_box (WPanel * panel, char **userp, char **minip, int *use_msformat
/* --------------------------------------------------------------------------------------------- */
const panel_field_t *
sort_box (panel_sort_info_t * info)
sort_box (dir_sort_options_t * op, const panel_field_t * sort_field)
{
const char **sort_orders_names;
gsize sort_names_num, i;
int sort_idx = 0;
const panel_field_t *result = info->sort_field;
const panel_field_t *result = NULL;
sort_orders_names = panel_get_sortable_fields (&sort_names_num);
for (i = 0; i < sort_names_num; i++)
if (strcmp (sort_orders_names[i], _(info->sort_field->title_hotkey)) == 0)
if (strcmp (sort_orders_names[i], _(sort_field->title_hotkey)) == 0)
{
sort_idx = i;
break;
@ -725,9 +725,9 @@ sort_box (panel_sort_info_t * info)
QUICK_START_COLUMNS,
QUICK_RADIO (sort_names_num, sort_orders_names, &sort_idx, NULL),
QUICK_NEXT_COLUMN,
QUICK_CHECKBOX (N_("Executable &first"), &info->exec_first, NULL),
QUICK_CHECKBOX (N_("Cas&e sensitive"), &info->case_sensitive, NULL),
QUICK_CHECKBOX (N_("&Reverse"), &info->reverse, NULL),
QUICK_CHECKBOX (N_("Executable &first"), &op->exec_first, NULL),
QUICK_CHECKBOX (N_("Cas&e sensitive"), &op->case_sensitive, NULL),
QUICK_CHECKBOX (N_("&Reverse"), &op->reverse, NULL),
QUICK_STOP_COLUMNS,
QUICK_BUTTONS_OK_CANCEL,
QUICK_END
@ -744,7 +744,7 @@ sort_box (panel_sort_info_t * info)
result = panel_get_field_by_title_hotkey (sort_orders_names[sort_idx]);
if (result == NULL)
result = info->sort_field;
result = sort_field;
}
g_strfreev ((gchar **) sort_orders_names);

View File

@ -21,7 +21,7 @@
void configure_box (void);
void panel_options_box (void);
int panel_listing_box (WPanel * p, char **user, char **mini, int *use_msformat, int num);
const panel_field_t *sort_box (panel_sort_info_t * info);
const panel_field_t *sort_box (dir_sort_options_t * op, const panel_field_t * sort_field);
void confirm_box (void);
void display_bits_box (void);
void configure_vfs (void);

View File

@ -264,7 +264,7 @@ select_unselect_cmd (const char *title, const char *history_name, gboolean do_se
search->is_entire_line = TRUE;
search->is_case_sensitive = case_sens != 0;
for (i = 0; i < current_panel->count; i++)
for (i = 0; i < current_panel->dir.len; i++)
{
if (DIR_IS_DOTDOT (current_panel->dir.list[i].fname))
continue;
@ -356,9 +356,9 @@ compare_dir (WPanel * panel, WPanel * other, enum CompareMode mode)
panel->dirs_marked = 0;
/* Handle all files in the panel */
for (i = 0; i < panel->count; i++)
for (i = 0; i < panel->dir.len; i++)
{
file_entry *source = &panel->dir.list[i];
file_entry_t *source = &panel->dir.list[i];
/* Default: unmarked */
file_mark (panel, i, 0);
@ -368,18 +368,18 @@ compare_dir (WPanel * panel, WPanel * other, enum CompareMode mode)
continue;
/* Search the corresponding entry from the other panel */
for (j = 0; j < other->count; j++)
for (j = 0; j < other->dir.len; j++)
{
if (strcmp (source->fname, other->dir.list[j].fname) == 0)
break;
}
if (j >= other->count)
if (j >= other->dir.len)
/* Not found -> mark */
do_file_mark (panel, i, 1);
else
{
/* Found */
file_entry *target = &other->dir.list[j];
file_entry_t *target = &other->dir.list[j];
if (mode != compare_size_only)
{
@ -1056,9 +1056,9 @@ void
select_invert_cmd (void)
{
int i;
file_entry *file;
file_entry_t *file;
for (i = 0; i < current_panel->count; i++)
for (i = 0; i < current_panel->dir.len; i++)
{
file = &current_panel->dir.list[i];
if (!panels_options.reverse_files_only || !S_ISDIR (file->st.st_mode))
@ -1604,7 +1604,7 @@ void
smart_dirsize_cmd (void)
{
WPanel *panel = current_panel;
file_entry *entry;
file_entry_t *entry;
entry = &(panel->dir.list[panel->selected]);
if ((S_ISDIR (entry->st.st_mode) && DIR_IS_DOTDOT (entry->fname)) || panel->dirs_marked)
@ -1619,7 +1619,7 @@ void
single_dirsize_cmd (void)
{
WPanel *panel = current_panel;
file_entry *entry;
file_entry_t *entry;
entry = &(panel->dir.list[panel->selected]);
if (S_ISDIR (entry->st.st_mode) && !DIR_IS_DOTDOT (entry->fname))
@ -1648,7 +1648,7 @@ single_dirsize_cmd (void)
recalculate_panel_summary (panel);
if (current_panel->sort_info.sort_field->sort_routine == (sortfn *) sort_size)
if (current_panel->sort_field->sort_routine == (GCompareFunc) sort_size)
panel_re_sort (panel);
panel->dirty = 1;
@ -1665,7 +1665,7 @@ dirsizes_cmd (void)
ui = compute_dir_size_create_ui (FALSE);
for (i = 0; i < panel->count; i++)
for (i = 0; i < panel->dir.len; i++)
if (S_ISDIR (panel->dir.list[i].st.st_mode)
&& ((panel->dirs_marked && panel->dir.list[i].f.marked)
|| !panel->dirs_marked) && !DIR_IS_DOTDOT (panel->dir.list[i].fname))
@ -1691,7 +1691,7 @@ dirsizes_cmd (void)
recalculate_panel_summary (panel);
if (current_panel->sort_info.sort_field->sort_routine == (sortfn *) sort_size)
if (current_panel->sort_field->sort_routine == (GCompareFunc) sort_size)
panel_re_sort (panel);
panel->dirty = 1;

View File

@ -7,6 +7,7 @@
Written by:
Slava Zanko <slavazanko@gmail.com>, 2013
Andrew Borodin <aborodin@vmail.ru>, 2013
This file is part of the Midnight Commander.
@ -72,7 +73,7 @@ static int case_sensitive = OS_SORT_CASE_SENSITIVE_DEFAULT;
/* Are the exec_bit files top in list */
static gboolean exec_first = TRUE;
static dir_list dir_copy = { 0, 0 };
static dir_list dir_copy = { NULL, 0, 0 };
/*** file scope functions ************************************************************************/
/* --------------------------------------------------------------------------------------------- */
@ -129,55 +130,34 @@ clean_sort_keys (dir_list * list, int start, int count)
for (i = 0; i < count; i++)
{
str_release_key (list->list[i + start].sort_key, case_sensitive);
list->list[i + start].sort_key = NULL;
str_release_key (list->list[i + start].second_sort_key, case_sensitive);
list->list[i + start].second_sort_key = NULL;
file_entry_t *fentry;
fentry = &list->list[i + start];
str_release_key (fentry->sort_key, case_sensitive);
fentry->sort_key = NULL;
str_release_key (fentry->second_sort_key, case_sensitive);
fentry->second_sort_key = NULL;
}
}
/* --------------------------------------------------------------------------------------------- */
/**
* Increase directory list by RESIZE_STEPS
*
* @param list directory list
* @return FALSE on failure, TRUE on success
* If you change handle_dirent then check also handle_path.
* @return FALSE = don't add, TRUE = add to the list
*/
static gboolean
grow_list (dir_list * list)
{
if (list == NULL)
return FALSE;
list->list = g_try_realloc (list->list, sizeof (file_entry) * (list->size + RESIZE_STEPS));
if (list->list == NULL)
return FALSE;
list->size += RESIZE_STEPS;
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
/**
* If you change handle_dirent then check also handle_path.
* @return -1 = failure, 0 = don't add, 1 = add to the list
*/
static int
handle_dirent (dir_list * list, const char *fltr, struct dirent *dp,
struct stat *buf1, int next_free, int *link_to_dir, int *stale_link)
handle_dirent (struct dirent *dp, const char *fltr, struct stat *buf1, int *link_to_dir,
int *stale_link)
{
vfs_path_t *vpath;
if (DIR_IS_DOT (dp->d_name) || DIR_IS_DOTDOT (dp->d_name))
return 0;
return FALSE;
if (!panels_options.show_dot_files && (dp->d_name[0] == '.'))
return 0;
if (!panels_options.show_backups && dp->d_name[NLENGTH (dp) - 1] == '~')
return 0;
return FALSE;
if (!panels_options.show_backups && dp->d_name[strlen (dp->d_name) - 1] == '~')
return FALSE;
vpath = vfs_path_from_str (dp->d_name);
if (mc_lstat (vpath, buf1) == -1)
@ -199,28 +179,24 @@ handle_dirent (dir_list * list, const char *fltr, struct dirent *dp,
if (S_ISLNK (buf1->st_mode))
{
struct stat buf2;
if (mc_stat (vpath, &buf2) == 0)
*link_to_dir = S_ISDIR (buf2.st_mode) != 0;
else
*stale_link = 1;
}
vfs_path_free (vpath);
if (!(S_ISDIR (buf1->st_mode) || *link_to_dir) && (fltr != NULL)
&& !mc_search (fltr, dp->d_name, MC_SEARCH_T_GLOB))
return 0;
/* Need to grow the *list? */
if (next_free == list->size && !grow_list (list))
return -1;
return 1;
return (S_ISDIR (buf1->st_mode) || *link_to_dir != 0 || fltr == NULL
|| mc_search (fltr, dp->d_name, MC_SEARCH_T_GLOB));
}
/* --------------------------------------------------------------------------------------------- */
/** get info about ".." */
static gboolean
get_dotdot_dir_stat (const vfs_path_t * vpath, struct stat *st)
dir_get_dotdot_stat (const vfs_path_t * vpath, struct stat *st)
{
gboolean ret = FALSE;
@ -232,12 +208,10 @@ get_dotdot_dir_stat (const vfs_path_t * vpath, struct stat *st)
if (path != NULL && *path != '\0')
{
vfs_path_t *tmp_vpath;
struct stat s;
tmp_vpath = vfs_path_append_new (vpath, "..", NULL);
ret = mc_stat (tmp_vpath, &s) == 0;
ret = mc_stat (tmp_vpath, st) == 0;
vfs_path_free (tmp_vpath);
*st = s;
}
}
@ -251,25 +225,117 @@ alloc_dir_copy (int size)
{
if (dir_copy.size < size)
{
if (dir_copy.list)
if (dir_copy.list != NULL)
{
int i;
for (i = 0; i < dir_copy.size; i++)
g_free (dir_copy.list[i].fname);
for (i = 0; i < dir_copy.len; i++)
{
file_entry_t *fentry;
fentry = &(dir_copy.list)[i];
g_free (fentry->fname);
}
g_free (dir_copy.list);
}
dir_copy.list = g_new0 (file_entry, size);
dir_copy.list = g_new0 (file_entry_t, size);
dir_copy.size = size;
dir_copy.len = 0;
}
}
/* --------------------------------------------------------------------------------------------- */
/*** public functions ****************************************************************************/
/* --------------------------------------------------------------------------------------------- */
/**
* Increase or decrease directory list size.
*
* @param list directory list
* @param delta value by increase (if positive) or decrease (if negative) list size
*
* @return FALSE on failure, TRUE on success
*/
gboolean
dir_list_grow (dir_list * list, int delta)
{
int size;
gboolean clear = FALSE;
if (list == NULL)
return FALSE;
if (delta == 0)
return TRUE;
size = list->size + delta;
if (size <= 0)
{
size = DIR_LIST_MIN_SIZE;
clear = TRUE;
}
if (size != list->size)
{
file_entry_t *fe;
fe = g_try_renew (file_entry_t, list->list, size);
if (fe == NULL)
return FALSE;
list->list = fe;
list->size = size;
}
list->len = clear ? 0 : min (list->len, size);
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
/**
* Append file info to the directory list.
*
* @param list directory list
* @param fname file name
* @param st file stat info
* @param link_to_dir is file link to directory
* @param stale_link is file stale elink
*
* @return FALSE on failure, TRUE on success
*/
gboolean
dir_list_append (dir_list * list, const char *fname, const struct stat * st,
gboolean link_to_dir, gboolean stale_link)
{
file_entry_t *fentry;
/* Need to grow the *list? */
if (list->len == list->size && !dir_list_grow (list, DIR_LIST_RESIZE_STEP))
return FALSE;
fentry = &list->list[list->len];
fentry->fnamelen = strlen (fname);
fentry->fname = g_strndup (fname, fentry->fnamelen);
fentry->f.marked = 0;
fentry->f.link_to_dir = link_to_dir ? 1 : 0;
fentry->f.stale_link = stale_link ? 1 : 0;
fentry->f.dir_size_computed = 0;
fentry->st = *st;
fentry->sort_key = NULL;
fentry->second_sort_key = NULL;
list->len++;
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
int
unsorted (file_entry * a, file_entry * b)
unsorted (file_entry_t * a, file_entry_t * b)
{
(void) a;
(void) b;
@ -279,7 +345,7 @@ unsorted (file_entry * a, file_entry * b)
/* --------------------------------------------------------------------------------------------- */
int
sort_name (file_entry * a, file_entry * b)
sort_name (file_entry_t * a, file_entry_t * b)
{
int ad = MY_ISDIR (a);
int bd = MY_ISDIR (b);
@ -300,7 +366,7 @@ sort_name (file_entry * a, file_entry * b)
/* --------------------------------------------------------------------------------------------- */
int
sort_vers (file_entry * a, file_entry * b)
sort_vers (file_entry_t * a, file_entry_t * b)
{
int ad = MY_ISDIR (a);
int bd = MY_ISDIR (b);
@ -318,7 +384,7 @@ sort_vers (file_entry * a, file_entry * b)
/* --------------------------------------------------------------------------------------------- */
int
sort_ext (file_entry * a, file_entry * b)
sort_ext (file_entry_t * a, file_entry_t * b)
{
int r;
int ad = MY_ISDIR (a);
@ -344,7 +410,7 @@ sort_ext (file_entry * a, file_entry * b)
/* --------------------------------------------------------------------------------------------- */
int
sort_time (file_entry * a, file_entry * b)
sort_time (file_entry_t * a, file_entry_t * b)
{
int ad = MY_ISDIR (a);
int bd = MY_ISDIR (b);
@ -364,7 +430,7 @@ sort_time (file_entry * a, file_entry * b)
/* --------------------------------------------------------------------------------------------- */
int
sort_ctime (file_entry * a, file_entry * b)
sort_ctime (file_entry_t * a, file_entry_t * b)
{
int ad = MY_ISDIR (a);
int bd = MY_ISDIR (b);
@ -384,7 +450,7 @@ sort_ctime (file_entry * a, file_entry * b)
/* --------------------------------------------------------------------------------------------- */
int
sort_atime (file_entry * a, file_entry * b)
sort_atime (file_entry_t * a, file_entry_t * b)
{
int ad = MY_ISDIR (a);
int bd = MY_ISDIR (b);
@ -404,7 +470,7 @@ sort_atime (file_entry * a, file_entry * b)
/* --------------------------------------------------------------------------------------------- */
int
sort_inode (file_entry * a, file_entry * b)
sort_inode (file_entry_t * a, file_entry_t * b)
{
int ad = MY_ISDIR (a);
int bd = MY_ISDIR (b);
@ -418,7 +484,7 @@ sort_inode (file_entry * a, file_entry * b)
/* --------------------------------------------------------------------------------------------- */
int
sort_size (file_entry * a, file_entry * b)
sort_size (file_entry_t * a, file_entry_t * b)
{
int ad = MY_ISDIR (a);
int bd = MY_ISDIR (b);
@ -437,59 +503,74 @@ sort_size (file_entry * a, file_entry * b)
/* --------------------------------------------------------------------------------------------- */
void
do_sort (dir_list * list, sortfn * sort, int top, gboolean reverse_f, gboolean case_sensitive_f,
gboolean exec_first_f)
dir_list_sort (dir_list * list, GCompareFunc sort, const dir_sort_options_t * sort_op)
{
file_entry_t *fentry;
int dot_dot_found = 0;
if (top == 0)
if (list->len < 2)
return;
/* If there is an ".." entry the caller must take care to
ensure that it occupies the first list element. */
if (DIR_IS_DOTDOT (list->list[0].fname))
fentry = &list->list[0];
if (DIR_IS_DOTDOT (fentry->fname))
dot_dot_found = 1;
reverse = reverse_f ? -1 : 1;
case_sensitive = case_sensitive_f ? 1 : 0;
exec_first = exec_first_f;
qsort (&(list->list)[dot_dot_found], top + 1 - dot_dot_found, sizeof (file_entry), sort);
reverse = sort_op->reverse ? -1 : 1;
case_sensitive = sort_op->case_sensitive ? 1 : 0;
exec_first = sort_op->exec_first;
qsort (&(list->list)[dot_dot_found], list->len - dot_dot_found, sizeof (file_entry_t), sort);
clean_sort_keys (list, dot_dot_found, top + 1 - dot_dot_found);
clean_sort_keys (list, dot_dot_found, list->len - dot_dot_found);
}
/* --------------------------------------------------------------------------------------------- */
void
clean_dir (dir_list * list, int count)
dir_list_clean (dir_list * list)
{
int i;
for (i = 0; i < count; i++)
for (i = 0; i < list->len; i++)
{
g_free (list->list[i].fname);
list->list[i].fname = NULL;
file_entry_t *fentry;
fentry = &list->list[i];
g_free (fentry->fname);
fentry->fname = NULL;
}
list->len = 0;
/* reduce memory usage */
dir_list_grow (list, DIR_LIST_MIN_SIZE - list->size);
}
/* --------------------------------------------------------------------------------------------- */
/** Used to set up a directory list when there is no access to a directory */
gboolean
set_zero_dir (dir_list * list)
dir_list_init (dir_list * list)
{
/* Need to grow the *list? */
if (list->size == 0 && !grow_list (list))
return FALSE;
file_entry_t *fentry;
memset (&(list->list)[0], 0, sizeof (file_entry));
list->list[0].fnamelen = 2;
list->list[0].fname = g_strndup ("..", list->list[0].fnamelen);
list->list[0].f.link_to_dir = 0;
list->list[0].f.stale_link = 0;
list->list[0].f.dir_size_computed = 0;
list->list[0].f.marked = 0;
list->list[0].st.st_mode = 040755;
/* Need to grow the *list? */
if (list->size == 0 && !dir_list_grow (list, DIR_LIST_RESIZE_STEP))
{
list->len = 0;
return FALSE;
}
fentry = &list->list[0];
memset (fentry, 0, sizeof (file_entry_t));
fentry->fnamelen = 2;
fentry->fname = g_strndup ("..", fentry->fnamelen);
fentry->f.link_to_dir = 0;
fentry->f.stale_link = 0;
fentry->f.dir_size_computed = 0;
fentry->f.marked = 0;
fentry->st.st_mode = 040755;
list->len = 1;
return TRUE;
}
@ -500,22 +581,21 @@ set_zero_dir (dir_list * list)
and panels_options.show_backups.
Moreover handle_path can't be used with a filemask.
If you change handle_path then check also handle_dirent. */
/* Return values: -1 = failure, 0 = don't add, 1 = add to the list */
/* Return values: FALSE = don't add, TRUE = add to the list */
int
handle_path (dir_list * list, const char *path,
struct stat *buf1, int next_free, int *link_to_dir, int *stale_link)
gboolean
handle_path (const char *path, struct stat * buf1, int *link_to_dir, int *stale_link)
{
vfs_path_t *vpath;
if (DIR_IS_DOT (path) || DIR_IS_DOTDOT (path))
return 0;
return FALSE;
vpath = vfs_path_from_str (path);
if (mc_lstat (vpath, buf1) == -1)
{
vfs_path_free (vpath);
return 0;
return FALSE;
}
if (S_ISDIR (buf1->st_mode))
@ -527,6 +607,7 @@ handle_path (dir_list * list, const char *path,
if (S_ISLNK (buf1->st_mode))
{
struct stat buf2;
if (mc_stat (vpath, &buf2) == 0)
*link_to_dir = S_ISDIR (buf2.st_mode) != 0;
else
@ -535,38 +616,34 @@ handle_path (dir_list * list, const char *path,
vfs_path_free (vpath);
/* Need to grow the *list? */
if (next_free == list->size && !grow_list (list))
return -1;
return 1;
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
int
do_load_dir (const vfs_path_t * vpath, dir_list * list, sortfn * sort, gboolean lc_reverse,
gboolean lc_case_sensitive, gboolean exec_ff, const char *fltr)
void
dir_list_load (dir_list * list, const vfs_path_t * vpath, GCompareFunc sort,
const dir_sort_options_t * sort_op, const char *fltr)
{
DIR *dirp;
struct dirent *dp;
int status, link_to_dir, stale_link;
int next_free = 0;
int link_to_dir, stale_link;
struct stat st;
file_entry_t *fentry;
/* ".." (if any) must be the first entry in the list */
if (!set_zero_dir (list))
return next_free;
if (!dir_list_init (list))
return;
if (get_dotdot_dir_stat (vpath, &st))
list->list[next_free].st = st;
next_free++;
fentry = &list->list[0];
if (dir_get_dotdot_stat (vpath, &st))
fentry->st = st;
dirp = mc_opendir (vpath);
if (dirp == NULL)
{
message (D_ERROR, MSG_ERROR, _("Cannot read directory contents"));
return next_free;
return;
}
tree_store_start_check (vpath);
@ -577,47 +654,33 @@ do_load_dir (const vfs_path_t * vpath, dir_list * list, sortfn * sort, gboolean
vpath_str = vfs_path_as_str (vpath);
/* Do not add a ".." entry to the root directory */
if ((vpath_str[0] == PATH_SEP) && (vpath_str[1] == '\0'))
next_free--;
list->len--;
}
while ((dp = mc_readdir (dirp)) != NULL)
{
status = handle_dirent (list, fltr, dp, &st, next_free, &link_to_dir, &stale_link);
if (status == 0)
if (!handle_dirent (dp, fltr, &st, &link_to_dir, &stale_link))
continue;
if (status == -1)
if (!dir_list_append (list, dp->d_name, &st, link_to_dir != 0, stale_link != 0))
goto ret;
list->list[next_free].fnamelen = NLENGTH (dp);
list->list[next_free].fname = g_strndup (dp->d_name, list->list[next_free].fnamelen);
list->list[next_free].f.marked = 0;
list->list[next_free].f.link_to_dir = link_to_dir;
list->list[next_free].f.stale_link = stale_link;
list->list[next_free].f.dir_size_computed = 0;
list->list[next_free].st = st;
list->list[next_free].sort_key = NULL;
list->list[next_free].second_sort_key = NULL;
next_free++;
if ((next_free & 31) == 0)
if ((list->len & 31) == 0)
rotate_dash (TRUE);
}
if (next_free != 0)
do_sort (list, sort, next_free - 1, lc_reverse, lc_case_sensitive, exec_ff);
dir_list_sort (list, sort, sort_op);
ret:
mc_closedir (dirp);
tree_store_end_check ();
rotate_dash (FALSE);
return next_free;
}
/* --------------------------------------------------------------------------------------------- */
gboolean
if_link_is_exe (const vfs_path_t * full_name_vpath, const file_entry * file)
if_link_is_exe (const vfs_path_t * full_name_vpath, const file_entry_t * file)
{
struct stat b;
@ -629,14 +692,13 @@ if_link_is_exe (const vfs_path_t * full_name_vpath, const file_entry * file)
/* --------------------------------------------------------------------------------------------- */
/** If fltr is null, then it is a match */
int
do_reload_dir (const vfs_path_t * vpath, dir_list * list, sortfn * sort, int count,
gboolean lc_reverse, gboolean lc_case_sensitive, gboolean exec_ff, const char *fltr)
void
dir_list_reload (dir_list * list, const vfs_path_t * vpath, GCompareFunc sort,
const dir_sort_options_t * sort_op, const char *fltr)
{
DIR *dirp;
struct dirent *dp;
int next_free = 0;
int i, status, link_to_dir, stale_link;
int i, link_to_dir, stale_link;
struct stat st;
int marked_cnt;
GHashTable *marked_files;
@ -646,27 +708,33 @@ do_reload_dir (const vfs_path_t * vpath, dir_list * list, sortfn * sort, int cou
if (dirp == NULL)
{
message (D_ERROR, MSG_ERROR, _("Cannot read directory contents"));
clean_dir (list, count);
return set_zero_dir (list) ? 1 : 0;
dir_list_clean (list);
dir_list_init (list);
return;
}
tree_store_start_check (vpath);
marked_files = g_hash_table_new (g_str_hash, g_str_equal);
alloc_dir_copy (list->size);
for (marked_cnt = i = 0; i < count; i++)
alloc_dir_copy (list->len);
for (marked_cnt = i = 0; i < list->len; i++)
{
dir_copy.list[i].fnamelen = list->list[i].fnamelen;
dir_copy.list[i].fname = list->list[i].fname;
dir_copy.list[i].f.marked = list->list[i].f.marked;
dir_copy.list[i].f.dir_size_computed = list->list[i].f.dir_size_computed;
dir_copy.list[i].f.link_to_dir = list->list[i].f.link_to_dir;
dir_copy.list[i].f.stale_link = list->list[i].f.stale_link;
dir_copy.list[i].sort_key = NULL;
dir_copy.list[i].second_sort_key = NULL;
if (list->list[i].f.marked)
file_entry_t *fentry, *dfentry;
fentry = &list->list[i];
dfentry = &dir_copy.list[i];
dfentry->fnamelen = fentry->fnamelen;
dfentry->fname = fentry->fname;
dfentry->f.marked = fentry->f.marked;
dfentry->f.dir_size_computed = fentry->f.dir_size_computed;
dfentry->f.link_to_dir = fentry->f.link_to_dir;
dfentry->f.stale_link = fentry->f.stale_link;
dfentry->sort_key = NULL;
dfentry->second_sort_key = NULL;
if (fentry->f.marked)
{
g_hash_table_insert (marked_files, dir_copy.list[i].fname, &dir_copy.list[i]);
g_hash_table_insert (marked_files, dfentry->fname, dfentry);
marked_cnt++;
}
}
@ -678,25 +746,28 @@ do_reload_dir (const vfs_path_t * vpath, dir_list * list, sortfn * sort, int cou
(vfs_path_elements_count (vpath) == 1 && (tmp_path[0] == PATH_SEP)
&& (tmp_path[1] == '\0')))
{
if (!set_zero_dir (list))
if (!dir_list_init (list))
{
clean_dir (list, count);
clean_dir (&dir_copy, count);
return next_free;
dir_list_clean (&dir_copy);
return;
}
if (get_dotdot_dir_stat (vpath, &st))
list->list[next_free].st = st;
if (dir_get_dotdot_stat (vpath, &st))
{
file_entry_t *fentry;
next_free++;
fentry = &list->list[0];
fentry->st = st;
}
}
while ((dp = mc_readdir (dirp)))
while ((dp = mc_readdir (dirp)) != NULL)
{
status = handle_dirent (list, fltr, dp, &st, next_free, &link_to_dir, &stale_link);
if (status == 0)
file_entry_t *fentry;
if (!handle_dirent (dp, fltr, &st, &link_to_dir, &stale_link))
continue;
if (status == -1)
if (!dir_list_append (list, dp->d_name, &st, link_to_dir != 0, stale_link != 0))
{
mc_closedir (dirp);
/* Norbert (Feb 12, 1997):
@ -704,55 +775,41 @@ do_reload_dir (const vfs_path_t * vpath, dir_list * list, sortfn * sort, int cou
-1 means big trouble (at the moment no memory left),
I don't bother with further cleanup because if one gets to
this point he will have more problems than a few memory
leaks and because one 'clean_dir' would not be enough (and
leaks and because one 'dir_list_clean' would not be enough (and
because I don't want to spent the time to make it working,
IMHO it's not worthwhile).
clean_dir (&dir_copy, count);
dir_list_clean (&dir_copy);
*/
tree_store_end_check ();
g_hash_table_destroy (marked_files);
return next_free;
return;
}
fentry = &list->list[list->len - 1];
list->list[next_free].f.marked = 0;
fentry->f.marked = 0;
/*
* If we have marked files in the copy, scan through the copy
* to find matching file. Decrease number of remaining marks if
* we copied one.
*/
if (marked_cnt > 0)
if (marked_cnt > 0 && g_hash_table_lookup (marked_files, dp->d_name) != NULL)
{
if ((g_hash_table_lookup (marked_files, dp->d_name)))
{
list->list[next_free].f.marked = 1;
marked_cnt--;
}
fentry->f.marked = 1;
marked_cnt--;
}
list->list[next_free].fnamelen = NLENGTH (dp);
list->list[next_free].fname = g_strndup (dp->d_name, list->list[next_free].fnamelen);
list->list[next_free].f.link_to_dir = link_to_dir;
list->list[next_free].f.stale_link = stale_link;
list->list[next_free].f.dir_size_computed = 0;
list->list[next_free].st = st;
list->list[next_free].sort_key = NULL;
list->list[next_free].second_sort_key = NULL;
next_free++;
if ((next_free % 16) == 0)
if ((list->len & 15) == 0)
rotate_dash (TRUE);
}
mc_closedir (dirp);
tree_store_end_check ();
g_hash_table_destroy (marked_files);
if (next_free)
{
do_sort (list, sort, next_free - 1, lc_reverse, lc_case_sensitive, exec_ff);
}
clean_dir (&dir_copy, count);
rotate_dash (FALSE);
return next_free;
dir_list_sort (list, sort, sort_op);
dir_list_clean (&dir_copy);
rotate_dash (FALSE);
}
/* --------------------------------------------------------------------------------------------- */

View File

@ -13,53 +13,67 @@
/*** typedefs(not structures) and defined constants **********************************************/
#define MIN_FILES 128
#define RESIZE_STEPS 128
typedef int sortfn (const void *, const void *);
#define DIR_LIST_MIN_SIZE 128
#define DIR_LIST_RESIZE_STEP 128
/*** enums ***************************************************************************************/
/*** structures declarations (and typedefs of structures)*****************************************/
/**
* A structure to represent directory content
*/
typedef struct
{
file_entry *list;
int size;
file_entry_t *list; /**< list of file_entry_t objects */
int size; /**< number of allocated elements in list (capacity) */
int len; /**< number of used elements in list */
} dir_list;
/**
* A structure to represent sort options for directory content
*/
typedef struct dir_sort_options_struct
{
gboolean reverse; /**< sort is reverse */
gboolean case_sensitive; /**< sort is case sensitive */
gboolean exec_first; /**< executables are at top of list */
} dir_sort_options_t;
/*** global variables defined in .c file *********************************************************/
/*** declarations of public functions ************************************************************/
int do_load_dir (const vfs_path_t * vpath, dir_list * list, sortfn * sort, gboolean reverse,
gboolean case_sensitive, gboolean exec_ff, const char *fltr);
void do_sort (dir_list * list, sortfn * sort, int top, gboolean reverse,
gboolean case_sensitive, gboolean exec_ff);
int do_reload_dir (const vfs_path_t * vpath, dir_list * list, sortfn * sort, int count,
gboolean reverse, gboolean case_sensitive, gboolean exec_ff, const char *fltr);
void clean_dir (dir_list * list, int count);
gboolean set_zero_dir (dir_list * list);
int handle_path (dir_list * list, const char *path, struct stat *buf1,
int next_free, int *link_to_dir, int *stale_link);
gboolean dir_list_grow (dir_list * list, int delta);
gboolean dir_list_append (dir_list * list, const char *fname, const struct stat *st,
gboolean link_to_dir, gboolean stale_link);
void dir_list_load (dir_list * list, const vfs_path_t * vpath, GCompareFunc sort,
const dir_sort_options_t * sort_op, const char *fltr);
void dir_list_reload (dir_list * list, const vfs_path_t * vpath, GCompareFunc sort,
const dir_sort_options_t * sort_op, const char *fltr);
void dir_list_sort (dir_list * list, GCompareFunc sort, const dir_sort_options_t * sort_op);
gboolean dir_list_init (dir_list * list);
void dir_list_clean (dir_list * list);
gboolean handle_path (const char *path, struct stat *buf1, int *link_to_dir, int *stale_link);
/* Sorting functions */
int unsorted (file_entry * a, file_entry * b);
int sort_name (file_entry * a, file_entry * b);
int sort_vers (file_entry * a, file_entry * b);
int sort_ext (file_entry * a, file_entry * b);
int sort_time (file_entry * a, file_entry * b);
int sort_atime (file_entry * a, file_entry * b);
int sort_ctime (file_entry * a, file_entry * b);
int sort_size (file_entry * a, file_entry * b);
int sort_inode (file_entry * a, file_entry * b);
int unsorted (file_entry_t * a, file_entry_t * b);
int sort_name (file_entry_t * a, file_entry_t * b);
int sort_vers (file_entry_t * a, file_entry_t * b);
int sort_ext (file_entry_t * a, file_entry_t * b);
int sort_time (file_entry_t * a, file_entry_t * b);
int sort_atime (file_entry_t * a, file_entry_t * b);
int sort_ctime (file_entry_t * a, file_entry_t * b);
int sort_size (file_entry_t * a, file_entry_t * b);
int sort_inode (file_entry_t * a, file_entry_t * b);
gboolean if_link_is_exe (const vfs_path_t * full_name, const file_entry * file);
gboolean if_link_is_exe (const vfs_path_t * full_name, const file_entry_t * file);
/*** inline functions ****************************************************************************/
static inline gboolean
link_isdir (const file_entry * file)
link_isdir (const file_entry_t * file)
{
return (gboolean) file->f.link_to_dir;
}

View File

@ -1214,7 +1214,7 @@ panel_get_file (WPanel * panel)
{
int i;
for (i = 0; i < panel->count; i++)
for (i = 0; i < panel->dir.len; i++)
if (panel->dir.list[i].f.marked)
return g_strdup (panel->dir.list[i].fname);
}
@ -1237,7 +1237,7 @@ panel_compute_totals (const WPanel * panel, void *ui, compute_dir_size_callback
{
int i;
for (i = 0; i < panel->count; i++)
for (i = 0; i < panel->dir.len; i++)
{
struct stat *s;
@ -2930,7 +2930,7 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl
if (panel_operate_init_totals (panel, NULL, ctx, dialog_type) == FILE_CONT)
{
/* Loop for every file, perform the actual copy operation */
for (i = 0; i < panel->count; i++)
for (i = 0; i < panel->dir.len; i++)
{
const char *source2;

View File

@ -1698,16 +1698,14 @@ do_find (const char *start_dir, ssize_t start_dir_len, const char *ignore_dirs,
if (return_value == B_PANELIZE && *filename)
{
int status, link_to_dir, stale_link;
int next_free = 0;
int link_to_dir, stale_link;
int i;
struct stat st;
GList *entry;
dir_list *list = &current_panel->dir;
char *name = NULL;
if (set_zero_dir (list))
next_free++;
dir_list_init (list);
for (i = 0, entry = find_list->list; entry != NULL; i++, entry = g_list_next (entry))
{
@ -1734,46 +1732,45 @@ do_find (const char *start_dir, ssize_t start_dir_len, const char *ignore_dirs,
p++;
}
status = handle_path (list, p, &st, next_free, &link_to_dir, &stale_link);
if (status == 0)
if (!handle_path (p, &st, &link_to_dir, &stale_link))
{
g_free (name);
continue;
}
if (status == -1)
/* Need to grow the *list? */
if (list->len == list->size && !dir_list_grow (list, DIR_LIST_RESIZE_STEP))
{
g_free (name);
break;
}
/* don't add files more than once to the panel */
if (content_pattern != NULL && next_free > 0
&& strcmp (list->list[next_free - 1].fname, p) == 0)
if (content_pattern != NULL && list->len != 0
&& strcmp (list->list[list->len - 1].fname, p) == 0)
{
g_free (name);
continue;
}
if (next_free == 0) /* first turn i.e clean old list */
if (list->len == 0) /* first turn i.e clean old list */
panel_clean_dir (current_panel);
list->list[next_free].fnamelen = strlen (p);
list->list[next_free].fname = g_strndup (p, list->list[next_free].fnamelen);
list->list[next_free].f.marked = 0;
list->list[next_free].f.link_to_dir = link_to_dir;
list->list[next_free].f.stale_link = stale_link;
list->list[next_free].f.dir_size_computed = 0;
list->list[next_free].st = st;
list->list[next_free].sort_key = NULL;
list->list[next_free].second_sort_key = NULL;
next_free++;
list->list[list->len].fnamelen = strlen (p);
list->list[list->len].fname = g_strndup (p, list->list[list->len].fnamelen);
list->list[list->len].f.marked = 0;
list->list[list->len].f.link_to_dir = link_to_dir;
list->list[list->len].f.stale_link = stale_link;
list->list[list->len].f.dir_size_computed = 0;
list->list[list->len].st = st;
list->list[list->len].sort_key = NULL;
list->list[list->len].second_sort_key = NULL;
list->len++;
g_free (name);
if ((next_free & 15) == 0)
if ((list->len & 15) == 0)
rotate_dash (TRUE);
}
if (next_free)
if (list->len != 0)
{
current_panel->count = next_free;
current_panel->is_panelized = TRUE;
/* absolute path */

View File

@ -1112,7 +1112,6 @@ swap_panels (void)
panelswap (active);
panelswap (cwd_vpath);
panelswap (lwd_vpath);
panelswap (count);
panelswap (marked);
panelswap (dirs_marked);
panelswap (total);
@ -1132,7 +1131,7 @@ swap_panels (void)
current_panel = panel1;
/* if sort options are different -> resort panels */
if (memcmp (&panel1->sort_info, &panel2->sort_info, sizeof (panel_sort_info_t)) != 0)
if (memcmp (&panel1->sort_info, &panel2->sort_info, sizeof (dir_sort_options_t)) != 0)
{
panel_re_sort (other_panel);
panel_re_sort (current_panel);

View File

@ -72,7 +72,7 @@
#include "hotlist.h"
#include "panelize.h"
#include "command.h" /* cmdline */
#include "dir.h" /* clean_dir() */
#include "dir.h" /* dir_list_clean() */
#include "chmod.h"
#include "chown.h"
@ -403,7 +403,7 @@ sort_cmd (void)
return;
p = MENU_PANEL;
sort_order = sort_box (&p->sort_info);
sort_order = sort_box (&p->sort_info, p->sort_field);
panel_set_sort_order (p, sort_order);
}
@ -821,7 +821,7 @@ put_tagged (WPanel * panel)
input_disable_update (cmdline);
if (panel->marked)
{
for (i = 0; i < panel->count; i++)
for (i = 0; i < panel->dir.len; i++)
{
if (panel->dir.list[i].f.marked)
command_insert (cmdline, panel->dir.list[i].fname, TRUE);
@ -1783,7 +1783,7 @@ do_nc (void)
/* don't handle VFS timestamps for dirs opened in panels */
mc_event_destroy (MCEVENT_GROUP_CORE, "vfs_timestamp");
clean_dir (&panelized_panel.list, panelized_panel.count);
dir_list_clean (&panelized_panel.list);
}
/* Program end */

View File

@ -86,27 +86,27 @@
hook_t *select_file_hook = NULL;
/* *INDENT-OFF* */
panelized_panel_t panelized_panel = { {NULL, 0}, -1, NULL };
panelized_panel_t panelized_panel = { {NULL, 0, -1}, NULL };
/* *INDENT-ON* */
static const char *string_file_name (file_entry *, int);
static const char *string_file_size (file_entry *, int);
static const char *string_file_size_brief (file_entry *, int);
static const char *string_file_type (file_entry *, int);
static const char *string_file_mtime (file_entry *, int);
static const char *string_file_atime (file_entry *, int);
static const char *string_file_ctime (file_entry *, int);
static const char *string_file_permission (file_entry *, int);
static const char *string_file_perm_octal (file_entry *, int);
static const char *string_file_nlinks (file_entry *, int);
static const char *string_inode (file_entry *, int);
static const char *string_file_nuid (file_entry *, int);
static const char *string_file_ngid (file_entry *, int);
static const char *string_file_owner (file_entry *, int);
static const char *string_file_group (file_entry *, int);
static const char *string_marked (file_entry *, int);
static const char *string_space (file_entry *, int);
static const char *string_dot (file_entry *, int);
static const char *string_file_name (file_entry_t *, int);
static const char *string_file_size (file_entry_t *, int);
static const char *string_file_size_brief (file_entry_t *, int);
static const char *string_file_type (file_entry_t *, int);
static const char *string_file_mtime (file_entry_t *, int);
static const char *string_file_atime (file_entry_t *, int);
static const char *string_file_ctime (file_entry_t *, int);
static const char *string_file_permission (file_entry_t *, int);
static const char *string_file_perm_octal (file_entry_t *, int);
static const char *string_file_nlinks (file_entry_t *, int);
static const char *string_inode (file_entry_t *, int);
static const char *string_file_nuid (file_entry_t *, int);
static const char *string_file_ngid (file_entry_t *, int);
static const char *string_file_owner (file_entry_t *, int);
static const char *string_file_group (file_entry_t *, int);
static const char *string_marked (file_entry_t *, int);
static const char *string_space (file_entry_t *, int);
static const char *string_dot (file_entry_t *, int);
/* *INDENT-OFF* */
panel_field_t panel_fields[] = {
@ -117,7 +117,7 @@ panel_field_t panel_fields[] = {
N_("sort|u"),
N_("&Unsorted"), TRUE, FALSE,
string_file_name,
(sortfn *) unsorted
(GCompareFunc) unsorted
}
,
{
@ -127,7 +127,7 @@ panel_field_t panel_fields[] = {
N_("sort|n"),
N_("&Name"), TRUE, TRUE,
string_file_name,
(sortfn *) sort_name
(GCompareFunc) sort_name
}
,
{
@ -137,7 +137,7 @@ panel_field_t panel_fields[] = {
N_("sort|v"),
N_("&Version"), TRUE, FALSE,
string_file_name,
(sortfn *) sort_vers
(GCompareFunc) sort_vers
}
,
{
@ -147,7 +147,7 @@ panel_field_t panel_fields[] = {
N_("sort|e"),
N_("E&xtension"), TRUE, FALSE,
string_file_name, /* TODO: string_file_ext */
(sortfn *) sort_ext
(GCompareFunc) sort_ext
}
,
{
@ -157,7 +157,7 @@ panel_field_t panel_fields[] = {
N_("sort|s"),
N_("&Size"), TRUE, TRUE,
string_file_size,
(sortfn *) sort_size
(GCompareFunc) sort_size
}
,
{
@ -165,7 +165,7 @@ panel_field_t panel_fields[] = {
"",
N_("Block Size"), FALSE, FALSE,
string_file_size_brief,
(sortfn *) sort_size
(GCompareFunc) sort_size
}
,
{
@ -183,7 +183,7 @@ panel_field_t panel_fields[] = {
N_("sort|m"),
N_("&Modify time"), TRUE, TRUE,
string_file_mtime,
(sortfn *) sort_time
(GCompareFunc) sort_time
}
,
{
@ -193,7 +193,7 @@ panel_field_t panel_fields[] = {
N_("sort|a"),
N_("&Access time"), TRUE, TRUE,
string_file_atime,
(sortfn *) sort_atime
(GCompareFunc) sort_atime
}
,
{
@ -203,7 +203,7 @@ panel_field_t panel_fields[] = {
N_("sort|h"),
N_("C&hange time"), TRUE, TRUE,
string_file_ctime,
(sortfn *) sort_ctime
(GCompareFunc) sort_ctime
}
,
{
@ -236,7 +236,7 @@ panel_field_t panel_fields[] = {
N_("sort|i"),
N_("&Inode"), TRUE, TRUE,
string_inode,
(sortfn *) sort_inode
(GCompareFunc) sort_inode
}
,
{
@ -345,7 +345,7 @@ typedef struct format_e
int field_len;
align_crt_t just_mode;
int expand;
const char *(*string_fn) (file_entry *, int len);
const char *(*string_fn) (file_entry_t *, int len);
char *title;
const char *id;
} format_e;
@ -406,7 +406,7 @@ delete_format (format_e * format)
/** This code relies on the default justification!!! */
static void
add_permission_string (const char *dest, int width, file_entry * fe, int attr, int color,
add_permission_string (const char *dest, int width, file_entry_t * fe, int attr, int color,
int is_octal)
{
int i, r, l;
@ -448,7 +448,7 @@ add_permission_string (const char *dest, int width, file_entry * fe, int attr, i
/** String representations of various file attributes name */
static const char *
string_file_name (file_entry * fe, int len)
string_file_name (file_entry_t * fe, int len)
{
static char buffer[MC_MAXPATHLEN * MB_LEN_MAX + 1];
@ -496,7 +496,7 @@ format_device_number (char *buf, size_t bufsize, dev_t dev)
/** size */
static const char *
string_file_size (file_entry * fe, int len)
string_file_size (file_entry_t * fe, int len)
{
static char buffer[BUF_TINY];
@ -519,7 +519,7 @@ string_file_size (file_entry * fe, int len)
/** bsize */
static const char *
string_file_size_brief (file_entry * fe, int len)
string_file_size_brief (file_entry_t * fe, int len)
{
if (S_ISLNK (fe->st.st_mode) && !fe->f.link_to_dir)
{
@ -538,7 +538,7 @@ string_file_size_brief (file_entry * fe, int len)
/** This functions return a string representation of a file entry type */
static const char *
string_file_type (file_entry * fe, int len)
string_file_type (file_entry_t * fe, int len)
{
static char buffer[2];
@ -580,7 +580,7 @@ string_file_type (file_entry * fe, int len)
/** mtime */
static const char *
string_file_mtime (file_entry * fe, int len)
string_file_mtime (file_entry_t * fe, int len)
{
(void) len;
return file_date (fe->st.st_mtime);
@ -590,7 +590,7 @@ string_file_mtime (file_entry * fe, int len)
/** atime */
static const char *
string_file_atime (file_entry * fe, int len)
string_file_atime (file_entry_t * fe, int len)
{
(void) len;
return file_date (fe->st.st_atime);
@ -600,7 +600,7 @@ string_file_atime (file_entry * fe, int len)
/** ctime */
static const char *
string_file_ctime (file_entry * fe, int len)
string_file_ctime (file_entry_t * fe, int len)
{
(void) len;
return file_date (fe->st.st_ctime);
@ -610,7 +610,7 @@ string_file_ctime (file_entry * fe, int len)
/** perm */
static const char *
string_file_permission (file_entry * fe, int len)
string_file_permission (file_entry_t * fe, int len)
{
(void) len;
return string_perm (fe->st.st_mode);
@ -620,7 +620,7 @@ string_file_permission (file_entry * fe, int len)
/** mode */
static const char *
string_file_perm_octal (file_entry * fe, int len)
string_file_perm_octal (file_entry_t * fe, int len)
{
static char buffer[10];
@ -633,7 +633,7 @@ string_file_perm_octal (file_entry * fe, int len)
/** nlink */
static const char *
string_file_nlinks (file_entry * fe, int len)
string_file_nlinks (file_entry_t * fe, int len)
{
static char buffer[BUF_TINY];
@ -646,7 +646,7 @@ string_file_nlinks (file_entry * fe, int len)
/** inode */
static const char *
string_inode (file_entry * fe, int len)
string_inode (file_entry_t * fe, int len)
{
static char buffer[10];
@ -659,7 +659,7 @@ string_inode (file_entry * fe, int len)
/** nuid */
static const char *
string_file_nuid (file_entry * fe, int len)
string_file_nuid (file_entry_t * fe, int len)
{
static char buffer[10];
@ -672,7 +672,7 @@ string_file_nuid (file_entry * fe, int len)
/** ngid */
static const char *
string_file_ngid (file_entry * fe, int len)
string_file_ngid (file_entry_t * fe, int len)
{
static char buffer[10];
@ -685,7 +685,7 @@ string_file_ngid (file_entry * fe, int len)
/** owner */
static const char *
string_file_owner (file_entry * fe, int len)
string_file_owner (file_entry_t * fe, int len)
{
(void) len;
return get_owner (fe->st.st_uid);
@ -695,7 +695,7 @@ string_file_owner (file_entry * fe, int len)
/** group */
static const char *
string_file_group (file_entry * fe, int len)
string_file_group (file_entry_t * fe, int len)
{
(void) len;
return get_group (fe->st.st_gid);
@ -705,7 +705,7 @@ string_file_group (file_entry * fe, int len)
/** mark */
static const char *
string_marked (file_entry * fe, int len)
string_marked (file_entry_t * fe, int len)
{
(void) len;
return fe->f.marked ? "*" : " ";
@ -715,7 +715,7 @@ string_marked (file_entry * fe, int len)
/** space */
static const char *
string_space (file_entry * fe, int len)
string_space (file_entry_t * fe, int len)
{
(void) fe;
(void) len;
@ -726,7 +726,7 @@ string_space (file_entry * fe, int len)
/** dot */
static const char *
string_dot (file_entry * fe, int len)
string_dot (file_entry_t * fe, int len)
{
(void) fe;
(void) len;
@ -736,7 +736,7 @@ string_dot (file_entry * fe, int len)
/* --------------------------------------------------------------------------------------------- */
static int
file_compute_color (int attr, file_entry * fe)
file_compute_color (int attr, file_entry_t * fe)
{
switch (attr)
{
@ -767,13 +767,13 @@ format_file (char *dest, int limit, WPanel * panel, int file_index, int width, i
int color, length, empty_line;
const char *txt;
format_e *format, *home;
file_entry *fe;
file_entry_t *fe;
filename_scroll_flag_t res = FILENAME_NOSCROLL;
(void) dest;
(void) limit;
length = 0;
empty_line = (file_index >= panel->count);
empty_line = (file_index >= panel->dir.len);
home = (isstatus) ? panel->status_format : panel->format;
fe = &panel->dir.list[file_index];
*field_lenght = 0;
@ -1008,7 +1008,7 @@ display_mini_info (WPanel * panel)
else if (DIR_IS_DOTDOT (panel->dir.list[panel->selected].fname))
{
/* FIXME:
* while loading directory (do_load_dir() and do_reload_dir()),
* while loading directory (dir_list_load() and dir_list_reload()),
* the actual stat info about ".." directory isn't got;
* so just don't display incorrect info about ".." directory */
tty_print_string (str_fit_to_term (_("UP--DIR"), w->cols - 2, J_LEFT));
@ -1032,7 +1032,7 @@ paint_dir (WPanel * panel)
panel->max_shift = -1;
for (i = 0; i < items; i++)
{
if (i + panel->top_file >= panel->count)
if (i + panel->top_file >= panel->dir.len)
color = 0;
else
{
@ -1342,7 +1342,7 @@ adjust_top_file (WPanel * panel)
{
int items = ITEMS (panel);
if (panel->count <= items)
if (panel->dir.len <= items)
{
/* If all files fit, show them all. */
panel->top_file = 0;
@ -1364,7 +1364,7 @@ adjust_top_file (WPanel * panel)
if (panel->top_file < i)
panel->top_file = i;
i = panel->count - items;
i = panel->dir.len - items;
if (panel->top_file > i)
panel->top_file = i;
@ -1505,13 +1505,13 @@ panel_format_modified (WPanel * panel)
static void
panel_paint_sort_info (WPanel * panel)
{
if (*panel->sort_info.sort_field->hotkey != '\0')
if (*panel->sort_field->hotkey != '\0')
{
const char *sort_sign =
panel->sort_info.reverse ? panel_sort_down_sign : panel_sort_up_sign;
char *str;
str = g_strdup_printf ("%s%s", sort_sign, Q_ (panel->sort_info.sort_field->hotkey));
str = g_strdup_printf ("%s%s", sort_sign, Q_ (panel->sort_field->hotkey));
widget_move (panel, 1, 1);
tty_print_string (str);
g_free (str);
@ -1580,7 +1580,7 @@ paint_frame (WPanel * panel)
g_string_set_size (format_txt, 0);
if (panel->list_type == list_long
&& strcmp (format->id, panel->sort_info.sort_field->id) == 0)
&& strcmp (format->id, panel->sort_field->id) == 0)
g_string_append (format_txt,
panel->sort_info.reverse
? panel_sort_down_sign : panel_sort_up_sign);
@ -2006,7 +2006,7 @@ unselect_item (WPanel * panel)
static void
move_down (WPanel * panel)
{
if (panel->selected + 1 == panel->count)
if (panel->selected + 1 == panel->dir.len)
return;
unselect_item (panel);
@ -2015,8 +2015,8 @@ move_down (WPanel * panel)
{
/* Scroll window half screen */
panel->top_file += ITEMS (panel) / 2;
if (panel->top_file > panel->count - ITEMS (panel))
panel->top_file = panel->count - ITEMS (panel);
if (panel->top_file > panel->dir.len - ITEMS (panel))
panel->top_file = panel->dir.len - ITEMS (panel);
paint_dir (panel);
}
select_item (panel);
@ -2053,8 +2053,8 @@ move_selection (WPanel * panel, int lines)
int adjust = 0;
new_pos = panel->selected + lines;
if (new_pos >= panel->count)
new_pos = panel->count - 1;
if (new_pos >= panel->dir.len)
new_pos = panel->dir.len - 1;
if (new_pos < 0)
new_pos = 0;
@ -2190,16 +2190,16 @@ next_page (WPanel * panel)
{
int items;
if (panel->selected == panel->count - 1)
if (panel->selected == panel->dir.len - 1)
return;
unselect_item (panel);
items = ITEMS (panel);
if (panel->top_file > panel->count - 2 * items)
items = panel->count - items - panel->top_file;
if (panel->top_file > panel->dir.len - 2 * items)
items = panel->dir.len - items - panel->top_file;
if (panel->top_file + items < 0)
items = -panel->top_file;
if (!items)
panel->selected = panel->count - 1;
panel->selected = panel->dir.len - 1;
else
panel->selected += items;
panel->top_file += items;
@ -2291,7 +2291,7 @@ move_home (WPanel * panel)
static void
move_end (WPanel * panel)
{
if (panel->selected == panel->count - 1)
if (panel->selected == panel->dir.len - 1)
return;
unselect_item (panel);
@ -2312,7 +2312,7 @@ move_end (WPanel * panel)
}
}
panel->selected = panel->count - 1;
panel->selected = panel->dir.len - 1;
paint_dir (panel);
select_item (panel);
}
@ -2363,7 +2363,7 @@ mark_file_right (WPanel * panel)
if (state_mark < 0)
state_mark = selection (panel)->f.marked ? 0 : 1;
lines = min (lines, panel->count - panel->selected - 1);
lines = min (lines, panel->dir.len - panel->selected - 1);
for (; lines != 0; lines--)
{
do_file_mark (panel, panel->selected, state_mark);
@ -2468,7 +2468,7 @@ do_search (WPanel * panel, int c_code)
sel = panel->selected;
for (i = panel->selected; !wrapped || i != panel->selected; i++)
{
if (i >= panel->count)
if (i >= panel->dir.len)
{
i = 0;
if (wrapped)
@ -2510,7 +2510,7 @@ start_search (WPanel * panel)
{
if (panel->searching)
{
if (panel->selected + 1 == panel->count)
if (panel->selected + 1 == panel->dir.len)
panel->selected = 0;
else
move_down (panel);
@ -2554,7 +2554,7 @@ stop_search (WPanel * panel)
/** Return 1 if the Enter key has been processed, 0 otherwise */
static int
do_enter_on_file_entry (file_entry * fe)
do_enter_on_file_entry_t (file_entry_t * fe)
{
vfs_path_t *full_name_vpath;
gboolean ok;
@ -2631,7 +2631,7 @@ do_enter_on_file_entry (file_entry * fe)
static int
do_enter (WPanel * panel)
{
return do_enter_on_file_entry (selection (panel));
return do_enter_on_file_entry_t (selection (panel));
}
/* --------------------------------------------------------------------------------------------- */
@ -2639,7 +2639,7 @@ do_enter (WPanel * panel)
static void
chdir_other_panel (WPanel * panel)
{
const file_entry *entry = &panel->dir.list[panel->selected];
const file_entry_t *entry = &panel->dir.list[panel->selected];
vfs_path_t *new_dir_vpath;
char *sel_entry = NULL;
@ -2817,7 +2817,7 @@ panel_toggle_sort_order_prev (WPanel * panel)
const panel_field_t *pfield = NULL;
title = panel_get_title_without_hotkey (panel->sort_info.sort_field->title_hotkey);
title = panel_get_title_without_hotkey (panel->sort_field->title_hotkey);
lc_index = panel_get_format_field_index_by_name (panel, title);
g_free (title);
@ -2837,7 +2837,7 @@ panel_toggle_sort_order_prev (WPanel * panel)
if (pfield != NULL)
{
panel->sort_info.sort_field = pfield;
panel->sort_field = pfield;
panel_set_sort_order (panel, pfield);
}
}
@ -2853,7 +2853,7 @@ panel_toggle_sort_order_next (WPanel * panel)
gchar *title;
format_field_count = panel_get_format_field_count (panel);
title = panel_get_title_without_hotkey (panel->sort_info.sort_field->title_hotkey);
title = panel_get_title_without_hotkey (panel->sort_field->title_hotkey);
lc_index = panel_get_format_field_index_by_name (panel, title);
g_free (title);
@ -2875,7 +2875,7 @@ panel_toggle_sort_order_next (WPanel * panel)
if (pfield != NULL)
{
panel->sort_info.sort_field = pfield;
panel->sort_field = pfield;
panel_set_sort_order (panel, pfield);
}
}
@ -2887,10 +2887,10 @@ panel_select_sort_order (WPanel * panel)
{
const panel_field_t *sort_order;
sort_order = sort_box (&panel->sort_info);
sort_order = sort_box (&panel->sort_info, panel->sort_field);
if (sort_order != NULL)
{
panel->sort_info.sort_field = sort_order;
panel->sort_field = sort_order;
panel_set_sort_order (panel, sort_order);
}
}
@ -2946,19 +2946,19 @@ panel_content_scroll_right (WPanel * panel)
static void
panel_set_sort_type_by_id (WPanel * panel, const char *name)
{
if (strcmp (panel->sort_info.sort_field->id, name) != 0)
if (strcmp (panel->sort_field->id, name) != 0)
{
const panel_field_t *sort_order;
sort_order = panel_get_field_by_id (name);
if (sort_order == NULL)
return;
panel->sort_info.sort_field = sort_order;
panel->sort_field = sort_order;
}
else
panel->sort_info.reverse = !panel->sort_info.reverse;
panel_set_sort_order (panel, panel->sort_info.sort_field);
panel_set_sort_order (panel, panel->sort_field);
}
/* --------------------------------------------------------------------------------------------- */
@ -3063,10 +3063,8 @@ _do_panel_cd (WPanel * panel, const vfs_path_t * new_dir_vpath, enum cd_enum cd_
/* Reload current panel */
panel_clean_dir (panel);
panel->count =
do_load_dir (panel->cwd_vpath, &panel->dir, panel->sort_info.sort_field->sort_routine,
panel->sort_info.reverse, panel->sort_info.case_sensitive,
panel->sort_info.exec_first, panel->filter);
dir_list_load (&panel->dir, panel->cwd_vpath, panel->sort_field->sort_routine,
&panel->sort_info, panel->filter);
try_to_select (panel, get_parent_dir_name (panel->cwd_vpath, olddir_vpath));
load_hint (0);
@ -3336,7 +3334,7 @@ panel_execute_cmd (WPanel * panel, unsigned long command)
break;
case CK_SortReverse:
panel->sort_info.reverse = !panel->sort_info.reverse;
panel_set_sort_order (panel, panel->sort_info.sort_field);
panel_set_sort_order (panel, panel->sort_field);
break;
case CK_SortByName:
panel_set_sort_type_by_id (panel, "name");
@ -3562,7 +3560,7 @@ mouse_sort_col (WPanel * panel, int x)
if (col_sort_format == NULL)
return;
if (panel->sort_info.sort_field == col_sort_format)
if (panel->sort_field == col_sort_format)
{
/* reverse the sort if clicked column is already the sorted column */
panel->sort_info.reverse = !panel->sort_info.reverse;
@ -3655,7 +3653,8 @@ panel_event (Gpm_Event * event, void *data)
{
if (is_active)
{
if (panels_options.mouse_move_pages && (panel->top_file + ITEMS (panel) < panel->count))
if (panels_options.mouse_move_pages
&& (panel->top_file + ITEMS (panel) < panel->dir.len))
next_page (panel);
else /* We are in last page */
move_down (panel);
@ -3671,16 +3670,16 @@ panel_event (Gpm_Event * event, void *data)
if (!is_active)
change_panel ();
if (panel->top_file + local.y > panel->count)
my_index = panel->count - 1;
if (panel->top_file + local.y > panel->dir.len)
my_index = panel->dir.len - 1;
else
{
my_index = panel->top_file + local.y - 1;
if (panel->split && (local.x > (w->cols - 2) / 2))
my_index += llines (panel);
if (my_index >= panel->count)
my_index = panel->count - 1;
if (my_index >= panel->dir.len)
my_index = panel->dir.len - 1;
}
if (my_index != panel->selected)
@ -3715,7 +3714,7 @@ reload_panelized (WPanel * panel)
if (panel != current_panel)
(void) mc_chdir (panel->cwd_vpath);
for (i = 0, j = 0; i < panel->count; i++)
for (i = 0, j = 0; i < panel->dir.len; i++)
{
vfs_path_t *vpath;
@ -3730,7 +3729,7 @@ reload_panelized (WPanel * panel)
do_file_mark (panel, i, 0);
}
vpath = vfs_path_from_str (list->list[i].fname);
if (mc_lstat (vpath, &list->list[i].st))
if (mc_lstat (vpath, &list->list[i].st) != 0)
g_free (list->list[i].fname);
else
{
@ -3743,9 +3742,9 @@ reload_panelized (WPanel * panel)
vfs_path_free (vpath);
}
if (j == 0)
panel->count = set_zero_dir (list) ? 1 : 0;
dir_list_init (list);
else
panel->count = j;
list->len = j;
if (panel != current_panel)
(void) mc_chdir (current_panel->cwd_vpath);
@ -3842,7 +3841,7 @@ do_try_to_select (WPanel * panel, const char *name)
subdir = vfs_strip_suffix_from_filename (x_basename (name));
/* Search that subdir or filename without prefix (if not panelized panel), select it if found */
for (i = 0; i < panel->count; i++)
for (i = 0; i < panel->dir.len; i++)
{
if (strcmp (subdir, panel->dir.list[i].fname) == 0)
{
@ -3853,8 +3852,8 @@ do_try_to_select (WPanel * panel, const char *name)
}
/* Try to select a file near the file that is missing */
if (panel->selected >= panel->count)
do_select (panel, panel->count - 1);
if (panel->selected >= panel->dir.len)
do_select (panel, panel->dir.len - 1);
g_free (subdir);
}
@ -3896,7 +3895,7 @@ panel_save_current_file_to_clip_file (const gchar * event_group_name, const gcha
gboolean first = TRUE;
char *flist = NULL;
for (i = 0; i < current_panel->count; i++)
for (i = 0; i < current_panel->dir.len; i++)
if (current_panel->dir.list[i].f.marked != 0)
{ /* Skip the unmarked ones */
if (first)
@ -3966,9 +3965,6 @@ try_to_select (WPanel * panel, const char *name)
void
panel_clean_dir (WPanel * panel)
{
int count = panel->count;
panel->count = 0;
panel->top_file = 0;
panel->selected = 0;
panel->marked = 0;
@ -3980,7 +3976,7 @@ panel_clean_dir (WPanel * panel)
panel->content_shift = -1;
panel->max_shift = -1;
clean_dir (&panel->dir, count);
dir_list_clean (&panel->dir);
}
/* --------------------------------------------------------------------------------------------- */
@ -4074,8 +4070,9 @@ panel_new_with_dir (const char *panel_name, const vfs_path_t * vpath)
panel->hist_name = g_strconcat ("Dir Hist ", panel_name, (char *) NULL);
/* directories history will be get later */
panel->dir.list = g_new (file_entry, MIN_FILES);
panel->dir.size = MIN_FILES;
panel->dir.size = DIR_LIST_MIN_SIZE;
panel->dir.list = g_new (file_entry_t, panel->dir.size);
panel->dir.len = 0;
panel->active = 0;
panel->filter = 0;
panel->split = 0;
@ -4142,10 +4139,8 @@ panel_new_with_dir (const char *panel_name, const vfs_path_t * vpath)
}
/* Load the default format */
panel->count =
do_load_dir (panel->cwd_vpath, &panel->dir, panel->sort_info.sort_field->sort_routine,
panel->sort_info.reverse, panel->sort_info.case_sensitive,
panel->sort_info.exec_first, panel->filter);
dir_list_load (&panel->dir, panel->cwd_vpath, panel->sort_field->sort_routine,
&panel->sort_info, panel->filter);
/* Restore old right path */
if (curdir != NULL)
@ -4181,7 +4176,7 @@ panel_reload (WPanel * panel)
{
panel->cwd_vpath = vfs_path_from_str (PATH_SEP_STR);
panel_clean_dir (panel);
panel->count = set_zero_dir (&panel->dir) ? 1 : 0;
dir_list_init (&panel->dir);
return;
}
@ -4189,14 +4184,12 @@ panel_reload (WPanel * panel)
memset (&(panel->dir_stat), 0, sizeof (panel->dir_stat));
show_dir (panel);
panel->count =
do_reload_dir (panel->cwd_vpath, &panel->dir, panel->sort_info.sort_field->sort_routine,
panel->count, panel->sort_info.reverse, panel->sort_info.case_sensitive,
panel->sort_info.exec_first, panel->filter);
dir_list_reload (&panel->dir, panel->cwd_vpath, panel->sort_field->sort_routine,
&panel->sort_info, panel->filter);
panel->dirty = 1;
if (panel->selected >= panel->count)
do_select (panel, panel->count - 1);
if (panel->selected >= panel->dir.len)
do_select (panel, panel->dir.len - 1);
recalculate_panel_summary (panel);
}
@ -4314,8 +4307,8 @@ select_item (WPanel * panel)
if (panel->selected < 0)
panel->selected = 0;
if (panel->selected > panel->count - 1)
panel->selected = panel->count - 1;
if (panel->selected > panel->dir.len - 1)
panel->selected = panel->dir.len - 1;
adjust_top_file (panel);
@ -4333,7 +4326,7 @@ unmark_files (WPanel * panel)
if (!panel->marked)
return;
for (i = 0; i < panel->count; i++)
for (i = 0; i < panel->dir.len; i++)
file_mark (panel, i, 0);
panel->dirs_marked = 0;
@ -4354,7 +4347,7 @@ recalculate_panel_summary (WPanel * panel)
panel->dirs_marked = 0;
panel->total = 0;
for (i = 0; i < panel->count; i++)
for (i = 0; i < panel->dir.len; i++)
if (panel->dir.list[i].f.marked)
{
/* do_file_mark will return immediately if newmark == oldmark.
@ -4447,13 +4440,11 @@ panel_re_sort (WPanel * panel)
filename = g_strdup (selection (panel)->fname);
unselect_item (panel);
do_sort (&panel->dir, panel->sort_info.sort_field->sort_routine, panel->count - 1,
panel->sort_info.reverse, panel->sort_info.case_sensitive,
panel->sort_info.exec_first);
dir_list_sort (&panel->dir, panel->sort_field->sort_routine, &panel->sort_info);
panel->selected = -1;
for (i = panel->count; i; i--)
for (i = panel->dir.len; i != 0; i--)
{
if (!strcmp (panel->dir.list[i - 1].fname, filename))
if (strcmp (panel->dir.list[i - 1].fname, filename) == 0)
{
panel->selected = i - 1;
break;
@ -4473,10 +4464,10 @@ panel_set_sort_order (WPanel * panel, const panel_field_t * sort_order)
if (sort_order == NULL)
return;
panel->sort_info.sort_field = sort_order;
panel->sort_field = sort_order;
/* The directory is already sorted, we have to load the unsorted stuff */
if (sort_order->sort_routine == (sortfn *) unsorted)
if (sort_order->sort_routine == (GCompareFunc) unsorted)
{
char *current_file;

View File

@ -69,25 +69,16 @@ typedef struct panel_field_struct
const char *title_hotkey;
gboolean is_user_choice;
gboolean use_in_user_format;
const char *(*string_fn) (file_entry *, int);
sortfn *sort_routine; /* used by mouse_sort_col() */
const char *(*string_fn) (file_entry_t *, int);
GCompareFunc sort_routine; /* used by mouse_sort_col() */
} panel_field_t;
typedef struct
{
dir_list list;
int count;
vfs_path_t *root_vpath;
} panelized_panel_t;
typedef struct panel_sort_info_struct
{
gboolean reverse; /* Show listing in reverse? */
gboolean case_sensitive; /* Listing is case sensitive? */
gboolean exec_first; /* Show executable top in list? */
const panel_field_t *sort_field;
} panel_sort_info_t;
typedef struct WPanel
{
Widget widget;
@ -100,7 +91,6 @@ typedef struct WPanel
GList *dir_history; /* directory history */
GList *dir_history_current; /* pointer to the current history item */
char *hist_name; /* directory history name for history file */
int count; /* Number of files in dir structure */
int marked; /* Count of marked files */
int dirs_marked; /* Count of marked directories */
uintmax_t total; /* Bytes in marked files */
@ -110,7 +100,10 @@ typedef struct WPanel
gboolean is_panelized; /* Flag: special filelisting, can't reload */
panel_display_t frame_size; /* half or full frame */
char *filter; /* File name filter */
panel_sort_info_t sort_info; /* Sort descriptor */
/* sort */
dir_sort_options_t sort_info;
const panel_field_t *sort_field;
int dirty; /* Should we redisplay the panel? */

View File

@ -311,8 +311,7 @@ remove_from_panelize (struct panelize *entry)
static void
do_external_panelize (char *command)
{
int status, link_to_dir, stale_link;
int next_free = 0;
int link_to_dir, stale_link;
struct stat st;
dir_list *list = &current_panel->dir;
char line[MC_MAXPATHLEN];
@ -331,10 +330,9 @@ do_external_panelize (char *command)
panelize_change_root (current_panel->cwd_vpath);
if (set_zero_dir (list))
next_free++;
dir_list_init (list);
while (1)
while (TRUE)
{
clearerr (external);
if (fgets (line, MC_MAXPATHLEN, external) == NULL)
@ -352,45 +350,36 @@ do_external_panelize (char *command)
name = line + 2;
else
name = line;
status = handle_path (list, name, &st, next_free, &link_to_dir, &stale_link);
if (status == 0)
if (!handle_path (name, &st, &link_to_dir, &stale_link))
continue;
if (status == -1)
if (!dir_list_append (list, name, &st, link_to_dir != 0, stale_link != 0))
break;
list->list[next_free].fnamelen = strlen (name);
list->list[next_free].fname = g_strndup (name, list->list[next_free].fnamelen);
file_mark (current_panel, next_free, 0);
list->list[next_free].f.link_to_dir = link_to_dir;
list->list[next_free].f.stale_link = stale_link;
list->list[next_free].f.dir_size_computed = 0;
list->list[next_free].st = st;
list->list[next_free].sort_key = NULL;
list->list[next_free].second_sort_key = NULL;
next_free++;
if ((next_free & 32) == 0)
file_mark (current_panel, list->len - 1, 0);
if ((list->len & 31) == 0)
rotate_dash (TRUE);
}
current_panel->is_panelized = TRUE;
if (next_free)
{
current_panel->count = next_free;
if (list->list[0].fname[0] == PATH_SEP)
{
vfs_path_t *vpath_root;
int ret;
vpath_root = vfs_path_from_str (PATH_SEP_STR);
panel_set_cwd (current_panel, vpath_root);
ret = mc_chdir (vpath_root);
vfs_path_free (vpath_root);
(void) ret;
}
}
else
if (list->len == 0)
dir_list_init (list);
else if (list->list[0].fname[0] == PATH_SEP)
{
current_panel->count = set_zero_dir (list) ? 1 : 0;
vfs_path_t *vpath_root;
int ret;
vpath_root = vfs_path_from_str (PATH_SEP_STR);
panel_set_cwd (current_panel, vpath_root);
ret = mc_chdir (vpath_root);
vfs_path_free (vpath_root);
(void) ret;
}
if (pclose (external) < 0)
message (D_NORMAL, _("External panelize"), _("Pipe close failed"));
close_error_pipe (D_NORMAL, NULL);
@ -405,29 +394,25 @@ static void
do_panelize_cd (struct WPanel *panel)
{
int i;
dir_list *list = &panel->dir;
dir_list *list;
gboolean panelized_same;
clean_dir (list, panel->count);
dir_list_clean (&panel->dir);
if (panelized_panel.root_vpath == NULL)
panelize_change_root (current_panel->cwd_vpath);
if (panelized_panel.count < 1)
{
if (set_zero_dir (&panelized_panel.list))
panelized_panel.count = 1;
}
else if (panelized_panel.count >= list->size)
{
list->list = g_try_realloc (list->list, sizeof (file_entry) * panelized_panel.count);
list->size = panelized_panel.count;
}
panel->count = panelized_panel.count;
if (panelized_panel.list.len < 1)
dir_list_init (&panelized_panel.list);
else if (panelized_panel.list.len > panel->dir.size)
dir_list_grow (&panel->dir, panelized_panel.list.len - panel->dir.size);
list = &panel->dir;
list->len = panelized_panel.list.len;
panel->is_panelized = TRUE;
panelized_same = (vfs_path_equal (panelized_panel.root_vpath, panel->cwd_vpath));
panelized_same = vfs_path_equal (panelized_panel.root_vpath, panel->cwd_vpath);
for (i = 0; i < panelized_panel.count; i++)
for (i = 0; i < panelized_panel.list.len; i++)
{
if (panelized_same || DIR_IS_DOTDOT (panelized_panel.list.list[i].fname))
{
@ -438,13 +423,15 @@ do_panelize_cd (struct WPanel *panel)
else
{
vfs_path_t *tmp_vpath;
const char *tmp_path;
tmp_vpath =
vfs_path_append_new (panelized_panel.root_vpath, panelized_panel.list.list[i].fname,
NULL);
list->list[i].fname = g_strdup (vfs_path_as_str (tmp_vpath));
tmp_path = vfs_path_as_str (tmp_vpath);
list->list[i].fnamelen = strlen (tmp_path);
list->list[i].fname = g_strndup (tmp_path, list->list[i].fnamelen);
vfs_path_free (tmp_vpath);
list->list[i].fnamelen = strlen (list->list[i].fname);
}
list->list[i].f.link_to_dir = panelized_panel.list.list[i].f.link_to_dir;
list->list[i].f.stale_link = panelized_panel.list.list[i].f.stale_link;
@ -482,19 +469,16 @@ panelize_save_panel (struct WPanel *panel)
panelize_change_root (current_panel->cwd_vpath);
if (panelized_panel.count > 0)
clean_dir (&panelized_panel.list, panelized_panel.count);
if (panel->count < 1)
if (panelized_panel.list.len > 0)
dir_list_clean (&panelized_panel.list);
if (panel->dir.len == 0)
return;
panelized_panel.count = panel->count;
if (panel->count >= panelized_panel.list.size)
{
panelized_panel.list.list = g_try_realloc (panelized_panel.list.list,
sizeof (file_entry) * panel->count);
panelized_panel.list.size = panel->count;
}
for (i = 0; i < panel->count; i++)
if (panel->dir.len > panelized_panel.list.size)
dir_list_grow (&panelized_panel.list, panel->dir.len - panelized_panel.list.size);
panelized_panel.list.len = panel->dir.len;
for (i = 0; i < panel->dir.len; i++)
{
panelized_panel.list.list[i].fnamelen = list->list[i].fnamelen;
panelized_panel.list.list[i].fname =

View File

@ -7,6 +7,7 @@
Written by:
Slava Zanko <slavazanko@gmail.com>, 2013
Andrew Borodin <aborodin@vmail.ru>, 2013
This file is part of the Midnight Commander.
@ -883,7 +884,7 @@ expand_format (struct WEdit *edit_widget, char c, gboolean do_quote)
block = g_string_sized_new (16);
for (i = 0; i < panel->count; i++)
for (i = 0; i < panel->dir.len; i++)
if (panel->dir.list[i].f.marked)
{
char *tmp;

View File

@ -1385,9 +1385,9 @@ panel_load_setup (WPanel * panel, const char *section)
/* Load sort order */
buffer = mc_config_get_string (mc_panels_config, section, "sort_order", "name");
panel->sort_info.sort_field = panel_get_field_by_id (buffer);
if (panel->sort_info.sort_field == NULL)
panel->sort_info.sort_field = panel_get_field_by_id ("name");
panel->sort_field = panel_get_field_by_id (buffer);
if (panel->sort_field == NULL)
panel->sort_field = panel_get_field_by_id ("name");
g_free (buffer);
@ -1431,7 +1431,7 @@ panel_save_setup (struct WPanel *panel, const char *section)
panel->sort_info.case_sensitive);
mc_config_set_int (mc_panels_config, section, "exec_first", panel->sort_info.exec_first);
mc_config_set_string (mc_panels_config, section, "sort_order", panel->sort_info.sort_field->id);
mc_config_set_string (mc_panels_config, section, "sort_order", panel->sort_field->id);
for (i = 0; list_types[i].key != NULL; i++)
if (list_types[i].list_type == panel->list_type)

View File

@ -1494,7 +1494,7 @@ resolve_symlink_without_ls_options (struct vfs_class *me, struct vfs_s_super *su
for (depth = 0; depth < 100; depth++)
{ /* depth protects against recursive symbolic links */
canonicalize_pathname (tmp);
fe = _get_file_entry (bucket, tmp, 0, 0);
fe = _get_file_entry_t (bucket, tmp, 0, 0);
if (fe)
{
if (S_ISLNK (fe->s.st_mode) && fe->l_stat == 0)

View File

@ -286,7 +286,6 @@ mcview_load_next_prev_init (mcview_t * view)
{
/* get file list from current panel. Update it each time */
view->dir = &current_panel->dir;
view->dir_count = &current_panel->count;
view->dir_idx = &current_panel->selected;
}
else if (view->dir == NULL)
@ -299,22 +298,21 @@ mcview_load_next_prev_init (mcview_t * view)
const char *fname;
size_t fname_len;
int i;
dir_sort_options_t sort_op = { FALSE, TRUE, FALSE };
/* load directory where requested file is */
view->dir = g_new0 (dir_list, 1);
view->dir_count = g_new (int, 1);
view->dir_idx = g_new (int, 1);
*view->dir_count = do_load_dir (view->workdir_vpath, view->dir, (sortfn *) sort_name, FALSE,
TRUE, FALSE, NULL);
dir_list_load (view->dir, view->workdir_vpath, (GCompareFunc) sort_name, &sort_op, NULL);
fname = x_basename (vfs_path_as_str (view->filename_vpath));
fname_len = strlen (fname);
/* search current file in the list */
for (i = 0; i != *view->dir_count; i++)
for (i = 0; i != view->dir->len; i++)
{
const file_entry *fe = &view->dir->list[i];
const file_entry_t *fe = &view->dir->list[i];
if (fname_len == fe->fnamelen && strncmp (fname, fe->fname, fname_len) == 0)
break;
@ -334,8 +332,8 @@ mcview_scan_for_file (mcview_t * view, int direction)
for (i = *view->dir_idx + direction; i != *view->dir_idx; i += direction)
{
if (i < 0)
i = *view->dir_count - 1;
if (i == *view->dir_count)
i = view->dir->len - 1;
if (i == view->dir->len)
i = 0;
if (!S_ISDIR (view->dir->list[i].st.st_mode))
break;
@ -350,7 +348,7 @@ static void
mcview_load_next_prev (mcview_t * view, int direction)
{
dir_list *dir;
int *dir_count, *dir_idx;
int *dir_idx;
vfs_path_t *vfile;
vfs_path_t *ext_script = NULL;
@ -359,10 +357,8 @@ mcview_load_next_prev (mcview_t * view, int direction)
/* reinit view */
dir = view->dir;
dir_count = view->dir_count;
dir_idx = view->dir_idx;
view->dir = NULL;
view->dir_count = NULL;
view->dir_idx = NULL;
vfile = vfs_path_append_new (view->workdir_vpath, dir->list[*dir_idx].fname, (char *) NULL);
mcview_done (view);
@ -372,7 +368,6 @@ mcview_load_next_prev (mcview_t * view, int direction)
mcview_load (view, NULL, vfs_path_as_str (vfile), 0);
vfs_path_free (vfile);
view->dir = dir;
view->dir_count = dir_count;
view->dir_idx = dir_idx;
view->ext_script = ext_script;

View File

@ -184,8 +184,6 @@ struct mcview_struct
dir_list *dir; /* List of current directory files
* to handle CK_FileNext and CK_FilePrev commands */
int *dir_count; /* Number of files in dir structure.
* Pointer is used here as reference to WPanel::count */
int *dir_idx; /* Index of current file in dir structure.
* Pointer is used here as reference to WPanel::count */
vfs_path_t *ext_script; /* Temporary script file created by regex_command_for() */

View File

@ -78,7 +78,7 @@ mcview_toggle_magic_mode (mcview_t * view)
{
char *command;
dir_list *dir;
int *dir_count, *dir_idx;
int *dir_idx;
mcview_altered_magic_flag = 1;
view->magic_mode = !view->magic_mode;
@ -86,16 +86,13 @@ mcview_toggle_magic_mode (mcview_t * view)
/* reinit view */
command = g_strdup (view->command);
dir = view->dir;
dir_count = view->dir_count;
dir_idx = view->dir_idx;
view->dir = NULL;
view->dir_count = NULL;
view->dir_idx = NULL;
mcview_done (view);
mcview_init (view);
mcview_load (view, command, vfs_path_as_str (view->filename_vpath), 0);
view->dir = dir;
view->dir_count = dir_count;
view->dir_idx = dir_idx;
g_free (command);
@ -253,9 +250,8 @@ mcview_done (mcview_t * view)
if (mc_global.mc_run_mode == MC_RUN_VIEWER && view->dir != NULL)
{
/* mcviewer is the owner of file list */
clean_dir (view->dir, *view->dir_count);
dir_list_clean (view->dir);
g_free (view->dir->list);
g_free (view->dir_count);
g_free (view->dir_idx);
g_free (view->dir);
}

View File

@ -51,8 +51,9 @@ setup (void)
mc_global.mc_run_mode = MC_RUN_FULL;
current_panel = g_new0 (struct WPanel, 1);
current_panel->cwd_vpath = vfs_path_from_str ("/home");
current_panel->dir.list = g_new0 (file_entry, MIN_FILES);
current_panel->dir.size = MIN_FILES;
current_panel->dir.size = DIR_LIST_MIN_SIZE;
current_panel->dir.list = g_new0 (file_entry_t, current_panel->dir.size);
current_panel->dir.len = 0;
}
static void
@ -74,12 +75,12 @@ START_TEST (sanitize_variables)
const char *expected_string;
current_panel->selected = 0;
current_panel->dir.len = 3;
current_panel->dir.list[0].fname = (char *) "selected file.txt";
current_panel->dir.list[1].fname = (char *) "tagged file1.txt";
current_panel->dir.list[1].f.marked = TRUE;
current_panel->dir.list[2].fname = (char *) "tagged file2.txt";
current_panel->dir.list[2].f.marked = TRUE;
current_panel->count = 3;
/* when */
filename_vpath = vfs_path_from_str ("/tmp/blabla.txt");