Changeset 6 for trunk/UKConfig.pas


Ignore:
Timestamp:
May 2, 2014, 2:12:56 AM (11 years ago)
Author:
chronos
Message:
  • Added: Search form for searching configuration tree.
  • Modified: Better menu category creation. Still not correct.
  • Added: Detect kernel version from Makefile.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/UKConfig.pas

    r5 r6  
    3131    Items: TObjectList; // TList<TMenuNode>
    3232    Parent: TMenuNode;
     33    NewParent: TMenuNode;
    3334    DefaultValue: string;
    3435    ValueType: TValueType;
     
    3738    constructor Create; virtual;
    3839    destructor Destroy; override;
     40    function HaveUpperNode(Node: TMenuNode): Boolean;
    3941    function GetName: string; virtual;
    40     function GetabsoluteName: string; virtual;
     42    function GetAbsoluteName: string; virtual;
    4143    procedure LoadTreeNode(Node: TTreeNode; Options: TLoadTreeOptions = []); virtual;
    4244    procedure LoadStats(List: TStrings); virtual;
    4345    procedure GetNodes(List: TStrings); virtual;
     46    procedure Search(Text: string; List: TObjectList); virtual;
    4447    procedure SaveToList(List: TStrings); virtual;
    4548    procedure PrepareMoveList(Lookup: TStringList; var List: TObjectMoves); virtual;
     
    5659  private
    5760    CurrentMenu: TMenuNode;
     61    ConditionStack: TStringList;
    5862    Arch: string;
    5963    FOnLog: TOnLogEvent;
     64    function GetTopCondition: string;
    6065    procedure Log(Text: string);
    6166    function IsWhiteSpace(Character: Char): Boolean;
    6267    function GetNextToken(var Text: string): string;
    6368    procedure ParseFile(FileName: string);
     69    procedure ParseConfig;
     70    procedure ParseMakeFile;
    6471  public
    6572    TopNode: TMenuNode;
    6673    BaseDir: string;
     74    Version: string;
    6775    procedure PrepareMoveList(var List: TObjectMoves);
    6876    procedure CompareStringLists(List1, List2: TStringList; Missing1,
     
    7078    procedure LoadFromDir(Dir: string; Arch: string);
    7179    property OnLog: TOnLogEvent read FOnLog write FOnLog;
     80    constructor Create;
     81    destructor Destroy; override;
    7282  end;
    7383
     
    96106end;
    97107
     108function TMenuNode.HaveUpperNode(Node: TMenuNode): Boolean;
     109begin
     110  Result := False;
     111  if NewParent = Node then Result := True
     112    else if Assigned(NewParent) then Result := NewParent.HaveUpperNode(Node);
     113end;
     114
    98115function TMenuNode.GetName: string;
    99116begin
     
    102119end;
    103120
    104 function TMenuNode.GetabsoluteName: string;
    105 begin
    106   if Assigned(Parent) then Result := Parent.GetabsoluteName + ' - ';
    107   Result := Result + GetName;
     121function TMenuNode.GetAbsoluteName: string;
     122begin
     123  if Assigned(Parent) then Result := Parent.GetAbsoluteName + ' - ';
     124  if Assigned(Parent) then Result := Result + GetName;
    108125end;
    109126
     
    119136      NewNode.Data := TMenuNode(Self.Items[I]);
    120137      LoadTreeNode(NewNode, Options);
    121     end;
     138    end else LoadTreeNode(Node, Options);
    122139  end;
    123140end;
     
    149166end;
    150167
     168procedure TMenuNode.Search(Text: string; List: TObjectList);
     169var
     170  I: Integer;
     171begin
     172  if (Pos(Text, ID) > 0) or (Pos(Text, Name) > 0) then List.Add(Self);
     173  for I := 0 to Items.Count - 1 do
     174    TMenuNode(Items[I]).Search(Text, List);
     175end;
     176
    151177procedure TMenuNode.SaveToList(List: TStrings);
    152178var
     
    167193  Index: Integer;
    168194begin
     195  if ID = 'KVM_INTEL' then
     196    Name := Name + '$';
     197  NewParent := Parent;
     198  if Condition <> '' then begin
     199    Index := Lookup.IndexOf(Condition);
     200    if Index <> -1 then Node := TMenuNode(Lookup.Objects[Index])
     201      else Node := nil;
     202    if Assigned(Node) and (NewParent <> Node) then begin
     203      NewParent := Node;
     204    end;
     205  end;
    169206  if Depends.Count > 0 then begin
    170207    Index := Lookup.IndexOf(Depends[0]);
    171208    if Index <> -1 then Node := TMenuNode(Lookup.Objects[Index])
    172209      else Node := nil;
    173     if Assigned(Node) and (Parent <> Node) then begin
    174       NewMove.Source := Self;
    175       NewMove.NewParent := Node;
    176       SetLength(List, Length(List) + 1);
    177       List[Length(List) - 1] := NewMove;
     210    if Assigned(Node) and (NewParent <> Node) and (Node.HaveUpperNode(NewParent)) then begin
     211      NewParent := Node;
    178212    end;
    179   end else
    180   if Condition <> '' then begin
    181     Index := Lookup.IndexOf(Condition);
    182     if Index <> -1 then Node := TMenuNode(Lookup.Objects[Index])
    183       else Node := nil;
    184     if Assigned(Node) and (Parent <> Node) then begin
    185       NewMove.Source := Self;
    186       NewMove.NewParent := Node;
    187       SetLength(List, Length(List) + 1);
    188       List[Length(List) - 1] := NewMove;
    189     end;
    190   end;
     213  end;
     214  if NewParent <> Parent then begin
     215    NewMove.Source := Self;
     216    NewMove.NewParent := NewParent;
     217    SetLength(List, Length(List) + 1);
     218    List[Length(List) - 1] := NewMove;
     219  end;
     220
    191221  I := 0;
    192222  while I < Items.Count do
     
    231261
    232262{ TConfigMenu }
     263
     264function TConfigMenu.GetTopCondition: string;
     265begin
     266  if ConditionStack.Count > 0 then
     267  Result := ConditionStack[ConditionStack.Count - 1]
     268  else Result := '';
     269end;
    233270
    234271procedure TConfigMenu.Log(Text: string);
     
    285322  NewMenu: TMenuNode;
    286323  MergedLines: string;
    287   Condition: string;
    288324  HelpIndent: Integer;
    289325  LineIndent: Integer;
     
    302338    NewItem := nil;
    303339    MergedLines := '';
    304     Condition := '';
    305340    HelpIndent := 0;
    306341    for I := 0 to Content.Count - 1 do begin
     
    394429        if Parameter = 'on' then begin
    395430          Parameter := GetNextToken(Line);
     431          if Copy(Parameter, 1, 1) = '!' then Delete(Parameter, 1, 1);
    396432          if not Assigned(NewItem) then raise Exception.Create('Item not defined. ' + GetLog);
    397433          NewItem.Depends.Add(Parameter);
     
    413449      if (Command = 'config') or (Command = 'menuconfig') then begin
    414450        Parameter := GetNextToken(Line);
    415           State := stConfig;
    416           NewItem := TMenuNode.Create;
    417           NewItem.Parent := CurrentMenu;
    418           NewItem.ID := Parameter;
    419           NewItem.Condition := Condition;
    420           CurrentMenu.Items.Add(NewItem);
    421         end else
    422         if (Command = 'comment')  then begin
    423           Parameter := GetNextToken(Line);
    424           NewItem := TMenuNode.Create;
    425           NewItem.Parent := CurrentMenu;
    426           NewItem.ID := Parameter;
    427           NewItem.Condition := Condition;
    428           NewItem.ValueType := vtComment;
    429           CurrentMenu.Items.Add(NewItem);
    430         end else
    431         if Command = 'source' then begin
    432           Parameter := GetNextToken(Line);
    433           if Pos('$SRCARCH', Parameter) > 0 then
    434             Parameter := StringReplace(Parameter, '$SRCARCH', Arch, [rfReplaceAll]);
    435           Parameter := BaseDir + DirectorySeparator + Parameter;
    436           if FileExistsUTF8(Parameter) then
    437             ParseFile(Parameter)
    438             else raise Exception.Create('Source file "' + Parameter + '" not found. ' + GetLog);
    439         end else
    440         if Command = 'choice' then begin
    441           Parameter := GetNextToken(Line);
    442           NewMenu := TMenuNode.Create;
    443           NewMenu.ValueType := vtChoice;
    444           NewMenu.Name := Parameter;
    445           NewMenu.Parent := CurrentMenu;
    446           NewItem := NewMenu;
    447           CurrentMenu.Items.Add(NewMenu);
    448           CurrentMenu := NewMenu;
    449         end else
    450         if command = 'endchoice' then begin
    451           if Assigned(CurrentMenu.Parent) then
    452             CurrentMenu := CurrentMenu.Parent
    453             else raise Exception.Create('Can''t change menu level up. ' + GetLog);
    454         end else
    455         if Command = 'mainmenu' then begin
    456           Parameter := GetNextToken(Line);
    457           TopNode.Name := Parameter;
    458         end else
    459         if Command = 'menu' then begin
    460           Parameter := GetNextToken(Line);
    461           Log('MENU ' + Parameter + ' IN ' + CurrentMenu.GetAbsoluteName);
    462           NewMenu := TMenuNode.Create;
    463           NewMenu.Name := Parameter;
    464           NewMenu.Parent := CurrentMenu;
    465           NewMenu.Condition := Condition;
    466           Condition := '';
    467           NewItem := NewMenu;
    468           CurrentMenu.Items.Add(NewMenu);
    469           CurrentMenu := NewMenu;
    470         end else
    471         if command = 'endmenu' then begin
    472           Log('ENDMENU ' + CurrentMenu.GetAbsoluteName);
    473           if Assigned(CurrentMenu.Parent) then begin
    474             Condition := CurrentMenu.Condition;
    475             CurrentMenu := CurrentMenu.Parent;
    476           end else raise Exception.Create('Can''t change menu level up. ' + GetLog);
    477         end else
    478         if Command = 'if' then begin
    479           Condition := GetNextToken(Line);
    480         end else
    481         if Command = 'visible' then begin
    482           //VisibleCondition := GetNextToken(Line);
    483         end else
    484         if command = 'endif' then begin
    485           Condition := '';
    486         end else
    487           raise Exception.Create('Unknown command "' + Command + '". ' + GetLog);
     451        State := stConfig;
     452        NewItem := TMenuNode.Create;
     453        NewItem.Parent := CurrentMenu;
     454        NewItem.ID := Parameter;
     455        NewItem.Condition := GetTopCondition;
     456        CurrentMenu.Items.Add(NewItem);
     457      end else
     458      if (Command = 'comment')  then begin
     459        Parameter := GetNextToken(Line);
     460        NewItem := TMenuNode.Create;
     461        NewItem.Parent := CurrentMenu;
     462        NewItem.Name := Parameter;
     463        NewItem.Condition := GetTopCondition;
     464        NewItem.ValueType := vtComment;
     465        CurrentMenu.Items.Add(NewItem);
     466      end else
     467      if Command = 'source' then begin
     468        Parameter := GetNextToken(Line);
     469        if Pos('$SRCARCH', Parameter) > 0 then
     470          Parameter := StringReplace(Parameter, '$SRCARCH', Arch, [rfReplaceAll]);
     471        Parameter := BaseDir + DirectorySeparator + Parameter;
     472        if FileExistsUTF8(Parameter) then
     473          ParseFile(Parameter)
     474          else raise Exception.Create('Source file "' + Parameter + '" not found. ' + GetLog);
     475      end else
     476      if Command = 'choice' then begin
     477        Parameter := GetNextToken(Line);
     478        NewMenu := TMenuNode.Create;
     479        NewMenu.ValueType := vtChoice;
     480        NewMenu.Name := Parameter;
     481        NewMenu.Parent := CurrentMenu;
     482        NewMenu.Condition := GetTopCondition;
     483        ConditionStack.Add('');
     484        NewItem := NewMenu;
     485        CurrentMenu.Items.Add(NewMenu);
     486        CurrentMenu := NewMenu;
     487      end else
     488      if command = 'endchoice' then begin
     489        if Assigned(CurrentMenu.Parent) then begin
     490          ConditionStack.Delete(ConditionStack.Count - 1);
     491          CurrentMenu := CurrentMenu.Parent;
     492        end else raise Exception.Create('Can''t change menu level up. ' + GetLog);
     493      end else
     494      if Command = 'mainmenu' then begin
     495        Parameter := GetNextToken(Line);
     496        Parameter := StringReplace(Parameter, '$ARCH', Arch, [rfReplaceAll]);
     497        Parameter := StringReplace(Parameter, '$KERNELVERSION', Version, [rfReplaceAll]);
     498        TopNode.Name := Parameter;
     499      end else
     500      if Command = 'menu' then begin
     501        Parameter := GetNextToken(Line);
     502        Log('MENU ' + Parameter + ' IN ' + CurrentMenu.GetAbsoluteName);
     503        NewMenu := TMenuNode.Create;
     504        NewMenu.Name := Parameter;
     505        NewMenu.Parent := CurrentMenu;
     506        NewMenu.Condition := GetTopCondition;
     507        ConditionStack.Add('');
     508        NewItem := NewMenu;
     509        CurrentMenu.Items.Add(NewMenu);
     510        CurrentMenu := NewMenu;
     511      end else
     512      if command = 'endmenu' then begin
     513        Log('ENDMENU ' + CurrentMenu.GetAbsoluteName);
     514        if Assigned(CurrentMenu.Parent) then begin
     515          ConditionStack.Delete(ConditionStack.Count - 1);
     516          CurrentMenu := CurrentMenu.Parent;
     517        end else raise Exception.Create('Can''t change menu level up. ' + GetLog);
     518      end else
     519      if Command = 'if' then begin
     520        ConditionStack.Add(GetNextToken(Line));
     521      end else
     522      if Command = 'visible' then begin
     523        //VisibleCondition := GetNextToken(Line);
     524      end else
     525      if command = 'endif' then begin
     526        ConditionStack.Delete(ConditionStack.Count - 1);
     527      end else
     528        raise Exception.Create('Unknown command "' + Command + '". ' + GetLog);
     529    end;
     530  finally
     531    Content.Free;
     532  end;
     533end;
     534
     535procedure TConfigMenu.ParseConfig;
     536begin
     537  ConditionStack.Clear;
     538  TopNode.Free;
     539  TopNode := TMenuNode.Create;
     540  TopNode.Name := 'Root';
     541  CurrentMenu := TopNode;
     542  ParseFile(BaseDir + DirectorySeparator + 'Kconfig');
     543end;
     544
     545procedure TConfigMenu.ParseMakeFile;
     546var
     547  Content: TStringList;
     548  I: Integer;
     549  Line: string;
     550  Token: string;
     551begin
     552  try
     553    Content := TStringList.Create;
     554    Content.LoadFromFile(BaseDir + DirectorySeparator + 'Makefile');
     555    for I := 0 to Content.Count - 1 do begin
     556      Line := Trim(Content[I]);
     557      Token := GetNextToken(Line);
     558      if Token = 'VERSION' then begin
     559        Line := Trim(Line);
     560        Token := GetNextToken(Line);
     561        if Token = '=' then
     562          Version := Trim(Line);
     563      end else
     564      if Token = 'PATCHLEVEL' then begin
     565        Line := Trim(Line);
     566        Token := GetNextToken(Line);
     567        if Token = '=' then
     568          Version := Version + '.' + Trim(Line);
     569      end else
     570      if Token = 'SUBLEVEL' then begin
     571        Line := Trim(Line);
     572        Token := GetNextToken(Line);
     573        if Token = '=' then
     574          Version := Version + '.' + Trim(Line);
     575      end;
    488576    end;
    489577  finally
     
    548636  Self.Arch := Arch;
    549637  BaseDir := Dir;
    550   TopNode.Free;
    551   TopNode := TMenuNode.Create;
    552   TopNode.Name := 'Root';
    553   CurrentMenu := TopNode;
    554   ParseFile(BaseDir + DirectorySeparator + 'Kconfig');
    555 
     638  ParseMakeFile;
     639  ParseConfig;
     640
     641  SetLength(Moves, 0);
    556642  PrepareMoveList(Moves);
    557643  for I := 0 to Length(Moves) - 1 do
     
    565651end;
    566652
     653constructor TConfigMenu.Create;
     654begin
     655  ConditionStack := TStringList.Create;
     656end;
     657
     658destructor TConfigMenu.Destroy;
     659begin
     660  ConditionStack.Free;
     661end;
     662
    567663end.
    568664
Note: See TracChangeset for help on using the changeset viewer.