1 /*****************************************************************************
2 * Copyright (c) 2019 FrontISTR Commons
3 * This software is released under the MIT License, see LICENSE.txt
4 *****************************************************************************/
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <errno.h>
10 #include <ctype.h>
11 #include <dirent.h>
12 #include <sys/stat.h>
13 #include <sys/types.h>
14 #include "hecmw_util.h"
15 #include "hecmw_control.h"
16 #include "hecmw_ctrllex.h"
17 #include "hecmw_path.h"
18
19 static char ctrl_filename[HECMW_FILENAME_LEN + 1];
20
21 static int table_entire_mesh[] = {
22 HECMW_CTRL_FTYPE_HECMW_ENTIRE, HECMW_CTRL_FTYPE_GEOFEM,
23 HECMW_CTRL_FTYPE_ABAQUS, HECMW_CTRL_FTYPE_NASTRAN,
24 HECMW_CTRL_FTYPE_FEMAP,
25 };
26
27 struct mesh_entry {
28 char *name_ID;
29 int type;
30 int io;
31 int refine;
32 char *filename;
33 struct mesh_entry *next;
34 };
35
36 struct mesh_grp_entry {
37 char *name_ID;
38 int n_mesh;
39 struct mesh_entry **mesh;
40 struct mesh_grp_entry *next;
41 };
42
43 struct restart_entry {
44 char *name_ID;
45 int io;
46 /*#define HECMW_CTRL_FILE_IO_IN 1*/
47 /*#define HECMW_CTRL_FILE_IO_OUT 2*/
48 /* #define HECMW_CTRL_FILE_IO_INOUT 4 */
49 char *filename;
50 struct restart_entry *next;
51 };
52
53 struct result_entry {
54 char *name_ID;
55 int io;
56 /*#define HECMW_CTRL_FILE_IO_IN 1*/
57 /*#define HECMW_CTRL_FILE_IO_OUT 2*/
58 int fg_text; /* 1:text(default), 0:binary */
59 char *filename;
60 struct result_entry *next;
61 };
62
63 struct ctrl_entry {
64 char *name_ID;
65 char *filename;
66 struct ctrl_entry *next;
67 };
68
69 static int subdir_on = 0;
70
71 static int nlimit;
72
73 static struct ctrl_entry *ctrl_ent;
74
75 static struct mesh_entry *mesh_ent;
76
77 static struct mesh_grp_entry *mesh_grp_ent;
78
79 static struct restart_entry *restart_ent;
80
81 static struct result_entry *result_ent;
82
83 /*----------------------------------------------------------------------------*/
84
is_entire_mesh(int type)85 static int is_entire_mesh(int type) {
86 int i, n;
87 n = sizeof(table_entire_mesh) / sizeof(table_entire_mesh[0]);
88
89 for (i = 0; i < n; i++) {
90 if (table_entire_mesh[i] == type) return 1;
91 }
92
93 return 0;
94 }
95
96 /* return dir + subdir + prefix + file + suffix + .rank */
make_filename(char * dir,char * subdir,char * prefix,char * file,char * suffix,int myrank,int flag_rank)97 static char *make_filename(char *dir, char *subdir, char *prefix, char *file,
98 char *suffix, int myrank, int flag_rank) {
99 static char filename[HECMW_FILENAME_LEN + 1];
100 char rank[10];
101 char separator[10];
102 strcpy(filename, "");
103
104 if (dir && strlen(dir) > 0) {
105 sprintf(separator, "%c", HECMW_get_path_separator());
106
107 if ((strlen(dir) + strlen(separator)) > HECMW_FILENAME_LEN) return NULL;
108
109 sprintf(filename, "%s%s", dir, separator);
110 }
111
112 if (subdir && strlen(subdir) > 0) {
113 sprintf(separator, "%c", HECMW_get_path_separator());
114
115 if ((strlen(filename) + strlen(subdir) + strlen(separator)) >
116 HECMW_FILENAME_LEN)
117 return NULL;
118
119 strcat(filename, subdir);
120 strcat(filename, separator);
121 }
122
123 if (prefix && strlen(prefix) > 0) {
124 sprintf(separator, "%c", HECMW_get_path_separator());
125
126 if ((strlen(filename) + strlen(prefix) + strlen(separator)) >
127 HECMW_FILENAME_LEN)
128 return NULL;
129
130 strcat(filename, prefix);
131 strcat(filename, separator);
132 }
133
134 if ((strlen(filename) + strlen(file)) > HECMW_FILENAME_LEN) return NULL;
135
136 strcat(filename, file);
137
138 if (suffix) {
139 if ((strlen(filename) + strlen(suffix)) > HECMW_FILENAME_LEN) return NULL;
140
141 strcat(filename, suffix);
142 }
143
144 if (flag_rank) {
145 sprintf(rank, ".%d", myrank);
146
147 if ((strlen(filename) + strlen(rank)) > HECMW_FILENAME_LEN) return NULL;
148
149 strcat(filename, rank);
150 }
151
152 return filename;
153 }
154
155 /* return dir + subdir + prefix + file + suffix + .rank (thread-safe version) */
make_filename_r(char * dir,char * subdir,char * prefix,char * file,char * suffix,int myrank,int flag_rank,char * filename,int filename_len)156 static char *make_filename_r(char *dir, char *subdir, char *prefix, char *file,
157 char *suffix, int myrank, int flag_rank,
158 char *filename, int filename_len) {
159 char rank[10];
160 char separator[10];
161 strcpy(filename, "");
162
163 HECMW_assert( filename );
164
165 if (dir && strlen(dir) > 0) {
166 sprintf(separator, "%c", HECMW_get_path_separator());
167
168 if ((strlen(dir) + strlen(separator)) > filename_len) return NULL;
169
170 sprintf(filename, "%s%s", dir, separator);
171 }
172
173 if (subdir && strlen(subdir) > 0) {
174 sprintf(separator, "%c", HECMW_get_path_separator());
175
176 if ((strlen(filename) + strlen(subdir) + strlen(separator)) >
177 filename_len)
178 return NULL;
179
180 strcat(filename, subdir);
181 strcat(filename, separator);
182 }
183
184 if (prefix && strlen(prefix) > 0) {
185 sprintf(separator, "%c", HECMW_get_path_separator());
186
187 if ((strlen(filename) + strlen(prefix) + strlen(separator)) >
188 filename_len)
189 return NULL;
190
191 strcat(filename, prefix);
192 strcat(filename, separator);
193 }
194
195 if ((strlen(filename) + strlen(file)) > filename_len) return NULL;
196
197 strcat(filename, file);
198
199 if (suffix) {
200 if ((strlen(filename) + strlen(suffix)) > filename_len) return NULL;
201
202 strcat(filename, suffix);
203 }
204
205 if (flag_rank) {
206 sprintf(rank, ".%d", myrank);
207
208 if ((strlen(filename) + strlen(rank)) > filename_len) return NULL;
209
210 strcat(filename, rank);
211 }
212
213 return filename;
214 }
215
216 /*----------------------------------------------------------------------------*/
217
free_mesh_entry(void)218 static void free_mesh_entry(void) {
219 struct mesh_entry *p, *q;
220
221 for (p = mesh_ent; p; p = q) {
222 q = p->next;
223 HECMW_free(p->name_ID);
224 HECMW_free(p->filename);
225 HECMW_free(p);
226 }
227
228 mesh_ent = NULL;
229 }
230
free_mesh_grp_entry(void)231 static void free_mesh_grp_entry(void) {
232 struct mesh_grp_entry *p, *q;
233
234 for (p = mesh_grp_ent; p; p = q) {
235 q = p->next;
236 HECMW_free(p->name_ID);
237 HECMW_free(p->mesh); /* free only mesh array */
238 HECMW_free(p);
239 }
240
241 mesh_grp_ent = NULL;
242 }
243
free_restart_entry(void)244 static void free_restart_entry(void) {
245 struct restart_entry *p, *q;
246
247 for (p = restart_ent; p; p = q) {
248 q = p->next;
249 HECMW_free(p->name_ID);
250 HECMW_free(p->filename);
251 HECMW_free(p);
252 }
253
254 restart_ent = NULL;
255 }
256
free_result_entry(void)257 static void free_result_entry(void) {
258 struct result_entry *p, *q;
259
260 for (p = result_ent; p; p = q) {
261 q = p->next;
262 HECMW_free(p->name_ID);
263 HECMW_free(p->filename);
264 HECMW_free(p);
265 }
266
267 result_ent = NULL;
268 }
269
free_ctrl_entry(void)270 static void free_ctrl_entry(void) {
271 struct ctrl_entry *p, *q;
272
273 for (p = ctrl_ent; p; p = q) {
274 q = p->next;
275 HECMW_free(p->name_ID);
276 HECMW_free(p->filename);
277 HECMW_free(p);
278 }
279
280 ctrl_ent = NULL;
281 }
282
283 /*----------------------------------------------------------------------------*/
284
get_mesh_entry(char * name_ID)285 static struct mesh_entry *get_mesh_entry(char *name_ID) {
286 struct mesh_entry *p;
287
288 if (name_ID == NULL) return NULL;
289
290 for (p = mesh_ent; p; p = p->next) {
291 if (strcmp(p->name_ID, name_ID) == 0) return p;
292 }
293
294 return NULL;
295 }
296
get_mesh_grp_entry(char * name_ID)297 static struct mesh_grp_entry *get_mesh_grp_entry(char *name_ID) {
298 struct mesh_grp_entry *p;
299
300 if (name_ID == NULL) return NULL;
301
302 for (p = mesh_grp_ent; p; p = p->next) {
303 if (strcmp(p->name_ID, name_ID) == 0) return p;
304 }
305
306 return NULL;
307 }
308
get_restart_entry(char * name_ID)309 static struct restart_entry *get_restart_entry(char *name_ID) {
310 struct restart_entry *p;
311
312 if (name_ID == NULL) return NULL;
313
314 for (p = restart_ent; p; p = p->next) {
315 if (strcmp(p->name_ID, name_ID) == 0) return p;
316 }
317
318 return NULL;
319 }
320
get_restart_entry_by_io(int io)321 static struct restart_entry *get_restart_entry_by_io(int io) {
322 struct restart_entry *p;
323
324 for (p = restart_ent; p; p = p->next) {
325 if (p->io & io) return p; /* attention!! arg io is bitmap */
326 }
327
328 return NULL;
329 }
330
get_result_entry(char * name_ID)331 static struct result_entry *get_result_entry(char *name_ID) {
332 struct result_entry *p;
333
334 if (name_ID == NULL) return NULL;
335
336 for (p = result_ent; p; p = p->next) {
337 if (strcmp(p->name_ID, name_ID) == 0) return p;
338 }
339
340 return NULL;
341 }
342
get_ctrl_entry(char * name_ID)343 static struct ctrl_entry *get_ctrl_entry(char *name_ID) {
344 struct ctrl_entry *p;
345
346 if (name_ID == NULL) return NULL;
347
348 for (p = ctrl_ent; p; p = p->next) {
349 if (strcmp(p->name_ID, name_ID) == 0) return p;
350 }
351
352 return NULL;
353 }
354
355 /*----------------------------------------------------------------------------*/
356
make_mesh_entry(char * name_ID,int type,int io,int refine,char * filename)357 static struct mesh_entry *make_mesh_entry(char *name_ID, int type, int io,
358 int refine, char *filename) {
359 char *p;
360 struct mesh_entry *mesh = NULL;
361 mesh = HECMW_calloc(1, sizeof(*mesh));
362
363 if (mesh == NULL) {
364 HECMW_set_error(errno, "");
365 goto error;
366 }
367
368 mesh->type = type;
369 mesh->io = io;
370 mesh->refine = refine;
371 mesh->next = NULL;
372 p = HECMW_strdup(name_ID);
373
374 if (p == NULL) {
375 HECMW_set_error(errno, "");
376 goto error;
377 }
378
379 mesh->name_ID = p;
380 p = HECMW_strdup(filename);
381
382 if (p == NULL) {
383 HECMW_set_error(errno, "");
384 goto error;
385 }
386
387 mesh->filename = p;
388 return mesh;
389 error:
390
391 if (mesh) {
392 HECMW_free(mesh->name_ID);
393 HECMW_free(mesh->filename);
394 HECMW_free(mesh);
395 }
396
397 return NULL;
398 }
399
add_mesh_entry(struct mesh_entry * mesh)400 static int add_mesh_entry(struct mesh_entry *mesh) {
401 struct mesh_entry *p, *q;
402 q = NULL;
403
404 for (p = mesh_ent; p; p = (q = p)->next)
405 ;
406
407 if (q == NULL) {
408 mesh_ent = mesh;
409
410 } else {
411 q->next = mesh;
412 }
413
414 return 0;
415 }
416
make_mesh_group_entry(char * name_ID,int n_mesh,char ** mesh)417 static struct mesh_grp_entry *make_mesh_group_entry(char *name_ID, int n_mesh,
418 char **mesh) {
419 int i;
420 struct mesh_grp_entry *meshgrp = NULL;
421 meshgrp = HECMW_calloc(1, sizeof(*meshgrp));
422
423 if (meshgrp == NULL) {
424 HECMW_set_error(errno, "");
425 goto error;
426 }
427
428 meshgrp->name_ID = HECMW_strdup(name_ID);
429
430 if (meshgrp->name_ID == NULL) {
431 HECMW_set_error(errno, "");
432 goto error;
433 }
434
435 meshgrp->n_mesh = n_mesh;
436 meshgrp->mesh = HECMW_calloc(n_mesh, sizeof(*meshgrp->mesh));
437
438 if (meshgrp->mesh == NULL) {
439 HECMW_set_error(errno, "");
440 goto error;
441 }
442
443 for (i = 0; i < n_mesh; i++) {
444 meshgrp->mesh[i] = get_mesh_entry(mesh[i]);
445
446 if (meshgrp->mesh[i] == NULL) goto error;
447 }
448
449 meshgrp->next = NULL;
450 return meshgrp;
451 error:
452
453 if (meshgrp) {
454 HECMW_free(meshgrp->name_ID);
455 HECMW_free(meshgrp->mesh);
456 HECMW_free(meshgrp);
457 }
458
459 return NULL;
460 }
461
add_mesh_group_entry(struct mesh_grp_entry * mesh)462 static int add_mesh_group_entry(struct mesh_grp_entry *mesh) {
463 struct mesh_grp_entry *p, *q;
464 q = NULL;
465
466 for (p = mesh_grp_ent; p; p = (q = p)->next)
467 ;
468
469 if (q == NULL) {
470 mesh_grp_ent = mesh;
471
472 } else {
473 q->next = mesh;
474 }
475
476 return 0;
477 }
478
make_result_entry(char * name_ID,int io,int fg_text,char * filename)479 static struct result_entry *make_result_entry(char *name_ID, int io,
480 int fg_text, char *filename) {
481 char *p;
482 struct result_entry *result = NULL;
483 result = HECMW_calloc(1, sizeof(*result));
484
485 if (result == NULL) {
486 HECMW_set_error(errno, "");
487 goto error;
488 }
489
490 result->io = io;
491 result->fg_text = fg_text;
492 result->next = NULL;
493 p = HECMW_strdup(name_ID);
494
495 if (p == NULL) {
496 HECMW_set_error(errno, "");
497 goto error;
498 }
499
500 result->name_ID = p;
501 p = HECMW_strdup(filename);
502
503 if (p == NULL) {
504 HECMW_set_error(errno, "");
505 goto error;
506 }
507
508 result->filename = p;
509 return result;
510 error:
511
512 if (result) {
513 HECMW_free(result->name_ID);
514 HECMW_free(result->filename);
515 HECMW_free(result);
516 }
517
518 return NULL;
519 }
520
add_result_entry(struct result_entry * result)521 static int add_result_entry(struct result_entry *result) {
522 struct result_entry *p, *q;
523 q = NULL;
524
525 for (p = result_ent; p; p = (q = p)->next)
526 ;
527
528 if (q == NULL) {
529 result_ent = result;
530
531 } else {
532 q->next = result;
533 }
534
535 return 0;
536 }
537
make_restart_entry(char * name_ID,int io,char * filename)538 static struct restart_entry *make_restart_entry(char *name_ID, int io,
539 char *filename) {
540 char *p;
541 struct restart_entry *restart = NULL;
542 restart = HECMW_calloc(1, sizeof(*restart));
543
544 if (restart == NULL) {
545 HECMW_set_error(errno, "");
546 goto error;
547 }
548
549 restart->io = io;
550 restart->next = NULL;
551 p = HECMW_strdup(name_ID);
552
553 if (p == NULL) {
554 HECMW_set_error(errno, "");
555 goto error;
556 }
557
558 restart->name_ID = p;
559 p = HECMW_strdup(filename);
560
561 if (p == NULL) {
562 HECMW_set_error(errno, "");
563 goto error;
564 }
565
566 restart->filename = p;
567 return restart;
568 error:
569
570 if (restart) {
571 HECMW_free(restart->name_ID);
572 HECMW_free(restart->filename);
573 HECMW_free(restart);
574 }
575
576 return NULL;
577 }
578
add_restart_entry(struct restart_entry * restart)579 static int add_restart_entry(struct restart_entry *restart) {
580 struct restart_entry *p, *q;
581 q = NULL;
582
583 for (p = restart_ent; p; p = (q = p)->next)
584 ;
585
586 if (q == NULL) {
587 restart_ent = restart;
588
589 } else {
590 q->next = restart;
591 }
592
593 return 0;
594 }
595
make_ctrl_entry(char * name_ID,char * filename)596 static struct ctrl_entry *make_ctrl_entry(char *name_ID, char *filename) {
597 char *p;
598 struct ctrl_entry *ctrl = NULL;
599 ctrl = HECMW_calloc(1, sizeof(*ctrl));
600
601 if (ctrl == NULL) {
602 HECMW_set_error(errno, "");
603 goto error;
604 }
605
606 ctrl->next = NULL;
607 p = HECMW_strdup(name_ID);
608
609 if (p == NULL) {
610 HECMW_set_error(errno, "");
611 goto error;
612 }
613
614 ctrl->name_ID = p;
615 p = HECMW_strdup(filename);
616
617 if (p == NULL) {
618 HECMW_set_error(errno, "");
619 goto error;
620 }
621
622 ctrl->filename = p;
623 return ctrl;
624 error:
625
626 if (ctrl) {
627 HECMW_free(ctrl->name_ID);
628 HECMW_free(ctrl->filename);
629 HECMW_free(ctrl);
630 }
631
632 return NULL;
633 }
634
add_ctrl_entry(struct ctrl_entry * ctrl)635 static int add_ctrl_entry(struct ctrl_entry *ctrl) {
636 struct ctrl_entry *p, *q;
637 q = NULL;
638
639 for (p = ctrl_ent; p; p = (q = p)->next)
640 ;
641
642 if (q == NULL) {
643 ctrl_ent = ctrl;
644
645 } else {
646 q->next = ctrl;
647 }
648
649 return 0;
650 }
651
652 /*----------------------------------------------------------------------------*/
653
do_logging(int loglv,int msgno,int add_location,const char * fmt,va_list ap)654 static void do_logging(int loglv, int msgno, int add_location, const char *fmt,
655 va_list ap) {
656 char line[100] = "";
657 char msg[HECMW_MSG_LEN + 1];
658 HECMW_vsnprintf(msg, sizeof(msg), fmt, ap);
659
660 if (add_location) {
661 char *s = "";
662
663 if (strlen(msg) > 0) s = ": ";
664
665 HECMW_snprintf(line, sizeof(line), "%s:%d%s", ctrl_filename,
666 HECMW_ctrllex_get_lineno(), s);
667 }
668
669 HECMW_set_error(msgno, "%s%s", line, msg);
670 }
671
set_err(int msgno,const char * fmt,...)672 static void set_err(int msgno, const char *fmt, ...) {
673 va_list ap;
674 va_start(ap, fmt);
675 do_logging(HECMW_LOG_ERROR, msgno, 1, fmt, ap);
676 va_end(ap);
677 }
678
set_err_token(int token,int msgno,const char * fmt,...)679 static void set_err_token(int token, int msgno, const char *fmt, ...) {
680 int msg_no;
681 va_list ap;
682
683 if (!token) {
684 msg_no = HECMW_UTIL_E0003;
685
686 } else {
687 msg_no = msgno;
688 }
689
690 va_start(ap, fmt);
691 do_logging(HECMW_LOG_ERROR, msg_no, 1, fmt, ap);
692 va_end(ap);
693 }
694
695 /*----------------------------------------------------------------------------*/
696
read_mesh_header(void)697 static int read_mesh_header(void) {
698 int token;
699 /* !MESH */
700 token = HECMW_ctrllex_next_token();
701
702 if (token != HECMW_CTRLLEX_H_MESH) {
703 set_err(HECMW_UTIL_E0010, "!MESH required");
704 return -1;
705 }
706
707 /* ',' */
708 token = HECMW_ctrllex_next_token();
709
710 if (token != ',') {
711 set_err_token(token, HECMW_UTIL_E0010, "',' required after !MESH");
712 return -1;
713 }
714
715 return 0;
716 }
717
read_mesh_head_param_name(char * name)718 static int read_mesh_head_param_name(char *name) {
719 int token;
720 char *p;
721 token = HECMW_ctrllex_next_token();
722
723 if (token != '=') {
724 set_err_token(token, HECMW_UTIL_E0010, "'=' required after NAME");
725 return -1;
726 }
727
728 /* NAME value */
729 token = HECMW_ctrllex_next_token();
730
731 if (token != HECMW_CTRLLEX_NAME) {
732 set_err_token(token, HECMW_UTIL_E0010,
733 "NAME must begin with a letter or '_'");
734 return -1;
735 }
736
737 p = HECMW_ctrllex_get_text();
738
739 if (strlen(p) > HECMW_NAME_LEN) {
740 set_err(HECMW_IO_E0001, "");
741 return -1;
742 }
743
744 strcpy(name, p);
745
746 /* check */
747 if (get_mesh_entry(name) || get_mesh_grp_entry(name)) {
748 set_err(HECMW_UTIL_E0013, "");
749 return -1;
750 }
751
752 return 0;
753 }
754
read_mesh_head_param_type(int * type)755 static int read_mesh_head_param_type(int *type) {
756 int token;
757 token = HECMW_ctrllex_next_token();
758
759 if (token != '=') {
760 set_err_token(token, HECMW_UTIL_E0010, "'=' required after TYPE");
761 return -1;
762 }
763
764 /* TYPE value */
765 token = HECMW_ctrllex_next_token();
766
767 if (token == HECMW_CTRLLEX_K_HECMW_DIST) {
768 *type = HECMW_CTRL_FTYPE_HECMW_DIST;
769
770 } else if (token == HECMW_CTRLLEX_K_HECMW_ENTIRE) {
771 *type = HECMW_CTRL_FTYPE_HECMW_ENTIRE;
772
773 } else if (token == HECMW_CTRLLEX_K_GEOFEM) {
774 *type = HECMW_CTRL_FTYPE_GEOFEM;
775
776 } else if (token == HECMW_CTRLLEX_K_ABAQUS) {
777 *type = HECMW_CTRL_FTYPE_ABAQUS;
778
779 } else if (token == HECMW_CTRLLEX_K_NASTRAN) {
780 *type = HECMW_CTRL_FTYPE_NASTRAN;
781 #if 0
782
783 } else if (token == HECMW_CTRLLEX_K_FEMAP) {
784 *type = HECMW_CTRL_FTYPE_FEMAP;
785 #endif
786
787 } else {
788 set_err_token(token, HECMW_UTIL_E0010, "Invalid TYPE");
789 return -1;
790 }
791
792 return 0;
793 }
794
read_mesh_head_param_io(int * io)795 static int read_mesh_head_param_io(int *io) {
796 int token;
797 token = HECMW_ctrllex_next_token();
798
799 if (token != '=') {
800 set_err_token(token, HECMW_UTIL_E0010, "'=' required after IO");
801 return -1;
802 }
803
804 /* IO value */
805 token = HECMW_ctrllex_next_token();
806
807 if (token == HECMW_CTRLLEX_K_IN) {
808 *io = HECMW_CTRL_FILE_IO_IN;
809
810 } else if (token == HECMW_CTRLLEX_K_OUT) {
811 *io = HECMW_CTRL_FILE_IO_OUT;
812
813 } else {
814 set_err_token(token, HECMW_UTIL_E0010, "Invalid IO");
815 return -1;
816 }
817
818 return 0;
819 }
820
read_mesh_head_param_refine(int * refine)821 static int read_mesh_head_param_refine(int *refine) {
822 int token;
823 token = HECMW_ctrllex_next_token();
824
825 if (token != '=') {
826 set_err_token(token, HECMW_UTIL_E0010, "'=' required after REFINE");
827 return -1;
828 }
829
830 /* REFINE value */
831 token = HECMW_ctrllex_next_token();
832
833 if (token != HECMW_CTRLLEX_INT) {
834 set_err_token(token, HECMW_UTIL_E0010, "Invalid REFINE");
835 return -1;
836
837 } else {
838 *refine = HECMW_ctrllex_get_number();
839 }
840
841 return 0;
842 }
843
read_mesh_data(char * name,int type,int io,int refine)844 static int read_mesh_data(char *name, int type, int io, int refine) {
845 int token;
846 char *p;
847 struct mesh_entry *mesh;
848 /* filename */
849 token = HECMW_ctrllex_next_token();
850
851 if (token != HECMW_CTRLLEX_NAME && token != HECMW_CTRLLEX_FILENAME) {
852 set_err_token(token, HECMW_UTIL_E0010, "Invalid filename");
853 return -1;
854 }
855
856 p = HECMW_ctrllex_get_text();
857
858 if (strlen(p) > HECMW_FILENAME_LEN) {
859 set_err(HECMW_IO_E0002, "");
860 return -1;
861 }
862
863 /* create */
864 mesh = make_mesh_entry(name, type, io, refine, p);
865
866 if (mesh == NULL) return -1;
867
868 /* add */
869 if (add_mesh_entry(mesh)) return -1;
870
871 /* NL*/
872 token = HECMW_ctrllex_next_token();
873
874 if (token != HECMW_CTRLLEX_NL) {
875 set_err_token(token, HECMW_UTIL_E0010, "NL required after filename");
876 return -1;
877 }
878
879 return 0;
880 }
881
read_mesh(void)882 static int read_mesh(void) {
883 int state;
884 int token = -1;
885 int flag_name = 0; /* flag for NAME */
886 int flag_type = 0; /* flag for TYPE */
887 int flag_io = 0; /* flag for IO */
888 int flag_refine = 0; /* flag for REFINE */
889 int type = -1;
890 int io = HECMW_CTRL_FILE_IO_IN;
891 int refine = 0;
892 char name[HECMW_NAME_LEN + 1] = "";
893 enum {
894 ST_FINISHED,
895 ST_HEADER_LINE,
896 ST_HEADER_LINE_PARAM,
897 ST_DATA_LINE,
898 };
899 state = ST_HEADER_LINE;
900
901 while (state != ST_FINISHED) {
902 if (state == ST_HEADER_LINE) {
903 if (read_mesh_header()) return -1;
904
905 /* set next state */
906 state = ST_HEADER_LINE_PARAM;
907
908 } else if (state == ST_HEADER_LINE_PARAM) {
909 token = HECMW_ctrllex_next_token();
910
911 if (token == HECMW_CTRLLEX_K_NAME) {
912 /* must */
913 if (read_mesh_head_param_name(name)) return -1;
914
915 flag_name = 1;
916
917 } else if (token == HECMW_CTRLLEX_K_TYPE) {
918 /* must */
919 if (read_mesh_head_param_type(&type)) return -1;
920
921 flag_type = 1;
922
923 } else if (token == HECMW_CTRLLEX_K_IO) {
924 /* optional */
925 if (read_mesh_head_param_io(&io)) return -1;
926
927 flag_io = 1;
928
929 } else if (token == HECMW_CTRLLEX_K_REFINE) {
930 /* optional */
931 if (read_mesh_head_param_refine(&refine)) return -1;
932
933 flag_refine = 1;
934
935 } else {
936 set_err_token(token, HECMW_UTIL_E0010, "Unknown parameter");
937 return -1;
938 }
939
940 /* check next parameter */
941 token = HECMW_ctrllex_next_token();
942
943 if (token == HECMW_CTRLLEX_NL) {
944 /* check NAME */
945 if (!flag_name) {
946 set_err(HECMW_UTIL_E0011, "");
947 return -1;
948 }
949
950 /* check TYPE */
951 if (!flag_type) {
952 set_err(HECMW_UTIL_E0012, "");
953 return -1;
954 }
955
956 state = ST_DATA_LINE;
957
958 } else if (token == ',') {
959 ; /* continue this state */
960
961 } else {
962 set_err_token(token, HECMW_UTIL_E0010, "Unknown parameter");
963 return -1;
964 }
965
966 } else if (state == ST_DATA_LINE) {
967 HECMW_assert(flag_name);
968 HECMW_assert(flag_type);
969
970 if (read_mesh_data(name, type, io, refine)) return -1;
971
972 state = ST_FINISHED;
973
974 } else {
975 HECMW_assert(0);
976 }
977 }
978
979 /* check */
980 if (!strcmp(name, "fstrMSH") && type == HECMW_CTRL_FTYPE_HECMW_ENTIRE &&
981 HECMW_comm_get_size() > 1) {
982 set_err_token(token, HECMW_UTIL_E0010, "Invalid TYPE");
983 return -1;
984 }
985
986 return 0;
987 }
988
989 /*----------------------------------------------------------------------------*/
990
read_meshgrp_header(void)991 static int read_meshgrp_header(void) {
992 int token;
993 /* !MESH GROUP */
994 token = HECMW_ctrllex_next_token();
995
996 if (token != HECMW_CTRLLEX_H_MESH_GROUP) {
997 set_err(HECMW_UTIL_E0050, "!MESH GROUP required");
998 return -1;
999 }
1000
1001 /* ',' */
1002 token = HECMW_ctrllex_next_token();
1003
1004 if (token != ',') {
1005 set_err_token(token, HECMW_UTIL_E0050, "',' required after !MESH GROUP");
1006 return -1;
1007 }
1008
1009 return 0;
1010 }
1011
read_meshgrp_head_param_name(char * name)1012 static int read_meshgrp_head_param_name(char *name) {
1013 int token;
1014 char *p;
1015 token = HECMW_ctrllex_next_token();
1016
1017 if (token != '=') {
1018 set_err_token(token, HECMW_UTIL_E0050, "'=' required after NAME");
1019 return -1;
1020 }
1021
1022 /* NAME value */
1023 token = HECMW_ctrllex_next_token();
1024
1025 if (token != HECMW_CTRLLEX_NAME) {
1026 set_err_token(token, HECMW_UTIL_E0050,
1027 "NAME must begin with a letter or '_'");
1028 return -1;
1029 }
1030
1031 p = HECMW_ctrllex_get_text();
1032
1033 if (strlen(p) > HECMW_NAME_LEN) {
1034 set_err(HECMW_IO_E0001, "");
1035 return -1;
1036 }
1037
1038 strcpy(name, p);
1039
1040 /* check */
1041 if (get_mesh_entry(name) || get_mesh_grp_entry(name)) {
1042 set_err(HECMW_UTIL_E0053, "");
1043 return -1;
1044 }
1045
1046 return 0;
1047 }
1048
read_meshgrp_data(char * name)1049 static int read_meshgrp_data(char *name) {
1050 int i, token, n_mesh, n_mesh_max;
1051 char *p, **q;
1052 char **mesh = NULL;
1053 struct mesh_grp_entry *meshgrp = NULL;
1054 struct mesh_entry *ment;
1055 n_mesh_max = 10; /* default */
1056 mesh = HECMW_malloc(sizeof(*mesh) * n_mesh_max);
1057
1058 if (mesh == NULL) {
1059 HECMW_set_error(errno, "");
1060 return -1;
1061 }
1062
1063 n_mesh = 0;
1064
1065 while (1) {
1066 /* filename */
1067 token = HECMW_ctrllex_next_token();
1068
1069 if (token != HECMW_CTRLLEX_NAME && token != HECMW_CTRLLEX_FILENAME) {
1070 if (n_mesh == 0) {
1071 set_err_token(token, HECMW_UTIL_E0050, "name_ID required");
1072 return -1;
1073 }
1074
1075 HECMW_ctrllex_unput_token();
1076 break;
1077 }
1078
1079 p = HECMW_ctrllex_get_text();
1080
1081 if (strlen(p) > HECMW_FILENAME_LEN) {
1082 set_err(HECMW_IO_E0002, "");
1083 return -1;
1084 }
1085
1086 if ((ment = get_mesh_entry(p)) == NULL) {
1087 set_err_token(token, HECMW_UTIL_E0052, "name_ID: %s", p);
1088 return -1;
1089 }
1090
1091 if (!is_entire_mesh(ment->type)) {
1092 set_err_token(token, HECMW_UTIL_E0055, "name_ID: %s", p);
1093 return -1;
1094 }
1095
1096 if (n_mesh == n_mesh_max) {
1097 n_mesh_max *= 2;
1098 q = HECMW_realloc(mesh, sizeof(*mesh) * n_mesh_max);
1099
1100 if (q == NULL) {
1101 HECMW_set_error(errno, "");
1102 return -1;
1103 }
1104
1105 mesh = q;
1106 }
1107
1108 mesh[n_mesh] = HECMW_strdup(p);
1109
1110 if (mesh[n_mesh] == NULL) {
1111 HECMW_set_error(errno, "");
1112 return -1;
1113 }
1114
1115 n_mesh++;
1116 /* ',' or NL*/
1117 token = HECMW_ctrllex_next_token();
1118
1119 if (token != HECMW_CTRLLEX_NL && token != ',') {
1120 set_err_token(token, HECMW_UTIL_E0050,
1121 "',' or NL required after name_ID");
1122 return -1;
1123 }
1124 }
1125
1126 /* create */
1127 meshgrp = make_mesh_group_entry(name, n_mesh, mesh);
1128
1129 if (meshgrp == NULL) return -1;
1130
1131 /* add */
1132 if (add_mesh_group_entry(meshgrp)) return -1;
1133
1134 for (i = 0; i < n_mesh; i++) {
1135 HECMW_free(mesh[i]);
1136 }
1137
1138 HECMW_free(mesh);
1139 return 0;
1140 }
1141
read_meshgrp(void)1142 static int read_meshgrp(void) {
1143 int token, state;
1144 int flag_name = 0; /* flag for NAME */
1145 char name[HECMW_NAME_LEN + 1] = "";
1146 enum {
1147 ST_FINISHED,
1148 ST_HEADER_LINE,
1149 ST_HEADER_LINE_PARAM,
1150 ST_DATA_LINE,
1151 };
1152 state = ST_HEADER_LINE;
1153
1154 while (state != ST_FINISHED) {
1155 if (state == ST_HEADER_LINE) {
1156 if (read_meshgrp_header()) return -1;
1157
1158 /* set next state */
1159 state = ST_HEADER_LINE_PARAM;
1160
1161 } else if (state == ST_HEADER_LINE_PARAM) {
1162 token = HECMW_ctrllex_next_token();
1163
1164 if (token == HECMW_CTRLLEX_K_NAME) {
1165 /* must */
1166 if (read_meshgrp_head_param_name(name)) return -1;
1167
1168 flag_name = 1;
1169
1170 } else {
1171 set_err_token(token, HECMW_UTIL_E0050, "Unknown parameter");
1172 return -1;
1173 }
1174
1175 /* check next parameter */
1176 token = HECMW_ctrllex_next_token();
1177
1178 if (token == HECMW_CTRLLEX_NL) {
1179 /* check NAME */
1180 if (!flag_name) {
1181 set_err(HECMW_UTIL_E0051, "");
1182 return -1;
1183 }
1184
1185 state = ST_DATA_LINE;
1186
1187 } else if (token == ',') {
1188 ; /* continue this state */
1189
1190 } else {
1191 set_err_token(token, HECMW_UTIL_E0050, "Unknown parameter");
1192 return -1;
1193 }
1194
1195 } else if (state == ST_DATA_LINE) {
1196 HECMW_assert(flag_name);
1197
1198 if (read_meshgrp_data(name)) return -1;
1199
1200 state = ST_FINISHED;
1201
1202 } else {
1203 HECMW_assert(0);
1204 }
1205 }
1206
1207 return 0;
1208 }
1209
1210 /*----------------------------------------------------------------------------*/
1211
read_result_head(void)1212 static int read_result_head(void) {
1213 int token;
1214 /* !RESULT */
1215 token = HECMW_ctrllex_next_token();
1216
1217 if (token != HECMW_CTRLLEX_H_RESULT) {
1218 set_err(HECMW_UTIL_E0020, "!RESULT required");
1219 return -1;
1220 }
1221
1222 /* ',' */
1223 token = HECMW_ctrllex_next_token();
1224
1225 if (token != ',') {
1226 set_err_token(token, HECMW_UTIL_E0020, "',' required after !RESULT");
1227 return -1;
1228 }
1229
1230 return 0;
1231 }
1232
read_result_param_name(char * name)1233 static int read_result_param_name(char *name) {
1234 int token;
1235 char *p;
1236 token = HECMW_ctrllex_next_token();
1237
1238 if (token != '=') {
1239 set_err_token(token, HECMW_UTIL_E0020, "'=' required after NAME");
1240 return -1;
1241 }
1242
1243 /* NAME value */
1244 token = HECMW_ctrllex_next_token();
1245
1246 if (token != HECMW_CTRLLEX_NAME) {
1247 set_err_token(token, HECMW_UTIL_E0020,
1248 "NAME must begin with a letter or '_'");
1249 return -1;
1250 }
1251
1252 p = HECMW_ctrllex_get_text();
1253
1254 if (strlen(p) > HECMW_NAME_LEN) {
1255 set_err(HECMW_IO_E0001, "");
1256 return -1;
1257 }
1258
1259 strcpy(name, p);
1260
1261 /* check */
1262 if (get_result_entry(name)) {
1263 set_err(HECMW_UTIL_E0023, "");
1264 return -1;
1265 }
1266
1267 return 0;
1268 }
1269
read_result_param_io(int * io)1270 static int read_result_param_io(int *io) {
1271 int token;
1272 token = HECMW_ctrllex_next_token();
1273
1274 if (token != '=') {
1275 set_err_token(token, HECMW_UTIL_E0020, "'=' required after IO");
1276 return -1;
1277 }
1278
1279 /* IO value */
1280 token = HECMW_ctrllex_next_token();
1281
1282 if (token == HECMW_CTRLLEX_K_IN) {
1283 *io = HECMW_CTRL_FILE_IO_IN;
1284
1285 } else if (token == HECMW_CTRLLEX_K_OUT) {
1286 *io = HECMW_CTRL_FILE_IO_OUT;
1287
1288 } else {
1289 set_err_token(token, HECMW_UTIL_E0020, "Invalid IO");
1290 return -1;
1291 }
1292
1293 return 0;
1294 }
1295
read_result_param_type(int * fg_text)1296 static int read_result_param_type(int *fg_text) {
1297 int token;
1298 char s[HECMW_NAME_LEN + 1];
1299 char *p;
1300 char *sp;
1301 token = HECMW_ctrllex_next_token();
1302
1303 if (token != '=') {
1304 set_err_token(token, HECMW_UTIL_E0020, "'=' required after TYPE");
1305 return -1;
1306 }
1307
1308 /* TYPE value */
1309 token = HECMW_ctrllex_next_token();
1310 p = HECMW_ctrllex_get_text();
1311
1312 if (strlen(p) > HECMW_NAME_LEN) {
1313 set_err(HECMW_UTIL_E0020, "");
1314 return -1;
1315 }
1316
1317 sp = s;
1318
1319 while (*p) {
1320 *sp = (char)toupper(*p);
1321 p++;
1322 sp++;
1323 }
1324
1325 *sp = 0;
1326
1327 if (strcmp(s, "TEXT") == 0) {
1328 *fg_text = 1;
1329
1330 } else if (strcmp(s, "BINARY") == 0) {
1331 *fg_text = 0;
1332
1333 } else {
1334 set_err(HECMW_UTIL_E0020, "TEXT or BINARY required");
1335 return -1;
1336 }
1337
1338 return 0;
1339 }
1340
read_result_data(char * name,int io,int fg_text)1341 static int read_result_data(char *name, int io, int fg_text) {
1342 int token;
1343 char *p;
1344 struct result_entry *result;
1345 /* filename */
1346 token = HECMW_ctrllex_next_token();
1347
1348 if (token != HECMW_CTRLLEX_NAME && token != HECMW_CTRLLEX_FILENAME) {
1349 set_err_token(token, HECMW_UTIL_E0020, "Invalid filename");
1350 }
1351
1352 p = HECMW_ctrllex_get_text();
1353
1354 if (strlen(p) > HECMW_FILENAME_LEN) {
1355 set_err(HECMW_IO_E0002, "NL required after filename");
1356 return -1;
1357 }
1358
1359 /* create */
1360 result = make_result_entry(name, io, fg_text, p);
1361
1362 if (result == NULL) return -1;
1363
1364 /* add */
1365 if (add_result_entry(result)) return -1;
1366
1367 /* NL*/
1368 token = HECMW_ctrllex_next_token();
1369
1370 if (token != HECMW_CTRLLEX_NL) {
1371 set_err_token(token, HECMW_UTIL_E0020, "NL required after filename");
1372 return -1;
1373 }
1374
1375 return 0;
1376 }
1377
read_result(void)1378 static int read_result(void) {
1379 int token, state;
1380 int flag_name = 0; /* flag for NAME */
1381 int flag_io = 0; /* flag for IO */
1382 int io;
1383 int fg_text; /* default : text */
1384 char name[HECMW_NAME_LEN + 1] = "";
1385 enum {
1386 ST_FINISHED,
1387 ST_HEADER_LINE,
1388 ST_HEADER_LINE_PARAM,
1389 ST_DATA_LINE,
1390 };
1391 fg_text = 1;
1392 state = ST_HEADER_LINE;
1393
1394 while (state != ST_FINISHED) {
1395 if (state == ST_HEADER_LINE) {
1396 if (read_result_head()) return -1;
1397
1398 state = ST_HEADER_LINE_PARAM;
1399
1400 } else if (state == ST_HEADER_LINE_PARAM) {
1401 token = HECMW_ctrllex_next_token();
1402
1403 if (token == HECMW_CTRLLEX_K_NAME) {
1404 /* must */
1405 if (read_result_param_name(name)) return -1;
1406
1407 flag_name = 1;
1408
1409 } else if (token == HECMW_CTRLLEX_K_IO) {
1410 /* must */
1411 if (read_result_param_io(&io)) return -1;
1412
1413 flag_io = 1;
1414
1415 } else if (token == HECMW_CTRLLEX_K_TYPE) {
1416 /* option */
1417 if (read_result_param_type(&fg_text)) return -1;
1418
1419 } else {
1420 set_err_token(token, HECMW_UTIL_E0020, "Unknown parameter");
1421 return -1;
1422 }
1423
1424 /* check next parameter */
1425 token = HECMW_ctrllex_next_token();
1426
1427 if (token == HECMW_CTRLLEX_NL) {
1428 /* check NAME */
1429 if (!flag_name) {
1430 set_err(HECMW_UTIL_E0021, "");
1431 return -1;
1432 }
1433
1434 /* check IO */
1435 if (!flag_io) {
1436 set_err(HECMW_UTIL_E0022, "");
1437 return -1;
1438 }
1439
1440 state = ST_DATA_LINE;
1441
1442 } else if (token == ',') {
1443 ; /* continue this state */
1444
1445 } else {
1446 set_err_token(token, HECMW_UTIL_E0020, "Unknown parameter");
1447 return -1;
1448 }
1449
1450 } else if (state == ST_DATA_LINE) {
1451 HECMW_assert(flag_name);
1452
1453 if (read_result_data(name, io, fg_text)) return -1;
1454
1455 state = ST_FINISHED;
1456
1457 } else {
1458 HECMW_assert(0);
1459 }
1460 }
1461
1462 return 0;
1463 }
1464
1465 /*----------------------------------------------------------------------------*/
1466
read_restart_head(void)1467 static int read_restart_head(void) {
1468 int token;
1469 /* !RESULT */
1470 token = HECMW_ctrllex_next_token();
1471
1472 if (token != HECMW_CTRLLEX_H_RESTART) {
1473 set_err(HECMW_UTIL_E0040, "!RESTART required");
1474 return -1;
1475 }
1476
1477 /* ',' */
1478 token = HECMW_ctrllex_next_token();
1479
1480 if (token != ',') {
1481 set_err_token(token, HECMW_UTIL_E0040, "',' required after !RESTART");
1482 return -1;
1483 }
1484
1485 return 0;
1486 }
1487
read_restart_param_name(char * name)1488 static int read_restart_param_name(char *name) {
1489 int token;
1490 char *p;
1491 token = HECMW_ctrllex_next_token();
1492
1493 if (token != '=') {
1494 set_err_token(token, HECMW_UTIL_E0040, "'=' required after NAME");
1495 return -1;
1496 }
1497
1498 /* NAME value */
1499 token = HECMW_ctrllex_next_token();
1500
1501 if (token != HECMW_CTRLLEX_NAME) {
1502 set_err_token(token, HECMW_UTIL_E0040,
1503 "NAME must begin with a letter or '_'");
1504 return -1;
1505 }
1506
1507 p = HECMW_ctrllex_get_text();
1508
1509 if (strlen(p) > HECMW_NAME_LEN) {
1510 set_err(HECMW_IO_E0001, "");
1511 return -1;
1512 }
1513
1514 strcpy(name, p);
1515
1516 /* check */
1517 if (get_restart_entry(name)) {
1518 set_err(HECMW_UTIL_E0043, "");
1519 return -1;
1520 }
1521
1522 return 0;
1523 }
1524
read_restart_param_io(int * io)1525 static int read_restart_param_io(int *io) {
1526 int token;
1527 token = HECMW_ctrllex_next_token();
1528
1529 if (token != '=') {
1530 set_err_token(token, HECMW_UTIL_E0040, "'=' required after IO");
1531 return -1;
1532 }
1533
1534 /* IO value */
1535 token = HECMW_ctrllex_next_token();
1536
1537 if (token == HECMW_CTRLLEX_K_IN) {
1538 *io = HECMW_CTRL_FILE_IO_IN;
1539
1540 } else if (token == HECMW_CTRLLEX_K_OUT) {
1541 *io = HECMW_CTRL_FILE_IO_OUT;
1542
1543 } else if (token == HECMW_CTRLLEX_K_INOUT) {
1544 *io = HECMW_CTRL_FILE_IO_INOUT;
1545
1546 } else {
1547 set_err_token(token, HECMW_UTIL_E0040, "Invalid IO");
1548 return -1;
1549 }
1550
1551 return 0;
1552 }
1553
read_restart_data(char * name,int io)1554 static int read_restart_data(char *name, int io) {
1555 int token;
1556 char *p;
1557 struct restart_entry *restart;
1558 /* filename */
1559 token = HECMW_ctrllex_next_token();
1560
1561 if (token != HECMW_CTRLLEX_NAME && token != HECMW_CTRLLEX_FILENAME) {
1562 set_err_token(token, HECMW_UTIL_E0040, "Invalid filename");
1563 }
1564
1565 p = HECMW_ctrllex_get_text();
1566
1567 if (strlen(p) > HECMW_FILENAME_LEN) {
1568 set_err(HECMW_IO_E0002, "NL required after filename");
1569 return -1;
1570 }
1571
1572 /* create */
1573 restart = make_restart_entry(name, io, p);
1574
1575 if (restart == NULL) return -1;
1576
1577 /* add */
1578 if (add_restart_entry(restart)) return -1;
1579
1580 /* NL*/
1581 token = HECMW_ctrllex_next_token();
1582
1583 if (token != HECMW_CTRLLEX_NL) {
1584 set_err_token(token, HECMW_UTIL_E0040, "NL required after filename");
1585 return -1;
1586 }
1587
1588 return 0;
1589 }
1590
read_restart(void)1591 static int read_restart(void) {
1592 int token, state;
1593 int flag_name = 0; /* flag for NAME */
1594 int flag_io = 0; /* flag for IO */
1595 int io;
1596 char name[HECMW_NAME_LEN + 1] = "";
1597 enum {
1598 ST_FINISHED,
1599 ST_HEADER_LINE,
1600 ST_HEADER_LINE_PARAM,
1601 ST_DATA_LINE,
1602 };
1603 state = ST_HEADER_LINE;
1604
1605 while (state != ST_FINISHED) {
1606 if (state == ST_HEADER_LINE) {
1607 if (read_restart_head()) return -1;
1608
1609 /* set next state */
1610 state = ST_HEADER_LINE_PARAM;
1611
1612 } else if (state == ST_HEADER_LINE_PARAM) {
1613 token = HECMW_ctrllex_next_token();
1614
1615 if (token == HECMW_CTRLLEX_K_NAME) {
1616 /* must */
1617 if (read_restart_param_name(name)) return -1;
1618
1619 flag_name = 1;
1620
1621 } else if (token == HECMW_CTRLLEX_K_IO) {
1622 /* must */
1623 if (read_restart_param_io(&io)) return -1;
1624
1625 flag_io = 1;
1626
1627 } else {
1628 set_err_token(token, HECMW_UTIL_E0040, "Unknown parameter");
1629 return -1;
1630 }
1631
1632 /* check next parameter */
1633 token = HECMW_ctrllex_next_token();
1634
1635 if (token == HECMW_CTRLLEX_NL) {
1636 /* check NAME */
1637 if (!flag_name) {
1638 set_err(HECMW_UTIL_E0041, "");
1639 return -1;
1640 }
1641
1642 /* check IO */
1643 if (!flag_io) {
1644 set_err(HECMW_UTIL_E0042, "");
1645 return -1;
1646 }
1647
1648 state = ST_DATA_LINE;
1649
1650 } else if (token == ',') {
1651 ; /* continue this state */
1652
1653 } else {
1654 set_err_token(token, HECMW_UTIL_E0040, "Unknown parameter");
1655 return -1;
1656 }
1657
1658 } else if (state == ST_DATA_LINE) {
1659 HECMW_assert(flag_name);
1660 HECMW_assert(flag_io);
1661
1662 if (read_restart_data(name, io)) return -1;
1663
1664 state = ST_FINISHED;
1665
1666 } else {
1667 HECMW_assert(0);
1668 }
1669 }
1670
1671 return 0;
1672 }
1673
1674 /*----------------------------------------------------------------------------*/
1675
read_control_head(void)1676 static int read_control_head(void) {
1677 int token;
1678 /* !CONTROL */
1679 token = HECMW_ctrllex_next_token();
1680
1681 if (token != HECMW_CTRLLEX_H_CONTROL) {
1682 set_err(HECMW_UTIL_E0030, "!CONTROL required");
1683 return -1;
1684 }
1685
1686 /* ',' */
1687 token = HECMW_ctrllex_next_token();
1688
1689 if (token != ',') {
1690 set_err_token(token, HECMW_UTIL_E0030, "',' required after !CONTROL");
1691 return -1;
1692 }
1693
1694 return 0;
1695 }
1696
read_control_head_param_name(char * name)1697 static int read_control_head_param_name(char *name) {
1698 int token;
1699 char *p;
1700 token = HECMW_ctrllex_next_token();
1701
1702 if (token != '=') {
1703 set_err_token(token, HECMW_UTIL_E0030, "'=' required after NAME");
1704 return -1;
1705 }
1706
1707 /* NAME value */
1708 token = HECMW_ctrllex_next_token();
1709
1710 if (token != HECMW_CTRLLEX_NAME) {
1711 set_err_token(token, HECMW_UTIL_E0030,
1712 "NAME must begin with a letter or '_'");
1713 return -1;
1714 }
1715
1716 p = HECMW_ctrllex_get_text();
1717
1718 if (strlen(p) > HECMW_NAME_LEN) {
1719 set_err(HECMW_IO_E0001, "");
1720 return -1;
1721 }
1722
1723 strcpy(name, p);
1724
1725 /* check */
1726 if (get_ctrl_entry(name)) {
1727 set_err(HECMW_UTIL_E0032, "");
1728 return -1;
1729 }
1730
1731 return 0;
1732 }
1733
read_control_data(char * name)1734 static int read_control_data(char *name) {
1735 int token;
1736 char *p;
1737 struct ctrl_entry *control;
1738 /* filename */
1739 token = HECMW_ctrllex_next_token();
1740
1741 if (token != HECMW_CTRLLEX_NAME && token != HECMW_CTRLLEX_FILENAME) {
1742 set_err_token(token, HECMW_UTIL_E0030, "Invalid filename");
1743 return -1;
1744 }
1745
1746 p = HECMW_ctrllex_get_text();
1747
1748 if (strlen(p) > HECMW_FILENAME_LEN) {
1749 set_err(HECMW_IO_E0002, "NL required after filename");
1750 return -1;
1751 }
1752
1753 /* create */
1754 control = make_ctrl_entry(name, p);
1755
1756 if (control == NULL) {
1757 return -1;
1758 }
1759
1760 /* add */
1761 if (add_ctrl_entry(control)) {
1762 return -1;
1763 }
1764
1765 /* NL*/
1766 token = HECMW_ctrllex_next_token();
1767
1768 if (token != HECMW_CTRLLEX_NL) {
1769 set_err_token(token, HECMW_UTIL_E0030, "NL required after filename");
1770 return -1;
1771 }
1772
1773 return 0;
1774 }
1775
read_control(void)1776 static int read_control(void) {
1777 int token, state;
1778 int flag_name = 0; /* flag for NAME */
1779 char name[HECMW_NAME_LEN + 1] = "";
1780 enum {
1781 ST_FINISHED,
1782 ST_HEADER_LINE,
1783 ST_HEADER_LINE_PARAM,
1784 ST_DATA_LINE,
1785 };
1786 state = ST_HEADER_LINE;
1787
1788 while (state != ST_FINISHED) {
1789 if (state == ST_HEADER_LINE) {
1790 if (read_control_head()) return -1;
1791
1792 /* set next state */
1793 state = ST_HEADER_LINE_PARAM;
1794
1795 } else if (state == ST_HEADER_LINE_PARAM) {
1796 token = HECMW_ctrllex_next_token();
1797
1798 if (token == HECMW_CTRLLEX_K_NAME) {
1799 /* must */
1800 if (read_control_head_param_name(name)) return -1;
1801
1802 flag_name = 1;
1803
1804 } else {
1805 set_err_token(token, HECMW_UTIL_E0030, "Unknown parameter");
1806 return -1;
1807 }
1808
1809 /* check next parameter */
1810 token = HECMW_ctrllex_next_token();
1811
1812 if (token == HECMW_CTRLLEX_NL) {
1813 /* check NAME */
1814 if (!flag_name) {
1815 set_err(HECMW_UTIL_E0031, "");
1816 return -1;
1817 }
1818
1819 state = ST_DATA_LINE;
1820
1821 } else if (token == ',') {
1822 ; /* continue this state */
1823
1824 } else {
1825 set_err_token(token, HECMW_UTIL_E0030, "Unknown parameter");
1826 return -1;
1827 }
1828
1829 } else if (state == ST_DATA_LINE) {
1830 HECMW_assert(flag_name);
1831
1832 if (read_control_data(name)) return -1;
1833
1834 state = ST_FINISHED;
1835
1836 } else {
1837 HECMW_assert(0);
1838 }
1839 }
1840
1841 return 0;
1842 }
1843
1844 /*----------------------------------------------------------------------------*/
1845
read_subdir_head(void)1846 static int read_subdir_head(void) {
1847 int token;
1848 /* !SUBDIR */
1849 token = HECMW_ctrllex_next_token();
1850
1851 if (token != HECMW_CTRLLEX_H_SUBDIR) {
1852 set_err(HECMW_UTIL_E0060, "!SUBDIR required");
1853 return -1;
1854 }
1855
1856 /* ',' */
1857 token = HECMW_ctrllex_next_token();
1858
1859 if (token != ',') {
1860 set_err_token(token, HECMW_UTIL_E0060, "',' required after !SUBDIR");
1861 return -1;
1862 }
1863
1864 return 0;
1865 }
1866
read_subdir_head_param_limit(void)1867 static int read_subdir_head_param_limit(void) {
1868 int token;
1869 token = HECMW_ctrllex_next_token();
1870
1871 if (token != '=') {
1872 set_err_token(token, HECMW_UTIL_E0060, "'=' required after LIMIT");
1873 return -1;
1874 }
1875
1876 /* LIMIT value */
1877 token = HECMW_ctrllex_next_token();
1878
1879 if (token != HECMW_CTRLLEX_INT) {
1880 set_err_token(token, HECMW_UTIL_E0060, "Invalid LIMIT");
1881 return -1;
1882
1883 } else {
1884 nlimit = HECMW_ctrllex_get_number();
1885 }
1886
1887 return 0;
1888 }
1889
read_subdir(void)1890 static int read_subdir(void) {
1891 int token, state;
1892 int flag_name = 0; /* flag for NAME */
1893 enum {
1894 ST_FINISHED,
1895 ST_HEADER_LINE,
1896 ST_HEADER_LINE_PARAM,
1897 };
1898 nlimit = 5000;
1899 state = ST_HEADER_LINE;
1900
1901 while (state != ST_FINISHED) {
1902 if (state == ST_HEADER_LINE) {
1903 if (read_subdir_head()) return -1;
1904
1905 /* set next state */
1906 state = ST_HEADER_LINE_PARAM;
1907
1908 } else if (state == ST_HEADER_LINE_PARAM) {
1909 token = HECMW_ctrllex_next_token();
1910
1911 if (token == HECMW_CTRLLEX_K_ON) {
1912 /* must */
1913 subdir_on = 1;
1914 flag_name = 1;
1915
1916 } else if (token == HECMW_CTRLLEX_K_OFF) {
1917 /* must */
1918 subdir_on = 0;
1919 flag_name = 1;
1920
1921 } else if (token == HECMW_CTRLLEX_K_LIMIT) {
1922 if (read_subdir_head_param_limit()) return -1;
1923
1924 } else {
1925 set_err_token(token, HECMW_UTIL_E0060, "Unknown parameter");
1926 return -1;
1927 }
1928
1929 /* check next parameter */
1930 token = HECMW_ctrllex_next_token();
1931
1932 if (token == HECMW_CTRLLEX_NL) {
1933 if (!flag_name) {
1934 set_err(HECMW_UTIL_E0061, "");
1935 return -1;
1936 }
1937
1938 state = ST_FINISHED;
1939
1940 } else if (token == ',') {
1941 ; /* continue this state */
1942
1943 } else {
1944 set_err_token(token, HECMW_UTIL_E0060, "Unknown parameter");
1945 return -1;
1946 }
1947
1948 } else {
1949 HECMW_assert(0);
1950 }
1951 }
1952
1953 return 0;
1954 }
1955
1956 /*------------------------------------------------------------------------------
1957 ReadFunc table
1958 */
1959
1960 typedef int (*ReadFunc)(void);
1961
1962 static struct read_func_table {
1963 int token;
1964 ReadFunc func;
1965 } read_func_table[] = {
1966 {HECMW_CTRLLEX_H_CONTROL, read_control},
1967 {HECMW_CTRLLEX_H_MESH, read_mesh},
1968 {HECMW_CTRLLEX_H_MESH_GROUP, read_meshgrp},
1969 {HECMW_CTRLLEX_H_RESULT, read_result},
1970 {HECMW_CTRLLEX_H_RESTART, read_restart},
1971 {HECMW_CTRLLEX_H_SUBDIR, read_subdir},
1972 };
1973
1974 #define N_READ_FUNC (sizeof(read_func_table) / sizeof(read_func_table[0]))
1975
1976 /* static int (* get_read_func(int token))(void) */
get_read_func(int token)1977 static ReadFunc get_read_func(int token) {
1978 int i;
1979
1980 for (i = 0; i < N_READ_FUNC; i++) {
1981 if (token == read_func_table[i].token) {
1982 return read_func_table[i].func;
1983 }
1984 }
1985
1986 return NULL;
1987 }
1988
1989 /*----------------------------------------------------------------------------*/
1990
parse(void)1991 static int parse(void) {
1992 int token;
1993 ReadFunc func;
1994
1995 while ((token = HECMW_ctrllex_next_token())) {
1996 if (token == HECMW_CTRLLEX_NL) continue;
1997
1998 func = get_read_func(token);
1999
2000 if (func == NULL) {
2001 char *p = HECMW_ctrllex_get_text();
2002
2003 if (p[0] == '!') {
2004 set_err(HECMW_UTIL_E0004, "");
2005
2006 } else {
2007 set_err(HECMW_UTIL_E0005, "");
2008 }
2009
2010 return -1;
2011 }
2012
2013 HECMW_ctrllex_unput_token(); /* unput !XXXX */
2014
2015 if ((*func)()) return -1;
2016 }
2017
2018 return 0;
2019 }
2020
HECMW_ctrl_init_ex(const char * ctrlfile)2021 int HECMW_ctrl_init_ex(const char *ctrlfile) {
2022 FILE *fp;
2023 HECMW_log(HECMW_LOG_DEBUG, "Getting control data");
2024
2025 if (ctrlfile == NULL) {
2026 HECMW_set_error(HECMW_ALL_E0101, "Not specified control file name");
2027 return -1;
2028 }
2029
2030 strcpy(ctrl_filename, ctrlfile);
2031 HECMW_log(HECMW_LOG_DEBUG, "Control file is '%s'", ctrl_filename);
2032
2033 if ((fp = fopen(ctrl_filename, "r")) == NULL) {
2034 HECMW_set_error(HECMW_UTIL_E0001, "File: %s, %s", ctrl_filename,
2035 strerror(errno));
2036 return -1;
2037 }
2038
2039 if (HECMW_ctrllex_set_input(fp)) return -1;
2040
2041 if (parse()) {
2042 return -1;
2043 }
2044
2045 if (fclose(fp)) {
2046 HECMW_set_error(HECMW_UTIL_E0002, "File: %s, %s", ctrl_filename,
2047 strerror(errno));
2048 return -1;
2049 }
2050
2051 return 0;
2052 }
2053
HECMW_ctrl_init(void)2054 int HECMW_ctrl_init(void) { return HECMW_ctrl_init_ex(HECMW_CTRL_FILE); }
2055
HECMW_ctrl_finalize(void)2056 int HECMW_ctrl_finalize(void) {
2057 HECMW_log(HECMW_LOG_DEBUG, "Finalizing control data");
2058 free_ctrl_entry();
2059 free_mesh_entry();
2060 free_mesh_grp_entry();
2061 free_result_entry();
2062 free_restart_entry();
2063 return 0;
2064 }
2065
HECMW_ctrl_free_meshfiles(struct hecmw_ctrl_meshfiles * meshfiles)2066 void HECMW_ctrl_free_meshfiles(struct hecmw_ctrl_meshfiles *meshfiles) {
2067 int i;
2068
2069 for (i = 0; i < meshfiles->n_mesh; i++) {
2070 HECMW_free(meshfiles->meshfiles[i].filename);
2071 }
2072
2073 HECMW_free(meshfiles->meshfiles);
2074 HECMW_free(meshfiles);
2075 }
2076
make_meshfiles_struct(int n_mesh,struct mesh_entry ** mesh,int n_rank,int i_rank,int flag_rank_none)2077 static struct hecmw_ctrl_meshfiles *make_meshfiles_struct(
2078 int n_mesh, struct mesh_entry **mesh, int n_rank, int i_rank,
2079 int flag_rank_none) {
2080 int i, flag_rank, nrank, myrank, irank;
2081 char *fname;
2082 char *retval;
2083 struct hecmw_ctrl_meshfiles *files;
2084 char prefix[10];
2085 files = HECMW_malloc(sizeof(*files));
2086
2087 if (files == NULL) {
2088 HECMW_set_error(errno, "");
2089 return NULL;
2090 }
2091
2092 if (n_rank == 0) {
2093 nrank = HECMW_comm_get_size();
2094 myrank = HECMW_comm_get_rank();
2095
2096 } else {
2097 nrank = n_rank;
2098 myrank = i_rank;
2099 }
2100
2101 files->n_mesh = n_mesh;
2102 files->meshfiles = HECMW_malloc(sizeof(*files->meshfiles) * n_mesh);
2103
2104 if (files->meshfiles == NULL) {
2105 HECMW_set_error(errno, "");
2106 return NULL;
2107 }
2108
2109 for (i = 0; i < n_mesh; i++) {
2110 struct hecmw_ctrl_meshfile *file = &files->meshfiles[i];
2111 struct mesh_entry *ment = mesh[i];
2112 file->type = ment->type;
2113 file->io = ment->io;
2114 file->refine = ment->refine;
2115
2116 if (flag_rank_none) {
2117 flag_rank = 0;
2118
2119 } else {
2120 if (is_entire_mesh(file->type)) {
2121 flag_rank = 0;
2122
2123 } else {
2124 flag_rank = 1;
2125 }
2126 }
2127
2128 fname = HECMW_malloc(sizeof(char) * (HECMW_FILENAME_LEN + 1));
2129
2130 if (fname == NULL) {
2131 HECMW_set_error(errno, "");
2132 return NULL;
2133 }
2134
2135 if (ment->type == HECMW_CTRL_FTYPE_HECMW_ENTIRE) {
2136 retval = make_filename_r(NULL, NULL, NULL, ment->filename, "", myrank,
2137 flag_rank, fname, HECMW_FILENAME_LEN);
2138
2139 } else {
2140 if (subdir_on && nrank > nlimit) {
2141 irank = myrank / nlimit;
2142 sprintf(prefix, "TRUNK%d", irank);
2143 retval = make_filename_r("MESH", NULL, prefix, ment->filename, "", myrank,
2144 flag_rank, fname, HECMW_FILENAME_LEN);
2145
2146 } else if (subdir_on && ment->type == HECMW_CTRL_FTYPE_HECMW_DIST) {
2147 retval = make_filename_r("MESH", NULL, NULL, ment->filename, "", myrank,
2148 flag_rank, fname, HECMW_FILENAME_LEN);
2149
2150 } else if (subdir_on && nrank > 1) {
2151 retval = make_filename_r("MESH", NULL, NULL, ment->filename, "", myrank,
2152 flag_rank, fname, HECMW_FILENAME_LEN);
2153
2154 } else {
2155 retval = make_filename_r(NULL, NULL, NULL, ment->filename, "", myrank,
2156 flag_rank, fname, HECMW_FILENAME_LEN);
2157 }
2158 }
2159
2160 if (retval == NULL) {
2161 HECMW_set_error(HECMW_IO_E0002, "Cannot create mesh filename");
2162 HECMW_free(fname);
2163 return NULL;
2164 }
2165
2166 file->filename = fname;
2167 }
2168
2169 return files;
2170 }
2171
get_meshfiles(char * name_ID,int n_rank,int i_rank,int flag_rank_none)2172 static struct hecmw_ctrl_meshfiles *get_meshfiles(char *name_ID, int n_rank,
2173 int i_rank,
2174 int flag_rank_none) {
2175 struct mesh_entry *mesh;
2176 struct mesh_grp_entry *mesh_grp;
2177 struct hecmw_ctrl_meshfiles *files = NULL;
2178 mesh_grp = get_mesh_grp_entry(name_ID);
2179
2180 if (mesh_grp) {
2181 files = make_meshfiles_struct(mesh_grp->n_mesh, mesh_grp->mesh, n_rank,
2182 i_rank, flag_rank_none);
2183
2184 if (files == NULL) return NULL;
2185 }
2186
2187 if (files == NULL) {
2188 mesh = get_mesh_entry(name_ID);
2189
2190 if (mesh) {
2191 files = make_meshfiles_struct(1, &mesh, n_rank, i_rank, flag_rank_none);
2192
2193 if (files == NULL) return NULL;
2194 }
2195 }
2196
2197 if (files == NULL) {
2198 HECMW_set_error(HECMW_UTIL_E0014, "NAME: %s", name_ID);
2199 return NULL;
2200 }
2201
2202 return files;
2203 }
2204
HECMW_ctrl_get_meshfiles(char * name_ID)2205 struct hecmw_ctrl_meshfiles *HECMW_ctrl_get_meshfiles(char *name_ID) {
2206 return get_meshfiles(name_ID, 0, 0, 0);
2207 }
2208
HECMW_ctrl_get_meshfiles_header(char * name_ID)2209 struct hecmw_ctrl_meshfiles *HECMW_ctrl_get_meshfiles_header(char *name_ID) {
2210 return get_meshfiles(name_ID, 0, 0, 1);
2211 }
2212
HECMW_ctrl_get_meshfiles_sub(char * name_ID,int n_rank,int i_rank)2213 struct hecmw_ctrl_meshfiles *HECMW_ctrl_get_meshfiles_sub(char *name_ID,
2214 int n_rank,
2215 int i_rank) {
2216 return get_meshfiles(name_ID, n_rank, i_rank, 0);
2217 }
2218
HECMW_ctrl_get_meshfiles_header_sub(char * name_ID,int n_rank,int i_rank)2219 struct hecmw_ctrl_meshfiles *HECMW_ctrl_get_meshfiles_header_sub(char *name_ID,
2220 int n_rank,
2221 int i_rank) {
2222 return get_meshfiles(name_ID, n_rank, i_rank, 1);
2223 }
2224
get_result_file(char * name_ID,int istep,int n_rank,int i_rank,int * fg_text,int flag_rank_none)2225 static char *get_result_file(char *name_ID, int istep, int n_rank,
2226 int i_rank, int *fg_text, int flag_rank_none) {
2227 int nrank, myrank, irank;
2228 char *fname, *retfname;
2229 struct result_entry *result;
2230 char subname[10], prefix[10];
2231 result = get_result_entry(name_ID);
2232
2233 if (result == NULL) {
2234 HECMW_set_error(HECMW_UTIL_E0024, "NAME: %s",
2235 name_ID ? name_ID : "Not specified");
2236 return NULL;
2237 }
2238
2239 if (n_rank == 0) {
2240 nrank = HECMW_comm_get_size();
2241 myrank = HECMW_comm_get_rank();
2242
2243 } else {
2244 nrank = n_rank;
2245 myrank = i_rank;
2246 }
2247
2248 if (subdir_on && !strcmp(name_ID, "vis_out")) {
2249 fname = make_filename(name_ID, NULL, NULL, result->filename, "", myrank,
2250 flag_rank_none);
2251
2252 } else if (subdir_on && nrank > nlimit) {
2253 sprintf(subname, "STEP%d", istep);
2254 irank = myrank / nlimit;
2255 sprintf(prefix, "TRUNK%d", irank);
2256 fname = make_filename(name_ID, subname, prefix, result->filename, "",
2257 myrank, flag_rank_none);
2258
2259 } else if (subdir_on) {
2260 sprintf(subname, "STEP%d", istep);
2261 fname = make_filename(name_ID, subname, NULL, result->filename, "", myrank,
2262 flag_rank_none);
2263
2264 } else {
2265 fname = make_filename(NULL, NULL, NULL, result->filename, "", myrank,
2266 flag_rank_none);
2267 }
2268
2269 if (fname == NULL) {
2270 HECMW_set_error(HECMW_IO_E0002, "Cannot create result filename");
2271 return NULL;
2272 }
2273
2274 retfname = HECMW_strdup(fname);
2275
2276 if (retfname == NULL) {
2277 HECMW_set_error(errno, "");
2278 return NULL;
2279 }
2280
2281 *fg_text = result->fg_text;
2282 return retfname;
2283 }
2284
get_filename_body(char * file)2285 static char *get_filename_body(char *file) {
2286 static char filename[HECMW_FILENAME_LEN+1];
2287 strcpy(filename, "");
2288 strcat(filename, file);
2289 return filename;
2290 }
2291
get_result_filebody(char * name_ID)2292 static char *get_result_filebody(char *name_ID) {
2293 struct result_entry *result;
2294 char *fname, *retfname;
2295
2296 result = get_result_entry(name_ID);
2297
2298 if (result == NULL) {
2299 HECMW_set_error(HECMW_UTIL_E0024, "NAME: %s",
2300 name_ID ? name_ID : "Not specified");
2301 return NULL;
2302 }
2303
2304 fname = get_filename_body(result->filename);
2305
2306 retfname = HECMW_strdup(fname);
2307
2308 if (retfname == NULL) {
2309 HECMW_set_error(errno, "");
2310 return NULL;
2311 }
2312
2313 return retfname;
2314 }
2315
HECMW_ctrl_get_result_file(char * name_ID,int istep,int * fg_text)2316 char *HECMW_ctrl_get_result_file(char *name_ID, int istep,
2317 int *fg_text) {
2318 return get_result_file(name_ID, istep, 0, 0, fg_text, 1);
2319 }
2320
HECMW_ctrl_get_result_fileheader(char * name_ID,int istep,int * fg_text)2321 char *HECMW_ctrl_get_result_fileheader(char *name_ID, int istep,
2322 int *fg_text) {
2323 return get_result_file(name_ID, istep, 0, 0, fg_text, 0);
2324 }
2325
HECMW_ctrl_get_result_file_sub(char * name_ID,int istep,int n_rank,int i_rank,int * fg_text)2326 char *HECMW_ctrl_get_result_file_sub(char *name_ID, int istep,
2327 int n_rank, int i_rank, int *fg_text) {
2328 return get_result_file(name_ID, istep, n_rank, i_rank, fg_text, 1);
2329 }
2330
HECMW_ctrl_get_result_fileheader_sub(char * name_ID,int istep,int n_rank,int i_rank,int * fg_text)2331 char *HECMW_ctrl_get_result_fileheader_sub(char *name_ID, int istep,
2332 int n_rank, int i_rank,
2333 int *fg_text) {
2334 return get_result_file(name_ID, istep, n_rank, i_rank, fg_text, 0);
2335 }
2336
HECMW_ctrl_get_result_filebody(char * name_ID)2337 char *HECMW_ctrl_get_result_filebody(char *name_ID) {
2338 return get_result_filebody(name_ID);
2339 }
2340
HECMW_ctrl_get_restart_file(char * name_ID)2341 char *HECMW_ctrl_get_restart_file(char *name_ID) {
2342 int nrank, myrank, irank;
2343 char *fname, *retfname;
2344 struct restart_entry *restart;
2345 char prefix[10];
2346 restart = get_restart_entry(name_ID);
2347
2348 if (restart == NULL) {
2349 HECMW_set_error(HECMW_UTIL_E0044, "NAME: %s",
2350 name_ID ? name_ID : "Not specified");
2351 return NULL;
2352 }
2353
2354 nrank = HECMW_comm_get_size();
2355 myrank = HECMW_comm_get_rank();
2356
2357 if (subdir_on && nrank > nlimit) {
2358 irank = myrank / nlimit;
2359 sprintf(prefix, "TRUNK%d", irank);
2360 fname =
2361 make_filename(name_ID, NULL, prefix, restart->filename, "", myrank, 1);
2362
2363 } else if (subdir_on) {
2364 fname =
2365 make_filename(name_ID, NULL, NULL, restart->filename, "", myrank, 1);
2366
2367 } else {
2368 fname = make_filename(NULL, NULL, NULL, restart->filename, "", myrank, 1);
2369 }
2370
2371 if (fname == NULL) {
2372 HECMW_set_error(HECMW_IO_E0002, "Cannot create restart filename");
2373 return NULL;
2374 }
2375
2376 retfname = HECMW_strdup(fname);
2377
2378 if (retfname == NULL) {
2379 HECMW_set_error(errno, "");
2380 return NULL;
2381 }
2382
2383 return retfname;
2384 }
2385
HECMW_ctrl_get_restart_file_by_io(int io)2386 char *HECMW_ctrl_get_restart_file_by_io(int io) {
2387 int nrank, myrank, irank;
2388 char *fname, *retfname;
2389 struct restart_entry *p;
2390 char prefix[10];
2391 p = get_restart_entry_by_io(io);
2392
2393 if (p == NULL) {
2394 HECMW_set_error(HECMW_UTIL_E0045, "");
2395 return NULL;
2396 }
2397
2398 nrank = HECMW_comm_get_size();
2399 myrank = HECMW_comm_get_rank();
2400
2401 if (subdir_on && nrank > nlimit) {
2402 irank = myrank / nlimit;
2403 sprintf(prefix, "TRUNK%d", irank);
2404 fname = make_filename(p->name_ID, NULL, prefix, p->filename, "", myrank, 1);
2405
2406 } else if (subdir_on) {
2407 fname = make_filename(p->name_ID, NULL, NULL, p->filename, "", myrank, 1);
2408
2409 } else {
2410 fname = make_filename(NULL, NULL, NULL, p->filename, "", myrank, 1);
2411 }
2412
2413 if (fname == NULL) {
2414 HECMW_set_error(HECMW_IO_E0002, "Cannot create restart filename");
2415 return NULL;
2416 }
2417
2418 retfname = HECMW_strdup(fname);
2419
2420 if (retfname == NULL) {
2421 HECMW_set_error(errno, "");
2422 return NULL;
2423 }
2424
2425 return retfname;
2426 }
2427
HECMW_ctrl_get_control_file(char * name_ID)2428 char *HECMW_ctrl_get_control_file(char *name_ID) {
2429 char *fname;
2430 struct ctrl_entry *ctrl;
2431 ctrl = get_ctrl_entry(name_ID);
2432
2433 if (ctrl == NULL) {
2434 HECMW_set_error(HECMW_UTIL_E0033, "NAME: %s",
2435 name_ID ? name_ID : "Not specified");
2436 return NULL;
2437 }
2438
2439 fname = HECMW_strdup(ctrl->filename);
2440 return fname;
2441 }
2442
HECMW_ctrl_is_exists_control(char * name_ID)2443 int HECMW_ctrl_is_exists_control(char *name_ID) {
2444 return get_ctrl_entry(name_ID) ? 1 : 0;
2445 }
2446
HECMW_ctrl_make_subdir(char * filename)2447 int HECMW_ctrl_make_subdir(char *filename) {
2448 char fname[HECMW_FILENAME_LEN + 1];
2449 char dirname[HECMW_FILENAME_LEN + 1];
2450 char *token;
2451 char separator[10];
2452 char *saveptr;
2453 mode_t mode;
2454 DIR *dp;
2455 #ifndef _WINDOWS
2456 mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
2457 #endif
2458 strcpy(fname, filename);
2459 sprintf(separator, "%c", HECMW_get_path_separator());
2460 #if defined(__WIN32__) || defined(__WIN64__)
2461 /* strtok is thread-safe on Windows */
2462 token = strtok(fname, separator);
2463 sprintf(dirname, "%s", token);
2464 token = strtok(NULL, separator);
2465 #else
2466 token = strtok_r(fname, separator, &saveptr);
2467 sprintf(dirname, "%s", token);
2468 token = strtok_r(NULL, separator, &saveptr);
2469 #endif
2470
2471 while (token) {
2472 if ((dp = opendir(dirname)) == NULL) {
2473 #ifndef _WINDOWS
2474
2475 if (mkdir(dirname, mode) != 0) {
2476 #else
2477
2478 if (mkdir(dirname) != 0) {
2479 #endif
2480
2481 if (errno != EEXIST) return -1;
2482 }
2483
2484 } else {
2485 closedir(dp);
2486 }
2487
2488 strcat(dirname, separator);
2489 strcat(dirname, token);
2490 #if defined(__WIN32__) || defined(__WIN64__)
2491 token = strtok(NULL, separator);
2492 #else
2493 token = strtok_r(NULL, separator, &saveptr);
2494 #endif
2495 }
2496
2497 return 0;
2498 }
2499
2500 int HECMW_ctrl_is_subdir(void) { return subdir_on; }
2501
2502 /*---------------------------------------------------------------------------*/
2503
2504 void hecmw_ctrl_init_if(int *err) {
2505 *err = 1;
2506
2507 if (HECMW_ctrl_init()) return;
2508
2509 *err = 0;
2510 }
2511
2512 void hecmw_ctrl_init_if_(int *err) { hecmw_ctrl_init_if(err); }
2513
2514 void hecmw_ctrl_init_if__(int *err) { hecmw_ctrl_init_if(err); }
2515
2516 void HECMW_CTRL_INIT_IF(int *err) { hecmw_ctrl_init_if(err); }
2517
2518 /*---------------------------------------------------------------------------*/
2519
2520 void hecmw_ctrl_init_ex_if(char *ctrlfile, int *err, int len) {
2521 char c_ctrlfile[HECMW_FILENAME_LEN + 1];
2522 *err = 1;
2523
2524 if (HECMW_strcpy_f2c_r(ctrlfile, len, c_ctrlfile, sizeof(c_ctrlfile)) == NULL)
2525 return;
2526
2527 if (HECMW_ctrl_init_ex(c_ctrlfile)) return;
2528
2529 *err = 0;
2530 }
2531
2532 void hecmw_ctrl_init_ex_if_(char *ctrlfile, int *err, int len) {
2533 hecmw_ctrl_init_ex_if(ctrlfile, err, len);
2534 }
2535
2536 void hecmw_ctrl_init_ex_if__(char *ctrlfile, int *err, int len) {
2537 hecmw_ctrl_init_ex_if(ctrlfile, err, len);
2538 }
2539
2540 void HECMW_CTRL_INIT_EX_IF(char *ctrlfile, int *err, int len) {
2541 hecmw_ctrl_init_ex_if(ctrlfile, err, len);
2542 }
2543
2544 /*---------------------------------------------------------------------------*/
2545
2546 void hecmw_ctrl_finalize_if(void) { HECMW_ctrl_finalize(); }
2547
2548 void hecmw_ctrl_finalize_if_(void) { hecmw_ctrl_finalize_if(); }
2549
2550 void hecmw_ctrl_finalize_if__(void) { hecmw_ctrl_finalize_if(); }
2551
2552 void HECMW_CTRL_FINALIZE_IF(void) { hecmw_ctrl_finalize_if(); }
2553
2554 /*---------------------------------------------------------------------------*/
2555
2556 void hecmw_ctrl_get_control_file_if(char *name_ID, char *buf, int *err,
2557 int name_len, int buf_len) {
2558 char c_name_ID[HECMW_NAME_LEN + 1];
2559 char *c_buf;
2560 int ret;
2561 *err = 1;
2562
2563 if (HECMW_strcpy_f2c_r(name_ID, name_len, c_name_ID, sizeof(c_name_ID)) ==
2564 NULL)
2565 return;
2566
2567 if ((c_buf = HECMW_ctrl_get_control_file(c_name_ID)) == NULL) return;
2568
2569 ret = HECMW_strcpy_c2f(c_buf, buf, buf_len);
2570 HECMW_free(c_buf);
2571
2572 if (ret == 0) return;
2573
2574 *err = 0;
2575 }
2576
2577 void hecmw_ctrl_get_control_file_if_(char *name_ID, char *buf, int *err,
2578 int name_len, int buf_len) {
2579 hecmw_ctrl_get_control_file_if(name_ID, buf, err, name_len, buf_len);
2580 }
2581
2582 void hecmw_ctrl_get_control_file_if__(char *name_ID, char *buf, int *err,
2583 int name_len, int buf_len) {
2584 hecmw_ctrl_get_control_file_if(name_ID, buf, err, name_len, buf_len);
2585 }
2586
2587 void HECMW_CTRL_GET_CONTROL_FILE_IF(char *name_ID, char *buf, int *err,
2588 int name_len, int buf_len) {
2589 hecmw_ctrl_get_control_file_if(name_ID, buf, err, name_len, buf_len);
2590 }
2591
2592 /*---------------------------------------------------------------------------*/
2593
2594 void hecmw_ctrl_make_subdir(char *filename, int *err, int len) {
2595 char fname[HECMW_FILENAME_LEN + 1];
2596 *err = 1;
2597
2598 if (HECMW_strcpy_f2c_r(filename, len, fname, sizeof(fname)) == NULL) return;
2599
2600 if (HECMW_ctrl_make_subdir(fname) != 0) return;
2601
2602 *err = 0;
2603 }
2604
2605 void hecmw_ctrl_make_subdir_(char *filename, int *err, int len) {
2606 hecmw_ctrl_make_subdir(filename, err, len);
2607 }
2608
2609 void hecmw_ctrl_make_subdir__(char *filename, int *err, int len) {
2610 hecmw_ctrl_make_subdir(filename, err, len);
2611 }
2612
2613 void HECMW_CTRL_MAKE_SUBDIR(char *filename, int *err, int len) {
2614 hecmw_ctrl_make_subdir(filename, err, len);
2615 }
2616
2617 /*---------------------------------------------------------------------------*/
2618
2619 void hecmw_ctrl_is_subdir(int *flag, int *limit) {
2620 *flag = subdir_on;
2621 *limit = nlimit;
2622 }
2623
2624 void hecmw_ctrl_is_subdir_(int *flag, int *limit) {
2625 hecmw_ctrl_is_subdir(flag, limit);
2626 }
2627
2628 void hecmw_ctrl_is_subdir__(int *flag, int *limit) {
2629 hecmw_ctrl_is_subdir(flag, limit);
2630 }
2631
2632 void HECMW_CTRL_IS_SUBDIR(int *flag, int *limit) {
2633 hecmw_ctrl_is_subdir(flag, limit);
2634 }
2635