fcl-res: memory management

Reintegrate fpcres-rc branch by Martok

git-svn-id: trunk@46386 -
This commit is contained in:
svenbarth 2020-08-12 19:06:12 +00:00
parent 8008f314b1
commit a2750fc5dc
4 changed files with 50 additions and 19 deletions

View File

@ -1,11 +1,9 @@
{%MainUnit rcparser.pas} {%MainUnit rcparser.pas}
{$modeswitch advancedrecords}
interface interface
uses uses
SysUtils, Classes, StrUtils, lexlib, yacclib, resource, SysUtils, Classes, StrUtils, Contnrs, lexlib, yacclib, resource,
acceleratorsresource, groupiconresource, stringtableresource, acceleratorsresource, groupiconresource, stringtableresource,
bitmapresource, versionresource, versiontypes, groupcursorresource; bitmapresource, versionresource, versiontypes, groupcursorresource;
@ -17,6 +15,7 @@ var
yyfilename: AnsiString; yyfilename: AnsiString;
yyparseresult: YYSType; yyparseresult: YYSType;
procedure DisposePools;
procedure SetDefaults; procedure SetDefaults;
procedure PragmaCodePage(cp: string); procedure PragmaCodePage(cp: string);
@ -137,11 +136,19 @@ begin
Result.v:= str_to_cbase(s); Result.v:= str_to_cbase(s);
end; end;
type
PStrPoolItem = ^TStrPoolItem;
TStrPoolItem = record
str: PUnicodeString;
next: PStrPoolItem;
end;
const const
MAX_RCSTR_LEN = 4096; MAX_RCSTR_LEN = 4096;
var var
strbuf: array[0..MAX_RCSTR_LEN + 1] of char; strbuf: array[0..MAX_RCSTR_LEN + 1] of char;
strbuflen: Integer; strbuflen: Integer;
stringpool: PStrPoolItem = nil;
procedure strbuf_begin(); procedure strbuf_begin();
begin begin
@ -161,10 +168,17 @@ begin
end; end;
procedure string_new(var str: rcstrtype; val: UnicodeString; cp: TSystemCodePage); procedure string_new(var str: rcstrtype; val: UnicodeString; cp: TSystemCodePage);
var
s: PStrPoolItem;
begin begin
New(str.v); New(str.v);
str.v^:= val; str.v^:= val;
str.cp:= cp; str.cp:= cp;
New(s);
s^.next:= stringpool;
s^.str:= str.v;
stringpool:= s;
end; end;
procedure string_new_uni(var str: rcstrtype; val: PAnsiChar; len: integer; cp: TSystemCodePage; escapes: boolean); procedure string_new_uni(var str: rcstrtype; val: PAnsiChar; len: integer; cp: TSystemCodePage; escapes: boolean);
@ -273,6 +287,8 @@ begin
r.LangID:= language; r.LangID:= language;
aktresources.Add(r); aktresources.Add(r);
aktresource:= r; aktresource:= r;
aId.Free;
aType.Free;
end; end;
procedure create_resource(aId, aType: TResourceDesc); overload; procedure create_resource(aId, aType: TResourceDesc); overload;
@ -398,4 +414,15 @@ begin
PragmaCodePage('DEFAULT'); PragmaCodePage('DEFAULT');
end; end;
procedure DisposePools;
var
s: PStrPoolItem;
begin
while stringpool <> nil do begin
s:= stringpool;
stringpool:= s^.next;
dispose(s^.str);
dispose(s);
end;
end;

View File

