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

📄 rt-page.c

📁 早期freebsd实现
💻 C
字号:
/* $Id: rt-page.c,v 3.0 1992/12/14 00:14:12 davison Trn $*/#include "EXTERN.h"#include "common.h"#include "cache.h"#include "term.h"#include "ngdata.h"#include "trn.h"#include "util.h"#include "rthread.h"#include "rt-select.h"#include "rt-util.h"#include "INTERN.h"#include "rt-page.h"extern char *display_mode;extern char sel_disp_char[];boolset_sel_mode(ch)char_int ch;{    switch (ch) {    case 'a':	set_selector(SM_ARTICLE, sel_artsort);	break;    case 's':	set_selector(SM_SUBJECT, sel_threadsort);	break;    case 't':	if (in_ng && !ThreadedGroup) {	    bool always_save = thread_always;	    ThreadedGroup = TRUE;	    thread_always = TRUE;	    if (sel_rereading)		firstart = absfirst;	    printf("\nThreading the group. "), fflush(stdout);	    thread_open();	    thread_always = always_save;	    if (last_cached < lastart)		ThreadedGroup = FALSE;	}	/* FALL THROUGH */    case 'T':	set_selector(SM_THREAD, sel_threadsort);	break;    default:	return FALSE;    }    return TRUE;}boolset_sel_sort(ch)char_int ch;{    if (isupper(ch)) {	sel_direction = -1;	ch = tolower(ch);    } else	sel_direction = 1;    switch (ch) {    case 'd':	sel_sort = SS_DATE;	break;    case 's':	sel_sort = SS_SUBJECT;	break;    case 'a':	sel_sort = SS_AUTHOR;	break;    case 'c':	sel_sort = SS_COUNT;	break;    case 'g':	sel_sort = SS_GROUPS;	break;    default:	return FALSE;    }    if (sel_mode == SM_ARTICLE)	set_selector(sel_mode, sel_sort);    else	set_selector(sel_threadmode, sel_sort);    return TRUE;}voidset_selector(smode, ssort)int smode;int ssort;{    sel_mode = smode;    sel_sort = ssort;    if (!ThreadedGroup && sel_mode == SM_THREAD)	sel_mode = SM_SUBJECT;    if (sel_mode == SM_ARTICLE) {	if (sel_sort == SS_COUNT)	    sel_sort = SS_DATE;    } else if (sel_sort == SS_AUTHOR || sel_sort == SS_GROUPS)	sel_sort = SS_DATE;    switch (sel_mode) {    case SM_THREAD:	sel_mode_string = "threads";	sel_threadmode = smode;	sel_threadsort = ssort;	break;    case SM_SUBJECT:	sel_mode_string = "subjects";	sel_threadmode = smode;	sel_threadsort = ssort;	break;    case SM_ARTICLE:	sel_mode_string = "articles";	sel_artsort = ssort;	break;    }    switch (sel_sort) {    case SS_DATE:	sel_sort_string = "date";	break;    case SS_SUBJECT:	sel_sort_string = "subject";	break;    case SS_AUTHOR:	sel_sort_string = "author";	break;    case SS_COUNT:	sel_sort_string = "count";	break;    case SS_GROUPS:	sel_sort_string = "SubjDate";	break;    }}voidinit_pages(){try_again:    sel_prior_arts = sel_total_arts = 0;    if (sel_mode == SM_ARTICLE) {	ARTICLE *ap, **app, **limit;	sort_articles();	while (sel_page_sp && sel_page_sp->misc == 0)	    sel_page_sp = sel_page_sp->next;	/* The artptr_list contains only unread or read articles, never both */	limit = artptr_list + article_count;	for (app = artptr_list; app < limit; app++) {	    ap = *app;	    if (sel_rereading && !(ap->flags & sel_mask))		ap->flags |= AF_DEL;	    if (sel_page_app == app	     || (!sel_page_app && ap->subj == sel_page_sp)) {		sel_page_app = app;		sel_prior_arts = sel_total_arts;	    }	    if (!sel_exclusive || (ap->flags & sel_mask)) {		sel_total_arts++;		ap->flags |= AF_INCLUDED;	    } else		ap->flags &= ~AF_INCLUDED;	}	if (sel_exclusive && !sel_total_arts) {	    sel_exclusive = FALSE;	    goto try_again;	}	if (!sel_page_app)	    (void) first_page();    } else {	SUBJECT *sp, *group_sp;	int group_arts;	sort_subjects();	for (sp = first_subject; sp; sp = sp->next) {	    if (sel_rereading && !(sp->flags & sel_mask))		sp->flags |= SF_DEL;	    group_sp = sp;	    group_arts = sp->misc;	    if (!sel_exclusive || (sp->flags & sel_mask))		sp->flags |= SF_INCLUDED;	    else		sp->flags &= ~SF_INCLUDED;	    if (sel_page_sp == group_sp)		sel_prior_arts = sel_total_arts;	    if (sel_mode == SM_THREAD) {		while (sp->next && sp->next->thread == sp->thread) {		    sp = sp->next;		    if (sp == sel_page_sp) {			sel_prior_arts = sel_total_arts;			sel_page_sp = group_sp;		    }		    sp->flags &= ~SF_INCLUDED;		    if (sp->flags & sel_mask)			group_sp->flags |= SF_INCLUDED;		    else if (sel_rereading)			sp->flags |= SF_DEL;		    group_arts += sp->misc;		}	    }	    if (group_sp->flags & SF_INCLUDED)		sel_total_arts += group_arts;	}	if (sel_exclusive && !sel_total_arts) {	    sel_exclusive = FALSE;	    goto try_again;	}	if (!sel_page_sp)	    (void) first_page();    }}boolfirst_page(){    sel_prior_arts = 0;    if (sel_mode == SM_ARTICLE) {	ARTICLE **app, **limit;	limit = artptr_list + article_count;	for (app = artptr_list; app < limit; app++) {	    if ((*app)->flags & AF_INCLUDED) {		if (sel_page_app != app) {		    sel_page_app = app;		    return TRUE;		}		break;	    }	}    } else {	SUBJECT *sp;	for (sp = first_subject; sp; sp = sp->next) {	    if (sp->flags & SF_INCLUDED) {		if (sel_page_sp != sp) {		    sel_page_sp = sp;		    return TRUE;		}		break;	    }	}    }    return FALSE;}boollast_page(){    sel_prior_arts = sel_total_arts;    if (sel_mode == SM_ARTICLE) {	ARTICLE **app = sel_page_app;	sel_page_app = artptr_list + article_count;	if (!prev_page())	    sel_page_app = app;	else if (app != sel_page_app)	    return TRUE;    } else {	SUBJECT *sp = sel_page_sp;	sel_page_sp = Nullsubj;	if (!prev_page())	    sel_page_sp = sp;	else if (sp != sel_page_sp)	    return TRUE;    }    return FALSE;}boolnext_page(){    if (sel_mode == SM_ARTICLE) {	if (sel_next_app < artptr_list + article_count) {	    sel_page_app = sel_next_app;	    sel_prior_arts += sel_page_arts;	    return TRUE;	}    } else {	if (sel_next_sp) {	    sel_page_sp = sel_next_sp;	    sel_prior_arts += sel_page_arts;	    return TRUE;	}    }    return FALSE;}boolprev_page(){    int item_cnt = 0;    /* Scan the items in reverse to go back a page */    if (sel_mode == SM_ARTICLE) {	ARTICLE *ap, **app, **page_app = sel_page_app;	for (app = sel_page_app; --app >= artptr_list; ) {	    ap = *app;	    if (ap->flags & AF_INCLUDED) {		page_app = app;		sel_prior_arts--;		if (++item_cnt >= sel_max_cnt)		    break;	    }	}	if (sel_page_app != page_app) {	    sel_page_app = page_app;	    return TRUE;	}    } else {	SUBJECT *sp, *page_sp = sel_page_sp;	int line_cnt, item_arts, line;	line = 2;	for (sp = (!page_sp? last_subject : page_sp->prev); sp; sp=sp->prev) {	    item_arts = sp->misc;	    if (sel_mode == SM_THREAD) {		while (sp->prev && sp->prev->thread == sp->thread) {		    sp = sp->prev;		    item_arts += sp->misc;		}		line_cnt = count_thread_lines(sp, NULL);	    } else		line_cnt = count_subject_lines(sp, NULL);	    if (!(sp->flags & SF_INCLUDED) || !line_cnt)		continue;	    if (line_cnt > LINES - 5)		line_cnt = LINES - 5;	    line += line_cnt;	    if (line > LINES - 3) {		sp = page_sp;		break;	    }	    sel_prior_arts -= item_arts;	    page_sp = sp;	    if (++item_cnt >= sel_max_cnt)		break;	}	if (sel_page_sp != page_sp) {	    sel_page_sp = (page_sp? page_sp : first_subject);	    return TRUE;	}    }    return FALSE;}voiddisplay_page(){    int sel;    sel_chars = getval("SELECTCHARS", SELECTCHARS);    sel_max_cnt = strlen(sel_chars);    if (sel_max_cnt > MAX_SEL)	sel_max_cnt = MAX_SEL;    if (sel_max_cnt > LINES-5)	sel_max_cnt = LINES-5;#ifndef CLEAREOL    clear();#else    if (can_home_clear) {	home_cursor();	maybe_eol();    } else	clear();#endif    carriage_return();#ifdef NOFIREWORKS    no_sofire();#endif    standout();    fputs(ngname, stdout);    un_standout();    printf("          %ld %sarticle%s", (long)sel_total_arts,	   sel_rereading? "read " : nullstr,	   article_count == 1 ? nullstr : "s");    if (sel_exclusive)	printf(" out of %ld", (long)article_count);    printf("%s\n", moderated);#ifdef CLEAREOL    maybe_eol();#endif    putchar('\n') FLUSH;try_again:    sel_line = 2;    sel_page_arts = 0;    sel_item_cnt = 0;    if (!sel_total_arts)	;    else if (sel_mode == SM_ARTICLE) {	ARTICLE *ap, **app, **limit;	limit = artptr_list + article_count;	app = sel_page_app;	do {	    ap = *app;	    if (ap == sel_last_ap)		sel_item_index = sel_item_cnt;	    if (!(ap->flags & AF_INCLUDED))		continue;	    sel = !!(ap->flags & sel_mask) + (ap->flags & AF_DEL);	    sel_items[sel_item_cnt].ptr = (void*)ap;	    sel_items[sel_item_cnt].line = sel_line;	    sel_items[sel_item_cnt].sel = sel;	    sel_page_arts++;	    /* Output the article, with optional author */	    display_article(ap, sel_chars[sel_item_cnt], sel);	    sel_item_cnt++;	} while (++app < limit && sel_item_cnt < sel_max_cnt);	if (!sel_page_arts) {	    if (last_page())		goto try_again;	}	sel_next_app = app;    } else {	SUBJECT *sp;	int line_cnt;	bool etc;	char ch;	sp = sel_page_sp;	do {	    if (sp == sel_last_sp)		sel_item_index = sel_item_cnt;	    etc = FALSE;	    if (sp->flags & SF_INCLUDED) {		/* Compute how many lines we need to display this group */		if (sel_mode == SM_THREAD)		    line_cnt = count_thread_lines(sp, &sel);		else		    line_cnt = count_subject_lines(sp, &sel);		if (line_cnt) {		    /* If this item is too long to fit on the screen all by		    ** itself, trim it to fit and set the "etc" flag.		    */		    if (line_cnt > LINES - 5) {			line_cnt = LINES - 5;			etc = TRUE;		    }		    /* If it doesn't fit, save it for the next page */		    if (sel_line + line_cnt > LINES - 3)			break;		    sel_items[sel_item_cnt].ptr = (void*)sp;		    sel_items[sel_item_cnt].line = sel_line;		    sel_items[sel_item_cnt].sel = sel;		    sel_page_arts += sp->misc;		    ch = sel_chars[sel_item_cnt];		    sel = sel_items[sel_item_cnt].sel;		    sel_item_cnt++;		    if (sp->misc) {			display_subject(sp, ch, sel);			ch = ' ';		    }		}	    } else		line_cnt = 0;	    if (sel_mode == SM_THREAD) {		while (sp->next && sp->next->thread == sp->thread) {		    sp = sp->next;		    if (!line_cnt || !sp->misc)			continue;		    if (sel_line < LINES - 3)			display_subject(sp, ch, sel);		    ch = ' ';		    sel_page_arts += sp->misc;		}	    }	    if (etc)		fputs("      ...etc.", stdout);	} while ((sp=sp->next)!=Nullsubj && !etc && sel_item_cnt<sel_max_cnt);	if (!sel_page_arts) {	    if (last_page())		goto try_again;	}	sel_next_sp = sp;    }    sel_last_line = sel_line+1;    sel_last_ap = Nullart;    sel_last_sp = Nullsubj;    sel_at_end = (sel_prior_arts + sel_page_arts == sel_total_arts);#ifdef CLEAREOL    maybe_eol();#endif    putchar('\n') FLUSH;}voidupdate_page(){    int sel;    int j;    for (j = 0; j < sel_item_cnt; j++) {	sel = sel_items[j].sel;	if (sel_mode == SM_ARTICLE) {	    ARTICLE *ap = (ARTICLE*)sel_items[j].ptr;	    if (sel == !!(ap->flags & sel_mask) + (ap->flags & AF_DEL))		continue;	} else {	    SUBJECT *sp = (SUBJECT*)sel_items[j].ptr;	    int real_sel;	    if (sel_mode == SM_THREAD)		(void) count_thread_lines(sp, &real_sel);	    else		(void) count_subject_lines(sp, &real_sel);	    if (sel == real_sel)		continue;	}	goto_line(sel_line, sel_items[j].line);	sel_line = sel_items[j].line;	sel_item_index = j;	output_sel(!sel);    }    if (++sel_item_index == sel_item_cnt)	sel_item_index = 0;}voidoutput_sel(sel)int sel;{    putchar(sel_chars[sel_item_index]);    putchar(sel_disp_char[sel]);    sel_items[sel_item_index].sel = sel;}/* Counts the number of lines needed to output a subject, including** optional authors.*/static intcount_subject_lines(subj, selptr)SUBJECT *subj;int *selptr;{    register ARTICLE *ap;    register int sel;    if (subj->flags & SF_DEL)	sel = 2;    else if (subj->flags & sel_mask) {	sel = 1;	for (ap = subj->articles; ap; ap = ap->subj_next) {	    if ((!(ap->flags&AF_READ) ^ sel_rereading)	      && !(ap->flags & sel_mask)) {		sel = 3;		break;	    }	}    } else	sel = 0;    if (selptr)	*selptr = sel;    if (*display_mode == 'l')	return subj->misc;    if (*display_mode == 'm')	return (subj->misc <= 4? subj->misc : (subj->misc - 4) / 3 + 4);    return (subj->misc != 0);}/* Counts the number of lines needed to output a thread, including** optional authors.*/static intcount_thread_lines(subj, selptr)SUBJECT *subj;int *selptr;{    register int total = 0;    register ARTICLE *thread = subj->thread;    int sel = -1, subj_sel;    do {	if (subj->misc) {	    total += count_subject_lines(subj, &subj_sel);	    if (sel < 0)		sel = subj_sel;	    else if (sel != subj_sel)		sel = 3;	}    } while ((subj = subj->next) != Nullsubj && subj->thread == thread);    if (selptr)	*selptr = (sel < 0? 0 : sel);    return total;}/* Display an article, perhaps with its author.*/static voiddisplay_article(ap, ch, sel)register ARTICLE *ap;char_int ch;int sel;{    int subj_width = COLS - 5;    int from_width = COLS / 5;#ifdef CLEAREOL    maybe_eol();#endif    if (subj_width < 32)	subj_width = 32;        putchar(ch);    putchar(sel_disp_char[sel]);    if (*display_mode == 's' || from_width < 8)	printf("  %s\n",compress_subj(ap->subj->articles,subj_width)) FLUSH;    else {	printf("%s  %s\n",	   compress_from(ap, from_width),	   compress_subj(ap, subj_width - from_width)) FLUSH;    }    sel_line++;}/* Display the given subject group, with optional authors.*/static voiddisplay_subject(subj, ch, sel)SUBJECT *subj;char_int ch;int sel;{    register ARTICLE *ap;    register int j, i;    int subj_width = COLS - 8;    int from_width = COLS / 5;#ifdef CLEAREOL    maybe_eol();#endif    if (subj_width < 32)	subj_width = 32;    j = subj->misc;    putchar(ch);    if (ch != ' ')	putchar(sel_disp_char[sel]);    else	putchar(' ');    if (*display_mode == 's' || from_width < 8)	printf("%3d  %s\n",j,compress_subj(subj->articles,subj_width)) FLUSH;    else {	/* Find the first unread article so we get the author right */	for (ap = subj->articles; ap; ap = ap->subj_next) {	    if (!(ap->flags&AF_READ) ^ sel_rereading)		break;	}	printf("%s%3d  %s\n",	   compress_from(ap, from_width), j,	   compress_subj(ap, subj_width - from_width)) FLUSH;	i = -1;	if (--j && ap) {	    for (ap = ap->subj_next; ap && j; ap = ap->subj_next) {		if (!(!(ap->flags&AF_READ) ^ sel_rereading))		    continue;		j--;		if (i < 0)		    i = 0;		else if (*display_mode == 'm') {		    if (!j) {			if (i)			    putchar('\n');		    } else {			if (i == 3 || !i) {			    if (i)				putchar('\n');			    if (++sel_line >= LINES - 3)				return;#ifdef CLEAREOL			    maybe_eol();#endif			    i = 1;			} else			    i++;			printf("  %s      ",			       compress_from(ap, from_width)) FLUSH;			continue;		    }		}		if (++sel_line >= LINES - 3)		    return;#ifdef CLEAREOL		maybe_eol();#endif		printf("  %s\n", compress_from(ap, from_width)) FLUSH;	    }	}    }    sel_line++;}

⌨️ 快捷键说明

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