Example #1
0
// Do a three step traversal: by file, then fn, then line.
// Returns a pointer to the line CC, creates a new one if necessary.
static LineCC* get_lineCC(Addr origAddr)
{
   Char    file[FILE_LEN], fn[FN_LEN];
   Int     line;
   CodeLoc loc;
   LineCC* lineCC;

   get_debug_info(origAddr, file, fn, &line);

   VGP_PUSHCC(VgpGetLineCC);

   loc.file = file;
   loc.fn   = fn;
   loc.line = line;

   lineCC = VG_(OSet_Lookup)(CC_table, &loc);
   if (!lineCC) {
      // Allocate and zero a new node.
      lineCC           = VG_(OSet_AllocNode)(CC_table, sizeof(LineCC));
      lineCC->loc.file = get_perm_string(loc.file);
      lineCC->loc.fn   = get_perm_string(loc.fn);
      lineCC->loc.line = loc.line;
      VG_(OSet_Insert)(CC_table, lineCC);
   }

   VGP_POPCC(VgpGetLineCC);
   return lineCC;
}
Example #2
0
File: ui.c Project: BlackLight/vifm
void
update_stat_window(FileView *view)
{
	char name_buf[20];
	char perm_buf[26];
	char size_buf[56];
	char uid_buf[26];
	struct passwd *pwd_buf;
	int x, y;

	getmaxyx(stat_win, y, x);
	snprintf(name_buf, sizeof(name_buf), "%s", get_current_file_name(view));
	describe_file_size(size_buf, sizeof(size_buf),
			view->dir_entry[view->list_pos].size);
	
	if((pwd_buf = getpwuid(view->dir_entry[view->list_pos].uid)) == NULL)
	{
		snprintf (uid_buf, sizeof(uid_buf), "  %d", 
				(int) view->dir_entry[view->list_pos].uid);
	}
	else
	{
		snprintf(uid_buf, sizeof(uid_buf), "  %s", pwd_buf->pw_name);
	}
	get_perm_string(perm_buf, sizeof(perm_buf), 
			view->dir_entry[view->list_pos].mode);
	werase(stat_win);

	mvwaddstr(stat_win, 0, 2, name_buf);
	mvwaddstr(stat_win, 0, 24, size_buf);
	mvwaddstr(stat_win, 0, 36, perm_buf);
	mvwaddstr(stat_win, 0, 46, uid_buf);
	snprintf(name_buf, sizeof(name_buf), "%d %s filtered", 
			view->filtered, view->filtered == 1 ? "file" : "files");


	if(view->filtered > 0)
		mvwaddstr(stat_win, 0, x - (strlen(name_buf) +2) , name_buf);  


	wnoutrefresh(stat_win);
	update_pos_window(view);
}
Example #3
0
void
redraw_file_info_dialog(void)
{
	const dir_entry_t *entry;
	char perm_buf[26];
	char size_buf[56];
	char buf[256];
#ifndef _WIN32
	char id_buf[26];
#endif
	int curr_y;
	uint64_t size;
	int size_not_precise;

	assert(view != NULL);

	if(resize_for_menu_like() != 0)
	{
		return;
	}

	werase(menu_win);

	entry = &view->dir_entry[view->list_pos];

	size = 0;
	if(entry->type == FT_DIR)
	{
		char full_path[PATH_MAX];
		get_current_full_path(view, sizeof(full_path), full_path);
		tree_get_data(curr_stats.dirsize_cache, full_path, &size);
	}

	if(size == 0)
	{
		size = entry->size;
	}

	size_not_precise = friendly_size_notation(size, sizeof(size_buf), size_buf);

	curr_y = 2;

	curr_y += print_item("Path: ", entry->origin, curr_y);
	curr_y += print_item("Name: ", entry->name, curr_y);

	mvwaddstr(menu_win, curr_y, 2, "Size: ");
	mvwaddstr(menu_win, curr_y, 8, size_buf);
	if(size_not_precise)
	{
		snprintf(size_buf, sizeof(size_buf), " (%" PRId64 " bytes)", size);
		waddstr(menu_win, size_buf);
	}
	curr_y += 2;

	curr_y += show_file_type(view, curr_y);
	curr_y += show_mime_type(view, curr_y);

#ifndef _WIN32
	get_perm_string(perm_buf, sizeof(perm_buf), entry->mode);
	curr_y += print_item("Permissions: ", perm_buf, curr_y);
#else
	copy_str(perm_buf, sizeof(perm_buf), attr_str_long(entry->attrs));
	curr_y += print_item("Attributes: ", perm_buf, curr_y);
#endif

	format_time(entry->mtime, buf, sizeof(buf));
	curr_y += print_item("Modified: ", buf, curr_y);

	format_time(entry->atime, buf, sizeof(buf));
	curr_y += print_item("Accessed: ", buf, curr_y);

	format_time(entry->ctime, buf, sizeof(buf));
#ifndef _WIN32
	curr_y += print_item("Changed: ", buf, curr_y);
#else
	curr_y += print_item("Created: ", buf, curr_y);
#endif

#ifndef _WIN32
	get_uid_string(entry, 0, sizeof(id_buf), id_buf);
	curr_y += print_item("Owner: ", id_buf, curr_y);

	get_gid_string(entry, 0, sizeof(id_buf), id_buf);
	curr_y += print_item("Group: ", id_buf, curr_y);
#endif

	/* Fake use after last assignment. */
	(void)curr_y;

	box(menu_win, 0, 0);
	checked_wmove(menu_win, 0, 3);
	wprint(menu_win, " File Information ");
	wrefresh(menu_win);

	was_redraw = 1;
}
Example #4
0
void
redraw_file_info_dialog(void)
{
	char name_buf[NAME_MAX];
	char perm_buf[26];
	char size_buf[56];
	char buf[256];
#ifndef _WIN32
	char uid_buf[26];
	struct passwd *pwd_buf;
	struct group *grp_buf;
#endif
	struct tm *tm_ptr;
	int curr_y;
	uint64_t size;
	int size_not_precise;

	assert(view != NULL);

	resize_for_menu_like();

	werase(menu_win);

	snprintf(name_buf, sizeof(name_buf), "%s",
			view->dir_entry[view->list_pos].name);

	size = 0;
	if(view->dir_entry[view->list_pos].type == DIRECTORY)
		tree_get_data(curr_stats.dirsize_cache,
				view->dir_entry[view->list_pos].name, &size);

	if(size == 0)
		size = view->dir_entry[view->list_pos].size;

	size_not_precise = friendly_size_notation(size, sizeof(size_buf), size_buf);

#ifndef _WIN32
	if((pwd_buf = getpwuid(view->dir_entry[view->list_pos].uid)) == NULL)
	{
		snprintf(uid_buf, sizeof(uid_buf), "%d",
				(int) view->dir_entry[view->list_pos].uid);
	}
	else
	{
		snprintf(uid_buf, sizeof(uid_buf), "%s", pwd_buf->pw_name);
	}
	get_perm_string(perm_buf, sizeof(perm_buf),
			view->dir_entry[view->list_pos].mode);
#else
	snprintf(perm_buf, sizeof(perm_buf), "%s",
			attr_str_long(view->dir_entry[view->list_pos].attrs));
#endif

	curr_y = 2;
	mvwaddstr(menu_win, curr_y, 2, "File: ");
	name_buf[getmaxx(menu_win) - 8] = '\0';
	checked_wmove(menu_win, curr_y, 8);
	wprint(menu_win, name_buf);
	curr_y += 2;
	mvwaddstr(menu_win, curr_y, 2, "Size: ");
	mvwaddstr(menu_win, curr_y, 8, size_buf);
	if(size_not_precise)
	{
		snprintf(size_buf, sizeof(size_buf), " (%" PRId64 " bytes)", size);
		waddstr(menu_win, size_buf);
	}
	curr_y += 2;

	curr_y += show_file_type(view, curr_y);
	curr_y += show_mime_type(view, curr_y);

#ifndef _WIN32
	mvwaddstr(menu_win, curr_y, 2, "Permissions: ");
#else
	mvwaddstr(menu_win, curr_y, 2, "Attributes: ");
#endif
	mvwaddstr(menu_win, curr_y, 15, perm_buf);
	curr_y += 2;

	mvwaddstr(menu_win, curr_y, 2, "Modified: ");
	tm_ptr = localtime(&view->dir_entry[view->list_pos].mtime);
	strftime(buf, sizeof (buf), "%a %b %d %Y %I:%M %p", tm_ptr);
	checked_wmove(menu_win, curr_y, 13);
	wprint(menu_win, buf);
	curr_y += 2;

	mvwaddstr(menu_win, curr_y, 2, "Accessed: ");
	tm_ptr = localtime(&view->dir_entry[view->list_pos].atime);
	strftime(buf, sizeof (buf), "%a %b %d %Y %I:%M %p", tm_ptr);
	checked_wmove(menu_win, curr_y, 13);
	wprint(menu_win, buf);
	curr_y += 2;

#ifndef _WIN32
	mvwaddstr(menu_win, curr_y, 2, "Changed: ");
#else
	mvwaddstr(menu_win, curr_y, 2, "Created: ");
#endif
	tm_ptr = localtime(&view->dir_entry[view->list_pos].ctime);
	strftime(buf, sizeof (buf), "%a %b %d %Y %I:%M %p", tm_ptr);
	checked_wmove(menu_win, curr_y, 13);
	wprint(menu_win, buf);
	curr_y += 2;

#ifndef _WIN32
	mvwaddstr(menu_win, curr_y, 2, "Owner: ");
	mvwaddstr(menu_win, curr_y, 10, uid_buf);
	curr_y += 2;

	mvwaddstr(menu_win, curr_y, 2, "Group: ");
	if((grp_buf = getgrgid(view->dir_entry[view->list_pos].gid)) != NULL)
		mvwaddstr(menu_win, curr_y, 10, grp_buf->gr_name);
#endif

	box(menu_win, 0, 0);
	checked_wmove(menu_win, 0, 3);
	wprint(menu_win, " File Information ");
	wrefresh(menu_win);

	was_redraw = 1;
}
Example #5
0
/* Expands macros in the *format string advancing the pointer as it goes.  The
 * opt represents conditional expression state, should be zero for non-recursive
 * calls.  Returns newly allocated string, which should be freed by the
 * caller. */
