aboutsummaryrefslogtreecommitdiffstats
path: root/src/grt/grt-wave_opt-design.adb
diff options
context:
space:
mode:
authorJonas Baggett <jonasb@tranquille.ch>2016-08-05 14:28:25 +0200
committerJonas Baggett <jonasb@tranquille.ch>2016-11-02 13:25:04 +0100
commitdf259b99050928cd72874377d7797c0de797935b (patch)
treee28835c3357a82ba1896130445d16f4999a480d7 /src/grt/grt-wave_opt-design.adb
parentb869a4acb52358fe8ca5decaac826af056bfdfca (diff)
downloadghdl-df259b99050928cd72874377d7797c0de797935b.tar.gz
ghdl-df259b99050928cd72874377d7797c0de797935b.tar.bz2
ghdl-df259b99050928cd72874377d7797c0de797935b.zip
Support added for * and **. Please note that wildcards inside names like /top/sub*/... are not supported yet, only synthax like /top/*/... works for now. Support for wildcards inside names will be added on version 1.2, at the same time as simple regexp support.
Current version set to 1.1
Diffstat (limited to 'src/grt/grt-wave_opt-design.adb')
-rw-r--r--src/grt/grt-wave_opt-design.adb152
1 files changed, 114 insertions, 38 deletions
diff --git a/src/grt/grt-wave_opt-design.adb b/src/grt/grt-wave_opt-design.adb
index 2002cca0d..989969ecd 100644
--- a/src/grt/grt-wave_opt-design.adb
+++ b/src/grt/grt-wave_opt-design.adb
@@ -33,72 +33,150 @@ package body Grt.Wave_Opt.Design is
-- Find the element that matches the name given. Starts with the element
-- given, then go thru all its siblings
function Find_Cursor (Name : String;
- First_Sibling : Elem_Acc;
+ Parent : Match_List;
Is_Signal : Boolean := False)
- return Elem_Acc;
+ return Match_List;
+
+ -- If the name of the current design object matches with the child tree
+ -- element given in parameter (Elem_Acc), this procedure is called to add
+ -- the latter to the list of all the child tree elements that match a design
+ -- object.
+ -- A list needs to be done, because if /top/sub/a, /top/sub/b and /top/sub/c
+ -- exist in the design and if we have /top/sub/a, /top/*/b and /top/**/c in
+ -- the tree, then a list of the child tree elements of /top will be done
+ -- with sub, * and ** so that /top/sub/a, /top/sub/b and /top/sub/c can be
+ -- matched with respectively /top/sub/a, /top/*/b and /top/**/c
+ procedure Match_List_Append
+ (List : in out Match_List; Tree_Elem : Elem_Acc);
+ -- TODO : Deallocate the list somewhere, but the memory gain shouldn't be
+ -- significative
function Get_Top_Cursor (Tree_Index : Tree_Index_Type; Name : Ghdl_C_String)
- return Elem_Acc
+ return Match_List
is
- Root : Elem_Acc;
+ Root : Match_List;
begin
- Root := Trees (Tree_Index);
- if State = Write_File and then Root.Next_Child = null then
+ if State = Write_File and then Trees (Tree_Index).Next_Child = null then
Write_Tree_Comment (Tree_Index);
end if;
+ Root := new Match_Elem_Type'(Trees (Tree_Index), null);
return Get_Cursor (Root, Name);
end Get_Top_Cursor;
- function Get_Cursor (Parent : Elem_Acc;
+ function Get_Cursor (Parent : Match_List;
Name : Ghdl_C_String;
- Is_Signal : Boolean := False) return Elem_Acc
+ Is_Signal : Boolean := False) return Match_List
is
- Cursor : Elem_Acc;
- Dummy_Bool : Boolean;
+ Tree_Elem_Cursor : Elem_Acc;
+ Last_Updated : Boolean;
Str_Name : constant String := Name (1 .. strlen (Name));
begin
case State is
when Write_File =>
- Cursor := Parent;
- Update_Tree (Cursor => Cursor,
- Updated => Dummy_Bool,
- Elem_Name => Str_Name,
- Level => Parent.Level + 1);
+ Tree_Elem_Cursor := Parent.Tree_Elem;
+ Last_Updated := True;
+ Update_Tree (Cursor => Tree_Elem_Cursor,
+ Last_Updated => Last_Updated,
+ Elem_Expr => Str_Name,
+ Level => Tree_Elem_Cursor.Level + 1);
if Is_Signal then
- Write_Signal_Path (Cursor);
+ Write_Signal_Path (Tree_Elem_Cursor);
end if;
- return Cursor;
+ return new Match_Elem_Type'(Tree_Elem_Cursor, null);
when Display_Tree =>
- return Find_Cursor (Str_Name, Parent.Next_Child, Is_Signal);
+ return Find_Cursor (Str_Name, Parent, Is_Signal);
when Display_All =>
return null;
end case;
end Get_Cursor;
function Find_Cursor (Name : String;
- First_Sibling : Elem_Acc;
+ Parent : Match_List;
Is_Signal : Boolean := False)
- return Elem_Acc
+ return Match_List
is
- Cursor : Elem_Acc;
+ Tree_Elem_Cursor : Elem_Acc;
+ Parent_Cursor, List : Match_List;
+ --
+ function Match_Expr return Boolean is
+ begin
+ if Tree_Elem_Cursor.Expr.all = Name then
+ return True;
+ elsif Tree_Elem_Cursor.Expr.all = "*" then
+ -- Returns true in the following cases :
+ -- Design object : /top/a | Tree element : /top/*
+ -- Design object : /top/sub/... | Tree element : /top/*/...
+ if Is_Signal xor Tree_Elem_Cursor.Next_Child /= null then
+ return True;
+ end if;
+ elsif Tree_Elem_Cursor.Expr.all = "**" then
+ -- Returns true in the following cases :
+ -- Design object : /top/sub/... | Tree element : /top/**
+ -- Design object : /top/a | Tree element : /top/**
+ -- But will return false in the following case :
+ -- Design object : /top/a | Tree element : /top/**/x
+ if not Is_Signal or else Tree_Elem_Cursor.Next_Child = null then
+ return True;
+ end if;
+ end if;
+ return False;
+ end Match_Expr;
+
+ function Get_Cursor_Kind return Elem_Kind_Type is
+ begin
+ if Tree_Elem_Cursor.Expr.all = "**" then
+ return Recursion;
+ elsif Is_Signal then
+ return Signal;
+ else
+ return Pkg_Entity;
+ end if;
+ end Get_Cursor_Kind;
begin
- Cursor := First_Sibling;
+ Parent_Cursor := Parent;
loop
- if Cursor = null then
- return null;
- elsif Cursor.Name.all = Name then
- if Is_Signal then
- Cursor.Kind := Signal;
- else
- Cursor.Kind := Pkg_Entity;
+ exit when Parent_Cursor = null;
+ Tree_Elem_Cursor := Parent_Cursor.Tree_Elem.Next_Child;
+ if Parent_Cursor.Tree_Elem.Expr.all = "**" then
+ -- Add the current tree element to the list in the following cases:
+ -- Design object : /top/y/x | Tree element : /top/**/x
+ -- Design object : /top/y/x/... | Tree element : /top/**/x/...
+ -- where x matchs the Name parameter, ** is the parent expression
+ if Tree_Elem_Cursor /= null
+ and then Tree_Elem_Cursor.Expr.all = Name
+ then
+ Match_List_Append (List, Tree_Elem_Cursor);
+ -- Add the parent tree element (**) to the list in the following
+ -- cases:
+ -- Design object : /top/y/x/... | Tree element : /top/**
+ -- Design object : /top/y/x | Tree element : /top/**
+ -- But it won't do it in the following case:
+ -- Design object : /top/y/x | Tree element : /top/**/z
+ -- as x != z
+ elsif not Is_Signal or else Tree_Elem_Cursor = null then
+ Match_List_Append (List, Parent_Cursor.Tree_Elem);
end if;
- return Cursor;
end if;
- Cursor := Cursor.Next_Sibling;
+ loop
+ exit when Tree_Elem_Cursor = null;
+ if Match_Expr then
+ Tree_Elem_Cursor.Kind := Get_Cursor_Kind;
+ Match_List_Append (List, Tree_Elem_Cursor);
+ end if;
+ Tree_Elem_Cursor := Tree_Elem_Cursor.Next_Sibling;
+ end loop;
+ Parent_Cursor := Parent_Cursor.Next;
end loop;
+ return List;
end Find_Cursor;
- function Is_Displayed (Cursor : Elem_Acc) return Boolean is
+ procedure Match_List_Append (List : in out Match_List; Tree_Elem : Elem_Acc)
+ is
+ begin
+ List := new Match_Elem_Type'(Tree_Elem => Tree_Elem, Next => List);
+ end Match_List_Append;
+
+ function Is_Displayed (Cursor : Match_List) return Boolean is
begin
if State /= Display_Tree or else Cursor /= null then
return True;
@@ -129,14 +207,12 @@ package body Grt.Wave_Opt.Design is
while Cursor /= null loop
if Cursor.Kind = Not_Found then
Print_Context (Cursor, Warning);
- Report_C (Cursor.Name.all);
+ Report_C (Cursor.Expr.all);
Report_C (" : first element of the path not found in design.");
- Report_E (" more references may follow");
- elsif Cursor.Level = Cursor.Path_Context.Max_Level
- and then Cursor.Kind = Pkg_Entity
- then
+ Report_E (" More references may follow");
+ elsif Cursor.Next_Child = null and then Cursor.Kind = Pkg_Entity then
Print_Context (Cursor, Warning);
- Report_C (Cursor.Name.all);
+ Report_C (Cursor.Expr.all);
Report_E (" is not a signal");
else
Check_Sub_Tree_If_All_Found (Cursor.Next_Child);