Re: [fpc-pascal] TMaskUtils.ValidateInput function: how is it supposed to behave?

2016-04-28 Thread Bart
On 4/18/16, Michael Van Canneyt  wrote:

> I think Bart meant that the maskutils unit should simply use unicodestring.
> Given that it almost surely will need to deal with $ and € etc, that seems
> like a better approach.

FWIW an unicode version for testing attached.

Bart


umaskutils.pp
Description: Binary data
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] TMaskUtils.ValidateInput function: how is it supposed to behave?

2016-04-19 Thread Bart
On 4/18/16, Luiz Americo Pereira Camara  wrote:

> I propose to write a test suite first with the desired output, based on
> Delphi.
>

I agree with the concept, but:
Please note that Delphi (AFAICS) does not have a TMaskUtils class.
The behaviour of TMaskEdit (and hence methods like ApplyMaskToText)
has been tested quit vigorously agains the behaviour of Delphi 3.
It is near 100% compatible.

So, since Delphi only publishes FormatMaskText function, this is all
we can compare.
The other 2 functions we have in the interface are only used
internally by Delphi if I understand correctly (from some old
fpc-devel mails), so there behaviour is an imlementation detail.

The Delphi docs on FormatMaskText don't clarify much about how it must behave.

Bart
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] TMaskUtils.ValidateInput function: how is it supposed to behave?

2016-04-18 Thread Graeme Geldenhuys
On 2016-04-18 19:26, Luiz Americo Pereira Camara wrote:
> I propose to write a test suite first with the desired output, based on
> Delphi.

Fantastic idea! Test Driven Development - the best way to write any
software.


Regards,
  Graeme

-- 
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

My public PGP key:  http://tinyurl.com/graeme-pgp
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] TMaskUtils.ValidateInput function: how is it supposed to behave?

2016-04-18 Thread Michael Van Canneyt



On Mon, 18 Apr 2016, Luiz Americo Pereira Camara wrote:


2016-04-18 13:47 GMT-03:00 Bart :

[..]


The internal processing of the (edit)mask is the same as TMaskEdit.
If that is broken somehow, it is also broken in TMaskEdit.

The only functions that may need adjustments are

* function FormatMaskText(const EditMask: string; const AValue: string):
string;
* function FormatMaskInput(const EditMask: string): string;
* function MaskDoFormatText(const EditMask: string; const AValue: string;
   ASpaceChar: Char): string;
* function TMaskUtils.TryValidateInput(out ValidatedString: String):
Boolean;

But since there is no real documentation and there is no test suite,
it's hard to tell if they do not function as they should or introduce
regressions.



I propose to write a test suite first with the desired output, based on
Delphi.


I agree 100%



Given that the implementation becomes a detail, subject to changes in
future.

I can take the duty of starting, just need to know the format. fpcunit or
plain tests like most fpc tests?


fpcunit. 'most fpc tests' are for the compiler, not for unit functionality.

Michael.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] TMaskUtils.ValidateInput function: how is it supposed to behave?

2016-04-18 Thread Luiz Americo Pereira Camara
2016-04-18 13:47 GMT-03:00 Bart :

[..]

> The internal processing of the (edit)mask is the same as TMaskEdit.
> If that is broken somehow, it is also broken in TMaskEdit.
>
> The only functions that may need adjustments are
>
> * function FormatMaskText(const EditMask: string; const AValue: string):
> string;
> * function FormatMaskInput(const EditMask: string): string;
> * function MaskDoFormatText(const EditMask: string; const AValue: string;
>ASpaceChar: Char): string;
> * function TMaskUtils.TryValidateInput(out ValidatedString: String):
> Boolean;
>
> But since there is no real documentation and there is no test suite,
> it's hard to tell if they do not function as they should or introduce
> regressions.
>
>
I propose to write a test suite first with the desired output, based on
Delphi.

Given that the implementation becomes a detail, subject to changes in
future.

I can take the duty of starting, just need to know the format. fpcunit or
plain tests like most fpc tests?

Luiz
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] TMaskUtils.ValidateInput function: how is it supposed to behave?

2016-04-18 Thread Bart
On 4/18/16, Michael Van Canneyt  wrote:

> I think Bart meant that the maskutils unit should simply use unicodestring.
> Given that it almost surely will need to deal with $ and € etc, that seems
> like a better approach.