static char *
parse_view_macros(FileView *view, const char **format, const char macros[],
		int opt)
{
	const dir_entry_t *const entry = &view->dir_entry[view->list_pos];
	char *result = strdup("");
	size_t len = 0;
	char c;
	int nexpansions = 0;

	while((c = **format) != '\0')
	{
		size_t width = 0;
		int left_align = 0;
		char buf[PATH_MAX];
		const char *const next = ++*format;
		int skip, ok;

		if(c != '%' || (!char_is_one_of(macros, *next) && !isdigit(*next)))
		{
			if(strappendch(&result, &len, c) != 0)
			{
				break;
			}
			continue;
		}

		if(*next == '-')
		{
			left_align = 1;
			++*format;
		}

		while(isdigit(**format))
		{
			width = width*10 + *(*format)++ - '0';
		}
		c = *(*format)++;

		skip = 0;
		ok = 1;
		switch(c)
		{
			case 't':
				format_entry_name(entry, sizeof(buf), buf);
				break;
			case 'A':
#ifndef _WIN32
				get_perm_string(buf, sizeof(buf), entry->mode);
#else
				snprintf(buf, sizeof(buf), "%s", attr_str_long(entry->attrs));
#endif
				break;
			case 'u':
				get_uid_string(entry, 0, sizeof(buf), buf);
				break;
			case 'g':
				get_gid_string(entry, 0, sizeof(buf), buf);
				break;
			case 's':
				friendly_size_notation(entry->size, sizeof(buf), buf);
				break;
			case 'E':
				{
					uint64_t size = 0;
					if(view->selected_files > 0)
					{
						int i;
						for(i = 0; i < view->list_rows; i++)
						{
							if(view->dir_entry[i].selected)
							{
								size += get_file_size_by_entry(view, i);
							}
						}
					}
					/* Make exception for VISUAL_MODE, since it can contain empty
					 * selection when cursor is on ../ directory. */
					else if(!vle_mode_is(VISUAL_MODE))
					{
						size = get_file_size_by_entry(view, view->list_pos);
					}
					friendly_size_notation(size, sizeof(buf), buf);
				}
				break;
			case 'd':
				{
					struct tm *tm_ptr = localtime(&entry->mtime);
					strftime(buf, sizeof(buf), cfg.time_format, tm_ptr);
				}
				break;
			case '-':
				skip = expand_num(buf, sizeof(buf), view->filtered);
				break;
			case 'l':
				skip = expand_num(buf, sizeof(buf), view->list_pos + 1);
				break;
			case 'L':
				skip = expand_num(buf, sizeof(buf), view->list_rows + view->filtered);
				break;
			case 'S':
				skip = expand_num(buf, sizeof(buf), view->list_rows);
				break;
			case '%':
				snprintf(buf, sizeof(buf), "%%");
				break;
			case '[':
				{
					char *const opt_str = parse_view_macros(view, format, macros, 1);
					copy_str(buf, sizeof(buf), opt_str);
					free(opt_str);
					break;
				}
			case ']':
				if(opt)
				{
					if(nexpansions == 0)
					{
						replace_string(&result, "");
					}
					return result;
				}
				else
				{
					LOG_INFO_MSG("Unmatched %]", c);
					ok = 0;
				}
				break;

			default:
				LOG_INFO_MSG("Unexpected %%-sequence: %%%c", c);
				ok = 0;
				break;
		}

		if(!ok)
		{
			*format = next;
			if(strappendch(&result, &len, '%') != 0)
			{
				break;
			}
			continue;
		}

		check_expanded_str(buf, skip, &nexpansions);
		stralign(buf, width, ' ', left_align);

		if(strappend(&result, &len, buf) != 0)
		{
			break;
		}
	}

	/* Unmatched %[. */
	if(opt)
	{
		(void)strprepend(&result, &len, "%[");
	}

	return result;
}
Example #6
0
/* Formats status line in the "old way" (before introduction of 'statusline'
 * option). */
