GCOV Execution Analysis for epath_utils.c

The left column is the number of times the code was executed during the unit test suites.

Exec CodeLine #
 
Source:epath_utils.c
1
 
Object:t/epath/epath_utils.bb
2
 
/*      -*- linux-c -*-
3
 
 *
4
 
 * (C) Copyright IBM Corp. 2003, 2004
5
 
 *
6
 
 * This program is distributed in the hope that it will be useful,
7
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  This
9
 
 * file and program are licensed under a BSD style license.  See
10
 
 * the Copying file included with the OpenHPI distribution for
11
 
 * full licensing terms.
12
 
 *
13
 
 * Author(s):
14
 
 *      Steve Sherman < address removed >
15
 
 *      Renier Morales < address removed >
16
 
 *      Thomas Kanngieser < address removed >
17
 
 *      Chris Chia < address removed >
18
 
 */
19
 
20
 
#include <glib.h>
21
 
#include <stdio.h>
22
 
#include <stdlib.h>
23
 
#include <string.h>
24
 
25
 
#include <oh_utils.h>
26
 
27
 
/**
28
 
 * oh_encode_entitypath:
29
 
 * @epstr: Pointer to canonical entity path string.
30
 
 * @ep: Location to store HPI's entity path structure.
31
 
 *
32
 
 * Converts an entity path canonical string (generally generated
33
 
 * by oh_decode_entitypath()) into an SaHpiEntityPathT structure.
34
 
 * 
35
 
 * Returns: 
36
 
 * SA_OK - normal operation.
37
 
 * SA_ERR_HPI_INVALID_PARAMS - Input pointer(s) NULL.
38
 
 * SA_ERR_HPI_INVALID_DATA - Invalid canonical entity path string.
39
 
 * SA_ERR_HPI_OUT_OF_SPACE - No memory for internal storage.
40
 
 **/
41
 
