예제 #1
0
void load_config(struct configfile *c, char *filename) {
  char buffer[1024];
  FILE *input;
  char *key_start, *key_end;
  char *val_start, *val_end;

  c->keys = c->values = 0;
  input = fopen(filename, "r");
  if (!input) {
    c->num_entries = 0;
    return;
  }
  
  while (fgets(buffer, 1024, input)) {
    val_start = buffer;
    strsep(&val_start, "#"); //Ignore comments;
    key_start = val_start = buffer;
    val_end = buffer + strlen(buffer);
    if (val_end == key_start) continue; //Blank line
    strsep(&val_start, "=");
    if (!val_start) continue; //No = sign found.
    key_end = val_start - 1;
    trim(&key_start, &key_end);
    trim(&val_start, &val_end);
    if (key_end < key_start) continue; //No key found.
    if (val_end < val_start) continue; //No value found.

    add_to_string_array(&(c->keys), key_start, key_end-key_start+1, c->num_entries);
    add_to_string_array(&(c->values), val_start, val_end-val_start+1, c->num_entries);
    c->num_entries++;
  }
  fclose(input);
}
예제 #2
0
파일: menus.c 프로젝트: cfillion/vifm
SETUP()
{
	init_menu_info(&m, strdup("test"), strdup("No matches"));
	m.search_repeat = 1;

	m.len = add_to_string_array(&m.items, m.len, 1, "a");
	m.len = add_to_string_array(&m.items, m.len, 1, "b");
	m.len = add_to_string_array(&m.items, m.len, 1, "c");
}
예제 #3
0
char *config_to_string(struct configfile *c, char *key, char *def_val) {
  char *val = _config_to_string(c, key);
  if (!val) {
    add_to_string_array(&(c->keys), key, strlen(key), c->num_entries);
    add_to_string_array(&(c->values), def_val, strlen(def_val), c->num_entries);
    c->num_entries++;
    return strdup(def_val);
  }
  return strdup(val);
}
예제 #4
0
double config_to_real(struct configfile *c, char *key, double def_val) {
  char buffer[100];
  char *val = _config_to_string(c, key);
  if (!val) {
    sprintf(buffer, "%.10e", def_val);
    add_to_string_array(&(c->keys), key, strlen(key), c->num_entries);
    add_to_string_array(&(c->values), buffer, strlen(buffer), c->num_entries);
    c->num_entries++;
    return def_val;
  }
  return atof(val);
}
예제 #5
0
int
show_volumes_menu(FileView *view)
{
	TCHAR c;
	TCHAR vol_name[MAX_PATH];
	TCHAR file_buf[MAX_PATH];

	static menu_info m;
	init_menu_info(&m, VOLUMES, strdup("No volumes mounted"));
	m.title = strdup(" Mounted Volumes ");

	for(c = TEXT('a'); c < TEXT('z'); c++)
	{
		if(drive_exists(c))
		{
			TCHAR drive[] = TEXT("?:\\");
			drive[0] = c;
			if(GetVolumeInformation(drive, vol_name, MAX_PATH, NULL, NULL, NULL,
					file_buf, MAX_PATH))
			{
				char item_buf[MAX_PATH + 5];
				snprintf(item_buf, sizeof(item_buf), "%s  %s ", drive, vol_name);
				m.len = add_to_string_array(&m.items, m.len, 1, item_buf);
			}
		}
	}

	return display_menu(&m, view);
}
예제 #6
0
파일: dictionary.c 프로젝트: Toeger/f-irc
BOOL load_dictionary(void)
{
	char buffer[4096] = { 0 };
	FILE *fh = fopen(dictionary_file, "r");
	if (!fh)
		return FALSE;

	free_string_array(&dictionary);

	while(!feof(fh))
	{
		if (fgets(buffer, sizeof buffer, fh) == NULL)
			break;

		if (strlen(buffer) == 0)
			continue;

		terminate_str(buffer, '\r');
		terminate_str(buffer, '\n');

		add_to_string_array(&dictionary, buffer);
	}

	fclose(fh);

	sort_string_array(&dictionary);

	return TRUE;
}
예제 #7
0
파일: sort.c 프로젝트: acklinr/vifm
/* Sorts specified range of entries according to sorting groups option. */
static void
sort_by_groups(dir_entry_t *entries, size_t nentries)
{
	char **groups = NULL;
	int ngroups = 0;
	const int optimize = (view_sort_groups != view->sort_groups_g);
	int i;

	char *const copy = strdup(view_sort_groups);
	char *group = copy, *state = NULL;
	while((group = split_and_get(group, ',', &state)) != NULL)
	{
		ngroups = add_to_string_array(&groups, ngroups, 1, group);
	}
	free(copy);

	for(i = ngroups - (optimize ? 1 : 0); i >= 1; --i)
	{
		regex_t regex;
		(void)regcomp(&regex, groups[i], REG_EXTENDED | REG_ICASE);
		sort_by_key(entries, nentries, SK_BY_GROUPS, &regex);
		regfree(&regex);
	}
	if(optimize && ngroups != 0)
	{
		sort_by_key(entries, nentries, SK_BY_GROUPS, &view->primary_group);
	}

	free_string_array(groups, ngroups);
}
예제 #8
0
파일: undolist_menu.c 프로젝트: jubalh/vifm
int
show_undolist_menu(FileView *view, int with_details)
{
	char **p;
	size_t len;

	static menu_info m;
	init_menu_info(&m, UNDOLIST_MENU, strdup("Undolist is empty"));
	m.current = get_undolist_pos(with_details) + 1;
	m.pos = m.current - 1;
	m.title = strdup(" Undolist ");

	m.items = undolist(with_details);
	p = m.items;
	while(*p++ != NULL)
		m.len++;

	if(m.len > 0)
	{
		m.len = add_to_string_array(&m.items, m.len, 1, "list end");

		/* Add current position mark to menu item. */
		len = (m.items[m.pos] != NULL) ? strlen(m.items[m.pos]) : 0;
		m.items[m.pos] = realloc(m.items[m.pos], len + 1 + 1);
		memmove(m.items[m.pos] + 1, m.items[m.pos], len + 1);
		m.items[m.pos][0] = '*';
	}

	return display_menu(&m, view);
}
예제 #9
0
파일: registers.c 프로젝트: lowtalker/vifm
int
regs_append(int reg_name, const char file[])
{
    reg_t *reg;

    if(reg_name == BLACKHOLE_REG_NAME)
    {
        return 0;
    }
    if((reg = regs_find(reg_name)) == NULL)
    {
        return 1;
    }
    if(!path_exists(file, NODEREF))
    {
        return 1;
    }
    if(check_for_duplicate_file_names(reg, file))
    {
        return 1;
    }

    reg->nfiles = add_to_string_array(&reg->files, reg->nfiles, 1, file);
    return 0;
}
예제 #10
0
/* Fills the menu with commands from association records. */
static void
fill_menu_from_records(menu_info *m, const assoc_records_t *records)
{
	int i;
	const int max_len = max_desc_len(records);

	for(i = 0; i < records->count; ++i)
	{
		m->len = add_to_string_array(&m->items, m->len, 1,
				form_filetype_menu_entry(records->list[i], max_len));
	}
}
예제 #11
0
파일: jobs_menu.c 프로젝트: cfillion/vifm
int
show_jobs_menu(FileView *view)
{
	job_t *p;
	int i;

	static menu_info m;
	init_menu_info(&m, strdup("Pid --- Command"),
			strdup("No jobs currently running"));
	m.execute_handler = &execute_jobs_cb;

	check_background_jobs();

	bg_jobs_freeze();

	p = jobs;

	i = 0;
	while(p != NULL)
	{
		if(p->running)
		{
			char info_buf[24];
			char item_buf[sizeof(info_buf) + strlen(p->cmd)];

			if(p->type == BJT_COMMAND)
			{
				snprintf(info_buf, sizeof(info_buf), "%" PRINTF_ULL,
						(unsigned long long)p->pid);
			}
			else if(p->bg_op.total == BG_UNDEFINED_TOTAL)
			{
				snprintf(info_buf, sizeof(info_buf), "n/a");
			}
			else
			{
				snprintf(info_buf, sizeof(info_buf), "%d/%d", p->bg_op.done + 1,
						p->bg_op.total);
			}

			snprintf(item_buf, sizeof(item_buf), "%-8s  %s", info_buf, p->cmd);
			i = add_to_string_array(&m.items, i, 1, item_buf);
		}

		p = p->next;
	}

	bg_jobs_unfreeze();

	m.len = i;

	return display_menu(&m, view);
}
예제 #12
0
파일: jobs_menu.c 프로젝트: ackeack/workenv
int
show_jobs_menu(FileView *view)
{
	job_t *p;
#ifndef _WIN32
	sigset_t new_mask;
#endif
	int i;
	static menu_info m;
	init_menu_info(&m, JOBS, strdup("No jobs currently running"));
	m.title = strdup(" Pid --- Command ");

	/*
	 * SIGCHLD needs to be blocked anytime the finished_jobs list
	 * is accessed from anywhere except the received_sigchld().
	 */
#ifndef _WIN32
	sigemptyset(&new_mask);
	sigaddset(&new_mask, SIGCHLD);
	sigprocmask(SIG_BLOCK, &new_mask, NULL);
#else
	check_background_jobs();
#endif

	p = jobs;

	i = 0;
	while(p != NULL)
	{
		if(p->running)
		{
			char item_buf[strlen(p->cmd) + 24];
			if(p->pid == -1)
				snprintf(item_buf, sizeof(item_buf), " %d/%d %s ", p->done + 1,
						p->total, p->cmd);
			else
				snprintf(item_buf, sizeof(item_buf), " " PRINTF_PID_T " %s ", p->pid,
						p->cmd);
			i = add_to_string_array(&m.items, i, 1, item_buf);
		}

		p = p->next;
	}

#ifndef _WIN32
	/* Unblock SIGCHLD signal. */
	sigprocmask(SIG_UNBLOCK, &new_mask, NULL);
#endif

	m.len = i;

	return display_menu(&m, view);
}
예제 #13
0
int
set_trash_dir(const char new_specs[])
{
	char **dirs = NULL;
	int ndirs = 0;

	int error;
	char *free_this;
	char *spec;

	error = 0;
	free_this = strdup(new_specs);
	spec = free_this;

	for(;;)
	{
		char *const p = until_first(spec, ',');
		const int last_element = *p == '\0';
		*p = '\0';

		if(!validate_spec(spec))
		{
			error = 1;
			break;
		}

		ndirs = add_to_string_array(&dirs, ndirs, 1, spec);

		if(last_element)
		{
			break;
		}
		spec = p + 1;
	}

	free(free_this);

	if(!error)
	{
		free_string_array(specs, nspecs);
		specs = dirs;
		nspecs = ndirs;

		copy_str(cfg.trash_dir, sizeof(cfg.trash_dir), new_specs);
	}
	else
	{
		free_string_array(dirs, ndirs);
	}

	return error;
}
예제 #14
0
int service_list_strategy_report_iterative(const struct buildmatrix_context *ctx, 
                                            void * const strategy_context, const void *ptr)
{
 struct service_list_strategy_report_context *sc;
 sc = (struct service_list_strategy_report_context *) strategy_context;

 if(add_to_string_array(&(sc->array), sc->array_size, ptr, strlen(ptr), 0))
  return 1;

 sc->array_size++;

 return 0;
}
예제 #15
0
파일: ipc.c 프로젝트: jubalh/vifm
static void
parse_data(const char *buf)
{
	char **array = NULL;
	size_t len = 0;
	while(*buf != '\0')
	{
		len = add_to_string_array(&array, len, 1, buf);
		buf += strlen(buf) + 1;
	}
	len = put_into_string_array(&array, len, NULL);
	callback(array);
	free_string_array(array, len);
}
예제 #16
0
/* fsdata_traverse() callback that collects names of existing files into a
 * list. */
