"Fossies" - the Fresh Open Source Software Archive 
Member "tin-2.6.2/src/memory.c" (9 Dec 2022, 13770 Bytes) of package /linux/misc/tin-2.6.2.tar.xz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "memory.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
2.6.1_vs_2.6.2.
1 /*
2 * Project : tin - a Usenet reader
3 * Module : memory.c
4 * Author : I. Lea & R. Skrenta
5 * Created : 1991-04-01
6 * Updated : 2022-08-26
7 * Notes :
8 *
9 * Copyright (c) 1991-2023 Iain Lea <iain@bricbrac.de>, Rich Skrenta <skrenta@pbm.com>
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 *
16 * 1. Redistributions of source code must retain the above copyright notice,
17 * this list of conditions and the following disclaimer.
18 *
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 *
23 * 3. Neither the name of the copyright holder nor the names of its
24 * contributors may be used to endorse or promote products derived from
25 * this software without specific prior written permission.
26 *
27 * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
31 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40
41 #ifndef TIN_H
42 # include "tin.h"
43 #endif /* !TIN_H */
44
45
46 /*
47 * Dynamic arrays maximum (initialized in init_alloc()) & current sizes
48 * num_* values are one past top of used part of array
49 */
50 int max_active;
51 int num_active = -1;
52 int max_newnews;
53 int num_newnews = 0;
54 int max_art;
55 int max_base;
56 int max_save;
57 int num_save = 0;
58 int max_scope;
59 int num_scope = -1;
60
61 /*
62 * Dynamic arrays
63 */
64 int *my_group; /* .newsrc --> active[] */
65 t_artnum *base; /* base articles for each thread */
66 struct t_group *active; /* active newsgroups */
67 struct t_scope *scopes = NULL; /* attributes stores in .tin/attributes */
68 struct t_newnews *newnews; /* active file sizes on different servers */
69 struct t_article *arts; /* articles headers in current group */
70 struct t_save *save; /* sorts articles before saving them */
71
72 /*
73 * Local prototypes
74 */
75 static void free_active_arrays(void);
76 static void free_attributes(struct t_attribute *attributes);
77 static void free_scopes_arrays(void);
78 static void free_newnews_array(void);
79 static void free_if_not_default(char **attrib, const char *deflt);
80 static void free_input_history(void);
81
82
83 /*
84 * Dynamic table management
85 * These settings are memory conservative: small initial allocations
86 * and a 50% expansion on table overflow. A fast vm system with
87 * much memory might want to start with higher initial allocations
88 * and a 100% expansion on overflow, especially for the arts[] array.
89 */
90 void
91 init_alloc(
92 void)
93 {
94 /*
95 * active file arrays
96 */
97 max_active = DEFAULT_ACTIVE_NUM;
98 max_newnews = DEFAULT_NEWNEWS_NUM;
99
100 active = my_malloc(sizeof(*active) * (size_t) max_active);
101 newnews = my_malloc(sizeof(*newnews) * (size_t) max_newnews);
102 my_group = my_calloc(1, sizeof(int) * (size_t) max_active);
103
104 /*
105 * article headers array
106 */
107 max_art = DEFAULT_ARTICLE_NUM;
108 max_base = DEFAULT_ARTICLE_NUM;
109
110 arts = my_calloc(1, sizeof(*arts) * (size_t) max_art);
111 base = my_malloc(sizeof(t_artnum) * (size_t) max_base);
112
113 ofmt = my_calloc(1, sizeof(*ofmt) * 9); /* initial number of overview fields */
114
115 /*
116 * save file array
117 */
118 max_save = DEFAULT_SAVE_NUM;
119
120 save = my_malloc(sizeof(*save) * (size_t) max_save);
121
122 /*
123 * scope array
124 */
125 max_scope = DEFAULT_SCOPE_NUM;
126 expand_scope();
127
128 #ifndef USE_CURSES
129 screen = (struct t_screen *) 0;
130 #endif /* !USE_CURSES */
131 }
132
133
134 void
135 expand_art(
136 void)
137 {
138 int i = max_art;
139
140 max_art += max_art >> 1; /* increase by 50% */
141 arts = my_realloc(arts, sizeof(*arts) * (size_t) max_art);
142 /*
143 * memset(&arts[i].artnum, 0, (max_art - i - 1) * sizeof(*arts));
144 * seems to be not faster at all
145 */
146 for (; i < max_art; i++)
147 arts[i].subject = arts[i].from = arts[i].xref = arts[i].path = arts[i].refs = arts[i].msgid = NULL;
148 }
149
150
151 void
152 expand_active(
153 void)
154 {
155 max_active += max_active >> 1; /* increase by 50% */
156 if (active == NULL) {
157 active = my_malloc(sizeof(*active) * (size_t) max_active);
158 my_group = my_calloc(1, sizeof(int) * (size_t) max_active);
159 } else {
160 active = my_realloc(active, sizeof(*active) * (size_t) max_active);
161 my_group = my_realloc(my_group, sizeof(int) * (size_t) max_active);
162 }
163 }
164
165
166 void
167 expand_base(
168 void)
169 {
170 max_base += max_base >> 1; /* increase by 50% */
171 base = my_realloc(base, sizeof(t_artnum) * (size_t) max_base);
172 }
173
174
175 void
176 expand_save(
177 void)
178 {
179 max_save += max_save >> 1; /* increase by 50% */
180 save = my_realloc(save, sizeof(struct t_save) * (size_t) max_save);
181 }
182
183
184 void
185 expand_scope(
186 void)
187 {
188 if ((scopes == NULL) || (num_scope < 0)) {
189 if (scopes == NULL)
190 scopes = my_malloc(sizeof(*scopes) * (size_t) max_scope);
191 num_scope = 0;
192 } else {
193 max_scope += max_scope >> 1; /* increase by 50% */
194 scopes = my_realloc(scopes, sizeof(*scopes) * (size_t) max_scope);
195 }
196 }
197
198
199 void
200 expand_newnews(
201 void)
202 {
203 max_newnews += max_newnews >> 1; /* increase by 50% */
204 newnews = my_realloc(newnews, sizeof(struct t_newnews) * (size_t) max_newnews);
205 }
206
207
208 #ifndef USE_CURSES
209 void
210 init_screen_array(
211 t_bool allocate)
212 {
213 int i;
214
215 if (allocate) {
216 screen = my_malloc(sizeof(struct t_screen) * (size_t) cLINES + 1);
217
218 for (i = 0; i < cLINES; i++)
219 # if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
220 screen[i].col = my_malloc((size_t) ((size_t) cCOLS * MB_CUR_MAX + 2));
221 # else
222 screen[i].col = my_malloc((size_t) ((size_t) cCOLS + 2));
223 # endif /* MULTIBYTE_ABLE && !NO_LOCALE */
224 } else {
225 if (screen != NULL) {
226 for (i = 0; i < cLINES; i++)
227 FreeAndNull(screen[i].col);
228
229 FreeAndNull(screen);
230 }
231 }
232 }
233 #endif /* !USE_CURSES */
234
235
236 void
237 free_all_arrays(
238 void)
239 {
240 hash_reclaim();
241
242 #ifndef USE_CURSES
243 if (!batch_mode)
244 init_screen_array(FALSE);
245 #endif /* !USE_CURSES */
246
247 free_art_array();
248 free_msgids();
249 FreeAndNull(arts);
250 free_filter_array(&glob_filter);
251 free_active_arrays();
252 free_scopes_arrays();
253
254 #ifdef HAVE_COLOR
255 regex_cache_destroy("e_regex);
256 regex_cache_destroy("e_regex2);
257 regex_cache_destroy("e_regex3);
258 regex_cache_destroy(&extquote_regex);
259 #endif /* HAVE_COLOR */
260 regex_cache_destroy(&slashes_regex);
261 regex_cache_destroy(&stars_regex);
262 regex_cache_destroy(&strokes_regex);
263 regex_cache_destroy(&underscores_regex);
264 regex_cache_destroy(&strip_re_regex);
265 regex_cache_destroy(&strip_was_regex);
266 regex_cache_destroy(&uubegin_regex);
267 regex_cache_destroy(&uubody_regex);
268 regex_cache_destroy(&verbatim_begin_regex);
269 regex_cache_destroy(&verbatim_end_regex);
270 regex_cache_destroy(&url_regex);
271 regex_cache_destroy(&mail_regex);
272 regex_cache_destroy(&news_regex);
273 regex_cache_destroy(&shar_regex);
274
275 if (!batch_mode) {
276 free_keymaps();
277 free_input_history();
278 }
279
280 FreeAndNull(base);
281
282 if (save != NULL) {
283 free_save_array();
284 FreeAndNull(save);
285 }
286
287 if (newnews != NULL) {
288 free_newnews_array();
289 FreeAndNull(newnews);
290 }
291
292 FreeAndNull(nntp_caps.headers_range);
293 FreeAndNull(nntp_caps.headers_id);
294 FreeAndNull(nntp_caps.implementation);
295
296 if (ofmt) { /* ofmt might not be allocated yet on early abort */
297 int i;
298 for (i = 0; ofmt[i].name; i++)
299 free(ofmt[i].name);
300 free(ofmt);
301 }
302
303 tin_fgets(NULL, FALSE);
304 rfc1522_decode(NULL);
305
306 free(tin_progname);
307 }
308
309
310 void
311 free_art_array(
312 void)
313 {
314 int i;
315
316 for_each_art(i) {
317 arts[i].artnum = T_ARTNUM_CONST(0);
318 arts[i].date = (time_t) 0;
319 FreeAndNull(arts[i].xref);
320 FreeAndNull(arts[i].path);
321
322 /*
323 * .refs & .msgid are usually free()d in build_references()
324 * nevertheless we try to free() it here in case tin_done()
325 * was called before build_references()
326 */
327 FreeAndNull(arts[i].refs);
328 FreeAndNull(arts[i].msgid);
329
330 arts[i].tagged = 0;
331 arts[i].thread = ART_EXPIRED;
332 arts[i].prev = ART_NORMAL;
333 arts[i].status = ART_UNREAD;
334 arts[i].killed = ART_NOTKILLED;
335 arts[i].selected = FALSE;
336 }
337 }
338
339
340 /*
341 * Use this only for attributes that have a fixed default of a static string
342 * in tinrc
343 */
344 static void
345 free_if_not_default(
346 char **attrib,
347 const char *deflt)
348 {
349 if (*attrib != deflt)
350 FreeAndNull(*attrib);
351 }
352
353
354 /*
355 * Free memory of one attributes struct only
356 */
357 static void
358 free_attributes(
359 struct t_attribute *attributes)
360 {
361 free_if_not_default(&attributes->group_format, tinrc.group_format);
362 free_if_not_default(&attributes->thread_format, tinrc.thread_format);
363 free_if_not_default(&attributes->date_format, tinrc.date_format);
364 free_if_not_default(&attributes->editor_format, tinrc.editor_format);
365 FreeAndNull(attributes->fcc);
366 free_if_not_default(&attributes->from, tinrc.mail_address);
367 FreeAndNull(attributes->followup_to);
368 #ifdef HAVE_ISPELL
369 FreeAndNull(attributes->ispell);
370 #endif /* HAVE_ISPELL */
371 free_if_not_default(&attributes->maildir, tinrc.maildir);
372 FreeAndNull(attributes->mailing_list);
373 FreeAndNull(attributes->mime_types_to_save);
374 free_if_not_default(&attributes->news_headers_to_display, tinrc.news_headers_to_display);
375 free_if_not_default(&attributes->news_headers_to_not_display, tinrc.news_headers_to_not_display);
376 if (attributes->headers_to_display) {
377 if (attributes->headers_to_display->header)
378 FreeIfNeeded(*attributes->headers_to_display->header);
379 FreeAndNull(attributes->headers_to_display->header);
380 free(attributes->headers_to_display);
381 attributes->headers_to_display = (struct t_newsheader *) 0;
382 }
383 if (attributes->headers_to_not_display) {
384 if (attributes->headers_to_not_display->header)
385 FreeIfNeeded(*attributes->headers_to_not_display->header);
386 FreeAndNull(attributes->headers_to_not_display->header);
387 free(attributes->headers_to_not_display);
388 attributes->headers_to_not_display = (struct t_newsheader *) 0;
389 }
390 free_if_not_default(&attributes->news_quote_format, tinrc.news_quote_format);
391 free_if_not_default(&attributes->organization, default_organization);
392 FreeAndNull(attributes->quick_kill_scope);
393 FreeAndNull(attributes->quick_select_scope);
394 free_if_not_default(&attributes->quote_chars, tinrc.quote_chars);
395 free_if_not_default(&attributes->savedir, tinrc.savedir);
396 FreeAndNull(attributes->savefile);
397 free_if_not_default(&attributes->sigfile, tinrc.sigfile);
398 #ifdef CHARSET_CONVERSION
399 FreeAndNull(attributes->undeclared_charset);
400 #endif /* CHARSET_CONVERSION */
401 FreeAndNull(attributes->x_headers);
402 FreeAndNull(attributes->x_body);
403 }
404
405
406 void
407 free_scope(
408 int num)
409 {
410 struct t_scope *scope;
411
412 scope = &scopes[num];
413 FreeAndNull(scope->scope);
414 free_attributes(scope->attribute);
415 free(scope->attribute);
416 scope->attribute = (struct t_attribute *) 0;
417 free(scope->state);
418 scope->state = (struct t_attribute_state *) 0;
419 }
420
421
422 static void
423 free_scopes_arrays(
424 void)
425 {
426 while (num_scope > 0)
427 free_scope(--num_scope);
428 FreeAndNull(scopes);
429 num_scope = -1;
430 }
431
432
433 static void
434 free_active_arrays(
435 void)
436 {
437 FreeAndNull(my_group); /* my_group[] */
438
439 if (active != NULL) { /* active[] */
440 int i;
441
442 for_each_group(i) {
443 FreeAndNull(active[i].name);
444 FreeAndNull(active[i].description);
445 FreeAndNull(active[i].aliasedto);
446 if (active[i].type == GROUP_TYPE_MAIL || active[i].type == GROUP_TYPE_SAVE) {
447 FreeAndNull(active[i].spooldir);
448 }
449 FreeAndNull(active[i].newsrc.xbitmap);
450 if (active[i].attribute && !active[i].attribute->global) {
451 free(active[i].attribute);
452 active[i].attribute = (struct t_attribute *) 0;
453 }
454 }
455 FreeAndNull(active);
456 }
457 num_active = -1;
458 }
459
460
461 void
462 free_save_array(
463 void)
464 {
465 int i;
466
467 for (i = 0; i < num_save; i++) {
468 FreeAndNull(save[i].path);
469 /* file does NOT need to be freed */
470 save[i].file = NULL;
471 save[i].mailbox = FALSE;
472 }
473 num_save = 0;
474 }
475
476
477 static void
478 free_newnews_array(
479 void)
480 {
481 int i;
482
483 for (i = 0; i < num_newnews; i++)
484 FreeAndNull(newnews[i].host);
485
486 num_newnews = 0;
487 }
488
489
490 static void
491 free_input_history(
492 void)
493 {
494 int his_w, his_e;
495
496 for (his_w = 0; his_w <= HIST_MAXNUM; his_w++) {
497 for (his_e = 0; his_e < HIST_SIZE; his_e++) {
498 FreeIfNeeded(input_history[his_w][his_e]);
499 }
500 }
501 }
502
503
504 void *
505 my_malloc1(
506 const char *file,
507 int line,
508 size_t size)
509 {
510 void *p;
511
512 #ifdef DEBUG
513 if (debug & DEBUG_MEM)
514 debug_print_malloc(TRUE, file, line, size);
515 #endif /* DEBUG */
516
517 if ((p = malloc(size)) == NULL) {
518 error_message(2, txt_out_of_memory, tin_progname, (unsigned long) size, file, line);
519 giveup();
520 }
521 return p;
522 }
523
524
525 /*
526 * TODO: add fallback code with malloc(nmemb*size);memset(0,nmemb*size)?
527 */
528 void *
529 my_calloc1(
530 const char *file,
531 int line,
532 size_t nmemb,
533 size_t size)
534 {
535 void *p;
536
537 #ifdef DEBUG
538 if (debug & DEBUG_MEM)
539 debug_print_malloc(TRUE, file, line, nmemb * size);
540 #endif /* DEBUG */
541
542 if ((p = calloc(nmemb, size)) == NULL) {
543 error_message(2, txt_out_of_memory, tin_progname, (unsigned long) (nmemb * size), file, line);
544 giveup();
545 }
546 return p;
547 }
548
549
550 void *
551 my_realloc1(
552 const char *file,
553 int line,
554 void *p,
555 size_t size)
556 {
557 #ifdef DEBUG
558 if (debug & DEBUG_MEM)
559 debug_print_malloc(FALSE, file, line, size);
560 #endif /* DEBUG */
561
562 if (!size) {
563 if (p)
564 free(p);
565
566 return NULL;
567 }
568
569 if (p) {
570 void *q = realloc(p, size);
571
572 if (q != NULL)
573 p = q;
574 else {
575 free(p);
576 p = NULL;
577 }
578 } else
579 p = malloc(size);
580
581 if (p == NULL) {
582 error_message(2, txt_out_of_memory, tin_progname, (unsigned long) size, file, line);
583 giveup();
584 }
585 return p;
586 }