1 /* kpathsea.c: creating and freeing library instances
2 
3    Copyright 2009, 2012 Taco Hoekwater.
4 
5    This library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    This library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public License
16    along with this library; if not, see <http://www.gnu.org/licenses/>.  */
17 
18 /* One big global struct, and a variable that points to it */
19 
20 /*
21  * The code freeing the strings used in this struct is enabled/disabled
22  * by KPATHSEA_CAN_FREE.
23  */
24 
25 #include <kpathsea/config.h>
26 
27 kpathsea
kpathsea_new(void)28 kpathsea_new (void)
29 {
30     kpathsea ret;
31     ret = xcalloc(1, sizeof(kpathsea_instance));
32     return ret;
33 }
34 
35 #if KPATHSEA_CAN_FREE
36 
37 #define string_free(a) if ((a) != NULL) free((char *)(a))
38 
39 static void
str_llist_free(str_llist_type p)40 str_llist_free (str_llist_type p)
41 {
42     str_llist_type q;
43     while (p != NULL) {
44         q = p->next;
45         free (p->str);
46         free (p);
47         p = q;
48     }
49 }
50 
51 static void
cache_free(cache_entry * the_cache,int cache_size)52 cache_free (cache_entry *the_cache, int cache_size)
53 {
54     int f ;
55     for (f = 0; f < cache_size; f++) {
56         string_free (the_cache[f].key);
57         str_llist_free (the_cache[f].value[0]);
58     }
59     free (the_cache);
60 }
61 #endif /* KPATHSEA_CAN_FREE */
62 
63 /* Sadly, quite a lot of the freeing is not safe:
64    it seems there are literals used all over. */
65 void
kpathsea_finish(kpathsea kpse)66 kpathsea_finish (kpathsea kpse)
67 {
68 #if KPATHSEA_CAN_FREE
69     int i;
70     kpse_format_info_type f;
71 #endif /* KPATHSEA_CAN_FREE */
72     if (kpse==NULL)
73         return;
74 #if KPATHSEA_CAN_FREE
75     /* free internal stuff */
76     hash_free (kpse->cnf_hash);
77     hash_free (kpse->db);
78     hash_free (kpse->alias_db);
79     str_list_free (&kpse->db_dir_list);
80     hash_free (kpse->link_table);
81     cache_free (kpse->the_cache, kpse->cache_length);
82     hash_free (kpse->map);
83     string_free (kpse->map_path);
84     string_free (kpse->elt);
85     /*string_free (kpse->path);*/
86     if (kpse->log_file != (FILE *)NULL)
87         fclose(kpse->log_file);
88     string_free (kpse->invocation_name);
89     string_free (kpse->invocation_short_name);
90     string_free (kpse->program_name);
91     string_free (kpse->fallback_font);
92     string_free (kpse->fallback_resolutions_string);
93     if(kpse->fallback_resolutions != NULL)
94         free(kpse->fallback_resolutions);
95     for (i = 0; i != kpse_last_format; ++i) {
96         f = kpse->format_info[i];
97         string_free (f.path);
98         string_free (f.override_path);
99         string_free (f.client_path);
100         /*string_free (f.cnf_path);*/
101     }
102 
103     if (kpse->missfont != (FILE *)NULL)
104         fclose (kpse->missfont);
105 
106     for (i = 0; i < (int)kpse->expansion_len; i++) {
107         string_free (kpse->expansions[i].var);
108     }
109     free (kpse->expansions);
110     if (kpse->saved_env != NULL) {
111         for (i = 0; i != kpse->saved_count; ++i)
112             string_free (kpse->saved_env[i]);
113         free (kpse->saved_env);
114     }
115 #endif /* KPATHSEA_CAN_FREE */
116 #if defined(WIN32) || defined(__CYGWIN__)
117     if (kpse->suffixlist != NULL) {
118         char **p;
119         for (p = kpse->suffixlist; *p; p++)
120             free (*p);
121         free (kpse->suffixlist);
122         kpse->suffixlist = NULL;
123     }
124 #endif /* WIN32 || __CYGWIN__ */
125 #if defined (KPSE_COMPAT_API)
126     if (kpse == kpse_def)
127         return;
128 #endif
129     free (kpse);
130 }
131 
132 
133 #if defined (KPSE_COMPAT_API)
134 
135 kpathsea_instance kpse_def_inst;
136 kpathsea kpse_def = &kpse_def_inst;
137 
138 #endif /* KPSE_COMPAT_API */
139