SaErrorT oh_encode_entitypath(const gchar *epstr, SaHpiEntityPathT *ep)
42
121 
{
43
121 
 	gchar **epathdefs = NULL, **epathvalues = NULL;
44
121 
	gchar *gstr = NULL, *endptr = NULL;
45
121 
        GSList  *epath_list = NULL, *lst = NULL;
46
121 
        int   i, location, num_entities = 0;
47
121 
        SaErrorT  err = SA_OK;
48
121 
	SaHpiEntityT  *entityptr = NULL;
49
121 
	SaHpiTextBufferT tmpbuffer;
50
121 
	SaHpiEntityTypeT eptype;
51
 
52
121 
	if (!epstr || epstr[0] == '\0' || !ep) {
53
1 
		dbg("Invalid parameter.");
54
1 
		return(SA_ERR_HPI_INVALID_PARAMS);
55
 
	}
56
 
57
 
	/* Check for runaway string */
58
120 
	if (strlen(epstr) >  OH_MAX_TEXT_BUFFER_LENGTH) {
59
0 
		dbg("Invalid parameter.");
60
0 
		return(SA_ERR_HPI_INVALID_DATA);
61
 
	}
62
 
63
 
        /* Split out {xxx,yyy} definition pairs */
64
120 
       	gstr = g_strstrip(g_strdup(epstr));
65
120 
	if (gstr == NULL || gstr[0] == '\0') {
66
1 
		dbg("Stripped entity path string is NULL"); 
67
1 
		err = SA_ERR_HPI_INVALID_DATA;
68
1 
		goto CLEANUP;
69
 
	}
70
 
71
119 
	epathdefs = g_strsplit(gstr, EPATHSTRING_END_DELIMITER, -1);
72
119 
	if (epathdefs == NULL) {
73
0 
		dbg("Cannot split entity path string.");
74
0 
		err = SA_ERR_HPI_INTERNAL_ERROR;
75
0 
		goto CLEANUP;
76
 
        }
77
 
78
 
	/* Split out HPI entity type and location strings */
79
340 
	for (i=0; epathdefs[i] != NULL && epathdefs[i][0] != '\0'; i++) {
80
 
81
230 
		epathdefs[i] = g_strstrip(epathdefs[i]);
82
 
		/* Check format - for starting delimiter and a comma */
83
230 
		if ((epathdefs[i][0] != EPATHSTRING_START_DELIMITER_CHAR) || 
84
 
		    (strpbrk(epathdefs[i], EPATHSTRING_VALUE_DELIMITER) == NULL)) {
85
4 
			dbg("Invalid entity path format.");
86
4 
			err = SA_ERR_HPI_INVALID_DATA;
87
4 
			goto CLEANUP;
88
 
		}
89
 
90
226 
		epathvalues = g_strsplit(epathdefs[i],
91
 
                                         EPATHSTRING_VALUE_DELIMITER,
92
 
                                         ELEMENTS_IN_SaHpiEntityT);
93
226 
		epathvalues[0] = g_strdelimit(epathvalues[0], EPATHSTRING_START_DELIMITER, ' ');
94
 
95
 
		/* Find entity type */
96
226 
		oh_init_textbuffer(&tmpbuffer);
97
226 
		oh_append_textbuffer(&tmpbuffer, g_strstrip(epathvalues[0]));
98
226 
		err = oh_encode_entitytype(&tmpbuffer, &eptype);
99
 
100
 
                /* If not an HPI type - support a numeric type. Needed by IPMI Direct plugin */
101
226 
		if (err) {
102
7 
			err = SA_OK;
103
7 
                        int num = strtol(g_strstrip(epathvalues[0]), &endptr, 0);
104
7 
                        if (num <= 0 || endptr[0] != '\0') {
105
4 
                                dbg("Invalid entity type string");
106
4 
                                err = SA_ERR_HPI_INVALID_DATA;
107
4 
                                goto CLEANUP;
108
 
                        }
109
3 
			eptype = num;
110
 
		}
111
 
112
 
		/* Find entity location */
113
222 
		location = strtol(g_strstrip(epathvalues[1]), &endptr, 10);
114
222 
		if (endptr[0] != '\0') {
115
1 
			dbg("Invalid location character");
116
1 
			err = SA_ERR_HPI_INVALID_DATA;
117
1 
			goto CLEANUP;
118
 
                }
119
 
120
 
		/* Save entity path definitions; reverse order */
121
221 
		if (num_entities < SAHPI_MAX_ENTITY_PATH) {
122
221 
			entityptr = (SaHpiEntityT *)g_malloc0(sizeof(*entityptr));
123
221 
			if (entityptr == NULL) {
124
0 
				dbg("No memory.");
125
0 
				err = SA_ERR_HPI_OUT_OF_SPACE;
126
0 
				goto CLEANUP;
127
 
			}
128
 
129
221 
			entityptr->EntityType = eptype;
130
221 
			entityptr->EntityLocation = location;
131
221 
			epath_list = g_slist_prepend(epath_list, (gpointer)entityptr);
132
 
		}
133
221 
		num_entities++;
134
 
	}
135
 
  
136
 
	/* Initialize and write HPI entity path structure */
137
110 
	oh_init_ep(ep);
138
326 
	for (i = 0; epath_list != NULL; i++) {
139
216 
                lst = epath_list;
140
216 
                if (i < SAHPI_MAX_ENTITY_PATH) {
141
216 
                        ep->Entry[i].EntityType =
142
 
                                ((SaHpiEntityT *)(lst->data))->EntityType;
143
216 
                        ep->Entry[i].EntityLocation =
144
 
                                ((SaHpiEntityT *)(lst->data))->EntityLocation;
145
 
                }
146
216 
                epath_list = g_slist_remove_link(epath_list,lst);
147
216 
                g_free(lst->data);
148
216 
		g_slist_free(lst);
149
 
	}
150
 
151
110 
	if (num_entities > SAHPI_MAX_ENTITY_PATH) {
152
0 
		dbg("Too many entity defs");
153
0 
		err = SA_ERR_HPI_INVALID_DATA;
154
 
	}
155
 
156
 
 CLEANUP:
157
120 
	g_free(gstr);
158
120 
	g_strfreev(epathdefs);
159
120 
	g_strfreev(epathvalues);
160
120 
	g_slist_free(epath_list);
161
 
162
120 
	return(err);
163
 
}
164
 
165
 
