Fix ICC warnings
[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,2014, 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 #include "gmxpre.h"
38
39 #include "config.h"
40
41 #include <ctype.h>
42 #include <errno.h>
43 #include <stdio.h>
44 #include <string.h>
45
46 #ifdef HAVE_IO_H
47 #include <io.h>
48 #endif
49
50 #include "gromacs/fileio/filenm.h"
51 #include "gromacs/fileio/gmxfio.h"
52 #include "gromacs/fileio/gmxfio_int.h"
53 #include "gromacs/fileio/md5.h"
54 #include "gromacs/legacyheaders/macros.h"
55 #include "gromacs/utility/cstringutil.h"
56 #include "gromacs/utility/fatalerror.h"
57 #include "gromacs/utility/futil.h"
58 #include "gromacs/utility/smalloc.h"
59
60
61 /* This is the part that reads dummy and ascii files.  */
62
63
64
65
66 /* file type functions */
67 static gmx_bool do_ascread(t_fileio *fio, void *item, int nitem, int eio,
68                            const char *desc, const char *srcfile, int line);
69 static gmx_bool do_ascwrite(t_fileio *fio, const void *item, int nitem, int eio,
70                             const char *desc, const char *srcfile, int line);
71 static gmx_bool do_dummyread(t_fileio *fio, void *item, int nitem, int eio,
72                              const char *desc, const char *srcfile, int line);
73 static gmx_bool do_dummywrite(t_fileio *fio, const void *item, int nitem, int eio,
74                               const char *desc, const char *srcfile, int line);
75
76
77 const t_iotype asc_iotype = {do_ascread, do_ascwrite};
78 const t_iotype dummy_iotype = {do_dummyread, do_dummywrite};
79
80
81
82
83
84
85 static gmx_bool do_dummyread(t_fileio gmx_unused *fio, void gmx_unused *item, int gmx_unused nitem, int gmx_unused eio,
86                              const char gmx_unused *desc, const char gmx_unused *srcfile, int gmx_unused line)
87 {
88     gmx_fatal(FARGS, "File type not set!");
89     return FALSE;
90 }
91
92 static gmx_bool do_dummywrite(t_fileio gmx_unused *fio, const void gmx_unused *item, int gmx_unused nitem, int gmx_unused eio,
93                               const char gmx_unused *desc, const char gmx_unused *srcfile, int gmx_unused line)
94 {
95     gmx_fatal(FARGS, "File type not set!");
96     return FALSE;
97 }
98
99
100
101 static void encode_string(int maxlen, char dst[], const char src[])
102 {
103     int i;
104
105     for (i = 0; (i < maxlen - 1) && (src[i] != '\0'); i++)
106     {
107         if ((src[i] == ' ') || (src[i] == '\t'))
108         {
109             dst[i] = '_';
110         }
111         else
112         {
113             dst[i] = src[i];
114         }
115     }
116     dst[i] = '\0';
117
118     if (i == maxlen)
119     {
120         fprintf(stderr, "String '%s' truncated to '%s'\n", src, dst);
121     }
122 }
123
124 static void decode_string(int maxlen, char dst[], const char src[])
125 {
126     int i;
127
128     for (i = 0; (i < maxlen - 1) && (src[i] != '\0'); i++)
129     {
130         if (src[i] == '_')
131         {
132             dst[i] = ' ';
133         }
134         else
135         {
136             dst[i] = src[i];
137         }
138     }
139     dst[i] = '\0';
140
141     if (i == maxlen)
142     {
143         fprintf(stderr, "String '%s' truncated to '%s'\n", src, dst);
144     }
145 }
146
147 static gmx_bool do_ascwrite(t_fileio *fio, const void *item, int nitem, int eio,
148                             const char *desc, const char *srcfile, int line)
149 {
150     int            i;
151     int            res = 0, *iptr;
152     real          *ptr;
153     char           strbuf[256];
154     char           buf[GMX_FIO_BUFLEN];
155     unsigned char *ucptr;
156     FILE          *fp = fio->fp;
157
158     gmx_fio_check_nitem(eio, nitem, srcfile, line);
159     switch (eio)
160     {
161         case eioREAL:
162         case eioFLOAT:
163         case eioDOUBLE:
164             res = fprintf(fp, "%18.10e%s\n", *((real *) item),
165                           gmx_fio_dbgstr(fio, desc, buf));
166             break;
167         case eioINT:
168             res = fprintf(fp, "%18d%s\n", *((int *) item), gmx_fio_dbgstr(fio,
169                                                                           desc,
170                                                                           buf));
171             break;
172         case eioINT64:
173             sprintf(strbuf, "%s%s%s", "%", GMX_PRId64, "\n");
174             res = fprintf(fp, strbuf, *((gmx_int64_t *) item),
175                           gmx_fio_dbgstr(fio, desc, buf));
176             break;
177         case eioUCHAR:
178             res = fprintf(fp, "%4d%s\n", *((unsigned char *) item),
179                           gmx_fio_dbgstr(fio, desc, buf));
180             break;
181         case eioNUCHAR:
182             ucptr = (unsigned char *) item;
183             for (i = 0; (i < nitem); i++)
184             {
185                 res = fprintf(fp, "%4d", (int) ucptr[i]);
186             }
187             fprintf(fio->fp, "%s\n", gmx_fio_dbgstr(fio, desc, buf));
188             break;
189         case eioUSHORT:
190             res = fprintf(fp, "%18d%s\n", *((unsigned short *) item),
191                           gmx_fio_dbgstr(fio, desc, buf));
192             break;
193         case eioRVEC:
194             ptr = (real *) item;
195             res = fprintf(fp, "%18.10e%18.10e%18.10e%s\n", ptr[XX],
196                           ptr[YY], ptr[ZZ], gmx_fio_dbgstr(fio, desc, buf));
197             break;
198         case eioNRVEC:
199             for (i = 0; (i < nitem); i++)
200             {
201                 ptr = ((rvec *) item)[i];
202                 res = fprintf(fp, "%18.10e%18.10e%18.10e%s\n", ptr[XX],
203                               ptr[YY], ptr[ZZ], gmx_fio_dbgstr(fio, desc, buf));
204             }
205             break;
206         case eioIVEC:
207             iptr = (int *) item;
208             res  = fprintf(fp, "%18d%18d%18d%s\n", iptr[XX], iptr[YY],
209                            iptr[ZZ], gmx_fio_dbgstr(fio, desc, buf));
210             break;
211         case eioSTRING:
212             encode_string(256, strbuf, (char *) item);
213             res = fprintf(fp, "%-18s%s\n", strbuf, gmx_fio_dbgstr(fio, desc, buf));
214             break;
215         default:
216             gmx_fio_fe(fio, eio, desc, srcfile, line);
217     }
218     if ((res <= 0) && fio->bDebug)
219     {
220         fprintf(stderr,
221                 "Error writing %s %s to file %s (source %s, line %d)\n",
222                 eioNames[eio], desc, fio->fn, srcfile, line);
223     }
224
225     return (res > 0);
226 }
227
228
229 static char *next_item(FILE *fp, char *buf, int buflen)
230 {
231     int      rd;
232     gmx_bool in_comment = FALSE;
233     gmx_bool in_token   = FALSE;
234     int      i          = 0;
235     /* This routine reads strings from the file fp, strips comment
236      * and buffers. For thread-safety reasons, It reads through getc()  */
237
238     rd = getc(fp);
239     if (rd == EOF)
240     {
241         gmx_file("End of file");
242     }
243     do
244     {
245         if (in_comment)
246         {
247             if (rd == '\n')
248             {
249                 in_comment = FALSE;
250             }
251         }
252         else if (in_token)
253         {
254             if (isspace(rd) || rd == ';')
255             {
256                 break;
257             }
258             buf[i++] = (char) rd;
259         }
260         else
261         {
262             if (!isspace(rd))
263             {
264                 if (rd == ';')
265                 {
266                     in_comment = TRUE;
267                 }
268                 else
269                 {
270                     in_token = TRUE;
271                     buf[i++] = (char) (rd);
272                 }
273             }
274         }
275         if (i >= buflen - 2)
276         {
277             break;
278         }
279     }
280     while ((rd = getc(fp)) != EOF);
281
282     fprintf(stderr, "WARNING, ftpASC file type not tested!\n");
283
284     buf[i] = 0;
285
286     return buf;
287 }
288
289 static gmx_bool do_ascread(t_fileio *fio, void *item, int nitem, int eio,
290                            const char *desc, const char *srcfile, int line)
291 {
292     FILE           *fp = fio->fp;
293     int             i, m, res = 0, *iptr, ix;
294     gmx_int64_t     s;
295     double          d, x;
296     char            c;
297     real           *ptr;
298     unsigned char  *ucptr;
299     char           *cptr;
300 #define NEXT_ITEM_BUF_LEN 128
301     char            ni_buf[NEXT_ITEM_BUF_LEN];
302
303     gmx_fio_check_nitem(eio, nitem, srcfile, line);
304     switch (eio)
305     {
306         case eioREAL:
307         case eioFLOAT:
308         case eioDOUBLE:
309             res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%lf", &d);
310             if (item)
311             {
312                 *((real *) item) = d;
313             }
314             break;
315         case eioINT:
316             res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%d", &i);
317             if (item)
318             {
319                 *((int *) item) = i;
320             }
321             break;
322         case eioINT64:
323             res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN),
324                          "%"GMX_SCNd64, &s);
325             if (item)
326             {
327                 *((gmx_int64_t *) item) = s;
328             }
329             break;
330         case eioUCHAR:
331             res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%c", &c);
332             if (item)
333             {
334                 *((unsigned char *) item) = (unsigned char)c;
335             }
336             break;
337         case eioNUCHAR:
338             ucptr = (unsigned char *) item;
339             for (i = 0; (i < nitem); i++)
340             {
341                 res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%d", &ix);
342                 if (item)
343                 {
344                     ucptr[i] = ix;
345                 }
346             }
347             break;
348         case eioUSHORT:
349             res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%d", &i);
350             if (item)
351             {
352                 *((unsigned short *) item) = i;
353             }
354             break;
355         case eioRVEC:
356             ptr = (real *) item;
357             for (m = 0; (m < DIM); m++)
358             {
359                 res    = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%lf\n", &x);
360                 ptr[m] = x;
361             }
362             break;
363         case eioNRVEC:
364             for (i = 0; (i < nitem); i++)
365             {
366                 ptr = ((rvec *) item)[i];
367                 for (m = 0; (m < DIM); m++)
368                 {
369                     res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%lf\n",
370                                  &x);
371                     if (item)
372                     {
373                         ptr[m] = x;
374                     }
375                 }
376             }
377             break;
378         case eioIVEC:
379             iptr = (int *) item;
380             for (m = 0; (m < DIM); m++)
381             {
382                 res = sscanf(next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN), "%d\n", &ix);
383                 if (item)
384                 {
385                     iptr[m] = ix;
386                 }
387             }
388             break;
389         case eioSTRING:
390             cptr = next_item(fp, ni_buf, NEXT_ITEM_BUF_LEN);
391             if (item)
392             {
393                 decode_string(strlen(cptr) + 1, (char *) item, cptr);
394                 /* res = sscanf(cptr,"%s",(char *)item);*/
395                 res = 1;
396             }
397             break;
398         default:
399             gmx_fio_fe(fio, eio, desc, srcfile, line);
400     }
401
402     if ((res <= 0) && fio->bDebug)
403     {
404         fprintf(stderr,
405                 "Error reading %s %s from file %s (source %s, line %d)\n",
406                 eioNames[eio], desc, fio->fn, srcfile, line);
407     }
408     return (res > 0);
409 }