static void
append_valid_nodes(const char name[], int valid, const void *parent_data,
		void *data, void *arg)
{
	strlist_t *const list = arg;
	dir_entry_t *const entry = *(dir_entry_t **)data;

	if(valid)
	{
		char full_path[PATH_MAX];
		get_full_path_of(entry, sizeof(full_path), full_path);
		list->nitems = add_to_string_array(&list->items, list->nitems, 1,
				full_path);
	}
}
예제 #17
0
/* Returns non-zero if status bar message should be saved. */
static int
show_history(FileView *view, int type, hist_t *hist, const char title[])
{
	int i;
	static menu_info m;

	init_menu_info(&m, type, strdup("History disabled or empty"));
	m.title = strdup(title);

	for(i = 0; i <= hist->pos; i++)
	{
		m.len = add_to_string_array(&m.items, m.len, 1, hist->items[i]);
	}

	return display_menu(&m, view);
}
예제 #18
0
파일: info.c 프로젝트: cfillion/vifm
/* Handles single directory history entry, possibly skipping merging it in. */
static void
process_hist_entry(FileView *view, const char dir[], const char file[], int pos,
		char ***lh, int *nlh, int **lhp, size_t *nlhp)
{
	if(view->history_pos + *nlh/2 == cfg.history_len - 1 ||
			is_in_view_history(view, dir) || !is_dir(dir))
	{
		return;
	}

	*nlh = add_to_string_array(lh, *nlh, 2, dir, file);
	if(*nlh/2U > *nlhp)
	{
		*nlhp = add_to_int_array(lhp, *nlhp, pos);
		*nlhp = MIN(*nlh/2U, *nlhp);
	}
}
예제 #19
0
int
show_history_menu(FileView *view)
{
	int i;
	static menu_info m;

	init_menu_info(&m, DIRHISTORY, strdup("History disabled or empty"));

	m.title = strdup(" Directory History ");

	for(i = 0; i < view->history_num && i < cfg.history_len; i++)
	{
		int j;
		if(view->history[i].dir[0] == '\0')
			break;
		for(j = i + 1; j < view->history_num && j < cfg.history_len; j++)
			if(stroscmp(view->history[i].dir, view->history[j].dir) == 0)
				break;
		if(j < view->history_num && j < cfg.history_len)
			continue;
		if(!is_valid_dir(view->history[i].dir))
			continue;

		/* Change the current dir to reflect the current file. */
		if(stroscmp(view->history[i].dir, view->curr_dir) == 0)
		{
			(void)replace_string(&view->history[i].file,
					view->dir_entry[view->list_pos].name);
			m.pos = m.len;
		}

		m.len = add_to_string_array(&m.items, m.len, 1, view->history[i].dir);
	}

	/* Reverse order in which items appear. */
	for(i = 0; i < m.len/2; i++)
	{
		char *t = m.items[i];
		m.items[i] = m.items[m.len - 1 - i];
		m.items[m.len - 1 - i] = t;
	}
	m.pos = m.len - 1 - m.pos;

	return display_menu(&m, view);
}
예제 #20
0
/* Returns non-zero if status bar message should be saved. */
static int
show_history(FileView *view, HistoryType type, hist_t *hist, const char title[])
{
	int i;
	static menu_info m;

	init_menu_info(&m, strdup(title), strdup("History disabled or empty"));
	m.execute_handler = &execute_history_cb;
	m.key_handler = &history_khandler;
	m.extra_data = type;

	for(i = 0; i <= hist->pos; ++i)
	{
		m.len = add_to_string_array(&m.items, m.len, 1, hist->items[i]);
	}

	return display_menu(&m, view);
}
예제 #21
0
/* Callback for listings of bookmarks. */
static void
bmarks_cb(const char path[], const char tags[], time_t timestamp, void *arg)
{
	menu_info *m = arg;
	char *line = format_str("%s: ", replace_home_part_strict(path));
	size_t len = strlen(line);

	char *dup = strdup(tags);
	char *tag = dup, *state = NULL;
	while((tag = split_and_get(tag, ',', &state)) != NULL)
	{
		strappendch(&line, &len, '[');
		strappend(&line, &len, tag);
		strappendch(&line, &len, ']');
	}
	free(dup);

	(void)add_to_string_array(&m->data, m->len, 1, path);
	m->len = put_into_string_array(&m->items, m->len, line);
}
예제 #22
0
int
show_file_menu(FileView *view, int background)
{
	static menu_info m;

	int i;
	int max_len;

	char *const typed_name = get_typed_current_fpath(view);
	assoc_records_t ft = ft_get_all_programs(typed_name);
	assoc_records_t magic = get_magic_handlers(typed_name);
	free(typed_name);

	init_menu_info(&m, strdup("Filetype associated commands"),
			strdup("No programs set for this filetype"));

	m.execute_handler = &execute_filetype_cb;
	m.key_handler = &filetypes_khandler;
	m.extra_data = (background ? 1 : 0);

	max_len = MAX(max_desc_len(&ft), max_desc_len(&magic));

	for(i = 0; i < ft.count; i++)
	{
		(void)add_to_string_array(&m.data, m.len, 1,
				form_filetype_data_entry(ft.list[i]));
		m.len = add_to_string_array(&m.items, m.len, 1,
				form_filetype_menu_entry(ft.list[i], max_len));
	}

	ft_assoc_records_free(&ft);

#ifdef ENABLE_DESKTOP_FILES
	(void)add_to_string_array(&m.data, m.len, 1,
			form_filetype_data_entry(NONE_PSEUDO_PROG));
	m.len = add_to_string_array(&m.items, m.len, 1, "");
#endif

	for(i = 0; i < magic.count; i++)
	{
		(void)add_to_string_array(&m.data, m.len, 1,
				form_filetype_data_entry(magic.list[i]));
		m.len = add_to_string_array(&m.items, m.len, 1,
				form_filetype_menu_entry(magic.list[i], max_len));
	}

	return display_menu(&m, view);
}
예제 #23
0
파일: map_menu.c 프로젝트: cfillion/vifm
int
show_map_menu(FileView *view, const char mode_str[], wchar_t *list[],
		const wchar_t start[])
{
	int x;
	const size_t start_len = wcslen(start);

	static menu_info m;
	init_menu_info(&m, format_str("Mappings for %s mode", mode_str),
			strdup("No mappings found"));

	x = 0;
	while(list[x] != NULL)
	{
		if(list[x][0] != '\0')
		{
			if(wcsncmp(start, list[x], start_len) == 0)
			{
				add_mapping_item(&m, list[x]);
				++m.len;
			}
		}
		else if(m.len != 0)
		{
			m.len = add_to_string_array(&m.items, m.len, 1, "");
		}

		free(list[x]);
		++x;
	}
	free(list);

	if(m.len > 0 && m.items[m.len - 1][0] == '\0')
	{
		free(m.items[m.len - 1]);
		--m.len;
	}

	return display_menu(&m, view);
}
예제 #24
0
int
show_trash_menu(FileView *view)
{
	int i;

	static menu_data_t m;
	init_menu_data(&m, view, strdup("Original paths of files in trash"),
			strdup("No files in trash"));
	m.key_handler = &trash_khandler;

	trash_prune_dead_entries();

	for(i = 0; i < nentries; ++i)
	{
		const trash_entry_t *const entry = &trash_list[i];
		if(is_under_trash(entry->trash_name))
		{
			m.len = add_to_string_array(&m.items, m.len, 1, entry->path);
		}
	}

	return display_menu(m.state, view);
}
예제 #25
0
파일: info.c 프로젝트: cfillion/vifm
/* Reads contents of the filename file as an info file and updates it with the
 * state of current instance. */
