Changeset 13 for trunk


Ignore:
Timestamp:
May 9, 2014, 12:37:10 AM (11 years ago)
Author:
chronos
Message:
  • Added: Basic parsing of "Depends on" expressions.
Location:
trunk
Files:
52 added
12 edited

Legend:

Unmodified
Added
Removed
  • trunk

    • Property svn:ignore
      •  

        old new  
        33LinuxBuilder.lps
        44LinuxBuilder.res
         5backup
  • trunk/LinuxBuilder.lpi

    r11 r13  
    2828      </local>
    2929    </RunParams>
    30     <RequiredPackages Count="2">
     30    <RequiredPackages Count="4">
    3131      <Item1>
     32        <PackageName Value="reg"/>
     33        <DefaultFilename Value="Packages/fcl-registry/reg.lpk" Prefer="True"/>
     34      </Item1>
     35      <Item2>
     36        <PackageName Value="TemplateGenerics"/>
     37        <DefaultFilename Value="Packages/TemplateGenerics/TemplateGenerics.lpk" Prefer="True"/>
     38      </Item2>
     39      <Item3>
    3240        <PackageName Value="Common"/>
    3341        <DefaultFilename Value="Packages/Common/Common.lpk" Prefer="True"/>
    34       </Item1>
    35       <Item2>
     42      </Item3>
     43      <Item4>
    3644        <PackageName Value="LCL"/>
    37       </Item2>
     45      </Item4>
    3846    </RequiredPackages>
    3947    <Units Count="7">
  • trunk/LinuxBuilder.lpr

    r11 r13  
    99  Interfaces, // this includes the LCL widgetset
    1010  Forms, UFormMain, UKConfig, UFormList, UFormLog, UFormCompare, UFormSearch,
    11   Common
     11  Common, TemplateGenerics
    1212  { you can add units after this };
    1313
  • trunk/Packages/Common/Common.lpk

    r11 r13  
    112112    </i18n>
    113113    <Type Value="RunAndDesignTime"/>
    114     <RequiredPkgs Count="2">
     114    <RequiredPkgs Count="3">
    115115      <Item1>
    116         <PackageName Value="TemplateGenerics"/>
     116        <PackageName Value="reg"/>
    117117      </Item1>
    118118      <Item2>
     119        <PackageName Value="TemplateGenerics"/>
     120      </Item2>
     121      <Item3>
    119122        <PackageName Value="FCL"/>
    120123        <MinVersion Major="1" Valid="True"/>
    121       </Item2>
     124      </Item3>
    122125    </RequiredPkgs>
    123126    <UsageOptions>
  • trunk/Packages/Common/UApplicationInfo.pas

    r11 r13  
    66
    77uses
    8   SysUtils, Registry, Classes, Forms, URegistry;
     8  SysUtils, Registry2, Classes, Forms, URegistry;
    99
    1010type
  • trunk/Packages/Common/ULastOpenedList.pas

    r11 r13  
    66
    77uses
    8   Classes, SysUtils, Registry, URegistry, Menus;
     8  Classes, SysUtils, myregistry, URegistry, Menus, Dialogs;
    99
    1010type
  • trunk/Packages/Common/UPersistentForm.pas

    r11 r13  
    88
    99uses
    10   Classes, SysUtils, Forms, URegistry, LCLIntf, Registry;
     10  Classes, SysUtils, Forms, URegistry, LCLIntf, Registry2;
    1111
    1212type
  • trunk/Packages/Common/URegistry.pas

    r11 r13  
    66
    77uses
    8   Classes, Registry;
     8  Classes, MyRegistry;
    99
    1010type
  • trunk/UFormMain.lfm

    r12 r13  
    145145      object MenuItemOpenRecent: TMenuItem
    146146        Caption = 'Open recent'
    147         OnClick = MenuItemOpenRecentClick
    148147      end
    149148      object MenuItem7: TMenuItem
  • trunk/UFormMain.pas

    r12 r13  
    77uses
    88  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Menus,
    9   ActnList, ComCtrls, StdCtrls, UKConfig, ULastOpenedList, URegistry, Registry;
     9  ActnList, ComCtrls, StdCtrls, UKConfig, ULastOpenedList, URegistry, Registry2;
    1010
    1111const
     
    6767    procedure LastOpenedListCompareChange(Sender: TObject);
    6868    procedure LastOpenedListOpenChange(Sender: TObject);
    69     procedure MenuItemOpenRecentClick(Sender: TObject);
    7069    procedure TreeView1SelectionChanged(Sender: TObject);
    7170  private
     
    9594begin
    9695  AutoOpen := True;
    97   LastOpenedListOpen.LoadFromRegistry(RegContext(RootKey, RootPath + '/OpenRecent'));
    98   LastOpenedListCompare.LoadFromRegistry(RegContext(RootKey, RootPath + '/CompareRecent'));
     96  LastOpenedListOpen.LoadFromRegistry(RegContext(RootKey, RootPath + '\OpenRecent'));
     97  LastOpenedListCompare.LoadFromRegistry(RegContext(RootKey, RootPath + '\CompareRecent'));
    9998  if AutoOpen and (LastOpenedListOpen.Items.Count > 0) then
    10099    OpenDir(LastOpenedListOpen.Items[0])
     
    112111  LastOpenedListOpen.LoadToMenuItem(MenuItemOpenRecent, AOpenDirExecute);
    113112  LastOpenedListOpen.LoadToMenuItem(PopupMenuOpenRecent.Items, AOpenDirExecute);
    114 end;
    115 
    116 procedure TFormMain.MenuItemOpenRecentClick(Sender: TObject);
    117 begin
    118 
    119113end;
    120114
     
    254248procedure TFormMain.FormClose(Sender: TObject; var CloseAction: TCloseAction);
    255249begin
    256   LastOpenedListOpen.SaveToRegistry(RegContext(RootKey, RootPath + '/OpenRecent'));
    257   LastOpenedListCompare.SaveToRegistry(RegContext(RootKey, RootPath + '/CompareRecent'));
     250  LastOpenedListOpen.SaveToRegistry(RegContext(RootKey, RootPath + '\OpenRecent'));
     251  LastOpenedListCompare.SaveToRegistry(RegContext(RootKey, RootPath + '\CompareRecent'));
    258252end;
    259253
  • trunk/UFormSearch.pas

    r6 r13  
    5050    FormMain.Config.TopNode.Search(EditText.Text, List);
    5151    ListView1.Items.Clear;
     52    ListView1.Items.BeginUpdate;
    5253    for I := 0 to List.Count - 1 do
    5354    with TMenuNode(List[I]) do begin
     
    5960    end;
    6061  finally
     62    ListView1.Items.EndUpdate;
    6163    List.Free;
    6264  end;
  • trunk/UKConfig.pas

    r11 r13  
    1515    vtComment);
    1616
     17  TMenuNode = class;
    1718  TLoadTreeOption = (toShowSystem);
    1819  TLoadTreeOptions = set of TLoadTreeOption;
     
    3031    ExpOperator: TExpOperator;
    3132    Items: TObjectList; // TList<TExpression>
    32     constructor Create;
     33    Parent: TExpression;
     34    function Show: String; virtual;
     35    procedure GetList(List: TStringList); virtual;
     36    constructor Create; virtual;
    3337    destructor Destroy; override;
    3438  end;
    3539
    36   TExpressionVar = class
     40  TCompareType = (ctNone, ctEqual, ctNotEqual);
     41
     42  { TExpressionVar }
     43
     44  TExpressionVar = class(TExpression)
    3745    Name: string;
     46    Node: TMenuNode;
    3847    Negative: Boolean;
     48    Compare: TCompareType;
     49    Value: string;
     50    constructor Create; override;
     51    procedure GetList(List: TStringList); override;
     52    function Show: String; override;
    3953  end;
    4054
     
    4256
    4357  TMenuNode = class
     58  private
     59    function GetVisible: Boolean;
     60  public
    4461    ID: string;
    4562    Name: string;
    46     Depends: TStringList;
     63    DependsOn: TExpression;
    4764    Selects: TStringList;
    4865    Description: TStringList;
     
    7087    function GetTopNode: TMenuNode; virtual;
    7188    function FindNode(ID: string): TMenuNode; virtual;
     89    property Visible: Boolean read GetVisible;
    7290  end;
    7391
     
    82100    Arch: string;
    83101    FOnLog: TOnLogEvent;
     102    ParseFileName: string;
     103    LineNumber: Integer;
    84104    function GetTopCondition: string;
    85105    procedure Log(Text: string);
    86106    function IsWhiteSpace(Character: Char): Boolean;
     107    function IsAlpha(Character: Char): Boolean;
     108    function IsAlphaNumeric(Character: Char): Boolean;
     109    function IsNumeric(Character: Char): Boolean;
     110    function IsIdentifier(Name: string): Boolean;
     111    function IsSpecialSymbol(Character: Char): Boolean;
     112    procedure Expect(var Text: string; Token: string);
    87113    function GetNextToken(var Text: string): string;
     114    procedure ParseExpression(Node: TMenuNode; Line: string);
    88115    procedure ParseFile(FileName: string);
    89116    procedure ParseConfig;
    90117    procedure ParseMakeFile;
     118    function GetLog: string;
    91119  public
    92120    TopNode: TMenuNode;
     
    105133implementation
    106134
     135{ TExpressionVar }
     136
     137constructor TExpressionVar.Create;
     138begin
     139  inherited;
     140  Compare := ctNone;
     141  Value := '';
     142  Negative := False;
     143  Name := '';
     144end;
     145
     146procedure TExpressionVar.GetList(List: TStringList);
     147begin
     148  inherited GetList(List);
     149  List.Add(Name);
     150end;
     151
     152function TExpressionVar.Show: String;
     153begin
     154  Result := Name;
     155  if Negative then Result := '!' + Result;
     156  if Compare = ctEqual then Result := Result + ' = ' + Value;
     157  if Compare = ctNotEqual then Result := Result + ' != ' + Value;
     158end;
     159
    107160{ TExpression }
    108161
     162function TExpression.Show: String;
     163var
     164  Operand: string;
     165  I: Integer;
     166begin
     167  Result := '';
     168  if ExpOperator = eoAnd then Operand := '&&';
     169  if ExpOperator = eoOr then Operand := '||';
     170  for I := 0 to Items.Count - 1 do begin
     171    Result := Result + TExpression(Items[I]).Show;
     172    if I < (Items.Count - 1) then Result := Result + ' ' + Operand + ' ';
     173  end;
     174  if Assigned(Parent) then Result := '(' + Result + ')';
     175end;
     176
     177procedure TExpression.GetList(List: TStringList);
     178var
     179  I: Integer;
     180begin
     181  for I := 0 to Items.Count - 1 do
     182    TExpression(Items[I]).GetList(List);
     183end;
     184
    109185constructor TExpression.Create;
    110186begin
    111187  Items := TObjectList.Create;
     188  Parent := nil;
     189  ExpOperator := eoAnd;
    112190end;
    113191
     
    119197
    120198{ TMenuNode }
     199
     200function TMenuNode.GetVisible: Boolean;
     201var
     202  I: Integer;
     203begin
     204  Result := True;
     205  //for I := 0 to Depends.Count - 1 do
     206  //if Depends[I]
     207end;
    121208
    122209constructor TMenuNode.Create;
     
    125212  ID := '';
    126213  Parent := nil;
    127   Depends := TStringList.Create;
     214  DependsOn := TExpression.Create;
    128215  Description := TStringList.Create;
    129216  Selects := TStringList.Create;
     
    134221destructor TMenuNode.Destroy;
    135222begin
     223  DependsOn.Free;
    136224  Items.Free;
    137   Depends.Free;
    138225  Description.Free;
    139226  Selects.Free;
     
    197284    Add('ID: ' + ID);
    198285    Add('Name: ' + Name);
    199     Add('Depends on: ' + Depends.Text);
     286    Add('Depends on: ' + DependsOn.Show);
    200287    Add('Selects: ' + Selects.Text);
    201288    Add('Description: ' + Description.Text);
     
    245332  LatestNode: TMenuNode;
    246333  CheckList: TObjectList;
     334  DepList: TStringList;
    247335begin
    248336  Result := False;
     
    250338    CheckList := TObjectList.Create;
    251339    CheckList.OwnsObjects := False;
     340    DepList := TStringList.Create;
    252341    if Assigned(Parent) then begin
    253342    Index := Parent.Items.IndexOf(Self);
    254343    if Index = -1 then raise Exception.Create('Node not found in parent');
    255344    if Index >= 1 then TMenuNode(Parent.Items[Index - 1]).AddLastToList(CheckList);
     345    DepList.Clear;
     346    DependsOn.GetList(DepList);
    256347    for I := CheckList.Count - 1 downto 0 do begin
    257       for J := 0 to Depends.Count - 1 do
    258       if Trim(Depends[J]) <> '' then begin
    259         if (Depends[J] = TMenuNode(CheckList[I]).ID) and (TMenuNode(CheckList[I]).ValueType <> vtChoice) then begin
     348      for J := 0 to DepList.Count - 1 do
     349      if Trim(DepList[J]) <> '' then begin
     350        if (DepList[J] = TMenuNode(CheckList[I]).ID) and (TMenuNode(CheckList[I]).ValueType <> vtChoice) then begin
    260351          ChangeParent(TMenuNode(CheckList[I]));
    261352          Result := True;
     
    267358    end;
    268359  finally
     360    DepList.Free;
    269361    CheckList.Free;
    270362  end;
     
    329421end;
    330422
     423function TConfigMenu.IsAlpha(Character: Char): Boolean;
     424begin
     425  Result := ((Character >= 'a') and (Character <= 'z'))
     426    or ((Character >= 'A') and (Character <= 'Z'));
     427end;
     428
     429function TConfigMenu.IsAlphaNumeric(Character: Char): Boolean;
     430begin
     431  Result := IsAlpha(Character) or IsNumeric(Character);
     432end;
     433
     434function TConfigMenu.IsNumeric(Character: Char): Boolean;
     435begin
     436  Result := (Character >= '0') and (Character <= '9');
     437end;
     438
     439function TConfigMenu.IsIdentifier(Name: string): Boolean;
     440var
     441  I: Integer;
     442begin
     443  Result := True;
     444  for I := 1 to Length(Name) do
     445    if not (IsAlphaNumeric(Name[I]) or (Name[I] = '_')) then begin
     446      Result := False;
     447      Break;
     448    end;
     449end;
     450
     451function TConfigMenu.IsSpecialSymbol(Character: Char): Boolean;
     452begin
     453  Result := (Character = '!') or (Character = '=') or (Character = '(') or
     454    (Character = ')') or (Character = '-') or (Character = '|') or (Character = '&');
     455end;
     456
     457procedure TConfigMenu.Expect(var Text: string; Token: string);
     458begin
     459  if GetNextToken(Text) <> Token then
     460    raise Exception.Create('Expected "' + Token + '"');
     461end;
     462
    331463function TConfigMenu.GetNextToken(var Text: string): string;
    332464var
    333465  I: Integer;
    334466  Terminate: Boolean;
    335   State: (stNormal, stWhiteSpace, stString);
     467  State: (stNormal, stWhiteSpace, stString, stSpecialSymbol, stIdent,
     468    stString2);
    336469begin
    337470  I := 1;
     
    350483        State := stNormal;
    351484        Terminate := True;
     485        Inc(I);
     486      end else Result := Result + Text[I];
     487    end else
     488    if State = stString2 then begin
     489      if Text[I] = '''' then begin
     490        State := stNormal;
     491        Terminate := True;
     492        Inc(I);
     493      end else Result := Result + Text[I];
     494    end else
     495    if State = stSpecialSymbol then begin
     496      if not IsSpecialSymbol(Text[I]) or (Result = '(') or (Result = ')') or
     497        ((Result = '!') and (Text[I] <> '=')) or (Result = '||') or
     498        (Result = '&&') then begin
     499        State := stNormal;
     500        Terminate := True;
     501      end else Result := Result + Text[I];
     502    end else
     503    if State = stIdent then begin
     504      if not (IsAlphanumeric(Text[I]) or (Text[I] = '_')) then begin
     505        State := stNormal;
     506        Terminate := True;
    352507      end else Result := Result + Text[I];
    353508    end else begin
    354509      if IsWhiteSpace(Text[I]) then State := stWhiteSpace
    355510      else if Text[I] = '"' then State := stString
     511      else if Text[I] = '''' then State := stString2
     512      else if Text[I] = '#' then begin
     513        // Comment
     514        Text := '';
     515        Terminate := True;
     516      end
     517      else if IsSpecialSymbol(Text[I]) then begin
     518        State := stSpecialSymbol;
     519        Result := Result + Text[I];
     520      end
     521      else if IsAlphaNumeric(Text[I]) then begin
     522        State := stIdent;
     523        Result := Result + Text[I];
     524      end
    356525      else Result := Result + Text[I];
    357526    end;
     
    359528  end;
    360529  Delete(Text, 1, I - 1);
     530end;
     531
     532procedure TConfigMenu.ParseExpression(Node: TMenuNode; Line: string);
     533var
     534  Token: string;
     535  Exp: TExpression;
     536  ExpVar: TExpressionVar;
     537  ExpNew: TExpression;
     538  Neg: Boolean;
     539  Compare: TCompareType;
     540begin
     541  Line := Trim(Line);
     542  Exp := Node.DependsOn;
     543  Neg := False;
     544  while Line <> '' do begin
     545    Token := GetNextToken(Line);
     546    if Token = '||' then begin
     547      Exp.ExpOperator := eoOr;
     548    end else
     549    if Token = '&&' then begin
     550      Exp.ExpOperator := eoAnd;
     551    end else
     552    if Token = '!' then begin
     553      Neg := True;
     554      Continue;
     555    end else
     556    if Token = '(' then begin
     557      ExpNew := TExpression.Create;
     558      ExpNew.Parent := Exp;
     559      Exp.Items.Add(ExpNew);
     560      Exp := ExpNew;
     561      Neg := False;
     562    end else
     563    if Token = ')' then begin
     564      if Assigned(Exp.Parent) then Exp := Exp.Parent
     565        else raise Exception.Create('Cannot go to expression parent.' + GetLog);
     566      Neg := False;
     567    end else
     568    if Token = '' then begin
     569      // White space
     570    end else
     571    if Token = '=' then begin
     572      ExpVar.Compare := ctEqual;
     573      Token := GetNextToken(Line);
     574      ExpVar.Value := Token;
     575      Continue;
     576    end else
     577    if Token = '!=' then begin
     578      ExpVar.Compare := ctNotEqual;
     579      Token := GetNextToken(Line);
     580      ExpVar.Value := Token;
     581      Continue;
     582    end else
     583    if IsIdentifier(Token) then begin
     584      ExpVar := TExpressionVar.Create;
     585      ExpVar.Negative := Neg;
     586      ExpVar.Name := Token;
     587      ExpVar.Compare := Compare;
     588      Exp.Items.Add(ExpVar);
     589      Neg := False;
     590    end else
     591      raise Exception.Create('Unknown token "' + Token + '".' + GetLog);
     592  end;
     593
     594  {// Just try to load symbol list. Do not parse expression
     595  while Trim(Line) <> '' do begin
     596    Parameter := GetNextToken(Line);
     597    if Copy(Parameter, 1, 1) = '!' then Delete(Parameter, 1, 1);
     598    if Copy(Parameter, 1, 1) = '(' then Delete(Parameter, 1, 1);
     599    if Copy(Parameter, Length(Parameter), 1) = ')' then Delete(Parameter, Length(Parameter), 1);
     600    Parameter := Trim(Parameter);
     601    if (Parameter <> '&&') and (Parameter <> '||') then
     602      Node.Depends.Add(Parameter);
     603  end;
     604  }
     605
     606end;
     607
     608function TConfigMenu.GetLog: string;
     609begin
     610  Result := ' ' + ParseFileName + ':' + IntToStr(LineNumber);
    361611end;
    362612
     
    375625  HelpIndent: Integer;
    376626  LineIndent: Integer;
    377 
    378 function GetLog: string;
    379 begin
    380   Result := FileName + ':' + IntToStr(I + 1) + ' ' + Content[I];
    381 end;
    382 
     627  NewExp: TExpressionVar;
    383628const
    384629  TabSize = 8;
    385 
    386 begin
     630begin
     631  ParseFileName := FileName;
    387632  Log('FILE ' + FileName);
    388633  try
     
    394639    HelpIndent := 0;
    395640    for I := 0 to Content.Count - 1 do begin
     641      LineNumber := I + 1;
    396642      Line := MergedLines + Content[I];
    397643      MergedLines := '';
     
    408654        HelpIndent := LineIndent;
    409655        if (State = stHelpStart) and (HelpIndent = 0) then
    410           raise Exception.Create('Error during help parsing');
     656          raise Exception.Create('Error during help parsing.' + GetLog);
    411657      end;
    412658      if (State = stHelpStart) and (Trim(Line) <> '') and (LineIndent < HelpIndent) then
     
    434680      end else
    435681      if (Command = 'bool') or (Command = 'boolean') then begin
    436         Parameter := GetNextToken(Line);
    437         if not Assigned(NewItem) then raise Exception.Create('Item not defined. ' + GetLog);
     682        Expect(Line, '');
     683        Parameter := GetNextToken(Line);
     684        if not Assigned(NewItem) then raise Exception.Create('Item not defined.' + GetLog);
    438685        NewItem.ValueType := vtBool;
    439686        NewItem.Name := Parameter;
    440687      end else
    441688      if Command = 'def_bool' then begin
    442         Parameter := GetNextToken(Line);
    443         if not Assigned(NewItem) then raise Exception.Create('Item not defined. ' + GetLog);
     689        Expect(Line, '');
     690        Parameter := GetNextToken(Line);
     691        if not Assigned(NewItem) then raise Exception.Create('Item not defined.' + GetLog);
    444692        NewItem.DefaultValue := Parameter;
    445693        NewItem.ValueType := vtBool;
    446694      end else
    447695      if Command = 'tristate' then begin
    448         Parameter := GetNextToken(Line);
    449         if not Assigned(NewItem) then raise Exception.Create('Item not defined. ' + GetLog);
     696        Expect(Line, '');
     697        Parameter := GetNextToken(Line);
     698        if not Assigned(NewItem) then raise Exception.Create('Item not defined.' + GetLog);
    450699        NewItem.Name := Parameter;
    451700        NewItem.ValueType := vtTristate;
    452701      end else
    453702      if Command = 'def_tristate' then begin
    454         Parameter := GetNextToken(Line);
    455         if not Assigned(NewItem) then raise Exception.Create('Item not defined. ' + GetLog);
     703        Expect(Line, '');
     704        Parameter := GetNextToken(Line);
     705        if not Assigned(NewItem) then raise Exception.Create('Item not defined.' + GetLog);
    456706        NewItem.Name := Parameter;
    457707      end else
    458708      if Command = 'string' then begin
    459         Parameter := GetNextToken(Line);
    460         if not Assigned(NewItem) then raise Exception.Create('Item not defined. ' + GetLog);
     709        Expect(Line, '');
     710        Parameter := GetNextToken(Line);
     711        if not Assigned(NewItem) then raise Exception.Create('Item not defined.' + GetLog);
    461712        NewItem.Name := Parameter;
    462713        NewItem.ValueType := vtString;
    463714      end else
    464715      if Command = 'int' then begin
    465         Parameter := GetNextToken(Line);
    466         if not Assigned(NewItem) then raise Exception.Create('Item not defined. ' + GetLog);
     716        Expect(Line, '');
     717        Parameter := GetNextToken(Line);
     718        if not Assigned(NewItem) then raise Exception.Create('Item not defined.' + GetLog);
    467719        NewItem.Name := Parameter;
    468720        NewItem.ValueType := vtInt;
    469721      end else
    470722      if Command = 'hex' then begin
    471         Parameter := GetNextToken(Line);
    472         if not Assigned(NewItem) then raise Exception.Create('Item not defined. ' + GetLog);
     723        Expect(Line, '');
     724        Parameter := GetNextToken(Line);
     725        if not Assigned(NewItem) then raise Exception.Create('Item not defined.' + GetLog);
    473726        NewItem.Name := Parameter;
    474727        NewItem.ValueType := vtHex;
    475728      end else
    476729      if Command = 'range' then begin
    477         Parameter := GetNextToken(Line);
    478         if not Assigned(NewItem) then raise Exception.Create('Item not defined. ' + GetLog);
     730        Expect(Line, '');
     731        Parameter := GetNextToken(Line);
     732        if not Assigned(NewItem) then raise Exception.Create('Item not defined.' + GetLog);
    479733        NewItem.RangeMin := Parameter;
    480734        Parameter := GetNextToken(Line);
     
    482736      end else
    483737      if Command = 'prompt' then begin
    484         Parameter := GetNextToken(Line);
    485         if not Assigned(NewItem) then raise Exception.Create('Item not defined. ' + GetLog);
     738        Expect(Line, '');
     739        Parameter := GetNextToken(Line);
     740        if not Assigned(NewItem) then raise Exception.Create('Item not defined.' + GetLog);
    486741        NewItem.Name := Parameter;
    487742      end else
    488743      if Command = 'default' then begin
    489         Parameter := GetNextToken(Line);
    490         if not Assigned(NewItem) then raise Exception.Create('Item not defined. ' + GetLog);
     744        Expect(Line, '');
     745        Parameter := GetNextToken(Line);
     746        if not Assigned(NewItem) then raise Exception.Create('Item not defined.' + GetLog);
    491747        NewItem.DefaultValue := Parameter;
    492748      end else
    493749      if Command = 'depends' then begin
     750        Expect(Line, '');
    494751        Parameter := GetNextToken(Line);
    495752        if Parameter = 'on' then begin
    496           if not Assigned(NewItem) then raise Exception.Create('Item not defined. ' + GetLog);
    497           // Just try to load symbol list. Do not parse expression
    498           while Trim(Line) <> '' do begin
    499             Parameter := GetNextToken(Line);
    500             if Copy(Parameter, 1, 1) = '!' then Delete(Parameter, 1, 1);
    501             if Copy(Parameter, 1, 1) = '(' then Delete(Parameter, 1, 1);
    502             if Copy(Parameter, Length(Parameter), 1) = ')' then Delete(Parameter, Length(Parameter), 1);
    503             Parameter := Trim(Parameter);
    504             if (Parameter <> '&&') and (Parameter <> '||') then
    505               NewItem.Depends.Add(Parameter);
    506           end;
     753          if not Assigned(NewItem) then raise Exception.Create('Item not defined.' + GetLog);
     754          ParseExpression(NewItem, Line);
    507755        end;
    508756      end else
    509757      if Command = 'select' then begin
    510         Parameter := GetNextToken(Line);
    511         if not Assigned(NewItem) then raise Exception.Create('Item not defined. ' + GetLog);
     758        Expect(Line, '');
     759        Parameter := GetNextToken(Line);
     760        if not Assigned(NewItem) then raise Exception.Create('Item not defined.' + GetLog);
    512761        NewItem.Selects.Add(Parameter);
    513762      end else
     
    524773      end else
    525774      if Command = 'option' then begin
     775        Expect(Line, '');
    526776        Parameter := GetNextToken(Line);
    527777      end else
    528778      if (Command = 'config') or (Command = 'menuconfig') then begin
     779        Expect(Line, '');
    529780        Parameter := GetNextToken(Line);
    530781        State := stConfig;
     
    532783        NewItem.Parent := CurrentMenu;
    533784        NewItem.ID := Parameter;
    534         NewItem.Depends.AddStrings(ConditionStack);
     785        for J := 0 to ConditionStack.Count - 1 do
     786        if ConditionStack[J] <> '' then
     787        begin
     788          NewExp := TExpressionVar.Create;
     789          NewExp.Name := ConditionStack[J];
     790          NewItem.DependsOn.Items.Add(NewExp);
     791        end;
    535792        CurrentMenu.Items.Add(NewItem);
    536793        if Command = 'menuconfig' then NewItem.MenuConfig := True;
    537794      end else
    538795      if (Command = 'comment')  then begin
     796        Expect(Line, '');
    539797        Parameter := GetNextToken(Line);
    540798        NewItem := TMenuNode.Create;
    541799        NewItem.Parent := CurrentMenu;
    542800        NewItem.Name := Parameter;
    543         NewItem.Depends.AddStrings(ConditionStack);
     801        for J := 0 to ConditionStack.Count - 1 do
     802        if ConditionStack[J] <> '' then begin
     803          NewExp := TExpressionVar.Create;
     804          NewExp.Name := ConditionStack[J];
     805          NewItem.DependsOn.Items.Add(NewExp);
     806        end;
    544807        NewItem.ValueType := vtComment;
    545808        CurrentMenu.Items.Add(NewItem);
    546809      end else
    547810      if Command = 'source' then begin
     811        Expect(Line, '');
    548812        Parameter := GetNextToken(Line);
    549813        if Pos('$SRCARCH', Parameter) > 0 then
     
    552816        if FileExistsUTF8(Parameter) then
    553817          ParseFile(Parameter)
    554           else raise Exception.Create('Source file "' + Parameter + '" not found. ' + GetLog);
     818          else raise Exception.Create('Source file "' + Parameter + '" not found.' + GetLog);
    555819      end else
    556820      if Command = 'choice' then begin
     821        Expect(Line, '');
    557822        Parameter := GetNextToken(Line);
    558823        NewMenu := TMenuNode.Create;
     
    560825        NewMenu.Name := Parameter;
    561826        NewMenu.Parent := CurrentMenu;
    562         NewMenu.Depends.AddStrings(ConditionStack);
     827        for J := 0 to ConditionStack.Count - 1 do
     828        if ConditionStack[J] <> '' then begin
     829          NewExp := TExpressionVar.Create;
     830          NewExp.Name := ConditionStack[J];
     831          NewMenu.DependsOn.Items.Add(NewExp);
     832        end;
    563833        ConditionStack.AddObject('', nil);
    564834        NewItem := NewMenu;
     
    570840          ConditionStack.Delete(ConditionStack.Count - 1);
    571841          CurrentMenu := CurrentMenu.Parent;
    572         end else raise Exception.Create('Can''t change menu level up. ' + GetLog);
     842        end else raise Exception.Create('Can''t change menu level up.' + GetLog);
    573843      end else
    574844      if Command = 'mainmenu' then begin
     845        Expect(Line, '');
    575846        Parameter := GetNextToken(Line);
    576847        Parameter := StringReplace(Parameter, '$ARCH', Arch, [rfReplaceAll]);
     
    579850      end else
    580851      if Command = 'menu' then begin
     852        Expect(Line, '');
    581853        Parameter := GetNextToken(Line);
    582854        Log('MENU ' + Parameter + ' IN ' + CurrentMenu.GetAbsoluteName);
     
    584856        NewMenu.Name := Parameter;
    585857        NewMenu.Parent := CurrentMenu;
    586         NewMenu.Depends.AddStrings(ConditionStack);
     858        for J := 0 to ConditionStack.Count - 1 do
     859        if ConditionStack[J] <> '' then begin
     860          NewExp := TExpressionVar.Create;
     861          NewExp.Name := ConditionStack[J];
     862          NewMenu.DependsOn.Items.Add(NewExp);
     863        end;
    587864        ConditionStack.AddObject('', nil);
    588865        NewItem := NewMenu;
     
    595872          ConditionStack.Delete(ConditionStack.Count - 1);
    596873          CurrentMenu := CurrentMenu.Parent;
    597         end else raise Exception.Create('Can''t change menu level up. ' + GetLog);
     874        end else raise Exception.Create('Can''t change menu level up.' + GetLog);
    598875      end else
    599876      if Command = 'if' then begin
     877        Expect(Line, '');
    600878        ConditionStack.AddObject(GetNextToken(Line), NewItem);
    601879      end else
     
    606884        ConditionStack.Delete(ConditionStack.Count - 1);
    607885      end else
    608         raise Exception.Create('Unknown command "' + Command + '". ' + GetLog);
     886        raise Exception.Create('Unknown command "' + Command + '".' + GetLog);
    609887    end;
    610888  finally
Note: See TracChangeset for help on using the changeset viewer.