Bug Summary

File:refine/../meshWriter/libMeshbWriter/libMeshb/sources/libmeshb7.c
Warning:line 1680, column 17
Potential leak of memory pointed to by 'BckBuf'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name libmeshb7.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=none -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -D REVISION=7.7 -I ../include -I /home/jenkins/workspace/ESP_Stanalizer/LINUX64/CAPS/scan-build/ESP/LINUX64/include -I ../meshWriter/libMeshbWriter/libMeshb/sources -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-dangling-else -Wno-parentheses -Wno-unused-result -Wno-format-truncation -fdebug-compilation-dir /home/jenkins/workspace/ESP_Stanalizer/LINUX64/CAPS/scan-build/CAPS/aim/refine -ferror-limit 19 -fmessage-length 0 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /home/jenkins/workspace/ESP_Stanalizer/LINUX64/CAPS/scan-build/scanCAPS/2023-09-04-214634-45111-1 -x c ../meshWriter/libMeshbWriter/libMeshb/sources/libmeshb7.c
1
2
3/*----------------------------------------------------------------------------*/
4/* */
5/* LIBMESHB V7.62 */
6/* */
7/*----------------------------------------------------------------------------*/
8/* */
9/* Description: handles .meshb file format I/O */
10/* Author: Loic MARECHAL */
11/* Creation date: dec 09 1999 */
12/* Last modification: jan 07 2022 */
13/* */
14/*----------------------------------------------------------------------------*/
15
16
17/*----------------------------------------------------------------------------*/
18/* Headers' macros */
19/*----------------------------------------------------------------------------*/
20
21// Silent Visual Studio warnings on string functions
22#define _CRT_SECURE_NO_WARNINGS
23
24#ifdef F77API
25
26// Add a final underscore to Fortran procedure names
27#ifdef F77_NO_UNDER_SCORE
28#define NAMF77(c,f)c f
29#define APIF77(x) x
30#else
31#define NAMF77(c,f)c f ## _
32#define APIF77(x) x ## _
33#endif
34
35// Pass parameters as pointers in Fortran
36#define VALF77(v)v *v
37#define TYPF77(t)t t*
38
39#else
40
41// Pass parameters as values in C
42#define NAMF77(c,f)c c
43#define VALF77(v)v v
44#define TYPF77(t)t t
45
46#endif
47
48
49/*----------------------------------------------------------------------------*/
50/* Includes */
51/*----------------------------------------------------------------------------*/
52
53#define _XOPEN_SOURCE500 500
54
55#include <stdio.h>
56#include <stdlib.h>
57#include <stdarg.h>
58#include <string.h>
59#include <float.h>
60#include <math.h>
61#include <ctype.h>
62#include <setjmp.h>
63#include <fcntl.h>
64
65
66/*
67 * [Bruno] include the headers with the prototypes for
68 * open()/close()/write()/lseek()
69 * and define the constants to be used to open() a file.
70 * Under Windows,
71 * 1) _O_BINARY should be set in the flags.
72 * 2) 'mode' has a completely different meaning
73 */
74
75#if defined(__unix__1) || defined(__linux__1) || defined(__APPLE__) || defined(__EMSCRIPTEN__)
76
77#include <unistd.h>
78
79#define OPEN_READ_FLAGS00 O_RDONLY00
80#define OPEN_WRITE_FLAGS0100 | 01 | 01000 O_CREAT0100 | O_WRONLY01 | O_TRUNC01000
81#define OPEN_READ_MODE0666 0666
82#define OPEN_WRITE_MODE0666 0666
83
84#elif defined(_WIN32) || defined(_WIN64)
85
86#define GMF_WINDOWS
87
88#include <windows.h>
89#include <io.h>
90#include <sys/stat.h>
91#include <sys/types.h>
92#include <wchar.h>
93
94#define OPEN_READ_FLAGS00 O_RDONLY00 | _O_BINARY
95#define OPEN_WRITE_FLAGS0100 | 01 | 01000 O_CREAT0100 | O_WRONLY01 | O_TRUNC01000 | _O_BINARY
96#define OPEN_READ_MODE0666 _S_IREAD
97#define OPEN_WRITE_MODE0666 _S_IREAD | S_IWRITE
98
99#endif
100
101
102#if defined(_WIN64)
103#define MYFTELL(s)ftell(s) (int64_t)_ftelli64(s)
104#define MYFSEEK(s,o,w)fseek(s,o,w) _fseeki64(s,(__int64)o,w)
105#else
106#define MYFTELL(s)ftell(s) ftell(s)
107#define MYFSEEK(s,o,w)fseek(s,o,w) fseek(s,o,w)
108#endif
109
110
111#include <errno(*__errno_location ()).h>
112#include <libmeshb7.h>
113
114// [Bruno] Using portable printf modifier from pstdint.h
115// (alternative: use "%zd" under Linux and "%Id" under Windows)
116
117#ifdef PRINTF_INT64_MODIFIER
118#define INT64_T_FMT"%" "l" "d" "%" PRINTF_INT64_MODIFIER "d"
119#else
120# ifdef GMF_WINDOWS
121# define INT64_T_FMT"%" "l" "d" "%Id"
122# else
123# include <inttypes.h>
124# define INT64_T_FMT"%" "l" "d" "%" PRId64"l" "d"
125# endif
126#endif
127
128
129// AIO: hardware or software mockup are both encapsulated into my_aio functions
130
131#ifdef WITH_GMF_AIO
132
133#include <aio.h>
134
135int my_aio_error (const struct aiocb *aiocbp){return(aio_error (aiocbp));}
136int my_aio_read ( struct aiocb *aiocbp){return(aio_read (aiocbp));}
137size_t my_aio_return( struct aiocb *aiocbp){return(aio_return(aiocbp));}
138int my_aio_write ( struct aiocb *aiocbp){return(aio_write (aiocbp));}
139
140#else
141
142// Mockup aio library
143
144struct aiocb
145{
146 FILE *aio_fildes; // File descriptor
147 off_t aio_offset; // File offset
148 void *aio_buf; // Location of buffer
149 size_t aio_nbytes; // Length of transfer
150 int aio_lio_opcode; // Operation to be performed
151};
152
153int my_aio_error(const struct aiocb *aiocbp)
154{
155 return(aiocbp->aio_lio_opcode);
156}
157
158// Set the file position and read a block of data
159int my_aio_read(struct aiocb *aiocbp)
160{
161 if( (MYFSEEK(aiocbp->aio_fildes, (off_t)aiocbp->aio_offset, SEEK_SET)fseek(aiocbp->aio_fildes,(off_t)aiocbp->aio_offset,0) == 0)
162 && (fread(aiocbp->aio_buf, 1, aiocbp->aio_nbytes, aiocbp->aio_fildes)
163 == aiocbp->aio_nbytes) )
164 {
165 aiocbp->aio_lio_opcode = 0;
166 }
167 else
168 {
169 aiocbp->aio_lio_opcode = -1;
170 }
171
172 return(aiocbp->aio_lio_opcode);
173}
174
175size_t my_aio_return(struct aiocb *aiocbp)
176{
177 return(aiocbp->aio_nbytes);
178}
179
180// Set the file position and write a block of data
181int my_aio_write(struct aiocb *aiocbp)
182{
183 if( (MYFSEEK(aiocbp->aio_fildes, (off_t)aiocbp->aio_offset, SEEK_SET)fseek(aiocbp->aio_fildes,(off_t)aiocbp->aio_offset,0) == 0)
184 && (fwrite(aiocbp->aio_buf, 1, aiocbp->aio_nbytes, aiocbp->aio_fildes)
185 == aiocbp->aio_nbytes) )
186 {
187 aiocbp->aio_lio_opcode = 0;
188 }
189 else
190 {
191 aiocbp->aio_lio_opcode = -1;
192 }
193
194 return(aiocbp->aio_lio_opcode);
195}
196
197#endif
198
199
200/*----------------------------------------------------------------------------*/
201/* Defines */
202/*----------------------------------------------------------------------------*/
203
204#define Asc1 1
205#define Bin2 2
206#define MshFil4 4
207#define SolFil8 8
208#define InfKwd1 1
209#define RegKwd2 2
210#define SolKwd3 3
211#define CmtKwd4 4
212#define WrdSiz4 4
213#define FilStrSiz64 64
214#define BufSiz10000L 10000L
215#define MaxArg20 20
216
217
218
219/*----------------------------------------------------------------------------*/
220/* Structures */
221/*----------------------------------------------------------------------------*/
222
223typedef struct
224{
225 int typ, deg, NmbNod, SolSiz, NmbWrd, NmbTyp, TypTab[ GmfMaxTyp1000 ];
226 int *OrdTab;
227 int64_t NmbLin;
228 size_t pos;
229 char fmt[ GmfMaxTyp1000*9 ];
230}KwdSct;
231
232typedef struct
233{
234 int dim, ver, mod, typ, cod, FilDes, FltSiz;
235 int64_t NexKwdPos, siz;
236 size_t pos;
237 jmp_buf err;
238 KwdSct KwdTab[ GmfMaxKwdGmfLastKeyword - 1 + 1 ];
239 FILE *hdl;
240 int *IntBuf;
241 float *FltBuf;
242 char *buf;
243 char FilNam[ GmfStrSiz1024 ];
244 double DblBuf[1000/8];
245 unsigned char blk[ BufSiz10000L + 1000L ];
246}GmfMshSct;
247
248
249/*----------------------------------------------------------------------------*/
250/* Global variables */
251/*----------------------------------------------------------------------------*/
252
253const char *GmfKwdFmt[ GmfMaxKwdGmfLastKeyword - 1 + 1 ][3] =
254{
255 {"Reserved", "", ""},
256 {"MeshVersionFormatted", "", "i"},
257 {"Reserved", "", ""},
258 {"Dimension", "", "i"},
259 {"Vertices", "i", "dri"},
260 {"Edges", "i", "iii"},
261 {"Triangles", "i", "iiii"},
262 {"Quadrilaterals", "i", "iiiii"},
263 {"Tetrahedra", "i", "iiiii"},
264 {"Prisms", "i", "iiiiiii"},
265 {"Hexahedra", "i", "iiiiiiiii"},
266 {"Reserved", "", ""},
267 {"Reserved", "", ""},
268 {"Corners", "i", "i"},
269 {"Ridges", "i", "i"},
270 {"RequiredVertices", "i", "i"},
271 {"RequiredEdges", "i", "i"},
272 {"RequiredTriangles", "i", "i"},
273 {"RequiredQuadrilaterals", "i", "i"},
274 {"TangentAtEdgeVertices", "i", "iii"},
275 {"NormalAtVertices", "i", "ii"},
276 {"NormalAtTriangleVertices", "i", "iii"},
277 {"NormalAtQuadrilateralVertices", "i", "iiii"},
278 {"AngleOfCornerBound", "", "r"},
279 {"TrianglesP2", "i", "iiiiiii"},
280 {"EdgesP2", "i", "iiii"},
281 {"SolAtPyramids", "i", "sr"},
282 {"QuadrilateralsQ2", "i", "iiiiiiiiii"},
283 {"ISolAtPyramids", "i", "iiiii"},
284 {"SubDomainFromGeom", "i", "iii"},
285 {"TetrahedraP2", "i", "iiiiiiiiiii"},
286 {"Fault_NearTri", "i", "i"},
287 {"Fault_Inter", "i", "i"},
288 {"HexahedraQ2", "i", "iiiiiiiiiiiiiiiiiiiiiiiiiiii"},
289 {"ExtraVerticesAtEdges", "i", "in"},
290 {"ExtraVerticesAtTriangles", "i", "in"},
291 {"ExtraVerticesAtQuadrilaterals", "i", "in"},
292 {"ExtraVerticesAtTetrahedra", "i", "in"},
293 {"ExtraVerticesAtPrisms", "i", "in"},
294 {"ExtraVerticesAtHexahedra", "i", "in"},
295 {"VerticesOnGeometricVertices", "i", "ii"},
296 {"VerticesOnGeometricEdges", "i", "iirr"},
297 {"VerticesOnGeometricTriangles", "i", "iirrr"},
298 {"VerticesOnGeometricQuadrilaterals", "i", "iirrr"},
299 {"EdgesOnGeometricEdges", "i", "ii"},
300 {"Fault_FreeEdge", "i", "i"},
301 {"Polyhedra", "i", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"},
302 {"Polygons", "", "iiiiiiiii"},
303 {"Fault_Overlap", "i", "i"},
304 {"Pyramids", "i", "iiiiii"},
305 {"BoundingBox", "", "drdr"},
306 {"Reserved", "", ""},
307 {"PrivateTable", "i", "i"},
308 {"Fault_BadShape", "i", "i"},
309 {"End", "", ""},
310 {"TrianglesOnGeometricTriangles", "i", "ii"},
311 {"TrianglesOnGeometricQuadrilaterals", "i", "ii"},
312 {"QuadrilateralsOnGeometricTriangles", "i", "ii"},
313 {"QuadrilateralsOnGeometricQuadrilaterals", "i", "ii"},
314 {"Tangents", "i", "dr"},
315 {"Normals", "i", "dr"},
316 {"TangentAtVertices", "i", "ii"},
317 {"SolAtVertices", "i", "sr"},
318 {"SolAtEdges", "i", "sr"},
319 {"SolAtTriangles", "i", "sr"},
320 {"SolAtQuadrilaterals", "i", "sr"},
321 {"SolAtTetrahedra", "i", "sr"},
322 {"SolAtPrisms", "i", "sr"},
323 {"SolAtHexahedra", "i", "sr"},
324 {"DSolAtVertices", "i", "sr"},
325 {"ISolAtVertices", "i", "i"},
326 {"ISolAtEdges", "i", "ii"},
327 {"ISolAtTriangles", "i", "iii"},
328 {"ISolAtQuadrilaterals", "i", "iiii"},
329 {"ISolAtTetrahedra", "i", "iiii"},
330 {"ISolAtPrisms", "i", "iiiiii"},
331 {"ISolAtHexahedra", "i", "iiiiiiii"},
332 {"Iterations", "", "i"},
333 {"Time", "", "r"},
334 {"Fault_SmallTri", "i", "i"},
335 {"CoarseHexahedra", "i", "i"},
336 {"Comments", "i", "c"},
337 {"PeriodicVertices", "i", "ii"},
338 {"PeriodicEdges", "i", "ii"},
339 {"PeriodicTriangles", "i", "ii"},
340 {"PeriodicQuadrilaterals", "i", "ii"},
341 {"PrismsP2", "i", "iiiiiiiiiiiiiiiiiii"},
342 {"PyramidsP2", "i", "iiiiiiiiiiiiiii"},
343 {"QuadrilateralsQ3", "i", "iiiiiiiiiiiiiiiii"},
344 {"QuadrilateralsQ4", "i", "iiiiiiiiiiiiiiiiiiiiiiiiii"},
345 {"TrianglesP3", "i", "iiiiiiiiiii"},
346 {"TrianglesP4", "i", "iiiiiiiiiiiiiiii"},
347 {"EdgesP3", "i", "iiiii"},
348 {"EdgesP4", "i", "iiiiii"},
349 {"IRefGroups", "i", "ciii"},
350 {"DRefGroups", "i", "iii"},
351 {"TetrahedraP3", "i", "iiiiiiiiiiiiiiiiiiiii"},
352 {"TetrahedraP4", "i", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"},
353 {"HexahedraQ3", "i", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"},
354 {"HexahedraQ4", "i", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"},
355 {"PyramidsP3", "i", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"},
356 {"PyramidsP4", "i", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"},
357 {"PrismsP3", "i", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"},
358 {"PrismsP4", "i", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"},
359 {"HOSolAtEdgesP1", "i", "hr"},
360 {"HOSolAtEdgesP2", "i", "hr"},
361 {"HOSolAtEdgesP3", "i", "hr"},
362 {"HOSolAtTrianglesP1", "i", "hr"},
363 {"HOSolAtTrianglesP2", "i", "hr"},
364 {"HOSolAtTrianglesP3", "i", "hr"},
365 {"HOSolAtQuadrilateralsQ1", "i", "hr"},
366 {"HOSolAtQuadrilateralsQ2", "i", "hr"},
367 {"HOSolAtQuadrilateralsQ3", "i", "hr"},
368 {"HOSolAtTetrahedraP1", "i", "hr"},
369 {"HOSolAtTetrahedraP2", "i", "hr"},
370 {"HOSolAtTetrahedraP3", "i", "hr"},
371 {"HOSolAtPyramidsP1", "i", "hr"},
372 {"HOSolAtPyramidsP2", "i", "hr"},
373 {"HOSolAtPyramidsP3", "i", "hr"},
374 {"HOSolAtPrismsP1", "i", "hr"},
375 {"HOSolAtPrismsP2", "i", "hr"},
376 {"HOSolAtPrismsP3", "i", "hr"},
377 {"HOSolAtHexahedraQ1", "i", "hr"},
378 {"HOSolAtHexahedraQ2", "i", "hr"},
379 {"HOSolAtHexahedraQ3", "i", "hr"},
380 {"BezierBasis", "", "i"},
381 {"ByteFlow", "i", "i"},
382 {"EdgesP2Ordering", "i", "i"},
383 {"EdgesP3Ordering", "i", "i"},
384 {"TrianglesP2Ordering", "i", "iii"},
385 {"TrianglesP3Ordering", "i", "iii"},
386 {"QuadrilateralsQ2Ordering", "i", "ii"},
387 {"QuadrilateralsQ3Ordering", "i", "ii"},
388 {"TetrahedraP2Ordering", "i", "iiii"},
389 {"TetrahedraP3Ordering", "i", "iiii"},
390 {"PyramidsP2Ordering", "i", "iii"},
391 {"PyramidsP3Ordering", "i", "iii"},
392 {"PrismsP2Ordering", "i", "iiii"},
393 {"PrismsP3Ordering", "i", "iiii"},
394 {"HexahedraQ2Ordering", "i", "iii"},
395 {"HexahedraQ3Ordering", "i", "iii"},
396 {"EdgesP1Ordering", "i", "i"},
397 {"EdgesP4Ordering", "i", "i"},
398 {"TrianglesP1Ordering", "i", "iii"},
399 {"TrianglesP4Ordering", "i", "iii"},
400 {"QuadrilateralsQ1Ordering", "i", "ii"},
401 {"QuadrilateralsQ4Ordering", "i", "ii"},
402 {"TetrahedraP1Ordering", "i", "iiii"},
403 {"TetrahedraP4Ordering", "i", "iiii"},
404 {"PyramidsP1Ordering", "i", "iii"},
405 {"PyramidsP4Ordering", "i", "iii"},
406 {"PrismsP1Ordering", "i", "iiii"},
407 {"PrismsP4Ordering", "i", "iiii"},
408 {"HexahedraQ1Ordering", "i", "iii"},
409 {"HexahedraQ4Ordering", "i", "iii"},
410 {"FloatingPointPrecision", "", "i"},
411 {"HOSolAtEdgesP4", "i", "hr"},
412 {"HOSolAtTrianglesP4", "i", "hr"},
413 {"HOSolAtQuadrilateralsQ4", "i", "hr"},
414 {"HOSolAtTetrahedraP4", "i", "hr"},
415 {"HOSolAtPyramidsP4", "i", "hr"},
416 {"HOSolAtPrismsP4", "i", "hr"},
417 {"HOSolAtHexahedraQ4", "i", "hr"},
418 {"HOSolAtEdgesP1NodesPositions", "i", "rr"},
419 {"HOSolAtEdgesP2NodesPositions", "i", "rr"},
420 {"HOSolAtEdgesP3NodesPositions", "i", "rr"},
421 {"HOSolAtEdgesP4NodesPositions", "i", "rr"},
422 {"HOSolAtTrianglesP1NodesPositions", "i", "rrr"},
423 {"HOSolAtTrianglesP2NodesPositions", "i", "rrr"},
424 {"HOSolAtTrianglesP3NodesPositions", "i", "rrr"},
425 {"HOSolAtTrianglesP4NodesPositions", "i", "rrr"},
426 {"HOSolAtQuadrilateralsQ1NodesPositions", "i", "rr"},
427 {"HOSolAtQuadrilateralsQ2NodesPositions", "i", "rr"},
428 {"HOSolAtQuadrilateralsQ3NodesPositions", "i", "rr"},
429 {"HOSolAtQuadrilateralsQ4NodesPositions", "i", "rr"},
430 {"HOSolAtTetrahedraP1NodesPositions", "i", "rrrr"},
431 {"HOSolAtTetrahedraP2NodesPositions", "i", "rrrr"},
432 {"HOSolAtTetrahedraP3NodesPositions", "i", "rrrr"},
433 {"HOSolAtTetrahedraP4NodesPositions", "i", "rrrr"},
434 {"HOSolAtPyramidsP1NodesPositions", "i", "rrr"},
435 {"HOSolAtPyramidsP2NodesPositions", "i", "rrr"},
436 {"HOSolAtPyramidsP3NodesPositions", "i", "rrr"},
437 {"HOSolAtPyramidsP4NodesPositions", "i", "rrr"},
438 {"HOSolAtPrismsP1NodesPositions", "i", "rrrr"},
439 {"HOSolAtPrismsP2NodesPositions", "i", "rrrr"},
440 {"HOSolAtPrismsP3NodesPositions", "i", "rrrr"},
441 {"HOSolAtPrismsP4NodesPositions", "i", "rrrr"},
442 {"HOSolAtHexahedraQ1NodesPositions", "i", "rrr"},
443 {"HOSolAtHexahedraQ2NodesPositions", "i", "rrr"},
444 {"HOSolAtHexahedraQ3NodesPositions", "i", "rrr"},
445 {"HOSolAtHexahedraQ4NodesPositions", "i", "rrr"},
446 {"EdgesReferenceElement", "", "rr"},
447 {"TriangleReferenceElement", "", "rrrrrr"},
448 {"QuadrilateralReferenceElement", "", "rrrrrrrr"},
449 {"TetrahedronReferenceElement", "", "rrrrrrrrrrrr"},
450 {"PyramidReferenceElement", "", "rrrrrrrrrrrrrrr"},
451 {"PrismReferenceElement", "", "rrrrrrrrrrrrrrrrrr"},
452 {"HexahedronReferenceElement", "", "rrrrrrrrrrrrrrrrrrrrrrrr"},
453 {"BoundaryLayers", "i", "iii"},
454 {"ReferenceStrings", "i", "iic"},
455 {"Prisms9", "i", "iiiiiiiiii"},
456 {"Hexahedra12", "i", "iiiiiiiiiiiii"},
457 {"Quadrilaterals6", "i", "iiiiiii"},
458 {"BoundaryPolygonHeaders", "i", "ii"},
459 {"BoundaryPolygonVertices", "i", "i"},
460 {"InnerPolygonHeaders", "i", "ii"},
461 {"InnerPolygonVertices", "i", "i"},
462 {"PolyhedraHeaders", "i", "ii"},
463 {"PolyhedraFaces", "i", "i"},
464 {"Domains", "", "ii"},
465 {"VerticesGID", "i", "iii"},
466 {"EdgesGID", "i", "iii"},
467 {"TrianglesGID", "i", "iii"},
468 {"QuadrilateralsGID", "i", "iii"},
469 {"TetrahedraGID", "i", "iii"},
470 {"PyramidsGID", "i", "iii"},
471 {"PrismsGID", "i", "iii"},
472 {"HexahedraGID", "i", "iii"},
473};
474
475#ifdef TRANSMESH
476int GmfMaxRefTab[ GmfMaxKwdGmfLastKeyword - 1 + 1 ];
477#endif
478
479
480/*----------------------------------------------------------------------------*/
481/* Prototypes of local procedures */
482/*----------------------------------------------------------------------------*/
483
484static void ScaWrd (GmfMshSct *, void *);
485static void ScaDblWrd(GmfMshSct *, void *);
486static int64_t GetPos (GmfMshSct *);
487static void RecWrd (GmfMshSct *, const void *);
488static void RecDblWrd(GmfMshSct *, const void *);
489static void RecBlk (GmfMshSct *, const void *, int);
490static void SetPos (GmfMshSct *, int64_t);
491static int ScaKwdTab(GmfMshSct *);
492static void ExpFmt (GmfMshSct *, int);
493static void ScaKwdHdr(GmfMshSct *, int);
494static void SwpWrd (char *, int);
495static int SetFilPos(GmfMshSct *, int64_t);
496static int64_t GetFilPos(GmfMshSct *msh);
497static int64_t GetFilSiz(GmfMshSct *);
498#ifdef F77API
499static void CalF77Prc(int64_t, int64_t, void *, int, void **);
500#endif
501
502
503/*----------------------------------------------------------------------------*/
504/* Fscanf and fgets checking for errors */
505/*----------------------------------------------------------------------------*/
506
507#define safe_fscanf(hdl, format, ptr, JmpErr)do { if( fscanf(hdl, format, ptr) != 1 ) longjmp( JmpErr, -1)
; } while(0)
\
508 do { \
509 if( fscanf(hdl, format, ptr) != 1 ) \
510 longjmp( JmpErr, -1); \
511 } while(0)
512
513
514#define safe_fgets(ptr, siz, hdl, JmpErr)do { if( fgets(ptr, siz, hdl) == ((void*)0) ) longjmp( JmpErr
, -2); } while(0)
\
515 do { \
516 if( fgets(ptr, siz, hdl) == NULL((void*)0) ) \
517 longjmp( JmpErr, -2); \
518 } while(0)
519
520
521#define safe_fread(ptr, siz, nit, str, JmpErr)do { if( fread(ptr, siz, nit, str) != nit ) longjmp( JmpErr, -
3); } while(0)
\
522 do { \
523 if( fread(ptr, siz, nit, str) != nit ) \
524 longjmp( JmpErr, -3); \
525 } while(0)
526
527
528/*----------------------------------------------------------------------------*/
529/* Open a mesh file in read or write mode */
530/*----------------------------------------------------------------------------*/
531
532int64_t GmfOpenMesh(const char *FilNam, int mod, ...)
533{
534 int KwdCod, res, *PtrVer, *PtrDim, err;
535 int64_t MshIdx;
536 char str[ GmfStrSiz1024 ];
537 va_list VarArg;
538 GmfMshSct *msh;
539
540 /*---------------------*/
541 /* MESH STRUCTURE INIT */
542 /*---------------------*/
543
544 if(!(msh = calloc(1, sizeof(GmfMshSct))))
545 return(0);
546
547 MshIdx = (int64_t)msh;
548
549 // Save the current stack environment for longjmp
550 if( (err = setjmp(msh->err)_setjmp (msh->err)) != 0)
551 {
552#ifdef GMFDEBUG
553 printf("libMeshb : mesh %p : error %d\n", msh, err);
554#endif
555 if(msh->hdl != NULL((void*)0))
556 fclose(msh->hdl);
557
558 if(msh->FilDes != 0)
559#ifdef GMF_WINDOWS
560 _close(msh->FilDes);
561#else
562 close(msh->FilDes);
563#endif
564
565 free(msh);
566 return(0);
567 }
568
569 // Copy the FilNam into the structure
570 if(strlen(FilNam) + 7 >= GmfStrSiz1024)
571 longjmp(msh->err, -4);
572
573 strcpy(msh->FilNam, FilNam);
574
575 // Store the opening mod (read or write) and guess
576 // the filetype (binary or ascii) depending on the extension
577 msh->mod = mod;
578 msh->buf = (void *)msh->DblBuf;
579 msh->FltBuf = (void *)msh->DblBuf;
580 msh->IntBuf = (void *)msh->DblBuf;
581
582 if(strstr(msh->FilNam, ".meshb"))
583 msh->typ |= (Bin2 | MshFil4);
584 else if(strstr(msh->FilNam, ".mesh"))
585 msh->typ |= (Asc1 | MshFil4);
586 else if(strstr(msh->FilNam, ".solb"))
587 msh->typ |= (Bin2 | SolFil8);
588 else if(strstr(msh->FilNam, ".sol"))
589 msh->typ |= (Asc1 | SolFil8);
590 else
591 longjmp(msh->err, -5);
592
593 // Open the file in the required mod and initialize the mesh structure
594 if(msh->mod == GmfRead1)
595 {
596
597 /*-----------------------*/
598 /* OPEN FILE FOR READING */
599 /*-----------------------*/
600
601 va_start(VarArg, mod)__builtin_va_start(VarArg, mod);
602 PtrVer = va_arg(VarArg, int *)__builtin_va_arg(VarArg, int *);
603 PtrDim = va_arg(VarArg, int *)__builtin_va_arg(VarArg, int *);
604 va_end(VarArg)__builtin_va_end(VarArg);
605
606 // Read the endian coding tag, the mesh version
607 // and the mesh dimension (mandatory kwd)
608 if(msh->typ & Bin2)
609 {
610 // Create the name string and open the file
611#ifdef WITH_GMF_AIO
612 // [Bruno] added binary flag (necessary under Windows)
613 msh->FilDes = open(msh->FilNam, OPEN_READ_FLAGS00, OPEN_READ_MODE0666);
614
615 if(msh->FilDes <= 0)
616 longjmp(msh->err, -6);
617
618 // Read the endian coding tag
619 if(read(msh->FilDes, &msh->cod, WrdSiz4) != WrdSiz4)
620 longjmp(msh->err, -7);
621#else
622 // [Bruno] added binary flag (necessary under Windows)
623 if(!(msh->hdl = fopen(msh->FilNam, "rb")))
624 longjmp(msh->err, -8);
625
626 // Read the endian coding tag
627 safe_fread(&msh->cod, WrdSiz, 1, msh->hdl, msh->err)do { if( fread(&msh->cod, 4, 1, msh->hdl) != 1 ) longjmp
( msh->err, -3); } while(0)
;
628#endif
629
630 // Read the mesh version and the mesh dimension (mandatory kwd)
631 if( (msh->cod != 1) && (msh->cod != 16777216) )
632 longjmp(msh->err, -9);
633
634 ScaWrd(msh, (unsigned char *)&msh->ver);
635
636 if( (msh->ver < 1) || (msh->ver > 4) )
637 longjmp(msh->err, -10);
638
639 if( (msh->ver >= 3) && (sizeof(int64_t) != 8) )
640 longjmp(msh->err, -11);
641
642 ScaWrd(msh, (unsigned char *)&KwdCod);
643
644 if(KwdCod != GmfDimension)
645 longjmp(msh->err, -12);
646
647 GetPos(msh);
648 ScaWrd(msh, (unsigned char *)&msh->dim);
649 }
650 else
651 {
652 // Create the name string and open the file
653 if(!(msh->hdl = fopen(msh->FilNam, "rb")))
654 longjmp(msh->err, -13);
655
656 do
657 {
658 res = fscanf(msh->hdl, "%100s", str);
659 }while( (res != EOF(-1)) && strcmp(str, "MeshVersionFormatted") );
660
661 if(res == EOF(-1))
662 longjmp(msh->err, -14);
663
664 safe_fscanf(msh->hdl, "%d", &msh->ver, msh->err)do { if( fscanf(msh->hdl, "%d", &msh->ver) != 1 ) longjmp
( msh->err, -1); } while(0)
;
665
666 if( (msh->ver < 1) || (msh->ver > 4) )
667 longjmp(msh->err, -15);
668
669 do
670 {
671 res = fscanf(msh->hdl, "%100s", str);
672 }while( (res != EOF(-1)) && strcmp(str, "Dimension") );
673
674 if(res == EOF(-1))
675 longjmp(msh->err, -16);
676
677 safe_fscanf(msh->hdl, "%d", &msh->dim, msh->err)do { if( fscanf(msh->hdl, "%d", &msh->dim) != 1 ) longjmp
( msh->err, -1); } while(0)
;
678 }
679
680 if( (msh->dim != 2) && (msh->dim != 3) )
681 longjmp(msh->err, -17);
682
683 (*PtrVer) = msh->ver;
684 (*PtrDim) = msh->dim;
685
686 // Set default real numbers size
687 if(msh->ver == 1)
688 msh->FltSiz = 32;
689 else
690 msh->FltSiz = 64;
691
692 /*------------*/
693 /* KW READING */
694 /*------------*/
695
696 // Read the list of kw present in the file
697 if(!ScaKwdTab(msh))
698 return(0);
699
700 return(MshIdx);
701 }
702 else if(msh->mod == GmfWrite2)
703 {
704
705 /*-----------------------*/
706 /* OPEN FILE FOR WRITING */
707 /*-----------------------*/
708
709 msh->cod = 1;
710
711 // Check if the user provided a valid version number and dimension
712 va_start(VarArg, mod)__builtin_va_start(VarArg, mod);
713 msh->ver = va_arg(VarArg, int)__builtin_va_arg(VarArg, int);
714 msh->dim = va_arg(VarArg, int)__builtin_va_arg(VarArg, int);
715 va_end(VarArg)__builtin_va_end(VarArg);
716
717 if( (msh->ver < 1) || (msh->ver > 4) )
718 longjmp(msh->err, -18);
719
720 if( (msh->ver >= 3) && (sizeof(int64_t) != 8) )
721 longjmp(msh->err, -19);
722
723 if( (msh->dim != 2) && (msh->dim != 3) )
724 longjmp(msh->err, -20);
725
726 // Set default real numbers size
727 if(msh->ver == 1)
728 msh->FltSiz = 32;
729 else
730 msh->FltSiz = 64;
731
732 // Create the mesh file
733 if(msh->typ & Bin2)
734 {
735 /*
736 * [Bruno] replaced previous call to creat():
737 * with a call to open(), because Windows needs the
738 * binary flag to be specified.
739 */
740#ifdef WITH_GMF_AIO
741 msh->FilDes = open(msh->FilNam, OPEN_WRITE_FLAGS0100 | 01 | 01000, OPEN_WRITE_MODE0666);
742
743 if(msh->FilDes <= 0)
744 longjmp(msh->err, -21);
745#else
746 if(!(msh->hdl = fopen(msh->FilNam, "wb")))
747 longjmp(msh->err, -22);
748#endif
749 }
750 else if(!(msh->hdl = fopen(msh->FilNam, "wb")))
751 longjmp(msh->err, -23);
752
753
754 /*------------*/
755 /* KW WRITING */
756 /*------------*/
757
758 // Write the mesh version and dimension
759 if(msh->typ & Asc1)
760 {
761 fprintf(msh->hdl, "%s %d\n\n",
762 GmfKwdFmt[ GmfVersionFormatted ][0], msh->ver);
763 fprintf(msh->hdl, "%s %d\n",
764 GmfKwdFmt[ GmfDimension ][0], msh->dim);
765 }
766 else
767 {
768 RecWrd(msh, (unsigned char *)&msh->cod);
769 RecWrd(msh, (unsigned char *)&msh->ver);
770 GmfSetKwd(MshIdx, GmfDimension, 0);
771 RecWrd(msh, (unsigned char *)&msh->dim);
772 }
773
774 return(MshIdx);
775 }
776 else
777 {
778 free(msh);
779 return(0);
780 }
781}
782
783
784/*----------------------------------------------------------------------------*/
785/* Close a meshfile in the right way */
786/*----------------------------------------------------------------------------*/
787
788int GmfCloseMesh(int64_t MshIdx)
789{
790 int i, res = 1;
791 GmfMshSct *msh = (GmfMshSct *)MshIdx;
792
793 RecBlk(msh, msh->buf, 0);
794
795 // In write down the "End" kw in write mode
796 if(msh->mod == GmfWrite2)
797 {
798 if(msh->typ & Asc1)
799 fprintf(msh->hdl, "\n%s\n", GmfKwdFmt[ GmfEnd ][0]);
800 else
801 GmfSetKwd(MshIdx, GmfEnd, 0);
802 }
803
804 // Close the file and free the mesh structure
805 if(msh->typ & Bin2)
806#ifdef WITH_GMF_AIO
807 close(msh->FilDes);
808#else
809 fclose(msh->hdl);
810#endif
811 else if(fclose(msh->hdl))
812 res = 0;
813
814 // Free optional H.O. renumbering tables
815 for(i=0;i<GmfLastKeyword;i++)
816 if(msh->KwdTab[i].OrdTab)
817 free(msh->KwdTab[i].OrdTab);
818
819 free(msh);
820
821 return(res);
822}
823
824
825/*----------------------------------------------------------------------------*/
826/* Read the number of lines and set the position to this kwd */
827/*----------------------------------------------------------------------------*/
828
829int64_t GmfStatKwd(int64_t MshIdx, int KwdCod, ...)
830{
831 int i, *PtrNmbTyp, *PtrSolSiz, *TypTab, *PtrDeg, *PtrNmbNod;
832 GmfMshSct *msh = (GmfMshSct *)MshIdx;
833 KwdSct *kwd;
834 va_list VarArg;
835
836 if( (KwdCod < 1) || (KwdCod > GmfMaxKwdGmfLastKeyword - 1) )
837 return(0);
838
839 kwd = &msh->KwdTab[ KwdCod ];
840
841 if(!kwd->NmbLin)
842 return(0);
843
844 // Read further arguments if this kw is a sol
845 if(kwd->typ == SolKwd3)
846 {
847 va_start(VarArg, KwdCod)__builtin_va_start(VarArg, KwdCod);
848
849 PtrNmbTyp = va_arg(VarArg, int *)__builtin_va_arg(VarArg, int *);
850 *PtrNmbTyp = kwd->NmbTyp;
851
852 PtrSolSiz = va_arg(VarArg, int *)__builtin_va_arg(VarArg, int *);
853 *PtrSolSiz = kwd->SolSiz;
854
855 TypTab = va_arg(VarArg, int *)__builtin_va_arg(VarArg, int *);
856
857 for(i=0;i<kwd->NmbTyp;i++)
858 TypTab[i] = kwd->TypTab[i];
859
860 // Add two extra paramaters for HO elements: degree and nmb nodes
861 if(!strcmp("hr", GmfKwdFmt[ KwdCod ][2]) )
862 {
863 PtrDeg = va_arg(VarArg, int *)__builtin_va_arg(VarArg, int *);
864 *PtrDeg = kwd->deg;
865
866 PtrNmbNod = va_arg(VarArg, int *)__builtin_va_arg(VarArg, int *);
867 *PtrNmbNod = kwd->NmbNod;
868 }
869
870 va_end(VarArg)__builtin_va_end(VarArg);
871 }
872
873 return(kwd->NmbLin);
874}
875
876
877/*----------------------------------------------------------------------------*/
878/* Set the current file position to a given kwd */
879/*----------------------------------------------------------------------------*/
880
881int GmfGotoKwd(int64_t MshIdx, int KwdCod)
882{
883 GmfMshSct *msh = (GmfMshSct *)MshIdx;
884 KwdSct *kwd = &msh->KwdTab[ KwdCod ];
885
886 if( (KwdCod < 1) || (KwdCod > GmfMaxKwdGmfLastKeyword - 1) || !kwd->NmbLin )
887 return(0);
888
889 return(SetFilPos(msh, kwd->pos));
890}
891
892
893/*----------------------------------------------------------------------------*/
894/* Write the kwd and set the number of lines */
895/*----------------------------------------------------------------------------*/
896
897int GmfSetKwd(int64_t MshIdx, int KwdCod, int64_t NmbLin, ...)
898{
899 int i, *TypTab;
900 int64_t CurPos;
901 va_list VarArg;
902 GmfMshSct *msh = (GmfMshSct *)MshIdx;
903 KwdSct *kwd;
904
905 RecBlk(msh, msh->buf, 0);
906
907 if( (KwdCod < 1) || (KwdCod > GmfMaxKwdGmfLastKeyword - 1) )
908 return(0);
909
910 kwd = &msh->KwdTab[ KwdCod ];
911
912 // Read further arguments if this kw is a solution
913 if(!strcmp(GmfKwdFmt[ KwdCod ][2], "sr")
914 || !strcmp(GmfKwdFmt[ KwdCod ][2], "hr"))
915 {
916 va_start(VarArg, NmbLin)__builtin_va_start(VarArg, NmbLin);
917
918 kwd->NmbTyp = va_arg(VarArg, int)__builtin_va_arg(VarArg, int);
919 TypTab = va_arg(VarArg, int *)__builtin_va_arg(VarArg, int *);
920
921 for(i=0;i<kwd->NmbTyp;i++)
922 kwd->TypTab[i] = TypTab[i];
923
924 // Add two extra paramaters for HO elements: degree and nmb nodes
925 if(!strcmp("hr", GmfKwdFmt[ KwdCod ][2]))
926 {
927 kwd->deg = va_arg(VarArg, int)__builtin_va_arg(VarArg, int);
928 kwd->NmbNod = va_arg(VarArg, int)__builtin_va_arg(VarArg, int);
929 }
930
931 va_end(VarArg)__builtin_va_end(VarArg);
932 }
933
934 // Setup the kwd info
935 ExpFmt(msh, KwdCod);
936
937 if(!kwd->typ)
938 return(0);
939 else if(kwd->typ == InfKwd1)
940 kwd->NmbLin = 1;
941 else
942 kwd->NmbLin = NmbLin;
943
944 // Store the next kwd position in binary file
945 if( (msh->typ & Bin2) && msh->NexKwdPos )
946 {
947 CurPos = GetFilPos(msh);
948
949 if(!SetFilPos(msh, msh->NexKwdPos))
950 return(0);
951
952 SetPos(msh, CurPos);
953
954 if(!SetFilPos(msh, CurPos))
955 return(0);
956 }
957
958 // Write the header
959 if(msh->typ & Asc1)
960 {
961 fprintf(msh->hdl, "\n%s\n", GmfKwdFmt[ KwdCod ][0]);
962
963 if(kwd->typ != InfKwd1)
964 fprintf(msh->hdl, INT64_T_FMT"%" "l" "d""\n", kwd->NmbLin);
965
966 // In case of solution field, write the extended header
967 if(kwd->typ == SolKwd3)
968 {
969 fprintf(msh->hdl, "%d ", kwd->NmbTyp);
970
971 for(i=0;i<kwd->NmbTyp;i++)
972 fprintf(msh->hdl, "%d ", kwd->TypTab[i]);
973
974 fprintf(msh->hdl, "\n");
975 }
976
977 if(!strcmp("hr", GmfKwdFmt[ KwdCod ][2]))
978 fprintf(msh->hdl, "%d %d\n", kwd->deg, kwd->NmbNod);
979 }
980 else
981 {
982 RecWrd(msh, (unsigned char *)&KwdCod);
983 msh->NexKwdPos = GetFilPos(msh);
984 SetPos(msh, 0);
985
986 if(kwd->typ != InfKwd1)
987 {
988 if(msh->ver < 4)
989 {
990 i = (int)kwd->NmbLin;
991 RecWrd(msh, (unsigned char *)&i);
992 }
993 else
994 RecDblWrd(msh, (unsigned char *)&kwd->NmbLin);
995 }
996
997 // In case of solution field, write the extended header at once
998 if(kwd->typ == SolKwd3)
999 {
1000 RecWrd(msh, (unsigned char *)&kwd->NmbTyp);
1001
1002 for(i=0;i<kwd->NmbTyp;i++)
1003 RecWrd(msh, (unsigned char *)&kwd->TypTab[i]);
1004
1005 if(!strcmp("hr", GmfKwdFmt[ KwdCod ][2]))
1006 {
1007 RecWrd(msh, (unsigned char *)&kwd->deg);
1008 RecWrd(msh, (unsigned char *)&kwd->NmbNod);
1009 }
1010 }
1011 }
1012
1013 // Reset write buffer position
1014 msh->pos = 0;
1015
1016 // Compute the total file size and check if it crosses the 2GB threshold
1017 msh->siz += kwd->NmbLin * kwd->NmbWrd * WrdSiz4;
1018
1019 return(1);
1020}
1021
1022
1023/*----------------------------------------------------------------------------*/
1024/* Read a full line from the current kwd */
1025/*----------------------------------------------------------------------------*/
1026
1027int NAMF77(GmfGetLin, gmfgetlin)GmfGetLin(TYPF77(int64_t)int64_tMshIdx, TYPF77(int)intKwdCod, ...)
1028{
1029 int i, err;
1030 float *FltSolTab, FltVal, *PtrFlt;
1031 double *DblSolTab, *PtrDbl;
1032 va_list VarArg;
1033 GmfMshSct *msh = (GmfMshSct *) VALF77(MshIdx)MshIdx;
1034 KwdSct *kwd = &msh->KwdTab[ VALF77(KwdCod)KwdCod ];
1035
1036 if( (VALF77(KwdCod)KwdCod < 1) || (VALF77(KwdCod)KwdCod > GmfMaxKwdGmfLastKeyword - 1) )
1037 return(0);
1038
1039 // Save the current stack environment for longjmp
1040 if( (err = setjmp(msh->err)_setjmp (msh->err)) != 0)
1041 {
1042#ifdef GMFDEBUG
1043 printf("libMeshb : mesh %p : error %d\n", msh, err);
1044#endif
1045 return(0);
1046 }
1047
1048 // Start decoding the arguments
1049 va_start(VarArg, KwdCod)__builtin_va_start(VarArg, KwdCod);
1050
1051 switch(kwd->typ)
1052 {
1053 case InfKwd1 : case RegKwd2 : case CmtKwd4 :
1054 {
1055 if(msh->typ & Asc1)
1056 {
1057 for(i=0;i<kwd->SolSiz;i++)
1058 {
1059 if(kwd->fmt[i] == 'r')
1060 {
1061 if(msh->FltSiz == 32)
1062 {
1063 safe_fscanf(msh->hdl, "%f", &FltVal, msh->err)do { if( fscanf(msh->hdl, "%f", &FltVal) != 1 ) longjmp
( msh->err, -1); } while(0)
;
1064 PtrDbl = va_arg(VarArg, double *)__builtin_va_arg(VarArg, double *);
1065 PtrFlt = (float *)PtrDbl;
1066 *PtrFlt = FltVal;
1067 }
1068 else
1069 {
1070 safe_fscanf(msh->hdl, "%lf",do { if( fscanf(msh->hdl, "%lf", __builtin_va_arg(VarArg, double
*)) != 1 ) longjmp( msh->err, -1); } while(0)
1071 va_arg(VarArg, double *), msh->err)do { if( fscanf(msh->hdl, "%lf", __builtin_va_arg(VarArg, double
*)) != 1 ) longjmp( msh->err, -1); } while(0)
;
1072 }
1073 }
1074 else if(kwd->fmt[i] == 'i')
1075 {
1076 if(msh->ver <= 3)
1077 {
1078 safe_fscanf(msh->hdl, "%d",do { if( fscanf(msh->hdl, "%d", __builtin_va_arg(VarArg, int
*)) != 1 ) longjmp( msh->err, -1); } while(0)
1079 va_arg(VarArg, int *), msh->err)do { if( fscanf(msh->hdl, "%d", __builtin_va_arg(VarArg, int
*)) != 1 ) longjmp( msh->err, -1); } while(0)
;
1080 }
1081 else
1082 {
1083 // [Bruno] %ld -> INT64_T_FMT
1084 safe_fscanf(msh->hdl, INT64_T_FMT,do { if( fscanf(msh->hdl, "%" "l" "d", __builtin_va_arg(VarArg
, int64_t *)) != 1 ) longjmp( msh->err, -1); } while(0)
1085 va_arg(VarArg, int64_t *), msh->err)do { if( fscanf(msh->hdl, "%" "l" "d", __builtin_va_arg(VarArg
, int64_t *)) != 1 ) longjmp( msh->err, -1); } while(0)
;
1086 }
1087 }
1088 else if(kwd->fmt[i] == 'c')
1089 {
1090 safe_fgets( va_arg(VarArg, char *),do { if( fgets(__builtin_va_arg(VarArg, char *), 4 * 64, msh->
hdl) == ((void*)0) ) longjmp( msh->err, -2); } while(0)
1091 WrdSiz * FilStrSiz, msh->hdl, msh->err)do { if( fgets(__builtin_va_arg(VarArg, char *), 4 * 64, msh->
hdl) == ((void*)0) ) longjmp( msh->err, -2); } while(0)
;
1092 }
1093 }
1094 }
1095 else
1096 {
1097 for(i=0;i<kwd->SolSiz;i++)
1098 if(kwd->fmt[i] == 'r')
1099 if(msh->FltSiz == 32)
1100 ScaWrd(msh, (unsigned char *)va_arg(VarArg, float *)__builtin_va_arg(VarArg, float *));
1101 else
1102 ScaDblWrd(msh, (unsigned char *)va_arg(VarArg, double *)__builtin_va_arg(VarArg, double *));
1103 else if(kwd->fmt[i] == 'i')
1104 if(msh->ver <= 3)
1105 ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *)__builtin_va_arg(VarArg, int *));
1106 else
1107 ScaDblWrd(msh, (unsigned char *)va_arg(VarArg, int64_t *)__builtin_va_arg(VarArg, int64_t *));
1108 else if(kwd->fmt[i] == 'c')
1109 // [Bruno] added error control
1110 safe_fread(va_arg(VarArg, char *), WrdSiz, FilStrSiz, msh->hdl, msh->err)do { if( fread(__builtin_va_arg(VarArg, char *), 4, 64, msh->
hdl) != 64 ) longjmp( msh->err, -3); } while(0)
;
1111 }
1112 }break;
1113
1114 case SolKwd3 :
1115 {
1116 if(msh->FltSiz == 32)
1117 {
1118 FltSolTab = va_arg(VarArg, float *)__builtin_va_arg(VarArg, float *);
1119
1120 if(msh->typ & Asc1)
1121 for(i=0; i<kwd->SolSiz; i++)
1122 safe_fscanf(msh->hdl, "%f", &FltSolTab[i], msh->err)do { if( fscanf(msh->hdl, "%f", &FltSolTab[i]) != 1 ) longjmp
( msh->err, -1); } while(0)
;
1123 else
1124 for(i=0; i<kwd->SolSiz; i++)
1125 ScaWrd(msh, (unsigned char *)&FltSolTab[i]);
1126 }
1127 else
1128 {
1129 DblSolTab = va_arg(VarArg, double *)__builtin_va_arg(VarArg, double *);
1130
1131 if(msh->typ & Asc1)
1132 for(i=0; i<kwd->SolSiz; i++)
1133 safe_fscanf(msh->hdl, "%lf", &DblSolTab[i], msh->err)do { if( fscanf(msh->hdl, "%lf", &DblSolTab[i]) != 1 )
longjmp( msh->err, -1); } while(0)
;
1134 else
1135 for(i=0; i<kwd->SolSiz; i++)
1136 ScaDblWrd(msh, (unsigned char *)&DblSolTab[i]);
1137 }
1138 }break;
1139 }
1140
1141 va_end(VarArg)__builtin_va_end(VarArg);
1142
1143 return(1);
1144}
1145
1146
1147/*----------------------------------------------------------------------------*/
1148/* Write a full line from the current kwd */
1149/*----------------------------------------------------------------------------*/
1150
1151int NAMF77(GmfSetLin, gmfsetlin)GmfSetLin(TYPF77(int64_t)int64_t MshIdx, TYPF77(int)int KwdCod, ...)
1152{
1153 int i, pos, *IntBuf, err;
1154 int64_t *LngBuf;
1155 float *FltSolTab, *FltBuf;
1156 double *DblSolTab, *DblBuf;
1157 va_list VarArg;
1158 GmfMshSct *msh = (GmfMshSct *) VALF77(MshIdx)MshIdx;
1159 KwdSct *kwd = &msh->KwdTab[ VALF77(KwdCod)KwdCod ];
1160
1161 if( ( VALF77(KwdCod)KwdCod < 1) || ( VALF77(KwdCod)KwdCod > GmfMaxKwdGmfLastKeyword - 1) )
1162 return(0);
1163
1164 // Save the current stack environment for longjmp
1165 // This is needed in RecBlk()
1166 if( (err = setjmp(msh->err)_setjmp (msh->err)) != 0)
1167 {
1168#ifdef GMFDEBUG
1169 printf("libMeshb : mesh %p : error %d\n", msh, err);
1170#endif
1171 return(0);
1172 }
1173
1174 // Save the current stack environment for longjmp
1175 // This is needed in RecBlk()
1176 if( (err = setjmp(msh->err)_setjmp (msh->err)) != 0)
1177 {
1178#ifdef GMFDEBUG
1179 printf("libMeshb : mesh %p : error %d\n", msh, err);
1180#endif
1181 return(0);
1182 }
1183
1184 // Start decoding the arguments
1185 va_start(VarArg, KwdCod)__builtin_va_start(VarArg, KwdCod);
1186
1187 if(kwd->typ != SolKwd3)
1188 {
1189 if(msh->typ & Asc1)
1190 {
1191 for(i=0;i<kwd->SolSiz;i++)
1192 {
1193 if(kwd->fmt[i] == 'r')
1194 {
1195 if(msh->FltSiz == 32)
1196#ifdef F77API
1197 fprintf(msh->hdl, "%.9g ", *(va_arg(VarArg, float *)__builtin_va_arg(VarArg, float *)));
1198#else
1199 fprintf(msh->hdl, "%.9g ", va_arg(VarArg, double)__builtin_va_arg(VarArg, double));
1200#endif
1201 else
1202 fprintf(msh->hdl, "%.17g ", VALF77(va_arg(VarArg, TYPF77(double)))__builtin_va_arg(VarArg, double));
1203 }
1204 else if(kwd->fmt[i] == 'i')
1205 {
1206 if(msh->ver <= 3)
1207 fprintf(msh->hdl, "%d ", VALF77(va_arg(VarArg, TYPF77(int)))__builtin_va_arg(VarArg, int));
1208 else
1209 {
1210 // [Bruno] %ld -> INT64_T_FMT
1211 fprintf( msh->hdl, INT64_T_FMT"%" "l" "d" " ",
1212 VALF77(va_arg(VarArg, TYPF77(int64_t)))__builtin_va_arg(VarArg, int64_t));
1213 }
1214 }
1215 else if(kwd->fmt[i] == 'c')
1216 fprintf(msh->hdl, "%s ", va_arg(VarArg, char *)__builtin_va_arg(VarArg, char *));
1217 }
1218 }
1219 else
1220 {
1221 pos = 0;
1222
1223 for(i=0;i<kwd->SolSiz;i++)
1224 {
1225 if(kwd->fmt[i] == 'r')
1226 {
1227 if(msh->FltSiz == 32)
1228 {
1229 FltBuf = (void *)&msh->buf[ pos ];
1230#ifdef F77API
1231 *FltBuf = (float)*(va_arg(VarArg, float *)__builtin_va_arg(VarArg, float *));
1232#else
1233 *FltBuf = (float)va_arg(VarArg, double)__builtin_va_arg(VarArg, double);
1234#endif
1235 pos += 4;
1236 }
1237 else
1238 {
1239 DblBuf = (void *)&msh->buf[ pos ];
1240 *DblBuf = VALF77(va_arg(VarArg, TYPF77(double)))__builtin_va_arg(VarArg, double);
1241 pos += 8;
1242 }
1243 }
1244 else if(kwd->fmt[i] == 'i')
1245 {
1246 if(msh->ver <= 3)
1247 {
1248 IntBuf = (void *)&msh->buf[ pos ];
1249 *IntBuf = VALF77(va_arg(VarArg, TYPF77(int)))__builtin_va_arg(VarArg, int);
1250 pos += 4;
1251 }
1252 else
1253 {
1254 LngBuf = (void *)&msh->buf[ pos ];
1255 *LngBuf = VALF77(va_arg(VarArg, TYPF77(int64_t)))__builtin_va_arg(VarArg, int64_t);
1256 pos += 8;
1257 }
1258 }
1259 else if(kwd->fmt[i] == 'c')
1260 {
1261 memset(&msh->buf[ pos ], 0, FilStrSiz64 * WrdSiz4);
1262 strncpy(&msh->buf[ pos ], va_arg(VarArg, char *)__builtin_va_arg(VarArg, char *), FilStrSiz64 * WrdSiz4);
1263 pos += FilStrSiz64;
1264 }
1265 }
1266
1267 RecBlk(msh, msh->buf, kwd->NmbWrd);
1268 }
1269 }
1270 else
1271 {
1272 if(msh->FltSiz == 32)
1273 {
1274 FltSolTab = va_arg(VarArg, float *)__builtin_va_arg(VarArg, float *);
1275
1276 if(msh->typ & Asc1)
1277 for(i=0; i<kwd->SolSiz; i++)
1278 fprintf(msh->hdl, "%.9g ", (double)FltSolTab[i]);
1279 else
1280 RecBlk(msh, (unsigned char *)FltSolTab, kwd->NmbWrd);
1281 }
1282 else
1283 {
1284 DblSolTab = va_arg(VarArg, double *)__builtin_va_arg(VarArg, double *);
1285
1286 if(msh->typ & Asc1)
1287 for(i=0; i<kwd->SolSiz; i++)
1288 fprintf(msh->hdl, "%.17g ", DblSolTab[i]);
1289 else
1290 RecBlk(msh, (unsigned char *)DblSolTab, kwd->NmbWrd);
1291 }
1292 }
1293
1294 va_end(VarArg)__builtin_va_end(VarArg);
1295
1296 if(msh->typ & Asc1)
1297 fprintf(msh->hdl, "\n");
1298
1299 return(1);
1300}
1301
1302
1303/*----------------------------------------------------------------------------*/
1304/* Private procedure for mesh : copy a whole line */
1305/*----------------------------------------------------------------------------*/
1306
1307#ifdef TRANSMESH
1308
1309int GmfCpyLin(int64_t InpIdx, int64_t OutIdx, int KwdCod)
1310{
1311 char s[ WrdSiz4 * FilStrSiz64 ];
1312 double d;
1313 float f;
1314 int i, a, err;
1315 int64_t l;
1316 GmfMshSct *InpMsh = (GmfMshSct *)InpIdx, *OutMsh = (GmfMshSct *)OutIdx;
1317 KwdSct *kwd = &InpMsh->KwdTab[ KwdCod ];
1318
1319 // Save the current stack environment for longjmp
1320 if( (err = setjmp(InpMsh->err)_setjmp (InpMsh->err)) != 0)
1321 {
1322#ifdef GMFDEBUG
1323 printf("libMeshb : mesh %p : error %d\n", InpMsh, err);
1324#endif
1325 return(0);
1326 }
1327
1328 for(i=0;i<kwd->SolSiz;i++)
1329 {
1330 if(kwd->fmt[i] == 'r')
1331 {
1332 if(InpMsh->FltSiz == 32)
1333 {
1334 if(InpMsh->typ & Asc1)
1335 safe_fscanf(InpMsh->hdl, "%f", &f, InpMsh->err)do { if( fscanf(InpMsh->hdl, "%f", &f) != 1 ) longjmp(
InpMsh->err, -1); } while(0)
;
1336 else
1337 ScaWrd(InpMsh, (unsigned char *)&f);
1338
1339 d = (double)f;
1340 }
1341 else
1342 {
1343 if(InpMsh->typ & Asc1)
1344 safe_fscanf(InpMsh->hdl, "%lf", &d, InpMsh->err)do { if( fscanf(InpMsh->hdl, "%lf", &d) != 1 ) longjmp
( InpMsh->err, -1); } while(0)
;
1345 else
1346 ScaDblWrd(InpMsh, (unsigned char *)&d);
1347
1348 f = (float)d;
1349 }
1350
1351 if(OutMsh->FltSiz == 32)
1352 if(OutMsh->typ & Asc1)
1353 fprintf(OutMsh->hdl, "%.9g ", (double)f);
1354 else
1355 RecWrd(OutMsh, (unsigned char *)&f);
1356 else
1357 if(OutMsh->typ & Asc1)
1358 fprintf(OutMsh->hdl, "%.17g ", d);
1359 else
1360 RecDblWrd(OutMsh, (unsigned char *)&d);
1361 }
1362 else if(kwd->fmt[i] == 'i')
1363 {
1364 if(InpMsh->ver <= 3)
1365 {
1366 if(InpMsh->typ & Asc1)
1367 safe_fscanf(InpMsh->hdl, "%d", &a, InpMsh->err)do { if( fscanf(InpMsh->hdl, "%d", &a) != 1 ) longjmp(
InpMsh->err, -1); } while(0)
;
1368 else
1369 ScaWrd(InpMsh, (unsigned char *)&a);
1370
1371 l = (int64_t)a;
1372 }
1373 else
1374 {
1375 if(InpMsh->typ & Asc1)
1376 safe_fscanf(InpMsh->hdl, INT64_T_FMT, &l, InpMsh->err)do { if( fscanf(InpMsh->hdl, "%" "l" "d", &l) != 1 ) longjmp
( InpMsh->err, -1); } while(0)
;
1377 else
1378 ScaDblWrd(InpMsh, (unsigned char *)&l);
1379
1380 a = (int)l;
1381 }
1382
1383 if( (i == kwd->SolSiz-1) && (a > GmfMaxRefTab[ KwdCod ]) )
1384 GmfMaxRefTab[ KwdCod ] = a;
1385
1386 if(OutMsh->ver <= 3)
1387 {
1388 if(OutMsh->typ & Asc1)
1389 fprintf(OutMsh->hdl, "%d ", a);
1390 else
1391 RecWrd(OutMsh, (unsigned char *)&a);
1392 }
1393 else
1394 {
1395 if(OutMsh->typ & Asc1)
1396 fprintf(OutMsh->hdl, INT64_T_FMT"%" "l" "d"" ", l);
1397 else
1398 RecDblWrd(OutMsh, (unsigned char *)&l);
1399 }
1400 }
1401 else if(kwd->fmt[i] == 'c')
1402 {
1403 memset(s, 0, FilStrSiz64 * WrdSiz4);
1404
1405 if(InpMsh->typ & Asc1)
1406 safe_fgets(s, WrdSiz * FilStrSiz, InpMsh->hdl, InpMsh->err)do { if( fgets(s, 4 * 64, InpMsh->hdl) == ((void*)0) ) longjmp
( InpMsh->err, -2); } while(0)
;
1407 else
1408#ifdef WITH_GMF_AIO
1409 read(InpMsh->FilDes, s, WrdSiz4 * FilStrSiz64);
1410#else
1411 safe_fread(s, WrdSiz, FilStrSiz, InpMsh->hdl, InpMsh->err)do { if( fread(s, 4, 64, InpMsh->hdl) != 64 ) longjmp( InpMsh
->err, -3); } while(0)
;
1412#endif
1413 if(OutMsh->typ & Asc1)
1414 fprintf(OutMsh->hdl, "%s ", s);
1415 else
1416#ifdef WITH_GMF_AIO
1417 write(OutMsh->FilDes, s, WrdSiz4 * FilStrSiz64);
1418#else
1419 fwrite(s, WrdSiz4, FilStrSiz64, OutMsh->hdl);
1420#endif
1421 }
1422 }
1423
1424 if(OutMsh->typ & Asc1)
1425 fprintf(OutMsh->hdl, "\n");
1426
1427 return(1);
1428}
1429
1430#endif
1431
1432
1433// [Bruno] Made asynchronous I/O optional
1434#ifndef WITHOUT_AIO
1435
1436/*----------------------------------------------------------------------------*/
1437/* Bufferized asynchronous reading of all keyword's lines */
1438/*----------------------------------------------------------------------------*/
1439
1440int NAMF77(GmfGetBlock, gmfgetblock)GmfGetBlock( TYPF77(int64_t)int64_t MshIdx,
1441 TYPF77(int)int KwdCod,
1442 TYPF77(int64_t)int64_t BegIdx,
1443 TYPF77(int64_t)int64_t EndIdx,
1444 TYPF77(int)int MapTyp,
1445 void *MapTab,
1446 void *prc, ... )
1447{
1448 char *UsrDat[ GmfMaxTyp1000 ], *UsrBas[ GmfMaxTyp1000 ], *FilPos, *EndUsrDat;
1449 char *FilBuf = NULL((void*)0), *FrtBuf = NULL((void*)0), *BckBuf = NULL((void*)0), *BegUsrDat;
1450 char *StrTab[5] = { "", "%f", "%lf", "%d", INT64_T_FMT"%" "l" "d" };
1451 char **BegTab, **EndTab;
1452 int i, j, k, *FilPtrI32, *UsrPtrI32, FilTyp[ GmfMaxTyp1000 ];
1453 int UsrTyp[ GmfMaxTyp1000 ], TypSiz[5] = {0,4,8,4,8};
1454 int *IntMapTab = NULL((void*)0), err, TotSiz = 0, IniFlg = 1, mod = GmfArgLst101;
1455 int *TypTab, *SizTab, typ, VecCnt, ArgCnt = 0;
1456 float *FilPtrR32, *UsrPtrR32;
1457 double *FilPtrR64, *UsrPtrR64;
1458 int64_t BlkNmbLin, *FilPtrI64, *UsrPtrI64, BlkBegIdx, BlkEndIdx = 0;
1459 int64_t *LngMapTab = NULL((void*)0), OldIdx = 0, UsrNmbLin, VecLen;
1460 size_t FilBegIdx = VALF77(BegIdx)BegIdx, FilEndIdx = VALF77(EndIdx)EndIdx;
1461 void (*UsrPrc)(int64_t, int64_t, void *) = NULL((void*)0);
1462 size_t UsrLen[ GmfMaxTyp1000 ], ret, LinSiz, b, NmbBlk;
1463 va_list VarArg;
1464 GmfMshSct *msh = (GmfMshSct *) VALF77(MshIdx)MshIdx;
1465 KwdSct *kwd = &msh->KwdTab[ VALF77(KwdCod)KwdCod ];
1466 struct aiocb aio;
1467#ifdef F77API
1468 int NmbArg = 0;
1469 void *ArgTab[ MaxArg20 ];
1470#else
1471 char *UsrArg = NULL((void*)0);
1472#endif
1473
1474 // Save the current stack environment for longjmp
1475 if( (err = setjmp(msh->err)_setjmp (msh->err)) != 0)
1
Assuming the condition is false
2
Taking false branch
1476 {
1477#ifdef GMFDEBUG
1478 printf("libMeshb : mesh %p : error %d\n", msh, err);
1479#endif
1480 if(BckBuf)
1481 free(BckBuf);
1482
1483 if(FrtBuf)
1484 free(FrtBuf);
1485
1486 return(0);
1487 }
1488
1489 // Check mesh and keyword
1490 if( (VALF77(KwdCod)KwdCod < 1) || (VALF77(KwdCod)KwdCod > GmfMaxKwdGmfLastKeyword - 1) || !kwd->NmbLin )
3
Assuming 'KwdCod' is >= 1
4
Assuming the condition is false
5
Assuming field 'NmbLin' is not equal to 0
6
Taking false branch
1491 return(0);
1492
1493 // Make sure it's not a simple information keyword
1494 if( (kwd->typ != RegKwd2) && (kwd->typ != SolKwd3) )
7
Assuming field 'typ' is equal to RegKwd
1495 return(0);
1496
1497 // Check user's bounds
1498 if( (FilBegIdx < 1) || (FilBegIdx > FilEndIdx) || (FilEndIdx > (size_t)kwd->NmbLin) )
8
Assuming 'FilBegIdx' is >= 1
9
Assuming 'FilBegIdx' is <= 'FilEndIdx'
10
Assuming 'FilEndIdx' is <= field 'NmbLin'
11
Taking false branch
1499 return(0);
1500
1501 // Compute the number of lines to be read
1502 UsrNmbLin = FilEndIdx - FilBegIdx + 1;
1503
1504 // Get the renumbering map if any
1505 if(VALF77(MapTyp)MapTyp == GmfInt3)
12
Assuming 'MapTyp' is not equal to GmfInt
13
Taking false branch
1506 IntMapTab = (int *)MapTab;
1507 else if(VALF77(MapTyp)MapTyp == GmfLong4)
14
Assuming 'MapTyp' is not equal to GmfLong
15
Taking false branch
1508 LngMapTab = (int64_t *)MapTab;
1509
1510 // Start decoding the arguments
1511 va_start(VarArg, prc)__builtin_va_start(VarArg, prc);
1512 LinSiz = 0;
1513
1514 // Get the user's preprocessing procedure and argument adresses, if any
1515#ifdef F77API
1516 if(prc)
1517 {
1518 UsrPrc = (void (*)(int64_t, int64_t, void *))prc;
1519 NmbArg = *(va_arg(VarArg, int *)__builtin_va_arg(VarArg, int *));
1520
1521 for(i=0;i<NmbArg;i++)
1522 ArgTab[i] = va_arg(VarArg, void *)__builtin_va_arg(VarArg, void *);
1523 }
1524#else
1525 if(prc)
16
Assuming 'prc' is null
17
Taking false branch
1526 {
1527 UsrPrc = (void (*)(int64_t, int64_t, void *))prc;
1528 UsrArg = va_arg(VarArg, void *)__builtin_va_arg(VarArg, void *);
1529 }
1530#endif
1531
1532 if( (kwd->typ
17.1
Field 'typ' is equal to RegKwd
!= RegKwd2) && (kwd->typ != SolKwd3) )
1533 return(0);
1534
1535 // Read the first data type to select between list and table mode
1536 typ = VALF77(va_arg(VarArg, TYPF77(int)))__builtin_va_arg(VarArg, int);
1537
1538 // If the table mode is selected, read the four additional tables
1539 // containing the arguments: type, vector size, begin and end pointers
1540 if(typ == GmfArgTab100)
18
Assuming 'typ' is not equal to GmfArgTab
19
Taking false branch
1541 {
1542 mod = GmfArgTab100;
1543 TypTab = va_arg(VarArg, int *)__builtin_va_arg(VarArg, int *);
1544 SizTab = va_arg(VarArg, int *)__builtin_va_arg(VarArg, int *);
1545 BegTab = va_arg(VarArg, char **)__builtin_va_arg(VarArg, char **);
1546 EndTab = va_arg(VarArg, char **)__builtin_va_arg(VarArg, char **);
1547 }
1548
1549 // Read the arguments until to total size reaches the keyword's size
1550 while(TotSiz < kwd->SolSiz)
20
Assuming 'TotSiz' is >= field 'SolSiz'
21
Loop condition is false. Execution continues on line 1611
1551 {
1552 // In list mode all arguments are read from the variable argument buffer
1553 if(mod == GmfArgLst101)
1554 {
1555 // Do not read the type argument for the first iteration because
1556 // it was read befeore the loop begins to get the argument mode
1557 if(IniFlg)
1558 IniFlg = 0;
1559 else
1560 typ = VALF77(va_arg(VarArg, TYPF77(int)))__builtin_va_arg(VarArg, int);
1561
1562 // In case the type is a vector. get its size and change the type
1563 // for the corresponding scalar type
1564 if(typ >= GmfFloatVec5 && typ <= GmfLongVec8)
1565 {
1566 typ -= 4;
1567 VecCnt = VALF77(va_arg(VarArg, TYPF77(int)))__builtin_va_arg(VarArg, int);
1568 }
1569 else
1570 VecCnt = 1;
1571
1572 BegUsrDat = va_arg(VarArg, char *)__builtin_va_arg(VarArg, char *);
1573 EndUsrDat = va_arg(VarArg, char *)__builtin_va_arg(VarArg, char *);
1574 }
1575 else
1576 {
1577 // Do exactly the same as above but the arguments are read from
1578 // the tables instead of VarArgs
1579 typ = TypTab[ ArgCnt ];
1580
1581 if(typ >= GmfFloatVec5 && typ <= GmfLongVec8)
1582 {
1583 typ -= 4;
1584 VecCnt = SizTab[ ArgCnt ];
1585 }
1586 else
1587 VecCnt = 1;
1588
1589 BegUsrDat = (char *)BegTab[ ArgCnt ];
1590 EndUsrDat = (char *)EndTab[ ArgCnt ];
1591 ArgCnt++;
1592 }
1593
1594 if(UsrNmbLin > 1)
1595 VecLen = (size_t)(EndUsrDat - BegUsrDat) / (UsrNmbLin - 1);
1596 else
1597 VecLen = 0;
1598
1599 // Compute the consecutive begin / end adresses for vector data types
1600 for(i=0;i<VecCnt;i++)
1601 {
1602 UsrTyp[ TotSiz ] = typ;
1603 UsrBas[ TotSiz ] = BegUsrDat + i * TypSiz[ typ ];
1604 UsrDat[ TotSiz ] = UsrBas[ TotSiz ];
1605 UsrLen[ TotSiz ] = VecLen;
1606 TotSiz++;
1607 }
1608 }
1609
1610 // Get the file's data type
1611 for(i=0;i
21.1
'i' is >= field 'SolSiz'
<kwd->SolSiz;i++)
22
Loop condition is false. Execution continues on line 1628
1612 {
1613 if(kwd->fmt[i] == 'r')
1614 if(msh->FltSiz == 32)
1615 FilTyp[i] = GmfFloat1;
1616 else
1617 FilTyp[i] = GmfDouble2;
1618 else
1619 if(msh->ver <= 3)
1620 FilTyp[i] = GmfInt3;
1621 else
1622 FilTyp[i] = GmfLong4;
1623
1624 // Compute the file stride
1625 LinSiz += TypSiz[ FilTyp[i] ];
1626 }
1627
1628 va_end(VarArg)__builtin_va_end(VarArg);
1629
1630 // Move file pointer to the keyword data
1631 SetFilPos(msh, kwd->pos);
1632
1633 // Read the whole kwd data
1634 if(msh->typ & Asc1)
23
Assuming the condition is false
24
Taking false branch
1635 {
1636 OldIdx = 1;
1637
1638 for(i=1;i<=FilEndIdx;i++)
1639 {
1640 for(j=0;j<kwd->SolSiz;j++)
1641 {
1642 // Reorder HO nodes on the fly
1643 if(kwd->OrdTab && (j != kwd->SolSiz-1))
1644 k = kwd->OrdTab[j];
1645 else
1646 k = j;
1647
1648 // Move to the next user's data line only when the desired
1649 // begining position in the ascii file has been reached since
1650 // we cannot move directly to an arbitrary position
1651 if(IntMapTab)
1652 UsrDat[j] = UsrBas[k] + (IntMapTab[ OldIdx ] - 1) * UsrLen[k];
1653 else if(LngMapTab)
1654 UsrDat[j] = UsrBas[k] + (LngMapTab[ OldIdx ] - 1) * UsrLen[k];
1655 else
1656 UsrDat[j] = UsrBas[k] + (OldIdx - 1) * UsrLen[k];
1657
1658 safe_fscanf(msh->hdl, StrTab[ UsrTyp[j] ], UsrDat[j], msh->err)do { if( fscanf(msh->hdl, StrTab[ UsrTyp[j] ], UsrDat[j]) !=
1 ) longjmp( msh->err, -1); } while(0)
;
1659 }
1660
1661 if(i >= FilBegIdx)
1662 OldIdx++;
1663
1664 // Call the user's preprocessing procedure
1665 if(UsrPrc)
1666#ifdef F77API
1667 CalF77Prc(1, kwd->NmbLin, UsrPrc, NmbArg, ArgTab);
1668#else
1669 UsrPrc(1, kwd->NmbLin, UsrArg);
1670#endif
1671 }
1672 }
1673 else
1674 {
1675 // Allocate both front and back buffers
1676 if(!(BckBuf = malloc(BufSiz10000L * LinSiz)))
25
Memory is allocated
26
Assuming 'BckBuf' is non-null
27
Taking false branch
1677 return(0);
1678
1679 if(!(FrtBuf = malloc(BufSiz10000L * LinSiz)))
28
Assuming 'FrtBuf' is null
29
Taking true branch
1680 return(0);
30
Potential leak of memory pointed to by 'BckBuf'
1681
1682 // Setup the ansynchonous parameters
1683 memset(&aio, 0, sizeof(struct aiocb));
1684 FilBuf = BckBuf;
1685 aio.aio_buf = BckBuf;
1686#ifdef WITH_GMF_AIO
1687 aio.aio_fildes = msh->FilDes;
1688#else
1689 aio.aio_fildes = msh->hdl;
1690#endif
1691 aio.aio_offset = (off_t)(GetFilPos(msh) + (FilBegIdx-1) * LinSiz);
1692
1693 NmbBlk = UsrNmbLin / BufSiz10000L;
1694
1695 // Loop over N+1 blocks
1696 for(b=0;b<=NmbBlk+1;b++)
1697 {
1698 // Wait for the previous block read to complete except
1699 // for the first loop interation
1700 if(b)
1701 {
1702 while(my_aio_error(&aio) == EINPROGRESS115);
1703
1704 err = my_aio_error(&aio);
1705 ret = my_aio_return(&aio);
1706
1707 if (err != 0) {
1708 printf (" Error at aio_error() : %s\n", strerror (err));
1709 exit(1);
1710 }
1711
1712 if (ret != aio.aio_nbytes) {
1713 printf(" Error at aio_return()\n");
1714 exit(1);
1715 }
1716
1717 // Increment the reading position
1718 aio.aio_offset += (off_t)aio.aio_nbytes;
1719
1720 // and swap the buffers
1721 if(aio.aio_buf == BckBuf)
1722 {
1723 aio.aio_buf = FrtBuf;
1724 FilBuf = BckBuf;
1725 }
1726 else
1727 {
1728 aio.aio_buf = BckBuf;
1729 FilBuf = FrtBuf;
1730 }
1731 }
1732
1733 // Read a chunk of data except for the last loop interarion
1734 if(b <= NmbBlk)
1735 {
1736 // The last block is shorter than the others
1737 if(b == NmbBlk)
1738 BlkNmbLin = UsrNmbLin - b * BufSiz10000L;
1739 else
1740 BlkNmbLin = BufSiz10000L;
1741
1742 aio.aio_nbytes = BlkNmbLin * LinSiz;
1743
1744 if(my_aio_read(&aio) == -1)
1745 {
1746 printf("block = %zd / %zd\n", b+1, NmbBlk+1);
1747 printf("size = "INT64_T_FMT"%" "l" "d"" lines\n", BlkNmbLin);
1748#ifdef WITH_GMF_AIO
1749 printf("aio_fildes = %d\n",aio.aio_fildes);
1750#else
1751 printf("aio_fildes = %p\n",aio.aio_fildes);
1752#endif
1753 printf("aio_buf = %p\n",aio.aio_buf);
1754 printf("aio_offset = " INT64_T_FMT"%" "l" "d" "\n",(int64_t)aio.aio_offset);
1755 printf("aio_nbytes = " INT64_T_FMT"%" "l" "d" "\n",(int64_t)aio.aio_nbytes);
1756 printf("errno = %d\n",errno(*__errno_location ()));
1757 exit(1);
1758 }
1759 }
1760
1761 // Then decode the block and store it in the user's data structure
1762 // except for the first loop interation
1763 if(b)
1764 {
1765 // The last block is shorter than the others
1766 if(b-1 == NmbBlk)
1767 BlkNmbLin = UsrNmbLin - (b-1) * BufSiz10000L;
1768 else
1769 BlkNmbLin = BufSiz10000L;
1770
1771 BlkBegIdx = BlkEndIdx+1;
1772 BlkEndIdx += BlkNmbLin;
1773 FilPos = FilBuf;
1774
1775 for(i=0;i<BlkNmbLin;i++)
1776 {
1777 OldIdx++;
1778
1779 for(j=0;j<kwd->SolSiz;j++)
1780 {
1781 if(msh->cod != 1)
1782 SwpWrd(FilPos, TypSiz[ FilTyp[j] ]);
1783
1784 // Reorder HO nodes on the fly
1785 if(kwd->OrdTab && (j != kwd->SolSiz-1))
1786 k = kwd->OrdTab[j];
1787 else
1788 k = j;
1789
1790 if(IntMapTab)
1791 UsrDat[j] = UsrBas[k] + (IntMapTab[ OldIdx ] - 1) * UsrLen[k];
1792 else if(LngMapTab)
1793 UsrDat[j] = UsrBas[k] + (LngMapTab[ OldIdx ] - 1) * UsrLen[k];
1794 else
1795 UsrDat[j] = UsrBas[k] + (OldIdx - 1) * UsrLen[k];
1796
1797 if(FilTyp[j] == GmfInt3)
1798 {
1799 FilPtrI32 = (int *)FilPos;
1800
1801 if(UsrTyp[j] == GmfInt3)
1802 {
1803 UsrPtrI32 = (int *)UsrDat[j];
1804 *UsrPtrI32 = *FilPtrI32;
1805 }
1806 else
1807 {
1808 UsrPtrI64 = (int64_t *)UsrDat[j];
1809 *UsrPtrI64 = (int64_t)*FilPtrI32;
1810 }
1811 }
1812 else if(FilTyp[j] == GmfLong4)
1813 {
1814 FilPtrI64 = (int64_t *)FilPos;
1815
1816 if(UsrTyp[j] == GmfLong4)
1817 {
1818 UsrPtrI64 = (int64_t *)UsrDat[j];
1819 *UsrPtrI64 = *FilPtrI64;
1820 }
1821 else
1822 {
1823 UsrPtrI32 = (int *)UsrDat[j];
1824 *UsrPtrI32 = (int)*FilPtrI64;
1825 }
1826 }
1827 else if(FilTyp[j] == GmfFloat1)
1828 {
1829 FilPtrR32 = (float *)FilPos;
1830
1831 if(UsrTyp[j] == GmfFloat1)
1832 {
1833 UsrPtrR32 = (float *)UsrDat[j];
1834 *UsrPtrR32 = *FilPtrR32;
1835 }
1836 else
1837 {
1838 UsrPtrR64 = (double *)UsrDat[j];
1839 *UsrPtrR64 = (double)*FilPtrR32;
1840 }
1841 }
1842 else if(FilTyp[j] == GmfDouble2)
1843 {
1844 FilPtrR64 = (double *)FilPos;
1845
1846 if(UsrTyp[j] == GmfDouble2)
1847 {
1848 UsrPtrR64 = (double *)UsrDat[j];
1849 *UsrPtrR64 = *FilPtrR64;
1850 }
1851 else
1852 {
1853 UsrPtrR32 = (float *)UsrDat[j];
1854 *UsrPtrR32 = (float)*FilPtrR64;
1855 }
1856 }
1857
1858 FilPos += TypSiz[ FilTyp[j] ];
1859 }
1860 }
1861
1862 // Call the user's preprocessing procedure
1863 if(UsrPrc)
1864#ifdef F77API
1865 CalF77Prc(BlkBegIdx, BlkEndIdx, UsrPrc, NmbArg, ArgTab);
1866#else
1867 UsrPrc(BlkBegIdx, BlkEndIdx, UsrArg);
1868#endif
1869 }
1870 }
1871
1872 free(BckBuf);
1873 free(FrtBuf);
1874 }
1875
1876 return(1);
1877}
1878
1879
1880/*----------------------------------------------------------------------------*/
1881/* Bufferized writing of all keyword's lines */
1882/*----------------------------------------------------------------------------*/
1883
1884int NAMF77(GmfSetBlock, gmfsetblock)GmfSetBlock( TYPF77(int64_t)int64_t MshIdx,
1885 TYPF77(int)int KwdCod,
1886 TYPF77(int64_t)int64_t BegIdx,
1887 TYPF77(int64_t)int64_t EndIdx,
1888 TYPF77(int)int MapTyp,
1889 void *MapTab,
1890 void *prc, ... )
1891{
1892 char *UsrDat[ GmfMaxTyp1000 ], *UsrBas[ GmfMaxTyp1000 ];
1893 char *StrTab[5] = { "", "%.9g", "%.17g", "%d", "%lld" }, *FilPos;
1894 char *FilBuf = NULL((void*)0), *FrtBuf = NULL((void*)0), *BckBuf = NULL((void*)0);
1895 char **BegTab, **EndTab, *BegUsrDat, *EndUsrDat;
1896 int i, j, *FilPtrI32, *UsrPtrI32, FilTyp[ GmfMaxTyp1000 ];
1897 int UsrTyp[ GmfMaxTyp1000 ], TypSiz[5] = {0,4,8,4,8};
1898 int err, *IntMapTab = NULL((void*)0), typ, mod = GmfArgLst101;
1899 int *TypTab, *SizTab, IniFlg = 1, TotSiz = 0, VecCnt, ArgCnt = 0;
1900 float *FilPtrR32, *UsrPtrR32;
1901 double *FilPtrR64, *UsrPtrR64;
1902 int64_t UsrNmbLin, BlkNmbLin = 0, BlkBegIdx, BlkEndIdx = 0;
1903 int64_t *FilPtrI64, *UsrPtrI64, *LngMapTab = NULL((void*)0), OldIdx = 0;
1904 size_t FilBegIdx = VALF77(BegIdx)BegIdx, FilEndIdx = VALF77(EndIdx)EndIdx;
1905 void (*UsrPrc)(int64_t, int64_t, void *) = NULL((void*)0);
1906 size_t UsrLen[ GmfMaxTyp1000 ], ret, LinSiz, VecLen, s, b, NmbBlk;
1907 va_list VarArg;
1908 GmfMshSct *msh = (GmfMshSct *) VALF77(MshIdx)MshIdx;
1909 KwdSct *kwd = &msh->KwdTab[ VALF77(KwdCod)KwdCod ];
1910 struct aiocb aio;
1911#ifdef F77API
1912 int NmbArg = 0;
1913 void *ArgTab[ MaxArg20 ];
1914#else
1915 char *UsrArg = NULL((void*)0);
1916#endif
1917
1918 // Save the current stack environment for longjmp
1919 if( (err = setjmp(msh->err)_setjmp (msh->err)) != 0)
1920 {
1921#ifdef GMFDEBUG
1922 printf("libMeshb : mesh %p : error %d\n", msh, err);
1923#endif
1924 if(FilBuf)
1925 free(FilBuf);
1926
1927 return(0);
1928 }
1929
1930 // Check mesh and keyword
1931 if( (VALF77(KwdCod)KwdCod < 1) || (VALF77(KwdCod)KwdCod > GmfMaxKwdGmfLastKeyword - 1) || !kwd->NmbLin )
1932 return(0);
1933
1934 // Make sure it's not a simple information keyword
1935 if( (kwd->typ != RegKwd2) && (kwd->typ != SolKwd3) )
1936 return(0);
1937
1938 // Temporarily overwright the given begin and end values
1939 // as arbitrary position block write is not yet implemented
1940 FilBegIdx = 1;
1941 FilEndIdx = kwd->NmbLin;
1942
1943 // Check user's bounds
1944 if( (FilBegIdx < 1) || (FilBegIdx > FilEndIdx) || (FilEndIdx > (size_t)kwd->NmbLin) )
1945 return(0);
1946
1947 // Compute the number of lines to be written
1948 UsrNmbLin = FilEndIdx - FilBegIdx + 1;
1949
1950 // Get the renumbering map if any
1951 if(VALF77(MapTyp)MapTyp == GmfInt3)
1952 IntMapTab = (int *)MapTab;
1953 else if(VALF77(MapTyp)MapTyp == GmfLong4)
1954 LngMapTab = (int64_t *)MapTab;
1955
1956 // Start decoding the arguments
1957 va_start(VarArg, prc)__builtin_va_start(VarArg, prc);
1958 LinSiz = 0;
1959
1960 // Get the user's postprocessing procedure and argument adresses, if any
1961#ifdef F77API
1962 if(prc)
1963 {
1964 UsrPrc = (void (*)(int64_t, int64_t, void *))prc;
1965 NmbArg = *(va_arg(VarArg, int *)__builtin_va_arg(VarArg, int *));
1966
1967 for(i=0;i<NmbArg;i++)
1968 ArgTab[i] = va_arg(VarArg, void *)__builtin_va_arg(VarArg, void *);
1969 }
1970#else
1971 if(prc)
1972 {
1973 UsrPrc = (void (*)(int64_t, int64_t, void *))prc;
1974 UsrArg = va_arg(VarArg, void *)__builtin_va_arg(VarArg, void *);
1975 }
1976#endif
1977
1978 if( (kwd->typ != RegKwd2) && (kwd->typ != SolKwd3) )
1979 return(0);
1980
1981 // Read the first data type to select between list and table mode
1982 typ = VALF77(va_arg(VarArg, TYPF77(int)))__builtin_va_arg(VarArg, int);
1983
1984 // If the table mode is selected, read the four additional tables
1985 // containing the arguments: type, vector size, begin and end pointers
1986 if(typ == GmfArgTab100)
1987 {
1988 mod = GmfArgTab100;
1989 TypTab = va_arg(VarArg, int *)__builtin_va_arg(VarArg, int *);
1990 SizTab = va_arg(VarArg, int *)__builtin_va_arg(VarArg, int *);
1991 BegTab = va_arg(VarArg, char **)__builtin_va_arg(VarArg, char **);
1992 EndTab = va_arg(VarArg, char **)__builtin_va_arg(VarArg, char **);
1993 }
1994
1995 // Read the arguments until to total size reaches the keyword's size
1996 while(TotSiz < kwd->SolSiz)
1997 {
1998 // In list mode all arguments are read from the variable argument buffer
1999 if(mod == GmfArgLst101)
2000 {
2001 // Do not read the type argument for the first iteration because
2002 // it was read befeore the loop begins to get the argument mode
2003 if(IniFlg)
2004 IniFlg = 0;
2005 else
2006 typ = VALF77(va_arg(VarArg, TYPF77(int)))__builtin_va_arg(VarArg, int);
2007
2008 // In case the type is a vector. get its size and change the type
2009 // for the corresponding scalar type
2010 if(typ >= GmfFloatVec5 && typ <= GmfLongVec8)
2011 {
2012 typ -= 4;
2013 VecCnt = VALF77(va_arg(VarArg, TYPF77(int)))__builtin_va_arg(VarArg, int);
2014 }
2015 else
2016 VecCnt = 1;
2017
2018 BegUsrDat = va_arg(VarArg, char *)__builtin_va_arg(VarArg, char *);
2019 EndUsrDat = va_arg(VarArg, char *)__builtin_va_arg(VarArg, char *);
2020 }
2021 else
2022 {
2023 // Do exactly the same as above but the arguments are read from
2024 // the tables instead of VarArgs
2025 typ = TypTab[ ArgCnt ];
2026
2027 if(typ >= GmfFloatVec5 && typ <= GmfLongVec8)
2028 {
2029 typ -= 4;
2030 VecCnt = SizTab[ ArgCnt ];
2031 }
2032 else
2033 VecCnt = 1;
2034
2035 BegUsrDat = (char *)BegTab[ ArgCnt ];
2036 EndUsrDat = (char *)EndTab[ ArgCnt ];
2037 ArgCnt++;
2038 }
2039
2040 if(UsrNmbLin > 1)
2041 VecLen = (size_t)(EndUsrDat - BegUsrDat) / (UsrNmbLin - 1);
2042 else
2043 VecLen = 0;
2044
2045 // Compute the consecutive begin / end adresses for vector data types
2046 for(i=0;i<VecCnt;i++)
2047 {
2048 UsrTyp[ TotSiz ] = typ;
2049 UsrBas[ TotSiz ] = BegUsrDat + i * TypSiz[ typ ];
2050 UsrDat[ TotSiz ] = UsrBas[ TotSiz ];
2051 UsrLen[ TotSiz ] = VecLen;
2052 TotSiz++;
2053 }
2054 }
2055
2056 // Get the file's data type
2057 for(i=0;i<kwd->SolSiz;i++)
2058 {
2059 if(kwd->fmt[i] == 'r')
2060 if(msh->FltSiz == 32)
2061 FilTyp[i] = GmfFloat1;
2062 else
2063 FilTyp[i] = GmfDouble2;
2064 else
2065 if(msh->ver <= 3)
2066 FilTyp[i] = GmfInt3;
2067 else
2068 FilTyp[i] = GmfLong4;
2069
2070 // Compute the file stride
2071 LinSiz += TypSiz[ FilTyp[i] ];
2072 }
2073
2074 va_end(VarArg)__builtin_va_end(VarArg);
2075
2076 // Write the whole kwd data
2077 if(msh->typ & Asc1)
2078 {
2079 if(UsrPrc)
2080#ifdef F77API
2081 CalF77Prc(1, kwd->NmbLin, UsrPrc, NmbArg, ArgTab);
2082#else
2083 UsrPrc(1, kwd->NmbLin, UsrArg);
2084#endif
2085
2086 for(s=FilBegIdx; s<=FilEndIdx; s++)
2087 for(j=0;j<kwd->SolSiz;j++)
2088 {
2089 if(UsrTyp[j] == GmfFloat1)
2090 {
2091 UsrPtrR32 = (float *)UsrDat[j];
2092 fprintf(msh->hdl, StrTab[ UsrTyp[j] ], (double)*UsrPtrR32);
2093 }
2094 else if(UsrTyp[j] == GmfDouble2)
2095 {
2096 UsrPtrR64 = (double *)UsrDat[j];
2097 fprintf(msh->hdl, StrTab[ UsrTyp[j] ], *UsrPtrR64);
2098 }
2099 else if(UsrTyp[j] == GmfInt3)
2100 {
2101 UsrPtrI32 = (int *)UsrDat[j];
2102 fprintf(msh->hdl, StrTab[ UsrTyp[j] ], *UsrPtrI32);
2103 }
2104 else if(UsrTyp[j] == GmfLong4)
2105 {
2106 UsrPtrI64 = (int64_t *)UsrDat[j];
2107 fprintf(msh->hdl, StrTab[ UsrTyp[j] ], *UsrPtrI64);
2108 }
2109
2110 if(j < kwd->SolSiz -1)
2111 fprintf(msh->hdl, " ");
2112 else
2113 fprintf(msh->hdl, "\n");
2114
2115 //UsrDat[j] += UsrLen[j];
2116 if(IntMapTab)
2117 UsrDat[j] = UsrBas[j] + IntMapTab[s] * UsrLen[j];
2118 else if(LngMapTab)
2119 UsrDat[j] = UsrBas[j] + LngMapTab[s] * UsrLen[j];
2120 else
2121 UsrDat[j] = UsrBas[j] + s * UsrLen[j];
2122 }
2123 }
2124 else
2125 {
2126 // Allocate the front and back buffers
2127 if(!(BckBuf = malloc(BufSiz10000L * LinSiz)))
2128 return(0);
2129
2130 if(!(FrtBuf = malloc(BufSiz10000L * LinSiz)))
2131 return(0);
2132
2133 // Setup the asynchronous parameters
2134 memset(&aio, 0, sizeof(struct aiocb));
2135 FilBuf = BckBuf;
2136#ifdef WITH_GMF_AIO
2137 aio.aio_fildes = msh->FilDes;
2138#else
2139 aio.aio_fildes = msh->hdl;
2140#endif
2141 aio.aio_offset = (off_t)GetFilPos(msh);
2142
2143 NmbBlk = UsrNmbLin / BufSiz10000L;
2144
2145 // Loop over N+1 blocks
2146 for(b=0;b<=NmbBlk+1;b++)
2147 {
2148 // Launch an asynchronous block write
2149 // except for the first loop iteration
2150 if(b)
2151 {
2152 aio.aio_nbytes = BlkNmbLin * LinSiz;
2153
2154 if(my_aio_write(&aio) == -1)
2155 {
2156#ifdef WITH_GMF_AIO
2157 printf("aio_fildes = %d\n",aio.aio_fildes);
2158#else
2159 printf("aio_fildes = %p\n",aio.aio_fildes);
2160#endif
2161 printf("aio_buf = %p\n",aio.aio_buf);
2162 printf("aio_offset = " INT64_T_FMT"%" "l" "d" "\n",(int64_t)aio.aio_offset);
2163 printf("aio_nbytes = " INT64_T_FMT"%" "l" "d" "\n",(int64_t)aio.aio_nbytes);
2164 printf("errno = %d\n",errno(*__errno_location ()));
2165 exit(1);
2166 }
2167 }
2168
2169 // Parse the block data except at the last loop iteration
2170 if(b<=NmbBlk)
2171 {
2172 // The last block is shorter
2173 if(b == NmbBlk)
2174 BlkNmbLin = UsrNmbLin - b * BufSiz10000L;
2175 else
2176 BlkNmbLin = BufSiz10000L;
2177
2178 FilPos = FilBuf;
2179 BlkBegIdx = BlkEndIdx+1;
2180 BlkEndIdx += BlkNmbLin;
2181
2182 // Call user's preprocessing first
2183 if(UsrPrc)
2184#ifdef F77API
2185 CalF77Prc(BlkBegIdx, BlkEndIdx, UsrPrc, NmbArg, ArgTab);
2186#else
2187 UsrPrc(BlkBegIdx, BlkEndIdx, UsrArg);
2188#endif
2189
2190 // Then copy it's data to the file buffer
2191 for(i=0;i<BlkNmbLin;i++)
2192 {
2193 OldIdx++;
2194
2195 for(j=0;j<kwd->SolSiz;j++)
2196 {
2197 if(IntMapTab)
2198 UsrDat[j] = UsrBas[j] + (IntMapTab[ OldIdx ] - 1) * UsrLen[j];
2199 else if(LngMapTab)
2200 UsrDat[j] = UsrBas[j] + (LngMapTab[ OldIdx ] - 1) * UsrLen[j];
2201 else
2202 UsrDat[j] = UsrBas[j] + (OldIdx - 1) * UsrLen[j];
2203
2204 if(FilTyp[j] == GmfInt3)
2205 {
2206 FilPtrI32 = (int *)FilPos;
2207
2208 if(UsrTyp[j] == GmfInt3)
2209 {
2210 UsrPtrI32 = (int *)UsrDat[j];
2211 *FilPtrI32 = *UsrPtrI32;
2212 }
2213 else
2214 {
2215 UsrPtrI64 = (int64_t *)UsrDat[j];
2216 *FilPtrI32 = (int)*UsrPtrI64;
2217 }
2218 }
2219 else if(FilTyp[j] == GmfLong4)
2220 {
2221 FilPtrI64 = (int64_t *)FilPos;
2222
2223 if(UsrTyp[j] == GmfLong4)
2224 {
2225 UsrPtrI64 = (int64_t *)UsrDat[j];
2226 *FilPtrI64 = *UsrPtrI64;
2227 }
2228 else
2229 {
2230 UsrPtrI32 = (int *)UsrDat[j];
2231 *FilPtrI64 = (int64_t)*UsrPtrI32;
2232 }
2233 }
2234 else if(FilTyp[j] == GmfFloat1)
2235 {
2236 FilPtrR32 = (float *)FilPos;
2237
2238 if(UsrTyp[j] == GmfFloat1)
2239 {
2240 UsrPtrR32 = (float *)UsrDat[j];
2241 *FilPtrR32 = *UsrPtrR32;
2242 }
2243 else
2244 {
2245 UsrPtrR64 = (double *)UsrDat[j];
2246 *FilPtrR32 = (float)*UsrPtrR64;
2247 }
2248 }
2249 else if(FilTyp[j] == GmfDouble2)
2250 {
2251 FilPtrR64 = (double *)FilPos;
2252
2253 if(UsrTyp[j] == GmfDouble2)
2254 {
2255 UsrPtrR64 = (double *)UsrDat[j];
2256 *FilPtrR64 = *UsrPtrR64;
2257 }
2258 else
2259 {
2260 UsrPtrR32 = (float *)UsrDat[j];
2261 *FilPtrR64 = (double)*UsrPtrR32;
2262 }
2263 }
2264
2265 FilPos += TypSiz[ FilTyp[j] ];
2266 }
2267 }
2268 }
2269
2270 // Wait for write completion execpt at the first loop iteration
2271 if(b)
2272 {
2273 while(my_aio_error(&aio) == EINPROGRESS115);
2274
2275 err = my_aio_error(&aio);
2276 ret = my_aio_return(&aio);
2277
2278 if (err != 0) {
2279 printf (" Error at aio_error() : %s\n", strerror (err));
2280 exit(1);
2281 }
2282
2283 if (ret != aio.aio_nbytes) {
2284 printf(" Error at aio_return()\n");
2285 exit(1);
2286 }
2287
2288 // Move the write position
2289 aio.aio_offset += (off_t)aio.aio_nbytes;
2290 }
2291
2292 // Swap the buffers
2293 if(FilBuf == BckBuf)
2294 {
2295 aio.aio_buf = BckBuf;
2296 FilBuf = FrtBuf;
2297 }
2298 else
2299 {
2300 aio.aio_buf = FrtBuf;
2301 FilBuf = BckBuf;
2302 }
2303 }
2304
2305 SetFilPos(msh, aio.aio_offset);
2306 free(BckBuf);
2307 free(FrtBuf);
2308 }
2309
2310 return(1);
2311}
2312
2313
2314/*----------------------------------------------------------------------------*/
2315/* Map two HO element's nodes numbering orders */
2316/*----------------------------------------------------------------------------*/
2317
2318int GmfSetHONodesOrdering(int64_t MshIdx, int KwdCod, int *BasTab, int *OrdTab)
2319{
2320 int i, j, k, flg, NmbNod, NmbCrd;
2321 GmfMshSct *msh = (GmfMshSct *)MshIdx;
2322 KwdSct *kwd;
2323
2324 // printf("\n\tGmfSetHONodesOrdering 0\n");
2325
2326 if( (KwdCod < 1) || (KwdCod > GmfMaxKwdGmfLastKeyword - 1) )
2327 return(0);
2328
2329 kwd = &msh->KwdTab[ KwdCod ];
2330
2331 // Find the Bezier indices dimension according to the element's kind
2332 switch(KwdCod)
2333 {
2334 case GmfEdges : NmbNod = 2; NmbCrd = 1; break;
2335 case GmfEdgesP2 : NmbNod = 3; NmbCrd = 1; break;
2336 case GmfEdgesP3 : NmbNod = 4; NmbCrd = 1; break;
2337 case GmfEdgesP4 : NmbNod = 5; NmbCrd = 1; break;
2338 case GmfTriangles : NmbNod = 3; NmbCrd = 3; break;
2339 case GmfTrianglesP2 : NmbNod = 6; NmbCrd = 3; break;
2340 case GmfTrianglesP3 : NmbNod = 10; NmbCrd = 3; break;
2341 case GmfTrianglesP4 : NmbNod = 15; NmbCrd = 3; break;
2342 case GmfQuadrilaterals : NmbNod = 4; NmbCrd = 2; break;
2343 case GmfQuadrilateralsQ2 : NmbNod = 9; NmbCrd = 2; break;
2344 case GmfQuadrilateralsQ3 : NmbNod = 16; NmbCrd = 2; break;
2345 case GmfQuadrilateralsQ4 : NmbNod = 25; NmbCrd = 2; break;
2346 case GmfTetrahedra : NmbNod = 4; NmbCrd = 4; break;
2347 case GmfTetrahedraP2 : NmbNod = 10; NmbCrd = 4; break;
2348 case GmfTetrahedraP3 : NmbNod = 20; NmbCrd = 4; break;
2349 case GmfTetrahedraP4 : NmbNod = 35; NmbCrd = 4; break;
2350 case GmfPyramids : NmbNod = 5; NmbCrd = 3; break;
2351 case GmfPyramidsP2 : NmbNod = 14; NmbCrd = 3; break;
2352 case GmfPyramidsP3 : NmbNod = 30; NmbCrd = 3; break;
2353 case GmfPyramidsP4 : NmbNod = 55; NmbCrd = 3; break;
2354 case GmfPrisms : NmbNod = 6; NmbCrd = 4; break;
2355 case GmfPrismsP2 : NmbNod = 18; NmbCrd = 4; break;
2356 case GmfPrismsP3 : NmbNod = 40; NmbCrd = 4; break;
2357 case GmfPrismsP4 : NmbNod = 75; NmbCrd = 4; break;
2358 case GmfHexahedra : NmbNod = 8; NmbCrd = 3; break;
2359 case GmfHexahedraQ2 : NmbNod = 27; NmbCrd = 3; break;
2360 case GmfHexahedraQ3 : NmbNod = 64; NmbCrd = 3; break;
2361 case GmfHexahedraQ4 : NmbNod =125; NmbCrd = 3; break;
2362 default : return(0);
2363 }
2364
2365 // Free and rebuild the mapping table if there were already one
2366 if(kwd->OrdTab)
2367 free(kwd->OrdTab);
2368
2369 if(!(kwd->OrdTab = malloc(NmbNod * sizeof(int))))
2370 return(0);
2371
2372 // Find the corresponding Bezier coordinates from the source table
2373 for(i=0;i<NmbNod;i++)
2374 {
2375 for(j=0;j<NmbNod;j++)
2376 {
2377 flg = 1;
2378
2379 for(k=0;k<NmbCrd;k++)
2380 if(BasTab[ i * NmbCrd + k ] != OrdTab[ j * NmbCrd + k ])
2381 {
2382 flg = 0;
2383 break;
2384 }
2385
2386 if(flg)
2387 kwd->OrdTab[j] = i;
2388 }
2389 }
2390
2391 // Check the ordering consistency
2392 for(i=0;i<NmbNod;i++)
2393 {
2394 flg = 0;
2395
2396 for(j=0;j<NmbNod;j++)
2397 if(kwd->OrdTab[j] == i)
2398 {
2399 flg = 1;
2400 break;
2401 }
2402
2403 if(!flg)
2404 {
2405 for(j=0;j<NmbNod;j++)
2406 kwd->OrdTab[j] = j;
2407
2408 return(0);
2409 }
2410 }
2411
2412 return(1);
2413}
2414
2415#endif
2416
2417
2418#ifndef F77API
2419
2420
2421/*----------------------------------------------------------------------------*/
2422/* Read an EGADS binary CAD and return the byte flow and its exact byte size */
2423/*----------------------------------------------------------------------------*/
2424
2425char *GmfReadByteFlow(int64_t MshIdx, int *NmbByt)
2426{
2427 int cod, *WrdTab;
2428 size_t i, NmbWrd;
2429 GmfMshSct *msh = (GmfMshSct *)MshIdx;
2430
2431 // Read and allocate the number of 4-byte words in the byteflow
2432 if(!(NmbWrd = GmfStatKwd(MshIdx, GmfByteFlow)))
2433 return(NULL((void*)0));
2434
2435 if(!(WrdTab = malloc(NmbWrd * WrdSiz4)))
2436 return(NULL((void*)0));
2437
2438 // Disable the endianess conversion
2439 cod = msh->cod;
2440 msh->cod = 1;
2441
2442 // Read the exact number of bytes in the byteflow
2443 GmfGotoKwd(MshIdx, GmfByteFlow);
2444 GmfGetLin(MshIdx, GmfByteFlow, NmbByt);
2445
2446 // Read the byteflow as 4-byte blocks
2447 for(i=0;i<NmbWrd;i++)
2448 GmfGetLin(MshIdx, GmfByteFlow, &WrdTab[i]);
2449
2450 // Enable endianess convertion
2451 msh->cod = cod;
2452
2453 return((char *)WrdTab);
2454}
2455
2456
2457/*----------------------------------------------------------------------------*/
2458/* Write an EGADS binary CAD as an integer table whose first entry is the size*/
2459/*----------------------------------------------------------------------------*/
2460
2461int GmfWriteByteFlow(int64_t MshIdx, char *BytTab, int NmbByt)
2462{
2463 int i, PadWrd = 0, *WrdTab = (int *)BytTab, NmbWrd = NmbByt / WrdSiz4;
2464
2465 // Add an extra padding word at the end if needed
2466 if(NmbByt > NmbWrd * 4)
2467 PadWrd = 1;
2468
2469 // Create the keyword with the number of words, not bytes
2470 if(!GmfSetKwd(MshIdx, GmfByteFlow, NmbWrd + PadWrd))
2471 return(0);
2472
2473 // Reacord the exact number of bytes
2474 GmfSetLin(MshIdx, GmfByteFlow, NmbByt);
2475
2476 // Write the byteflow as 4-byte words, missing up to 3 endding bytes
2477 for(i=0;i<NmbWrd;i++)
2478 GmfSetLin(MshIdx, GmfByteFlow, WrdTab[i]);
2479
2480 // Write the extra 1,2 or 3 ending bytes
2481 if(PadWrd)
2482 {
2483 PadWrd = 0;
2484
2485 // Copy the last bytes in an integer
2486 for(i=0; i<NmbByt - NmbWrd * 4; i++)
2487 PadWrd |= BytTab[ NmbWrd * 4 + i ] << (i*8);
2488
2489 // And write it as the last line
2490 GmfSetLin(MshIdx, GmfByteFlow, PadWrd);
2491 }
2492
2493 return(1);
2494}
2495
2496
2497/*----------------------------------------------------------------------------*/
2498/* Override the floating point precision deduced form the file version */
2499/* with the one read from the GmfFloatingPointPrecision field */
2500/*----------------------------------------------------------------------------*/
2501
2502int GmfGetFloatPrecision(int64_t MshIdx)
2503{
2504 int FltSiz;
2505 GmfMshSct *msh = (GmfMshSct *)MshIdx;
2506
2507 if(GmfStatKwd(MshIdx, GmfFloatingPointPrecision))
2508 {
2509 GmfGotoKwd(MshIdx, GmfFloatingPointPrecision);
2510 GmfGetLin(MshIdx, GmfFloatingPointPrecision, &FltSiz);
2511
2512 if(FltSiz == 32 || FltSiz == 64)
2513 msh->FltSiz = FltSiz;
2514 }
2515
2516 return(msh->FltSiz);
2517}
2518
2519
2520/*----------------------------------------------------------------------------*/
2521/* Set the floating point precision arbitrarily, regardless the file version */
2522/*----------------------------------------------------------------------------*/
2523
2524void GmfSetFloatPrecision(int64_t MshIdx , int FltSiz)
2525{
2526 GmfMshSct *msh = (GmfMshSct *)MshIdx;
2527
2528 if(FltSiz != 32 && FltSiz != 64)
2529 return;
2530
2531 msh->FltSiz = FltSiz;
2532 GmfSetKwd(MshIdx, GmfFloatingPointPrecision, 1);
2533 GmfSetLin(MshIdx, GmfFloatingPointPrecision, FltSiz);
2534}
2535
2536#endif
2537
2538
2539/*----------------------------------------------------------------------------*/
2540/* Find every kw present in a meshfile */
2541/*----------------------------------------------------------------------------*/
2542
2543static int ScaKwdTab(GmfMshSct *msh)
2544{
2545 int KwdCod, c;
2546 int64_t NexPos, EndPos, LstPos;
2547 char str[ GmfStrSiz1024 ];
2548
2549 if(msh->typ & Asc1)
2550 {
2551 // Scan each string in the file until the end
2552 while(fscanf(msh->hdl, "%100s", str) != EOF(-1))
2553 {
2554 // Fast test in order to reject quickly the numeric values
2555 if(isalpha(str[0])((*__ctype_b_loc ())[(int) ((str[0]))] & (unsigned short int
) _ISalpha)
)
2556 {
2557 // Search which kwd code this string is associated with, then get its
2558 // header and save the curent position in file (just before the data)
2559 for(KwdCod=1; KwdCod<= GmfMaxKwdGmfLastKeyword - 1; KwdCod++)
2560 if(!strcmp(str, GmfKwdFmt[ KwdCod ][0]))
2561 {
2562 ScaKwdHdr(msh, KwdCod);
2563 break;
2564 }
2565 }
2566 else if(str[0] == '#')
2567 while((c = fgetc(msh->hdl)) != '\n' && c != EOF(-1));
2568 }
2569 }
2570 else
2571 {
2572 // Get file size
2573 EndPos = GetFilSiz(msh);
2574 LstPos = -1;
2575
2576 // Jump through kwd positions in the file
2577 do
2578 {
2579 // Get the kwd code and the next kwd position
2580 ScaWrd(msh, ( char *)&KwdCod);
2581 NexPos = GetPos(msh);
2582
2583 // Make sure the flow does not move beyond the file size
2584 if(NexPos > EndPos)
2585 longjmp(msh->err, -24);
2586
2587 // And check that it does not move back
2588 if(NexPos && (NexPos <= LstPos))
2589 longjmp(msh->err, -30);
2590
2591 LstPos = NexPos;
2592
2593 // Check if this kwd belongs to this mesh version
2594 if( (KwdCod >= 1) && (KwdCod <= GmfMaxKwdGmfLastKeyword - 1) )
2595 ScaKwdHdr(msh, KwdCod);
2596
2597 // Go to the next kwd
2598 if(NexPos && !(SetFilPos(msh, NexPos)))
2599 longjmp(msh->err, -25);
2600
2601 }while(NexPos && (KwdCod != GmfEnd));
2602 }
2603
2604 return(1);
2605}
2606
2607
2608/*----------------------------------------------------------------------------*/
2609/* Read and setup the keyword's header */
2610/*----------------------------------------------------------------------------*/
2611
2612static void ScaKwdHdr(GmfMshSct *msh, int KwdCod)
2613{
2614 int i;
2615 KwdSct *kwd = &msh->KwdTab[ KwdCod ];
2616
2617 if(!strcmp("i", GmfKwdFmt[ KwdCod ][1]))
2618 if(msh->typ & Asc1)
2619 safe_fscanf(msh->hdl, INT64_T_FMT, &kwd->NmbLin, msh->err)do { if( fscanf(msh->hdl, "%" "l" "d", &kwd->NmbLin
) != 1 ) longjmp( msh->err, -1); } while(0)
;
2620 else
2621 if(msh->ver <= 3)
2622 {
2623 ScaWrd(msh, (unsigned char *)&i);
2624 kwd->NmbLin = i;
2625 }
2626 else
2627 ScaDblWrd(msh, (unsigned char *)&kwd->NmbLin);
2628 else
2629 kwd->NmbLin = 1;
2630
2631 if(!strcmp("sr", GmfKwdFmt[ KwdCod ][2])
2632 || !strcmp("hr", GmfKwdFmt[ KwdCod ][2]) )
2633 {
2634 if(msh->typ & Asc1)
2635 {
2636 safe_fscanf(msh->hdl, "%d", &kwd->NmbTyp, msh->err)do { if( fscanf(msh->hdl, "%d", &kwd->NmbTyp) != 1 )
longjmp( msh->err, -1); } while(0)
;
2637
2638 for(i=0;i<kwd->NmbTyp;i++)
2639 safe_fscanf(msh->hdl, "%d", &kwd->TypTab[i], msh->err)do { if( fscanf(msh->hdl, "%d", &kwd->TypTab[i]) !=
1 ) longjmp( msh->err, -1); } while(0)
;
2640
2641 // Scan two extra fields for HO solutions: deg and nmb Nodes
2642 if(!strcmp("hr", GmfKwdFmt[ KwdCod ][2]))
2643 {
2644 safe_fscanf(msh->hdl, "%d", &kwd->deg, msh->err)do { if( fscanf(msh->hdl, "%d", &kwd->deg) != 1 ) longjmp
( msh->err, -1); } while(0)
;
2645 safe_fscanf(msh->hdl, "%d", &kwd->NmbNod, msh->err)do { if( fscanf(msh->hdl, "%d", &kwd->NmbNod) != 1 )
longjmp( msh->err, -1); } while(0)
;
2646 }
2647 else
2648 {
2649 kwd->deg = 0;
2650 kwd->NmbNod = 1;
2651 }
2652
2653 }
2654 else
2655 {
2656 ScaWrd(msh, (unsigned char *)&kwd->NmbTyp);
2657
2658 for(i=0;i<kwd->NmbTyp;i++)
2659 ScaWrd(msh, (unsigned char *)&kwd->TypTab[i]);
2660
2661 // Scan two extra fields for HO solutions: deg and nmb Nodes
2662 if(!strcmp("hr", GmfKwdFmt[ KwdCod ][2]))
2663 {
2664 ScaWrd(msh, (unsigned char *)&kwd->deg);
2665 ScaWrd(msh, (unsigned char *)&kwd->NmbNod);
2666 }
2667 else
2668 {
2669 kwd->deg = 0;
2670 kwd->NmbNod = 1;
2671 }
2672 }
2673 }
2674
2675 ExpFmt(msh, KwdCod);
2676 kwd->pos = GetFilPos(msh);
2677}
2678
2679
2680/*----------------------------------------------------------------------------*/
2681/* Expand the compacted format and compute the line size */
2682/*----------------------------------------------------------------------------*/
2683
2684static void ExpFmt(GmfMshSct *msh, int KwdCod)
2685{
2686 int i, j, TmpSiz=0, IntWrd, FltWrd;
2687 char chr;
2688 const char *InpFmt = GmfKwdFmt[ KwdCod ][2];
2689 KwdSct *kwd = &msh->KwdTab[ KwdCod ];
2690
2691 // Set the kwd's type
2692 if(!strlen(GmfKwdFmt[ KwdCod ][1]))
2693 kwd->typ = InfKwd1;
2694 else if( !strcmp(InpFmt, "sr") || !strcmp(InpFmt, "hr") )
2695 kwd->typ = SolKwd3;
2696 else
2697 kwd->typ = RegKwd2;
2698
2699 // Get the solution-field's size
2700 if(kwd->typ == SolKwd3)
2701 for(i=0;i<kwd->NmbTyp;i++)
2702 switch(kwd->TypTab[i])
2703 {
2704 case GmfSca1 : TmpSiz += 1; break;
2705 case GmfVec2 : TmpSiz += msh->dim; break;
2706 case GmfSymMat3 : TmpSiz += (msh->dim * (msh->dim+1)) / 2; break;
2707 case GmfMat4 : TmpSiz += msh->dim * msh->dim; break;
2708 }
2709
2710 // Scan each character from the format string
2711 i = kwd->SolSiz = kwd->NmbWrd = 0;
2712
2713 while(i < (int)strlen(InpFmt))
2714 {
2715 chr = InpFmt[ i++ ];
2716
2717 if(chr == 'd')
2718 {
2719 chr = InpFmt[i++];
2720
2721 for(j=0;j<msh->dim;j++)
2722 kwd->fmt[ kwd->SolSiz++ ] = chr;
2723 }
2724 else if((chr == 's')||(chr == 'h'))
2725 {
2726 chr = InpFmt[i++];
2727
2728 for(j=0;j<TmpSiz;j++)
2729 kwd->fmt[ kwd->SolSiz++ ] = chr;
2730 }
2731 else
2732 kwd->fmt[ kwd->SolSiz++ ] = chr;
2733 }
2734
2735 if(msh->FltSiz == 32)
2736 FltWrd = 1;
2737 else
2738 FltWrd = 2;
2739
2740 if(msh->ver <= 3)
2741 IntWrd = 1;
2742 else
2743 IntWrd = 2;
2744
2745 for(i=0;i<kwd->SolSiz;i++)
2746 switch(kwd->fmt[i])
2747 {
2748 case 'i' : kwd->NmbWrd += IntWrd; break;
2749 case 'c' : kwd->NmbWrd += FilStrSiz64; break;
2750 case 'r' : kwd->NmbWrd += FltWrd;break;
2751 }
2752
2753 // HO solution: duplicate the format as many times as the number of nodes
2754 if( !strcmp(InpFmt, "hr") && (kwd->NmbNod > 1) )
2755 {
2756 for(i=1;i<=kwd->NmbNod;i++)
2757 for(j=0;j<kwd->SolSiz;j++)
2758 kwd->fmt[ i * kwd->SolSiz + j ] = kwd->fmt[j];
2759
2760 kwd->SolSiz *= kwd->NmbNod;
2761 kwd->NmbWrd *= kwd->NmbNod;
2762 }
2763}
2764
2765
2766/*----------------------------------------------------------------------------*/
2767/* Read a four bytes word from a mesh file */
2768/*----------------------------------------------------------------------------*/
2769
2770static void ScaWrd(GmfMshSct *msh, void *ptr)
2771{
2772#ifdef WITH_GMF_AIO
2773 if(read(msh->FilDes, ptr, WrdSiz4) != WrdSiz4)
2774#else
2775 if(fread(ptr, WrdSiz4, 1, msh->hdl) != 1)
2776#endif
2777 longjmp(msh->err, -26);
2778
2779 if(msh->cod != 1)
2780 SwpWrd((char *)ptr, WrdSiz4);
2781}
2782
2783
2784/*----------------------------------------------------------------------------*/
2785/* Read an eight bytes word from a mesh file */
2786/*----------------------------------------------------------------------------*/
2787
2788static void ScaDblWrd(GmfMshSct *msh, void *ptr)
2789{
2790#ifdef WITH_GMF_AIO
2791 if(read(msh->FilDes, ptr, WrdSiz4 * 2) != WrdSiz4 * 2)
2792#else
2793 if( fread(ptr, WrdSiz4, 2, msh->hdl) != 2 )
2794#endif
2795 longjmp(msh->err, -27);
2796
2797 if(msh->cod != 1)
2798 SwpWrd((char *)ptr, 2 * WrdSiz4);
2799}
2800
2801
2802/*----------------------------------------------------------------------------*/
2803/* Read a 4 or 8 bytes position in mesh file */
2804/*----------------------------------------------------------------------------*/
2805
2806static int64_t GetPos(GmfMshSct *msh)
2807{
2808 int IntVal;
2809 int64_t pos;
2810
2811 if(msh->ver >= 3)
2812 ScaDblWrd(msh, (unsigned char*)&pos);
2813 else
2814 {
2815 ScaWrd(msh, (unsigned char*)&IntVal);
2816 pos = (int64_t)IntVal;
2817 }
2818
2819 return(pos);
2820}
2821
2822
2823/*----------------------------------------------------------------------------*/
2824/* Write a four bytes word to a mesh file */
2825/*----------------------------------------------------------------------------*/
2826
2827static void RecWrd(GmfMshSct *msh, const void *wrd)
2828{
2829 // [Bruno] added error control
2830#ifdef WITH_GMF_AIO
2831 if(write(msh->FilDes, wrd, WrdSiz4) != WrdSiz4)
2832#else
2833 if(fwrite(wrd, WrdSiz4, 1, msh->hdl) != 1)
2834#endif
2835 longjmp(msh->err,-28);
2836}
2837
2838
2839/*----------------------------------------------------------------------------*/
2840/* Write an eight bytes word to a mesh file */
2841/*----------------------------------------------------------------------------*/
2842
2843static void RecDblWrd(GmfMshSct *msh, const void *wrd)
2844{
2845 // [Bruno] added error control
2846#ifdef WITH_GMF_AIO
2847 if(write(msh->FilDes, wrd, WrdSiz4 * 2) != WrdSiz4*2)
2848#else
2849 if(fwrite(wrd, WrdSiz4, 2, msh->hdl) != 2)
2850#endif
2851 longjmp(msh->err,-29);
2852}
2853
2854
2855/*----------------------------------------------------------------------------*/
2856/* Write a block of four bytes word to a mesh file */
2857/*----------------------------------------------------------------------------*/
2858
2859static void RecBlk(GmfMshSct *msh, const void *blk, int siz)
2860{
2861 // Copy this line-block into the main mesh buffer
2862 if(siz)
2863 {
2864 memcpy(&msh->blk[ msh->pos ], blk, (size_t)(siz * WrdSiz4));
2865 msh->pos += siz * WrdSiz4;
2866 }
2867
2868 // When the buffer is full or this procedure is APIF77ed with a 0 size,
2869 // flush the cache on disk
2870
2871 if( (msh->pos > BufSiz10000L) || (!siz && msh->pos) )
2872 {
2873#ifdef GMF_WINDOWS
2874 /*
2875 * [Bruno] TODO: check that msh->pos is smaller
2876 * than 4G (fits in 32 bits).
2877 * Note: for now, when trying to write more than 4Gb, it will
2878 * trigger an error (longjmp).
2879 * As far as I understand:
2880 * Given that this function just flushes the cache, and given that
2881 * the cache size is 10000 words, this is much much smaller than 4Gb
2882 * so there is probably no problem.
2883 */
2884#ifdef WITH_GMF_AIO
2885 if(write(msh->FilDes, msh->blk, (int)msh->pos) != (ssize_t)msh->pos)
2886#else
2887 if(fwrite(msh->blk, 1, (size_t)msh->pos, msh->hdl) != msh->pos)
2888#endif
2889 longjmp(msh->err, -30);
2890#else
2891#ifdef WITH_GMF_AIO
2892 if(write(msh->FilDes, msh->blk, msh->pos) != (ssize_t)msh->pos)
2893#else
2894 if(fwrite(msh->blk, 1, msh->pos, msh->hdl) != msh->pos)
2895#endif
2896 longjmp(msh->err, -31);
2897#endif
2898 msh->pos = 0;
2899 }
2900}
2901
2902
2903/*----------------------------------------------------------------------------*/
2904/* Write a 4 or 8 bytes position in a mesh file */
2905/*----------------------------------------------------------------------------*/
2906
2907static void SetPos(GmfMshSct *msh, int64_t pos)
2908{
2909 int IntVal;
2910
2911 if(msh->ver >= 3)
2912 RecDblWrd(msh, (unsigned char*)&pos);
2913 else
2914 {
2915 IntVal = (int)pos;
2916 RecWrd(msh, (unsigned char*)&IntVal);
2917 }
2918}
2919
2920
2921/*----------------------------------------------------------------------------*/
2922/* Endianness conversion */
2923/*----------------------------------------------------------------------------*/
2924
2925static void SwpWrd(char *wrd, int siz)
2926{
2927 char swp;
2928 int i;
2929
2930 for(i=0;i<siz/2;i++)
2931 {
2932 swp = wrd[ siz-i-1 ];
2933 wrd[ siz-i-1 ] = wrd[i];
2934 wrd[i] = swp;
2935 }
2936}
2937
2938
2939/*----------------------------------------------------------------------------*/
2940/* Set current position in a file */
2941/*----------------------------------------------------------------------------*/
2942
2943static int SetFilPos(GmfMshSct *msh, int64_t pos)
2944{
2945#ifdef WITH_GMF_AIO
2946 if(msh->typ & Bin2)
2947 return((lseek(msh->FilDes, (off_t)pos, 0) != -1));
2948 else
2949 return((MYFSEEK(msh->hdl, (off_t)pos, SEEK_SET)fseek(msh->hdl,(off_t)pos,0) == 0));
2950#else
2951 return((MYFSEEK(msh->hdl, (off_t)pos, SEEK_SET)fseek(msh->hdl,(off_t)pos,0) == 0));
2952#endif
2953}
2954
2955
2956/*----------------------------------------------------------------------------*/
2957/* Get current position in a file */
2958/*----------------------------------------------------------------------------*/
2959
2960static int64_t GetFilPos(GmfMshSct *msh)
2961{
2962#ifdef WITH_GMF_AIO
2963 if(msh->typ & Bin2)
2964 return(lseek(msh->FilDes, 0, 1));
2965 else
2966 return(MYFTELL(msh->hdl)ftell(msh->hdl));
2967#else
2968 return(MYFTELL(msh->hdl)ftell(msh->hdl));
2969#endif
2970}
2971
2972
2973/*----------------------------------------------------------------------------*/
2974/* Move the position to the end of file and return the size */
2975/*----------------------------------------------------------------------------*/
2976
2977static int64_t GetFilSiz(GmfMshSct *msh)
2978{
2979 int64_t CurPos, EndPos = 0;
2980
2981 if(msh->typ & Bin2)
2982 {
2983#ifdef WITH_GMF_AIO
2984 CurPos = lseek(msh->FilDes, 0, 1);
2985 EndPos = lseek(msh->FilDes, 0, 2);
2986 lseek(msh->FilDes, (off_t)CurPos, 0);
2987#else
2988 CurPos = MYFTELL(msh->hdl)ftell(msh->hdl);
2989
2990 if(MYFSEEK(msh->hdl, 0, SEEK_END)fseek(msh->hdl,0,2) != 0)
2991 longjmp(msh->err, -32);
2992
2993 EndPos = MYFTELL(msh->hdl)ftell(msh->hdl);
2994
2995 if(MYFSEEK(msh->hdl, (off_t)CurPos, SEEK_SET)fseek(msh->hdl,(off_t)CurPos,0) != 0)
2996 longjmp(msh->err, -33);
2997#endif
2998 }
2999 else
3000 {
3001 CurPos = MYFTELL(msh->hdl)ftell(msh->hdl);
3002
3003 if(MYFSEEK(msh->hdl, 0, SEEK_END)fseek(msh->hdl,0,2) != 0)
3004 longjmp(msh->err, -34);
3005
3006 EndPos = MYFTELL(msh->hdl)ftell(msh->hdl);
3007
3008 if(MYFSEEK(msh->hdl, (off_t)CurPos, SEEK_SET)fseek(msh->hdl,(off_t)CurPos,0) != 0)
3009 longjmp(msh->err, -35);
3010 }
3011
3012 return(EndPos);
3013}
3014
3015
3016/*----------------------------------------------------------------------------*/
3017/* Fortran 77 API */
3018/*----------------------------------------------------------------------------*/
3019
3020#ifdef F77API
3021
3022int64_t APIF77(gmfopenmesh)( char *FilNam, int *mod,
3023 int *ver, int *dim, int StrSiz )
3024{
3025 int i = 0;
3026 char TmpNam[ GmfStrSiz1024 ];
3027
3028 if(StrSiz <= 0)
3029 return(0);
3030
3031 // Trim trailing spaces from the fortran string
3032 while(isspace(FilNam[ StrSiz-1 ])((*__ctype_b_loc ())[(int) ((FilNam[ StrSiz-1 ]))] & (unsigned
short int) _ISspace)
)
3033 StrSiz--;
3034
3035 for(i=0;i<StrSiz;i++)
3036 TmpNam[i] = FilNam[i];
3037
3038 TmpNam[ StrSiz ] = 0;
3039
3040 if(*mod == GmfRead1)
3041 return(GmfOpenMesh(TmpNam, *mod, ver, dim));
3042 else
3043 return(GmfOpenMesh(TmpNam, *mod, *ver, *dim));
3044}
3045
3046int APIF77(gmfclosemesh)(int64_t *idx)
3047{
3048 return(GmfCloseMesh(*idx));
3049}
3050
3051int APIF77(gmfgotokwd)(int64_t *MshIdx, int *KwdIdx)
3052{
3053 return(GmfGotoKwd(*MshIdx, *KwdIdx));
3054}
3055
3056int APIF77(gmfstatkwd)( int64_t *MshIdx, int *KwdIdx, int *NmbTyp,
3057 int *SolSiz, int *TypTab, int *deg, int *NmbNod)
3058{
3059 if(!strcmp(GmfKwdFmt[ *KwdIdx ][2], "hr"))
3060 return(GmfStatKwd(*MshIdx, *KwdIdx, NmbTyp, SolSiz, TypTab, deg, NmbNod));
3061 else if(!strcmp(GmfKwdFmt[ *KwdIdx ][2], "sr"))
3062 return(GmfStatKwd(*MshIdx, *KwdIdx, NmbTyp, SolSiz, TypTab));
3063 else
3064 return(GmfStatKwd(*MshIdx, *KwdIdx));
3065}
3066
3067int APIF77(gmfsetkwd)( int64_t *MshIdx, int *KwdIdx, int *NmbLin,
3068 int *NmbTyp, int *TypTab, int *deg, int *NmbNod)
3069{
3070 if(!strcmp(GmfKwdFmt[ *KwdIdx ][2], "hr"))
3071 return(GmfSetKwd(*MshIdx, *KwdIdx, *NmbLin, *NmbTyp, TypTab, *deg, *NmbNod));
3072 else if(!strcmp(GmfKwdFmt[ *KwdIdx ][2], "sr"))
3073 return(GmfSetKwd(*MshIdx, *KwdIdx, *NmbLin, *NmbTyp, TypTab));
3074 else
3075 return(GmfSetKwd(*MshIdx, *KwdIdx, *NmbLin));
3076}
3077
3078
3079int APIF77(gmfsethonodesordering)(int64_t *MshIdx, int *KwdCod, int *BasTab, int *OrdTab)
3080{
3081 return(GmfSetHONodesOrdering(*MshIdx, *KwdCod, BasTab, OrdTab));
3082}
3083/*
3084int APIF77(gmfreadbyteflow)(int64_t *MshIdx, char *BytFlo, int *NmbByt)
3085{
3086 int TmpNmb;
3087 char *TmpFlo;
3088
3089 TmpFlo = GmfReadByteFlow(*MshIdx, &TmpNmb);
3090
3091 if(!TmpFlo || NmbByt <= 0 || !BytFlo || TmpNmb > *NmbByt)
3092 return(0);
3093
3094 *NmbByt = TmpNmb;
3095 memcpy(BytFlo, TmpFlo, *NmbByt);
3096 free(TmpFlo);
3097
3098 return(TmpNmb);
3099}
3100
3101int APIF77(gmfwritebyteflow)(int64_t *MshIdx, char *BytFlo, int *NmbByt)
3102{
3103 return(GmfWriteByteFlow(*MshIdx, BytFlo, *NmbByt));
3104}
3105
3106int APIF77(gmfgetfloatprecision)(int64_t *MshIdx)
3107{
3108 return(GmfGetFloatPrecision(*MshIdx));
3109}
3110
3111int APIF77(gmfsetfloatprecision)(int64_t *MshIdx, int *FltSiz)
3112{
3113 GmfSetFloatPrecision(*MshIdx, *FltSiz);
3114 return(0);
3115}
3116*/
3117
3118/*----------------------------------------------------------------------------*/
3119/* Duplication macros */
3120/*----------------------------------------------------------------------------*/
3121
3122#define DUP(s,n) DUP ## n (s)
3123#define DUP1(s) s
3124#define DUP2(s) DUP1(s),s
3125#define DUP3(s) DUP2(s),s
3126#define DUP4(s) DUP3(s),s
3127#define DUP5(s) DUP4(s),s
3128#define DUP6(s) DUP5(s),s
3129#define DUP7(s) DUP6(s),s
3130#define DUP8(s) DUP7(s),s
3131#define DUP9(s) DUP8(s),s
3132#define DUP10(s) DUP9(s),s
3133#define DUP11(s) DUP10(s),s
3134#define DUP12(s) DUP11(s),s
3135#define DUP13(s) DUP12(s),s
3136#define DUP14(s) DUP13(s),s
3137#define DUP15(s) DUP14(s),s
3138#define DUP16(s) DUP15(s),s
3139#define DUP17(s) DUP16(s),s
3140#define DUP18(s) DUP17(s),s
3141#define DUP19(s) DUP18(s),s
3142#define DUP20(s) DUP19(s),s
3143
3144
3145#define ARG(a,n) ARG ## n (a)
3146#define ARG1(a) a[0]
3147#define ARG2(a) ARG1(a),a[1]
3148#define ARG3(a) ARG2(a),a[2]
3149#define ARG4(a) ARG3(a),a[3]
3150#define ARG5(a) ARG4(a),a[4]
3151#define ARG6(a) ARG5(a),a[5]
3152#define ARG7(a) ARG6(a),a[6]
3153#define ARG8(a) ARG7(a),a[7]
3154#define ARG9(a) ARG8(a),a[8]
3155#define ARG10(a) ARG9(a),a[9]
3156#define ARG11(a) ARG10(a),a[10]
3157#define ARG12(a) ARG11(a),a[11]
3158#define ARG13(a) ARG12(a),a[12]
3159#define ARG14(a) ARG13(a),a[13]
3160#define ARG15(a) ARG14(a),a[14]
3161#define ARG16(a) ARG15(a),a[15]
3162#define ARG17(a) ARG16(a),a[16]
3163#define ARG18(a) ARG17(a),a[17]
3164#define ARG19(a) ARG18(a),a[18]
3165#define ARG20(a) ARG19(a),a[19]
3166
3167
3168/*----------------------------------------------------------------------------*/
3169/* Call a fortran thread with 1 to 20 arguments */
3170/*----------------------------------------------------------------------------*/
3171
3172static void CalF77Prc( int64_t BegIdx, int64_t EndIdx,
3173 void *prc, int NmbArg, void **ArgTab )
3174{
3175 switch(NmbArg)
3176 {
3177 case 1 :
3178 {
3179 void (*prc1)(int64_t *, int64_t *, DUP(void *, 1)) =
3180 (void (*)(int64_t *, int64_t *, DUP(void *, 1)))prc;
3181 prc1(&BegIdx, &EndIdx, ARG(ArgTab, 1));
3182 }break;
3183
3184 case 2 :
3185 {
3186 void (*prc1)(int64_t *, int64_t *, DUP(void *, 2)) =
3187 (void (*)(int64_t *, int64_t *, DUP(void *, 2)))prc;
3188 prc1(&BegIdx, &EndIdx, ARG(ArgTab, 2));
3189 }break;
3190
3191 case 3 :
3192 {
3193 void (*prc1)(int64_t *, int64_t *, DUP(void *, 3)) =
3194 (void (*)(int64_t *, int64_t *, DUP(void *, 3)))prc;
3195 prc1(&BegIdx, &EndIdx, ARG(ArgTab, 3));
3196 }break;
3197
3198 case 4 :
3199 {
3200 void (*prc1)(int64_t *, int64_t *, DUP(void *, 4)) =
3201 (void (*)(int64_t *, int64_t *, DUP(void *, 4)))prc;
3202 prc1(&BegIdx, &EndIdx, ARG(ArgTab, 4));
3203 }break;
3204
3205 case 5 :
3206 {
3207 void (*prc1)(int64_t *, int64_t *, DUP(void *, 5)) =
3208 (void (*)(int64_t *, int64_t *, DUP(void *, 5)))prc;
3209 prc1(&BegIdx, &EndIdx, ARG(ArgTab, 5));
3210 }break;
3211
3212 case 6 :
3213 {
3214 void (*prc1)(int64_t *, int64_t *, DUP(void *, 6)) =
3215 (void (*)(int64_t *, int64_t *, DUP(void *, 6)))prc;
3216 prc1(&BegIdx, &EndIdx, ARG(ArgTab, 6));
3217 }break;
3218
3219 case 7 :
3220 {
3221 void (*prc1)(int64_t *, int64_t *, DUP(void *, 7)) =
3222 (void (*)(int64_t *, int64_t *, DUP(void *, 7)))prc;
3223 prc1(&BegIdx, &EndIdx, ARG(ArgTab, 7));
3224 }break;
3225
3226 case 8 :
3227 {
3228 void (*prc1)(int64_t *, int64_t *, DUP(void *, 8)) =
3229 (void (*)(int64_t *, int64_t *, DUP(void *, 8)))prc;
3230 prc1(&BegIdx, &EndIdx, ARG(ArgTab, 8));
3231 }break;
3232
3233 case 9 :
3234 {
3235 void (*prc1)(int64_t *, int64_t *, DUP(void *, 9)) =
3236 (void (*)(int64_t *, int64_t *, DUP(void *, 9)))prc;
3237 prc1(&BegIdx, &EndIdx, ARG(ArgTab, 9));
3238 }break;
3239
3240 case 10 :
3241 {
3242 void (*prc1)(int64_t *, int64_t *, DUP(void *, 10)) =
3243 (void (*)(int64_t *, int64_t *, DUP(void *, 10)))prc;
3244 prc1(&BegIdx, &EndIdx, ARG(ArgTab, 10));
3245 }break;
3246
3247 case 11 :
3248 {
3249 void (*prc1)(int64_t *, int64_t *, DUP(void *, 11)) =
3250 (void (*)(int64_t *, int64_t *, DUP(void *, 11)))prc;
3251 prc1(&BegIdx, &EndIdx, ARG(ArgTab, 11));
3252 }break;
3253
3254 case 12 :
3255 {
3256 void (*prc1)(int64_t *, int64_t *, DUP(void *, 12)) =
3257 (void (*)(int64_t *, int64_t *, DUP(void *, 12)))prc;
3258 prc1(&BegIdx, &EndIdx, ARG(ArgTab, 12));
3259 }break;
3260
3261 case 13 :
3262 {
3263 void (*prc1)(int64_t *, int64_t *, DUP(void *, 13)) =
3264 (void (*)(int64_t *, int64_t *, DUP(void *, 13)))prc;
3265 prc1(&BegIdx, &EndIdx, ARG(ArgTab, 13));
3266 }break;
3267
3268 case 14 :
3269 {
3270 void (*prc1)(int64_t *, int64_t *, DUP(void *, 14)) =
3271 (void (*)(int64_t *, int64_t *, DUP(void *, 14)))prc;
3272 prc1(&BegIdx, &EndIdx, ARG(ArgTab, 14));
3273 }break;
3274
3275 case 15 :
3276 {
3277 void (*prc1)(int64_t *, int64_t *, DUP(void *, 15)) =
3278 (void (*)(int64_t *, int64_t *, DUP(void *, 15)))prc;
3279 prc1(&BegIdx, &EndIdx, ARG(ArgTab, 15));
3280 }break;
3281
3282 case 16 :
3283 {
3284 void (*prc1)(int64_t *, int64_t *, DUP(void *, 16)) =
3285 (void (*)(int64_t *, int64_t *, DUP(void *, 16)))prc;
3286 prc1(&BegIdx, &EndIdx, ARG(ArgTab, 16));
3287 }break;
3288
3289 case 17 :
3290 {
3291 void (*prc1)(int64_t *, int64_t *, DUP(void *, 17)) =
3292 (void (*)(int64_t *, int64_t *, DUP(void *, 17)))prc;
3293 prc1(&BegIdx, &EndIdx, ARG(ArgTab, 17));
3294 }break;
3295
3296 case 18 :
3297 {
3298 void (*prc1)(int64_t *, int64_t *, DUP(void *, 18)) =
3299 (void (*)(int64_t *, int64_t *, DUP(void *, 18)))prc;
3300 prc1(&BegIdx, &EndIdx, ARG(ArgTab, 18));
3301 }break;
3302
3303 case 19 :
3304 {
3305 void (*prc1)(int64_t *, int64_t *, DUP(void *, 19)) =
3306 (void (*)(int64_t *, int64_t *, DUP(void *, 19)))prc;
3307 prc1(&BegIdx, &EndIdx, ARG(ArgTab, 19));
3308 }break;
3309
3310 case 20 :
3311 {
3312 void (*prc1)(int64_t *, int64_t *, DUP(void *, 20)) =
3313 (void (*)(int64_t *, int64_t *, DUP(void *, 20)))prc;
3314 prc1(&BegIdx, &EndIdx, ARG(ArgTab, 20));
3315 }break;
3316 }
3317}
3318
3319#endif