static void
update_stat_window_old(FileView *view, int lazy_redraw)
{
	const dir_entry_t *const entry = &view->dir_entry[view->list_pos];
	char name_buf[160*2 + 1];
	char perm_buf[26];
	char size_buf[56];
	char id_buf[52];
	int x;
	int cur_x;
	size_t print_width;
	char *filename;

	x = getmaxx(stdscr);
	wresize(stat_win, 1, x);
	wbkgdset(stat_win, COLOR_PAIR(cfg.cs.pair[STATUS_LINE_COLOR]) |
			cfg.cs.color[STATUS_LINE_COLOR].attr);

	filename = get_current_file_name(view);
	print_width = utf8_strsnlen(filename, 20 + MAX(0, x - 83));
	snprintf(name_buf, MIN(sizeof(name_buf), print_width + 1), "%s", filename);
	friendly_size_notation(entry->size, sizeof(size_buf), size_buf);

	get_uid_string(entry, 0, sizeof(id_buf), id_buf);
	if(id_buf[0] != '\0')
		strcat(id_buf, ":");
	get_gid_string(entry, 0, sizeof(id_buf) - strlen(id_buf),
			id_buf + strlen(id_buf));
#ifndef _WIN32
	get_perm_string(perm_buf, sizeof(perm_buf), entry->mode);
#else
	snprintf(perm_buf, sizeof(perm_buf), "%s", attr_str_long(entry->attrs));
#endif

	werase(stat_win);
	cur_x = 2;
	checked_wmove(stat_win, 0, cur_x);
	wprint(stat_win, name_buf);
	cur_x += 22;
	if(x > 83)
		cur_x += x - 83;
	mvwaddstr(stat_win, 0, cur_x, size_buf);
	cur_x += 12;
	mvwaddstr(stat_win, 0, cur_x, perm_buf);
	cur_x += 11;

	snprintf(name_buf, sizeof(name_buf), "%d %s filtered", view->filtered,
			(view->filtered == 1) ? "file" : "files");
	if(view->filtered > 0)
		mvwaddstr(stat_win, 0, x - (strlen(name_buf) + 2), name_buf);

	if(cur_x + strlen(id_buf) + 1 > x - (strlen(name_buf) + 2))
		break_at(id_buf, ':');
	if(cur_x + strlen(id_buf) + 1 > x - (strlen(name_buf) + 2))
		id_buf[0] = '\0';
	mvwaddstr(stat_win, 0, cur_x, id_buf);

	if(lazy_redraw)
	{
		wnoutrefresh(stat_win);
	}
	else
	{
		wrefresh(stat_win);
	}
}
Example #7
0
File: sort.c Project: lyuts/vifm
static int
sort_dir_list(const void *one, const void *two)
{
	int retval;
	char *pfirst, *psecond;
	dir_entry_t *const first = (dir_entry_t *)one;
	dir_entry_t *const second = (dir_entry_t *)two;
	int first_is_dir;
	int second_is_dir;
	int dirs;

	if(is_parent_dir(first->name))
	{
		return -1;
	}
	else if(is_parent_dir(second->name))
	{
		return 1;
	}

	first_is_dir = is_directory_entry(first);
	second_is_dir = is_directory_entry(second);

	dirs = first_is_dir || second_is_dir;

	retval = 0;
	switch(sort_type)
	{
		case SORT_BY_NAME:
		case SORT_BY_INAME:
			if(first->name[0] == '.' && second->name[0] != '.')
				retval = -1;
			else if(first->name[0] != '.' && second->name[0] == '.')
				retval = 1;
			else
				retval = compare_file_names(dirs, first->name, second->name,
						sort_type == SORT_BY_INAME);
			break;

		case SORT_BY_TYPE:
			if(first_is_dir != second_is_dir)
			{
				retval = first_is_dir ? -1 : 1;
			}
			break;

		case SORT_BY_EXTENSION:
			pfirst  = strrchr(first->name,  '.');
			psecond = strrchr(second->name, '.');

			if(pfirst && psecond)
				retval = compare_file_names(dirs, ++pfirst, ++psecond, 0);
			else if(pfirst || psecond)
				retval = pfirst ? -1 : 1;
			else
				retval = compare_file_names(dirs, first->name, second->name, 0);
			break;

		case SORT_BY_SIZE:
			{
				if(first_is_dir)
					tree_get_data(curr_stats.dirsize_cache, first->name, &first->size);

				if(second_is_dir)
					tree_get_data(curr_stats.dirsize_cache, second->name, &second->size);

				retval = (first->size < second->size) ?
						-1 : (first->size > second->size);
			}
			break;

		case SORT_BY_TIME_MODIFIED:
			retval = first->mtime - second->mtime;
			break;

		case SORT_BY_TIME_ACCESSED:
			retval = first->atime - second->atime;
			break;

		case SORT_BY_TIME_CHANGED:
			retval = first->ctime - second->ctime;
			break;
#ifndef _WIN32
		case SORT_BY_MODE:
			retval = first->mode - second->mode;
			break;

		case SORT_BY_OWNER_NAME: /* FIXME */
		case SORT_BY_OWNER_ID:
			retval = first->uid - second->uid;
			break;

		case SORT_BY_GROUP_NAME: /* FIXME */
		case SORT_BY_GROUP_ID:
			retval = first->gid - second->gid;
			break;

		case SORT_BY_PERMISSIONS:
			{
				char first_perm[11], second_perm[11];
				get_perm_string(first_perm, sizeof(first_perm), first->mode);
				get_perm_string(second_perm, sizeof(second_perm), second->mode);
				retval = strcmp(first_perm, second_perm);
			}
			break;
#endif

		default:
			assert(0 && "All possible sort options should be handled");
			break;
	}

	if(retval == 0)
	{
		retval = first->list_num - second->list_num;
	}
	else if(sort_descending)
	{
		retval = -retval;
	}

	return retval;
}
Example #8
0
/* Expands macros in the *format string advancing the pointer as it goes.  The
 * opt represents conditional expression state, should be zero for non-recursive
 * calls.  Returns newly allocated string, which should be freed by the
 * caller. */
