#1 2011-06-30 14:26:04

Leander007
Member
From: Slovenia
Registered: 2011-04-29
Posts: 113

Internationalization

In unit SQLite3i18n at procedure ExtractAllResources is possible stack overflow!

More precisely this happens at iterative procedure AddClass when you use e.g. "Master/Detail" approach with TSQLRecordMany, which contains as  property "Source" object which contains this TSQLRecordMany...

My quick solution is that I check which classes were already iterated:

procedure ExtractAllResources(const EnumTypeInfo: array of pointer;
  const Objects: array of TObject; const Records: array of TClass;
  const CustomCaptions: array of WinAnsiString);
(...)
var F: Text;
    (...)
    clist: array of TClass;
    ccount: integer;

  procedure AddClass(C: TClass);
  var i,j: integer;
      (...)
      cfound: boolean;
  begin 
    if C=nil then
      exit; // no RTTI information (e.g. reached TObject level)

    cfound := false;
    for j:=0 to ccount-1 do
      if C = clist[j] then
      begin
        cfound := true;
        break;
      end;

    if not cfound then
    begin
      clist[ccount] := C;
      Inc(ccount);
      if Length(clist) = ccount then
        SetLength(clist, Length(clist) + 3);
    end;

    AddClass(C.ClassParent); // add parent properties first
    CP := InternalClassProp(C);
    if CP=nil then
      exit;

    P := @CP^.PropList;
    for i := 1 to CP^.PropCount do begin // add all field names
      AddOnceDynArray(WinAnsiString(TSQLRecord.CaptionName(@P^.ShortName)));
      // for Delphi 2009/2010/XE: CaptionName converted into a WinAnsiString
      with P^.PropType^^ do
      case Kind of
      tkClass:       // add contained objects
      begin
        cfound := false;
        for j:=0 to ccount - 1 do
          if ClassType^.ClassType = clist[j] then
          begin
            cfound := true;
            break;
          end;
        if not cfound then
          AddClass(ClassType^.ClassType);
      end;
(...)
begin
  // all code below use *A() Win32 API -> only english=Ansi text is expected here
  assign(F,ChangeFileExt(paramstr(0),'.messages'));
  SetLength(buf,65536);
  SetLength(clist, Length(Objects)+Length(Records));
  ccount := 0;
(...)

Last edited by Leander007 (2011-06-30 14:27:13)


"Uncertainty in science: There no doubt exist natural laws, but once this fine reason of ours was corrupted, it corrupted everything.", Blaise Pascal

Offline

#2 2011-07-20 06:39:34

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,700
Website

Re: Internationalization

My solution simply uses a TList:

  procedure AddClass(C: TClass);
  var i: integer;
      P: PPropInfo;
      CP: PClassProp;
  begin 
    if (C=nil) or (ClassList.IndexOf(C)>=0) then
      exit; // already done or no RTTI information (e.g. reached TObject level)
    ClassList.Add(C);
    AddClass(C.ClassParent); // add parent properties first
   (...)

I've also made several changes in the implementation (using a faster TDynArrayHashed for instance).

See http://synopse.info/fossil/info/4a4dd21806

Thanks for the feedback!

Offline

#3 2011-07-20 11:08:39

Leander007
Member
From: Slovenia
Registered: 2011-04-29
Posts: 113

Re: Internationalization

You have one small lapsus (which is show stopper smile) in SQLite3i18n at line 1904:

      text := ppi^.GetGenericStringValue(comp);

should be

      old := ppi^.GetGenericStringValue(comp);

"Uncertainty in science: There no doubt exist natural laws, but once this fine reason of ours was corrupted, it corrupted everything.", Blaise Pascal

Offline

#4 2011-07-20 14:23:58

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,700
Website

Re: Internationalization

Offline

Board footer

Powered by FluxBB