⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hotlist.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 3 页
字号:
	    target = strdup (l_hotlist->current->text);
	break;
    }

    hotlist_done ();
    return target;
}

void load_group (struct hotlist *grp)
{
    void *profile_keys;
    char *key, *value;
    char *group_section;
    struct hotlist *current = 0;

    group_section = find_group_section (grp);

    profile_keys = profile_init_iterator (group_section, profile_name);

    current_group = grp;

    while (profile_keys){
	profile_keys = profile_iterator_next (profile_keys, &key, &value);
	add2hotlist (strdup (value), strdup (key), HL_TYPE_GROUP, 0);
    }
    free (group_section);

    profile_keys = profile_init_iterator (grp->directory, profile_name);

    while (profile_keys){
	profile_keys = profile_iterator_next (profile_keys, &key, &value);
	add2hotlist (strdup (value), strdup (key), HL_TYPE_ENTRY, 0);
    }

    for (current = grp->head; current; current = current->next)
	load_group (current);
}

#define TKN_GROUP	0
#define TKN_ENTRY	1
#define TKN_STRING	2
#define TKN_URL		3
#define TKN_ENDGROUP	4
#define TKN_COMMENT	5
#define TKN_EOL		125
#define TKN_EOF		126
#define TKN_UNKNOWN	127

static char *tkn_buf;
static int  tkn_buf_length;
static int  tkn_length;

static char *hotlist_file_name;
static FILE *hotlist_file;
static time_t hotlist_file_mtime;

static int hot_skip_blanks ()
{
    int c;

    while ((c = getc (hotlist_file)) != EOF && c != '\n' && isspace (c))
	;
    return c;

}

static int hot_next_token ()
{
    int	c;

#define CHECK_BUF() \
do { \
    if (tkn_length == tkn_buf_length) \
	tkn_buf = tkn_buf ? (realloc (tkn_buf, tkn_buf_length += 1024)) \
			  : (malloc (tkn_buf_length = 1024)); \
} while (0)

    tkn_length = 0;

again:
    c = hot_skip_blanks ();
    switch (c) {
    case EOF:
	return TKN_EOF;
	break;
    case '\n':
	return TKN_EOL;
	break;
    case '#':
	while ((c = getc (hotlist_file)) != EOF && c != '\n') {
	    if (c == EOF)
		return TKN_EOF;
	    if (c != '\n') {
		CHECK_BUF();
		tkn_buf[tkn_length++] = c == '\n' ? ' ' : c;
	    }
	}
	CHECK_BUF();
	tkn_buf[tkn_length] = '\0';
	return TKN_COMMENT;
	break;
    case '"':
	while ((c = getc (hotlist_file)) != EOF && c != '"') {
	    if (c == '\\')
		if ((c = getc (hotlist_file)) == EOF)
		    return TKN_EOF;
	    CHECK_BUF();
	    tkn_buf[tkn_length++] = c == '\n' ? ' ' : c;
	}
	if (c == EOF)
	    return TKN_EOF;
	CHECK_BUF();
	tkn_buf[tkn_length] = '\0';
	return TKN_STRING;
	break;
    case '\\':
	if ((c = getc (hotlist_file)) == EOF)
	    return TKN_EOF;
	if (c == '\n')
	    goto again;

	/* fall through; it is taken as normal character */

    default:
	do {
	    CHECK_BUF();
	    tkn_buf[tkn_length++] = toupper(c);
	} while ((c = fgetc (hotlist_file)) != EOF && isalnum (c));
	if (c != EOF)
	    ungetc (c, hotlist_file);
	CHECK_BUF();
	tkn_buf[tkn_length] = '\0';
	if (strncmp (tkn_buf, "GROUP", tkn_length) == 0)
	    return TKN_GROUP;
	else if (strncmp (tkn_buf, "ENTRY", tkn_length) == 0)
	    return TKN_ENTRY;
	else if (strncmp (tkn_buf, "ENDGROUP", tkn_length) == 0)
	    return TKN_ENDGROUP;
	else if (strncmp (tkn_buf, "URL", tkn_length) == 0)
	    return TKN_URL;
	else
	    return TKN_UNKNOWN;
	break;
    }
}

