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: struct.c /main/4 1995/11/01 15:56:35 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. */
39 #include <X11/Intrinsic.h>
40 #include <X11/IntrinsicP.h>
41 #include <X11/CoreP.h>
42 #include <X11/StringDefs.h>
43 #include <Xm/XmStrDefs.h>
49 #include <Xm/Protocols.h>
61 #include "xmwidgets.h"
65 #include "exksh_tbls.h"
68 const static char use[] = "0x%x";
69 const static char use2[] = "%s=0x%x";
71 static char structInited = 0;
72 static void *Hashnams = NULL;
74 static struct memtbl **Dynmem = NULL;
75 static int Ndynmem = 0;
76 static int Sdynmem = 0;
85 struct structlist *Structlist = NULL;
92 static growmem( void ) ;
95 static int chg_structlist(
96 struct memtbl **memptr,
98 static struct_init( void ) ;
108 static memtbl_t tbluse[2];
111 unsigned int len, sub;
117 tbluse[1] = Null_tbl;
119 while (tbl2 && q && *q) {
125 xk_par_int(&q, &sub, NULL);
128 *pptr = ((char **) (*pptr))[0];
129 *pptr += sub * tbl2->size;
134 if ((len = strcspn(p, "[.")) < strlen(p)) {
141 tbl2 = asl_find(NULL, tbluse, p, pptr);
142 if (tbl2 && (tbl2 != tbluse)) {
143 /* A field should not be a subfield of itself */
168 ** Because structures and typedefs now inherit fields (i.e. copy
169 ** the memtbl entry) we must keep the fields of a structure
170 ** around permanently, (unless we implement a reference count).
171 ** Let's keep the code handy in case we do.
172 if (mem->kind == K_STRUCT) {
175 fmem = Dynmem[mem->tbl];
176 for (i = 0; fmem[i].name; i++) {
189 if (!(Dynmem = (struct memtbl **) realloc(Dynmem, (Sdynmem + 20) * sizeof(memtbl_t *))))
191 chg_structlist(Dynmem, DYNMEM_ID);
192 memset(((char *) Dynmem) + Sdynmem * sizeof(memtbl_t *), '\0', 20 * sizeof(memtbl_t *));
201 struct memtbl *mem, *fmem;
202 int i, j, argstart, redo;
209 if (argc > 1 && C_PAIR(argv[1], '-', 'R')) {
217 if ((argstart + 1) >= argc)
221 name = argv[argstart++];
222 for (i = 0; i < Ndynmem; i++)
223 if (!(Dynmem[i]->flags & F_FIELD) && (strcmp(name, Dynmem[i]->name) == 0))
225 if ((i < Ndynmem) && !redo) {
228 if (Sdynmem - Ndynmem < 1)
231 else if (Sdynmem - Ndynmem < 2)
234 ** Number of memtbls needed: two for structure table and one for
235 ** each field plus one for null termination. The number of
236 ** fields is argc - 2.
238 if (!(mem = (struct memtbl *) malloc(2 * sizeof(struct memtbl))))
240 if (!(fmem = (struct memtbl *) malloc((argc - 1) * sizeof(struct memtbl))))
242 memset(mem, '\0', 2 * sizeof(struct memtbl));
243 memset(fmem, '\0', (argc - 1) * sizeof(struct memtbl));
245 mem->tbl = Ndynmem++;
247 xkhash_override(Hashnams, name, mem);
254 Dynmem[mem->tbl] = fmem;
255 mem->flags = F_TBL_IS_PTR;
257 mem->name = strdup(name);
258 mem->kind = K_STRUCT;
259 for (j = argstart; (j < argc) && argv[j]; j++) {
260 if (p = strchr(argv[j], ':')) {
261 fname = malloc(p - argv[j] + 1);
262 strncpy(fname, argv[j], p - argv[j]);
263 fname[p - argv[j]] = '\0';
264 parse_decl(argv[0], fmem + j - argstart, p + 1, 0);
267 fname = strdup(argv[j]);
268 fmem[j - argstart] = T_unsigned_long[0];
270 fmem[j - argstart].name = fname;
271 fmem[j - argstart].flags |= F_FIELD;
272 fmem[j - argstart].delim = 0;
273 fmem[j - argstart].offset = mem->size;
274 mem->size += (fmem[j - argstart].ptr) ? sizeof(void *) : fmem[j - argstart].size;
292 if (argc > 1 && C_PAIR(argv[i], '-', 'R'))
307 for (i = 0; i < Ndynmem; i++)
308 if (!(Dynmem[i]->flags & F_FIELD) && (strcmp(name, Dynmem[i]->name) == 0))
310 if ((i < Ndynmem) && !redo) {
314 else if (Sdynmem - Ndynmem < 1)
316 if (!(mem = (struct memtbl *) malloc(2 * sizeof(struct memtbl))))
321 xkhash_override(Hashnams, name, mem);
326 parse_decl(argv[0], mem, decl, 0);
327 mem->name = strdup(name);
335 while(*start && !isspace(*start))
362 done = ((strcmp(p, (const char *) "struct") != 0) &&
363 (strcmp(p, (const char *) "const") != 0) &&
364 (strcmp(p, (const char *) "unsigned") != 0) &&
365 (strcmp(p, (const char *) "signed") != 0) &&
366 (strcmp(p, (const char *) "union") != 0));
368 } while (!done && hold);
373 errmsg = strdup(GetSharedMsg(DT_BAD_DECL));
374 printerrf(argv0, errmsg,
375 decl,NULL, NULL, NULL, NULL, NULL, NULL, NULL);
377 mem[0] = T_unsigned_long[0];
382 tbl = all_tbl_search(p, flag|NOHASH);
388 errmsg = strdup(GetSharedMsg(DT_BAD_DECL));
389 printerrf(argv0, errmsg,
390 decl, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
392 mem[0] = T_unsigned_long[0];
396 for (p = end; *p; p++) {
400 char *q = strchr(p, ']');
403 errmsg=strdup(GETMESSAGE(12,1,
404 "Found a '[' character without a matching ']'"));
405 printerr(argv0, errmsg, NULL);
410 xk_par_int(&p, &(mem->subscr), NULL);
411 mem->flags &= ~(F_SIMPLE);
413 mem->size *= mem->subscr;
418 if ((mem->kind == K_CHAR) && !(mem->ptr)) {
422 mem[0] = T_string_t[0];
427 mem->flags &= ~(F_SIMPLE);
442 struct memtbl **memptr = NULL;
445 for (i = 1; (i < argc) && argv[i]; i++) {
446 if (argv[i][0] == '-') {
447 for (j = 1; argv[i][j]; j++) {
451 fdef(argv[i] + j + 1, &id);
453 fdef(argv[++i], &id);
454 j = strlen(argv[i]) - 1;
458 prefix = argv[i] + j + 1;
461 j = strlen(prefix) - 1;
464 errmsg = strdup(GetSharedMsg(
466 printerrf(argv[0], errmsg,
467 argv[i], NULL, NULL, NULL, NULL,
476 if ((memptr = (memtbl_t **) getaddr(argv[i])) == NULL)
478 errmsg=strdup(GETMESSAGE(12,2,
479 "Unable to locate the following symbol: %s"));
480 printerrf(argv[0], errmsg, argv[i],
481 NULL, NULL, NULL, NULL, NULL, NULL,
494 for (i = 0; i < Nstructlist; i++)
496 if ((Structlist[i].mem == memptr) &&
497 (!prefix || (Structlist[i].prefix &&
498 (strcmp(Structlist[i].prefix, prefix) == 0))) &&
499 (!id || (Structlist[i].id == id)))
505 add_structlist(memptr, prefix, id);
510 struct memtbl **memptr,
515 for (i = 0; i < Nstructlist; i++)
516 if (Structlist[i].id == id) {
517 Structlist[i].mem = memptr;
524 struct memtbl **memptr,
531 Structlist = (struct structlist *) malloc((Nstructlist + 1) * sizeof(struct structlist));
533 Structlist = (struct structlist *) realloc(Structlist, (Nstructlist + 1) * sizeof(struct structlist));
536 Structlist[Nstructlist].mem = memptr;
537 Structlist[Nstructlist].id = id;
538 Structlist[Nstructlist].prefix = prefix ? strdup(prefix) : (char *)NULL;
539 if (memptr[0] && memptr[0][0].name) {
540 for (i = 1; memptr[i] && memptr[i][0].name && memptr[i][0].name[0]; i++)
541 if (strcmp(memptr[i][0].name, memptr[i - 1][0].name) < 0)
543 if (!(memptr[i] && memptr[i][0].name && memptr[i][0].name[0]))
544 Structlist[Nstructlist].size = i - 1;
546 Structlist[Nstructlist].size = -1;
549 Structlist[Nstructlist].size = 0;
563 if (!IS_SIMPLE(tbl) && !tbl->ptr && !(tbl->flags & F_TYPE_IS_PTR))
565 phold = p = strdup(val);
566 ret = XK_PARSE(tbl, &p, (char *)pbuf, 0, 0, NULL, all_tbl_find);
578 if (parse_decl("strfree", &tbl, type, 1) == FAIL)
580 if (!IS_SIMPLE(&tbl) && !tbl.ptr && !(tbl.flags & F_TYPE_IS_PTR))
582 if (XK_FREE(&tbl, (char *)&buf, 0, 0, all_tbl_find) == FAIL)
598 if ((tbl = all_tbl_search(argv[1], 0)) == NULL) {
599 errmsg=strdup(GETMESSAGE(12,3,
600 "The following is not a valid data type or structure name: %s"));
601 printerrf(argv[0], errmsg, argv[1], NULL, NULL,
602 NULL, NULL, NULL, NULL, NULL);
609 sprintf(buf, use2, argv[2], tbl->ptr ? sizeof(void *) : tbl->size);
613 sprintf(xk_ret_buffer, use, tbl->ptr ? sizeof(void *) : tbl->size);
614 xk_ret_buf = xk_ret_buffer;
628 for (i = 0; i < Nstructlist; i++)
629 if (id == Structlist[i].id)
630 return(Structlist[i].mem[tbl]);
633 return(all_tbl_search(name, TYPEONLY));
647 if (found = (void *) xkhash_find(Hashnams, name))
648 return((memtbl_t *) found);
651 register memtbl_t **subtbl;
653 for (i = 0; i < Nstructlist; i++) {
654 if (subtbl = Structlist[i].mem)
655 for (j = 0; subtbl[j]; j++)
656 if (!(subtbl[j]->flags & F_FIELD) && (strcmp(name, subtbl[j]->name) == 0) && ((subtbl[j]->kind != K_TYPEDEF) || (subtbl[j]->tbl != -1))) {
657 if (!(flag & NOHASH))
658 xkhash_add(Hashnams, name, (char *)subtbl[j]);
678 if (!pptr && (ptbl == tbls))
680 for (i = 0; tbls[i].name; i++) {
681 if ((xk_Strncmp(tbls[i].name, fld, strlen(fld)) == 0) && (strlen(fld) == strlen(tbls[i].name))) {
682 if (pptr && ptbl && ((ptbl->kind == K_STRUCT) || (ptbl->kind == K_ANY)))
683 *pptr += tbls[i].offset;
687 for (i = 0; tbls[i].name; i++) {
688 if ((tbls[i].kind == K_TYPEDEF) || (tbls[i].kind == K_STRUCT) || (tbls[i].kind == K_UNION) || (tbls[i].kind == K_ANY)) {
692 if ((tbl = asl_find(tbls + i, all_tbl_find(tbls[i].tname, tbls[i].tbl, tbls[i].id), fld, pptr)) != NULL)
701 /* if you hit a NULL, stop the loop */
703 *pptr = *((char **) *pptr);
704 } while (*pptr && --nptr);
708 *pptr += tbls[i].offset;
709 if ((tbl = asl_find(tbls + i, all_tbl_find(tbls[i].tname, tbls[i].tbl, tbls[i].id), fld, pptr)) != NULL)
725 Hashnams = (void *) xkhash_init(50);
726 if (!(Dynmem = (struct memtbl **) malloc(20 * sizeof(struct memtbl *))))
728 errhdr = strdup(GetSharedMsg(DT_ERROR));
729 errmsg = strdup(GetSharedMsg(DT_ALLOC_FAILURE));
730 printerr(errhdr, errmsg, NULL);
738 add_structlist(basemems, "base", BASE_ID);
739 add_structlist(Dynmem, "dynamic", DYNMEM_ID);