Yep.
In UTF8 the 1 on 1 relation between the internal mask structure and
the content of Value gets lost.
In LCL's MaskEdit unit this is solved by assuming all string data is UTF8.
(We convert the result from the widgetset to UTF8 explicitely)
The MaskEdit unit has routines (GetCodePoint/SetCodePoint) that rely
on routines in LazUtf8 in order to match a position of a codepoint to
a position in the internal mask.
This cannot be done in pure fpc, so a TMaskUtils based on AnsiChar can
only function with single byte encoding (as it is now, so that doesn't
break anything)..
(UTF8 might even work if no case conversion is used in the mask, I
have not tested).

I attach an alterative _maskutils unit, which basically uses the same
approach as TMaskEdit, but without the UTF8 support.
Rewriting this to use WideChar and UnicodeString should be very easy.

The internal processing of the (edit)mask is the same as TMaskEdit.
If that is broken somehow, it is also broken in TMaskEdit.

The only functions that may need adjustments are

* function FormatMaskText(const EditMask: string; const AValue: string): string;
* function FormatMaskInput(const EditMask: string): string;
* function MaskDoFormatText(const EditMask: string; const AValue: string;
   ASpaceChar: Char): string;
* function TMaskUtils.TryValidateInput(out ValidatedString: String): Boolean;

But since there is no real documentation and there is no test suite,
it's hard to tell if they do not function as they should or introduce
regressions.

Note; I did not find any reference to use of MaskUtils in FreePascal
itself, except for the uses clause in the db uit (where I did not find
any reference to the above mentioned functions).

Q: Would changing the implementation to UnicodeString introduce
regressions or compilation errors for existing programs using this
unit?
(It'll probably give warnings about possible data loss due to implicit
conversions.)

Bart
{
 /***
  maskutils.pas
  -

 ***/

 *
 *   *
 *  This file is part of the Lazarus Component Library (LCL) *
 *   *
 *  See the file COPYING.modifiedLGPL, included in this distribution,*
 *  for details about the copyright. *
 *   *
 *  This program 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. *
 *   *
 *


 Author: Bart Broersma

}


unit _maskutils;

{$mode objfpc}{$H+}
{.$define DebugMaskUtils}

interface

uses
  Classes, SysUtils;


function FormatMaskText(const EditMask: string; const AValue: string): string;
function FormatMaskInput(const EditMask: string): string;
function MaskDoFormatText(const EditMask: string; const AValue: string; ASpaceChar: Char): string;


type
  TEditMask = type string;
  TMaskeditTrimType = (metTrimLeft, metTrimRight);

  { Type for mask (internal) }
  tMaskedType = (Char_Start,
 Char_Number,
 Char_NumberFixed,
 Char_NumberPlusMin,
 Char_Letter,
 Char_LetterFixed,
 Char_LetterUpCase,
 Char_LetterDownCase,
 Char_LetterFixedUpCase,
 Char_LetterFixedDownCase,
 Char_AlphaNum,
 Char_AlphaNumFixed,
 Char_AlphaNumUpCase,
 Char_AlphaNumDownCase,
 Char_AlphaNumFixedUpCase,
 Char_AlphaNumFixedDownCase,
 Char_All,
 Char_AllFixed,
 Char_AllUpCase,
 Char_AllDownCase,
 Char_AllFixedUpCase,
 Char_AllFixedDownCase,
 Char_HourSeparator,
 Char_DateSeparator,
 Char_Stop);


{ TMaskUtils }

type
  TMaskUtils = class(TObject)
  private
FRealMask: String;
FMask: String;  // internal representatio of the mask
FValue: String;
FMaskLength: Integer;
FMaskSave: Boolean;
FSpaceChar: Char;
FTrimTyp

Re: [fpc-pascal] TMaskUtils.ValidateInput function: how is it supposed to behave?

2016-04-18 Thread Michael Van Canneyt



On Mon, 18 Apr 2016, Graeme Geldenhuys wrote:


On 2016-04-18 15:51, Bart wrote:

Maybe a version of maskutils unit based on UnicodeString should also
be made?


This seems so redundant. I still need to study the new FPC 3.0 string
handling, but I was hoping such duplication of implementations would not
be necessary with newer FPC versions. We don't see such rubbish
[duplication of code with various string types] in Java or C# or Qt, so
why must we put up with it in Object Pascal.


I think Bart meant that the maskutils unit should simply use unicodestring.
Given that it almost surely will need to deal with $ and € etc, that seems
like a better approach.


Michael.___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] TMaskUtils.ValidateInput function: how is it supposed to behave?

2016-04-18 Thread Graeme Geldenhuys
On 2016-04-18 15:51, Bart wrote:
> Maybe a version of maskutils unit based on UnicodeString should also
> be made?