static void
update_info_file(const char filename[])
{
	/* TODO: refactor this function update_info_file() */

	FILE *fp;
	char **cmds_list;
	int ncmds_list = -1;
	char **ft = NULL, **fx = NULL, **fv = NULL, **cmds = NULL, **marks = NULL;
	char **lh = NULL, **rh = NULL, **cmdh = NULL, **srch = NULL, **regs = NULL;
	int *lhp = NULL, *rhp = NULL, *bt = NULL, *bmt = NULL;
	char **prompt = NULL, **filter = NULL, **trash = NULL;
	char **bmarks = NULL;
	int nft = 0, nfx = 0, nfv = 0, ncmds = 0, nmarks = 0, nlh = 0, nrh = 0;
	int ncmdh = 0, nsrch = 0, nregs = 0, nprompt = 0, nfilter = 0, ntrash = 0;
	int nbmarks = 0;
	char **dir_stack = NULL;
	int ndir_stack = 0;
	char *non_conflicting_marks;

	if(cfg.vifm_info == 0)
		return;

	cmds_list = list_udf();
	while(cmds_list[++ncmds_list] != NULL);

	non_conflicting_marks = strdup(valid_marks);

	if((fp = os_fopen(filename, "r")) != NULL)
	{
		size_t nlhp = 0UL, nrhp = 0UL, nbt = 0UL, nbmt = 0UL;
		char *line = NULL, *line2 = NULL, *line3 = NULL, *line4 = NULL;
		while((line = read_vifminfo_line(fp, line)) != NULL)
		{
			const char type = line[0];
			const char *const line_val = line + 1;

			if(type == LINE_TYPE_COMMENT || type == '\0')
				continue;

			if(type == LINE_TYPE_FILETYPE)
			{
				if((line2 = read_vifminfo_line(fp, line2)) != NULL)
				{
					if(!ft_assoc_exists(&filetypes, line_val, line2))
					{
						nft = add_to_string_array(&ft, nft, 2, line_val, line2);
					}
				}
			}
			else if(type == LINE_TYPE_XFILETYPE)
			{
				if((line2 = read_vifminfo_line(fp, line2)) != NULL)
				{
					if(!ft_assoc_exists(&xfiletypes, line_val, line2))
					{
						nfx = add_to_string_array(&fx, nfx, 2, line_val, line2);
					}
				}
			}
			else if(type == LINE_TYPE_FILEVIEWER)
			{
				if((line2 = read_vifminfo_line(fp, line2)) != NULL)
				{
					if(!ft_assoc_exists(&fileviewers, line_val, line2))
					{
						nfv = add_to_string_array(&fv, nfv, 2, line_val, line2);
					}
				}
			}
			else if(type == LINE_TYPE_COMMAND)
			{
				if(line_val[0] == '\0')
					continue;
				if((line2 = read_vifminfo_line(fp, line2)) != NULL)
				{
					int i;
					const char *p = line_val;
					for(i = 0; i < ncmds_list; i += 2)
					{
						int cmp = strcmp(cmds_list[i], p);
						if(cmp < 0)
							continue;
						if(cmp == 0)
							p = NULL;
						break;
					}
					if(p == NULL)
						continue;
					ncmds = add_to_string_array(&cmds, ncmds, 2, line_val, line2);
				}
			}
			else if(type == LINE_TYPE_LWIN_HIST || type == LINE_TYPE_RWIN_HIST)
			{
				if(line_val[0] == '\0')
					continue;
				if((line2 = read_vifminfo_line(fp, line2)) != NULL)
				{
					const int pos = read_optional_number(fp);

					if(type == LINE_TYPE_LWIN_HIST)
					{
						process_hist_entry(&lwin, line_val, line2, pos, &lh, &nlh, &lhp,
								&nlhp);
					}
					else
					{
						process_hist_entry(&rwin, line_val, line2, pos, &rh, &nrh, &rhp,
								&nrhp);
					}
				}
			}
			else if(type == LINE_TYPE_MARK)
			{
				const char mark = line_val[0];
				if(line_val[1] != '\0')
				{
					LOG_ERROR_MSG("Expected end of line, but got: %s", line_val + 1);
				}
				if((line2 = read_vifminfo_line(fp, line2)) != NULL)
				{
					if((line3 = read_vifminfo_line(fp, line3)) != NULL)
					{
						const int timestamp = read_optional_number(fp);
						const char mark_str[] = { mark, '\0' };

						if(!char_is_one_of(valid_marks, mark))
						{
							continue;
						}

						if(is_mark_older(mark, timestamp))
						{
							char *const pos = strchr(non_conflicting_marks, mark);
							if(pos != NULL)
							{
								nmarks = add_to_string_array(&marks, nmarks, 3, mark_str, line2,
										line3);
								nbt = add_to_int_array(&bt, nbt, timestamp);

								*pos = '\xff';
							}
						}
					}
				}
			}
			else if(type == LINE_TYPE_BOOKMARK)
			{
				if((line2 = read_vifminfo_line(fp, line2)) != NULL)
				{
					if((line3 = read_vifminfo_line(fp, line3)) != NULL)
					{
						long timestamp;
						if(read_number(line3, &timestamp) &&
								bmark_is_older(line_val, timestamp))
						{
							nbmarks = add_to_string_array(&bmarks, nbmarks, 2, line_val,
									line2);
							nbmt = add_to_int_array(&bmt, nbmt, timestamp);
						}
					}
				}
			}
			else if(type == LINE_TYPE_TRASH)
			{
				if((line2 = read_vifminfo_line(fp, line2)) != NULL)
				{
					char *const trash_name = convert_old_trash_path(line_val);
					if(exists_in_trash(trash_name) && !is_in_trash(trash_name))
					{
						ntrash = add_to_string_array(&trash, ntrash, 2, trash_name, line2);
					}
					free(trash_name);
				}
			}
			else if(type == LINE_TYPE_CMDLINE_HIST)
			{
				if(!hist_contains(&cfg.cmd_hist, line_val))
				{
					ncmdh = add_to_string_array(&cmdh, ncmdh, 1, line_val);
				}
			}
			else if(type == LINE_TYPE_SEARCH_HIST)
			{
				if(!hist_contains(&cfg.search_hist, line_val))
				{
					nsrch = add_to_string_array(&srch, nsrch, 1, line_val);
				}
			}
			else if(type == LINE_TYPE_PROMPT_HIST)
			{
				if(!hist_contains(&cfg.prompt_hist, line_val))
				{
					nprompt = add_to_string_array(&prompt, nprompt, 1, line_val);
				}
			}
			else if(type == LINE_TYPE_FILTER_HIST)
			{
				if(!hist_contains(&cfg.filter_hist, line_val))
				{
					nfilter = add_to_string_array(&filter, nfilter, 1, line_val);
				}
			}
			else if(type == LINE_TYPE_DIR_STACK)
			{
				if((line2 = read_vifminfo_line(fp, line2)) != NULL)
				{
					if((line3 = read_vifminfo_line(fp, line3)) != NULL)
					{
						if((line4 = read_vifminfo_line(fp, line4)) != NULL)
						{
							ndir_stack = add_to_string_array(&dir_stack, ndir_stack, 4,
									line_val, line2, line3 + 1, line4);
						}
					}
				}
			}
			else if(type == LINE_TYPE_REG)
			{
				if(regs_exists(line_val[0]))
				{
					continue;
				}
				nregs = add_to_string_array(&regs, nregs, 1, line);
			}
		}
		free(line);
		free(line2);
		free(line3);
		free(line4);
		fclose(fp);
	}

	if((fp = os_fopen(filename, "w")) != NULL)
	{
		fprintf(fp, "# You can edit this file by hand, but it's recommended not to "
				"do that.\n");

		if(cfg.vifm_info & VIFMINFO_OPTIONS)
		{
			write_options(fp);
		}

		if(cfg.vifm_info & VIFMINFO_FILETYPES)
		{
			write_assocs(fp, "Filetypes", LINE_TYPE_FILETYPE, &filetypes, nft, ft);
			write_assocs(fp, "X Filetypes", LINE_TYPE_XFILETYPE, &xfiletypes, nfx,
					fx);
			write_assocs(fp, "Fileviewers", LINE_TYPE_FILEVIEWER, &fileviewers, nfv,
					fv);
		}

		if(cfg.vifm_info & VIFMINFO_COMMANDS)
		{
			write_commands(fp, cmds_list, cmds, ncmds);
		}

		if(cfg.vifm_info & VIFMINFO_MARKS)
		{
			write_marks(fp, non_conflicting_marks, marks, bt, nmarks);
		}

		if(cfg.vifm_info & VIFMINFO_BOOKMARKS)
		{
			write_bmarks(fp, bmarks, bmt, nbmarks);
		}

		if(cfg.vifm_info & VIFMINFO_TUI)
		{
			write_tui_state(fp);
		}

		if((cfg.vifm_info & VIFMINFO_DHISTORY) && cfg.history_len > 0)
		{
			write_view_history(fp, &lwin, "Left", LINE_TYPE_LWIN_HIST, nlh, lh, lhp);
			write_view_history(fp, &rwin, "Right", LINE_TYPE_RWIN_HIST, nrh, rh, rhp);
		}

		if(cfg.vifm_info & VIFMINFO_CHISTORY)
		{
			write_history(fp, "Command line", LINE_TYPE_CMDLINE_HIST,
					MIN(ncmdh, cfg.history_len - cfg.cmd_hist.pos), cmdh, &cfg.cmd_hist);
		}

		if(cfg.vifm_info & VIFMINFO_SHISTORY)
		{
			write_history(fp, "Search", LINE_TYPE_SEARCH_HIST, nsrch, srch,
					&cfg.search_hist);
		}

		if(cfg.vifm_info & VIFMINFO_PHISTORY)
		{
			write_history(fp, "Prompt", LINE_TYPE_PROMPT_HIST, nprompt, prompt,
					&cfg.prompt_hist);
		}

		if(cfg.vifm_info & VIFMINFO_FHISTORY)
		{
			write_history(fp, "Local filter", LINE_TYPE_FILTER_HIST, nfilter, filter,
					&cfg.filter_hist);
		}

		if(cfg.vifm_info & VIFMINFO_REGISTERS)
		{
			write_registers(fp, regs, nregs);
		}

		if(cfg.vifm_info & VIFMINFO_DIRSTACK)
		{
			write_dir_stack(fp, dir_stack, ndir_stack);
		}

		write_trash(fp, trash, ntrash);

		if(cfg.vifm_info & VIFMINFO_STATE)
		{
			write_general_state(fp);
		}

		if(cfg.vifm_info & VIFMINFO_CS)
		{
			fputs("\n# Color scheme:\n", fp);
			fprintf(fp, "c%s\n", cfg.cs.name);
		}

		fclose(fp);
	}

	free_string_array(ft, nft);
	free_string_array(fv, nfv);
	free_string_array(fx, nfx);
	free_string_array(cmds, ncmds);
	free_string_array(marks, nmarks);
	free_string_array(cmds_list, ncmds_list);
	free_string_array(lh, nlh);
	free_string_array(rh, nrh);
	free(lhp);
	free(rhp);
	free(bt);
	free(bmt);
	free_string_array(cmdh, ncmdh);
	free_string_array(srch, nsrch);
	free_string_array(regs, nregs);
	free_string_array(prompt, nprompt);
	free_string_array(filter, nfilter);
	free_string_array(trash, ntrash);
	free_string_array(bmarks, nbmarks);
	free_string_array(dir_stack, ndir_stack);
	free(non_conflicting_marks);
}
예제 #26
0
파일: info.c 프로젝트: francogonzaga/vifm
/* Reads contents of the filename file as an info file and updates it with the
 * state of current instance. */
