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