Imported libSDF into VOID tree

This commit is contained in:
Guilhem Lavaux 2013-02-27 13:27:23 -05:00
parent c6dd08bd7d
commit 2d09cb68df
55 changed files with 12667 additions and 0 deletions

313
external/libsdf/libSDF/ChangeLog.14 vendored Normal file
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

139
external/libsdf/libSDF/SDF-lex.l vendored Normal file
View 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

File diff suppressed because it is too large Load diff

754
external/libsdf/libSDF/SDF-parse.y vendored Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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