/**
166
 
 * oh_decode_entitypath:
167
 
 * @ep: Pointer to HPI's entity path structure.
168
 
 * @bigbuf: Location to store canonical entity path string.
169
 
 *
170
 
 * Converts an entity path structure into its canonical string version. 
171
 
 * The canonical string is formed by removing the "SAHPI_ENT_" prefix
172
 
 * from the HPI types, and creating tuples for the entity types.
173
 
 * Order of significance is inverted to make entity paths look more
174
 
 * like Unix directory structure. It is also assumed that {ROOT,0}
175
 
 * exists implicitly before all of these entries. For example:
176
 
 *
177
 
 * {SYSTEM_CHASSIS,2}{PROCESSOR_BOARD,0}
178
 
 *
179
 
 * SAHPI_ENT_ROOT is used to identify end element of an entity path.
180
 
 * Fully populated entity path may not have an SAHPI_ENT_ROOT.
181
 
 * Duplicate names in SaHPIEntityTypeT enumeration aren't handled
182
 
 * and won't be preserved across conversion calls.
183
 
 *
184
 
 * Returns: 
185
 
 * SA_OK - normal case.
186
 
 * SA_ERR_HPI_INVALID_PARAMS - Input pointer(s) NULL.
187
 
 * SA_ERR_HPI_INVALID_DATA - Location value too big for OpenHpi.
188
 
 * SA_ERR_HPI_OUT_OF_SPACE - No memory for internal storage.
189
 
 **/
190
 
SaErrorT oh_decode_entitypath(const SaHpiEntityPathT *ep,
191
 
			      oh_big_textbuffer *bigbuf)
192
114 
{
193
114 
        char  *typestr;
194
114 
 	gchar  *locstr, *catstr;
195
114 
        gchar  typestr_buffer[20];
196
114 
	int    i;
197
114 
	oh_big_textbuffer tmpbuf;
198
114 
	SaErrorT  err = SA_OK;
199
 
200
114 
	if (!bigbuf || !ep) {
201
1 
		dbg("Invalid parameter");
202
1 
		return(SA_ERR_HPI_INVALID_PARAMS);
203
 
	}
204
 
205
113 
	err = oh_init_bigtext(&tmpbuf);
206
113 
	if (err) return(err);
207
 
208
 
#if 0
209
 
	/* Turn off strict HPI EP validation, for IPMI Direct
210
 
           numeric entity type support */
211
 
	if (!oh_valid_ep(ep)) {
212
 
		dbg("Invalid entity path");
213
 
		return(SA_ERR_HPI_INVALID_DATA);
214
 
	}
215
 
#endif
216
 
217
113 
	locstr = (gchar *)g_malloc0(OH_MAX_LOCATION_DIGITS + 1);
218
113 
	if (locstr == NULL) {
219
0 
		dbg("No memory.");
220
0 
		err = SA_ERR_HPI_OUT_OF_SPACE;
221
0 
		goto CLEANUP;
222
 
	}
223
 
        
224
 
        /* Find last element of structure. Disregard ROOT element
225
 
         * and count as last in entity path. */
226
368 
        for (i=0; i<SAHPI_MAX_ENTITY_PATH; i++) {
227
366 
                if (ep->Entry[i].EntityType == SAHPI_ENT_ROOT) {
228
111 
                            break;
229
 
                }
230
 
        }
231
 
232
 
        /* Parse entity path into a string */
233
367 
	for (i--; i >= 0; i--) {
234
255 
                guint num_digits, work_location_num;
235
 
                
236
 
		/* Validate and convert data */
237
255 
                work_location_num = ep->Entry[i].EntityLocation;
238
255 
                for (num_digits=1;
239
 
		     (work_location_num = work_location_num/10) > 0;
240
 
		     num_digits++);
241
 
		
242
255 
		if (num_digits > OH_MAX_LOCATION_DIGITS) {
243
1 
                        dbg("Location value too big");
244
1 
                        err = SA_ERR_HPI_INVALID_DATA;
245
1 
			goto CLEANUP;
246
 
		}
247
254 
                memset(locstr, 0, OH_MAX_LOCATION_DIGITS + 1);
248
254 
                snprintf(locstr, OH_MAX_LOCATION_DIGITS + 1, 
249
 
			 "%d", ep->Entry[i].EntityLocation);
250
 
251
 
                /* Find string for current entity type */
252
254 
		typestr = oh_lookup_entitytype(ep->Entry[i].EntityType);
253
 
254
 
		/* Support numeric entity types - need by IPMI Direct plugin */
255
254 
		if (typestr == NULL) {
256
10 
			snprintf(typestr_buffer, 20, "%d", ep->Entry[i].EntityType);
257
10 
			typestr = typestr_buffer;
258
 
		}
259
 
260
254 
		catstr = g_strconcat(EPATHSTRING_START_DELIMITER,
261
 
				     typestr,
262
 
				     EPATHSTRING_VALUE_DELIMITER,
263
 
				     locstr,
264
 
				     EPATHSTRING_END_DELIMITER,
265
 
				     NULL);
266
 
267
254 
		oh_append_bigtext(&tmpbuf, catstr);
268
254 
		g_free(catstr);
269
 
	}
270
 
271
 
	/* Write string */
272
112 
	oh_init_bigtext(bigbuf);
273
112 
	oh_append_bigtext(bigbuf, (char *)tmpbuf.Data);
274
 
275
 
 CLEANUP:
276
113 
	g_free(locstr);
277
 
278
113 
	return(err);
279
 
}
280
 
