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