Mahdi Safsafi
Members-
Content Count
383 -
Joined
-
Last visited
-
Days Won
10
Everything posted by Mahdi Safsafi
-
There are many reasons : - This is a good place where using RegEx makes sense. - RegEx interacts perfectly with UDB. Eg: '^[\p{Arabic}\p{P}A-Za-z0-9\s]+$'. How someone can represent \p{P}, \p{Arabic} smoothly when doing hand-writing ? - In many times(but not always), RegEx can outperform a hand writing function specially if you compile them. I didn't test but I believe RegEx-solution performs better than your hand-writing-solution. - RegEx is much faster for typing and reading. - Extending a RegEx pattern is much simple than extending a function. - ... AFAIK, RegEx do not rely on OS. They have their own DB.
-
For curiosity, why are you mixing arabic with latin letters. Does such ArabicLatin word make sense for you?
-
You need to match EOS "$": if Regexs.IsMatch(astr, '^[ء-ي-A-Z-a-z-0-9 ]+$') then // match fro the begining to the end of astr
-
Is that what you want ? procedure TForm1.FormCreate(Sender: TObject); type TControlHack = type TControl; begin TControlHack(pgc1).Color := clWindow; end;
-
Possible custom Format types?
Mahdi Safsafi replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
@Mike Torrettinni I don't know if this going to help. A while ago I wrote a regular expression to match the following pattern ""%" [index ":"] ["-"] [width] ["." prec] type" for format %((\d+|\*)\:)?[\-]?(\d+|\*)?(\.(\d+|\*))?[duefgnmpsx] The regex was used with Perl but I believe its still compatible with PCRE like. -
And that's not your first time when you show un-professionalism behavior(remember last time) ! I believe that I never showed disrespect for anyone here. All what I did is argumenting. So I really don't know why you think that disagree with someone is an attack ! And telling someone that he is not a judge, I think that's not an attack ... is it ? Go on all those posts, I challenge you to prove that its me who started a discussion ! For this post, I gave an explanation to the bug, as well as an answer, I was argumenting with some people peacefully ... until some people started provocating me! So please don't be driven by your subjectivity and try to view things neutrally. Peace.
-
Prove it ! FYI, the vcl core is calling CM_RECREATEWND directly. You're not the judge here ! Don't speak on his name. He is definitely able/free to explain what he means ! David tell your friends there is no need to interfere ... I really started thinking you guys are making a kind of gang here.
-
Yes, I make a lot of choice based on implementation details ! don't you ? Simply you didn't convince me (it requires more than words to convince someone) ! Do you use "perverse" each time you disagree with someone ?
-
I wish if you were right ... but things are much much more complex than that. E.g : sometimes there is an official mechanism but you choose message instead because you don't want the official mechanism to perform a paint for example ... there is a lot of those examples. I didn't take any dependency (please read my example again) ! When you know that the handle is allocated, its just pointless to call RecreateWnd instead of CM_RECREATEWND. procedure Main.StyleChanged; begin // I won't be here if handle is empty. // Perform(CM_RECREATEWND, ...); // VCL core is using the same Principle too ... take a look at Vcl.Forms,... (there are call to Perform(CM_RECREATEWND) instead of RecreateWnd). end;
-
We have plenty of private implementation specific message (CM_XX) should we make XX() for each ? FYI, there is no concept of private/protected for messages. Messages are public ! I'd understand if the logic was implemented in RecreateWnd but that's not the case here !
-
For Main form that's not necessary. RecreateWnd is useful when creating dynamic controls as you don't know when there would be the handle available.
-
@Janek.d Remember that's not the proper way ! So please report the bug at QC.
-
One more memory leak and FastMM4
Mahdi Safsafi replied to Alberto Paganini's topic in RTL and Delphi Object Pascal
Obviously its a typos (read again Remy explanation). I believe he means : LJSONValueObj := TJSONObject.ParseJSONValue(IdHTTP.Post(URL_LOGIN, sList)); try if LJSONValueObj is TJSONObject then begin LJSONObject := TJSONObject(LJSONValueObj); {$IFDEF VER230} LJSONPair := LJSONObject.Get('token'); if LJSONPair <> nil then LJSONValue := LJSONPair.JsonValue else LJSONValue := nil; {$ELSE} LJSONValue := LJSONObject.Values['token']; {$ENDIF} if LJSONValue <> nil then FToken := LJSONValue.Value; end; finally LJSONValueObj.Free; end; -
The problem is that TFormStyleHook uses a cached version of Icon(See TFormStyleHook .GetIconFast ). Once the StyleHook is attached to a form it makes a cached copy of its icon. However it does not update the cache when you change the icon. This is a bug ! Until we have a fix, you may need to recreate the window handle in order to change the icon. main_form.Icon.LoadFromFile(ico_file); main_form.Perform(CM_RECREATEWND, 0, 0);
-
I made a quick test that uses buttons with hints and empty hints ... and it worked just fine on Delphi 10.3. Perhaps the issue is on your Delphi (can you give more details about your version, are you using vcl-style ?,...). Something like this ? procedure CheckEmptyHint(AComponent: TComponent); var LComponent: TComponent; LControl: TControl; begin if (AComponent is TControl) then begin LControl := TControl(AComponent); if LControl.ShowHint and (LControl.Hint = EmptyStr) then Main.Memo1.Lines.Add(Format('%s has empty hint property.', [AComponent.Name])); end; for LComponent in AComponent do CheckEmptyHint(LComponent); end; // CheckEmptyHint(Application);
-
@Attila Kovacs do it like this "(PWord(P + i)^ xor PWord(fc + i)^) = 0" this is better than (P + i)^ = (fc + i)^
-
-- command line It should work after all its just a two-byte type.
-
I use pyscripter version. FYI guys, pyscripter is one of the best developers that knows how to correctly maintain/extend 3rd party library.
-
Your new version rocks ! it passed all the cases, except this: LineBreak = '--'; Text = LineBreak; LIST.COUNT= EXPECT(0) GOT(1) Great job 🙂 Perhaps you can use xor operator to handle LinebreakLength when its in [1,2,3,4]: case length (linebreak) of 1: b := (PWord(P + i)^ xor PWord(fc + i)^) = 0; 2,3,4:... else for ...
-
Should Delphi have native interfaces?
Mahdi Safsafi replied to Koru's topic in RTL and Delphi Object Pascal
I'm not aware about Scala but is this like what java does with default implementation for interface ? -
@Kas Ob Performance is not always related to conditional jump. I made a quick optimization on SetTextStr, bellow is my implementation and it uses jcc heavy but outperforms original/Attila algo. You can use jcc to make your own prediction (cheat and step): // this algo can be optimized further // requires length(LineBreak) > 1 procedure TStringList2.SetTextStr(const Value: string); label Again; var P, PStart, PEnd: PChar; s: string; FirstLineBreakChar: Char; LastLineBreakChar: Char; LineBreakLength: integer; TextLength: integer; PMax: PChar; function IsBreak(PC: PChar): Boolean; var P: PChar; begin P := PChar(LineBreak); while (P^ <> #00) do begin if P^ <> PC^ then Exit(False); inc(P); inc(PC); end; Result := True; end; begin LineBreakLength := Length(LineBreak); if (LineBreakLength = 1) or (LineBreak = sLineBreak) then begin // this algo does not handle LineBreakLength = 1 inherited end else begin BeginUpdate(); try Clear(); FirstLineBreakChar := LineBreak[1]; LastLineBreakChar := LineBreak[LineBreakLength]; TextLength := Length(Value); P := PChar(Value); PStart := P; PEnd := P + TextLength; if P^ <> #00 then begin Again: // skip all non important char: while (P^ <> FirstLineBreakChar) and (P^ <> #00) do inc(P); PMax := P + LineBreakLength; // either null or FirstLineBreakChar. if (PMax < PEnd) then begin // current char = FirstLineBreakChar ... could be a line break ! if (P[LineBreakLength - 1] = LastLineBreakChar) then begin // there is a hight chance that its a linebreak ! if IsBreak(P) then begin // this is a linebreak. SetString(s, PStart, P - PStart); Add(s); PStart := P + LineBreakLength; end; end; inc(P, LineBreakLength); // eat all processed chars... goto Again; end else begin if (P > PStart) then begin SetString(s, PStart, P - PStart); Add(s); end else if (P = PStart) then begin // didn't move. if (PMax <> PEnd) then begin SetString(s, PStart, PEnd - PStart); Add(s); end; end; end; end; finally EndUpdate(); end; end; end; @Attila Kovacs Note that the original implementation and yours do not handle correctly trailing.
-
@Attila Kovacs He is really a good guy ... I'd understand if he kicked us. Indeed ! BTW, AChar is de-referenced twice ! try to declare a local CH that holds AChar^ "var Ch: Char := AChar^", this may improve a little bit your function. You're right ! that's some how difficult to cover all your logic.
-
How to get pointer to record at the top of TStack<T>
Mahdi Safsafi replied to Dave Novo's topic in RTL and Delphi Object Pascal
My bad, I didn't understood you correctly. As I mentioned before, you can still use @stk.List[value] to get a pointer of your record without copying the data. -
How to get pointer to record at the top of TStack<T>
Mahdi Safsafi replied to Dave Novo's topic in RTL and Delphi Object Pascal
Hmmm that depends on him e.g : stk.count - 1 ; 0 ; 1 .... -
How to get pointer to record at the top of TStack<T>
Mahdi Safsafi replied to Dave Novo's topic in RTL and Delphi Object Pascal
He wrote "@stk.Peek" and I understood that he wanted the address of the peeked value.