static LineWithAttrs
parse_view_macros(view_t *view, const char **format, const char macros[],
		int opt)
{
	const dir_entry_t *const curr = get_current_entry(view);
	LineWithAttrs result = { .line = strdup(""), .attrs = strdup("") };
	char c;
	int nexpansions = 0;
	int has_expander = 0;

	if(curr == NULL)
	{
		return result;
	}

	while((c = **format) != '\0')
	{
		size_t width = 0;
		int left_align = 0;
		char buf[PATH_MAX + 1];
		const char *const next = ++*format;
		int skip, ok;

		if(c != '%' ||
				(!char_is_one_of(macros, *next) && !isdigit(*next) &&
				 (*next != '=' || has_expander)))
		{
			if(strappendch(&result.line, &result.line_len, c) != 0)
			{
				break;
			}
			continue;
		}

		if(*next == '=')
		{
			(void)sync_attrs(&result, 0);

			if(strappend(&result.line, &result.line_len, "%=") != 0 ||
					strappendch(&result.attrs, &result.attrs_len, '=') != 0)
			{
				break;
			}
			++*format;
			has_expander = 1;
			continue;
		}

		if(*next == '-')
		{
			left_align = 1;
			++*format;
		}

		while(isdigit(**format))
		{
			width = width*10 + *(*format)++ - '0';
		}
		c = *(*format)++;

		skip = 0;
		ok = 1;
		buf[0] = '\0';
		switch(c)
		{
			case 'a':
				friendly_size_notation(get_free_space(curr_view->curr_dir), sizeof(buf),
						buf);
				break;
			case 't':
				format_entry_name(curr, NF_FULL, sizeof(buf), buf);
				break;
			case 'T':
				if(curr->type == FT_LINK)
				{
					char full_path[PATH_MAX + 1];
					char link_path[PATH_MAX + 1];  //add by sim1
					get_full_path_of(curr, sizeof(full_path), full_path);
					//mod by sim1 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
					if(get_link_target(full_path, link_path, sizeof(link_path)) != 0)
					{
						copy_str(buf, sizeof(buf), "Failed to resolve link");
					}
					else
					{
						snprintf(buf, sizeof(buf), " -> %s", link_path);
					}
					//mod by sim1 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
				}
				break;
			case 'f':
				get_short_path_of(view, curr, NF_FULL, 0, sizeof(buf), buf);
				break;
			case 'A':
#ifndef _WIN32
				get_perm_string(buf, sizeof(buf), curr->mode);
#else
				copy_str(buf, sizeof(buf), attr_str_long(curr->attrs));
#endif
				break;
			case 'u':
				get_uid_string(curr, 0, sizeof(buf), buf);
				break;
			case 'g':
				get_gid_string(curr, 0, sizeof(buf), buf);
				break;
			case 's':
				friendly_size_notation(fentry_get_size(view, curr), sizeof(buf), buf);
				break;
			//add by sim1 ************************************************
			case 'r':
				{
					char path[PATH_MAX] = {0};
					get_full_path_at(view, view->list_pos, sizeof(path), path);
					(void)get_rating_string(buf, sizeof(buf), path);
				}
				break;
			case 'n':
				{
					int nitems = !fentry_is_dir(curr) ? 0 : (int)fentry_get_nitems(view, curr);
					snprintf(buf, sizeof(buf), "%d", nitems);
				}
				break;
			//add by sim1 ************************************************
			case 'E':
				{
					uint64_t size = 0U;

					typedef int (*iter_f)(view_t *view, dir_entry_t **entry);
					/* No current element for visual mode, since it can contain truly
					 * empty selection when cursor is on ../ directory. */
					iter_f iter = vle_mode_is(VISUAL_MODE) ? &iter_selected_entries
					                                       : &iter_selection_or_current;

					dir_entry_t *entry = NULL;
					while(iter(view, &entry))
					{
						size += fentry_get_size(view, entry);
					}

					friendly_size_notation(size, sizeof(buf), buf);
				}
				break;
			case 'd':
				{
					struct tm *tm_ptr = localtime(&curr->mtime);
					strftime(buf, sizeof(buf), cfg.time_format, tm_ptr);
				}
				break;
			case '-':
			case 'x':
				skip = expand_num(buf, sizeof(buf), view->filtered);
				break;
			case 'l':
				skip = expand_num(buf, sizeof(buf), view->list_pos + 1);
				break;
			case 'L':
				skip = expand_num(buf, sizeof(buf), view->list_rows + view->filtered);
				break;
			case 'S':
				skip = expand_num(buf, sizeof(buf), view->list_rows);
				break;
			case '%':
				copy_str(buf, sizeof(buf), "%");
				break;
			case 'z':
				copy_str(buf, sizeof(buf), get_tip());
				break;
			case 'D':
				if(curr_stats.number_of_windows == 1)
				{
					view_t *const other = (view == curr_view) ? other_view : curr_view;
					//mod by sim1
					//copy_str(buf, sizeof(buf), replace_home_part(other->curr_dir));
					snprintf(buf, sizeof(buf), " ‖ %s", replace_home_part(other->curr_dir));
				}
				break;
			case '[':
				{
					LineWithAttrs opt = parse_view_macros(view, format, macros, 1);
					copy_str(buf, sizeof(buf), opt.line);
					free(opt.line);

					char *attrs = opt.attrs;
					if(sync_attrs(&result, 0) && opt.attrs_len > 0U)
					{
						if(*attrs != ' ')
						{
							result.attrs[result.attrs_len - 1U] = *attrs;
						}
						++attrs;
					}
					strappend(&result.attrs, &result.attrs_len, attrs);
					free(opt.attrs);
					break;
				}
			case ']':
				if(opt)
				{
					if(nexpansions == 0)
					{
						replace_string(&result.line, "");
						replace_string(&result.attrs, "");
						result.line_len = 0U;
						result.attrs_len = 0U;
					}
					if(sync_attrs(&result, 0))
					{
						result.attrs[--result.attrs_len] = '\0';
					}
					return result;
				}

				LOG_INFO_MSG("Unmatched %%]");
				ok = 0;
				break;
			case '{':
				{
					/* Try to find matching closing bracket
					 * TODO: implement the way to escape it, so that the expr may contain
					 * closing brackets */
					const char *e = strchr(*format, '}');
					char *expr = NULL, *resstr = NULL;
					var_t res = var_false();
					ParsingErrors parsing_error;

					/* If there's no matching closing bracket, just add the opening one
					 * literally */
					if(e == NULL)
					{
						ok = 0;
						break;
					}

					/* Create a NULL-terminated copy of the given expr.
					 * TODO: we could temporarily use buf for that, to avoid extra
					 * allocation, but explicitly named variable reads better. */
					expr = calloc(e - (*format) + 1 /* NUL-term */, 1);
					memcpy(expr, *format, e - (*format));

					/* Try to parse expr, and convert the res to string if succeed. */
					parsing_error = parse(expr, 0, &res);
					if(parsing_error == PE_NO_ERROR)
					{
						resstr = var_to_str(res);
					}

					if(resstr != NULL)
					{
						copy_str(buf, sizeof(buf), resstr);
					}
					else
					{
						copy_str(buf, sizeof(buf), "<Invalid expr>");
					}

					var_free(res);
					free(resstr);
					free(expr);

					*format = e + 1 /* closing bracket */;
				}
				break;
			case '*':
				if(width > 9)
				{
					snprintf(buf, sizeof(buf), "%%%d*", (int)width);
					width = 0;
					break;
				}
				(void)sync_attrs(&result, 1);
				result.attrs[result.attrs_len - 1] = '0' + width;
				width = 0;
				break;

			default:
				LOG_INFO_MSG("Unexpected %%-sequence: %%%c", c);
				ok = 0;
				break;
		}

		if(char_is_one_of("tTAugsEd", c) && fentry_is_fake(curr))
		{
			buf[0] = '\0';
		}

		if(!ok)
		{
			*format = next;
			if(strappendch(&result.line, &result.line_len, '%') != 0)
			{
				break;
			}
			continue;
		}

		check_expanded_str(buf, skip, &nexpansions);
		stralign(buf, width, ' ', left_align);

		if(strappend(&result.line, &result.line_len, buf) != 0)
		{
			break;
		}
	}

	/* Unmatched %[. */
	if(opt)
	{
		(void)strprepend(&result.line, &result.line_len, "%[");
	}

	if(sync_attrs(&result, 0))
	{
		result.attrs[--result.attrs_len] = '\0';
	}
	return result;
}

