2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: exksh_tbls.c /main/4 1995/11/01 15:54:33 rswiston $ */
24 /* Copyright (c) 1991, 1992 UNIX System Laboratories, Inc. */
25 /* All Rights Reserved */
27 /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF */
28 /* UNIX System Laboratories, Inc. */
29 /* The copyright notice above does not evidence any */
30 /* actual or intended publication of such source code. */
36 #include <sys/types.h>
39 #include "exksh_tbls.h"
40 #include "exksh_prpar.h"
46 static int struct_size;
48 int Pr_tmpnonames = 0;
50 static const char *Str_close_curly = "}";
51 static const char *Str_open_curly = "{";
53 #define MALMEMBERS (4) /* initial number of members of malloc'ed array to malloc */
55 #define UPPER(C) (islower(C) ? toupper(C) : (C))
56 #define isvarchar(C) (isalnum(C) || ((C) == '_'))
59 * Some of our test programs use xk_parse() to parse cdata from command
60 * lines. This has the drawback that anys or externals will get a malloc'ed
61 * buffer for their char * on the send side, which would not normally be
62 * freed, because xk_free() knows that such any's usually point into the
63 * ubuf rather than being malloced. On the receive side, this would be
64 * true even in our test program. So, on the send side, we keep a table
65 * of any any or external char * that is malloc'ed, and xk_free checks
66 * this table before free'ing the given item. After being freed, the
67 * stack is decremented for efficiency.
72 static char **Anytbl = NULL;
73 static int Nanytbl = 0;
74 static int Maxanytbl = 0;
87 static struct special *Special = NULL;
88 static int Nspecs = 0;
90 static char **Dont = NULL;
91 static int Ndont, Sdont;
102 for (i = 0; i < Nspecs; i++) {
103 if (strcmp(Special[i].name, name) == 0) {
106 return(Special[i].print);
108 return(Special[i].free);
110 return(Special[i].parse);
126 for (i = 0; i < Nspecs; i++)
127 if (strcmp(Special[i].name, name) == 0)
131 Special = (struct special *) malloc(sizeof(struct special));
132 Special[0].name = strdup(name);
136 Special = (struct special *) realloc(Special, (Nspecs + 1) * sizeof(struct special));
137 Special[i].name = strdup(name);
143 Special[i].free = free;
144 Special[i].parse = parse;
145 Special[i].print = print;
150 * xk_parse: Takes a pointer to a structure member table, a pointer
151 * to a buffer containing an ascii representation of the structure
152 * represented by the table pointer, and the number of pointers saved
153 * from previous recursive calls to this routine, and parses the
156 * Increments buf to the last point at which it read a character,
157 * and returns SUCCESS or FAIL.
168 memtbl_t *(*tbl_find)() )
172 int skind, delim_type;
173 long val = 0; /* used for choice selection */
176 int nmal; /* number of members malloc'ed arrays */
184 errmsg=strdup(GETMESSAGE(8,1,
185 "xk_parse: A NULL 'type' table was specified\n"));
186 fprintf(stderr, errmsg);
193 * If this is supposed to be a pointer, and we have a string that
194 * starts with "P" and a number then we should take the pointer
195 * itself. This is done by stripping off the 'p' and parsing it as a
198 * Further, if it starts with an '&', then we want the address of
199 * a variable, use fsym() to find it.
201 if (((tbl->flags & F_TYPE_IS_PTR) || ((tbl->ptr + nptr) > 0)) &&
202 (((UPPER((*buf)[0]) == 'P') && isdigit((*buf)[1])) || ((*buf)[0] == '&'))) {
203 if ((*buf)[0] == '&') {
207 for (start = *buf; isvarchar(*buf[0]); (*buf)++)
209 if ((((unsigned long *) p)[0] = fsym(start, -1)) == NULL)
214 RIF(xk_par_int(buf, (long *)p, pass));
216 if (Ndont == Sdont) {
218 Dont = (char **) realloc(Dont, (Sdont + 20) * sizeof(char *));
220 Dont = (char **) malloc((Sdont + 20) * sizeof(char *));
222 errmsg = strdup(GetSharedMsg(DT_ALLOC_FAILURE));
229 Dont[Ndont++] = ((char **) p)[0];
232 if (tbl->tname && (spec_parse = find_special(SPEC_PARSE, tbl->tname)))
233 return(spec_parse(tbl, buf, p, nptr, sub, pass, tbl_find));
234 if (tbl->name && (spec_parse = find_special(SPEC_PARSE, tbl->name)))
235 return(spec_parse(tbl, buf, p, nptr, sub, pass, tbl_find));
237 if (sub > 0 && tbl->subscr > 0) {
240 errmsg=strdup(GETMESSAGE(8,2,
241 "xk_parse: Multiple array subscripts are not handled in '%s'\n"));
242 fprintf(stderr, errmsg, tbl->name);
248 * If there is exactly one pointer associated with this
249 * member, and no length delimiters, and no subscripts,
250 * or there are multiple pointers,
251 * then malloc space for the structure and call ourself
254 if ((nptr > 1 && tbl->delim != 0) || (nptr == 1 && tbl->delim == 0 && tbl->subscr == 0)) {
255 if (PARPEEK(buf, ",") || PARPEEK(buf, Str_close_curly)) {
256 ((char **)p)[0] = NULL;
259 errmsg=strdup(GetSharedMsg(DT_XK_PARSE_SET_NULL));
260 fprintf(stderr, errmsg, tbl->name);
265 if (xk_parpeek(buf, "NULL")) {
266 RIF(xk_parexpect(buf, "NULL"));
267 ((char **)p)[0] = NULL;
270 errmsg=strdup(GetSharedMsg(
271 DT_XK_PARSE_SET_NULL));
272 fprintf(stderr, errmsg, tbl->name);
278 if ((((char **)p)[0] = malloc(tbl->size)) == NULL) {
283 errmsg=strdup(GETMESSAGE(8,3,
284 "xk_parse: Setting '%s' to malloc'ed address 0x%x, of size %d\n"));
285 fprintf(stderr,errmsg,tbl->name, ((char **)p)[0], tbl->size);
288 return(xk_parse(tbl, buf, ((char **)p)[0], nptr-1-tbl->ptr, sub, pass, tbl_find));
291 * If there is exactly one pointer level, or one subscripting level,
292 * and there is a delimiter,
293 * and no subscript, then we are a length delimited malloced array.
296 if (tbl->delim != 0 && ((nptr == 1 && tbl->subscr == 0) ||
297 (nptr == 0 && tbl->subscr != 0 && tbl->kind != K_STRING))) {
299 if (tbl->subscr == 0) {
300 if (PARPEEK(buf, ",") || PARPEEK(buf, Str_close_curly)) {
301 ((char **)p)[0] = NULL;
304 errmsg=strdup(GETMESSAGE(8,4,
305 "xk_parse: Setting malloc'ed array '%s' to NULL\n"));
306 fprintf(stderr, errmsg, tbl->name);
311 if (xk_parpeek(buf, "NULL")) {
312 RIF(xk_parexpect(buf, "NULL"));
313 ((char **)p)[0] = NULL;
316 errmsg=strdup(GetSharedMsg(
317 DT_XK_PARSE_SET_NULL));
318 fprintf(stderr, errmsg, tbl->name);
324 if ((np = malloc(nmal*tbl->size)) == NULL) {
327 ((char **)p)[0] = np;
330 errmsg=strdup(GETMESSAGE(8,5,
331 "xk_parse: Setting member '%s' to malloc'ed pointer 0x%x, of size %d\n"));
332 fprintf(stderr, errmsg, tbl->name, np, 4*tbl->size);
339 RIF(PAREXPECT(buf, Str_open_curly));
343 while (PARPEEK(buf, Str_close_curly) == FALSE) {
344 if (tbl->subscr == 0 && i >= nmal) {
346 if((np = realloc(np, nmal*tbl->size)) == NULL) {
349 ((char **)p)[0] = np;
351 errmsg=strdup(GetSharedMsg(
352 DT_XK_PARSE_ARRAY_OVERFLOW));
353 fprintf(stderr, errmsg, tbl->name, nmal, nmal*tbl->size);
356 } else if (tbl->subscr > 0 && i > tbl->subscr) {
359 errmsg=strdup(GETMESSAGE(8,6,
360 "xk_parse: The array '%s' overflowed at element number %d\n"));
361 fprintf(stderr, errmsg, tbl->name, i);
367 errmsg=strdup(GETMESSAGE(8,7,
368 "xk_parse: Parsing array element [%d] of '%s' into address 0x%x\n"));
369 fprintf(stderr, errmsg, i, tbl->name, &np[i*tbl->size]);
374 if (PARPEEK(buf, ",") == FALSE) {
375 if (PARPEEK(buf, Str_close_curly) == FALSE) {
376 RIF(PAREXPECT(buf, ","));
381 RIF(PAREXPECT(buf, ","));
385 RIF(xk_parse(tbl, buf, &np[i*tbl->size], nptr ? -1 : 0,
386 0, (void *)-1, tbl_find));
391 RIF(PAREXPECT(buf, Str_close_curly));
396 * If there is no delimiter, and there are two levels of pointer,
397 * then we are a NULL terminated array of pointers
399 if (tbl->delim == 0 &&
400 ((nptr == 2 && sub == 0) || (sub == 1 && nptr == 1))) {
402 * malloc a few members, realloc as needed
405 if ((((char **)p)[0] = malloc(nmal*tbl->size)) == NULL) {
409 RIF(PAREXPECT(buf, Str_open_curly));
412 while (PARPEEK(buf, Str_close_curly) == FALSE) {
415 if ((((char **)p)[0] = realloc(((char **)p)[0], nmal*tbl->size)) == NULL) {
419 errmsg=strdup(GetSharedMsg(
420 DT_XK_PARSE_ARRAY_OVERFLOW));
421 fprintf(stderr, errmsg, tbl->name, nmal, nmal*tbl->size);
427 errmsg=strdup(GETMESSAGE(8,8,
428 "xk_parse: Parsing array element [%d] of '%s'\n"));
429 fprintf(stderr, errmsg, i, tbl->name);
433 RIF(PAREXPECT(buf, ","));
436 RIF(xk_parse(tbl, buf, &p[i*tbl->size],
437 nptr == 2 ? -2 : -1, 0, (void *)-1,
442 RIF(PAREXPECT(buf, Str_close_curly));
444 ((char **)p)[i*tbl->size] = NULL;
450 RIF(xk_par_int(buf, &val, pass));
451 ((unsigned char *)p)[0] = val;
454 RIF(xk_par_int(buf, &val, pass));
455 ((ushort *)p)[0] = val;
458 RIF(xk_par_int(buf, &val, pass));
462 RIF(xk_par_int(buf, (long *)p, pass));
467 RIF(xk_par_chararr(buf, (char *)p, (int *)&val));
468 if (tbl->delim <= 0 && val > -1) {
473 RIF(xk_par_charstr(buf, (char **)p, (int *)&val));
474 /* If this is not a delimited char string,
475 * then it must be null terminated
477 if (tbl->delim <= 0 && val > -1) {
478 ((char **) p)[0][val] = '\0';
484 ntbl = tbl_find(tbl->tname, tbl->tbl, tbl->id);
485 RIF(xk_parse(ntbl, buf, p, nptr, 0, pass, tbl_find));
489 RIF(PAREXPECT(buf, Str_open_curly));
491 ntbl = tbl_find(tbl->tname, tbl->tbl, tbl->id);
493 for (i = 0; ntbl[i].name != NULL; i++) {
494 _Delim = xk_get_pardelim(&ntbl[i], p);
495 if (ntbl[i].kind >= K_DSHORT) {
496 skind = ntbl[i].kind;
497 pp = p + ntbl[i].offset;
501 delim_type = ntbl[i].kind;
503 if (i && ntbl[i-1].kind < K_DSHORT) {
505 if (PARPEEK(buf, ",") == FALSE) {
506 if (PARPEEK(buf, Str_close_curly) == FALSE) {
507 RIF(PAREXPECT(buf, ","));
512 RIF(PAREXPECT(buf, ","));
518 errmsg=strdup(GETMESSAGE(8,9,
519 "xk_parse: Parsing member '%s' into location 0x%x\n"));
520 fprintf(stderr, errmsg, ntbl[i].name, p + ntbl[i].offset);
523 if (xk_parse(&ntbl[i], buf, p+ntbl[i].offset, nptr, sub, pass, tbl_find) == FAIL) {
526 errmsg=strdup(GetSharedMsg(
528 fprintf(stderr, errmsg, ntbl[i].name);
537 if (delim_type == K_STRING)
538 ((short *)pp)[0] = strglen;
540 ((short *)pp)[0] = struct_size;
543 if (delim_type == K_STRING)
544 ((int *)pp)[0] = strglen;
546 ((int *)pp)[0] = struct_size;
549 if (delim_type == K_STRING)
550 ((long *)pp)[0] = strglen;
552 ((long *)pp)[0] = struct_size;
559 RIF(PAREXPECT(buf, Str_close_curly));
563 if (strncmp(tbl[-1].name, "ch_", 3) != 0) {
566 errmsg=strdup(GETMESSAGE(8,10,
567 "xk_parse: Cannot determine the choice in '%s'\n"));
568 fprintf(stderr, errmsg, tbl->name);
573 ntbl = tbl_find(tbl->tname, tbl->tbl, tbl->id);
575 RIF(PAREXPECT(buf, Str_open_curly));
577 for (i = 0; ntbl[i].name != NULL; i++) {
578 if (xk_parpeek(buf, ntbl[i].name) == TRUE) {
579 RIF(xk_parexpect(buf, ntbl[i].name));
580 ((long *)(p - sizeof(long)))[0] = ntbl[i].choice;
583 errmsg=strdup(GETMESSAGE(8,11,
584 "xk_parse: Parsing union member '%s' into location 0x%x\n"));
585 fprintf(stderr, errmsg, ntbl[i].name, p + ntbl[i].offset);
588 if (xk_parse(&ntbl[i], buf, p, nptr, sub, pass, tbl_find) == FAIL) {
591 errmsg=strdup(GetSharedMsg(
593 fprintf(stderr, errmsg, ntbl[i].name);
602 RIF(PAREXPECT(buf, Str_close_curly));
620 memtbl_t *dtbl = &tbl[tbl->delim];
623 if (tbl->delim == 0) {
628 errmsg=strdup(GETMESSAGE(8,12,
629 "xk_get_delim: The delimiter for field '%s' is field '%s'\n"));
630 fprintf(stderr, errmsg, tbl->name, dtbl->name);
634 switch (dtbl->kind) {
637 return(((long *)p)[0]);
639 return(((char *)p)[0]);
642 return(((short *)p)[0]);
645 return(((int *)p)[0]);
649 errmsg=strdup(GETMESSAGE(8,13,
650 "xk_get_delim: Cannot find a delimiter value in '%s'\n"));
651 fprintf(stderr, errmsg, tbl->name);
664 memtbl_t *dtbl = &tbl[tbl->delim];
667 if (tbl->delim == 0) {
672 errmsg=strdup(GETMESSAGE(8,14,
673 "xk_get_pardelim: The delimiter for field '%s' is field '%s'\n"));
674 fprintf(stderr, errmsg, tbl->name, dtbl->name);
678 switch (dtbl->kind) {
682 return(((long *)p)[0]);
686 return(((char *)p)[0]);
688 return(((short *)p)[0]);
692 return(((int *)p)[0]);
696 errmsg=strdup(GETMESSAGE(8,15,
697 "xk_get_pardelim: Cannot find a delimiter value in '%s'\n"));
698 fprintf(stderr, errmsg, tbl->name);
706 * xk_print: Takes a pointer to a structure member table, a pointer
707 * to a buffer big enough to hold an ascii representation of the structure
708 * represented by the table pointer, and a pointer to a structure to
709 * be filled in, and the number of pointers saved
710 * from previous recursive calls to this routine, and prints the
713 * Increments buf to the last point at which it wrote a character,
714 * and returns SUCCESS or FAIL.
726 memtbl_t *(*tbl_find)() )
730 long val; /* used for choice selection */
737 *buf += lsprintf(*buf, "NULL");
743 errmsg=strdup(GETMESSAGE(8,16,
744 "xk_print: A NULL 'type' table was specified\n"));
745 fprintf(stderr, errmsg);
750 if (tbl->tname && (spec_print = find_special(SPEC_PRINT, tbl->tname)))
751 return(spec_print(tbl, buf, p, nptr, sub, pass, tbl_find));
752 if (tbl->name && (spec_print = find_special(SPEC_PRINT, tbl->name)))
753 return(spec_print(tbl, buf, p, nptr, sub, pass, tbl_find));
755 if (sub > 0 && tbl->subscr > 0) {
758 errmsg=strdup(GETMESSAGE(8,17,
759 "xk_print: Multiple array subscripts are not handled in '%s'\n"));
760 fprintf(stderr, errmsg, tbl->name);
766 * If there is exactly one pointer associated with this
767 * member, and no length delimiters, and no subscripts,
768 * or there are multiple pointers,
769 * then dereference the structure and call ourself
772 if ((nptr > 1 && tbl->delim != 0) || (nptr == 1 && tbl->delim == 0 && tbl->subscr == 0)) {
775 errmsg=strdup(GETMESSAGE(8,18,
776 "xk_print: Dereferencing '%s' to address 0x%x\n"));
777 fprintf(stderr, errmsg, tbl->name, ((char **)p)[0]);
780 return(xk_print(tbl, buf, ((char **)p)[0], nptr-1-tbl->ptr, sub, pass, tbl_find));
783 * If there is exactly one pointer level, or one subscripting level,
784 * and there is a delimiter,
785 * and no subscript, then we are a length delimited array.
787 if (tbl->delim != 0 && ((nptr == 1 && tbl->subscr == 0) ||
788 nptr == 0 && tbl->subscr != 0 && tbl->kind != K_STRING)) {
792 errmsg=strdup(GETMESSAGE(8,19,
793 "xk_print: The delimiter for '%s' is %d\n"));
794 fprintf(stderr, errmsg, tbl->name, delim);
797 if (tbl->subscr == 0) {
798 np = ((char **)p)[0];
801 errmsg=strdup(GETMESSAGE(8,20,
802 "xk_print: Using the pointer 0x%x as an array\n"));
803 fprintf(stderr, errmsg, np);
810 *buf += lsprintf(*buf, "NULL");
813 *buf += lsprintf(*buf, Str_open_curly);
814 for (i = 0; i < delim; i++) {
817 errmsg=strdup(GETMESSAGE(8,21,
818 "xk_print: Printing array level %d of member '%s' at location 0x%x\n"));
819 fprintf(stderr, errmsg, i, tbl->name, &np[i*tbl->size]);
823 *buf += lsprintf(*buf, ", ");
824 RIF(xk_print(tbl, buf, &np[i*tbl->size], nptr ? -1 : 0,
825 0, (void *)-1, tbl_find));
827 *buf += lsprintf(*buf, Str_close_curly);
831 * If there is no delimiter, and there are two levels of pointer,
832 * then we are a NULL terminated array.
834 if (tbl->delim == 0 &&
835 ((nptr == 2 && sub == 0) || (sub == 1 && nptr == 1))) {
836 *buf += lsprintf(*buf, Str_open_curly);
837 for (i = 0; ((char **)p)[i*tbl->size] != NULL; i++) {
839 *buf += lsprintf(*buf, ", ");
842 errmsg=strdup(GETMESSAGE(8,22,
843 "xk_print: Printing array level %d of member '%s'\n"));
844 fprintf(stderr, errmsg, i, tbl->name);
847 RIF(xk_print(tbl, buf, ((char **)p)[i*tbl->size],
848 nptr-(!sub), 0, (void *)-1, tbl_find));
850 *buf += lsprintf(*buf, Str_close_curly);
854 if (!Pr_tmpnonames && (Pr_format & PRNAMES)) {
861 *buf += lsprintf(*buf, "%s=", tbl->name);
869 RIF(xk_prin_int(tbl, buf, (unsigned long *)p));
874 RIF(xk_prin_hexstr(buf, (char *)p, delim));
876 RIF(xk_prin_hexstr(buf, ((char **)p)[0], delim));
880 RIF(xk_prin_nts(buf, (char *)p));
882 RIF(xk_prin_nts(buf, ((char **)p)[0]));
887 ntbl = tbl_find(tbl->tname, tbl->tbl, tbl->id);
888 return(xk_print(ntbl, buf, p, nptr, 0, pass, tbl_find));
890 *buf += lsprintf(*buf, Str_open_curly);
891 ntbl = tbl_find(tbl->tname, tbl->tbl, tbl->id);
892 for (i = 0; ntbl[i].name != NULL; i++) {
893 _Delim = xk_get_delim(&ntbl[i], p);
896 errmsg=strdup(GETMESSAGE(8,23,
897 "xk_print: Printing member '%s' at location 0x%x\n"));
898 fprintf(stderr, errmsg, ntbl[i].name, p+ntbl[i].offset);
901 RIF(xk_print(&ntbl[i], buf, p+ntbl[i].offset, nptr, sub, pass, tbl_find));
902 if (ntbl[i].kind < K_DSHORT && ntbl[i+1].name != NULL)
903 *buf += lsprintf(*buf, ", ");
905 *buf += lsprintf(*buf, Str_close_curly);
908 if (strncmp(tbl[-1].name, "ch_", 3) != 0) {
911 errmsg=strdup(GETMESSAGE(8,24,
912 "xk_print: Cannot determine the choice in '%s'\n"));
913 fprintf(stderr, errmsg, tbl->name);
918 val = *((long *)(p - sizeof(long)));
919 ntbl = tbl_find(tbl->tname, tbl->tbl, tbl->id);
920 *buf += lsprintf(*buf, Str_open_curly);
921 for (i = 0; ntbl[i].name != NULL; i++) {
922 if (ntbl[i].choice == val) {
923 *buf += lsprintf(*buf, "%s ", ntbl[i].name);
926 errmsg=strdup(GETMESSAGE(8,25,
927 "xk_print: Printing union member '%s' into location 0x%x\n"));
928 fprintf(stderr, errmsg, ntbl[i].name, p + ntbl[i].offset);
931 RIF(xk_print(&ntbl[i], buf, p, nptr, sub, pass, tbl_find));
935 *buf += lsprintf(*buf, Str_close_curly);
948 * xk_free: Takes a pointer to a structure member table, and
949 * free any malloc'ec elements in it at all levels.
950 * Returns SUCCESS or FAIL.
952 * Contains an optimization that if a structure or union contains a
953 * type that is a simple type and nptr is zero, does not do a recursive call.
962 memtbl_t *(*tbl_find)() )
966 long val; /* used for choice selection */
975 errmsg=strdup(GETMESSAGE(8,26,
976 "xk_free: A NULL 'type' table was specified\n"));
977 fprintf(stderr, errmsg);
982 if (tbl->tname && (spec_free = find_special(SPEC_FREE, tbl->tname)))
983 return(spec_free(tbl, p, nptr, sub, tbl_find));
984 if (tbl->name && (spec_free = find_special(SPEC_FREE, tbl->name)))
985 return(spec_free(tbl, p, nptr, sub, tbl_find));
987 if ((tbl->flags & F_TYPE_IS_PTR) || (nptr > 0)) {
988 for (i = Ndont - 1; i >= 0; i--) {
989 if (Dont[i] == ((char **) p)[0]) {
990 for ( ; i < Ndont - 1; i++)
991 Dont[i] = Dont[i + 1];
997 if (sub > 0 && tbl->subscr > 0) {
1000 errmsg=strdup(GETMESSAGE(8,27,
1001 "xk_free: Multiple array subscripts are not handled in '%s'\n"));
1002 fprintf(stderr, errmsg, tbl->name);
1008 * If there is exactly one pointer associated with this
1009 * member, and no length delimiters, and no subscripts,
1010 * or there are multiple pointers,
1011 * then recursively call ourselves on the structure, then
1012 * free the structure itself.
1014 if ((nptr > 1 && tbl->delim != 0) || (nptr == 1 && tbl->delim == 0 && tbl->subscr == 0)) {
1015 if (((char **)p)[0] != NULL) {
1016 RIF(xk_free(tbl, ((char **)p)[0], nptr-1-tbl->ptr, sub, tbl_find));
1017 free(((char **)p)[0]);
1020 errmsg=strdup(GETMESSAGE(8,28,
1021 "xk_free: The member '%s' at location 0x%x was freed and set to NULL\n"));
1022 fprintf(stderr, errmsg, tbl->name, ((char **)p)[0]);
1025 ((char **)p)[0] = NULL;
1029 errmsg=strdup(GETMESSAGE(8,29,
1030 "xk_free: The member '%s' is NULL; no free occurred\n"));
1031 fprintf(stderr, errmsg, tbl->name);
1038 * If there is exactly one pointer level, or one subscripting level,
1039 * and there is a delimiter,
1040 * and no subscript, then we are a length delimited malloced array.
1041 * Free each element, then free the whole array.
1043 if (tbl->delim != 0 && ((nptr == 1 && tbl->subscr == 0) ||
1044 nptr == 0 && tbl->subscr != 0 && tbl->kind != K_STRING)) {
1047 errmsg=strdup(GETMESSAGE(8,30,
1048 "xk_free: The delimiter for '%s' is %d\n"));
1049 fprintf(stderr, errmsg, tbl->name, delim);
1052 if (tbl->subscr == 0)
1053 np = ((char **)p)[0];
1056 for (i = 0; i < delim; i++) {
1059 errmsg=strdup(GETMESSAGE(8,31,
1060 "xk_free: Freeing array element [%d] of '%s' at address 0x%x\n"));
1061 fprintf(stderr, errmsg, i, tbl->name, &np[i*tbl->size]);
1064 RIF(xk_free(tbl, &np[i*tbl->size], nptr ? -1 : 0, 0, tbl_find));
1066 if (tbl->subscr == 0) {
1070 errmsg=strdup(GETMESSAGE(8,32,
1071 "xk_free: Freeing pointer to array of '%s' at location 0x%x and setting to NULL\n"));
1072 fprintf(stderr, errmsg, tbl->name, np);
1076 if (tbl->subscr == 0)
1077 ((char **)p)[0] = NULL;
1078 } else if (_Prdebug) {
1079 errmsg=strdup(GETMESSAGE(8,33,
1080 "xk_free: The pointer to array of '%s'is NULL; no free occurred\n"));
1081 fprintf(stderr, errmsg, tbl->name);
1098 if (((char **)p)[0] != NULL) {
1101 errmsg=strdup(GETMESSAGE(8,34,
1102 "xk_free: Freeing string '%s' at location 0x%x, and setting to NULL\n"));
1103 fprintf(stderr, errmsg, tbl->name, p);
1106 free(((char **)p)[0]);
1107 ((char **)p)[0] = NULL;
1108 } else if (_Prdebug) {
1109 errmsg=strdup(GETMESSAGE(8,35,
1110 "xk_free: The string '%s' is NULL; no free occurred\n"));
1111 fprintf(stderr, errmsg, tbl->name, p);
1117 ntbl = tbl_find(tbl->tname, tbl->tbl, tbl->id);
1118 return(xk_free(ntbl, p, nptr, 0, tbl_find));
1120 ntbl = tbl_find(tbl->tname, tbl->tbl, tbl->id);
1121 for (i = 0; ntbl[i].name != NULL; i++) {
1122 if ((ntbl[i].flags & F_SIMPLE) && nptr+ntbl[i].ptr == 0) {
1125 errmsg=strdup(GetSharedMsg(
1126 DT_XK_FREE_NO_MEMBER));
1127 fprintf(stderr, errmsg, ntbl[i].name, p + ntbl[i].offset);
1132 _Delim = xk_get_delim(&ntbl[i], p);
1135 errmsg=strdup(GETMESSAGE(8,36,
1136 "xk_free: Freeing member '%s' at location 0x%x\n"));
1137 fprintf(stderr, errmsg, ntbl[i].name, p + ntbl[i].offset);
1140 if (xk_free(&ntbl[i], p+ntbl[i].offset, nptr, sub, tbl_find) == FAIL) {
1143 errmsg=strdup(GETMESSAGE(8,37,
1144 "xk_free: A failure occurred while freeing the '%s' member\n"));
1145 fprintf(stderr, errmsg, ntbl[i].name);
1153 if (strncmp(tbl[-1].name, "ch_", 3) != 0) {
1156 errmsg=strdup(GETMESSAGE(8,38,
1157 "xk_free: Cannot determine the choice in '%s'\n"));
1158 fprintf(stderr, errmsg, tbl->name);
1163 val = *((long *)(p - sizeof(long)));
1164 ntbl = tbl_find(tbl->tname, tbl->tbl, tbl->id);
1165 for (i = 0; ntbl[i].name != NULL; i++) {
1166 if (ntbl[i].choice == val) {
1167 if ((ntbl[i].flags & F_SIMPLE) && nptr+ntbl[i].ptr == 0) {
1170 errmsg=strdup(GetSharedMsg(
1171 DT_XK_FREE_NO_MEMBER));
1172 fprintf(stderr, errmsg, ntbl[i].name, p + ntbl[i].offset);
1179 errmsg=strdup(GETMESSAGE(8,39,
1180 "xk_free: Freeing union member '%s' at location 0x%x\n"));
1181 fprintf(stderr, errmsg, ntbl[i].name, p + ntbl[i].offset);
1184 RIF(xk_free(&ntbl[i], p, nptr, sub, tbl_find));
1188 if (ntbl[i].name == NULL && _Prdebug)
1191 errmsg=strdup(GETMESSAGE(8,40,
1192 "xk_free: There is no legal union choice for '%s' (value is 0x%x); no free occurred\n"));
1193 fprintf(stderr, errmsg, tbl->name, val);