Re: Segmentation fault on closing file in destructor

2010-09-28 Thread Tom Kazimiers
Hi Jérôme,

On 09/26/2010 10:59 PM, Jérôme M. Berger wrote:
   The way I see it, there are two possible situations:
 
 1. You really need precise control as to when the file is closed. In
 that case, your class contains an explicit cleanup function that you
 call before dropping the last reference and you can close the file
 at that time;
 
 2. You only need to be sure that the file gets closed at some point
 but it doesn't really signify when. In that case, you let the GC
 collect your class and you don't close the file. Eventually the GC
 will collect the std.stream.File instance which will result in
 calling its destructor which will close the file without your
 needing to do anything about it.

That are probably the two choices I have, yes. I already have such a
cleanup function and will probably go for that.

Thanks,
Tom


Re: Segmentation fault on closing file in destructor

2010-09-28 Thread Tom Kazimiers
Hi,

On 09/26/2010 10:05 PM, Simen kjaeraas wrote:
 Can you use scope(exit) or the std.stdio.File?

 Well, I have no idea. You mentioning scope(exit) was actually the first
 time I heard of it. Unfortunately I have not found any resource about
 it. Do you have a link to point me in the right direction?
 
 http://digitalmars.com/d/2.0/statement.html#ScopeGuardStatement

thanks, strange I did not find that page by searching. Good to know
about that concept, but I guess it is not fitting as a solution here. My
scope is the from creation to destrution of the class, so this will no
be working. But anyway, thanks.

Tom


Re: Segmentation fault on closing file in destructor

2010-09-28 Thread Tom Kazimiers
Hi,

On 09/27/2010 02:09 PM, Steven Schveighoffer wrote:
 On Sun, 26 Sep 2010 20:20:18 -0400, Michel Fortin
 In fact, it's generally a good idea to not wait for the GC to collect
 your objects before closing files, because waiting for the GC could
 take an indeterminate amount of time and leave files open for a long
 time (the GC only runs when needed).
 
 Yes, this is true no matter what File construct you use.

I'll keep that in mind and will go for a cleanup method that I have to
call explicitely. Especially files should probably only be opened if in
use or if one wants to prevent others from using it.

Cheers,
Tom


Segmentation fault on closing file in destructor

2010-09-26 Thread Tom Kazimiers
Hi,

a file reading class of mine can be constructed with a filename as
parameter. It instantiates a new std.stream.File (without the passed
file name and closes it when opened within the destructor. The last part
is where things are getting unclear for me. On the file.isOpen() call
in the destructor a segmentation fault occurs. What is the problem with
that?

Thanks in advance,
Tom

An example class to demonstrate the problem:

import std.stdio;
import std.string;
import std.stream;

class FileReader(T) {
string  filename; // the name of the object file
std.stream.File file; // the object file

  public:
this(string filename) {
// make an immutable copy of the filename
this.filename = filename.idup;
file = new std.stream.File();
}

// destructor
~this() {
if(file.isOpen())  //  crashes here
writefln(open);
}

// open file, return true if successful
bool open() {
try {
file = new std.stream.File(filename, FileMode.In);
} catch(OpenException e) {
writefln([Error] Could not open file:  ~ filename);
return false;
}
return true;
}
}


Re: Segmentation fault on closing file in destructor

2010-09-26 Thread Tom Kazimiers
Hi,

On 09/26/2010 07:13 PM, bearophile wrote:
 Tom Kazimiers:
 
 Do you have any suggestion how I should make
 sure that the file gets closed on destruction?
 
 Can you use scope(exit) or the std.stdio.File?

Well, I have no idea. You mentioning scope(exit) was actually the first
time I heard of it. Unfortunately I have not found any resource about
it. Do you have a link to point me in the right direction?

If I would use std.stdio.File, what would be different?

Thanks,
Tom


Re: FIle I/O

2010-09-16 Thread Tom Kazimiers
Hi Graham,

On 09/16/2010 04:28 PM, Graham Nicholls wrote:
 I'm writing a program to take a file and convert it into a binary format which
 matches the format produced by a system which we use.  If I get it right, this
 will allow me to replay the file into the system.  However I can't find how
 to do I/O in D.  I've got the D Programming Language and Tango books, but
 not much there, and as a C/C++ programmer, Tango doesn't seem that appealing
 :-).  Is there a tutorial anywhere?