/* Makes sure that result->attrs has at least as many elements as result->line
 * contains characters + extra_width.  Returns non-zero if result->attrs has
 * extra characters compared to result->line. */
static int
sync_attrs(LineWithAttrs *result, int extra_width)
{
	const size_t nchars = utf8_strsw(result->line) + extra_width;
	if(result->attrs_len < nchars)
	{
		char *const new_attrs = format_str("%s%*s", result->attrs,
				(int)(nchars - result->attrs_len), "");
		free(result->attrs);
		result->attrs = new_attrs;
		result->attrs_len = nchars;
	}
	return (result->attrs_len > nchars);
}

/* Prints number into the buffer.  Returns non-zero if numeric value is
 * "empty" (zero). */
static int
expand_num(char buf[], size_t buf_len, int val)
{
	snprintf(buf, buf_len, "%d", val);
	return (val == 0);
}
Example #9
0
/* Formats status line in the "old way" (before introduction of 'statusline'
 * option). */
static void
update_stat_window_old(view_t *view, int lazy_redraw)
{
	const dir_entry_t *const curr = get_current_entry(view);
	char name_buf[160*2 + 1];
	char perm_buf[26];
	char size_buf[64];
	char id_buf[52];
	int x;
	int cur_x;
	size_t print_width;
	char *filename;

	if(curr == NULL || fentry_is_fake(curr))
	{
		werase(stat_win);
		refresh_window(stat_win, lazy_redraw);
		return;
	}

	x = getmaxx(stdscr);
	wresize(stat_win, 1, x);

	ui_set_bg(stat_win, &cfg.cs.color[STATUS_LINE_COLOR],
			cfg.cs.pair[STATUS_LINE_COLOR]);

	filename = get_current_file_name(view);
	print_width = utf8_strsnlen(filename, 20 + MAX(0, x - 83));
	copy_str(name_buf, MIN(sizeof(name_buf), print_width + 1), filename);
	friendly_size_notation(fentry_get_size(view, curr), sizeof(size_buf),
			size_buf);

	get_uid_string(curr, 0, sizeof(id_buf), id_buf);
	if(id_buf[0] != '\0')
		strcat(id_buf, ":");
	get_gid_string(curr, 0, sizeof(id_buf) - strlen(id_buf),
			id_buf + strlen(id_buf));
#ifndef _WIN32
	get_perm_string(perm_buf, sizeof(perm_buf), curr->mode);
#else
	copy_str(perm_buf, sizeof(perm_buf), attr_str_long(curr->attrs));
#endif

	werase(stat_win);
	cur_x = 2;
	checked_wmove(stat_win, 0, cur_x);
	wprint(stat_win, name_buf);
	cur_x += 22;
	if(x > 83)
		cur_x += x - 83;
	mvwaddstr(stat_win, 0, cur_x, size_buf);
	cur_x += 12;
	mvwaddstr(stat_win, 0, cur_x, perm_buf);
	cur_x += 11;

	snprintf(name_buf, sizeof(name_buf), "%d %s filtered", view->filtered,
			(view->filtered == 1) ? "file" : "files");
	if(view->filtered > 0)
		mvwaddstr(stat_win, 0, x - (strlen(name_buf) + 2), name_buf);

	if(cur_x + strlen(id_buf) + 1 > x - (strlen(name_buf) + 2))
		break_at(id_buf, ':');
	if(cur_x + strlen(id_buf) + 1 > x - (strlen(name_buf) + 2))
		id_buf[0] = '\0';
	mvwaddstr(stat_win, 0, cur_x, id_buf);

	refresh_window(stat_win, lazy_redraw);
}
Example #10
0
static int
sort_dir_list(const void *one, const void *two)
{
	int retval;
	char *pfirst, *psecond;
	dir_entry_t *const first = (dir_entry_t *)one;
	dir_entry_t *const second = (dir_entry_t *)two;
	int first_is_dir;
	int second_is_dir;

	if(is_parent_dir(first->name))
	{
		return -1;
	}
	else if(is_parent_dir(second->name))
	{
		return 1;
	}

	first_is_dir = is_directory_entry(first);
	second_is_dir = is_directory_entry(second);

	retval = 0;
	switch(sort_type)
	{
		case SK_BY_NAME:
		case SK_BY_INAME:
			if(custom_view)
			{
				retval = compare_entry_names(first, second, sort_type == SK_BY_INAME);
			}
			else
			{
				retval = compare_full_file_names(first->name, second->name,
						sort_type == SK_BY_INAME);
			}
			break;

		case SK_BY_DIR:
			if(first_is_dir != second_is_dir)
			{
				retval = first_is_dir ? -1 : 1;
			}
			break;

		case SK_BY_TYPE:
			retval = strcmp(get_type_str(first->type), get_type_str(second->type));
			break;

		case SK_BY_FILEEXT:
		case SK_BY_EXTENSION:
			pfirst = strrchr(first->name,  '.');
			psecond = strrchr(second->name, '.');

			if(first_is_dir && second_is_dir && sort_type == SK_BY_FILEEXT)
			{
				retval = compare_file_names(first->name, second->name, 0);
			}
			else if(first_is_dir != second_is_dir && sort_type == SK_BY_FILEEXT)
			{
				retval = first_is_dir ? -1 : 1;
			}
			else if(pfirst && psecond)
			{
				if(pfirst == first->name && psecond != second->name)
				{
					retval = -1;
				}
				else if(pfirst != first->name && psecond == second->name)
				{
					retval = 1;
				}
				else
				{
					retval = compare_file_names(++pfirst, ++psecond, 0);
				}
			}
			else if(pfirst || psecond)
				retval = pfirst ? -1 : 1;
			else
				retval = compare_file_names(first->name, second->name, 0);
			break;

		case SK_BY_SIZE:
			{
				if(first_is_dir)
				{
					char full_path[PATH_MAX];
					get_full_path_of(first, sizeof(full_path), full_path);
					tree_get_data(curr_stats.dirsize_cache, full_path, &first->size);
				}

				if(second_is_dir)
				{
					char full_path[PATH_MAX];
					get_full_path_of(second, sizeof(full_path), full_path);
					tree_get_data(curr_stats.dirsize_cache, full_path, &second->size);
				}

				retval = (first->size < second->size)
				       ? -1
				       : (first->size > second->size);
			}
			break;

		case SK_BY_TIME_MODIFIED:
			retval = first->mtime - second->mtime;
			break;

		case SK_BY_TIME_ACCESSED:
			retval = first->atime - second->atime;
			break;

		case SK_BY_TIME_CHANGED:
			retval = first->ctime - second->ctime;
			break;
#ifndef _WIN32
		case SK_BY_MODE:
			retval = first->mode - second->mode;
			break;

		case SK_BY_OWNER_NAME: /* FIXME */
		case SK_BY_OWNER_ID:
			retval = first->uid - second->uid;
			break;

		case SK_BY_GROUP_NAME: /* FIXME */
		case SK_BY_GROUP_ID:
			retval = first->gid - second->gid;
			break;

		case SK_BY_PERMISSIONS:
			{
				char first_perm[11], second_perm[11];
				get_perm_string(first_perm, sizeof(first_perm), first->mode);
				get_perm_string(second_perm, sizeof(second_perm), second->mode);
				retval = strcmp(first_perm, second_perm);
			}
			break;
#endif
	}

	if(retval == 0)
	{
		retval = first->list_num - second->list_num;
	}
	else if(sort_descending)
	{
		retval = -retval;
	}

	return retval;
}
Example #11
0
int
flist_find_group(const FileView *view, int next)
{
	/* TODO: refactor/simplify this function (flist_find_group()). */

	const int correction = next ? -1 : 0;
	const int lb = correction;
	const int ub = view->list_rows + correction;
	const int inc = next ? +1 : -1;

	int pos = view->list_pos;
	dir_entry_t *pentry = &view->dir_entry[pos];
	const char *ext = get_last_ext(pentry->name);
	size_t char_width = utf8_chrw(pentry->name);
	wchar_t ch = towupper(get_first_wchar(pentry->name));
	const SortingKey sorting_key =
		flist_custom_active(view) && cv_compare(view->custom.type)
		? SK_BY_ID
		: abs(view->sort[0]);
	const int is_dir = fentry_is_dir(pentry);
	const char *const type_str = get_type_str(pentry->type);
	regmatch_t pmatch = { .rm_so = 0, .rm_eo = 0 };
#ifndef _WIN32
	char perms[16];
	get_perm_string(perms, sizeof(perms), pentry->mode);
#endif
	if(sorting_key == SK_BY_GROUPS)
	{
		pmatch = get_group_match(&view->primary_group, pentry->name);
	}
	while(pos > lb && pos < ub)
	{
		dir_entry_t *nentry;
		pos += inc;
		nentry = &view->dir_entry[pos];
		switch(sorting_key)
		{
			case SK_BY_FILEEXT:
				if(fentry_is_dir(nentry))
				{
					if(strncmp(pentry->name, nentry->name, char_width) != 0)
					{
						return pos;
					}
				}
				if(strcmp(get_last_ext(nentry->name), ext) != 0)
				{
					return pos;
				}
				break;
			case SK_BY_EXTENSION:
				if(strcmp(get_last_ext(nentry->name), ext) != 0)
					return pos;
				break;
			case SK_BY_GROUPS:
				{
					regmatch_t nmatch = get_group_match(&view->primary_group,
							nentry->name);

					if(pmatch.rm_eo - pmatch.rm_so != nmatch.rm_eo - nmatch.rm_so ||
							(pmatch.rm_eo != pmatch.rm_so &&
							 strncmp(pentry->name + pmatch.rm_so, nentry->name + nmatch.rm_so,
								 pmatch.rm_eo - pmatch.rm_so + 1U) != 0))
						return pos;
				}
				break;
			case SK_BY_TARGET:
				if((nentry->type == FT_LINK) != (pentry->type == FT_LINK))
				{
					/* One of the entries is not a link. */
					return pos;
				}
				if(nentry->type == FT_LINK)
				{
					/* Both entries are symbolic links. */
					char full_path[PATH_MAX];
					char nlink[PATH_MAX], plink[PATH_MAX];

					get_full_path_of(nentry, sizeof(full_path), full_path);
					if(get_link_target(full_path, nlink, sizeof(nlink)) != 0)
					{
						return pos;
					}
					get_full_path_of(pentry, sizeof(full_path), full_path);
					if(get_link_target(full_path, plink, sizeof(plink)) != 0)
					{
						return pos;
					}

					if(stroscmp(nlink, plink) != 0)
					{
						return pos;
					}
				}
				break;
			case SK_BY_NAME:
				if(strncmp(pentry->name, nentry->name, char_width) != 0)
					return pos;
				break;
			case SK_BY_INAME:
				if((wchar_t)towupper(get_first_wchar(nentry->name)) != ch)
					return pos;
				break;
			case SK_BY_SIZE:
				if(nentry->size != pentry->size)
					return pos;
				break;
			case SK_BY_NITEMS:
				if(entry_get_nitems(view, nentry) != entry_get_nitems(view, pentry))
					return pos;
				break;
			case SK_BY_TIME_ACCESSED:
				if(nentry->atime != pentry->atime)
					return pos;
				break;
			case SK_BY_TIME_CHANGED:
				if(nentry->ctime != pentry->ctime)
					return pos;
				break;
			case SK_BY_TIME_MODIFIED:
				if(nentry->mtime != pentry->mtime)
					return pos;
				break;
			case SK_BY_DIR:
				if(is_dir != fentry_is_dir(nentry))
				{
					return pos;
				}
				break;
			case SK_BY_TYPE:
				if(get_type_str(nentry->type) != type_str)
				{
					return pos;
				}
				break;
#ifndef _WIN32
			case SK_BY_GROUP_NAME:
			case SK_BY_GROUP_ID:
				if(nentry->gid != pentry->gid)
					return pos;
				break;
			case SK_BY_OWNER_NAME:
			case SK_BY_OWNER_ID:
				if(nentry->uid != pentry->uid)
					return pos;
				break;
			case SK_BY_MODE:
				if(nentry->mode != pentry->mode)
					return pos;
				break;
			case SK_BY_PERMISSIONS:
				{
					char nperms[16];
					get_perm_string(nperms, sizeof(nperms), nentry->mode);
					if(strcmp(nperms, perms) != 0)
					{
						return pos;
					}
					break;
				}
			case SK_BY_NLINKS:
				if(nentry->nlinks != pentry->nlinks)
				{
					return pos;
				}
				break;
#endif
		}
		/* Id sorting is builtin only and is defined outside SortingKey
		 * enumeration. */
		if((int)sorting_key == SK_BY_ID)
		{
			if(nentry->id != pentry->id)
			{
				return pos;
			}
		}
	}
	return pos;
}

