1 /*****************************************************************************
2  *
3  *  Elmer, A Finite Element Software for Multiphysical Problems
4  *
5  *  Copyright 1st April 1995 - , CSC - IT Center for Science Ltd., Finland
6  *
7  *  This program is free software; you can redistribute it and/or
8  *  modify it under the terms of the GNU General Public License
9  *  as published by the Free Software Foundation; either version 2
10  *  of the License, or (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program (in file fem/GPL-2); if not, write to the
19  *  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  *  Boston, MA 02110-1301, USA.
21  *
22  *****************************************************************************/
23 
24 /*******************************************************************************
25  *
26  *     IO handling for MATC.
27  *
28  *******************************************************************************
29  *
30  *                     Author:       Juha Ruokolainen
31  *
32  *                    Address: CSC - IT Center for Science Ltd.
33  *                                Keilaranta 14, P.O. BOX 405
34  *                                  02101 Espoo, Finland
35  *                                  Tel. +358 0 457 2723
36  *                                Telefax: +358 0 457 2302
37  *                              EMail: Juha.Ruokolainen@csc.fi
38  *
39  *                       Date: 30 May 1996
40  *
41  *                Modified by:
42  *
43  *       Date of modification:
44  *
45  ******************************************************************************/
46 
47 /*
48  * $Id: files.c,v 1.1.1.1 2005/04/14 13:29:14 vierinen Exp $
49  *
50  * $Log: files.c,v $
51  * Revision 1.1.1.1  2005/04/14 13:29:14  vierinen
52  * initial matc automake package
53  *
54  * Revision 1.2  1998/08/01 12:34:36  jpr
55  *
56  * Added Id, started Log.
57  *
58  *
59  */
60 
61 #include "elmer/matc.h"
62 #include "str.h"
63 
64 /***********************************************************************
65 |
66 |  FILES.C - Last Edited 10. 8. 1988
67 |
68 ***********************************************************************/
69 
70 /*======================================================================
71 |Syntax of the manual pages:
72 |
73 |FUNCTION NAME(...) params ...
74 |
75 $  usage of the function and type of the parameters
76 ?  explane the effects of the function
77 =  return value and the type of value if not of type int
78 @  globals effected directly by this routine
79 !  current known bugs or limitations
80 &  functions called by this function
81 ~  these functions may interest you as an alternative function or
82 |  because they control this function somehow
83 ^=====================================================================*/
84 
85 #define FILE_BINARY 0
86 #define FILE_ASCII 1
87 
88 #define MAXFILES 32
89 static FILE *fil_fps[MAXFILES];
90 static FILE *fil_fps_save[3];
91 
fil_fread(var)92 VARIABLE *fil_fread(var) VARIABLE *var;
93 {
94   VARIABLE *res;
95   FILE *fp;
96 
97   int i, ind, len;
98 
99   ind = *MATR(var);
100   if (ind < 0 || ind >= MAXFILES)
101   {
102     error("fread: Invalid file number.\n");
103   }
104   else if (fil_fps[ind] == NULL)
105   {
106     error("fread: File not open.\n");
107   }
108   fp = fil_fps[ind];
109 
110   if (feof(fp))
111   {
112     clearerr(fp);
113     error("fread: end of file detected.\n");
114   }
115 
116   len = *MATR(NEXT(var));
117   if (len <= 0)
118   {
119     error("fread: invalid length specified.\n");
120   }
121   res = var_temp_new(TYPE_DOUBLE, 1, (len+sizeof(double)-1)>>3);
122   fread(MATR(res), 1, len, fp);
123 
124   if (feof(fp))
125   {
126     clearerr(fp);
127     error("fread: end of file detected.\n");
128   }
129 
130   if (ferror(fp))
131   {
132     clearerr(fp);
133     error("fread: error reading file.\n");
134   }
135 
136   return res;
137 }
138 
fil_fwrite(var)139 VARIABLE *fil_fwrite(var) VARIABLE *var;
140 {
141   int i, ind, len;
142   FILE *fp;
143 
144   ind = *MATR(var);
145   if (ind < 0 || ind >= MAXFILES)
146   {
147     error("fwrite: Invalid file number.\n");
148   }
149   else if (fil_fps[ind] == NULL)
150   {
151     error("fwrite: File not open.\n");
152   }
153   fp = fil_fps[ind];
154 
155   if (NEXT(NEXT(var)) != NULL)
156   {
157     len = *MATR(NEXT(NEXT(var)));
158     if (len > MATSIZE(NEXT(var)))
159     {
160       error("fwrite: attempt to write more data than provided.\n");
161     }
162   }
163   else
164   {
165     len = MATSIZE(NEXT(var));
166   }
167   fwrite(MATR(NEXT(var)), 1, len, fp);
168 
169   if (ferror(fp))
170   {
171     clearerr(fp);
172     error("fwrite: error writing file.\n");
173   }
174 
175   return (VARIABLE *)NULL;
176 }
177 
fil_fscanf(var)178 VARIABLE *fil_fscanf(var) VARIABLE *var;
179 {
180   VARIABLE *res;
181   FILE *fp;
182 
183   char *fmt = var_to_string(NEXT(var));
184   int i, ind, got;
185 
186   ind = *MATR(var);
187   if (ind < 0 || ind >= MAXFILES)
188   {
189     error("fscanf: Invalid file number.\n");
190   }
191   else if (fil_fps[ind] == NULL)
192   {
193     error("fscanf: File not open.\n");
194   }
195   fp = fil_fps[ind];
196 
197   if (feof(fp))
198   {
199     clearerr(fp);
200     error("fscanf: end of file detected.\n");
201   }
202 
203   got = fscanf(fp, fmt,
204       &str_p[0],  &str_p[1],  &str_p[2],  &str_p[3],  &str_p[4],  &str_p[5],
205       &str_p[6],  &str_p[7],  &str_p[8],  &str_p[9],  &str_p[10], &str_p[11],
206       &str_p[12], &str_p[13], &str_p[14], &str_p[15], &str_p[16], &str_p[17],
207       &str_p[18], &str_p[19], &str_p[20], &str_p[21], &str_p[22], &str_p[23],
208       &str_p[24], &str_p[25], &str_p[26], &str_p[27], &str_p[28], &str_p[29]);
209 
210   res = NULL;
211   if (got > 0) {
212     res = var_temp_new(TYPE_DOUBLE,1,got);
213     for(i = 0; i < got; i++)
214     {
215       M(res,0,i) = str_p[i];
216     }
217   }
218   FREEMEM(fmt);
219 
220   if (feof(fp))
221   {
222     clearerr(fp);
223     error("fscanf: end of file detected.\n");
224   }
225 
226   if (ferror(fp))
227   {
228     clearerr(fp);
229     error("fscanf: error reading file.\n");
230   }
231 
232   return res;
233 }
234 
fil_fgets(var)235 VARIABLE *fil_fgets(var) VARIABLE *var;
236 {
237   VARIABLE *res;
238   FILE *fp;
239 
240   int i, ind;
241 
242   ind = *MATR(var);
243   if (ind < 0 || ind >= MAXFILES)
244   {
245     error("fgets: Invalid file number.\n");
246   }
247   else if (fil_fps[ind] == NULL)
248   {
249     error("fgets: File not open.\n");
250   }
251   fp = fil_fps[ind];
252 
253   if (feof(fp))
254   {
255     clearerr(fp);
256     error("fgets: end of file detected.\n");
257   }
258 
259   fgets(str_pstr, STR_MAXLEN, fp);
260 
261   if (feof(fp))
262   {
263     clearerr(fp);
264     error("fgets: end of file detected.\n");
265   }
266 
267   if (ferror(fp))
268   {
269     clearerr(fp);
270     error("fgets: error reading file.\n");
271   }
272 
273   res = var_temp_new(TYPE_STRING, 1, strlen(str_pstr)-1);
274   for(i = 0; i < strlen(str_pstr)-1; i++)
275     M(res,0,i) = str_pstr[i];
276 
277   return res;
278 }
279 
fil_fprintf(var)280 VARIABLE *fil_fprintf(var) VARIABLE *var;
281 {
282   int i, ind;
283   char *str;
284   FILE *fp;
285 
286   ind = *MATR(var);
287   if (ind < 0 || ind >= MAXFILES)
288   {
289     error("fprintf: Invalid file number.\n");
290   }
291   else if (fil_fps[ind] == NULL)
292   {
293     error("fprintf: File not open.\n");
294   }
295   fp = fil_fps[ind];
296 
297   var = str_sprintf(NEXT(var));
298   str = var_to_string(var);
299   fprintf(fp, "%s",str);
300 
301   var_delete_temp(var);
302   FREEMEM(str);
303 
304   if (ferror(fp))
305   {
306     clearerr(fp);
307     error("fprintf: error writing file.\n");
308   }
309 
310   return (VARIABLE *)NULL;
311 }
312 
fil_fputs(var)313 VARIABLE *fil_fputs(var) VARIABLE *var;
314 {
315   char *str = var_to_string(NEXT(var));
316   int ind = *MATR(var);
317   FILE *fp;
318 
319   if (ind < 0 || ind >= MAXFILES)
320   {
321     error("fputs: Invalid file number.\n");
322   }
323   else if (fil_fps[ind] == NULL)
324   {
325     error("fputs: File not open.\n");
326   }
327   fp = fil_fps[ind];
328 
329   fprintf(fp, "%s", str);
330 
331   FREEMEM(str);
332 
333   if (ferror(fp))
334   {
335     clearerr(fp);
336     error("fprintf: error writing file.\n");
337   }
338 
339   return (VARIABLE *)NULL;
340 }
341 
fil_fopen(var)342 VARIABLE *fil_fopen(var) VARIABLE *var;
343 {
344   VARIABLE *res;
345 
346   char *name, *mode;
347   int file;
348 
349   mode = var_to_string(NEXT(var));
350   name = var_to_string(var);
351 
352   for(file = 0; file < MAXFILES; file++)
353   {
354     if (fil_fps[file] == NULL) break;
355   }
356 
357   if (file >= MAXFILES)
358   {
359     error("fopen: maximum number of files already open.\n");
360   }
361 
362   if ((fil_fps[file] = fopen(name, mode)) == (FILE *)NULL)
363   {
364     error("fopen: can't open file: %s.\n", name);
365   }
366 
367   switch(file)
368   {
369     case 0:
370       fil_fps_save[0] = math_in;
371       math_in = fil_fps[0];
372     break;
373 
374     case 1:
375       fil_fps_save[1] = math_out;
376       math_out = fil_fps[1];
377     break;
378 
379     case 2:
380       fil_fps_save[2] = math_err;
381       math_err = fil_fps[2];
382     break;
383   }
384 
385   res = var_temp_new(TYPE_DOUBLE, 1, 1);
386   M(res,0,0) = file;
387 
388   FREEMEM(name);
389   FREEMEM(mode);
390 
391   return res;
392 }
393 
fil_fclose(var)394 VARIABLE *fil_fclose(var) VARIABLE *var;
395 {
396   int file = *MATR(var);
397 
398   if (file < 0 || file >= MAXFILES)
399   {
400     error("fclose: Invalid file number.\n");
401   }
402 
403   switch(file)
404   {
405     case 0:
406       math_in = fil_fps_save[0];
407       if (
408            fil_fps[0] != math_out && fil_fps[0] != NULL
409          ) fclose(fil_fps[0]);
410       fil_fps[0] = math_in;
411     break;
412 
413     case 1:
414       math_out = fil_fps_save[1];
415       if (
416            fil_fps[1] != math_out && fil_fps[1] != NULL
417          ) fclose(fil_fps[1]);
418       fil_fps[1] = math_out;
419     break;
420 
421     case 2:
422       math_err = fil_fps_save[2];
423       if (
424            fil_fps[2] != math_err && fil_fps[2] != NULL
425          ) fclose(fil_fps[2]);
426       fil_fps[2] = math_err;
427     break;
428 
429     default:
430       if (fil_fps[file] != NULL)
431         fclose(fil_fps[file]);
432       fil_fps[file] = NULL;
433     break;
434   }
435 
436   return (VARIABLE *)NULL;
437 }
438 
fil_freopen(var)439 VARIABLE *fil_freopen(var) VARIABLE *var;
440 {
441   int file = *MATR(var);
442 
443   fil_fclose(var);
444   fil_fps[file] = NULL;
445   var = fil_fopen(NEXT(var));
446   var_delete_temp(var);
447 
448   return (VARIABLE *)NULL;
449 }
450 
fil_save(ptr)451 VARIABLE *fil_save(ptr) VARIABLE *ptr;
452 {
453   VARIABLE *tmp;
454   char *file;
455   FILE *fp;
456 
457   int i, j, ascflg = FALSE;
458 
459   file = var_to_string(ptr);
460 
461   if ((fp = fopen(file, "w")) == (FILE *)NULL)
462   {
463     error( "save: can't open file: %s.\n", file );
464   }
465 
466   tmp = NEXT(ptr);
467 
468   if (NEXT(NEXT(ptr)) != (VARIABLE *)NULL)
469     ascflg = M(NEXT(NEXT(ptr)), 0, 0);
470 
471   if (ascflg)
472   {
473 
474     fprintf(fp, "%d %d %d %d\n", FILE_ASCII, TYPE(tmp), NROW(tmp), NCOL(tmp));
475     if (ferror(fp))
476     {
477        fclose(fp); error("save: error writing file.\n");
478     }
479 
480     for(i = 0; i < NROW(tmp); i++)
481       for(j = 0; j < NCOL(tmp); j++)
482       {
483         fprintf(fp, "%e\n", M(tmp, i, j));
484         if (ferror(fp))
485         {
486            fclose(fp); error("save: error writing file.\n");
487         }
488       }
489   }
490 
491   else
492   {
493 
494     fprintf(fp, "%d %d %d %d\n", FILE_BINARY, TYPE(tmp), NROW(tmp), NCOL(tmp));
495     if (ferror(fp))
496     {
497        fclose(fp); error("save: error writing file.\n");
498     }
499 
500     fwrite(MATR(tmp), 1, MATSIZE(tmp), fp);
501     if (ferror(fp))
502     {
503        fclose(fp); error("save: error writing file.\n");
504     }
505   }
506 
507   fclose(fp); FREEMEM(file);
508 
509   return NULL;
510 }
511 
fil_load(ptr)512 VARIABLE *fil_load(ptr) VARIABLE *ptr;
513 {
514   int i, j, ftype, type, ncol, nrow;
515 
516   VARIABLE *res;
517 
518   char *file;
519   FILE *fp;
520 
521   file = var_to_string(ptr);
522 
523   if ((fp = fopen(file, "r")) == (FILE *)NULL)
524   {
525     error( "load: can't open file: %s.\n", file );
526   }
527 
528   fscanf(fp, "%d %d %d %d", &ftype, &type, &nrow, &ncol);
529 
530   if (ferror(fp)) {
531     fclose(fp); error("load: error reading file.n");
532   }
533 
534   res = var_temp_new(type, nrow, ncol);
535 
536   if (ftype == FILE_ASCII)
537   {
538     for(i = 0; i < nrow; i++)
539       for(j = 0; j < ncol; j++)
540       {
541         fscanf(fp, "%lf", &M(res, i, j));
542         if (ferror(fp))
543         {
544            fclose(fp); error("load: error reading file.\n");
545          }
546       }
547   }
548   else
549   {
550     fgetc(fp);
551     fread(MATR(res), 1, MATSIZE(res), fp);
552     if (ferror(fp))
553     {
554         fclose(fp); error("load: error reading file.\n");
555      }
556   }
557 
558   fclose(fp); FREEMEM(file);
559 
560   return res;
561 }
562 
fil_com_init()563 void fil_com_init()
564 {
565   static char *freadHelp =
566   {
567       "str = fread( fp,len )\n\n"
568       "Read len character from file fp.  File pointer fp should have been\n"
569       "obtained from a call to fopen or freopen, or be the standard input\n"
570       "file stdin. Characters are returned as function value.\n"
571       "\n"
572       "SEE ALSO: fopen,freopen,fgets,fscanf,matcvt,cvtmat.\n"
573   };
574 
575   static char *fscanfHelp =
576   {
577       "vec = fscanf( fp,format )\n\n"
578       "Read file fp as given in format. Format is equal to C-language format\n"
579       "File pointer fp should have been obtained from a call to fopen or freopen,\n"
580       "or be the standard input.\n"
581       "\n"
582       "SEE ALSO: fopen,freopen,fgets,fread,matcvt,cvtmat.\n"
583   };
584 
585   static char *fgetsHelp =
586   {
587       "str = fgets( fp )\n\n"
588       "Read next line from fp. File pointer fp should have been obtained from a call\n"
589       "to fopen or freopen or be the standard input.\n"
590       "\n"
591       "SEE ALSO: fopen,freopen,fread,fscanf,matcvt,cvtmat.\n"
592   };
593 
594   static char *fwriteHelp =
595   {
596       "n = fwrite( fp, buf,len )\n\n"
597       "Write len bytes form buf to file fp. File pointer fp should have been obtained\n"
598       "from a call to fopen or freopen or be the standard output (stdout) or standard\n"
599       "error (stderr). Return value is number of characters actually written.\n"
600       "\n"
601       "SEE ALSO: fopen,freopen,fputs,fprintf,matcvt,cvtmat.\n"
602   };
603 
604   static char *fprintfHelp =
605   {
606       "n = fprintf( fp, format[, vec] )\n\n"
607       "Write formatted string to file fp. File pointer fp should have been obtained\n"
608       "from a call to fopen or freopen or be the standard output (stdout) or standard\n"
609       "error (stderr). The format is equal to C-language format.\n"
610       "\n"
611       "SEE ALSO: fopen,freopen,fputs,fwrite,matcvt,cvtmat.\n"
612   };
613 
614   static char *fputsHelp =
615   {
616       "fputs( fp, str )\n\n"
617       "Write line to file fp. File pointer fp should have been obtained from a call\n"
618       "to fopen or freopen or be the standard input (stdin).\n"
619       "\n"
620       "SEE ALSO: fopen,freopen,fwrite,matcvt,cvtmat.\n"
621   };
622 
623   static char *fopenHelp =
624   {
625       "fp = fopen( name, mode )\n\n"
626       "Open file given name and access mode. The most usual modes are \"r\" for reading\n"
627       "and \"w\" for writing. Return value fp is used in functions reading and writing\n"
628       "the file.\n"
629       "\n"
630       "SEE ALSO: freopen.\n"
631   };
632 
633   static char *freopenHelp =
634   {
635       "fp = freopen( fp, name, mode )\n\n"
636       "Reopen file given previous file pointer, name and access mode. The most usual modes\n"
637       "are \"r\" for reading and \"w\" for writing. Return value fp is used in functions  \n"
638       "reading and writing the file.\n"
639       "\n"
640       "SEE ALSO: fopen.\n"
641   };
642 
643   static char *fcloseHelp =
644   {
645       "fclose( fp )\n\n"
646       "Close file previously opened with fopen or freopen.\n"
647       "\n"
648       "SEE ALSO: fopen, freopen.\n"
649   };
650 
651   static char *saveHelp =
652   {
653       "save( name, matrix[, ascii_flag] )\n\n"
654       "Save matrix in file with name given as first parameter. If ascii_flag is\n"
655       "given and is not zero the file will be in ascii format, otherwise matrix\n"
656       "is saved in double precsision binary format. In either case the first line\n"
657       "of the file contains four digits (in ascii):\n\n"
658       "ascii_flag 0 NROW(matrix) NCOL(matrix).\n"
659       "\n"
660       "SEE ALSO: load.\n"
661   };
662 
663   static char *loadHelp =
664   {
665       "matrix = load( name )\n\n"
666       "Load matrix from a file given name and in format used by save-command.\n"
667       "\n"
668       "SEE ALSO: save.\n"
669   };
670 
671   com_init( "fread",   FALSE, FALSE, fil_fread,   2, 2, freadHelp   );
672   com_init( "fscanf",  FALSE, FALSE, fil_fscanf,  2, 2, fscanfHelp  );
673   com_init( "fgets",   FALSE, FALSE, fil_fgets,   1, 1, fgetsHelp   );
674   com_init( "fwrite",  FALSE, FALSE, fil_fwrite,  2, 3, fwriteHelp  );
675   com_init( "fprintf", FALSE, FALSE, fil_fprintf, 2, 3, fprintfHelp );
676   com_init( "fputs",   FALSE, FALSE, fil_fputs,   2, 2, fputsHelp   );
677   com_init( "fopen",   FALSE, FALSE, fil_fopen,   2, 2, fopenHelp   );
678   com_init( "freopen", FALSE, FALSE, fil_freopen, 3, 3, freopenHelp );
679   com_init( "fclose",  FALSE, FALSE, fil_fclose,  1, 1, fcloseHelp  );
680   com_init( "save",    FALSE, FALSE, fil_save,    2, 3, saveHelp    );
681   com_init( "load",    FALSE, FALSE, fil_load,    1, 1, loadHelp    );
682 
683   fil_fps[0] = fil_fps_save[0] = stdin;
684   fil_fps[1] = fil_fps_save[1] = stdout;
685   fil_fps[2] = fil_fps_save[2] = stderr;
686 }
687