static void
update_info_file(const char filename[])
{
	/* TODO: refactor this function update_info_file() */

	FILE *fp;
	char ** list;
	int nlist = -1;
	char **ft = NULL, **fx = NULL , **fv = NULL, **cmds = NULL, **marks = NULL;
	char **lh = NULL, **rh = NULL, **cmdh = NULL, **srch = NULL, **regs = NULL;
	int *lhp = NULL, *rhp = NULL;
	size_t nlhp = 0, nrhp = 0;
	char **prompt = NULL, **trash = NULL;
	int nft = 0, nfx = 0, nfv = 0, ncmds = 0, nmarks = 0, nlh = 0, nrh = 0;
	int ncmdh = 0, nsrch = 0, nregs = 0, nprompt = 0, ntrash = 0;
	int i;

	if(cfg.vifm_info == 0)
		return;

	list = list_udf();
	while(list[++nlist] != NULL);

	if((fp = fopen(filename, "r")) != NULL)
	{
		char *line = NULL, *line2 = NULL, *line3 = NULL;
		while((line = read_vifminfo_line(fp, line)) != NULL)
		{
			const char type = line[0];
			const char *const line_val = line + 1;

			if(type == LINE_TYPE_COMMENT || type == '\0')
				continue;

			if(type == LINE_TYPE_FILETYPE)
			{
				if((line2 = read_vifminfo_line(fp, line2)) != NULL)
				{
					assoc_record_t prog;
					if(get_default_program_for_file(line_val, &prog))
					{
						free_assoc_record(&prog);
						continue;
					}
					nft = add_to_string_array(&ft, nft, 2, line_val, line2);
				}
			}
			else if(type == LINE_TYPE_XFILETYPE)
			{
				if((line2 = read_vifminfo_line(fp, line2)) != NULL)
				{
					assoc_record_t x_prog;
					if(get_default_program_for_file(line_val, &x_prog))
					{
						assoc_record_t console_prog;
						if(get_default_program_for_file(line_val, &console_prog))
						{
							if(strcmp(x_prog.command, console_prog.command) == 0)
							{
								free_assoc_record(&console_prog);
								free_assoc_record(&x_prog);
								continue;
							}
						}
						free_assoc_record(&x_prog);
					}
					nfx = add_to_string_array(&fx, nfx, 2, line_val, line2);
				}
			}
			else if(type == LINE_TYPE_FILEVIEWER)
			{
				if((line2 = read_vifminfo_line(fp, line2)) != NULL)
				{
					if(get_viewer_for_file(line_val) != NULL)
						continue;
					nfv = add_to_string_array(&fv, nfv, 2, line_val, line2);
				}
			}
			else if(type == LINE_TYPE_COMMAND)
			{
				if(line_val[0] == '\0')
					continue;
				if((line2 = read_vifminfo_line(fp, line2)) != NULL)
				{
					const char *p = line_val;
					for(i = 0; i < nlist; i += 2)
					{
						int cmp = strcmp(list[i], p);
						if(cmp < 0)
							continue;
						if(cmp == 0)
							p = NULL;
						break;
					}
					if(p == NULL)
						continue;
					ncmds = add_to_string_array(&cmds, ncmds, 2, line_val, line2);
				}
			}
			else if(type == LINE_TYPE_LWIN_HIST)
			{
				if(line_val[0] == '\0')
					continue;
				if((line2 = read_vifminfo_line(fp, line2)) != NULL)
				{
					int pos;

					if(lwin.history_pos + nlh/2 == cfg.history_len - 1)
						continue;
					if(is_in_view_history(&lwin, line_val))
						continue;

					pos = read_possible_possible_pos(fp);
					nlh = add_to_string_array(&lh, nlh, 2, line_val, line2);
					if(nlh/2 > nlhp)
					{
						nlhp = add_to_int_array(&lhp, nlhp, pos);
						nlhp = MIN(nlh/2, nlhp);
					}
				}
			}
			else if(type == LINE_TYPE_RWIN_HIST)
			{
				if(line_val[0] == '\0')
					continue;
				if((line2 = read_vifminfo_line(fp, line2)) != NULL)
				{
					int pos;

					if(rwin.history_pos + nrh/2 == cfg.history_len - 1)
						continue;
					if(is_in_view_history(&rwin, line_val))
						continue;

					pos = read_possible_possible_pos(fp);
					nrh = add_to_string_array(&rh, nrh, 2, line_val, line2);
					if(nrh/2 > nrhp)
					{
						nrhp = add_to_int_array(&rhp, nrhp, pos);
						nrhp = MIN(nrh/2, nrhp);
					}
				}
			}
			else if(type == LINE_TYPE_BOOKMARK)
			{
				const char mark = line_val[0];
				if(line_val[1] != '\0')
				{
					LOG_ERROR_MSG("Expected end of line, but got: %s", line_val + 1);
				}
				if((line2 = read_vifminfo_line(fp, line2)) != NULL)
				{
					if((line3 = read_vifminfo_line(fp, line3)) != NULL)
					{
						const char mark_str[] = { mark, '\0' };
						if(!char_is_one_of(valid_bookmarks, mark))
							continue;
						if(!is_bookmark_empty(mark2index(mark)))
							continue;
						nmarks = add_to_string_array(&marks, nmarks, 3, mark_str, line2,
								line3);
					}
				}
			}
			else if(type == LINE_TYPE_TRASH)
			{
				if((line2 = read_vifminfo_line(fp, line2)) != NULL)
				{
					if(!path_exists_at(cfg.trash_dir, line_val))
						continue;
					if(is_in_trash(line_val))
						continue;
					ntrash = add_to_string_array(&trash, ntrash, 2, line_val, line2);
				}
			}
			else if(type == LINE_TYPE_CMDLINE_HIST)
			{
				if(cfg.cmd_history_num >= 0 && is_in_string_array(cfg.cmd_history,
						cfg.cmd_history_num + 1, line_val))
					continue;
				ncmdh = add_to_string_array(&cmdh, ncmdh, 1, line_val);
			}
			else if(type == LINE_TYPE_SEARCH_HIST)
			{
				if(cfg.search_history_num >= 0 && is_in_string_array(cfg.search_history,
						cfg.search_history_num + 1, line_val))
					continue;
				nsrch = add_to_string_array(&srch, nsrch, 1, line_val);
			}
			else if(type == LINE_TYPE_PROMPT_HIST)
			{
				if(cfg.prompt_history_num >= 0 && is_in_string_array(cfg.prompt_history,
						cfg.prompt_history_num + 1, line_val))
					continue;
				nprompt = add_to_string_array(&prompt, nprompt, 1, line_val);
			}
			else if(type == LINE_TYPE_REG)
			{
				if(register_exists(line_val[0]))
					continue;
				nregs = add_to_string_array(&regs, nregs, 1, line);
			}
		}
		free(line);
		free(line2);
		free(line3);
		fclose(fp);
	}

	if((fp = fopen(filename, "w")) == NULL)
	{
		return;
	}

	fprintf(fp, "# You can edit this file by hand, but it's recommended not to do that.\n");

	if(cfg.vifm_info & VIFMINFO_OPTIONS)
	{
		fputs("\n# Options:\n", fp);
		fprintf(fp, "=aproposprg=%s\n", escape_spaces(cfg.apropos_prg));
		fprintf(fp, "=%sautochpos\n", cfg.auto_ch_pos ? "" : "no");
		fprintf(fp, "=columns=%d\n", cfg.columns);
		fprintf(fp, "=%sconfirm\n", cfg.confirm ? "" : "no");
		fprintf(fp, "=cpoptions=%s%s%s\n",
				cfg.filter_inverted_by_default ? "f" : "",
				cfg.selection_is_primary ? "s" : "",
				cfg.tab_switches_pane ? "t" : "");
		fprintf(fp, "=%sfastrun\n", cfg.fast_run ? "" : "no");
		fprintf(fp, "=findprg=%s\n", escape_spaces(cfg.find_prg));
		fprintf(fp, "=%sfollowlinks\n", cfg.follow_links ? "" : "no");
		fprintf(fp, "=fusehome=%s\n", escape_spaces(cfg.fuse_home));
		fprintf(fp, "=%sgdefault\n", cfg.gdefault ? "" : "no");
		fprintf(fp, "=grepprg=%s\n", escape_spaces(cfg.grep_prg));
		fprintf(fp, "=history=%d\n", cfg.history_len);
		fprintf(fp, "=%shlsearch\n", cfg.hl_search ? "" : "no");
		fprintf(fp, "=%siec\n", cfg.use_iec_prefixes ? "" : "no");
		fprintf(fp, "=%signorecase\n", cfg.ignore_case ? "" : "no");
		fprintf(fp, "=%sincsearch\n", cfg.inc_search ? "" : "no");
		fprintf(fp, "=%slaststatus\n", cfg.last_status ? "" : "no");
		fprintf(fp, "=lines=%d\n", cfg.lines);
		fprintf(fp, "=locateprg=%s\n", escape_spaces(cfg.locate_prg));
		fprintf(fp, "=rulerformat=%s\n", escape_spaces(cfg.ruler_format));
		fprintf(fp, "=%srunexec\n", cfg.auto_execute ? "" : "no");
		fprintf(fp, "=%sscrollbind\n", cfg.scroll_bind ? "" : "no");
		fprintf(fp, "=scrolloff=%d\n", cfg.scroll_off);
		fprintf(fp, "=shell=%s\n", escape_spaces(cfg.shell));
		fprintf(fp, "=shortmess=%s\n", cfg.trunc_normal_sb_msgs ? "T" : "");
#ifndef _WIN32
		fprintf(fp, "=slowfs=%s\n", escape_spaces(cfg.slow_fs_list));
#endif
		fprintf(fp, "=%ssmartcase\n", cfg.smart_case ? "" : "no");
		fprintf(fp, "=%ssortnumbers\n", cfg.sort_numbers ? "" : "no");
		fprintf(fp, "=statusline=%s\n", escape_spaces(cfg.status_line));
		fprintf(fp, "=tabstop=%d\n", cfg.tab_stop);
		fprintf(fp, "=timefmt=%s\n", escape_spaces(cfg.time_format + 1));
		fprintf(fp, "=timeoutlen=%d\n", cfg.timeout_len);
		fprintf(fp, "=%strash\n", cfg.use_trash ? "" : "no");
		fprintf(fp, "=undolevels=%d\n", cfg.undo_levels);
		fprintf(fp, "=vicmd=%s%s\n", escape_spaces(cfg.vi_command),
				cfg.vi_cmd_bg ? " &" : "");
		fprintf(fp, "=vixcmd=%s%s\n", escape_spaces(cfg.vi_x_command),
				cfg.vi_cmd_bg ? " &" : "");
		fprintf(fp, "=%swrapscan\n", cfg.wrap_scan ? "" : "no");
		fprintf(fp, "=[viewcolumns=%s\n", escape_spaces(lwin.view_columns));
		fprintf(fp, "=]viewcolumns=%s\n", escape_spaces(rwin.view_columns));
		fprintf(fp, "=[%slsview\n", lwin.ls_view ? "" : "no");
		fprintf(fp, "=]%slsview\n", rwin.ls_view ? "" : "no");

		fprintf(fp, "%s", "=dotdirs=");
		if(cfg.dot_dirs & DD_ROOT_PARENT)
			fprintf(fp, "%s", "rootparent,");
		if(cfg.dot_dirs & DD_NONROOT_PARENT)
			fprintf(fp, "%s", "nonrootparent,");
		fprintf(fp, "\n");

		fprintf(fp, "=classify=%s\n", escape_spaces(classify_to_str()));

		fprintf(fp, "=vifminfo=options");
		if(cfg.vifm_info & VIFMINFO_FILETYPES)
			fprintf(fp, ",filetypes");
		if(cfg.vifm_info & VIFMINFO_COMMANDS)
			fprintf(fp, ",commands");
		if(cfg.vifm_info & VIFMINFO_BOOKMARKS)
			fprintf(fp, ",bookmarks");
		if(cfg.vifm_info & VIFMINFO_TUI)
			fprintf(fp, ",tui");
		if(cfg.vifm_info & VIFMINFO_DHISTORY)
			fprintf(fp, ",dhistory");
		if(cfg.vifm_info & VIFMINFO_STATE)
			fprintf(fp, ",state");
		if(cfg.vifm_info & VIFMINFO_CS)
			fprintf(fp, ",cs");
		if(cfg.vifm_info & VIFMINFO_SAVEDIRS)
			fprintf(fp, ",savedirs");
		if(cfg.vifm_info & VIFMINFO_CHISTORY)
			fprintf(fp, ",chistory");
		if(cfg.vifm_info & VIFMINFO_SHISTORY)
			fprintf(fp, ",shistory");
		if(cfg.vifm_info & VIFMINFO_PHISTORY)
			fprintf(fp, ",phistory");
		if(cfg.vifm_info & VIFMINFO_DIRSTACK)
			fprintf(fp, ",dirstack");
		if(cfg.vifm_info & VIFMINFO_REGISTERS)
			fprintf(fp, ",registers");
		fprintf(fp, "\n");

		fprintf(fp, "=%svimhelp\n", cfg.use_vim_help ? "" : "no");
		fprintf(fp, "=%swildmenu\n", cfg.wild_menu ? "" : "no");
		fprintf(fp, "=%swrap\n", cfg.wrap_quick_view ? "" : "no");
	}

	if(cfg.vifm_info & VIFMINFO_FILETYPES)
	{
		fputs("\n# Filetypes:\n", fp);
		for(i = 0; i < filetypes.count; i++)
		{
			int j;
			assoc_t ft_assoc = filetypes.list[i];
			for(j = 0; j < ft_assoc.records.count; j++)
			{
				assoc_record_t ft_record = ft_assoc.records.list[j];
				/* The type check is to prevent builtin fake associations to be written
				 * into vifminfo file */
				if(ft_record.command[0] != '\0' && ft_record.type != ART_BUILTIN)
				{
					fprintf(fp, ".%s\n\t{%s}%s\n", ft_assoc.pattern,
							ft_record.description, ft_record.command);
				}
			}
		}
		for(i = 0; i < nft; i += 2)
			fprintf(fp, ".%s\n\t%s\n", ft[i], ft[i + 1]);

		fputs("\n# X Filetypes:\n", fp);
		for(i = 0; i < xfiletypes.count; i++)
		{
			int j;
			assoc_t xft_assoc = xfiletypes.list[i];
			for(j = 0; j < xft_assoc.records.count; j++)
			{
				assoc_record_t xft_record = xft_assoc.records.list[j];
				if(xft_record.command[0] != '\0')
				{
					fprintf(fp, "x%s\n\t{%s}%s\n", xft_assoc.pattern,
							xft_record.description, xft_record.command);
				}
			}
		}
		for(i = 0; i < nfx; i += 2)
			fprintf(fp, ".%s\n\t%s\n", fx[i], fx[i + 1]);

		fputs("\n# Fileviewers:\n", fp);
		for(i = 0; i < fileviewers.count; i++)
		{
			int j;
			assoc_t fv_assoc = fileviewers.list[i];
			for(j = 0; j < fv_assoc.records.count; j++)
			{
				assoc_record_t fv_record = fileviewers.list[i].records.list[j];
				if(fv_record.command[0] != '\0')
				{
					fprintf(fp, ",%s\n\t%s\n", fv_assoc.pattern, fv_record.command);
				}
			}
		}
		for(i = 0; i < nfv; i += 2)
			fprintf(fp, ",%s\n\t%s\n", fv[i], fv[i + 1]);
	}

	if(cfg.vifm_info & VIFMINFO_COMMANDS)
	{
		fputs("\n# Commands:\n", fp);
		for(i = 0; list[i] != NULL; i += 2)
			fprintf(fp, "!%s\n\t%s\n", list[i], list[i + 1]);
		for(i = 0; i < ncmds; i += 2)
			fprintf(fp, "!%s\n\t%s\n", cmds[i], cmds[i + 1]);
	}

	if(cfg.vifm_info & VIFMINFO_BOOKMARKS)
	{
		int len = init_active_bookmarks(valid_bookmarks);

		fputs("\n# Bookmarks:\n", fp);
		for(i = 0; i < len; i++)
		{
			int j = active_bookmarks[i];
			if(is_spec_bookmark(j))
				continue;
			fprintf(fp, "'%c\n\t%s\n\t", index2mark(j), bookmarks[j].directory);
			fprintf(fp, "%s\n", bookmarks[j].file);
		}
		for(i = 0; i < nmarks; i += 3)
			fprintf(fp, "'%c\n\t%s\n\t%s\n", marks[i][0], marks[i + 1], marks[i + 2]);
	}

	if(cfg.vifm_info & VIFMINFO_TUI)
	{
		fputs("\n# TUI:\n", fp);
		fprintf(fp, "a%c\n", (curr_view == &rwin) ? 'r' : 'l');
		fprintf(fp, "q%d\n", curr_stats.view);
		fprintf(fp, "v%d\n", curr_stats.number_of_windows);
		fprintf(fp, "o%c\n", (curr_stats.split == VSPLIT) ? 'v' : 'h');
		fprintf(fp, "m%d\n", curr_stats.splitter_pos);

		put_sort_info(fp, 'l', &lwin);
		put_sort_info(fp, 'r', &rwin);
	}

	if((cfg.vifm_info & VIFMINFO_DHISTORY) && cfg.history_len > 0)
	{
		save_view_history(&lwin, NULL, NULL, -1);
		fputs("\n# Left window history (oldest to newest):\n", fp);
		for(i = 0; i < nlh; i += 2)
			fprintf(fp, "d%s\n\t%s\n%d\n", lh[i], lh[i + 1], lhp[i/2]);
		for(i = 0; i <= lwin.history_pos; i++)
			fprintf(fp, "d%s\n\t%s\n%d\n", lwin.history[i].dir, lwin.history[i].file,
					lwin.history[i].rel_pos);
		if(cfg.vifm_info & VIFMINFO_SAVEDIRS)
			fprintf(fp, "d\n");

		save_view_history(&rwin, NULL, NULL, -1);
		fputs("\n# Right window history (oldest to newest):\n", fp);
		for(i = 0; i < nrh; i += 2)
			fprintf(fp, "D%s\n\t%s\n%d\n", rh[i], rh[i + 1], rhp[i/2]);
		for(i = 0; i <= rwin.history_pos; i++)
			fprintf(fp, "D%s\n\t%s\n%d\n", rwin.history[i].dir, rwin.history[i].file,
					rwin.history[i].rel_pos);
		if(cfg.vifm_info & VIFMINFO_SAVEDIRS)
			fprintf(fp, "D\n");
	}

	if(cfg.vifm_info & VIFMINFO_CHISTORY)
	{
		fputs("\n# Command line history (oldest to newest):\n", fp);
		for(i = 0; i < MIN(ncmdh, cfg.history_len - cfg.cmd_history_num); i++)
			fprintf(fp, ":%s\n", cmdh[i]);
		for(i = cfg.cmd_history_num; i >= 0; i--)
			fprintf(fp, ":%s\n", cfg.cmd_history[i]);
	}

	if(cfg.vifm_info & VIFMINFO_SHISTORY)
	{
		fputs("\n# Search history (oldest to newest):\n", fp);
		for(i = 0; i < nsrch; i++)
			fprintf(fp, "/%s\n", srch[i]);
		for(i = cfg.search_history_num; i >= 0; i--)
			fprintf(fp, "/%s\n", cfg.search_history[i]);
	}

	if(cfg.vifm_info & VIFMINFO_PHISTORY)
	{
		fputs("\n# Prompt history (oldest to newest):\n", fp);
		for(i = 0; i < nprompt; i++)
			fprintf(fp, "p%s\n", prompt[i]);
		for(i = cfg.prompt_history_num; i >= 0; i--)
			fprintf(fp, "p%s\n", cfg.prompt_history[i]);
	}

	if(cfg.vifm_info & VIFMINFO_REGISTERS)
	{
		fputs("\n# Registers:\n", fp);
		for(i = 0; i < nregs; i++)
			fprintf(fp, "%s\n", regs[i]);
		for(i = 0; valid_registers[i] != '\0'; i++)
		{
			int j;
			registers_t *reg = find_register(valid_registers[i]);
			if(reg == NULL)
				continue;
			for(j = 0; j < reg->num_files; j++)
			{
				if(reg->files[j] == NULL)
					continue;
				fprintf(fp, "\"%c%s\n", reg->name, reg->files[j]);
			}
		}
	}

	if(cfg.vifm_info & VIFMINFO_DIRSTACK)
	{
		fputs("\n# Directory stack (oldest to newest):\n", fp);
		for(i = 0; i < stack_top; i++)
		{
			fprintf(fp, "S%s\n\t%s\n", stack[i].lpane_dir, stack[i].lpane_file);
			fprintf(fp, "S%s\n\t%s\n", stack[i].rpane_dir, stack[i].rpane_file);
		}
	}

	fputs("\n# Trash content:\n", fp);
	for(i = 0; i < nentries; i++)
		fprintf(fp, "t%s\n\t%s\n", trash_list[i].trash_name, trash_list[i].path);
	for(i = 0; i < ntrash; i += 2)
		fprintf(fp, "t%s\n\t%s\n", trash[i], trash[i + 1]);

	if(cfg.vifm_info & VIFMINFO_STATE)
	{
		fputs("\n# State:\n", fp);
		fprintf(fp, "f%s\n", lwin.filename_filter);
		fprintf(fp, "i%d\n", lwin.invert);
		fprintf(fp, "[.%d\n", lwin.hide_dot);
		fprintf(fp, "F%s\n", rwin.filename_filter);
		fprintf(fp, "I%d\n", rwin.invert);
		fprintf(fp, "].%d\n", rwin.hide_dot);
		fprintf(fp, "s%d\n", cfg.use_screen);
	}

	if(cfg.vifm_info & VIFMINFO_CS)
	{
		fputs("\n# Color scheme:\n", fp);
		fprintf(fp, "c%s\n", cfg.cs.name);
	}

	fclose(fp);

	free_string_array(ft, nft);
	free_string_array(fv, nfv);
	free_string_array(fx, nfx);
	free_string_array(cmds, ncmds);
	free_string_array(marks, nmarks);
	free_string_array(list, nlist);
	free_string_array(lh, nlh);
	free_string_array(rh, nrh);
	free(lhp);
	free(rhp);
	free_string_array(cmdh, ncmdh);
	free_string_array(srch, nsrch);
	free_string_array(regs, nregs);
	free_string_array(prompt, nprompt);
	free_string_array(trash, ntrash);
}
예제 #27
0
파일: config.c 프로젝트: Toeger/f-irc
int load_config(const char *file)
{
	char *description = NULL, *server_host = NULL, *username = NULL, *password = NULL, *nickname = NULL, *user_complete_name = NULL;
	int server_index = -1;
	int linenr = 0;
	int fd = open(file, O_RDONLY);

	if (fd == -1)
	{
		if (errno == ENOENT)
			return -1;

		error_exit(TRUE, "Cannot open config file %s\n", file);
	}

	conf_file = strdup(file);

	for(;;)
	{
		char *line = read_line_fd(fd);
		char *cmd, *par;
		char *is;

		if (!line)
			break;

		linenr++;

		if (strlen(line) == 0)
		{
			myfree(line);
			continue;
		}

		if (line[0] == '#' || line[0] == ';')
		{
			myfree(line);
			continue;
		}

		is = strchr(line, '=');
		if (!is)
			error_exit(FALSE, "config: line %d is missing either command or parameter! (%s)", linenr, line);

		/* find parameter */
		par = is + 1;
		while(*par == ' ')
			par++;

		/* remove spaces around command */
		/* spaces at the start */
		cmd = line;
		while(*cmd == ' ')
			cmd++;
		/* spaces at the end */
		*is = 0x00;
		is--;
		while(*is == ' ')
		{
			*is = 0x00;
			is--;
		}

		if (strcmp(cmd, "server") == 0 || strcmp(cmd, "send_after_login") == 0 || strcmp(cmd, "auto_join") == 0 || strcmp(cmd, "channel") == 0 || strcmp(cmd, "rejoin") == 0)
		{
			/* all stuff already known? */
			if (server_host)
			{
				if (nickname == NULL)
					error_exit(FALSE, "nickname must be set for %s", server_host);

				server_index = add_server(server_host, username, password, nickname, user_complete_name, description ? description : server_host);
				myfree(server_host);
				server_host = NULL;
				myfree(username);
				myfree(password);
				myfree(nickname);
				myfree(user_complete_name);
				myfree(description);

				username = password = nickname = user_complete_name = description = NULL;
			}
		}

		if (strcmp(cmd, "server") == 0)
		{
			/* new server */
			server_host = strdup(par);
		}
		else if (strcmp(cmd, "favorite") == 0)
		{
			int n = -1;
			string_array_t parts;

			init_string_array(&parts);

			split_string(par, " ", TRUE, &parts);
			n = string_array_get_n(&parts);

			if (n != 1 && n != 2)
				error_exit(FALSE, "favorite needs either be in format \"server channel\" or \"channel\"");

			if (n == 2)
				add_favorite(string_array_get(&parts, 0), string_array_get(&parts, 1));
			else
				add_favorite(NULL, string_array_get(&parts, 0));

			free_splitted_string(&parts);
		}
		else if (strcmp(cmd, "username") == 0)
			username = strdup(par);
		else if (strcmp(cmd, "password") == 0)
			password = strdup(par);
		else if (strcmp(cmd, "nick") == 0 || strcmp(cmd, "nickname") == 0)
			nickname = strdup(par);
		else if (strcmp(cmd, "name") == 0)
			user_complete_name = strdup(par);
		else if (strcmp(cmd, "dictionary_file") == 0)
		{
			const char *filename = explode_path(par);

			if (!filename)
				error_exit(TRUE, "Path '%s' is not understood\n", par);

			dictionary_file = filename;

			if (load_dictionary() == FALSE)
				error_exit(TRUE, "Failure loading dictionary file %s (%s)", filename, par);
		}
		else if (strcmp(cmd, "description") == 0)
			description = strdup(par);
		else if (strcmp(cmd, "server_exit_message") == 0)
			server_exit_message = strdup(par);
		else if (strcmp(cmd, "log_dir") == 0)
			log_dir = strdup(par);
		else if (strcmp(cmd, "part_message") == 0)
			part_message = strdup(par);
		else if (strcmp(cmd, "notify_nick") == 0)
			notify_nick = strdup(par);
		else if (strcmp(cmd, "userinfo") == 0)
			userinfo = strdup(par);
		else if (strcmp(cmd, "finger_str") == 0)
			finger_str = strdup(par);
		else if (strcmp(cmd, "mark_personal_messages") == 0)
			mark_personal_messages = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "meta-colors") == 0)
			colors_meta = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "headline_matcher") == 0)
			add_headline_matcher(par);
		else if (strcmp(cmd, "all-colors") == 0)
			colors_all = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "dcc_bind_to") == 0)
			dcc_bind_to = strdup(par);
		else if (strcmp(cmd, "update_clock_at_data") == 0)
			update_clock_at_data = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "nick-color") == 0)
			nick_color = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "use_nonbasic_colors") == 0)
			use_nonbasic_colors = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "ignore_unknown_irc_protocol_msgs") == 0)
			ignore_unknown_irc_protocol_msgs = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "auto_markerline") == 0)
			auto_markerline = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "inverse_window_heading") == 0)
			inverse_window_heading = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "keep_channels_sorted") == 0)
			keep_channels_sorted = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "allow_invite") == 0)
			allow_invite = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "show_headlines") == 0)
			show_headlines = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "remember_channels") == 0)
			remember_channels = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "allow_userinfo") == 0)
			allow_userinfo = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "extra_highlights") == 0)
			add_to_string_array(&extra_highlights, par);
		else if (strcmp(cmd, "only_one_markerline") == 0)
			only_one_markerline = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "auto_rejoin") == 0)
			auto_rejoin = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "ignore_mouse") == 0)
			ignore_mouse = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "irc_keepalive") == 0)
			irc_keepalive = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "space_after_start_marker") == 0)
			space_after_start_marker = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "jumpy_navigation") == 0)
			jumpy_navigation = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "mark_meta") == 0)
			mark_meta = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "user_column") == 0)
			user_column = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "full_user") == 0)
			full_user = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "grep_filter") == 0)
			add_filter(gp, par, linenr);
		else if (strcmp(cmd, "headline_filter") == 0)
			add_filter(hlgp, par, linenr);
		else if (strcmp(cmd, "show_parts") == 0)
			show_parts = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "show_mode_changes") == 0)
			show_mode_changes = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "show_nick_change") == 0)
			show_nick_change = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "show_joins") == 0)
			show_joins = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "store_config_on_exit") == 0)
			store_config_on_exit = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "partial_highlight_match") == 0)
			partial_highlight_match = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "topic_scroll") == 0)
			topic_scroll = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "notice_in_serverchannel") == 0)
			notice_in_server_channel = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "highlight") == 0)
			highlight = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "fuzzy_highlight") == 0)
			fuzzy_highlight = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "theme") == 0)
		{
			struct stat status;
			const char *filename = explode_path(par);

			if (!filename)
				error_exit(TRUE, "Path '%s' is not understood\n", par);

			if (stat(filename, &status) == -1) 	/* file doesn't exist, look for it under SYSCONFDIR */
			{
				int len = strlen(SYSCONFDIR) + strlen(par) + 2;
				char *theme_path = malloc(len * sizeof(char));

				snprintf(theme_path, len, "%s/%s", SYSCONFDIR, par);
				load_theme(theme_path);

				theme_file = theme_path;
			} 
			else
			{
				load_theme(filename);

				theme_file = strdup(par);
			}

			myfree(filename);
		}
		else if (strcmp(cmd, "ignore_file") == 0)
		{
			struct stat status;
			const char *filename = explode_path(par);

			if (!filename)
				error_exit(TRUE, "Path '%s' is not understood\n", par);

			if (load_ignore_list(par) == TRUE)
			{
			}
			else if (load_ignore_list(filename) == TRUE)
			{
			}
			else if (stat(filename, &status) == -1) 	/* file doesn't exist, look elsewhere */
			{
				int len = strlen(SYSCONFDIR) + strlen(par) + 2;
				char *ignore_file = malloc(len * sizeof(char));

				/* look for it under SYSCONFDIR */
				snprintf(ignore_file, len, "%s/%s", SYSCONFDIR, par);

				/* look for it under ~/.firc location */
				if (stat(ignore_file, &status) == -1)
					snprintf(ignore_file, len, "%s/%s", dirname(conf_file), par);

				load_ignore_list(ignore_file);

				myfree(ignore_file);
			} 

			myfree(filename);
		}
		else if (strcmp(cmd, "send_after_login") == 0)
		{
			server *ps = &server_list[server_index];

			if (server_index == -1)
				error_exit(FALSE, "send_after_login: you need to define a server first\n");

			add_to_string_array(&ps -> send_after_login, par);
		}
		else if (strcmp(cmd, "auto_join") == 0 || strcmp(cmd, "channel") == 0)
		{
			if (server_index == -1)
				error_exit(FALSE, "auto_join: you need to define a server first\n");

			add_autojoin(server_index, par);
		}
		else if (strcmp(cmd, "rejoin") == 0)
		{
			add_channel(server_index, par);

			if (keep_channels_sorted)
				sort_channels(server_index);
		}
		else if (strcmp(cmd, "auto_private_channel") == 0)
			auto_private_channel = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "dcc_path") == 0)
			dcc_path = strdup(par);
		else if (strcmp(cmd, "default_colorpair") == 0)
			default_colorpair = parse_color_spec(par, linenr, cmd);
		else if (strcmp(cmd, "markerline_colorpair") == 0)
			markerline_colorpair = parse_color_spec(par, linenr, cmd);
		else if (strcmp(cmd, "highlight_colorpair") == 0)
			highlight_colorpair = parse_color_spec(par, linenr, cmd);
		else if (strcmp(cmd, "meta_colorpair") == 0)
			meta_colorpair = parse_color_spec(par, linenr, cmd);
		else if (strcmp(cmd, "error_colorpair") == 0)
			error_colorpair = parse_color_spec(par, linenr, cmd);
		else if (strcmp(cmd, "temp_colorpair") == 0)
			temp_colorpair = parse_color_spec(par, linenr, cmd);
		else if (strcmp(cmd, "check_for_mail") == 0)
			check_for_mail = atoi(par);
		else if (strcmp(cmd, "user_column_width") == 0)
			user_column_width = atoi(par);
		else if (strcmp(cmd, "delay_before_reconnect") == 0)
			delay_before_reconnect = atoi(par);
		else if (strcmp(cmd, "word_cloud_n") == 0)
			word_cloud_n = atoi(par);
		else if (strcmp(cmd, "word_cloud_refresh") == 0)
		{
			word_cloud_refresh = atoi(par);
			word_cloud_last_refresh = time(NULL);
		}
		else if (strcmp(cmd, "word_cloud_win_height") == 0)
			word_cloud_win_height = atoi(par);
		else if (strcmp(cmd, "max_channel_record_lines") == 0)
			max_channel_record_lines = atoi(par);
		else if (strcmp(cmd, "word_cloud_min_word_size") == 0)
			word_cloud_min_word_size = atoi(par);
		else
		{
			error_exit(FALSE, "'%s=%s' is not understood\n", cmd, par);
		}

		myfree(line);
	}

	close(fd);

	if (server_host)
	{
		if (nickname == NULL)
			error_exit(FALSE, "nickname must be set for %s", server_host);
		add_server(server_host, username, password, nickname, user_complete_name, description);
		myfree(server_host);
		myfree(username);
		myfree(password);
		myfree(nickname);
		myfree(user_complete_name);
		myfree(description);
	}

	return 0;
}
예제 #28
0
/* Parses command-line arguments into fields of the *args structure. */
void
args_parse(args_t *args, int argc, char *argv[], const char dir[])
{
	/* Request getopt() reinitialization. */
	optind = 0;

	while(1)
	{
		switch(getopt_long(argc, argv, "-c:fhv", long_opts, NULL))
		{
			case 'f': /* -f */
				args->file_picker = 1;
				break;
			case 'F': /* --choose-files <path>|- */
				get_path_or_std(dir, optarg, args->chosen_files_out);
				args->file_picker = 0;
				break;
			case 'D': /* --choose-dir <path>|- */
				get_path_or_std(dir, optarg, args->chosen_dir_out);
				break;
			case 'd': /* --delimiter <delimiter> */
				args->delimiter = optarg;
				break;
			case 'o': /* --on-choose <cmd> */
				args->on_choose = optarg;
				break;

			case 'r': /* --remote <args>... */
				args->remote_cmds = argv + optind;
				return;

			case 'h': /* -h, --help */
				/* Only first one of -v and -h should take effect. */
				if(!args->version)
				{
					args->help = 1;
				}
				break;
			case 'v': /* -v, --version */
				/* Only first one of -v and -h should take effect. */
				if(!args->help)
				{
					args->version = 1;
				}
				break;

			case 'c': /* -c <cmd> */
				args->ncmds = add_to_string_array(&args->cmds, args->ncmds, 1, optarg);
				break;
			case 'l': /* --logging */
				args->logging = 1;
				break;
			case 'n': /* --no-configs */
				args->no_configs = 1;
				break;

			case 's': /* --select <path> */
				handle_arg_or_fail(optarg, 1, dir, args);
				break;
			case 1: /* Positional argument. */
				if(argv[optind - 1][0] == '+')
				{
					args->ncmds = add_to_string_array(&args->cmds, args->ncmds, 1,
							argv[optind - 1] + 1);
				}
				else
				{
					handle_arg_or_fail(argv[optind - 1], 0, dir, args);
				}
				break;

			case '?': /* Parsing error. */
#ifndef ENABLE_REMOTE_CMDS
				if(starts_with("--remote", argv[optind - 1]))
				{
					fprintf(stderr,
							"Warning: remote commands were disabled at build-time!\n");
				}
#endif
				/* getopt_long() already printed error message. */
				quit_on_arg_parsing(EXIT_FAILURE);
				break;

			case -1: /* No more arguments. */
				return;
		}
	}
}
예제 #29
0
void string_array_add(string_array *sa,char *string)
{
  add_to_string_array(sa,string);
}