281
 
/**
282
 
 * oh_init_ep:
283
 
 * @ep: Pointer to SaHpiEntityPathT structure to initialize.
284
 
 *
285
 
 * Initializes an entity path to all {ROOT,0} elements.
286
 
 *
287
 
 * Returns:
288
 
 * SA_OK - normal operations.
289
 
 * SA_ERR_HPI_INVALID_PARAMS - @ep is NULL.
290
 
 **/
291
 
SaErrorT oh_init_ep(SaHpiEntityPathT *ep)
292
112 
{
293
112 
	 int i;
294
 
295
112 
         if (!ep) {
296
0 
		 dbg("Invalid parameter.");
297
0 
		 return(SA_ERR_HPI_INVALID_PARAMS);
298
 
	 }
299
 
         
300
1904 
         for (i=0; i<SAHPI_MAX_ENTITY_PATH; i++) {
301
1792 
                 ep->Entry[i].EntityType = SAHPI_ENT_ROOT;
302
1792 
                 ep->Entry[i].EntityLocation = 0;
303
 
         }
304
 
305
112 
	 return(SA_OK);
306
 
 }
307
 
308
 
/**
309
 
 * oh_concat_ep:
310
 
 * @dest: Pointer to entity path. Gets appended with @append.
311
 
 * @append: Pointer to entity path to append.
312
 
 *
313
 
 * Concatenate two entity path structures (SaHpiEntityPathT).
314
 
 * @append is appeded to @dest. If @dest doesn't have enough room, @append
315
 
 * will be truncated into @dest.
316
 
 *
317
 
 * Returns:
318
 
 * SA_OK - normal operations.
319
 
 * SA_ERR_HPI_INVALID_PARAMS - @dest is NULL.
320
 
 **/
321
 
SaErrorT oh_concat_ep(SaHpiEntityPathT *dest, const SaHpiEntityPathT *append)
322
16 
{
323
16 
        int i, j;
324
 
325
16 
        if (!dest) {
326
1 
		dbg("Invalid parameter.");
327
1 
		return(SA_ERR_HPI_INVALID_PARAMS);
328
 
	}
329
 
330
15 
        if (!append) return(SA_OK);
331
 
332
96 
        for (i=0; i<SAHPI_MAX_ENTITY_PATH; i++) {
333
94 
                if (dest->Entry[i].EntityType == SAHPI_ENT_ROOT) break;
334
 
        }
335
 
336
68 
        for (j=0; i<SAHPI_MAX_ENTITY_PATH; i++) {
337
63 
                dest->Entry[i].EntityLocation = append->Entry[j].EntityLocation;
338
63 
                dest->Entry[i].EntityType = append->Entry[j].EntityType;
339
63 
                if (append->Entry[j].EntityType == SAHPI_ENT_ROOT) break;
340
54 
                j++;
341
 
        }
342
 
	
343
14 
        return(SA_OK);
344
 
}
345
 
346
 
/**
347
 
 * oh_valid_ep:
348
 
 * @ep: Pointer to an SaHpiEntityPathT structure.
349
 
 *
350
 
 * Check an entity path to make sure it does not contain
351
 
 * any invalid entity types. The entity path is checked up to
352
 
 * the first root element or to the end of the array, if there
353
 
 * are no root elements in the structure.
354
 
 *
355
 
 * Returns:
356
 
 * SAHPI_TRUE - Valid entity path.
357
 
 * SAHPI_FALSE - Invalid entity path.
358
 
 **/