This seems so redundant. I still need to study the new FPC 3.0 string
handling, but I was hoping such duplication of implementations would not
be necessary with newer FPC versions. We don't see such rubbish
[duplication of code with various string types] in Java or C# or Qt, so
why must we put up with it in Object Pascal.

Regards,
  Graeme

-- 
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

My public PGP key:  http://tinyurl.com/graeme-pgp
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] TMaskUtils.ValidateInput function: how is it supposed to behave?

2016-04-18 Thread Bart
On 4/18/16, Bart  wrote:

>> I recently did some work on it; the class works completely wrong IMO, and

As a side note:
function ValidateInput : string;

The function raises an exception upon failure.
Since we did not have to follow Delphi here, a better declaration IMHO
would have been:
function ValidateInput (out ValidatedString: string): Boolean;

or as a pair of functions (like the conversion routines for strings):

function ValidateInput : string;
function TryValidateInput (out ValidatedString: string): Boolean;

Bart
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] TMaskUtils.ValidateInput function: how is it supposed to behave?

2016-04-18 Thread Bart
On 4/18/16, Michael Van Canneyt  wrote:

> I recently did some work on it; the class works completely wrong IMO, and I
> though to replace it completely with the functions found in the LCL.

Yep, I was going that way too (and started coding it so).
Currently FormatMaskText from maskedit (LCL) behaves better than the
one from maskutils.

The LCL implementation handles UTF8, the fpc's will (also with code
ported form LCL) only handle single byte encoding.

Maybe a version of maskutils unit based on UnicodeString should also be made?

Bart
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] TMaskUtils.ValidateInput function: how is it supposed to behave?

2016-04-18 Thread Michael Van Canneyt



On Sun, 17 Apr 2016, Bart wrote:


Hi,

I cannot find any documentation about TMaskUtils.ValidateInput
function (unit MaskUtils).
AFAICS Delphi does not have such a class?
(ref: http://docwiki.embarcadero.com/Libraries/XE6/en/System.MaskUtils)

There are some bugreports about this unit in Mantis which got me interested.


I recently did some work on it; the class works completely wrong IMO, and I
though to replace it completely with the functions found in the LCL.

Michael.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


[fpc-pascal] TMaskUtils.ValidateInput function: how is it supposed to behave?

2016-04-17 Thread Bart
Hi,

I cannot find any documentation about TMaskUtils.ValidateInput
function (unit MaskUtils).
AFAICS Delphi does not have such a class?
(ref: http://docwiki.embarcadero.com/Libraries/XE6/en/System.MaskUtils)

There are some bugreports about this unit in Mantis which got me interested.

See the attached demo program.

It outputs:
C:\Users\Bart\LazarusProjecten\ConsoleProjecten\bugs\maskutils>mutest
Mask : "###"
Value: "ABCD"
VI   : "   "   (Shouldn't this fail?)

Mask : "999"
Value: "ABCD"
VI   : "   "   (Shouldn't this fail?)

Mask : "000"
Value: "ABCD"
ValidateInput Failed

Mask : "LLL"
Value: "1234"
ValidateInput Failed

Mask : "lll"
Value: "1234"
VI   : "   "   (Shouldn't this fail?)

Mask : "AAA"
Value: "[{|/"
ValidateInput Failed

Mask : "aaa"
Value: "[{|/"
VI   : "   "   (Shouldn't this fail?)

I am the maintainer of the Lazarus MaskEdit unit.
I find the results rather confusing and inconsistent with
Lazarus/Delphi MaskEdit behaviour.

Note:
When the mask contains mask-characters that mean "value must be of
type XYZ, but not required" the ValidateInput accepts any input.
The same characters in MaskEdit (both Lazarus and Delphi) interpret
this as: "if you put anything in that place it must be of type XYZ,
but you may leave this place empty (e.g. a blank)".
Basically ValidateInput now treats '#', '9', 'l' and 'a' as if it were
'c' (any character allowed here). This seems wrong to me.

However, since the function lacks any documentation one can argue that
current behaviour is correct.

To me the (IMO more logical) behaviour of the ValidateInput function
could be described as the result of these actions in a LCL/VCL
program:

- have a MaskEdit1: TMaskEdit
- do MaskEdit1.EditMask := Mask
- do MaskEdit1.Text := Value
- do MaskEdit1.ValidateEdit
- if no exception is raised then the result will be
MaskEdit1.EditText, but with all "SpaceChar" repkaced by #32.

I.o.w. the function shall raise an exception it Value (after appllying
Mask to it) does NOT match the Mask.

So, is it a bug?
If so, I'll open a ticket in Mantis for it (and the discussion should
then move there).

Bart


mutest.lpr
Description: Binary data
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal