mirror of
https://bitbucket.org/cosmicvoids/vide_public.git
synced 2025-07-05 15:51:12 +00:00
Imported libSDF into VOID tree
This commit is contained in:
parent
c6dd08bd7d
commit
2d09cb68df
55 changed files with 12667 additions and 0 deletions
313
external/libsdf/libSDF/ChangeLog.14
vendored
Normal file
313
external/libsdf/libSDF/ChangeLog.14
vendored
Normal file
|
@ -0,0 +1,313 @@
|
|||
Fri Jan 7 13:50:53 1994 John Salmon (johns@haggis)
|
||||
|
||||
* Terminate this ChangeLog. Future changes to be logged
|
||||
in the parent directory.
|
||||
|
||||
Wed Dec 29 08:57:39 1993 John Salmon (johns@sampson)
|
||||
|
||||
* fseekrd.c (fseekrd): #include protos.h and error.h
|
||||
|
||||
Mon Dec 27 18:05:36 1993 John Salmon (johns@lux)
|
||||
|
||||
* fseekrd.c: Bail out with Error in the event of an error.
|
||||
|
||||
Sun Oct 10 21:02:27 1993 John Salmon (johns@sockeye)
|
||||
|
||||
* SDFget.c: Added protos.h. Silenced a warning.
|
||||
|
||||
Tue Jul 13 11:19:20 1993 John Salmon (johns@lux)
|
||||
|
||||
* libSDF/: changed some formats to silence complaints about
|
||||
incorrect argument passing to printf. These SHOULD all be
|
||||
changed to singlWarning.
|
||||
|
||||
Thu Jun 10 15:34:01 1993 John Salmon (johns@haggis)
|
||||
|
||||
* SDF.h, SDFget.c: Added the functions SDFgetint, SDFgetdouble
|
||||
SDFgetfloat and SDFgetstring to the library. In addition, added
|
||||
the macros SDFget*OrDie and SDFget*OrDefault to SDF.h. The macros
|
||||
use Error and singlWarning, which can be found in the swutils
|
||||
library, or which the user may redefine to taste.
|
||||
|
||||
Thu Jun 3 16:32:18 1993 John Salmon (johns at haggis)
|
||||
|
||||
* Revert back to the i860_utils style of managing the PGI,
|
||||
IPSC_XDEV, etc. environment variables. "The management apologizes
|
||||
for the inconvenience." The reason is that i860_target doesn't
|
||||
interact well with Make running inside emacs.
|
||||
|
||||
Tue Jun 1 20:51:16 1993 John Salmon (johns@sockeye)
|
||||
|
||||
* (../SDF): Changed Make.common so it creates libraries in, e.g.,
|
||||
sun4/libSDF.a. Make the old-style SDF_sun4.a a symbolic link to
|
||||
the new file. Use of <ARCH>/libSDF.a is encouraged.
|
||||
|
||||
Tue Jun 1 20:47:04 1993 John Salmon (johns at haggis)
|
||||
|
||||
* Added (this) ChangeLog to the list of docs copied into .tar files!
|
||||
|
||||
Wed May 26 20:02:14 1993 John Salmon (johns at sampson)
|
||||
|
||||
* Removed the -delta flags from Make.delta. Use the i860_target
|
||||
technology instead.
|
||||
|
||||
* Fixed two bugs related to ascii data. On line 399 of
|
||||
SDF-parse.y and line 646 of SDFfuncs.c. Recompiled sun4 and delta
|
||||
versions. It should now correctly handle ascii data.
|
||||
|
||||
Tue Mar 2 20:26:09 1993 John Salmon (johns at sampson)
|
||||
|
||||
* Conditionalized the #define YYDEBUG 1 so it won't get linked on
|
||||
the delta. It surely can't do us any good!
|
||||
|
||||
* Added a comment (but no code) to SDF-parse.y that worries about
|
||||
what to do when a string constant is too long to fit in a char array.
|
||||
|
||||
* Changed SDFtst.c so it prints the first element of every vector
|
||||
in the file it reads. Just another diagnostic that might show up
|
||||
an error...
|
||||
|
||||
Wed Feb 10 20:12:15 1993 John Salmon (johns at sampson)
|
||||
|
||||
* Don't close stdin in SDFissdf!
|
||||
|
||||
Wed Dec 9 11:36:53 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Changed the #ifdef SEEK_SET conditionals in SDF.h. Now
|
||||
the 'preferred' usage is SDF_SEEK_SET, etc., but they are
|
||||
almost guaranteed to be the same as SEEK_SET from stdio.h.
|
||||
If they aren't, complete and untraceable confusion will surely
|
||||
result. Changed SEEK_SET, etc. in SDFfuncs.c to SDF_SEEK_SET,
|
||||
etc.
|
||||
|
||||
Wed Dec 2 17:55:08 1992 John Salmon (johns at pollux)
|
||||
|
||||
* Added ncube2 support. This means setting up a Make.ncube2,
|
||||
and getting alloca.c (unmodified) from the emacs distribution,
|
||||
and saying 'extrasrc:=alloca.c' in Make.ncube2. Also added
|
||||
a call to alloca(0) to SDFopen just after yyparse, which should
|
||||
clean up any mess left behind by the C alloca.
|
||||
|
||||
Fri Nov 13 18:42:33 1992 John Salmon (johns at sampson)
|
||||
|
||||
* Reset yylineno in SDFyyprepare(). Otherwise error message
|
||||
line numbers accumulate!
|
||||
|
||||
Tue Nov 10 20:21:11 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Changed the typedef for SDF in SDF.h. It still doesn't tell
|
||||
you what's really going on in an SDF hdr, but at least prototypes
|
||||
get checked for correctness, and printing an SDF* under gdb might
|
||||
even tell you most of what you care to know.
|
||||
|
||||
Tue Oct 27 12:24:50 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Fixed a bug in SDF-lex.l that didn't recognize signed
|
||||
integer constants. How did this last for so long?! The
|
||||
{Sign} specifier was simply missing from the regex.
|
||||
|
||||
Fri Oct 16 11:10:13 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Added halocenterx, halocentery and halocenterz to the
|
||||
generic tree.sdfh and tree_ap.sdfh files. These are used
|
||||
by the isothermal halo integrator (i.e., Carl).
|
||||
|
||||
Thu Oct 15 21:34:20 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Try to be even more defensive in SDFclose, in order to not
|
||||
get SEGV when bailing out of a parse error. This is not
|
||||
a finished project! Careful cleanup should be attempted in
|
||||
yyerror().
|
||||
|
||||
Fri Oct 9 08:34:50 1992 John Salmon (johns at delilah)
|
||||
|
||||
* SDF now only uses SEEK_CUR to reposition itself in the file.
|
||||
fseekrd() will work with SEEK_CUR and any positive offset by
|
||||
freading into a junk buffer, regardless of whether the file is
|
||||
seekable. Thus, operations on unseekable files need not be
|
||||
sequential. They must still be "monotonic increasing".
|
||||
|
||||
Thu Oct 8 10:06:49 1992 John Salmon (johns at delilah)
|
||||
|
||||
* Added support for reading from unseekable files. This means
|
||||
keeping track of the "seek pointer" ourselves, and checking
|
||||
whether seeking is really necessary to accomodate requests. If
|
||||
the caller doesn't require us to seek, then we don't. If he does,
|
||||
then we fail.
|
||||
|
||||
* Added SDFsetbufsz/SDFgetbufsz, which induce SDF to malloc a
|
||||
buffer and call setvbuf in all subsequent SDFopen's. Use for
|
||||
tuning access to tape devices and pipes.
|
||||
|
||||
Wed Sep 16 11:12:40 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Added the keyword "long" to the set of possible types.
|
||||
It behaves EXACTLY the same as "int". There is no corresponding
|
||||
SDF_LONG. Is this really a good idea (the same was done for unsigned).
|
||||
|
||||
* Fixed a bug in SDF-parse.y which caused miscounting the
|
||||
lengths of implicit arrays, e.g., char greeting[] = "hello";
|
||||
|
||||
* Added Const to many of the arguments in SDF.h.
|
||||
|
||||
Tue Sep 15 17:10:48 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Eliminated the huge redundancy in SDFrdvecsarr, and made it
|
||||
call SDFseekrdvecsarr. This not only shortens the code, but it
|
||||
probably means more reasonable behavior on return from errors.
|
||||
Ever wonder what would happen if you do an SDFrdvecsarr and the
|
||||
last "name" you give it doesn't exist? Well it's much better now.
|
||||
|
||||
Wed Sep 2 15:12:06 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Changed the strategy for grabbing temporary space in SDFrdvecsarr
|
||||
and SDFseekrdvecsarr. Now if malloc fails, we try successively
|
||||
smaller requests until we get something. We only give up with
|
||||
an error if we can't get enough for a single "record" (i.e.,
|
||||
struct). The memory is freed at the end of the execution of
|
||||
SDF*rdvecsarr.
|
||||
|
||||
* In the interests of reducing namespace pollution, changed the enum
|
||||
names in SDF_type_enum to be SDF_INT, SDF_FLOAT, etc. This will
|
||||
break some old codes. Old codes can be made to compile by
|
||||
adding a #define OLD_ENUM_NAMES before #include "SDF.h".
|
||||
|
||||
* Changed the external name of swapn to SDFswapn. This should
|
||||
not effect anything.
|
||||
|
||||
Tue Sep 1 10:13:05 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Added an if( hdr==NULL ) test to each of the exported SDF
|
||||
functions. This should cut down on memory faults from users
|
||||
who don't check the return from SDFopen. It might even be
|
||||
worthwhile to put a magic number in the SDF hdr.
|
||||
|
||||
Mon Aug 31 17:43:25 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Fixed a typo in SDF-lex.l and recompiled delta and sun4.
|
||||
|
||||
* Checked the return of realloc against NULL in the middle of
|
||||
SDFrdvecsarr and SDFseekrdvecsarr. The program now fails with
|
||||
a message rather than getting a Segv. It is probably not recoverable.
|
||||
We really should reduce the size of some of these buffers by
|
||||
staging them.
|
||||
|
||||
Tue Jun 30 02:39:30 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Removed some spurious newlines from the ends of the .sdfh files.
|
||||
These make trouble if you try to do "cat tree.sdfh foo.tree > foo.sdf"
|
||||
|
||||
* INCOMPATIBLE CHANGE: changed the calling convention for
|
||||
SDFopen. Now we pass in two char strings, both filenames, one
|
||||
for the header and one for the data. This has a number of
|
||||
beneficial effects:
|
||||
1) It means we don't have to 'agree' on what kind of FILE is
|
||||
in use with the 'user'. (e.g., CUBIX, NX, SRV, etc.) All the nasty
|
||||
business gets handled inside SDF in the Makefile and such.
|
||||
2) It's easier for a 'user' to specify a header that comes from a
|
||||
file. The user doesn't have to stat the file, malloc space, read
|
||||
it in and then call SDFopen with the contents as an arg.
|
||||
3) SDF is reasonably careful about checking out whether fopen
|
||||
returns NULL. This means less obscure failure when a bad name
|
||||
is provided.
|
||||
|
||||
If the hdrname is NULL, or if it is empty or if it strcmp's
|
||||
equal to the datafname, then the data file is treated as an
|
||||
SDF file with a header attached.
|
||||
|
||||
* Made a similar change to SDFissdf, so that one calls it with
|
||||
a name rather than a FILE *. "-" is stdin.
|
||||
|
||||
Tue Jun 9 17:30:13 1992 John Salmon (johns at delilah)
|
||||
|
||||
* Created SDF_sun4.a SDF_risc6000.a and SDF_delta.a.
|
||||
|
||||
* Added some new functions to SDF.h and SDFfuncs.c:
|
||||
SDFissdf, SDFbyteorder, SDFswap, SDFnoswap, SDFisswapping.
|
||||
|
||||
These make it simpler to use generic header files for things
|
||||
like pjq, tree, etc. files. The nbio_ routines are no longer
|
||||
the preferred way to read old-style files. It might be worth
|
||||
writing a function that reads an alternative header directly
|
||||
from disk, rather than from a string. It really is a shame
|
||||
that there is no portable way to treat a string as a FILE *.
|
||||
|
||||
Sat Apr 4 09:34:16 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Created SDF_risc6000.a.
|
||||
|
||||
* Changed the declaration of do_value_param so it DOES NOT say
|
||||
Static int do_value_param(...., const_t const);
|
||||
This caused the AIX compiler to fail in a very obscure way!
|
||||
|
||||
Thu Mar 26 05:20:04 1992 John Salmon (johns at kastor)
|
||||
|
||||
* Some minor surgery on SDF-parse.y to deal with zero-length
|
||||
blocks at the end of the data file. We now try to fstat the
|
||||
file to figure out how many records will fit in the file. This
|
||||
should make writing generic tree-file readers easier, because
|
||||
"npart" is implicit.
|
||||
|
||||
Tue Mar 24 09:32:01 1992 John Salmon (johns at haggis)
|
||||
|
||||
* "Released" v1.2.0.
|
||||
|
||||
* Changed the Makefile, SDFfuncs.c and SDF-parse.y so the
|
||||
bison-generated externals now start with SDFyy, i.e.,
|
||||
SDFyyparse, SDFyyerror, etc. This makes it easier to merge
|
||||
SDF with programs like sm.
|
||||
|
||||
Thu Mar 19 05:05:12 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Removed #pragma once from the rest of the .h files
|
||||
|
||||
* Changed malloc to calloc in SDFopen.
|
||||
|
||||
Fri Mar 13 08:24:32 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Rebuilt SDF_delta.a and SDF_sun4.a
|
||||
|
||||
* Removed #pragma once from all the .h files.
|
||||
|
||||
* Added dependency for SDF-lex.c and SDF-parse.o to Makefile
|
||||
so changes to SDF-lex.l are understood by make.
|
||||
|
||||
* Added the 'unsigned' keyword to SDF-lex.l. It's a total
|
||||
no-op. It may make it somewhat easier (and dangerous?) to
|
||||
convert C structs into SDF headers.
|
||||
|
||||
* Changed the definition of the end-of-header symbol.
|
||||
Now it's any comment line containing the string SDF-EOH.
|
||||
The newline is the last character in the header. It is
|
||||
highly recommended that users add their own form-feeds
|
||||
to this line, but it is now at the user's discretion.
|
||||
|
||||
Thu Mar 12 22:23:37 1992 Mike Warren (msw at sampson)
|
||||
|
||||
* (nbio_open) Added a break to the case NBIO_SDF_TYPE:
|
||||
|
||||
Sun Feb 9 13:26:20 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Added some more error reporting to nbio. On most errors,
|
||||
something is now written into nbio_errstring. If the error
|
||||
is detected by SDF, then we (usually) copy SDFerrstring too.
|
||||
|
||||
* Added the SDFhasname() and nbio_hasname() functions to test
|
||||
for the existence of a name in a file.
|
||||
|
||||
Fri Feb 7 18:32:04 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Added missing ';' in the "parameter byteorder=blaa; "
|
||||
strings in nbio.c
|
||||
|
||||
* Added the char nbio_errstring[] array for messages.
|
||||
|
||||
* Added the char *nbio_type_names[] array.
|
||||
|
||||
* Added the "seekrd" functions to SDF and nbio, which use the
|
||||
fseekrd(...) "primitive". Hopefully, this will be supported
|
||||
by servix on all future parallel machines.
|
||||
|
||||
* Fiddled around with the header files. There's now only
|
||||
one copy of the prototypes in the "public" files, nbio.h and
|
||||
SDF.h.
|
64
external/libsdf/libSDF/GNUmakefile
vendored
Normal file
64
external/libsdf/libSDF/GNUmakefile
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
# Make.$(ARCH) sets many of the variables used below including:
|
||||
# CC, CFLAGS, AS, RANLIB, objdir, objsuf, asmdir
|
||||
|
||||
treedir=..
|
||||
treedir_sed=\.\.
|
||||
appexcludes=
|
||||
# Put everything into the libsw library!!!
|
||||
libname=libsw
|
||||
|
||||
# The "SDF" library
|
||||
src:= \
|
||||
SDF-parse.c SDFfuncs.c SDFget.c SDFhdrio.c
|
||||
|
||||
include $(treedir)/Make-common/Make.$(ARCH)
|
||||
|
||||
include $(treedir)/Make-common/Make.generic
|
||||
|
||||
# These rules are slight modifications of the builtin ones
|
||||
$(objdir)/%.c : %.y
|
||||
$(YACC.y) $<
|
||||
mv -f y.tab.c $@
|
||||
|
||||
$(objdir)/%.c : %.l
|
||||
# commands to execute (built-in):
|
||||
@$(RM) $@
|
||||
$(LEX.l) $< > $@
|
||||
|
||||
# Makedepends can't pick these up...
|
||||
$(objdir)/SDF-parse$(objsuf): SDF-private.h $(objdir)/SDF-lex.c $(objdir)/SDF-parse.c
|
||||
(cd $(objdir); $(CC) $(CFLAGS) -I../../../include -I../.. -c SDF-parse.c)
|
||||
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
|
||||
$(objdir)/SDF-parse$(objsuf):
|
||||
$(objdir)/SDF-parse$(objsuf):
|
||||
$(objdir)/SDF-parse$(objsuf): $(treedir)/include/libsdf/protos.h
|
||||
$(objdir)/SDF-parse$(objsuf): $(treedir)/include/libsdf/Msgs.h
|
||||
$(objdir)/SDF-parse$(objsuf): $(treedir)/include/libsdf/gccextensions.h SDF-private.h stdio.h
|
||||
$(objdir)/SDF-parse$(objsuf): $(treedir)/include/libsdf/mpmy_io.h
|
||||
$(objdir)/SDF-parse$(objsuf): $(treedir)/include/libsdf/SDF.h $(treedir)/include/libsdf/Malloc.h
|
||||
$(objdir)/SDF-parse$(objsuf): $(treedir)/include/libsdf/error.h SDF-lex.c
|
||||
$(objdir)/SDF-parse$(objsuf):
|
||||
$(objdir)/SDF-parse$(objsuf):
|
||||
$(objdir)/SDFfuncs$(objsuf):
|
||||
$(objdir)/SDFfuncs$(objsuf):
|
||||
$(objdir)/SDFfuncs$(objsuf):
|
||||
$(objdir)/SDFfuncs$(objsuf):
|
||||
$(objdir)/SDFfuncs$(objsuf): $(treedir)/include/libsdf/Msgs.h $(treedir)/include/libsdf/gccextensions.h
|
||||
$(objdir)/SDFfuncs$(objsuf): stdio.h $(treedir)/include/libsdf/mpmy_io.h SDF-private.h
|
||||
$(objdir)/SDFfuncs$(objsuf): $(treedir)/include/libsdf/SDF.h
|
||||
$(objdir)/SDFfuncs$(objsuf): $(treedir)/include/libsdf/byteswap.h $(treedir)/include/libsdf/Malloc.h
|
||||
$(objdir)/SDFfuncs$(objsuf): $(treedir)/include/libsdf/error.h $(treedir)/include/libsdf/protos.h
|
||||
$(objdir)/SDFfuncs$(objsuf): $(treedir)/include/libsdf/mpmy.h $(treedir)/include/libsdf/timers.h
|
||||
$(objdir)/SDFfuncs$(objsuf):
|
||||
$(objdir)/SDFget$(objsuf): stdio.h $(treedir)/include/libsdf/mpmy_io.h
|
||||
$(objdir)/SDFget$(objsuf): $(treedir)/include/libsdf/error.h $(treedir)/include/libsdf/gccextensions.h
|
||||
$(objdir)/SDFget$(objsuf): $(treedir)/include/libsdf/SDF.h
|
||||
$(objdir)/SDFhdrio$(objsuf):
|
||||
$(objdir)/SDFhdrio$(objsuf): $(treedir)/include/libsdf/Msgs.h $(treedir)/include/libsdf/gccextensions.h
|
||||
$(objdir)/SDFhdrio$(objsuf): $(treedir)/include/libsdf/error.h SDF-private.h
|
||||
$(objdir)/SDFhdrio$(objsuf): stdio.h
|
||||
$(objdir)/SDFhdrio$(objsuf): $(treedir)/include/libsdf/mpmy_io.h
|
||||
$(objdir)/SDFhdrio$(objsuf):
|
||||
$(objdir)/SDFhdrio$(objsuf): $(treedir)/include/libsdf/SDF.h
|
199
external/libsdf/libSDF/README
vendored
Normal file
199
external/libsdf/libSDF/README
vendored
Normal file
|
@ -0,0 +1,199 @@
|
|||
--------README from 1.3 -------------
|
||||
|
||||
This is version 1.3 of SDF. This version has been de-stdio-ized. It
|
||||
uses MY* functions in lieu of all stdio functions. Unless I've missed
|
||||
something, the only stdio function that remains is sprintf. Because
|
||||
lex is brain-damaged and insists on writing #include "stdio.h" into
|
||||
its output, I created a "./stdio.h" to override the system one. This
|
||||
is not strictly ANSI, but then, what is?
|
||||
|
||||
--------README from 1.2-------
|
||||
|
||||
This is version 1.2 of SDF ("Self Describing Files" or "Super-Duper
|
||||
Files, depending on how impressed you are). It is the first version
|
||||
of the last i/o package you'll ever need. SDF files are binary data
|
||||
files with an optional header which contains 1) a description of the
|
||||
layout of the data, and 2) optional ascii constants. There is no
|
||||
output capability because the sdf files are so easy to write :-).
|
||||
This document is completely unstructured, and probably
|
||||
incomprehensible to anyone but the author. It's a
|
||||
stream-of-consciousness first-draft. Be generous.
|
||||
|
||||
The user-callable SDF programs are declared with prototypes in SDF.h.
|
||||
I refuse to consider systems that can't deal with prototypes,
|
||||
<stdarg.h> and the ellipsis for variadic functions and enum types. If
|
||||
you don't have gcc on your Sun, then call up Sun and give them a piece
|
||||
of your mind, and then go get gcc. The ANSI standard has been out for
|
||||
long enough now. Accept no substitutes. The object modules are in
|
||||
the library SDF_<machine>.a. I have tried to keep the "name-space
|
||||
pollution" to a minimum. Unfortunately, there are a few additional
|
||||
external names used by the SDF package that do not appear explicitly in
|
||||
SDF.h. These include anything starting with "obstack_" (SDF uses the
|
||||
gnu obstack package) and all names starting with "SDF".
|
||||
|
||||
There are no provisions for writing SDF files. The reason is that
|
||||
it would be more complicated to go through a programmatic interface than
|
||||
to just create the files with fprintf() and fwrite(). The basic
|
||||
idea behind SDF files is that they are self-describing. That is, they
|
||||
have an ASCII header (human-readable, machine-parseable), which describes
|
||||
the contents of the file. The ascii header may contain explicit
|
||||
values, like:
|
||||
|
||||
float npart = 200000.;
|
||||
int int_npart = 200000;
|
||||
char text[] = "Perhaps a few words about the file's pedigree could go here";
|
||||
|
||||
Notice the similarity to C declarations.
|
||||
|
||||
In addition, the header contains declarations for the binary
|
||||
data that appears immediately after it. The allowed data
|
||||
types are char, short, int, float and double, arrays of same, and
|
||||
structs containing the basic types and arrays. (Multi-dimensional arrays
|
||||
are not supported. Nor are nested structures. But some kinds of two
|
||||
dimensional arrays can be captured by an array of structs, c.f., the
|
||||
'id' vector in .tree files. These limitations may be relaxed in the
|
||||
future.)
|
||||
|
||||
The header is terminated by a comment of the form
|
||||
|
||||
# <anything> SDF-EOH <anything> \n
|
||||
|
||||
That is, any comment containing the string SDF-EOH.
|
||||
The final new-line is the last character of the header. The
|
||||
binary data follows immediately after the new-line character.
|
||||
It is strongly recommended that the terminal comment contain
|
||||
one or more form-feeds (ctrl-L, \f in ANSI, \014 (octal), 0xc (hex),
|
||||
12 (decimal)). That way, 'more' or similar programs can be
|
||||
used on the file without getting confused by the binary data.
|
||||
Similarly, it is strongly recommended that the first line
|
||||
of an SDF file contain the comment:
|
||||
|
||||
# SDF <anything> \n
|
||||
|
||||
This makes it easy for a modified version of 'file', as well as
|
||||
other utilities to figure out that they are dealing with an SDF file.
|
||||
|
||||
Thus, the header for the output of an nbody simulation might look like:
|
||||
|
||||
# SDF
|
||||
float npart;
|
||||
float iter;
|
||||
float time;
|
||||
...
|
||||
char tree_header_text[384];
|
||||
struct {float mass;
|
||||
float x, y, z;
|
||||
char id[4];
|
||||
float vx, vy, vz;
|
||||
} [];
|
||||
# SDF-EOH ^L^L
|
||||
|
||||
This header means that the floats npart, iter, time, etc. are stored
|
||||
as binary data following the header. Then comes a 384 byte character
|
||||
array, followed by an array (of unspecified length) containing the
|
||||
vectors mass, x, y, z, id, vx, vy, vz. Only the last array in the
|
||||
header may be of unspecifiec length. It means that when the file is
|
||||
read, the array is assumed to extend to the end of the file. SDF
|
||||
routines figure out the length of the file by asking the OS, and hence
|
||||
can determine the number of elements in arrays of unspecified length.
|
||||
Specifications with unknown length are useful for creating generic SDF
|
||||
headers, i.e., headers that describe binary files that you may already
|
||||
be using.
|
||||
|
||||
If one were writing out a new SDF file, it is possible to write a
|
||||
header exactly as above, followed by the identical binary data.
|
||||
However, it would be much more convenient to write the "scalar" data
|
||||
as ascii values into the header. A new SDF file might look like:
|
||||
|
||||
# SDF
|
||||
/* Comments may be between C-like comment delimiters */
|
||||
# Or they follow the shell-like comment delimiter to end-of-line
|
||||
# This file was created by dave@h9k.hal.com on January 12, 1992...
|
||||
float npart = 200000.;
|
||||
int int_npart = 200000;
|
||||
float Gnewt = 1.0;
|
||||
float iter = 17.;
|
||||
float masstot = 1.1;
|
||||
float epsilon = 0.02;
|
||||
...
|
||||
struct {float mass;
|
||||
float x, y, z;
|
||||
char id[4];
|
||||
float vx, vy, vz;} [200000];
|
||||
# SDF-EOH ^L^L
|
||||
|
||||
This has the great advantage that most of the file's parameters are
|
||||
now both human-readable and machine-readable. A disadvantage to
|
||||
putting "history" information into comments is that it becomes
|
||||
inaccessable to programs (since SDF doesn't record comments). Another
|
||||
option is to put it in a character string:
|
||||
|
||||
char history[] =
|
||||
"This file created by ... on ...
|
||||
200000 body torqued Jaffe model constructed using:
|
||||
cubix ...
|
||||
";
|
||||
|
||||
Don't bother with C-syntax for newlines, etc in character strings.
|
||||
SDF just scans till it hits another " character. It doesn't do any
|
||||
escape-interpretation, so don't bother with '\n' and especially don't
|
||||
try to put the double-quote character inside strings.
|
||||
|
||||
Byte order is another headache. The function SDFcpubyteorder()
|
||||
returns an unsigned int which "describes" the host-cpu's byte order,
|
||||
in a format which may be placed into an SDF header with the.
|
||||
"parameter byteorder" keyword.
|
||||
|
||||
parameter byteorder = 0x12345678;
|
||||
|
||||
You can make this line in a C program with:
|
||||
fprintf(fp, "parameter byteorder = 0x%x;\n", SDFcpubyteorder());
|
||||
|
||||
If such a parameter is in the header, then SDFread functions will
|
||||
assume that the binary data is written in the file in the byte order
|
||||
specified by the parameter. If the machine doing the reading has a
|
||||
different byte order, then bytes are swapped automatically. If there
|
||||
is no such parameter, you can tell the read functions to swap with
|
||||
SDFswapon(). Similarly, you can turn off swapping (for whatever
|
||||
reason) with SDFswapoff(), and you can inquire about swapping with
|
||||
SDFisswapping();
|
||||
|
||||
Non-ieee floats are completely out of the question. Don't even
|
||||
mention them in my presence.
|
||||
|
||||
Dictionaries
|
||||
------------
|
||||
|
||||
Nbody files contain a number of scalars, and a number of vectors. The
|
||||
names of these objects must be agreed upon between the entity creating
|
||||
the file and the entity reading the file. Since the creators of pjq,
|
||||
tree and tree_ap files could barely agree that the sun rises in the
|
||||
east and sets in the west, I have created a set of names for the items
|
||||
in common amongst these file types. The list is in the file
|
||||
"./dictionary". SDF files name their own contents. It's important
|
||||
that the names continue to agree with the names in ./dictionary.
|
||||
Thus, with the current dictionary it is agreed that the name "npart"
|
||||
refers to a float value equal to the number of bodies in the file.
|
||||
Similarly, the name "masstot" refers to the total mass of the file.
|
||||
These are the strings that you have to pass as names to SDFread routines in
|
||||
order to extract the appropriate values from a file. What you call
|
||||
these quantities inside your program is completely irrelevant, but if
|
||||
you create another SDF file, it's important to use the same names.
|
||||
|
||||
The SDFopen function now takes two char* arguments, one for the
|
||||
filename of the header and one for the data. If they strcmp the same,
|
||||
or if the header is NULL or if the header is "", the descriptor is
|
||||
found at the beginning of the data file. If the name is "-", then
|
||||
stdin is used. If you really must open a file called "-", then you
|
||||
can do it by opening "./-". SDF will not gratuitously do random seeks
|
||||
around the file. In fact, it will struggle mightily to read the file
|
||||
sequentially. In many cases, SDFread will succeed on files that are
|
||||
not seekable. However, there are some requests that simply require
|
||||
rewinding the file. If your program does such a thing, then it MUST
|
||||
be possible to do arbitrary seeks on the data file, so taking stdin
|
||||
from a tty or a pipe would be a bad idea.
|
||||
|
||||
You're supposed to get an error message in SDFerrstring for this (and
|
||||
all other) errors. Segmentation violations are increasingly rare. I'm
|
||||
certain that bugs still remain which will blow SDF right away, but
|
||||
they're getting harder to find every day.
|
2055
external/libsdf/libSDF/SDF-lex.c
vendored
Normal file
2055
external/libsdf/libSDF/SDF-lex.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
139
external/libsdf/libSDF/SDF-lex.l
vendored
Normal file
139
external/libsdf/libSDF/SDF-lex.l
vendored
Normal file
|
@ -0,0 +1,139 @@
|
|||
%{
|
||||
/*
|
||||
SDF Library for reading Self-Describing Files
|
||||
Copyright (C) 1991,1992 John K. Salmon
|
||||
|
||||
Terms and conditions are specified in the file "copyright.h",
|
||||
and more precisely in the file COPYING.LIB which you should have
|
||||
received with this library.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
/* This define means we don't have to link with the lex library! */
|
||||
#define YY_SKIP_YYWRAP
|
||||
#define yywrap() 1
|
||||
|
||||
/* This one is ugly.
|
||||
Lex's output contains fprintf(yyout, of various error messages.
|
||||
We try here to redirect them to a Msg_doalist. */
|
||||
#include <stdarg.h>
|
||||
#include "Msgs.h"
|
||||
#undef fprintf
|
||||
#define fprintf MYFprintf
|
||||
void MYFprintf(int *junk, const char *fmt, ...){
|
||||
va_list alist;
|
||||
va_start(alist, fmt);
|
||||
Msg_doalist(fmt, alist);
|
||||
va_end(alist);
|
||||
}
|
||||
|
||||
#ifdef FLEX_SCANNER
|
||||
/* Flex DOES have a much better way to handle non-standard input strategies.
|
||||
This doesn't have to be this twisted to work with Flex, but if we are
|
||||
going to continue to support lex, it's easiest to just follow along */
|
||||
#define YY_INPUT(buf, result, maxsize) \
|
||||
{ \
|
||||
int c = SDF_Hdrgetc(); \
|
||||
/* Msgf(("YY_INPUT: c=%c\n", c)); */\
|
||||
result = (c==EOF) ? YY_NULL : (buf[0] = c, 1); \
|
||||
}
|
||||
/* Flex also has some new-and-different behavior AFTER YY_INPUT has returned
|
||||
NULL. In particular, all subsequent calls to yylex will immediately
|
||||
return NULL unless yyrestart is called. If we were always using Flex,
|
||||
I could attach this to the BEGIN rule, but I can't do that with lex,
|
||||
so I have to call it from outside, e.g., in SDFyyprepare. */
|
||||
void SDFlexprepare(void){
|
||||
yyrestart(NULL);
|
||||
}
|
||||
#else /* Not FLEX_SCANNER */
|
||||
void SDFlexprepare(void){}
|
||||
#endif
|
||||
%}
|
||||
White [ \f\t\n]
|
||||
Dig [0-9]
|
||||
Alpha [A-Za-z_]
|
||||
Hex [A-Fa-f0-9]
|
||||
Octal [0-7]
|
||||
Alphanum [A-Za-z0-9_]
|
||||
Expon [Ee]{Sign}{Dig}+
|
||||
Punct "="|"["|"]"|"{"|"}"|";"|","
|
||||
Sign [-+]?
|
||||
%%
|
||||
#.*SDF-EOH.* {SDFlineno++; return EOHDR;} /* Terminate the header on a comment line */
|
||||
#.* {SDFlineno++;} /* Otherwise, skip comments from '#' to eol. */
|
||||
{White} {if(yytext[0] == '\n') SDFlineno++;} /* skip white space. count lines*/
|
||||
"/*" { int c;
|
||||
loop:
|
||||
while((c=input()) != '*') {if(c=='\n') SDFlineno++;}
|
||||
switch(input()){
|
||||
case '/': break;
|
||||
case '*': unput('*');
|
||||
default: goto loop;
|
||||
}
|
||||
} /* Skip normal C comments. (no nesting) */
|
||||
char {yylval.type = SDF_CHAR; return TYPE;}
|
||||
short {yylval.type = SDF_SHORT; return TYPE;}
|
||||
int {yylval.type = SDF_INT; return TYPE;}
|
||||
long {yylval.type = SDF_LONG; return TYPE;}
|
||||
int64_t {yylval.type = SDF_INT64; return TYPE;}
|
||||
float {yylval.type = SDF_FLOAT; return TYPE;}
|
||||
double {yylval.type = SDF_DOUBLE; return TYPE;}
|
||||
struct {return STRUCT;}
|
||||
unsigned ; /* WARNING. The keyword 'unsigned' is skipped entirely. */
|
||||
parameter {return PARAMETER;}
|
||||
byteorder {yylval.valueparam = BYTEORDER; return VALUEPARAM;}
|
||||
{Alpha}{Alphanum}* {yylval.string = Malloc(yyleng+1);
|
||||
strcpy(yylval.string, (char *)yytext);
|
||||
#if YYDEBUG
|
||||
if(yydebug)
|
||||
printf("lex-malloc(%d) at 0x%lx\n",
|
||||
yyleng+1, (unsigned long)yylval.string);
|
||||
#endif
|
||||
return NAME;}
|
||||
\"[^"]*\" {
|
||||
/* strings extend to the next double-quote. */
|
||||
/* there are no escapes, and no exceptions. */
|
||||
/* We fiddle with the yyleng so we only get the contents in yylval. */
|
||||
/* Newlines embedded in strings will be missed by SDFlineno! */
|
||||
yylval.constant.u.stringval = Malloc(yyleng-1);
|
||||
strncpy(yylval.constant.u.stringval, (char *)yytext+1, yyleng-2);
|
||||
yylval.constant.u.stringval[yyleng-2] = '\0';
|
||||
yylval.constant.type = SDF_STRING;
|
||||
#if YYDEBUG
|
||||
if(yydebug)
|
||||
printf("lex-malloc(%d) = 0x%lx\n", yyleng-1,
|
||||
(unsigned long)yylval.constant.u.stringval);
|
||||
#endif
|
||||
return CONST;}
|
||||
{Sign}{Dig}+"."{Dig}*({Expon})? |
|
||||
{Sign}{Dig}*"."{Dig}+({Expon})? |
|
||||
{Sign}{Dig}+{Expon} {
|
||||
yylval.constant.type = SDF_DOUBLE;
|
||||
sscanf((char *)yytext, "%lf", &yylval.constant.u.doubleval);
|
||||
return CONST;}
|
||||
0x{Hex}+ {
|
||||
yylval.constant.type = SDF_INT64;
|
||||
#if __WORDSIZE==64
|
||||
sscanf((char *)yytext+2, "%lx", &yylval.constant.u.int64val);
|
||||
#else
|
||||
sscanf((char *)yytext+2, "%llx", &yylval.constant.u.int64val);
|
||||
#endif
|
||||
return CONST;}
|
||||
0{Octal}+ {
|
||||
yylval.constant.type = SDF_INT64;
|
||||
#if __WORDSIZE==64
|
||||
sscanf((char *)yytext+1, "%lo", &yylval.constant.u.int64val);
|
||||
#else
|
||||
sscanf((char *)yytext+1, "%llo", &yylval.constant.u.int64val);
|
||||
#endif
|
||||
return CONST;}
|
||||
{Sign}{Dig}+ {
|
||||
yylval.constant.type = SDF_INT64;
|
||||
#if __WORDSIZE==64
|
||||
sscanf((char *)yytext, "%ld", &yylval.constant.u.int64val);
|
||||
#else
|
||||
sscanf((char *)yytext, "%lld", &yylval.constant.u.int64val);
|
||||
#endif
|
||||
return CONST;}
|
||||
{Punct} {return yytext[0];}
|
||||
. {yyerror("lexer confusion on char: <%c>, line: %d\n", (yytext[0])?yytext[0]:'?',
|
||||
SDFlineno); return LEXERROR;}
|
2366
external/libsdf/libSDF/SDF-parse.c
vendored
Normal file
2366
external/libsdf/libSDF/SDF-parse.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
754
external/libsdf/libSDF/SDF-parse.y
vendored
Normal file
754
external/libsdf/libSDF/SDF-parse.y
vendored
Normal file
|
@ -0,0 +1,754 @@
|
|||
%{
|
||||
/*
|
||||
SDF Library for reading Self-Describing Files
|
||||
Copyright (C) 1991,1992 John K. Salmon
|
||||
|
||||
Terms and conditions are specified in the file "copyright.h",
|
||||
and more precisely in the file COPYING.LIB which you should have
|
||||
received with this library.
|
||||
*/
|
||||
|
||||
/* We don't rely on bison's -p argument any more.
|
||||
Instead, just #define the name changes ourselves. These are taken
|
||||
from the beginning of bison -p output. These are far from a complete
|
||||
set of external 'yy' names, as a quick run throug 'nm' will show. Maybe
|
||||
all the others come from lex. I dunno. In any event, the namespace is only
|
||||
partially cleaned up. Perhaps we should apply for Superfund money
|
||||
to finish the cleanup? bison -p does no better.
|
||||
*/
|
||||
#define yyparse SDFyyparse
|
||||
#define yylex SDFyylex
|
||||
#define yyerror SDFyyerror
|
||||
#define yylval SDFyylval
|
||||
#define yychar SDFyychar
|
||||
#define yydebug SDFyydebug
|
||||
#define yynerrs SDFyynerrs
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <float.h>
|
||||
#include <string.h>
|
||||
#include "protos.h"
|
||||
#include "Msgs.h"
|
||||
#include "SDF-private.h"
|
||||
#include "obstack.h"
|
||||
#include "Malloc.h"
|
||||
|
||||
#ifndef __DELTA__
|
||||
#define YYDEBUG 1
|
||||
#endif
|
||||
|
||||
#if YYDEBUG
|
||||
/* yacc sends its debug output throught printf. We change that... */
|
||||
#define printf Msg_do /* MUST be after protos.h!!! */
|
||||
#endif
|
||||
|
||||
#ifdef cray
|
||||
/* This wants to be a long on the cray?? */
|
||||
extern long int yydebug;
|
||||
#else
|
||||
extern int yydebug;
|
||||
#endif
|
||||
extern void yyerror(char *fmt, ...);
|
||||
|
||||
|
||||
static enum SDF_type_enum curtype;
|
||||
static blk_descrip_t cur_blk;
|
||||
static int cur_file_offset;
|
||||
static int cur_data_offset;
|
||||
static SDF *cur_hdr;
|
||||
static int no_more_data_blks;
|
||||
static int zero_len_blknum;
|
||||
|
||||
char *SDFtype_names[] = {"notype", "char", "short", "int", "long", "int64_t",
|
||||
"float", "double", "string"};
|
||||
|
||||
int SDFtype_sizes[] = {0, sizeof(char), sizeof(short), sizeof(int), sizeof(long),
|
||||
sizeof(int64_t), sizeof(float), sizeof(double), sizeof(char *)};
|
||||
|
||||
static int do_value_param(enum value_param_enum type, const_t value);
|
||||
static int data_dcl(declaration_t dcl);
|
||||
static int const_dcl(declaration_t dcl, const_list_t consts);
|
||||
static void finish_curblk(void);
|
||||
static const_t convert_const(const_t *cp, enum SDF_type_enum type);
|
||||
static int finish_parse(void);
|
||||
|
||||
%}
|
||||
|
||||
%token STRUCT
|
||||
%token <string> NAME
|
||||
%token <type> TYPE
|
||||
%token <constant> CONST
|
||||
%token <valueparam> VALUEPARAM
|
||||
%token PARAMETER
|
||||
%token EOHDR LEXERROR
|
||||
%token ';' '=' '[' ']' '{' '}' ','
|
||||
%type <declaration> declaration
|
||||
%type <one_dcl> dcl1
|
||||
%type <const_list> const_lst comma_sep_consts
|
||||
%type <dcl_list> comma_sep_dcls typed_dcl_list many_typed_dcl_list
|
||||
%union{
|
||||
enum SDF_type_enum type;
|
||||
enum value_param_enum valueparam;
|
||||
char *string;
|
||||
const_t constant;
|
||||
declaration_t declaration;
|
||||
dcl_list_t dcl_list;
|
||||
one_dcl_t one_dcl;
|
||||
const_list_t const_list;
|
||||
}
|
||||
%%
|
||||
hdr : hdr1 {if(finish_parse()) YYERROR;}
|
||||
| hdr1 EOHDR {if(finish_parse()) YYERROR; else YYACCEPT;}
|
||||
| LEXERROR {YYERROR;}
|
||||
;
|
||||
|
||||
hdr1 : stmt
|
||||
| hdr1 stmt
|
||||
;
|
||||
|
||||
stmt : declaration ';' {if(data_dcl($1)) YYERROR;}
|
||||
| declaration '=' const_lst ';' {if(const_dcl($1, $3)) YYERROR;}
|
||||
| PARAMETER VALUEPARAM '=' CONST ';' {if(do_value_param($2, $4)) YYERROR;}
|
||||
;
|
||||
|
||||
declaration : typed_dcl_list {$$.dcl_list = $1; $$.Nrec = 1;}
|
||||
| STRUCT '{' many_typed_dcl_list ';' '}' {$$.dcl_list=$3; $$.Nrec=1;}
|
||||
| STRUCT '{' many_typed_dcl_list ';' '}' '[' CONST ']'
|
||||
{
|
||||
if( $7.type != SDF_INT64 ){
|
||||
yyerror("Expected integer constant");
|
||||
YYERROR;
|
||||
}else{
|
||||
$$.dcl_list = $3; $$.Nrec = $7.u.int64val;
|
||||
}
|
||||
}
|
||||
| STRUCT '{' many_typed_dcl_list ';' '}' '[' ']'
|
||||
{ $$.dcl_list = $3; $$.Nrec = 0;}
|
||||
;
|
||||
|
||||
many_typed_dcl_list : typed_dcl_list {$$ = $1;}
|
||||
| many_typed_dcl_list ';' typed_dcl_list
|
||||
{
|
||||
int sz;
|
||||
|
||||
$$.ndcl = $1.ndcl + $3.ndcl;
|
||||
$$.obs = $1.obs;
|
||||
sz = obstack_object_size(&$3.obs);
|
||||
(void)obstack_grow(&$$.obs, obstack_finish(&$3.obs), sz);
|
||||
(void)obstack_free(&$3.obs, NULL);
|
||||
}
|
||||
;
|
||||
|
||||
typed_dcl_list: TYPE {curtype = $1;} comma_sep_dcls {$$ = $3;}
|
||||
;
|
||||
|
||||
comma_sep_dcls: dcl1
|
||||
{
|
||||
obstack_begin(&$$.obs, 16*sizeof($1));
|
||||
$$.ndcl = 1;
|
||||
(void)obstack_grow(&$$.obs, &$1, sizeof($1));
|
||||
}
|
||||
| comma_sep_dcls ',' dcl1
|
||||
{
|
||||
$$ = $1;
|
||||
$$.ndcl += 1;
|
||||
(void)obstack_grow(&$$.obs, &$3, sizeof($3));
|
||||
}
|
||||
;
|
||||
|
||||
dcl1 : NAME {$$.name = $1; $$.type = curtype; $$.arrcnt = 1;}
|
||||
| NAME '[' CONST ']'
|
||||
{
|
||||
if( $3.type != SDF_INT64 ){
|
||||
yyerror("Expected integer constant");
|
||||
YYERROR;
|
||||
}else{
|
||||
$$.name = $1; $$.type = curtype; $$.arrcnt = $3.u.int64val;
|
||||
}
|
||||
}
|
||||
| NAME '[' ']' {$$.name=$1; $$.type=curtype; $$.arrcnt = 0;}
|
||||
;
|
||||
|
||||
const_lst : CONST
|
||||
{
|
||||
$$.nconst = 1;
|
||||
obstack_begin(&$$.obs, 16*sizeof($1));
|
||||
(void)obstack_grow(&$$.obs, &$1, sizeof($1));
|
||||
}
|
||||
| '{' comma_sep_consts '}' {$$ = $2;}
|
||||
;
|
||||
|
||||
comma_sep_consts : CONST
|
||||
{
|
||||
$$.nconst = 1;
|
||||
obstack_begin(&$$.obs, 16*sizeof($1));
|
||||
(void)obstack_grow(&$$.obs, &$1, sizeof($1));
|
||||
}
|
||||
| comma_sep_consts ',' CONST
|
||||
{
|
||||
$$ = $1;
|
||||
$$.nconst += 1;
|
||||
(void)obstack_grow(&$$.obs, &$3, sizeof($3));
|
||||
}
|
||||
;
|
||||
|
||||
%%
|
||||
static int SDFlineno;
|
||||
|
||||
static const char *Dataname, *Hdrname;
|
||||
|
||||
#ifdef STANDALONE
|
||||
char SDFerrstring[512];
|
||||
unsigned int SDFcpubyteorder(void){return 0;}
|
||||
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
SDF hdr;
|
||||
|
||||
if(argc > 1){
|
||||
yydebug = 1;
|
||||
}else{
|
||||
yydebug = 0;
|
||||
}
|
||||
SDFyyprepare(&hdr, "-", "-");
|
||||
if(yyparse()){
|
||||
printf("Terminated on error. \n");
|
||||
exit(1);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int SDF_iomode = MPMY_RDONLY | MPMY_MULTI;
|
||||
|
||||
void SDFsetiomode(int mode)
|
||||
{
|
||||
if (mode == SDF_SINGL) {
|
||||
SDF_iomode = MPMY_RDONLY | MPMY_SINGL;
|
||||
} else {
|
||||
SDF_iomode = MPMY_RDONLY | MPMY_MULTI;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SDFyyerror(char *fmt, ...)
|
||||
{
|
||||
char *p;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsprintf(SDFerrstring, fmt, ap);
|
||||
p = SDFerrstring + strlen(SDFerrstring);
|
||||
sprintf(p, " lineno = %d\n", SDFlineno);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
int SDFyyprepare(SDF *hdr, const char *hdrname, const char *dataname)
|
||||
{
|
||||
no_more_data_blks = 0;
|
||||
|
||||
cur_file_offset = 0;
|
||||
cur_data_offset = 0;
|
||||
|
||||
cur_blk.Nrec = 1;
|
||||
cur_blk.inmem = 1;
|
||||
cur_blk.begin_offset = 0;
|
||||
cur_blk.reclen = 0;
|
||||
|
||||
cur_hdr = hdr;
|
||||
cur_hdr->nblks = 0;
|
||||
cur_hdr->nvecs = 0;
|
||||
/* Assume that MPMY_Fopen does the 'right' thing with "-" */
|
||||
if( SDF_Hdropen(hdrname) < 0 ){
|
||||
sprintf(SDFerrstring, "SDFopen: could not open %s\n", hdrname);
|
||||
return -1;
|
||||
}
|
||||
Dataname = dataname;
|
||||
Hdrname = hdrname;
|
||||
SDFlineno = 0; /* or 1? It's always +-1 anyway */
|
||||
SDFlexprepare();
|
||||
|
||||
obstack_begin(&cur_hdr->blks_obs, 16*sizeof(blk_descrip_t));
|
||||
obstack_begin(&cur_hdr->vecs_obs, 32*sizeof(vec_descrip_t));
|
||||
obstack_begin(&cur_hdr->data_obs, 2048);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int finish_parse(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
finish_curblk();
|
||||
cur_hdr->blks = (blk_descrip_t *)obstack_finish(&cur_hdr->blks_obs);
|
||||
cur_hdr->vecs = (vec_descrip_t *)obstack_finish(&cur_hdr->vecs_obs);
|
||||
cur_hdr->data = obstack_finish(&cur_hdr->data_obs);
|
||||
cur_hdr->vec_names = Malloc(cur_hdr->nvecs * sizeof(char *));
|
||||
for(i=0; i<cur_hdr->nvecs; i++){
|
||||
cur_hdr->vec_names[i] = cur_hdr->vecs[i].name;
|
||||
}
|
||||
|
||||
if( (Dataname == NULL) || (Dataname[0] == '\0')
|
||||
|| (strcmp(Hdrname, Dataname)==0)){
|
||||
cur_hdr->begin_file_offset = SDF_Hdroffset();
|
||||
if( cur_hdr->begin_file_offset < 0 ){
|
||||
yyerror("Can't get offset of end of header\n");
|
||||
return -1;
|
||||
}
|
||||
}else{
|
||||
cur_hdr->begin_file_offset = 0;
|
||||
}
|
||||
SDF_Hdrclose();
|
||||
|
||||
/* cur_hdr->datafp = MPMY_Fopen(Dataname, MPMY_RDONLY); */
|
||||
/* If we come up with a better model for IO, call it here.. */
|
||||
cur_hdr->datafp = MPMY_Fopen(Dataname, SDF_iomode);
|
||||
|
||||
Msgf(("cur_hdr->datafp = %p\n", cur_hdr->datafp));
|
||||
|
||||
if( cur_hdr->datafp == NULL ){
|
||||
sprintf(SDFerrstring, "SDFopen: could not open data file: %s\n",
|
||||
Dataname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(no_more_data_blks){
|
||||
blk_descrip_t *zerolenblk;
|
||||
off_t bytesleft, recsleft;
|
||||
off_t datalen;
|
||||
|
||||
zerolenblk = &cur_hdr->blks[zero_len_blknum];
|
||||
if(zerolenblk->Nrec != 0){
|
||||
yyerror("Zero length block has non-zero length!?\n");
|
||||
return -1;
|
||||
}
|
||||
if( cur_hdr->begin_file_offset < 0 ){
|
||||
yyerror("Can't have zero-len blk in an unseekable file\n");
|
||||
return -1;
|
||||
}
|
||||
Msgf(("About to call MPMY_Flen\n"));
|
||||
if( (datalen = MPMY_Flen(cur_hdr->datafp)) < 0 ){
|
||||
yyerror("Could not get length of data file.\n");
|
||||
return -1;
|
||||
}
|
||||
bytesleft = datalen
|
||||
- (zerolenblk->begin_offset + cur_hdr->begin_file_offset);
|
||||
Msgf(("datalen = %ld, butesleft = %ld\n",
|
||||
(long)datalen, (long)bytesleft));
|
||||
if( bytesleft < 0 ){
|
||||
yyerror("File too short.\n");
|
||||
return -1;
|
||||
}
|
||||
recsleft = bytesleft/zerolenblk->reclen;
|
||||
if( recsleft*zerolenblk->reclen != bytesleft ){
|
||||
printf("datalen is %ld, bytesleft is %ld\n", (long)datalen, (long)bytesleft);
|
||||
yyerror("File ends between record boundaries\n");
|
||||
return -1;
|
||||
}
|
||||
zerolenblk->Nrec = recsleft;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_value_param(enum value_param_enum param, const_t value)
|
||||
{
|
||||
switch(param){
|
||||
case BYTEORDER:
|
||||
if( value.type != SDF_INT64 )
|
||||
return -1;
|
||||
cur_hdr->byteorder = value.u.int64val;
|
||||
cur_hdr->swapping = (cur_hdr->byteorder != SDFcpubyteorder());
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int data_dcl(declaration_t dcl)
|
||||
{
|
||||
dcl_list_t *dcl_list;
|
||||
one_dcl_t *base, *dclp;
|
||||
int i, offset;
|
||||
vec_descrip_t vec_descrip;
|
||||
|
||||
#if YYDEBUG
|
||||
if(yydebug)
|
||||
printf("Declaration of %ld records:\n", dcl.Nrec);
|
||||
#endif
|
||||
if(no_more_data_blks){
|
||||
yyerror("You can't have data following an implicit-length dcl.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Test to see if we can append this dcl to the current */
|
||||
/* block. */
|
||||
if(cur_blk.inmem || cur_blk.Nrec != 1 || dcl.Nrec != 1){
|
||||
finish_curblk();
|
||||
cur_blk.Nrec = dcl.Nrec;
|
||||
cur_blk.reclen = 0;
|
||||
cur_blk.inmem = 0;
|
||||
cur_blk.begin_offset = cur_file_offset;
|
||||
#if YYDEBUG
|
||||
if(yydebug)
|
||||
printf("New block (%d) at offset %d in file\n",
|
||||
cur_hdr->nblks, cur_file_offset);
|
||||
#endif
|
||||
}
|
||||
|
||||
if(dcl.Nrec == 0){
|
||||
no_more_data_blks = 1;
|
||||
zero_len_blknum = cur_hdr->nblks;
|
||||
}
|
||||
|
||||
offset = cur_blk.reclen;
|
||||
|
||||
dcl_list = &dcl.dcl_list;
|
||||
base = (one_dcl_t *)obstack_base(&dcl_list->obs);
|
||||
for(i=0; i<dcl_list->ndcl; i++){
|
||||
dclp = &base[i];
|
||||
vec_descrip.name = dclp->name;
|
||||
vec_descrip.arrcnt = dclp->arrcnt;
|
||||
vec_descrip.type = dclp->type;
|
||||
vec_descrip.blk_off = offset;
|
||||
vec_descrip.blk_num = cur_hdr->nblks;
|
||||
vec_descrip.nread = 0;
|
||||
offset += SDFtype_sizes[dclp->type] * dclp->arrcnt;
|
||||
cur_hdr->nvecs++;
|
||||
(void)obstack_grow(&cur_hdr->vecs_obs,
|
||||
&vec_descrip, sizeof(vec_descrip));
|
||||
#if YYDEBUG
|
||||
if(yydebug){
|
||||
printf("\t %s %s[%d]", SDFtype_names[dclp->type], dclp->name,
|
||||
dclp->arrcnt);
|
||||
printf(" in block %ld at offset %ld\n",
|
||||
vec_descrip.blk_num, vec_descrip.blk_off);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
(void)obstack_free(&dcl_list->obs, NULL);
|
||||
cur_blk.reclen = offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void finish_curblk(void)
|
||||
{
|
||||
cur_hdr->nblks++;
|
||||
(void)obstack_grow(&cur_hdr->blks_obs, &cur_blk, sizeof(cur_blk));
|
||||
if(cur_blk.inmem){
|
||||
cur_data_offset += cur_blk.reclen * cur_blk.Nrec;
|
||||
}else{
|
||||
cur_file_offset += cur_blk.reclen * cur_blk.Nrec;
|
||||
}
|
||||
}
|
||||
|
||||
static int const_dcl(declaration_t dcl, const_list_t consts)
|
||||
{
|
||||
dcl_list_t *dcl_list;
|
||||
one_dcl_t *dclbase, *dclp;
|
||||
const_t *cp, *cbase, converted;
|
||||
vec_descrip_t vec_descrip;
|
||||
int i, j, k;
|
||||
int offset;
|
||||
void *to;
|
||||
|
||||
dcl_list = &dcl.dcl_list;
|
||||
if(dcl.Nrec == 0){
|
||||
dcl.Nrec = consts.nconst;
|
||||
#if 0 /* Was it really this easy?? */
|
||||
yyerror("Cannot deal with implicit length constant dcls.");
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Test to see if we can append this dcl to the current */
|
||||
/* block. */
|
||||
if(!cur_blk.inmem || cur_blk.Nrec != 1 || dcl.Nrec != 1){
|
||||
finish_curblk();
|
||||
cur_blk.Nrec = dcl.Nrec;
|
||||
cur_blk.reclen = 0;
|
||||
cur_blk.inmem = 1;
|
||||
cur_blk.begin_offset = cur_data_offset;
|
||||
#if YYDEBUG
|
||||
if(yydebug)
|
||||
printf("New block (%d) at offset %d in data\n",
|
||||
cur_hdr->nblks, cur_data_offset);
|
||||
#endif
|
||||
}
|
||||
|
||||
offset = cur_blk.reclen;
|
||||
cbase = (const_t *)obstack_base(&consts.obs);
|
||||
dclbase = (one_dcl_t *)obstack_base(&dcl_list->obs);
|
||||
|
||||
for(i=0; i<dcl_list->ndcl; i++){
|
||||
dclp = &dclbase[i];
|
||||
if(dclp->arrcnt == 0){
|
||||
if(dclp->type == SDF_CHAR
|
||||
&& cbase[i].type == SDF_STRING
|
||||
&& dcl.Nrec == 1){
|
||||
dclp->arrcnt = strlen(cbase[i].u.stringval)+1;
|
||||
/* Round up for padding purposes. */
|
||||
dclp->arrcnt = (dclp->arrcnt + 7)& (~0x7);
|
||||
}else if(i == dcl_list->ndcl-1 && dcl.Nrec == 1){
|
||||
dclp->arrcnt = consts.nconst - i;
|
||||
}else{
|
||||
yyerror("Can't figure out implicit dcl from context.");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
vec_descrip.name = dclp->name;
|
||||
vec_descrip.arrcnt = dclp->arrcnt;
|
||||
vec_descrip.type = dclp->type;
|
||||
vec_descrip.blk_off = offset;
|
||||
vec_descrip.blk_num = cur_hdr->nblks;
|
||||
vec_descrip.nread = 0;
|
||||
offset += SDFtype_sizes[dclp->type] * dclp->arrcnt;
|
||||
cur_hdr->nvecs++;
|
||||
(void)obstack_grow(&cur_hdr->vecs_obs,
|
||||
&vec_descrip, sizeof(vec_descrip));
|
||||
#if YYDEBUG
|
||||
if(yydebug){
|
||||
printf("\t %s %s[%d]", SDFtype_names[dclp->type], dclp->name,
|
||||
dclp->arrcnt);
|
||||
printf(" in block %ld at offset %ld\n",
|
||||
vec_descrip.blk_num, vec_descrip.blk_off);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
cur_blk.reclen = offset;
|
||||
|
||||
cp = cbase;
|
||||
for(i=0; i<dcl.Nrec; i++){
|
||||
for(j=0; j<dcl_list->ndcl; j++){
|
||||
dclp = &dclbase[j];
|
||||
#if YYDEBUG
|
||||
if(yydebug)
|
||||
printf("\t %s %s[%d] (%d) = ",
|
||||
SDFtype_names[dclp->type], dclp->name,
|
||||
dclp->arrcnt, i);
|
||||
#endif
|
||||
if( dclp->type == SDF_CHAR && cp->type == SDF_STRING){
|
||||
#if YYDEBUG
|
||||
if(yydebug)
|
||||
printf("\"%s\"\n", cp->u.stringval);
|
||||
#endif
|
||||
to = obstack_next_free(&cur_hdr->data_obs);
|
||||
(void)obstack_blank(&cur_hdr->data_obs, dclp->arrcnt);
|
||||
/* Should we warn
|
||||
if strlen(cp->u.stringval) > dclp->arrcnt ????
|
||||
It implies that the 'string' won't be null-terminated? */
|
||||
(void)strncpy(to, cp->u.stringval, dclp->arrcnt);
|
||||
#ifdef YYDEBUG
|
||||
if(yydebug)
|
||||
printf("Freeing const string 0x%lx\n",
|
||||
(unsigned long)cp->u.stringval);
|
||||
#endif
|
||||
Free(cp->u.stringval);
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
|
||||
for(k=0; k<dclp->arrcnt; k++){
|
||||
converted = convert_const(cp, dclp->type);
|
||||
if(converted.type == SDF_NOTYPE){
|
||||
yyerror("Failed constant conversion.");
|
||||
return -1;
|
||||
}
|
||||
(void)obstack_grow(&cur_hdr->data_obs, &converted.u,
|
||||
SDFtype_sizes[converted.type]);
|
||||
|
||||
#ifdef YYDEBUG
|
||||
if(yydebug){
|
||||
printf("(%s)", SDFtype_names[cp->type]);
|
||||
switch(converted.type){
|
||||
case SDF_CHAR:
|
||||
printf("%c", converted.u.charval);
|
||||
break;
|
||||
case SDF_SHORT:
|
||||
printf("%d", converted.u.shortval);
|
||||
break;
|
||||
case SDF_INT:
|
||||
printf("%d", converted.u.intval);
|
||||
break;
|
||||
case SDF_LONG:
|
||||
printf("%ld", converted.u.longval);
|
||||
break;
|
||||
case SDF_INT64:
|
||||
#if __WORDSIZE==64
|
||||
printf("%ld", converted.u.int64val);
|
||||
#else
|
||||
printf("%lld", converted.u.int64val);
|
||||
#endif
|
||||
break;
|
||||
case SDF_FLOAT:
|
||||
printf("%.7g", converted.u.floatval);
|
||||
break;
|
||||
case SDF_DOUBLE:
|
||||
printf("%.17g", converted.u.doubleval);
|
||||
break;
|
||||
default:
|
||||
printf("Unrecognized type: %d\n", converted.type);
|
||||
break;
|
||||
}
|
||||
if(k == dclp->arrcnt-1){
|
||||
printf("\n");
|
||||
}else{
|
||||
printf(", ");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
cp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
(void)obstack_free(&dcl_list->obs, NULL);
|
||||
(void)obstack_free(&consts.obs, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const_t convert_const(const_t *cp, enum SDF_type_enum newtype)
|
||||
/* Return a constant of type NEWTYPE, with the same value as */
|
||||
/* *CP. If the conversion does not preserve value, then */
|
||||
/* return a constant of NOTYPE, with garbage value. */
|
||||
{
|
||||
const_t value;
|
||||
double dval = 0.;
|
||||
int64_t ival = 0;
|
||||
|
||||
if(cp->type == newtype){
|
||||
/* IRIX -32 bug fix */
|
||||
memcpy(&value, cp, sizeof(value));
|
||||
/* value = *cp; */
|
||||
return value;
|
||||
}
|
||||
|
||||
if(cp->type == SDF_STRING || newtype == SDF_STRING){
|
||||
value.type = SDF_NOTYPE;
|
||||
yyerror("Cannot do const conversions with strings.\n");
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Now rely on the fact that a double can faithfully hold */
|
||||
/* any other arithmetic type (except long ints on 64-bit archs). */
|
||||
switch(cp->type){
|
||||
case SDF_CHAR:
|
||||
dval = (double)cp->u.charval;
|
||||
break;
|
||||
case SDF_SHORT:
|
||||
dval = (double)cp->u.shortval;
|
||||
break;
|
||||
case SDF_INT:
|
||||
dval = (double)cp->u.intval;
|
||||
ival = cp->u.intval;
|
||||
break;
|
||||
case SDF_LONG:
|
||||
dval = (double)cp->u.longval;
|
||||
ival = cp->u.longval;
|
||||
break;
|
||||
case SDF_INT64:
|
||||
dval = (double)cp->u.int64val;
|
||||
ival = cp->u.int64val;
|
||||
break;
|
||||
case SDF_FLOAT:
|
||||
dval = cp->u.floatval;
|
||||
break;
|
||||
case SDF_DOUBLE:
|
||||
dval = cp->u.doubleval;
|
||||
break;
|
||||
default:
|
||||
dval = 0.0;
|
||||
yyerror("Cannot do const conversions with strings.\n");
|
||||
}
|
||||
|
||||
value.type = newtype;
|
||||
switch(newtype){
|
||||
case SDF_CHAR:
|
||||
value.u.charval = (char)dval;
|
||||
if( value.u.charval != dval ){
|
||||
yyerror("Can't fit value into char.");
|
||||
value.type = SDF_NOTYPE;
|
||||
}
|
||||
break;
|
||||
case SDF_SHORT:
|
||||
value.u.shortval = (short)dval;
|
||||
if( value.u.shortval != dval ){
|
||||
yyerror("Can't fit value into short.");
|
||||
value.type = SDF_NOTYPE;
|
||||
}
|
||||
break;
|
||||
case SDF_INT:
|
||||
value.u.intval = (int)dval;
|
||||
if( value.u.intval != dval ){
|
||||
value.u.intval = ival;
|
||||
if( value.u.intval != ival ){
|
||||
yyerror("Can't fit value into int.");
|
||||
value.type = SDF_NOTYPE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SDF_LONG:
|
||||
value.u.longval = (long)dval;
|
||||
if( value.u.longval != dval ){
|
||||
value.u.longval = ival;
|
||||
if( value.u.longval != ival ){
|
||||
yyerror("Can't fit value into long.");
|
||||
value.type = SDF_NOTYPE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SDF_INT64:
|
||||
value.u.int64val = (int64_t)dval;
|
||||
if( value.u.int64val != dval ){
|
||||
value.u.int64val = ival;
|
||||
if( value.u.int64val != ival ){
|
||||
yyerror("Can't fit value into int64_t.");
|
||||
value.type = SDF_NOTYPE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SDF_FLOAT:
|
||||
if(dval > FLT_MAX || dval < -FLT_MAX){
|
||||
yyerror("Can't fit value into float.");
|
||||
value.type = SDF_NOTYPE;
|
||||
}
|
||||
value.u.floatval = dval;
|
||||
break;
|
||||
case SDF_DOUBLE:
|
||||
value.u.doubleval = dval;
|
||||
break;
|
||||
default:
|
||||
yyerror("Impossible case.\n");
|
||||
break;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void *SDFobstack_chunk_alloc(size_t n)
|
||||
{
|
||||
void *p = Malloc(n);
|
||||
#if YYDEBUG
|
||||
if(yydebug)
|
||||
printf("malloc(%ld) = 0x%lx\n", (long)n, (unsigned long)p);
|
||||
#endif
|
||||
return p;
|
||||
}
|
||||
|
||||
void SDFobstack_chunk_free(void *p)
|
||||
{
|
||||
#if YYDEBUG
|
||||
if(yydebug)
|
||||
printf("free(0x%lx)\n", (unsigned long)p);
|
||||
#endif
|
||||
Free(p);
|
||||
}
|
||||
|
||||
/* This symbol tells a Flex-based scanner not to bother trying to
|
||||
call isatty to figure out whether to do char-at-a-time input. The
|
||||
actual behavior is under our explicit control anyway (see SDF-lex.l),
|
||||
but linking against fileno() and isatty() can be annoying. */
|
||||
#define YY_ALWAYS_INTERACTIVE 1
|
||||
#include "SDF-lex.c"
|
119
external/libsdf/libSDF/SDF-private.h
vendored
Normal file
119
external/libsdf/libSDF/SDF-private.h
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
SDF Library for reading Self-Describing Files
|
||||
Copyright (C) 1991,1992 John K. Salmon
|
||||
|
||||
Terms and conditions are specified in the file "copyright.h",
|
||||
and more precisely in the file COPYING.LIB which you should have
|
||||
received with this library.
|
||||
*/
|
||||
#ifndef sdfprivateDOTh
|
||||
#define sdfprivateDOTh
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include "stdio.h" /* from this directory!! */
|
||||
#include "obstack.h"
|
||||
|
||||
/* Exact copy of declaration in SDF.h */
|
||||
enum SDF_type_enum{SDF_NOTYPE,
|
||||
SDF_CHAR,
|
||||
SDF_SHORT,
|
||||
SDF_INT,
|
||||
SDF_LONG,
|
||||
SDF_INT64,
|
||||
SDF_FLOAT,
|
||||
SDF_DOUBLE,
|
||||
SDF_STRING};
|
||||
|
||||
extern char SDFerrstring[];
|
||||
|
||||
enum toggle_param_enum{NOTHING};
|
||||
|
||||
enum value_param_enum{BYTEORDER};
|
||||
|
||||
/* How the lexical analyzer returns constants. */
|
||||
typedef struct{
|
||||
enum SDF_type_enum type;
|
||||
union{
|
||||
char charval;
|
||||
short shortval;
|
||||
int intval;
|
||||
long longval;
|
||||
int64_t int64val;
|
||||
float floatval;
|
||||
double doubleval;
|
||||
char *stringval;
|
||||
} u;
|
||||
} const_t;
|
||||
|
||||
typedef struct{
|
||||
int nconst;
|
||||
struct obstack obs;
|
||||
} const_list_t;
|
||||
|
||||
typedef struct{
|
||||
char *name;
|
||||
enum SDF_type_enum type;
|
||||
int arrcnt;
|
||||
} one_dcl_t;
|
||||
|
||||
typedef struct{
|
||||
int ndcl;
|
||||
struct obstack obs;
|
||||
} dcl_list_t;
|
||||
|
||||
typedef struct{
|
||||
dcl_list_t dcl_list;
|
||||
int64_t Nrec;
|
||||
} declaration_t;
|
||||
|
||||
typedef struct{
|
||||
char *name;
|
||||
enum SDF_type_enum type;
|
||||
int arrcnt;
|
||||
int64_t blk_off;
|
||||
int64_t blk_num;
|
||||
int64_t nread;
|
||||
} vec_descrip_t;
|
||||
|
||||
typedef struct{
|
||||
int reclen;
|
||||
int inmem;
|
||||
int64_t Nrec;
|
||||
int64_t begin_offset;
|
||||
} blk_descrip_t;
|
||||
|
||||
typedef struct{
|
||||
int nblks;
|
||||
struct obstack blks_obs;
|
||||
blk_descrip_t *blks;
|
||||
int nvecs;
|
||||
struct obstack vecs_obs;
|
||||
vec_descrip_t *vecs;
|
||||
char **vec_names;
|
||||
struct obstack data_obs;
|
||||
void *data;
|
||||
MPMYFile *datafp;
|
||||
int64_t begin_file_offset;
|
||||
int byteorder;
|
||||
int swapping;
|
||||
int hashsz;
|
||||
vec_descrip_t **hashtbl;
|
||||
} SDF;
|
||||
|
||||
void SDFlexprepare(void);
|
||||
int SDFyyprepare(SDF *hdr, const char *hdrname, const char *dataname);
|
||||
void SDFobstack_chunk_free(void *p);
|
||||
void *SDFobstack_chunk_alloc(size_t n);
|
||||
|
||||
int SDF_Hdropen(const char *name);
|
||||
void SDF_Hdrclose(void);
|
||||
int SDF_Hdroffset(void);
|
||||
int SDF_Hdrgetc();
|
||||
|
||||
#define obstack_chunk_alloc SDFobstack_chunk_alloc
|
||||
#define obstack_chunk_free SDFobstack_chunk_free
|
||||
|
||||
#include "SDF.h"
|
||||
|
||||
|
||||
#endif /* sdfprivateDOTh */
|
941
external/libsdf/libSDF/SDFfuncs.c
vendored
Normal file
941
external/libsdf/libSDF/SDFfuncs.c
vendored
Normal file
|
@ -0,0 +1,941 @@
|
|||
/*
|
||||
SDF Library for reading Self-Describing Files
|
||||
Copyright (C) 1991,1992 John K. Salmon
|
||||
|
||||
Terms and conditions are specified in the file "copyright.h",
|
||||
and more precisely in the file COPYING.LIB which you should have
|
||||
received with this library.
|
||||
*/
|
||||
/* Implement the user-visible functions that make up the */
|
||||
/* SDF package. */
|
||||
|
||||
/* Using alloca reduces memory fragmentation, and allows the halo */
|
||||
/* finder to work on larger datasets */
|
||||
#define USE_ALLOCA
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#ifdef USE_ALLOCA
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
#include "Msgs.h"
|
||||
#include "stdio.h" /* for sprintf, etc. No 'real' stdio */
|
||||
#include "SDF-private.h"
|
||||
#include "obstack.h"
|
||||
#include "byteswap.h"
|
||||
#include "Malloc.h"
|
||||
#include "protos.h"
|
||||
#include "mpmy.h"
|
||||
#include "mpmy_io.h"
|
||||
|
||||
/* max_bufsz is the maximum read-buffer that we will attempt to
|
||||
malloc. The code in rdvecs is capable of requesting arbitrarily
|
||||
large blocks and scaling back (in powers of 2) until malloc returns
|
||||
non-NULL. That doesn't seem like a good idea on virtual systems,
|
||||
though, so the maximum first attempt is dynamically settable with
|
||||
SDFsetmaxbufsz. Setting it to zero will remove the limit. This is
|
||||
the initial value. */
|
||||
#define DEFAULT_MAX_BUFSZ (256LL*1024*1024)
|
||||
|
||||
static void buildhash(SDF *hdr);
|
||||
static vec_descrip_t *lookup(const char *name, SDF *hdr);
|
||||
static int compar_func(const void *p1, const void *p2);
|
||||
static vec_descrip_t **compar_vds;
|
||||
static unsigned char junk[4] = {0x12, 0x34, 0x56, 0x78};
|
||||
static unsigned int *cpubyteorder = (unsigned int *)&junk[0];
|
||||
static int max_bufsz = DEFAULT_MAX_BUFSZ;
|
||||
|
||||
char SDFerrstring[256];
|
||||
extern int SDFyyparse(void);
|
||||
|
||||
/* This is a non-guaranteed way to test if a file is SDF or not. */
|
||||
/* It really only tests the initial comment! This is not fail-safe! */
|
||||
int SDFissdf(const char *name){
|
||||
MPMYFile *fp;
|
||||
int result = 1;
|
||||
int c;
|
||||
char buf[64];
|
||||
int bufcnt = 0;
|
||||
|
||||
if( MPMY_Initialized() == 0 ){
|
||||
MPMY_Init(0, NULL);
|
||||
}
|
||||
/* Assume we do the 'right' thing with "-" */
|
||||
/* but what IS the right thing?? (see below) */
|
||||
fp = MPMY_Fopen(name, MPMY_RDONLY | MPMY_SINGL | MPMY_IOZERO);
|
||||
if( fp == NULL )
|
||||
return 0;
|
||||
|
||||
buf[bufcnt] = 0; /* In case read returns nothing */
|
||||
MPMY_Fread(buf, 1, 64, fp);
|
||||
if( (c=buf[bufcnt++]) != '#' ){ result=0; goto done;}
|
||||
while( isspace(c = buf[bufcnt++]) && c != '\n' );
|
||||
if( c == '\n' ) { result=0; goto done; }
|
||||
if( c != 'S' ) { result=0; goto done; }
|
||||
if( buf[bufcnt++] != 'D' ) { result=0; goto done; }
|
||||
if( buf[bufcnt++] != 'F' ) { result=0; goto done; }
|
||||
done:
|
||||
MPMY_Fclose(fp);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
SDF *SDFopen(const char *hdrfname, const char *datafname)
|
||||
{
|
||||
SDF *hdr;
|
||||
int parseerr;
|
||||
|
||||
/* Is this a good idea? Does it promote sloppy programming? Or does
|
||||
it allow a program that has no interest in MPMY to behave as
|
||||
expected? Or does it belong in MPMY_Fopen instead? */
|
||||
if( MPMY_Initialized() == 0 ){
|
||||
MPMY_Init(0, NULL);
|
||||
}
|
||||
|
||||
if( datafname == NULL ){
|
||||
sprintf(SDFerrstring, "SDFopen: NULL data file %s\n", datafname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hdr = Calloc(1, sizeof(SDF));
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFopen: could not calloc space for hdr\n");
|
||||
return NULL;
|
||||
}
|
||||
/* Handle the case of only one name in the arg list. */
|
||||
/* Don't worry about which one it is. Is this right? */
|
||||
if( hdrfname == NULL || hdrfname[0] == '\0' )
|
||||
hdrfname = datafname;
|
||||
if( datafname == NULL || datafname[0] == '\0' )
|
||||
datafname = hdrfname;
|
||||
|
||||
Msgf(("SDFopen: Calling SDFyyprepare(ptr, hdr=%s, data=%s)\n", hdrfname, datafname));
|
||||
if( SDFyyprepare(hdr, hdrfname, datafname) < 0 ){
|
||||
/* Hopefully, errstring was already set... */
|
||||
Free(hdr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
parseerr= SDFyyparse();
|
||||
|
||||
if(parseerr){
|
||||
/* Try to free up whatever's been allocated inside the hdr */
|
||||
SDFclose(hdr);
|
||||
return NULL;
|
||||
}else{
|
||||
Msgf(("SDFopen: SDFyyparse completed ok\n"));
|
||||
/* buildhash belongs in SDF_finishparse, but then I'd need to add
|
||||
a bunch more externals... Yuck. */
|
||||
buildhash(hdr);
|
||||
return hdr;
|
||||
}
|
||||
}
|
||||
|
||||
int SDFclose(SDF *hdr)
|
||||
{
|
||||
int i;
|
||||
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFclose: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
/* The check here is necessary in case we are trying to bail */
|
||||
/* out from inside SDFopen on a parse error. Cleaning up the */
|
||||
/* mess after a parse error still needs work! */
|
||||
if( hdr->vecs ){
|
||||
for(i=0; i<hdr->nvecs; i++){
|
||||
Free(hdr->vecs[i].name);
|
||||
}
|
||||
}
|
||||
obstack_free(&hdr->blks_obs, NULL);
|
||||
obstack_free(&hdr->vecs_obs, NULL);
|
||||
obstack_free(&hdr->data_obs, NULL);
|
||||
if( hdr->vec_names )
|
||||
Free(hdr->vec_names);
|
||||
if( hdr->datafp )
|
||||
MPMY_Fclose(hdr->datafp);
|
||||
if( hdr->hashtbl )
|
||||
Free(hdr->hashtbl);
|
||||
Free(hdr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDFnvecs(SDF *hdr)
|
||||
{
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFnvecs: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
return hdr->nvecs;
|
||||
}
|
||||
|
||||
int SDFseekable(SDF *hdr)
|
||||
{
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFseekable: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
return (MPMY_Fseek(hdr->datafp, 0, MPMY_SEEK_CUR) >= 0);
|
||||
}
|
||||
|
||||
int SDFhasname(const char *name, SDF *hdr)
|
||||
{
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFhasname: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
return (lookup(name, hdr)) ? 1 : 0;
|
||||
}
|
||||
|
||||
char **SDFvecnames(SDF *hdr)
|
||||
{
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFvecnames: not an SDF hdr\n");
|
||||
return NULL;
|
||||
}
|
||||
return hdr->vec_names;
|
||||
}
|
||||
|
||||
int64_t SDFnrecs(const char *name, SDF *hdr)
|
||||
{
|
||||
vec_descrip_t *desc;
|
||||
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFnrecs: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
desc = lookup(name, hdr);
|
||||
if(desc)
|
||||
return hdr->blks[desc->blk_num].Nrec;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDFarrcnt(const char *name, SDF *hdr)
|
||||
{
|
||||
vec_descrip_t *desc;
|
||||
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFarrcnt: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
desc = lookup(name, hdr);
|
||||
if(desc)
|
||||
return desc->arrcnt;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum SDF_type_enum SDFtype(const char *name, SDF *hdr)
|
||||
{
|
||||
vec_descrip_t *desc;
|
||||
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFtype: not an SDF hdr\n");
|
||||
return SDF_NOTYPE;
|
||||
}
|
||||
desc = lookup(name, hdr);
|
||||
if(desc)
|
||||
return desc->type;
|
||||
else
|
||||
return SDF_NOTYPE;
|
||||
}
|
||||
|
||||
int SDFtell(const char *name, SDF *hdr)
|
||||
{
|
||||
vec_descrip_t *desc;
|
||||
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFtell: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
desc = lookup(name, hdr);
|
||||
if(desc)
|
||||
return desc->nread;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
int SDFseek(const char *name, int64_t offset, int whence, SDF *hdr)
|
||||
{
|
||||
vec_descrip_t *desc;
|
||||
int64_t nrec;
|
||||
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFseek: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
desc = lookup(name, hdr);
|
||||
if(desc == NULL)
|
||||
return -1;
|
||||
|
||||
switch(whence){
|
||||
case SDF_SEEK_SET:
|
||||
desc->nread = offset;
|
||||
break;
|
||||
case SDF_SEEK_CUR:
|
||||
desc->nread += offset;
|
||||
break;
|
||||
case SDF_SEEK_END:
|
||||
nrec = hdr->blks[desc->blk_num].Nrec ;
|
||||
if(nrec == 0)
|
||||
return -1;
|
||||
desc->nread = nrec + offset;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* SDFfileoffset and SDFfilestride are for those who think they */
|
||||
/* can outsmart SDF*rdvecs*. They tell you the offset of the FIRST */
|
||||
/* element of NAME in the file, and the stride between successive */
|
||||
/* elements. They do not pay any attention to the current seek pointer. */
|
||||
/* We do not provide SDFfilefp because we don't want you to mess with */
|
||||
/* our file pointer. Open the file yourself if you're so smart... */
|
||||
int64_t SDFfileoffset(const char *name, SDF *hdr){
|
||||
vec_descrip_t *desc;
|
||||
blk_descrip_t *blk;
|
||||
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFfileoffset: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
if( hdr->begin_file_offset < 0 ){
|
||||
sprintf(SDFerrstring, "SDFfileoffset: unseekable file\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
desc = lookup(name, hdr);
|
||||
if(desc == NULL)
|
||||
return -1;
|
||||
blk = &hdr->blks[desc->blk_num];
|
||||
if( blk->inmem ){
|
||||
sprintf(SDFerrstring, "SDFfileoffset: %s not in data segment\n", name);
|
||||
return -1;
|
||||
}
|
||||
return blk->begin_offset + desc->blk_off + hdr->begin_file_offset;
|
||||
}
|
||||
|
||||
int64_t SDFfilestride(const char *name, SDF *hdr){
|
||||
vec_descrip_t *desc;
|
||||
blk_descrip_t *blk;
|
||||
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFfilestride: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
desc = lookup(name, hdr);
|
||||
if(desc == NULL)
|
||||
return -1;
|
||||
blk = &hdr->blks[desc->blk_num];
|
||||
if( blk->inmem ){
|
||||
sprintf(SDFerrstring, "SDFfilestride: %s not in data segment\n", name);
|
||||
return -1;
|
||||
}
|
||||
return blk->reclen;
|
||||
}
|
||||
|
||||
unsigned int SDFcpubyteorder(void){
|
||||
return *cpubyteorder;
|
||||
}
|
||||
|
||||
unsigned int SDFbyteorder(SDF *hdr){
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFbyteorder: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
/* This is either 0 or the value set by a 'parameter byteorder=' stmt */
|
||||
return hdr->byteorder;
|
||||
}
|
||||
|
||||
int SDFswap(SDF *hdr){
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFswap: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
hdr->swapping = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDFnoswap(SDF *hdr){
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFnoswap: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
hdr->swapping = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDFisswapping(SDF *hdr){
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFisswapping: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
return hdr->swapping;
|
||||
}
|
||||
|
||||
int SDFsetmaxbufsz(int new){
|
||||
int ret = max_bufsz;
|
||||
max_bufsz = new;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDFrdvecs(SDF *hdr, ...
|
||||
/* char *name, int n, void *address, int stride, ... */ )
|
||||
{
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFrdvecs: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
va_start(ap, hdr);
|
||||
ret = SDFrdvecsv(hdr, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDFrdvecsv(SDF *hdr, va_list ap)
|
||||
{
|
||||
int *narray;
|
||||
char **namearray;
|
||||
void **addressarray;
|
||||
int *stridearray;
|
||||
struct obstack nobs;
|
||||
struct obstack nameobs;
|
||||
struct obstack addressobs;
|
||||
struct obstack strideobs;
|
||||
int nrequests;
|
||||
char *name;
|
||||
int stride, n;
|
||||
void *address;
|
||||
int ret;
|
||||
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFrdvecsv: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
obstack_begin(&nameobs, 32*sizeof(char *));
|
||||
obstack_begin(&strideobs, 32*sizeof(int));
|
||||
obstack_begin(&nobs, 32*sizeof(int));
|
||||
obstack_begin(&addressobs, 32*sizeof(void *));
|
||||
|
||||
nrequests = 0;
|
||||
while( (name = va_arg(ap, char *)) ){
|
||||
nrequests++;
|
||||
obstack_ptr_grow(&nameobs, name);
|
||||
n = va_arg(ap, int);
|
||||
obstack_int_grow(&nobs, n);
|
||||
address = va_arg(ap, void *);
|
||||
obstack_ptr_grow(&addressobs, address);
|
||||
stride = va_arg(ap, int);
|
||||
obstack_int_grow(&strideobs, stride);
|
||||
}
|
||||
obstack_int_grow(&nobs, 0);
|
||||
obstack_int_grow(&strideobs, 0);
|
||||
obstack_ptr_grow(&nameobs, NULL);
|
||||
obstack_ptr_grow(&addressobs, NULL);
|
||||
|
||||
narray = (int *)obstack_finish(&nobs);
|
||||
namearray = (char **)obstack_finish(&nameobs);
|
||||
addressarray = (void **)obstack_finish(&addressobs);
|
||||
stridearray = (int *)obstack_finish(&strideobs);
|
||||
ret = SDFrdvecsarr(hdr, nrequests,
|
||||
namearray, narray, addressarray, stridearray);
|
||||
obstack_free(&nobs, NULL);
|
||||
obstack_free(&nameobs, NULL);
|
||||
obstack_free(&addressobs, NULL);
|
||||
obstack_free(&strideobs, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDFrdvecsarr(SDF *hdr, int nreq,
|
||||
char **names, int *ns, void **addresses, int *strides)
|
||||
{
|
||||
int64_t *starts;
|
||||
int i;
|
||||
int ret;
|
||||
vec_descrip_t *descrip;
|
||||
|
||||
starts = Malloc(nreq*sizeof(int64_t));
|
||||
if( starts == NULL && nreq>0 ){
|
||||
sprintf(SDFerrstring, "Could not malloc tmp space in SDFrdvecsarr\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(i=0; i<nreq; i++){
|
||||
if( (descrip = lookup(names[i], hdr)) == NULL ){
|
||||
ret = -1;
|
||||
sprintf(SDFerrstring, "SDFrdvecsarr: \"%s\" name not found\n",
|
||||
names[i]);
|
||||
goto outahere;
|
||||
}
|
||||
starts[i] = descrip->nread;
|
||||
}
|
||||
if( (ret = SDFseekrdvecsarr(hdr, nreq, names,
|
||||
starts, ns, addresses, strides)) ){
|
||||
goto outahere;
|
||||
}
|
||||
/* At this point, we have successfully looked up all */
|
||||
/* the names twice (at least). */
|
||||
for(i=0; i<nreq; i++){
|
||||
descrip = lookup(names[i], hdr);
|
||||
/* assert(descrip); */
|
||||
descrip->nread += ns[i];
|
||||
}
|
||||
outahere:
|
||||
Free(starts);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDFseekrdvecs(SDF *hdr, ...
|
||||
/* char *name, int start, int n, void *addr, int stride, ... */ )
|
||||
{
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFseekrdvecs: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
va_start(ap, hdr);
|
||||
ret = SDFseekrdvecsv(hdr, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDFseekrdvecsv(SDF *hdr, va_list ap)
|
||||
{
|
||||
int *narray;
|
||||
int64_t *startarray;
|
||||
char **namearray;
|
||||
void **addressarray;
|
||||
int *stridearray;
|
||||
struct obstack nobs;
|
||||
struct obstack nameobs;
|
||||
struct obstack startobs;
|
||||
struct obstack addressobs;
|
||||
struct obstack strideobs;
|
||||
int nrequests;
|
||||
char *name;
|
||||
int64_t start;
|
||||
int64_t zero64 = 0;
|
||||
int stride, n;
|
||||
void *address;
|
||||
int ret;
|
||||
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFseekrdvecsv: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
obstack_begin(&nameobs, 32*sizeof(char *));
|
||||
obstack_begin(&startobs, 32*sizeof(int64_t));
|
||||
obstack_begin(&strideobs, 32*sizeof(int));
|
||||
obstack_begin(&nobs, 32*sizeof(int));
|
||||
obstack_begin(&addressobs, 32*sizeof(void *));
|
||||
|
||||
nrequests = 0;
|
||||
while( (name = va_arg(ap, char *)) ){
|
||||
nrequests++;
|
||||
obstack_ptr_grow(&nameobs, name);
|
||||
start = va_arg(ap, int64_t);
|
||||
obstack_grow(&startobs, &start, sizeof(int64_t));
|
||||
n = va_arg(ap, int);
|
||||
obstack_int_grow(&nobs, n);
|
||||
address = va_arg(ap, void *);
|
||||
obstack_ptr_grow(&addressobs, address);
|
||||
stride = va_arg(ap, int);
|
||||
obstack_int_grow(&strideobs, stride);
|
||||
}
|
||||
obstack_int_grow(&nobs, 0);
|
||||
obstack_grow(&startobs, &zero64, sizeof(int64_t));
|
||||
obstack_int_grow(&strideobs, 0);
|
||||
obstack_ptr_grow(&nameobs, NULL);
|
||||
obstack_ptr_grow(&addressobs, NULL);
|
||||
|
||||
narray = (int *)obstack_finish(&nobs);
|
||||
namearray = (char **)obstack_finish(&nameobs);
|
||||
startarray = (int64_t *)obstack_finish(&startobs);
|
||||
addressarray = (void **)obstack_finish(&addressobs);
|
||||
stridearray = (int *)obstack_finish(&strideobs);
|
||||
ret = SDFseekrdvecsarr(hdr, nrequests,
|
||||
namearray, startarray, narray, addressarray, stridearray);
|
||||
obstack_free(&nobs, NULL);
|
||||
obstack_free(&nameobs, NULL);
|
||||
obstack_free(&startobs, NULL);
|
||||
obstack_free(&addressobs, NULL);
|
||||
obstack_free(&strideobs, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
void no_problem(const char *fmt, ...){
|
||||
/* Pass this to the MallocHandler function to tell Malloc that we
|
||||
know what we're doing, and we really can recover from malloc
|
||||
returning null! */
|
||||
return;
|
||||
}
|
||||
|
||||
int SDFseekrdvecsarr(SDF *hdr, int nreq,
|
||||
char **names, int64_t *starts, int *ns, void **addresses, int *strides)
|
||||
{
|
||||
int nn;
|
||||
off_t fileoffset;
|
||||
int i;
|
||||
int64_t nrec;
|
||||
int vecnum, first;
|
||||
int next_blknum;
|
||||
int last_blknum;
|
||||
int64_t sz_needed;
|
||||
int *sort_index;
|
||||
vec_descrip_t *descrip, **vd_array;
|
||||
char *fromptr, *toptr;
|
||||
char *recptr, *buf;
|
||||
int64_t buf_sz;
|
||||
int64_t last_rec, first_rec, new_last_rec;
|
||||
blk_descrip_t *blk;
|
||||
int stride, sz;
|
||||
int ret;
|
||||
int64_t nread, rec_cnt, rec_left, ncopy, ntry;
|
||||
int64_t *nleft, *seekto;
|
||||
char **toptr_arr;
|
||||
int64_t whole_sz;
|
||||
Error_t oldmallochandler;
|
||||
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFseekrdvecsarr: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
buf = NULL;
|
||||
buf_sz = 0;
|
||||
#ifdef USE_ALLOCA
|
||||
sort_index = alloca(nreq*sizeof(int));
|
||||
vd_array = alloca(nreq*sizeof(vec_descrip_t *));
|
||||
nleft = alloca(nreq*sizeof(int64_t));
|
||||
toptr_arr = alloca(nreq*sizeof(char *));
|
||||
seekto = alloca(nreq*sizeof(int64_t));
|
||||
#else
|
||||
sort_index = Malloc(nreq*sizeof(int));
|
||||
vd_array = Malloc(nreq*sizeof(vec_descrip_t *));
|
||||
nleft = Malloc(nreq*sizeof(int64_t));
|
||||
toptr_arr = Malloc(nreq*sizeof(char *));
|
||||
seekto = Malloc(nreq*sizeof(int64_t));
|
||||
#endif
|
||||
|
||||
if( nreq>0 && (sort_index == NULL
|
||||
|| vd_array == NULL || nleft == NULL || toptr_arr == NULL
|
||||
|| seekto == NULL) ){
|
||||
sprintf(SDFerrstring,
|
||||
"SDFseekrdvecsarr: Malloc failed\n"
|
||||
"sort_index(%lu) = 0x%lx, vd_array(%lu) = 0x%lx\n",
|
||||
(unsigned long)nreq*sizeof(int), (unsigned long)sort_index,
|
||||
(unsigned long)nreq*sizeof(vec_descrip_t),
|
||||
(unsigned long)vd_array);
|
||||
ret = -1;
|
||||
goto outahere;
|
||||
}
|
||||
|
||||
for(i=0; i<nreq; i++){
|
||||
sort_index[i] = i;
|
||||
if( (descrip = lookup(names[i], hdr)) != NULL ){
|
||||
vd_array[i] = descrip;
|
||||
}else{
|
||||
ret = -1;
|
||||
goto outahere;
|
||||
}
|
||||
/* Check to make sure we don't go past the end of a record */
|
||||
nrec = hdr->blks[vd_array[i]->blk_num].Nrec;
|
||||
if(nrec > 0 && starts[i] + ns[i] > nrec){
|
||||
ret = -1;
|
||||
Msg_do("nrec %ld i %d starts[i] %ld ns[i] %d\n",
|
||||
nrec, i, starts[i], ns[i]);
|
||||
sprintf(SDFerrstring,
|
||||
"SDFseekrdvecsarr: attempt to read past end of vector \"%s\"",
|
||||
names[i]);
|
||||
goto outahere;
|
||||
}
|
||||
}
|
||||
|
||||
compar_vds = vd_array;
|
||||
qsort(sort_index, nreq, sizeof(sort_index[0]), compar_func);
|
||||
/* Now the descrip_list is sorted so that we can do all the */
|
||||
/* vectors in the same block at once. */
|
||||
|
||||
vecnum = 0;
|
||||
while( vecnum < nreq ){
|
||||
descrip = vd_array[sort_index[vecnum]];
|
||||
first = vecnum;
|
||||
next_blknum = descrip->blk_num;
|
||||
blk = &hdr->blks[next_blknum];
|
||||
first_rec = starts[sort_index[vecnum]];
|
||||
last_rec = first_rec;
|
||||
do{
|
||||
new_last_rec = ns[sort_index[vecnum]] + starts[sort_index[vecnum]];
|
||||
if(new_last_rec > last_rec)
|
||||
last_rec = new_last_rec;
|
||||
last_blknum = next_blknum;
|
||||
if(++vecnum == nreq)
|
||||
break;
|
||||
descrip = vd_array[sort_index[vecnum]];
|
||||
next_blknum = descrip->blk_num;
|
||||
}while( last_blknum==next_blknum );
|
||||
|
||||
/* We are going to do all the vectors between first and vecnum */
|
||||
/* all at once. They all point at the same block. */
|
||||
rec_left = rec_cnt = last_rec - first_rec;
|
||||
for(i=first; i<vecnum; i++){
|
||||
nleft[i] = ns[sort_index[i]];
|
||||
toptr_arr[i] = addresses[sort_index[i]];
|
||||
seekto[i] = starts[sort_index[i]];
|
||||
}
|
||||
if(blk->inmem){
|
||||
recptr = ((char *)hdr->data) + blk->begin_offset + blk->reclen*first_rec;
|
||||
fileoffset = 0; /* not necessary, but it quiets a warning */
|
||||
}else{
|
||||
whole_sz = blk->reclen * rec_left;
|
||||
if( max_bufsz > 0 && whole_sz > max_bufsz ){
|
||||
sz_needed = (max_bufsz/blk->reclen)*blk->reclen;
|
||||
if( sz_needed < blk->reclen )
|
||||
sz_needed = blk->reclen;
|
||||
}else{
|
||||
sz_needed = whole_sz;
|
||||
}
|
||||
if( sz_needed > buf_sz ){
|
||||
oldmallochandler = MallocHandler(no_problem);
|
||||
if( buf )
|
||||
Free(buf);
|
||||
buf_sz = sz_needed;
|
||||
buf = Malloc(buf_sz);
|
||||
while( buf == NULL && buf_sz >= blk->reclen ){
|
||||
buf_sz >>= 1;
|
||||
buf = Malloc(buf_sz);
|
||||
}
|
||||
MallocHandler(oldmallochandler);
|
||||
if( buf == NULL ){
|
||||
sprintf(SDFerrstring, "SDFrdvecsarr: no space!\n");
|
||||
ret = -1;
|
||||
goto outahere;
|
||||
}
|
||||
}
|
||||
recptr = buf;
|
||||
/* Repaired by msw Mon Jul 11 14:35:19 PDT 1994 */
|
||||
/* Repaired again by johns Tue Jun 27 14:55:42 EST 1995 */
|
||||
fileoffset = blk->begin_offset + (off_t)blk->reclen * first_rec
|
||||
+ hdr->begin_file_offset;
|
||||
Msgf(("blk->reclen %d, first_rec %ld\n", blk->reclen, first_rec));
|
||||
Msgf(("fileoffset is %ld\n", fileoffset));
|
||||
Msgf(("buf_sz is %ld\n", buf_sz));
|
||||
}
|
||||
|
||||
while( rec_left > 0 ){
|
||||
if(blk->inmem){
|
||||
nread = rec_left;
|
||||
rec_left = 0;
|
||||
}else{
|
||||
if( blk->reclen > buf_sz ){
|
||||
sprintf(SDFerrstring, "SDFrdvecsarr: not enough for one record!\n");
|
||||
ret = -1;
|
||||
goto outahere;
|
||||
}
|
||||
whole_sz = blk->reclen * rec_left;
|
||||
if( whole_sz > buf_sz ){
|
||||
ntry = (buf_sz-blk->reclen)/blk->reclen + 1;
|
||||
}else{
|
||||
ntry = rec_left;
|
||||
}
|
||||
|
||||
/* SDFlib2 model has one file pointer, thus use SEEK_SET */
|
||||
if((nread = MPMY_Fseekrd(hdr->datafp, fileoffset,
|
||||
MPMY_SEEK_SET, buf, blk->reclen, ntry))
|
||||
!= ntry ){
|
||||
ret = -1;
|
||||
sprintf(SDFerrstring,
|
||||
"SDFrdvecsarr: fseekrd(offset=%ld, SEEK_CUR, reclen=%d, ntry=%ld) only got %ld, errno=%d\n",
|
||||
fileoffset, blk->reclen, ntry, nread, errno);
|
||||
goto outahere;
|
||||
}
|
||||
rec_left -= nread;
|
||||
fileoffset += blk->reclen * (off_t)nread;
|
||||
}
|
||||
|
||||
for(i=first; i<vecnum; i++){
|
||||
descrip = vd_array[sort_index[i]];
|
||||
if( seekto[i] > (first_rec + nread) || nleft[i] == 0 )
|
||||
continue;
|
||||
fromptr = recptr + (seekto[i] - first_rec)*blk->reclen
|
||||
+ descrip->blk_off;
|
||||
ncopy = nread - (seekto[i] - first_rec);
|
||||
if( ncopy > nleft[i] ){
|
||||
ncopy = nleft[i];
|
||||
}
|
||||
toptr = toptr_arr[i];
|
||||
stride = strides[sort_index[i]];
|
||||
sz = SDFtype_sizes[descrip->type];
|
||||
if( stride == 0 )
|
||||
stride = sz*descrip->arrcnt;
|
||||
if( sz*descrip->arrcnt > stride ){
|
||||
/* This could have been checked earlier!!! */
|
||||
sprintf(SDFerrstring, "stride for %s not long enough to step over successive elements. arrcnt=%d, unit_sz=%d, stride=%d\n",
|
||||
descrip->name, descrip->arrcnt, sz, stride);
|
||||
ret = -1;
|
||||
goto outahere;
|
||||
}
|
||||
for(nn=0; nn< ncopy; nn++){
|
||||
if(!blk->inmem && hdr->swapping){
|
||||
if(Byteswap( sz, descrip->arrcnt, fromptr, toptr)){
|
||||
sprintf(SDFerrstring, "SDFswapn(%d, %d, 0x%lx, 0x%lx) Failed",
|
||||
sz, descrip->arrcnt,
|
||||
(unsigned long)fromptr,
|
||||
(unsigned long)toptr);
|
||||
/* There's probably more cleaning up to do! */
|
||||
ret = -1;
|
||||
goto outahere;
|
||||
}
|
||||
}else{
|
||||
(void)memcpy( toptr, fromptr, sz * descrip->arrcnt);
|
||||
}
|
||||
fromptr += blk->reclen;
|
||||
toptr += stride;
|
||||
}
|
||||
seekto[i] += ncopy;
|
||||
nleft[i] -= ncopy;
|
||||
toptr_arr[i] = toptr;
|
||||
}
|
||||
first_rec += nread;
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
outahere:
|
||||
/* alloca would be simpler! */
|
||||
/* The tests are not necessary according to ANSI... */
|
||||
#ifndef USE_ALLOCA
|
||||
if( seekto ) Free(seekto);
|
||||
if( toptr_arr ) Free(toptr_arr);
|
||||
if( nleft ) Free(nleft);
|
||||
if( vd_array ) Free(vd_array);
|
||||
if( sort_index ) Free(sort_index);
|
||||
#endif
|
||||
if( buf ) Free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int compar_func(const void *p1, const void *p2){
|
||||
int i1 = *(int *)p1;
|
||||
int i2 = *(int *)p2;
|
||||
vec_descrip_t *d1 = compar_vds[i1];
|
||||
vec_descrip_t *d2 = compar_vds[i2];
|
||||
|
||||
if(d1->blk_num < d2->blk_num)
|
||||
return -1;
|
||||
else if(d1->blk_num > d2->blk_num)
|
||||
return 1;
|
||||
else if(d1->nread < d2->nread)
|
||||
return -1;
|
||||
else if(d1->nread > d2->nread)
|
||||
return 1;
|
||||
else if(d1->blk_off < d2->blk_off)
|
||||
return -1;
|
||||
else if(d1->blk_off > d2->blk_off)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* a few prime numbers chosen entirely at random... */
|
||||
#define NCOEF (sizeof(hashcoef)/sizeof(*hashcoef))
|
||||
static int hashcoef[] = { 17, 37, 3, 97, 57, 23, 151, 7, 41 };
|
||||
|
||||
/*
|
||||
This completely bogus hash function computes a linear combination of
|
||||
characters in the word.
|
||||
*/
|
||||
static int SDFhash(const char *word, SDF *hdr){
|
||||
int i;
|
||||
const char *p;
|
||||
int sum = 0;
|
||||
|
||||
p = word;
|
||||
i = 0;
|
||||
while(*p){
|
||||
sum += hashcoef[i] * *p;
|
||||
p++;
|
||||
if( ++i == NCOEF )
|
||||
i = 0;
|
||||
}
|
||||
Msgf(("hash(%s) = %d%%%d = %d\n", word, sum, hdr->hashsz, sum%hdr->hashsz));
|
||||
return sum % hdr->hashsz;
|
||||
}
|
||||
|
||||
static int isprime(int n){
|
||||
int d;
|
||||
/* this only needs to work for small O(few hundred) values of n */
|
||||
/* first make sure it's not even */
|
||||
if( (n&1) == 0 )
|
||||
return 0;
|
||||
/* Extremely naive. Now check all odd potential divisors up to sqrt(n) */
|
||||
for(d = 3; d*d<=n ; d+=2){
|
||||
if( n%d == 0 )
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nextprime(int n){
|
||||
Msgf(("nextprime(%d) = ", n));
|
||||
if( (n&1) == 0 )
|
||||
n++;
|
||||
while(!isprime(n)) n+=2;
|
||||
Msgf(("%d\n", n));
|
||||
return n;
|
||||
}
|
||||
|
||||
static void buildhash(SDF *hdr){
|
||||
int sz;
|
||||
int i, h;
|
||||
|
||||
sz = nextprime(5*hdr->nvecs);
|
||||
Msgf(("hash table of size %d\n", sz));
|
||||
hdr->hashsz = sz;
|
||||
hdr->hashtbl = Calloc(sz, sizeof(*hdr->hashtbl));
|
||||
|
||||
for(i=0; i<hdr->nvecs; i++){
|
||||
h = SDFhash(hdr->vecs[i].name, hdr);
|
||||
while( hdr->hashtbl[h] != NULL ){
|
||||
Msgf(("build: hcollision between %s and %s in name-space\n",
|
||||
hdr->hashtbl[h]->name, hdr->vecs[i].name));
|
||||
h++;
|
||||
if(h==sz) /* wrap */
|
||||
h = 0;
|
||||
}
|
||||
hdr->hashtbl[h] = &hdr->vecs[i];
|
||||
}
|
||||
}
|
||||
|
||||
static vec_descrip_t *lookup(const char *name, SDF *hdr)
|
||||
{
|
||||
int i, istart;
|
||||
vec_descrip_t *possible;
|
||||
|
||||
i = istart = SDFhash(name, hdr);
|
||||
do{
|
||||
possible = hdr->hashtbl[i];
|
||||
if( possible == NULL ){
|
||||
break;
|
||||
}
|
||||
if( strcmp(possible->name, name) == 0 )
|
||||
return possible;
|
||||
|
||||
Msgf(("lookup: hcollision i=%d, name=%s, tblname=%s\n",
|
||||
i, name, possible->name));
|
||||
i++;
|
||||
if( i==hdr->hashsz ) /* wrap */
|
||||
i = 0;
|
||||
/* It ought to be imposible to fall off the bottom of this loop */
|
||||
}while(i!= istart);
|
||||
|
||||
sprintf(SDFerrstring, "No such name, \"%s\" in file.", name);
|
||||
return NULL;
|
||||
}
|
278
external/libsdf/libSDF/SDFget.c
vendored
Normal file
278
external/libsdf/libSDF/SDFget.c
vendored
Normal file
|
@ -0,0 +1,278 @@
|
|||
#include <stddef.h>
|
||||
/* stdio only needed for sprintf proto */
|
||||
#include <stdio.h>
|
||||
#include "error.h"
|
||||
#include "SDF.h"
|
||||
/*
|
||||
|
||||
These routines return 0 on success and 1 on failure. They set
|
||||
SDFerrstring if they think something strange is happening. They
|
||||
don't change the value under the VALUE argument until they are sure
|
||||
that everything is OK, so it's possible (but what would Henry Spencer
|
||||
say?) to use them by setting a default value, then calling the routine,
|
||||
and not worrying about the error condition.
|
||||
|
||||
*/
|
||||
|
||||
/* An abbreviation used many times... */
|
||||
|
||||
#define SDFget(sdfp, name, addr) \
|
||||
if(SDFseekrdvecs(sdfp, name, 0, 1, addr, 0, NULL)) return -1
|
||||
|
||||
/* I'll resist the temptation to make one macro to cover all these cases */
|
||||
/* Should we check for loss of precision in float too? */
|
||||
int
|
||||
SDFgetfloat(SDF *sdfp, char *name, float *value)
|
||||
{
|
||||
double double_value;
|
||||
int int_value;
|
||||
long long_value;
|
||||
int64_t int64_value;
|
||||
float float_value;
|
||||
|
||||
if( sdfp == NULL || !SDFhasname(name, sdfp) ){
|
||||
return -1;
|
||||
}
|
||||
switch(SDFtype(name, sdfp)){
|
||||
case SDF_FLOAT:
|
||||
SDFget(sdfp, name, &float_value);
|
||||
*value = float_value;
|
||||
return 0;
|
||||
case SDF_DOUBLE:
|
||||
SDFget(sdfp, name, &double_value);
|
||||
*value = (float) double_value;
|
||||
return 0;
|
||||
case SDF_INT:
|
||||
SDFget(sdfp, name, &int_value);
|
||||
*value = (float) int_value;
|
||||
return 0;
|
||||
case SDF_LONG:
|
||||
SDFget(sdfp, name, &long_value);
|
||||
*value = (float) long_value;
|
||||
return 0;
|
||||
case SDF_INT64:
|
||||
SDFget(sdfp, name, &int64_value);
|
||||
*value = (float) int64_value;
|
||||
return 0;
|
||||
default:
|
||||
sprintf(SDFerrstring,
|
||||
"SDFgetfloat: \"%s\" must be either float or int.\n", name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
SDFgetdouble(SDF *sdfp, char *name, double *value)
|
||||
{
|
||||
double double_value;
|
||||
float float_value;
|
||||
int int_value;
|
||||
long long_value;
|
||||
int64_t int64_value;
|
||||
|
||||
if( sdfp == NULL || !SDFhasname(name, sdfp) ){
|
||||
return -1;
|
||||
}
|
||||
switch(SDFtype(name, sdfp)){
|
||||
case SDF_DOUBLE:
|
||||
SDFget(sdfp, name, &double_value);
|
||||
*value = double_value;
|
||||
return 0;
|
||||
case SDF_FLOAT:
|
||||
SDFget(sdfp, name, &float_value);
|
||||
*value = (double) float_value;
|
||||
return 0;
|
||||
case SDF_INT:
|
||||
SDFget(sdfp, name, &int_value);
|
||||
*value = (double) int_value;
|
||||
return 0;
|
||||
case SDF_LONG:
|
||||
SDFget(sdfp, name, &long_value);
|
||||
*value = (double) long_value;
|
||||
return 0;
|
||||
case SDF_INT64:
|
||||
SDFget(sdfp, name, &int64_value);
|
||||
*value = (double) int64_value;
|
||||
return 0;
|
||||
default:
|
||||
sprintf(SDFerrstring,
|
||||
"SDFgetdouble: \"%s\" must be either float or int.\n", name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
SDFgetint(SDF *sdfp, char *name, int *value)
|
||||
{
|
||||
int int_value;
|
||||
float float_value;
|
||||
double double_value;
|
||||
|
||||
if( sdfp == NULL || !SDFhasname(name, sdfp) ){
|
||||
return -1;
|
||||
}
|
||||
switch(SDFtype(name, sdfp)){
|
||||
case SDF_INT:
|
||||
SDFget(sdfp, name, &int_value);
|
||||
*value = int_value;
|
||||
return 0;
|
||||
case SDF_DOUBLE:
|
||||
SDFget(sdfp, name, &double_value);
|
||||
int_value = (int) double_value;
|
||||
if ((double)int_value != double_value){
|
||||
sprintf(SDFerrstring,
|
||||
"SDFgetint: \"%s\" has lost precision\n", name);
|
||||
return -1;
|
||||
}
|
||||
*value = int_value;
|
||||
return 0;
|
||||
case SDF_FLOAT:
|
||||
SDFget(sdfp, name, &float_value);
|
||||
int_value = (int) float_value;
|
||||
if ((float)int_value != float_value){
|
||||
Warning("SDFgetint: \"%s\" has lost precision\n", name);
|
||||
return -1;
|
||||
}
|
||||
*value = int_value;
|
||||
return 0;
|
||||
default:
|
||||
sprintf(SDFerrstring, "SDFgetint: \"%s\" must be either float or int.\n", name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
SDFgetlong(SDF *sdfp, char *name, long *value)
|
||||
{
|
||||
int int_value;
|
||||
float float_value;
|
||||
double double_value;
|
||||
long long_value;
|
||||
int64_t int64_value;
|
||||
|
||||
if( sdfp == NULL || !SDFhasname(name, sdfp) ){
|
||||
return -1;
|
||||
}
|
||||
switch(SDFtype(name, sdfp)){
|
||||
case SDF_INT:
|
||||
SDFget(sdfp, name, &int_value);
|
||||
*value = int_value;
|
||||
return 0;
|
||||
case SDF_LONG:
|
||||
SDFget(sdfp, name, &long_value);
|
||||
*value = long_value;
|
||||
return 0;
|
||||
case SDF_INT64:
|
||||
SDFget(sdfp, name, &int64_value);
|
||||
long_value = (long) int64_value;
|
||||
if ((int64_t)long_value != int64_value){
|
||||
sprintf(SDFerrstring,
|
||||
"SDFgetint: \"%s\" has lost precision\n", name);
|
||||
return -1;
|
||||
}
|
||||
*value = int64_value;
|
||||
return 0;
|
||||
case SDF_DOUBLE:
|
||||
SDFget(sdfp, name, &double_value);
|
||||
long_value = (long) double_value;
|
||||
if ((double)int_value != double_value){
|
||||
sprintf(SDFerrstring,
|
||||
"SDFgetlong: \"%s\" has lost precision\n", name);
|
||||
return -1;
|
||||
}
|
||||
*value = int_value;
|
||||
return 0;
|
||||
case SDF_FLOAT:
|
||||
SDFget(sdfp, name, &float_value);
|
||||
long_value = (long) float_value;
|
||||
if ((float)long_value != float_value){
|
||||
Warning("SDFgetlong: \"%s\" has lost precision\n", name);
|
||||
return -1;
|
||||
}
|
||||
*value = long_value;
|
||||
return 0;
|
||||
default:
|
||||
sprintf(SDFerrstring, "SDFgetint: \"%s\" must be either float or int.\n", name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
SDFgetint64(SDF *sdfp, char *name, int64_t *value)
|
||||
{
|
||||
int int_value;
|
||||
float float_value;
|
||||
double double_value;
|
||||
long long_value;
|
||||
int64_t int64_value;
|
||||
|
||||
if( sdfp == NULL || !SDFhasname(name, sdfp) ){
|
||||
return -1;
|
||||
}
|
||||
switch(SDFtype(name, sdfp)){
|
||||
case SDF_INT:
|
||||
SDFget(sdfp, name, &int_value);
|
||||
*value = int_value;
|
||||
return 0;
|
||||
case SDF_LONG:
|
||||
SDFget(sdfp, name, &long_value);
|
||||
*value = long_value;
|
||||
return 0;
|
||||
case SDF_INT64:
|
||||
SDFget(sdfp, name, &int64_value);
|
||||
*value = int64_value;
|
||||
return 0;
|
||||
case SDF_DOUBLE:
|
||||
SDFget(sdfp, name, &double_value);
|
||||
int64_value = (int64_t) double_value;
|
||||
if ((double)int64_value != double_value){
|
||||
sprintf(SDFerrstring,
|
||||
"SDFgetint64: \"%s\" has lost precision\n", name);
|
||||
return -1;
|
||||
}
|
||||
*value = int64_value;
|
||||
return 0;
|
||||
case SDF_FLOAT:
|
||||
SDFget(sdfp, name, &float_value);
|
||||
int64_value = (int64_t) float_value;
|
||||
if ((float)int64_value != float_value){
|
||||
Warning("SDFgetint64: \"%s\" has lost precision\n", name);
|
||||
return -1;
|
||||
}
|
||||
*value = int64_value;
|
||||
return 0;
|
||||
default:
|
||||
sprintf(SDFerrstring, "SDFgetint: \"%s\" must be either float or int.\n", name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
SDFgetstring(SDF *sdfp, const char *name, char *string, int size){
|
||||
int len;
|
||||
int ret;
|
||||
|
||||
if( sdfp == NULL ){
|
||||
sprintf(SDFerrstring, "SDFgetint: NULL sdfp\n");
|
||||
return -1;
|
||||
}
|
||||
if( !SDFhasname(name, sdfp) ){
|
||||
return -1;
|
||||
}
|
||||
if( SDFtype(name, sdfp) != SDF_CHAR ){
|
||||
return -1;
|
||||
}
|
||||
if( (len=SDFarrcnt(name, sdfp)) >= size ){
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = SDFseekrdvecs(sdfp, name, 0, 1, string, 0, NULL);
|
||||
if( string[len-1] != '\0' ){
|
||||
sprintf(SDFerrstring,
|
||||
"Read non-terminated string in SDFgetstring(\"%s\")\n", name);
|
||||
string[len] = '\0';
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
86
external/libsdf/libSDF/SDFhdrio.c
vendored
Normal file
86
external/libsdf/libSDF/SDFhdrio.c
vendored
Normal file
|
@ -0,0 +1,86 @@
|
|||
/* An implementation of getc, using MPMY functions. */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
#include "Msgs.h"
|
||||
#include "error.h"
|
||||
#include "SDF-private.h"
|
||||
#include "stdio.h"
|
||||
#include "mpmy_io.h"
|
||||
|
||||
#define MYBUFSZ 4096
|
||||
|
||||
/* Assumption: we can only have one header at a time being read.
|
||||
The header is opened, read anc closed, all during the course of SDFopen
|
||||
so we don't have to screw around with multiple open files, etc. */
|
||||
|
||||
static MPMYFile *fp;
|
||||
static char buf[MYBUFSZ];
|
||||
static char *ptr;
|
||||
static char *endbuf;
|
||||
static int buf_offset;
|
||||
|
||||
|
||||
int SDF_Hdropen(const char *name){
|
||||
fp = MPMY_Fopen(name, MPMY_RDONLY|MPMY_SINGL);
|
||||
if( fp == NULL )
|
||||
return -1;
|
||||
endbuf = ptr = buf;
|
||||
buf_offset = 0;
|
||||
Msg("SDF", ("SDFhdropen: return fp=%p\n", fp));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SDF_Hdrclose(void){
|
||||
Msg("SDF", ("SDFhdrclose called\n"));
|
||||
MPMY_Fclose(fp);
|
||||
endbuf = ptr = NULL;
|
||||
fp = NULL;
|
||||
buf_offset = -1;
|
||||
}
|
||||
|
||||
int SDF_Hdroffset(void){
|
||||
if( ptr == NULL )
|
||||
return -1;
|
||||
return buf_offset + (ptr - buf);
|
||||
}
|
||||
|
||||
int SDF_Hdrgetc(){
|
||||
int nread;
|
||||
|
||||
if( ptr == NULL ){
|
||||
Msgf(("SDFhdrgetc: Returning EOF, ptr==NULL\n"));
|
||||
return EOF;
|
||||
}
|
||||
|
||||
if( ptr < endbuf ){
|
||||
if( *ptr == '\0' ){
|
||||
SinglWarning("Returning NULL at char %d in SDFhdrio\n", (int)(ptr-buf));
|
||||
}
|
||||
Msgf(("SDF_hdrgetc: %c\n", *ptr));
|
||||
return *ptr++;
|
||||
}
|
||||
|
||||
nread = MPMY_Fread(buf, 1, MYBUFSZ, fp);
|
||||
{int i;
|
||||
int sum = 0;
|
||||
for(i=0; i<nread; i++){
|
||||
sum ^= buf[i];
|
||||
}
|
||||
Msgf(("SDFhdrio Fread(%d), obtained %d, sum=%d\n", MYBUFSZ, nread, sum));
|
||||
}
|
||||
if(nread <= 0 ) {
|
||||
if( nread < 0 ){
|
||||
SinglWarning("SDFhdrio: MPMY_Fread returns %d, errno=%d\n", nread, errno);
|
||||
}
|
||||
Msgf(("SDFhdrgetc: Returning EOF, nread=%d, errno=%d\n", nread, errno));
|
||||
return EOF; /* don't distinguish between error and EOF? */
|
||||
}
|
||||
buf_offset += endbuf - buf;
|
||||
ptr = buf;
|
||||
endbuf = ptr + nread;
|
||||
/* This tail recursion is guaranteed to terminate on the second try
|
||||
because we have guaranteed that endbuf>ptr */
|
||||
return SDF_Hdrgetc();
|
||||
}
|
||||
|
54
external/libsdf/libSDF/dictionary
vendored
Normal file
54
external/libsdf/libSDF/dictionary
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
This is a dictionary of "known" names in nbody files.
|
||||
It will be extended as the need arises.
|
||||
|
||||
The first few come from the headers:
|
||||
|
||||
float npart
|
||||
float iter
|
||||
float time
|
||||
float ke
|
||||
float pe
|
||||
float masstot
|
||||
float l_ang
|
||||
float Gnewt
|
||||
float epsilon
|
||||
float zinitial
|
||||
float omega
|
||||
float hubble
|
||||
float box_size
|
||||
float znow
|
||||
float initial_rsize
|
||||
float initial_rmin_x
|
||||
float initial_rmin_y
|
||||
float initial_rmin_z
|
||||
float veltime
|
||||
float sizeof_ext
|
||||
float alpha
|
||||
float beta
|
||||
float curvature
|
||||
float lambda
|
||||
float cosm_integral
|
||||
float radius
|
||||
int int_npart
|
||||
int int_sizeof_ext
|
||||
char tree_header_text[384];
|
||||
|
||||
The following arrays are of length (int)nbody. Unfortunately,
|
||||
in order to maintain historical compatibilty, the length of the
|
||||
array is stored as a binary float in the files, so consider using
|
||||
nbio_rd_double(..., "nbody") to figure out how long these vectors are.
|
||||
|
||||
float x[], y[], z[]
|
||||
float vx[], vy[], vz[]
|
||||
float mass[]
|
||||
|
||||
From the msw .ap files, we also have
|
||||
float acc[]
|
||||
float phi[]
|
||||
|
||||
Presumably, we should also reserve:
|
||||
float ax[], ay[], az[]
|
||||
|
||||
The char id[][4] is specified by tree and tree_ap files.
|
||||
|
||||
There will undoubtedly be others.
|
35
external/libsdf/libSDF/stdio.h
vendored
Normal file
35
external/libsdf/libSDF/stdio.h
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* This file is a replacement for the few parts of stdio.h */
|
||||
/* that are assumed by the output of lex and yacc. */
|
||||
/* It is here because lex's output contains #include "stdio.h" */
|
||||
/* and we don't want to be contaminated by the system stdio.h */
|
||||
|
||||
#ifndef MYSTDIOdotH
|
||||
#define MYSTDIOdotH
|
||||
#include "mpmy_io.h"
|
||||
|
||||
/* These are replacements for stdio */
|
||||
#undef getc
|
||||
#define getc(fp) SDF_Hdrgetc()
|
||||
/* Putc is used by 'output'. This is the easiest way to deal with it */
|
||||
#undef putc
|
||||
#define putc(c, fp) (Msg_do("%c", c))
|
||||
#undef FILE
|
||||
#define FILE MPMYFile
|
||||
#undef stdin
|
||||
#define stdin NULL
|
||||
#undef stdout
|
||||
#define stdout NULL
|
||||
#undef stderr
|
||||
#define stderr NULL
|
||||
#undef EOF
|
||||
#define EOF (-1)
|
||||
#undef BUFSIZ
|
||||
#define BUFSIZ 512
|
||||
|
||||
/* A couple of prototypes that are in stdio are also needed */
|
||||
#include <stdarg.h>
|
||||
int sscanf(const char *, const char *, ...);
|
||||
int vsprintf(char *, const char *, va_list);
|
||||
int sprintf(char *, const char *, ...);
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue