struct.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  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)
  10. * any later version.
  11. *
  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
  16. * details.
  17. *
  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
  22. */
  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 */
  26. /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF */
  27. /* UNIX System Laboratories, Inc. */
  28. /* The copyright notice above does not evidence any */
  29. /* actual or intended publication of such source code. */
  30. #undef printf
  31. #include "shell.h"
  32. #include <signal.h>
  33. #include <fcntl.h>
  34. #include <X11/X.h>
  35. #include <X11/Intrinsic.h>
  36. #include <X11/IntrinsicP.h>
  37. #include <X11/CoreP.h>
  38. #include <X11/StringDefs.h>
  39. #include <Xm/XmStrDefs.h>
  40. #include <Xm/List.h>
  41. #include <setjmp.h>
  42. #include <string.h>
  43. #include <ctype.h>
  44. #include <Xm/Xm.h>
  45. #include <Xm/Protocols.h>
  46. #include "hash.h"
  47. #include "stdio.h"
  48. #define NO_AST
  49. #include "dtksh.h"
  50. #undef NO_AST
  51. #include "exksh.h"
  52. #include "xmksh.h"
  53. #include "dtkcmds.h"
  54. #include "xmcvt.h"
  55. #include "widget.h"
  56. #include "extra.h"
  57. #include "xmwidgets.h"
  58. #include "struct.h"
  59. #include "basetbl.h"
  60. #include "docall.h"
  61. #include "exksh_tbls.h"
  62. #include "msgs.h"
  63. const static char use[] = "0x%x";
  64. const static char use2[] = "%s=0x%x";
  65. static char structInited = 0;
  66. static void *Hashnams = NULL;
  67. static struct memtbl **Dynmem = NULL;
  68. static int Ndynmem = 0;
  69. static int Sdynmem = 0;
  70. struct structlist {
  71. char *prefix;
  72. int id;
  73. int size;
  74. struct memtbl **mem;
  75. };
  76. struct structlist *Structlist = NULL;
  77. int Nstructlist;
  78. static int freemem(
  79. struct memtbl *mem) ;
  80. static growmem( void ) ;
  81. static char * endtok(
  82. char *start) ;
  83. static int chg_structlist(
  84. struct memtbl **memptr,
  85. int id) ;
  86. static struct_init( void ) ;
  87. memtbl_t *
  88. ffind(
  89. memtbl_t *tbl,
  90. char *fld,
  91. char **pptr )
  92. {
  93. static memtbl_t tbluse[2];
  94. memtbl_t *tbl2;
  95. char *p, *q, op;
  96. unsigned int len, sub;
  97. if (!fld || !(*fld))
  98. return(tbl);
  99. tbl2 = tbluse;
  100. tbluse[0] = *tbl;
  101. tbluse[1] = Null_tbl;
  102. q = fld;
  103. while (tbl2 && q && *q) {
  104. p = q;
  105. if (*q == '[') {
  106. if (!tbl2->ptr)
  107. return(NULL);
  108. q++;
  109. xk_par_int(&q, &sub, NULL);
  110. if (*q != ']')
  111. return(NULL);
  112. *pptr = ((char **) (*pptr))[0];
  113. *pptr += sub * tbl2->size;
  114. q++;
  115. tbluse[0].ptr--;
  116. continue;
  117. }
  118. if ((len = strcspn(p, "[.")) < strlen(p)) {
  119. q = p + len;
  120. op = *q;
  121. *q = '\0';
  122. }
  123. else
  124. q = NULL;
  125. tbl2 = asl_find(NULL, tbluse, p, pptr);
  126. if (tbl2 && (tbl2 != tbluse)) {
  127. /* A field should not be a subfield of itself */
  128. tbluse[0] = *tbl2;
  129. tbl2 = tbluse;
  130. tbl2->name = ".";
  131. tbl2->offset = 0;
  132. }
  133. if (q) {
  134. if (op == '.')
  135. *q++ = op;
  136. else
  137. *q = op;
  138. }
  139. }
  140. return(tbl2);
  141. }
  142. static int
  143. freemem(
  144. struct memtbl *mem )
  145. {
  146. free(mem->name);
  147. /*
  148. int i;
  149. ** Because structures and typedefs now inherit fields (i.e. copy
  150. ** the memtbl entry) we must keep the fields of a structure
  151. ** around permanently, (unless we implement a reference count).
  152. ** Let's keep the code handy in case we do.
  153. if (mem->kind == K_STRUCT) {
  154. struct memtbl *fmem;
  155. fmem = Dynmem[mem->tbl];
  156. for (i = 0; fmem[i].name; i++) {
  157. free(fmem[i].name);
  158. if (fmem[i].tname)
  159. free(fmem[i].tname);
  160. }
  161. }
  162. */
  163. free(mem);
  164. }
  165. static
  166. growmem( void )
  167. {
  168. if (!(Dynmem = (struct memtbl **) realloc(Dynmem, (Sdynmem + 20) * sizeof(memtbl_t *))))
  169. return(SH_FAIL);
  170. chg_structlist(Dynmem, DYNMEM_ID);
  171. memset(((char *) Dynmem) + Sdynmem * sizeof(memtbl_t *), '\0', 20 * sizeof(memtbl_t *));
  172. Sdynmem += 20;
  173. }
  174. int
  175. do_struct(
  176. int argc,
  177. char **argv )
  178. {
  179. struct memtbl *mem, *fmem;
  180. int i, j, argstart, redo;
  181. char *name, *fname;
  182. char *p;
  183. if (!structInited)
  184. struct_init();
  185. if (argc > 1 && C_PAIR(argv[1], '-', 'R')) {
  186. redo = 0;
  187. argstart = 2;
  188. }
  189. else {
  190. argstart = 1;
  191. redo = 1;
  192. }
  193. if ((argstart + 1) >= argc)
  194. {
  195. XK_USAGE(argv[0]);
  196. }
  197. name = argv[argstart++];
  198. for (i = 0; i < Ndynmem; i++)
  199. if (!(Dynmem[i]->flags & F_FIELD) && (strcmp(name, Dynmem[i]->name) == 0))
  200. break;
  201. if ((i < Ndynmem) && !redo) {
  202. if (!redo)
  203. return(SH_SUCC);
  204. if (Sdynmem - Ndynmem < 1)
  205. growmem();
  206. }
  207. else if (Sdynmem - Ndynmem < 2)
  208. growmem();
  209. /*
  210. ** Number of memtbls needed: two for structure table and one for
  211. ** each field plus one for null termination. The number of
  212. ** fields is argc - 2.
  213. */
  214. if (!(mem = (struct memtbl *) malloc(2 * sizeof(struct memtbl))))
  215. return(SH_FAIL);
  216. if (!(fmem = (struct memtbl *) malloc((argc - 1) * sizeof(struct memtbl))))
  217. return(SH_FAIL);
  218. memset(mem, '\0', 2 * sizeof(struct memtbl));
  219. memset(fmem, '\0', (argc - 1) * sizeof(struct memtbl));
  220. if (i < Ndynmem) {
  221. mem->tbl = Ndynmem++;
  222. freemem(Dynmem[i]);
  223. xkhash_override(Hashnams, name, mem);
  224. }
  225. else {
  226. Ndynmem += 2;
  227. mem->tbl = i + 1;
  228. }
  229. Dynmem[i] = mem;
  230. Dynmem[mem->tbl] = fmem;
  231. mem->flags = F_TBL_IS_PTR;
  232. mem->id = DYNMEM_ID;
  233. mem->name = strdup(name);
  234. mem->kind = K_STRUCT;
  235. for (j = argstart; (j < argc) && argv[j]; j++) {
  236. if (p = strchr(argv[j], ':')) {
  237. fname = malloc(p - argv[j] + 1);
  238. strncpy(fname, argv[j], p - argv[j]);
  239. fname[p - argv[j]] = '\0';
  240. parse_decl(argv[0], fmem + j - argstart, p + 1, 0);
  241. }
  242. else {
  243. fname = strdup(argv[j]);
  244. fmem[j - argstart] = T_unsigned_long[0];
  245. }
  246. fmem[j - argstart].name = fname;
  247. fmem[j - argstart].flags |= F_FIELD;
  248. fmem[j - argstart].delim = 0;
  249. fmem[j - argstart].offset = mem->size;
  250. mem->size += (fmem[j - argstart].ptr) ? sizeof(void *) : fmem[j - argstart].size;
  251. }
  252. return(SH_SUCC);
  253. }
  254. int
  255. do_typedef(
  256. int argc,
  257. char **argv )
  258. {
  259. struct memtbl *mem;
  260. int i, redo;
  261. char *name, *decl;
  262. if (!structInited)
  263. struct_init();
  264. i = 1;
  265. if (argc > 1 && C_PAIR(argv[i], '-', 'R'))
  266. {
  267. redo = 0;
  268. i++;
  269. }
  270. else
  271. redo = 1;
  272. if ((i + 1) >= argc)
  273. {
  274. XK_USAGE(argv[0]);
  275. }
  276. decl = argv[i++];
  277. name = argv[i++];
  278. for (i = 0; i < Ndynmem; i++)
  279. if (!(Dynmem[i]->flags & F_FIELD) && (strcmp(name, Dynmem[i]->name) == 0))
  280. break;
  281. if ((i < Ndynmem) && !redo) {
  282. if (!redo)
  283. return(SH_SUCC);
  284. }
  285. else if (Sdynmem - Ndynmem < 1)
  286. growmem();
  287. if (!(mem = (struct memtbl *) malloc(2 * sizeof(struct memtbl))))
  288. return(SH_FAIL);
  289. mem[1] = Null_tbl;
  290. if (i < Ndynmem) {
  291. freemem(Dynmem[i]);
  292. xkhash_override(Hashnams, name, mem);
  293. }
  294. else
  295. Ndynmem++;
  296. Dynmem[i] = mem;
  297. parse_decl(argv[0], mem, decl, 0);
  298. mem->name = strdup(name);
  299. return(SH_SUCC);
  300. }
  301. static char *
  302. endtok(
  303. char *start )
  304. {
  305. while(*start && !isspace(*start))
  306. start++;
  307. return(start);
  308. }
  309. int
  310. parse_decl(
  311. char * argv0,
  312. struct memtbl *mem,
  313. char *decl,
  314. int tst )
  315. {
  316. struct memtbl *tbl;
  317. char *p, *end;
  318. char hold;
  319. int flag = 0, done;
  320. char * msg;
  321. char * errbuf;
  322. char * errmsg;
  323. end = decl;
  324. do {
  325. p = end;
  326. xk_skipwhite(&p);
  327. end = endtok(p);
  328. hold = *end;
  329. *end = '\0';
  330. done = ((strcmp(p, (const char *) "struct") != 0) &&
  331. (strcmp(p, (const char *) "const") != 0) &&
  332. (strcmp(p, (const char *) "unsigned") != 0) &&
  333. (strcmp(p, (const char *) "signed") != 0) &&
  334. (strcmp(p, (const char *) "union") != 0));
  335. *end = hold;
  336. } while (!done && hold);
  337. if (!p[0]) {
  338. if (tst) {
  339. return(FAIL);
  340. }
  341. errmsg = strdup(GetSharedMsg(DT_BAD_DECL));
  342. printerrf(argv0, errmsg,
  343. decl,NULL, NULL, NULL, NULL, NULL, NULL, NULL);
  344. free(errmsg);
  345. mem[0] = T_unsigned_long[0];
  346. return(SUCCESS);
  347. }
  348. hold = *end;
  349. *end = '\0';
  350. tbl = all_tbl_search(p, flag|NOHASH);
  351. *end = hold;
  352. if (!tbl) {
  353. if (tst) {
  354. return(FAIL);
  355. }
  356. errmsg = strdup(GetSharedMsg(DT_BAD_DECL));
  357. printerrf(argv0, errmsg,
  358. decl, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
  359. free(errmsg);
  360. mem[0] = T_unsigned_long[0];
  361. return(SUCCESS);
  362. }
  363. mem[0] = tbl[0];
  364. for (p = end; *p; p++) {
  365. switch(*p) {
  366. case '[':
  367. {
  368. char *q = strchr(p, ']');
  369. if (!q) {
  370. errmsg=strdup(GETMESSAGE(12,1,
  371. "Found a '[' character without a matching ']'"));
  372. printerr(argv0, errmsg, NULL);
  373. free(errmsg);
  374. continue;
  375. }
  376. p++;
  377. xk_par_int(&p, &(mem->subscr), NULL);
  378. mem->flags &= ~(F_SIMPLE);
  379. if (mem->subscr)
  380. mem->size *= mem->subscr;
  381. p = q;
  382. break;
  383. }
  384. case '*':
  385. if ((mem->kind == K_CHAR) && !(mem->ptr)) {
  386. char *name;
  387. name = mem->name;
  388. mem[0] = T_string_t[0];
  389. mem->name = name;
  390. }
  391. else {
  392. mem->ptr++;
  393. mem->flags &= ~(F_SIMPLE);
  394. }
  395. break;
  396. }
  397. }
  398. return(SUCCESS);
  399. }
  400. int
  401. do_structlist(
  402. int argc,
  403. char **argv )
  404. {
  405. int i, j, id = 0;
  406. char *prefix = NULL;
  407. struct memtbl **memptr = NULL;
  408. char * errmsg;
  409. for (i = 1; (i < argc) && argv[i]; i++) {
  410. if (argv[i][0] == '-') {
  411. for (j = 1; argv[i][j]; j++) {
  412. switch(argv[i][j]) {
  413. case 'i':
  414. if (argv[i][j + 1])
  415. fdef(argv[i] + j + 1, &id);
  416. else
  417. fdef(argv[++i], &id);
  418. j = strlen(argv[i]) - 1;
  419. break;
  420. case 'p':
  421. if (argv[i][j + 1])
  422. prefix = argv[i] + j + 1;
  423. else
  424. prefix = argv[++i];
  425. j = strlen(prefix) - 1;
  426. break;
  427. default:
  428. errmsg = strdup(GetSharedMsg(
  429. DT_UNKNOWN_OPTION));
  430. printerrf(argv[0], errmsg,
  431. argv[i], NULL, NULL, NULL, NULL,
  432. NULL, NULL, NULL);
  433. free(errmsg);
  434. xk_usage(argv[0]);
  435. return(SH_FAIL);
  436. }
  437. }
  438. }
  439. else {
  440. if ((memptr = (memtbl_t **) getaddr(argv[i])) == NULL)
  441. {
  442. errmsg=strdup(GETMESSAGE(12,2,
  443. "Unable to locate the following symbol: %s"));
  444. printerrf(argv[0], errmsg, argv[i],
  445. NULL, NULL, NULL, NULL, NULL, NULL,
  446. NULL);
  447. free(errmsg);
  448. return(SH_FAIL);
  449. }
  450. }
  451. }
  452. if (memptr == NULL)
  453. {
  454. XK_USAGE(argv[0]);
  455. }
  456. for (i = 0; i < Nstructlist; i++)
  457. {
  458. if ((Structlist[i].mem == memptr) &&
  459. (!prefix || (Structlist[i].prefix &&
  460. (strcmp(Structlist[i].prefix, prefix) == 0))) &&
  461. (!id || (Structlist[i].id == id)))
  462. {
  463. return(SH_SUCC);
  464. }
  465. }
  466. add_structlist(memptr, prefix, id);
  467. }
  468. static int
  469. chg_structlist(
  470. struct memtbl **memptr,
  471. int id )
  472. {
  473. int i;
  474. for (i = 0; i < Nstructlist; i++)
  475. if (Structlist[i].id == id) {
  476. Structlist[i].mem = memptr;
  477. return;
  478. }
  479. }
  480. int
  481. add_structlist(
  482. struct memtbl **memptr,
  483. char *prefix,
  484. int id )
  485. {
  486. int i;
  487. if (!Structlist)
  488. Structlist = (struct structlist *) malloc((Nstructlist + 1) * sizeof(struct structlist));
  489. else
  490. Structlist = (struct structlist *) realloc(Structlist, (Nstructlist + 1) * sizeof(struct structlist));
  491. if (!Structlist)
  492. return(SH_FAIL);
  493. Structlist[Nstructlist].mem = memptr;
  494. Structlist[Nstructlist].id = id;
  495. Structlist[Nstructlist].prefix = prefix ? strdup(prefix) : (char *)NULL;
  496. if (memptr[0] && memptr[0][0].name) {
  497. for (i = 1; memptr[i] && memptr[i][0].name && memptr[i][0].name[0]; i++)
  498. if (strcmp(memptr[i][0].name, memptr[i - 1][0].name) < 0)
  499. break;
  500. if (!(memptr[i] && memptr[i][0].name && memptr[i][0].name[0]))
  501. Structlist[Nstructlist].size = i - 1;
  502. else
  503. Structlist[Nstructlist].size = -1;
  504. }
  505. else
  506. Structlist[Nstructlist].size = 0;
  507. Nstructlist++;
  508. return(SH_SUCC);
  509. }
  510. int
  511. strparse(
  512. memtbl_t *tbl,
  513. char **pbuf,
  514. char *val )
  515. {
  516. char *p, *phold;
  517. int ret;
  518. if (!IS_SIMPLE(tbl) && !tbl->ptr && !(tbl->flags & F_TYPE_IS_PTR))
  519. tbl->ptr = 1;
  520. phold = p = strdup(val);
  521. ret = XK_PARSE(tbl, &p, (char *)pbuf, 0, 0, NULL, all_tbl_find);
  522. free(phold);
  523. return(ret != FAIL);
  524. }
  525. int
  526. strfree(
  527. char *buf,
  528. char *type )
  529. {
  530. memtbl_t tbl;
  531. if (parse_decl("strfree", &tbl, type, 1) == FAIL)
  532. return(SH_FAIL);
  533. if (!IS_SIMPLE(&tbl) && !tbl.ptr && !(tbl.flags & F_TYPE_IS_PTR))
  534. tbl.ptr = 1;
  535. if (XK_FREE(&tbl, (char *)&buf, 0, 0, all_tbl_find) == FAIL)
  536. return(SH_FAIL);
  537. return(SH_SUCC);
  538. }
  539. int
  540. do_sizeof(
  541. int argc,
  542. char **argv )
  543. {
  544. memtbl_t *tbl;
  545. char * errmsg;
  546. if (argc <= 1) {
  547. XK_USAGE(argv[0]);
  548. }
  549. if ((tbl = all_tbl_search(argv[1], 0)) == NULL) {
  550. errmsg=strdup(GETMESSAGE(12,3,
  551. "The following is not a valid data type or structure name: %s"));
  552. printerrf(argv[0], errmsg, argv[1], NULL, NULL,
  553. NULL, NULL, NULL, NULL, NULL);
  554. free(errmsg);
  555. return(SH_FAIL);
  556. }
  557. if (argc >= 3) {
  558. char buf[50];
  559. sprintf(buf, use2, argv[2], tbl->ptr ? sizeof(void *) : tbl->size);
  560. env_set(buf);
  561. }
  562. else {
  563. sprintf(xk_ret_buffer, use, tbl->ptr ? sizeof(void *) : tbl->size);
  564. xk_ret_buf = xk_ret_buffer;
  565. }
  566. return(SH_SUCC);
  567. }
  568. memtbl_t *
  569. all_tbl_find(
  570. char *name,
  571. int tbl,
  572. long id )
  573. {
  574. int i;
  575. if (tbl != -1) {
  576. for (i = 0; i < Nstructlist; i++)
  577. if (id == Structlist[i].id)
  578. return(Structlist[i].mem[tbl]);
  579. return(NULL);
  580. }
  581. return(all_tbl_search(name, TYPEONLY));
  582. }
  583. memtbl_t *
  584. all_tbl_search(
  585. char *name,
  586. int flag )
  587. {
  588. register int i;
  589. void *found;
  590. if (!structInited)
  591. struct_init();
  592. if (found = (void *) xkhash_find(Hashnams, name))
  593. return((memtbl_t *) found);
  594. else {
  595. register int j;
  596. register memtbl_t **subtbl;
  597. for (i = 0; i < Nstructlist; i++) {
  598. if (subtbl = Structlist[i].mem)
  599. for (j = 0; subtbl[j]; j++)
  600. if (!(subtbl[j]->flags & F_FIELD) && (strcmp(name, subtbl[j]->name) == 0) && ((subtbl[j]->kind != K_TYPEDEF) || (subtbl[j]->tbl != -1))) {
  601. if (!(flag & NOHASH))
  602. xkhash_add(Hashnams, name, (char *)subtbl[j]);
  603. return(subtbl[j]);
  604. }
  605. }
  606. }
  607. return(NULL);
  608. }
  609. memtbl_t *
  610. asl_find(
  611. memtbl_t *ptbl,
  612. memtbl_t *tbls,
  613. char *fld,
  614. char **pptr )
  615. {
  616. int i;
  617. memtbl_t *tbl;
  618. if (!Structlist)
  619. return(NULL);
  620. if (!pptr && (ptbl == tbls))
  621. return(NULL);
  622. for (i = 0; tbls[i].name; i++) {
  623. if ((xk_Strncmp(tbls[i].name, fld, strlen(fld)) == 0) && (strlen(fld) == strlen(tbls[i].name))) {
  624. if (pptr && ptbl && ((ptbl->kind == K_STRUCT) || (ptbl->kind == K_ANY)))
  625. *pptr += tbls[i].offset;
  626. return(tbls + i);
  627. }
  628. }
  629. for (i = 0; tbls[i].name; i++) {
  630. if ((tbls[i].kind == K_TYPEDEF) || (tbls[i].kind == K_STRUCT) || (tbls[i].kind == K_UNION) || (tbls[i].kind == K_ANY)) {
  631. char *hold;
  632. if (!pptr) {
  633. if ((tbl = asl_find(tbls + i, all_tbl_find(tbls[i].tname, tbls[i].tbl, tbls[i].id), fld, pptr)) != NULL)
  634. return(tbl);
  635. continue;
  636. }
  637. hold = *pptr;
  638. if (tbls[i].ptr) {
  639. int nptr;
  640. nptr = tbls[i].ptr;
  641. /* if you hit a NULL, stop the loop */
  642. do {
  643. *pptr = *((char **) *pptr);
  644. } while (*pptr && --nptr);
  645. }
  646. if (*pptr) {
  647. if (!tbls[i].ptr)
  648. *pptr += tbls[i].offset;
  649. if ((tbl = asl_find(tbls + i, all_tbl_find(tbls[i].tname, tbls[i].tbl, tbls[i].id), fld, pptr)) != NULL)
  650. return(tbl);
  651. *pptr = hold;
  652. }
  653. }
  654. }
  655. return(NULL);
  656. }
  657. static
  658. struct_init( void )
  659. {
  660. char * errhdr;
  661. char * errmsg;
  662. structInited = 1;
  663. Hashnams = (void *) xkhash_init(50);
  664. if (!(Dynmem = (struct memtbl **) malloc(20 * sizeof(struct memtbl *))))
  665. {
  666. errhdr = strdup(GetSharedMsg(DT_ERROR));
  667. errmsg = strdup(GetSharedMsg(DT_ALLOC_FAILURE));
  668. printerr(errhdr, errmsg, NULL);
  669. free(errhdr);
  670. free(errmsg);
  671. exit(1);
  672. }
  673. Dynmem[0] = NULL;
  674. Sdynmem = 20;
  675. Ndynmem = 0;
  676. add_structlist(basemems, "base", BASE_ID);
  677. add_structlist(Dynmem, "dynamic", DYNMEM_ID);
  678. }