Search the web
Sign In
New User? Sign Up
smalleiffel
? Already a member? Sign in to Yahoo!

Yahoo! Groups Tips

Did you know...
Message search is now enhanced, find messages faster. Take it for a spin.

Best of Y! Groups

   Check them out and nominate your group.
Having problems with message search? Fill out this form to ensure your group is one of the first to be migrated to the new message search system.

Messages

  Messages Help
Advanced
Messages 4978 - 5007 of 5007   Newest  |  < Newer  |  Older >  |  Oldest
Messages: Show Message Summaries   (Group by Topic) Sort by Date v  
#5007 From: Uwe Sander <usander@...>
Date: Thu Jun 27, 2002 5:24 am
Subject: Re: SmallEiffel related projects
usander@...
Send Email Send Email
 
Hi,

a little late, but we have been busy ...

We have two SE based projects here at work:

- a Pervasive SQL2000 admin and query tool
- a company information system running against a Firebird database

Both projects are Open Source GUI applications and are based on our work for
the ELJ project. They are also meant as research projects if SE could be the
tool of our choice for the next revision of our large commercial application
called ImmoXpress. The only thing we are missing for that is dynamic class
loading.

BTW, after carefully checking the behaviour of the two apps, I finally found
that the reported 'bug' in the GC was simply my own fault, so please SE team,
accept my apologizes.


Regards

Uwe, team leader development Sykosch Software AG

#5006 From: Olivier Zendra <Olivier.Zendra@...>
Date: Wed Jun 26, 2002 5:25 pm
Subject: mail server maintenance / SE mailing list
Olivier.Zendra@...
Send Email Send Email
 
Hi all.

There's going to be some heavy maintenance on the LORIA mailserver, which hosts
this SmallEiffel mailing-list, on Thursday, June 27th.

So, expect delays, especially in the morning (Central European Summer Time, for
France). No email should be lost, we're told ;)

By the way, the mailing-list manager and archive
(http://wwsympa.loria.fr/wwsympa/arc/smalleiffel) should be faster, afterwards.
But how much faster, nobody really knows :))

Regards,

--
Olivier ZENDRA, Ph.D.                | INRIA Researcher - MIRÓ Team
INRIA Lorraine - LORIA,              | E-mail: Olivier.Zendra@...
615 Rue du Jardin Botanique, BP 101, | Phone:  (+33) 3.83.58.17.07
54602 VILLERS-LES-NANCY CEDEX,       | Fax:    (+33) 3.83.58.17.01
FRANCE                               | Web: http://www.loria.fr/~zendra

#5005 From: "Eddie Eyles" <eddie@...>
Date: Mon Jun 24, 2002 10:57 pm
Subject: short utility and obsolete clause
eddie@...
Send Email Send Email
 
Hi,

I'm a newcomer to Eiffel so please forgive me if this is a naive question.
I'm using Release -0.74 Beta #17 of SmallEiffel wrapped in ELJ-Win32 on
Windows 95.

When running the short utility, I see that it does not output the obsolete
clause of a class.  (e.g. for the blank feature of the STRING class.)  Would
this not be extremely useful to have in the output from short?  In an
environment where the short output is the only description of a class's
interface available to a programmer and the implementation is hidden, I
would have thought it was pretty essential.

FYI I've tried to trace where this would be implemented in the Eiffel source
for short, but got hopelessly lost!

Regards,
Eddie.
-----
Eddie Eyles
eddie@...
6 Devonshire Villas, Bath, BA2 4SX, United Kingdom
+44 (0)1225-48 03 71 (home)
+44 (0)7879-89 62 03 (mobile)
-----

#5004 From: Benedikt Grundmann <bgrundmann@...>
Date: Mon Jun 24, 2002 2:52 pm
Subject: FWD: [gclist] Ravenbrook open-sources the Memory Pool System Kit
bgrundmann@...
Send Email Send Email
 
Having the recent gc problems of the elj project and the quest for a gc
system for  SCOOP in mind I thing everybody
working on SmallEiffel or SCOOP should have a look at that.

Cheers,

Bene


>I saw this on the gclist mailing list. This is the very system used to
>build the Fun-O garbage collector, and some very familiar names have
>worked on it. Congratulations, guys!
>
>Nick Barnes writes:
> > I am pleased to announce that Ravenbrook Limited has released the
> > Memory Pool System Kit under an open source license.  The current
> > public release is 1.100.1, available from
> > <http://www.ravenbrook.com/project/mps/release/1.100.1/>.
> >
> > The Memory Pool System (MPS) is a very general, adaptable, flexible,
> > reliable, and efficient memory management system.  It permits the
> > flexible combination of memory management techniques, supporting
> > manual and automatic memory management, in-line allocation,
> > finalization, weakness, and multiple concurrent co-operating
> > incremental generational garbage collections.  It also includes a
> > library of memory pool classes implementing specialized memory
> > management policies.  It is suitable for use in language runtimes,
> > virtual machines, and applications.  It is designed from the ground up
> > to be portable to almost any platform and adaptable to almost any
> > client requirement.
> >
> > For a more detailed overview of the MPS, see "The Memory Pool System:
> > Thirty person-years of memory management development goes Open Source"
> > <http://www.ravenbrook.com/project/mps/doc/2002-01-30/ismm2002-paper/>.
> >
> > The Kit includes sources, a test suite, a partial reference manual and
> > a number of design documents.  We have only been able to include a few
> > dozen key documents in the current release.  We are working on
> > converting additional MPS documents, especially more design and
> > analysis, for inclusion in future releases.  There are a great number
> > of such documents.
> >
> > This release is under an open source license.  The license is intended
> > to make it possible for you to use the MPS in your own projects,
> > provided that any distribution of the resulting software is open
> > source.  If you are developing a closed source product and want to use
> > the MPS you must license under commercial terms from Ravenbrook
> > Limited.  Please write to us <mps-questions@...> for more
> > information.
> >
> > Ravenbrook <http://www.ravenbrook.com/> is a software engineering
> > consultancy founded in 1997 by Richard Brooksby and Nicholas Barnes,
> > previously members of the memory management group at Harlequin, where
> > the MPS was originally developed.  Richard Brooksby is the original
> > architect of the MPS.
> >
> > Nick Barnes
> > Director
> > Ravenbrook Limited
>
>--
>Neel Krishnaswami
>neelk@...

#5003 From: Berend de Boer <berend@...>
Date: Thu Jun 20, 2002 8:03 pm
Subject: Re: The Shootout benchmarks
berend@...
Send Email Send Email
 
Greg C <gmc444@...> writes:

> One of the interesting missing benchmarks is Echo, where a process creates
> a socket, opens one end, spawns a child that opens the other end, and then
> sends data between parent and child. I know there are a couple of socket
> bindings out there. Anyone interested in giving this one a shot?

eposix can do this easily, I'll take a look.

--
Live long and prosper,

Berend de Boer

#5002 From: Greg C <gmc444@...>
Date: Fri Jun 21, 2002 6:02 pm
Subject: Re: The Shootout benchmarks
gmc444@...
Send Email Send Email
 
--- Greg C <gmc444@...> wrote:
> I finally heard back from Aldo Calpini [dada@...] the gentleman
> running the The Great Win32 Computer Language Shootout.
> http://dada.perl.it/shootout/


In a fit of boredom while running tests, I implemented the Shootout
Regexmatch benchmark yesterday, using the ELJ version of the PCRE library.

That's the good news.

The bad news is that while goofing around in my code I found that the
following program will crash the SmallEiffel compiler, release version
-0.74, using the version of REGULAR_EXPRESSION mentioned above. I'm using
the recent ELJ-Win32 build.

class T1 creation make

feature
    my_re : STRING is once
          Result  := "(?:^[^\d\(]*)"      end

    re : expanded REGULAR_EXPRESSION
    is
       once
          Result.compile (my_re)
       end

    num: INTEGER

    make is do
       re.match ("can this be matched?")
       end
end

The compiler apparently crashes on a reference to a NULL pointer. I
attempted to reproduce this with a smaller class replacing
REGULAR_EXPRESSION but was unable to do so.

Greg C

=====
http://www.geocities.com/gmc444/gregs.html
Apologies for the stupid Yahoo ad below.

__________________________________________________
Do You Yahoo!?
Yahoo! - Official partner of 2002 FIFA World Cup
http://fifaworldcup.yahoo.com

#5001 From: "H. Erdbrügger" <he@...>
Date: Fri Jun 21, 2002 5:58 pm
Subject: Q related to bitwise shift operator
he@...
Send Email Send Email
 
Hi,

one question about the bitwise shift and rotate operators in the BIT class.

Why does have operators like:

infix "@<<" (s: INTEGER) is like Current is

a require clause of

require
	 s > 0

IMHO the neutral element of the shift/rotate operations (zero) should be
also in this contracts. Is this reqired by the ELK standard and if yes
should this be changed.

Any other opinions?

Harald

#5000 From: Arno Wagner <wagner@...>
Date: Fri Jun 21, 2002 10:27 am
Subject: Re: class names
wagner@...
Send Email Send Email
 
On Thu, Jun 20, 2002 at 05:12:43PM -0400, Alexander Rios wrote:
> I only recommended this convention
>
> >> Except for classes that have only deferred features
> >>  (like COMPARABLE, HASHABLE, OBSERVABLE) class names should be:
> >>
> >> <NOUN> |
> >> <ADJECTIVE> <NOUN> |
> >> <ADVERB> <ADJECTIVE> <NOUN>
>
> because most of the classes in SmallEiffel libraries
> already conform.
> Names should be consistent across a single library.
> At least that's what BM's OOSC says, and I think ELKS would agree.

I see. Well, in that case you are right. I am not sure ELKS says
anything about naming, though.

Arno
--
Arno Wagner, Communication Systems Group, ETH Zuerich, wagner@...
GnuPG:  ID: 1E25338F  FP: 0C30 5782 9D93 F785 E79C  0296 797F 6B50 1E25 338F
----
For every complex problem there is an answer that is clear, simple,
and wrong. -- H L Mencken

#4999 From: Philippe Ribet <p.ribet@...>
Date: Fri Jun 21, 2002 6:59 am
Subject: Re: SmallEiffel GC limited memory - real time
p.ribet@...
Send Email Send Email
 
"J. Scott Edwards" wrote:
I think in this case it would make the code extremely messy to not use GC.
The user has so many options and the memory space is so limited that we
couldn't have enough stuff at a given time for all possible combinations.
Ok. I depends on your project architecture.
> PS: don't forget that foo := "foo" or io.put_string("...") allocates memory
> for new string each time you go thru this line. Most of the time you have to
> use "once" keyword before the string (except for messages used once like
> error message before exit so no precomputed string is allocated).
>

It surprises me that foo := "foo" creates a new string.  I thought it just
made foo reference the "foo" manifest string?  Is this something new or
have I misunderstood something?
 

