A freeze group can now be allowed to move rigidly in some dimension by using "freezed...
[gromacs/rigid-bodies.git] / src / mdlib / gmx_qhop_xml.c
blobabc18db29f29521c8e9f6466178e2bb4ad96c650
1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
2 *
3 * This source code is part of
4 *
5 * G R O M A C S
6 *
7 * GROningen MAchine for Chemical Simulations
8 *
9 * VERSION 4.5
10 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12 * Copyright (c) 2001-2008, The GROMACS development team,
13 * check out http://www.gromacs.org for more information.
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * If you want to redistribute modifications, please consider that
21 * scientific software is very special. Version control is crucial -
22 * bugs must be traceable. We will be happy to consider code for
23 * inclusion in the official distribution, but derived work must not
24 * be called official GROMACS. Details are found in the README & COPYING
25 * files - if they are missing, get the official version at www.gromacs.org.
27 * To help us fund GROMACS development, we humbly ask that you cite
28 * the papers on the package - you can find them in the top README file.
30 * For more info, check our website at http://www.gromacs.org
32 * And Hey:
33 * Groningen Machine for Chemical Simulation
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
40 #include <string.h>
41 #include "gmx_fatal.h"
42 #include "smalloc.h"
43 #include "macros.h"
44 #include "futil.h"
45 #include "gmx_qhop_parm.h"
47 #ifdef HAVE_LIBXML2
48 #include <libxml/parser.h>
49 #include <libxml/tree.h>
51 extern int xmlDoValidityCheckingDefaultValue;
53 #define NN(x) (NULL != (x))
55 static const char *xmltypes[] = {
56 NULL,
57 "XML_ELEMENT_NODE",
58 "XML_ATTRIBUTE_NODE",
59 "XML_TEXT_NODE",
60 "XML_CDATA_SECTION_NODE",
61 "XML_ENTITY_REF_NODE",
62 "XML_ENTITY_NODE",
63 "XML_PI_NODE",
64 "XML_COMMENT_NODE",
65 "XML_DOCUMENT_NODE",
66 "XML_DOCUMENT_TYPE_NODE",
67 "XML_DOCUMENT_FRAG_NODE",
68 "XML_NOTATION_NODE",
69 "XML_HTML_DOCUMENT_NODE",
70 "XML_DTD_NODE",
71 "XML_ELEMENT_DECL",
72 "XML_ATTRIBUTE_DECL",
73 "XML_ENTITY_DECL",
74 "XML_NAMESPACE_DECL",
75 "XML_XINCLUDE_START",
76 "XML_XINCLUDE_END"
78 #define NXMLTYPES asize(xmltypes)
80 enum {
81 exmlQHOPS,
82 exmlQHOP, exmlDONOR, exmlACCEPTOR,
83 exmlPARAM, exmlNAME, exmlVALUE,
84 exmlUNIT,
85 exmlNR
88 static const char *exml_names[exmlNR] = {
89 "qhops",
90 "qhop", "donor", "acceptor", "parameter",
91 "name", "value", "unit"
94 typedef struct {
95 int nqh;
96 gmx_qhop_t *gqh;
97 } t_xmlrec;
99 static int find_elem(char *name,int nr,const char *names[])
101 int i;
103 for(i=0; (i<nr); i++)
104 if (strcmp(name,names[i]) == 0)
105 break;
106 if (i == nr)
107 gmx_fatal(FARGS,"Unknown element name %s",name);
109 return i;
112 void add_xml_int(xmlNodePtr ptr,const char *name,int val)
114 xmlChar buf[32];
116 sprintf((char *)buf,"%d",val);
117 if (xmlSetProp(ptr,(xmlChar *)name,buf) == 0)
118 gmx_fatal(FARGS,"Setting",(char *)name);
121 void add_xml_double(xmlNodePtr ptr,const char *name,double val)
123 xmlChar buf[32];
125 sprintf((char *)buf,"%g",val);
126 if (xmlSetProp(ptr,(xmlChar *)name,buf) == 0)
127 gmx_fatal(FARGS,"Setting",(char *)name);
130 void add_xml_char(xmlNodePtr ptr,const char *name,char *val)
132 if (xmlSetProp(ptr,(xmlChar *)name,(xmlChar *)val) == 0)
133 gmx_fatal(FARGS,"Setting",(char *)name);
136 xmlNodePtr add_xml_child(xmlNodePtr parent,const char *type)
138 xmlNodePtr child;
140 if ((child = xmlNewChild(parent,NULL,(xmlChar *)type,NULL)) == NULL)
141 gmx_fatal(FARGS,"Creating element",(char *)type);
143 return child;
146 xmlNodePtr add_xml_comment(xmlDocPtr doc,
147 xmlNodePtr prev,char *comment)
149 xmlNodePtr comm,ptr;
151 if ((comm = xmlNewComment((xmlChar *)comment)) == NULL)
152 gmx_fatal(FARGS,"Creating doc comment element","");
153 ptr = prev;
154 while (ptr->next != NULL)
155 ptr=ptr->next;
156 ptr->next = comm;
157 comm->prev = ptr;
158 comm->doc = doc;
160 return comm;
163 static char *sp(int n, char buf[], int maxindent)
165 int i;
166 if(n>=maxindent)
167 n=maxindent-1;
169 /* Don't indent more than maxindent characters */
170 for(i=0; (i<n); i++)
171 buf[i] = ' ';
172 buf[i] = '\0';
174 return buf;
177 static void qhop_process_attr(FILE *fp,xmlAttrPtr attr,int parent,
178 int elem,int indent,gmx_qhop_t qht)
180 char *attrname,*attrval;
181 char buf[100];
182 int i,kkk,eprop;
183 char *xbuf[exmlNR];
185 for(i=0; (i<exmlNR); i++)
186 xbuf[i] = NULL;
187 while (attr != NULL) {
188 attrname = (char *)attr->name;
189 attrval = (char *)attr->children->content;
191 #define atest(s) ((gmx_strcasecmp(attrname,s) == 0) && (attrval != NULL))
192 kkk = find_elem(attrname,exmlNR,exml_names);
193 if (attrval != NULL)
194 xbuf[kkk] = strdup(attrval);
196 if (fp)
197 fprintf(fp,"%sProperty: '%s' Value: '%s'\n",sp(indent,buf,99),
198 attrname,attrval);
199 attr = attr->next;
200 #undef atest
203 switch (elem) {
204 case exmlQHOP:
205 if (NN(xbuf[exmlDONOR]) && NN(xbuf[exmlACCEPTOR])) {
206 gmx_qhop_set_donor(qht,xbuf[exmlDONOR]);
207 gmx_qhop_set_acceptor(qht,xbuf[exmlACCEPTOR]);
209 break;
210 case exmlPARAM:
211 if (NN(xbuf[exmlNAME]) && NN(xbuf[exmlUNIT]) && NN(xbuf[exmlVALUE])) {
212 gmx_qhop_add_param(qht,xbuf[exmlNAME],xbuf[exmlVALUE],
213 xbuf[exmlUNIT]);
215 break;
216 default:
217 break;
219 for(i=0; (i<exmlNR); i++)
220 if (NN(xbuf[i]))
221 sfree(xbuf[i]);
224 static void qhop_process_element(FILE *fp,xmlNodePtr tree,int parent,
225 int indent,t_xmlrec *xml)
227 int elem;
228 char buf[100];
230 elem = find_elem((char *)tree->name,exmlNR,exml_names);
231 if (fp)
232 fprintf(fp,"%sElement node name %s\n",sp(indent,buf,99),
233 (char *)tree->name);
234 if (elem == exmlQHOP) {
235 xml->nqh++;
236 srenew(xml->gqh,xml->nqh);
237 xml->gqh[xml->nqh-1] = gmx_qhop_init();
239 if (elem != exmlQHOPS)
240 qhop_process_attr(fp,tree->properties,parent,
241 elem,indent+2,xml->gqh[xml->nqh-1]);
244 static void qhop_process_tree(FILE *fp,xmlNodePtr tree,int parent,
245 int indent,t_xmlrec *xml)
247 char buf[100];
248 int elem;
250 while (tree != NULL) {
251 if (fp) {
252 if ((tree->type > 0) && (tree->type < NXMLTYPES))
253 fprintf(fp,"Node type %s encountered with name %s\n",
254 xmltypes[tree->type],(char *)tree->name);
255 else
256 fprintf(fp,"Node type %d encountered\n",tree->type);
259 switch (tree->type) {
260 case XML_ELEMENT_NODE:
261 qhop_process_element(fp,tree,parent,indent+2,xml);
263 if (tree->children) {
264 elem = find_elem((char *)tree->name,exmlNR,exml_names);
265 qhop_process_tree(fp,tree->children,elem,indent+2,xml);
267 break;
268 default:
269 break;
271 tree = tree->next;
275 gmx_qhop_t *
276 gmx_qhops_read(char *fn,int *nqhop)
278 xmlDocPtr doc;
279 int i,npd;
280 t_xmlrec *xml;
281 const char *db="qhops.dat";
282 gmx_bool fna=FALSE;
284 xmlDoValidityCheckingDefaultValue = 0;
285 if (NULL == fn)
287 fn = (char *)gmxlibfn(db);
288 fna=TRUE;
290 if ((doc = xmlParseFile(fn)) == NULL) {
291 fprintf(stderr,"Reading XML file %s. Run a syntax checker such as nsgmls.",
292 fn);
293 exit(1);
296 snew(xml,1);
297 qhop_process_tree(NULL,doc->children,0,0,xml);
299 xmlFreeDoc(doc);
300 if (fna)
301 sfree(fn);
303 *nqhop = xml->nqh;
305 return xml->gqh;
308 static void add_xml_qhop(xmlNodePtr parent,gmx_qhop_t qht)
310 xmlNodePtr ptr,child,grandchild,comp;
311 char *name,*type,*value,*unit;
313 ptr = add_xml_child(parent,exml_names[exmlQHOP]);
314 add_xml_char(ptr,exml_names[exmlDONOR],gmx_qhop_get_donor(qht));
315 add_xml_char(ptr,exml_names[exmlACCEPTOR],gmx_qhop_get_acceptor(qht));
317 while (gmx_qhop_get_param(qht,&name,&value,&unit) == 1) {
318 child = add_xml_child(ptr,exml_names[exmlPARAM]);
319 add_xml_char(child,exml_names[exmlNAME],name);
320 add_xml_char(child,exml_names[exmlVALUE],value);
321 add_xml_char(child,exml_names[exmlUNIT],unit);
322 sfree(name);
323 sfree(value);
324 sfree(unit);
328 void gmx_qhops_write(char *fn,int nqhop,gmx_qhop_t qht[])
330 xmlDocPtr doc;
331 xmlDtdPtr dtd;
332 xmlNodePtr myroot;
333 int i,nmt;
334 xmlChar *libdtdname,*dtdname,*gmx;
336 gmx = (xmlChar *) "qhops";
337 dtdname = (xmlChar *) "qhops.dtd";
338 libdtdname = dtdname;
340 if ((doc = xmlNewDoc((xmlChar *)"1.0")) == NULL)
341 gmx_fatal(FARGS,"Creating XML document","");
343 if ((dtd = xmlCreateIntSubset(doc,dtdname,libdtdname,dtdname)) == NULL)
344 gmx_fatal(FARGS,"Creating XML DTD","");
346 if ((myroot = xmlNewDocNode(doc,NULL,gmx,NULL)) == NULL)
347 gmx_fatal(FARGS,"Creating root element","");
348 dtd->next = myroot;
349 myroot->prev = (xmlNodePtr) dtd;
351 /* Add molecule definitions */
352 for(i=0; (i<nqhop); i++)
353 add_xml_qhop(myroot,qht[i]);
355 xmlSetDocCompressMode(doc,0);
356 xmlIndentTreeOutput = 1;
357 if (xmlSaveFormatFileEnc(fn,doc,"ISO-8859-1",2) == 0)
358 gmx_fatal(FARGS,"Saving file",fn);
359 xmlFreeDoc(doc);
364 #else
366 gmx_qhop_t gmx_qhops_read(char *fn,int *nqhop)
368 gmx_fatal(FARGS,"You need to configure the software with --with-xml for function gmx_qhops_read to work");
369 return NULL;
372 void gmx_qhops_write(char *fn,int nqhop,gmx_qhop_t qht)
374 gmx_fatal(FARGS,"You need to configure the software with --with-xml for function gmx_qhops_write to work");
377 #endif