359
 
SaHpiBoolT oh_valid_ep(const SaHpiEntityPathT *ep)
360
13 
{
361
13 
	int i;
362
 
363
212 
        for (i=0; i<SAHPI_MAX_ENTITY_PATH; i++) {
364
200 
		if (ep->Entry[i].EntityType == SAHPI_ENT_ROOT) break;
365
 
/* FIXME:: Add explicit check for types with HPI resolves its conflicts with IPMI types */
366
 
/* Right now we're allowing users to specify any numeric type */
367
 
#if 0
368
 
		char *typestr;
369
 
370
 
		typestr = oh_lookup_entitytype(ep->Entry[i].EntityType);
371
 
		if (typestr == NULL) return(SAHPI_FALSE);
372
 
#endif
373
 
        }
374
 
375
13 
        return(SAHPI_TRUE);
376
 
}
377
 
378
 
/**
379
 
 * oh_set_ep_location:
380
 
 * @ep: Pointer to entity path to work on
381
 
 * @et: entity type to look for
382
 
 * @ei: entity location to set when entity type is found
383
 
 *
384
 
 * Set an location number in the entity path given at the first
385
 
 * position (from least significant to most) the specified entity type is found.
386
 
 *
387
 
 * Returns:
388
 
 * SA_OK - normal operations.
389
 
 * SA_ERR_HPI_INVALID_PARAMS - @ep is NULL.
390
 
 * SA_ERR_HPI_INVALID_DATA - @ep invalid entity path.
391
 
 **/
392
 
SaErrorT oh_set_ep_location(SaHpiEntityPathT *ep, SaHpiEntityTypeT et, SaHpiEntityLocationT ei)
393
14 
{
394
14 
        int i;
395
 
396
14 
	if (!ep) {
397
1 
		dbg("Invalid parameter.");
398
1 
		return(SA_ERR_HPI_INVALID_PARAMS);
399
 
	}
400
 
401
13 
	if (!oh_valid_ep(ep)) {
402
0 
		dbg("Invalid entity path");
403
0 
		return(SA_ERR_HPI_INVALID_DATA);
404
 
	}
405
 
406
95 
        for (i=0; i<SAHPI_MAX_ENTITY_PATH; i++) {
407
92 
                if (ep->Entry[i].EntityType == et) {
408
9 
                        ep->Entry[i].EntityLocation = ei;
409
9 
                        break;
410
 
                } else {
411
83 
			if (ep->Entry[i].EntityType == SAHPI_ENT_ROOT) break;
412
 
                }
413
 
        }
414
 
415
13 
        return(SA_OK);
416
 
}
417
 
418
 
/**
419
 
 * oh_cmp_ep:
420
 
 * @ep1: Pointer to entity path structure.
421
 
 * @ep2: Pointer to entity path structure.
422
 
 *
423
 
 * Compares two entity paths up to their root element.
424
 
 * To be equal, they must have the same number of elements and each element
425
 
 * (type and location pair) must be equal to the corresponding element
426
 
 * in the other entity path.
427
 
 *
428
 
 * Returns:
429
 
 * SAHPI_TRUE - if equal.
430
 
 * SAHPI_FALSE - if not equal.
431
 
 **/
432
 