From HISTORY.txt:
   * The new manifest string notation for verbatim manifest string is
       now implemented as well as the new optional once keyword which may
       precede the manifest string itself. See also the new
       [2]-manifest_string_trace flag documentation to track non-once
       manifest strings creations.

From man/compile_to_c.txt:
    -manifest_string_trace:
          This option add some extra code into the executable in order to
          track non-once manifest string allocations. The default
          behavior is to print an information message each time a
          non-once manifest string is allocated at runtime. The message
          also indicates the position of the corresponding manifest
          string in the Eiffel source file. This default behavior can be
          adapted to your needs by modifying the
          SmallEiffel/sys/runtime/manifest_string_trace.c file.

As you can see, this new flag help to find such hidden string allocations.
 

This does remind me of something I noted on this list a couple of months
ago as well.  Not using GC also means you have to be careful which classes
you can and cannot use.  As I discovered you can't really use the
linked_list class if you don't have GC on, because every time you add an
element to the list it creates a link object.
Yes, new linked_list with link object reuse have to be added. If there are any volunteer to submit such work for inclusion in SmallEiffel...
[...] I've tried (until I'm blue in the face) to convince them that
most of the problems they have seen were due to the C++ language not to
the OO programming paradigm.

My idea then was to take the C++ version (that's supposed to be finished
any day ;-) and completely redo it in Eiffel [...]

Good luck !
-- 
Philippe Ribet



                         The README file said
              "Requires Windows 95, NT 4.0, or better."
                    So... I installed it on Linux!
 

#4998 From: "WILLIAMS Dominic" <D.WILLIAMS@...>
Date: Fri Jun 21, 2002 6:36 am
Subject: RE: class names
D.WILLIAMS@...
Send Email Send Email
 
> From: Arno Wagner [mailto:wagner@...]
> Subject: Re: class names
>
> I agree with you that names are important. I do not agree that
> your convention is the only one or that there is really a need
> for one global naming sheme used in all that is eiffel.
> Projects may have their own naming conventions. As long
> as collision is minimized and names are descriptive and
> consisten within a library, I don't really see a problem.

I also think names are important, and I agree with Alexander's critique of the
class names in SmallEiffel's lib.

As to whether naming conventions should be "global in all that is eiffel", I
think we should encourage this. The fact that some things (e.g. use of
uppercase, underscore etc.) are already far more homogeneous in Eiffel libs and
code than in, say, C++, is a great advantage.

But even if no one can stop a project from adopting its own conventions, I think
Alexander was referring to SmallEiffel's lib, which I do think should have a
global naming scheme. And the convention suggested is consistent with Bertrand
Meyer's guidelines which I agree with, and now apply not only in Eiffel but C++,
Python and Java.

Best regards,

Dominic Williams

#4997 From: AlexanderRios@... (Alexander Rios)
Date: Thu Jun 20, 2002 9:12 pm
Subject: Re: class names
AlexanderRios@...
Send Email Send Email
 
I only recommended this convention

>> Except for classes that have only deferred features
>>  (like COMPARABLE, HASHABLE, OBSERVABLE) class names should be:
>>
>> <NOUN> |
>> <ADJECTIVE> <NOUN> |
>> <ADVERB> <ADJECTIVE> <NOUN>

because most of the classes in SmallEiffel libraries
already conform.
Names should be consistent across a single library.
At least that's what BM's OOSC says, and I think ELKS would agree.

Arno Wagner <wagner@...> wrote:

>I agree with you that names are important. I do not agree that
>your convention is the only one or that there is really a need
>for one global naming sheme used in all that is eiffel.
>Projects may have their own naming conventions. As long
>as collision is minimized and names are descriptive and
>consisten within a library, I don't really see a problem.
>



__________________________________________________________________
Your favorite stores, helpful shopping tools and great gift ideas. Experience
the convenience of buying online with Shop@Netscape!
http://shopnow.netscape.com/

Get your own FREE, personal Netscape Mail account today at
http://webmail.netscape.com/

#4996 From: Arno Wagner <wagner@...>
Date: Thu Jun 20, 2002 7:34 pm
Subject: Re: class names
wagner@...
Send Email Send Email
 
On Thu, Jun 20, 2002 at 03:07:09PM -0400, Alexander Rios wrote:
> I know that to some people names don't matter too much but I think
> they matter alot.
>
> Except for classes that have only deferred features
>  (like COMPARABLE, HASHABLE, OBSERVABLE) class names should be:
>
> <NOUN> |
> <ADJECTIVE> <NOUN> |
> <ADVERB> <ADJECTIVE> <NOUN>
>
[...]

I agree with you that names are important. I do not agree that
your convention is the only one or that there is really a need
for one global naming sheme used in all that is eiffel.
Projects may have their own naming conventions. As long
as collision is minimized and names are descriptive and
consisten within a library, I don't really see a problem.

[...]
> Or are these names chosen by comittee and written in stone?

The ELKS standardizing group has not gotten to these yet, so no
commitee involved, as far as I know ;-)=)

Regards,
Arno

--
Arno Wagner, Communication Systems Group, ETH Zuerich, wagner@...
GnuPG:  ID: 1E25338F  FP: 0C30 5782 9D93 F785 E79C  0296 797F 6B50 1E25 338F
----
For every complex problem there is an answer that is clear, simple,
and wrong. -- H L Mencken

#4995 From: alexanderrios@... (Alexander Rios)
Date: Thu Jun 20, 2002 7:07 pm
Subject: class names
alexanderrios@...
Send Email Send Email
 
I know that to some people names don't matter too much but I think
they matter alot.

Except for classes that have only deferred features
  (like COMPARABLE, HASHABLE, OBSERVABLE) class names should be:

<NOUN> |
<ADJECTIVE> <NOUN> |
<ADVERB> <ADJECTIVE> <NOUN>

IMO
TEXT_FILE_READ should be renamed TEXT_FILE_INPUT_STREAM
TEXT_FILE_WRITE should be renames TEXT_FILE_OUTPUT_STREAM
TEXT_FILE_READ_WRITE should be renamed TEXT_FILE_IO_STREAM

GEN_RAND should be renamed RANDOM_NUMBER_GENERATOR or RANDOM_GENERATOR

MIN_STAND should be renamed MINIMAL_STANDARD_RANDOM_NUMBER_GENERATOR or
MINIMAL_STANDARD_RANDOM_GENERATOR or MINIMAL_STANDARD_GENERATOR or even
MINIMAL_STD_GENERATOR

Is their any hope for better names?  Or are these names chosen by comittee and
written in stone?

Can I use an ACE file to make these preferred names map to the current names?

Thanks.



__________________________________________________________________
Your favorite stores, helpful shopping tools and great gift ideas. Experience
the convenience of buying online with Shop@Netscape!
http://shopnow.netscape.com/

Get your own FREE, personal Netscape Mail account today at
http://webmail.netscape.com/

#4994 From: "J. Scott Edwards" <sedwards@...>
Date: Thu Jun 20, 2002 6:38 pm
Subject: Re: SmallEiffel GC limited memory - real time
sedwards@...
Send Email Send Email
 
On Thu, 20 Jun 2002, Philippe Ribet wrote:

> "J. Scott Edwards" wrote:
>
> > I've determined that I need to use GC for my little experimental project:
> >
> > http://wwsympa.loria.fr/wwsympa/arc/smalleiffel/2002-04/msg00018.html
> >
> > Even though the program is real-time, I figured I could get away with it
> > if I forced a garbage collecting (with the MEMORY:full_collect feature) at
> > points in the program when I know it won't be obvious.  And I am hoping
> > that if an occasional GC cycle happens it won't be too obtrusive.
> >
>
> Are you sure you really need GC ? If you carefully handle object creation and
> reuse in your code, you didn't need any GC. compile_to_c work this way. If
> you need more information on how to do this, tell me.

I think in this case it would make the code extremely messy to not use GC.
The user has so many options and the memory space is so limited that we
couldn't have enough stuff at a given time for all possible combinations.

Most (if not all) of the Eiffel programs I have written have been -no_gc
and I agree that many times GC in unneccessary.  But it seems to me that
as a program gets more complicated that it gets more difficult to manage
object creation.

For example, in an old version of compile_to_c I seem to remember some
classes that declared once strings like "tmp_string_1", "tmp_string_2",
"tmp_string_3", etc. which were used for temporary storage instead of
creating a string object in repeated calls to features.  While this works
fine, it seems like it adds another level of complexity to the code.
Because if more than one feature uses these once strings then the
programmer must make sure that none of those features never invokes any of
the other features that use them.  And then two years later when some new
programmer joins the project and modifies the code so that one of those
features now calls one of the other features, he's just introduced a funky
bug that may not be obvious to him.

> PS: don't forget that foo := "foo" or io.put_string("...") allocates memory
> for new string each time you go thru this line. Most of the time you have to
> use "once" keyword before the string (except for messages used once like
> error message before exit so no precomputed string is allocated).
>

It surprises me that foo := "foo" creates a new string.  I thought it just
made foo reference the "foo" manifest string?  Is this something new or
have I misunderstood something?

This does remind me of something I noted on this list a couple of months
ago as well.  Not using GC also means you have to be careful which classes
you can and cannot use.  As I discovered you can't really use the
linked_list class if you don't have GC on, because every time you add an
element to the list it creates a link object.

So as this project is totally academic (see below) I would very much
prefer to try to get it to work with GC on.  I have wondered for years how
well Eiffel would work on these types of programs and, as I mentioned
before, there are people here who are convinced that OO programming will
NOT work.  I've tried (until I'm blue in the face) to convince them that
most of the problems they have seen were due to the C++ language not to
the OO programming paradigm.

My idea then was to take the C++ version (that's supposed to be finished
any day ;-) and completely redo it in Eiffel in as good a OO fashon as I
can.  The C++ code is not currently really OO, it's mostly C.  It has very
little inheritance, all of the classes contain every variable and function
needed for every possible subtype.

In rewritting it, I can learn something in the process and see for myself
how well OO and Eiffel works on a large project like this.  Actually, I
can say at this point I have already learned quite a bit, and
interestingly, I have discovered several bugs in the original C++ code.
Even though we use ASSERT's in the C++ code, using the require and ensure
in Eiffel has wrung out several flaws in that didn't show up in C++.
Anyway, I my other hopw was that when I was done (or at some point) if it
worked well, I could show it to the non-believers and they could see for
themselves how well it worked.

Therefore, those are two more reasons I would like to have GC work on
this.  I would like the code to be as clean and simple as possible and not
have the extra complexity of trying to manage object creation and reuse
in the code.  And I would like to see how well GC will work in this
real-time environment.


>     Best regards,
>
> --
> Philippe Ribet
>
>                          The README file said
>               "Requires Windows 95, NT 4.0, or better."
>                     So... I installed it on Linux!
>
>
>

I like it!


Thanks
   -Scott

