[M3devel] INTEGER
Jay K
jay.krell at cornell.edu
Mon Apr 19 23:25:48 CEST 2010
> If we were to revert, I have no idea what the implications would be. Jay?
I'm sure we could cope.
Besides, we'd put in a library-based solution anyway?
That the compiler inlines?
Like atomics?
Let me suggest a small exercise though:
I'm not going to do it.
Write a program that copies files. Or just one file. "cp.exe".
Have it print "progress feedback" to the user -- how many bytes and percentage copied. Leave out "time estimation".
And also write "ls.exe".
And maybe one last program, like "dos2unix.exe" or "fix_nl.exe" that alters newlines. This program should work on files that don't fit in memory.
That is, get some experience working with files that don't fit in memory/address space. But also for which lots memory/address space really aren't needed.
Also think about what an idea representation of time is.
Isn't a 64bit integer number of units smaller than a second a very good one?
And aren't infix operators darned nice?
- Jay
From: hosking at cs.purdue.edu
Date: Mon, 19 Apr 2010 14:44:00 -0400
To: mika at async.async.caltech.edu
CC: m3devel at elegosoft.com
Subject: Re: [M3devel] INTEGER
On 19 Apr 2010, at 13:23, Mika Nystrom wrote:
Well *my* problem is that I still use PM3 for a lot of things. Trying to
switch to CM3, yes, but I can't "certify" CM3 for critical stuff yet.
So I'm maintaining a significant amount of code that needs to compile
under both PM3 and CM3. Two problems crop up.
1. If there are bugs in m3tk/stubgen, the fixes only apply to one or
the other version of m3tk/stubgen.
2. Some of the code I'm maintaining processes Modula-3 code as input.
It needs to be in two versions.
In this kind of environment, programming languages don't really
evolve, since the system depends on their being both forward- and
backward-compatible. They "change" is more correct. The way Java
changes.
Indeed: Growing a Language, by Guy Steele
More in general, though, Modula-3's designers were clearly well acquainted
with C, Fortran, and other languages that provide different-range
integers. They chose not to indulge. I even have a version of Modula-3
for a 16-bit machine that doesn't do it, even though on this machine the
need for a 32-bit integer is arguably greater than the need for 64-bit
integers on 32-bit machines. Now we indulge in this language complication
to solve what is clearly a temporary problem, since anyone who cares
about large problems is going to have 64-bit systems yesterday... and
meanwhile no one seems to have availed himself of the solution!
If we were to revert, I have no idea what the implications would be. Jay?
My worst fear is that once the process gets started, the reason for
staying with the original Green-Book specification has now been defeated
and we will see more and more "evolution". Trying to actually build
systems that process Modula-3 like data becomes, at that point, like
trying to stand in quicksand.
Indeed!
I'm not incredibly picky here... I just hope it doesn't go further.
I would personally support either sticking with the current status quo
or going back to the Green Book w.r.t. integers and characters.
Indeed, I would not want to see this go any further. I am still not sure I am comfortable with the LONGINT extension (even though I put a lot of time into it). There just seemed to be a lot of pressure for it to so CM3 could handle large file indexes. I've never been convinced that WIDECHAR was a winner either -- it was a reflexive action in the face of Java's Unicode. The CM3 people were building a Java VM above CM3 at the time.
Saying that EWD wasn't renowned for his practicality is something he
would have taken as a great compliment, I'm sure.
;-)
Mika
Tony Hosking writes:
Mika,
First off, I'd be very interested to know what the issues are with =
LONGINT and stubgen. We are building that every day in regression =
testing. It would be really good to get some precise feedback.
True, LONGINT is integrated with all of the language tools (same as =
WIDECHAR).
I suppose that is the price we pay for the language having evolved. =
Nevertheless, CM3 should be totally backward compatible with the green =
book. There is no reason it should not build packages from PM3 or SRC.
Now, this is not to say that perhaps we haven't overreached with LONGINT =
given that 64-bit is more prevalent. But then it is also useful to be =
able to interoperate with C libraries. The previous interfacing was =
pretty much a kludge, using ARRAY[0..1] OF INTEGER for "long long" but =
then not propagating the double INTEGER value properly throughout the =
Modula-3 libraries.
I'm sorry to say that EWD was not particularly renowned for his =
practicality; pedant more like. Nice to be high and mighty but we also =
need to interact with the real world.
We should be able to make this work. Is there a better alternative? =
Revoke LONGINT, and WIDECHAR?
On 18 Apr 2010, at 15:59, Mika Nystrom wrote:
=20
My problem is really just that it's ugly. LONGx is showing up as an =
issue
in all sorts of low-level code, which is not surprising since Modula-3
with LONGx is not the same language as Modula-3 (maybe we should call
it Modula-3+?)=20
=20
The compiler bootstrapping process has gotten more complicated due to =
it,
and when I cvs updated m3tk yesterday stubgen wouldn't compile because =
there
was something "long" in it that wasn't there before. I have no idea =
what
library or components I needed to update and recompile and didn't have =
the
time to deal with the issue at the time.
=20
And the new m3tk, stubgen, and compiler(?) won't compile using PM3 or
SRC M3 since we're no longer using the language of the Green Book.
(Same comment goes for WIDECHAR, by the way.)
=20
One of the wonderful things about Modula-3 *used to be* that I could
grab some old package from DECSRC and just use it without changes =
since
no one had messed with the language definition. This is still true as
far as programs that just use the tools go, but it's no longer true =
for
programs that process Modula-3 code as input data. Of which there are
more than a few: many aspects of Modula-3 were specifically designed =
to
make the language easy to process by program, as an intermediate =
format
and whatnot.
=20
To quote E.W.D.:
=20
'Unfathomed misunderstanding is further revealed by the term "software
maintenance", as a result of which many people continue to believe =
that
programs and even programming languages themselves are subject to wear
and tear. Your car needs maintenance too, doesn't it? Famous is the =
story
of the oil company that believed that its PASCAL programs did not last
as long as its FORTRAN programs "because PASCAL was not maintained".'
=20
LONGx is causing me to have to do "software maintenance" on Modula-3
programs... for a feature that no one appears to be using and is =
quickly
becoming irrelevant.
=20
Mika
=20
=20
Tony Hosking writes:
In the language spec NUMBER(a) and LAST(a) - FIRST(a) + 1 are *not* =3D=
defined to mean the same thing for all types.
NUMBER does have an INTEGER value, as expected for subranges of =
LONGINT =3D
that are not too large.
This is as it has always been for subranges of INTEGER that are not =
too =3D
large.
=20
Mika, I'm not sure I see any of the problems you are worrying about =
in =3D
the current definition of LONGINT/LONGCARD.
=20
On 18 Apr 2010, at 03:49, Mika Nystrom wrote:
=20
=3D20
Jay I know most of this, and it doesn't really answer the question
"what is it for?"
=3D20
I think we've already established that LONGINT isn't useful for =3D
counting
anything that might actually reside in the computer's memory: it =
makes
no sense as an array index, for instance. INTEGER suffices for =
that.
=3D20
I thought that the only real reason for LONGINT was to match C's
declaration of various seek-related routines on 32-bit machines.
That's not a very good reason.
=3D20
C++ succeeds because it does very well in the area(s) it is good at.
People who want to program in C++ will clearly program in C++, not
Modula-3. Modula-3 is never, ever going to be the language of =
choice =3D
for
people who want lots of snazzy infix operators. Modula-3 is =
supposed =3D
to
be a language with about as powerful semantics as C++ and an =
extremely
simple syntax and definition---snazzy infix is one of the things you
give up for that. I don't see how LONGINT fits into this picture.
Now we have LONGCARD too? And it's infected the definitions
of FIRST and LAST? But not NUMBER... argh!
=3D20
so,
=3D20
NUMBER(a) and LAST(a) - FIRST(a) + 1
=3D20
no longer mean the same thing? Are we going to see lots of comments
in generics in the future where it says T may not be an open array
type nor an array type indexed on LONGINT or a subrange thereof?
=3D20
Your comments about different parameter-passing techniques was what =
I =3D
was
trying to address with my suggestion to have a pragma for =
this---just =3D
to
match C (and Fortran?), of course. Name me a single Modula-3 =3D
programmer
who cares in what order the bits in his parameters are pushed on the
stack in a Modula-3-to-Modula-3 call.
=3D20
And I am definitely in that school of thought that says that =3D
programming
languages should not "evolve". Better to leave well enough alone.
=3D20
How much Modula-3 code has been written that uses LONGINT? Other =
than
to talk to C? I've certainly never used it.
=3D20
Mika
=3D20
=3D20
=3D20
Jay K writes:
--_264cb69b-0215-44c3-807c-8b4d8ea0ea59_
Content-Type: text/plain; charset=3D3D"iso-8859-1"
Content-Transfer-Encoding: quoted-printable
=3D20
=3D20
TYPE LONGINT =3D3D3D ARRAY [0..1] OF INTEGER on a 32bit system is =
very =3D
close to=3D3D
LONGINT.
=3D20
Plus treating it opaquely and providing a bunch of functions to =3D
operate on=3D3D
it.
=3D20
Just as well therefore could be RECORD hi=3D3D2Clo:LONGINT END (see =
=3D
LARGE_INTE=3D3D
GER and ULARGE_INTEGER in winnt.h)
=3D20
=3D3D20
=3D20
Differences that come to mind:
=3D20
infix operators <=3D3D3D=3D3D3D=3D3D3D=3D3D20
=3D20
possibly passed differently as a parameter
=3D20
or returned differently as a result
=3D20
ie. probably "directly compatible with" "long long"=3D3D2C passed =
by =3D
value (o=3D3D
f course you could always pass by pointer and achieve =
compatibilitity =3D
trivi=3D3D
ally)
=3D20
=3D3D20
=3D20
=3D3D20
=3D20
I have to say though=3D3D2C the biggest reason is in-fix operators. =
=3D
Convenient =3D3D
syntax.
=3D20
C++ is the best and some way worst of example of the general right =
=3D
way to d=3D3D
o this -- you let programmers define types and their infix =
operators. =3D
Other=3D3D
languages just come with a passle of special cases of types that =
have =3D
in-f=3D3D
ix operators.
=3D20
A good example is that Java infix operator + on string=3D3D2C =
besides =3D
the vario=3D3D
us integers=3D3D2C and nothing else.
=3D20
=3D3D20
=3D20
=3D3D20
=3D20
I think C# lets you define operators=3D3D2C yet people don't =
complain =3D
that it i=3D3D
s "a mess" as they do of C++.
=3D20
I think Python does now too.
=3D20
So it is feature growing in popularity among "mainstream" =3D
languages=3D3D2C not =3D3D
just C++.
=3D20
C++ of course is extremely mainstream=3D3D2C but also a favorite =3D
target. (ht=3D3D
tp://www.relisoft.com/tools/CppCritic.html)
=3D20
=3D3D20
=3D20
=3D3D20
=3D20
We also have subranges of LONGINT.
=3D20
I'm not sure what the generalization of subranges are=3D3D2C =
granted.
=3D20
Maybe some sort of C++ template that takes constants in the =
template =3D
and d=3D3D
oes range checks at runtime. Yeah=3D3D2C maybe.
=3D20
=3D3D20
=3D20
=3D3D20
=3D20
And as you point out=3D3D2C convenient literal syntax.
=3D20
=3D3D20
=3D20
=3D3D20
=3D20
People reasonably argue for library extension in place of language =
=3D
extensio=3D3D
n=3D3D2C but that requires a language which is flexible enough to =
write =3D
librari=3D3D
es with the desired interface=3D3D2C and so many languages don't =
let =3D
infix oper=3D3D
ators be in a user-written library.
=3D20
(There is a subtle but useless distinction here -- infix operators =
=3D
being in=3D3D
libraries vs. "user-written" libraries. The infix set operations =
for =3D
examp=3D3D
le are in a library=3D3D2C but not user-written=3D3D2C special=3D3D2C=
the =3D
compiler know=3D3D
s about it.)
=3D20
=3D3D20
=3D20
that would perhaps not match how C handles "long long" on the same
platform (which is how=3D3D2C come to think of it?)=3D3D2C and =
that =3D
would require
=3D20
=3D20
=3D3D20
=3D20
On NT/x86=3D3D2C __int64/long long is returned in the register pair =
=3D
edx:eax.
=3D20
edx is high=3D3D2C eax is low.
=3D20
When passed as a parameter to __stdcall or __cdecl is just passed =
as =3D
two 32=3D3D
bit values adjacent on the stack=3D3D2C "hi=3D3D2C lo=3D3D2C =
hi=3D3D2C lo=3D3D2C =3D
it's off to pu=3D3D
sh we go" is the Snow White-influenced mantra to remember how to =
pass =3D
them=3D3D
=3D3D2C at least on little endian stack-growing-down machines =
(which =3D
includes x=3D3D
86). For __fastcall I'm not sure they are passed in registers or on =
=3D
the sta=3D3D
ck.
=3D20
Passing and/or returning small structs also has special efficient =3D=
handling =3D3D
in the ABI=3D3D2C so __int64 really might be equivalent to a small =
=3D
record. Not =3D3D
that cm3 necessarily implements that "correctly" -- for interop =
with =3D
C=3D3D3B =3D3D
for Modula-3 calling Modula-3 we can make up our own ABI so there =3D=
isn't rea=3D3D
lly an "incorrect" way. Notice the mingw problem I had passing a =3D
Win32 poin=3D3D
t struct by value=3D3D2C I cheated and passed it by VAR to a C =
wrapper =3D
to worka=3D3D
round the gcc backend bug (which was mentioned a few times and =
which =3D
I look=3D3D
ed into the code for=3D3D2C but took the easy route)
=3D20
=3D3D20
=3D20
=3D3D20
=3D20
I don't know how long long works on other platforms but probably =3D
similar.
=3D20
Probably a certain register pair for return values.
=3D20
=3D3D20
=3D20
- Jay
=3D20
=3D3D20
To: hosking at cs.purdue.edu
Date: Sat=3D3D2C 17 Apr 2010 19:47:03 -0700
From: mika at async.async.caltech.edu
CC: m3devel at elegosoft.com
Subject: Re: [M3devel] INTEGER
=3D3D20
Tony Hosking writes:
=3D20
...
=3D20
We need it to match 64-bit integers on 32-bit machines? That =
seems =3D
=3D3D3D
like
a very weak rationale indeed=3D3D2C if the same functionality =
could =3D
be =3D3D3D
provided
through some other mechanism (e.g.=3D3D2C ARRAY [0..1] OF =3D
INTEGER---even =3D3D
=3D3D3D
with
a pragma e.g. <*CLONGLONG*>.. if it is necessary to tell the =3D
compiler =3D3D
=3D3D3D
that
a special linkage convention is needed).
=3D20
There's no special linkage convention. Not sure what you mean =
here.
=3D20
=3D3D20
I just mean if we had
=3D3D20
TYPE LONGINT =3D3D3D ARRAY [0..1] OF INTEGER
=3D3D20
that would perhaps not match how C handles "long long" on the same
platform (which is how=3D3D2C come to think of it?)=3D3D2C and =
that =3D
would require
special linkage tricks.
=3D3D20
But what would be lost? The ability to type literals.=3D3D20
=3D3D20
You could get the same code interface on 32- and 64-bit machine by
defining
=3D3D20
TYPE FileOffset =3D3D3D ARRAY[0..1] OF [-16_80000000 .. =
+16_7fffffff ]
=3D3D20
and using that.
=3D3D20
=3D3D20
Mika
=3D3D
=3D20
--_264cb69b-0215-44c3-807c-8b4d8ea0ea59_
Content-Type: text/html; charset=3D3D"iso-8859-1"
Content-Transfer-Encoding: quoted-printable
=3D20
<html>
<head>
<style><!--
.hmmessage P
{
margin:0px=3D3D3B
padding:0px
}
body.hmmessage
{
font-size: 10pt=3D3D3B
font-family:Verdana
}
--></style>
</head>
<body class=3D3D3D'hmmessage'>
TYPE LONGINT =3D3D3D ARRAY [0..1] OF INTEGER on a =3D3D3B32bit =
system =3D
is very c=3D3D
lose to LONGINT.<BR>
 =3D3D3BPlus treating it opaquely and providing a bunch of =3D
functions to ope=3D3D
rate on it.<BR>
 =3D3D3BJust as well therefore could be RECORD =
hi=3D3D2Clo:LONGINT =3D
END (see LAR=3D3D
GE_INTEGER and ULARGE_INTEGER in winnt.h)<BR>
 =3D3D3B<BR>
Differences that come to mind:<BR>
 =3D3D3B =3D3D3Binfix operators =3D3D3B =
<=3D3D3B=3D3D3D=3D3D3D=3D3D3D =3D
<BR>
 =3D3D3B possibly passed differently =3D3D3Bas a =
parameter<BR>
 =3D3D3B or returned differently as a result<BR>
 =3D3D3B ie. probably "directly compatible with" "long =
long"=3D3D2C =3D
passed by v=3D3D
alue (of course you could always pass by pointer and achieve =3D
compatibilitit=3D3D
y trivially)<BR>
 =3D3D3B<BR>
 =3D3D3B<BR>
I have to say though=3D3D2C the biggest reason is in-fix operators. =
=3D
Convenient =3D3D
syntax.<BR>
C++ is the best and some way worst of example of the general right =
=3D
way to d=3D3D
o this -- you let programmers define types and their infix =
operators. =3D
Other=3D3D
languages just come with a passle of special cases of types that =
have =3D
in-f=3D3D
ix operators.<BR>
A good example is that Java infix operator + on string=3D3D2C =
besides =3D
the vario=3D3D
us integers=3D3D2C and nothing else.<BR>
 =3D3D3B<BR>
 =3D3D3B<BR>
I think C# lets you define operators=3D3D2C yet people don't =
complain =3D
that it i=3D3D
s "a mess" as they do of C++.<BR>
I think Python does now too.<BR>
So it is feature growing in popularity among "mainstream" =3D
languages=3D3D2C not =3D3D
just C++.<BR>
 =3D3D3B =3D3D3B C++ of course is extremely mainstream=3D3D2C=
but =3D
also a favori=3D3D
te target. (<A =3D
href=3D3D3D"http://www.relisoft.com/tools/CppCritic.html">http:/=3D3D
/www.relisoft.com/tools/CppCritic.html</A>)<BR>
 =3D3D3B<BR>
 =3D3D3B<BR>
We also have subranges of LONGINT.<BR>
I'm not sure what the generalization of subranges are=3D3D2C =3D
granted.<BR>
 =3D3D3BMaybe some sort of C++ template that takes constants in =
the =3D
templat=3D3D
e and does range checks at runtime. Yeah=3D3D2C maybe.<BR>
 =3D3D3B<BR>
 =3D3D3B<BR>
And as you point out=3D3D2C convenient literal syntax.<BR>
 =3D3D3B<BR>
 =3D3D3B<BR>
People reasonably argue for library extension in place of language =
=3D
extensio=3D3D
n=3D3D2C but that requires a language which is flexible enough to =
write =3D
librari=3D3D
es with the desired interface=3D3D2C and so many languages don't =
let =3D
infix oper=3D3D
ators be in a user-written library.<BR>
(There is a subtle but useless distinction here -- infix operators =
=3D
being in=3D3D
libraries vs. "user-written" libraries. The infix set operations =
for =3D
examp=3D3D
le are in a library=3D3D2C but not user-written=3D3D2C special=3D3D2C=
the =3D
compiler know=3D3D
s about it.)<BR>
 =3D3D3B<BR>
>=3D3D3B that would perhaps not match how C handles "long long" =
on =3D
the same<B=3D3D
R>>=3D3D3B platform (which is how=3D3D2C come to think of =
it?)=3D3D2C and =3D
that would =3D3D
require<BR><BR>
 =3D3D3B<BR>
On NT/x86=3D3D2C __int64/long long is returned in the register pair =
=3D
edx:eax.<BR=3D3D
=3D20
edx is high=3D3D2C eax is low.<BR>
When passed as a parameter to __stdcall or __cdecl is just passed =
as =3D
two 32=3D3D
bit values adjacent on the stack=3D3D2C "hi=3D3D2C lo=3D3D2C =
hi=3D3D2C lo=3D3D2C =3D
it's off to pu=3D3D
sh we go" is the Snow White-influenced mantra to remember how to =
pass =3D
them=3D3D
=3D3D2C at least on little endian stack-growing-down machines =
(which =3D
includes x=3D3D
86). For __fastcall I'm not sure they are passed in registers or on =
=3D
the sta=3D3D
ck.<BR>
Passing and/or returning small structs also has special efficient =3D=
handling =3D3D
in the ABI=3D3D2C so __int64 really might be equivalent to a small =
=3D
record. Not =3D3D
that cm3 necessarily implements that "correctly" =3D3D3B -- for =
=3D
interop wit=3D3D
h C=3D3D3B for Modula-3 calling Modula-3 we can make up our own ABI =
so =3D
there is=3D3D
n't =3D3D3Breally an "incorrect" way. =3D3D3BNotice the =
mingw =3D
problem I had=3D3D
passing a Win32 point struct by value=3D3D2C I cheated and passed =
it by =3D
VAR to=3D3D
a =3D3D3BC wrapper to workaround the gcc backend bug (which was =
=3D
mentioned =3D3D
a few times and which I looked into the code for=3D3D2C but took =
the =3D
easy route=3D3D
)<BR>
 =3D3D3B<BR>
 =3D3D3B<BR>
I don't know how long long works on other platforms but probably =3D
similar.<B=3D3D
R>
Probably a certain register pair for return values.<BR>
 =3D3D3B<BR>
 =3D3D3B- Jay<BR><BR> =3D3D3B<BR>>=3D3D3B To: =3D
hosking at cs.purdue.edu<BR>>=3D3D3B=3D3D
Date: Sat=3D3D2C 17 Apr 2010 19:47:03 -0700<BR>>=3D3D3B From: =3D
mika at async.async.c=3D3D
altech.edu<BR>>=3D3D3B CC: m3devel at elegosoft.com<BR>>=3D3D3B =
Subject: =3D
Re: [M3de=3D3D
vel] INTEGER<BR>>=3D3D3B <BR>>=3D3D3B Tony Hosking =
writes:<BR>>=3D3D3B =3D
>=3D3D3B<BR>=3D3D
>=3D3D3B ...<BR>>=3D3D3B >=3D3D3B<BR>>=3D3D3B =
>=3D3D3B>=3D3D3B We =3D
need it to match 64-b=3D3D
it integers on 32-bit machines? That seems =3D3D3D<BR>>=3D3D3B =3D
>=3D3D3Blike<BR>>=3D3D
=3D3D3B >=3D3D3B>=3D3D3B a very weak rationale indeed=3D3D2C if =
the same =3D
functionality =3D3D
could be =3D3D3D<BR>>=3D3D3B >=3D3D3Bprovided<BR>>=3D3D3B =
>=3D3D3B>=3D3D3=3D
B through some o=3D3D
ther mechanism (e.g.=3D3D2C ARRAY [0..1] OF INTEGER---even =3D
=3D3D3D<BR>>=3D3D3B >=3D3D3B=3D3D
with<BR>>=3D3D3B >=3D3D3B>=3D3D3B a pragma e.g. =3D
<=3D3D3B*CLONGLONG*>=3D3D3B.. if it i=3D3D
s necessary to tell the compiler =3D3D3D<BR>>=3D3D3B =3D
>=3D3D3Bthat<BR>>=3D3D3B >=3D3D3B&=3D3D
gt=3D3D3B a special linkage convention is needed).<BR>>=3D3D3B =3D
>=3D3D3B<BR>>=3D3D3B &=3D3D
gt=3D3D3BThere's no special linkage convention. Not sure what you =
mean =3D
here.<BR=3D3D
>=3D3D3B >=3D3D3B<BR>>=3D3D3B <BR>>=3D3D3B I just mean if =
we =3D
had<BR>>=3D3D3B <BR>>=3D3D
=3D3D3B TYPE LONGINT =3D3D3D ARRAY [0..1] OF INTEGER<BR>>=3D3D3B =
=3D
<BR>>=3D3D3B that woul=3D3D
d perhaps not match how C handles "long long" on the =
same<BR>>=3D3D3B =3D
platfor=3D3D
m (which is how=3D3D2C come to think of it?)=3D3D2C and that would =
=3D
require<BR>>=3D3D
=3D3D3B special linkage tricks.<BR>>=3D3D3B <BR>>=3D3D3B But =
what would =3D
be lost? Th=3D3D
e ability to type literals. <BR>>=3D3D3B <BR>>=3D3D3B You could =
get =3D
the same co=3D3D
de interface on 32- and 64-bit machine by<BR>>=3D3D3B =3D
defining<BR>>=3D3D3B <BR>=3D3D
>=3D3D3B TYPE FileOffset =3D3D3D ARRAY[0..1] OF [-16_80000000 .. =
=3D
+16_7fffffff ]<B=3D3D
R>>=3D3D3B <BR>>=3D3D3B and using that.<BR>>=3D3D3B =
<BR>>=3D3D3B =3D
<BR>>=3D3D3B Mika<BR=3D3D
</body>
</html>=3D3D
=3D20
--_264cb69b-0215-44c3-807c-8b4d8ea0ea59_--
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20100419/6388accd/attachment-0002.html>
More information about the M3devel
mailing list