📄 rthread.c
字号:
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 + -