mirror of https://github.com/red-prig/fpPS4.git
728 lines
15 KiB
Plaintext
728 lines
15 KiB
Plaintext
|
|
uses
|
|
Classes,
|
|
SysUtils;
|
|
|
|
type
|
|
TChars=Set of AnsiChar;
|
|
|
|
Function CountOf(var Value:RawByteString;Delimiters:TChars):SizeUInt;
|
|
Var
|
|
i:SizeUInt;
|
|
begin
|
|
Result:=0;
|
|
if Length(Value)>0 then
|
|
begin
|
|
For i:=1 to Length(Value) do
|
|
begin
|
|
if (Value[i] in Delimiters) then Inc(Result);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure DelChars(var Value:RawByteString;Delimiters:TChars);
|
|
Var
|
|
i:SizeUInt;
|
|
begin
|
|
if Length(Value)>0 then
|
|
begin
|
|
i:=1;
|
|
While (i<=Length(Value)) do
|
|
begin
|
|
if (Value[i] in Delimiters) then
|
|
begin
|
|
System.Delete(Value,i,1);
|
|
end else
|
|
begin
|
|
Inc(i);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function SpaceChars(b:byte;ch:char):RawByteString;
|
|
begin
|
|
SetLength(Result,b);
|
|
FillChar(Result[1],b,ch);
|
|
end;
|
|
|
|
procedure TrimComm(var Value:RawByteString;Delimiters:TChars);
|
|
Var
|
|
i:SizeUInt;
|
|
begin
|
|
if Length(Value)>0 then
|
|
begin
|
|
For i:=1 to Length(Value) do
|
|
begin
|
|
if (Value[i] in Delimiters) then
|
|
begin
|
|
System.Delete(Value,i,Length(Value)-i+1);
|
|
Exit;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function FetchAny(var Value:RawByteString;Delimiters,Quotations:TChars):RawByteString;
|
|
Var
|
|
i:SizeUInt;
|
|
Quote:AnsiChar;
|
|
State:Byte;
|
|
begin
|
|
Result:='';
|
|
Quote:=#0;
|
|
State:=0;
|
|
if Length(Value)>0 then
|
|
begin
|
|
For i:=1 to Length(Value) do
|
|
begin
|
|
case State of
|
|
0:begin
|
|
if (Value[i] in Quotations) then
|
|
begin
|
|
State:=2;
|
|
Quote:=Value[i];
|
|
end else
|
|
if (Value[i] in Delimiters) then
|
|
begin
|
|
|
|
end else
|
|
begin
|
|
Result:=Result+Value[i];
|
|
State:=1;
|
|
end;
|
|
end;
|
|
1:begin
|
|
if (Value[i] in Quotations) then
|
|
begin
|
|
State:=2;
|
|
Quote:=Value[i];
|
|
end else
|
|
if (Value[i] in Delimiters) then
|
|
begin
|
|
System.Delete(Value,1,i);
|
|
Exit;
|
|
end else
|
|
begin
|
|
Result:=Result+Value[i];
|
|
end;
|
|
end;
|
|
2:begin
|
|
if Value[i]=Quote then
|
|
begin
|
|
State:=3;
|
|
end else
|
|
begin
|
|
Result:=Result+Value[i];
|
|
end;
|
|
end;
|
|
3:begin
|
|
if Value[i]=Quote then
|
|
begin
|
|
State:=2;
|
|
Result:=Result+Quote;
|
|
end else
|
|
if (Value[i] in Delimiters) then
|
|
begin
|
|
System.Delete(Value,1,i);
|
|
Exit;
|
|
end else
|
|
begin
|
|
State:=1;
|
|
Quote:=#0;
|
|
Result:=Result+Value[i];
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
Value:='';
|
|
end;
|
|
end;
|
|
|
|
type
|
|
TEnum=class(TStringList)
|
|
public
|
|
name:RawByteString;
|
|
namelen:SizeUInt;
|
|
pre :RawByteString;
|
|
post:RawByteString;
|
|
end;
|
|
|
|
var
|
|
EnumList:TStringList;
|
|
|
|
function FixFieldName(const S:RawByteString):RawByteString;
|
|
begin
|
|
Case S of
|
|
'type' ,
|
|
'label',
|
|
'file' ,
|
|
'a' ,
|
|
'v' ,
|
|
's' :Result:='_'+S;
|
|
else
|
|
Result:=S;
|
|
end;
|
|
end;
|
|
|
|
function FixFuncName(const S:RawByteString):RawByteString;
|
|
begin
|
|
Case S of
|
|
'vop_lock1':Result:='vop_lock';
|
|
else
|
|
Result:=S;
|
|
end;
|
|
end;
|
|
|
|
Procedure load_if(const fname:RawByteString);
|
|
var
|
|
L:TStringList;
|
|
i,x:Integer;
|
|
S,Name:RawByteString;
|
|
|
|
pre,post:RawByteString;
|
|
releflags:RawByteString;
|
|
vpp_offset:RawByteString;
|
|
rele:ptruint;
|
|
|
|
F:THandle;
|
|
|
|
Enum:TEnum;
|
|
|
|
state:Integer;
|
|
|
|
links,maxlen:SizeUInt;
|
|
vpnum:Integer;
|
|
begin
|
|
EnumList:=TStringList.Create;
|
|
|
|
state:=0;
|
|
pre :='';
|
|
post:='';
|
|
|
|
L:=TStringList.Create;
|
|
L.LoadFromFile(fname);
|
|
For i:=0 to L.Count -1 do
|
|
begin
|
|
S:=L.Strings[i];
|
|
|
|
TrimComm(S,['#']);
|
|
|
|
Name:=FetchAny(S,[' ',#9],[]);
|
|
|
|
Case Name of
|
|
'' :;
|
|
'%%':;
|
|
'%!':begin //pre/post
|
|
Name:=FetchAny(S,[' ',#9],[]); //enum name
|
|
Name:=FetchAny(S,[' ',#9],[]); //cmd
|
|
|
|
//exclude
|
|
Case S of
|
|
'vop_strategy_pre',
|
|
'vop_lock_pre',
|
|
'vop_lock_post',
|
|
'vop_unlock_pre',
|
|
'vop_unlock_post':S:='';
|
|
else;
|
|
end;
|
|
|
|
Case Name of
|
|
'pre' :pre :=S;
|
|
'post':post:=S;
|
|
else;
|
|
end;
|
|
end;
|
|
'};':begin //close
|
|
state:=0;
|
|
pre :='';
|
|
post:='';
|
|
Enum:=nil;
|
|
end;
|
|
else
|
|
Case state of
|
|
0:begin //open
|
|
Case Name of
|
|
'vop_cachedlookup' :state:=2; //skip
|
|
'vop_advise' :state:=2; //skip
|
|
'vop_is_text' :state:=2; //skip
|
|
'vop_set_text' :state:=2; //skip
|
|
'vop_unset_text' :state:=2; //skip
|
|
'vop_get_writecount':state:=2; //skip
|
|
'vop_add_writecount':state:=2; //skip
|
|
'vop_setlabel' :state:=2; //skip
|
|
'vop_getacl' :state:=2; //skip
|
|
'vop_setacl' :state:=2; //skip
|
|
'vop_aclcheck' :state:=2; //skip
|
|
'vop_closeextattr' :state:=2; //skip
|
|
'vop_getextattr' :state:=2; //skip
|
|
'vop_listextattr' :state:=2; //skip
|
|
'vop_openextattr' :state:=2; //skip
|
|
'vop_deleteextattr' :state:=2; //skip
|
|
'vop_setextattr' :state:=2; //skip
|
|
'vop_spare4' :state:=2; //skip
|
|
'vop_spare5' :state:=2; //skip
|
|
else
|
|
begin
|
|
Enum:=TEnum.Create;
|
|
Enum.name:=name;
|
|
Enum.NameValueSeparator:=':';
|
|
|
|
Enum.pre :=pre;
|
|
Enum.post:=post;
|
|
|
|
EnumList.AddObject(Enum.name,Enum);
|
|
|
|
state:=1;
|
|
end;
|
|
end;
|
|
end;
|
|
1:begin //value
|
|
|
|
rele:=0;
|
|
repeat
|
|
case Name of
|
|
'IN':;
|
|
'OUT':;
|
|
'INOUT':;
|
|
'WILLRELE':rele:=1;
|
|
'struct':;
|
|
'const':;
|
|
else
|
|
Break;
|
|
end;
|
|
Name:=FetchAny(S,[' ',#9],[]);
|
|
until false;
|
|
|
|
Case Name of
|
|
'thread':Continue; //skip
|
|
'ucred' :Continue; //skip
|
|
end;
|
|
|
|
links:=CountOf(S,['*']);
|
|
DelChars(S,['*',';']);
|
|
S:=Trim(S);
|
|
|
|
Case Name of
|
|
'int' :Name:=SpaceChars(links,'P')+'Integer';
|
|
'void' :Name:=SpaceChars(links-1,'P')+'Pointer';
|
|
'u_long',
|
|
'register_t',
|
|
'vm_ooffset_t',
|
|
'size_t',
|
|
'off_t' :Name:=SpaceChars(links,'P')+'PtrUint';
|
|
'char' :Name:=SpaceChars(links,'P')+'Char';
|
|
else
|
|
begin
|
|
if (links<>0) then
|
|
Name:=SpaceChars(links,'p')+'_'+Name;
|
|
end;
|
|
end;
|
|
|
|
Case S of
|
|
'end' :S:='__end';
|
|
else;
|
|
end;
|
|
|
|
if (Length(S)>Enum.namelen) then Enum.namelen:=Length(S);
|
|
|
|
Enum.AddPair(S,Name,TObject(rele));
|
|
Writeln(S,':',Name);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
L.Free;
|
|
|
|
F:=FileCreate(ChangeFileExt(fname,'.pas'));
|
|
|
|
S:='{This file is automatically generated by "vop_generator"}'#13#10;
|
|
S:=S+#13#10;
|
|
S:=S+'unit '+ChangeFileExt(ExtractFileName(fname),'')+';'#13#10;
|
|
S:=S+#13#10;
|
|
S:=S+'interface'#13#10;
|
|
S:=S+#13#10;
|
|
S:=S+'{$mode objfpc}{$H+}'#13#10;
|
|
S:=S+'{$CALLING SysV_ABI_CDecl}'#13#10;
|
|
S:=S+#13#10;
|
|
|
|
S:=S+'uses'#13#10;
|
|
S:=S+' sys_event,'#13#10;
|
|
S:=S+' vnode,'#13#10;
|
|
S:=S+' vnamei,'#13#10;
|
|
S:=S+' vfile,'#13#10;
|
|
S:=S+' vuio,'#13#10;
|
|
S:=S+' vmount,'#13#10;
|
|
S:=S+' vfcntl,'#13#10;
|
|
S:=S+' vsocketvar;'#13#10;
|
|
S:=S+#13#10;
|
|
|
|
S:=S+'type'#13#10;
|
|
S:=S+' PPPtrUint =^PPtrUint;'#13#10;
|
|
S:=S+' pp_bufobj =Pointer;'#13#10;
|
|
S:=S+' daddr_t =PtrUint;'#13#10;
|
|
S:=S+' p_daddr_t =PPtrUint;'#13#10;
|
|
S:=S+' p_buf =Pointer;'#13#10;
|
|
S:=S+' p_task =Pointer;'#13#10;
|
|
S:=S+' p_cluster_save=Pointer;'#13#10;
|
|
S:=S+' p_vm_page_t =Pointer;'#13#10;
|
|
//S:=S+' acl_type_t =Integer;'#13#10;
|
|
//S:=S+' p_acl =Pointer;'#13#10;
|
|
//S:=S+' p_label =Pointer;'#13#10;
|
|
S:=S+#13#10;
|
|
FileWrite(F,Pchar(S)^,Length(S));
|
|
|
|
maxlen:=0;
|
|
|
|
//records
|
|
For i:=0 to EnumList.Count-1 do
|
|
begin
|
|
Enum:=TEnum(EnumList.Objects[i]);
|
|
|
|
S:=' p_'+Enum.name+'_args=^'+Enum.name+'_args;'#13#10;
|
|
S:=S+' '+Enum.name+'_args=record'#13#10;
|
|
FileWrite(F,Pchar(S)^,Length(S));
|
|
|
|
if (Length(Enum.name)>maxlen) then maxlen:=Length(Enum.name);
|
|
|
|
if Length('gen')>Enum.namelen then Enum.namelen:=Length('gen');
|
|
|
|
S:=' a_gen'+Space(Enum.namelen-Length('gen'))+':p_vnodeop_desc;'#13#10;
|
|
|
|
For x:=0 to Enum.Count-1 do
|
|
begin
|
|
Name:=Enum.Names[x];
|
|
S:=S+' a_'+Name+Space(Enum.namelen-Length(Name))+':'+Enum.ValueFromIndex[x]+';'#13#10;
|
|
end;
|
|
|
|
S:=S+' end;'#13#10#13#10;
|
|
FileWrite(F,Pchar(S)^,Length(S));
|
|
end;
|
|
|
|
//callbacks
|
|
For i:=0 to EnumList.Count-1 do
|
|
begin
|
|
Enum:=TEnum(EnumList.Objects[i]);
|
|
|
|
S:=' '+Enum.name+'_t'+Space(maxlen-Length(Enum.name))+'=function(ap:p_'+Enum.name+'_args):Integer;'#13#10;
|
|
FileWrite(F,Pchar(S)^,Length(S));
|
|
end;
|
|
|
|
S:=#13#10;
|
|
FileWrite(F,Pchar(S)^,Length(S));
|
|
|
|
//list
|
|
//For i:=0 to EnumList.Count-1 do
|
|
//begin
|
|
// Enum:=TEnum(EnumList.Objects[i]);
|
|
//
|
|
// S:='//'+Enum.name+Space(maxlen-Length(Enum.name))+':Pointer;'#13#10;
|
|
// FileWrite(F,Pchar(S)^,Length(S));
|
|
//end;
|
|
|
|
//S:=#13#10;
|
|
//FileWrite(F,Pchar(S)^,Length(S));
|
|
|
|
//functions header
|
|
For i:=0 to EnumList.Count-1 do
|
|
begin
|
|
Enum:=TEnum(EnumList.Objects[i]);
|
|
|
|
Name:=FixFuncName(Enum.name);
|
|
Name:=Upcase(Name);
|
|
|
|
S:='function '+Name+Space(maxlen-Length(Name))+'(';
|
|
FileWrite(F,Pchar(S)^,Length(S));
|
|
|
|
For x:=0 to Enum.Count-1 do
|
|
begin
|
|
Name:=Enum.Names[x];
|
|
S:=FixFieldName(Name)+':'+Enum.ValueFromIndex[x];
|
|
if (x<>Enum.Count-1) then
|
|
begin
|
|
S:=S+';';
|
|
end;
|
|
FileWrite(F,Pchar(S)^,Length(S));
|
|
end;
|
|
|
|
S:='):Integer;'#13#10;
|
|
FileWrite(F,Pchar(S)^,Length(S));
|
|
end;
|
|
|
|
//const
|
|
S:=#13#10'const'#13#10;
|
|
FileWrite(F,Pchar(S)^,Length(S));
|
|
|
|
//vp_offsets
|
|
For i:=0 to EnumList.Count-1 do
|
|
begin
|
|
Enum:=TEnum(EnumList.Objects[i]);
|
|
|
|
S:=' '+Enum.name+'_vp_offsets'+Space(maxlen-Length(Enum.name))+':array[0..';
|
|
|
|
//calc count
|
|
vpnum:=0;
|
|
For x:=0 to Enum.Count-1 do
|
|
begin
|
|
Name:=Enum.ValueFromIndex[x];
|
|
if (Name='p_vnode') then
|
|
begin
|
|
Inc(vpnum);
|
|
end;
|
|
end;
|
|
Assert(vpnum<>0);
|
|
|
|
S:=S+IntToStr(vpnum)+'] of Byte=(';
|
|
|
|
//offsets
|
|
vpnum:=0;
|
|
For x:=0 to Enum.Count-1 do
|
|
begin
|
|
Name:=Enum.ValueFromIndex[x];
|
|
if (Name='p_vnode') then
|
|
begin
|
|
if (vpnum<>0) then
|
|
begin
|
|
S:=S+',';
|
|
end;
|
|
|
|
Name:=Enum.Names[x];
|
|
Name:='a_'+Name;
|
|
|
|
S:=S+'Byte(ptrint(@p_'+Enum.name+'_args(nil)^.'+Name+'))';
|
|
|
|
Inc(vpnum);
|
|
end;
|
|
end;
|
|
|
|
S:=S+',Byte(-1));'#13#10;
|
|
|
|
FileWrite(F,Pchar(S)^,Length(S));
|
|
end;
|
|
|
|
S:=#13#10;
|
|
S:=S+' vop_default_desc:t_vnodeop_desc=('#13#10;
|
|
S:=S+' vdesc_name :''default'';'#13#10;
|
|
S:=S+' vdesc_call :nil;'#13#10;
|
|
S:=S+' vdesc_vp_offsets :nil;'#13#10;
|
|
S:=S+' vdesc_flags :0;'#13#10;
|
|
S:=S+' vdesc_vpp_offset :-1;'#13#10;
|
|
S:=S+' );'#13#10;
|
|
FileWrite(F,Pchar(S)^,Length(S));
|
|
|
|
//vnodeop_desc
|
|
For i:=0 to EnumList.Count-1 do
|
|
begin
|
|
Enum:=TEnum(EnumList.Objects[i]);
|
|
|
|
//releflags
|
|
vpnum:=0;
|
|
releflags:='';
|
|
For x:=0 to Enum.Count-1 do
|
|
begin
|
|
Name:=Enum.ValueFromIndex[x];
|
|
if (Name='p_vnode') then
|
|
begin
|
|
if (Enum.Objects[x]<>nil) then //rele
|
|
begin
|
|
if (releflags<>'') then
|
|
begin
|
|
releflags:=releflags+' or ';
|
|
end;
|
|
releflags:=releflags+'VDESC_VP'+IntToStr(vpnum)+'_WILLRELE';
|
|
end;
|
|
Inc(vpnum);
|
|
end;
|
|
end;
|
|
|
|
//vppwillrele,vpp_offset
|
|
vpp_offset:='';
|
|
For x:=0 to Enum.Count-1 do
|
|
begin
|
|
Name:=Enum.ValueFromIndex[x];
|
|
if (Name='pp_vnode') then
|
|
begin
|
|
if (vpp_offset='') then
|
|
begin
|
|
Name:=Enum.Names[x];
|
|
Name:='a_'+Name;
|
|
|
|
vpp_offset:='Integer(ptrint(@p_'+Enum.name+'_args(nil)^.'+Name+'))';
|
|
end;
|
|
|
|
if (Enum.Objects[x]<>nil) then //rele
|
|
begin
|
|
if (releflags<>'') then
|
|
begin
|
|
releflags:=releflags+' or ';
|
|
end;
|
|
releflags:=releflags+'VDESC_VPP_WILLRELE';
|
|
Break;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
if (releflags='') then releflags:='0';
|
|
if (vpp_offset='') then vpp_offset:='-1';
|
|
|
|
S:=#13#10;
|
|
S:=S+' '+Enum.name+'_desc:t_vnodeop_desc=('#13#10;
|
|
S:=S+' vdesc_name :'''+Enum.name+''';'#13#10;
|
|
S:=S+' vdesc_call :@p_vop_vector(nil)^.'+Enum.name+';'#13#10;
|
|
S:=S+' vdesc_vp_offsets :@'+Enum.name+'_vp_offsets;'#13#10;
|
|
S:=S+' vdesc_flags :'+releflags+';'#13#10;
|
|
S:=S+' vdesc_vpp_offset :'+vpp_offset+';'#13#10;
|
|
S:=S+' );'#13#10;
|
|
FileWrite(F,Pchar(S)^,Length(S));
|
|
end;
|
|
|
|
S:=#13#10;
|
|
S:=S+'implementation'#13#10;
|
|
S:=S+#13#10;
|
|
S:=S+'uses'#13#10;
|
|
S:=S+' errno,'#13#10;
|
|
S:=S+' vfs_subr;'#13#10;
|
|
S:=S+#13#10;
|
|
|
|
S:=S+'function get_vp_cb(vp:p_vnode;offset:Pointer):Pointer; inline;'#13#10;
|
|
S:=S+'var'#13#10;
|
|
S:=S+' v:p_vop_vector;'#13#10;
|
|
S:=S+' p:Pointer;'#13#10;
|
|
S:=S+'begin'#13#10;
|
|
S:=S+' Result:=nil;'#13#10;
|
|
S:=S+' if (vp=nil) then Exit;'#13#10;
|
|
S:=S+' v:=vp^.v_op;'#13#10;
|
|
S:=S+' while (v<>nil) do'#13#10;
|
|
S:=S+' begin'#13#10;
|
|
S:=S+' p:=PPointer(Pointer(v)+ptrint(offset))^;'#13#10;
|
|
S:=S+' if (p<>nil) then'#13#10;
|
|
S:=S+' begin'#13#10;
|
|
S:=S+' Exit(p);'#13#10;
|
|
S:=S+' end;'#13#10;
|
|
S:=S+' p:=v^.vop_bypass;'#13#10;
|
|
S:=S+' if (p<>nil) then'#13#10;
|
|
S:=S+' begin'#13#10;
|
|
S:=S+' Exit(p);'#13#10;
|
|
S:=S+' end;'#13#10;
|
|
S:=S+' v:=v^.vop_default;'#13#10;
|
|
S:=S+' end;'#13#10;
|
|
S:=S+'end;'#13#10;
|
|
S:=S+#13#10;
|
|
|
|
FileWrite(F,Pchar(S)^,Length(S));
|
|
|
|
//functions body
|
|
For i:=0 to EnumList.Count-1 do
|
|
begin
|
|
Enum:=TEnum(EnumList.Objects[i]);
|
|
|
|
//header
|
|
Name:=FixFuncName(Enum.name);
|
|
Name:=Upcase(Name);
|
|
|
|
S:='function '+Name+'(';
|
|
FileWrite(F,Pchar(S)^,Length(S));
|
|
|
|
For x:=0 to Enum.Count-1 do
|
|
begin
|
|
Name:=Enum.Names[x];
|
|
S:=FixFieldName(Name)+':'+Enum.ValueFromIndex[x];
|
|
if (x<>Enum.Count-1) then
|
|
begin
|
|
S:=S+';';
|
|
end;
|
|
FileWrite(F,Pchar(S)^,Length(S));
|
|
end;
|
|
|
|
S:='):Integer;'#13#10;
|
|
FileWrite(F,Pchar(S)^,Length(S));
|
|
//header
|
|
|
|
//var
|
|
S:='var'#13#10;
|
|
|
|
if (Upcase(Enum.name)='VOP_WRITE') then
|
|
begin
|
|
S:=S+' osize,ooffset:Int64;'#13#10;
|
|
end;
|
|
|
|
S:=S+' c:Pointer;'#13#10;
|
|
S:=S+' a:'+Enum.name+'_args;'#13#10;
|
|
S:=S+' s:Boolean;'#13#10;
|
|
FileWrite(F,Pchar(S)^,Length(S));
|
|
|
|
//body
|
|
S:='begin'#13#10;
|
|
FileWrite(F,Pchar(S)^,Length(S));
|
|
|
|
Name:=FixFuncName(Enum.name);
|
|
Name:=Upcase(Name);
|
|
|
|
S:=' c:=get_vp_cb('+FixFieldName(Enum.Names[0])+','+Enum.name+'_desc.vdesc_call);'#13#10;
|
|
S:=S+' Assert(c<>nil,'+''''+Name+''''+');'#13#10;
|
|
FileWrite(F,Pchar(S)^,Length(S));
|
|
|
|
//set val
|
|
S:=' a.a_gen'+Space(Enum.namelen-Length('gen'))+':=@'+Enum.name+'_desc;'#13#10;
|
|
|
|
For x:=0 to Enum.Count-1 do
|
|
begin
|
|
Name:=Enum.Names[x];
|
|
|
|
S:=S+' a.a_'+Name+Space(Enum.namelen-Length(Name))+':='+FixFieldName(Name)+';'#13#10;
|
|
end;
|
|
|
|
FileWrite(F,Pchar(S)^,Length(S));
|
|
|
|
//pre
|
|
if (Enum.pre<>'') then
|
|
begin
|
|
S:=' '+Enum.pre+'(@'+'a';
|
|
if (Upcase(Enum.name)='VOP_WRITE') then
|
|
begin
|
|
S:=S+',osize,ooffset';
|
|
end;
|
|
S:=S+');'#13#10;
|
|
FileWrite(F,Pchar(S)^,Length(S));
|
|
end;
|
|
|
|
S:=' s:=VFS_PROLOGUE('+FixFieldName(Enum.Names[0])+'^.v_mount);'#13#10;
|
|
|
|
//call
|
|
S:=S+' Result:='+Enum.name+'_t(c)(@a);'#13#10;
|
|
|
|
S:=S+' VFS_EPILOGUE(s);'#13#10;
|
|
FileWrite(F,Pchar(S)^,Length(S));
|
|
|
|
//post
|
|
if (Enum.post<>'') then
|
|
begin
|
|
S:=' '+Enum.post+'(@a,Result';
|
|
if (Upcase(Enum.name)='VOP_WRITE') then
|
|
begin
|
|
S:=S+',osize,ooffset';
|
|
end;
|
|
S:=S+');'#13#10;
|
|
FileWrite(F,Pchar(S)^,Length(S));
|
|
end;
|
|
|
|
S:='end;'#13#10#13#10;
|
|
FileWrite(F,Pchar(S)^,Length(S));
|
|
//body
|
|
end;
|
|
|
|
S:='end.'#13#10#13#10;
|
|
FileWrite(F,Pchar(S)^,Length(S));
|
|
|
|
FileClose(F);
|
|
end;
|
|
|
|
//
|
|
|
|
begin
|
|
load_if('vnode_if.src');
|
|
readln;
|
|
end.
|
|
|