SaHpiBoolT oh_cmp_ep(const SaHpiEntityPathT *ep1, const SaHpiEntityPathT *ep2)
433
26 
{
434
26 
        unsigned int i, j;
435
 
        
436
26 
        if (!ep1 || !ep2) {
437
3 
                dbg("Invalid parameter.");
438
3 
                return(SAHPI_FALSE);
439
 
        }
440
 
441
207 
        for (i=0; i <SAHPI_MAX_ENTITY_PATH; i++) {
442
201 
                if (ep1->Entry[i].EntityType == SAHPI_ENT_ROOT) {
443
17 
                        i++;
444
17 
                        break;                                
445
 
                }
446
 
        }
447
 
448
207 
        for (j=0; j<SAHPI_MAX_ENTITY_PATH; j++) {
449
201 
                if (ep2->Entry[j].EntityType == SAHPI_ENT_ROOT) {
450
17 
                        j++;
451
17 
                        break;
452
 
                }
453
 
        }
454
 
455
23 
        if (i != j) return(SAHPI_FALSE);
456
 
457
212 
        for (i=0; i<j; i++) {
458
193 
                if (ep1->Entry[i].EntityType != ep2->Entry[i].EntityType ||
459
 
                    ep1->Entry[i].EntityLocation != ep2->Entry[i].EntityLocation) {
460
 
                        /* dbg("Entity element %d: EP1 {%d,%d} != EP2 {%d,%d}", i, 
461
 
                            ep1->Entry[i].EntityType,
462
 
                            ep1->Entry[i].EntityLocation,
463
 
                            ep2->Entry[i].EntityType,
464
 
                            ep2->Entry[i].EntityLocation); */
465
2 
                        return(SAHPI_FALSE);
466
 
                }
467
 
        }
468
 
        
469
19 
        return(SAHPI_TRUE);
470
 
}
471
 
472
 
/**
473
 
 * oh_fprint_ep:
474
 
 * @ep: Pointer to entity path stucture.
475
 
 *
476
 
 * Prints the string form of an entity path structure.
477
 
 * The MACRO oh_print_ep(), uses this function to print to STDOUT.
478
 
 *
479
 
 * Returns:
480
 
 * SA_OK - normal operations.
481
 
 * SA_ERR_HPI_INVALID_PARAMS - @ep is NULL.
482
 
 **/
483
 
SaErrorT oh_fprint_ep(FILE *stream, const SaHpiEntityPathT *ep, int offsets)
484
6 
{
485
6 
	oh_big_textbuffer bigbuf1, bigbuf2;
486
6 
        SaErrorT err;
487
 
	
488
6 
        if (!ep) {
489
1 
		dbg("Invalid parameter.");
490
1 
		return(SA_ERR_HPI_INVALID_PARAMS);
491
 
        }
492
 
493
5 
	err = oh_init_bigtext(&bigbuf1);
494
5 
	if (err) return(err);
495
5 
	err = oh_init_bigtext(&bigbuf2);
496
5 
	if (err) return(err);
497
 
498
5 
	err = oh_append_offset(&bigbuf1, offsets);
499
5 
	if (err) return(err);
500
5 
	err = oh_append_bigtext(&bigbuf1, "Entity Path: ");
501
5 
	if (err) return(err);
502
 
	
503
5 
	err = oh_decode_entitypath(ep, &bigbuf2);
504
5 
	if (err) return(err);
505
 
506
5 
	err = oh_append_bigtext(&bigbuf1, (char *)bigbuf2.Data);
507
5 
	if (err) return(err);
508
5 
	err = oh_append_bigtext(&bigbuf1, "\n");
509
5 
	if (err) return(err);
510
 
511
5 
	fprintf(stream, "%s", bigbuf1.Data);
512
 
513
5 
        return(SA_OK);
514
 
}
515
 
516
 
/**********************************************************************
517
 
 * oh_derive_string:
518
 
 * @ep - Pointer to entity's HPI SaHpiEntityPathT.
519
 
 * @str - Un-normalized character string.
520
 
 *
521
 
 * This function "normalizes" a string (such as an SNMP OID) 
522
 
 * based on entity path. Starting from the end of @str, this routine 
523
 
 * replaces the letter 'x', with the last location number of entity path,
524
 
 * the process is repeated until all 'x' are replaced by an location number.
525
 
 * For example,
526
 
 * 
527
 
 * @str = ".1.3.6.1.4.1.2.3.x.2.22.1.5.1.1.5.x"
528
 
 * @ep = {SAHPI_ENT_CHASSIS, 51}{SAHPI_ENT_SBC_BLADE, 3}
529
 
 *
530
 
 * Returns a normalized string of ".1.3.6.1.4.1.2.3.51.2.22.1.5.1.1.5.3".
531
 
 *
532
 
 * If @str does not contain any 'x' characters, this routine still 
533
 
 * allocates memory and returns a "normalized" string. In this case,
534
 
 * the normalized string is identical to @str.
535
 
 *
536
 
 * Note!
537
 
 * Caller of this routine MUST g_free() the returned normalized string
538
 
 * when finished with it.
539
 
 *
540
 
 * Returns:
541
 
 * Pointer to normalize string - Normal case.
542
 
 * NULL - Error.
543
 
 **********************************************************************/
