Changeset 10


Ignore:
Timestamp:
May 2, 2014, 8:06:58 PM (10 years ago)
Author:
chronos
Message:
  • Modified: Improved help text parsing.
  • Modified: Reworked menu structure rearranging according "Depends on" items. Now it better corresponds to kernel config tools.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/UKConfig.pas

    r9 r10  
    4242
    4343  TMenuNode = class
    44     Index: Integer;
    4544    ID: string;
    4645    Name: string;
    47     Condition: string;
    4846    Depends: TStringList;
    4947    Selects: TStringList;
     
    5149    Items: TObjectList; // TList<TMenuNode>
    5250    Parent: TMenuNode;
    53     NewParent: TMenuNode;
     51    //NewParent: TMenuNode;
    5452    DefaultValue: string;
    5553    ValueType: TValueType;
     
    5957    constructor Create; virtual;
    6058    destructor Destroy; override;
    61     function HaveUpperNode(Node: TMenuNode): Boolean;
     59    procedure ChangeParent(NewParent: TMenuNode);
     60    procedure AddLastToList(List: TObjectList);
    6261    function GetName: string; virtual;
    6362    function GetAbsoluteName: string; virtual;
     
    6766    procedure Search(Text: string; List: TObjectList); virtual;
    6867    procedure SaveToList(List: TStrings); virtual;
    69     procedure PrepareMoveList(Lookup: TStringList; var List: TObjectMoves); virtual;
     68    function PrepareMoveList(Lookup: TStringList; var List: TObjectMoves): Boolean; virtual;
    7069    function GetCount: Integer; virtual;
    7170    function GetTopNode: TMenuNode; virtual;
     
    8382    Arch: string;
    8483    FOnLog: TOnLogEvent;
    85     IndexCounter: Integer;
    8684    function GetTopCondition: string;
    8785    procedure Log(Text: string);
     
    143141end;
    144142
    145 function TMenuNode.HaveUpperNode(Node: TMenuNode): Boolean;
    146 begin
    147   Result := False;
    148   if NewParent = Node then Result := True
    149     else if Assigned(NewParent) then Result := NewParent.HaveUpperNode(Node);
     143procedure TMenuNode.ChangeParent(NewParent: TMenuNode);
     144var
     145  LastOwnState: Boolean;
     146begin
     147  try
     148    LastOwnState := Parent.Items.OwnsObjects;
     149    Parent.Items.OwnsObjects := False;
     150    Parent.Items.Remove(Self);
     151  finally
     152    Parent.Items.OwnsObjects := LastOwnState;
     153  end;
     154  Parent := NewParent;
     155  NewParent.Items.Add(Self);
     156end;
     157
     158procedure TMenuNode.AddLastToList(List: TObjectList);
     159begin
     160  List.Add(Self);
     161  if Items.Count > 0 then begin
     162    TMenuNode(Items.Last).AddLastToList(List);
     163  end;
    150164end;
    151165
     
    181195  with List do begin
    182196    Clear;
    183     Add('Index: ' + IntToStr(Index));
    184197    Add('ID: ' + ID);
    185198    Add('Name: ' + Name);
     
    187200    Add('Selects: ' + Selects.Text);
    188201    Add('Description: ' + Description.Text);
    189     Add('Condition: ' + Condition);
    190202    Add('Value type: ' + IntToStr(Integer(ValueType)));
    191203    Add('Default value: ' + DefaultValue);
     204    Add('Path: ' + GetAbsoluteName);
    192205  end;
    193206end;
     
    224237end;
    225238
    226 procedure TMenuNode.PrepareMoveList(Lookup: TStringList; var List: TObjectMoves);
    227 var
    228   I: Integer;
    229   Node: TMenuNode;
     239function TMenuNode.PrepareMoveList(Lookup: TStringList; var List: TObjectMoves): Boolean;
     240var
     241  I: Integer;
     242  J: Integer;
    230243  NewMove: TObjectMove;
    231244  Index: Integer;
    232   P: TMenuNode;
    233245  LatestNode: TMenuNode;
    234 begin
    235   if ID = 'PARAVIRT_DEBUG' then
    236     Name := Name + '$';
    237   NewParent := Parent;
    238   P := Parent;
    239 {  if Condition <> '' then begin
    240     Index := Lookup.IndexOf(Condition);
    241     if Index <> -1 then Node := TMenuNode(Lookup.Objects[Index])
    242       else Node := nil;
    243     if Assigned(Node) and (NewParent <> Node) and Node.MenuConfig then begin
    244       NewParent := Node;
     246  CheckList: TObjectList;
     247begin
     248  Result := False;
     249  try
     250    CheckList := TObjectList.Create;
     251    CheckList.OwnsObjects := False;
     252    if Assigned(Parent) then begin
     253    Index := Parent.Items.IndexOf(Self);
     254    if Index = -1 then raise Exception.Create('Node not found in parent');
     255    if Index >= 1 then TMenuNode(Parent.Items[Index - 1]).AddLastToList(CheckList);
     256    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
     260          ChangeParent(TMenuNode(CheckList[I]));
     261          Result := True;
     262          Break;
     263        end;
     264      end;
     265      if Result then Break;
    245266    end;
    246   end;}
    247   I := 0;
    248   LatestNode := NewParent;
    249   while I < Depends.Count do begin
    250     Index := Lookup.IndexOf(Depends[I]);
    251     if Index <> -1 then Node := TMenuNode(Lookup.Objects[Index])
    252       else Node := nil;
    253     if Assigned(Node) and (NewParent <> Node) and (Node.HaveUpperNode(NewParent)) and
    254       (Node.Index > LatestNode.Index) then begin
    255       LatestNode := Node;
    256267    end;
    257     Inc(I);
    258   end;
    259   NewParent := LatestNode;
    260 
    261   if NewParent <> Parent then begin
    262     NewMove.Source := Self;
    263     NewMove.NewParent := NewParent;
    264     SetLength(List, Length(List) + 1);
    265     List[Length(List) - 1] := NewMove;
     268  finally
     269    CheckList.Free;
    266270  end;
    267271
     
    269273  while I < Items.Count do
    270274  with TMenuNode(Items[I]) do begin
    271     PrepareMoveList(Lookup, List);
    272     Inc(I);
     275    if not PrepareMoveList(Lookup, List) then Inc(I);
    273276  end;
    274277end;
     
    323326function TConfigMenu.IsWhiteSpace(Character: Char): Boolean;
    324327begin
    325   Result := (Character = ' ') or (Character = #9);
     328  Result := (Character >= #0) and (Character <= ' ');
    326329end;
    327330
     
    362365  Content: TStringList;
    363366  I: Integer;
     367  J: Integer;
    364368  Command: string;
    365369  Parameter: string;
    366370  Line: string;
    367   State: (stNormal, stConfig, stHelp);
     371  State: (stNormal, stConfig, stHelp, stHelpStart);
    368372  NewItem: TMenuNode;
    369373  NewMenu: TMenuNode;
     
    376380  Result := FileName + ':' + IntToStr(I + 1) + ' ' + Content[I];
    377381end;
     382
     383const
     384  TabSize = 8;
    378385
    379386begin
     
    389396      Line := MergedLines + Content[I];
    390397      MergedLines := '';
    391       LineIndent := 1;
    392       while (LineIndent <= Length(Line)) and IsWhiteSpace(Line[LineIndent]) do Inc(LineIndent);
    393       if (State = stHelp) and (Trim(Line) <> '') and (LineIndent = 1) then
     398      LineIndent := 0;
     399      J := 1;
     400      while (J <= Length(Line)) and IsWhiteSpace(Line[J]) do begin
     401        if Line[J] = #9 then LineIndent := (Trunc(LineIndent / TabSize) + 1) * TabSize
     402          else Inc(LineIndent);
     403        Inc(J);
     404      end;
     405      if (State = stHelp) and (Trim(Line) <> '') then begin
     406        State := stHelpStart;
     407        if LineIndent = 0 then State := stNormal;
     408        HelpIndent := LineIndent;
     409        if (State = stHelpStart) and (HelpIndent = 0) then
     410          raise Exception.Create('Error during help parsing');
     411      end;
     412      if (State = stHelpStart) and (Trim(Line) <> '') and (LineIndent < HelpIndent) then
    394413        State := stNormal;
    395414
     
    411430      end;
    412431      Command := GetNextToken(Line);
    413       if State = stHelp then begin
     432      if (State = stHelp) or (State = stHelpStart) then begin
    414433        NewItem.Description.Add(Trim(Content[I]));
    415434      end else
     
    496515        Command := GetNextToken(Line);
    497516        if Command = 'help' then begin
    498           Parameter := GetNextToken(Line);
    499517          State := stHelp;
    500518          HelpIndent := LineIndent;
     
    502520      end else
    503521      if (Command = 'help') or (Command = '---help---') then begin
    504         Parameter := GetNextToken(Line);
    505522        State := stHelp;
    506523        HelpIndent := LineIndent;
     
    515532        NewItem.Parent := CurrentMenu;
    516533        NewItem.ID := Parameter;
    517         NewItem.Condition := GetTopCondition;
    518         NewItem.Index := IndexCounter;
    519         Inc(IndexCounter);
     534        NewItem.Depends.AddStrings(ConditionStack);
    520535        CurrentMenu.Items.Add(NewItem);
    521536        if Command = 'menuconfig' then NewItem.MenuConfig := True;
     
    526541        NewItem.Parent := CurrentMenu;
    527542        NewItem.Name := Parameter;
    528         NewItem.Condition := GetTopCondition;
    529         NewItem.Index := IndexCounter;
    530         Inc(IndexCounter);
     543        NewItem.Depends.AddStrings(ConditionStack);
    531544        NewItem.ValueType := vtComment;
    532545        CurrentMenu.Items.Add(NewItem);
     
    547560        NewMenu.Name := Parameter;
    548561        NewMenu.Parent := CurrentMenu;
    549         NewMenu.Condition := GetTopCondition;
    550         NewMenu.Index := IndexCounter;
    551         Inc(IndexCounter);
     562        NewMenu.Depends.AddStrings(ConditionStack);
    552563        ConditionStack.AddObject('', nil);
    553564        NewItem := NewMenu;
     
    573584        NewMenu.Name := Parameter;
    574585        NewMenu.Parent := CurrentMenu;
    575         NewMenu.Condition := GetTopCondition;
     586        NewMenu.Depends.AddStrings(ConditionStack);
    576587        ConditionStack.AddObject('', nil);
    577588        NewItem := NewMenu;
     
    588599      if Command = 'if' then begin
    589600        ConditionStack.AddObject(GetNextToken(Line), NewItem);
    590         if Assigned(NewItem) and NewItem.MenuConfig then begin
    591           CurrentMenu := NewItem;
    592         end;
    593601      end else
    594602      if Command = 'visible' then begin
     
    596604      end else
    597605      if Command = 'endif' then begin
    598         if Assigned(ConditionStack.Objects[ConditionStack.Count - 1]) then
    599           if TMenuNode(ConditionStack.Objects[ConditionStack.Count - 1]).MenuConfig then
    600             CurrentMenu := CurrentMenu.Parent;
    601606        ConditionStack.Delete(ConditionStack.Count - 1);
    602607      end else
     
    615620  TopNode.Name := 'Root';
    616621  CurrentMenu := TopNode;
    617   IndexCounter := 1;
    618622  ParseFile(BaseDir + DirectorySeparator + 'Kconfig');
    619623end;
     
    664668    Node := TopNode.FindNode(List[I]);
    665669    if Assigned(Node) then
    666       List[I] := Node.GetAbsoluteName + ' (' + List[I] + ')';
     670      List[I] := '"' + Node.GetAbsoluteName + '";' + List[I];
    667671  end;
    668672end;
Note: See TracChangeset for help on using the changeset viewer.