Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2007-10

Re: Re: fpc-devel Digest, Vol 40, Issue 16

7 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Daniël Mantione
to L: One thing that has come to my mind now is the exceptional raise calls in some of the…

Op Tue, 16 Oct 2007, schreef L:

Show quoted text 22 lines
> Let's first discuss a plan, then we'll see about the name. Suppose we put = > > everything that does something with paths and files in a unit: > > * Extractfilepath and friends > * Exec, findfirst, etc. > > ... then it could be called something like fsutils, "fs" from filesystem. > > So, let's first discuss the purpose of the unit and which functions = > > types will be in it. > > Dani=EBl > One thing that has come to my mind now is the exceptional raise calls in some of the functions. Some of the functions don't contain raise calls, which is great because they are automatically standalone capable as is. Functions without any raise calls AFAIR are ExtractFilePath and friends. Sysutils Functions like strtoint however have raise calls.

Yes, but there already exists a raise-less version of strtoint, called "val". So, there is IMO absolutely no need for an exceptionless version of strtoint in another unit.

What does a raise call rely on? I can play and find out, but maybe you know off hand.

Afaik it is a statement, therefore handled by the compiler.

Show quoted text 5 lines
The raise call can be ifdefed.. which gets messy, which is why I probably forked the unit.. because sometimes a forked duplicate function is easier to maintain than a single ifdefed function. Now it is all coming back to me. However, it isn't all bad news.. as I said many functions do not rely on raise and can be moved to fsutils immediately without any hassle.

Exactly, we should not put ifdefs into sysutils. This would useless anyway, since then the decision is made at compile time, and users generally don't compile sysutils themselves. I agree a forked unit can be easier to maintain on itself, but on the other hand it causes a serious problem for the maintenance of the project, since updates and bugfixes will have to be applied in two places. Therefore moving the implementation of some group of related functions, which you have an interrest in using, without being forced to have the exceptions as well, is the only sane way of handling this.

Show quoted text 6 lines
If a raise call can work in fsutils.pp somehow, that's the other option. I am not familiar with how raise calls work when you don't have a sysutils in the uses.. wasn't it one of the features added to fpc recently: the ability to use exceptions without sysutils some way? But would this require syntax changes anyhow, as a different style of raise is used when you don't have sysutils in uses?

There is no need for a raise call to work inside a fsutils. All that is needed is that sysutils raises an exception on an error condition, and this raise call can be in sysutils itself.

Compare again "inttostr". The actual implementation, "val", is in the system unit. The only thing sysutils does is that calls "val" and raises an exception on error.

Daniël

Reply by email

L
Show quoted text 15 lines
Let's first discuss a plan, then we'll see about the name. Suppose we put = everything that does something with paths and files in a unit: * Extractfilepath and friends * Exec, findfirst, etc. ... then it could be called something like fsutils, "fs" from filesystem. So, let's first discuss the purpose of the unit and which functions = types will be in it. Dani=EBl

One thing that has come to my mind now is the exceptional raise calls in some of the functions. Some of the functions don't contain raise calls, which is great because they are automatically standalone capable as is. Functions without any raise calls AFAIR are ExtractFilePath and friends. Sysutils

Functions like strtoint however have raise calls.

What does a raise call rely on? I can play and find out, but maybe you know off hand.

The raise call can be ifdefed.. which gets messy, which is why I probably forked the unit.. because sometimes a forked duplicate function is easier to maintain than a single ifdefed function. Now it is all coming back to me. However, it isn't all bad news.. as I said many functions do not rely on raise and can be moved to fsutils immediately without any hassle.

If a raise call can work in fsutils.pp somehow, that's the other option. I am not familiar with how raise calls work when you don't have a sysutils in the uses.. wasn't it one of the features added to fpc recently: the ability to use exceptions without sysutils some way? But would this require syntax changes anyhow, as a different style of raise is used when you don't have sysutils in uses?

One other quick thought... many of the algorithms are robust in sysutils and don't change. So duplicate code isn't the end of the world for short functions like StrToInt. i.e. one that uses sysutils exceptions and one that uses.. the other special non-sysutils exceptions recently implemented in fpc, or no exceptions.

Reply by email

L
Show quoted text 5 lines
Functions like strtoint however have raise calls. > Yes, but there already exists a raise-less version of strtoint, called > "val". So, there is IMO absolutely no need for an exceptionless version of > strtoint in another unit.

Of course we can use our own functions that emulate what is in the sysutils unit.. but if they aren't drop in replacements this means that code is broken and now we have to add Val calls and Str calls instead of just using a drop in replacement.

The str() and val() functions I use occasionally, and I know turbopascal programmers had to use them.. but they are not drop in replacements. One of the goals of compactsysutils was to be a drop in replacement. It is nice to be able to immediately convert a string to integer instead of using var params or OUT params. There is a way to build a StrToInt that still reports errors.. it returns a zero on error.

In KOL, Kladov also returns a zero with his Str2Int function if string is bad. You may be thinking.. but what if the string really is a zero and we want to know that it is?
Well then we can do this:
if (s = '0') or (StrToInt(s) 0) then writeln('S is an integer'); if StrToInt('SomeString') = 0 then writeln('s is not an integer');

Since the strtoint function is just a simple val call, we can maintain two copies if it. It's robust bone simple function that needs zero maintenance. So having two copies isn't an issue with it...

With other functions that use raise calls that are more complex.. then we worry more about the double maintenance for sure..

StrToInt may not fit in fsutils.pp since fsutils is for file system functions though?

So we'd have to make another unit. IntUtils.pp ... and another one for CompareText/Wraptext().. TxtUtils.pp

