File: eutils.c

package info (click to toggle)
entity 1.0.1-8
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 5,604 kB
  • ctags: 5,394
  • sloc: ansic: 64,242; sh: 7,377; makefile: 776; perl: 319
file content (313 lines) | stat: -rw-r--r-- 7,378 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
#include <glib.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>

#include "entity.h"

/* Should be able to do this with user_data, but I think * I had problems
 * when I tried it. */
static GSList *key_list = NULL;
static GSList *value_list = NULL;


/* Disable memchunk allocation, and use straight g_malloc instead */
#define MEMORY_PROFILE 1


static void
eutils_foreach_key_append_to_list (gpointer key,
				   gpointer value, gpointer user_data)
{
    key_list = g_slist_prepend (key_list, key);
}


static void
eutils_foreach_value_append_to_list (gpointer key,
				     gpointer value, gpointer user_data)
{
    value_list = g_slist_prepend (value_list, value);
}


/* list of currently set keys, appended to list, or NULL to start new list. */
GSList *
eutils_hash_key_list (GHashTable * table, GSList * list)
{
    key_list = list;

    if (!table)
	return (list);

    g_hash_table_foreach (table, eutils_foreach_key_append_to_list, NULL);

    return (key_list);
}

GSList *
eutils_hash_value_list (GHashTable * table, GSList * list)
{
    value_list = list;

    if (!table)
	return (list);

    g_hash_table_foreach (table, eutils_foreach_value_append_to_list, NULL);

    return (value_list);
}


gint eutils_file_exists (gchar * filename)
{
    g_return_val_if_fail (filename != NULL, FALSE);

    return (access (filename, F_OK) == 0);
}

gchar *
eutils_file_search (ENode * node, gchar * filename)
{
    ENode *parent;
    gchar *path;
    gchar *entity_startup_dir;

    EDEBUG (("eutils", "file search, checking '%s'", filename));

    /* First check current working dir/absolute path at startup. */
    entity_startup_dir = econfig_get_attr ("entity-startup-dir");
    path = g_strconcat (entity_startup_dir, "/", filename, NULL);
    EDEBUG (("eutils", "file search, checking '%s'", path));
    if (eutils_file_exists (path))
	return (path);
    g_free (path);

    /* Check current working dir. eg ~home/entity/^^filename^^ */
    if (eutils_file_exists (filename))
	return (g_strdup (filename));

    /* Now relative to object filename */
    parent = node;
    while (parent) {
	gchar *parent_srcfile = enode_attrib_str (parent, "__filename", NULL);

	EDEBUG (("eutils", "parent source file for %s set to '%s'",
		 parent->element->str, parent_srcfile));

	if (parent_srcfile) {
	    gchar *dir = g_dirname (parent_srcfile);

	    path = g_strconcat (dir, "/", filename, NULL);
	    g_free (dir);

	    EDEBUG (("eutils", "file search, checking '%s'", path));
	    if (eutils_file_exists (path))
		return (path);
	    g_free (path);
	}
	parent = enode_parent (parent, NULL);
    }

    /* Now entity home */
    path = g_strconcat (ENTITY_HOME, "/", filename, NULL);
    EDEBUG (("eutils", "file search, checking '%s'", path));
    if (eutils_file_exists (path))
	return (path);
    g_free (path);

    /* System dir */
    path = g_strconcat (DATADIR, "/", filename, NULL);
    EDEBUG (("eutils", "file search, checking '%s'", path));
    if (eutils_file_exists (path))
	return (path);
    g_free (path);

    /* elib System dir - basically for backwards compat */
    path = g_strconcat (DATADIR, "/elib/", filename, NULL);
    EDEBUG (("eutils", "file search, checking '%s'", path));
    if (eutils_file_exists (path))
	return (path);
    g_free (path);

    return (NULL);
}

/* extract the full filename from a .la file.  This seems to * be the only
 * portable way to dlopen () a libtool library */

gchar *
eutils_module_dlname (gchar * lafile)
{
    FILE *fp;
    gchar buf[1024];
    gchar *start = NULL;
    gchar *end = NULL;

    fp = fopen (lafile, "r");
    if (!fp) {
	g_warning ("Unable to open .la file '%s' for reading: %s",
		   lafile, g_strerror (errno));
	return (NULL);
    }

    while (fgets (buf, sizeof (buf), fp)) {
	if (strncmp (buf, "dlname", strlen ("dlname")) == 0) {
	    start = strstr (buf, "'");
	    if (!start) {
		g_warning ("Unable to determine dlname from file '%s'", lafile);
		goto done;
	    }
	    start++;
	    end = strstr (start, "'");
	    if (!end) {
		g_warning ("Unable to determine dlname from file '%s'", lafile);
		goto done;
	    }
	    end[0] = '\0';

	    goto done;
	}
    }

  done:

    fclose (fp);

    if (start) {
	return (g_strdup (start));
    } else {
	return (NULL);
    }
}

