1 #if !defined(lint) && !defined(DOS)
2 static char rcsid
[] = "$Id: icache.c 874 2007-12-15 02:51:06Z hubert@u.washington.edu $";
6 * ========================================================================
7 * Copyright 2006-2007 University of Washington
8 * Copyright 2013-2016 Eduardo Chappa
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * ========================================================================
19 #include "../pith/headers.h"
20 #include "../pith/icache.h"
21 #include "../pith/mailindx.h"
22 #include "../pith/flag.h"
23 #include "../pith/msgno.h"
24 #include "../pith/status.h"
25 #include "../pith/pineelt.h"
33 * * * * Index entry cache manager * * *
38 * Erase a particular entry in the cache.
41 clear_index_cache_ent(MAILSTREAM
*stream
, long int msgno
, unsigned int flags
)
48 if(flags
& IC_USE_RAW_MSGNO
)
51 rawno
= mn_m2raw(sp_msgmap(stream
), msgno
);
53 if(rawno
> 0L && rawno
<= stream
->nmsgs
){
54 mc
= mail_elt(stream
, rawno
);
56 peltp
= (PINELT_S
**) &mc
->sparep
;
59 * This is intended to be a lightweight reset of
60 * just the widths and print_format strings. For example,
61 * the width of the screen changed and nothing else.
62 * We simply unset the widths_done bit and it
63 * is up to the drawer to free and recalculate the
64 * print_format strings and to reset the widths.
66 * The else case is a clear of the entire cache entry
67 * leaving behind only the empty structure.
69 if(flags
& IC_CLEAR_WIDTHS_DONE
){
70 (*peltp
)->ice
->widths_done
= 0;
72 /* also zero out hash value */
73 (*peltp
)->ice
->id
= 0;
75 if((*peltp
)->ice
->tice
){
76 (*peltp
)->ice
->tice
->widths_done
= 0;
78 /* also zero out hash value */
79 (*peltp
)->ice
->tice
->id
= 0;
83 clear_ice(&(*peltp
)->ice
);
92 clear_index_cache(MAILSTREAM
*stream
, unsigned int flags
)
97 set_need_format_setup(stream
);
98 for(rawno
= 1L; rawno
<= stream
->nmsgs
; rawno
++)
99 clear_index_cache_ent(stream
, rawno
, flags
| IC_USE_RAW_MSGNO
);
105 clear_index_cache_for_thread(MAILSTREAM
*stream
, PINETHRD_S
*thrd
, MSGNO_S
*msgmap
)
109 if(!thrd
|| !stream
|| thrd
->rawno
< 1L || thrd
->rawno
> stream
->nmsgs
)
112 msgno
= mn_raw2m(msgmap
, thrd
->rawno
);
114 clear_index_cache_ent(stream
, msgno
, 0);
117 clear_index_cache_for_thread(stream
, fetch_thread(stream
, thrd
->next
),
121 clear_index_cache_for_thread(stream
, fetch_thread(stream
, thrd
->branch
),
127 clear_icache_flags(MAILSTREAM
*stream
)
129 sp_set_icache_flags(stream
, 0);
134 set_need_format_setup(MAILSTREAM
*stream
)
136 sp_set_icache_flags(stream
, sp_icache_flags(stream
) | SP_NEED_FORMAT_SETUP
);
141 need_format_setup(MAILSTREAM
*stream
)
143 return(sp_icache_flags(stream
) & SP_NEED_FORMAT_SETUP
);
148 set_format_includes_msgno(MAILSTREAM
*stream
)
150 sp_set_icache_flags(stream
, sp_icache_flags(stream
) | SP_FORMAT_INCLUDES_MSGNO
);
155 format_includes_msgno(MAILSTREAM
*stream
)
157 return(sp_icache_flags(stream
) & SP_FORMAT_INCLUDES_MSGNO
);
162 set_format_includes_smartdate(MAILSTREAM
*stream
)
164 sp_set_icache_flags(stream
, sp_icache_flags(stream
) | SP_FORMAT_INCLUDES_SMARTDATE
);
169 format_includes_smartdate(MAILSTREAM
*stream
)
171 return(sp_icache_flags(stream
) & SP_FORMAT_INCLUDES_SMARTDATE
);
176 * Almost a free_ice, but we leave the memory there for the ICE_S.
179 clear_ice(ICE_S
**ice
)
182 free_ifield(&(*ice
)->ifield
);
184 if((*ice
)->linecolor
)
185 free_color_pair(&(*ice
)->linecolor
);
188 clear_ice(&(*ice
)->tice
);
190 /* do these one at a time so we don't clear tice */
191 (*ice
)->color_lookup_done
= 0;
201 free_ice(ICE_S
**ice
)
206 free_ice(&(*ice
)->tice
);
210 fs_give((void **) ice
);
216 free_ifield(IFIELD_S
**ifld
)
219 free_ifield(&(*ifld
)->next
);
220 free_ielem(&(*ifld
)->ielem
);
221 fs_give((void **) ifld
);
227 free_ielem(IELEM_S
**il
)
230 free_ielem(&(*il
)->next
);
231 if((*il
)->freeprintf
&& (*il
)->print_format
)
232 fs_give((void **) &(*il
)->print_format
);
234 if((*il
)->freecolor
&& (*il
)->color
)
235 free_color_pair(&(*il
)->color
);
237 if((*il
)->freedata
&& (*il
)->data
)
238 fs_give((void **) &(*il
)->data
);
240 fs_give((void **) il
);
246 * Returns the index cache entry associated with this message.
247 * If it doesn't already exist it is instantiated.
250 fetch_ice(MAILSTREAM
*stream
, long unsigned int rawno
)
255 if(!stream
|| rawno
< 1L || rawno
> stream
->nmsgs
)
258 if(!(mc
= mail_elt(stream
, rawno
)))
262 * any private elt data yet?
264 if(*(peltp
= (PINELT_S
**) &mc
->sparep
) == NULL
){
265 *peltp
= (PINELT_S
*) fs_get(sizeof(PINELT_S
));
266 memset(*peltp
, 0, sizeof(PINELT_S
));
269 if((*peltp
)->ice
== NULL
)
270 (*peltp
)->ice
= new_ice();
272 if(need_format_setup(stream
) && setup_header_widths
)
273 (*setup_header_widths
)(stream
);
275 return((*peltp
)->ice
);
280 fetch_ice_ptr(MAILSTREAM
*stream
, long unsigned int rawno
)
285 if(!stream
|| rawno
< 1L || rawno
> stream
->nmsgs
)
288 if(!(mc
= mail_elt(stream
, rawno
)))
292 * any private elt data yet?
294 if(*(peltp
= (PINELT_S
**) &mc
->sparep
) == NULL
){
295 *peltp
= (PINELT_S
*) fs_get(sizeof(PINELT_S
));
296 memset(*peltp
, 0, sizeof(PINELT_S
));
299 return(&(*peltp
)->ice
);
311 head
->color_lookup_done
= src
->color_lookup_done
;
312 head
->widths_done
= src
->widths_done
;
313 head
->to_us
= src
->to_us
;
314 head
->cc_us
= src
->cc_us
;
315 head
->plus
= src
->plus
;
319 head
->linecolor
= new_color_pair(src
->linecolor
->fg
, src
->linecolor
->bg
);
322 head
->ifield
= copy_ifield(src
->ifield
);
325 head
->tice
= copy_ice(src
->tice
);
333 copy_ifield(IFIELD_S
*src
)
335 IFIELD_S
*head
= NULL
;
338 head
= new_ifield(NULL
);
341 head
->next
= copy_ifield(src
->next
);
343 head
->ctype
= src
->ctype
;
344 head
->width
= src
->width
;
345 head
->leftadj
= src
->leftadj
;
348 head
->ielem
= copy_ielem(src
->ielem
);
356 copy_ielem(IELEM_S
*src
)
358 IELEM_S
*head
= NULL
;
361 head
= new_ielem(NULL
);
364 head
->next
= copy_ielem(src
->next
);
366 head
->type
= src
->type
;
367 head
->wid
= src
->wid
;
370 head
->color
= new_color_pair(src
->color
->fg
, src
->color
->bg
);
375 head
->data
= cpystr(src
->data
);
376 head
->datalen
= strlen(head
->data
);
380 if(src
->print_format
){
381 head
->print_format
= cpystr(src
->print_format
);
382 head
->freeprintf
= strlen(head
->print_format
) + 1;
395 ice
= (ICE_S
*) fs_get(sizeof(ICE_S
));
396 memset(ice
, 0, sizeof(ICE_S
));
402 * Create new IFIELD_S, zero it out, and insert it at end.
405 new_ifield(IFIELD_S
**ifieldp
)
407 IFIELD_S
*ifield
, *ip
;
409 ifield
= (IFIELD_S
*) fs_get(sizeof(*ifield
));
410 memset(ifield
, 0, sizeof(*ifield
));
415 for(ip
= (*ifieldp
); ip
&& ip
->next
; ip
= ip
->next
)
429 * Create new IELEM_S, zero it out, and insert it at end.
432 new_ielem(IELEM_S
**ielemp
)
436 ielem
= (IELEM_S
*) fs_get(sizeof(*ielem
));
437 memset(ielem
, 0, sizeof(*ielem
));
442 for(ip
= (*ielemp
); ip
&& ip
->next
; ip
= ip
->next
)