program makeobj;
{$I define.pas}
(*
  writeln('Usage: MakeComp [@[pathXXXDef]UlanRecs.LST | XXXXType.pas]');
  writeln('Creates TxxObj object declaration/definition units xxxxOBJU.PAS');
  writeln('and objects' + '''' + ' editing form xxxxFRMU.PAS and xxxxFRMU.DFM');
  writeln('(use delphi convert program)');
  writeln('Using fields from "TxxxxRec = packed record" found in xxxxTYPE.PAS file ');
  writeln('xxxx is 1-4 uppercase chars. Ulan projects uses ULxx.');
  writeln('Generated sources use ULRecType.PAS, ULObju.PAS and IniObj.PAS');
*)
{ used for source files specified in ULREC.LST file }
uses
  SysUtils,
  Classes,
  Math,
  Windows,
  Stru,
  Attrib,
  AttrType,
  ULRecTyp {v1.01},
  WinUtl {/v1.01},
  ULRecUtl {/v0.14},
  Graphics {/v0.24};

const
  Version = '1.05';
  {1.05 tfieldinfo }
  {1.04 destdir, source dir }
  {1.03 rfEditModal }
  {1.01 floattostr accepts '.'}

type
  TFieldInfo = class(TObject)
     Left, Top, Width, Height: integer;{ position in edit window }
  end;
var
  inN, objFn, frmFn, frdFn: string;
    { names of input file, output obj file, output frm file and frm resource (DFM) file }
  inF, objF, frmF, frdF: text;
    { correspondint text file variables }
  prefix, objN, objUn, frmN, frmUn: string;
    { = ULx, TULxObj, ULxObju, TULxForm, ULxFrmu }
  line: string;
    { current line from inn }
  recattr: string;
    { list of attributes for whole record (in the form "attr1=value1 attr2=value2 ..."),
      specified in the ulxxtype.pas file in the format: }
    {<attr1=value1 attr2=value2 ..>}
    { just after the record word (see uldtype) }
  fldn: TStringList;
    { list of field names found in record }
  fldt: TStringList;
    { list of field pascal types found in record }
  flda: TStringList;
    { lists of attributes for the fields in the form "attr1=value1 attr2=value2 ...",
      specified after the field declaration in braces and in <> (see uldtype) }
  editflds: TStringList;
    { list of field names that should appear in edit window }
  recdesc: TULRecDesc;
    { Values set from recattr list. }
  childrecids: TULChildRecIDs;
  usesStr: string;
    { if some additional unit(s) should be added uses clause of the created
      units, it should be specified here (comma separated list, after last
      name no comma); specified as record's attributes pnUses }

const
  inRecord:boolean = false;
    { parsing the record's fields? }
  inAttr:boolean = false;
    { parsing the record's or field's attributes? }

{include files for ULFOBJU.PAS; called only from MakeObjs }
var
  xu, xo, xf, xc, xd, xr: text;
  ulst: TStringList;{unit prefixes list}
  urecattr: TStringList;{rec attributes for units}
  fclst: TStringList;
    { list of root records (ulFid Childs) }

{v1.04}
const
  DestDir: string = '';
  SourceDir: string = '';
  ProjectPrefix: string = 'Ulan';
{/v1.04}

procedure IncInit;
var s:string;
begin
  s := '{ Created by MAKECOMP v'+ Version + '}';

  assign(xu, DestDir + 'ULXUNLST.INC');
  rewrite(xu);
  writeln(xu, s);

  assign(xo, DestDir + 'ULXOCREA.INC');
  rewrite(xo);
  writeln(xo, s);

  assign(xf, DestDir + 'ULXFCREA.INC');
  rewrite(xf);
  writeln(xf, s);

  assign(xc, DestDir + 'ULXCNT.INC');
  rewrite(xc);
  writeln(xc, s);

  assign(xd, DestDir + 'ULXRDESC.INC');
  rewrite(xd);
  writeln(xd, s);

  assign(xr, DestDir + 'ULFDESC.INC');
  rewrite(xr);
  writeln(xr, s);

  ulst := TStringList.Create;
  urecattr := TStringList.Create;
  fclst := TStringList.Create;
end;

procedure IncWrite;
var
  i:integer;
  ch:string[1];
  pref:string[4];
  s:string;
begin
  writeln(xc, 'const');
  writeln(xc, '  ULRecIDCount = ' + IntToStr(ulst.Count) + ';');
  writeln(xc, '  ULRecIDs: array[0..ULRecIDCount - 1] of TULRecID =(');
  write(xc, '    ');


  writeln(xr, 'const');
  writeln(xr, '  ULFChildRecIDs: array[0..' + IntToStr(fclst.Count-1) +
    '] of TULRecID = (');
  s := '';
  for i  := 0 to fclst.Count - 1 do begin
    if s = '' then
      s := fclst[i]
    else
      s := s + ', ' + fclst[i]
  end;
  writeln(xr, '    ' + s);
  writeln(xr, '  );');
  writeln(xr, '  ULFRecDesc: TULRecDesc = (');
  writeln(xr, '    Caption: ' + '''' + 'File' + '''' + ';');
  writeln(xr, '    ChildRecIDsStr: ' + '''' + s + '''' + ';');
  writeln(xr, '    ChildRecIDs: @ULFChildRecIDs;');
  writeln(xr, '    ChildRecIDCount: ' + IntToStr(fclst.Count) + ';');
  writeln(xr, '    FldCount: 0;');
  writeln(xr, '    Flds: nil;');
  writeln(xr, '    Flags: rfChildAllowed;');
  writeln(xr, '    SortExp: ' + '''' + '''' + '');
  writeln(xr, '  );');
  writeln(xr,'');


  for i := 0 to ulst.Count - 1 do begin
    pref := ulst[i];
    if i = ulst.Count - 1 then begin
      ch := '';
      writeln(xc, pref + 'ID');
    end else begin
      ch := ',';
      write(xc, pref + 'ID, ');
      if ((i + 1) mod 8 = 0) then begin
        writeln(xc);
        write(xc, '    ');
      end;
    end;

    writeln(xu, '  ' + pref + 'Type, {$IFNDEF CONSOLE}' + pref + 'Frmu,{$ENDIF} ' + pref + 'Obju' + ch);

    writeln(xo, '  ' + pref + 'ID : o := T' + pref + 'Obj.Create(AOwner);');
    writeln(xf, '  ' + pref + 'ID: f := T' + pref + 'Form.Create(Application);');
    if urecattr[i] <> '' then begin
      writeln(xd, '    ' + pref + 'ID: Result := @' + pref + 'RecDesc;');
    end;
  end;
  writeln(xc, '  );');
end;

procedure IncDone;
begin
  urecattr.Free;
  ulst.Free;
  close(xu);
  close(xo);
  close(xf);
  close(xc);
  close(xd);
  close(xr);
end;
{/include files}

procedure InInit;
begin
  assign(inf, SourceDir + inn);
  reset(inf);
end;

procedure InDone;
begin
  close(inf);
end;

procedure ow(s:string);
begin
  writeln(objf, s);
end;

procedure ObjInit;
begin
  assign(objF, DestDir + objFn);
  rewrite(objf);
end;

procedure ObjDone;
var
  i, j: integer;
  s, an, av: string;
  fval:string;
  {v0.22}
  a: string;
  {/v0.22}

  {v0.23}
  function CheckSetPropValue:boolean;
  begin
    Result :=
      ( (recdesc.Flds^[i].Flags and ffCommand) = 0 )
      and
      ( (recdesc.Flds^[i].Flags and ffWriteAlways) = 0 )
      and
      (av <> pvMethod);
  end;
  {/v0.23}

  procedure WriteFldColors(AFieldNr: integer);
  var
    j: integer;
    col: integer;
    wrd: string;
    wrds: string;
  begin
    with recdesc.Flds^[AFieldNr] do begin
      ow('     FieldColors' + IntToStr(AFieldNr) + ' : array[0..' +
        IntToStr(FieldColorCount-1) + '] of TULFieldColor = (');
      for j := 0 to FieldColorCount - 1 do begin
        wrds := '(';
        if j < FieldColorCount then begin
          col := FieldColors^[j, 0];
          if not ColorToIdent(col, wrd) then begin
            wrd := 'clBlack';
          end;
          wrds := wrds + wrd + ',';
          col  := FieldColors^[j, 1];
          if not ColorToIdent(col, wrd) then begin
            wrd := 'clWhite';
          end;
          wrds := wrds + wrd + ')';
        end else begin
          wrds := '(clBlack,clWhite)';
        end;

        if j < FieldColorCount - 1 then
          ow('      ' + wrds + ',')
        else
          ow('      ' + wrds);
      end;
      ow('     ' + ')' + ';');
    end;
    ow('');
  end;

  procedure WriteFldsColors;
  var i: integer;
  begin
    for i := 0 to recdesc.FldCount - 1 do begin
      if recdesc.Flds^[i].FieldColorCount > 0 then
        WriteFldColors(i);
    end;
  end;

  procedure WriteFldDesc(AFieldNr: integer);
  var j: integer;
  begin
    with recdesc.Flds^[AFieldNr] do begin
      ow('    (');
      ow('     Caption: ' + '''' + Caption + '''' + ';');
      ow('     Hint: ' + '''' + Hint + '''' + ';');
      ow('     EditWidth: ' + IntToStr(EditWidth) + ';');
      ow('     BrowseWidth: ' + IntToStr(BrowseWidth) + ';');
      ow('     Flags: ' + IntToStr(Flags) + ';');
      fval := FloatToStrF(UserCoef, ffFixed, 7, 2);
      for j := 1 to length(fval) do begin
        if fval[j] = ',' then
          fval[j] := '.';
      end;
      ow('     UserCoef: ' + fval + ';');
      ow('     NumDec: ' + IntToStr(NumDec) + ';');
      {v0.14}
      if ValuesSourceRecID <> 0 then begin
        ow('     ValuesSourceRecID: ' + ULRecIDToStrStrip(ValuesSourceRecID) + 'ID' + ';');
      end else begin
        ow('     ValuesSourceRecID: 0' + ';');
      end;
      {v0.24}
      ow('     FieldColorCount : ' + IntToStr(FieldColorCount) +  ';');
      if FieldColorCount > 0 then begin
        ow('     FieldColors : @FieldColors' + IntToStr(AFieldNr) + ';');
      end else begin
        ow('     FieldColors : nil' + ';');
      end;
      ow('     Filter: ' + '''' + Filter + '''' + '');
      {/v0.24}
      {/v0.14}
      if AFieldNr = recdesc.FldCount - 1 then
        ow('    )')
      else
        ow('    ),');
    end;
  end;

  procedure WriteFldsDescs;
  var
    i: integer;
  begin
    if recdesc.FldCount = 0 then
      exit;
    WriteFldsColors;
    ow('  ' + prefix + 'FldDescs: array[0..' + IntToStr(recdesc.FldCount - 1) +
     '] of TULFldDesc = (');
    for i := 0 to recdesc.FldCount - 1 do begin
      WriteFldDesc(i);
    end;
    ow('  );');
    ow('');
  end;

begin
  ow('unit ' + objUn + ';');
  ow('{ Generated by MakeComp ' + Version + ' from ' + inN +
   '. Don' + '''' + 't modify manually !!! }');
  ow('interface');
  {v1.04}
  ow('uses Classes, SysUtils, Graphics, ' + ProjectPrefix + 'Type, ULRecTyp, ULObju, ');
  {/v1.04
  ow('uses Classes, UlanType, ULRecTyp, ULObju, ');}
  if usesStr <> '' then
    ow('  ' + usesStr + ',');
  ow('  ' + prefix + 'Type;');
  ow('');
  ow('type');
  ow('  ' + objn + ' = class(TULObj)');
  {
  ow('  private');
  for i := 0 to fldn.Count -1 do begin
    ow('    F' + fldn[i] + ': ' + fldt[i] + ';');
  end;
  }
  ow('  protected');
  for i := 0 to fldn.Count - 1 do begin
    ow('    function Get' + fldn[i] + ': ' + fldt[i] + ';');
    ow('    procedure Set' + fldn[i] + '(A'+ fldn[i] + ': ' +
      fldt[i] + ');');
  end;
  ow('    function GetMinRecLen: TULRecLen; override;');
  ow('  public');
  ow('    constructor Create(AOwner:TULObj);');
  if recattr <> '' then begin
    ow('    function GetULRecDesc: PULRecDesc; override;');
  end;
  if recdesc.SortExp <> '' then begin
    if (recdesc.Flags and rfSortedByNumber) <> 0 then
      ow('    function GetSortNum: extended; override;')
    else
      ow('    function GetSortStr: string; override;')
  end;
  ow('  published');
  for i := 0 to fldn.Count - 1 do begin
    ow('    property ' + fldn[i] + ': ' + fldt[i]);
    ow('      read Get' + fldn[i] + ' write Set' + fldn[i] + ';');
  end;
  ow('  end;');
  ow('');

  if recattr <> '' then begin
    with recdesc do begin
      ow('const');
      if recdesc.ChildRecIDCount > 0 then begin
        ow('  ' + prefix + 'ChildRecIDs: array[0..' +
          IntToStr(recdesc.ChildRecIDCount - 1) + '] of TULRecID = (');
            ow('    ' + recdesc.ChildRecIDsStr);
     {  s := '';
        for i := 0 to recdesc.ChildRecIDCount - 1 do begin
          if s = '' then
            s := IntToStr(recdesc.ChildRecIDs^[i])
          else
            s := s + ', ' + IntToStr(recdesc.ChildRecIDs^[i]);
        end;
        ow('    ' + s);
        }
        ow('  );');
      end;

      WriteFldsDescs;

      ow('  ' + prefix + 'RecDesc: TULRecDesc = (');
      ow('    Caption: ' + '''' + recdesc.Caption + '''' + ';');
      ow('    ChildRecIDsStr: ' + '''' + recdesc.ChildRecIDsStr + '''' + ';');
      if recdesc.ChildRecIDCount > 0 then begin
        ow('    ChildRecIDs: @' + prefix + 'ChildRecIDs;');
      end else begin
        ow('    ChildRecIDs: nil;');
      end;
      ow('    ChildRecIDCount: ' + IntToStr(recdesc.ChildRecIDCount) + ';');
      ow('    FldCount: '+ IntToStr(recdesc.FldCount) + ';');
      if recdesc.FldCount > 0 then begin
        ow('    Flds: @' + prefix + 'FldDescs;');
      end else begin
        ow('    Flds: nil;');
      end;
      s := '';
      if (Flags and rfChildAllowed) <> 0 then
        s := s + 'rfChildAllowed OR ';
      if (Flags and rfDataChild) <> 0 then
        s := s + 'rfDataChild OR ';
      if (Flags and rfRootChild) <> 0 then begin
        fclst.Add(prefix + 'ID');
        s := s + 'rfRootChild OR ';
      end;
      if (Flags and rfChildSorted) <> 0 then
        s := s + 'rfChildSorted OR ';
      if (Flags and rfHasRecName) <> 0 then
        s := s + 'rfHasRecName OR ';
      {v0.22}
      if (Flags and rfHasPointer) <> 0 then
        s := s + 'rfHasPointer OR ';
      {/v0.22}
      {v0.24}
      if (Flags and rfUsingColors) <> 0 then
        s := s + 'rfUsingColors OR ';
      {/v0.24}
      if (Flags and rfTemporary) <> 0 then
        s := s + 'rfTemporary OR ';
      if (Flags and rfEnabled) <> 0 then
        s := s + 'rfEnabled OR ';
      {v1.03}
      if (Flags and rfEditModal) <> 0 then
        s := s + 'rfEditModal OR ';
      {v0.23}
      if (Flags and rfBrowseModal) <> 0 then
        s := s + 'rfBrowseModal OR ';
      {/v0.23}
      if (Flags and rfVisible) <> 0 then
        s := s + 'rfVisible OR ';
      if (Flags and rfFileDataStream) <> 0 then
        s := s + 'rfFileDataStream OR ';
      if (Flags and rfBrowseOnEdit) <> 0 then
        s := s + 'rfBrowseOnEdit OR ';
      if (Flags and rfSortedByNumber) <> 0 then
        s := s + 'rfSortedByNumber OR ';

      if s = '' then
        s := '0';
      while s[length(s)] in [' ','+','O','R'] do SetLength(s, length(s) - 1);
      ow('    Flags: ' + s + ';');
      ow('    SortExp: ' + '''' + SortExp + '''' + ';');
      ow('    EditFieldList: ' + '''' + EditFieldList + '''' + ';');
      ow('    BrowseFieldList: ' + '''' + BrowseFieldList + '''' + ';');
      {v0.22}
      ow('    MenuFieldList: ' + '''' + MenuFieldList + '''' + ';');
      {/v0.22}
      {v0.23}
      ow('    BrowseChildRecIDs: ' + '''' + BrowseChildRecIDs + '''' + ';');
      ow('    NameProp: ' + '''' + NameProp + '''' + ';');
      {/v0.23}
      ow('    MainProp: ' + '''' + MainProp + '''' + '');
      ow('   );');
      ow('');
    end;
  end;

  ow('implementation');
  ow('');
  ow('{' + objN + '}');
  ow('function ' + objN + '.GetMinRecLen: TULRecLen;');
  ow('begin');
  ow('  GetMinRecLen := sizeof(T' + prefix + 'Rec);');
  ow('end;');
  ow('');
  ow('constructor '+ objN + '.Create(AOwner: TULObj);');
  ow('begin');
  ow('  inherited Create(TComponent(AOwner), ' + prefix + 'ID);');
  s := recattr;
  while GetNextAttrib(s, an, av) do begin
    if pos('Create', an) = 1 then begin
      ow('  ' + av);
    end;
  end;
  {v0.24}
  for i := 0 to fldn.Count - 1 do begin
    av := '';
    a := flda[i];
    if FindAttrib(a, pnDefVal, av, false) and (av <> '') then begin
      ow('  ' + fldn[i] + ' := ' + av + ';');
    end;
  end;
  {/v0.24}
  ow('end;');
  ow('');
  if recattr <> '' then begin
    ow('function ' + objN + '.GetULRecDesc: PULRecDesc;');
    ow('begin');
    ow('  Result := @' + prefix + 'RecDesc;');
    ow('end;');
    ow('');
  end;

  if recdesc.SortExp <> '' then begin
    if (recdesc.Flags and rfSortedByNumber) <> 0 then
      ow('function ' + objN + '.GetSortNum: Extended;')
    else
      ow('function ' + objN + '.GetSortStr: string;');
    ow('begin');
    ow('  Result := ' + recdesc.SortExp + ';');
    ow('end;');
  end;

  for i := 0 to fldn.Count - 1 do begin
    {v0.22}
    av := '';
    a := flda[i];
    FindAttrib(a, pnType, av, false);
    {/v0.22}

    ow('procedure ' + objN + '.Set' + fldn[i] + '(A' + fldn[i] + ': ' + fldt[i] + ');');
    ow('begin');

    {v0.23}
    if CheckSetPropValue then
    {/v0.23
    if (av <> pvMethod) then}
      ow('  if P' + prefix + 'Rec(Rec)^.' + fldn[i]+ ' <> A' + fldn[i] + ' then begin');

    ow('    P' + prefix + 'Rec(Rec)^.' + fldn[i]+ ' := A' + fldn[i] + ';');
    ow('    DoChange;');

    {v0.22} { uldptype }
    if av = pvMethod then
    begin
      ow('    Fields['+IntToStr(i) + '].Method := TMethod(A' + fldn[i] + ');');
    end else
    {/0.22}
    begin
      {v0.23}
      if CheckSetPropValue then
      {/v0.23}
        ow('  end;');
    end;
    {v0.24}
    if recdesc.MainProp = fldn[i] then begin
      ow('  DoMainPropUpdated;');
    end;
    {/v0.24}

    ow('end;');
    ow('');
    ow('function ' + objN + '.Get' + fldn[i] + ': ' + fldt[i] + ';');
    ow('begin');
    ow('  Get' + fldn[i] + ' := P' + prefix + 'Rec(Rec)^.' + fldn[i] + ';');
    ow('end;');
    ow('');
  end;
  ow('{/' + objN + '}');
  ow('');
  ow('end.');
  close(objf);
end;

procedure fw(s:string);
begin
  writeln(frmF, s);
end;

procedure FrmInit;
begin
  assign(frmF, DestDir + frmFN);
  rewrite(frmF);
end;

procedure FrmDone;
var
  i, p: integer;
  a, {an, }av: string;

  procedure DoFld(i:integer);
  {v0.22}
  var
    typeFound:boolean;
  {/v0.22}
  begin
    fw('    ' + fldn[i] + 'Lbl: TLabel;');
    a := flda[i];
    {v0.22}
    typeFound := FindAttrib(a, pnType, av, false);
    if fldt[i] = 'boolean' then begin
      fw('    ' + fldn[i] + 'Edit: TCheckBox;');
    end else if
      ({v0.22}typeFound{/v0.22 FindAttrib(a, pnType, av, false)} and
       ((av = pvEnum)) {v0.14} or (av = pvULEnum) {/v0.14}
      )
    then begin
      fw('    ' + fldn[i] + 'Edit: TComboBox;');
    end else {v0.22}if typeFound and (av = pvMemo) then begin
      fw('    ' + fldn[i] + 'Edit: TMemo;');
    end else if typeFound and (av = pvMethod) then begin

    end else {/v0.22}begin
      fw('    ' + fldn[i] + 'Edit: TEdit;');
    end;
  end;

begin
  fw('unit ' + prefix + 'Frmu;');
  fw('{ Generated by MakeComp ' + Version + ' from ' + inN +
   '. Don' + '''' + 't modify manually !!! }');
  fw('interface');
  fw('');
  fw('uses');
  fw('  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,');
  fw('  IniObj, StdCtrls, ULObju, ULEdFrm;');
  fw('');
  fw('type');
  fw('  T' + prefix + 'Form = class(TULEditForm)');
  for p := 0 to editflds.Count - 1 do begin
    i := fldn.IndexOf(editflds[p]);
    if i >= 0 then
      DoFld(i)
    else begin
      writeln('Error: ' + prefix + ' field ' + editflds[p] + ' not found. Press enter...');
      readln;
    end;
  end;
  fw('    OKBtn: TButton;');
  fw('    CancelBtn: TButton;');
  if recdesc.ChildRecIDCount > 0 then begin
    fw('    ParamsBtn: TButton;');
  end;
  fw('    ' + prefix + 'FormIni: TIniObject;');
  if recdesc.ChildRecIDCount > 0 then begin
    fw('    procedure ParamsBtnClick(Sender: TObject);');
  end;
  fw('    procedure FormCreate(Sender: TObject);');
  fw('    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);');
  fw('  private');
  fw('    { Private declarations }');
  fw('  public');
  fw('    { Public declarations }');
{  fw('    Obj: TULObj;');}
  fw('  end;');
  fw('');
  fw('var');
  fw('  ' + prefix + 'Form: T' + prefix + 'Form;');
  fw('');
  fw('implementation');
  fw('{$R *.DFM}');
  fw('');
  if recdesc.ChildRecIDCount > 0 then begin
    fw('procedure T' + prefix + 'Form.ParamsBtnClick(Sender: TObject);');
    fw('begin');
    fw('  if Obj <> nil then');
    fw('    Obj.Browse;');
    fw('end;');
    fw('');
  end;
  fw('procedure T' + prefix + 'Form.FormCreate(Sender: TObject);');
  fw('begin');
{  fw('  Obj := CurULObj;');
  fw('  CurULObj := nil;');}
  fw('end;');
  fw('');
  fw('procedure T' + prefix + 'Form.FormCloseQuery(Sender: TObject; var CanClose: Boolean);');
  fw('begin');
  fw('  if Sender = OKBtn then begin');
  fw('    CanClose := Obj.IsValidInput(Self);');
  fw('  end;');
  fw('end;');

  fw('');
  fw('end.');

  close(frmF);
end;

procedure dw(s:string);
begin
  writeln(frdF, s);
end;

procedure FrdInit;
begin
  assign(frdF, DestDir + frdFn);
  rewrite(frdF);
end;

procedure FrdDone;
const
  compSize = 30;
    { what is the nonvisual component visual size during designing }
  fcheight = 24;
    { from caption height }

  {v0.22}
  MemoRowCount = 3;
  {/v0.22}
var
  left, top, width, height: integer;
    { current values }
  fleft, ftop, fwidth, fheight: integer;
    { form's values }
  lleft, ltop, lwidth, lheight: integer;
    { values for inserting label controls, cltop - changes }
  eleft, etop, ewidth, eheight: integer;
    { values for inserting edit controls, cetop - changes }
  rheight: integer;
    { row height (distance between tops of neighbour edit controls }
  bleft, btop, bwidth, bheight: integer;
    { values for buttons, cbleft - changes }
  wdist, hdist: integer;
    { witdth and height minimal distances between controls }
  i: integer;
    { index in fldn }
  pi: integer;
    { index in editflds }
  tabord:integer;
    { taborder of edits, buttons }
  p:array[0..255]of char;
  convfn:string;
  res:longint;
  cap: string;

  a, {an, }av:string;
  typ: string;

  {v0.22}
  typeFound: boolean;
  editRowCount:integer;
  {/v0.22}
begin
  tabord := 0;
  rheight := 22;

  wdist := 5;
  hdist := 8;

  lleft := 16;
  ltop := {v0.11}20{v0.11 24};
  lheight := 13;
  lwidth  := 60;

  eleft := {v0.11}140{/v0.11 118};
  etop := 16;
  eheight := 21;
  ewidth := 121;

  {v0.22}
  {/v0.22
  btop := ltop + editflds.Count * rheight + hdist;}
  bwidth := 75;
  {bleft := wdist;{will set to (fwidth - 2 * bwidth) div 3 below}
  bheight := 25;

  fleft := 181;
  ftop := 129;
  fwidth := max(eleft + ewidth, 339);

  {v0.22}
  fheight := ltop + 2 * hdist + bheight + fcheight;
  btop := ltop + hdist;
  for pi := 0 to editflds.Count - 1 do begin
    i := fldn.IndexOf(editflds[pi]);
    if i >= 0 then begin
      a := flda[i];
      typeFound := FindAttrib(a, pnType, av, false);
      editRowCount := 1;
      if typeFound then begin
        if (av = pvMemo) then
          editRowCount := MemoRowCount;
        if (av = pvMethod) then
          editRowCount := 0;
      end;
      fheight := fheight + editRowCount * rheight;
      btop := btop + editRowCount * rheight;
    end;
  end;
  {/v0.22
  fheight := ltop + editflds.Count * rheight + 2 * hdist + bheight + fcheight;}


  bleft := (fwidth - 2 * bwidth) div 3;
  if recdesc.ChildRecIDCount > 0 then begin
    bleft := (fwidth - 3 * bwidth) div 4;
  end;

  left := fleft;
  top := ftop;
  width := fwidth;
  height := fheight;
    { form's dimensions }

  dw('object ' + prefix + 'Form: T' + prefix + 'Form');
  dw('  Left = ' + IntToStr(left));
  dw('  Top = ' + IntToStr(top));
  dw('  Width = ' + IntToStr(width));
  dw('  Height = ' + IntToStr(height));
  dw('  Caption = ' + '''' + prefix + 'Form' + '''');
  dw('  Color = clBtnFace');
  dw('  Font.Charset = DEFAULT_CHARSET');
  dw('  Font.Color = clWindowText');
  dw('  Font.Height = -11');
  dw('  Font.Name = ' + '''' + 'MS Sans Serif' + '''');
  dw('  Font.Style = []');
  dw('  OldCreateOrder = False');
  dw('  OnCloseQuery = FormCloseQuery');
  dw('  OnCreate = FormCreate');
  dw('  PixelsPerInch = 96');
  dw('  TextHeight = 13');

  {v0.22}
  top := ltop;
  {/v0.22}
  for pi := 0 to editflds.Count - 1 do begin
    i := fldn.IndexOf(editflds[pi]);
    if i >= 0 then begin
      {v0.22}
      a := flda[i];
      typeFound := FindAttrib(a, pnType, av, false);
      editRowCount := 1;
      if typeFound then begin
        if (av = pvMemo) then
          editRowCount := MemoRowCount;
        if (av = pvMethod) then
          editRowcount := 0;
      end;
      if editRowCount > 0 then begin
      {/v0.22
      top := ltop + pi * rheight;}

        left := lleft;
        width := lwidth;
        height := lheight;
        dw('  object ' + fldn[i] + 'Lbl: TLabel');
        dw('    Left = ' + IntToStr(left));
        dw('    Top = ' + IntToStr(top));
        dw('    Width = ' + IntToStr(width));
        dw('    Height = ' + IntToStr(height));
        if recdesc.Flds^[i].Caption = '' then
          cap := InsertSpacesIntoMultiWordName(fldn[i])
        else
          cap := recdesc.Flds^[i].Caption;

        dw('    Caption = ' + ''' ' + cap + '''');
          { let space before caption to leave enough space from form margin -
             autosized forms put caption to close to the margin }
        dw('    FocusControl = ' + fldn[i] + 'Edit');
        dw('  end');
      {v0.22}
      end;
      top := top + rheight * editRowCount;
      {/v0.22}
    end;

  end;

  {v0.22}
  top := etop;
  {/v0.22}
  for pi := 0 to editflds.Count - 1 do begin
    i := fldn.IndexOf(editflds[pi]);
    if i >= 0 then begin
      a := flda[i];
      {v0.22}
      typeFound := FindAttrib(a, pnType, av, false);
      editRowCount := 1;
      {/v0.22
      top := etop + pi * rheight;}
      left := eleft;
      width := ewidth;
      height := eheight;
      if fldt[i] = 'boolean' then begin
        dw('  object ' + fldn[i] + 'Edit: TCheckBox');
        dw('    Left = ' + IntToStr(left));
        dw('    Top = ' + IntToStr(top));
        dw('    Width = ' + IntToStr(width));
        dw('    Height = ' + IntToStr(height));
        dw('    TabOrder = ' + IntToStr(tabord));
        typ := 'TCheckBox';
      end else if {v0.22} typeFound{/v0.22 FindAttrib(a, pnType, av, false)} and
        ( (av = pvEnum)
          {v0.14} or (av = pvULEnum){/v0.14}
        )
      then begin
        dw('  object ' + fldn[i] + 'Edit: TComboBox');
        dw('    Left = ' + IntToStr(left));
        dw('    Top = ' + IntToStr(top));
        dw('    Width = ' + IntToStr(width));
        dw('    Height = ' + IntToStr(height));
        dw('    TabOrder = ' + IntToStr(tabord));
        {v0.14}
        dw('    Style = csDropDownList');
        typ := 'TComboBox';
        {/v0.14}
      end else {v0.22} if typeFound and (av = pvMemo) then begin
        editRowCount := MemoRowCount;
        height := eheight * editRowCount;
        dw('  object ' + fldn[i] + 'Edit: TMemo');
        dw('    Left = ' + IntToStr(left));
        dw('    Top = ' + IntToStr(top));
        dw('    Width = ' + IntToStr(width));
        dw('    Height = ' + IntToStr(height));
        dw('    TabOrder = ' + IntToStr(tabord));
        typ := 'TMemo';
      end else if typeFound and (av = pvMethod) then begin
        editRowcount := 0;
      end else {/v0.22} begin
        dw('  object ' + fldn[i] + 'Edit: TEdit');
        dw('    Left = ' + IntToStr(left));
        dw('    Top = ' + IntToStr(top));
        dw('    Width = ' + IntToStr(width));
        dw('    Height = ' + IntToStr(height));
        dw('    TabOrder = ' + IntToStr(tabord));
        typ := 'TEdit';
      end;

      if (recdesc.Flds <> nil) and ((recdesc.Flds^[i].Flags and ffEnabled) = 0) then begin
        {if typ  = 'TEdit' then begin
          dw('    ReadOnly = True');
        end else}
        begin
          {v0.22}
          if editRowCount > 0 then
          {/v0.22}
            dw('    Enabled = False');
        end;
      end;
      {v0.14}
      if (recdesc.Flds <> nil) and ((recdesc.Flds^[i].Flags and ffReadOnly) <> 0) then begin
        {v0.22}
        if editRowCount > 0 then
        {/v0.22}
          dw('    ReadOnly = True');
      end;
      {/v0.14}

      {v0.22}
      if editRowCount > 0 then
      begin
        inc(tabord);
        dw('  end');
        top := top + rheight * editRowCount;
      end;
      {/v0.22
      inc(tabord);
      dw('  end');
      }
    end;
  end;

  left := bleft;
  top := btop;
  width := bwidth;
  height := bheight;

  dw('  object OKBtn: TButton');
  dw('    Left = ' + IntToStr(left));
  dw('    Top = ' + IntToStr(top));
  dw('    Width = ' + IntToStr(width));
  dw('    Height = ' + IntToStr(height));
  dw('    Caption = ' + '''' + '&OK' + '''');
  dw('    Default = True');
  dw('    ModalResult = 1');
  dw('    TabOrder = ' + IntToStr(tabord));
    inc(tabord);
  dw('  end');

  left := left + bwidth + bleft;

  dw('  object CancelBtn: TButton');
  dw('    Left = ' + IntToStr(left));
  dw('    Top = ' + IntToStr(top));
  dw('    Width = ' + IntToStr(width));
  dw('    Height = ' +  IntToStr(height));
  dw('    Caption = ' + '''' + '&Cancel' + '''');
  dw('    ModalResult = 2');
  dw('    TabOrder = ' + IntToStr(tabord));
    inc(tabord);
  dw('  end');

  if recdesc.ChildRecIDCount > 0 then begin
    left := left + bwidth + bleft;

    dw('  object ParamsBtn: TButton');
    dw('    Left = ' + IntToStr(left));
    dw('    Top = ' + IntToStr(top));
    dw('    Width = ' + IntToStr(width));
    dw('    Height = ' +  IntToStr(height));
    dw('    Caption = ' + '''' + '&Parameters' + '''');
    dw('    OnClick = ParamsBtnClick');
    dw('    TabOrder = ' + IntToStr(tabord));
    {  inc(tabord);}
    dw('  end');
  end;

  left := fwidth - compSize - wdist;
  top := hdist;
  dw('  object ' + prefix + 'FormIni: TIniObject');
  dw('    FormNameIsIniName = False');
  dw('    Disabled = True');
  dw('    Left = ' + IntToStr(left));
  dw('    Top = ' + IntToStr(top));
  dw('  end');
  dw('end');

  close(frdF);
  convfn := 'c:\PROGRA~1\Borland\Delphi4\Bin\convert';

  convfn := 'cmd /c convert';
  res := WinExec(StrPCopy(p,convfn + ' ' + DestDir + frdFn), 0);
  if (res <= 31) then begin
    writeln(convfn + ' ' + DestDir + frdFn + ' failed ' + IntToStr(res));
    readln;
  end;
end;

function ParseLine: boolean;
var
  s,ats:string;
  i:integer;
begin
  ParseLine:= true;
  if inRecord then begin
    if pos(' end;', Line) <> 0 then begin
      inRecord := false;
      ParseLine := false;
    end else begin
      { Line = fieldname: fieldtype; }
      if inAttr then begin
        if GetAttributesLine(Line, '{<','>}', inAttr, s) then begin
          ats := Trim(flda[flda.Count - 1] + ' ' + s);
          flda[flda.Count - 1] := ats;
        end;
      end else begin
        i := pos(':', Line);
        if i <> 0 then begin
          s := Trim(copy(Line, 1, i - 1));
          if (s <> 'Head') and (s <> 'Info')
          then begin
            fldn.Add(s);
            s := Trim(copy(Line, i + 1, 255));
            GetAttributesLine(s, '{<','>}', inAttr, ats);
            s := copy(s, 1, length(s) - 1);
              { strip ';' }
            fldt.Add(s);
            flda.Add(ats);
          end;
        end;
      end;
    end;
  end else begin
    if (pos('T' + prefix + 'Rec = packed record', Line) <> 0) or inAttr then begin
      if not inAttr then
        recattr := '';
      if GetAttributesLine(Line, '{<','>}', inAttr, s) then
        recattr := Trim(recattr + ' ' + s);
      if not inAttr then
        inRecord := true;
    end;
  end;
end;

procedure ParseAttr;
var
  av, s: string;
  i, p: integer;
  wrd:string;
  colr:longint;

  procedure SetRecFlags(rf:longint; OnOff:boolean);
  begin
    if OnOff then
      recdesc.Flags := recdesc.Flags or rf
    else
      recdesc.Flags := recdesc.Flags and (not rf);
  end;

  procedure SetFieldFlag(var f:longint; ff:longint; OnOff:boolean);
  begin
    if OnOff then
      f := f or ff
    else
      f := f and (not ff);
  end;

  procedure ParseFieldAttrs(var AFld: TULFldDesc);
  var
    curFieldColors: TULFieldColors;
  begin
    with AFld{v0.24}{/v0.24 recdesc.Flds^[i]} do begin
      s := flda[i];
      if FindAttrib(s, pnCaption, av, false) then
        Caption := av;
      if FindAttrib(s, pnHint, av, false) then
        Hint := av;
      if FindAttrib(s, pnEditWidth, av, false) then
        EditWidth := StrToInt(av);
      if FindAttrib(s, pnBrowseWidth, av, false) then
        BrowseWidth := StrToInt(av);
      if FindAttrib(s, pnUserCoef, av, false) then
        UserCoef := StrToFloat(FixDecSep(av));
      if FindAttrib(s, pnNumDec, av, false) then
        NumDec := StrToInt(av);
      if FindAttrib(s, pnEnabled, av, false) then begin
        SetFieldFlag(Flags, ffEnabled, (av='1'));
      end;
      {v0.22}
      if FindAttrib(s, pnNonVisible, av, false) then begin
        SetFieldFlag(Flags, ffNonVisible, (av='1'));
      end;
      {/v0.22}
      {v0.14}
      if FindAttrib(s, pnReadOnly, av, false) then begin
        SetFieldFlag(Flags, ffReadOnly, (av = '1'));
      end;
      {/v0.14}
      if FindAttrib(s, pnType, av, false) then begin
        if av = pvFileName then begin
          SetFieldFlag(Flags, ffFileName, true);
        end;
        {v0.24}
        if av = pvDir then begin
          SetFieldFlag(Flags, ffDir, true);
        end;
        {/v0.24}
        {v0.14}
        if av = pvULEnum then begin
          SetFieldFlag(Flags, ffULEnum, true);
        end;
        if av = pvFileDateTime then begin
          SetFieldFlag(Flags, ffFileDateTime, true);
        end;
        {/v0.14}
        {/v0.22}
        if av = pvMemo then begin
          SetFieldFlag(Flags, ffMemo, true);
        end;
        if av = pvMethod then begin
          SetFieldFlag(Flags, ffMethod, true);
        end;
        {/v0.22}
      end;
      {v0.14 moved above}{/v0.14
      if FindAttrib(s, pnType, av, false) then begin
        if av = pvFileDateTime then begin
          SetFieldFlag(Flags, ffFileDateTime, true);
        end;
      end;}
      {v0.14}
      if FindAttrib(s, pnValuesSourceRecID, av, false) then begin
        p := pos('ID', av);
        if p = (length(av) - 1) then begin
          av := copy(av, 1, p - 1);
        end;
        ValuesSourceRecID := StrToULRecID(av);
        {v0.22}
        SetRecFlags(rfHasPointer, true);
        {/v0.22}
      end;
      {/v0.14}

      {v0.23}
      if FindAttrib(s, pvWriteAlways, av, false) then begin
        SetFieldFlag(Flags, ffWriteAlways, true);
      end;
      if fldt[i] = 'TCommand' then
        SetFieldFlag(Flags, ffCommand, true);
      {/v0.23}

      {v0.23}
      if fldt[i] = 'TCommand' then
        SetFieldFlag(Flags, ffCommand, true);
      {/v0.23}

      {v0.24}
      if FindAttrib(s, pnColors, av, false) then begin
        fillchar(curFieldColors, sizeof(curFieldColors), 0);
        while ExtractWord([','], wrd, av) do begin
          if not IdentToColor(wrd, colr) then begin
            wrd := 'clBlack';
            colr := clBlack;
          end;
          curFieldColors[FieldColorCount, 0] := colr;

          if not ExtractWord([','], wrd, av) then begin
            wrd := 'clWhite';
          end;
          if not IdentToColor(wrd, colr) then
            colr := clWhite;
          curFieldColors[FieldColorCount, 1] := colr;

          inc(FieldColorCount);{uldrtype ulanobj\uldrobju}
          if FieldColorCount = ULMaxFieldColorCount then
            break;
        end;
        if FieldColorCount > 0 then begin
          GetMem(FieldColors, sizeof(TULFieldColor) * FieldColorCount);
          Move(curFieldColors, FieldColors^, sizeof(TULFieldColor) * FieldColorCount);
          SetRecFlags(rfUsingColors, true);
        end;
      end;

      if FindAttrib(s, pnFilter, av, false) then begin
        Filter := av;
      end;

      {/v0.24}
    end;

    {v0.22}
    if pos('_Ptr', fldn[i]) > 0 then
      SetRecFlags(rfHasPointer, true);
    {/v0.22}
  end;

begin
  if recattr <> '' then begin
    with recdesc do begin
      if FindAttrib(recattr, pnCaption, av, false) then
        Caption := av;
      if FindAttrib(recattr, pnSortExp, av, false) then
        SortExp := av;
      if FindAttrib(recattr, pnUses, av, false) then
        usesStr := av;
      if FindAttrib(recattr, pnRootChild, av, false) then
        SetRecFlags(rfRootChild, (av = '1'));
      if FindAttrib(recattr, pnChildSorted, av, false) then
        SetRecFlags(rfChildSorted, (av = '1'));
      if FindAttrib(recattr, pnHasRecName, av, false) then
        SetRecFlags(rfHasRecName, (av = '1'));
      {v0.22}
      if FindAttrib(recattr, pnHasPointer, av, false) then
        SetRecFlags(rfHasPointer, (av = '1'));
      {/v0.22}
      {v0.24}
      if FindAttrib(recattr, pnUsingColors, av, false) then
        SetRecFlags(rfUsingColors, (av = '1'));
      {/v0.24}
      if FindAttrib(recattr, pnDataChild, av, false) then begin
        SetRecFlags(rfDataChild, (av = '1'));
        if (Flags and rfDataChild) <> 0 then
         SetRecFlags(rfChildAllowed, true);
      end;
      if FindAttrib(recattr, pnTemporary, av, false) then
        SetRecFlags(rfTemporary, (av = '1'));
      if FindAttrib(recattr, pnEnabled, av, false) then
        SetRecFlags(rfEnabled, (av = '1'));
      {v1.03}
      if FindAttrib(recattr, pnEditModal, av, false) then
        SetRecFlags(rfEditModal, (av = '1'));
      {/v1.03}
      {v0.23}
      if FindAttrib(recattr, pnBrowseModal, av, false) then
        SetRecFlags(rfBrowseModal, (av = '1'));
      {/v0.23}

      {v0.14}
{      if FindAttrib(recattr, pnReadOnly, av, false) then
        SetRecFlags(rfReadOnly, (av = '1'));}
      {/v0.14}
      if FindAttrib(recattr, pnVisible, av, false) then
        SetRecFlags(rfVisible, (av = '1'));
      if FindAttrib(recattr, pnFileDataStream, av, false) then
        SetRecFlags(rfFileDataStream, (av = '1'));
      if FindAttrib(recattr, pnBrowseOnEdit, av, false) then
        SetRecFlags(rfBrowseOnEdit, (av = '1'));
      if FindAttrib(recattr, pnSortedByNumber, av, false) then
        SetRecFlags(rfSortedByNumber, (av = '1'));
      if FindAttrib(recattr, pnEditFieldList, av, false) then
        EditFieldList := av;
      if FindAttrib(recattr, pnBrowseFieldList, av, false) then
        BrowseFieldList := av;
      {v0.22}
      if FindAttrib(recattr, pnMenuFieldList, av, false) then
        MenuFieldList := av;
      {/v0.22}
      {v0.23}
      if FindAttrib(recattr, pnBrowseChildRecIDs, av, false) then
        BrowseChildRecIDs := av;
      if FindAttrib(recattr, pnNameProp, av, false) then
        NameProp := av;
      {/v0.23}
      {v0.24}
      if FindAttrib(recattr, pnMainProp, av, false) then
        MainProp := av;
      {/v0.24}

      if FindAttrib(recattr, pnChildRecIDs, av, false) then begin
        Flags := (Flags or rfChildAllowed) and (not rfDataChild);
        ChildRecIDsStr := av;             {ulrectyp}
        i := 1;
        repeat
          s := FindWord([' ',','], av, i, true);
          if s = '' then
            break;
          inc(ChildRecIDCount);
        until false;
      end;
      FldCount := 0;{for now}
      Flds := nil;
    end;
  end;

  if flda.Count > 0 then begin
    recdesc.FldCount := flda.Count;
    GetMem(recdesc.Flds, sizeof(TULFldDesc)* flda.Count);
    FillChar(recdesc.Flds^, sizeof(TULFldDesc)* flda.Count, 0);
    for i := 0 to flda.Count - 1 do begin
      ParseFieldAttrs(recdesc.Flds^[i]);
    end;
  end;

  editflds.Clear;
  if recdesc.EditFieldList <> '' then begin
    p := 1;
    repeat
      av := FindWord([','], recdesc.EditFieldList, p, true);
      if av <> '' then begin
        editflds.Add(av);
      end else
        break;
    until false;
  end else begin
    for i := 0 to fldn.Count - 1 do begin
      {v0.22}
      if (recdesc.Flds^[i].Flags and ffNonVisible) = 0 then
      {/v0.22}
      editflds.Add(fldn[i]);
    end;
  end;

end;

procedure MakeObj(fn:string);
var i: integer;
begin
  i := pos('TYPE', UpperCase(fn));
  prefix := UpperCase(copy(fn, 1, i - 1));
  inn := UpperCase(fn) + '.PAS';
  usesStr := '';

  objFn := prefix + 'OBJU.PAS';
  objN := 'T' + prefix + 'Obj';
  objUn := prefix + 'Obju';

  frmFn := prefix + 'FRMU.PAS';
  frmN := 'T' + prefix + 'Form';
  frmUn := prefix + 'Frmu';

  frdFn := prefix + 'FRMU.TXT';

  editflds := TStringList.Create;
  fldn := TStringList.Create;
  fldt := TStringList.Create;
  flda := TStringList.Create;


  recattr := '';
  FillChar(childrecids, sizeof(childrecids), 0);
  recdesc.ChildRecIDs := @childrecids;
  recdesc.Caption := '';
  recdesc.ChildRecIDsStr := '';
  recdesc.ChildRecIDCount := 0;
  recdesc.FldCount := 0;
  recdesc.Flds := nil;
  recdesc.SortExp := '';
  recdesc.Flags := 0;
  recdesc.EditFieldList := '';
  recdesc.BrowseFieldList := '';
  {v0.22}
  recdesc.MenuFieldList := '';
  {/v0.22}
  {v0.22}
  recdesc.BrowseChildRecIDs := '';
  recdesc.NameProp := '';
  {/v0.22}
  {v0.24}
  recdesc.MainProp := '';
  {/v0.24}

  InInit;

  ObjInit;
  FrmInit;
  FrdInit;

  while not eof(inf) do begin
    readln(inf, Line);
    if not ParseLine then
      break;
  end;
  urecattr.Add(recattr);
  ParseAttr;

  InDone;

  ObjDone;
  FrdDone;
  FrmDone;

  editflds.Free;
  fldn.Free;
  fldt.Free;
  flda.Free;
  if recdesc.FldCount > 0 then begin
    FreeMem(recdesc.Flds);
  end;
end;

procedure MakeObjs(ListFn:string);
var
  f:text;
  s:string;
  i:integer;
  pref:string;
{v1.04}
  fn:string;
{/v1.04}
begin
  fn := ExpandFileName(ListFn);
  {v1.04}
  SourceDir := ExtractFilePath(fn);
  DestDir := SourceDir;
  if UpperCase(copy(DestDir, length(DestDir) - 3, 3)) = 'DEF' then
    DestDir := copy(DestDir, 1, length(DestDir) - 4) + 'Obj\';
  fn := ExtractFileName(fn);
  i := pos('RECS', UpperCase(fn));
  if i > 0 then begin
    ProjectPrefix := copy(fn, 1, i - 1);
  end;
  {/v1.04}
  IncInit;
  assign(f, ListFn);
  reset(f);
  while not eof(f) do begin
    readln(f, s);
    if (s <> '') and (s[1] <> ' ') then begin
      i := pos(' ', s);
      if i <> 0 then begin
        pref := copy(s, 1, i - 1);
        ulst.add(pref);
        MakeObj(pref + 'Type');
      end;
    end;
  end;
  close(f);
  IncWrite;
  IncDone;
end;

procedure Help;
begin
  writeln('Usage: MakeComp [@[PathXXXX[Def]\]UlanRecs.lst | xxxxTYPE[.PAS] ]');
  writeln('Creates TxxxxObj object declaration/definition units xxxxOBJU.PAS,');
  writeln('objects' + '''' + ' editing form xxxxFRMU.PAS, xxxFRMU.DFM and');
  writeln('include files necessary for compiling ULFObju.pas file.');
  writeln('(Uses Delphi CONVERT.EXE program)');
  writeln('Using fields from "TxxxxRec = packed record" found in xxxxTYPE.PAS file.');
  writeln('xxxx is 1-4 uppercase chars. Ulan projects use ULxx.');
  writeln;
  writeln('If path of xxxxtype file specified then output will be made ');
  writeln('to the same directory. If the input path ends by "Def\" then ');
  writeln('the end is replaced by "Obj\" end the output will be made there.');
  writeln;
  writeln('If @file is specified as input, then the file will be');
  writeln('scanned for xxType.pas file names. Only lines that do not start');
  writeln('with space will be included to searching.');
  writeln('If the file name contains "Recs" string, then chars (xxx) before this word');
  writeln('will be used for including type file xxxType to all generated .pas files');
  writeln('uses section. If no "Recs" is in the file name, UlanType will be included.');
end;


var s: string;
begin
  if paramcount = 0 then
    Help
  else begin
    s := paramstr(1);
    if s[1] = '@' then begin
      s := copy(s, 2, 255);
      MakeObjs(s);
    end else
      MakeObj(s);
  end;
  writeln('Press Enter to finish.');
  readln;
end.