#4993 From: "Marcio Marchini" <mqm@...>
Date: Thu Jun 20, 2002 5:02 pm
Subject: RE: The Shootout benchmarks
mqm@...
Send Email Send Email
 
> One of the interesting missing benchmarks is Echo, where a process creates
> a socket, opens one end, spawns a child that opens the other end, and then
> sends data between parent and child. I know there are a couple of socket
> bindings out there. Anyone interested in giving this one a shot?


	 Yaesockets comes with an Echo example. It might be a good starting point.


marcio

#4992 From: Greg C <gmc444@...>
Date: Thu Jun 20, 2002 4:37 pm
Subject: The Shootout benchmarks
gmc444@...
Send Email Send Email
 
I finally heard back from Aldo Calpini [dada@...] the gentleman
running the The Great Win32 Computer Language Shootout.
http://dada.perl.it/shootout/

He said that he was sick for a week, and that he's rebuilding the Shootout
from scratch on a new machine. He also said that he's gladly accepting
contributions.

I've forwarded him new versions of the Hash II benchmark and the
Spellcheck benchmark.

One of the interesting missing benchmarks is Echo, where a process creates
a socket, opens one end, spawns a child that opens the other end, and then
sends data between parent and child. I know there are a couple of socket
bindings out there. Anyone interested in giving this one a shot?

Greg C

=====
http://www.geocities.com/gmc444/gregs.html
Apologies for the stupid Yahoo ad below.

__________________________________________________
Do You Yahoo!?
Yahoo! - Official partner of 2002 FIFA World Cup
http://fifaworldcup.yahoo.com

#4991 From: "J. Scott Edwards" <sedwards@...>
Date: Wed Jun 19, 2002 10:11 pm
Subject: Please support more than one copies of system runtime (was :SmallEiffel GC limited memory - real time) (fwd)
sedwards@...
Send Email Send Email
 
---------- Forwarded message ----------
Date: Wed, 19 Jun 2002 13:01:50 -0700 (PDT)
From: Cheng-Chang Wu <chengchangwu@...>
To: J. Scott Edwards <sedwards@...>
Subject: Please support more than one copies of system runtime (was
     :SmallEiffel GC limited memory - real time)


may you forward my last message to SmallEiffel's
mailing list. I forgot to cc it.

Thanks

Cheng-Chang Wu

__________________________________________________
Do You Yahoo!?
Yahoo! - Official partner of 2002 FIFA World Cup
http://fifaworldcup.yahoo.com

#4990 From: "J. Scott Edwards" <sedwards@...>
Date: Wed Jun 19, 2002 6:03 pm
Subject: SmallEiffel GC limited memory - real time
sedwards@...
Send Email Send Email
 
I've determined that I need to use GC for my little experimental project:

http://wwsympa.loria.fr/wwsympa/arc/smalleiffel/2002-04/msg00018.html

Even though the program is real-time, I figured I could get away with it
if I forced a garbage collecting (with the MEMORY:full_collect feature) at
points in the program when I know it won't be obvious.  And I am hoping
that if an occasional GC cycle happens it won't be too obtrusive.

However as soon as I turn on GC things get flakey and it crashes before it
even gets to the real critical run time mode.  I dug around a bit and I
can't say for sure (because it crashes down in some of the networking
library code which I don't have the source for) but I suspect it's using
up all of the memory and the networking cannot allocate any memory.  The
machine is limited to 32 mb of ram (and does NOT have virtual memory) and
much of that is used to load data and OS stuff.  There is probably less
than 1 mb left for dynamically allocated memory.


So I turned on gc_info and discovered some behaviour that is not so good
for the way this system works.  I have many objects that are created of
which there are only 1 or 2 that are ever created, and it appears to
allocate 8K (fixed size object chunk) for each one.

I'm currently stuck at an older version of SE and I notice that in the
newer versions there appear to be some more options for the GC, but I
couldn't find any documentation on specifically how they work.  I am going
to try to update to -0.74 however it will take some work.  Can anyone
point me to information about the modes in -0.74?

Thanks
   -Scott

#4989 From: Wolfgang Jansen <wolfgang@...>
Date: Tue Jun 18, 2002 7:59 am
Subject: Re: Problem with Character_bits still exists
wolfgang@...
Send Email Send Email
 
Greg C wrote:

> Back in April someone reported that running "short" with an ACE file and
> the case_insensitive option set to yes caused a compiler error message
> like this:
>
> ****** Fatal Error: It is not an integer value.
> Line 85 column 4 in PLATFORM
> (D:\elj-win32\SmallEiffel\\lib\kernel\platform.e) :
>    Character_bits: INTEGER is
>    ^
> Line 299 column 16 in CHARACTER
> (D:\elj-win32\SmallEiffel\\lib\kernel\character.e) :
>    to_bit: BIT Character_bits is
>
> This problem still exists and is messing with efforts to use the ELJ
> library. Is there any plan to fix this?
>

Hi,

meanwhile, I found that the trouble is caused in the compiler class
RUN_FEATURE_8. Its function `integer_value' compares the string
"character_bits" (obtained from PLATFORMS's `Character_bits'
by convertion to lower case) with the fixed string "Character_bits"
(which is not converted) and fails.
Thus, in case of case-insensitive compilation a case-insensitive
string comparision should be applied. I hope that this will be managable.

WJ


--
Wolfgang Jansen,
Universit"at Potsdam, Am Neuen Palais, Haus 19,
POB 601553, D-14415 Potsdam,
Voice: +49-331-977-1639, -1611, Fax: -1142,
E-mail: wjansen@...,
Internet homepage: http://www.agnld.Uni-Potsdam.de/~wolfgang/wolfgang.html

#4988 From: Benjamin Franksen <franksen@...>
Date: Mon Jun 17, 2002 10:30 pm
Subject: Re: Bug with ?? in manifest strings
franksen@...
Send Email Send Email
 
Eric Bezault wrote:
>
> Thanks to Franck Arnaud's explanation, I think that the
> problem is that SmallEiffel generates:
>
> ---
> se_ms(3,"??>");
> ---
>
> in the C code, which is then interpreted by an ANSI C
> compiler as a trigraph whose associated value is "}".
> Under Linux one might have to use the C option -ansi
> to reproduce the problem, although I didn't try.

From the gcc manual, chapter on command options:

-trigraphs
     Support ANSI C trigraphs. You don't want to know about
     this brain-damage. The `-ansi' option implies `-trigraphs'.

Ben

#4987 From: Eric Bezault <gobosoft@...>
Date: Mon Jun 17, 2002 9:26 pm
Subject: Bug with ?? in manifest strings
gobosoft@...
Send Email Send Email
 
Hello,

I'm using SmallEiffel -0.74 under Windows with MSVC which
is an ANSI C compiler. When compiling this program:

----
class A


creation

         make

feature

         make is
                 do
                         print ("??>")
                 end

end
----

we get:

---
}
---

instead of:

---
??>
---

Thanks to Franck Arnaud's explanation, I think that the
problem is that SmallEiffel generates:

---
se_ms(3,"??>");
---

in the C code, which is then interpreted by an ANSI C
compiler as a trigraph whose associated value is "}".
Under Linux one might have to use the C option -ansi
to reproduce the problem, although I didn't try.

For your information, I looked at the C code generated
by ISE Eiffel, and the "?" appearing in manifest strings
are escaped, probably to avoid this trigraph problem:

---
RTMS_EX("\?\?>",3);
---

I have the feeling that a similar solution should be
adopted by SmallEiffel.

--
Eric Bezault
mailto:ericb@...
http://www.gobosoft.com


______________________________________________________________________________
ifrance.com, l'email gratuit le plus complet de l'Internet !
vos emails depuis un navigateur, en POP3, sur Minitel, sur le WAP...
http://www.ifrance.com/_reloc/email.emailif

#4986 From: Greg C <gmc444@...>
Date: Mon Jun 17, 2002 9:13 pm
Subject: (No subject)
gmc444@...
Send Email Send Email
 
The obsolete text with the feature "system" in class GENERAL is incorrect.
Currently it reads,

    frozen system(system_command_line: STRING) is
          -- To execute a `system_command_line' as for example, "ls -l" on
UNIX.
       obsolete "Since release -0.74 you have to use feature `execute' %
                %of class SYSTEM."

When instead it should state that you have to use feature
'execute_command' or  'execute_command_line'.

Greg C

=====
http://www.geocities.com/gmc444/gregs.html
Apologies for the stupid Yahoo ad below.

__________________________________________________
Do You Yahoo!?
Yahoo! - Official partner of 2002 FIFA World Cup
http://fifaworldcup.yahoo.com

#4985 From: Greg C <gmc444@...>
Date: Mon Jun 17, 2002 8:34 pm
Subject: Problem with Character_bits still exists
gmc444@...
Send Email Send Email
 
Back in April someone reported that running "short" with an ACE file and
the case_insensitive option set to yes caused a compiler error message
like this:

****** Fatal Error: It is not an integer value.
Line 85 column 4 in PLATFORM
(D:\elj-win32\SmallEiffel\\lib\kernel\platform.e) :
    Character_bits: INTEGER is
    ^
Line 299 column 16 in CHARACTER
(D:\elj-win32\SmallEiffel\\lib\kernel\character.e) :
    to_bit: BIT Character_bits is

This problem still exists and is messing with efforts to use the ELJ
library. Is there any plan to fix this?

Greg C

