Bug Summary

File:/home/jenkins/workspace/ESP_Stanalizer/LINUX64/CAPS/scan-build/CAPS/aim/refine/../meshWriter/libmeshbWriter/libMeshb/sources/libmeshb7.c
Warning:line 1652, column 9
Although the value stored to 'err' is used in the enclosing expression, the value is never actually read from 'err'

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