Update copyright statements and change license to LGPL
[alexxy/gromacs.git] / src / gmxlib / gmxfio_asc.c
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5  * Copyright (c) 2001-2004, The GROMACS development team,
6  * check out http://www.gromacs.org for more information.
7  * Copyright (c) 2012, by the GROMACS development team, led by
8  * David van der Spoel, Berk Hess, Erik Lindahl, and including many
9  * others, as listed in the AUTHORS file in the top-level source
10  * directory and at http://www.gromacs.org.
11  *
12  * GROMACS is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public License
14  * as published by the Free Software Foundation; either version 2.1
15  * of the License, or (at your option) any later version.
16  *
17  * GROMACS is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Lesser General Public License for more details.
21  *
22  * You should have received a copy of the GNU Lesser General Public
23  * License along with GROMACS; if not, see
24  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
26  *
27  * If you want to redistribute modifications to GROMACS, please
28  * consider that scientific software is very special. Version
29  * control is crucial - bugs must be traceable. We will be happy to
30  * consider code for inclusion in the official distribution, but
31  * derived work must not be called official GROMACS. Details are found
32  * in the README & COPYING files - if they are missing, get the
33  * official version at http://www.gromacs.org.
34  *
35  * To help us fund GROMACS development, we humbly ask that you cite
36  * the research papers on the package. Check out http://www.gromacs.org.
37  */
38
39
40 #ifdef HAVE_CONFIG_H
41 #include <config.h>
42 #endif
43
44 #include <ctype.h>
45 #include <stdio.h>
46 #include <errno.h>
47 #ifdef HAVE_IO_H
48 #include <io.h>
49 #endif
50
51 #include "gmx_fatal.h"
52 #include "macros.h"
53 #include "smalloc.h"
54 #include "futil.h"
55 #include "filenm.h"
56 #include "string2.h"
57 #include "gmxfio.h"
58 #include "md5.h"
59
60 #ifdef GMX_THREAD_MPI
61 #include "thread_mpi.h"
62 #endif
63
64 #include "gmxfio_int.h"
65
66
67 /* This is the part that reads dummy and ascii files.  */
68
69
70
71
72 /* file type functions */
73 static gmx_bool do_ascread(t_fileio *fio, void *item, int nitem, int eio, 
74                        const char *desc, const char *srcfile, int line);
75 static gmx_bool do_ascwrite(t_fileio *fio, const void *item, int nitem, int eio, 
76                         const char *desc, const char *srcfile, int line);
77 static gmx_bool do_dummyread(t_fileio *fio, void *item, int nitem, int eio,
78                          const char *desc, const char *srcfile, int line);
79 static gmx_bool do_dummywrite(t_fileio *fio, const void *item, int nitem, int eio,
80                           const char *desc, const char *srcfile, int line);
81
82
83 const t_iotype asc_iotype={do_ascread, do_ascwrite};
84 const t_iotype dummy_iotype={do_dummyread, do_dummywrite};
85
86
87
88
89
90
91 static gmx_bool do_dummyread(t_fileio *fio, void *item, int nitem, int eio,
92                          const char *desc, const char *srcfile, int line)
93 {
94     gmx_fatal(FARGS, "File type not set!");
95     return FALSE;
96 }
97
98 static gmx_bool do_dummywrite(t_fileio *fio, const void *item, int nitem, int eio,
99                           const char *desc, const char *srcfile, int line)
100 {
101     gmx_fatal(FARGS, "File type not set!");
102     return FALSE;
103 }
104
105
106
107 static void encode_string(int maxlen, char dst[], const char src[])
108 {
109     int i;
110
111     for (i = 0; (src[i] != '\0') && (i < maxlen - 1); i++)
112         if ((src[i] == ' ') || (src[i] == '\t'))
113             dst[i] = '_';
114         else
115             dst[i] = src[i];
116     dst[i] = '\0';
117
118     if (i == maxlen)
119         fprintf(stderr, "String '%s' truncated to '%s'\n", src, dst);
120 }
121
122 static void decode_string(int maxlen, char dst[], const char src[])
123 {
124     int i;
125
126     for (i = 0; (src[i] != '\0') && (i < maxlen - 1); i++)
127     {
128         if (src[i] == '_')
129         {
130             dst[i] = ' ';
131         }
132         else
133         {
134             dst[i] = src[i];
135         }
136     }
137     dst[i] = '\0';
138
139     if (i == maxlen)
140     {
141         fprintf(stderr, "String '%s' truncated to '%s'\n", src, dst);
142     }
143 }
144
145 static gmx_bool do_ascwrite(t_fileio *fio, const void *item, int nitem, int eio, 
146                         const char *desc, const char *srcfile, int line)
147 {
148     int i;
149     int res = 0, *iptr;
150     real *ptr;
151     char strbuf[256];
152     char buf[GMX_FIO_BUFLEN];
153     unsigned char *ucptr;
154     FILE *fp=fio->fp;
155
156     gmx_fio_check_nitem(fio, eio, nitem, srcfile, line);
157     switch (eio)
158     {
159     case eioREAL:
160     case eioFLOAT:
161     case eioDOUBLE:
162         res = fprintf(fp, "%18.10e%s\n", *((real *) item), 
163                       gmx_fio_dbgstr(fio, desc, buf));
164         break;
165     case eioINT:
166         res = fprintf(fp, "%18d%s\n", *((int *) item), gmx_fio_dbgstr(fio, 
167                                                                       desc, 
168                                                                       buf));
169         break;
170     case eioGMX_LARGE_INT:
171         sprintf(strbuf, "%s%s%s", "%", gmx_large_int_fmt, "\n");
172         res = fprintf(fp, strbuf, *((gmx_large_int_t *) item),
173                       gmx_fio_dbgstr(fio, desc, buf));
174         break;
175     case eioUCHAR:
176         res = fprintf(fp, "%4d%s\n", *((unsigned char *) item),
177                       gmx_fio_dbgstr(fio, desc, buf));
178         break;
179     case eioNUCHAR:
180         ucptr = (unsigned char *) item;
181         for (i = 0; (i < nitem); i++)
182             res = fprintf(fp, "%4d", (int) ucptr[i]);
183         fprintf(fio->fp, "%s\n", gmx_fio_dbgstr(fio, desc, buf));
184         break;
185     case eioUSHORT:
186         res = fprintf(fp, "%18d%s\n", *((unsigned short *) item),
187                       gmx_fio_dbgstr(fio, desc, buf));
188         break;
189     case eioRVEC:
190         ptr = (real *) item;
191         res = fprintf(fp, "%18.10e%18.10e%18.10e%s\n", ptr[XX],
192                       ptr[YY], ptr[ZZ], gmx_fio_dbgstr(fio, desc, buf));
193         break;
194     case eioNRVEC:
195         for (i = 0; (i < nitem); i++)
196         {
197             ptr = ((rvec *) item)[i];
198             res = fprintf(fp, "%18.10e%18.10e%18.10e%s\n", ptr[XX],
199                           ptr[YY], ptr[ZZ], gmx_fio_dbgstr(fio, desc, buf));
200         }
201         break;
202     case eioIVEC:
203         iptr = (int *) item;
204         res = fprintf(fp, "%18d%18d%18d%s\n", iptr[XX], iptr[YY],
205                       iptr[ZZ], gmx_fio_dbgstr(fio, desc, buf));
206         break;
207     case eioSTRING:
208         encode_string(256, strbuf, (char *) item);
209         res = fprintf(fp, "%-18s%s\n", strbuf, gmx_fio_dbgstr(fio, desc, buf));
210         break;
211     default:
212         gmx_fio_fe(fio, eio, desc, srcfile, line);
213     }
214     if ((res <= 0) && fio->bDebug)
215         fprintf(stderr,
216                 "Error writing %s %s to file %s (source %s, line %d)\n",
217                 eioNames[eio], desc, fio->fn, srcfile, line);
218
219     return (res > 0);
220 }
221
222
223 static char *next_item(FILE *fp, char *buf, int buflen)
224 {
225     int rd;
226     gmx_bool in_comment = FALSE;
227     gmx_bool in_token = FALSE;
228     int i = 0;
229     /* This routine reads strings from the file fp, strips comment
230      * and buffers. For thread-safety reasons, It reads through getc()  */
231
232     rd = getc(fp);
233     if (rd == EOF)
234         gmx_file("End of file");
235     do
236     {
237         if (in_comment)
238         {
239             if (rd == '\n')
240                 in_comment = FALSE;
241         }
242         else if (in_token)
243         {
244             if (isspace(rd) || rd == ';')
245                 break;
246             buf[i++] = (char) rd;
247         }
248         else
249         {
250             if (!isspace(rd))
251             {
252                 if (rd == ';')
253                     in_comment = TRUE;
254                 else
255                 {
256                     in_token = TRUE;
257                     buf[i++] = (char) (rd);
258                 }
259             }
260         }
261         if (i >= buflen - 2)
262             break;
263     } while ((rd = getc(fp)) != EOF);
264
265     fprintf(stderr, "WARNING, ftpASC file type not tested!\n");
266
267     buf[i] = 0;
268
269     return buf;
270 }
271
272 static gmx_bool do_ascread(t_fileio *fio, void *item, int nitem, int eio, 
273                        const char *desc, const char *srcfile, int line)
274 {
275     FILE *fp = fio->fp;
276     int i, m, res = 0, *iptr, ix;
277     gmx_large_int_t s;
278     double d, x;
279     real *ptr;
280     unsigned char uc, *ucptr;
281     char *cptr;
282 #define NEXT_ITEM_BUF_LEN 128
283     char ni_buf[NEXT_ITEM_BUF_LEN];
284
285     gmx_fio_check_nitem(fio, eio, nitem, srcfile, line);
286     switch (eio)
287     {
288     case eioREAL:
289     case eioFLOAT:
290     case eioDOUBLE:
291         res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%lf", &d);
292         if (item)
293             *((real *) item) = d;
294         break;
295     case eioINT:
296         res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%d", &i);
297         if (item)
298             *((int *) item) = i;
299         break;
300     case eioGMX_LARGE_INT:
301         res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN),
302                      gmx_large_int_pfmt, &s);
303         if (item)
304             *((gmx_large_int_t *) item) = s;
305         break;
306     case eioUCHAR:
307         res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%c", &uc);
308         if (item)
309             *((unsigned char *) item) = uc;
310         break;
311     case eioNUCHAR:
312         ucptr = (unsigned char *) item;
313         for (i = 0; (i < nitem); i++)
314         {
315             res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%d", &ix);
316             if (item)
317                 ucptr[i] = ix;
318         }
319         break;
320     case eioUSHORT:
321         res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%d", &i);
322         if (item)
323             *((unsigned short *) item) = i;
324         break;
325     case eioRVEC:
326         ptr = (real *) item;
327         for (m = 0; (m < DIM); m++)
328         {
329             res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%lf\n", &x);
330             ptr[m] = x;
331         }
332         break;
333     case eioNRVEC:
334         for (i = 0; (i < nitem); i++)
335         {
336             ptr = ((rvec *) item)[i];
337             for (m = 0; (m < DIM); m++)
338             {
339                 res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%lf\n",
340                              &x);
341                 if (item)
342                     ptr[m] = x;
343             }
344         }
345         break;
346     case eioIVEC:
347         iptr = (int *) item;
348         for (m = 0; (m < DIM); m++)
349         {
350             res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%d\n", &ix);
351             if (item)
352                 iptr[m] = ix;
353         }
354         break;
355     case eioSTRING:
356         cptr = next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN);
357         if (item)
358         {
359             decode_string(strlen(cptr) + 1, (char *) item, cptr);
360             /* res = sscanf(cptr,"%s",(char *)item);*/
361             res = 1;
362         }
363         break;
364     default:
365         gmx_fio_fe(fio, eio, desc, srcfile, line);
366     }
367
368     if ((res <= 0) && fio->bDebug)
369         fprintf(stderr,
370                 "Error reading %s %s from file %s (source %s, line %d)\n",
371                 eioNames[eio], desc, fio->fn, srcfile, line);
372     return (res > 0);
373 }
374