home *** CD-ROM | disk | FTP | other *** search
- /* $Header: rt-select.c,v 4.3.3.3 91/01/16 03:28:50 davison Trn $
- **
- ** $Log: rt-select.c,v $
- ** Revision 4.3.3.3 91/01/16 03:28:50 davison
- ** Changed %d --> %ld.
- ** Changed some expressions to registers to bypass a compiler problem.
- **
- ** Revision 4.3.3.2 90/08/20 18:32:33 davison
- ** Reset scan_all_roots while selecting.
- **
- ** Revision 4.3.3.1 90/07/24 22:04:07 davison
- ** Initial Trn Release
- **
- */
-
- #include "EXTERN.h"
- #include "common.h"
- #include "rn.h"
- #include "rcstuff.h"
- #include "term.h"
- #include "final.h"
- #include "util.h"
- #include "help.h"
- #include "bits.h"
- #include "artsrch.h"
- #include "ng.h"
- #include "ngstuff.h"
- #include "rthreads.h"
-
- #ifdef USETHREADS
-
- static int count_subj_lines();
- static void display_subj();
-
- /* When display mode is 'l', each author gets a separate line; when 'm', up to
- ** three authors share a line; when 's', no authors are displayed.
- */
- static char *display_mode = select_order;
- static ART_NUM article_count;
- static int author_line;
- static char first_two_chars[3] = { ' ', ' ', '\0' }, mask = 1;
-
- #define MAX_SEL 64
-
- /* Display a menu of roots for the user to choose from. If cmd is '+'
- ** we display all the unread roots and allow the user to mark roots as
- ** selected and perform various commands upon the articles. If cmd is
- ** 'U' we display all the previously read roots and allow the user to
- ** select which ones should be marked as unread.
- */
- char
- select_thread( cmd )
- char cmd;
- {
- register int i, j, cnt;
- ART_NUM art_hold = art;
- int line_cnt, screen_line, subj_line_cnt;
- int cur_root, page_root, last_root = -1;
- ART_LINE running_total, last_running;
- int last_line, got_dash;
- int max_root;
- int first, last;
- int root_line[MAX_SEL], root_hold[MAX_SEL];
- int ch, action;
- char page_char, end_char;
- char promptbuf[80];
- bool etc, clean_screen, empty_ok, displayed_status;
- char oldmode = mode;
- #ifndef CONDSUB
- char tmpbuf[2];
- #endif
- char *select_chars, *in_select;
- int max_cnt;
-
- mode = 't';
- unread_selector = (cmd == 'U');
- clear_on_stop = TRUE;
- empty_ok = FALSE;
-
- select_threads:
- /* Setup for selecting articles to read or set unread */
- scan_all_roots = FALSE;
- if( unread_selector ) {
- page_char = '>';
- end_char = 'Z';
- page_root = 0;
- last_root = -1;
- cmd = 0;
- } else {
- page_char = page_select;
- end_char = end_select;
- page_root = select_page;
- if( curr_p_art ) {
- last_root = curr_p_art->root;
- }
- }
- mask = unread_selector+1;
-
- /* Leave empty roots selected for a short time to give them a chance
- ** to 'q' out of the selector if they got here by mistake.
- */
- max_root = count_roots( FALSE );
-
- /* If nothing to display, we're done. */
- if( !article_count && !empty_ok ) {
- all_empty:
- clear_on_stop = FALSE;
- mode = oldmode;
- putchar( '\n' );
- if( unread_selector ) {
- #ifdef VERBOSE
- IF(verbose)
- fputs( "\nNo articles to set unread.\n", stdout );
- ELSE
- #endif
- #ifdef TERSE
- fputs( "\nNo articles.\n", stdout ) FLUSH;
- #endif
- unread_selector = 0;
- mask = 1;
- } else {
- #ifdef VERBOSE
- IF(verbose)
- fputs( "\nNo unread articles to select.\n", stdout );
- ELSE
- #endif
- #ifdef TERSE
- fputs( "\nNo articles.\n", stdout ); /* let "them" FLUSH */
- #endif
- }
- (void) count_roots( TRUE );
- art = art_hold;
- p_art = curr_p_art;
- return 'q';
- }
- if( unread_selector ) {
- for( j = 0; j < total.root; j++ ) {
- selected_roots[j] |= 4;
- }
- }
- if( page_root >= max_root ) {
- ch = '<';
- } else {
- ch = '>';
- }
- cur_root = 0;
- running_total = 0;
- for( i = 0; i < page_root; i++ ) {
- running_total += root_article_cnts[i];
- }
- do {
- select_chars = getval( "SELECTCHARS", SELECTCHARS );
- max_cnt = strlen( select_chars );
- if( max_cnt > MAX_SEL ) {
- max_cnt = MAX_SEL;
- }
- if( ch == '<' && i ) {
- screen_line = 2;
- cnt = 0;
- /* Scan the roots in reverse to go back a page */
- do {
- if( !root_article_cnts[--i] ) {
- continue;
- }
- first = root_subjects[i];
- last = first + p_roots[i].subject_cnt;
- line_cnt = 0;
- for( j = first; j < last; j++ ) {
- line_cnt += count_subj_lines( i, j );
- }
- if( line_cnt > LINES - 5 ) {
- line_cnt = LINES - 5;
- }
- screen_line += line_cnt;
- if( screen_line > LINES - 3 ) {
- i++;
- break;
- }
- running_total -= root_article_cnts[i];
- cnt++;
- } while( i > 0 && cnt < max_cnt );
- }
-
- /* Present a page of subjects to the user */
- #ifndef CLEAREOL
- clear();
- #else
- if( can_home_clear ) {
- home_cursor();
- maybe_eol();
- } else {
- clear();
- }
- #endif
- carriage_return();
- page_root = i;
- last_running = running_total;
- #ifdef NOFIREWORKS
- no_sofire();
- #endif
- standout();
- fputs( ngname, stdout );
- un_standout();
- printf( "\t\t\t\t%ld %sarticle%s\n", (long)article_count,
- unread_selector? "read " : nullstr,
- article_count == 1 ? nullstr : "s" );
- #ifdef CLEAREOL
- maybe_eol();
- #endif
- putchar( '\n' ) FLUSH;
- screen_line = 2;
- for( cnt = 0; i < max_root && cnt < max_cnt; i++ ) {
- if( last_root == i ) {
- cur_root = cnt;
- }
- /* Check each root for articles to list */
- if( !root_article_cnts[i] ) {
- continue;
- }
- first = root_subjects[i];
- last = first + p_roots[i].subject_cnt;
-
- /* Compute how many lines we need to display the subjects/authors */
- etc = FALSE;
- line_cnt = 0;
- for( j = first; j < last; j++ ) {
- subj_line_cnt = count_subj_lines( i, j );
- line_cnt += subj_line_cnt;
- /* If this root 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 ) {
- last = j;
- line_cnt -= subj_line_cnt;
- if( line_cnt != LINES - 5 ) {
- last++;
- line_cnt = LINES - 5;
- }
- if( screen_line == 2 ) {
- etc = TRUE;
- }
- break;
- }
- }
- /* If it doesn't fit, save it for the next page */
- if( screen_line + line_cnt > LINES - 3 ) {
- break;
- }
- /* Output the subjects, with optional authors */
- root_line[cnt] = screen_line;
- running_total += root_article_cnts[i];
- first_two_chars[0] = select_chars[cnt];
- first_two_chars[1] = (selected_roots[i] & 4) ? '-' :
- (selected_roots[i] & mask) ? '+' : ' ';
- author_line = screen_line;
- for( j = first; j < last; j++ ) {
- display_subj( i, j );
- }
- screen_line += line_cnt;
- root_hold[cnt++] = i;
- if( etc ) {
- fputs( " ...etc.", stdout );
- i++;
- break;
- }
- }/* for */
- last_root = -1;
- if( cur_root && cur_root >= cnt ) {
- cur_root = cnt - 1;
- }
-
- /* Check if there is really anything left to display. */
- if( !running_total && !empty_ok ) {
- goto all_empty;
- }
- empty_ok = FALSE;
-
- last_line = screen_line+1;
- #ifdef CLEAREOL
- maybe_eol();
- #endif
- putchar( '\n' ) FLUSH;
- /* Prompt the user */
- strcpy( promptbuf, "-- Select threads -- " );
- if( i != max_root ) {
- sprintf( promptbuf+21, "%s%ld%% [%c%c] --",
- (!page_root? "Top " : nullstr),
- (long)(running_total*100 / article_count),
- page_char, end_char );
- } else {
- sprintf( promptbuf+21, "%s [%c%c] --",
- (!page_root? "All" : "Bot"), end_char, page_char );
- }
- if( cur_root > cnt ) {
- cur_root = 0;
- }
- screen_line = root_line[cur_root];
- #ifdef CLEAREOL
- if( erase_screen && can_home_clear ) {
- clear_rest();
- }
- #endif
- displayed_status = FALSE;
- prompt_select:
- standout();
- fputs( promptbuf, stdout );
- un_standout();
- if( can_home ) {
- carriage_return();
- goto_line( last_line, screen_line );
- }
- got_dash = 0;
- /* Grab some commands from the user */
- for( ;; ) {
- fflush(stdout);
- eat_typeahead();
- #ifdef CONDSUB
- getcmd( buf );
- ch = *buf;
- #else
- getcmd( tmpbuf ); /* If no conditionals, don't allow macros */
- ch = *tmpbuf;
- buf[0] = ch;
- buf[1] = FINISHCMD;
- #endif
- in_select = index( select_chars, ch );
- /* Plaster any inherited empty roots on first command, if not q. */
- if( cmd && (in_select || (ch != '\033' && ch != 'q')) ) {
- max_root = count_roots( TRUE );
- cmd = 0;
- }
- if( displayed_status && can_home ) {
- goto_line( screen_line, last_line+1 );
- erase_eol();
- screen_line = last_line+1;
- displayed_status = FALSE;
- }
- if( ch == '-' ) {
- got_dash = 1;
- if( !can_home ) {
- putchar( '-' );
- fflush( stdout );
- }
- continue;
- }
- if( ch == ' ' ) {
- if( i == max_root ) {
- ch = end_char;
- } else {
- ch = page_char;
- }
- }
- if( !in_select && (index( "<>^$!?&:/hDJLNqQUXZ\n\r\t\033", ch )
- || ch == Ctl('l') || ch == Ctl('r') || ch == Ctl('k')) ) {
- break;
- }
- if( in_select ) {
- j = in_select - select_chars;
- if( j >= cnt ) {
- dingaling();
- j = -1;
- } else if( got_dash ) {
- ;
- } else if( selected_roots[root_hold[j]] & mask ) {
- action = (unread_selector ? 'k' : '-');
- } else {
- action = '+';
- }
- } else if( ch == 'y' || ch == '.' ) {
- j = cur_root;
- if( selected_roots[root_hold[j]] & mask ) {
- action = (unread_selector ? 'k' : '-');
- } else {
- action = '+';
- }
- } else if( ch == 'k' || ch == 'j' || ch == ',' ) {
- j = cur_root;
- action = 'k';
- } else if( ch == 'm' || ch == '\\' ) {
- j = cur_root;
- action = 'm';
- } else if( ch == '@' ) {
- cur_root = 0;
- j = cnt-1;
- got_dash = 1;
- action = '@';
- } else if( ch == '[' || ch == 'p' ) {
- if( --cur_root < 0 ) {
- cur_root = cnt ? cnt-1 : 0;
- }
- j = -1;
- } else if( ch == ']' || ch == 'n' ) {
- if( ++cur_root >= cnt ) {
- cur_root = 0;
- }
- j = -1;
- } else {
- if( can_home ) {
- goto_line( screen_line, last_line+1 );
- screen_line = last_line+1;
- } else {
- putchar( '\n' );
- }
- printf( "Type ? for help." );
- settle_down();
- displayed_status = TRUE;
-
- if( can_home ) {
- carriage_return();
- } else {
- putchar( '\n' );
- }
- j = -1;
- }
- if( j >= 0 ) {
- if( !got_dash ) {
- cur_root = j;
- } else {
- got_dash = 0;
- if( j < cur_root ) {
- ch = cur_root-1;
- cur_root = j;
- j = ch;
- }
- }
- if( ++j == cnt ) {
- j = 0;
- }
- do {
- register int r;
- register char maskr = mask;
- r = root_hold[cur_root];
- if( can_home ) {
- goto_line( screen_line, root_line[cur_root] );
- screen_line = root_line[cur_root];
- }
- putchar( select_chars[cur_root] );
- if( action == '@' ) {
- if( selected_roots[r] & 4 ) {
- ch = (unread_selector ? '+' : ' ');
- } else if( unread_selector ) {
- ch = 'k';
- } else
- if( selected_roots[r] & maskr ) {
- ch = '-';
- } else {
- ch = '+';
- }
- } else {
- ch = action;
- }
- switch( ch ) {
- case '+':
- if( !(selected_roots[r] & maskr) ) {
- selected_roots[r] |= maskr;
- selected_root_cnt++;
- selected_count += root_article_cnts[r];
- putchar( '+' );
- }
- /* FALL THROUGH */
- case 'm':
- if( selected_roots[r] & 4 ) {
- selected_roots[r] &= ~4;
- if( ch == 'm' ) {
- putchar( ' ' );
- }
- } else if( ch == 'm' ) {
- goto unsel;
- }
- break;
- case 'k':
- if( !(selected_roots[r] & 4) ) {
- selected_roots[r] |= 4;
- putchar( '-' );
- }
- /* FALL THROUGH */
- case '-':
- unsel:
- if( selected_roots[r] & maskr ) {
- selected_roots[r] &= ~maskr;
- selected_root_cnt--;
- selected_count -= root_article_cnts[r];
- if( ch != 'k' ) {
- putchar( ' ' );
- }
- }
- break;
- }
- fflush( stdout );
- if( ++cur_root == cnt ) {
- cur_root = 0;
- }
- if( can_home ) {
- carriage_return();
- }
- } while( cur_root != j );
- } else {
- got_dash = FALSE;
- }
- if( can_home ) {
- goto_line( screen_line, root_line[cur_root] );
- screen_line = root_line[cur_root];
- }
- }/* for */
- if( can_home) {
- goto_line( screen_line, last_line );
- }
- clean_screen = TRUE;
- do_command:
- if( ch == 'L' ) {
- if( !*++display_mode ) {
- display_mode = select_order;
- }
- ch = Ctl('l');
- cur_root = 0;
- } else if( ch == '$' ) {
- ch = '<';
- page_root = max_root;
- last_running = article_count;
- cur_root = 0;
- } else if( ch == '^' || ch == Ctl('r') ) {
- ch = '>';
- i = 0;
- running_total = 0;
- cur_root = 0;
- } else if( ch == 'h' || ch == '?' ) {
- putchar( '\n' );
- if( (ch = help_select()) || (ch = pause_getcmd()) ) {
- goto got_cmd;
- }
- ch = Ctl('l');
- } else if( index( ":/&!", ch ) ) {
- erase_eol(); /* erase the prompt */
- if( !finish_command( TRUE ) ) { /* get rest of command */
- if( clean_screen ) {
- screen_line = root_line[cur_root];
- goto prompt_select;
- }
- goto extend_done;
- }
- if( ch == '&' || ch == '!' ) {
- one_command = TRUE;
- perform( buf, FALSE );
- one_command = FALSE;
-
- putchar( '\n' ) FLUSH;
- clean_screen = FALSE;
- } else {
- int selected_save = selected_root_cnt;
-
- if( ch == ':' ) {
- clean_screen = (use_selected() == 2) && clean_screen;
- } else {
- /* Force the search to begin at absfirst or firstart,
- ** depending upon whether they specified the 'r' option.
- */
- art = lastart+1;
- page_line = 1;
- switch( art_search( buf, sizeof buf, FALSE ) ) {
- case SRCH_ERROR:
- case SRCH_ABORT:
- case SRCH_INTR:
- fputs( "\nInterrupted\n", stdout ) FLUSH;
- break;
- case SRCH_DONE:
- case SRCH_SUBJDONE:
- fputs( "Done\n", stdout ) FLUSH;
- break;
- case SRCH_NOTFOUND:
- fputs( "\nNot found.\n", stdout ) FLUSH;
- break;
- case SRCH_FOUND:
- break;
- }
- clean_screen = FALSE;
- }
- /* Recount, in case something has changed. */
- max_root = count_roots( !unread_selector );
-
- if( (selected_save -= selected_root_cnt) != 0 ) {
- putchar( '\n' );
- if( selected_save < 0 ) {
- fputs( "S", stdout );
- selected_save *= -1;
- } else {
- fputs( "Des", stdout );
- }
- printf( "elected %d thread%s.", selected_save,
- selected_save == 1 ? nullstr : "s" );
- clean_screen = FALSE;
- }
- if( !clean_screen ) {
- putchar('\n') FLUSH;
- }
- }/* if !& or :/ */
-
- if( clean_screen ) {
- carriage_return();
- up_line();
- erase_eol();
- screen_line = root_line[cur_root];
- goto prompt_select;
- }
- extend_done:
- if( (ch = pause_getcmd()) ) {
- got_cmd:
- if( ch > 0 ) {
- /* try to optimize the screen update for some commands. */
- if( !index( select_chars, ch )
- && (index( "<>^$!?&:/hDJLNqQUXZ\n\r\t\033", ch )
- || ch == Ctl('k')) ) {
- buf[0] = ch;
- buf[1] = FINISHCMD;
- goto do_command;
- }
- pushchar( ch | 0200 );
- }
- }
- ch = Ctl('l');
- } else if( ch == Ctl('k') ) {
- edit_kfile();
- ch = Ctl('l');
- } else if( !unread_selector && (ch == 'X' || ch == 'D' || ch == 'J') ) {
- if( ch == 'D' ) {
- j = page_root;
- last = i;
- } else {
- j = 0;
- last = max_root;
- }
- for( ; j < last; j++ ) {
- if( (!(selected_roots[j] & 1) ^ (ch == 'J'))
- && (cnt = root_article_cnts[j]) ) {
- p_art = p_articles + p_roots[j].articles;
- art = 0;
- follow_thread( 'J' );
- }
- }
- max_root = count_roots( TRUE );
- if( article_count
- && (ch == 'J' || (ch == 'D' && !selected_root_cnt)) ) {
- ch = Ctl('l');
- cur_root = 0;
- } else {
- break;
- }
- } else if( ch == 'J' ) {
- for( j = 0; j < max_root; j++ ) {
- selected_roots[j] = (selected_roots[j] & ~2) | 4;
- }
- selected_root_cnt = selected_count = 0;
- ch = Ctl('l');
- }
- if( ch == '>' ) {
- cur_root = 0;
- } else if( ch == '<' || (page_root && page_root >= max_root) ) {
- cur_root = 0;
- running_total = last_running;
- if( !(i = page_root) || !max_root ) {
- ch = '>';
- } else {
- ch = '<';
- }
- } else if( ch == Ctl('l') ) {
- i = page_root;
- running_total = last_running;
- ch = '>';
- } else if( ch == '\r' || ch == '\n' ) {
- if( !selected_root_cnt ) {
- register r = root_hold[cur_root];
- selected_roots[r] = mask;
- selected_root_cnt++;
- selected_count += root_article_cnts[r];
- }
- }
- } while( (ch == '>' && i < max_root) || ch == '<' );
- putchar( '\n' ) FLUSH;
-
- if( unread_selector ) {
- /* Turn selections into unread selected roots. Let count_roots()
- ** fix the counts after we're through.
- */
- last_root = -1;
- for( j = 0; j < total.root; j++ ) {
- if( !(selected_roots[j] & 4) ) {
- if( selected_roots[j] & 2 ) {
- selected_roots[j] = 1;
- }
- p_art = p_articles + p_roots[j].articles;
- art = 0;
- follow_thread( 'u' );
- } else {
- selected_roots[j] &= ~4;
- }
- }
- } else {
- select_page = page_root;
- for( j = 0; j < total.root; j++ ) {
- if( selected_roots[j] & 4 ) {
- selected_roots[j] = 0;
- p_art = p_articles + p_roots[j].articles;
- art = 0;
- follow_thread( 'J' );
- }
- }
- }
- if( ch == 'U' ) {
- unread_selector = !unread_selector;
- empty_ok = TRUE;
- goto select_threads;
- }
-
- if( unread_selector ) {
- unread_selector = 0;
- mask = 1;
- (void) count_roots( FALSE );
- }
- if( ch == '\033' || Ctl(ch) == Ctl('q') ) {
- ch = (ch == 'Q' ? 'Q' : 'q');
- art = art_hold;
- p_art = curr_p_art;
- } else if( ch == 'N' ) {
- art = art_hold;
- p_art = curr_p_art;
- } else {
- first_art();
- }
- clear_on_stop = FALSE;
- mode = oldmode;
- return ch;
- }
-
- static int author_cnt, first_author;
-
- /* Counts the number of lines needed to output a subject, including optional
- ** authors.
- */
- static int
- count_subj_lines( root, subj )
- int root;
- int subj;
- {
- PACKED_ARTICLE *artp, *root_limit;
- int author_subj;
-
- author_cnt = 0;
- author_subj = subj;
- first_author = -1;
-
- if( !subject_cnts[subj] ) {
- return 0;
- }
- if( *display_mode == 's' ) { /* no-author mode takes one line */
- return ++author_cnt;
- }
- bzero( author_cnts, total.author * sizeof (WORD) );
-
- /* Count authors associated with this subject. Increments author_cnts. */
- artp = p_articles + p_roots[root].articles;
- root_limit = upper_limit( artp, FALSE );
- for( ; artp != root_limit; artp++ ) {
- if( artp->subject == author_subj
- && (!was_read( artp->num ) ^ unread_selector) ) {
- if( artp->author < 0 || artp->author >= total.author ) {
- printf( "\
- Found invalid author (%d) with valid subject (%d)! [%ld]\n",
- artp->author, artp->subject, artp->num );
- artp->author = 0;
- } else {
- if( first_author < 0 ) {
- first_author = artp->author;
- }
- if( !author_cnts[artp->author]++ ) {
- author_cnt++;
- }
- }
- }
- }
-
- if( *display_mode == 'm' ) {
- return (author_cnt+4)/3;
- } else {
- return author_cnt;
- }
- }
-
- static void
- display_subj( root, subj )
- int root;
- int subj;
- {
- PACKED_ARTICLE *artp, *root_limit;
- char *str;
-
- count_subj_lines( root, subj );
- if( !author_cnt ) {
- return;
- }
- artp = p_articles + p_roots[root].articles;
- if( artp->subject != -1 && (artp->flags & ROOT_ARTICLE)
- && (!was_read(artp->num) ^ unread_selector) ) {
- str = nullstr;
- } else {
- str = ">";
- }
- #ifdef CLEAREOL
- maybe_eol();
- #endif
- if( *display_mode == 's' ) {
- printf( "%s%3d %s%.71s\n", first_two_chars,
- subject_cnts[subj], str, subject_ptrs[subj] ) FLUSH;
- } else {
- printf( "%s%-16.16s%3d %s%.55s", first_two_chars,
- author_ptrs[first_author],
- subject_cnts[subj], str, subject_ptrs[subj] );
- if( author_cnt > 1 ) {
- author_cnts[first_author] = 0;
- author_cnt = 0;
- root_limit = upper_limit( artp, FALSE );
- for( ; artp != root_limit; artp++ ) {
- if( artp->author >= 0 && author_cnts[artp->author] ) {
- switch( author_cnt % 3 ) {
- case 0:
- putchar( '\n' ) FLUSH;
- if( ++author_line >= LINES - 3 ) {
- return;
- }
- #ifdef CLEAREOL
- maybe_eol();
- #endif
- putchar( ' ' );
- putchar( ' ' );
- break;
- case 1:
- putchar( '\t' );
- putchar( '\t' );
- break;
- case 2:
- putchar( '\t' );
- break;
- }
- author_cnt += (*display_mode == 'm');
- printf( "%-16.16s", author_ptrs[artp->author] );
- author_cnts[artp->author] = 0;
- }/* if */
- }/* for */
- }/* if */
- putchar( '\n' ) FLUSH;
- author_line++;
- }/* if */
- first_two_chars[0] = first_two_chars[1] = ' ';
- }
-
- /* Get each root's article count, and subject count(s); count total
- ** articles and selected articles (use unread_selector to determine
- ** whether to count read or unread articles); deselect any roots we
- ** find that are empty (if do_unselect is TRUE); find the last non-
- ** empty root, and return its count (the index+1).
- */
- int
- count_roots( do_unselect )
- bool do_unselect;
- {
- register int count;
- register PACKED_ARTICLE *artp, *root_limit, *art_limit;
- int last_root = -1;
-
- article_count = selected_count = selected_root_cnt = 0;
-
- if( !(artp = p_articles) ) {
- return 0;
- }
- art_limit = artp + total.article;
- root_limit = upper_limit( artp, 0 );
-
- bzero( subject_cnts, total.subject * sizeof (WORD) );
- count = 0;
-
- for( ;; ) {
- if( artp->subject == -1 ) {
- if( !was_read( artp->num ) ) {
- oneless( artp->num );
- }
- } else if( (!was_read( artp->num ) ^ unread_selector) ) {
- count++;
- subject_cnts[artp->subject]++;
- }
- if( ++artp == root_limit ) {
- register int root_num = artp[-1].root;
- register char maskr = mask;
-
- root_article_cnts[root_num] = count;
- if( count ) {
- article_count += count;
- if( selected_roots[root_num] & maskr ) {
- selected_roots[root_num] &= ~4;
- selected_root_cnt++;
- selected_count += count;
- }
- last_root = root_num;
- } else if( do_unselect ) {
- selected_roots[root_num] &= ~maskr;
- } else if( selected_roots[root_num] & maskr ) {
- selected_roots[root_num] &= ~4;
- selected_root_cnt++;
- }
- if( artp == art_limit ) {
- break;
- }
- root_limit = upper_limit( artp, 0 );
- count = 0;
- }
- }
- if( do_unselect ) {
- scan_all_roots = !article_count;
- }
- unthreaded = toread[ng] - article_count;
-
- return last_root+1;
- }
-
- /* Count the unread articles attached to the given root number.
- */
- int
- count_one_root( root_num )
- int root_num;
- {
- int last = (root_num == total.root-1 ? total.article
- : p_roots[root_num+1].articles);
- register int count = 0, i;
-
- for( i = p_roots[root_num].articles; i < last; i++ ) {
- if( p_articles[i].subject != -1 && !was_read( p_articles[i].num ) ) {
- count++;
- }
- }
- root_article_cnts[root_num] = count;
-
- return count;
- }
-
- #endif /* USETHREADS */
-