1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
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
33 * Groningen Machine for Chemical Simulation
41 #include "gmx_fatal.h"
45 #include "gmx_qhop_parm.h"
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
[] = {
60 "XML_CDATA_SECTION_NODE",
61 "XML_ENTITY_REF_NODE",
66 "XML_DOCUMENT_TYPE_NODE",
67 "XML_DOCUMENT_FRAG_NODE",
69 "XML_HTML_DOCUMENT_NODE",
78 #define NXMLTYPES asize(xmltypes)
82 exmlQHOP
, exmlDONOR
, exmlACCEPTOR
,
83 exmlPARAM
, exmlNAME
, exmlVALUE
,
88 static const char *exml_names
[exmlNR
] = {
90 "qhop", "donor", "acceptor", "parameter",
91 "name", "value", "unit"
99 static int find_elem(char *name
,int nr
,const char *names
[])
103 for(i
=0; (i
<nr
); i
++)
104 if (strcmp(name
,names
[i
]) == 0)
107 gmx_fatal(FARGS
,"Unknown element name %s",name
);
112 void add_xml_int(xmlNodePtr ptr
,const char *name
,int val
)
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
)
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
)
140 if ((child
= xmlNewChild(parent
,NULL
,(xmlChar
*)type
,NULL
)) == NULL
)
141 gmx_fatal(FARGS
,"Creating element",(char *)type
);
146 xmlNodePtr
add_xml_comment(xmlDocPtr doc
,
147 xmlNodePtr prev
,char *comment
)
151 if ((comm
= xmlNewComment((xmlChar
*)comment
)) == NULL
)
152 gmx_fatal(FARGS
,"Creating doc comment element","");
154 while (ptr
->next
!= NULL
)
163 static char *sp(int n
, char buf
[], int maxindent
)
169 /* Don't indent more than maxindent characters */
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
;
185 for(i
=0; (i
<exmlNR
); i
++)
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
);
194 xbuf
[kkk
] = strdup(attrval
);
197 fprintf(fp
,"%sProperty: '%s' Value: '%s'\n",sp(indent
,buf
,99),
205 if (NN(xbuf
[exmlDONOR
]) && NN(xbuf
[exmlACCEPTOR
])) {
206 gmx_qhop_set_donor(qht
,xbuf
[exmlDONOR
]);
207 gmx_qhop_set_acceptor(qht
,xbuf
[exmlACCEPTOR
]);
211 if (NN(xbuf
[exmlNAME
]) && NN(xbuf
[exmlUNIT
]) && NN(xbuf
[exmlVALUE
])) {
212 gmx_qhop_add_param(qht
,xbuf
[exmlNAME
],xbuf
[exmlVALUE
],
219 for(i
=0; (i
<exmlNR
); i
++)
224 static void qhop_process_element(FILE *fp
,xmlNodePtr tree
,int parent
,
225 int indent
,t_xmlrec
*xml
)
230 elem
= find_elem((char *)tree
->name
,exmlNR
,exml_names
);
232 fprintf(fp
,"%sElement node name %s\n",sp(indent
,buf
,99),
234 if (elem
== exmlQHOP
) {
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
)
250 while (tree
!= NULL
) {
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
);
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
);
276 gmx_qhops_read(char *fn
,int *nqhop
)
281 const char *db
="qhops.dat";
284 xmlDoValidityCheckingDefaultValue
= 0;
287 fn
= (char *)gmxlibfn(db
);
290 if ((doc
= xmlParseFile(fn
)) == NULL
) {
291 fprintf(stderr
,"Reading XML file %s. Run a syntax checker such as nsgmls.",
297 qhop_process_tree(NULL
,doc
->children
,0,0,xml
);
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
);
328 void gmx_qhops_write(char *fn
,int nqhop
,gmx_qhop_t qht
[])
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","");
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
);
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");
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");