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