From: Axel Kohlmeyer (
Date: Tue Jun 16 2009 - 07:31:03 CDT

On Tue, 2009-06-16 at 01:27 -0700, Rob wrote:
> Axel Kohlmeyer wrote:
> >
> > - if you use strtok(), you cannot flag your code as re-entrant.
> > strtok() uses a global static storage. if there is an easy way
> > to avoid it, i'd encourage you to do so. unfortunately, this is
> > not always the case (since strtok is convenient, we may be forced
> > to provide a portable and thread-safe work-alike for molfile).
> OK; I'll look into this. I'll try to replace it by something else;
> The "sscanf(string, " %d %d", &i, &k)" does not have this problem,
> or does it?

not as such. it is all about static memory allocation. so
if you would allocate "string" statically, it would become
non-reentrant. it doesn't matter much, since at the moment
no plugin is called from threads, but that may change in
the future and we decided to play it safe. ;-)

> By the way, the vasp plugins have the same problem here
> (I used those to help me design the abinit plugin....).

exactly. you told me that you would and this is how i know
that there could be a problem. the vasp plugins are already
adjusted in the cvs.

> > which compiler do you use for ABINIT?
> >
> > as far as i can tell, your code does not seem to be compatible
> > with big-endian files and 64-bit record-length markers.
> > if you compile ABINIT with gfortran, you should be able to emulate
> > this via setting the GFORTRAN_CONVERT_UNIT environment variable
> > or using the -fconvert compile option and using the
> > -frecord-marker=<length> option, respectively.
> I use gfortran indeed.
> Should I then use "-fconvert=big-endian -frecord-marker=8" and then
> design the plugin to be able to read those files?

at least for big/little endian it would be more convenient to use
the existing abinit executable and just the environment variable.
if you use intel compilers, please check the documentation, they
have similar options.

> Is it possible to find out directly from the binary file whether it's big/little
> endian? (probably not....).
> The gfortran manual says that the default length is 4, but it used to be 8
> with older gfortran versions....

right. it is easy to find out which is which, if you know that the first
fortran unformatted WRITE() statement is of a fixed or similar size.
check out the dcdplugin code. in .dcd files the first record is exactly
84 bytes and the first entry is a string 'CORD', so the first 4 or 8
bytes should be the integer number 84 followed by 'C' 'O' 'R' 'D'.
if you look at a binary file in a hex viewer, you can check it out
easily. if the file was written with 4-byte record markers on a little
endian machine (x86/x86_64 PC, alpha) you would see:
54 00 00 00 43 4f 52 44

with 8-byte record markers it would be:
54 00 00 00 00 00 00 00 43 4f 52 44

on a big-endian machine with 4-byte record markers.
00 00 00 54 43 4f 52 44

and with 8-byte markers accordingly
00 00 00 00 00 00 00 54 43 4f 52 44

so you see the position of the string and
the location of the non-zero byte allows to determine
the record marker size and endianness.


> Rob.

Axel Kohlmeyer
   Center for Molecular Modeling   --   University of Pennsylvania
Department of Chemistry, 231 S.34th Street, Philadelphia, PA 19104-6323
tel: 1-215-898-1582,  fax: 1-215-573-6233,  office-tel: 1-215-898-5425
If you make something idiot-proof, the universe creates a better idiot.