in case you did not find some example code yet:
http://www.dprogramming.com/FileTutorial.html

Regards,
Tom


Re: FIle I/O

2010-09-16 Thread Tom Kazimiers
Graham,

On 09/16/2010 05:02 PM, Graham Nicholls wrote:
 Is this D 1.0 ? I get errors regarding printf - I understood that writeln was 
 the
 2.0 way.

Yes, I think it's D 1.0. For a D 2.0 version I replaced those printf's
with writeln's, too.

Bye,
Tom


Convert strings with different format to float

2010-09-08 Thread Tom Kazimiers
Hi,

I try to read data in from a file. This data consist mainly of numbers
and I have a hard time converting it to number type variables. Two data
lines could look like this

v 0 0 0
v 1.5 1.2 0

Now I want to parse those lines and call a method, the line in passed
(as char[]) to it:

int index = indexOf(line, v );
if(index != -1) {
vc++;
float x = 0.0, y = 0.0, z = 0.0;
char[][] vertexCoords = split( line[index+2 .. $] );

if (vertexCoords.length  0)
x = to!int(vertexCoords[0]);
if (vertexCoords.length  1)
y = to!int(vertexCoords[1]);
if (vertexCoords.length  2)
z = to!int(vertexCoords[2]);

process_vertex(vc,x,y,z);
return;
}

First I split the remaining characters (after v ) into parts (here is
probably dynamic copying included?). Then I want to convert each part to
a float value.

The problem I have is that I obviously need to use to!int for numbers
with out decimal point and to!float for numbers with. But since those
can be mixed I would ask for every part if there is a decimal point, e.g:

if (vertexCoords.length  0) {
if (indexOf(vertexCoords[0], .) != -1)
x = to!float(vertexCoords[0]);
else
x = to!int(vertexCoords[0]);
}

Is there a more convient way to achieve that? I am coming from C++ and
IIRC one could do there sth. like this:

int index = line.find(v );
if(index != std::string::npos) {
line.erase(0,index+1);
vc++;
float x,y,z = 0;

std::istringstream ins;
ins.str(line);
ins  x  y  z;

process_vertex(vc,x,y,z);
return;
}

That looks much cleaner to me (besides the  operators). So I am
looking for sth. similar in D :-). Maybe a to!float that can cope with
numbers without decimal point.

Cheers,
Tom


Re: Convert strings with different format to float

2010-09-08 Thread Tom Kazimiers
Hi,

On 09/08/2010 10:02 AM, Stanislav Blinov wrote:
 I would have thought that to!float() could handle a number without a
 decimal point. If it can't I would suggest creating a bug report for
 it. Now, since such a fix would not help you immediately in either
 case, I would suggest creating a wrapper function which took a string
 and then used to!int() for numbers without decimal points and
 to!float() for number with them, and then returned a float. That way,
 you wouldn't have to keep worrying about it. Also, you could try
 parse(). It might be more forgiving.

 - Jonathan M Davis

 No it wouldn't :)
 It's indeed a bug, and it happens if string contains e.g. single 0
 (other digits are parsed normally). It seems that parse for floating
 points tries to determine if the number is in hex format, thus eating
 first 0, but it does not reuse this 0 later while it tries to pop next
 characters (and that results in assertion in std.array).

thanks for your answers. Indeed, it is a bug. As Don states no bug
report is needed, because it is fixed for a couple of weeks (in svn).

In the meantime (of waiting for upcoming release) I will, as Jonathan
suggested, create a wrapper function.

Cheers,
Tom


Re: Convert strings with different format to float

2010-09-08 Thread Tom Kazimiers
On 09/08/2010 06:58 PM, Stanislav Blinov wrote:
  08.09.2010 20:46, Tom Kazimiers wrote:
 Great! I am looking forward to that release :-). Any idea when it will
 be available?

 For the mean time I will, as proposed, make a separate function that
 checks if there is a dot in it or not. Then I take to!float and to!int,
 respectively.

 Cheers,
 Tom
 That won't really help against this bug: to!float(0.) will also
 trigger assertion. You probably should just check if string contains
 single 0.
 

Ah, thanks, I must have missed that!

Regards,
Tom


Re: Fast temporary dynamic arrays? (And slicing of them)