Or, instead of fsutils.pp we could have tinyutils.pp which didn't just have filesystem
functions, but others such as CompareText, WrapText, ExtractFilePath, StrToInt, etc.

I think the more units we add the more bytes we lose (not sure how many, but a namespace requires something.. premature optimization? Yes.. but still).

Show quoted text 5 lines
What does a raise call rely on? I can play and find out, but maybe you know off hand. > Afaik it is a statement, therefore handled by the compiler.

Sorry I meant.. how do you make an exception without using sysutils.. because we could use the raise statement for functions that have raise calls like wraptext/comparetext/strtoint.

I and err.pas to see how exceptions work without sysutils. That was just another idea for the strtoint function so that we wouldn't have to remove the raise call in intutils.pp or tinyutils.pp. But the returning zero option would remove need for raise altogether.

Just clear things up for other readers.. I'm not proposing we change any code in sysutils.. sysutils will remain delphi compatible.. so when I say remove raise call from strtoint.. I mean remove it in a duplicate funciton, not the original. Michael was worried about breaking delphi compat but this can't happen if we just make fsutils.wrapper() calls within sysutils original unit. Then in tinyutils.pp we make wrapper calls to intutils.pp and fsutils.pp so that tinyutils.pp doesn't use any of the sysutils interface stays the same.. it is illegal to break the sysutils contract.

Reply by email

L
Show quoted text 7 lines
In KOL, Kladov also returns a zero with his Str2Int function if string is bad. You may be thinking.. but what if the string really is a zero and we want to know that it is? Well then we can do this: if (s = '0') or (StrToInt(s) 0) then writeln('S is an integer'); if StrToInt('SomeString') = 0 then writeln('s is not an integer');

Rather..

var
  i: integer;
begin
  i:= StrToInt(s);
  if (s = '0') or (i  0) then
    writeln('S is an integer, and i is now: ', i)
  else
    writeln('S is not an integer: ', s);
end;

Alternatively:

function IsInteger(s: string; i: integer);
begin
  result:= false;
  if (s = '0') or (i  0) then result:= true;
end;
var
  i: integer;
begin
  i:= StrToInt(s);
  if IsInteger(s, i) then
    writeln('S was an integer')
  else
    writeln('S was not an integer: ', s);
end;

That's pseudo code.. I haven't of course checked it.

People can use Tinyutils.pp (IntUtils.pp) way of doing it as I show above.. or they can use sysutils and use try/except style coding. They just choose which to put in their uses clause.

Either tinyutils contains all the functions in one unit, such as ExtractFilePath, StrToInt,WrapText, CompareText.. or we separate it into several units such as:

IntUtils.pp (StrToInt, IntToStr, and others)
TextUtils/TxtUtils.pp (CompareText, WrapText, and others) fsutils.pp (ExtractFilePath and friends)

Or.. someone else may have better ideas for naming.

Reply by email

L
for functions that have raise calls like wraptext/comparetext/strtoint.

Spoke to soon.. it's good news for those functions. Looks like wraptext/comparetext are standalone anyway, according to what I see in compactsyutils on my svn.

So mainly its the strtoint strtobool functions that contain raise.

function sscanf also has raise. Not too worried about it.. it can stay in sysutils maybe.

Lars

Reply by email

Daniël Mantione
to L: Of course we can use our own functions that emulate what is in the sysutils unit.. but if…

y

Op Tue, 16 Oct 2007, schreef L:

Show quoted text 17 lines
> Functions like strtoint however have raise calls. > > Yes, but there already exists a raise-less version of strtoint, called > > "val". So, there is IMO absolutely no need for an exceptionless version of > > strtoint in another unit. Of course we can use our own functions that emulate what is in the sysutils unit.. but if they aren't drop in replacements this means that code is broken and now we have to add Val calls and Str calls instead of just using a drop in replacement. The str() and val() functions I use occasionally, and I know turbopascal programmers had to use them.. but they are not drop in replacements. One of the goals of compactsysutils was to be a drop in replacement. It is nice to be able to immediately convert a string to integer instead of using var params or OUT params. There is a way to build a StrToInt that still reports errors.. it returns a zero on error.

The whole reason why strtoint can work without var paramaters is that it throws as exception. You can only write e:=a(b(c(inttostr(d))) if you don't need to check an error condition.

If you have to check for the error condition, you can just as well use a var parameter. In short:

x:=strtoint(s);
if (s'0') and (x=0) then
  {handle error};
e:=a(b(c(x));

... is no improvement over:

val(s,x,code);
if code0 then
  {handle error};
e:=a(b(c(x));

Therefore, an exceptionless "strtoint" is not a drop in replacement, you need to recode your error handling. If you do so you can just as well replace it by val.

So, if you want to write e:=a(b(c(inttostr(d))); you have to pay the price
for exception handling.

Daniël

Reply by email

Florian Klaempfl
to L: Rather.. var i: integer; begin i:= StrToInt(s); if (s = '0') or (i 0) then writeln('S is…
Show quoted text 27 lines
I wrote: > In KOL, Kladov also returns a zero with his Str2Int function if string is bad. > You may be thinking.. but what if the string really is a zero and we want to > know that it is? > Well then we can do this: > if (s = '0') or (StrToInt(s) 0) then writeln('S is an integer'); > if StrToInt('SomeString') = 0 then writeln('s is not an integer'); > Rather.. var i: integer; begin i:= StrToInt(s); if (s = '0') or (i 0) then writeln('S is an integer, and i is now: ', i) else writeln('S is not an integer: ', s); end; Alternatively: function IsInteger(s: string; i: integer); begin result:= false; if (s = '0') or (i 0) then result:= true;

s can be 00 000 0000 etc. as well as +0 +00 etc.

Reply by email