(And yes, I'm running the release version.)





=====
http://www.geocities.com/gmc444/gregs.html
Apologies for the stupid Yahoo ad below.

__________________________________________________
Do You Yahoo!?
Yahoo! - Official partner of 2002 FIFA World Cup
http://fifaworldcup.yahoo.com

#4984 From: Wolfgang Jansen <wolfgang@...>
Date: Mon Jun 17, 2002 11:47 am
Subject: Re: STORABLE experiences with elj-win32 ..
wolfgang@...
Send Email Send Email
 
geldridg@... wrote:

> I had the chance to recompile SmallEiffel -0.74 with the latest STORABLE

Thank you for the bug report.

> --8<--
> C:\temp\SmallEiffel\demo>compile retrieve_persons
> Warning retrieve_persons4.c: 3224  no type specified. Defaulting to int
> 0 errors, 1 warnings

This was my mistake, but not so dramatic.

> Warning retrieve_persons3.c: 4692  unreachable code
> 0 errors, 1 warnings
> ->8--

This is the compiler's mistake (also not dramatic): A routine like
   some_routine is
     do
       -- do something dangerous
     rescue
       -- repair action
       retry
     end
becomes in C code:

> if(SETJMP(rc.jb)!=0){/*rescue*/
> (ds.p=50393358);

/* other statements */

> fd.assertion_flag=1;
> goto retry_tag;
> internal_exception_handler(Routine_failure);   // line 4692

The call to `internal_exception_handler' is generated even nothing follows
the `retry' statement. The bug belongs to the responsibility of the
SE developers.


> When I compiled with the -boost option, the demos would not compile, giving
> an application error from the lcc-win32 runtime ..

Unfortunately, currently I have no access to a PC (neither Windows nor Linux).
So I cannot reproduce the bug, I can only guess that it is related to the one
mentioned in the "Known bugs" section.

> However, compiling at the next assertion level up from boost (ie -no_check),
> the application compiled (with the same warnings as above) and ran correctly.

I just have put a new version onto the net. Besides the minor bug discussed
above also a much more sereve one has been fixed. The 1st warning should
no longer occur.

Wolfgang Jansen

--
Wolfgang Jansen,
Universit"at Potsdam, Am Neuen Palais, Haus 19,
POB 601553, D-14415 Potsdam,
Voice: +49-331-977-1639, -1611, Fax: -1142,
E-mail: wjansen@...,
Internet homepage: http://www.agnld.Uni-Potsdam.de/~wolfgang/wolfgang.html

#4983 From: geldridg@...
Date: Mon Jun 17, 2002 6:01 am
Subject: STORABLE experiences with elj-win32 ..
geldridg@...
Send Email Send Email
 
I had the chance to recompile SmallEiffel -0.74 with the latest STORABLE
patches submitted by Wolfgang Jansen ..

    http://wwsympa.loria.fr/wwsympa/arc/smalleiffel/2002-06/msg00080.html

The backend C compiler is lcc-win32 v3.8 - Jun 3 2002 .. this is basically
the elj-win32 package - http://www.elj.com/elj-win32/

The compile_to_c.exe increased in size from 1,139,232 to 1,208,864 bytes.
The other tools remained the same size as the original -0.74.

Following recompilation of the SmallEiffel tools I was able to compile
and correctly run the store_persons and retrieve_persons in the demos
directory. For retrieve_persons, the following warning were produced
when compiled ..

--8<--
C:\temp\SmallEiffel\demo>compile retrieve_persons
Warning retrieve_persons4.c: 3224  no type specified. Defaulting to int
0 errors, 1 warnings
Warning retrieve_persons3.c: 4692  unreachable code
0 errors, 1 warnings
->8--

retrieve_persons4.c: 3224  follows ..

--8<--
void se_fill_agents(){
{se_agent1 M; static FD ca[]=
{{"target",11}};
ca[0].offset=(size_t)&M.C-(size_t)&M;
se_ad[1].ca=ca;  {static ii[]={0};  se_ad[1].ca_pos=ii;}  // line 3224
}
}
-->8--

Warning retrieve_persons3.c: 4692  follows ..

--8<--
if(SETJMP(rc.jb)!=0){/*rescue*/
(ds.p=50393358);
_a=((T0*)(C));
fd.assertion_flag=1;
goto retry_tag;
internal_exception_handler(Routine_failure);   // line 4692
}
-->8--

Here is a copy of the output or retrieve_persons (following store_persons)..

--8<--
C:\temp\SmallEiffel\demo>retrieve_persons
Start retrieving . . .
Figaro loves somebody, has a lord
Susanna loves Figaro, has a lord
Almaviva loves Susanna, has no lord

Retrieving successful, all persons:
Figaro loves Susanna, has lord Almaviva
Almaviva loves Susanna, has no lord
Susanna loves Figaro, has lord Almaviva

C:\temp\SmallEiffel\demo>
-->8--

When I compiled with the -boost option, the demos would not compile, giving
an application error from the lcc-win32 runtime ..

However, compiling at the next assertion level up from boost (ie -no_check),
the application compiled (with the same warnings as above) and ran correctly.

Hope this helps ..

Geoff

-- geoff@...
-- http://elj.sourceforge.net/

#4982 From: Greg Reagle <greagl1@...>
Date: Sun Jun 16, 2002 4:11 pm
Subject: post-conditions for NUMERIC
greagl1@...
Send Email Send Email
 
I thought of more post-conditions for NUMERIC.  Could they be added to
SmallEiffel?

    one: like Current
       -- Neutral element for "*" and "/".
       ensure
          Result.sign = 1

    zero: like Current
       -- Neutral element for "+" and "-".
       ensure
          Result.sign = 0

    prefix "+": like Current
       -- Unary plus of `Current'.
       ensure
          Result.sign = Current.sign

    prefix "-": like Current
       -- Unary minus of `Current'.
       ensure
          Result.sign = -Current.sign

--
Signature rotation provided by Signify v1.07.  See http://www.debian.org/.
          But I was young and foolish then; I feel old and foolish now.
                             -- They Might Be Giants

#4981 From: Arno Wagner <wagner@...>
Date: Sat Jun 15, 2002 4:20 pm
Subject: Bugfix: Re: bug in string.is_integer
wagner@...
Send Email Send Email
 
Dear group,

Daniel F Moisset reported a bug in STRING, where
("+").is_integer or ("-").is_integer had a "true" result.

The same happens with is_double in STRING.
"is_number" in STRING and NUMBER_TOOLS is not affected.

The fix is by classifying loop termination in state "1"
as failure, which was not done before. Such a termination
can only happen if the string ends with the sign.

Patchfile relative to string.e from SE074b22:

472c472
<        if state /= 0 and then state /= 4 then
---
>        if state /= 0 and then state /= 1 and then state /= 4 then
677c677
<        if state /= 0 and then state /= 9 then
---
>        if state /= 0 and then state /= 1 and then state /= 9 then

The patched version of string.e is also attached.

Regards,
Arno

--
Arno Wagner, Communication Systems Group, ETH Zuerich, wagner@...
GnuPG:  ID: 1E25338F  FP: 0C30 5782 9D93 F785 E79C  0296 797F 6B50 1E25 338F
----
For every complex problem there is an answer that is clear, simple,
and wrong. -- H L Mencken
-- This file is  free  software, which  comes  along  with  SmallEiffel. This
-- software  is  distributed  in the hope that it will be useful, but WITHOUT
-- ANY  WARRANTY;  without  even  the  implied warranty of MERCHANTABILITY or
-- FITNESS  FOR A PARTICULAR PURPOSE. You can modify it as you want, provided
-- this header is kept unaltered, and a notification of the changes is added.
-- You  are  allowed  to  redistribute  it and sell it, alone or as a part of
-- another product.
--       Copyright (C) 1994-2002 LORIA - INRIA - U.H.P. Nancy 1 - FRANCE
--          Dominique COLNET and Suzanne COLLIN - SmallEiffel@...
--                       http://SmallEiffel.loria.fr
--
class STRING
    --
    -- Resizable character STRINGs indexed from `1' to `count'.
    --

inherit
    HASHABLE
       undefine is_equal
       end;

    COMPARABLE
       redefine
          is_equal, copy, compare, three_way_comparison,
          out_in_tagged_out_memory, fill_tagged_out_memory
       end;

creation make, copy, make_empty, make_filled, blank, from_external,
    from_external_copy, make_from_string

feature {STRING,POINTER,TEXT_FILE_READ}

    storage: NATIVE_ARRAY[CHARACTER];
          -- The place where characters are stored.

feature

    count: INTEGER;
          -- String length which is also the maximum valid index.

    capacity: INTEGER;
          -- Capacity of the `storage' area.

    lower: INTEGER is 1;
	  -- Minimum index; actually, this is always 1 (this feature is
	  -- here to mimic the one of the COLLECTIONs hierarchy).

    upper: INTEGER is
	  -- Maximum index; actually the same value as `count' (this
	  -- feature is here to mimic the one of the COLLECTION hierarchy).
       do
	  Result := count;
       ensure
	  Result = count
       end;

feature -- Creation / Modification:

    make(needed_capacity: INTEGER) is
          -- Initialize the string to have at least `needed_capacity'
          -- characters of storage.
       require
           non_negative_size: needed_capacity >= 0;
       do
          if needed_capacity > 0 then
             if capacity < needed_capacity then
                storage := storage.calloc(needed_capacity);
                capacity := needed_capacity;
             end;
          end;
          count := 0;
       ensure
          needed_capacity <= capacity;
          empty_string: count = 0
       end;

    make_empty is
          -- Create an empty string.
       do
          make(0)
       end;

    make_filled(c: CHARACTER; n: INTEGER) is
          -- Initialize string with `n' copies of `c'.
       require
          valid_count: n >= 0
       do
          make(n);
          count := n;
          fill_with(c);
       ensure
          count_set: count = n
          filled: occurrences(c) = count
       end;

    blank(nr_blanks: INTEGER) is
       obsolete "Use ELKS 2001 conform feature `make_filled' instead."
       do
          make_filled(' ',nr_blanks)
       end;

feature -- Testing:

    is_empty: BOOLEAN is
          -- Has string length 0?
       do
          Result := (count = 0);
       end;

    empty: BOOLEAN is
       obsolete "The new name of this feature is `is_empty'."
       do
          Result := is_empty;
       end;

    item, infix "@" (i: INTEGER): CHARACTER is
          -- Character at position `i'.
       require
          valid_index: valid_index(i)
       do
          Result := storage.item(i - 1);
       end;

    valid_index(i: INTEGER): BOOLEAN is
          -- True when `i' is valid (i.e., inside actual bounds).
       do
          Result := 1 <= i and then i <= count;
       ensure
          definition: Result = (1 <= i and i <= count)
       end;

    hash_code: INTEGER is
       local
          i, j: INTEGER
       do
          from
	     j := count;
	     i := 1
	  until
	     j <= 0
	  loop
             Result := 5 * Result + item(i).code;
             i := i + 1;
	     j := j - 1;
          end;
          if Result < 0 then
             Result := - (Result + 1);
          end;
       end;

    infix "<" (other: like Current): BOOLEAN is
          -- Is `Current' less than `other'?
       local
          i: INTEGER;
       do
          from
             i := 1;
          until
             count < i or else other.count < i
             or else item(i) /= other.item(i)
          loop
             i := i + 1;
          end;
          if count < i then
             Result := other.count >= i;
          elseif other.count < i then
             Result := false;
          else
             Result := item(i) < other.item(i);
          end;
       end;

    compare, three_way_comparison(other: like Current): INTEGER is
       local
          i: INTEGER;
       do
          from
             i := 1;
          until
             count < i or else other.count < i
             or else item(i) /= other.item(i)
          loop
             i := i + 1;
          end;
          if count < i then
             if other.count < i then
             else
                Result := -1;
             end;
          elseif other.count < i then
             Result := 1;
          elseif item(i) < other.item(i) then
             Result := -1;
          else
             Result := 1;
          end;
       end;

    is_equal(other: like Current): BOOLEAN is
          -- Do both strings have the same character sequence?
          -- (Redefined from GENERAL)
       do
          if count = other.count then
             Result := storage.fast_memcmp(other.storage,count);
          end;
       end;

    same_as(other: STRING): BOOLEAN is
          -- Case insensitive `is_equal'.
       require
          other /= Void
       local
          s1, s2: like storage;
          i: INTEGER;
       do
          i := count;
          if i = other.count then
             if storage.fast_memcmp(other.storage,i) then
                Result := true;
             else
                from
                   i := i - 1;
                   s1 := storage;
                   s2 := other.storage;
                   Result := true;
                until
                   i < 0
                loop
                   if s1.item(i).same_as(s2.item(i)) then
                      i := i - 1;
                   else
                      i := -1;
                      Result := false;
                   end;
                end;
             end;
          end;
       end;

    item_code(i: INTEGER): INTEGER is
	  -- Code of character at position `i'.
       require
	  valid_index: valid_index (i)
       do
	  Result := storage.item(i - 1).code
       end

    index_of(c: CHARACTER; start_index: INTEGER): INTEGER is
          -- Index of first occurrence of `c' at or after `start_index',
          -- 0 if none.
	  --
          -- Note: see also `first_index_of' to start searching at 1.
	  -- Actually `first_index_of' is not exactely the equivalent of `index_of'
	  -- in release -0.76: when the search failed the result is
	  -- now 0 (and no longer `count' + 1). So, to update your code from
	  -- release -0.76 to release -0.75, replace `index_of' with `first_index_of'
	  -- and be careful to see what's done with the result !
       require
	  valid_start_index: start_index >= 1 and start_index <= count + 1
       do
	  from
	     Result := start_index
	  until
	     Result > count or else c = item(Result)
	  loop
	     Result := Result + 1
	  end;
	  if Result > count then
	     Result := 0
	  end;
       ensure
         (Result /= 0) implies (item(Result) = c);
       end;

    first_index_of(c: CHARACTER): INTEGER is
          -- Index of first occurrence of `c' at index 1 or after index 1.
       do
	  Result := index_of(c,1);
       ensure
	  definition: Result = index_of(c,1)
       end;

    index_of_string(other: STRING): INTEGER is
       obsolete "Since release -0.75 you have to use `first_substring_index'
instead.%
               %Also Note that the `Result' is now 0 when the search fail."
	       -- Position of the first occurrence of `other' or `count + 1' if none.
       require
          not other.is_empty
       do
          Result := substring_index(other,1)
          if Result = 0 then
             Result := count + 1
          end;
       end;

    has(c: CHARACTER): BOOLEAN is
          -- True if `c' is in the STRING.
       do
          Result := storage.fast_has(c,count - 1);
       end;

    has_string(other: STRING): BOOLEAN is
       obsolete "Use ELKS2001 conform feature `has_substring' instead."
       do
          Result := has_substring(other);
       end;

    has_substring(other: STRING): BOOLEAN is
          -- True if `Current' contains `other'.
       require
          other_not_void: other /= Void
       do
          Result := substring_index(other,1) /= 0;
       end;

    nb_occurrences, occurrences_of(c: CHARACTER): INTEGER is
       obsolete "Use ELKS2001 conform feature `occurrences' instead."
          -- Number of times character `c' appears in the string.
       do
          Result := occurrences(c);
       end;

    occurrences(c: CHARACTER): INTEGER is
          -- Number of times character `c' appears in the string.
       do
          Result := storage.fast_occurrences(c,count - 1);
       ensure
          Result >= 0
       end;

    has_suffix(s: STRING): BOOLEAN is
          -- True if suffix of `Current' is `s'.
       require
          s /= Void
       local
          i1, i2: INTEGER;
       do
          if s.count <= count then
             from
                i1 := count - s.count + 1;
                i2 := 1;
             until
                i1 > count or else
                i2 > s.count or else
                item(i1) /= s.item(i2)
             loop
                i1 := i1 + 1;
                i2 := i2 + 1;
             end;
             Result := i1 > count;
          end;
       end;

    has_prefix(p: STRING): BOOLEAN is
          -- True if prefix of `Current' is `p'.
       require
          p /= Void;
       local
          i: INTEGER;
       do
          if p.count <= count then
             from
                i := p.count;
             until
                i = 0 or else item(i) /= p.item(i)
             loop
                i := i - 1;
             end;
             Result := i = 0;
          end;
       end;

feature -- Testing and Conversion:

    is_boolean: BOOLEAN is
          -- Does `Current' represent a BOOLEAN?
          -- Valid BOOLEANS are "true" and "false".
       do
          Result := (once "true").is_equal(Current) or else (once
"false").is_equal(Current);
       end;

    to_boolean: BOOLEAN is
          -- Boolean value;
          -- "true" yields true, "false" yields false (what a surprise).
       require
          represents_a_boolean: is_boolean
       do
          Result := (once "true").is_equal(Current);
       end;

    is_integer: BOOLEAN is
          -- Does 'Current' represent an INTEGER?
          -- `Result' is true if and only if the following two conditions hold:
          --
          -- 1. In the following BNF grammar, the value of `Current' can be
          -- produced by "Integer_literal", if leading and trailing
          -- separators are ignored:
          --
          -- Integer_literal = [Sign] Integer
          -- Sign            = "+" | "-"
          -- Integer         = Digit | Digit Integer
          -- Digit           = "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"
          --
          -- 2. The numerical value represented by `Current' is within the
          -- range that can be represented by an instance of type INTEGER.
       local
          i, state, value: INTEGER; negative: BOOLEAN; cc: CHARACTER;
       do
          -- state 0: nothing read.
          -- state 1: "+" or "-" read.
          -- state 2: in the number.
          -- state 3: after the number.
          -- state 4: error.
          from
             i := 1;
	  variant
	     count - i
          until
             state = 4 or else i > count
          loop
             cc := item(i);
             inspect
                state
             when 0 then
                if cc.is_separator then
                elseif cc = '+' then
                   state := 1;
                elseif cc = '-' then
                   negative := true;
                   state := 1;
                elseif cc.is_digit then
                   value := cc.decimal_value;
                   state := 2;
                else
                   state := 4;
                end;
             when 1 then
                if cc.is_digit then
                   value := cc.decimal_value;
                   if negative then
                      value := -1 * value;
                   end
                   state := 2;
                else
                   state := 4;
                end;
             when 2 then
                if cc.is_digit then
                   if negative then
                      value := 10 * value - cc.decimal_value;
                   else
                      value := 10 * value + cc.decimal_value;
                   end
                   -- over/underflow check here
                   if (negative and then value > 0)
                      or else (not negative and then value < 0) then
                      state := 4;
                   end
                elseif cc.is_separator then
                   state := 3;
                else
                   state := 4;
                end;
             when 3 then
                if cc.is_separator then
                else
                   state := 4;
                end;
             end;
             i := i + 1;
          end;
	  if state /= 0 and then state /= 1 and then state /= 4 then
             Result := true;
          end;
       end;

    to_integer: INTEGER is
          -- `Current' must look like an INTEGER.
       require
          is_integer
       local
          i, state: INTEGER; cc: CHARACTER; negative: BOOLEAN;
       do
          -- state 0: nothing read.
          -- state 1: "+" or "-" read.
          -- state 2: in the number.
          -- state 3: after the number.
          from
             i := 1;
	  variant
	     count - i
          until
             i > count
          loop
             cc := item(i);
             inspect
                state
             when 0 then
                if cc.is_separator then
                elseif cc = '+' then
                   state := 1;
                elseif cc = '-' then
                   negative := true;
                   state := 1;
                else -- cc.is_digit
                   Result := cc.value;
                   state := 2;
                end;
             when 1 then
                -- cc.is_digit
                Result := cc.value;
                if negative then
                      Result := -1 * Result
                end
                state := 2;
             when 2 then
                if cc.is_digit then
                   if negative then
                      Result := 10 * Result - cc.decimal_value
                   else
                      Result := 10 * Result + cc.decimal_value
                   end
                else -- cc.is_separator
                   state := 3;
                end;
             when 3 then
                -- cc.is_separator
                i := count; -- terminate the loop
             end;
             i := i + 1;
          end;
       end;

    is_double: BOOLEAN is
          -- Can contents be read as a DOUBLE?
          -- Fails for numbers where the base or "10 ^ exponent" are not in
          -- the range `Minimum_double' ... `Maximum_double'. Parsing is done
          -- positive. That means if `Minimum_double.abs' is not equal to
          -- `Maximum_double' it will not work correctly. Furthermore the
          -- arithmetric package used must support the value 'inf' for a
          -- number greater than Maximum_double.
          -- `Result' is true if and only if the following two conditions hold:
          --
          -- 1. In the following BNF grammar, the value of `Current' can be
          -- produced by "Real_literal", if leading or trailing separators
          -- are ignored.
          --
          -- Real_literal    = Mantissa [Exponent_part]
          -- Exponent_part   = "E" Exponent
          --                 | "e" Exponent
          -- Exponent        = Integer_literal
          -- Mantissa        = Decimal_literal
          -- Decimal_literal = Integer_literal ["." Integer]
          -- Integer_literal = [Sign] Integer
          -- Sign            = "+" | "-"
          -- Integer         = Digit | Digit Integer
          -- Digit           = "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"
          --
          --
          -- 2. The numerical value represented by `Current' is within the range
          -- that can be represented by an instance of type DOUBLE.
       local
          i, state: INTEGER; cc: CHARACTER;
          base, exp, value, multiplier: DOUBLE;
          negative, neg_exp: BOOLEAN;
       do
          -- state 0: nothing read.
          -- state 1: "+" or "-" read.
          -- state 2: in the number.
          -- state 3: decimal point read
          -- state 4: in fractional part
          -- state 5: read 'E' or 'e' for scientific notation
          -- state 6: read "-" or "+" sign of exponent
          -- state 7: in exponent
          -- state 8: after the number.
          -- state 9: error.
          from
             i := 1;
	  variant
	     count - i
          until
             state = 9 or else i > count
          loop
             cc := item(i);
             inspect
                state
             when 0 then
                if cc.is_separator then
                elseif cc = '+' then
                   state := 1;
                elseif cc = '-' then
                   negative := true;
                   state := 1;
                elseif cc.is_digit then
                   base := cc.decimal_value;
                   state := 2;
                elseif cc = '.' then
                   state := 3;
                else
                   state := 9;
                end;
             when 1 then
                if cc.is_digit then
                   base := cc.decimal_value;
                   state := 2;
                elseif cc = '.' then
                   state := 3;
                else
                   state := 9;
                end;
             when 2 then
                if cc.is_digit then
                   base := base * 10 + cc.decimal_value;
                elseif cc = '.' then
                   state := 3;
                elseif (cc = 'e' or else cc = 'E') then
                   state := 5;
	        elseif cc.is_separator then
		   state := 8;
	        else
                   state := 9;
                end;
             when 3 then
                multiplier := 0.1;
                if cc.is_digit then
                   base := base + multiplier * cc.decimal_value
                   state := 4;
                else
                   state := 9;
                end;
             when 4 then
                multiplier := multiplier * 0.1;
                if cc.is_digit then
                   base := base + multiplier * cc.decimal_value;
                elseif cc.is_separator then
                   state := 8;
                elseif (cc = 'e' or else cc = 'E') then
                   state := 5;
                else
                   state := 9;
                end;
             when 5 then
                if cc = '-' then
                   neg_exp := true;
                   state := 6;
                elseif cc = '+'  then
                   state := 6;
                elseif cc.is_digit then
                   exp := cc.decimal_value;
                   state := 7;
                else
                   state := 9;
                end;
             when 6 then
                if cc.is_digit then
                   exp := cc.decimal_value
                   state := 7;
                else
                   state := 9;
                end;
             when 7 then
                if cc.is_digit then
                   exp := exp * 10 + cc.decimal_value;
                elseif cc.is_separator then
                   state := 8;
                else
                   state := 9;
                end;
             when 8 then
                if cc.is_separator then
                else
                   state := 9;
                end;
             end;
             i := i + 1;
          end;
	  if state /= 0 and then state /= 1 and then state /= 9 then
	     Result := true;
	     if neg_exp then exp := -1 * exp end;
	     value := base * (10.0).pow(exp);
	     if value > Maximum_double then
	        -- can only happen if value = inf
	        Result := false;
	     end;
	  end;
       end;

    to_double: DOUBLE is
          -- Conversion to the corresponding DOUBLE value. The string must
          -- looks like a DOUBLE (or like an INTEGER because fractionnal part
          -- is optional). For an exact definition see 'is_double'.
          -- Note that this conversion might not be exact.
       require
          represents_a_double: is_double
       local
          i, state: INTEGER; cc: CHARACTER; base, exp, multiplier: DOUBLE;
          negative, neg_exp: BOOLEAN
       do
          -- state 0: nothing read.
          -- state 1: "+" or "-" read.
          -- state 2: in the number.
          -- state 3: decimal point read
          -- state 4: in fractional part
          -- state 5: read 'E' or 'e' for scientific notation
          -- state 6: read "-" or "+" sign of exponent
          -- state 7: in exponent
          -- state 8: after the number.
          from
             i := 1;
	  variant
	     count - i
          until
             i > count
          loop
             cc := item(i);
             inspect
                state
             when 0 then
                if cc.is_separator then
                elseif cc = '+' then
                   state := 1;
                elseif cc = '-' then
                   negative := true
                   state := 1;
                elseif cc.is_digit then
                   base := cc.decimal_value
                   state := 2;
                else -- cc = '.'
                   state := 3;
                end;
             when 1 then
                if cc.is_digit then
                   base := cc.decimal_value;
                   state := 2;
                else -- cc = '.'
                   state := 3;
                end;
             when 2 then
                if cc.is_digit then
                   base := base * 10 + cc.decimal_value;
                elseif cc = '.' then
                   state := 3;
	        elseif cc.is_separator then
		   state := 8;
                else -- cc = 'e' or else cc = 'E'
                   state := 5;
                end;
             when 3 then
                multiplier := 0.1;
                if cc.is_separator then
                    state := 8;
                else -- cc.is_digit
                   base := base + multiplier * cc.decimal_value
                   state := 4;
                end;
             when 4 then
                multiplier := multiplier * 0.1;
                if cc.is_digit then
                   base := base + multiplier * cc.decimal_value;
                elseif cc.is_separator then
                   state := 8;
                else -- cc = 'e' or else cc = 'E'
                   state := 5;
                end;
             when 5 then
                if cc = '-' then
                   neg_exp := true;
                   state := 6;
                elseif cc = '+'  then
                   state := 6;
                else -- cc.is_digit
                   exp := cc.decimal_value;
                   state := 7;
                end;
             when 6 then
                -- cc.is_digit
                   exp := cc.decimal_value;
                   state := 7;
             when 7 then
                if cc.is_digit then
                   exp := exp * 10 + cc.decimal_value;
                else -- cc.is_separator
                   state := 8;
                end;
             when 8 then
                -- cc.is_separator
                i := count; -- terminate the loop
             end;
             i := i + 1;
          end;
          if neg_exp then exp := -1 * exp end;
          if negative then
             Result := -1 * base * (10.0).pow(exp);
          else
             Result :=  base * (10.0).pow(exp);
          end;
       end;

    is_real: BOOLEAN is
          -- Can contents be read as a REAL?
       local
          d: DOUBLE;
       do
          if is_double then
             d := to_double;
             if Minimum_real <= d and then d <= Maximum_real then
                Result := true;
                -- This gives only approximate accuracy; the comparison
                -- is not accurate to nearly as many significant figures
                -- as are displayed for the limits.
             end;
          end;
       end;

    to_real: REAL is
          -- Conversion to the corresponding REAL value.
          -- The string must looks like a REAL (or like an
          -- INTEGER because fractionnal part is optional).
       require
          is_integer or is_real
       do
          Result := to_double.to_real;
       end;

    is_number: BOOLEAN is
 	  -- Can contents be read as a NUMBER?
       local
	  number_tools: NUMBER_TOOLS;
       do
	  Result := number_tools.is_number(Current);
       end;

    to_number: NUMBER is
          -- Current must looks like an INTEGER.
       require
	  is_number
       local
	  number_tools: NUMBER_TOOLS;
       do
	  Result := number_tools.from_string(Current);
       end;

    is_bit: BOOLEAN is
          -- True when the contents is a sequence of bits (i.e., mixed
          -- characters `0' and characters `1').
       local
          i: INTEGER;
       do
          from
             i := count;
             Result := true;
          until
             not Result or else i = 0
          loop
             Result := item(i).is_bit;
             i := i - 1;
          end;
       ensure
          Result = (count = occurrences('0') + occurrences('1'))
       end;

    to_hexadecimal is
          -- Convert Current bit sequence into the corresponding
          -- hexadecimal notation.
       require
          is_bit
       local
          i, k, new_count: INTEGER;
          value: INTEGER;
       do
          from
             i := 1;
             k := count \\ 4;
             if k > 0 then
                new_count := 1;
             end;
          until
             k = 0
          loop
             value := value * 2 + item(i).value;
             i := i + 1;
             k := k - 1;
          end;
          if new_count > 0 then
             put(value.hexadecimal_digit,new_count);
          end;
          from
          until
             i > count
          loop
             from
                value := item(i).value;
                i := i + 1;
                k := 3;
             until
                k = 0
             loop
                value := value * 2 + item(i).value;
                i := i + 1;
                k := k - 1;
             end;
             new_count := new_count + 1;
             put(value.hexadecimal_digit,new_count);
          end;
          count := new_count;
       end;

    binary_to_integer: INTEGER is
          -- Assume there is enougth space in the INTEGER to store
          -- the corresponding decimal value.
       require
          is_bit
          count <= Integer_bits
       local
          i: INTEGER;
       do
          from
             i := 1;
          until
             i > count
          loop
             if item(i) = '1' then
                Result := (2 * Result) + 1;
             else
                Result := 2 * Result;
             end;
             i := i + 1;
          end;
       end;

feature -- Modification:

    resize(new_count: INTEGER) is
          -- Resize Current. When `new_count' is greater than
          -- `count', new positions are initialized with the
          -- default value of type CHARACTER ('%U').
       require
          new_count >= 0
       local
	  s: like storage;
       do
          if new_count <= count then
	  elseif capacity < new_count then
	     if capacity = 0 then
	        storage := storage.calloc(new_count);
	     else
	        storage := storage.realloc(capacity,new_count);
	     end;
	     capacity := new_count;
          else
	     storage.clear(count,new_count - 1);
	  end;
	  count := new_count;
       ensure
          count = new_count;
          capacity >= old capacity
       end;

    clear, wipe_out is
          -- Clear out the current STRING.
          -- Note: internal `storage' memory is neither released nor shrunk.
       do
          count := 0
       ensure
          count = 0
       end;

    copy(other: like Current) is
          -- Copy `other' onto Current.
       local
	  c: INTEGER;
       do
	  c := other.count;
          if c > 0 then
             if capacity < c then
                storage := storage.calloc(c);
                capacity := c;
             end;
             storage.copy_from(other.storage,c - 1);
          end;
          count := c;
       ensure then
          count = other.count
       end;

    fill(c: CHARACTER) is
       obsolete "Use ELKS 2001 conform feature `fill_with' instead."
          -- Replace every character with `c'.
       do
          fill_with(c);
       end;

    fill_with(c: CHARACTER) is
          -- Replace every character with `c'.
       do
          storage.set_all_with(c,count - 1);
       ensure
          occurrences(c) = count
       end;

    fill_blank is
       obsolete "Use ELKS 2001 conform feature `fill_with' instead."
          -- Fill entire string with blanks
       do
          fill_with(' ');
       ensure
          occurrences(' ') = count
       end;

    replace_all(old_character, new_character: like item) is
          -- Replace all occurrences of the element `old_character' by
          -- `new_character'.
       do
          storage.fast_replace_all(old_character,new_character,count - 1);
       ensure
          count = old count;
          occurrences(old_character) = 0
       end;

    append, append_string(s: STRING) is
          -- Append a copy of 's' to `Current'.
       require
          s_not_void: s /= Void
       local
          s_count, needed_capacity: INTEGER;
          new_capacity: INTEGER;
       do
	  s_count := s.count;
          needed_capacity := count + s_count;
          if needed_capacity > capacity then
             if capacity = 0 then
                storage := storage.calloc(needed_capacity);
                capacity := needed_capacity;
             else
                new_capacity := 2 * capacity
                if needed_capacity > new_capacity then
                   storage := storage.realloc(capacity,needed_capacity);
                   capacity := needed_capacity;
                else
                   storage := storage.realloc(capacity,new_capacity);
                   capacity := new_capacity;
                end;
             end;
          end;
          storage.copy_at(count,s.storage,s_count);
          count := needed_capacity;
       end;

    prepend(other: STRING) is
          -- Prepend `other' to `Current'.
       require
          other /= Void
       local
          i, j: INTEGER;
       do
	  i := count;
	  j := other.count;
	  resize(i + j);
	  if i > 0 and then j > 0 then
	     storage.move(0, i - 1, j);
	  end;
	  storage.copy_from(other.storage, j - 1);
       ensure
	  Current.is_equal(old other.twin + old Current.twin)
       end;

    insert_string(s: STRING; i: INTEGER) is
          -- Insert `s' at index `i', shifting characters from index `i'
          -- to `count' rightwards.
       require
          string_not_void: s /= Void;
          valid_insertion_index: 1 <= i and i <= count + 1
       local
          j, k: INTEGER;
       do
          j := count;
          k := s.count;
          resize(j + k);
	  if i <= j then
	     storage.move(i - 1, j - 1, k);
	  end;
          storage.copy_at(i - 1, s.storage, k);
       end;

    replace_substring(s: STRING; start_index, end_index: INTEGER) is
          -- Replace the substring from `start_index' to `end_index',
          -- inclusive, with `s'.
       require
          string_not_void: s /= Void;
          valid_start_index: 1 <= start_index;
          valid_end_index: end_index <= count;
          meaningful_interval: start_index <= end_index + 1
       local
          remove_len, insert_len, difference, old_count: INTEGER
       do
          old_count := count;
          remove_len := end_index - start_index + 1
          insert_len := s.count
          difference := insert_len - remove_len
          if difference > 0 then
	     resize(old_count + difference)
	     if end_index < old_count then -- something to move?
	        storage.move(end_index + 1 - 1 , old_count - 1, difference)
	     end
	  elseif difference < 0 then
	     if end_index < count then -- something to move?
	        storage.move(end_index + 1 - 1, old_count - 1, difference)
	     end
	     resize(old_count + difference)
	  end;
          storage.copy_at(start_index - 1, s.storage, s.count)
       end;

    infix "+" (other: STRING): like Current is
          -- Create a new STRING which is the concatenation of
          -- `Current' and `other'.
       require
          other_exists: other /= Void
       do
          !!Result.make(count + other.count);
          Result.append(Current);
          Result.append(other);
       ensure
          result_count: Result.count = count + other.count
       end;

    put(c: CHARACTER; i: INTEGER) is
          -- Put `c' at position `index'.
       require
          valid_index: valid_index(i)
       do
          storage.put(c,i - 1);
       ensure
          item (i) = c
       end;

    swap(i1, i2: INTEGER) is
       require
          valid_index(i1);
          valid_index(i2)
       local
          tmp: CHARACTER;
       do
          tmp := item(i1);
          put(item(i2),i1);
          put(tmp,i2);
       ensure
          item(i1) = old item(i2);
          item(i2) = old item(i1);
       end;

    insert(c: CHARACTER; i: INTEGER) is
       obsolete "Use ELKS 2001 conform feature `insert_character' instead."
          -- Insert `ch' after position `index'.
       do
          insert_character(c, i + 1);
       end;

    insert_character(c: CHARACTER; i: INTEGER) is
          -- Inserts `c' at index `i', shifting characters from
          -- position 'i' to `count' rightwards.
       require
          valid_insertion_index: 1 <= i and i <= count + 1
       local
          j: INTEGER;
       do
          from
             j := count;
             append_character(' ');
          until
             j = i - 1
          loop
             put(item(j), j + 1);
             j := j - 1;
          end;
          put(c, i);
       ensure
          item (i) = c
       end;

    shrink(min_index, max_index: INTEGER) is
          -- Keep only the slice [`min_index' .. `max_index'] or nothing
          -- when the slice is empty.
       require
          1 <= min_index;
          max_index <= count;
          min_index <= max_index + 1
       do
          if max_index < min_index then
             count := 0;
          elseif min_index = 1 then
             count := max_index;
          else
	     storage.copy_slice(0,storage,min_index - 1,max_index - 1);
	     count := max_index - min_index + 1
          end;
       ensure
          count = max_index - min_index + 1;
       end;

    remove(i: INTEGER) is
          -- Remove character at position `i'.
       require
          valid_removal_index: valid_index(i)
       do
          remove_between(i,i);
       ensure
          count = (old count) - 1
       end;

    add_first, precede(c: CHARACTER) is
          -- Add `c' at first position.
       local
          i: INTEGER;
       do
          from
             append_character(' ');
             i := count;
          until
             i = 1
          loop
             put(item(i - 1),i);
             i := i - 1;
          end;
          put(c,1);
       ensure
          count = 1 + old count;
          item(1) = c
       end;

    add_last, append_character, extend(c: CHARACTER) is
          -- Append `c' to string.
       local
          new_capacity: INTEGER;
       do
          if capacity > count then
          elseif capacity = 0 then
	     new_capacity := 32;
             storage := storage.calloc(new_capacity);
             capacity := new_capacity;
          else
             new_capacity := 2 * capacity;
             storage := storage.realloc(capacity,new_capacity);
             capacity := new_capacity;
          end;
          storage.put(c,count);
          count := count + 1;
       ensure
          count = 1 + old count;
          item (count) = c
       end;

    to_lower is
          -- Convert all characters to lower case.
       local
          i: INTEGER;
       do
          from
             i := count;
          until
             i = 0
          loop
             put(item(i).to_lower,i);
             i := i - 1;
          end;
       end;

    to_upper is
          -- Convert all characters to upper case.
       local
          i: INTEGER;
       do
          from
             i := count;
          until
             i = 0
          loop
             put(item(i).to_upper,i);
             i := i - 1;
          end;
       end;

    as_lower: like Current is
	  -- New object with all letters in lower case.
       do
          create Result.copy(Current);
          Result.to_lower;
       end;

    as_upper: like Current is
	  -- New object with all letters in upper case.
       do
          create Result.copy(Current);
          Result.to_upper;
       end;

    keep_head(n: INTEGER) is
	  -- Remove all characters except for the first `n'.
	  -- Do nothing if `n' >= `count'.
       require
          n_non_negative: n >= 0
       do
          if n < count then
             remove_last(count - n);
          end;
       ensure
          count = n.min(old count)
       end;

    keep_tail(n: INTEGER) is
	  -- Remove all characters except for the last `n'.
	  -- Do nothing if `n' >= `count'.
       require
          n_non_negative: n >= 0
       do
          if n < count then
             remove_first(count - n);
          end;
       ensure
          count = n.min(old count)
       end;

    remove_head, remove_first(n: INTEGER) is
          -- Remove `n' first characters.
          -- If `n' >= `count', remove all.
       require
          n_non_negative: n >= 0
       do
          if (n > count) then
             count := 0;
          else
             if n > 0 then
                remove_between(1, n)
             end;
          end;
       ensure
          count = (0).max((old count) - n)
       end;

    remove_tail, remove_last(n: INTEGER) is
          -- Remove `n' last characters.
          -- If `n' >= `count', remove all.
       require
          n_non_negative: n >= 0
       do
          if (n > count) then
             count := 0;
          else
             count := count - n;
          end;
       ensure
          count = (0).max(old count - n)
       end;

    remove_substring, remove_between(start_index, end_index: INTEGER) is
          -- Remove all characters from `strt_index' to `end_index' inclusive.
       require
          valid_start_index: 1 <= start_index
          valid_end_index: end_index <= count
          meaningful_interval: start_index <= end_index + 1
       local
          i, len: INTEGER;
       do
          len := end_index - start_index + 1;
          if (len > 0) then
             from
                i := end_index + 1;
             until
                i > count
             loop
                put(item(i), i - len);
                i := i + 1;
             end;
             count := count - len;
          end;
       ensure
          count = (old count) - (end_index - start_index + 1)
       end;

    remove_suffix(s: STRING) is
       -- Remove the suffix `s' of current string.
       require
          has_suffix(s)
       do
          remove_last(s.count);
       ensure
	  (old Current.twin).is_equal(Current + old s.twin)
       end;

    remove_prefix(s: STRING) is
       -- Remove the prefix `s' of current string.
       require
          has_prefix(s)
       do
          remove_first(s.count);
       ensure
	  (old Current.twin).is_equal(old s.twin + Current)
       end;

    left_adjust is
          -- Remove leading blanks.
       local
          i: INTEGER;
       do
          from
          until
             i + 1 > count or else item(i + 1) /= ' '
          loop
             i := i + 1;
          end;
          remove_first(i);
       ensure
          stripped: is_empty or else item (1) /= ' '
       end;

    right_adjust is
          -- Remove trailing blanks.
       do
          from
          until
             count = 0 or else item(count) /= ' '
          loop
             count := count - 1;
          end
       ensure
          stripped: is_empty or else item (count) /= ' '
       end;

