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

📄 rthread.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/* $Id: rthread.c,v 3.0 1992/12/14 00:14:13 davison Trn $*/#include "EXTERN.h"#include "common.h"#include "intrp.h"#include "trn.h"#include "cache.h"#include "bits.h"#include "ng.h"#include "rcln.h"#include "search.h"#include "artstate.h"#include "rcstuff.h"#include "ngdata.h"#include "kfile.h"#include "head.h"#include "util.h"#include "hash.h"#include "nntp.h"#include "rt-mt.h"#include "rt-ov.h"#include "rt-page.h"#include "rt-process.h"#include "rt-select.h"#include "rt-wumpus.h"#include "INTERN.h"#include "rthread.h"HASHTABLE *msgid_hash = 0;bool try_ov = FALSE;bool try_mt = FALSE;voidthread_init(){#ifdef USE_OV    try_ov = ov_init();#endif#ifdef USE_MT    try_mt = mt_init();#endif}/* Generate the thread data we need for this group.  We must call** thread_close() before calling this again.*/voidthread_open(){    if (!msgid_hash)	msgid_hash = hashcreate(201, msgid_cmp); /*TODO: pick a better size */    if (ThreadedGroup) {	/* Parse input and use msgid_hash for quick article lookups. */	/* If cached but not threaded articles exist, set up to thread them. */	if (first_subject) {	    first_cached = firstart;	    last_cached = firstart - 1;	    parsed_art = 0;	}    }    if (sel_mode == SM_ARTICLE)	set_selector(sel_mode, sel_artsort);    else	set_selector(sel_threadmode, sel_threadsort);#ifdef USE_MT    if (try_mt && !first_subject)	if (!mt_data())	    return;#endif#ifdef USE_OV    if (try_ov && first_cached > last_cached)	if (thread_always)	    (void) ov_data(absfirst, lastart, FALSE);	else if (firstart > lastart) {	    /* If no unread articles, see if ov. exists as quick as possible */	    (void) ov_data(absfirst, absfirst, FALSE);	    first_cached = last_cached+1;	} else	    (void) ov_data(firstart, lastart, FALSE);#endif#ifdef USE_NNTP    if (!ov_opened)	setmissingbits();#endif    if (last_cached > lastart) {	toread[ng] += (ART_UNREAD)(last_cached-lastart);	/* ensure getngsize() knows the new maximum */	ngmax[ng] = lastart = last_cached;    }    thread_grow();	/* thread any new articles not yet in the database */    added_articles = 0;    sel_page_sp = 0;    sel_page_app = 0;}/* Update the group's thread info.*/voidthread_grow(){    added_articles = lastart - last_cached;    if (added_articles > 0 && thread_always)	cache_range(last_cached + 1, lastart);    count_subjects(CS_NORM);    if (artptr_list)	sort_articles();    else	sort_subjects();}static voidkill_tmp_arts(data, extra)HASHDATUM *data;int extra;{    register ARTICLE *ap = (ARTICLE*)data->dat_ptr;    if (ap)	free((char*)ap);}voidthread_close(){    curr_artp = artp = Nullart;    init_tree();			/* free any tree lines */    if (msgid_hash) {	hashwalk(msgid_hash, kill_tmp_arts, 0);	hashdestroy(msgid_hash);	msgid_hash = 0;    }    sel_page_sp = 0;    sel_page_app = 0;    sel_last_ap = 0;    sel_last_sp = 0;    selected_only = FALSE;#ifdef USE_OV    ov_close();#endif}ARTICLE *find_article(artnum)ART_NUM artnum;{    if (artp && (artp->flags & AF_TMPMEM) == AF_TMPMEM && !artnum)	return artp;    if (artnum < absfirst || artnum > lastart)	return (artp = Nullart);    return (artp = article_ptr(artnum));}voidtop_article(){    art = lastart+1;    artp = Nullart;    inc_art(selected_only, FALSE);}ARTICLE *first_art(sp)register SUBJECT *sp;{    register ARTICLE *ap = (ThreadedGroup? sp->thread : sp->articles);    if (ap && (ap->flags & AF_MISSING))	ap = next_art(ap);    return ap;}ARTICLE *last_art(sp)register SUBJECT *sp;{    register ARTICLE *ap;    if (!ThreadedGroup) {	ap = sp->articles;	while (ap->subj_next)	    ap = ap->subj_next;	return ap;    }    ap = sp->thread;    if (ap) {	for (;;) {	    if (ap->sibling)		ap = ap->sibling;	    else if (ap->child1)		ap = ap->child1;	    else		break;	}	if (ap->flags & AF_MISSING)	    ap = prev_art(ap);    }    return ap;}/* Bump art/artp to the next article, wrapping from thread to thread.** If sel_flag is TRUE, only stops at selected articles.** If rereading is FALSE, only stops at unread articles.*/voidinc_art(sel_flag, rereading)bool_int sel_flag, rereading;{    register ARTICLE *ap = artp;    int subj_mask = (sel_mode == SM_THREAD? (SF_THREAD|SF_VISIT) : SF_VISIT);    /* Use the explicit article-order if it exists */    if (artptr_list) {	ARTICLE **limit = artptr_list + article_count;	if (!ap)	    artptr = artptr_list-1;	else if (!artptr || *artptr != ap) {	    for (artptr = artptr_list; artptr < limit; artptr++) {		if (*artptr == ap)		    break;	    }	}	do {	    if (++artptr >= limit)		break;	    ap = *artptr;	} while ((!rereading && (ap->flags & AF_READ))	      || (sel_flag && !(ap->flags & AF_SEL)));	if (artptr < limit) {	    artp = *artptr;	    art = article_num(artp);	} else {	    artp = Nullart;	    art = lastart+1;	    artptr = artptr_list;	}	return;    }    /* Use subject- or thread-order when possible */    if (ThreadedGroup || srchahead) {	register SUBJECT *sp;	bool try_this_group_again = !rereading;	if (ap)	    sp = ap->subj;	else	    for (sp = first_subject; sp && (sp->flags&subj_mask) != subj_mask;)		sp = sp->next;	if (!sp)	    goto num_inc;	do {	    if (ap)		ap = next_art(ap);	    else		ap = first_art(sp);	    while (!ap) {		if (try_this_group_again)		    try_this_group_again = FALSE;		else {		    while ((sp = sp->next) != Nullsubj		        && (sp->flags & subj_mask) != subj_mask)			;		    if (!sp)			break;		}		ap = first_art(sp);	    }	} while (ap && ((!rereading && (ap->flags & AF_READ))		     || (sel_flag && !(ap->flags & AF_SEL))));	if ((artp = ap) != Nullart)	    art = article_num(ap);	else	    art = lastart+1;	return;    }    /* Otherwise, just increment through the art numbers */  num_inc:    if (!ap) {	art = firstart-1;	ap = article_ptr(art);    }    do {	if (++art > lastart) {	    ap = Nullart;	    break;	}	ap++;    } while ((!rereading && (ap->flags & AF_READ))	  || (sel_flag && !(ap->flags & AF_SEL))	  || (ap->flags & AF_MISSING));    artp = ap;}/* Bump art/artp to the previous article, wrapping from thread to thread.** If sel_flag is TRUE, only stops at selected articles.** If rereading is FALSE, only stops at unread articles.*/voiddec_art(sel_flag, rereading)bool_int sel_flag, rereading;{    register ARTICLE *ap = artp;    int subj_mask = (sel_mode == SM_THREAD? (SF_THREAD|SF_VISIT) : SF_VISIT);    /* Use the explicit article-order if it exists */    if (artptr_list) {	ARTICLE **limit = artptr_list + article_count;	if (!ap)	    artptr = limit;	else if (!artptr || *artptr != ap) {	    for (artptr = artptr_list; artptr < limit; artptr++) {		if (*artptr == ap)		    break;	    }	}	do {	    if (artptr == artptr_list)		break;	    ap = *--artptr;	} while ((!rereading && (ap->flags & AF_READ))	      || (sel_flag && !(ap->flags & AF_SEL)));	artp = *artptr;	art = article_num(artp);	return;    }    /* Use subject- or thread-order when possible */    if (ThreadedGroup || srchahead) {	register SUBJECT *sp;	if (ap)	    sp = ap->subj;	else	    for (sp = last_subject; sp && (sp->flags&subj_mask) != subj_mask;)		sp = sp->prev;	if (!sp)	    goto num_dec;	do {	    if (ap)		ap = prev_art(ap);	    else		ap = last_art(sp);	    while (!ap) {		while ((sp = sp->prev) != Nullsubj		    && (sp->flags & subj_mask) != subj_mask)		    ;		if (!sp)		    break;		ap = last_art(sp);	    }	} while (ap && ((!rereading && (ap->flags & AF_READ))		     || (sel_flag && !(ap->flags & AF_SEL))));	if ((artp = ap) != Nullart)	    art = article_num(ap);	else	    art = absfirst-1;	return;    }    /* Otherwise, just decrement through the art numbers */  num_dec:    ap = article_ptr(art);    do {	if (--art < absfirst) {	    ap = Nullart;	    break;	}	ap--;    } while ((!rereading && (ap->flags & AF_READ))	  || (sel_flag && !(ap->flags & AF_SEL))	  || (ap->flags & AF_MISSING));    artp = ap;}/* Bump the param to the next article in depth-first order.*/ARTICLE *bump_art(ap)register ARTICLE *ap;{    if (ap->child1)	return ap->child1;    while (!ap->sibling) {	if (!(ap = ap->parent))	    return Nullart;    }    return ap->sibling;}/* Bump the param to the next REAL article.  Uses subject order in a** non-threaded group; honors the breadth_first flag in a threaded one.*/ARTICLE *next_art(ap)register ARTICLE *ap;{try_again:    if (!ThreadedGroup) {	ap = ap->subj_next;	goto done;    }    if (breadth_first) {	if (ap->sibling) {	    ap = ap->sibling;	    goto done;	}	if (ap->parent)	    ap = ap->parent->child1;	else	    ap = ap->subj->thread;    }    do {	if (ap->child1) {	    ap = ap->child1;	    goto done;	}	while (!ap->sibling) {	    if (!(ap = ap->parent))		return Nullart;	}	ap = ap->sibling;    } while (breadth_first);done:    if (ap && (ap->flags & AF_MISSING))	goto try_again;    return ap;}/* Bump the param to the previous REAL article.  Uses subject order in a** non-threaded group.*/ARTICLE *prev_art(ap)register ARTICLE *ap;{    register ARTICLE *initial_ap;try_again:    initial_ap = ap;    if (!ThreadedGroup) {	if ((ap = ap->subj->articles) == initial_ap)	    ap = Nullart;	else	    while (ap->subj_next != initial_ap)		ap = ap->subj_next;	goto done;    }    ap = (ap->parent ? ap->parent->child1 : ap->subj->thread);    if (ap == initial_ap) {	ap = ap->parent;	goto done;    }    while (ap->sibling != initial_ap)	ap = ap->sibling;    while (ap->child1) {	ap = ap->child1;	while (ap->sibling)	    ap = ap->sibling;    }done:    if (ap && (ap->flags & AF_MISSING))	goto try_again;    return ap;}/* Find the next art/artp with the same subject as this one.  Returns** FALSE if no such article exists.*/boolnext_art_with_subj(){    register ARTICLE *ap = artp;    register SUBJECT *sp;    bool try_this_subj_again = TRUE;    if (!ap)	return FALSE;    sp = ap->subj;    do {	ap = ap->subj_next;	if (!ap) {	    if (try_this_subj_again) {		ap = sp->articles;		try_this_subj_again = FALSE;	    } else {		if (!art)		    art = firstart;		return FALSE;	    }	}    } while ((ap->flags & (AF_READ|AF_MISSING))	  || (selected_only && !(ap->flags & AF_SEL)));    artp = ap;    art = article_num(ap);#ifdef ARTSEARCH    srchahead = -1;#endif    return TRUE;}/* Find the previous art/artp with the same subject as this one.  Returns** FALSE if no such article exists.*/

⌨️ 快捷键说明

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