#define SKIP_TO_EOL	{ \
int _tkn; \
while ((_tkn = hot_next_token ()) != TKN_EOF && _tkn != TKN_EOL) ; \
}

#define CHECK_TOKEN(_TKN_) \
if ((tkn = hot_next_token ()) != _TKN_) { \
    hotlist_state.readonly = 1; \
    hotlist_state.file_error = 1; \
    while (tkn != TKN_EOL && tkn != TKN_EOF) \
	tkn = hot_next_token (); \
break; \
}

static void
hot_load_group (struct hotlist * grp)
{
    int		tkn;
    struct hotlist *new_grp;
    char	*label, *url;

    current_group = grp;

    while ((tkn = hot_next_token()) != TKN_ENDGROUP)
	switch (tkn) {
	case TKN_GROUP:
	    CHECK_TOKEN(TKN_STRING);
	    new_grp = add2hotlist (strdup (tkn_buf), 0, HL_TYPE_GROUP, 0);
	    SKIP_TO_EOL;
	    hot_load_group (new_grp);
	    current_group = grp;
	    break;
	case TKN_ENTRY:
	    CHECK_TOKEN(TKN_STRING);
	    label = strdup (tkn_buf);
	    CHECK_TOKEN(TKN_URL);
	    CHECK_TOKEN(TKN_STRING);
	    url = strdup (tkn_buf);
	    add2hotlist (label, url, HL_TYPE_ENTRY, 0);
	    SKIP_TO_EOL;
	    break;
	case TKN_COMMENT:
	    label = strdup (tkn_buf);
	    add2hotlist (label, 0, HL_TYPE_COMMENT, 0);
	    break;
	case TKN_EOF:
	    hotlist_state.readonly = 1;
	    hotlist_state.file_error = 1;
	    return;
	    break;
	case TKN_EOL:
	    /* skip empty lines */
	    break;
	default:
	    hotlist_state.readonly = 1;
	    hotlist_state.file_error = 1;
	    SKIP_TO_EOL;
	    break;
	}
    SKIP_TO_EOL;
}

static void
hot_load_file (struct hotlist * grp)
{
    int		tkn;
    struct hotlist *new_grp;
    char	*label, *url;

    current_group = grp;

    while ((tkn = hot_next_token())!= TKN_EOF)
	switch (tkn) {
	case TKN_GROUP:
	    CHECK_TOKEN(TKN_STRING);
	    new_grp = add2hotlist (strdup (tkn_buf), 0, HL_TYPE_GROUP, 0);
	    SKIP_TO_EOL;
	    hot_load_group (new_grp);
	    current_group = grp;
	    break;
	case TKN_ENTRY:
	    CHECK_TOKEN(TKN_STRING);
	    label = strdup (tkn_buf);
	    CHECK_TOKEN(TKN_URL);
	    CHECK_TOKEN(TKN_STRING);
	    url = strdup (tkn_buf);
	    add2hotlist (label, url, HL_TYPE_ENTRY, 0);
	    SKIP_TO_EOL;
	    break;
	case TKN_COMMENT:
	    label = strdup (tkn_buf);
	    add2hotlist (label, 0, HL_TYPE_COMMENT, 0);
	    break;
	case TKN_EOL:
	    /* skip empty lines */
	    break;
	default:
	    hotlist_state.readonly = 1;
	    hotlist_state.file_error = 1;
	    SKIP_TO_EOL;
	    break;
	}
}

void
clean_up_hotlist_groups (char *section)
{
    char	*grp_section;
    void	*profile_keys;
    char	*key, *value;

    grp_section = copy_strings (section, ".Group", (char *)0);
    if (profile_has_section (section, profile_name))
	profile_clean_section (section, profile_name);
    if (profile_has_section (grp_section, profile_name)) {
	profile_keys = profile_init_iterator (grp_section, profile_name);

	while (profile_keys) {
	    profile_keys = profile_iterator_next (profile_keys, &key, &value);
	    clean_up_hotlist_groups (key);
	}
	profile_clean_section (grp_section, profile_name);
    }
    free (grp_section);
}