/* Finds pointer to the beginning of the last extension of the file name.
 * Returns the pointer, which might point to the NUL byte if there are no
 * extensions. */
static const char *
get_last_ext(const char name[])
{
	const char *const ext = strrchr(name, '.');
	return (ext == NULL) ? (name + strlen(name)) : (ext + 1);
}

int
flist_find_dir_group(const FileView *view, int next)
{
	const int correction = next ? -1 : 0;
	const int lb = correction;
	const int ub = view->list_rows + correction;
	const int inc = next ? +1 : -1;

	int pos = curr_view->list_pos;
	dir_entry_t *pentry = &curr_view->dir_entry[pos];
	const int is_dir = fentry_is_dir(pentry);
	while(pos > lb && pos < ub)
	{
		dir_entry_t *nentry;
		pos += inc;
		nentry = &curr_view->dir_entry[pos];
		if(is_dir != fentry_is_dir(nentry))
		{
			break;
		}
	}
	return pos;
}

int
flist_first_sibling(const FileView *view)
{
	const int parent = view->list_pos - view->dir_entry[view->list_pos].child_pos;
	return (parent == view->list_pos ? 0 : parent + 1);
}

int
flist_last_sibling(const FileView *view)
{
	int pos = view->list_pos - view->dir_entry[view->list_pos].child_pos;
	if(pos == view->list_pos)
	{
		/* For top-level entry, find the last top-level entry. */
		pos = view->list_rows - 1;
		while(view->dir_entry[pos].child_pos != 0)
		{
			pos -= view->dir_entry[pos].child_pos;
		}
	}
	else
	{
		/* For non-top-level entry, go to last tree item and go up until our
		 * child. */
		const int parent = pos;
		pos = parent + view->dir_entry[parent].child_count;
		while(pos - view->dir_entry[pos].child_pos != parent)
		{
			pos -= view->dir_entry[pos].child_pos;
		}
	}
	return pos;
}
Example #12
0
File: sort.c Project: acklinr/vifm
static int
sort_dir_list(const void *one, const void *two)
{
	/* TODO: refactor this function sort_dir_list(). */

	int retval;
	const dir_entry_t *const first = one;
	const dir_entry_t *const second = two;

	const int first_is_dir = fentry_is_dir(first);
	const int second_is_dir = fentry_is_dir(second);

	if(first_is_dir && is_parent_dir(first->name))
	{
		return -1;
	}
	if(second_is_dir && is_parent_dir(second->name))
	{
		return 1;
	}

	retval = 0;
	switch(sort_type)
	{
		char *pfirst, *psecond;

		case SK_BY_NAME:
		case SK_BY_INAME:
			if(custom_view)
			{
				retval = compare_entry_names(first, second, sort_type == SK_BY_INAME);
			}
			else
			{
				retval = compare_full_file_names(first->name, second->name,
						sort_type == SK_BY_INAME);
			}
			break;

		case SK_BY_DIR:
			if(first_is_dir != second_is_dir)
			{
				retval = first_is_dir ? -1 : 1;
			}
			break;

		case SK_BY_TYPE:
			retval = strcmp(get_type_str(first->type), get_type_str(second->type));
			break;

		case SK_BY_FILEEXT:
		case SK_BY_EXTENSION:
			pfirst = strrchr(first->name,  '.');
			psecond = strrchr(second->name, '.');

			if(first_is_dir && second_is_dir && sort_type == SK_BY_FILEEXT)
			{
				retval = compare_file_names(first->name, second->name, 0);
			}
			else if(first_is_dir != second_is_dir && sort_type == SK_BY_FILEEXT)
			{
				retval = first_is_dir ? -1 : 1;
			}
			else if(pfirst && psecond)
			{
				if(pfirst == first->name && psecond != second->name)
				{
					retval = -1;
				}
				else if(pfirst != first->name && psecond == second->name)
				{
					retval = 1;
				}
				else
				{
					retval = compare_file_names(++pfirst, ++psecond, 0);
				}
			}
			else if(pfirst || psecond)
				retval = pfirst ? -1 : 1;
			else
				retval = compare_file_names(first->name, second->name, 0);
			break;

		case SK_BY_SIZE:
			retval = compare_file_sizes(first, second);
			break;

		case SK_BY_NITEMS:
			retval = compare_item_count(first, first_is_dir, second, second_is_dir);
			break;

		case SK_BY_GROUPS:
			retval = compare_group(first->name, second->name, sort_data);
			break;

		case SK_BY_TARGET:
			retval = compare_targets(first, second);
			break;

		case SK_BY_TIME_MODIFIED:
			retval = first->mtime - second->mtime;
			break;

		case SK_BY_TIME_ACCESSED:
			retval = first->atime - second->atime;
			break;

		case SK_BY_TIME_CHANGED:
			retval = first->ctime - second->ctime;
			break;

#ifndef _WIN32
		case SK_BY_MODE:
			retval = first->mode - second->mode;
			break;

		case SK_BY_INODE:
			retval = first->inode - second->inode;
			break;

		case SK_BY_OWNER_NAME: /* FIXME */
		case SK_BY_OWNER_ID:
			retval = first->uid - second->uid;
			break;

		case SK_BY_GROUP_NAME: /* FIXME */
		case SK_BY_GROUP_ID:
			retval = first->gid - second->gid;
			break;

		case SK_BY_PERMISSIONS:
			{
				char first_perm[11], second_perm[11];
				get_perm_string(first_perm, sizeof(first_perm), first->mode);
				get_perm_string(second_perm, sizeof(second_perm), second->mode);
				retval = strcmp(first_perm, second_perm);
			}
			break;

		case SK_BY_NLINKS:
			retval = first->nlinks - second->nlinks;
			break;
#endif
	}

	if(retval == 0)
	{
		retval = first->tag - second->tag;
	}
	else if(sort_descending)
	{
		retval = -retval;
	}

	return retval;
}