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