FrontISTR 5.2.0
Large-scale structural analysis program with finit element method
Loading...
Searching...
No Matches
CHECData.cpp
Go to the documentation of this file.
1/*****************************************************************************
2 * Copyright (c) 2019 FrontISTR Commons
3 * This software is released under the MIT License, see LICENSE.txt
4 *****************************************************************************/
5/*
6 CHECData Ver.1.0
7*/
8
9#include <stdarg.h>
10#include <assert.h>
11#include "CHECData.h"
12#include "hecd_util.h"
13
14using namespace std;
15using namespace hecd_util;
16
17//=============================================================================
18// common
19//=============================================================================
20
22
24
26 vector<CHECDataBlock *>::iterator iter;
27
28 for (iter = DB.begin(); iter != DB.end(); iter++) {
29 delete *iter;
30 }
31
32 DB.clear();
33}
34
35void CHECData::StoreDataBlock(CHECDataBlock *block) { DB.push_back(block); }
36
37//=============================================================================
38// Save
39//=============================================================================
40
41bool CHECData::Save(const char *file_name) {
42 strcpy(fname, file_name);
43 fp = fopen(fname, "w");
44
45 if (!fp) return false;
46
47 vector<CHECDataBlock *>::iterator iter;
48
49 for (iter = DB.begin(); iter != DB.end(); iter++) {
50 (*iter)->Write(this);
51 }
52
53 fclose(fp);
54 fp = 0;
55 return true;
56}
57
58void CHECData::WriteLine(const char *s) { fprintf(fp, "%s\n", s); }
59
60// ----------------------------------------------------------------------------
61// Header Line
62// ----------------------------------------------------------------------------
63// fmt : format of parameters.
64// Each character specify the parameter's type
65// 'I': integer, 'F':float, 'S':string
66// ... : piars of parameter name and value
67
68void CHECData::WriteHeader(const char *name, const char *fmt, ...) {
69 va_list va;
70 va_start(va, fmt);
71 int n = strlen(fmt);
72 char *c = (char *)fmt;
73 char line[256];
74 char param[256];
75 char s[256];
76 strcpy(line, name);
77
78 for (int i = 0; i < n; i++, c++) {
79 strcpy(param, va_arg(va, char *));
80 strcat(line, ",");
81 strcat(line, param);
82 strcat(line, "=");
83
84 switch (*c) {
85 case 'I':
86 sprintf(s, "%d", va_arg(va, int));
87 break;
88
89 case 'F':
90 // sprintf(s, "%lg", va_arg(va, double));
91 ftos(va_arg(va, double), s);
92 break;
93
94 case 'S':
95 sprintf(s, "%s", va_arg(va, char *));
96 break;
97
98 default:
99 assert(0);
100 }
101
102 strcat(line, s);
103 }
104
105 fprintf(fp, "%s\n", line);
106 va_end(va);
107}
108
109// ----------------------------------------------------------------------------
110// Parameter Line
111// ----------------------------------------------------------------------------
112
113void CHECData::WriteParameter(const char *fmt, ...) {
114 va_list va;
115 va_start(va, fmt);
116 int n = strlen(fmt);
117 char *c = (char *)fmt;
118 char line[256];
119 char param[256];
120 char s[256];
121 strcpy(line, "!");
122
123 for (int i = 0; i < n; i++, c++) {
124 strcpy(param, va_arg(va, char *));
125
126 if (i != 0) strcat(line, ",");
127
128 strcat(line, param);
129 strcat(line, "=");
130
131 switch (*c) {
132 case 'I':
133 sprintf(s, "%d", va_arg(va, int));
134 break;
135
136 case 'F':
137 // sprintf(s, "%lg", va_arg(va, double));
138 ftos(va_arg(va, double), s);
139 break;
140
141 case 'S':
142 sprintf(s, "%s", va_arg(va, char *));
143 break;
144
145 default:
146 assert(0);
147 }
148
149 strcat(line, s);
150 }
151
152 fprintf(fp, "%s\n", line);
153 va_end(va);
154}
155
156// ----------------------------------------------------------------------------
157// Data Line
158// ----------------------------------------------------------------------------
159// fmt : formt of data like one of WriteHeader
160// ... : values to write the file.
161
162void CHECData::WriteData(const char *fmt, ...) {
163 va_list va;
164 va_start(va, fmt);
165 int n = strlen(fmt);
166 char *c = (char *)fmt;
167 char line[256];
168 char s[256];
169 line[0] = 0;
170
171 for (int i = 0; i < n; i++, c++) {
172 if (i != 0) strcat(line, ",");
173
174 switch (*c) {
175 case 'I':
176 sprintf(s, "%d", va_arg(va, int));
177 break;
178
179 case 'F':
180 // sprintf(s, "%lg", va_arg(va, double));
181 ftos(va_arg(va, double), s);
182 break;
183
184 case 'S':
185 sprintf(s, "%s", va_arg(va, char *));
186 break;
187
188 default:
189 assert(0);
190 }
191
192 strcat(line, s);
193 }
194
195 fprintf(fp, "%s\n", line);
196 va_end(va);
197}
198
200
201void CHECData::AddDataLineItems(const char *fmt, ...) {
202 va_list va;
203 va_start(va, fmt);
204 int n = strlen(fmt);
205 char *c = (char *)fmt;
206 char s[256];
207
208 for (int i = 0; i < n; i++, c++) {
209 switch (*c) {
210 case 'I':
211 sprintf(s, "%d", va_arg(va, int));
212 break;
213
214 case 'F':
215 // sprintf(s, "%lg", va_arg(va, double));
216 ftos(va_arg(va, double), s);
217 break;
218
219 case 'S':
220 sprintf(s, "%s", va_arg(va, char *));
221 break;
222
223 default:
224 assert(0);
225 }
226
227 strcat(data_line_buffer, s);
228 strcat(data_line_buffer, ",");
229 }
230
231 va_end(va);
232}
233
235 int len = strlen(data_line_buffer);
236 char *p = &data_line_buffer[len - 1];
237
238 // remove ',' of tail
239 while (p >= data_line_buffer) {
240 if (*p == ',') {
241 *p = 0;
242 break;
243
244 } else if (*p == ' ') {
245 *p = 0;
246
247 } else {
248 break;
249 }
250
251 p--;
252 }
253
254 fprintf(fp, "%s\n", data_line_buffer);
256}
257
258//=============================================================================
259// Load
260//=============================================================================
261
262bool CHECData::Load(const char *file_name) {
263 Clear();
264 return AddLoad(file_name);
265}
266
267bool CHECData::AddLoad(const char *file_name) {
268 line_count = 0;
269 fg_header_pushed = false;
270 strcpy(fname, file_name);
271 fp = fopen(fname, "r");
272
273 if (!fp) return false;
274
275 char line[256];
276 char header_name[256];
277 CHECDataBlock *block;
278
279 while (ReadLine(line)) {
280 if (!GetHeaderName(line, header_name)) {
281 fclose(fp);
282 return false;
283 }
284
285 if (strcmp(header_name, "!END") == 0) break;
286
287 block = CreateDataBlock(header_name);
288
289 if (!block) {
290 fclose(fp);
291 return false;
292 }
293
294 if (!block->Read(this, line)) {
295 fclose(fp);
296 return false;
297 }
298
299 DB.push_back(block);
300 }
301
302 fclose(fp);
303 fp = 0;
304 return true;
305}
306
307bool CHECData::ReadLine(char *s, int size) {
308 line_count++;
309
310 if (fg_header_pushed) {
311 strcpy(s, header_line_buffer);
312 fg_header_pushed = false;
313 return true;
314 }
315
316 while (fgets(s, size, fp)) {
317 if (s[0] == 0 || s[0] == '#' || s[0] == '\r' || s[0] == '\n') continue;
318
319 if (s[0] == '!' && s[1] == '!') continue;
320
321 remove_cr(s);
322 return true;
323 }
324
325 return false;
326}
327
328void CHECData::PushReadLine(const char *s) {
329 strcpy(header_line_buffer, s);
330 fg_header_pushed = true;
331 line_count--;
332}
333
334CHECDataBlock *CHECData::CreateDataBlock(const char *header_name) {
335 return CreateHECDataBlock(header_name);
336}
337
338bool CHECData::GetHeaderName(const char *header_line, char *header_name) {
339#define is_separator(x) \
340 (x == ',' || x == ' ' || x == '\t' || x == '\r' || x == '\n')
341 char *p = (char *)header_line;
342
343 while (*p && is_separator(*p)) p++;
344
345 if (*p != '!') return false;
346
347 char *bp = header_name;
348
349 while (*p && !is_separator(*p)) {
350 *bp = (char)toupper(*p);
351 p++;
352 bp++;
353 }
354
355 *bp = 0;
356 return true;
357#undef is_separator
358}
359
360//-----------------------------------------------------------------------------
361// ParseHeader
362//-----------------------------------------------------------------------------
363// rcode[i] : 1 -- set, 0 -- not set, -1 -- error
364// fmt : string composed by following characters
365// 'I' : int
366// 'F' : double
367// 'S' : char*
368// 'E' : int (exist or not)
369// ... : pairs of a parameter name and a pointer of the parameter
370// example)
371// char* line = "!SOLVER, TYPE=CG, PRECOND=1, ITERLOG=YES";
372// int rcode[3];
373// char type[30]; int precond; char iterlog[30];
374// ParseHeader(line,rcode,"SIS","TYPE",type,"PRECOND",&precond,"ITERLOG",iterlog);
375//-----------------------------------------------------------------------------
376
377static bool get_param_token(char *&p, char *token) {
378#define is_separator(x) \
379 (x == ',' || x == ' ' || x == '\t' || x == '\r' || x == '\n')
380
381 while (*p && is_separator(*p)) p++;
382
383 if (!*p) return false;
384
385 char *t = token;
386
387 if (*p == '=') {
388 t[0] = '=';
389 t[1] = 0;
390 p++;
391 return true;
392 }
393
394 while (*p && is_separator(*p)) p++;
395
396 if (!*p) return false;
397
398 while (*p && !is_separator(*p) && *p != '=') {
399 *t = *p;
400 t++;
401 p++;
402 }
403
404 *t = 0;
405 return true;
406}
407
408bool CHECData::vParseParameter(char *line, int *rcode, const char *fmt,
409 va_list va) {
410 const int max_param_n = 40;
411 char param_name[max_param_n][20];
412 void *param[max_param_n];
413 int param_n = strlen(fmt);
414 int i;
415 int *ip;
416
417 for (i = 0; i < param_n; i++) {
418 strcpy(param_name[i], va_arg(va, char *));
419 param[i] = va_arg(va, void *);
420 rcode[i] = 0;
421
422 if (fmt[i] == 'E') {
423 ip = (int *)param[i];
424 *ip = 0;
425 }
426 }
427
428 char *p = line;
429 char p_token[50];
430 char eq_token[50];
431 char v_token[50];
432 char p_str[50];
433
434 while (get_param_token(p, p_token)) {
435 cleanup_token(p_token, p_str);
436 toupper(p_str);
437
438 for (i = 0; i < param_n; i++) {
439 if (strcmp(p_str, param_name[i]) == 0) break;
440 }
441
442 if (i == param_n) return false;
443
444 // ---------------------------------
445 if (fmt[i] == 'E') {
446 rcode[i] = 1;
447 ip = (int *)param[i];
448 *ip = 1;
449 continue;
450 }
451
452 // ---------------------------------
453 if (!get_param_token(p, eq_token) || eq_token[0] != '=') {
454 rcode[i] = -1;
455 return false;
456 }
457
458 if (!get_param_token(p, v_token)) {
459 rcode[i] = -1;
460 return false;
461 }
462
463 switch (fmt[i]) {
464 case 'S':
465 if (sscanf(v_token, "%s", (char *)(param[i])) != 1) {
466 rcode[i] = -1;
467 return false;
468 }
469
470 break;
471
472 case 'I':
473 if (sscanf(v_token, "%d", (int *)(param[i])) != 1) {
474 rcode[i] = -1;
475 return false;
476 }
477
478 break;
479
480 case 'F':
481 if (sscanf(v_token, "%lf", (double *)(param[i])) != 1) {
482 rcode[i] = -1;
483 return false;
484 }
485
486 break;
487
488 default:
489 assert(0);
490 }
491
492 rcode[i] = 1;
493 }
494
495 return true;
496}
497
498bool CHECData::ParseParameter(char *line, int *rcode, const char *fmt, ...) {
499 va_list va;
500 va_start(va, fmt);
501 bool fg = vParseParameter(line, rcode, fmt, va);
502 va_end(va);
503 return fg;
504}
505
506bool CHECData::ParseHeader(char *header_line, int *rcode, const char *fmt,
507 ...) {
508 char *p = header_line;
509
510 while (*p) {
511 if (*p == ',' || *p == '\r' || *p == '\n') {
512 break;
513 }
514
515 p++;
516 }
517
518 va_list va;
519 va_start(va, fmt);
520 bool fg = vParseParameter(p, rcode, fmt, va);
521 va_end(va);
522 return fg;
523}
524
525bool CHECData::ReadParameter(int *rcode, const char *fmt, ...) {
526 char line[256];
527
528 if (!ReadLine(line)) return false;
529
530 char *p = line;
531
532 if (*p == '!') p++;
533
534 va_list va;
535 va_start(va, fmt);
536 bool fg = vParseParameter(p, rcode, fmt, va);
537 va_end(va);
538 return fg;
539}
540
541//-----------------------------------------------------------------------------
542// ReadData
543//-----------------------------------------------------------------------------
544// fmt : string composed by 'I', 'F' or 'S'
545// ... : pointers of parameter
546//-----------------------------------------------------------------------------
547
548bool CHECData::ReadData(int *rcode, const char *fmt, ...) {
549 char line[256];
550
551 if (!ReadLine(line)) return false;
552
553 if (line[0] == '!') {
554 PushReadLine(line);
555 return false;
556 }
557
558 const int max_param_n = 100;
559 int i;
560 int param_n = strlen(fmt);
561 void *param[max_param_n];
562 va_list va;
563 va_start(va, fmt);
564
565 for (i = 0; i < param_n; i++) {
566 param[i] = va_arg(va, void *);
567 rcode[i] = 0;
568 }
569
570 va_end(va);
571 char *token = strtok(line, ",\r\n");
572 i = 0;
573
574 while (token && i < param_n) {
575 switch (fmt[i]) {
576 case 'I':
577 if (sscanf(token, "%d", (int *)(param[i])) != 1) return false;
578
579 break;
580
581 case 'F':
582 if (sscanf(token, "%lf", (double *)(param[i])) != 1) return false;
583
584 break;
585
586 case 'S':
587 if (sscanf(token, "%s", (char *)(param[i])) != 1) return false;
588
589 break;
590
591 default:
592 assert(0);
593 }
594
595 rcode[i] = 1;
596 token = strtok(0, ",\r\n");
597 i++;
598 }
599
600 return true;
601}
602
603int CHECData::ParseDoubleDataArray(char *line, double *data) {
604 int n = 0;
605 char *token = strtok(line, ",\r\n");
606
607 while (token) {
608 if (sscanf(token, "%lf", &data[n]) != 1) return -(n + 1);
609
610 n++;
611 token = strtok(0, ",\r\n");
612 }
613
614 return n;
615}
616
617int CHECData::ParseIntDataArray(char *line, int *data) {
618 int n = 0;
619 char *token = strtok(line, ",\r\n");
620
621 while (token) {
622 if (sscanf(token, "%d", &data[n]) != 1) return -(n + 1);
623
624 n++;
625 token = strtok(0, ",\r\n");
626 }
627
628 return n;
629}
630
631//=============================================================================
632// Utility
633//=============================================================================
634
635template <class T>
636T hecdata_get(CHECData *hd, int data_type, const char *name) {
637 vector<CHECDataBlock *>::iterator iter;
638
639 for (iter = hd->DB.begin(); iter != hd->DB.end(); iter++) {
640 if ((*iter)->data_type == data_type) {
641 T block = (T)(*iter);
642
643 if (strcmp(block->name, name) == 0) {
644 return block;
645 }
646 }
647 }
648
649 return 0;
650}
651
653 return hecdata_get<CHECDB_Material *>(this, HECDB_MATERIAL, name);
654}
655
657 return hecdata_get<CHECDB_NGroup *>(this, HECDB_NGROUP, name);
658}
659
661 return hecdata_get<CHECDB_EGroup *>(this, HECDB_EGROUP, name);
662}
663
665 return hecdata_get<CHECDB_SGroup *>(this, HECDB_SGROUP, name);
666}
667
669 vector<CHECDataBlock *>::iterator iter;
670
671 for (iter = DB.begin(); iter != DB.end(); iter++) {
672 if ((*iter)->data_type != HECDB_NODE) continue;
673
674 CHECDB_Node::CNodeItem *nitem = ((CHECDB_Node *)(*iter))->GetNode(id);
675
676 if (nitem) return nitem;
677 }
678
679 return 0;
680}
681
683 vector<CHECDataBlock *>::iterator iter;
684
685 for (iter = DB.begin(); iter != DB.end(); iter++) {
686 if ((*iter)->data_type != HECDB_ELEMENT) continue;
687
688 CHECDB_Element::CElemItem *eitem = ((CHECDB_Element *)(*iter))->GetElem(id);
689
690 if (eitem) return eitem;
691 }
692
693 return 0;
694}
695
697 vector<CHECDataBlock *>::iterator iter;
698
699 for (iter = DB.begin(); iter != DB.end(); iter++) {
700 if ((*iter)->data_type != HECDB_ELEMENT) continue;
701
702 CHECDB_Element::CElemItem *eitem = ((CHECDB_Element *)(*iter))->GetElem(id);
703
704 if (eitem) return ((CHECDB_Element *)(*iter))->type;
705 }
706
707 return 0;
708}
CHECDataBlock * CreateHECDataBlock(const char *header_name)
Definition: HECDB_util.cpp:16
@ HECDB_EGROUP
Definition: CHECDB.h:24
@ HECDB_MATERIAL
Definition: CHECDB.h:21
@ HECDB_NODE
Definition: CHECDB.h:19
@ HECDB_SGROUP
Definition: CHECDB.h:25
@ HECDB_ELEMENT
Definition: CHECDB.h:20
@ HECDB_NGROUP
Definition: CHECDB.h:23
#define is_separator(x)
T hecdata_get(CHECData *hd, int data_type, const char *name)
Definition: CHECData.cpp:636
virtual bool Read(class CHECData *hecd, char *header_line)=0
int line_count
Definition: CHECData.h:29
virtual int ParseIntDataArray(char *line, int *data)
Definition: CHECData.cpp:617
virtual void WriteDataLine()
Definition: CHECData.cpp:234
virtual class CHECDB_Node::CNodeItem * GetNodeItem(int id)
Definition: CHECData.cpp:668
virtual bool ReadData(int *rcode, const char *fmt,...)
Definition: CHECData.cpp:548
virtual void WriteParameter(const char *fmt="",...)
Definition: CHECData.cpp:113
bool fg_header_pushed
Definition: CHECData.h:106
virtual ~CHECData()
Definition: CHECData.cpp:23
virtual bool ParseParameter(char *line, int *rcode, const char *fmt,...)
Definition: CHECData.cpp:498
virtual int GetElemType(int id)
Definition: CHECData.cpp:696
virtual bool vParseParameter(char *line, int *rcode, const char *fmt, va_list va)
Definition: CHECData.cpp:408
virtual class CHECDB_SGroup * GetSGroup(const char *name)
Definition: CHECData.cpp:664
virtual int ParseDoubleDataArray(char *line, double *data)
Definition: CHECData.cpp:603
virtual bool Save(const char *file_name)
Definition: CHECData.cpp:41
virtual bool ParseHeader(char *header_line, int *rcode, const char *fmt,...)
Definition: CHECData.cpp:506
std::vector< CHECDataBlock * > DB
Definition: CHECData.h:30
char data_line_buffer[256]
Definition: CHECData.h:104
virtual bool AddLoad(const char *file_name)
Definition: CHECData.cpp:267
FILE * fp
Definition: CHECData.h:27
virtual void Clear()
Definition: CHECData.cpp:25
virtual void StoreDataBlock(CHECDataBlock *block)
Definition: CHECData.cpp:35
CHECData()
Definition: CHECData.cpp:21
virtual bool Load(const char *file_name)
Definition: CHECData.cpp:262
virtual class CHECDB_Element::CElemItem * GetElemItem(int id)
Definition: CHECData.cpp:682
virtual void WriteData(const char *fmt,...)
Definition: CHECData.cpp:162
virtual class CHECDB_Material * GetMaterial(const char *name)
Definition: CHECData.cpp:652
virtual bool ReadLine(char *s, int size=256)
Definition: CHECData.cpp:307
virtual bool ReadParameter(int *rcode, const char *fmt,...)
Definition: CHECData.cpp:525
virtual void WriteHeader(const char *name, const char *fmt="",...)
Definition: CHECData.cpp:68
virtual void ClearDataLineBuffer()
Definition: CHECData.cpp:199
virtual void AddDataLineItems(const char *fmt,...)
Definition: CHECData.cpp:201
virtual class CHECDB_EGroup * GetEGroup(const char *name)
Definition: CHECData.cpp:660
virtual class CHECDB_NGroup * GetNGroup(const char *name)
Definition: CHECData.cpp:656
virtual void WriteLine(const char *s)
Definition: CHECData.cpp:58
virtual void PushReadLine(const char *s)
Definition: CHECData.cpp:328
virtual bool GetHeaderName(const char *header_line, char *header_name)
Definition: CHECData.cpp:338
virtual CHECDataBlock * CreateDataBlock(const char *header_name)
Definition: CHECData.cpp:334
char header_line_buffer[256]
Definition: CHECData.h:105
char fname[mw_fname_size]
Definition: CHECData.h:28
void toupper(char *s)
Definition: hecd_util.cpp:37
void cleanup_token(char *s)
Definition: hecd_util.cpp:13
void remove_cr(char *s)
Definition: hecd_util.cpp:75
void ftos(double x, char *s)
Definition: hecd_util.cpp:90
CNFData data