33#include <libFreeWRL.h>
35#include "../vrml_parser/Structs.h"
36#include "../main/headers.h"
37#include "../vrml_parser/CParseGeneral.h"
38#include "../scenegraph/Vector.h"
39#include "../vrml_parser/CFieldDecls.h"
40#include "../world_script/JScript.h"
41#include "../world_script/CScripts.h"
42#include "../world_script/fieldSet.h"
43#include "../vrml_parser/CParseParser.h"
44#include "../vrml_parser/CParseLexer.h"
45#include "../vrml_parser/CParse.h"
46#include "../vrml_parser/CRoutes.h"
47#include "../input/EAIHeaders.h"
48#include "../input/EAIHelpers.h"
53#include <libxml/parser.h>
55typedef xmlSAXHandler* XML_Parser;
58#define XML_GetCurrentLineNumber(aaa) (int)999
61#define XML_ParserFree(aaa) FREE_IF_NZ(aaa)
62#define XML_SetUserData(aaa,bbb)
63#define XML_STATUS_ERROR -1
68#define PARSING_NODES 1
69#define PARSING_SCRIPT 2
70#define PARSING_PROTODECLARE 3
71#define PARSING_PROTOINTERFACE 4
72#define PARSING_PROTOBODY 5
73#define PARSING_PROTOINSTANCE 6
75#define PARSING_CONNECT 8
76#define PARSING_EXTERNPROTODECLARE 9
77#define PARSING_FIELD 10
78#define PARSING_PROTOINSTANCE_USE 11
81#define PROTOINSTANCE_MAX_LEVELS 50
83#define LINE freewrl_XML_GetCurrentLineNumber()
86struct X3D_Node *broto_search_DEFname(
struct X3D_Proto *context,
const char *name);
87static struct X3D_Node *DEFNameIndex (
const char *name,
struct X3D_Node* node,
int force);
99 ud->context = ud->nodes = ud->atts = ud->modes = ud->fields = NULL;
100 ud->context = newVector(
struct X3D_Node*,256);
102 ud->nodes = newVector(
struct X3D_Node*,256);
104 ud->atts = newVector(
void*,256);
106 ud->modes = newVector(
int,256);
108 ud->fields = newVector(
char *,256);
114 deleteVector(
struct X3D_Node*,ud->context);
115 deleteVector(
struct X3D_Node*,ud->nodes);
116 deleteVector(
void*,ud->atts);
117 deleteVector(
void*,ud->modes);
118 deleteVector(
void*,ud->fields);
131static void pushContext(
void *userData,
struct X3D_Node* context){
133 if(context->_nodeType != NODE_Proto && context->_nodeType != NODE_Inline)
134 printf(
"attempt to cast a node of type %d to Proto\n",context->_nodeType);
135 stack_push(
struct X3D_Proto*,ud->context,X3D_PROTO(context));
137static struct X3D_Proto* getContext(
void *userData,
int index){
141 return vector_get(
struct X3D_Proto*,ud->context, vectorSize(ud->context)+index);
143 return vector_get(
struct X3D_Proto*,ud->context, index);
145static void popContext(
void *userData){
147 stack_pop(
struct X3D_Proto*,ud->context);
150static void pushNode(
void *userData,
struct X3D_Node* node){
152 stack_push(
struct X3D_Node*,ud->nodes,node);
153 stack_push(
void* ,ud->atts,NULL);
155static struct X3D_Node* getNode(
void *userData,
int index){
158 return vector_get(
struct X3D_Node*,ud->nodes, vectorSize(ud->nodes)+index);
160 return vector_get(
struct X3D_Node*,ud->nodes, index);
163static void popNode(
void *userData){
165 stack_pop(
struct X3D_Node*,ud->nodes);
166 stack_pop(
void* ,ud->atts);
174 {PARSING_NODES,
"PARSING_NODES"},
175 {PARSING_SCRIPT,
"PARSING_SCRIPT"},
176 {PARSING_PROTODECLARE,
"PARSING_PROTODECLARE"},
177 {PARSING_PROTOINTERFACE,
"PARSING_PROTOINTERFACE"},
178 {PARSING_PROTOBODY,
"PARSING_PROTOBODY"},
179 {PARSING_PROTOINSTANCE,
"PARSING_PROTOINSTANCE"},
180 {PARSING_IS,
"PARSING_IS"},
181 {PARSING_CONNECT,
"PARSING_CONNECT"},
182 {PARSING_EXTERNPROTODECLARE,
"PARSING_EXTERNPROTODECLARE"},
183 {PARSING_FIELD,
"PARSING_FIELD"},
184 {PARSING_PROTOINSTANCE_USE,
"PARSING_PROTOINSTANCE_USE"},
188static void pushMode(
void *userData,
int parsingmode){
190 stack_push(
int,ud->modes,parsingmode);
192static int getMode(
void *userData,
int index){
196 return vector_get(
int,ud->modes, vectorSize(ud->modes)+index);
198 return vector_get(
int,ud->modes, index);
200static void popMode(
void *userData){
202 stack_pop(
int,ud->modes);
205static void pushField(
void *userData,
const char *fname){
207 stack_push(
char *,ud->fields,(
char *)fname);
208 if(0) printf(
"push n=%d\n",ud->fields->n);
210static char * getField(
void *userData,
int index){
212 if(0) printf(
"get n=%d\n",ud->fields->n);
214 return vector_get(
char *,ud->fields, vectorSize(ud->fields)+index);
216 return vector_get(
char *,ud->fields, index);
219static void popField(
void *userData){
221 stack_pop(
char *,ud->fields);
222 if(0) printf(
"pop n=%d\n",ud->fields->n);
225static int XML_ParseFile(xmlSAXHandler *me,
void *user_data,
const char *myinput,
int myinputlen,
int recovery) {
227 if (xmlSAXUserParseMemory(me, user_data, myinput,myinputlen) == 0)
return 0;
228 return XML_STATUS_ERROR;
233#define XML_CreateParserLevel(aaa) \
234 aaa = MALLOC(xmlSAXHandler *, sizeof (xmlSAXHandler)); \
235 bzero (aaa,sizeof(xmlSAXHandler));
237#define XML_SetElementHandler(aaa,bbb,ccc) \
238 aaa->startElement = bbb; \
239 aaa->endElement = ccc;
242#define XML_SetDefaultHandler(aaa,bbb)
243#define XML_SetCdataSectionHandler(aaa,bbb,ccc) \
244 aaa->cdataBlock = endCDATA;
262 int CDATA_TextMallocSize;
264 int in3_3_fieldValue;
265 int in3_3_fieldIndex;
267 int X3DParserRecurseLevel;
268 XML_Parser x3dparser[PROTOINSTANCE_MAX_LEVELS];
269 XML_Parser currentX3DParser;
271 int currentParserMode[PROTOINSTANCE_MAX_LEVELS];
272 int currentParserModeIndex;
277static void *X3DParser_constructor(){
283void X3DParser_init(
struct tX3DParser *t){
286 t->CDATA_Text = NULL;
287 t->CDATA_Text_curlen = 0;
289 t->prv = X3DParser_constructor();
293 p->DEFedNodes = NULL;
295 p->CDATA_TextMallocSize = 0;
297 p->in3_3_fieldValue = FALSE;
298 p->in3_3_fieldIndex = INT_ID_UNDEFINED;
300 p->X3DParserRecurseLevel = INT_ID_UNDEFINED;
301 p->currentX3DParser = NULL;
303 p->currentParserModeIndex = 0;
309void X3DParser_clear(
struct tX3DParser *t){
313 free_xml_user_data(p->user_data);
315 lexer_destroyData(p->myLexer);
316 FREE_IF_NZ(p->myLexer);
326#ifdef X3DPARSERVERBOSE
327static const char *parserModeStrings[] = {
331 "PARSING_PROTODECLARE ",
332 "PARSING_PROTOINTERFACE ",
334 "PARSING_PROTOINSTANCE",
337 "PARSING_EXTERNPROTODECLARE",
340#undef X3DPARSERVERBOSE
344int freewrl_XML_GetCurrentLineNumber(
void) {
346 if (p->X3DParserRecurseLevel > INT_ID_UNDEFINED)
348 p->currentX3DParser = p->x3dparser[p->X3DParserRecurseLevel];
349 return (
int) XML_GetCurrentLineNumber(p->currentX3DParser);
351 return INT_ID_UNDEFINED;
406char *X3DParser_getNameFromNode(
struct X3D_Node* myNode) {
412 if (!p->DEFedNodes)
return NULL;
416 for (ind=0; ind<vectorSize(stack_top(
struct Vector*, p->DEFedNodes)); ind++) {
417 node=vector_get(
struct X3D_Node*, stack_top(
struct Vector*, p->DEFedNodes),ind);
421 if (myNode == node) {
424 ns = stack_top(
struct Vector*, p->myLexer->userNodeNames);
425 return ((
char *)vector_get (
const char*, ns,ind));
434struct X3D_Node *X3DParser_getNodeFromName(
const char *name) {
435 return DEFNameIndex(name,NULL,FALSE);
443void kill_X3DDefs(
void) {
450printf (
"kill_X3DDefs... DEFedNodes %p\n",p->DEFedNodes);
451printf (
"kill_X3DDefs... myLexer %p\n",p->myLexer);
453 if (p->DEFedNodes != NULL) {
454 for (i=0; i<vectorSize(p->DEFedNodes); i++) {
455 struct Vector * myele = vector_get (
struct Vector*, p->DEFedNodes, i);
460 deleteVector (
struct Vector *,myele);
462 deleteVector(
struct Vector*, p->DEFedNodes);
463 p->DEFedNodes = NULL;
467 if (p->myLexer != NULL) {
468 lexer_destroyData(p->myLexer);
469 deleteLexer(p->myLexer);
474 Parser_deleteParserForScanStringValueToMem();
481static struct X3D_Node *DEFNameIndex (
const char *name,
struct X3D_Node* node,
int force) {
486#ifdef X3DPARSERVERBOSE
487 printf (
"DEFNameIndex, p is %p\n",p);
488 printf (
"DEFNameIndex, looking for :%s:, force %d nodePointer %u\n",name,force,node);
489 printf (
"DEFNameIndex, p->myLexer %p\n",p->myLexer);
490 printf (
"DEFNameIndex, stack %p\n",p->DEFedNodes);
491 printf (
"DEFNameIndex, p->user_data %p\n",p->user_data);
494 if (p->user_data != NULL) {
497 struct X3D_Proto *context2 = getContext(ud,TOP);
499 if (ud->context != NULL) {
503 node = broto_search_DEFname(context2,name);
511#ifdef X3DPARSERVERBOSE
512 if (node != NULL) printf (
"DEFNameIndex for %s, returning %u, nt %s\n",
513 name, node,stringNodeType(node->_nodeType));
514 else printf (
"DEFNameIndex, node is NULL\n");
520#undef X3DPARSERVERBOSE
524int getFieldFromNodeAndName(
struct X3D_Node* node,
const char *fieldname,
int *type,
int *kind,
int *iifield,
union anyVrml **value);
525int getFieldFromNodeAndNameC(
struct X3D_Node* node,
const char *fieldname,
int *type,
int *kind,
int *iifield,
int *builtIn,
union anyVrml **value,
const char **cname);
526int getFieldFromNodeAndNameU(
struct X3D_Node* node,
const char *fieldname,
int *type,
int *kind,
int *iifield,
int *builtIn,
union anyVrml **value,
int *iunca,
const char **cname);
527void broto_store_route(
struct X3D_Proto* proto,
struct X3D_Node* fromNode,
int fromOfs,
struct X3D_Node* toNode,
int toOfs,
int ft);
528struct IMEXPORT *broto_search_IMPORTname(
struct X3D_Proto *context,
const char *name);
529void broto_store_ImportRoute(
struct X3D_Proto* proto,
char *fromNode,
char *fromField,
char *toNode,
char* toField);
533static int QA_routeEnd(
struct X3D_Proto *context,
char* cnode,
char* cfield,
struct brouteEnd* brend,
int isFrom){
539 brend->cfield = STRDUP(cfield);
540 brend->cnode = STRDUP(cnode);
542 node = broto_search_DEFname(context,cnode);
545 imp = broto_search_IMPORTname(context, cnode);
552 int type,kind,ifield,source;
555 if(isFrom) idir = PKW_outputOnly;
556 else idir = PKW_inputOnly;
557 found = find_anyfield_by_nameAndRouteDir(node,&value,&kind,&type,cfield,&source,&decl,&ifield,idir);
562 brend->ifield = ifield;
563 brend->builtIn = source == 0? TRUE : FALSE;
570void QAandRegister_parsedRoute_B(
struct X3D_Proto *context,
char* fnode,
char* ffield,
char* tnode,
char* tfield){
575 int haveFrom, haveTo, ok;
578 int allowingVeryWeakRoutes = 1;
581 route = createNewBrotoRoute();
582 haveFrom = QA_routeEnd(context, fnode, ffield, &route->from, 1);
583 haveTo = QA_routeEnd(context, tnode, tfield, &route->to, 0);
584 if((haveFrom && haveTo) || allowingVeryWeakRoutes){
587 if( !route->from.weak) ftf = route->from.ftype;
588 if( !route->to.weak) ftt = route->to.ftype;
589 route->ft = ftf > -1 ? ftf : ftt > -1? ftt : -1;
590 route->lastCommand = 0;
591 if(ftf == ftt && ftf > -1){
593 int pflags = context->__protoFlags;
594 char oldwayflag = ciflag_get(pflags,1);
595 char instancingflag = ciflag_get(pflags,0);
596 if(oldwayflag || instancingflag){
597 CRoutes_RegisterSimpleB(route->from.node, route->from.ifield, route->from.builtIn, route->to.node, route->to.ifield, route->to.builtIn, route->ft);
598 route->lastCommand = 1;
603 }
else if(route->to.weak || route->from.weak){
608 if(ok || allowingVeryWeakRoutes)
609 broto_store_broute(context,route);
610 if(!ok || !(haveFrom && haveTo)){
611 ConsoleMessage(
"Routing problem: ");
613 if (haveFrom && haveTo && route->from.ftype != route->to.ftype) {
614 ConsoleMessage (
"type mismatch %s != %s, ",stringFieldtypeType(route->from.ftype), stringFieldtypeType(route->to.ftype));
616 if(!haveFrom) ConsoleMessage(
" _From_ ");
617 if(!haveTo) ConsoleMessage(
" _To_ ");
618 ConsoleMessage (
"from %s %s, ",fnode,ffield);
619 ConsoleMessage (
"to %s %s\n",tnode,tfield);
626static void parseRoutes_B (
void *ud,
char **atts) {
637 char *ffield, *tfield, *fnode, *tnode;
639 context = getContext(ud,TOP);
641 ffield = tfield = fnode = tnode = NULL;
642 for (i = 0; atts[i]; i += 2) {
643 if (strcmp(
"fromNode",atts[i]) == 0) {
645 }
else if (strcmp(
"toNode",atts[i]) == 0) {
647 }
else if (strcmp(
"fromField",atts[i])==0) {
649 }
else if (strcmp(
"toField",atts[i]) ==0) {
653 QAandRegister_parsedRoute_B(context, fnode, ffield, tnode, tfield);
699int getFieldFromNodeAndName(
struct X3D_Node* node,
const char *fieldname,
int *type,
int *kind,
int *iifield,
union anyVrml **value);
700int indexChildrenName(
struct X3D_Node *node);
702#define PPX(A) getTypeNode(X3D_NODE(A))
706static void linkNodeIn_B(
void *ud) {
725 struct X3D_Node *node, *typenode, *parent;
726 char *parentsSuggestion;
727 int type, kind, iifield, ok, isRootNode, mode;
731 mode = getMode(ud,TOP);
732 node = getNode(ud,TOP);
733 typenode = PPX(node);
734 parent = getNode(ud,TOP-1);
735 if(!node || !parent)
return;
736 if(node && !typenode)
739 if(parent->_nodeType == NODE_Proto){
740 if(mode == PARSING_PROTOBODY) isRootNode = TRUE;
748 union anyVrml *valueadd = NULL;
749 ok = getFieldFromNodeAndName(parent,
"__children",&type,&kind,&iifield,&valueadd);
750 AddRemoveChildren(parent,&valueadd->mfnode,&node,1,1,__FILE__,__LINE__);
753 unsigned int iContainer, jContainer, defaultContainer[3];
755 parentsSuggestion = getField(ud,TOP-1);
758 jContainer = typenode->_defaultContainer;
761 defaultContainer[0] = (jContainer << 22) >> 22;
762 defaultContainer[1] = (jContainer << 12) >> 22;
763 defaultContainer[2] = (jContainer << 2) >> 22;
765 if(defaultContainer[1])
767 if(defaultContainer[2])
769 for(i=0;i<ncontainer;i++){
770 iContainer = defaultContainer[i];
771 if(iContainer == FIELDNAMES_children) iContainer = 0;
776 fname = FIELDNAMES[iContainer];
777 ok = getFieldFromNodeAndName(parent,fname,&type,&kind,&iifield,&value);
778 ok = ok && (kind == PKW_initializeOnly || kind == PKW_inputOutput);
780 if(!value && iContainer == FIELDNAMES_children){
783 ok = getFieldFromNodeAndName(parent,
"children",&type,&kind,&iifield,&value);
784 ok = ok && (kind == PKW_initializeOnly || kind == PKW_inputOutput);
786 int kids = indexChildrenName(parent);
788 value = (
union anyVrml*)childrenField(parent);
789 type = FIELDTYPE_MFNode;
798 if(!ok && parentsSuggestion) {
805 ok =getFieldFromNodeAndName(parent,parentsSuggestion,&type,&kind,&iifield,&value);
808 if(!value && parent){
809 ok = getFieldFromNodeAndName(parent,
"children",&type,&kind,&iifield,&value);
811 int kids = indexChildrenName(parent);
813 value = (
union anyVrml*)childrenField(parent);
814 type = FIELDTYPE_MFNode;
820 if(type == FIELDTYPE_SFNode){
821 value->sfnode = node;
822 ADD_PARENT(node,parent);
823 }
else if(type == FIELDTYPE_MFNode){
824 union anyVrml *valueadd = NULL;
826 if(parent->_nodeType == NODE_Proto){
827 struct X3D_Proto *pparent = X3D_PROTO(parent);
828 char cflag = ciflag_get(pparent->__protoFlags,2);
830 ok = getFieldFromNodeAndName(parent,
"addChildren",&type,&kind,&iifield,&valueadd);
833 AddRemoveChildren(parent,&valueadd->mfnode,&node,1,1,__FILE__,__LINE__);
835 AddRemoveChildren(parent,&value->mfnode,&node,1,1,__FILE__,__LINE__);
838 printf(
"no where to put node in parent\n");
839 printf(
"nodetype=%s parenttype=%s\n",stringNodeType(node->_nodeType),stringNodeType(parent->_nodeType));
847void Parser_scanStringValueToMem_B(
union anyVrml* any, indexT ctype,
const char *value,
int isXML);
849static void endCDATA_B (
void *ud,
const xmlChar *
string,
int len) {
850 char *fieldname = getField(ud,TOP);
851 struct X3D_Node *node = getNode(ud,TOP);
852 int type, kind, iifield, ok, handled;
854 ok = getFieldFromNodeAndName(node,fieldname,&type,&kind,&iifield,&value);
857 if(!strcmp(fieldname,
"url")){
859 if(strstr((
char*)
string,
"script")){
861 value->mfstring.n = 1;
862 value->mfstring.p = MALLOCV(
sizeof(
void *));
863 value->mfstring.p[0] = newASCIIString((
char *)
string);
868 Parser_scanStringValueToMem_B(value, type, (
const char*)
string, TRUE);
872void endCDATA (
void *ud,
const xmlChar *
string,
int len) {
873 endCDATA_B(ud,
string,len);
879void handleImport_B (
struct X3D_Node *nodeptr,
char *nodeName,
char *nodeImport,
char *as);
880static void parseImport_B(
void *ud,
char **atts) {
882 char *inlinedef, *exporteddef, *as;
884 context = getContext(ud,TOP);
886 inlinedef = exporteddef = as = NULL;
887 for (i = 0; atts[i]; i += 2) {
888 printf(
"import field:%s=%s\n", atts[i], atts[i + 1]);
889 if(!strcmp(atts[i],
"inlineDEF")) inlinedef = atts[i+1];
890 if(!strcmp(atts[i],
"exportedDEF")) exporteddef = atts[i+1];
891 if(!strcmp(atts[i],
"AS")) as = atts[i+1];
894 handleImport_B (X3D_NODE(context), inlinedef, exporteddef, as);
898void handleExport_B (
void *nodeptr,
char *node,
char *as);
899static void parseExport_B(
void *ud,
char **atts) {
904 context = getContext(ud,TOP);
906 localdef = as = NULL;
907 for (i = 0; atts[i]; i += 2) {
908 printf(
"export field:%s=%s\n", atts[i], atts[i + 1]);
909 if(!strcmp(atts[i],
"localDEF")) localdef = atts[i+1];
910 if(!strcmp(atts[i],
"AS")) as = atts[i+1];
912 handleExport_B(context,localdef, as);
917static void parseComponent(
char **atts) {
919 int myComponent = INT_ID_UNDEFINED;
920 int myLevel = INT_ID_UNDEFINED;
923 for (i = 0; atts[i]; i += 2) {
925 if (strcmp(
"level",atts[i]) == 0) {
926 if (sscanf(atts[i+1],
"%d",&myLevel) != 1) {
927 ConsoleMessage (
"Line %d: Expected Component level for component %s, got %s",LINE, atts[i], atts[i+1]);
930 }
else if (strcmp(
"name",atts[i]) == 0) {
931 myComponent = findFieldInCOMPONENTS(atts[i+1]);
932 if (myComponent == INT_ID_UNDEFINED) {
933 ConsoleMessage(
"Line %d: Component statement, but component name not valid :%s:",LINE,atts[i+1]);
938 ConsoleMessage (
"Line %d: Unknown fields in Component statement :%s: :%s:",LINE,atts[i], atts[i+1]);
942 if (myComponent == INT_ID_UNDEFINED) {
943 ConsoleMessage(
"Line %d: Component statement, but component name not stated",LINE);
944 }
else if (myLevel == INT_ID_UNDEFINED) {
945 ConsoleMessage(
"Line %d: Component statement, but component level not stated",LINE);
947 handleComponent(myComponent,myLevel);
952static void parseX3Dhead(
void *ud,
char **atts) {
954 int myProfile = -10000;
955 int versionIndex = INT_ID_UNDEFINED;
958 for (i = 0; atts[i]; i += 2) {
960 if (strcmp(
"profile",atts[i]) == 0) {
961 myProfile = findFieldInPROFILES(atts[i+1]);
962 }
else if (strcmp(
"version",atts[i]) == 0) {
970 if (myProfile == INT_ID_UNDEFINED) {
971 ConsoleMessage (
"expected valid profile in X3D header");
974 if (myProfile >= 0) handleProfile (myProfile);
977 if (versionIndex != INT_ID_UNDEFINED) {
978 handleVersion (atts[versionIndex]);
981 ec->__specversion = inputFileVersion[0]*100 + inputFileVersion[1]*10 + inputFileVersion[2];
985static void parseHeader(
char **atts) {
987 for (i = 0; atts[i]; i += 2) {
991static void parseScene(
char **atts) {
993 for (i = 0; atts[i]; i += 2) {
997static void parseMeta(
char **atts) {
999 for (i = 0; atts[i]; i += 2) {
1003static void parseUnit(
void *ud,
char **atts) {
1004 double conversionFactor = 1.0;
1005 char *name, *category;
1008 name = category = NULL;
1010 for (i = 0; atts[i]; i += 2){
1011 if(!strcmp(atts[i],
"name"))
1013 if(!strcmp(atts[i],
"category"))
1014 category = atts[i+1];
1015 if(!strcmp(atts[i],
"conversionFactor"))
1016 sscanf(atts[i+1],
"%lf",&conversionFactor);
1018 handleUnitDataStringString(ec,category, name, conversionFactor);
1020void deleteMallocedFieldValue(
int type,
union anyVrml *fieldPtr);
1021static void parseFieldValue_B(
void *ud,
char **atts) {
1022 int i, type, kind, iifield, builtIn, ok;
1023 const char *fname, *svalue, *cname;
1025 struct X3D_Node *node = getNode(ud,TOP);
1027 fname = svalue = NULL;
1028 for(i=0;atts[i];i+=2){
1029 if(!strcmp(atts[i],
"name")) fname = atts[i+1];
1030 if(!strcmp(atts[i],
"value")) svalue = atts[i+1];
1037 ok = getFieldFromNodeAndNameC(node,fname,&type,&kind,&iifield,&builtIn,&value,&cname);
1039 if(cname && value && svalue){
1040 deleteMallocedFieldValue(type,value);
1041 Parser_scanStringValueToMem_B(value,type,svalue,TRUE);
1043 if(cname && (node->_nodeType == NODE_Proto) && !builtIn){
1053 pnode = X3D_PROTO(node);
1055 pfield = vector_get(
struct ProtoFieldDecl*,pstruct->iface,iifield);
1059 if(pfield->type == FIELDTYPE_MFNode){
1060 struct Multi_Node* mfn = &pfield->defaultVal.mfnode;
1062 AddRemoveChildren(node,mfn,mfn->p,mfn->n,2,__FILE__,__LINE__);
1063 pfield->defaultVal.mfnode.n = 0;
1064 pfield->defaultVal.mfnode.p = NULL;
1066 if(pfield->type == FIELDTYPE_SFNode){
1067 struct X3D_Node **sfn = &pfield->defaultVal.sfnode;
1069 AddRemoveSFNodeFieldChild(node,sfn,*sfn,2,__FILE__,__LINE__);
1070 pfield->defaultVal.sfnode = NULL;
1072 pfield->alreadySet = TRUE;
1074 pushField(ud,cname);
1076static void endFieldValue_B(
void *ud){
1077 if(0) printf(
"endFieldValue\n");
1084static void parseIS(
void *ud) {
1085 #ifdef X3DPARSERVERBOSE
1086 printf (
"parseIS mode is %s\n",parserModeStrings[getMode(ud,TOP)]);
1088 pushMode(ud,PARSING_IS);
1094static void endIS(
void *ud) {
1095 #ifdef X3DPARSERVERBOSE
1096 printf (
"endIS mode is %s\n",parserModeStrings[getMode(ud,TOP)]);
1103static void endProtoInterfaceTag(
void *ud) {
1104 if (getMode(ud,TOP) != PARSING_PROTOINTERFACE) {
1105 ConsoleMessage (
"endProtoInterfaceTag: got a </ProtoInterface> but not parsing one at line %d",LINE);
1111static void endProtoBodyTag_B(
void *ud,
const char *name) {
1113 if (getMode(ud,TOP) != PARSING_PROTOBODY) {
1114 ConsoleMessage (
"endProtoBodyTag: got a </ProtoBody> but not parsing one at line %d",LINE);
1120static void endExternProtoDeclareTag_B(
void *ud) {
1126static void endProtoDeclareTag_B(
void *ud) {
1131 if (getMode(ud,TOP) != PARSING_PROTODECLARE) {
1132 ConsoleMessage (
"endProtoDeclareTag: got a </ProtoDeclare> but not parsing one at line %d",LINE);
1133 pushMode(ud,PARSING_PROTODECLARE);
1135 if(0) printf(
"end protoDeclare\n");
1137 proto = X3D_PROTO(getNode(ud,TOP));
1139 if(proto->__children.n)
1140 cptr = &proto->__children;
1141 else if(proto->addChildren.n)
1142 cptr = &proto->addChildren;
1145 if(c1->_defaultContainer > INT_ID_UNDEFINED)
1146 proto->_defaultContainer = c1->_defaultContainer;
1155static void endProtoInstance_B(
void *ud,
const char *name) {
1159 if(0) printf(
"endProtoInstance_B\n");
1161 node = getNode(ud,TOP);
1162 mode = getMode(ud,TOP);
1164 if(node->_nodeType == NODE_Proto || node->_nodeType == NODE_Inline ){
1165 if(mode != PARSING_PROTOINSTANCE_USE){
1167 struct X3D_Proto *pnode = X3D_PROTO(node);
1168 pflagdepth = ciflag_get(pnode->__protoFlags,0);
1174 pdeclare = X3D_PROTO(pnode->__prototype);
1179 deep_copy_broto_body2(&pdeclare,&pnode);
1207void **shaderFields(
struct X3D_Node* node){
1209 switch(node->_nodeType){
1211 shaderfield = &X3D_SCRIPT(node)->__scriptObj;
break;
1212 case NODE_ComposedShader:
1213 shaderfield = (
void**)&X3D_COMPOSEDSHADER(node)->_shaderUserDefinedFields;
break;
1215 shaderfield = (
void**)&X3D_EFFECT(node)->_shaderUserDefinedFields;
break;
1216 case NODE_ShaderProgram:
1217 shaderfield = (
void**)&X3D_SHADERPROGRAM(node)->_shaderUserDefinedFields;
break;
1218 case NODE_PackagedShader:
1219 shaderfield = (
void**)&X3D_PACKAGEDSHADER(node)->_shaderUserDefinedFields;
break;
1226void broto_store_DEF(
struct X3D_Proto* proto,
struct X3D_Node* node,
const char *name);
1227static void parseAttributes_B(
void *ud,
char **atts);
1229void push_binding_stack_set(
struct X3D_Node* layersetnode);
1230void push_next_layerId_from_binding_stack_set(
struct X3D_Node* layer);
1231void pop_binding_stack_set();
1233static void startBuiltin_B(
void *ud,
int myNodeType,
const xmlChar *name,
char** atts) {
1234 struct X3D_Node *node, *fromDEFtable;
1239 const char *defname, *suggestedChildField, *containerfield;
1241 suggestedChildField = containerfield = NULL;
1242 context = getContext(ud,TOP);
1243 pflagdepth = ciflag_get(context->__protoFlags,0);
1244 if(0) printf(
"start builtin %s\n",name);
1249 for (i = 0; atts[i]; i += 2) {
1251 if (strcmp (
"DEF",atts[i]) == 0) {
1252 defname = atts[i+1];
1253 fromDEFtable = broto_search_DEFname(context,defname);
1255 #ifdef X3DPARSERVERBOSE
1256 printf (
"Warning - line %d duplicate DEF name: \'%s\'\n",LINE,atts[i+1]);
1259 }
else if (strcmp (
"USE",atts[i]) == 0) {
1260 #ifdef X3DPARSERVERBOSE
1261 printf (
"this is a USE, name %s\n",atts[i+1]);
1265 fromDEFtable = broto_search_DEFname(context,atts[i+1]);
1266 if (!fromDEFtable) {
1267 ConsoleMessage (
"Warning - line %d DEF name: \'%s\' not found",LINE,atts[i+1]);
1268 ConsoleMessage(
"\n");
1270 #ifdef X3DPARSERVERBOSE
1271 printf (
"copying for field %s defName %s\n",atts[i], atts[i+1]);
1275 if (myNodeType != fromDEFtable->_nodeType) {
1276 ConsoleMessage (
"Warning, line %d DEF/USE mismatch, '%s', %s != %s", LINE,
1277 atts[i+1],stringNodeType(fromDEFtable->_nodeType), stringNodeType (myNodeType));
1280 node = fromDEFtable;
1281 node->referenceCount++;
1283 #ifdef X3DPARSERVERBOSE
1284 printf (
"successful copying for field %s defName %s\n",atts[i], atts[i+1]);
1289 }
else if(!strcmp(atts[i],
"containerField")) containerfield = atts[i+1];
1294 node = createNewX3DNode(myNodeType);
1296 node = createNewX3DNode0(myNodeType);
1298 broto_store_DEF(context,node,defname);
1302 if(containerfield) {
1304 int builtinField = findFieldInFIELDNAMES(containerfield);
1305 if(builtinField > INT_ID_UNDEFINED){
1310 node->_defaultContainer = (node->_defaultContainer << 10) + builtinField;
1318 shaderfield = shaderFields(node);
1320 (*shaderfield) = (
void *)new_Shader_ScriptB(node);
1323 if(node->_nodeType == NODE_LayerSet)
1324 push_binding_stack_set(node);
1325 if(node->_nodeType == NODE_Layer || node->_nodeType == NODE_LayoutLayer)
1326 push_next_layerId_from_binding_stack_set(node);
1327 if(node->_nodeType == NODE_Inline)
1328 X3D_INLINE(node)->__parentProto = X3D_NODE(context);
1329 node->_executionContext = X3D_NODE(context);
1330 add_node_to_broto_context(context,node);
1332 kids = indexChildrenName(node);
1334 suggestedChildField = FIELDNAMES[kids];
1335 if(node->_nodeType == NODE_Script || node->_nodeType == NODE_ShaderPart
1336 || node->_nodeType == NODE_ShaderProgram || node->_nodeType == NODE_EffectPart)
1337 suggestedChildField = FIELDNAMES[FIELDNAMES_url];
1339 pushField(ud,suggestedChildField);
1341 parseAttributes_B(ud,atts);
1348void applyUnitsToNode(
struct X3D_Node *node);
1349static void endBuiltin_B(
void *ud,
const xmlChar *name){
1353 node = getNode(ud,TOP);
1354 context = getContext(ud,TOP);
1355 if(0)printf(
"end builtin %s\n",name);
1356 pflagdepth = ciflag_get(context->__protoFlags,0);
1357 applyUnitsToNode(node);
1358 if(node->_nodeType == NODE_Script && pflagdepth){
1361 initialize_one_script(sn->__scriptObj,&sn->url);
1364 if(node->_nodeType == NODE_LayerSet)
1365 pop_binding_stack_set();
1374static xmlChar* fixAmp(
const unsigned char *InFieldValue)
1376 char *fieldValue = (
char *)InFieldValue;
1385 char *pp = strstr((
char *)fieldValue,
"&");
1387 memmove(pp+1,pp+5,strlen(fieldValue) - (pp+1 - fieldValue));
1388 pp = strstr(pp,
"&");
1401 return (xmlChar *)fieldValue;
1404void sfunitf(
int nodeType,
char *fieldname,
float *var,
int n,
int iuncafield);
1405void mfunitrotation(
int nodeType,
char *fieldname,
struct SFRotation *var,
int n,
int iuncafield);
1406void sfunitd(
int nodeType,
char *fieldname,
double *var,
int n,
int iuncafield);
1407void mfunit3f(
int nodetype,
char *fieldname,
struct SFVec3f *var,
int n,
int iuncafield);
1408static void parseAttributes_B(
void *ud,
char **atts) {
1409 int i, type, kind, iifield, builtIn, iunca, isunits;
1412 char *name, *svalue;
1413 const char *ignore [] = {
"containerField",
"USE",
"DEF"};
1416 node = getNode(ud,TOP);
1417 isunits = isUnits();
1418 for (i=0; atts[i]; i+=2) {
1422 if(findFieldInARR(name,ignore,3) == INT_ID_UNDEFINED){
1424 if(getFieldFromNodeAndNameU(node,name,&type,&kind,&iifield,&builtIn,&value,&iunca,&cname)){
1425 deleteMallocedFieldValue(type,value);
1426 Parser_scanStringValueToMem_B(value, type,svalue, TRUE);
1431 case FIELDTYPE_SFRotation:
1432 sfunitf(node->_nodeType,name,&value->sfrotation.c[3],1,iunca);
1434 case FIELDTYPE_SFFloat:
1435 sfunitf(node->_nodeType,name,&value->sffloat,1,iunca);
1437 case FIELDTYPE_MFFloat:
1438 sfunitf(node->_nodeType,name,value->mffloat.p,value->mffloat.n,iunca);
1440 case FIELDTYPE_SFVec3f:
1441 sfunitf(node->_nodeType,name,value->sfvec3f.c,3,iunca);
1443 case FIELDTYPE_SFVec4f:
1444 if(iunca == UNCA_PLANE)
1445 sfunitf(node->_nodeType,name,&value->sfvec4f.c[3],1,UNCA_LENGTH);
1447 sfunitf(node->_nodeType,name,value->sfvec4f.c,4,iunca);
1449 case FIELDTYPE_SFVec2f:
1450 sfunitf(node->_nodeType,name,value->sfvec2f.c,2,iunca);
1452 case FIELDTYPE_MFVec3f:
1453 mfunit3f(node->_nodeType,name,value->mfvec3f.p,value->mfvec3f.n,iunca);
1455 case FIELDTYPE_SFMatrix3f:
1456 sfunitf(node->_nodeType,name,value->sfmatrix3f.c, 9,iunca);
1458 case FIELDTYPE_MFRotation:
1459 mfunitrotation(node->_nodeType,name,value->mfrotation.p,value->mfrotation.n,iunca);
1461 case FIELDTYPE_SFDouble:
1462 sfunitd(node->_nodeType,name,&value->sfdouble,1,iunca);
1469 if(!strcmp(name,
"side")){
1471 if(!strcmp(svalue,
"left"))
1472 node->_renderFlags |= VF_HideRight;
1473 else if(!strcmp(svalue,
"right"))
1474 node->_renderFlags |= VF_HideLeft;
1481int findFieldInARR(
const char* field,
const char** arr,
size_t cnt);
1482static void parseScriptProtoField_B(
void *ud,
char **atts) {
1491 int mp_name, mp_accesstype, mp_type, mp_value, i;
1494 char *fname, *cname;
1497 mp_name = mp_accesstype = mp_type = mp_value = ID_UNDEFINED;
1498 if(0) printf(
"start scriptProtoField\n");
1500 for (i = 0; atts[i]; i += 2) {
1502 if ((strcmp(
"appinfo", atts[i]) != 0) &&
1503 (strcmp(
"documentation",atts[i]) != 0)) {
1504 if (strcmp(atts[i],
"name") == 0) { mp_name = i+1;
1505 }
else if (strcmp(atts[i],
"accessType") == 0) { mp_accesstype = i+1;
1506 }
else if (strcmp(atts[i],
"type") == 0) { mp_type = i+1;
1507 }
else if (strcmp(atts[i],
"value") == 0) { mp_value = i+1;
1509 ConsoleMessage (
"X3D Proto/Script parsing line %d: unknown field type %s",LINE,atts[i]);
1514 if(mp_accesstype > -1 && mp_type > -1 && mp_name > -1){
1516 pkwmode = findFieldInARR(atts[mp_accesstype], PROTOKEYWORDS, PROTOKEYWORDS_COUNT);
1517 pkwmode = pkwmode > -1? X3DMODE(pkwmode) : pkwmode;
1518 type = findFieldInARR(atts[mp_type],FIELDTYPES,FIELDTYPES_COUNT);
1519 fname = atts[mp_name];
1522 bzero(&defaultValue,
sizeof (
union anyVrml));
1523 if(type == FIELDTYPE_SFString)
1524 defaultValue.sfstring = newASCIIString(
"");
1527 Parser_scanStringValueToMem_B(&defaultValue, type, atts[mp_value], TRUE);
1530 if(pkwmode > -1 && type > -1){
1531 struct X3D_Node * node = getNode(ud,TOP);
1532 if(node->_nodeType == NODE_Proto){
1536 pnode = X3D_PROTO(node);
1538 pfield = newProtoFieldDecl(pkwmode,type,0);
1539 pfield->cname = STRDUP(fname);
1540 cname = pfield->cname;
1541 memcpy(&pfield->defaultVal,&defaultValue,
sizeof(
union anyVrml));
1548 switch(node->_nodeType)
1550 case NODE_Script: shader =(
struct Shader_Script *)(X3D_SCRIPT(node)->__scriptObj);
break;
1551 case NODE_ComposedShader: shader =(
struct Shader_Script *)(X3D_COMPOSEDSHADER(node)->_shaderUserDefinedFields);
break;
1552 case NODE_Effect: shader =(
struct Shader_Script *)(X3D_EFFECT(node)->_shaderUserDefinedFields);
break;
1553 case NODE_ShaderProgram: shader =(
struct Shader_Script *)(X3D_SHADERPROGRAM(node)->_shaderUserDefinedFields);
break;
1554 case NODE_PackagedShader: shader =(
struct Shader_Script *)(X3D_PACKAGEDSHADER(node)->_shaderUserDefinedFields);
break;
1556 jsname = JSparamIndex (fname, atts[mp_type],pkwmode);
1557 cname = getJSparamnames()[jsname].name;
1561 sfield->fieldDecl = newFieldDecl(pkwmode,type,0,jsname,0);
1562 memcpy(&sfield->value,&defaultValue,
sizeof(
union anyVrml));
1563 sfield->valueSet = valueSet;
1564 sfield->eventInSet = FALSE;
1570 pushField(ud,cname);
1571 pushMode(ud,PARSING_FIELD);
1575static void parseProtoInterface (
void *ud,
char **atts) {
1576 if (getMode(ud,TOP) != PARSING_PROTODECLARE && getMode(ud,TOP) != PARSING_EXTERNPROTODECLARE) {
1577 ConsoleMessage (
"got a <ProtoInterface>, but not within a <ProtoDeclare>\n");
1580 pushMode(ud,PARSING_PROTOINTERFACE);
1582void Parser_scanStringValueToMem_B(
union anyVrml* any, indexT ctype,
const char *value,
int isXML);
1583double getunitlengthfactor();
1584static void parseExternProtoDeclare_B (
void *ud,
char **atts) {
1592 char *type_name, *appinfo, *documentation, *containerfield, *url;
1596 type_name = appinfo = documentation = containerfield = url = NULL;
1597 if(0) printf(
"in parseExternProtoDeclare_B\n");
1599 proto = createNewX3DNode0(NODE_Proto);
1600 for (i = 0; atts[i]; i += 2) {
1601 #ifdef X3DPARSERVERBOSE
1603 printf (
"parseProtoDeclare: field:%s=%s\n", atts[i], atts[i+1]);
1606 if (!strcmp(
"name",atts[i]) ) type_name = atts[i+1];
1607 else if(!strcmp(
"containerField",atts[i])) containerfield = atts[i+1];
1608 else if(!strcmp(
"appInfo",atts[i])) appinfo = atts[i+1];
1609 else if(!strcmp(
"documentation",atts[i])) documentation = atts[i+1];
1610 else if(!strcmp(
"url",atts[i])) url = atts[i+1];
1613 parent = (
struct X3D_Proto*)getContext(ud,TOP);
1614 obj=newProtoDefinition();
1618 obj->protoName = STRDUP(type_name);
1620 printf (
"warning - have proto but no name, so just copying a default string in\n");
1621 obj->protoName = STRDUP(
"noProtoNameDefined");
1623 type_name = obj->protoName;
1625 if(parent->__externProtoDeclares == NULL)
1626 parent->__externProtoDeclares = newVector(
struct X3D_Proto*,4);
1627 vector_pushBack(
struct X3D_Proto*,parent->__externProtoDeclares,proto);
1628 proto->__parentProto = X3D_NODE(parent);
1629 proto->__protoFlags = parent->__protoFlags;
1630 proto->__protoFlags = ciflag_set(proto->__protoFlags,0,0);
1632 proto->__protoFlags = ciflag_set(proto->__protoFlags,0,2);
1633 proto->__protoFlags = ciflag_set(proto->__protoFlags,1,3);
1635 proto->__protoDef = obj;
1636 proto->__prototype = X3D_NODE(proto);
1637 proto->__typename = STRDUP(obj->protoName);
1638 proto->__unitlengthfactor = getunitlengthfactor();
1639 proto->__specversion = inputFileVersion[0]*100 + inputFileVersion[1]*10 + inputFileVersion[2];
1641 int builtinField = findFieldInFIELDNAMES(containerfield);
1642 if(builtinField > -1){
1643 proto->_defaultContainer = builtinField;
1647 Parser_scanStringValueToMem_B((
union anyVrml*)&proto->url, FIELDTYPE_MFString,url, TRUE);
1649 proto->__loadstatus = 0;
1650 pushMode(ud,PARSING_EXTERNPROTODECLARE);
1651 pushNode(ud,X3D_NODE(proto));
1652 pushField(ud,
"__children");
1656static void parseProtoDeclare_B (
void *ud,
char **atts) {
1665 char *type_name, *appinfo, *documentation, *containerfield;
1669 type_name = appinfo = documentation = containerfield = NULL;
1670 if(0) printf(
"in start protoDeclare\n");
1672 proto = createNewX3DNode0(NODE_Proto);
1673 for (i = 0; atts[i]; i += 2) {
1674 #ifdef X3DPARSERVERBOSE
1676 printf (
"parseProtoDeclare: field:%s=%s\n", atts[i], atts[i+1]);
1679 if (!strcmp(
"name",atts[i]) ) type_name = atts[i+1];
1680 else if(!strcmp(
"containerField",atts[i])) containerfield = atts[i+1];
1681 else if(!strcmp(
"appInfo",atts[i])) appinfo = atts[i+1];
1682 else if(!strcmp(
"documentation",atts[i])) documentation = atts[i+1];
1685 parent = (
struct X3D_Proto*)getContext(ud,TOP);
1686 obj=newProtoDefinition();
1690 obj->protoName = STRDUP(type_name);
1692 printf (
"warning - have proto but no name, so just copying a default string in\n");
1693 obj->protoName = STRDUP(
"noProtoNameDefined");
1695 type_name = obj->protoName;
1697 if(parent->__protoDeclares == NULL)
1698 parent->__protoDeclares = newVector(
struct X3D_Proto*,4);
1699 vector_pushBack(
struct X3D_Proto*,parent->__protoDeclares,proto);
1700 proto->__parentProto = X3D_NODE(parent);
1701 proto->__protoFlags = parent->__protoFlags;
1702 proto->__protoFlags = ciflag_set(proto->__protoFlags,0,0);
1704 proto->__protoFlags = ciflag_set(proto->__protoFlags,0,2);
1705 proto->__protoFlags = ciflag_set(proto->__protoFlags,0,3);
1707 proto->__protoDef = obj;
1708 proto->__prototype = X3D_NODE(proto);
1709 proto->__typename = STRDUP(obj->protoName);
1710 proto->__unitlengthfactor = getunitlengthfactor();
1711 proto->__specversion = inputFileVersion[0]*100 + inputFileVersion[1]*10 + inputFileVersion[2];
1713 int builtinField = findFieldInFIELDNAMES(containerfield);
1714 if(builtinField > -1){
1715 proto->_defaultContainer = builtinField;
1719 pushMode(ud,PARSING_PROTODECLARE);
1720 pushNode(ud,X3D_NODE(proto));
1721 pushField(ud,
"__children");
1724static void parseProtoBody_B (
void *ud,
char **atts) {
1726 pushContext(ud,getNode(ud,TOP));
1727 pushMode(ud,PARSING_PROTOBODY);
1732void linkNodeIn_B(
void *ud);
1733struct X3D_Node *broto_search_DEFname(
struct X3D_Proto *context,
const char *name);
1735static void parseProtoInstance_B(
void *ud,
char **atts) {
1755 nameIndex = INT_ID_UNDEFINED;
1758 defNameIndex = INT_ID_UNDEFINED;
1760 if(0) printf(
"parseProtoInstance\n");
1762 for (i = 0; atts[i]; i += 2) {
1763 if (strcmp(
"name",atts[i]) == 0) {
1765 }
else if (strcmp(
"containerField",atts[i]) == 0) {
1767 }
else if (strcmp(
"DEF",atts[i]) == 0) {
1769 }
else if (strcmp(
"class",atts[i]) == 0) {
1770 ConsoleMessage (
"field \"class\" not currently used in a ProtoInstance parse... sorry");
1771 }
else if (strcmp(
"USE",atts[i]) == 0) {
1778 currentContext = getContext(ud,TOP);
1780 pflagdepth = ciflag_get(currentContext->__protoFlags,0);
1786 char * defname = atts[defNameIndex];
1788 fromDEFtable = broto_search_DEFname(currentContext,defname);
1789 if (!fromDEFtable) {
1790 ConsoleMessage (
"Warning - line %d DEF name: \'%s\' not found",LINE,atts[i+1]);
1791 ConsoleMessage(
"\n");
1793 #ifdef X3DPARSERVERBOSE
1794 printf (
"copying for field %s defName %s\n",atts[i], atts[i+1]);
1798 if (NODE_Proto != fromDEFtable->_nodeType) {
1799 ConsoleMessage (
"Warning, line %d DEF/USE mismatch, '%s', %s != %s", LINE,
1800 atts[i+1],stringNodeType(fromDEFtable->_nodeType), stringNodeType (NODE_Proto));
1803 char* containerfield;
1804 node = fromDEFtable;
1805 node->referenceCount++;
1807 #ifdef X3DPARSERVERBOSE
1808 printf (
"successful copying for field %s defName %s\n",atts[i], atts[i+1]);
1811 containerfield = NULL;
1812 for (i = 0; atts[i]; i += 2) {
1813 if(!strcmp(atts[i],
"containerField")) containerfield = atts[i+1];
1815 if(containerfield) {
1816 int builtinField = findFieldInFIELDNAMES(containerfield);
1817 if(builtinField > INT_ID_UNDEFINED){
1818 node->_defaultContainer = builtinField;
1822 pushMode(ud,PARSING_PROTOINSTANCE_USE);
1830 if (nameIndex != INT_ID_UNDEFINED) {
1831 protoname = atts[nameIndex];
1833 ConsoleMessage (
"\"ProtoInstance\" found, but field \"name\" not found!\n");
1838 if( isAvailableBroto(protoname, currentContext , &proto))
1841 char* containerfield;
1844 idepth = pflagdepth == 1;
1845 node=X3D_NODE(brotoInstance(proto,idepth));
1846 node->_executionContext = X3D_NODE(proto);
1847 if (defNameIndex != INT_ID_UNDEFINED){
1848 char * defname = atts[defNameIndex];
1849 broto_store_DEF(currentContext,node, defname);
1851 add_node_to_broto_context(currentContext,node);
1854 containerfield = NULL;
1855 for (i = 0; atts[i]; i += 2) {
1856 if(!strcmp(atts[i],
"containerField")) containerfield = atts[i+1];
1858 if(containerfield) {
1859 int builtinField = findFieldInFIELDNAMES(containerfield);
1860 if(builtinField > INT_ID_UNDEFINED){
1861 node->_defaultContainer = builtinField;
1868 ConsoleMessage (
"Attempt to instance undefined prototype typename %s\n",protoname);
1873 pushMode(ud,PARSING_PROTOINSTANCE);
1877BOOL nodeTypeSupportsUserFields(
struct X3D_Node *node);
1878int getFieldFromNodeAndName(
struct X3D_Node* node,
const char *fieldname,
int *type,
int *kind,
int *iifield,
union anyVrml **value);
1879void broto_store_IS(
struct X3D_Proto *proto,
char *protofieldname,
int pmode,
int iprotofield,
int pBuiltIn,
int type,
1880 struct X3D_Node *node,
char* nodefieldname,
int mode,
int ifield,
int nBuiltIn,
int source);
1882static void parseConnect_B(
void *ud,
char **atts) {
1888 node = getNode(ud,TOP);
1889 proto = context = getContext(ud,TOP);
1891 nodefield = protofield = NULL;
1892 for(i=0;atts[i];i+=2){
1893 if(!strcmp(atts[i],
"nodeField")) nodefield = atts[i+1];
1894 if(!strcmp(atts[i],
"protoField")) protofield = atts[i+1];
1897 if(nodefield && protofield){
1898 int ptype, pkind, pifield, pBuiltIn, ntype, nkind, nifield, nBuiltIn;
1899 const char *pname, *nname;
1900 union anyVrml *pvalue, *nvalue;
1901 okp = getFieldFromNodeAndNameC(X3D_NODE(proto),protofield,&ptype, &pkind, &pifield, &pBuiltIn, &pvalue, &pname);
1902 okn = getFieldFromNodeAndNameC(node, nodefield,&ntype, &nkind, &nifield, &nBuiltIn, &nvalue, &nname);
1917 ConsoleMessage(
"Parser error: IS - we have a name match: %s IS %s found protofield %s\n",
1918 nodefield,protofield,protofield);
1919 ConsoleMessage(
"...But the types don't match: nodefield %s protofield %s\n",
1920 FIELDTYPES[ntype],FIELDTYPES[ptype]);
1924 if(nkind != PKW_inputOutput && nkind != pkind){
1925 if(pkind != PKW_inputOutput){
1926 ConsoleMessage(
"Parser Error: IS - we have a name match: %s IS %s found protofield %s\n",
1927 nodefield,protofield,protofield);
1928 ConsoleMessage(
"...But the modes don't jive: nodefield %s protofield %s\n",
1929 PROTOKEYWORDS[nkind],PROTOKEYWORDS[pkind]);
1932 ConsoleMessage(
"Parser Warning: IS - we have a name match: %s IS %s found protofield %s\n",
1933 nodefield,protofield,protofield);
1934 ConsoleMessage(
"...But the modes don't jive: nodefield %s protofield %s\n",
1935 PROTOKEYWORDS[nkind],PROTOKEYWORDS[pkind]);
1936 ConsoleMessage(
"...will thunk\n");
1943 if(pkind == PKW_initializeOnly || pkind == PKW_inputOutput)
1945 shallow_copy_field(ntype, pvalue , nvalue);
1948 source = node->_nodeType == NODE_Proto ? 3 : node->_nodeType == NODE_Script ? 1 : nodeTypeSupportsUserFields(node) ? 2 : 0;
1950 broto_store_IS(context,protofield,pkind,pifield,pBuiltIn,ptype,
1951 node,nodefield,nkind,nifield,nBuiltIn,source);
1956static void XMLCALL X3DstartElement(
void *ud,
const xmlChar *iname,
const xmlChar **atts) {
1960 char *blankAtts[] = {NULL,NULL};
1961 const char *name = (
const char*) iname;
1964 if (atts == NULL) myAtts = blankAtts;
1965 else myAtts = (
char **) atts;
1967 #ifdef X3DPARSERVERBOSE
1969 printf (
"X3DstartElement: %s: atts %p\n",name,atts);
1972 for (i = 0; myAtts[i]; i += 2) {
1973 printf(
" X3DStartElement field:%s=%s\n", myAtts[i], atts[i + 1]);
1980 for (i = 0; atts[i]; i += 2) {
1981 atts[i+1] = fixAmp(atts[i+1]);
1985 myNodeIndex = findFieldInNODES(name);
1988 if (myNodeIndex != INT_ID_UNDEFINED) {
1989 startBuiltin_B(ud,myNodeIndex,(
const xmlChar *)name,myAtts);
1998 myNodeIndex = findFieldInX3DSPECIAL(name);
1999 if (myNodeIndex != INT_ID_UNDEFINED) {
2000 switch (myNodeIndex) {
2001 case X3DSP_ProtoDeclare:
2002 parseProtoDeclare_B(ud,myAtts);
2004 case X3DSP_ExternProtoDeclare:
2005 parseExternProtoDeclare_B(ud,myAtts);
2007 case X3DSP_ProtoBody:
2008 parseProtoBody_B(ud,myAtts);
2010 case X3DSP_ProtoInterface:
2011 parseProtoInterface(ud,myAtts);
2013 case X3DSP_ProtoInstance:
2014 parseProtoInstance_B(ud,myAtts);
2017 parseRoutes_B(ud,myAtts);
2019 case X3DSP_meta: parseMeta(myAtts);
break;
2020 case X3DSP_Scene: parseScene(myAtts);
break;
2022 case X3DSP_Header: parseHeader(myAtts);
break;
2023 case X3DSP_X3D: parseX3Dhead(ud,myAtts);
break;
2024 case X3DSP_fieldValue:
2025 parseFieldValue_B(ud,myAtts);
2028 parseScriptProtoField_B (ud, myAtts);
2030 case X3DSP_IS: parseIS(ud);
break;
2031 case X3DSP_component: parseComponent(myAtts);
break;
2033 parseExport_B(ud,myAtts);
2036 parseImport_B(ud,myAtts);
2039 parseConnect_B(ud,myAtts);
2042 parseUnit(ud,myAtts);
break;
2043 default: printf (
" huh? startElement, X3DSPECIAL, but not handled?? %d, :%s:\n",myNodeIndex,X3DSPECIAL[myNodeIndex]);
2047 printf (
"startElement name do not currently handle this one :%s: index %d\n",name,myNodeIndex);
2050static void endScriptProtoField_B(
void *ud) {
2051 if(0) printf(
"end scriptprotofield\n");
2057static void XMLCALL X3DendElement(
void *ud,
const xmlChar *iname) {
2059 const char*name = (
const char*) iname;
2065 #ifdef X3DPARSERVERBOSE
2066 printf (
"endElement: %s : parentIndex %d mode %s\n",name,parentIndex,parserModeStrings[getMode(ud,TOP)]);
2071 myNodeIndex = findFieldInNODES(name);
2072 if (myNodeIndex != INT_ID_UNDEFINED) {
2073 endBuiltin_B(ud,iname);
2081 myNodeIndex = findFieldInX3DSPECIAL(name);
2082 if (myNodeIndex != INT_ID_UNDEFINED) {
2083 switch (myNodeIndex) {
2084 case X3DSP_ProtoInstance:
2085 endProtoInstance_B(ud,name);
2087 case X3DSP_ProtoInterface:
2088 endProtoInterfaceTag(ud);
2090 case X3DSP_ProtoBody:
2091 endProtoBodyTag_B(ud,name);
2093 case X3DSP_ProtoDeclare:
2094 endProtoDeclareTag_B(ud);
2096 case X3DSP_ExternProtoDeclare:
2097 endExternProtoDeclareTag_B(ud);
2108 case X3DSP_component:
2112 case X3DSP_X3D:
break;
2114 endScriptProtoField_B(ud);
2116 case X3DSP_fieldValue:
2117 endFieldValue_B(ud);
2122 printf (
"endElement: huh? X3DSPECIAL, but not handled?? %s\n",X3DSPECIAL[myNodeIndex]);
2127 printf (
"unhandled endElement name %s index %d\n",name,myNodeIndex);
2128 #ifdef X3DPARSERVERBOSE
2129 printf (
"endElement %s\n",name);
2133static XML_Parser initializeX3DParser () {
2135 p->X3DParserRecurseLevel++;
2137 if (p->X3DParserRecurseLevel >= PROTOINSTANCE_MAX_LEVELS) {
2138 ConsoleMessage (
"XML_PARSER init: XML file PROTO nested too deep\n");
2139 p->X3DParserRecurseLevel--;
2141 XML_CreateParserLevel(p->x3dparser[p->X3DParserRecurseLevel]);
2142 XML_SetElementHandler(p->x3dparser[p->X3DParserRecurseLevel], X3DstartElement, X3DendElement);
2143 XML_SetCdataSectionHandler (p->x3dparser[p->X3DParserRecurseLevel], startCDATA, endCDATA);
2144 XML_SetDefaultHandler (p->x3dparser[p->X3DParserRecurseLevel],handleCDATA);
2145 XML_SetUserData(p->x3dparser[p->X3DParserRecurseLevel], &parentIndex);
2148 return p->x3dparser[p->X3DParserRecurseLevel];
2151static void shutdownX3DParser (
void *ud) {
2156 XML_ParserFree(p->x3dparser[p->X3DParserRecurseLevel]);
2157 p->X3DParserRecurseLevel--;
2160 if (p->X3DParserRecurseLevel == INT_ID_UNDEFINED) {
2162 gglobal()->X3DParser.parentIndex = 0;
2166 if (p->X3DParserRecurseLevel < INT_ID_UNDEFINED) {
2167 ConsoleMessage (
"XML_PARSER close underflow");
2168 p->X3DParserRecurseLevel = INT_ID_UNDEFINED;
2172 FREE_IF_NZ(tg->X3DParser.CDATA_Text);
2173 p->CDATA_TextMallocSize = 0;
2174 if (p->X3DParserRecurseLevel > INT_ID_UNDEFINED)
2175 p->currentX3DParser = p->x3dparser[p->X3DParserRecurseLevel];
2181 for(i=0;i<vectorSize(p->DEFedNodes);i++){
2182 struct Vector* vd = vector_get(
struct Vector*,p->DEFedNodes,i);
2185 deleteVector(
struct Vector*, p->DEFedNodes);
2198int X3DParse (
struct X3D_Node* ectx,
struct X3D_Node* myParent,
const char *inputstring) {
2201 p->currentX3DParser = initializeX3DParser();
2206 DEBUG_X3DPARSER (
"X3DPARSE on :\n%s:\n",inputstring);
2207 if(p->user_data == NULL){
2210 p->user_data = new_xml_user_data();
2212 pushContext(p->user_data,ectx);
2213 if(myParent->_nodeType == NODE_Proto )
2214 pushField(p->user_data,
"__children");
2216 pushField(p->user_data,
"children");
2217 pushNode(p->user_data,myParent);
2218 pushMode(p->user_data,PARSING_NODES);
2220 if (XML_ParseFile(p->currentX3DParser, p->user_data, inputstring, (
int) strlen(inputstring), TRUE) == XML_STATUS_ERROR) {
2222 xmlErrorPtr xe = xmlGetLastError();
2223 ConsoleMessage(
"Xml Error %s \n",xe->message);
2224 ConsoleMessage(
"Line %d\n",xe->line);
2231 popField(p->user_data);
2232 shutdownX3DParser(p->user_data);
2233 Parser_deleteParserForScanStringValueToMem();
2236 popField(p->user_data);
2237 shutdownX3DParser(p->user_data);
2238 Parser_deleteParserForScanStringValueToMem();