2010-09-07 Thread Tom Kazimiers
Hi,

thanks for your tests.

On 09/06/2010 04:59 AM, bearophile wrote:
 My first test shows that it may work. But I have to grow the array
 backwards, and push back the array start, because that's how my stack
 grows (using alloca to allocate geometrically bigger chunks). So
 unless you want to reverse the items once the array is built, you
 have to change the algorithm that uses the array a little.

Unfortunately I need the elements to stay in the order I have added
them. But good to know that it would work with backward growing of the
array - do have you an example of that?

Cheers,
Tom


Fast temporary dynamic arrays? (And slicing of them)

2010-09-05 Thread Tom Kazimiers
Hi all,

so I have started to look at D and dug through the documentation, but
could not get a good answer on the following:

How can I have a (temporary) dynamic array on stack and make references
to it (no copying)? I successively put integers in an array (but don't
know how much there will be in advance) with an appender!(int[]) and get
the date out with appender.data(). Later on I pass the result to a
method as an in int[] parameter. Is that already a reference or will
it be copied? Are there better methods to accomplish this? The method
receiving such an array will not modifiy contents of the array, but only
read from it.

Thanks in advance,
Tom

--

P.s. To put a bit of context around that, here some notes on what I am
working (some questions here as well, but above is the primary one):

My first try-out project in D is an Object file reader (often used in
computer graphics). Part of that is a parsing method which parses a
single line that contains a definition of a face (a polygon). It could
for instance look like this:

f 1//10 2//10 3//10

That means it is a triangle face of points 1, 2 and 3 (three groups,
first number is point index). Furthermore no texture coordinate index
(no number between two slashes) and each with normal vector index 10.
But I don't want to go into detail of that. Say I want to parse that
line with D and in the end call a method to process that face with
references to lists of the different point indices:

void process_face(int index, int vcount, in int[] vertices,
  in int[] texcoords = null, in int[] normals = null)
{
...
}

(I guess in means sth. like const reference)

The arrays should not be copied, but be references. The line parsing
method now has the following lines (line is a char[]):

//search face
int index = indexOf(line, f );
if(index != -1)
{
line = line[index+2 .. $];  // slice away the f  part
fc++; // increment face count

int slash;
while(true)
{
 slash = indexOf(line,  /);  // leading spaces + slashes?
 if(slash != -1)
 // remove space
 line = line[0 .. slash] ~ line[slash+1 .. $];
 else
 break;
}
while(true)
{
slash = indexOf(line, / );  // trailing spaces + slashes?
if(slash != -1)
// remove space 
line = line[0 .. slash+1] ~ line[slash+2 .. $];
else
break;
}

// dynamic vertex, texture and normal arrays
auto vIndices = appender!(int[])();
auto tIndices = appender!(int[])();
auto nIndices = appender!(int[])();

// some indices
int vi,ti,ni;

// split line on white spaces
char[][] vertexCoords = split( line );
// go through each part - are those splittings ok?
foreach(char[] coord; vertexCoords) {
vi = parse!(int)(coord); //get int from string
vIndices.put( vi ); // save it in vertex array
if (coord[0] == '/') { // follows a slash?
coord = coord[1 ..$]; // get rid of it
if (coord[0] == '/') { // follows another slash?
coord = coord[1 ..$]; // get rid of it
ni = parse!(int)( coord ); // git following int
nIndices.put( ni ); // save it in normal array
} else {
ti = parse!(int)( coord );
tIndices.put( ti );
if (coord[0] == '/') {
coord = coord[1 ..$];
int ni = parse!(int)( coord );
nIndices.put( ni );
}
}
}
}

// array references for passing to processing method
int[] varray = null, tarray = null, narray = null;

// if we have data, save it to appropriate varible
if( !(vIndices.data().empty()) )
varray = vIndices.data();

if( !(tIndices.data().empty()) )
tarray = tIndices.data();


if( !(nIndices.data().empty()) )
narray = nIndices.data();

// process it
process_face(fc, vIndices.data().length, varray, tarray, narray);

return;
}

I hope this rather lengthy explanation is no problem here (if looked on
it at all, since it was not my primary question :-) ). If you are in the
mood, please comment on how make parts on it better. It is pretty much
my first D code. Well, thanks.

Cheers
Tom