@ -88,16 +88,17 @@ begin
rcparser.yyfilename:= '#MAIN.RC'; rcparser.yyfilename:= '#MAIN.RC';
rcparser.SetDefaults; rcparser.SetDefaults;
SetTextCodePage(lexlib.yyinput, rcparser.opt_code_page); SetTextCodePage(lexlib.yyinput, rcparser.opt_code_page);
rcparser.yinclude.init(); rcparser.yinclude:= tyinclude.Create;
rcparser.yinclude.WorkDir:= aLocation; rcparser.yinclude.WorkDir:= aLocation;
rcparser.ypreproc.init(); rcparser.ypreproc:= typreproc.Create;
rcparser.ypreproc.Defines.Add('RC_INVOKED', ''); rcparser.ypreproc.Defines.Add('RC_INVOKED', '');
rcparser.aktresources:= aResources; rcparser.aktresources:= aResources;
if rcparser.yyparse <> 0 then if rcparser.yyparse <> 0 then
raise EReadError.Create('Parse Error'); raise EReadError.Create('Parse Error');
rcparser.ypreproc.done();
rcparser.yinclude.done();
finally finally
rcparser.DisposePools;
FreeAndNil(rcparser.ypreproc);
FreeAndNil(rcparser.yinclude);
end; end;
end; end;
@ -113,7 +114,6 @@ begin
end; end;
initialization initialization
TResources.RegisterReader('.fpcres',TRCResourceReader); TResources.RegisterReader('.rc',TRCResourceReader);
TResources.RegisterReader('.frs',TRCResourceReader);
end. end.

View File

@ -3,7 +3,7 @@
{$IFDEF INC_HEADER} {$IFDEF INC_HEADER}
type type
tyinclude = record tyinclude = class
const const
yi_maxlevels = 5; yi_maxlevels = 5;
var var
@ -18,8 +18,8 @@ type
WorkDir: string; WorkDir: string;
SearchPaths: TStringList; SearchPaths: TStringList;
public public
procedure init(); constructor Create;
procedure done(); destructor Destroy; override;
class function wrapone(): Boolean; static; class function wrapone(): Boolean; static;
function push(const incfile: ansistring): Boolean; function push(const incfile: ansistring): Boolean;
function pop(): Boolean; function pop(): Boolean;
@ -103,16 +103,18 @@ begin
yyerror('Invalid include directive: "'+fn+'"'); yyerror('Invalid include directive: "'+fn+'"');
end; end;
procedure tyinclude.init(); constructor tyinclude.Create;
begin begin
inherited;
level:= 0; level:= 0;
WorkDir:= GetCurrentDir; WorkDir:= GetCurrentDir;
SearchPaths:= TStringList.Create; SearchPaths:= TStringList.Create;
end; end;
procedure tyinclude.done(); destructor tyinclude.Destroy;
begin begin
FreeAndNil(SearchPaths); FreeAndNil(SearchPaths);
inherited;
end; end;
{$ENDIF} {$ENDIF}

View File

@ -3,7 +3,7 @@
{$IFDEF INC_HEADER} {$IFDEF INC_HEADER}
type type
typreproc = record typreproc = class
const const
yp_maxlevels = 16; yp_maxlevels = 16;
var var
@ -12,8 +12,8 @@ type
cheadermode: boolean; cheadermode: boolean;
level : longint; level : longint;
public public
procedure init(); constructor Create;
procedure done(); destructor Destroy; override;
function isdefine(ident: string): boolean; function isdefine(ident: string): boolean;
function getdefine(ident: string): string; function getdefine(ident: string): string;
function useline(line: string): boolean; function useline(line: string): boolean;
@ -25,17 +25,19 @@ var
{$ELSE} {$ELSE}
procedure typreproc.init(); constructor typreproc.Create;
begin begin
inherited;
Defines:= TFPStringHashTable.Create; Defines:= TFPStringHashTable.Create;
level:= 0; level:= 0;
cheadermode:= false; cheadermode:= false;
fillchar(skip,sizeof(skip),0); fillchar(skip,sizeof(skip),0);
end; end;
procedure typreproc.done(); destructor typreproc.Destroy;
begin begin
FreeAndNil(Defines); FreeAndNil(Defines);
inherited;
end; end;
function Copy2SpaceDelTrim(var s: string): string; function Copy2SpaceDelTrim(var s: string): string;