feature -- Printing:

    out_in_tagged_out_memory is
       do
          tagged_out_memory.append(Current);
       end;

    fill_tagged_out_memory is
       do
          tagged_out_memory.append(once "count: ");
          count.append_in(tagged_out_memory);
          tagged_out_memory.append(once "capacity: ");
          capacity.append_in(tagged_out_memory);
          tagged_out_memory.append(once "storage: %"");
          tagged_out_memory.append(Current);
          tagged_out_memory.append_character('%"');
       end;

feature -- Other features:

    first: CHARACTER is
	  -- Access to the very `first' character.
       require
          not is_empty
       do
          Result := storage.item(0);
       ensure
	  definition: Result = item(1)
       end;

    last: CHARACTER is
	  -- Access to the very `last' character.
       require
          not is_empty
       do
          Result := storage.item(count - 1);
       ensure
	  definition: Result = item(count)
       end;

    substring(start_index, end_index: INTEGER): like Current is
          -- New string consisting of items [`start_index'.. `end_index'].
       require
          valid_start_index: 1 <= start_index;
          valid_end_index: end_index <= count;
          meaningful_interval: start_index <= end_index + 1
       local
	  c: INTEGER;
       do
	  c := end_index - start_index + 1;
	  !!Result.make(c);
	  Result.set_count(c);
          Result.storage.copy_slice(0, storage, start_index - 1, end_index - 1);
       ensure
          substring_count: Result.count = end_index - start_index + 1
       end;

    extend_multiple(c: CHARACTER; n: INTEGER) is
          -- Extend Current with `n' times character `c'.
       require
          n >= 0
       local
          i: INTEGER;
       do
          from
             i := n;
          until
             i = 0
          loop
             append_character(c);
             i := i - 1;
          end;
       ensure
          count = n + old count
       end;

    precede_multiple(c: CHARACTER; n: INTEGER) is
          -- Prepend `n' times character `c' to Current.
       require
          n >= 0
       local
          old_count: INTEGER;
       do
          if n > 0 then
             old_count := count;
             if old_count = 0 then
                extend_multiple(c,n);
             else
                extend_multiple('%U',n);
                storage.move(0,old_count - 1,n);
                storage.set_all_with(c,n - 1);
             end;
          end;
       ensure
          count = n + old count
       end;

    extend_to_count(c: CHARACTER; needed_count: INTEGER) is
          -- Extend Current with `c' until `needed_count' is reached.
          -- Do nothing if `needed_count' is already greater or equal
          -- to `count'.
       require
          needed_count >= 0
       local
          offset: INTEGER;
       do
          from
             offset := needed_count - count;
          until
             offset <= 0
          loop
             append_character(c);
             offset := offset - 1;
          end;
       ensure
          count >= needed_count
       end;

    precede_to_count(c: CHARACTER; needed_count: INTEGER) is
          -- Prepend `c' to Current until `needed_count' is reached.
          -- Do nothing if `needed_count' is already greater or equal
          -- to `count'.
       require
          needed_count >= 0
       local
          offset, old_count: INTEGER;
       do
          old_count := count;
          offset := needed_count - old_count;
          if offset > 0 then
             extend_to_count('%U',needed_count);
             storage.move(0,old_count - 1,offset);
             storage.set_all_with(c,offset - 1);
          end;
       ensure
          count >= needed_count
       end;

    reverse is
          -- Reverse the string.
       local
          i1, i2: INTEGER;
       do
          from
             i1 := 1;
             i2 := count;
          until
             i1 >= i2
          loop
             swap(i1,i2);
             i1 := i1 + 1;
             i2 := i2 - 1;
          end;
       end;

    remove_all_occurrences(ch: CHARACTER) is
          -- Remove all occurrences of `ch'.
       local
          i, j: INTEGER;
       do
          from
             i := 1;
             j := 1;
          until
             i > count
          loop
             if item(i) /= ch then
                put(item(i),j);
                j := j + 1;
             end;
             i := i + 1;
          end;
          count := j - 1;
       ensure
          count = old count - old occurrences(ch)
       end;

    substring_index(other: STRING; start_index: INTEGER): INTEGER is
          -- Position of first occurrence of `other' at or after `start';
          -- 0 if none.
       require
          other_not_void: other /= Void
          valid_start_index: start_index >= 1 and start_index <= count + 1
       local
          i, s: INTEGER;
       do
          from
             s := start_index;
          until
             Result /= 0 or else (s + other.count - 1) > count
          loop
             from
                i := 1;
             until
                i > other.count or else item(s + i - 1) /= other.item(i)
             loop
                i := i + 1;
             end;
             if i > other.count then
                Result := s;
             else
                s := s + 1
             end;
          end;
       end;

    first_substring_index(other: STRING): INTEGER is
          -- Position of first occurrence of `other' at or after 1;
          -- 0 if none.
       require
          other_not_void: other /= Void
       do
	  Result := substring_index(other,1);
       ensure
	  definition: Result = substring_index(other,1)
       end;

feature -- Splitting a STRING:

    split: ARRAY[STRING] is
          -- Split the string into an array of words. Uses `is_separator' of
          -- CHARACTER to find words. Gives Void or a non empty array.
       do
          if count > 0 then
             split_buffer.clear;
             split_in(split_buffer);
             if not split_buffer.is_empty then
                Result := split_buffer.twin;
             end;
          end;
       ensure
          Result /= Void implies not Result.is_empty
       end;

    split_in(words: COLLECTION[STRING]) is
          -- Same jobs as `split' but result is appended in `words'.
       require
          words /= Void
       local
          state, i: INTEGER;
          -- state = 0: waiting next word.
          -- state = 1: inside a new word.
          c: CHARACTER;
       do
          if count > 0 then
             from
                i := 1;
             until
                i > count
             loop
                c := item(i);
                if state = 0 then
                   if not c.is_separator then
                      string_buffer.clear;
                      string_buffer.append_character(c);
                      state := 1;
                   end;
                else
                   if not c.is_separator then
                      string_buffer.append_character(c);
                   else
                      words.add_last(string_buffer.twin);
                      state := 0;
                   end;
                end;
                i := i + 1;
             end;
             if state = 1 then
                words.add_last(string_buffer.twin);
             end;
          end;
       ensure
          words.count >= old (words.count)
       end;

feature -- Other features:

    extend_unless(ch: CHARACTER) is
          -- Extend `Current' (using `extend') with `ch' unless `ch' is
          -- already the `last' character.
       do
          if count = 0 or else item(count) /= ch then
             append_character(ch);
          end;
       ensure
          last = ch;
          count >= old count
       end;

    get_new_iterator: ITERATOR[CHARACTER] is
       do
          !ITERATOR_ON_STRING!Result.make(Current);
       end;

feature -- Interfacing with C string:

    to_external: POINTER is
          -- Gives C access to the internal `storage' (may be dangerous).
          -- To be compatible with C, a null character is added at the end
          -- of the internal `storage'. This extra null character is not
          -- part of the Eiffel STRING.
       do
          if capacity > count then
             count := count + 1;
             if item(count) /= '%U' then
                put('%U',count);
             end;
          else
             append_character('%U');
          end;
          count := count - 1;
          Result := storage.to_pointer;
       ensure
          count = old count;
          Result.is_not_null
       end;

    from_external(p: POINTER) is
          -- Internal `storage' is set using `p' (may be dangerous because
          -- the external C string `p' is not duplicated).
          -- Assume `p' has a null character at the end in order to
          -- compute the Eiffel `count'. This extra null character
          -- is not part of the Eiffel STRING.
          -- Also consider `from_external_copy' to choose the most appropriate.
       require
          p.is_not_null
       do
          from
             storage := storage.from_pointer(p);
             count := 0;
          until
             storage.item(count) = '%U'
          loop
             count := count + 1;
          end;
          capacity := count + 1;
       ensure
          capacity = count + 1;
          p = to_external
       end;

    from_external_copy, from_c(p: POINTER) is
          -- Internal `storage' is set using a copy of `p'.
          -- Assume `p' has a null character at the end in order to
          -- compute the Eiffel `count'. This extra null character
          -- is not part of the Eiffel STRING.
          -- Also consider `from_external' to choose the most appropriate.
       require
	  p.is_not_null
       local
          s: like storage; i: INTEGER;
       do
          from
             s := s.from_pointer(p);
	     count := 0;
          until
             s.item(i) = '%U'
          loop
             append_character(s.item(i));
             i := i + 1;
          end;
       end;

feature -- Other features here for ELKS compatibility:

    make_from_string(model: STRING) is
	  -- (Here for ELKS compatibility.)
          -- Initialize from the characters of `model'.
          -- Useful in proper descendants of STRING.
       require
          model /= Void
       local
	  c: INTEGER;
       do
	  c := model.count;
	  if capacity < c then
	     storage := storage.calloc(c);
	     capacity := c;
	  end;
	  count := c;
	  storage.copy_from(model.storage,c - 1);
       ensure
          count = model.count
       end;

    head(n: INTEGER) is
       obsolete "Since release -0.74, the new name for this feature is
`keep_head'."
       do
          keep_head(n);
       end;

    tail(n: INTEGER) is
       obsolete "Since release -0.74, the new name for this feature is
`keep_tail'."
       do
          keep_tail(n);
       end;

    same_string(other: STRING): BOOLEAN is
	  -- (Here for ELKS compatibility.)
	  -- Do `Current' and `other' have the same character sequence?
	  -- Useful in proper descendants of STRING.
       require
          other_not_void: other /= Void
       do
          Result := string.is_equal(other.string)
       end;

    string: STRING is
	  -- (Here for ELKS compatibility.)
          -- New STRING having the same character sequence as `Current'.
          -- Useful in proper descendants of STRING.
       do
          create Result.make_from_string(Current);
       end;

feature {STRING,TEXT_FILE_READ}

    set_count(new_count: INTEGER) is
       require
	  new_count <= capacity
       do
	  count := new_count;
       end;

feature {NONE}

    string_buffer: STRING is
	  -- Private, temporary once buffer.
       once
          create Result.make(256);
       end;

    split_buffer: ARRAY[STRING] is
       once
          create Result.with_capacity(4,1);
       end;

invariant

    0 <= count;

    count <= capacity;

    capacity > 0 implies storage.is_not_null;

end -- STRING

#4980 From: Greg Reagle <greagl1@...>
Date: Sat Jun 15, 2002 2:36 pm
Subject: please explain algorithm for large integers in NUMBER
greagl1@...
Send Email Send Email
 
I want to extract a BIG_INTEGER from NUMBER, but I need help understanding
the algorithm that NUMBER uses to store large integers.  I have looked at
the code, and I don't understand how it works.  Is the algorithm described
in an article or book or webpage?

The next paragraph is my motivation.

In my quest to make NUMBER NUMERIC and COMPARABLE, I discovered that it
could be done by making a wrapper class for NUMBER.  I have abandoned this
approach (because it requires a very big wrapper class that does nothing
but call the same features with an added level of indirection) in favor of
splitting NUMBER into a fraction class and a big number class.  I have
completed the fraction class, which is generic, and of course NUMERIC and
COMPARABLE.  FRACTION[INTEGER] works fine, and I hope that it will work
with FRACTION[BIG_INTEGER] too, but BIG_INTEGER doesn't exist yet.

--
Signature rotation provided by Signify v1.07.  See http://www.debian.org/.
  . . . as all experience proves, whenever temptations to evil are sufficiently
    strong and sufficiently frequent, men and women generally succumb to them.
                                 -- Aldous Huxley

#4979 From: Greg Reagle <greagl1@...>
Date: Sat Jun 15, 2002 2:23 pm
Subject: how about an object equality infix operator
greagl1@...
Send Email Send Email
 
I got this idea from ETL3.  There it's called infix "}={".  I call it "@=="
since SmallEiffel doesn't like "}={".

a @== b is equivalent to equal (a, b)

Here is my attempt to implement it (in class GENERAL):

    frozen infix "@==" (other: like Current): BOOLEAN is
       do
          Result := equal (Current, other)
       end

The only problem with this implementation is that the variable on the left
side of the operator (i.e. the target of the feature call, `Current')
cannot be Void or there will be a "*** Error at Run Time ***: Call with a
Void target."  In order to handle such a case, I think that the compiler
would have to be modified.

--
Signature rotation provided by Signify v1.07.  See http://www.debian.org/.
             For [some] . . . men the instruments of violence are as
            fearfully tempting as are, to others, the bodies of women.
                                 -- Aldous Huxley

#4978 From: Arno Wagner <wagner@...>
Date: Sat Jun 15, 2002 1:40 pm
Subject: Re: bug in string.is_integer
wagner@...
Send Email Send Email
 
On Sat, Jun 15, 2002 at 12:15:49AM -0300, Daniel F Moisset wrote:
> The method `is_integer' of class STRING returns True when applied to
> strings "+" and "-", which don't satisfy the grammar specified in tis
> header comment.
>
> the line
>          if state /= 0 and then state /= 4 then
> should be changed to
>          if state /= 0 and then state /= 4 and then state /= 1 then
>
>
>  Daniel F Moisset
>

True.

The state goes to 1, but the block for 1 is never executed
as i > count is true.

Thanks for the notice!


Dominique:

I suspect the same is true for is_double.
I'll correct this bug and send a corrected version
of string.e made from the current beta (b074beta22) today
or tomorrow.

Regards,
Arno
--
Arno Wagner, Communication Systems Group, ETH Zuerich, wagner@...
GnuPG:  ID: 1E25338F  FP: 0C30 5782 9D93 F785 E79C  0296 797F 6B50 1E25 338F
----
For every complex problem there is an answer that is clear, simple,
and wrong. -- H L Mencken

Messages 4978 - 5007 of 5007   Newest  |  < Newer  |  Older >  |  Oldest
Advanced
Add to My Yahoo!      XML What's This?

Copyright © 2009 Yahoo! Inc. All rights reserved.
Privacy Policy - Terms of Service - Guidelines - Help