Commit 0c6432fc authored by jdelange's avatar jdelange
Browse files

* Main purpose : introduce the ability to define doxygen-compliant

   comments in the generated code.

 * ocarina/src/backends/ocarina-backends-po_hi_c.adb
   - Generate a doxygen.cfg file per node.

 * ocarina/src/backends/ocarina-backends-po_hi_c-activity.adb
   - Add some doxygen comments.

 * ocarina/src/backends/ocarina-backends-c_tree-nutils.adb
   ocarina/src/backends/ocarina-backends-c_tree-nutils.ads
   - Add the Make_Doxygen_Comment_Node function

 * ocarina/src/backends/ocarina-backends-c_tree-nodes.idl
   - Add a new node to handle doxygen comment

 * ocarina/src/backends/ocarina-backends-c_tree-generator.adb
   - Generate comments according to doxygen rules.

 * ocarina/src/backends/ocarina-backends-po_hi_c-main.adb
   - Add comments compliant with doxygen requirements



git-svn-id: https://tecsw.estec.esa.int/svn/taste/trunk/ocarina@2709 129961e7-ef38-4bb5-a8f7-c9a525a55882
parent 9572c52c
...@@ -60,6 +60,7 @@ package body Ocarina.Backends.C_Tree.Generator is ...@@ -60,6 +60,7 @@ package body Ocarina.Backends.C_Tree.Generator is
procedure Generate_C_Comment (N : Node_Id); procedure Generate_C_Comment (N : Node_Id);
procedure Generate_Call_Profile (N : Node_Id); procedure Generate_Call_Profile (N : Node_Id);
procedure Generate_Macro_Call (N : Node_Id); procedure Generate_Macro_Call (N : Node_Id);
procedure Generate_Doxygen_C_Comment (N : Node_Id);
procedure Generate_HI_Distributed_Application (N : Node_Id); procedure Generate_HI_Distributed_Application (N : Node_Id);
procedure Generate_HI_Node (N : Node_Id); procedure Generate_HI_Node (N : Node_Id);
procedure Generate_Assignment_Statement (N : Node_Id); procedure Generate_Assignment_Statement (N : Node_Id);
...@@ -165,6 +166,9 @@ package body Ocarina.Backends.C_Tree.Generator is ...@@ -165,6 +166,9 @@ package body Ocarina.Backends.C_Tree.Generator is
when K_Assignment_Statement => when K_Assignment_Statement =>
Generate_Assignment_Statement (N); Generate_Assignment_Statement (N);
when K_Doxygen_C_Comment =>
Generate_Doxygen_C_Comment (N);
when K_Call_Profile => when K_Call_Profile =>
Generate_Call_Profile (N); Generate_Call_Profile (N);
...@@ -388,6 +392,208 @@ package body Ocarina.Backends.C_Tree.Generator is ...@@ -388,6 +392,208 @@ package body Ocarina.Backends.C_Tree.Generator is
Write_Eol; Write_Eol;
end Generate_C_Comment; end Generate_C_Comment;
--------------------------
-- Generate_Doxygen_C_Comment --
--------------------------
procedure Generate_Doxygen_C_Comment (N : Node_Id) is
-- This procedure does the following :
-- * It generates a C comment basing on the name of node N
-- * If the name it too long, and depending on the location of
-- the comment in the source code, the procedure splits the
-- comment into more than a line.
-- The comment is assumed to be a sequence of caracters,
-- beginning and ending with a NON-SPACE caracter.
-- A word is :
-- a space character, or else a sequence of non space
-- characters located between two spaces.
-- The maximum length of a line, in colums
Max_Line_Length : constant Natural := 78;
function Are_There_More_Words return Boolean;
-- This function returns True if there are words in the buffer
function Next_Word_Length return Natural;
-- This function returns the size of the next word to be
-- got. It returns zero when the buffer is empty.
function Get_Next_Word return String;
-- This function extracts the next word from the buffer
--------------------------
-- Are_There_More_Words --
--------------------------
function Are_There_More_Words return Boolean is
begin
return (Name_Len /= 0);
end Are_There_More_Words;
----------------------
-- Next_Word_Length --
----------------------
function Next_Word_Length return Natural is
L : Natural;
begin
if not Are_There_More_Words then
L := 0;
elsif Name_Buffer (1) = ' ' then
L := 1;
else
L := 0;
while L + 1 <= Name_Len and then Name_Buffer (L + 1) /= ' ' loop
L := L + 1;
end loop;
end if;
return L;
end Next_Word_Length;
-------------------
-- Get_Next_Word --
-------------------
function Get_Next_Word return String is
L : constant Natural := Next_Word_Length;
begin
if L = 0 then
return "";
else
declare
Next_Word : constant String := Name_Buffer (1 .. L);
begin
if Name_Len = L then
Name_Len := 0;
else
Set_Str_To_Name_Buffer (Name_Buffer (L + 1 .. Name_Len));
end if;
return Next_Word;
end;
end if;
end Get_Next_Word;
Used_Columns : Natural;
begin
Used_Columns := N_Space;
Used_Columns := Used_Columns + 3;
Write_Eol;
Write_Str ("/*!");
if For_Struct (N) then
Write_Eol;
Write_Str (" * \struct ");
Write_Name (Name (Element (N)));
end if;
if For_Union (N) then
Write_Eol;
Write_Str (" * \union ");
Write_Name (Name (Element (N)));
end if;
if For_Enum (N) then
Write_Eol;
Write_Str (" * \enum ");
Write_Name (Name (Element (N)));
end if;
if For_Function (N) then
Write_Eol;
Write_Str (" * \fn ");
Write_Name (Name (Element (N)));
end if;
if For_Variable (N) then
Write_Eol;
Write_Str (" * \var ");
Write_Name (Name (Element (N)));
end if;
if For_Define (N) then
Write_Eol;
Write_Str (" * \def ");
Write_Name (Name (Element (N)));
end if;
if For_Typedef (N) then
Write_Eol;
Write_Str (" * \typedef ");
Write_Name (Name (Element (N)));
end if;
if For_File (N) then
Write_Eol;
Write_Str (" * \file ");
Write_Name (Name (Element (N)));
end if;
if For_Namespace (N) then
Write_Eol;
Write_Str (" * \namespace ");
Write_Name (Name (Element (N)));
end if;
if For_Package (N) then
Write_Eol;
Write_Str (" * \package ");
Write_Name (Name (Element (N)));
end if;
if For_Interface (N) then
Write_Eol;
Write_Str (" * \interface ");
Write_Name (Name (Element (N)));
end if;
if Summary (N) /= No_Node then
Write_Eol;
Write_Str (" * \brief ");
Write_Name
(Name (Summary (N)));
Write_Eol;
Write_Str (" *");
end if;
Write_Eol;
Get_Name_String
(Name (Description (N)));
while Are_There_More_Words loop
Used_Columns := N_Space;
-- We consume 4 colums
Used_Columns := Used_Columns + 2;
Write_Str (" * ");
if Has_Header_Spaces (N) then
Used_Columns := Used_Columns + 2;
Write_Str (" ");
end if;
Used_Columns := Used_Columns + Next_Word_Length;
Write_Str (Get_Next_Word);
while Are_There_More_Words
and then (Used_Columns + Next_Word_Length < Max_Line_Length)
loop
Used_Columns := Used_Columns + Next_Word_Length;
Write_Str (Get_Next_Word);
end loop;
if Are_There_More_Words then
Write_Eol;
end if;
end loop;
Write_Eol;
Write_Str (" */");
Write_Eol;
end Generate_Doxygen_C_Comment;
----------------------------------- -----------------------------------
-- Generate_Assignment_Statement -- -- Generate_Assignment_Statement --
----------------------------------- -----------------------------------
...@@ -546,6 +752,7 @@ package body Ocarina.Backends.C_Tree.Generator is ...@@ -546,6 +752,7 @@ package body Ocarina.Backends.C_Tree.Generator is
begin begin
-- Enter If_Statement -- Enter If_Statement
Write_Str ("/* :: Yes if commentary :: */");
Write (Tok_If); Write (Tok_If);
Write_Space; Write_Space;
Write (Tok_Left_Paren); Write (Tok_Left_Paren);
...@@ -1099,7 +1306,9 @@ package body Ocarina.Backends.C_Tree.Generator is ...@@ -1099,7 +1306,9 @@ package body Ocarina.Backends.C_Tree.Generator is
or else Kind (N) = K_Function_Implementation or else Kind (N) = K_Function_Implementation
then then
Write_Eol; Write_Eol;
elsif Kind (N) /= K_C_Comment then elsif Kind (N) /= K_C_Comment
and then Kind (N) /= K_Doxygen_C_Comment
then
Write_Line (Tok_Semicolon); Write_Line (Tok_Semicolon);
end if; end if;
end Generate_Statement_Delimiter; end Generate_Statement_Delimiter;
......
...@@ -302,6 +302,24 @@ module Ocarina::Backends::C_Tree::Nodes { ...@@ -302,6 +302,24 @@ module Ocarina::Backends::C_Tree::Nodes {
boolean Has_Header_Spaces; boolean Has_Header_Spaces;
}; };
interface Doxygen_C_Comment : Node_Id {
boolean Has_Header_Spaces;
boolean For_Struct;
boolean For_Union;
boolean For_Enum;
boolean For_Function;
boolean For_Variable;
boolean For_Define;
boolean For_Typedef;
boolean For_File;
boolean For_Namespace;
boolean For_Package;
boolean For_Interface;
Node_Id Summary;
Node_Id Description;
Node_Id Element;
};
interface Define_Statement : Definition { interface Define_Statement : Definition {
Node_Id Defined_Value; Node_Id Defined_Value;
}; };
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- -- -- --
-- B o d y -- -- B o d y --
-- -- -- --
-- Copyright (C) 2008-2010, European Space Agency (ESA). -- -- Copyright (C) 2008-2011, European Space Agency (ESA). --
-- -- -- --
-- Ocarina is free software; you can redistribute it and/or modify -- -- Ocarina is free software; you can redistribute it and/or modify --
-- it under terms of the GNU General Public License as published by the -- -- it under terms of the GNU General Public License as published by the --
...@@ -2563,4 +2563,82 @@ package body Ocarina.Backends.C_Tree.Nutils is ...@@ -2563,4 +2563,82 @@ package body Ocarina.Backends.C_Tree.Nutils is
return Map_C_Data_Type_Designator (Corresponding_Instance (Port)); return Map_C_Data_Type_Designator (Corresponding_Instance (Port));
end Get_Inter_Partition_Port_Type; end Get_Inter_Partition_Port_Type;
----------------------------
-- Make_Doxygen_C_Comment --
----------------------------
function Make_Doxygen_C_Comment
(Desc : String;
Brief : String := "";
Element_Name : String := "";
Is_Struct : Boolean := False;
Is_Union : Boolean := False;
Is_Enum : Boolean := False;
Is_Function : Boolean := False;
Is_Variable : Boolean := False;
Is_Define : Boolean := False;
Is_Typedef : Boolean := False;
Is_File : Boolean := False;
Is_Namespace : Boolean := False;
Is_Package : Boolean := False;
Is_Interface : Boolean := False;
Has_Header_Spaces : Boolean := True)
return Node_Id
is
C : Node_Id;
begin
C := New_Node (K_Doxygen_C_Comment);
CTN.Set_Summary (C, No_Node);
CTN.Set_Element (C, No_Node);
CTN.Set_Description (C, No_Node);
CTN.Set_For_Struct (C, False);
CTN.Set_For_Union (C, False);
CTN.Set_For_Enum (C, False);
CTN.Set_For_Function (C, False);
CTN.Set_For_Variable (C, False);
CTN.Set_For_Define (C, False);
CTN.Set_For_Typedef (C, False);
CTN.Set_For_File (C, False);
CTN.Set_For_Namespace (C, False);
CTN.Set_For_Package (C, False);
CTN.Set_For_Interface (C, False);
CTN.Set_Has_Header_Spaces (C, Has_Header_Spaces);
if Desc /= "" then
Set_Description
(C, New_Node (K_Defining_Identifier));
CTN.Set_Name
(Description (C), Get_String_Name (Desc));
end if;
if Element_Name /= "" then
Set_Element
(C, New_Node (K_Defining_Identifier));
CTN.Set_Name
(Element (C), Get_String_Name (Element_Name));
end if;
if Brief /= "" then
Set_Summary
(C, New_Node (K_Defining_Identifier));
CTN.Set_Name
(Summary (C), Get_String_Name (Brief));
end if;
CTN.Set_For_Struct (C, Is_Struct);
CTN.Set_For_Union (C, Is_Union);
CTN.Set_For_Enum (C, Is_Enum);
CTN.Set_For_Function (C, Is_Function);
CTN.Set_For_Variable (C, Is_Variable);
CTN.Set_For_Define (C, Is_Define);
CTN.Set_For_Typedef (C, Is_Typedef);
CTN.Set_For_File (C, Is_File);
CTN.Set_For_Namespace (C, Is_Namespace);
CTN.Set_For_Package (C, Is_Package);
CTN.Set_For_Interface (C, Is_Interface);
return C;
end Make_Doxygen_C_Comment;
end Ocarina.Backends.C_Tree.Nutils; end Ocarina.Backends.C_Tree.Nutils;
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- -- -- --
-- S p e c -- -- S p e c --
-- -- -- --
-- Copyright (C) 2008-2010, European Space Agency (ESA). -- -- Copyright (C) 2008-2011, European Space Agency (ESA). --
-- -- -- --
-- Ocarina is free software; you can redistribute it and/or modify -- -- Ocarina is free software; you can redistribute it and/or modify --
-- it under terms of the GNU General Public License as published by the -- -- it under terms of the GNU General Public License as published by the --
...@@ -213,6 +213,7 @@ package Ocarina.Backends.C_Tree.Nutils is ...@@ -213,6 +213,7 @@ package Ocarina.Backends.C_Tree.Nutils is
V_Got_Data, V_Got_Data,
V_Dev_Id, V_Dev_Id,
V_Entity, V_Entity,
V_Period,
V_Port, V_Port,
V_Pkt, V_Pkt,
V_Thread, V_Thread,
...@@ -624,4 +625,24 @@ package Ocarina.Backends.C_Tree.Nutils is ...@@ -624,4 +625,24 @@ package Ocarina.Backends.C_Tree.Nutils is
-- all information to generate a C data type linked with -- all information to generate a C data type linked with
-- virtual bus layers. -- virtual bus layers.
function Make_Doxygen_C_Comment
(Desc : String;
Brief : String := "";
Element_Name : String := "";
Is_Struct : Boolean := False;
Is_Union : Boolean := False;
Is_Enum : Boolean := False;
Is_Function : Boolean := False;
Is_Variable : Boolean := False;
Is_Define : Boolean := False;
Is_Typedef : Boolean := False;
Is_File : Boolean := False;
Is_Namespace : Boolean := False;
Is_Package : Boolean := False;
Is_Interface : Boolean := False;
Has_Header_Spaces : Boolean := True)
return Node_Id;
-- The Make_Doxygen_C_Comment.
end Ocarina.Backends.C_Tree.Nutils; end Ocarina.Backends.C_Tree.Nutils;
...@@ -1387,6 +1387,11 @@ package body Ocarina.Backends.PO_HI_C.Activity is ...@@ -1387,6 +1387,11 @@ package body Ocarina.Backends.PO_HI_C.Activity is
end if; end if;
end; end;
N := Make_Doxygen_C_Comment
("Waiting for other tasks initialization",
Has_Header_Spaces => False);
Append_Node_To_List (N, Statements);
-- Call __po_hi_wait_initialization -- Call __po_hi_wait_initialization
N := CTU.Make_Call_Profile (RE (RE_Wait_Initialization), N := CTU.Make_Call_Profile (RE (RE_Wait_Initialization),
......
...@@ -116,9 +116,19 @@ package body Ocarina.Backends.PO_HI_C.Main is ...@@ -116,9 +116,19 @@ package body Ocarina.Backends.PO_HI_C.Main is
-- the fact that an aperiodic thread is sporadic, with -- the fact that an aperiodic thread is sporadic, with
-- period of 0. -- period of 0.
if Period_Variable_Declared = False then if Period_Variable_Declared = False then
N := Make_Doxygen_C_Comment
(Brief => "Variable for task period",
Is_Variable => True,
Desc => "This variable is used to store the value" &
"of the period of a task when we create it. The " &
"value put in the variable is set according to " &
"AADL model description",
Element_Name => Get_Name_String (VN (V_Period)),
Has_Header_Spaces => False);
Append_Node_To_List (N, CTN.Declarations (Main_Function));
N := Make_Variable_Declaration N := Make_Variable_Declaration
(Make_Defining_Identifier (Make_Defining_Identifier (VN (V_Period)),
(Get_String_Name ("period")),
RE (RE_Time_T)); RE (RE_Time_T));
Append_Node_To_List (N, CTN.Declarations (Main_Function)); Append_Node_To_List (N, CTN.Declarations (Main_Function));
...@@ -172,6 +182,18 @@ package body Ocarina.Backends.PO_HI_C.Main is ...@@ -172,6 +182,18 @@ package body Ocarina.Backends.PO_HI_C.Main is
case Get_Thread_Dispatch_Protocol (E) is case Get_Thread_Dispatch_Protocol (E) is
when Thread_Periodic => when Thread_Periodic =>
N := Make_Doxygen_C_Comment
(Brief => "Making Periodic Task",
Desc => "Make a periodic task according to " &
"AADL model requirements. The first " &
"parameter is the task identifier defined " &
"in deployment.h, the second is the period " &
"defined in the AADL model. Third is the task " &
"priority, fourth is the stack size and last "&
"the subprogram executed by the task",
Has_Header_Spaces => False);
Append_Node_To_List (N, CTN.Statements (Main_Function));
Append_Node_To_List Append_Node_To_List
(CTU.Make_Call_Profile (CTU.Make_Call_Profile
(RE (RE_Create_Periodic_Task), Parameters), (RE (RE_Create_Periodic_Task), Parameters),
...@@ -179,12 +201,20 @@ package body Ocarina.Backends.PO_HI_C.Main is ...@@ -179,12 +201,20 @@ package body Ocarina.Backends.PO_HI_C.Main is
when Thread_Sporadic when Thread_Sporadic
| Thread_Aperiodic => | Thread_Aperiodic =>
N := Make_Doxygen_C_Comment
("Making Sporadic task", Has_Header_Spaces => False);
Append_Node_To_List (N, CTN.Statements (Main_Function));
Append_Node_To_List Append_Node_To_List
(CTU.Make_Call_Profile (CTU.Make_Call_Profile
(RE (RE_Create_Sporadic_Task), Parameters), (RE (RE_Create_Sporadic_Task), Parameters),
CTN.Statements (Main_Function)); CTN.Statements (Main_Function));
when Thread_Background => when Thread_Background =>
N := Make_Doxygen_C_Comment
("Making background task", Has_Header_Spaces => False);
Append_Node_To_List (N, CTN.Statements (Main_Function));
Append_Node_To_List Append_Node_To_List
(CTU.Make_Call_Profile (CTU.Make_Call_Profile
(RE (RE_Create_Sporadic_Task), Parameters), (RE (RE_Create_Sporadic_Task), Parameters),
...@@ -312,6 +342,10 @@ package body Ocarina.Backends.PO_HI_C.Main is ...@@ -312,6 +342,10 @@ package body Ocarina.Backends.PO_HI_C.Main is
end loop; end loop;
end if; end if;
N := Make_Doxygen_C_Comment
("Initialize the runtime", Has_Header_Spaces => False);
Append_Node_To_List (N, CTN.Statements (Main_Function));
N := CTU.Make_Call_Profile (RE (RE_Initialize)); N := CTU.Make_Call_Profile (RE (RE_Initialize));
Append_Node_To_List (N, CTN.Statements (Main_Function)); Append_Node_To_List (N, CTN.Statements (Main_Function));
...@@ -446,6 +480,11 @@ package body Ocarina.Backends.PO_HI_C.Main is ...@@ -446,6 +480,11 @@ package body Ocarina.Backends.PO_HI_C.Main is
-- Call __po_hi_wait_initialization(). With this function, -- Call __po_hi_wait_initialization(). With this function,
-- the main function will wait all other tasks initialization. -- the main function will wait all other tasks initialization.
N := Make_Doxygen_C_Comment
("Waiting for other tasks initialization",
Has_Header_Spaces => False);
Append_Node_To_List (N, Statements);
N := CTU.Make_Call_Profile (RE (RE_Wait_Initialization), N := CTU.Make_Call_Profile (RE (RE_Wait_Initialization),
No_List); No_List);
Append_Node_To_List (N, Statements); Append_Node_To_List (N, Statements);
...@@ -454,6 +493,11 @@ package body Ocarina.Backends.PO_HI_C.Main is ...@@ -454,6 +493,11 @@ package body Ocarina.Backends.PO_HI_C.Main is
-- all other task. In fact, no task will terminate, so this function -- all other task. In fact, no task will terminate, so this function
-- will only switch the main task to the sleep state all the time. -- will only switch the main task to the sleep state all the time.
N := Make_Doxygen_C_Comment
("Used to switch the main task to sleep all the time",
Has_Header_Spaces => False);
Append_Node_To_List (N, CTN.Statements (Main_Function));
if not PO_HI_C.Use_Performance_Analysis then if not PO_HI_C.Use_Performance_Analysis then
N := CTU.Make_Call_Profile (RE (RE_Wait_For_Tasks)); N := CTU.Make_Call_Profile (RE (RE_Wait_For_Tasks));
else else
...@@ -462,6 +506,10 @@ package body Ocarina.Backends.PO_HI_C.Main is ...@@ -462,6 +506,10 @@ package body Ocarina.Backends.PO_HI_C.Main is
Append_Node_To_List (N, CTN.Statements (Main_Function)); Append_Node_To_List (N, CTN.Statements (Main_Function));
N := Make_Doxygen_C_Comment
("Return Statement", Has_Header_Spaces => False);