2 * ========================================================================
3 * Copyright 2013-2022 Eduardo Chappa
4 * Copyright 2006-2007 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/icache.h"
17 #include "../pith/mailindx.h"
18 #include "../pith/flag.h"
19 #include "../pith/msgno.h"
20 #include "../pith/status.h"
21 #include "../pith/pineelt.h"
29 * * * * Index entry cache manager * * *
34 * Erase a particular entry in the cache.
37 clear_index_cache_ent(MAILSTREAM
*stream
, long int msgno
, unsigned int flags
)
44 if(flags
& IC_USE_RAW_MSGNO
)
47 rawno
= mn_m2raw(sp_msgmap(stream
), msgno
);
49 if(rawno
> 0L && rawno
<= stream
->nmsgs
){
50 mc
= mail_elt(stream
, rawno
);
52 peltp
= (PINELT_S
**) &mc
->sparep
;
55 * This is intended to be a lightweight reset of
56 * just the widths and print_format strings. For example,
57 * the width of the screen changed and nothing else.
58 * We simply unset the widths_done bit and it
59 * is up to the drawer to free and recalculate the
60 * print_format strings and to reset the widths.
62 * The else case is a clear of the entire cache entry
63 * leaving behind only the empty structure.
65 if(flags
& IC_CLEAR_WIDTHS_DONE
){
66 (*peltp
)->ice
->widths_done
= 0;
68 /* also zero out hash value */
69 (*peltp
)->ice
->id
= 0;
71 if((*peltp
)->ice
->tice
){
72 (*peltp
)->ice
->tice
->widths_done
= 0;
74 /* also zero out hash value */
75 (*peltp
)->ice
->tice
->id
= 0;
79 clear_ice(&(*peltp
)->ice
);
88 clear_index_cache(MAILSTREAM
*stream
, unsigned int flags
)
93 set_need_format_setup(stream
);
94 for(rawno
= 1L; rawno
<= stream
->nmsgs
; rawno
++)
95 clear_index_cache_ent(stream
, rawno
, flags
| IC_USE_RAW_MSGNO
);
101 clear_index_cache_for_thread(MAILSTREAM
*stream
, PINETHRD_S
*thrd
, MSGNO_S
*msgmap
)
105 if(!thrd
|| !stream
|| thrd
->rawno
< 1L || thrd
->rawno
> stream
->nmsgs
)
108 msgno
= mn_raw2m(msgmap
, thrd
->rawno
);
110 clear_index_cache_ent(stream
, msgno
, 0);
113 clear_index_cache_for_thread(stream
, fetch_thread(stream
, thrd
->next
),
117 clear_index_cache_for_thread(stream
, fetch_thread(stream
, thrd
->branch
),
123 clear_icache_flags(MAILSTREAM
*stream
)
125 sp_set_icache_flags(stream
, 0);
130 set_need_format_setup(MAILSTREAM
*stream
)
132 sp_set_icache_flags(stream
, sp_icache_flags(stream
) | SP_NEED_FORMAT_SETUP
);
137 need_format_setup(MAILSTREAM
*stream
)
139 return(sp_icache_flags(stream
) & SP_NEED_FORMAT_SETUP
);
144 set_format_includes_msgno(MAILSTREAM
*stream
)
146 sp_set_icache_flags(stream
, sp_icache_flags(stream
) | SP_FORMAT_INCLUDES_MSGNO
);
151 format_includes_msgno(MAILSTREAM
*stream
)
153 return(sp_icache_flags(stream
) & SP_FORMAT_INCLUDES_MSGNO
);
158 set_format_includes_smartdate(MAILSTREAM
*stream
)
160 sp_set_icache_flags(stream
, sp_icache_flags(stream
) | SP_FORMAT_INCLUDES_SMARTDATE
);
165 format_includes_smartdate(MAILSTREAM
*stream
)
167 return(sp_icache_flags(stream
) & SP_FORMAT_INCLUDES_SMARTDATE
);
172 * Almost a free_ice, but we leave the memory there for the ICE_S.
175 clear_ice(ICE_S
**ice
)
178 free_ifield(&(*ice
)->ifield
);
180 if((*ice
)->linecolor
)
181 free_color_pair(&(*ice
)->linecolor
);
184 clear_ice(&(*ice
)->tice
);
186 /* do these one at a time so we don't clear tice */
187 (*ice
)->color_lookup_done
= 0;
197 free_ice(ICE_S
**ice
)
202 free_ice(&(*ice
)->tice
);
206 fs_give((void **) ice
);
212 free_ifield(IFIELD_S
**ifld
)
215 free_ifield(&(*ifld
)->next
);
216 free_ielem(&(*ifld
)->ielem
);
217 fs_give((void **) ifld
);
223 free_ielem(IELEM_S
**il
)
226 free_ielem(&(*il
)->next
);
227 if((*il
)->freeprintf
&& (*il
)->print_format
)
228 fs_give((void **) &(*il
)->print_format
);
230 if((*il
)->freecolor
&& (*il
)->color
)
231 free_color_pair(&(*il
)->color
);
233 if((*il
)->freedata
&& (*il
)->data
)
234 fs_give((void **) &(*il
)->data
);
236 fs_give((void **) il
);
242 * Returns the index cache entry associated with this message.
243 * If it doesn't already exist it is instantiated.
246 fetch_ice(MAILSTREAM
*stream
, long unsigned int rawno
)
251 if(!stream
|| rawno
< 1L || rawno
> stream
->nmsgs
)
254 if(!(mc
= mail_elt(stream
, rawno
)))
258 * any private elt data yet?
260 if(*(peltp
= (PINELT_S
**) &mc
->sparep
) == NULL
){
261 *peltp
= (PINELT_S
*) fs_get(sizeof(PINELT_S
));
262 memset(*peltp
, 0, sizeof(PINELT_S
));
265 if((*peltp
)->ice
== NULL
)
266 (*peltp
)->ice
= new_ice();
268 if(need_format_setup(stream
) && setup_header_widths
)
269 (*setup_header_widths
)(stream
);
271 return((*peltp
)->ice
);
276 fetch_ice_ptr(MAILSTREAM
*stream
, long unsigned int rawno
)
281 if(!stream
|| rawno
< 1L || rawno
> stream
->nmsgs
)
284 if(!(mc
= mail_elt(stream
, rawno
)))
288 * any private elt data yet?
290 if(*(peltp
= (PINELT_S
**) &mc
->sparep
) == NULL
){
291 *peltp
= (PINELT_S
*) fs_get(sizeof(PINELT_S
));
292 memset(*peltp
, 0, sizeof(PINELT_S
));
295 return(&(*peltp
)->ice
);
307 head
->color_lookup_done
= src
->color_lookup_done
;
308 head
->widths_done
= src
->widths_done
;
309 head
->to_us
= src
->to_us
;
310 head
->cc_us
= src
->cc_us
;
311 head
->plus
= src
->plus
;
315 head
->linecolor
= new_color_pair(src
->linecolor
->fg
, src
->linecolor
->bg
);
318 head
->ifield
= copy_ifield(src
->ifield
);
321 head
->tice
= copy_ice(src
->tice
);
329 copy_ifield(IFIELD_S
*src
)
331 IFIELD_S
*head
= NULL
;
334 head
= new_ifield(NULL
);
337 head
->next
= copy_ifield(src
->next
);
339 head
->ctype
= src
->ctype
;
340 head
->width
= src
->width
;
341 head
->leftadj
= src
->leftadj
;
344 head
->ielem
= copy_ielem(src
->ielem
);
352 copy_ielem(IELEM_S
*src
)
354 IELEM_S
*head
= NULL
;
357 head
= new_ielem(NULL
);
360 head
->next
= copy_ielem(src
->next
);
362 head
->type
= src
->type
;
363 head
->wid
= src
->wid
;
366 head
->color
= new_color_pair(src
->color
->fg
, src
->color
->bg
);
371 head
->data
= cpystr(src
->data
);
372 head
->datalen
= strlen(head
->data
);
376 if(src
->print_format
){
377 head
->print_format
= cpystr(src
->print_format
);
378 head
->freeprintf
= strlen(head
->print_format
) + 1;
391 ice
= (ICE_S
*) fs_get(sizeof(ICE_S
));
392 memset(ice
, 0, sizeof(ICE_S
));
398 * Create new IFIELD_S, zero it out, and insert it at end.
401 new_ifield(IFIELD_S
**ifieldp
)
403 IFIELD_S
*ifield
, *ip
;
405 ifield
= (IFIELD_S
*) fs_get(sizeof(*ifield
));
406 memset(ifield
, 0, sizeof(*ifield
));
411 for(ip
= (*ifieldp
); ip
&& ip
->next
; ip
= ip
->next
)
425 * Create new IELEM_S, zero it out, and insert it at end.
428 new_ielem(IELEM_S
**ielemp
)
432 ielem
= (IELEM_S
*) fs_get(sizeof(*ielem
));
433 memset(ielem
, 0, sizeof(*ielem
));
438 for(ip
= (*ielemp
); ip
&& ip
->next
; ip
= ip
->next
)