void load_hotlist (void)
{
    char	*grp_section;
    int		has_old_list = 0;
    int		remove_old_list = 0;
    struct stat stat_buf;

    if (hotlist_state.loaded) {
	stat (hotlist_file_name, &stat_buf);
	if (hotlist_file_mtime < stat_buf.st_mtime)
	    done_hotlist ();
	else
	    return;
    }

    if (!hotlist_file_name)
	hotlist_file_name = concat_dir_and_file (home_dir, HOTLIST_FILENAME);

    hotlist	       = new_hotlist ();
    hotlist->type      = HL_TYPE_GROUP;
    hotlist->label     = strdup (_(" Top level group "));
    hotlist->up        = hotlist;
    /*
     * compatibility :-(
     */
    hotlist->directory = strdup ("Hotlist");

    grp_section = copy_strings ("Hotlist", ".Group", (char *)0);
    has_old_list = profile_has_section ("Hotlist", profile_name) ||
		   profile_has_section (grp_section, profile_name);
    free (grp_section);

    if ((hotlist_file = fopen (hotlist_file_name, "r")) == 0) {
	int	result;
	char    *msg;

	msg = copy_strings (_("Hotlist is now kept in file ~/"), HOTLIST_FILENAME,
			    _("MC will load hotlist from ~/"),  PROFILE_NAME,
			    _(" and then delete [Hotlist] section there"), NULL);
	message (0, _(" Hotlist Load "), msg);
	free (msg);

	load_group (hotlist);
	hotlist_state.loaded   = 1;
	/*
	 * just to be shure we got copy
	 */
	hotlist_state.modified = 1;
	result = save_hotlist ();
	hotlist_state.modified = 0;
	if (result) {
	    remove_old_list = 1;
	} else {
	    char *msg;

	    msg = copy_strings (_("MC was unable to write ~/"), HOTLIST_FILENAME,
				_(" file, your old hotlist entries were not deleted"), NULL);

	    message (D_ERROR, _(" Hotlist Load "), msg);
	    free (msg);
	}
    } else {
	hot_load_file (hotlist);
	fclose (hotlist_file);
	hotlist_state.loaded = 1;
	if (has_old_list) {
	    int		result;
	    char        *msg;

	    msg = copy_strings (
		    _("You have ~/"), HOTLIST_FILENAME, _(" file and [Hotlist] section in ~/"), PROFILE_NAME, "\n",
		    _("Your ~/"), HOTLIST_FILENAME, _(" most probably was created\n"),
		    _("by an earlier development version of MC\nand is more actual than ~/"),
		    PROFILE_NAME, _(" entries\n\n"),
		    _("You can choose between\n\n"
		      "  Remove - remove old hotlist entries from ~/"), PROFILE_NAME, "\n",
		    _("  Keep   - keep your old entries; you will be asked\n"
		      "           the same question next time\n"
		      "  Merge  - add old entries to hotlist as group \"Entries from ~/"),
		    PROFILE_NAME, "\"\n\n", NULL);

	    result = query_dialog (_(" Hotlist Load "),
				   msg, D_ERROR, 3, _("&Remove"), _("&Keep"), _("&Merge"));
	    if (result == 0)
		remove_old_list = 1;
	    else if (result == 2) {
		struct hotlist	*grp = hotlist->head;
		struct hotlist	*old;

		hotlist->head = 0;
		load_group (hotlist);

		old            = new_hotlist ();
		old->type      = HL_TYPE_GROUP;
		old->label     = copy_strings (_(" Entries from ~/"), PROFILE_NAME, NULL);
		old->up	       = hotlist;
		old->head      = hotlist->head;
		old->next      = grp;
		hotlist->head  = old;
		hotlist_state.modified = 1;
		if (!save_hotlist ()){
		    char *str;

		    str = copy_strings (_("MC was unable to write ~/"), HOTLIST_FILENAME,
					_(" file your old hotlist entries were not deleted"), NULL);

		    message (D_ERROR, _(" Hotlist Load "), str);
		    free (str);
		} else
		    remove_old_list = 1;
		hotlist_state.modified = 0;
	    }
	}
    }

    if (remove_old_list) {
	clean_up_hotlist_groups ("Hotlist");
	sync_profiles ();
    }

    stat (hotlist_file_name, &stat_buf);
    hotlist_file_mtime = stat_buf.st_mtime;
    current_group = hotlist;
}

