1 /* This file Copyright 1992 by Clifford A. Adams */
2 /* samisc.c
3  *
4  * lower-level routines
5  */
6 
7 #include "EXTERN.h"
8 #include "common.h"
9 #ifdef SCAN_ART
10 #include "list.h"
11 #include "hash.h"
12 #include "cache.h"
13 #include "artio.h"		/* openart */
14 #include "bits.h"
15 #include "final.h"		/* assert's sig_catcher() */
16 #include "term.h"		/* for "backspace" */
17 #include "util.h"
18 #include "scanart.h"
19 #include "samain.h"
20 #include "sathread.h"
21 #include "sorder.h"
22 #include "trn.h"
23 #include "ngdata.h"		/* several */
24 #include "rcstuff.h"
25 #include "ng.h"			/* for "art" */
26 #include "head.h"		/* fetchsubj */
27 #include "rthread.h"
28 #include "rt-select.h"		/* sel_mode */
29 #ifdef SCORE
30 #include "score.h"
31 #endif
32 #include "INTERN.h"
33 #include "samisc.h"
34 
35 #ifdef UNDEF	/* use function for breakpoint debugging */
36 int
check_article(a)37 check_article(a)
38 long a;
39 {
40     if (a < absfirst || a > lastart) {
41 	printf("\nArticle %d out of range\n",a) FLUSH;
42 	return FALSE;
43     }
44     return TRUE;
45 }
46 #else
47 /* note that argument is used twice. */
48 #define check_article(a) ((a) >= absfirst && (a) <= lastart)
49 #endif
50 
51 /* ignoring "Fold" (or later recursive) mode(s), is this article eligible? */
52 bool
sa_basic_elig(a)53 sa_basic_elig(a)
54 long a;
55 {
56     ART_NUM artnum;
57 
58     artnum = sa_ents[a].artnum;
59     assert(check_article(artnum));
60 
61     /* "run the gauntlet" style (:-) */
62     if (!sa_mode_read_elig && was_read(artnum))
63 	return FALSE;
64     if (sa_mode_zoom && !sa_selected1(a))
65 	return FALSE;
66 #ifdef SCORE
67     if (sa_mode_order == 2)	/* score order */
68 	if (!SCORED(artnum))
69 	    return FALSE;
70 #endif
71     /* now just check availability */
72     if (is_unavailable(artnum)) {
73 	if (!was_read(artnum))
74 	    oneless_artnum(artnum);
75 	return FALSE;		/* don't try positively unavailable */
76     }
77     /* consider later positively checking availability */
78     return TRUE;	/* passed all tests */
79 }
80 
81 bool
sa_eligible(a)82 sa_eligible(a)
83 long a;
84 {
85 
86     assert(check_article(sa_ents[a].artnum));
87     if (!sa_basic_elig(a))
88 	return FALSE;		/* must always be basic-eligible */
89     if (!sa_mode_fold)
90 	return TRUE;		/* just use basic-eligible */
91     else {
92 	if (sa_subj_thread_prev(a))
93 	    return FALSE;	/* there was an earlier match */
94 	return TRUE;		/* no prior matches */
95     }
96 }
97 
98 /* given an article number, return the entry number for that article */
99 /* (There is no easy mapping between entry numbers and article numbers.) */
100 long
sa_artnum_to_ent(artnum)101 sa_artnum_to_ent(artnum)
102 ART_NUM artnum;
103 {
104     long i;
105     for (i = 1; i < sa_num_ents; i++)
106 	if (sa_ents[i].artnum == artnum)
107 	    return i;
108     /* this had better not happen (complain?) */
109     return -1;
110 }
111 
112 /* select1 the articles picked in the TRN thread selector */
113 void
sa_selthreads()114 sa_selthreads()
115 {
116     register SUBJECT *sp;
117     register ARTICLE *ap;
118     bool want_unread;
119 #if 0
120     /* this does not work now, but maybe it will help debugging? */
121     int subj_mask = (sel_mode == SM_THREAD? (SF_THREAD|SF_VISIT) : SF_VISIT);
122 #endif
123     int subj_mask = SF_VISIT;
124 
125     long art;
126     long i;
127 
128     want_unread = !sa_mode_read_elig;
129 
130     /* clear any old selections */
131     for (i = 1; i < sa_num_ents; i++)
132 	sa_ents[i].sa_flags =
133 	    (sa_ents[i].sa_flags & 0xfd);
134 
135     /* Loop through all (selected) articles. */
136     for (sp = first_subject; sp; sp = sp->next) {
137 	if ((sp->flags & subj_mask) == subj_mask) {
138 	    for (ap = first_art(sp); ap; ap = next_art(ap)) {
139 		art = article_num(ap);
140 		if ((ap->flags & AF_SEL)
141 		 && (!(ap->flags & AF_UNREAD) ^ want_unread)) {
142 		    /* this was a trn-thread selected article */
143 		    sa_select1(sa_artnum_to_ent(art));
144 #ifdef SCORE
145     /* if scoring, make sure that this article is scored... */
146 		    if (sa_mode_order == 2)	/* score order */
147 			sc_score_art(art,FALSE);
148 #endif
149 		    }
150 		}/* for all articles */
151 	    }/* if selected */
152 	}/* for all threads */
153     s_sort();
154 }
155 
156 int
sa_number_arts()157 sa_number_arts()
158 {
159     int total;
160     long i;
161     ART_NUM a;
162 
163     if (sa_mode_read_elig)
164 	i = absfirst;
165     else
166 	i = firstart;
167     total = 0;
168     for (i = 1; i < sa_num_ents; i++) {
169 	a = sa_ents[i].artnum;
170 	if (is_unavailable(a))
171 	    continue;
172 	if (!article_unread(a) && !sa_mode_read_elig)
173 	    continue;
174 	total++;
175     }
176     return total;
177 }
178 
179 /* needed for a couple functions which act within the
180  * scope of an article.
181  */
182 void
sa_go_art(a)183 sa_go_art(a)
184 long a;
185 {
186     art = a;
187     (void)article_find(art);
188     if (openart != art)
189         artopen(art,(ART_POS)0);
190 }
191 
192 int
sa_compare(a,b)193 sa_compare(a,b)
194 long a,b;		/* the entry numbers to compare */
195 {
196     long i,j;
197 
198 #ifdef SCORE
199     if (sa_mode_order == 2) {	/* score order */
200 	/* do not score the articles here--move the articles to
201 	 * the end of the list if unscored.
202 	 */
203 	if (!SCORED(sa_ents[a].artnum)) {	/* a unscored */
204 	    if (!SCORED(sa_ents[b].artnum)) {	/* a+b unscored */
205 	        if (a < b)		/* keep ordering consistent */
206 		    return -1;
207 		return 1;
208 	    }
209 	    return 1;		/* move unscored (a) to end */
210 	}
211 	if (!SCORED(sa_ents[b].artnum))	/* only b unscored */
212 	    return -1;		/* move unscored (b) to end */
213 
214 	i = sc_score_art(sa_ents[a].artnum,TRUE);
215 	j = sc_score_art(sa_ents[b].artnum,TRUE);
216 	if (i < j)
217 	    return 1;
218 	if (i > j)
219 	    return -1;
220 	/* i == j */
221 	if (score_newfirst) {
222 	    if (a < b)
223 		return 1;
224 	    return -1;
225 	} else {
226 	    if (a < b)
227 		return -1;
228 	    return 1;
229 	}
230     }
231 #endif
232     if (a < b)
233 	return -1;
234     return 1;
235 }
236 #endif /* SCAN */
237