544
 
gchar * oh_derive_string(SaHpiEntityPathT *ep, const gchar *str)
545
2 
{
546
2 
        gchar *new_str = NULL, *str_walker = NULL;
547
2 
        gchar **fragments = NULL, **str_nodes = NULL;
548
2 
        guint num_epe, num_blanks, str_strlen = 0;
549
2 
        guint total_num_digits, i, work_location_num, num_digits;
550
 
551
2 
	if (!ep || !str) {
552
0 
		dbg("NULL parameter.");
553
0 
		return(NULL);
554
 
	}
555
 
556
2 
        for (num_epe = 0;
557
 
             ep->Entry[num_epe].EntityType != SAHPI_ENT_ROOT && num_epe < SAHPI_MAX_ENTITY_PATH;
558
 
             num_epe++);
559
 
        /* trace("Number of elements in entity path: %d", num_epe); */
560
 
561
2 
        if (num_epe == 0) {
562
0 
                dbg("Entity Path is null.");
563
0 
                return(NULL);
564
 
        }
565
2 
        if ((str_strlen = strlen(str)) == 0) return(NULL); /* Str is zero length */
566
2 
        if (!strrchr(str, OH_DERIVE_BLANK_CHAR)) return(g_strdup(str)); /* Nothing to replace */
567
 
568
8 
        for (num_blanks=0, i=0; i<str_strlen; i++) {
569
7 
                if (str[i] == OH_DERIVE_BLANK_CHAR) num_blanks++;
570
 
        }
571
 
        /* trace("Number of blanks in str: %d, %s", num_blanks, str); */
572
1 
        if (num_blanks > num_epe) {
573
0 
                dbg("Number of replacments=%d > entity path elements=%d", num_blanks, num_epe);
574
0 
                return(NULL);
575
 
        }
576
 
577
1 
        fragments = g_strsplit(str, OH_DERIVE_BLANK_STR, - 1);
578
1 
        if (!fragments) { dbg("Cannot split string"); goto CLEANUP; }
579
1 
        str_nodes = g_malloc0((num_blanks + 1) * sizeof(gchar **));
580
1 
        if (!str_nodes) { dbg("Out of memory."); goto CLEANUP; }
581
1 
        total_num_digits = 0;
582
3 
        for (i=0; i<num_blanks; i++) {
583
2 
                work_location_num = ep->Entry[num_blanks-1-i].EntityLocation;
584
2 
                for (num_digits = 1;
585
 
                     (work_location_num = work_location_num/10) > 0; num_digits++);
586
2 
                str_nodes[i] = g_malloc0((num_digits+1) * sizeof(gchar));
587
2 
                if (!str_nodes[i]) {dbg("Out of memory."); goto CLEANUP;}
588
2 
                snprintf(str_nodes[i], (num_digits + 1) * sizeof(gchar), "%d", 
589
 
			 ep->Entry[num_blanks - 1 - i].EntityLocation);
590
 
                /* trace("Location number: %s", str_nodes[i]); */
591
2 
                total_num_digits = total_num_digits + num_digits;
592
 
        }
593
 
594
1 
        new_str = g_malloc0((str_strlen-num_blanks + total_num_digits + 1) * sizeof(gchar));
595
1 
        if (!new_str) { dbg("Out of memory."); goto CLEANUP; }
596
1 
        str_walker = new_str;
597
4 
        for (i=0; fragments[i]; i++) {
598
3 
                str_walker = strcpy(str_walker, fragments[i]);
599
3 
                str_walker = str_walker + strlen(fragments[i]);
600
3 
                if (str_nodes[i]) {
601
2 
                        str_walker = strcpy(str_walker, str_nodes[i]);
602
 
                        /* trace("Location number: %s", str_nodes[i]); */
603
2 
                        str_walker = str_walker + strlen(str_nodes[i]);
604
 
                }
605
 
                /* trace("New str: %s", new_str); */
606
 
        }
607
 
608
 
CLEANUP:
609
1 
        g_strfreev(fragments);
610
1 
        g_strfreev(str_nodes);
611
 
612
1 
        return(new_str);
613
 
}
614