* For mailing lists, Alpine adds a description of the type of link
[alpine.git] / pith / help.c
blobbb91d376bb5fe94f7b12fc25d1c0c00102275378
1 /*
2 * ========================================================================
3 * Copyright 2013-2022 Eduardo Chappa
4 * Copyright 2006-2008 University of Washington
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * ========================================================================
15 #include "../pith/headers.h"
16 #include "../pith/help.h"
17 #include "../pith/flag.h"
18 #include "../pith/conf.h"
19 #include "../pith/sort.h"
22 REV_MSG_S rmjoarray[RMJLEN]; /* For regular journal */
23 REV_MSG_S rmloarray[RMLLEN]; /* debug 0-4 */
24 REV_MSG_S rmhiarray[RMHLEN]; /* debug 5-9 */
25 int rmjofirst = -1, rmjolast = -1;
26 int rmlofirst = -1, rmlolast = -1;
27 int rmhifirst = -1, rmhilast = -1;
28 int rm_not_right_now;
32 HelpType
33 help_name2section(char *url, int url_len)
35 char name[256];
36 HelpType newhelp = NO_HELP;
37 struct help_texts *t;
39 snprintf(name, sizeof(name), "%.*s", (int) MIN(url_len,sizeof(name)), url);
41 for(t = h_texts; t->help_text != NO_HELP; t++)
42 if(!strucmp(t->tag, name)){
43 newhelp = t->help_text;
44 break;
47 return(newhelp);
51 char *
52 get_alpine_revision_string(char *buf, size_t nbuf)
54 char ourbuf[100], *p;
55 char *rev = NULL;
57 buf[0] = '\0';
58 ourbuf[0] = '\0';
60 /* HelpType (the type of h_revision) is assumed to be char ** */
61 if(h_revision && h_revision[0] && h_revision[0][0]){
62 strncpy(ourbuf, h_revision[0], sizeof(ourbuf)-1);
63 ourbuf[sizeof(ourbuf)-1] = '\0';
66 if(ourbuf[0]){
67 /* move to revision number */
68 for(p = ourbuf; *p && !isdigit((unsigned char) (*p)); p++)
71 if(*p)
72 rev = p;
74 if(rev){
75 /* skip to following space */
76 for(; *p && !isspace((unsigned char) (*p)); p++)
79 /* skip whitespace */
80 for(; *p && isspace((unsigned char) (*p)); p++)
83 /* skip over date to following space */
84 for(; *p && !isspace((unsigned char) (*p)); p++)
87 strncpy(buf, rev, MIN(p-rev, nbuf-1));
88 buf[MIN(p-rev,nbuf-1)] = '\0';
92 return(buf);
96 char *
97 get_alpine_revision_number(char *buf, size_t nbuf)
99 char ourbuf[100], *p;
100 char *rev = NULL;
102 buf[0] = '\0';
103 ourbuf[0] = '\0';
105 /* HelpType (the type of h_revision) is assumed to be char ** */
106 if(h_revision && h_revision[0] && h_revision[0][0]){
107 strncpy(ourbuf, h_revision[0], sizeof(ourbuf)-1);
108 ourbuf[sizeof(ourbuf)-1] = '\0';
111 if(ourbuf[0]){
112 /* move to revision number */
113 for(p = ourbuf; *p && !isdigit((unsigned char) (*p)); p++)
116 if(*p)
117 rev = p;
119 if(rev){
120 /* skip to following space */
121 for(; *p && !isspace((unsigned char) (*p)); p++)
124 strncpy(buf, rev, MIN(p-rev, nbuf-1));
125 buf[MIN(p-rev,nbuf-1)] = '\0';
129 return(buf);
133 #ifdef DEBUG
135 void
136 debugjournal_to_file(FILE *dfile)
138 int donejo, donelo, donehi, jo, lo, hi;
139 RMCat rmcat;
141 if(dfile && (rmjofirst >= 0 || rmlofirst >= 0 || rmhifirst >= 0)
142 && rmjofirst < RMJLEN && rmjolast < RMJLEN
143 && rmlofirst < RMLLEN && rmlolast < RMLLEN
144 && rmhifirst < RMHLEN && rmhilast < RMHLEN
145 && (rmjofirst < 0 || rmjolast >= 0)
146 && (rmlofirst < 0 || rmlolast >= 0)
147 && (rmhifirst < 0 || rmhilast >= 0)){
149 donejo = donehi = donelo = 0;
150 jo = rmjofirst;
151 if(jo < 0)
152 donejo = 1;
154 lo = rmlofirst;
155 if(lo < 0)
156 donelo = 1;
158 hi = rmhifirst;
159 if(hi < 0)
160 donehi = 1;
162 while(!(donejo && donelo && donehi)){
163 REV_MSG_S *pjo, *plo, *phi, *p;
165 if(!donejo)
166 pjo = &rmjoarray[jo];
167 else
168 pjo = NULL;
170 if(!donelo)
171 plo = &rmloarray[lo];
172 else
173 plo = NULL;
175 if(!donehi)
176 phi = &rmhiarray[hi];
177 else
178 phi = NULL;
180 if(pjo && (!plo || pjo->seq <= plo->seq)
181 && (!phi || pjo->seq <= phi->seq))
182 rmcat = Jo;
183 else if(plo && (!phi || plo->seq <= phi->seq))
184 rmcat = Lo;
185 else if(phi)
186 rmcat = Hi;
187 else
188 rmcat = No;
190 if(rmcat == Jo){
191 p = pjo;
192 if(jo == rmjofirst &&
193 (((rmjolast + 1) % RMJLEN) == rmjofirst) &&
194 fputs("*** Level -1 entries prior to this are deleted", dfile) == EOF)
195 break;
197 else if(rmcat == Lo){
198 p = plo;
199 if(lo == rmlofirst &&
200 (((rmlolast + 1) % RMLLEN) == rmlofirst) &&
201 fputs("*** Level 0-4 entries prior to this are deleted", dfile) == EOF)
202 break;
204 else if(rmcat == Hi){
205 p = phi;
206 if(hi == rmhifirst &&
207 (((rmhilast + 1) % RMHLEN) == rmhifirst) &&
208 fputs("*** Level 5-9 entries prior to this are deleted", dfile) == EOF)
209 break;
211 else if(rmcat == No){
212 p = NULL;
215 if(p != NULL){
216 if(p->timestamp && p->timestamp[0]
217 && (fputs(p->timestamp, dfile) == EOF
218 || fputs(": ", dfile) == EOF))
219 break;
221 if(p->message && p->message[0]
222 && (fputs(p->message, dfile) == EOF
223 || fputs("\n", dfile) == EOF))
224 break;
227 switch(rmcat){
228 case Jo:
229 if(jo == rmjolast)
230 donejo++;
231 else
232 jo = (jo + 1) % RMJLEN;
234 break;
236 case Lo:
237 if(lo == rmlolast)
238 donelo++;
239 else
240 lo = (lo + 1) % RMLLEN;
242 break;
244 case Hi:
245 if(hi == rmhilast)
246 donehi++;
247 else
248 hi = (hi + 1) % RMHLEN;
250 break;
252 default:
253 donejo++;
254 donelo++;
255 donehi++;
256 break;
262 #endif /* DEBUG */
265 /*----------------------------------------------------------------------
266 Add a message to the circular status message review buffer
268 Args: message -- The message to add
269 -----*/
270 void
271 add_review_message(char *message, int level)
273 int next_is_continuation = 0, cur_is_continuation = 0;
274 char *p, *q;
275 static unsigned long rmseq = 0L;
277 if(rm_not_right_now || !(message && *message))
278 return;
281 * Debug output can have newlines in it, so split up each newline piece
282 * by hand and make them separate messages.
284 rm_not_right_now = 1;
285 for(p = message; *p; p = (*q && !next_is_continuation) ? q+1 : q){
286 for(q = p; *q && *q != '\n' && (q-p) < RMMSGLEN; q++)
289 if(p == q)
290 continue;
292 cur_is_continuation = next_is_continuation;
294 if((q-p) == RMMSGLEN && *q && *q != '\n')
295 next_is_continuation = 1;
296 else
297 next_is_continuation = 0;
299 if(level < 0){
300 if(rmjofirst < 0){
301 rmjofirst = 0;
302 rmjolast = 0;
304 else{
305 rmjolast = (rmjolast + 1) % RMJLEN;
306 if(rmjolast == rmjofirst)
307 rmjofirst = (rmjofirst + 1) % RMJLEN;
310 rmjoarray[rmjolast].level = (short) level;
311 rmjoarray[rmjolast].seq = rmseq++;
312 rmjoarray[rmjolast].continuation = cur_is_continuation ? 1 : 0;
313 memset(rmjoarray[rmjolast].message, 0, (RMMSGLEN+1)*sizeof(char));
314 strncpy(rmjoarray[rmjolast].message, p, MIN(q-p,RMMSGLEN));
315 #ifdef DEBUG
316 memset(rmjoarray[rmjolast].timestamp, 0, (RMTIMLEN+1)*sizeof(char));
317 strncpy(rmjoarray[rmjolast].timestamp, debug_time(0,1,ps_global->signal_in_progress), RMTIMLEN);
318 #endif
320 else if(level <= 4){
321 if(rmlofirst < 0){
322 rmlofirst = 0;
323 rmlolast = 0;
325 else{
326 rmlolast = (rmlolast + 1) % RMLLEN;
327 if(rmlolast == rmlofirst)
328 rmlofirst = (rmlofirst + 1) % RMLLEN;
331 rmloarray[rmlolast].level = (short) level;
332 rmloarray[rmlolast].seq = rmseq++;
333 rmloarray[rmlolast].continuation = cur_is_continuation ? 1 : 0;
334 memset(rmloarray[rmlolast].message, 0, (RMMSGLEN+1)*sizeof(char));
335 strncpy(rmloarray[rmlolast].message, p, MIN(q-p,RMMSGLEN));
336 #ifdef DEBUG
337 memset(rmloarray[rmlolast].timestamp, 0, (RMTIMLEN+1)*sizeof(char));
338 strncpy(rmloarray[rmlolast].timestamp, debug_time(0,1,ps_global->signal_in_progress), RMTIMLEN);
339 #endif
341 else{
342 if(rmhifirst < 0){
343 rmhifirst = 0;
344 rmhilast = 0;
346 else{
347 rmhilast = (rmhilast + 1) % RMHLEN;
348 if(rmhilast == rmhifirst)
349 rmhifirst = (rmhifirst + 1) % RMHLEN;
352 rmhiarray[rmhilast].level = (short) level;
353 rmhiarray[rmhilast].seq = rmseq++;
354 rmhiarray[rmhilast].continuation = cur_is_continuation ? 1 : 0;
355 memset(rmhiarray[rmhilast].message, 0, (RMMSGLEN+1)*sizeof(char));
356 strncpy(rmhiarray[rmhilast].message, p, MIN(q-p,RMMSGLEN));
357 #ifdef DEBUG
358 memset(rmhiarray[rmhilast].timestamp, 0, (RMTIMLEN+1)*sizeof(char));
359 strncpy(rmhiarray[rmhilast].timestamp, debug_time(0,1,ps_global->signal_in_progress), RMTIMLEN);
360 #endif
364 rm_not_right_now = 0;