]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - plugins/mapxml/xmlparse.cpp
8MB stack size linker options on all VC2008 proj files.
[xonotic/netradiant.git] / plugins / mapxml / xmlparse.cpp
index 85795cdf1a2f14c064b1639289446be57714f0eb..f9093a5f01aee44214417fae947afd49743fe23f 100644 (file)
-//\r
-// parses xml tree format into internal objects\r
-//\r
-\r
-\r
-#include "plugin.h"\r
-\r
-void Patch_XMLParse(patchMesh_t *pPatch, xmlNodePtr surface)\r
-{\r
-  char *str, *content;\r
-  int i, j;\r
-\r
-  for(xmlNodePtr current = surface->children; current != NULL; current = current->next)\r
-  {\r
-    if(current->type != XML_ELEMENT_NODE) continue;\r
-    if(!strcmp((char *)current->name, "matrix"))\r
-    {\r
-      str = (char *)xmlGetProp(current, (xmlChar *)"width");\r
-      pPatch->width = atoi(str);\r
-      xmlFree(str);\r
-      str = (char *)xmlGetProp(current, (xmlChar *)"height");\r
-      pPatch->height = atoi(str);\r
-      xmlFree(str);\r
-\r
-      content = Q_StrDup((char *)current->children->content);\r
-\r
-      str = strtok(content, " \n\r\t\v\0");\r
-      for(i=0; i<pPatch->width; i++)\r
-      {\r
-        for(j=0; j<pPatch->height; j++)\r
-        {\r
-          pPatch->ctrl[i][j].xyz[0] = atof(str);\r
-          str = strtok(NULL, " \n\r\t\v\0");\r
-          pPatch->ctrl[i][j].xyz[1] = atof(str);\r
-          str = strtok(NULL, " \n\r\t\v\0");\r
-          pPatch->ctrl[i][j].xyz[2] = atof(str);\r
-          str = strtok(NULL, " \n\r\t\v\0");\r
-          pPatch->ctrl[i][j].st[0] = atof(str);\r
-          str = strtok(NULL, " \n\r\t\v\0");\r
-          pPatch->ctrl[i][j].st[1] = atof(str);\r
-          str = strtok(NULL, " \n\r\t\v\0");\r
-        }\r
-      }\r
-\r
-      delete [] content;\r
-    }\r
-    else if(!strcmp((char *)current->name, "shader")) {\r
-      pPatch->pShader = QERApp_Shader_ForName((char*)current->children->content);\r
-      pPatch->d_texture = pPatch->pShader->getTexture();\r
-    }\r
-  }\r
-}\r
-\r
-void Face_XMLParse (face_t *face, xmlNodePtr surface)\r
-{\r
-  char *str, *content;\r
-  int i, j;\r
-\r
-  for(xmlNodePtr current = surface->children; current != NULL; current = current->next)\r
-  {\r
-    if(current->type != XML_ELEMENT_NODE) continue;\r
-    if(!strcmp((char *)current->name, "planepts"))\r
-    {\r
-      content = Q_StrDup((char *)current->children->content);\r
-\r
-      str = strtok(content, " \n\r\t\v\0");\r
-      for (i=0 ; i<3 ; i++)\r
-           {\r
-                   for (j=0 ; j<3 ; j++)\r
-                   {\r
-                           face->planepts[i][j] = atof(str);\r
-          str = strtok(NULL, " \n\r\t\v\0");\r
-                   }\r
-      }\r
-\r
-      delete [] content;\r
-    }\r
-    else if(!strcmp((char *)current->name, "texdef"))\r
-    {\r
-      content = Q_StrDup((char *)current->children->content);\r
-  \r
-      str = strtok(content, " \n\r\t\v\0");\r
-      face->texdef.shift[0] = atof(str);\r
-      str = strtok(NULL, " \n\r\t\v\0");\r
-      face->texdef.shift[1] = atof(str);\r
-      str = strtok(NULL, " \n\r\t\v\0");\r
-      face->texdef.rotate = atof(str);\r
-      str = strtok(NULL, " \n\r\t\v\0");\r
-      face->texdef.scale[0] = atof(str);\r
-      str = strtok(NULL, " \n\r\t\v\0");\r
-      face->texdef.scale[1] = atof(str);\r
-\r
-      delete [] content;\r
-    }\r
-    else if(!strcmp((char *)current->name, "bpmatrix"))\r
-    {\r
-      content = Q_StrDup((char *)current->children->content);\r
-  \r
-      str = strtok(content, " \n\r\t\v\0");\r
-      face->brushprimit_texdef.coords[0][0] = atof(str);\r
-      str = strtok(NULL, " \n\r\t\v\0");\r
-      face->brushprimit_texdef.coords[0][1] = atof(str);\r
-      str = strtok(NULL, " \n\r\t\v\0");\r
-      face->brushprimit_texdef.coords[0][2] = atof(str);\r
-      str = strtok(NULL, " \n\r\t\v\0");\r
-      face->brushprimit_texdef.coords[1][0] = atof(str);\r
-      str = strtok(NULL, " \n\r\t\v\0");\r
-      face->brushprimit_texdef.coords[1][1] = atof(str);\r
-      str = strtok(NULL, " \n\r\t\v\0");\r
-      face->brushprimit_texdef.coords[1][2] = atof(str);\r
-\r
-      delete [] content;\r
-    }\r
-    else if(!strcmp((char *)current->name, "flags"))\r
-    {\r
-      content = Q_StrDup((char *)current->children->content);\r
-\r
-      str = strtok(content, " \n\r\t\v\0");\r
-      face->texdef.contents = atoi(str);\r
-      str = strtok(NULL, " \n\r\t\v\0");\r
-      face->texdef.flags = atoi(str);\r
-      str = strtok(NULL, " \n\r\t\v\0");\r
-      face->texdef.value = atoi(str);\r
-\r
-      delete [] content;\r
-    }\r
-    else if(!strcmp((char *)current->name, "shader"))\r
-    {\r
-      face->texdef.SetName((char *)current->children->content);\r
-    }\r
-  }\r
-}\r
-\r
-void Brush_XMLParse (brush_t *pBrush, xmlNodePtr primitive)\r
-{\r
-  face_t    *f;\r
-\r
-  for(xmlNodePtr current = primitive->children; current != NULL; current = current->next)\r
-  {\r
-    if(current->type != XML_ELEMENT_NODE) continue;\r
-    f = pBrush->brush_faces;\r
-    pBrush->brush_faces = Face_Alloc();\r
-    Face_XMLParse(pBrush->brush_faces, current);\r
-    pBrush->brush_faces->next = f;\r
-  }\r
-}\r
-\r
-void Entity_XMLParse(entity_t *pEntity, xmlNodePtr entity)\r
-{\r
-  brush_t *pBrush;\r
-\r
-  for(xmlNodePtr current = entity->children; current != NULL; current = current->next)\r
-  {\r
-    if(current->type != XML_ELEMENT_NODE) continue;\r
-    if(!strcmp((char *)current->name, "epair"))\r
-    {\r
-      char *key = (char *)xmlGetProp(current, (xmlChar *)"key");\r
-      char *value = (char *)xmlGetProp(current, (xmlChar *)"value");\r
-      SetKeyValue(pEntity, key, value);\r
-      xmlFree(key);\r
-      xmlFree(value);\r
-    }\r
-    else if(strcmp((char *)current->name, "brush") == 0)\r
-    {\r
-      pBrush = Brush_Alloc();\r
-      Brush_XMLParse(pBrush, current);\r
-      ((CPtrArray*)pEntity->pData)->Add(pBrush);\r
-    }\r
-    else if(strcmp((char *)current->name, "patch") == 0)\r
-    {\r
-      pBrush = Brush_Alloc();\r
-      pBrush->patchBrush = true;\r
-      pBrush->pPatch = Patch_Alloc();\r
-      pBrush->pPatch->pSymbiot = pBrush;\r
-      Patch_XMLParse(pBrush->pPatch, current);\r
-      ((CPtrArray*)pEntity->pData)->Add(pBrush);\r
-    }\r
-  }\r
-}\r
-\r
-void Map_XMLRead(CPtrArray *map, xmlNodePtr map_node)\r
-{\r
-  entity_t *pEntity;\r
-  xmlNodePtr current;\r
-\r
-  for(current = map_node->children; current != NULL; current = current->next)\r
-  {\r
-    if(current->type != XML_ELEMENT_NODE) continue;\r
-    pEntity = Entity_Alloc();\r
-    pEntity->pData = new CPtrArray;\r
-    Entity_XMLParse(pEntity, current);\r
-    map->Add(pEntity);\r
-  }\r
-}\r
-\r
-// SPoG\r
-// temporarily copied from qe3.cpp\r
-// duplicate code starts here (note: g_strAppPath swapped for g_FuncTable.m_pfnGetQERPath())\r
-\r
-void HandleXMLError( void* ctxt, const char* text, ... )\r
-{\r
-  va_list argptr;\r
-  static char buf[32768];\r
-\r
-  va_start (argptr,text);\r
-  vsprintf (buf, text, argptr);\r
-  Sys_FPrintf (SYS_ERR, "XML %s\n", buf);\r
-  va_end (argptr);\r
-}\r
-\r
-#define DTD_BUFFER_LENGTH 1024\r
-xmlDocPtr ParseXMLStream(IDataStream *stream, bool validate = false)\r
-{\r
-  xmlDocPtr doc = NULL;\r
-  bool wellFormed = false, valid = false;\r
-  int res, size = 1024;\r
-  char chars[1024];\r
-  xmlParserCtxtPtr ctxt;\r
-\r
-  // SPoG\r
-  // HACK: use AppPath to resolve DTD location\r
-  // do a buffer-safe string copy and concatenate\r
-  int i;\r
-  char* w;\r
-  const char* r;\r
-  char buf[DTD_BUFFER_LENGTH];\r
-\r
-  w = buf;\r
-  i = 0;\r
-  // copy\r
-  //assert(g_FuncTable.m_pfnGetQERPath() != NULL);\r
-  for(r = g_FuncTable.m_pfnGetQERPath(); i<DTD_BUFFER_LENGTH && *r != '\0'; i++, r++)  w[i] = *r;\r
-  // concatenate\r
-  for(r = "dtds/"; i<DTD_BUFFER_LENGTH && *r != '\0'; i++, r++)  w[i] = *r;\r
-  // terminate\r
-  w[i] = '\0';\r
-\r
-  if(i == DTD_BUFFER_LENGTH)\r
-  {\r
-    HandleXMLError(NULL, "ERROR: buffer overflow: DTD path length too large\n");\r
-    return NULL;\r
-  }\r
-\r
-  //if(validate)\r
-  //  xmlDoValidityCheckingDefaultValue = 1;\r
-  //else\r
-    xmlDoValidityCheckingDefaultValue = 0;\r
-\r
-  xmlSetGenericErrorFunc(NULL, HandleXMLError);\r
-\r
-  res = stream->Read(chars, 4);\r
-  if (res > 0)\r
-  {\r
-    ctxt = xmlCreatePushParserCtxt(NULL, NULL, chars, res, buf);\r
-\r
-    while ((res = stream->Read(chars, size)) > 0)\r
-    {\r
-      xmlParseChunk(ctxt, chars, res, 0);\r
-    }\r
-    xmlParseChunk(ctxt, chars, 0, 1);\r
-    doc = ctxt->myDoc;\r
-\r
-    wellFormed = (ctxt->wellFormed == 1);\r
-    valid = (ctxt->valid == 1);\r
-\r
-    xmlFreeParserCtxt(ctxt);\r
-  }\r
-\r
-  if(wellFormed && (!validate || (validate && valid)))\r
-    return doc;\r
-\r
-  if(doc != NULL)\r
-    xmlFreeDoc(doc);\r
-\r
-  return NULL;\r
-}\r
-\r
-// duplicate code ends here\r
-\r
-void Map_Read (IDataStream *in, CPtrArray *map)\r
-{\r
-  xmlDocPtr doc;\r
-\r
-  doc = ParseXMLStream(in, false ); // quick hack while dtd validation is broken\r
-\r
-  if(doc != NULL)\r
-  {\r
-    xmlNodePtr node=doc->children;\r
-    while(node != NULL && node->type != XML_ELEMENT_NODE) node=node->next;\r
-    if(node != NULL)\r
-      Map_XMLRead(map, node);\r
-  }\r
\r
-  xmlFreeDoc(doc);\r
-}\r
+//
+// parses xml tree format into internal objects
+//
+
+
+#include "plugin.h"
+
+void Patch_XMLParse(patchMesh_t *pPatch, xmlNodePtr surface)
+{
+  char *str, *content;
+  int i, j;
+
+  for(xmlNodePtr current = surface->children; current != NULL; current = current->next)
+  {
+    if(current->type != XML_ELEMENT_NODE) continue;
+    if(!strcmp((char *)current->name, "matrix"))
+    {
+      str = (char *)xmlGetProp(current, (xmlChar *)"width");
+      pPatch->width = atoi(str);
+      xmlFree(str);
+      str = (char *)xmlGetProp(current, (xmlChar *)"height");
+      pPatch->height = atoi(str);
+      xmlFree(str);
+
+      content = Q_StrDup((char *)current->children->content);
+
+      str = strtok(content, " \n\r\t\v\0");
+      for(i=0; i<pPatch->width; i++)
+      {
+        for(j=0; j<pPatch->height; j++)
+        {
+          pPatch->ctrl[i][j].xyz[0] = atof(str);
+          str = strtok(NULL, " \n\r\t\v\0");
+          pPatch->ctrl[i][j].xyz[1] = atof(str);
+          str = strtok(NULL, " \n\r\t\v\0");
+          pPatch->ctrl[i][j].xyz[2] = atof(str);
+          str = strtok(NULL, " \n\r\t\v\0");
+          pPatch->ctrl[i][j].st[0] = atof(str);
+          str = strtok(NULL, " \n\r\t\v\0");
+          pPatch->ctrl[i][j].st[1] = atof(str);
+          str = strtok(NULL, " \n\r\t\v\0");
+        }
+      }
+
+      delete [] content;
+    }
+    else if(!strcmp((char *)current->name, "shader")) {
+      pPatch->pShader = QERApp_Shader_ForName((char*)current->children->content);
+      pPatch->d_texture = pPatch->pShader->getTexture();
+    }
+  }
+}
+
+void Face_XMLParse (face_t *face, xmlNodePtr surface)
+{
+  char *str, *content;
+  int i, j;
+
+  for(xmlNodePtr current = surface->children; current != NULL; current = current->next)
+  {
+    if(current->type != XML_ELEMENT_NODE) continue;
+    if(!strcmp((char *)current->name, "planepts"))
+    {
+      content = Q_StrDup((char *)current->children->content);
+
+      str = strtok(content, " \n\r\t\v\0");
+      for (i=0 ; i<3 ; i++)
+           {
+                   for (j=0 ; j<3 ; j++)
+                   {
+                           face->planepts[i][j] = atof(str);
+          str = strtok(NULL, " \n\r\t\v\0");
+                   }
+      }
+
+      delete [] content;
+    }
+    else if(!strcmp((char *)current->name, "texdef"))
+    {
+      content = Q_StrDup((char *)current->children->content);
+  
+      str = strtok(content, " \n\r\t\v\0");
+      face->texdef.shift[0] = atof(str);
+      str = strtok(NULL, " \n\r\t\v\0");
+      face->texdef.shift[1] = atof(str);
+      str = strtok(NULL, " \n\r\t\v\0");
+      face->texdef.rotate = atof(str);
+      str = strtok(NULL, " \n\r\t\v\0");
+      face->texdef.scale[0] = atof(str);
+      str = strtok(NULL, " \n\r\t\v\0");
+      face->texdef.scale[1] = atof(str);
+
+      delete [] content;
+    }
+    else if(!strcmp((char *)current->name, "bpmatrix"))
+    {
+      content = Q_StrDup((char *)current->children->content);
+  
+      str = strtok(content, " \n\r\t\v\0");
+      face->brushprimit_texdef.coords[0][0] = atof(str);
+      str = strtok(NULL, " \n\r\t\v\0");
+      face->brushprimit_texdef.coords[0][1] = atof(str);
+      str = strtok(NULL, " \n\r\t\v\0");
+      face->brushprimit_texdef.coords[0][2] = atof(str);
+      str = strtok(NULL, " \n\r\t\v\0");
+      face->brushprimit_texdef.coords[1][0] = atof(str);
+      str = strtok(NULL, " \n\r\t\v\0");
+      face->brushprimit_texdef.coords[1][1] = atof(str);
+      str = strtok(NULL, " \n\r\t\v\0");
+      face->brushprimit_texdef.coords[1][2] = atof(str);
+
+      delete [] content;
+    }
+    else if(!strcmp((char *)current->name, "flags"))
+    {
+      content = Q_StrDup((char *)current->children->content);
+
+      str = strtok(content, " \n\r\t\v\0");
+      face->texdef.contents = atoi(str);
+      str = strtok(NULL, " \n\r\t\v\0");
+      face->texdef.flags = atoi(str);
+      str = strtok(NULL, " \n\r\t\v\0");
+      face->texdef.value = atoi(str);
+
+      delete [] content;
+    }
+    else if(!strcmp((char *)current->name, "shader"))
+    {
+      face->texdef.SetName((char *)current->children->content);
+    }
+  }
+}
+
+void Brush_XMLParse (brush_t *pBrush, xmlNodePtr primitive)
+{
+  face_t    *f;
+
+  for(xmlNodePtr current = primitive->children; current != NULL; current = current->next)
+  {
+    if(current->type != XML_ELEMENT_NODE) continue;
+    f = pBrush->brush_faces;
+    pBrush->brush_faces = Face_Alloc();
+    Face_XMLParse(pBrush->brush_faces, current);
+    pBrush->brush_faces->next = f;
+  }
+}
+
+void Entity_XMLParse(entity_t *pEntity, xmlNodePtr entity)
+{
+  brush_t *pBrush;
+
+  for(xmlNodePtr current = entity->children; current != NULL; current = current->next)
+  {
+    if(current->type != XML_ELEMENT_NODE) continue;
+    if(!strcmp((char *)current->name, "epair"))
+    {
+      char *key = (char *)xmlGetProp(current, (xmlChar *)"key");
+      char *value = (char *)xmlGetProp(current, (xmlChar *)"value");
+      SetKeyValue(pEntity, key, value);
+      xmlFree(key);
+      xmlFree(value);
+    }
+    else if(strcmp((char *)current->name, "brush") == 0)
+    {
+      pBrush = Brush_Alloc();
+      Brush_XMLParse(pBrush, current);
+      ((CPtrArray*)pEntity->pData)->Add(pBrush);
+    }
+    else if(strcmp((char *)current->name, "patch") == 0)
+    {
+      pBrush = Brush_Alloc();
+      pBrush->patchBrush = true;
+      pBrush->pPatch = Patch_Alloc();
+      pBrush->pPatch->pSymbiot = pBrush;
+      Patch_XMLParse(pBrush->pPatch, current);
+      ((CPtrArray*)pEntity->pData)->Add(pBrush);
+    }
+  }
+}
+
+void Map_XMLRead(CPtrArray *map, xmlNodePtr map_node)
+{
+  entity_t *pEntity;
+  xmlNodePtr current;
+
+  for(current = map_node->children; current != NULL; current = current->next)
+  {
+    if(current->type != XML_ELEMENT_NODE) continue;
+    pEntity = Entity_Alloc();
+    pEntity->pData = new CPtrArray;
+    Entity_XMLParse(pEntity, current);
+    map->Add(pEntity);
+  }
+}
+
+// SPoG
+// temporarily copied from qe3.cpp
+// duplicate code starts here (note: g_strAppPath swapped for g_FuncTable.m_pfnGetQERPath())
+
+void HandleXMLError( void* ctxt, const char* text, ... )
+{
+  va_list argptr;
+  static char buf[32768];
+
+  va_start (argptr,text);
+  vsprintf (buf, text, argptr);
+  Sys_FPrintf (SYS_ERR, "XML %s\n", buf);
+  va_end (argptr);
+}
+
+#define DTD_BUFFER_LENGTH 1024
+xmlDocPtr ParseXMLStream(IDataStream *stream, bool validate = false)
+{
+  xmlDocPtr doc = NULL;
+  bool wellFormed = false, valid = false;
+  int res, size = 1024;
+  char chars[1024];
+  xmlParserCtxtPtr ctxt;
+
+  // SPoG
+  // HACK: use AppPath to resolve DTD location
+  // do a buffer-safe string copy and concatenate
+  int i;
+  char* w;
+  const char* r;
+  char buf[DTD_BUFFER_LENGTH];
+
+  w = buf;
+  i = 0;
+  // copy
+  //assert(g_FuncTable.m_pfnGetQERPath() != NULL);
+  for(r = g_FuncTable.m_pfnGetQERPath(); i<DTD_BUFFER_LENGTH && *r != '\0'; i++, r++)  w[i] = *r;
+  // concatenate
+  for(r = "dtds/"; i<DTD_BUFFER_LENGTH && *r != '\0'; i++, r++)  w[i] = *r;
+  // terminate
+  w[i] = '\0';
+
+  if(i == DTD_BUFFER_LENGTH)
+  {
+    HandleXMLError(NULL, "ERROR: buffer overflow: DTD path length too large\n");
+    return NULL;
+  }
+
+  //if(validate)
+  //  xmlDoValidityCheckingDefaultValue = 1;
+  //else
+    xmlDoValidityCheckingDefaultValue = 0;
+
+  xmlSetGenericErrorFunc(NULL, HandleXMLError);
+
+  res = stream->Read(chars, 4);
+  if (res > 0)
+  {
+    ctxt = xmlCreatePushParserCtxt(NULL, NULL, chars, res, buf);
+
+    while ((res = stream->Read(chars, size)) > 0)
+    {
+      xmlParseChunk(ctxt, chars, res, 0);
+    }
+    xmlParseChunk(ctxt, chars, 0, 1);
+    doc = ctxt->myDoc;
+
+    wellFormed = (ctxt->wellFormed == 1);
+    valid = (ctxt->valid == 1);
+
+    xmlFreeParserCtxt(ctxt);
+  }
+
+  if(wellFormed && (!validate || (validate && valid)))
+    return doc;
+
+  if(doc != NULL)
+    xmlFreeDoc(doc);
+
+  return NULL;
+}
+
+// duplicate code ends here
+
+void Map_Read (IDataStream *in, CPtrArray *map)
+{
+  xmlDocPtr doc;
+
+  doc = ParseXMLStream(in, false ); // quick hack while dtd validation is broken
+
+  if(doc != NULL)
+  {
+    xmlNodePtr node=doc->children;
+    while(node != NULL && node->type != XML_ELEMENT_NODE) node=node->next;
+    if(node != NULL)
+      Map_XMLRead(map, node);
+  }
+  xmlFreeDoc(doc);
+}