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();
291 ppX3DParser p = (ppX3DParser)t->prv;
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){
312 ppX3DParser p = (ppX3DParser)t->prv;
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) {
345 ppX3DParser p = (ppX3DParser)gglobal()->X3DParser.prv;
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) {
409 ppX3DParser p = (ppX3DParser)gglobal()->X3DParser.prv;
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) {
445 ppX3DParser p = (ppX3DParser)gglobal()->X3DParser.prv;
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) {
482 ppX3DParser p = (ppX3DParser)gglobal()->X3DParser.prv;
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;
772 for(i=0;i<ncontainer;i++){
773 if(i==0) iContainer = jContainer;
775 struct X3D_Node *typenode = getTypeNode(node);
777 int nt = typenode->_nodeType;
778 iContainer = NODE_DEFAULT_CONTAINER[nt][i-1];
782 if(iContainer == FIELDNAMES_children) iContainer = 0;
787 fname = FIELDNAMES[iContainer];
788 ok = getFieldFromNodeAndName(parent,fname,&type,&kind,&iifield,&value);
789 ok = ok && (kind == PKW_initializeOnly || kind == PKW_inputOutput);
791 if(!value && iContainer == FIELDNAMES_children){
794 ok = getFieldFromNodeAndName(parent,
"children",&type,&kind,&iifield,&value);
795 ok = ok && (kind == PKW_initializeOnly || kind == PKW_inputOutput);
797 int kids = indexChildrenName(parent);
799 value = (
union anyVrml*)childrenField(parent);
800 type = FIELDTYPE_MFNode;
809 if(!ok && parentsSuggestion) {
816 ok =getFieldFromNodeAndName(parent,parentsSuggestion,&type,&kind,&iifield,&value);
819 if(!value && parent){
820 ok = getFieldFromNodeAndName(parent,
"children",&type,&kind,&iifield,&value);
822 int kids = indexChildrenName(parent);
824 value = (
union anyVrml*)childrenField(parent);
825 type = FIELDTYPE_MFNode;
831 if(type == FIELDTYPE_SFNode){
832 value->sfnode = node;
833 ADD_PARENT(node,parent);
834 }
else if(type == FIELDTYPE_MFNode){
839 union anyVrml *valueadd = NULL;
841 if(parent->_nodeType == NODE_Proto){
842 struct X3D_Proto *pparent = X3D_PROTO(parent);
843 char cflag = ciflag_get(pparent->__protoFlags,2);
845 ok = getFieldFromNodeAndName(parent,
"addChildren",&type,&kind,&iifield,&valueadd);
848 AddRemoveChildren(parent,&valueadd->mfnode,&node,1,1,__FILE__,__LINE__);
851 AddRemoveChildren(parent,&value->mfnode,&node,1,1,__FILE__,__LINE__);
854 printf(
"no where to put node in parent\n");
855 printf(
"nodetype=%s parenttype=%s\n",stringNodeType(node->_nodeType),stringNodeType(parent->_nodeType));
863void Parser_scanStringValueToMem_B(
union anyVrml* any, indexT ctype,
const char *value,
int isXML);
865static void endCDATA_B (
void *ud,
const xmlChar *
string,
int len) {
866 char *fieldname = getField(ud,TOP);
867 struct X3D_Node *node = getNode(ud,TOP);
868 int type, kind, iifield, ok, handled;
870 ok = getFieldFromNodeAndName(node,fieldname,&type,&kind,&iifield,&value);
873 if(!strcmp(fieldname,
"url")){
875 if(strstr((
char*)
string,
"script")){
877 value->mfstring.n = 1;
878 value->mfstring.p = MALLOCV(
sizeof(
void *));
879 value->mfstring.p[0] = newASCIIString((
char *)
string);
884 Parser_scanStringValueToMem_B(value, type, (
const char*)
string, TRUE);
888void endCDATA (
void *ud,
const xmlChar *
string,
int len) {
889 endCDATA_B(ud,
string,len);
895void handleImport_B (
struct X3D_Node *nodeptr,
char *nodeName,
char *nodeImport,
char *as);
896static void parseImport_B(
void *ud,
char **atts) {
898 char *inlinedef, *exporteddef, *as;
900 context = getContext(ud,TOP);
902 inlinedef = exporteddef = as = NULL;
903 for (i = 0; atts[i]; i += 2) {
904 printf(
"import field:%s=%s\n", atts[i], atts[i + 1]);
905 if(!strcmp(atts[i],
"inlineDEF")) inlinedef = atts[i+1];
906 if(!strcmp(atts[i],
"exportedDEF")) exporteddef = atts[i+1];
907 if(!strcmp(atts[i],
"AS")) as = atts[i+1];
910 handleImport_B (X3D_NODE(context), inlinedef, exporteddef, as);
914void handleExport_B (
void *nodeptr,
char *node,
char *as);
915static void parseExport_B(
void *ud,
char **atts) {
920 context = getContext(ud,TOP);
922 localdef = as = NULL;
923 for (i = 0; atts[i]; i += 2) {
924 printf(
"export field:%s=%s\n", atts[i], atts[i + 1]);
925 if(!strcmp(atts[i],
"localDEF")) localdef = atts[i+1];
926 if(!strcmp(atts[i],
"AS")) as = atts[i+1];
928 handleExport_B(context,localdef, as);
933static void parseComponent(
char **atts) {
935 int myComponent = INT_ID_UNDEFINED;
936 int myLevel = INT_ID_UNDEFINED;
939 for (i = 0; atts[i]; i += 2) {
941 if (strcmp(
"level",atts[i]) == 0) {
942 if (sscanf(atts[i+1],
"%d",&myLevel) != 1) {
943 ConsoleMessage (
"Line %d: Expected Component level for component %s, got %s",LINE, atts[i], atts[i+1]);
946 }
else if (strcmp(
"name",atts[i]) == 0) {
947 char *comp_name = atts[i+1];
948 if(!strcmp(comp_name,
"H-Anim")) comp_name =
"HAnim";
949 myComponent = findFieldInCOMPONENTS(comp_name);
950 if (myComponent == INT_ID_UNDEFINED) {
951 ConsoleMessage(
"Line %d: Component statement, but component name not valid :%s:",LINE,atts[i+1]);
956 ConsoleMessage (
"Line %d: Unknown fields in Component statement :%s: :%s:",LINE,atts[i], atts[i+1]);
960 if (myComponent == INT_ID_UNDEFINED) {
961 ConsoleMessage(
"Line %d: Component statement, but component name not stated",LINE);
962 }
else if (myLevel == INT_ID_UNDEFINED) {
963 ConsoleMessage(
"Line %d: Component statement, but component level not stated",LINE);
965 handleComponent(myComponent,myLevel);
970static void parseX3Dhead(
void *ud,
char **atts) {
972 int myProfile = -10000;
973 int versionIndex = INT_ID_UNDEFINED;
976 for (i = 0; atts[i]; i += 2) {
978 if (strcmp(
"profile",atts[i]) == 0) {
979 myProfile = findFieldInPROFILES(atts[i+1]);
980 }
else if (strcmp(
"version",atts[i]) == 0) {
988 if (myProfile == INT_ID_UNDEFINED) {
989 ConsoleMessage (
"expected valid profile in X3D header");
992 if (myProfile >= 0) handleProfile (myProfile);
995 if (versionIndex != INT_ID_UNDEFINED) {
996 handleVersion (atts[versionIndex]);
999 ec->__specversion = inputFileVersion[0]*100 + inputFileVersion[1]*10 + inputFileVersion[2];
1003static void parseHeader(
char **atts) {
1005 for (i = 0; atts[i]; i += 2) {
1009static void parseScene(
char **atts) {
1011 for (i = 0; atts[i]; i += 2) {
1015static void parseMeta(
void* ud,
char **atts) {
1017 char* name, * content;
1021 for (i = 0; atts[i]; i += 2) {
1023 if (!strcmp(atts[i],
"name"))
1025 if (!strcmp(atts[i],
"category"))
1026 content = atts[i + 1];
1028 handleMetaDataStringString((
void*)ec, name, content);
1030static void parseUnit(
void *ud,
char **atts) {
1031 double conversionFactor = 1.0;
1032 char *name, *category;
1035 name = category = NULL;
1037 for (i = 0; atts[i]; i += 2){
1038 if(!strcmp(atts[i],
"name"))
1040 if(!strcmp(atts[i],
"category"))
1041 category = atts[i+1];
1042 if(!strcmp(atts[i],
"conversionFactor"))
1043 sscanf(atts[i+1],
"%lf",&conversionFactor);
1045 handleUnitDataStringString(ec,category, name, conversionFactor);
1047void deleteMallocedFieldValue(
int type,
union anyVrml *fieldPtr);
1048static void parseFieldValue_B(
void *ud,
char **atts) {
1049 int i, type, kind, iifield, builtIn, ok;
1050 const char *fname, *svalue, *cname;
1052 struct X3D_Node *node = getNode(ud,TOP);
1054 fname = svalue = NULL;
1055 for(i=0;atts[i];i+=2){
1056 if(!strcmp(atts[i],
"name")) fname = atts[i+1];
1057 if(!strcmp(atts[i],
"value")) svalue = atts[i+1];
1064 ok = getFieldFromNodeAndNameC(node,fname,&type,&kind,&iifield,&builtIn,&value,&cname);
1066 if(cname && value && svalue){
1067 deleteMallocedFieldValue(type,value);
1068 Parser_scanStringValueToMem_B(value,type,svalue,TRUE);
1070 if(cname && (node->_nodeType == NODE_Proto) && !builtIn){
1080 pnode = X3D_PROTO(node);
1082 pfield = vector_get(
struct ProtoFieldDecl*,pstruct->iface,iifield);
1086 if(pfield->type == FIELDTYPE_MFNode){
1087 struct Multi_Node* mfn = &pfield->defaultVal.mfnode;
1089 AddRemoveChildren(node,mfn,mfn->p,mfn->n,2,__FILE__,__LINE__);
1090 pfield->defaultVal.mfnode.n = 0;
1091 pfield->defaultVal.mfnode.p = NULL;
1093 if(pfield->type == FIELDTYPE_SFNode){
1094 struct X3D_Node **sfn = &pfield->defaultVal.sfnode;
1096 AddRemoveSFNodeFieldChild(node,sfn,*sfn,2,__FILE__,__LINE__);
1097 pfield->defaultVal.sfnode = NULL;
1099 pfield->alreadySet = TRUE;
1101 pushField(ud,cname);
1103static void endFieldValue_B(
void *ud){
1104 if(0) printf(
"endFieldValue\n");
1111static void parseIS(
void *ud) {
1112 #ifdef X3DPARSERVERBOSE
1113 printf (
"parseIS mode is %s\n",parserModeStrings[getMode(ud,TOP)]);
1115 pushMode(ud,PARSING_IS);
1121static void endIS(
void *ud) {
1122 #ifdef X3DPARSERVERBOSE
1123 printf (
"endIS mode is %s\n",parserModeStrings[getMode(ud,TOP)]);
1130static void endProtoInterfaceTag(
void *ud) {
1131 if (getMode(ud,TOP) != PARSING_PROTOINTERFACE) {
1132 ConsoleMessage (
"endProtoInterfaceTag: got a </ProtoInterface> but not parsing one at line %d",LINE);
1138static void endProtoBodyTag_B(
void *ud,
const char *name) {
1140 if (getMode(ud,TOP) != PARSING_PROTOBODY) {
1141 ConsoleMessage (
"endProtoBodyTag: got a </ProtoBody> but not parsing one at line %d",LINE);
1147static void endExternProtoDeclareTag_B(
void *ud) {
1153static void endProtoDeclareTag_B(
void *ud) {
1158 if (getMode(ud,TOP) != PARSING_PROTODECLARE) {
1159 ConsoleMessage (
"endProtoDeclareTag: got a </ProtoDeclare> but not parsing one at line %d",LINE);
1160 pushMode(ud,PARSING_PROTODECLARE);
1162 if(0) printf(
"end protoDeclare\n");
1164 proto = X3D_PROTO(getNode(ud,TOP));
1166 if(proto->__children.n)
1167 cptr = &proto->__children;
1168 else if(proto->addChildren.n)
1169 cptr = &proto->addChildren;
1172 if(c1->_defaultContainer > INT_ID_UNDEFINED)
1173 proto->_defaultContainer = c1->_defaultContainer;
1182static void endProtoInstance_B(
void *ud,
const char *name) {
1186 if(0) printf(
"endProtoInstance_B\n");
1188 node = getNode(ud,TOP);
1189 mode = getMode(ud,TOP);
1191 if(node->_nodeType == NODE_Proto || node->_nodeType == NODE_Inline ){
1192 if(mode != PARSING_PROTOINSTANCE_USE){
1194 struct X3D_Proto *pnode = X3D_PROTO(node);
1195 pflagdepth = ciflag_get(pnode->__protoFlags,0);
1201 pdeclare = X3D_PROTO(pnode->__prototype);
1206 deep_copy_broto_body2(&pdeclare,&pnode);
1234void **shaderFields(
struct X3D_Node* node){
1236 switch(node->_nodeType){
1238 shaderfield = &X3D_SCRIPT(node)->__scriptObj;
break;
1239 case NODE_ComposedShader:
1240 shaderfield = (
void**)&X3D_COMPOSEDSHADER(node)->_shaderUserDefinedFields;
break;
1242 shaderfield = (
void**)&X3D_EFFECT(node)->_shaderUserDefinedFields;
break;
1243 case NODE_ShaderProgram:
1244 shaderfield = (
void**)&X3D_SHADERPROGRAM(node)->_shaderUserDefinedFields;
break;
1245 case NODE_PackagedShader:
1246 shaderfield = (
void**)&X3D_PACKAGEDSHADER(node)->_shaderUserDefinedFields;
break;
1253void broto_store_DEF(
struct X3D_Proto* proto,
struct X3D_Node* node,
const char *name);
1254static void parseAttributes_B(
void *ud,
char **atts);
1256void push_binding_stack_set(
struct X3D_Node* layersetnode);
1257void push_next_layerId_from_binding_stack_set(
struct X3D_Node* layer);
1258void pop_binding_stack_set();
1260static void startBuiltin_B(
void *ud,
int myNodeType,
const xmlChar *name,
char** atts) {
1261 struct X3D_Node *node, *fromDEFtable;
1266 const char *defname, *suggestedChildField, *containerfield;
1268 suggestedChildField = containerfield = NULL;
1269 context = getContext(ud,TOP);
1270 pflagdepth = ciflag_get(context->__protoFlags,0);
1271 if(0) printf(
"start builtin %s\n",name);
1277 for (i = 0; atts[i]; i += 2) {
1279 if (strcmp (
"DEF",atts[i]) == 0) {
1280 defname = atts[i+1];
1281 fromDEFtable = broto_search_DEFname(context,defname);
1283 #ifdef X3DPARSERVERBOSE
1284 printf (
"Warning - line %d duplicate DEF name: \'%s\'\n",LINE,atts[i+1]);
1287 }
else if (strcmp (
"USE",atts[i]) == 0) {
1288 #ifdef X3DPARSERVERBOSE
1289 printf (
"this is a USE, name %s\n",atts[i+1]);
1293 fromDEFtable = broto_search_DEFname(context,atts[i+1]);
1294 if (!fromDEFtable) {
1295 ConsoleMessage (
"Warning - line %d DEF name: \'%s\' not found",LINE,atts[i+1]);
1296 ConsoleMessage(
"\n");
1298 #ifdef X3DPARSERVERBOSE
1299 printf (
"copying for field %s defName %s\n",atts[i], atts[i+1]);
1303 if (myNodeType != fromDEFtable->_nodeType) {
1304 ConsoleMessage (
"Warning, line %d DEF/USE mismatch, '%s', %s != %s", LINE,
1305 atts[i+1],stringNodeType(fromDEFtable->_nodeType), stringNodeType (myNodeType));
1308 node = fromDEFtable;
1309 node->referenceCount++;
1311 #ifdef X3DPARSERVERBOSE
1312 printf (
"successful copying for field %s defName %s\n",atts[i], atts[i+1]);
1317 }
else if(!strcmp(atts[i],
"containerField")) containerfield = atts[i+1];
1322 node = createNewX3DNode(myNodeType);
1324 node = createNewX3DNode0(myNodeType);
1326 broto_store_DEF(context,node,defname);
1330 if(containerfield) {
1332 int builtinField = findFieldInFIELDNAMES(containerfield);
1333 if(builtinField > INT_ID_UNDEFINED){
1342 node->_defaultContainer = builtinField;
1350 shaderfield = shaderFields(node);
1352 (*shaderfield) = (
void *)new_Shader_ScriptB(node);
1355 if(node->_nodeType == NODE_LayerSet)
1356 push_binding_stack_set(node);
1357 if(node->_nodeType == NODE_Layer || node->_nodeType == NODE_LayoutLayer)
1358 push_next_layerId_from_binding_stack_set(node);
1359 if(node->_nodeType == NODE_Inline)
1360 X3D_INLINE(node)->__parentProto = X3D_NODE(context);
1361 node->_executionContext = X3D_NODE(context);
1362 add_node_to_broto_context(context,node);
1364 kids = indexChildrenName(node);
1366 suggestedChildField = FIELDNAMES[kids];
1367 if(node->_nodeType == NODE_Script || node->_nodeType == NODE_ShaderPart
1368 || node->_nodeType == NODE_ShaderProgram || node->_nodeType == NODE_EffectPart)
1369 suggestedChildField = FIELDNAMES[FIELDNAMES_url];
1371 pushField(ud,suggestedChildField);
1373 parseAttributes_B(ud,atts);
1380void applyUnitsToNode(
struct X3D_Node *node);
1381static void endBuiltin_B(
void *ud,
const xmlChar *name){
1385 node = getNode(ud,TOP);
1386 context = getContext(ud,TOP);
1387 if(0)printf(
"end builtin %s\n",name);
1388 pflagdepth = ciflag_get(context->__protoFlags,0);
1389 applyUnitsToNode(node);
1390 if(node->_nodeType == NODE_Script && pflagdepth){
1393 initialize_one_script(sn->__scriptObj,&sn->url);
1396 if(node->_nodeType == NODE_LayerSet)
1397 pop_binding_stack_set();
1405struct X3D_Proto* availableBroto(
void* ud,
const char* name) {
1407 char nonconstname[1000];
1408 strcpy(nonconstname, name);
1409 struct X3D_Proto* context = getContext(ud, TOP);
1410 if (isAvailableBroto(nonconstname, context, &proto))
return proto;
1413void startProto_B(
void* ud,
const char* name,
struct X3D_Proto* nodetype,
const xmlChar** atts) {
1420 int kids, i, isUSE, visibleIndex, displayBBoxIndex;
1421 const char* defname, * suggestedChildField, * containerfield;
1422 suggestedChildField = containerfield = NULL;
1423 context = getContext(ud, TOP);
1424 pflagdepth = ciflag_get(context->__protoFlags, 0);
1425 if (0) printf(
"start proto %s\n", name);
1431 displayBBoxIndex = -1;
1433 for (i = 0; atts[i]; i += 2) {
1435 if (strcmp(
"DEF", atts[i]) == 0) {
1436 defname = atts[i + 1];
1437 fromDEFtable = (
struct X3D_Proto*)broto_search_DEFname(context, defname);
1439 else if (strcmp(
"USE", atts[i]) == 0) {
1441 fromDEFtable = (
struct X3D_Proto*)broto_search_DEFname(context, atts[i + 1]);
1442 if (!fromDEFtable) {
1443 ConsoleMessage(
"Warning - line %d DEF name: \'%s\' not found", LINE, atts[i + 1]);
1444 ConsoleMessage(
"\n");
1447 if (fromDEFtable->_nodeType != NODE_Proto || strcmp(X3D_PROTO(fromDEFtable->__prototype)->__typename, X3D_PROTO(nodetype->__prototype)->__typename)) {
1449 ConsoleMessage(
"Warning, line %d DEF/USE mismatch, '%s', %s != %s", LINE,
1450 atts[i + 1], fromDEFtable->__typename, nodetype->__typename);
1454 node = X3D_NODE(fromDEFtable);
1455 node->referenceCount++;
1460 else if (!strcmp(atts[i],
"containerField"))
1461 containerfield = atts[i + 1];
1462 else if (strcmp(
"visible", atts[i]) == 0) {
1463 visibleIndex = i + 1;
1465 else if (strcmp(
"displayBBox", atts[i]) == 0) {
1466 displayBBoxIndex = i + 1;
1472 idepth = pflagdepth == 1;
1473 node = X3D_NODE(brotoInstance(nodetype, idepth));
1474 node->_executionContext = X3D_NODE(context);
1477 broto_store_DEF(context, node, defname);
1479 add_node_to_broto_context(context, node);
1481 if (containerfield) {
1482 int builtinField = findFieldInFIELDNAMES(containerfield);
1483 if (builtinField > INT_ID_UNDEFINED) {
1484 node->_defaultContainer = builtinField;
1487 kids = indexChildrenName(node);
1489 suggestedChildField = FIELDNAMES[kids];
1490 pushField(ud, suggestedChildField);
1497 const char *fname, *svalue;
1498 const char* ignore[] = {
"containerField",
"USE",
"DEF",
"visible",
"displayBBox", NULL };
1500 for (i = 0; atts[i]; i += 2) {
1502 svalue = atts[i + 1];
1503 if (findFieldInARR(fname, ignore, 5) == INT_ID_UNDEFINED) {
1504 int ok, builtIn, type, kind, iifield;
1512 ok = getFieldFromNodeAndNameC(node, fname, &type, &kind, &iifield, &builtIn, &value, (
const char **)&cname);
1514 if (cname && value && svalue) {
1515 deleteMallocedFieldValue(type, value);
1516 Parser_scanStringValueToMem_B(value, type, svalue, TRUE);
1518 if (cname && (node->_nodeType == NODE_Proto) && !builtIn) {
1522 pnode = X3D_PROTO(node);
1524 pfield = vector_get(
struct ProtoFieldDecl*, pstruct->iface, iifield);
1525 pfield->alreadySet = TRUE;
1531 if (visibleIndex != INT_ID_UNDEFINED) {
1532 if (!strcmp(atts[visibleIndex],
"false"))
1533 X3D_PROTO(node)->visible = FALSE;
1535 if (displayBBoxIndex != INT_ID_UNDEFINED) {
1536 if (!strcmp(atts[displayBBoxIndex],
"true"))
1537 X3D_PROTO(node)->bboxDisplay = TRUE;
1540 ptype = X3D_PROTO(X3D_PROTO(node)->__prototype);
1541 pdest = X3D_PROTO(node);
1542 deep_copy_broto_body2(&ptype, &pdest);
1546 pushField(ud, NULL);
1551void endProto_B(
void* ud,
const char* name,
struct X3D_Proto* proto) {
1556 node = getNode(ud, TOP);
1557 context = getContext(ud, TOP);
1558 if (0)printf(
"endProto_B %s\n", name);
1559 pflagdepth = ciflag_get(context->__protoFlags, 0);
1560 applyUnitsToNode(node);
1568static xmlChar* fixAmp(
const unsigned char *InFieldValue)
1570 char *fieldValue = (
char *)InFieldValue;
1579 char *pp = strstr((
char *)fieldValue,
"&");
1581 memmove(pp+1,pp+5,strlen(fieldValue) - (pp+1 - fieldValue));
1582 pp = strstr(pp,
"&");
1595 return (xmlChar *)fieldValue;
1598void sfunitf(
int nodeType,
char *fieldname,
float *var,
int n,
int iuncafield);
1599void mfunitrotation(
int nodeType,
char *fieldname,
struct SFRotation *var,
int n,
int iuncafield);
1600void sfunitd(
int nodeType,
char *fieldname,
double *var,
int n,
int iuncafield);
1601void mfunit3f(
int nodetype,
char *fieldname,
struct SFVec3f *var,
int n,
int iuncafield);
1602static void parseAttributes_B(
void *ud,
char **atts) {
1603 int i, type, kind, iifield, builtIn, iunca, isunits;
1606 char *name, *svalue;
1607 const char *ignore [] = {
"containerField",
"USE",
"DEF"};
1610 node = getNode(ud,TOP);
1611 isunits = isUnits();
1612 for (i=0; atts[i]; i+=2) {
1616 if(findFieldInARR(name,ignore,3) == INT_ID_UNDEFINED){
1618 if(getFieldFromNodeAndNameU(node,name,&type,&kind,&iifield,&builtIn,&value,&iunca,&cname)){
1619 deleteMallocedFieldValue(type,value);
1620 Parser_scanStringValueToMem_B(value, type,svalue, TRUE);
1625 case FIELDTYPE_SFRotation:
1626 sfunitf(node->_nodeType,name,&value->sfrotation.c[3],1,iunca);
1628 case FIELDTYPE_SFFloat:
1629 sfunitf(node->_nodeType,name,&value->sffloat,1,iunca);
1631 case FIELDTYPE_MFFloat:
1632 sfunitf(node->_nodeType,name,value->mffloat.p,value->mffloat.n,iunca);
1634 case FIELDTYPE_SFVec3f:
1635 sfunitf(node->_nodeType,name,value->sfvec3f.c,3,iunca);
1637 case FIELDTYPE_SFVec4f:
1638 if(iunca == UNCA_PLANE)
1639 sfunitf(node->_nodeType,name,&value->sfvec4f.c[3],1,UNCA_LENGTH);
1641 sfunitf(node->_nodeType,name,value->sfvec4f.c,4,iunca);
1643 case FIELDTYPE_SFVec2f:
1644 sfunitf(node->_nodeType,name,value->sfvec2f.c,2,iunca);
1646 case FIELDTYPE_MFVec3f:
1647 mfunit3f(node->_nodeType,name,value->mfvec3f.p,value->mfvec3f.n,iunca);
1649 case FIELDTYPE_SFMatrix3f:
1650 sfunitf(node->_nodeType,name,value->sfmatrix3f.c, 9,iunca);
1652 case FIELDTYPE_MFRotation:
1653 mfunitrotation(node->_nodeType,name,value->mfrotation.p,value->mfrotation.n,iunca);
1655 case FIELDTYPE_SFDouble:
1656 sfunitd(node->_nodeType,name,&value->sfdouble,1,iunca);
1663 if(!strcmp(name,
"side")){
1665 if(!strcmp(svalue,
"left"))
1666 node->_renderFlags |= VF_HideRight;
1667 else if(!strcmp(svalue,
"right"))
1668 node->_renderFlags |= VF_HideLeft;
1675int findFieldInARR(
const char* field,
const char** arr,
size_t cnt);
1676static void parseScriptProtoField_B(
void *ud,
char **atts) {
1685 int mp_name, mp_accesstype, mp_type, mp_value, i;
1688 char *fname, *cname;
1691 mp_name = mp_accesstype = mp_type = mp_value = ID_UNDEFINED;
1692 if(0) printf(
"start scriptProtoField\n");
1694 for (i = 0; atts[i]; i += 2) {
1696 if ((strcmp(
"appinfo", atts[i]) != 0) &&
1697 (strcmp(
"documentation",atts[i]) != 0)) {
1698 if (strcmp(atts[i],
"name") == 0) { mp_name = i+1;
1699 }
else if (strcmp(atts[i],
"accessType") == 0) { mp_accesstype = i+1;
1700 }
else if (strcmp(atts[i],
"type") == 0) { mp_type = i+1;
1701 }
else if (strcmp(atts[i],
"value") == 0) { mp_value = i+1;
1703 ConsoleMessage (
"X3D Proto/Script parsing line %d: unknown field type %s",LINE,atts[i]);
1708 if(mp_accesstype > -1 && mp_type > -1 && mp_name > -1){
1710 pkwmode = findFieldInARR(atts[mp_accesstype], PROTOKEYWORDS, PROTOKEYWORDS_COUNT);
1711 pkwmode = pkwmode > -1? X3DMODE(pkwmode) : pkwmode;
1712 type = findFieldInARR(atts[mp_type],FIELDTYPES,FIELDTYPES_COUNT);
1713 fname = atts[mp_name];
1716 bzero(&defaultValue,
sizeof (
union anyVrml));
1717 if(type == FIELDTYPE_SFString)
1718 defaultValue.sfstring = newASCIIString(
"");
1721 Parser_scanStringValueToMem_B(&defaultValue, type, atts[mp_value], TRUE);
1724 if(pkwmode > -1 && type > -1){
1725 struct X3D_Node * node = getNode(ud,TOP);
1726 if(node->_nodeType == NODE_Proto){
1730 pnode = X3D_PROTO(node);
1732 pfield = newProtoFieldDecl(pkwmode,type,0);
1733 pfield->cname = STRDUP(fname);
1734 cname = pfield->cname;
1735 memcpy(&pfield->defaultVal,&defaultValue,
sizeof(
union anyVrml));
1742 switch(node->_nodeType)
1744 case NODE_Script: shader =(
struct Shader_Script *)(X3D_SCRIPT(node)->__scriptObj);
break;
1745 case NODE_ComposedShader: shader =(
struct Shader_Script *)(X3D_COMPOSEDSHADER(node)->_shaderUserDefinedFields);
break;
1746 case NODE_Effect: shader =(
struct Shader_Script *)(X3D_EFFECT(node)->_shaderUserDefinedFields);
break;
1747 case NODE_ShaderProgram: shader =(
struct Shader_Script *)(X3D_SHADERPROGRAM(node)->_shaderUserDefinedFields);
break;
1748 case NODE_PackagedShader: shader =(
struct Shader_Script *)(X3D_PACKAGEDSHADER(node)->_shaderUserDefinedFields);
break;
1750 jsname = JSparamIndex (fname, atts[mp_type],pkwmode);
1751 cname = getJSparamnames()[jsname].name;
1755 sfield->fieldDecl = newFieldDecl(pkwmode,type,0,jsname,0);
1756 memcpy(&sfield->value,&defaultValue,
sizeof(
union anyVrml));
1757 sfield->valueSet = valueSet;
1758 sfield->eventInSet = FALSE;
1764 pushField(ud,cname);
1765 pushMode(ud,PARSING_FIELD);
1769static void parseProtoInterface (
void *ud,
char **atts) {
1770 if (getMode(ud,TOP) != PARSING_PROTODECLARE && getMode(ud,TOP) != PARSING_EXTERNPROTODECLARE) {
1771 ConsoleMessage (
"got a <ProtoInterface>, but not within a <ProtoDeclare>\n");
1774 pushMode(ud,PARSING_PROTOINTERFACE);
1776void Parser_scanStringValueToMem_B(
union anyVrml* any, indexT ctype,
const char *value,
int isXML);
1777double getunitlengthfactor();
1778static void parseExternProtoDeclare_B (
void *ud,
char **atts) {
1786 char *type_name, *appinfo, *documentation, *containerfield, *url;
1790 type_name = appinfo = documentation = containerfield = url = NULL;
1791 if(0) printf(
"in parseExternProtoDeclare_B\n");
1793 proto = createNewX3DNode0(NODE_Proto);
1794 for (i = 0; atts[i]; i += 2) {
1795 #ifdef X3DPARSERVERBOSE
1797 printf (
"parseProtoDeclare: field:%s=%s\n", atts[i], atts[i+1]);
1800 if (!strcmp(
"name",atts[i]) ) type_name = atts[i+1];
1801 else if(!strcmp(
"containerField",atts[i])) containerfield = atts[i+1];
1802 else if(!strcmp(
"appInfo",atts[i])) appinfo = atts[i+1];
1803 else if(!strcmp(
"documentation",atts[i])) documentation = atts[i+1];
1804 else if(!strcmp(
"url",atts[i])) url = atts[i+1];
1807 parent = (
struct X3D_Proto*)getContext(ud,TOP);
1808 obj=newProtoDefinition();
1812 obj->protoName = STRDUP(type_name);
1814 printf (
"warning - have proto but no name, so just copying a default string in\n");
1815 obj->protoName = STRDUP(
"noProtoNameDefined");
1817 type_name = obj->protoName;
1819 if(parent->__externProtoDeclares == NULL)
1820 parent->__externProtoDeclares = newVector(
struct X3D_Proto*,4);
1821 vector_pushBack(
struct X3D_Proto*,parent->__externProtoDeclares,proto);
1822 proto->__parentProto = X3D_NODE(parent);
1823 proto->__protoFlags = parent->__protoFlags;
1824 proto->__protoFlags = ciflag_set(proto->__protoFlags,0,0);
1826 proto->__protoFlags = ciflag_set(proto->__protoFlags,0,2);
1827 proto->__protoFlags = ciflag_set(proto->__protoFlags,1,3);
1829 proto->__protoDef = obj;
1830 proto->__prototype = X3D_NODE(proto);
1831 proto->__typename = STRDUP(obj->protoName);
1832 proto->__unitlengthfactor = getunitlengthfactor();
1833 proto->__specversion = inputFileVersion[0]*100 + inputFileVersion[1]*10 + inputFileVersion[2];
1835 int builtinField = findFieldInFIELDNAMES(containerfield);
1836 if(builtinField > -1){
1837 proto->_defaultContainer = builtinField;
1841 Parser_scanStringValueToMem_B((
union anyVrml*)&proto->url, FIELDTYPE_MFString,url, TRUE);
1843 proto->__loadstatus = 0;
1844 pushMode(ud,PARSING_EXTERNPROTODECLARE);
1845 pushNode(ud,X3D_NODE(proto));
1846 pushField(ud,
"__children");
1849#define LOAD_STABLE 10
1850static void parseProtoInclude(
void* ud,
char** atts) {
1860 if (0) printf(
"in parseProtoInclude\n");
1862 proto = createNewX3DNode0(NODE_Proto);
1863 for (i = 0; atts[i]; i += 2) {
1864 if (!strcmp(
"names", atts[i])) names = atts[i + 1];
1865 else if (!strcmp(
"url", atts[i])) url = atts[i + 1];
1867 parent = (
struct X3D_Proto*)getContext(ud, TOP);
1869 Parser_scanStringValueToMem_B((
union anyVrml*)&proto->url, FIELDTYPE_MFString, url, TRUE);
1871 proto->__protoFlags = parent->__protoFlags;
1872 proto->__protoFlags = ciflag_set(proto->__protoFlags, 0, 0);
1874 proto->__protoFlags = ciflag_set(proto->__protoFlags, 0, 2);
1875 proto->__protoFlags = ciflag_set(proto->__protoFlags, 1, 3);
1877 proto->__loadstatus = 0;
1881 load_externProtoDeclare(proto);
1883 }
while (proto->__loadstatus != LOAD_STABLE);
1884 printf(
"library %s loaded\n", proto->url.p[0]->strptr);
1891static void parseProtoDeclare_B (
void *ud,
char **atts) {
1900 char *type_name, *appinfo, *documentation, *containerfield;
1904 type_name = appinfo = documentation = containerfield = NULL;
1905 if(0) printf(
"in start protoDeclare\n");
1907 proto = createNewX3DNode0(NODE_Proto);
1908 for (i = 0; atts[i]; i += 2) {
1909 #ifdef X3DPARSERVERBOSE
1911 printf (
"parseProtoDeclare: field:%s=%s\n", atts[i], atts[i+1]);
1914 if (!strcmp(
"name",atts[i]) ) type_name = atts[i+1];
1915 else if(!strcmp(
"containerField",atts[i])) containerfield = atts[i+1];
1916 else if(!strcmp(
"appInfo",atts[i])) appinfo = atts[i+1];
1917 else if(!strcmp(
"documentation",atts[i])) documentation = atts[i+1];
1920 parent = (
struct X3D_Proto*)getContext(ud,TOP);
1921 obj=newProtoDefinition();
1925 obj->protoName = STRDUP(type_name);
1927 printf (
"warning - have proto but no name, so just copying a default string in\n");
1928 obj->protoName = STRDUP(
"noProtoNameDefined");
1930 type_name = obj->protoName;
1932 if(parent->__protoDeclares == NULL)
1933 parent->__protoDeclares = newVector(
struct X3D_Proto*,4);
1934 vector_pushBack(
struct X3D_Proto*,parent->__protoDeclares,proto);
1935 proto->__parentProto = X3D_NODE(parent);
1936 proto->__protoFlags = parent->__protoFlags;
1937 proto->__protoFlags = ciflag_set(proto->__protoFlags,0,0);
1939 proto->__protoFlags = ciflag_set(proto->__protoFlags,0,2);
1940 proto->__protoFlags = ciflag_set(proto->__protoFlags,0,3);
1942 proto->__protoDef = obj;
1943 proto->__prototype = X3D_NODE(proto);
1944 proto->__typename = STRDUP(obj->protoName);
1945 proto->__unitlengthfactor = getunitlengthfactor();
1946 proto->__specversion = inputFileVersion[0]*100 + inputFileVersion[1]*10 + inputFileVersion[2];
1948 int builtinField = findFieldInFIELDNAMES(containerfield);
1949 if(builtinField > -1){
1950 proto->_defaultContainer = builtinField;
1954 pushMode(ud,PARSING_PROTODECLARE);
1955 pushNode(ud,X3D_NODE(proto));
1956 pushField(ud,
"__children");
1959static void parseProtoBody_B (
void *ud,
char **atts) {
1961 pushContext(ud,getNode(ud,TOP));
1962 pushMode(ud,PARSING_PROTOBODY);
1967void linkNodeIn_B(
void *ud);
1968struct X3D_Node *broto_search_DEFname(
struct X3D_Proto *context,
const char *name);
1970static void parseProtoInstance_B(
void *ud,
char **atts) {
1981 int defNameIndex, visibleIndex, displayBBoxIndex;
1990 nameIndex = INT_ID_UNDEFINED;
1991 visibleIndex = displayBBoxIndex = nameIndex;
1994 defNameIndex = INT_ID_UNDEFINED;
1996 if(0) printf(
"parseProtoInstance\n");
1998 for (i = 0; atts[i]; i += 2) {
1999 if (strcmp(
"name",atts[i]) == 0) {
2001 }
else if (strcmp(
"containerField",atts[i]) == 0) {
2003 }
else if (strcmp(
"DEF",atts[i]) == 0) {
2005 }
else if (strcmp(
"class",atts[i]) == 0) {
2006 ConsoleMessage (
"field \"class\" not currently used in a ProtoInstance parse... sorry");
2007 }
else if (strcmp(
"USE",atts[i]) == 0) {
2011 }
else if (strcmp(
"visible",atts[i]) == 0) {
2013 }
else if (strcmp(
"displayBBox",atts[i]) == 0) {
2014 displayBBoxIndex = i+1;
2018 currentContext = getContext(ud,TOP);
2020 pflagdepth = ciflag_get(currentContext->__protoFlags,0);
2026 char * defname = atts[defNameIndex];
2028 fromDEFtable = broto_search_DEFname(currentContext,defname);
2029 if (!fromDEFtable) {
2030 ConsoleMessage (
"Warning - line %d DEF name: \'%s\' not found",LINE,atts[i+1]);
2031 ConsoleMessage(
"\n");
2033 #ifdef X3DPARSERVERBOSE
2034 printf (
"copying for field %s defName %s\n",atts[i], atts[i+1]);
2038 if (NODE_Proto != fromDEFtable->_nodeType) {
2039 ConsoleMessage (
"Warning, line %d DEF/USE mismatch, '%s', %s != %s", LINE,
2040 atts[i+1],stringNodeType(fromDEFtable->_nodeType), stringNodeType (NODE_Proto));
2043 char* containerfield;
2044 node = fromDEFtable;
2045 node->referenceCount++;
2047 #ifdef X3DPARSERVERBOSE
2048 printf (
"successful copying for field %s defName %s\n",atts[i], atts[i+1]);
2051 containerfield = NULL;
2052 for (i = 0; atts[i]; i += 2) {
2053 if(!strcmp(atts[i],
"containerField")) containerfield = atts[i+1];
2055 if(containerfield) {
2056 int builtinField = findFieldInFIELDNAMES(containerfield);
2057 if(builtinField > INT_ID_UNDEFINED){
2058 node->_defaultContainer = builtinField;
2062 pushMode(ud,PARSING_PROTOINSTANCE_USE);
2070 if (nameIndex != INT_ID_UNDEFINED) {
2071 protoname = atts[nameIndex];
2073 ConsoleMessage (
"\"ProtoInstance\" found, but field \"name\" not found!\n");
2078 if( isAvailableBroto(protoname, currentContext , &proto))
2081 char* containerfield;
2084 idepth = pflagdepth == 1;
2085 node=X3D_NODE(brotoInstance(proto,idepth));
2086 node->_executionContext = X3D_NODE(proto);
2087 if (defNameIndex != INT_ID_UNDEFINED){
2088 char * defname = atts[defNameIndex];
2089 broto_store_DEF(currentContext,node, defname);
2091 add_node_to_broto_context(currentContext,node);
2094 containerfield = NULL;
2095 for (i = 0; atts[i]; i += 2) {
2096 if(!strcmp(atts[i],
"containerField")) containerfield = atts[i+1];
2098 if(containerfield) {
2099 int builtinField = findFieldInFIELDNAMES(containerfield);
2100 if(builtinField > INT_ID_UNDEFINED){
2101 node->_defaultContainer = builtinField;
2104 if(visibleIndex != INT_ID_UNDEFINED){
2105 if(!strcmp(atts[visibleIndex],
"false"))
2106 X3D_PROTO(node)->visible = FALSE;
2108 if(displayBBoxIndex != INT_ID_UNDEFINED){
2109 if(!strcmp(atts[displayBBoxIndex],
"true"))
2110 X3D_PROTO(node)->bboxDisplay = TRUE;
2117 ConsoleMessage (
"Attempt to instance undefined prototype typename %s\n",protoname);
2122 pushMode(ud,PARSING_PROTOINSTANCE);
2126BOOL nodeTypeSupportsUserFields(
struct X3D_Node *node);
2127int getFieldFromNodeAndName(
struct X3D_Node* node,
const char *fieldname,
int *type,
int *kind,
int *iifield,
union anyVrml **value);
2128void broto_store_IS(
struct X3D_Proto *proto,
char *protofieldname,
int pmode,
int iprotofield,
int pBuiltIn,
int type,
2129 struct X3D_Node *node,
char* nodefieldname,
int mode,
int ifield,
int nBuiltIn,
int source);
2131static void parseConnect_B(
void *ud,
char **atts) {
2137 node = getNode(ud,TOP);
2138 proto = context = getContext(ud,TOP);
2140 nodefield = protofield = NULL;
2141 for(i=0;atts[i];i+=2){
2142 if(!strcmp(atts[i],
"nodeField")) nodefield = atts[i+1];
2143 if(!strcmp(atts[i],
"protoField")) protofield = atts[i+1];
2146 if(nodefield && protofield){
2147 int ptype, pkind, pifield, pBuiltIn, ntype, nkind, nifield, nBuiltIn;
2148 const char *pname, *nname;
2149 union anyVrml *pvalue, *nvalue;
2150 okp = getFieldFromNodeAndNameC(X3D_NODE(proto),protofield,&ptype, &pkind, &pifield, &pBuiltIn, &pvalue, &pname);
2151 okn = getFieldFromNodeAndNameC(node, nodefield,&ntype, &nkind, &nifield, &nBuiltIn, &nvalue, &nname);
2166 ConsoleMessage(
"Parser error: IS - we have a name match: %s IS %s found protofield %s\n",
2167 nodefield,protofield,protofield);
2168 ConsoleMessage(
"...But the types don't match: nodefield %s protofield %s\n",
2169 FIELDTYPES[ntype],FIELDTYPES[ptype]);
2173 if(nkind != PKW_inputOutput && nkind != pkind){
2174 if(pkind != PKW_inputOutput){
2175 ConsoleMessage(
"Parser Error: IS - we have a name match: %s IS %s found protofield %s\n",
2176 nodefield,protofield,protofield);
2177 ConsoleMessage(
"...But the modes don't jive: nodefield %s protofield %s\n",
2178 PROTOKEYWORDS[nkind],PROTOKEYWORDS[pkind]);
2181 ConsoleMessage(
"Parser Warning: IS - we have a name match: %s IS %s found protofield %s\n",
2182 nodefield,protofield,protofield);
2183 ConsoleMessage(
"...But the modes don't jive: nodefield %s protofield %s\n",
2184 PROTOKEYWORDS[nkind],PROTOKEYWORDS[pkind]);
2185 ConsoleMessage(
"...will thunk\n");
2192 if(pkind == PKW_initializeOnly || pkind == PKW_inputOutput)
2194 shallow_copy_field(ntype, pvalue , nvalue);
2197 source = node->_nodeType == NODE_Proto ? 3 : node->_nodeType == NODE_Script ? 1 : nodeTypeSupportsUserFields(node) ? 2 : 0;
2199 broto_store_IS(context,protofield,pkind,pifield,pBuiltIn,ptype,
2200 node,nodefield,nkind,nifield,nBuiltIn,source);
2206static void XMLCALL X3DstartElement(
void *ud,
const xmlChar *iname,
const xmlChar **atts) {
2210 char *blankAtts[] = {NULL,NULL};
2211 const char *name = (
const char*) iname;
2214 if (atts == NULL) myAtts = blankAtts;
2215 else myAtts = (
char **) atts;
2217 #ifdef X3DPARSERVERBOSE
2219 printf (
"X3DstartElement: %s: atts %p\n",name,atts);
2220 printf (
"startElement, myAtts :%p contents %p\n",myAtts,myAtts[0]);
2222 for (i = 0; myAtts[i]; i += 2) {
2223 printf(
" X3DStartElement field:%s=%s\n", myAtts[i], atts[i + 1]);
2230 for (i = 0; atts[i]; i += 2) {
2231 atts[i+1] = fixAmp(atts[i+1]);
2235 myNodeIndex = findFieldInNODES(name);
2238 if (myNodeIndex != INT_ID_UNDEFINED) {
2239 startBuiltin_B(ud,myNodeIndex,(
const xmlChar *)name,myAtts);
2244 myNodeIndex = findFieldInX3DSPECIAL(name);
2245 if (myNodeIndex != INT_ID_UNDEFINED) {
2246 switch (myNodeIndex) {
2247 case X3DSP_ProtoDeclare:
2248 parseProtoDeclare_B(ud,myAtts);
2250 case X3DSP_ExternProtoDeclare:
2251 parseExternProtoDeclare_B(ud,myAtts);
2253 case X3DSP_ProtoBody:
2254 parseProtoBody_B(ud,myAtts);
2256 case X3DSP_ProtoInterface:
2257 parseProtoInterface(ud,myAtts);
2259 case X3DSP_ProtoInstance:
2260 parseProtoInstance_B(ud,myAtts);
2262 case X3DSP_ProtoInclude:
2263 parseProtoInclude(ud, myAtts);
2266 parseRoutes_B(ud,myAtts);
2268 case X3DSP_meta: parseMeta(ud, myAtts);
break;
2269 case X3DSP_Scene: parseScene(myAtts);
break;
2271 case X3DSP_Header: parseHeader(myAtts);
break;
2272 case X3DSP_X3D: parseX3Dhead(ud,myAtts);
break;
2273 case X3DSP_fieldValue:
2274 parseFieldValue_B(ud,myAtts);
2277 parseScriptProtoField_B (ud, myAtts);
2279 case X3DSP_IS: parseIS(ud);
break;
2280 case X3DSP_component: parseComponent(myAtts);
break;
2282 parseExport_B(ud,myAtts);
2285 parseImport_B(ud,myAtts);
2288 parseConnect_B(ud,myAtts);
2291 parseUnit(ud,myAtts);
break;
2292 default: printf (
" huh? startElement, X3DSPECIAL, but not handled?? %d, :%s:\n",myNodeIndex,X3DSPECIAL[myNodeIndex]);
2300 struct X3D_Proto* isProto = availableBroto(ud, name);
2302 startProto_B(ud, name, isProto, (
const xmlChar **)myAtts);
2306 printf (
"startElement name do not currently handle this one :%s: index %d\n",name,myNodeIndex);
2309static void endScriptProtoField_B(
void *ud) {
2310 if(0) printf(
"end scriptprotofield\n");
2316static void XMLCALL X3DendElement(
void *ud,
const xmlChar *iname) {
2318 const char *name = (
const char*) iname;
2324 #ifdef X3DPARSERVERBOSE
2325 printf (
"endElement: %s : parentIndex %d mode %s\n",name,parentIndex,parserModeStrings[getMode(ud,TOP)]);
2330 myNodeIndex = findFieldInNODES(name);
2331 if (myNodeIndex != INT_ID_UNDEFINED) {
2332 endBuiltin_B(ud,iname);
2340 myNodeIndex = findFieldInX3DSPECIAL(name);
2341 if (myNodeIndex != INT_ID_UNDEFINED) {
2342 switch (myNodeIndex) {
2343 case X3DSP_ProtoInstance:
2344 endProtoInstance_B(ud,name);
2346 case X3DSP_ProtoInterface:
2347 endProtoInterfaceTag(ud);
2349 case X3DSP_ProtoBody:
2350 endProtoBodyTag_B(ud,name);
2352 case X3DSP_ProtoDeclare:
2353 endProtoDeclareTag_B(ud);
2355 case X3DSP_ExternProtoDeclare:
2356 endExternProtoDeclareTag_B(ud);
2367 case X3DSP_component:
2371 case X3DSP_X3D:
break;
2373 endScriptProtoField_B(ud);
2375 case X3DSP_fieldValue:
2376 endFieldValue_B(ud);
2381 printf (
"endElement: huh? X3DSPECIAL, but not handled?? %s\n",X3DSPECIAL[myNodeIndex]);
2386 struct X3D_Proto* proto = availableBroto(ud, name);
2388 endProto_B(ud, name, proto);
2392 printf (
"unhandled endElement name %s index %d\n",name,myNodeIndex);
2393 #ifdef X3DPARSERVERBOSE
2394 printf (
"endElement %s\n",name);
2398static XML_Parser initializeX3DParser () {
2399 ppX3DParser p = (ppX3DParser)gglobal()->X3DParser.prv;
2400 p->X3DParserRecurseLevel++;
2402 if (p->X3DParserRecurseLevel >= PROTOINSTANCE_MAX_LEVELS) {
2403 ConsoleMessage (
"XML_PARSER init: XML file PROTO nested too deep\n");
2404 p->X3DParserRecurseLevel--;
2406 XML_CreateParserLevel(p->x3dparser[p->X3DParserRecurseLevel]);
2407 XML_SetElementHandler(p->x3dparser[p->X3DParserRecurseLevel], X3DstartElement, X3DendElement);
2408 XML_SetCdataSectionHandler (p->x3dparser[p->X3DParserRecurseLevel], startCDATA, endCDATA);
2409 XML_SetDefaultHandler (p->x3dparser[p->X3DParserRecurseLevel],handleCDATA);
2410 XML_SetUserData(p->x3dparser[p->X3DParserRecurseLevel], &parentIndex);
2413 return p->x3dparser[p->X3DParserRecurseLevel];
2416static void shutdownX3DParser (
void *ud) {
2417 ttglobal tg = gglobal();
2418 ppX3DParser p = (ppX3DParser)tg->X3DParser.prv;
2421 XML_ParserFree(p->x3dparser[p->X3DParserRecurseLevel]);
2422 p->X3DParserRecurseLevel--;
2425 if (p->X3DParserRecurseLevel == INT_ID_UNDEFINED) {
2427 gglobal()->X3DParser.parentIndex = 0;
2431 if (p->X3DParserRecurseLevel < INT_ID_UNDEFINED) {
2432 ConsoleMessage (
"XML_PARSER close underflow");
2433 p->X3DParserRecurseLevel = INT_ID_UNDEFINED;
2437 FREE_IF_NZ(tg->X3DParser.CDATA_Text);
2438 p->CDATA_TextMallocSize = 0;
2439 if (p->X3DParserRecurseLevel > INT_ID_UNDEFINED)
2440 p->currentX3DParser = p->x3dparser[p->X3DParserRecurseLevel];
2446 for(i=0;i<vectorSize(p->DEFedNodes);i++){
2447 struct Vector* vd = vector_get(
struct Vector*,p->DEFedNodes,i);
2450 deleteVector(
struct Vector*, p->DEFedNodes);
2463int X3DParse (
struct X3D_Node* ectx,
struct X3D_Node* myParent,
const char *inputstring) {
2464 ttglobal tg = gglobal();
2465 ppX3DParser p = (ppX3DParser)tg->X3DParser.prv;
2466 p->currentX3DParser = initializeX3DParser();
2471 DEBUG_X3DPARSER (
"X3DPARSE on :\n%s:\n",inputstring);
2472 if(p->user_data == NULL){
2475 p->user_data = new_xml_user_data();
2477 pushContext(p->user_data,ectx);
2478 if(myParent->_nodeType == NODE_Proto )
2479 pushField(p->user_data,
"__children");
2481 pushField(p->user_data,
"children");
2482 pushNode(p->user_data,myParent);
2483 pushMode(p->user_data,PARSING_NODES);
2485 if (XML_ParseFile(p->currentX3DParser, p->user_data, inputstring, (
int) strlen(inputstring), TRUE) == XML_STATUS_ERROR) {
2487 xmlErrorPtr xe = xmlGetLastError();
2488 ConsoleMessage(
"Xml Error %s \n",xe->message);
2489 ConsoleMessage(
"Line %d\n",xe->line);
2496 popField(p->user_data);
2497 shutdownX3DParser(p->user_data);
2498 Parser_deleteParserForScanStringValueToMem();
2501 popField(p->user_data);
2502 shutdownX3DParser(p->user_data);
2503 Parser_deleteParserForScanStringValueToMem();