void save_group (struct hotlist *grp)
{
    struct hotlist *current = grp->head;
    char           *group_section;

    group_section = find_group_section (grp);

    profile_clean_section (group_section, profile_name);
    for (;current && current->type == HL_TYPE_GROUP; current = current->next){
	WritePrivateProfileString (group_section,
				   current->directory,
				   current->label,
				   profile_name);
    }
    free (group_section);

    for (current = grp->head;
	 current && current->type == HL_TYPE_GROUP;
	 current = current->next)
	 save_group (current);

    profile_clean_section (grp->directory, profile_name);
    for (;current; current = current->next){
	WritePrivateProfileString (grp->directory,
				   current->directory,
				   current->label,
				   profile_name);
    }
}

static int  list_level = 0;

void hot_save_group (struct hotlist *grp)
{
    struct hotlist *current = grp->head;
    int		    i;
    char	   *s;

#define INDENT(n) \
do { \
    for (i = 0; i < n; i++) \
	putc (' ', hotlist_file); \
} while (0)

    for (;current; current = current->next)
        switch (current->type) {
        case HL_TYPE_GROUP:
	    INDENT (list_level);
	    fputs ("GROUP \"", hotlist_file);
	    for (s = current->label; *s; s++) {
		if (*s == '"')
		    putc ('\\', hotlist_file);
		else if (*s == '\\')
		    putc ('\\', hotlist_file);
		putc (*s, hotlist_file);
	    }
	    fputs ("\"\n", hotlist_file);
	    list_level += 2;
	    hot_save_group (current);
	    list_level -= 2;
	    INDENT (list_level);
	    fputs ("ENDGROUP\n", hotlist_file);
	    break;
        case HL_TYPE_ENTRY:
	    INDENT(list_level);
	    fputs ("ENTRY \"", hotlist_file);
	    for (s = current->label; *s; s++) {
		if (*s == '"')
		    putc ('\\', hotlist_file);
		else if (*s == '\\')
		    putc ('\\', hotlist_file);
		putc (*s, hotlist_file);
	    }
	    fputs ("\" URL \"", hotlist_file);
	    for (s = current->directory; *s; s++) {
		if (*s == '"')
		    putc ('\\', hotlist_file);
		else if (*s == '\\')
		    putc ('\\', hotlist_file);
		putc (*s, hotlist_file);
	    }
	    fputs ("\"\n", hotlist_file);
	    break;
	case HL_TYPE_COMMENT:
	    fprintf (hotlist_file, "#%s\n", current->label);
	    break;

	}
}

int save_hotlist (void)
{
    int		saved = 0;
    struct      stat stat_buf;

    if (!hotlist_state.readonly && hotlist_state.modified && hotlist_file_name) {
	char	*fbak = copy_strings (hotlist_file_name, ".bak", 0);

	rename (hotlist_file_name, fbak);
	if ((hotlist_file = fopen (hotlist_file_name, "w")) != 0) {
	    if (stat (fbak, &stat_buf) == 0)
		chmod (hotlist_file_name, stat_buf.st_mode);
	    else
		chmod (hotlist_file_name, S_IRUSR | S_IWUSR);
	    hot_save_group (hotlist);
	    fflush (hotlist_file);
	    fclose (hotlist_file);
	    stat (hotlist_file_name, &stat_buf);
	    hotlist_file_mtime = stat_buf.st_mtime;
	    saved = 1;
	    hotlist_state.modified = 0;
	} else
	    rename (fbak, hotlist_file_name);
	free (fbak);
    }

    return saved;
}

void done_hotlist (void)
{
    remove_group (hotlist);
    hotlist_state.loaded = 0;
    if (hotlist->label)
        free (hotlist->label);
    if (hotlist->directory)
        free (hotlist->directory);
    free (hotlist);
    if (hotlist_file_name)
        free (hotlist_file_name);
    hotlist_file_name = 0;
    hotlist = current_group = 0;
    l_hotlist = 0;
    current_group = 0;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -