1
/*___INFO__MARK_BEGIN__*/
2
/*************************************************************************
4
* The Contents of this file are made available subject to the terms of
5
* the Sun Industry Standards Source License Version 1.2
7
* Sun Microsystems Inc., March, 2001
10
* Sun Industry Standards Source License Version 1.2
11
* =================================================
12
* The contents of this file are subject to the Sun Industry Standards
13
* Source License Version 1.2 (the "License"); You may not use this file
14
* except in compliance with the License. You may obtain a copy of the
15
* License at http://gridengine.sunsource.net/Gridengine_SISSL_license.html
17
* Software provided under this License is provided on an "AS IS" basis,
18
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
19
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
20
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
21
* See the License for the specific provisions governing your rights and
22
* obligations concerning the Software.
24
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
26
* Copyright: 2001 by Sun Microsystems, Inc.
28
* All Rights Reserved.
30
************************************************************************/
31
/*___INFO__MARK_END__*/
37
/* do not compile in monitoring code */
38
#ifndef NO_SGE_COMPILE_DEBUG
39
#define NO_SGE_COMPILE_DEBUG
43
#include "cull_dump_scan.h"
44
#include "cull_listP.h"
45
#include "cull_multitypeP.h"
46
#include "cull_lerrnoP.h"
47
#include "basis_types.h"
49
#include "uti/sge_dstring.h"
50
#include "uti/sge_stdio.h"
51
#include "uti/sge_string.h"
53
#define READ_LINE_LENGHT 255
55
#define INDENT_STRING " "
57
static int space_comment(char *s);
59
static int fGetLine(FILE *fp, char *line, int max_line);
60
static int fGetBra(FILE *fp);
61
static int fGetKet(FILE *fp);
62
static int fGetDescr(FILE *fp, lDescr *dp);
63
static int fGetInt(FILE *fp, lInt *value);
64
static int fGetUlong(FILE *fp, lUlong *value);
65
static int fGetString(FILE *fp, lString *value);
66
static int fGetHost(FILE *fp, lHost *value);
67
static int fGetFloat(FILE *fp, lFloat *value);
68
static int fGetDouble(FILE *fp, lDouble *value);
69
static int fGetLong(FILE *fp, lLong *value);
70
static int fGetChar(FILE *fp, lChar *value);
71
static int fGetBool(FILE *fp, lBool *value);
72
static int fGetList(FILE *fp, lList **value);
73
static int fGetObject(FILE *fp, lListElem **value);
75
/****** cull/dump_scan/lDumpDescr() ****************************************
77
* lDumpDescr() -- Write a descriptor (for debugging purpose)
80
* int lDumpDescr(FILE *fp, const lDescr *dp, int indent)
83
* Write a descriptor (for debugging purpose)
86
* FILE *fp - file pointer
87
* const lDescr *dp - descriptor
94
******************************************************************************/
95
int lDumpDescr(FILE *fp, const lDescr *dp, int indent)
100
DENTER(CULL_LAYER, "lDumpDescr");
103
for (i = 0; i < indent; i++)
104
strcat(space, INDENT_STRING);
111
ret = fprintf(fp, "%s{ /* DESCR BEGIN */\n", space);
118
ret = fprintf(fp, "%s/* NUMBER OF DESCR FIELDS */ %d\n", space,
121
for (i = 0; dp[i].mt != lEndT && ret != EOF; i++) {
122
ret = fprintf(fp, "%s/* %-20.20s */ { %d, %d }\n", space,
123
lNm2Str(dp[i].nm), dp[i].nm, dp[i].mt);
126
ret = fprintf(fp, "%s} /* DESCR END */\n", space);
129
return (ret == EOF) ? -1 : 0;
132
/****** cull/dump_scan/lUndumpDescr() ****************************************
134
* lUndumpDescr() -- Read a descriptor from file (debug)
137
* lDescr* lUndumpDescr(FILE *fp)
140
* Read a descriptor from file (for debugging purposes)
143
* FILE *fp - file stream
146
* lDescr* - descriptor
147
*******************************************************************************/
148
lDescr *lUndumpDescr(FILE *fp)
153
DENTER(CULL_LAYER, "lUndumpDescr");
163
printf("bra is missing\n");
169
/* read Descriptor Count */
170
if (fGetInt(fp, &n)) {
171
printf("reading integer from dump file failed\n");
177
if (!(dp = (lDescr *) malloc(sizeof(lDescr) * (n + 1)))) {
183
for (i = 0; i < n; i++) {
184
/* read descriptor */
185
if (fGetDescr(fp, &(dp[i]))) {
197
printf("ket is missing");
208
/****** cull/dump_scan/lDumpElem() ********************************************
210
* lDumpElem() -- Dump a given element into a file
213
* int lDumpElem(const char *fname, const lListElem *ep, int indent)
216
* Dump a given element into a file
219
* const char *fname - filename
220
* const lListElem *ep - element
229
* MT-NOTE: lDumpElem() is not MT safe
230
******************************************************************************/
231
int lDumpElem(const char *fname, const lListElem *ep, int indent)
236
fp = fopen(fname, "w");
238
ret = lDumpElemFp(fp, ep, indent);
250
/****** cull/dump_scan/lDumpElemFp() ******************************************
252
* lDumpElemFp() -- Dump a given element into FILE stream
255
* int lDumpElemFp(FILE *fp, const lListElem *ep, int indent)
258
* Dump a given element into FILE stream
261
* FILE *fp - file stream
262
* const lListElem *ep - element
271
* MT-NOTE: lDumpElemFp() is not MT safe
272
******************************************************************************/
273
int lDumpElemFp(FILE *fp, const lListElem *ep, int indent)
280
dstring dstr = DSTRING_INIT;
282
DENTER(CULL_LAYER, "lDumpElemFp");
285
for (i = 0; i < indent; i++)
286
strcat(space, INDENT_STRING);
299
ret = fprintf(fp, "%s{ \n", space);
300
for (i = 0, ret = 0; ep->descr[i].nm != NoName && ret != EOF; i++) {
303
switch (mt_get_type(ep->descr[i].mt)) {
305
ret = fprintf(fp, "%s/* %-20.20s */ %d\n",
306
space, lNm2Str(ep->descr[i].nm), lGetPosInt(ep, i));
309
ret = fprintf(fp, "%s/* %-20.20s */ " sge_u32 "\n",
310
space, lNm2Str(ep->descr[i].nm), lGetPosUlong(ep, i));
313
str = lGetPosString(ep, i);
314
/* quote " inside str */
315
if ((tok = sge_strtok(str, "\"")) != NULL) {
316
sge_dstring_append(&dstr, tok);
317
while ((tok=sge_strtok(NULL, "\"")) != NULL) {
318
sge_dstring_append(&dstr, "\\\"");
319
sge_dstring_append(&dstr, tok);
322
str = sge_dstring_get_string(&dstr);
323
ret = fprintf(fp, "%s/* %-20.20s */ \"%s\"\n",
324
space, lNm2Str(ep->descr[i].nm), str != NULL ? str : "");
325
sge_dstring_clear(&dstr);
328
str = lGetPosHost(ep, i);
329
ret = fprintf(fp, "%s/* %-20.20s */ \"%s\"\n",
330
space, lNm2Str(ep->descr[i].nm), str != NULL ? str : "");
333
ret = fprintf(fp, "%s/* %-20.20s */ %f\n",
334
space, lNm2Str(ep->descr[i].nm), lGetPosFloat(ep, i));
337
ret = fprintf(fp, "%s/* %-20.20s */ %f\n",
338
space, lNm2Str(ep->descr[i].nm), lGetPosDouble(ep, i));
341
ret = fprintf(fp, "%s/* %-20.20s */%ld \n",
342
space, lNm2Str(ep->descr[i].nm), lGetPosLong(ep, i));
345
ret = fprintf(fp, "%s/* %-20.20s */ %c\n",
346
space, lNm2Str(ep->descr[i].nm), lGetPosChar(ep, i));
349
ret = fprintf(fp, "%s/* %-20.20s */ %d\n",
350
space, lNm2Str(ep->descr[i].nm), lGetPosBool(ep, i));
353
ret = fprintf(fp, "%s/* %-20.20s */ %ld\n",
354
space, lNm2Str(ep->descr[i].nm), (long)lGetPosRef(ep, i));
357
if ((tep = lGetPosObject(ep, i)) == NULL)
358
ret = fprintf(fp, "%s/* %-20.20s */ none\n",
359
space, lNm2Str(ep->descr[i].nm));
361
ret = fprintf(fp, "%s/* %-20.20s */ object\n",
362
space, lNm2Str(ep->descr[i].nm));
364
ret = lDumpObject(fp, tep, indent + 1);
368
if ((tlp = lGetPosList(ep, i)) == NULL)
369
ret = fprintf(fp, "%s/* %-20.20s */ empty\n",
370
space, lNm2Str(ep->descr[i].nm));
372
ret = fprintf(fp, "%s/* %-20.20s */ full\n",
373
space, lNm2Str(ep->descr[i].nm));
375
ret = lDumpList(fp, tlp, indent + 1);
380
sge_dstring_free(&dstr);
382
ret = fprintf(fp, "%s}\n", space);
385
return (ret == EOF) ? -1 : 0;
388
/****** cull/dump_scan/lDumpObject() ********************************************
390
* lDumpObject() -- Writes an object to a FILE stream
393
* int lDumpObject(FILE *fp, const lListElem *ep, int indent)
396
* Writes an object to a FILE stream.
399
* FILE *fp - file stream
400
* const lListElem *ep - object
407
*******************************************************************************/
408
int lDumpObject(FILE *fp, const lListElem *ep, int indent)
414
DENTER(CULL_LAYER, "lDumpObject");
417
for (i = 0; i < indent; i++)
418
strcat(space, INDENT_STRING);
431
ret = fprintf(fp, "%s{ /* OBJECT BEGIN */\n", space);
433
ret = lDumpDescr(fp, ep->descr, indent);
435
ret = lDumpElemFp(fp, ep, indent);
437
ret = fprintf(fp, "%s} /* OBJECT END */\n", space);
440
return (ret == EOF) ? -1 : 0;
443
/****** cull/dump_scan/lDumpList() ********************************************
445
* lDumpList() -- Writes a list to a FILE stream
448
* int lDumpList(FILE *fp, const lList *lp, int indent)
451
* Writes a list to a FILE stream.
454
* FILE *fp - file stream
455
* const lList *lp - list
464
* MT-NOTE: lDumpList() is not MT safe
465
*******************************************************************************/
466
int lDumpList(FILE *fp, const lList *lp, int indent)
473
DENTER(CULL_LAYER, "lDumpList");
476
for (i = 0; i < indent; i++)
477
strcat(space, INDENT_STRING);
490
ret = fprintf(fp, "%s{ /* LIST BEGIN */\n", space);
492
ret = fprintf(fp, "%s/* LISTNAME */ \"%s\"\n", space,
494
ret = fprintf(fp, "%s/* NUMBER OF ELEMENTS */ %d\n", space,
495
lGetNumberOfElem(lp));
497
ret = lDumpDescr(fp, lGetListDescr(lp), indent);
499
for (ep = lFirst(lp); ep && ret != EOF; ep = lNext(ep))
500
ret = lDumpElemFp(fp, ep, indent);
502
ret = fprintf(fp, "%s} /* LIST END */\n", space);
505
return (ret == EOF) ? -1 : 0;
508
/****** cull/dump_scan/lUndumpElem() ******************************************
510
* lUndumpElem() -- Read element from FILE stream
513
* lListElem* lUndumpElem(FILE *fp, const lDescr *dp)
516
* Read element from FILE stream
519
* FILE *fp - file stream
520
* const lDescr *dp - descriptor
523
* lListElem* - Read element
524
******************************************************************************/
525
lListElem *lUndumpElem(const char *fname, const lDescr *dp)
527
lListElem *ep = NULL;
530
DENTER(CULL_LAYER, "lUndumpElemFp");
532
fp = fopen(fname, "r");
536
ep = lUndumpElemFp(fp, dp);
543
/****** cull/dump_scan/lUndumpElemFp() ******************************************
545
* lUndumpElemFp() -- Read element from FILE stream
548
* lListElem* lUndumpElemFp(FILE *fp, const lDescr *dp)
551
* Read element from FILE stream
554
* FILE *fp - file stream
555
* const lDescr *dp - descriptor
558
* lListElem* - Read element
559
******************************************************************************/
560
lListElem *lUndumpElemFp(FILE *fp, const lDescr *dp)
568
DENTER(CULL_LAYER, "lUndumpElemFp");
580
if (!(ep = lCreateElem(dp))) {
581
LERROR(LECREATEELEM);
586
if ((n = lCountDescr(dp)) <= 0) {
587
LERROR(LECOUNTDESCR);
595
printf("bra is missing\n");
602
for (i = 0; i < n && ret == 0; i++) {
603
switch (mt_get_type(dp[i].mt)) {
605
ret = fGetInt(fp, &(ep->cont[i].i));
608
ret = fGetUlong(fp, &(ep->cont[i].ul));
611
ret = fGetString(fp, &str);
612
lSetPosString(ep, i, str);
613
free(str); /* fGetString strdup's */
616
ret = fGetHost(fp, &str);
617
lSetPosHost(ep, i, str);
618
free(str); /* fGetHost strdup's */
621
ret = fGetFloat(fp, &(ep->cont[i].fl));
624
ret = fGetDouble(fp, &(ep->cont[i].db));
627
ret = fGetLong(fp, &(ep->cont[i].l));
630
ret = fGetChar(fp, &(ep->cont[i].c));
633
ret = fGetBool(fp, &(ep->cont[i].b));
636
/* we will not undump references! But we have to skip the line! */
637
ret = fGetUlong(fp, &dummy);
638
ep->cont[i].ref = NULL;
641
ret = fGetObject(fp, &(ep->cont[i].obj));
644
ret = fGetList(fp, &(ep->cont[i].glp));
648
unknownType("lUndumpElemFp");
652
/* error handling for loop */
663
printf("ket is missing\n");
673
/****** cull/dump_scan/lUndumpObject() ******************************************
675
* lUndumpObject() -- Reads a by lDumpList dumped dump
678
* lListElem* lUndumpObject(FILE *fp)
681
* Reads a by lDumpList dumped dump into the memory.
684
* FILE *fp - file pointer
687
* lListElem* - Read list element
691
******************************************************************************/
692
lListElem *lUndumpObject(FILE *fp)
697
DENTER(CULL_LAYER, "lUndumpObject");
706
printf("bra is missing\n");
712
/* read Descriptor from file */
713
if ((dp = lUndumpDescr(fp)) == NULL) {
719
if (lCountDescr(dp) <= 0) {
720
LERROR(LECOUNTDESCR);
726
if ((ep = lUndumpElemFp(fp, dp)) == NULL) {
727
LERROR(LEUNDUMPELEM);
738
printf("ket is missing\n");
748
/****** cull/dump_scan/lUndumpList() ******************************************
750
* lUndumpList() -- Reads a by lDumpList dumped dump
753
* lList* lUndumpList(FILE *fp, const char *name, const lDescr *dp)
756
* Reads a by lDumpList dumped dump into the memory.
759
* FILE *fp - file pointer
760
* const char *name - new name of list or NULL if the old name in the
761
* dumpfile should be used as listname
762
* const lDescr *dp - new list descriptor or NULL if the old list
763
* descriptor should be used as list descriptor
769
* Actually a type/name matching is only performed for the list
770
* itself and not for its sublists.
771
* If an implementation of changed sublist descriptors is desired
772
* we can probably use the following syntax for lUndumpList.
773
* lList* lUndumpList(fp, name, formatstring, ...)
774
* with formatstring like "%T(%I -> %T(%I->%T))" and the varargs
775
* list: ".....", lDescr1, fieldname1, lDescr2, fieldname2, lDescr3
776
* or write a wrapper around lUndumpList which parses this format and
777
* hands over the varargs list to lUndumpList
778
******************************************************************************/
779
lList *lUndumpList(FILE *fp, const char *name, const lDescr *dp)
784
int i, j, nelem, n, k;
788
DENTER(CULL_LAYER, "lUndumpList");
798
printf("bra is missing\n");
804
if (fGetString(fp, &oldname)) {
805
printf("fGetString failed\n");
811
/* read number of elems */
812
if (fGetInt(fp, &nelem)) {
813
printf("fGetInt failed\n");
819
/* read Descriptor from file */
820
if (!(fdp = lUndumpDescr(fp))) {
826
if (!dp) /* dp is NULL, use lDescr from dumpfile */
829
/* use old name (from file) if name is NULL */
830
if (!(lp = lCreateList((name) ? name : oldname, dp))) {
831
LERROR(LECREATELIST);
835
free(oldname); /* fGetString strdup's */
837
if ((n = lCountDescr(dp)) <= 0) {
838
LERROR(LECOUNTDESCR);
844
if (!(found = (int *) malloc(sizeof(int) * n))) {
851
/* Initialize found array */
852
for (i = 0; i < n; i++)
855
/* Here warnings are displayed if there are additional or missing fields */
856
for (j = 0; fdp[j].nm != NoName; j++) {
857
for (i = 0; i < n; i++) {
858
if (dp[i].nm == fdp[j].nm &&
859
dp[i].mt == fdp[j].mt) {
861
DPRINTF(("lUndumpList: field %s found twice\n",
868
DPRINTF(("lUndumpList: field %s not needed\n", lNm2Str(fdp[j].nm)));
871
for (i = 0; i < n; i++)
873
DPRINTF(("lUndumpList: field %s not found\n", lNm2Str(dp[i].nm)));
875
/* LOOP OVER THE LIST ELEMENTS */
876
for (k = 0; k < nelem; k++) {
877
if (!(fep = lUndumpElemFp(fp, fdp))) {
878
LERROR(LEUNDUMPELEM);
885
if (!(ep = lCreateElem(dp))) {
888
LERROR(LECREATEELEM);
893
for (i = 0; i < n; i++) {
894
if (found[i] == -1) {
896
} else if (lCopySwitchPack(fep, ep, found[i], i, true, NULL, NULL) == -1) {
900
LERROR(LECOPYSWITCH);
906
if (lAppendElem(lp, ep) == -1) {
910
LERROR(LEAPPENDELEM);
920
printf("ket is missing\n");
930
static int space_comment(char *s)
934
DENTER(CULL_LAYER, "space_comment");
936
while ((t = strstr(s, "/*"))) {
937
if (!(p = strstr(t + 2, "*/"))) {
949
static int fGetLine(FILE *fp, char *line, int max_line)
951
DENTER(CULL_LAYER, "fGetLine");
959
if (!(fgets(line, max_line, fp))) {
964
if (space_comment(line)) {
965
LERROR(LESPACECOMMENT);
974
static int fGetBra(FILE *fp)
976
char s[READ_LINE_LENGHT + 1];
978
DENTER(CULL_LAYER, "fGetBra");
980
if (fGetLine(fp, s, READ_LINE_LENGHT)) {
987
return strstr(s, "{") ? 0 : -1;
990
static int fGetKet(FILE *fp)
992
char s[READ_LINE_LENGHT + 1];
994
DENTER(CULL_LAYER, "fGetKet");
996
if (fGetLine(fp, s, READ_LINE_LENGHT)) {
1003
return strstr(s, "}") ? 0 : -1;
1006
static int fGetDescr(FILE *fp, lDescr *dp)
1008
char s[READ_LINE_LENGHT + 1];
1010
char bra[2], comma[2], ket[2];
1012
DENTER(CULL_LAYER, "fGetDescr");
1021
LERROR(LEDESCRNULL);
1026
if (fGetLine(fp, s, READ_LINE_LENGHT)) {
1033
We use this strange form of scanf to skip the
1034
white space at the beginning. scanf is magic isn't it?
1036
if (sscanf(s, "%1s %d %1s %d %1s", bra, &nm, comma, &mt, ket) != 5) {
1042
if (bra[0] != '{' || comma[0] != ',' || ket[0] != '}') {
1056
static int fGetInt(FILE *fp, int *ip)
1058
char s[READ_LINE_LENGHT + 1];
1060
DENTER(CULL_LAYER, "fGetInt");
1068
if (fGetLine(fp, s, READ_LINE_LENGHT)) {
1074
if (sscanf(s, "%d", ip) != 1) {
1084
static int fGetUlong(FILE *fp, lUlong *up)
1086
char s[READ_LINE_LENGHT + 1];
1088
DENTER(CULL_LAYER, "fGetUlong");
1096
if (fGetLine(fp, s, READ_LINE_LENGHT)) {
1102
if (sscanf(s, sge_u32, up) != 1) {
1112
static int fGetString(FILE *fp, lString *tp)
1115
char line[READ_LINE_LENGHT + 1];
1116
dstring sp = DSTRING_INIT;
1119
DENTER(CULL_LAYER, "fGetString");
1126
if (fGetLine(fp, line, READ_LINE_LENGHT)) {
1133
while (isspace((int) *s)) {
1141
for (i = 0; s[i] != '\0' && s[i] != '"'; i++) {
1145
sge_dstring_append_char(&sp, s[i]);
1149
/* String is diveded by a newline */
1151
if (fGetLine(fp, line, READ_LINE_LENGHT)) {
1152
sge_dstring_free(&sp);
1158
for (j = 0; s[j] != '\0' && s[j] != '"'; j++, i++) {
1159
sge_dstring_append_char(&sp, s[j]);
1168
s = sge_dstring_get_string(&sp);
1175
sge_dstring_free(&sp);
1187
static int fGetHost(FILE *fp, lHost *tp)
1190
char line[READ_LINE_LENGHT + 1];
1191
char sp[READ_LINE_LENGHT + 1];
1194
DENTER(CULL_LAYER, "fGetHost");
1202
if (fGetLine(fp, line, READ_LINE_LENGHT)) {
1209
while (isspace((int) *s))
1216
for (i = 0; s[i] != '\0' && s[i] != '"'; i++)
1225
if (!(*tp = strdup(sp))) {
1235
static int fGetFloat(FILE *fp, lFloat *flp)
1237
char s[READ_LINE_LENGHT + 1];
1239
DENTER(CULL_LAYER, "fGetFloat");
1247
if (fGetLine(fp, s, READ_LINE_LENGHT)) {
1253
if (sscanf(s, "%f", flp) != 1) {
1263
static int fGetDouble(FILE *fp, lDouble *dp)
1265
char s[READ_LINE_LENGHT + 1];
1267
DENTER(CULL_LAYER, "fGetDouble");
1275
if (fGetLine(fp, s, READ_LINE_LENGHT)) {
1281
if (sscanf(s, "%lf", dp) != 1) {
1291
static int fGetLong(FILE *fp, lLong *lp)
1293
char s[READ_LINE_LENGHT + 1];
1295
DENTER(CULL_LAYER, "fGetLong");
1303
if (fGetLine(fp, s, READ_LINE_LENGHT)) {
1309
if (sscanf(s, "%ld", lp) != 1) {
1319
static int fGetChar(FILE *fp, lChar *cp)
1321
char s[READ_LINE_LENGHT + 1];
1323
DENTER(CULL_LAYER, "fGetChar");
1331
if (fGetLine(fp, s, READ_LINE_LENGHT)) {
1337
if (sscanf(s, "%c", cp) != 1) {
1347
static int fGetBool(FILE *fp, lBool *cp)
1349
char s[READ_LINE_LENGHT + 1];
1352
DENTER(CULL_LAYER, "fGetBool");
1360
if (fGetLine(fp, s, READ_LINE_LENGHT)) {
1366
if (sscanf(s, "%d", &i) != 1) {
1378
static int fGetList(FILE *fp, lList **lpp)
1380
char s[READ_LINE_LENGHT + 1];
1382
DENTER(CULL_LAYER, "fGetList");
1390
if (fGetLine(fp, s, READ_LINE_LENGHT)) {
1396
if (strstr(s, "empty") != NULL)
1397
*lpp = NULL; /* empty sublist */
1400
if (strstr(s, "full") == 0) {
1406
if ((*lpp = lUndumpList(fp, NULL, NULL)) == NULL) {
1407
LERROR(LEUNDUMPLIST);
1417
static int fGetObject(FILE *fp, lListElem **epp)
1419
char s[READ_LINE_LENGHT + 1];
1421
DENTER(CULL_LAYER, "fGetObject");
1429
if (fGetLine(fp, s, READ_LINE_LENGHT)) {
1435
if (strstr(s, "none") != NULL)
1436
*epp = NULL; /* no object stored */
1438
if (strstr(s, "object") == 0) {
1444
if ((*epp = lUndumpObject(fp)) == NULL) {
1445
LERROR(LEUNDUMPELEM);
1449
(*epp)->status = OBJECT_ELEM;