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

📄 rthread.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
	    reread = FALSE;	}    }    artp = Nullart;    art = lastart+1;    forcelast = TRUE;}/* Find previous thread (or last if artp == NULL).  If articles are selected,** only choose from threads with selected articles.*/voidprev_subject(){    register SUBJECT *sp;    register ARTICLE *ap;    sp = ((ap = artp) ? ap->subj->prev : last_subject);    for (; sp; sp = sp->prev) {	if (sp->flags & SF_VISIT) {	    if ((ap = subj_art(sp)) != Nullart) {		art = article_num(ap);		artp = ap;		return;	    }	    reread = FALSE;	}    }    artp = Nullart;    art = lastart+1;    forcelast = TRUE;}/* Find artp's parent or oldest ancestor.  Returns FALSE if no such** article.  Sets art and artp otherwise.*/boolfind_parent(keep_going)bool_int keep_going;{    register ARTICLE *ap = artp;    if (!ap->parent)	return FALSE;    do {	ap = ap->parent;    } while (keep_going && ap->parent);    if (((artp = ap)->flags & AF_TMPMEM) == AF_TMPMEM)	art = 0;    else	art = article_num(ap);    return TRUE;}/* Find artp's first child or youngest decendent.  Returns FALSE if no** such article.  Sets art and artp otherwise.*/boolfind_leaf(keep_going)bool_int keep_going;{    register ARTICLE *ap = artp;    if (!ap->child1)	return FALSE;    do {	ap = ap->child1;    } while (keep_going && ap->child1);    if (((artp = ap)->flags & AF_TMPMEM) == AF_TMPMEM)	art = 0;    else	art = article_num(ap);    return TRUE;}static ARTICLE *first_sib(), *last_sib();/* Find the next "sibling" of artp, including cousins that are the** same distance down the thread as we are.  Returns FALSE if no such** article.  Sets art and artp otherwise.*/boolfind_next_sib(){    ARTICLE *ta, *tb;    int ascent;    ascent = 0;    ta = artp;    for (;;) {	while (ta->sibling) {	    ta = ta->sibling;	    if (tb = first_sib(ta, ascent)) {		if (((artp = tb)->flags & AF_TMPMEM) == AF_TMPMEM)		    art = 0;		else		    art = article_num(tb);		return TRUE;	    }	}	if (!(ta = ta->parent))	    break;	ascent++;    }    return FALSE;}/* A recursive routine to find the first node at the proper depth.  This** article is at depth 0.*/static ARTICLE *first_sib(ta, depth)ARTICLE *ta;int depth;{    ARTICLE *tb;    if (!depth)	return ta;    for (;;) {	if (ta->child1 && (tb = first_sib(ta->child1, depth-1)))	    return tb;	if (!ta->sibling)	    return Nullart;	ta = ta->sibling;    }}/* Find the previous "sibling" of artp, including cousins that are** the same distance down the thread as we are.  Returns FALSE if no** such article.  Sets art and artp otherwise.*/boolfind_prev_sib(){    ARTICLE *ta, *tb;    int ascent;    ascent = 0;    ta = artp;    for (;;) {	tb = ta;	if (ta->parent)	    ta = ta->parent->child1;	else	    ta = ta->subj->thread;	if (tb = last_sib(ta, ascent, tb)) {	    if (((artp = tb)->flags & AF_TMPMEM) == AF_TMPMEM)		art = 0;	    else		art = article_num(tb);	    return TRUE;	}	if (!(ta = ta->parent))	    break;	ascent++;    }    return FALSE;}/* A recursive routine to find the last node at the proper depth.  This** article is at depth 0.*/static ARTICLE *last_sib(ta, depth, limit)ARTICLE *ta;int depth;ARTICLE *limit;{    ARTICLE *tb, *tc;    if (ta == limit)	return Nullart;    if (ta->sibling) {	tc = ta->sibling;	if (tc != limit && (tb = last_sib(tc,depth,limit)))	    return tb;    }    if (!depth)	return ta;    if (ta->child1)	return last_sib(ta->child1, depth-1, limit);    return Nullart;}/* Get each subject's article count; count total articles and selected** articles (use sel_rereading to determine whether to count read or** unread articles); deselect any subjects we find that are empty if** CS_UNSELECT or CS_UNSEL_STORE is specified.  If mode is CS_RESELECT** is specified, the selections from the last CS_UNSEL_STORE are** reselected.*/voidcount_subjects(mode)int mode;{    register int count, sel_count;    register ARTICLE *ap;    register SUBJECT *sp;    int desired_flags = (sel_rereading? AF_READ : 0);    time_t subjdate;    article_count = selected_count = selected_subj_cnt = 0;    if (last_cached >= lastart)	firstart = lastart+1;    for (sp = first_subject; sp; sp = sp->next)	sp->flags &= ~SF_VISIT;    for (sp = first_subject; sp; sp = sp->next) {	subjdate = 0;	count = sel_count = 0;	for (ap = sp->articles; ap; ap = ap->subj_next) {	    if ((ap->flags & (AF_MISSING|AF_READ)) == desired_flags) {		count++;		if (ap->flags & sel_mask)		    sel_count++;		if (!subjdate)		    subjdate = ap->date;		if (article_num(ap) < firstart)		    firstart = article_num(ap);	    }	}	if (mode == CS_UNSEL_STORE) {	    if (sp->flags & SF_SEL)		sp->flags |= SF_OLDSEL;	    else		sp->flags &= ~SF_OLDSEL;	} else if (mode == CS_RESELECT) {	    if (sp->flags & SF_OLDSEL)		sp->flags |= SF_SEL;	    else		sp->flags &= ~SF_SEL;	}	sp->misc = count;	if (subjdate)	    sp->date = subjdate;	article_count += count;	if (sel_count) {	    sp->flags = (sp->flags & ~(SF_SEL|SF_DEL)) | sel_mask;	    selected_count += sel_count;	    selected_subj_cnt++;	} else if (mode >= CS_UNSELECT)	    sp->flags &= ~sel_mask;	else if (sp->flags & sel_mask) {	    sp->flags &= ~SF_DEL;	    selected_subj_cnt++;	}	if (count && (!selected_only || (sp->flags & sel_mask))) {	    sp->flags |= SF_VISIT;	    if (sel_mode == SM_THREAD) {		if ((ap = sp->thread) != NULL)		    ap->subj->flags |= SF_VISIT;	    }	}    }    if (mode && !article_count && !selected_only) {	for (sp = first_subject; sp; sp = sp->next)	    sp->flags |= SF_VISIT;    }}intsubjorder_subject(spp1, spp2)register SUBJECT **spp1;register SUBJECT **spp2;{    return strCASEcmp((*spp1)->str+4, (*spp2)->str+4) * sel_direction;}intsubjorder_date(spp1, spp2)register SUBJECT **spp1;register SUBJECT **spp2;{    return (int)((*spp1)->date - (*spp2)->date) * sel_direction;}intsubjorder_count(spp1, spp2)register SUBJECT **spp1;register SUBJECT **spp2;{    int eq;    if ((eq = (int)((*spp1)->misc - (*spp2)->misc)) != 0)	return eq * sel_direction;    return (int)((*spp1)->date - (*spp2)->date) * sel_direction;}intthreadorder_subject(spp1, spp2)SUBJECT **spp1;SUBJECT **spp2;{    register ARTICLE *t1 = (*spp1)->thread;    register ARTICLE *t2 = (*spp2)->thread;    if (t1 != t2 && t1 && t2)	return strCASEcmp(t1->subj->str+4, t2->subj->str+4) * sel_direction;    return (int)((*spp1)->date - (*spp2)->date) * sel_direction;}intthreadorder_date(spp1, spp2)SUBJECT **spp1;SUBJECT **spp2;{    register ARTICLE *t1 = (*spp1)->thread;    register ARTICLE *t2 = (*spp2)->thread;    if (t1 != t2 && t1 && t2) {	register SUBJECT *sp1, *sp2;	int eq;	if (!(sp1 = t1->subj)->misc)	    for (sp1=sp1->thread_link; sp1 != t1->subj; sp1=sp1->thread_link)		if (sp1->misc)		    break;	if (!(sp2 = t2->subj)->misc)	    for (sp2=sp2->thread_link; sp2 != t2->subj; sp2=sp2->thread_link)		if (sp2->misc)		    break;	if ((eq = (int)(sp1->date - sp2->date) * sel_direction) != 0)	    return eq;	return strCASEcmp(sp1->str+4, sp2->str+4) * sel_direction;    }    return (int)((*spp1)->date - (*spp2)->date) * sel_direction;}intthreadorder_count(spp1, spp2)SUBJECT **spp1;SUBJECT **spp2;{    register int size1 = (*spp1)->misc;    register int size2 = (*spp2)->misc;    if ((*spp1)->thread != (*spp2)->thread) {	register SUBJECT *sp;	for (sp = (*spp1)->thread_link; sp != *spp1; sp = sp->thread_link)	    size1 += sp->misc;	for (sp = (*spp2)->thread_link; sp != *spp2; sp = sp->thread_link)	    size2 += sp->misc;    }    if (size1 != size2)	return (size1 - size2) * sel_direction;    return threadorder_date(spp1, spp2);}/* Sort the subjects according to the chosen order.*/voidsort_subjects(){    register SUBJECT *sp;    register int i;    SUBJECT **lp, **subj_list;    int (*sort_procedure)();    /* If we don't have at least two subjects, we're done! */    if (!first_subject || !first_subject->next)	return;    switch (sel_sort) {    case SS_DATE:    case SS_AUTHOR:    case SS_GROUPS:	sort_procedure = (sel_mode == SM_THREAD?			  threadorder_date : subjorder_date);	break;    case SS_SUBJECT:	sort_procedure = (sel_mode == SM_THREAD?			  threadorder_subject : subjorder_subject);	break;    case SS_COUNT:	sort_procedure = (sel_mode == SM_THREAD?			  threadorder_count : subjorder_count);	break;    }    subj_list = (SUBJECT**)safemalloc(subject_count * sizeof (SUBJECT*));    for (lp = subj_list, sp = first_subject; sp; sp = sp->next)	*lp++ = sp;    assert(lp - subj_list == subject_count);    qsort(subj_list, subject_count, sizeof (SUBJECT*), sort_procedure);    first_subject = sp = subj_list[0];    sp->prev = Nullsubj;    for (i = subject_count, lp = subj_list; --i; lp++) {	lp[0]->next = lp[1];	lp[1]->prev = lp[0];	if (sel_mode == SM_THREAD) {	    if (lp[0]->thread == lp[1]->thread)		lp[0]->thread_link = lp[1];	    else {		lp[0]->thread_link = sp;		sp = lp[1];	    }	}    }    last_subject = lp[0];    last_subject->next = Nullsubj;    if (sel_mode == SM_THREAD)	last_subject->thread_link = sp;    free((char*)subj_list);}intartorder_date(art1, art2)register ARTICLE **art1;register ARTICLE **art2;{    return (int)((*art1)->date - (*art2)->date) * sel_direction;}intartorder_subject(art1, art2)register ARTICLE **art1;register ARTICLE **art2;{    if ((*art1)->subj == (*art2)->subj)	return (int)((*art1)->date - (*art2)->date);    return strCASEcmp((*art1)->subj->str + 4, (*art2)->subj->str + 4)	* sel_direction;}intartorder_author(art1, art2)register ARTICLE **art1;register ARTICLE **art2;{    int eq;    if ((eq = strCASEcmp((*art1)->from, (*art2)->from)) != 0)	return eq * sel_direction;    return (int)((*art1)->date - (*art2)->date);}intartorder_groups(art1, art2)register ARTICLE **art1;register ARTICLE **art2;{    if ((*art1)->subj == (*art2)->subj)	return (int)((*art1)->date - (*art2)->date);    return (int)((*art1)->subj->date - (*art2)->subj->date) * sel_direction;}/* Sort the articles according to the chosen order.*/voidsort_articles(){    int (*sort_procedure)();    build_artptrs();    /* If we don't have at least two articles, we're done! */    if (article_count <2)	return;    switch (sel_sort) {    case SS_DATE:    case SS_COUNT:	sort_procedure = artorder_date;	break;    case SS_SUBJECT:	sort_procedure = artorder_subject;	break;    case SS_AUTHOR:	sort_procedure = artorder_author;	break;    case SS_GROUPS:	sort_procedure = artorder_groups;	break;    }    if (sel_page_app)	sel_last_ap = *sel_page_app;    sel_page_app = 0;    qsort(artptr_list, article_count, sizeof (ARTICLE*), sort_procedure);}static long artptr_list_size = 0;static voidbuild_artptrs(){    ARTICLE **app, *ap;    long count = article_count;    int desired_flags = (sel_rereading? AF_READ : 0);    if (!artptr_list || artptr_list_size != count) {	artptr_list = (ARTICLE**)saferealloc((char*)artptr_list,		(MEM_SIZE)count * sizeof (ARTICLE*));	artptr_list_size = count;    }    for (app = artptr_list, ap = article_list; count; ap++) {	if ((ap->flags & (AF_MISSING|AF_READ)) == desired_flags) {	    *app++ = ap;	    count--;	}    }}

⌨️ 快捷键说明

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