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