GModule *
eutils_load_module (gchar * modname)
{
    GModule *module = NULL;
    gchar *libpath;
    gchar *desttmp;
    gchar *dlname;

    /* XXX: Check this one.. */
    desttmp = g_strconcat (econfig_get_attr ("config-location"), "/clib/lib",
			   modname, ".la", NULL);
    dlname = eutils_module_dlname (desttmp);
    g_free (desttmp);

    if (strlen (dlname) <= 1) {
	g_warning
	    ("Unable to glean the 'dlname' to open module '%s'.  Probably an incorrect build or install",
	     modname);
	goto done;
    }

    libpath = g_strconcat (econfig_get_attr ("config-location"), "/clib/",
			   dlname, NULL);
    module = g_module_open (libpath, G_MODULE_BIND_LAZY);
    EDEBUG (("eutils", "Loaded dynamic library %s", libpath));
    g_free (libpath);

    if (!module)
	g_warning ("Error loading module %s: %s", modname, g_module_error ());

  done:
    g_free (dlname);

    return (module);
}

/* Create a new memchunk struct */
EMemChunk *
eutils_memchunk_admin_new (guint chunk_size, guint alloc_num)
{
    EMemChunk *chunk;

    chunk = g_new0 (EMemChunk, 1);

    chunk->size = chunk_size;
    chunk->alloc_num = alloc_num;

    return (chunk);
}

/* Allocate a new chunk */
void *
eutils_memchunk_alloc (EMemChunk * chunk)
{
#ifdef MEMORY_PROFILE
    return (g_malloc0 (chunk->size));
#else				/* MEMORY_PROFILE */
    void *buf;
    void *newbuf;
    gint i;
    GSList *tmp;

    /* Make sure we have free chunks around */
    if (!chunk->free_list) {
	buf = g_malloc0 (chunk->size * chunk->alloc_num);
	for (i = 0; i < chunk->alloc_num; i++) {
	    chunk->free_list =
		g_slist_prepend (chunk->free_list, (char *) buf + (chunk->size * i));
	}
#ifdef EMEMCHUNK_PROFILE
	chunk->number_of_allocated_chunks += chunk->alloc_num;
#endif				/* EMEMCHUNK_PROFILE */
    }

    /* Grab top one of list */
    newbuf = chunk->free_list->data;

    /* Clean up list */
    tmp = chunk->free_list;
    chunk->free_list = chunk->free_list->next;
    tmp->next = NULL;
    g_slist_free (tmp);

#ifdef EMEMCHUNK_PROFILE
    chunk->number_of_used_chunks++;
#endif				/* EMEMCHUNK_PROFILE */

    return (newbuf);

#endif				/* MEMORY_PROFILE */
}

/* Free a chunk */
void
eutils_memchunk_free (EMemChunk * chunk, void *buf)
{
#ifdef MEMORY_PROFILE
    g_free (buf);
#else				/* MEMORY_PROFILE */
    memset (buf, 0, chunk->size);

    /* Give to the pool for reuse */
    chunk->free_list = g_slist_prepend (chunk->free_list, buf);

#ifdef EMEMCHUNK_PROFILE
    chunk->number_of_freed_chunks++;
#endif				/* EMEMCHUNK_PROFILE */

#endif				/* MEMORY_PROFILE */
}

void
eutils_memchunk_stats (EMemChunk * chunk)
{
#ifdef EMEMCHUNK_PROFILE
    if (!chunk) {
	g_print ("  Not initialized\n");
	return;
    }
    g_print ("  Number of freed chunks: %d\n", chunk->number_of_freed_chunks);
    g_print ("  Number of used chunks: %d\n", chunk->number_of_used_chunks);
    g_print ("  Number of allocated chunks: %d\n",
	     chunk->number_of_allocated_chunks);
    g_print ("  Total memory allocated: %d bytes\n",
	     chunk->number_of_allocated_chunks * chunk->size);
#endif
}