home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / pdl / docmgr.src < prev    next >
Encoding:
Text File  |  1988-05-03  |  566.7 KB  |  19,189 lines

  1. ::::::::::::::
  2. addp.ada
  3. ::::::::::::::
  4. with Standard_Interface;
  5. with String_Pkg;
  6. with Host_Lib;
  7. with Item_Library_Manager;
  8. with Item_Library_Manager_Declarations;
  9.  
  10. function Add_Property return INTEGER is
  11.  
  12.     package SI  renames Standard_Interface;
  13.     package SP  renames String_Pkg;
  14.     package HL  renames Host_Lib;
  15.     package ILM renames Item_Library_Manager;
  16.     package ILD renames Item_Library_Manager_Declarations;
  17.  
  18.     package LIB is new SI.String_Argument(
  19.                 String_Type_Name => "library_name");
  20.     package STR is new SI.String_Argument(
  21.                 String_Type_Name => "string");
  22.  
  23.     Add_Property_Process : SI.Process_Handle;
  24.     Library              : SP.String_Type;
  25.     Keyword              : SP.String_Type;
  26.     Value                : SP.String_Type;
  27.  
  28. begin
  29.  
  30.     SP.Mark;
  31.  
  32.     SI.Set_Tool_Identifier(Identifier => "1.0");
  33.  
  34.     SI.Define_Process(
  35.     Proc    => Add_Property_Process,
  36.     Name    => "Add_Property",
  37.     Help    => "Add a Property Keyword/Value to the Item Library");
  38.  
  39.     LIB.Define_Argument(
  40.     Proc => Add_Property_Process,
  41.     Name => "library",
  42.     Help => "Name of the item library");
  43.  
  44.     STR.Define_Argument(
  45.     Proc    => Add_Property_Process,
  46.     Name    => "keyword",
  47.     Help    => "Property keyword");
  48.  
  49.     STR.Define_Argument(
  50.     Proc    => Add_Property_Process,
  51.     Name    => "value",
  52.     Help    => "Property value");
  53.  
  54.     SP.Release;
  55.  
  56.     SI.Parse_Line(Add_Property_Process);
  57.  
  58.     Library := LIB.Get_Argument(
  59.             Proc => Add_Property_Process,
  60.             Name => "library");
  61.  
  62.     Keyword := STR.Get_Argument(
  63.             Proc => Add_Property_Process,
  64.             Name => "keyword");
  65.  
  66.     Value := STR.Get_Argument(
  67.             Proc => Add_Property_Process,
  68.             Name => "value");
  69.  
  70.     ILM.Add_Property(Library, Keyword, Value);
  71.     return HL.Return_Code(HL.SUCCESS);
  72.  
  73. exception
  74.  
  75.     when SI.Process_Help =>
  76.     return HL.Return_Code(HL.INFORMATION);
  77.  
  78.     when SI.Abort_Process =>
  79.     return HL.Return_Code(HL.SUCCESS);
  80.  
  81.     when ILD.Library_Does_Not_Exist =>
  82.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ does not exist.");
  83.     return HL.Return_Code(HL.ERROR);
  84.  
  85.     when ILD.Library_Master_Locked =>
  86.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is master locked.");
  87.     return HL.Return_Code(HL.ERROR);
  88.  
  89.     when ILD.Library_Write_Locked =>
  90.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is write locked.");
  91.     return HL.Return_Code(HL.ERROR);
  92.  
  93.     when ILD.Library_Read_Locked =>
  94.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is read locked.");
  95.     return HL.Return_Code(HL.ERROR);
  96.  
  97.     when ILD.Invalid_Keyword =>
  98.         HL.Put_Error("Property keyword """ & SP.Value(SP.Upper(Keyword)) & """ invalid.");
  99.     return HL.Return_Code(HL.ERROR);
  100.  
  101.     when ILD.Invalid_Value =>
  102.         HL.Put_Error("Property value """ & SP.Value(SP.Upper(Value)) & """ invalid.");
  103.     return HL.Return_Code(HL.ERROR);
  104.  
  105.     when ILD.Keyword_Already_Exists =>
  106.         HL.Put_Error("Property keyword """ & SP.Value(SP.Upper(Keyword)) &
  107.              """ already exists.");
  108.     return HL.Return_Code(HL.ERROR);
  109.  
  110.     when ILD.Not_Authorized =>
  111.     HL.Put_Error("Not authorized.");
  112.     return HL.Return_Code(HL.ERROR);
  113.  
  114.     when ILD.No_Privilege =>
  115.     HL.Put_Error("No privilege for attempted operation.");
  116.     return HL.Return_Code(HL.ERROR);
  117.  
  118.     when others =>
  119.     HL.Put_Error("Add Property internal error.");
  120.     return HL.Return_Code(HL.SEVERE);
  121.  
  122. end Add_Property;
  123.  
  124. ::::::::::::::
  125. addp.bdy
  126. ::::::::::::::
  127. with Library_Errors;
  128. with Library_Utilities;
  129. with HIF_Node_Defs;
  130. with HIF_Node_Management;
  131. with HIF_Attributes;
  132. with HIF_List_Utils;
  133.  
  134. function Add_Property_Interface(
  135.     Library   : in String_Pkg.String_Type;
  136.     Keyword   : in String_Pkg.String_Type;
  137.     Value     : in String_Pkg.String_Type;
  138.     Privilege : in Privilege_Type := WORLD
  139.     ) return Host_Lib.Severity_Code is
  140.  
  141.     package SP  renames String_Pkg;
  142.     package HL  renames Host_Lib;
  143.     package LE  renames Library_Errors;
  144.     package LU  renames Library_Utilities;
  145.     package HND renames HIF_Node_Defs;
  146.     package HNM renames HIF_Node_Management;
  147.     package HA  renames HIF_Attributes;
  148.     package HLU renames HIF_List_Utils;
  149.  
  150.     Node : HND.Node_Type;
  151.     Trap : HL.Interrupt_State := HL.Get_Interrupt_State;
  152.  
  153. begin
  154.  
  155.     if HL."="(Trap, HL.DISABLED) then
  156.     HL.Enable_Interrupt_Trap;
  157.     end if;
  158.     if not LU.Lock_Library(Library, WRITE_LOCK) then
  159.     raise Library_Write_Locked;
  160.     end if;
  161.     if not LU.Privileged(Privilege, Library) then
  162.     raise No_Privilege; 
  163.     end if;
  164.     LU.Open_Property_Node(Library, Keyword, Value, ADD, Node);
  165.     HA.Set_Node_Attribute(Node   => Node,
  166.               Attrib => SP.Value(Keyword),
  167.               Value  => HLU.To_List(SP.Value(Value)));
  168.     HNM.Close_Node_Handle(Node);
  169.     LU.Unlock_Library(Library, WRITE_LOCK);
  170.     if Message_on_Completion then
  171.     HL.Put_Message_Line(
  172.         "Property " & SP.Value(SP.Upper(Keyword)) &
  173.         " with value " & SP.Value(SP.Upper(Value)) &
  174.         " added to library " & SP.Value(SP.Upper(Library)) & '.');
  175.     end if;
  176.     HL.Set_Interrupt_State(Trap);
  177.     return HL.SUCCESS;
  178.  
  179. exception
  180.  
  181.     when Invalid_Library_Name =>
  182.     LE.Report_Error(LE.Invalid_Library_Name, Library);
  183.     HL.Set_Interrupt_State(Trap);
  184.     return HL.ERROR;
  185.  
  186.     when Library_Does_Not_Exist =>
  187.     LE.Report_Error(LE.Library_Does_Not_Exist, Library);
  188.     HL.Set_Interrupt_State(Trap);
  189.     return HL.ERROR;
  190.  
  191.     when Library_Master_Locked =>
  192.     LE.Report_Error(LE.Library_Master_Locked, Library);
  193.     HL.Set_Interrupt_State(Trap);
  194.     return HL.ERROR;
  195.  
  196.     when Library_Write_Locked =>
  197.     LE.Report_Error(LE.Library_Write_Locked, Library);
  198.     HL.Set_Interrupt_State(Trap);
  199.     return HL.ERROR;
  200.  
  201.     when Invalid_Keyword =>
  202.     LU.Unlock_Library(Library, WRITE_LOCK);
  203.     LE.Report_Error(LE.Invalid_Keyword, Keyword);
  204.     HL.Set_Interrupt_State(Trap);
  205.     return HL.ERROR;
  206.  
  207.     when Invalid_Value =>
  208.     LU.Unlock_Library(Library, WRITE_LOCK);
  209.     LE.Report_Error(LE.Invalid_Value, Value);
  210.     HL.Set_Interrupt_State(Trap);
  211.     return HL.ERROR;
  212.  
  213.     when Keyword_Already_Exists =>
  214.     LU.Unlock_Library(Library, WRITE_LOCK);
  215.     LE.Report_Error(LE.Keyword_Already_Exists, Keyword);
  216.     HL.Set_Interrupt_State(Trap);
  217.     return HL.ERROR;
  218.  
  219.     when No_Privilege =>
  220.     LU.Unlock_Library(Library, WRITE_LOCK);
  221.     LE.Report_Error(LE.No_Privilege, Library, SP.Create(LU.Get_Library_Attribute(Library, "OWNER")));
  222.     HL.Set_Interrupt_State(Trap);
  223.     return HL.ERROR;
  224.  
  225.     when HL.Interrupt_Encountered =>
  226.     begin
  227.         LU.Unlock_Library(Library, WRITE_LOCK);
  228.     exception
  229.         when others => null;
  230.     end;
  231.     if HL."="(Trap, HL.ENABLED) then
  232.         raise HL.Interrupt_Encountered;
  233.     end if;
  234.     LE.Report_Error(LE.Process_Interrupted, SP.Create("Add_Property"));
  235.     HL.Set_Interrupt_State(Trap);
  236.     return HL.WARNING;
  237.  
  238.     when others =>
  239.     begin
  240.         LU.Unlock_Library(Library, WRITE_LOCK);
  241.     exception
  242.         when others => null;
  243.     end;
  244.     LE.Report_Error(LE.Internal_Error, SP.Create("Add_Property"));
  245.     HL.Set_Interrupt_State(Trap);
  246.     return HL.SEVERE;
  247.  
  248. end Add_Property_Interface;
  249.                                                                     pragma page;
  250. ::::::::::::::
  251. addp.spc
  252. ::::::::::::::
  253. with Library_Declarations;            use Library_Declarations;
  254. with String_Pkg;
  255. with Host_Lib;
  256.  
  257. function Add_Property_Interface(        --| Add Property Keyword/Value
  258.     Library   : in String_Pkg.String_Type;    --| Item library
  259.     Keyword   : in String_Pkg.String_Type;    --| Property keyword
  260.     Value     : in String_Pkg.String_Type;    --| Property value
  261.     Privilege : in Privilege_Type := WORLD    --| Add privilege
  262.     ) return Host_Lib.Severity_Code;
  263.  
  264. --| Requires:
  265. --| The names of the library, and the keyword-value pair.
  266.  
  267. --| Effects:
  268. --| Associates a keyword-value pair to the specified library.
  269.  
  270. --| N/A: Modifies, Raises, Errors
  271.                                                                     pragma page;
  272. ::::::::::::::
  273. adduser.ada
  274. ::::::::::::::
  275. with String_Pkg;
  276. with Host_Lib;
  277. with File_Manager;
  278. with HIF_System_Management;
  279. with Standard_Interface;
  280. with Tool_Identifier;
  281.      
  282. function Add_User return INTEGER is
  283.  
  284.     package SP  renames String_Pkg;
  285.     package HL  renames Host_Lib;
  286.     package FM  renames File_Manager;
  287.     package HSM renames HIF_System_Management;
  288.     package SI  renames Standard_Interface;
  289.     package SA  is new SI.String_Argument("string");
  290.  
  291.     Process   : SI.Process_Handle;
  292.     Directory : SP.String_Type;
  293.  
  294. begin
  295.  
  296.     SI.Set_Tool_Identifier(Tool_Identifier);
  297.     SI.Define_Process(
  298.     "add_user",
  299.     "Adds the named user to the set of documentation system users",
  300.     Process);
  301.     SA.Define_Argument(
  302.     Process,
  303.     "directory",
  304.     "Name of the directory in which to store documentation information");
  305.     SA.Define_Argument(
  306.     Process,
  307.     "user",
  308.     HL.get_item(HL.user_name),
  309.     "Name of the user to add");
  310.     SI.Define_Help(
  311.     Process,
  312.     "This procedure can be used to add any user to the set of documentation");
  313.     SI.Append_Help(
  314.     Process,
  315.     "system users.  If a person wants to be able to use the system they must");
  316.     SI.Append_Help(
  317.     Process,
  318.     "be entered in the system with the same user name as they have on the");
  319.     SI.Append_Help(
  320.     Process,
  321.     "host machine.  If this is not the case the person will not be recognized");
  322.     SI.Append_Help(
  323.     Process,
  324.     "as a documentation system user.  Each user name must be unique");
  325.  
  326.     SI.Parse_Line(Process);
  327.  
  328.     Directory := SP.Create(FM.Path_Name(Directory => SP.Value(SA.Get_Argument(Process, "directory")),
  329.                     File      => "",
  330.                     Absolute  => TRUE));
  331.  
  332.     if FM.Is_Directory(SP.Value(Directory)) then
  333.     HL.Put_Error("Directory already exists");
  334.     return HL.Return_Code(HL.ERROR);
  335.     end if;
  336.  
  337.     HSM.Add_User(User_Name      => SP.Value(SA.Get_Argument(Process, "user")),
  338.          Partition_Name => SP.Value(Directory));
  339.  
  340.     return HL.Return_Code(HL.SUCCESS);
  341.  
  342. exception 
  343.  
  344.     when FM.Device_Not_Ready =>
  345.     HL.Put_Error("Device not ready");
  346.     return HL.Return_Code(HL.ERROR);
  347.     when FM.Directory_Not_Found =>
  348.     HL.Put_Error("Directory not found");
  349.     return HL.Return_Code(HL.ERROR);
  350.     when FM.Privilege_Violation =>
  351.     HL.Put_Error("Privilege violation");
  352.     return HL.Return_Code(HL.ERROR);
  353.     when FM.Parse_Error =>
  354.     HL.Put_Error("Incorrect syntax for directory specification");
  355.     return HL.Return_Code(HL.ERROR);
  356.     when SI.Process_Help =>
  357.     return HL.Return_Code(HL.INFORMATION);
  358.     when SI.Abort_Process =>
  359.     return HL.Return_Code(HL.ERROR);
  360.     when others =>
  361.     HL.Put_Error("Fatal error in Add_User");
  362.     return HL.Return_Code(HL.SEVERE);
  363.  
  364. end Add_User;
  365.                                                                     pragma page;
  366. ::::::::::::::
  367. canceli.ada
  368. ::::::::::::::
  369. with Standard_Interface;
  370. with String_Pkg;
  371. with Host_Lib;
  372. with Item_Library_Manager;
  373. with Item_Library_Manager_Declarations;
  374.  
  375. function Cancel_Item return INTEGER is
  376.  
  377.     package SI  renames Standard_Interface;
  378.     package SP  renames String_Pkg;
  379.     package HL  renames Host_Lib;
  380.     package ILM renames Item_Library_Manager;
  381.     package ILD renames Item_Library_Manager_Declarations;
  382.     package LIB is new SI.String_Argument(
  383.                 String_Type_Name => "library_name");
  384.     package ITM is new SI.String_Argument(
  385.                 String_Type_Name => "item_name");
  386.  
  387.     Cancel_Item_Process : SI.Process_Handle;
  388.     Library             : SP.String_Type;
  389.     Item                : SP.String_Type;
  390.     Checked_In_Version  : SP.String_Type;
  391.  
  392. begin
  393.  
  394.     SP.Mark;
  395.  
  396.     SI.Set_Tool_Identifier(Identifier => "1.0");
  397.  
  398.     SI.Define_Process(
  399.     Proc    => Cancel_Item_Process,
  400.     Name    => "Cancel_Item",
  401.     Help    => "Cancel a Pending Return for an Item in the Item Library");
  402.  
  403.     LIB.Define_Argument(
  404.     Proc => Cancel_Item_Process,
  405.     Name => "library",
  406.     Help => "Name of the item library");
  407.  
  408.     ITM.Define_Argument(
  409.     Proc => Cancel_Item_Process,
  410.     Name => "item",
  411.     Help => "Name of the item to cancel the pending return");
  412.  
  413.     SP.Release;
  414.  
  415.     SI.Parse_Line(Cancel_Item_Process);
  416.  
  417.     Library := LIB.Get_Argument(
  418.             Proc => Cancel_Item_Process,
  419.             Name => "library");
  420.  
  421.     Item := ITM.Get_Argument(
  422.             Proc => Cancel_Item_Process,
  423.             Name => "item");
  424.  
  425.     ILM.Check_In_Item(Library, Item, SP.Create(""), ILD.RETURN_ITEM, ILD.NO_UPDATE, Checked_In_Version);
  426.  
  427.     HL.Put_Message_Line("Item """ &
  428.             SP.Value(SP.Upper(Item)) & '/' &
  429.             SP.Value(Checked_In_Version) &
  430.             """ canceled.");
  431.     return HL.Return_Code(HL.SUCCESS);
  432.  
  433. exception
  434.  
  435.     when SI.Process_Help =>
  436.     return HL.Return_Code(HL.INFORMATION);
  437.  
  438.     when SI.Abort_Process =>
  439.     return HL.Return_Code(HL.SUCCESS);
  440.  
  441.     when ILD.Library_Does_Not_Exist =>
  442.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ does not exist.");
  443.     return HL.Return_Code(HL.ERROR);
  444.  
  445.     when ILD.Library_Master_Locked =>
  446.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is master locked.");
  447.     return HL.Return_Code(HL.ERROR);
  448.  
  449.     when ILD.Library_Write_Locked =>
  450.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is write locked.");
  451.     return HL.Return_Code(HL.ERROR);
  452.  
  453.     when ILD.Library_Read_Locked =>
  454.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is read locked.");
  455.     return HL.Return_Code(HL.ERROR);
  456.  
  457.     when ILD.Item_Not_Found =>
  458.     HL.Put_Error("Item """ & SP.Value(SP.Upper(Item)) & """ not found.");
  459.     return HL.Return_Code(HL.ERROR);
  460.  
  461.     when ILD.Item_Not_Checked_Out =>
  462.     HL.Put_Error("Item """ & SP.Value(SP.Upper(Item)) & """ not checked out.");
  463.     return HL.Return_Code(HL.ERROR);
  464.  
  465.     when ILD.Not_Authorized =>
  466.     HL.Put_Error("Not authorized.");
  467.     return HL.Return_Code(HL.ERROR);
  468.  
  469.     when ILD.No_Privilege =>
  470.     HL.Put_Error("No privilege for attempted operation.");
  471.     return HL.Return_Code(HL.ERROR);
  472.  
  473.     when others =>
  474.     HL.Put_Error("Cancel Item internal error.");
  475.     return HL.Return_Code(HL.SEVERE);
  476.  
  477. end Cancel_Item;
  478.  
  479. ::::::::::::::
  480. canceli.bdy
  481. ::::::::::::::
  482. with Library_Declarations;            use Library_Declarations;
  483. with Library_Errors;
  484. with Library_Utilities;
  485.  
  486. function Cancel_Item_Interface(
  487.     Library : in String_Pkg.String_Type;
  488.     Item    : in String_Pkg.String_Type
  489.     ) return Host_Lib.Severity_Code is
  490.  
  491.     package SP  renames String_Pkg;
  492.     package HL  renames Host_Lib;
  493.     package LE  renames Library_Errors;
  494.     package LU  renames Library_Utilities;
  495.  
  496.     Returned : SP.String_Type;
  497.     Trap     : HL.Interrupt_State := HL.Get_Interrupt_State;
  498.  
  499. begin
  500.  
  501.     if HL."="(Trap, HL.DISABLED) then
  502.     HL.Enable_Interrupt_Trap;
  503.     end if;
  504.     if not LU.Lock_Library(Library, WRITE_LOCK) then
  505.     raise Library_Write_Locked;
  506.     end if;
  507.     LU.Check_In_Item(Library, Item, SP.Create(""), CANCEL_ITEM, Returned);
  508.     if Message_on_Completion then
  509.     HL.Put_Message_Line(
  510.         "Item " & SP.Value(SP.Upper(Item)) & '/' & SP.Value(Returned) &
  511.         " canceled in library " & SP.Value(SP.Upper(Library)) & '.');
  512.     end if;
  513.     LU.Unlock_Library(Library, WRITE_LOCK);
  514.     HL.Set_Interrupt_State(Trap);
  515.     return HL.SUCCESS;
  516.  
  517. exception 
  518.  
  519.     when Invalid_Library_Name =>
  520.     LE.Report_Error(LE.Invalid_Library_Name, Library);
  521.     HL.Set_Interrupt_State(Trap);
  522.     return HL.ERROR;
  523.  
  524.     when Library_Does_Not_Exist =>
  525.     LE.Report_Error(LE.Library_Does_Not_Exist, Library);
  526.     HL.Set_Interrupt_State(Trap);
  527.     return HL.ERROR;
  528.  
  529.     when Library_Master_Locked =>
  530.     LE.Report_Error(LE.Library_Master_Locked, Library);
  531.     HL.Set_Interrupt_State(Trap);
  532.     return HL.ERROR;
  533.  
  534.     when Library_Write_Locked =>
  535.     LE.Report_Error(LE.Library_Write_Locked, Library);
  536.     HL.Set_Interrupt_State(Trap);
  537.     return HL.ERROR;
  538.  
  539.     when Item_Not_Found =>
  540.     LU.Unlock_Library(Library, WRITE_LOCK);
  541.     LE.Report_Error(LE.Item_Not_Found, Item);
  542.     HL.Set_Interrupt_State(Trap);
  543.     return HL.ERROR;
  544.  
  545.     when Item_Not_Checked_Out =>
  546.     LU.Unlock_Library(Library, WRITE_LOCK);
  547.     LE.Report_Error(LE.Item_Not_Checked_Out, Item);
  548.     HL.Set_Interrupt_State(Trap);
  549.     return HL.ERROR;
  550.  
  551.     when Item_Checked_Out =>
  552.     LU.Unlock_Library(Library, WRITE_LOCK);
  553.     LE.Report_Error(LE.Item_Checked_Out, Item, Returned);
  554.     HL.Set_Interrupt_State(Trap);
  555.     return HL.ERROR;
  556.  
  557.     when HL.Interrupt_Encountered =>
  558.     begin
  559.         LU.Unlock_Library(Library, WRITE_LOCK);
  560.     exception
  561.         when others => null;
  562.     end;
  563.     if HL."="(Trap, HL.ENABLED) then
  564.         raise HL.Interrupt_Encountered;
  565.     end if;
  566.     LE.Report_Error(LE.Process_Interrupted, SP.Create("Cancel_Item"));
  567.     HL.Set_Interrupt_State(Trap);
  568.     return HL.WARNING;
  569.  
  570.     when others =>
  571.     begin
  572.         LU.Unlock_Library(Library, WRITE_LOCK);
  573.     exception
  574.         when others => null;
  575.     end;
  576.     LE.Report_Error(LE.Internal_Error, SP.Create("Cancel_Item"));
  577.     HL.Set_Interrupt_State(Trap);
  578.     return HL.SEVERE;
  579.  
  580. end Cancel_Item_Interface;
  581.                                                                     pragma page;
  582. ::::::::::::::
  583. canceli.spc
  584. ::::::::::::::
  585. with String_Pkg;
  586. with Host_Lib;
  587.  
  588. function Cancel_Item_Interface(            --| Cancel a Pending Return
  589.    Library : in String_Pkg.String_Type;        --| Item library
  590.    Item    : in String_Pkg.String_Type        --| Item to cancel return
  591.    ) return Host_Lib.Severity_Code;
  592.  
  593. --| Requires:
  594. --| Name of the library and the item name
  595.  
  596. --| Effects:
  597. --| Checked out state for the given item in the library is canceled
  598.  
  599. --| N/A: Modifies, Raises, Errors
  600.                                                                     pragma page;
  601. ::::::::::::::
  602. catdecls.dat
  603. ::::::::::::::
  604. with string_pkg;
  605. with set_pkg;
  606. with lists;
  607. with ci_ids;
  608.  
  609. package catalog_decls is
  610.  
  611. --| Overview: Declarations of types and items which need to be global to
  612. --| the whole catalog.  These items should be kept to a minimum.
  613.  
  614. package SP renames string_pkg;
  615.  
  616. type hist_record is
  617.     record
  618.     name    : SP.string_type;
  619.     history : SP.string_type;
  620.     creator : SP.string_type;
  621.     date      : SP.string_type;
  622.     submit  : SP.string_type;
  623.     delete  : SP.string_type;
  624.     end record;
  625.  
  626. package CI_sets is new set_pkg(ci_ids.ci_id_type, ci_ids.equal);
  627. subtype CI_set is CI_sets.set;
  628. package string_sets is new set_pkg(SP.string_type, SP.equal);
  629. subtype string_set is string_sets.set;
  630. package hist_lists is new lists(hist_record);
  631. subtype hist_list is hist_lists.list;
  632.  
  633. end catalog_decls;
  634. ::::::::::::::
  635. catmgr.bdy
  636. ::::::::::::::
  637. with text_io;
  638. with hif_node_defs;    use hif_node_defs;    -- use for current node
  639. with hif_node_management;
  640. with hif_attributes;
  641. with hif_list_utils;    use hif_list_utils;    -- use for visible "="
  642. with ci_ids;
  643. with catalog_locks;
  644. with ci_index_mgr;
  645. with lists;
  646. with string_utilities;
  647. with host_lib;
  648. with property_set;
  649. with properties;
  650. with version_lists;
  651. with library_utilities;
  652. with hif_utils;
  653.  
  654. package body catalog_manager is
  655.  
  656. ---- Package Renames:
  657. package ND  renames hif_node_defs;
  658. package NM  renames hif_node_management;
  659. package LU  renames hif_list_utils;
  660. package Attr renames hif_attributes;
  661. package ID  renames ci_ids;
  662. package CL  renames catalog_locks;
  663. package IM  renames ci_index_mgr;
  664. package SU  renames string_utilities;
  665. package HL  renames host_lib;
  666. package VL  renames version_lists;
  667. package UT  renames library_utilities;
  668. package HU  renames hif_utils;
  669.  
  670. use string_pkg;            -- to use infix "&"
  671. use library_declarations;    -- for visibility of fetch_type "="
  672.  
  673.  
  674. ---- Package instantiations:
  675. package SS is new SU.generic_string_utilities(SP.string_type, 
  676.                           SP.create,
  677.                           SP.value);
  678.  
  679. ---- Types:
  680. type pair is 
  681.     record
  682.     key : SP.string_type;
  683.     val : SP.string_type;
  684.     end record;
  685.  
  686. package pair_lists is new lists(pair);
  687. subtype p_list is pair_lists.list;
  688.  
  689. ---- Items global to the package catalog_manager:
  690. wait : duration := 0.0;        -- used for the locks
  691. pairs : p_list := pair_lists.create;
  692.  
  693. ---- Operations local to the package catalog_manager:
  694.  
  695. procedure check_properties (
  696.     node : in ND.node_type;    -- node the properties are on
  697.     stat : in out status_type    -- status of keywords
  698.     );
  699.  
  700. procedure add_properties (
  701.     name : in ID.ci_id_type    -- ci id of the ci to add the properties under
  702.     );
  703.  
  704. function check_list (        --| check the checked out list to make sure 
  705.                 --| this fetch can be done.
  706.     ci_id : in ID.ci_id_type;    --| name of the ci being fetched
  707.     mode  : in LD.fetch_type    --| type of fetch being done
  708.     ) return boolean;
  709.  
  710. function check_list (        --| check the checked out list to make sure 
  711.                 --| this store can be done.
  712.     ci_id : in ID.ci_id_type;    --| name of the ci being stored
  713.     mode  : in LD.fetch_type;    --| type of fetch done originally
  714.     user  : in STRING        --| name of the user to check for
  715.     ) return boolean;
  716.  
  717. procedure update_list (        --| Update the checked out list with this 
  718.                 --| person's name and the type of update
  719.     ci_id : in ID.ci_id_type;    --| name of the ci being fetched
  720.     mode  : in LD.fetch_type    --| type of fetch being done
  721.     );
  722.  
  723. procedure remove_name (        --| remove the user's name from the checked
  724.                 --| out list when a CI is stored
  725.     ci_id : in ID.ci_id_type;    --| name of the ci being stored
  726.     mode  : in LD.fetch_type;    --| type of fetch done originally
  727.     user  : in STRING        --| name of the user to check for
  728.     );    
  729.  
  730. procedure find_versions (    --| recursively find all the versions of a
  731.                 --| ci starting at its root
  732.     root : in ND.node_type;    --| node to start at
  733.     name : in SP.string_type;    --| name of the root node
  734.     list : in out SL.list    --| list returned
  735.     );
  736.  
  737. function strip_v (        --| given a string of the form "v11", strip the
  738.                 --| 'v' just leaving the number.
  739.     ver : in string        --| input version string
  740.     ) return string;
  741.  
  742. ---- Operations global to the package catalog_manager:
  743.  
  744. -- Operations on the catalog:
  745. -- list_cis            list all the CI's in the cpcicat
  746. -- verify_password         verify the password given is the correct one
  747. -- set_password            set a new password
  748.  
  749. function list_cis (        --| list the contents of the catalog
  750.     CIs : in SP.string_type      --| name to match
  751.     := SP.create("*")
  752.     ) return SL.list is
  753.     node    : ND.node_type;
  754.     ci_node : ND.node_type;
  755.     iter    : NM.node_iterator;
  756.     list    : SL.list;
  757.     begin
  758.     --? get a read lock on the root node
  759.     NM.get_current_node (node);
  760.     NM.iterate (iterator => iter,
  761.             node     => node,
  762.             key      => SP.value (cis),
  763.             relation => "ci_root");
  764.     while NM.more (iter) loop
  765.         NM.get_next (iter, ci_node);
  766.         SL.attach (list, SP.create (NM.primary_key (ci_node)));
  767.         NM.close_node_handle (ci_node);
  768.     end loop;
  769.     NM.close_node_handle (node);
  770.     --? unlock the read lock
  771.     return list;
  772.     end list_cis;
  773.  
  774. --| Effects: List the identifiers of CIs which match the pattern given.
  775. --| The default is "*" which matches all identifiers in the catalog.
  776. --| No versions are returned just identifiers.
  777.  
  778. function verify_password (    --| verify the privilege operations password
  779.     p : in  SP.string_type    --| word to check
  780.     ) return boolean is
  781.     node : ND.node_type;
  782.     pass_node : ND.node_type;
  783.     begin
  784.     --| Algorithm:  Open the password relation with the given password.
  785.     --| If it is the correct password the relation exists and the open will
  786.     --| be okay so close the node and return true.  If it is not the 
  787.     --| password the relation will not exist, so name error will be raised.
  788.     --| in this case return false.
  789.     --? get a read lock on the root
  790.     NM.get_current_node (node);
  791.     NM.open_node_handle (node => pass_node,
  792.                  base => node,
  793.                  key  => SP.value (p),
  794.                  relation => "password");
  795.     NM.close_node_handle (pass_node);
  796.     NM.close_node_handle (node);
  797.     --? remove read lock
  798.     return true;
  799.     exception when ND.name_error =>
  800.     -- name error is raised when the path given for the node to be opened
  801.     -- does not exist.
  802.     return false;
  803.     end verify_password;
  804.  
  805. --| Effects: Checks that the string given is the password for the catalog.
  806. --| If it is the password true if returned, false otherwise.
  807.  
  808. procedure set_password (    --| set a new password
  809.     next : in SP.string_type;    --| new password
  810.     old  : in SP.string_type    --| old password for verification
  811.     ) is
  812.     node : ND.node_type;
  813.     begin
  814.     if CL.upgrade_lock (wait) then
  815.     begin
  816.         if verify_password (old) then
  817.             NM.get_current_node (node);
  818.         -- link first to make sure the new password gets in.
  819.         -- it seems that it is less harmful to have an old
  820.         -- password left around (due to aborting between the
  821.         -- time one link is made and the other is severed) than
  822.         -- to get left with out a password.  What would happen
  823.         -- if the links were done the other way around.  I think
  824.         -- it is reasonable to have check_consistency report if there
  825.         -- is more than one password.  In which case a super user then
  826.         -- just has to do a change_password from the old to the new
  827.         -- again.
  828.         begin
  829.             NM.link (node, node, SP.value (next), "password");
  830.         exception when name_error =>
  831.             -- link was already there so there's no need for an error
  832.             null;
  833.         end;
  834.         NM.unlink (node, SP.value (old), "password");
  835.         NM.close_node_handle (node);
  836.         else 
  837.             CL.remove_write;
  838.         raise invalid_password;
  839.         end if;
  840.         CL.remove_write;
  841.       exception 
  842.         when ND.status_error | ND.name_error | ND.use_error |
  843.          ND.hif_internal_error | ND.IO_error | ND.lock_error  |
  844.          ND.access_violation =>
  845.         CL.remove_write;
  846.         raise internal_hif_failure;
  847.     end;
  848.     else
  849.         raise cant_lock;
  850.     end if;        
  851.     end set_password;
  852.     --| raises: invalid_password, cant_lock
  853.  
  854. --| Effects: Sets the password to be the new one if the word given as the
  855. --| old one is the correct password in actuality.  Raises invalid password
  856. --| if not.  If this is really invoked by the catalog interface invalid
  857. --| password should never be raised.
  858.  
  859. -- Operations on a configuration item:
  860. -- create_CI            create a new configuration item from a library
  861. -- store            update a configuration item from an itemlib
  862. -- cancel            cancel a fetch for update
  863. -- fetch            fetch an itemlib from the catalog
  864. -- delete (*)            delete a CI
  865. -- modify_property        change the value associated with a property
  866. -- describe            list all the keywords and values for a CI, and
  867. --                 other information like history as asked for.
  868. -- list_components        list the components of a CI
  869. -- match_keys            match keywords on a CI
  870.  
  871. function create_CI (        --| create a new CI in the catalog
  872.     name    : in SP.string_type;--| name of the new CI
  873.     library : in SP.string_type;--| name of the library to find the CI in
  874.     history : in SP.string_type --| description of the CI
  875.     ) return status_type is
  876.     --| Raises: name_in_use
  877.  
  878. --| Algorithm: The following is a basic outline of the procedure:
  879. --|-
  880. --| 1. Upgrade the user's lock to a write lock.
  881. --| 2. lock the library ci is coming from.
  882. --| 3. check the name to make sure it is not a duplicate.
  883. --| 4. check the mode on the libray to make sure it is no_update. (this
  884. --|     is because update implies that the catalog is waiting for this
  885. --|    ci to be checked back in)
  886. --| 5. Check that the properties on the library are both valid and include
  887. --|    all the required keywords.
  888. --| 6. purge the library.
  889. --| 7. create the node that the ci will hang off of.
  890. --| 8. copytree the library to that node.
  891. --| 9. Add all the properties on the node to the index database.
  892. --|10. Delete the library.
  893. --|11. Unlock the catalog lock.
  894. --|+
  895. --| Between steps one and five no changes have been made to either library
  896. --| or catalog so they are completely safe.  If any of the checks fail the
  897. --| idea is to report it and continue in order to report as many errors as
  898. --| possible.  After step five we begin changing the library and the catalog
  899. --| but all of the changes should be recoverable.  Purging the library 
  900. --| should be ok since the user was trying to check it in anyway the old
  901. --| versions weren't needed.  If at any time between step 7 and 10 the
  902. --| process is aborted the library hasn't been deleted so the catalog can
  903. --| be cleaned up by deleting the incomplete CI and then recreating it.
  904. --| the properties are added to the index after the ci is copied since
  905. --| check_consistency can tell when all the properties on a CI are not in
  906. --| the database, but it can't do the opposite.
  907.  
  908.     status   : status_type := ok;
  909.     ci_id    : ID.ci_id_type;
  910.     ci_node  : ND.node_type;
  911.     ci_root  : ND.node_type;
  912.     lib_node : ND.node_type;
  913.     last     : natural;
  914.     time     : HL.time_value;
  915.     attrib   : string(1..80);
  916.     len      : natural;
  917.     deleted  : boolean := false;
  918.     remain   : LD.LL.list;
  919.     priv     : LD.privilege_type := LD.WORLD;
  920.  
  921.     begin
  922.     if CL.upgrade_lock (wait) then
  923.     begin
  924.  
  925.         begin
  926.             ci_id := ID.get_ci_id (name & " 1");  -- the version is always 1
  927.         exception when ID.invalid_ci_id =>
  928.             status := error;
  929.             errors(non_ada) := true;
  930.         end;
  931.  
  932.         begin
  933.             -- try to open the node.  This should fail since the node
  934.         -- shouldn't exist.  If it does check it for the attribute
  935.         -- deleted.  If it is deleted then it is ok, otherwise
  936.         -- report it as a duplicate name.  However, it can't be
  937.         -- checked if the ci_id is invalid.
  938.         if not errors(non_ada) then
  939.                 NM.open_node_handle (ci_node, ID.get_hif_path (ci_id));
  940.             HU.get_node_attribute (ci_node, "deleted", attrib, len);
  941.             if attrib(1..len) /= "" then
  942.                 deleted := true;
  943.             else
  944.                 status := error;
  945.                 errors(dup_name) := true;    -- name already is used
  946.             --  only close the node handle if it is a duplicate
  947.             --  it will be used below if it was deleted.
  948.                 NM.close_node_handle (ci_node);
  949.              end if;
  950.         end if;
  951.         exception when ND.name_error =>
  952.         null;
  953.         end;
  954.  
  955.         if not 
  956.           (LD.fetch_type'value(UT.get_library_attribute(library,"MODE"))
  957.             = LD.no_update) then
  958.             status := error;
  959.             errors(create_mode) := true;
  960.         end if;
  961.  
  962.         if UT.is_item_checked_out (library) then
  963.         status := error;
  964.         errors(ready) := true;
  965.         end if;
  966.  
  967.         -- we are starting to look at things the user could change so
  968.         -- lock the library
  969.         if UT.lock_library (library, LD.write_lock) then
  970.         NM.open_node_handle (lib_node, 
  971.             SP.value (UT.node_name (library, SP.create("*"))));
  972.         check_properties (lib_node, status);
  973.         -- only continue with the creation if there are no errors
  974.  
  975.             -- purge the library and rename all items to be version 1
  976.         UT.purge (library, privilege=>priv, remainder=>remain);
  977.         if not LD.LL.isempty (remain) then
  978.             status := error;
  979.             errors(purge) := true;
  980.         else
  981.             -- remain is empty if we get here so re-use it.  Rename
  982.             -- version should not fail if you were able to purge.
  983.             begin
  984.                 UT.rename_version (library, 
  985.                               SP.create("*"), 
  986.                               SP.create("0"), 
  987.                               SP.create("1"), 
  988.                            privilege=>priv,
  989.                            remainder=>remain);
  990.             exception when LD.item_not_found =>
  991.             -- means it was an empty library
  992.             null;
  993.             end;
  994.         end if;
  995.  
  996.         if status = ok then    
  997.         
  998.          -- if the node is not one of a deleted one then the hif
  999.         -- nodes have to be created.  In the case where this was
  1000.         -- a ci that was deleted the nodes already exist because
  1001.         -- that's where the deleted attribute is! So just remove 
  1002.         -- the attribute so that it reflects the new status of the
  1003.         -- node.
  1004.  
  1005.             if not deleted then
  1006.             begin
  1007.                   NM.create_node (node => ci_root,
  1008.                         name => "'current_node'ci_root(" &
  1009.                              SP.value (name) & ")",
  1010.                         form => "");
  1011.                   NM.create_node (node => ci_node, 
  1012.                         name => ID.get_hif_path (ci_id),
  1013.                         form => "");
  1014.               NM.close_node_handle (ci_root);
  1015.             exception when ND.name_error=>
  1016.               NM.create_node (node => ci_node, 
  1017.                         name => ID.get_hif_path (ci_id),
  1018.                         form => "");
  1019.               NM.close_node_handle (ci_root);
  1020.             end;
  1021.             else
  1022.         --      the ci_node already exists.  It has to because
  1023.         --    that's where we read the deleted attribute.
  1024.         --    I would have put the create nodes in with the
  1025.         --     requirement "no_effect_if_exists", but there
  1026.         --     seems to be some problem with that call.
  1027.         --    Since it is going to be recreated delete the
  1028.         --    "deleted" attribute.
  1029.  
  1030.             Attr.set_node_attribute(ci_node, "deleted", "");
  1031.  
  1032.             end if;
  1033.  
  1034.             NM.copy_tree (lib_node,
  1035.                   ci_node, 
  1036.                   "ci");
  1037.             Attr.set_node_attribute (ci_node,
  1038.                          "branches",
  1039.                          "0");
  1040.             Attr.set_node_attribute (ci_node, 
  1041.                          "history", 
  1042.                          SP.value(history));
  1043.             Attr.set_node_attribute (ci_node,
  1044.                          "creator",
  1045.                          UT.get_library_attribute (library,
  1046.                                        "OWNER")
  1047.                          );
  1048.             Attr.set_node_attribute (ci_node,
  1049.                          "submitter",
  1050.                          HL.get_item(HL.user_name));
  1051.             HL.get_time (time);
  1052.             Attr.set_node_attribute (ci_node,
  1053.                          "date",
  1054.                          HL.date(time)&" "&HL.time(time));
  1055.             add_properties (ci_id);
  1056.             UT.delete_library (library);
  1057.             NM.close_node_handle (ci_node);
  1058.          else
  1059.             UT.unlock_library (library, LD.write_lock);
  1060.         end if;
  1061.         else
  1062.             CL.remove_write;
  1063.         raise library_locked;
  1064.         end if;
  1065.         CL.remove_write;
  1066.     exception 
  1067.         when ND.status_error | ND.use_error | ND.hif_internal_error |
  1068.          ND.IO_error | ND.lock_error | ND.access_violation =>
  1069.         raise internal_hif_failure;
  1070.         when ND.name_error =>
  1071.         -- you can try to unlock a library that has already been 
  1072.         -- unlocked without any bad side effects.
  1073.         UT.unlock_library (library, LD.write_lock);
  1074.         CL.remove_write;
  1075.         raise internal_name_error;
  1076.         when constraint_error | LD.invalid_library_name =>
  1077.         CL.remove_write;
  1078.         raise invalid_library;
  1079.         when LD.library_does_not_exist =>
  1080.         CL.remove_write;
  1081.         raise library_nonexistent;
  1082.     end;
  1083.     else
  1084.         raise cant_lock;
  1085.     end if;
  1086.         return status;
  1087.     end create_ci;
  1088.  
  1089.  
  1090. function store (        --| store a CI in the catalog from an 
  1091.                 --| item library
  1092.     library : in SP.string_type;    --| itemlibrary name to get the CI from
  1093.     history : in SP.string_type        --| description of the CI
  1094.     ) return status_type is
  1095.  
  1096. --| Algorithm:  This is very similar to create_ci:
  1097. --|-
  1098. --| 1. upgrade the catalog lock.
  1099. --| 2. lock the library.
  1100. --| 3. check that the mode is trunk or branch (both imply update)
  1101. --| 4. Check the properties on the library for validity and required.
  1102. --| 5. Get the ci_id of what wsa checked out.
  1103. --| 6. Check that the current user is the one who checked it out.
  1104. --| 7. Massage the ci_id into the new one.
  1105. --| 8. purge the library.
  1106. --| 9. do a copytree.
  1107. --|10. change mode on library to no update.
  1108. --|11. add all the properties.
  1109. --|12. delete the library.
  1110. --|13. remove the catalog lock.
  1111. --|+
  1112. --| The rationale for store is pretty much the same as for create_ci.  The
  1113. --| only differences lying in the fact that whether it is a trunk or a 
  1114. --| branch makes a difference to what nodes are created.
  1115.  
  1116.     status     : status_type := ok;
  1117.     ci_id      : ID.ci_id_type;
  1118.     ci_node     : ND.node_type;
  1119.     old_node    : ND.node_type;
  1120.     lib_node    : ND.node_type;
  1121.     old_ci_id   : ID.ci_id_type;
  1122.     trunk_node  : ND.node_type;
  1123.     branch_node : ND.node_type;
  1124.     branch_path : SP.string_type;
  1125.     branch      : natural;
  1126.     user         : SP.string_type;
  1127.     creator    : SP.string_type;
  1128.     last         : natural;
  1129.     time         : HL.time_value;
  1130.     mode        : LD.fetch_type;
  1131.     attrib      : string (1..80);
  1132.     remain    : LD.LL.list;
  1133.     priv        : LD.privilege_type := LD.WORLD;
  1134.  
  1135.     begin
  1136.     if CL.upgrade_lock (wait) then
  1137.     begin
  1138.         begin
  1139.             old_ci_id := ID.get_ci_id (UT.get_library_attribute(library,
  1140.                                     "CI"));
  1141.         exception when ID.invalid_ci_id =>
  1142.             status := error;
  1143.             errors(non_ci_id) := true;
  1144.         end;
  1145.         mode := LD.fetch_type'value(UT.get_library_attribute (library,
  1146.                                   "MODE"));
  1147.         if not errors(non_ci_id) then
  1148.         -- you can't check the name on the list if the ci id isn't
  1149.         -- right
  1150.         user := SP.create (HL.get_item(HL.user_name));
  1151.           creator := SP.create (
  1152.                 UT.get_library_attribute (library, "OWNER"));
  1153.         if not check_list (old_ci_id, mode, SP.value(creator))
  1154.           then
  1155.             CL.remove_write;
  1156.             raise incorrect_person;
  1157.         end if;
  1158.         end if;
  1159.         begin
  1160.             NM.open_node_handle (old_node, ID.get_hif_path (old_ci_id));
  1161.         exception when ND.name_error =>
  1162.         status := error;
  1163.         errors(non_existent) := true;
  1164.         end;
  1165.         if (mode = LD.no_update) then
  1166.             status := error;
  1167.             errors(in_mode) := true;
  1168.         end if;
  1169.  
  1170.         if UT.is_item_checked_out (library) then
  1171.         status := error;
  1172.         errors(ready) := true;
  1173.         end if;
  1174.  
  1175.         -- we are starting to look at things the user could change so
  1176.         -- lock the library
  1177.         if UT.lock_library (library, LD.write_lock) then
  1178.         NM.open_node_handle (lib_node, 
  1179.             SP.value (UT.node_name (library, SP.create("*"))));
  1180.         check_properties (lib_node, status);
  1181.         -- only continue with the store if there are no errors
  1182.  
  1183.             -- purge the library and rename all items to be version 1
  1184.         UT.purge (library, privilege=>priv, remainder=>remain);
  1185.         if not LD.LL.isempty (remain) then
  1186.             status := error;
  1187.             errors(purge) := true;
  1188.         else
  1189.             begin
  1190.                 UT.rename_version (library, 
  1191.                        SP.create("*"), 
  1192.                        SP.create("0"), 
  1193.                        SP.create("1"),
  1194.                        privilege=>priv,
  1195.                        remainder=>remain);
  1196.             exception when LD.item_not_found =>
  1197.             -- means its an empty library
  1198.             null;
  1199.             end;
  1200.         end if;
  1201.  
  1202.         if status = ok then    
  1203.  
  1204.             if mode = LD.update then
  1205.             ci_id := ID.increment_ci_id (old_ci_id);
  1206.             Attr.set_node_attribute (old_node, "status", "UPDATE");
  1207.             begin
  1208.                 NM.open_node_handle (ci_node, 
  1209.                          ID.get_hif_path(ci_id));
  1210.                 HU.get_node_attribute (ci_node, 
  1211.                              "deleted", 
  1212.                              attrib, 
  1213.                              last);
  1214.                 if attrib(1..last) = "" then
  1215.                     CL.remove_write; 
  1216.                 UT.unlock_library (library, LD.write_lock);
  1217.                 raise update_already_exists;
  1218.                 end if;
  1219.             exception when ND.name_error =>
  1220.                 NM.create_node (node => ci_node,
  1221.                         name => ID.get_hif_path (ci_id),
  1222.                         form => "");
  1223.             end;
  1224.             else     -- mode = LD.branch
  1225.             NM.open_node_handle(trunk_node,
  1226.                         ID.get_hif_path(old_ci_id));
  1227.             HU.get_node_attribute (trunk_node,
  1228.                          "branches",
  1229.                          attrib,
  1230.                          last);
  1231.             branch := integer'value (attrib(1..last)) + 1;
  1232.             branch_path := ID.get_hif_path(old_ci_id) & 
  1233.                     "'branch(v" & SU.image(branch) &")";
  1234.             ci_id := ID.get_ci_id(string'(ID.image(old_ci_id)) & 
  1235.                           "." & SU.image(branch) & ".1");
  1236.             begin
  1237.                 NM.open_node_handle (ci_node,
  1238.                          ID.get_hif_path (ci_id));
  1239.                 HU.get_node_attribute (ci_node, 
  1240.                              "deleted", 
  1241.                              attrib, 
  1242.                              last);
  1243.                 if attrib(1..last) = "" then
  1244.                 -- the branch is already here and it's not
  1245.                 -- deleted.  The way to fix is to increment
  1246.                 -- the branch number and call store again.
  1247.                 Attr.set_node_attribute (trunk_node,
  1248.                              "branches",
  1249.                              integer'image(branch));
  1250.                 CL.remove_write;
  1251.                 status := store (library, history);
  1252.                 return status;
  1253.                 end if;
  1254.             exception when ND.name_error =>
  1255.                 begin
  1256.                   NM.create_node (node => branch_node,
  1257.                           name => SP.value(branch_path),
  1258.                           form => "");
  1259.                   NM.create_node (node => ci_node,
  1260.                           name => ID.get_hif_path (ci_id),
  1261.                           form => "");
  1262.                   NM.close_node_handle (branch_node);
  1263.                 exception when ND.name_error =>
  1264.                   NM.create_node (node => ci_node,
  1265.                           name => ID.get_hif_path (ci_id),
  1266.                           form => "");
  1267.                   NM.close_node_handle (branch_node);
  1268.                 end;
  1269.             end;
  1270.             end if;
  1271.             Attr.set_node_attribute (ci_node,
  1272.                          "branches",
  1273.                          "0");
  1274.             NM.copy_tree (lib_node,
  1275.                   ci_node, 
  1276.                   "ci");
  1277.             Attr.set_node_attribute (ci_node, 
  1278.                          "history", 
  1279.                          SP.value(history));
  1280.             Attr.set_node_attribute (ci_node,
  1281.                          "creator",
  1282.                          SP.value(creator));
  1283.             Attr.set_node_attribute (ci_node,
  1284.                          "submitter",
  1285.                          SP.value(user));
  1286.             HL.get_time (time);
  1287.             Attr.set_node_attribute (ci_node,
  1288.                          "date",
  1289.                          HL.date(time)&" "&HL.time(time));
  1290.             add_properties (ci_id);
  1291.             if mode = LD.branch then
  1292.             Attr.set_node_attribute (trunk_node,
  1293.                          "branches",
  1294.                          integer'image(branch));
  1295.             NM.close_node_handle (trunk_node);
  1296.             end if;
  1297.             remove_name (old_ci_id, mode, SP.value(user));
  1298.             -- set library to be no_update at this point otherwise
  1299.             -- delete_library will fail.  Besides we don't want it
  1300.             -- being added again.  You also have to unlock the
  1301.             -- library for delete to work.
  1302.             UT.set_library_attribute (library, "mode", "NO_UPDATE");
  1303.             UT.delete_library (library);
  1304.             NM.close_node_handle (ci_node);
  1305.             NM.close_node_handle (old_node);
  1306.          else
  1307.             UT.unlock_library (library, LD.write_lock);
  1308.         end if;
  1309.         else
  1310.             CL.remove_write;
  1311.         raise library_locked;
  1312.         end if;
  1313.         CL.remove_write;
  1314.     exception 
  1315.         when constraint_error | LD.invalid_library_name =>
  1316.         CL.remove_write;
  1317.         raise invalid_library;
  1318.         when ND.name_error =>
  1319.         CL.remove_write;
  1320.         raise no_such_ci;
  1321.  
  1322.         when LD.library_does_not_exist =>
  1323.         CL.remove_write;
  1324.         raise library_nonexistent;
  1325.         when ND.status_error | ND.use_error | ND.hif_internal_error |
  1326.          ND.IO_error | ND.lock_error | ND.access_violation =>
  1327.         raise internal_hif_failure;
  1328.     end;
  1329.     else
  1330.         raise cant_lock;
  1331.     end if;
  1332.         return status;
  1333.     end store;
  1334.  
  1335. procedure cancel (        --| cancel a fetch for update
  1336.     library : in SP.string_type;--| name of the library where the CI is checked
  1337.                 --| out
  1338.     user    : in SP.string_type --| user that checked out the CI
  1339.     ) is
  1340.  
  1341. --| Algorithm: Cancel is pretty simple.  The idea is to cancel a fetch that
  1342. --| was branch or trunk.  The library should be left alone however, so the
  1343. --| steps are to take the name from the checked out list and then to
  1344. --| change the mode on the library.  Of course the catalog will be locked 
  1345. --| before the cancel and unlocked after.
  1346.  
  1347.     ci_id  : ID.ci_id_type;
  1348.     mode   : LD.fetch_type;
  1349.  
  1350.     begin
  1351.     if CL.upgrade_lock(wait) then
  1352.     begin
  1353.         ci_id := ID.get_ci_id (UT.get_library_attribute (library, "ci"));
  1354.         mode := LD.fetch_type'value (
  1355.             UT.get_library_attribute (library, "mode"));
  1356.         remove_name (ci_id, mode, SP.value (user));
  1357.         UT.set_library_attribute (library, "mode", "NO_UPDATE");
  1358.         CL.remove_write;
  1359.      exception 
  1360.         when ID.invalid_ci_id | ND.name_error =>
  1361.         CL.remove_write;
  1362.         raise ci_not_fetched;
  1363.         when constraint_error =>
  1364.         CL.remove_write;
  1365.         raise invalid_mode;
  1366.         when LD.library_does_not_exist =>
  1367.         CL.remove_write;
  1368.         raise library_nonexistent;
  1369.         when LD.invalid_library_name =>
  1370.         CL.remove_write;
  1371.         raise invalid_library;
  1372.         when ND.status_error | ND.use_error | ND.hif_internal_error |
  1373.          ND.IO_error | ND.lock_error | ND.access_violation =>
  1374.         raise internal_hif_failure;
  1375.     end;
  1376.     else
  1377.         raise cant_lock;
  1378.     end if;
  1379.     end cancel;
  1380.  
  1381. procedure fetch (        --| Fetches the specified configuration item
  1382.                 --| and places it in the given item_library
  1383.     CI_name : in SP.string_type;--| name of the CI to fetch
  1384.     library : in SP.string_type;--| name of the item_library to put the CI in
  1385.     dir        : in SP.string_type;--| where to put the item_library
  1386.     mode    : in LD.fetch_type    --| whether the fetch is for updating or not
  1387.     := LD.no_update
  1388.     ) is
  1389.  
  1390. --| Algorithm: The following is an outline of the fetch procedure.
  1391. --|-
  1392. --| 1. Upgrade the catalog lock.
  1393. --| 2. if the mode isn't no_update then check the checked out list to 
  1394. --|     make sure the checkout can be done.
  1395. --| 3. create the library.
  1396. --| 4. lock the library.
  1397. --| 5. copy tree.
  1398. --| 6. put all the other info that a library needs on the library node
  1399. --| 7. add them to the checked out list.
  1400. --| 8. unlock both locks.
  1401. --|+
  1402. --| Note that the ci is not officially checked out until the name is on the
  1403. --| checked out list.
  1404.  
  1405.     cat_node : ND.node_type; 
  1406.     ci_node  : ND.node_type; 
  1407.     parent   : ND.node_type;
  1408.     ci_id    : ID.ci_id_type;
  1409.     attrib   : string (1..80);
  1410.     last     : natural;
  1411.     begin
  1412.     if CL.upgrade_lock (wait) then
  1413.     begin
  1414.         ci_id := ID.get_ci_id (ci_name);
  1415.         begin 
  1416.         NM.open_node_handle (parent, ID.get_hif_path(ci_id));
  1417.         exception when ND.name_error =>
  1418.         CL.remove_write;
  1419.         raise no_such_ci;
  1420.         end;        
  1421.         begin
  1422.              NM.open_node_handle (ci_node, ID.get_hif_path(ci_id) & ".ci");
  1423.         exception when ND.name_error =>
  1424.         HU.get_node_attribute (parent, "deleted", attrib, last);
  1425.         if attrib(1..last) /= "" then
  1426.             CL.remove_write;
  1427.             raise deleted_ci;
  1428.         else
  1429.             CL.remove_write;
  1430.             raise incomplete_store;    
  1431.         end if;
  1432.         end;
  1433.         if not check_list (ci_id, mode) then
  1434.         CL.remove_write;
  1435.         raise already_fetched;
  1436.         end if;
  1437.         if mode = LD.update then
  1438.             HU.get_node_attribute (parent, "status", attrib, last);
  1439.             if attrib(1..last) = "UPDATE" then
  1440.             CL.remove_write;
  1441.             raise already_updated;
  1442.             end if;
  1443.         end if;
  1444.         NM.get_current_node (cat_node);
  1445.         UT.create_library (    library, 
  1446.                 dir, 
  1447.                 ci_name,
  1448.                 mode,
  1449.                 ci_node,
  1450.                 locked=>TRUE);
  1451.         update_list (ci_id, mode);
  1452.         NM.close_node_handle (ci_node);
  1453.         NM.close_node_handle (cat_node);
  1454.         NM.close_node_handle (parent);
  1455.         UT.unlock_library (library, LD.write_lock);
  1456.         CL.remove_write;
  1457.  
  1458.       exception 
  1459.         when ID.invalid_ci_id =>
  1460.         CL.remove_write;
  1461.         raise invalid_ci_id;
  1462.         when ND.name_error =>
  1463.         CL.remove_write;
  1464.         raise no_such_ci;
  1465.         when LD.invalid_library_name =>
  1466.         CL.remove_write;
  1467.         raise invalid_library;
  1468.         when LD.directory_already_exists | LD.library_already_exists |
  1469.          LD.invalid_directory_name  =>
  1470.         CL.remove_write;
  1471.         raise;
  1472.         when ND.status_error | ND.use_error | ND.hif_internal_error |
  1473.          ND.IO_error | ND.lock_error | ND.access_violation =>
  1474.         raise internal_hif_failure;
  1475.     end;
  1476.     else
  1477.         raise cant_lock;
  1478.     end if;
  1479.     end fetch;
  1480.  
  1481.  
  1482. procedure modify_property (    --| modify the value associated with a property
  1483.                 --| for a given CI
  1484.     CI_name : in SP.string_type;--| the name of the CI to change
  1485.     keyword : in SP.string_type;--| the name of the keyword to modify
  1486.     value   : in SP.string_type    --| the new value to give the keyword
  1487.     ) is
  1488.  
  1489.     ci_id : ID.ci_id_type;
  1490.     node  : ND.node_type;
  1491.     list  : LU.list_type;
  1492.     attrib: string(1..80);
  1493.     last  : natural;
  1494.  
  1495.     begin
  1496.  
  1497.     if SP.is_empty(keyword) then    -- it causes a hif internal error if
  1498.                     -- you don't catch a null string here.
  1499.         raise IM.invalid_keyword;
  1500.     end if;
  1501.         if CL.upgrade_lock (wait) then
  1502.         begin
  1503.             -- Update the information in the index.
  1504.         -- delete doesn't do anything if the ci is not in this set 
  1505.         -- already.
  1506.         ci_id := ID.get_ci_id (ci_name);
  1507.         begin
  1508.                 NM.open_node_handle (node, 
  1509.                      ID.get_hif_path (ci_id) & ".CI");
  1510.         exception when ND.name_error =>
  1511.             begin
  1512.             NM.open_node_handle (node,
  1513.                          ID.get_hif_path (ci_id));
  1514.             HU.get_node_attribute (node, 
  1515.                          "deleted",
  1516.                          attrib,
  1517.                          last);
  1518.             if last /= 0 then
  1519.                 CL.remove_write;
  1520.                 raise deleted_ci;
  1521.             else    
  1522.                     CL.remove_write;
  1523.                     raise no_such_ci;
  1524.             end if;
  1525.             NM.close_node_handle (node);
  1526.             exception 
  1527.             when ND.name_error =>
  1528.                     CL.remove_write;
  1529.                     raise no_such_ci;
  1530.             end;
  1531.         end;
  1532.         if IM.is_required_keyword(keyword) and SP.is_empty(value) then
  1533.             CL.remove_write;
  1534.             raise required_keyword;
  1535.         end if;
  1536.         IM.delete_ci (keyword, 
  1537.                   get_property (ci_name, keyword),
  1538.                   ci_id);
  1539.  
  1540.         if not SP.is_empty(value) then
  1541.             -- have to check the value here otherwise you get a list
  1542.             -- use error.
  1543.             LU.add_positional (list, LU.to_item(SP.value(value)));
  1544.             -- set node attribute clobbers the old value.
  1545.             Attr.set_node_attribute (node, SP.value(keyword), list);
  1546.             NM.close_node_handle (node);
  1547.             LU.free_list (list);
  1548.             IM.add_ci (keyword, value, ci_id);
  1549.         else
  1550.             LU.init_list(list);
  1551.             Attr.set_node_attribute (node, SP.value(keyword), list);
  1552.             NM.close_node_handle (node);
  1553.             LU.free_list (list);
  1554.         end if;
  1555.  
  1556.         CL.remove_write;
  1557.         exception 
  1558.         when ND.name_error =>
  1559.             CL.remove_write;
  1560.             raise invalid_key_or_val;
  1561.         when ID.invalid_ci_id =>
  1562.             CL.remove_write;
  1563.             raise invalid_ci_id;
  1564.         when IM.invalid_keyword | IM.invalid_value =>
  1565.             CL.remove_write;
  1566.             raise;    -- these two are handled in command interpreter
  1567.             when ND.status_error | ND.use_error | ND.hif_internal_error |
  1568.              ND.IO_error | ND.lock_error | ND.access_violation =>
  1569.             raise internal_hif_failure;
  1570.         end;
  1571.     else
  1572.         raise cant_lock;
  1573.     end if;
  1574.     end modify_property;
  1575.  
  1576. function get_property (        --| get the value associated with a particular
  1577.                 --| property for a given CI
  1578.     CI_name : in SP.string_type;--| name of the CI to give the info about
  1579.     keyword : in SP.string_type    --| name of the keyword for the property
  1580.     ) return SP.string_type is
  1581.  
  1582.     ci_id   : ID.ci_id_type;
  1583.     node    : ND.node_type;
  1584.     attrib  : string(1..80);
  1585.     last    : natural;
  1586.  
  1587.     begin
  1588.     ci_id := ID.get_ci_id (ci_name);
  1589.     NM.open_node_handle (node, ID.get_hif_path (ci_id) & ".CI");
  1590.     begin
  1591.         HU.get_node_attribute (node, SP.value(keyword), attrib, last);
  1592.         NM.close_node_handle (node);
  1593.     exception when ND.name_error =>
  1594.         raise IM.invalid_keyword;
  1595.     end;
  1596.     return SP.create(attrib(1..last));
  1597.     exception when ND.name_error =>
  1598.     raise incomplete_store;
  1599.     end get_property;
  1600.  
  1601. function history (        --| return the history of a particular CI
  1602.     CI_name : in SP.string_type --| name of the CI
  1603.     ) return CD.hist_list is
  1604.  
  1605.     ci_id  : ID.ci_id_type;
  1606.     curr_id  : ID.ci_id_type;
  1607.     node   : ND.node_type;
  1608.     ver_list : VL.list;
  1609.     name     : SP.string_type;
  1610.     iter     : VL.listiter;
  1611.     ci_ver   : SP.string_type;
  1612.     curr_ver : SP.string_type := SP.create ("1");
  1613.     history  : CD.hist_list;
  1614.     hist     : string(1..256);
  1615.     hist_len : natural;
  1616.     date     : string(1..20);
  1617.     date_len : natural;
  1618.     prog     : string(1..80);
  1619.     prog_len : natural;
  1620.     del         : string(1..80);
  1621.     del_len  : natural;
  1622.     sub      : string(1..80);
  1623.     sub_len  : natural;
  1624.     num      : positive;
  1625.  
  1626.     package HLS renames CD.hist_lists;
  1627.  
  1628.     begin
  1629.     begin
  1630.         ci_id := ID.get_ci_id (ci_name);
  1631.         NM.open_node_handle (node, ID.get_hif_path(ci_id));
  1632.         NM.close_node_handle(node);
  1633.     exception 
  1634.         when ID.invalid_ci_id =>
  1635.             raise invalid_ci_id;
  1636.         when ND.name_error =>
  1637.         raise no_such_ci;
  1638.     end;
  1639.     ver_list := ID.get_version (ci_id);
  1640.     name := ID.get_name (ci_id);
  1641.     iter := VL.makelistiter (ver_list);
  1642.         VL.next (iter, num);
  1643.     ci_ver := SS.image (num);
  1644.     loop
  1645.         ci_id := ID.get_ci_id (name & " " & ci_ver);
  1646.         curr_id := ID.get_ci_id (name & " " & curr_ver);
  1647.         while ID."<=" (curr_id, ci_id) loop
  1648.         NM.open_node_handle (node, ID.get_hif_path (curr_id));
  1649.         HU.get_node_attribute (node, "history", hist, hist_len);
  1650.         HU.get_node_attribute (node, "date", date, date_len);
  1651.         HU.get_node_attribute (node, "creator", prog, prog_len);
  1652.         HU.get_node_attribute (node, "submitter", sub, sub_len);
  1653.         HU.get_node_attribute (node, "deleted", del, del_len);
  1654.         HLS.attach ((name    => ID.image(curr_id),
  1655.                  history => SP.create(hist(1..hist_len)),
  1656.                  creator => SP.create(prog(1..prog_len)),
  1657.                  submit  => SP.create( sub(1..sub_len)),
  1658.                  date    => SP.create(date(1..date_len)),
  1659.                  delete  => SP.create( del(1..del_len))),
  1660.                 history);
  1661.         NM.close_node_handle (node);
  1662.         curr_id := ID.increment_ci_id (curr_id);
  1663.         end loop;
  1664.         if VL.more (iter) then
  1665.         VL.next (iter, num);
  1666.         ci_ver := ci_ver & "." & SU.image(num);
  1667.         curr_ver := ci_ver & ".1";
  1668.         VL.next (iter, num);
  1669.         ci_ver := ci_ver & "." & SU.image(num);
  1670.         else
  1671.         exit;
  1672.         end if;
  1673.     end loop;
  1674.     return history;
  1675.     exception
  1676.     when ID.invalid_ci_id =>
  1677.         raise no_such_ci;
  1678.     when  ND.name_error =>
  1679.         raise incomplete_store;
  1680.     end history;
  1681.  
  1682. function list_versions (    --| return a list of the different versions of
  1683.                 --| a ci given a ci name (not a ci id)
  1684.     ci_name : in SP.string_type --| ada id part of ci id
  1685.     ) return SL.list is
  1686.     hif_path  : SP.string_type;
  1687.     name      : SP.string_type;
  1688.     root      : SP.string_type;
  1689.     hif_node  : ND.node_type;
  1690.     iter      : NM.node_iterator;
  1691.     list      : SL.list;
  1692.     next_node : ND.node_type;
  1693.     trunk     : boolean;
  1694.     attrib    : string(1..80);
  1695.     len       : natural;
  1696.  
  1697.     begin
  1698.     if not UT.is_ada_id (ci_name) then
  1699.         raise invalid_ci_name;
  1700.     end if;
  1701.     hif_path := "'current_node'ci_root(" & ci_name & ")";
  1702.     begin
  1703.         NM.open_node_handle (hif_node, SP.value(hif_path));
  1704.     exception when ND.name_error =>
  1705.         raise no_such_ci;
  1706.     end;
  1707.     find_versions (hif_node, ci_name & " ", list);
  1708.     return list;
  1709.     end list_versions;
  1710.  
  1711. --| Effects:  Returns a list of the versions of a CI given a name.
  1712. --| If the list is of trunk updates then the ci_id should be incomplete and
  1713. --| the program will show all trunk updates on that branch.  If a list
  1714. --| of branches is what is needed then the ci_id should be complete and
  1715. --| a list of the branches from that ci will be shown.
  1716.  
  1717. function list_components (    --| list the components of a given CI
  1718.     CI_name : in SP.string_type --| name of the CI
  1719.     ) return LD.LL.list is
  1720.  
  1721.     ci_id : ID.ci_id_type;
  1722.     node  : ND.node_type;
  1723.     attrib: string(1..80);
  1724.     last  : natural;
  1725.     
  1726.     begin
  1727.     ci_id := ID.get_ci_id (ci_name);
  1728.      NM.open_node_handle (node, ID.get_hif_path (ci_id) & ".CI");
  1729.     return UT.list_item (node);
  1730.     exception 
  1731.     when ND.name_error=>
  1732.         begin
  1733.         NM.open_node_handle (node,
  1734.                      ID.get_hif_path (ci_id));
  1735.         HU.get_node_attribute (node, 
  1736.                      "deleted",
  1737.                      attrib,
  1738.                      last);
  1739.         if last /= 0 then
  1740.             raise deleted_ci;
  1741.         else    
  1742.                 raise no_such_ci;
  1743.         end if;
  1744.         NM.close_node_handle (node);
  1745.         exception 
  1746.         when ND.name_error =>
  1747.                 raise no_such_ci;
  1748.         end;
  1749.     when LD.item_not_found =>
  1750.         return LD.LL.create;
  1751.     end list_components;
  1752.  
  1753. --| Effects: Returns a list that is all the components of the given CI.
  1754.  
  1755. function match_keys (        --| match keywords in a list to the 
  1756.                 --| keywords on a CI and return the list
  1757.     CI_name : in SP.string_type;--| name of the CI
  1758.     key_list : in SL.list    --| keywords list 
  1759.     ) return PS.set is
  1760.  
  1761. --| Effects: Reads each of the elements of the list (which could have
  1762. --| wild cards) and matches them to all the properties on the given
  1763. --| CI.  Returns the set of matched properties which includes the value
  1764. --| as well as the keyword.
  1765.  
  1766.     ci_id : ID.ci_id_type;
  1767.     p_set : PS.set;
  1768.     iter  : SL.listiter;
  1769.     node  : ND.node_type;
  1770.     match : SP.string_type;
  1771.     key   : string(1..80);
  1772.     last  : natural;
  1773.     list  : LU.list_type;
  1774.     i     : Attr.attrib_iterator;
  1775.     attrib: string(1..80);
  1776.  
  1777.     begin
  1778.      ci_id := ID.get_ci_id (ci_name);
  1779.     iter := SL.makelistiter (key_list);
  1780.     begin
  1781.         NM.open_node_handle (node, ID.get_hif_path(ci_id) & ".CI");
  1782.     exception when ND.name_error=>
  1783.         begin
  1784.         NM.open_node_handle (node,
  1785.                      ID.get_hif_path (ci_id));
  1786.         HU.get_node_attribute (node, 
  1787.                      "deleted",
  1788.                      attrib,
  1789.                      last);
  1790.         if last /= 0 then
  1791.             raise deleted_ci;
  1792.         else    
  1793.                 raise no_such_ci;
  1794.         end if;
  1795.         NM.close_node_handle (node);
  1796.         exception 
  1797.         when ND.name_error =>
  1798.                 raise no_such_ci;
  1799.         end;
  1800.     end;
  1801.     while SL.more (iter) loop
  1802.         SL.next (iter, match);
  1803.         Attr.node_attribute_iterate (i, node, SP.value(match));
  1804.         while Attr.more (i) loop
  1805.         Attr.get_next (i, key, last, list);
  1806.         PS.insert ((key => SP.create (key(1..last)),
  1807.                 val => SP.create (LU.identifier(
  1808.                         LU.positional(list,1)))),
  1809.                p_set);
  1810.         LU.free_list (list);
  1811.         end loop;
  1812.     end loop;
  1813.     NM.close_node_handle (node);
  1814.     return p_set;
  1815.     end match_keys;
  1816.  
  1817. -- Operations for libuser's use
  1818. -- get_hif_file_name        returns a hif file name for the given CI
  1819. -- audit_trail            gives the audit trail for a CI item
  1820. -- check_obsolescence        checks to see if a file is included that
  1821. --                 is obsolete
  1822.  
  1823. function get_hif_file_name (     --| return the hif file name for a CI item
  1824.    catalog : in SP.string_type;    --| name of the catalog
  1825.    CI_name : in SP.string_type;    --| name of the CI
  1826.    item    : in SP.string_type  --| name of the item in the CI
  1827.    ) return SP.string_type is
  1828.     node : ND.node_type;
  1829.     ci_id   : ID.ci_id_type;
  1830.     path : SP.string_type;
  1831.     file : SP.string_type;
  1832.     begin
  1833.     SP.mark;
  1834.     ci_id := ID.get_ci_id (CI_name);
  1835.     begin
  1836.         NM.set_current_node ("'user(" & SP.value(catalog) & ")");
  1837.     exception when ND.name_error =>
  1838.         raise no_such_catalog;
  1839.     end;
  1840.     path := ID.get_hif_path(ci_id);
  1841.     begin
  1842.         NM.open_node_handle (node, SP.value(path));
  1843.         NM.close_node_handle (node);
  1844.     exception when ND.name_error =>
  1845.         raise no_such_ci;
  1846.     end;
  1847.     path := path & ".CI." & UT.internal_name (item) & ".V1";
  1848.     begin
  1849.         NM.open_node_handle (node, SP.value(path));
  1850.     exception when ND.name_error =>
  1851.         raise no_such_component;
  1852.     end;
  1853.     file := SP.make_persistent(NM.host_file_name (node));
  1854.     SP.release;
  1855.     NM.close_node_handle (node);
  1856.     return file;
  1857.     end get_hif_file_name;
  1858.  
  1859. --| Effects: Returns the internal hif name for a CI item.  The item  is 
  1860. --| identified by first giving the CI_id and then the item name.
  1861.  
  1862. function ci_date_time (        --| return the date and time a CI was
  1863.                 --| created.
  1864.    catalog : in SP.string_type;    --| name of the catalog
  1865.    name    : in SP.string_type;    --| name part of the CI id
  1866.    version : in SP.string_type    --| version part of the ci id
  1867.    ) return SP.string_type is
  1868.  
  1869.     begin
  1870.     return sp.create("");
  1871.     end;
  1872.  
  1873. --| Effects: Returns the date stored at the time of creation.
  1874.  
  1875.  
  1876. -- Operations to allow a privileged user to clean up the database:
  1877. -- remove_lock (*)        removes a temporary lock on a CI
  1878. -- delete (*)            delete a CI
  1879.  
  1880. procedure remove_lock (        --| remove a temporary lock that was left 
  1881.                 --| behind by an aborted process
  1882.     name : in SP.string_type;    --| name of the person owning the lock
  1883.     lock : in lock_type;    --| type of lock read or write
  1884.     node_name : in SP.string_type; --| Name of the node to be unlocked
  1885.     node : in node_type        --| type of node, CI or index
  1886.     ) is
  1887.     list : LU.list_type;
  1888.     hif_node : ND.node_type;
  1889.     begin
  1890.     -- At the moment the only thing that can be locked is the catalog
  1891.     -- itself.  The second two arguments are provided so that the 
  1892.     -- interface won't have to change later.  However, since they are
  1893.     -- meaningless right now I won't even look at them.
  1894.     if lock = write then
  1895.         Attr.get_path_attribute (current_node & "'write_lock", 
  1896.                      "userid", 
  1897.                      list);
  1898.         -- the following depends upon the fact that lists always
  1899.         -- uppercase everything
  1900.         if LU.identifier(LU.positional(list, 1)) /= 
  1901.         SP.value(SP.upper (name)) then
  1902.         -- if the userid on the lock doesn't match the user given there is
  1903.         -- no lock that can be removed
  1904.         LU.free_list (list);
  1905.             raise no_lock;
  1906.         end if;
  1907.         LU.free_list(list);
  1908.         NM.get_current_node (hif_node);
  1909.         NM.unlink (hif_node, relation => "write_lock");
  1910.     else -- it's a read lock
  1911.         NM.get_current_node (hif_node);
  1912.         NM.unlink (hif_node, 
  1913.                key => SP.value (name), 
  1914.                relation => "read_lock");
  1915.     end if;
  1916.     exception 
  1917.     when ND.name_error =>
  1918.         raise no_lock;
  1919.     end remove_lock;
  1920.     --| Raises: no_lock
  1921.  
  1922. --| Effects: Removes a lock from a node.  The lock should be one that is
  1923. --| not for a current process, but there is no way for the catalog manager
  1924. --| to check this.  However, to try and protect this operation somewhat, it
  1925. --| is a privileged operation and therefore can only be performed by someone
  1926. --| who ought to know better than to remove the lock belonging to a current
  1927. --| process.  The lock can be on either a CI or an index.  In both cases the
  1928. --| lock may be a read lock or a write lock.  With a read lock it should be
  1929. --| safe to just remove the lock.  With a write lock it may be necessary to
  1930. --| find out what was being written so that the user can tell whether it
  1931. --| was actually written or not.  The information put in with a writing 
  1932. --| operation that was aborted should probably be deleted, but that is up
  1933. --| to the discretion of the super user.
  1934.  
  1935. procedure delete (        --| delete a CI from the catalog
  1936.     CI_name : in SP.string_type;--| name of the CI to delete
  1937.     mode    : in delete_type    --| type of delete being done
  1938.     := clean_up
  1939.     ) is
  1940.  
  1941.     ci_id  : ID.ci_id_type;
  1942.     node   : ND.node_type;
  1943.     trunk  : string(1..80);
  1944.      len1   : natural;
  1945.     branch : string(1..80);
  1946.     len2   : natural;
  1947.     time   : HL.time_value;
  1948.     last   : natural;
  1949.     
  1950.     begin
  1951.     if CL.upgrade_lock (wait) then
  1952.     begin
  1953.         ci_id := ID.get_ci_id (ci_name);
  1954.         begin
  1955.             NM.open_node_handle (node, ID.get_hif_path (ci_id));
  1956.         exception when ND.name_error =>
  1957.         CL.remove_write;
  1958.         raise no_such_ci;
  1959.         end;
  1960.         if mode = clean_up then
  1961.             HU.get_node_attribute (node, "updating", trunk, len1);
  1962.             HU.get_node_attribute (node, "branching", branch, len2);
  1963.             if trunk(1..len1) /= "" or else branch(1..len2) /= "" then
  1964.             CL.remove_write;
  1965.             raise is_checked_out;
  1966.             end if;
  1967.         end if;
  1968.         HL.get_time(time);
  1969.         Attr.set_node_attribute (node, "deleted", 
  1970.         HL.get_item(HL.user_name) & "   " & HL.date(time) & " " & HL.time(time));
  1971.         NM.close_node_handle (node);
  1972.         begin
  1973.             NM.open_node_handle (node, ID.get_hif_path (ci_id) & ".CI");
  1974.             NM.delete_tree (node);
  1975.         exception when ND.name_error =>
  1976.         -- this could be fix up and the .CI relation never created.
  1977.         -- so just continue since nothing is there anyway.
  1978.         null;
  1979.         end;
  1980.         CL.remove_write;
  1981.  
  1982.       exception
  1983.         when ID.invalid_ci_id =>
  1984.         CL.remove_write;
  1985.         raise invalid_ci_id;
  1986.         when ND.status_error | ND.use_error | ND.hif_internal_error |
  1987.          ND.IO_error | ND.lock_error | ND.access_violation =>
  1988.         raise internal_hif_failure;
  1989.     end;
  1990.     else
  1991.         raise cant_lock;
  1992.     end if;
  1993.     end delete;
  1994.  
  1995.  --| Effects: Delete a CI from the catalog.  Since CI's are supposed to be
  1996. --| almost permanent this is a privileged operation.  In this way only
  1997. --| someone cleaning up the database would be allowed to delete CI's.
  1998.  
  1999. -- the following procedure is for debugging purposes since the debugger
  2000. -- goes crazy on pointers and that's what a string_type is.
  2001.  
  2002. procedure print_string (
  2003.     s : in SP.string_type
  2004.     ) is
  2005.     begin
  2006.     Text_io.put_line (SP.value(s));
  2007.     end;
  2008. procedure print_ci_id (
  2009.     i : in ID.ci_id_type
  2010.     ) is
  2011.     begin
  2012.     Text_io.put (ID.get_name (i) & ", ");
  2013.     Text_io.put (ID.get_version (i) & ", ");
  2014.     Text_io.put_line (ID.get_hif_path (i));
  2015.     end;
  2016. procedure print_list_item (
  2017.     l : in LU.list_type;
  2018.     n : in LU.positive_count
  2019.     ) is
  2020.     begin
  2021.     text_io.put_line (LU.identifier (LU.positional (l, n)));
  2022.     exception when others =>
  2023.     begin
  2024.         text_io.put_line(LU.quoted_string(LU.positional (l, n)));
  2025.     exception when others =>
  2026.         null;
  2027.     end;
  2028.     end;
  2029.  
  2030. ---- Bodies of local operations:
  2031.  
  2032. procedure check_properties (
  2033.     node : in ND.node_type;    -- node the properties are on
  2034.     stat : in out status_type    -- status of keywords
  2035.     ) is
  2036.     iter : Attr.attrib_iterator;
  2037.     attrib : string (1..80);
  2038.     last : natural;
  2039.     list : LU.list_type;
  2040.     keyword : SP.string_type;
  2041.     value : SP.string_type;
  2042.     keys : CD.string_set;
  2043.     begin
  2044.     Attr.node_attribute_iterate (iter, node, "*");
  2045.     while Attr.more (iter) loop
  2046.         Attr.get_next (iter, attrib, last, list);
  2047.         keyword := SP.create (attrib(1..last));
  2048.         if IM.is_valid_keyword (keyword) then
  2049.         value := SP.create(LU.identifier(LU.positional(list, 1)));
  2050.         pair_lists.attach (pairs, (key=>keyword, val=>value));
  2051.         CD.string_sets.insert(keys, keyword);
  2052.         else
  2053.         SL.attach(invalid, keyword);
  2054.         end if;
  2055.         LU.free_list (list);
  2056.     end loop;
  2057.     missing := IM.check_required(keys);
  2058.     if not SL.isempty (invalid) then 
  2059.         errors(keywords) := true;
  2060.         stat := error;
  2061.     end if;
  2062.     if not CD.string_sets.is_empty(missing) then
  2063.         errors(required) := true;
  2064.         stat := error;
  2065.     end if;
  2066.     CD.string_sets.destroy (keys);
  2067.     end;
  2068.  
  2069. procedure add_properties (
  2070.     name : in ID.ci_id_type    -- ci id of the ci to add the properties under
  2071.     ) is
  2072.     i : pair_lists.listiter;
  2073.     p : pair;
  2074.  
  2075. -- pairs is the list of keyword-value pairs.  It is created by check_properties
  2076. -- since that is always called before adding any properties.  the actual 
  2077. -- variable is global to the package.
  2078.     begin
  2079.     i := pair_lists.makelistiter (pairs);
  2080.      while pair_lists.more (i) loop
  2081.         pair_lists.next (i, p);
  2082.         IM.add_ci (p.key, p.val, name);
  2083.     end loop;
  2084.     pair_lists.destroy (pairs);
  2085.     end;
  2086.  
  2087. function check_list (        --| check the checked out list to make sure 
  2088.                 --| this fetch can be done.
  2089.     ci_id : in ID.ci_id_type;    --| name of the ci being fetched
  2090.     mode  : in LD.fetch_type    --| type of fetch being done
  2091.     ) return boolean is
  2092.  
  2093.     node : ND.node_type;
  2094.     attrib : string(1..80);
  2095.     last : natural;
  2096.  
  2097.     begin
  2098.     if mode = LD.no_update or    -- can always check out no update
  2099.        mode = LD.branch then    -- or branch
  2100.         return true;
  2101.     end if;
  2102.     NM.open_node_handle (node, ID.get_hif_path(ci_id));
  2103.     HU.get_node_attribute (node, "updating", attrib, last);
  2104.     NM.close_node_handle (node);
  2105.     return (attrib(1..last) = "");
  2106.     end;
  2107.  
  2108. function check_list (        --| check the checked out list to make sure 
  2109.                 --| this store can be done.
  2110.     ci_id : in ID.ci_id_type;    --| name of the ci being stored
  2111.     mode  : in LD.fetch_type;    --| type of fetch done originally
  2112.     user  : in STRING        --| name of the user to check for
  2113.     ) return boolean is
  2114.  
  2115.     node  : ND.node_type;
  2116.     attrib  : string(1..80);
  2117.     last  : natural;
  2118.     list  : LU.list_type;
  2119.     index : LU.count;
  2120.  
  2121.     begin
  2122.     if mode = LD.no_update then  -- if the mode is no_update then there
  2123.                      -- is no list to check.
  2124.         return true;
  2125.     end if;
  2126.     NM.open_node_handle (node, ID.get_hif_path(ci_id));
  2127.     if mode = LD.update then
  2128.         HU.get_node_attribute (node, "updating", attrib, last);
  2129.         NM.close_node_handle (node);
  2130.          return (attrib(1..last) = user);
  2131.     else
  2132.         Attr.get_node_attribute (node, "branching", list);
  2133.         LU.find_positional (list, LU.to_item(user), index);
  2134.         NM.close_node_handle (node);
  2135.         LU.free_list (list);
  2136.         return (index /= 0);
  2137.     end if;
  2138.     end;
  2139.  
  2140. procedure update_list (        --| Update the checked out list with this 
  2141.                 --| person's name and the type of update
  2142.     ci_id : in ID.ci_id_type;    --| name of the ci being fetched
  2143.     mode  : in LD.fetch_type    --| type of fetch being done
  2144.     ) is
  2145.     list  : LU.list_type;
  2146.     index : LU.count;
  2147.     last  : natural;
  2148.     node  : ND.node_type;
  2149.  
  2150.     begin
  2151.     if mode = LD.no_update then return; end if;
  2152.     NM.open_node_handle (node, ID.get_hif_path(ci_id));
  2153.     if mode = LD.update then
  2154.         Attr.set_node_attribute (node, 
  2155.                      "updating", 
  2156.                      HL.get_item(HL.user_name));
  2157.       else
  2158.         Attr.get_node_attribute (node, "branching", list);
  2159.         LU.add_positional (list, HL.get_item(HL.user_name));
  2160.         Attr.set_node_attribute (node, "branching", list);
  2161.         LU.free_list (list);
  2162.     end if;
  2163.         NM.close_node_handle (node);
  2164.     end;
  2165.  
  2166. procedure remove_name (        --| remove the user's name from the checked
  2167.                 --| out list when a CI is stored (or cancelled)
  2168.     ci_id : in ID.ci_id_type;    --| name of the ci being stored
  2169.     mode  : in LD.fetch_type ;    --| type of fetch done originally
  2170.     user  : in STRING        --| name of the user to check for
  2171.     ) is
  2172.     
  2173.     node  : ND.node_type;
  2174.     list  : LU.list_type;
  2175.     pos   : LU.count;
  2176.     index : natural;
  2177.     new_list : LU.list_type;
  2178.  
  2179.     begin
  2180.     NM.open_node_handle (node, ID.get_hif_path(ci_id));
  2181.     if mode = LD.update then
  2182.         Attr.set_node_attribute (node, "updating", "");
  2183.     elsif mode = LD.branch then
  2184.         Attr.get_node_attribute (node, "branching", list);
  2185.         LU.find_positional (list, LU.to_item(user), pos);
  2186.         if pos /= 0 then
  2187.             for index in 1..(pos-1) loop
  2188.             LU.add_positional (new_list, LU.positional(list, index));
  2189.             end loop;
  2190.             for index in (pos+1)..LU.num_positional(list) loop
  2191.             LU.add_positional (new_list, LU.positional(list, index));
  2192.             end loop;
  2193.         Attr.set_node_attribute (node, "branching", new_list);
  2194.         LU.free_list (list);
  2195.         LU.free_list (new_list);
  2196.         end if;
  2197.        end if;
  2198.     NM.close_node_handle (node);
  2199.     end;
  2200.  
  2201. procedure find_versions (    --| recursively find all the versions of a
  2202.                 --| ci starting at its root
  2203.     root : in ND.node_type;    --| node to start at
  2204.     name : in SP.string_type;    --| name of the ci to start with
  2205.     list : in out SL.list    --| list returned
  2206.     ) is
  2207.  
  2208.     node      : ND.node_type;
  2209.     next_node : ND.node_type;
  2210.     attrib    : string (1..50);
  2211.     iter      : NM.node_iterator;
  2212.     last      : natural;
  2213.     num       : natural;
  2214.     index     : natural;
  2215.     trunk     : natural := 0;
  2216.     temp      : SP.string_type;
  2217.     output    : SP.string_type;
  2218.  
  2219.     begin
  2220.     NM.iterate (iter, root, relation => "trunk");
  2221.     while NM.more (iter) loop
  2222.         trunk := trunk + 1;
  2223.         NM.get_next (iter, node);
  2224.         HU.get_node_attribute (node, "branches", attrib, last);
  2225. -- WORKAROUND
  2226. -- for some reason (i suspect a hif bug) last will at times come back as
  2227. -- 0 even if there is a number in attrib.  I was in the debugger and
  2228. -- attrib had a '0' as the first character (which it should have), but
  2229. -- last was 0 instead of 1!  So the workaround is to set num := 0 if
  2230. -- last = 0.  Other wise you get a constraint error.  I am also going to
  2231. -- try reseting last to 1 at the top of the loop to see if it just wasn't
  2232. -- getting the return value.  Setting last didn't help so I took it out.
  2233.         if last = 0 then
  2234.         num := 0;
  2235.         else
  2236.             num := integer'value (attrib(1..last));
  2237.         end if;
  2238. -- WORKAROUND
  2239.  
  2240.         HU.get_node_attribute (node, "deleted", attrib, last);
  2241.         temp := name & ss.image(trunk);
  2242.         output := temp;
  2243.         if last /= 0 then
  2244.             output := output & " (deleted by " & attrib(1..last) & ")";
  2245.         end if;
  2246.         SL.attach (list, output);
  2247.         if num /= 0 then  -- there are branches
  2248.         for index in 1..num loop
  2249.             NM.open_node_handle(node=>next_node, 
  2250.                     base=>node, 
  2251.                     name=>"'branch(v"&SU.image(num) & ")");
  2252.             find_versions (next_node, 
  2253.                    temp & "." & SS.image(num) & ".",
  2254.                    list);
  2255.             NM.close_node_handle (next_node);
  2256.         end loop;
  2257.         end if;
  2258.         NM.close_node_handle (node);
  2259.     end loop;
  2260.     exception
  2261.     when ND.name_error =>
  2262.         -- I don't think this is a bad error.  It would generally mean
  2263.         -- that a branches attribute got out of order.  For the moment
  2264.         -- I am going to take the attitude that if it is something really
  2265.         -- bad it will show up as a major inconsistency in the listing.
  2266.         -- If it is not bad enough for someone to notice it in the list
  2267.         -- then it doens't matter that I don't do anything here.  --cg
  2268.         -- p.s. you could add a message to the list saying "missing node"
  2269.         null;
  2270.     end;
  2271.  
  2272. function strip_v (        --| given a string of the form "v11", strip the
  2273.                 --| 'v' just leaving the number.
  2274.     ver : in string        --| input version string
  2275.     ) return string is
  2276.     last : integer;
  2277.     begin
  2278.     last := ver'last;
  2279.     return ver(2..last);
  2280.     end;
  2281.  
  2282. end catalog_manager;
  2283. ::::::::::::::
  2284. catmgr.spc
  2285. ::::::::::::::
  2286. with string_pkg;
  2287. with string_lists;
  2288. with catalog_decls;
  2289. with library_declarations;
  2290. with property_set;
  2291.  
  2292. package catalog_manager is
  2293.  
  2294. ---- Package Renames:
  2295.  
  2296. package SP renames string_pkg;
  2297. package SL renames string_lists;
  2298. package CD renames catalog_decls;
  2299. package LD renames library_declarations;
  2300. package PS renames property_set;
  2301.  
  2302. ---- Types:
  2303.  
  2304. type lock_type       is (read, write);
  2305. type node_type     is (catalog_node, CI_node, index_node);
  2306. type status_type   is (ok, error);
  2307. type delete_type   is (fix_up, clean_up);
  2308. type ci_type        is (update, branch);
  2309. type error_type    is (    dup_name,         -- the name is not unique
  2310.             non_ada,    -- the name is not and ada identifier
  2311.             non_ci_id,    -- the name is not a valid ci_id
  2312.             non_existent,    -- cannot store a ci that didn't exist
  2313.             create_mode,    -- the mode is not correct for creation
  2314.             in_mode,    -- the mode is not correct for check in
  2315.             required,     -- not all required keywords included
  2316.             person,     -- person isn't the same as checked out
  2317.             out_status,     -- cannot be checked out for update 
  2318.             purge,        -- cannot purge all files in library
  2319.             keywords,    -- there are invalid keywords included
  2320.             ready
  2321.                );
  2322. type error_array   is array (error_type) of boolean;
  2323. type message_array is array (error_type) of SP.string_type;
  2324.  
  2325. ---- Exceptions:
  2326.  
  2327. invalid_password : exception;    -- raised when set_password is given an invalid
  2328.                 -- one
  2329. cant_lock     : exception;    -- raised when a lock cant be placed due to 
  2330.                 -- another person having a lock
  2331. no_lock         : exception;    -- raised when you try to remove a lock that
  2332.                 -- doesn't exist
  2333. library_locked   : exception;    -- raised when the library to be copied is
  2334.                 -- already locked
  2335. no_such_ci     : exception;    -- raised when the ci named doesn't exist
  2336. no_such_catalog  : exception;    -- raised when the catalog doesn't exist
  2337. no_such_component: exception;    -- raised when the component is not in the CI
  2338. already_fetched     : exception;    -- raised when trying to fetch for update a ci
  2339.                 -- which has already been fetched for update
  2340.                 -- by someone.  Doesn't apply to branches 
  2341.                 -- because there can be any number of branches
  2342. already_updated  : exception;    -- raised when a CI already has an update on
  2343.                 -- the trunk.  At that point the only changes 
  2344.                 -- that can be made are on a branch
  2345. invalid_ci_id     : exception;    -- raised when a parameter to be used as a
  2346.                 -- ci id is not in the correct format
  2347. invalid_ci_name     : exception;    -- raised when the name given to list_versions
  2348.                 -- is not an ada id
  2349. incorrect_person : exception;    -- raised when the wrong person tries to check
  2350.                 -- a ci back into the catalog (or tries to
  2351.                 -- do a cancel)
  2352. is_checked_out   : exception;    -- raised when someone tries to delete a ci 
  2353.                 -- that is checked out
  2354. deleted_ci     : exception;    -- raised when someone tries to fetch a ci that
  2355.                 -- has been deleted
  2356. incomplete_store : exception;    -- raised when the node for the ci exists but
  2357.                 -- the nodes of the ci are not there during
  2358.                 -- a fetch.  check_consistency should also
  2359.                 -- find these cases.
  2360. invalid_key_or_val : exception;    -- raised when name error is raised and it
  2361.                 -- could either be and invalid keyword or
  2362.                 -- value
  2363. required_keyword : exception;    -- raised when a person tries to delete a 
  2364.                 -- required keyword in modify_property
  2365. ci_not_fetched   : exception;    -- raised when invalid ci id is raised
  2366.                 -- in a cancel
  2367. invalid_mode     : exception;    -- raised when a cancel is done and the
  2368.                 -- mode is not recognised
  2369. update_already_exists : exception;    -- raised when a store is being done
  2370.                     -- and a node exists with that
  2371.                     -- version number that is not deleted.
  2372.                     -- this should probably be a very fatal
  2373.                     -- error since as far as I know it is
  2374.                     -- not possible to do this
  2375. internal_hif_failure : exception;    -- raised if any unexpected hif errors
  2376.                     -- like use error are raised.
  2377. internal_name_error : exception;    -- raised when an unexpected name_error
  2378.                     -- is caught.
  2379. invalid_library : exception;        -- raised when you get invalid library
  2380.                     -- name or one of the required info
  2381.                     -- attributes are not on the library.
  2382. library_nonexistent : exception;    -- raised when the library is not found
  2383.  
  2384.  
  2385. ---- Items global to the package catalog_manager:
  2386.  
  2387. empty_list   : SL.list := SL.create;
  2388. errors          : error_array := (others => false);
  2389. messages     : message_array := (
  2390.     SP.create ("The given name is already being used in the catalog"),
  2391.     SP.create ("The given name is not a valid id, give an ada identifier"),
  2392.     SP.create ("The id on the library is not a valid CI id, use create_ci"),
  2393.     SP.create ("You cannot store an update to a CI that doesn't exist"),
  2394.     SP.create ("Cannot use Create_CI to return a CI fetched for update"),
  2395.     SP.create ("Cannot store a library that was not created for update"),
  2396.     SP.create ("The following required keywords are missing: "),
  2397.     SP.create ("The owner of this library is not in the check out list"),
  2398.     SP.create ("This ci is already fetched for update by "),
  2399.     SP.create ("Cannot purge all files in the library -- Create_CI not " &
  2400.                             "complete"),
  2401.     SP.create ("The following keywords are invalid: "),
  2402.     SP.create ("Cannot create/store since a library item is still fetched"));
  2403.  
  2404. missing      : CD.string_set;        -- the set of missing required keywords
  2405. invalid      : SL.list := empty_list;    -- the list of invalid keywords
  2406. fetchee         : SP.string_type;        -- the person with a CI already fetched
  2407.  
  2408. ---- Operations global to the package catalog_manager:
  2409.  
  2410. -- Operations on the catalog:
  2411. -- list_cis            list all the CI's in the cpcicat
  2412. -- verify_password         verify the password given is the correct one
  2413. -- set_password            set a new password
  2414.  
  2415. function list_cis (        --| list the contents of the catalog
  2416.     CIs : in SP.string_type      --| name to match
  2417.     := SP.create("*")
  2418.     ) return SL.list;
  2419.  
  2420. --| Effects: List the identifiers of CIs which match the pattern given.
  2421. --| The default is "*" which matches all identifiers in the catalog.
  2422. --| No versions are returned just identifiers.
  2423.  
  2424. function verify_password (    --| verify the privilege operations password
  2425.     p : in  SP.string_type    --| word to check
  2426.     ) return boolean;
  2427.  
  2428. --| Effects: Checks that the string given is the password for the catalog.
  2429. --| If it is the password true if returned, false otherwise.
  2430.  
  2431. procedure set_password (    --| set a new password
  2432.     next : in SP.string_type;    --| new password
  2433.     old  : in SP.string_type    --| old password for verification
  2434.     );
  2435.     --| raises: invalid_password
  2436.  
  2437. --| Effects: Sets the password to be the new one if the word given as the
  2438. --| old one is the correct password in actuality.  Raises invalid password
  2439. --| if not.  If this is really invoked by the catalog interface invalid
  2440. --| password should never be raised.
  2441.  
  2442. -- Operations on a configuration item:
  2443. -- create_CI            create a new configuration item from a library
  2444. -- store            update a configuration item from an itemlib
  2445. -- cancel            cancel a fetch for update
  2446. -- fetch            fetch an itemlib from the catalog
  2447. -- delete (*)            delete a CI
  2448. -- modify_property        change the value associated with a property
  2449. -- get_property            list all the keywords and values for a CI, and
  2450. --                 other information like creator as asked for.
  2451. -- history            history of a CI
  2452. -- list_versions        list the versions of a ci given a name
  2453. -- list_components        list the components of a CI
  2454. -- match_keys            match a list of keywords with the ones on a CI
  2455.  
  2456. function  create_CI (        --| create a new CI in the catalog
  2457.     name    : in SP.string_type;--| name of the new CI
  2458.     library : in SP.string_type;--| name of the library to find the CI in
  2459.     history : in SP.string_type --| description of the CI
  2460.     ) return status_type;
  2461.     --| Raises: name_in_use
  2462.  
  2463. --| Effects: Creates a new CI in the catalog under the given name.  The name
  2464. --| is checked to make sure it doesn't conflict with a name already in the 
  2465. --| catalog.  Properties on the item library will be used as the properties for
  2466. --| this CI, and at this point they will be checked for vcalidity and that
  2467. --| all the required ones are included.  Errors will be reported as found and
  2468. --| if there are any errors are found the create will not take place although
  2469. --| it will continue to report as many errors as can be found at that point.
  2470. --| The history ought to be a description of the purposes of this CI.  It is
  2471. --| not necessarily a description of the creation history of this CI, but more
  2472. --| a description of its uses.  The library being checked in is checked that
  2473. --| it is not on another CI's list as being fetched as a branch or a trunk.
  2474. --| If it is, the user will get a message to  cancel the fetch before creating
  2475. --| the new CI.  
  2476.  
  2477. function store (        --| store a CI in the catalog from an 
  2478.                 --| item library
  2479.     library : in SP.string_type;    --| itemlibrary name to get the CI from
  2480.     history : in SP.string_type        --| description of the CI
  2481.     ) return status_type;
  2482.  
  2483. --| Effects: Stores the contents of the item_library in the catalog under the
  2484. --| Ci named by the name given.  The Version number is given by the catalog
  2485. --| depending upon whether the CI was checked out to branch from the trunk
  2486. --| or update the trunk.  When storing a CI the catalog checks that the
  2487. --| person doing the store did indeed fetch it for modification, if they didn't
  2488. --| an error is raised and the store does not take place.  The keywords and
  2489. --| values applied to the new CI will be those that are on the item library
  2490. --| at the time of the store.  The predefined keywords person and date_in
  2491. --| will be given the appropriate values by the catalog, person being the
  2492. --| userid of the person doing the store and date_in being the current date
  2493. --| and time.
  2494. --| If the CI does not have all the required keywords on the itemlibrary 
  2495. --| error messages will be reported and the store will not take place.
  2496. --| The history parameter is a field containing a description of the changes
  2497. --| made to the CI.  The description should be on a global scale rather than
  2498. --| a file by file description of the changes.  The file by file histories
  2499. --| will be handled by the item libraries.
  2500. --| In the case where there are any errors the errors will be reported and
  2501. --| the store will not take place.  However, the procedure will not stop at
  2502. --| the first error, but will continue and try to find as many errors as
  2503. --| possible.  It would have to stop in the case of a really fatal error.
  2504.  
  2505. procedure cancel (        --| cancel a fetch for update
  2506.     library : in SP.string_type;--| name of the library where the CI is checked
  2507.                 --| out
  2508.     user    : in SP.string_type --| user that checked out the CI
  2509.     );
  2510.  
  2511. --| Effects: Takes the person's name from the checked out list leaving the 
  2512. --| item library where it is.  The person cannot check that library in as
  2513. --| an update to anything.  Also if a person tries to create a new CI with 
  2514. --| an item library that was fetched as a branch or trunk they will get an 
  2515. --| error message that the should cancel the fetch first if they are still
  2516. --| on the list as having it checked out.  If they are not on any lists
  2517. --| there would not be any problem.
  2518.  
  2519. procedure fetch (        --| Fetches the specified configuration item
  2520.                 --| and places it in the given item_library
  2521.     CI_name : in SP.string_type;--| name of the CI to fetch
  2522.     library : in SP.string_type;--| name of the item_library to put the CI in
  2523.     dir        : in SP.string_type;--| where to put the item_library
  2524.     mode    : in LD.fetch_type    --| whether the fetch is for updating or not
  2525.     := LD.no_update
  2526.     );
  2527.  
  2528. --| Effects: Makes a copy of the specified CI in the given item library.
  2529. --| If the mode is branch or trunk the user may modify the files in the
  2530. --| item library and store them back in the catalog as a new version of
  2531. --| the CI.  Trunk and branch indicate updating the CI along different
  2532. --| paths.  The trunk is the main path along which updates take place,
  2533. --| a branch is an update which begins another path.  Only one person
  2534. --| can update the trunk at any time, but there can be any number of
  2535. --| branches.  If the CI_name is just the identifier part with out a version
  2536. --| number, it is assumed that a trunk update would just be a fetch of the
  2537. --| most recent version along the main trunk.    A branch would be a branch
  2538. --| from the same CI.  Once a branch is started however, it begins another
  2539. --| minor trunk, from which the user can also update along the trunk or
  2540. --| branch.  To specify a fetch of one of these CIs the CI_name needs to 
  2541. --| include a version number.  It is an error to try and fetch as a trunk
  2542. --| a CI which is not the most recent CI along the trunk.  If the mode
  2543. --| is not update, trying to store the CI in the catalog later will
  2544. --| result in an error.  The only user who can store a CI is the user who
  2545. --| fetched it from the catalog in the first place.
  2546.  
  2547.  
  2548. procedure modify_property (    --| modify the value associated with a property
  2549.                 --| for a given CI
  2550.     CI_name : in SP.string_type;--| the name of the CI to change
  2551.     keyword : in SP.string_type;--| the name of the keyword to modify
  2552.     value   : in SP.string_type    --| the new value to give the keyword
  2553.     );
  2554.  
  2555. --| Effects: Modifies the value associated with a particular keyword on
  2556. --| the specified CI.  If the keyword is not already a keyword on that CI
  2557. --| it will be added with the given value.  If it does already exist on that
  2558. --| CI the value will be changed.  If, however, the value is the empty
  2559. --| string the keyword will be removed from that CI.
  2560.  
  2561. function get_property (        --| get the value associated with a particular
  2562.                 --| property for a given CI
  2563.     CI_name : in SP.string_type;--| name of the CI to give the info about
  2564.     keyword : in SP.string_type    --| name of the keyword for the property
  2565.     ) return SP.string_type;
  2566.  
  2567. --| Effects: Returns the value associated with the keyword  for that CI.
  2568. --| The keyword may not contain any wild cards.  It recognises both
  2569. --| user defined keywords and the predefined ones, creator, date.
  2570.  
  2571. function history (        --| return the history of a particular CI
  2572.     CI_name : in SP.string_type --| name of the CI
  2573.     ) return CD.hist_list;
  2574.  
  2575. --| Effects: returns a list which is the history of the given CI.  Each
  2576. --| element of the list is the creator, date and description of the changes
  2577. --| given for a predecessor of the named CI.
  2578.  
  2579. function list_versions (    --| return a list of the different versions of
  2580.                 --| a ci given an incomplete ci_id
  2581.    ci_name : in SP.string_type    --| incomplete ci_id
  2582.    ) return SL.list;
  2583.  
  2584. --| Effects:  Returns a list of the versions of a CI given a name.
  2585. --| If the list is of trunk updates then the ci_id should be incomplete and
  2586. --| the program will show all trunk updates on that branch.  If a list
  2587. --| of branches is what is needed then the ci_id should be complete and
  2588. --| a list of the branches from that ci will be shown.
  2589.  
  2590. function list_components (    --| list the components of a given CI
  2591.     CI_name : in SP.string_type --| name of the CI
  2592.     ) return LD.LL.list;
  2593.  
  2594. --| Effects: Returns a list that is all the components of the given CI.
  2595.  
  2596. function match_keys (        --| match keywords in a list to the 
  2597.                 --| keywords on a CI and return the list
  2598.     CI_name : in SP.string_type;--| name of the CI
  2599.     key_list : in SL.list    --| keywords list 
  2600.     ) return PS.set;
  2601.  
  2602. --| Effects: Reads each of the elements of the list (which could have
  2603. --| wild cards) and matches them to all the properties on the given
  2604. --| CI.  Returns the set of matched properties which includes the value
  2605. --| as well as the keyword.
  2606.  
  2607. -- Operations for libuser's use
  2608. -- get_hif_file_name        returns a hif file name for the given CI
  2609.  
  2610. function get_hif_file_name (     --| return the hif file name for a CI item
  2611.    catalog : in SP.string_type;    --| name of the catalog
  2612.    CI_name : in SP.string_type;    --| name of the CI
  2613.    item    : in SP.string_type  --| name of the item in the CI
  2614.    ) return SP.string_type;
  2615.  
  2616. --| Effects: Returns the internal hif name for a CI item.  The item  is 
  2617. --| identified by first giving the CI_id and then the item name.
  2618.  
  2619. function ci_date_time (        --| return the date and time a CI was
  2620.                 --| created.
  2621.    catalog : in SP.string_type;    --| name of the catalog
  2622.    name    : in SP.string_type;    --| name part of the CI id
  2623.    version : in SP.string_type    --| version part of the ci id
  2624.    ) return SP.string_type;
  2625.  
  2626. --| Effects: Returns the date stored at the time of creation.
  2627.  
  2628. -- Operations to allow a privileged user to clean up the database:
  2629. -- remove_lock (*)        removes a temporary lock on a CI
  2630. -- delete (*)            delete a CI
  2631.  
  2632. procedure remove_lock (        --| remove a temporary lock that was left 
  2633.                 --| behind by an aborted process
  2634.     name : in SP.string_type;    --| name of the thing to be unlocked
  2635.     lock : in lock_type;    --| type of lock read or write
  2636.     node_name : in SP.string_type; --| Name of the node to be unlocked
  2637.     node : in node_type        --| type of node, CI or index
  2638.     );
  2639.     --| Raises: no_lock
  2640.  
  2641. --| Effects: Removes a lock from a node.  The lock should be one that is
  2642. --| not for a current process, but there is no way for the catalog manager
  2643. --| to check this.  However, to try and protect this operation somewhat, it
  2644. --| is a privileged operation and therefore can only be performed by someone
  2645. --| who ought to know better than to remove the lock belonging to a current
  2646. --| process.  The lock can be on either a CI or an index.  In both cases the
  2647. --| lock may be a read lock or a write lock.  With a read lock it should be
  2648. --| safe to just remove the lock.  With a write lock it may be necessary to
  2649. --| find out what was being written so that the user can tell whether it
  2650. --| was actually written or not.  The information put in with a writing 
  2651. --| operation that was aborted should probably be deleted, but that is up
  2652. --| to the discretion of the super user.
  2653.  
  2654. procedure delete (        --| delete a CI from the catalog
  2655.     CI_name : in SP.string_type;--| name of the CI to delete
  2656.     mode    : in delete_type    --| type of delete being done
  2657.     := clean_up
  2658.     );
  2659.  
  2660. --| Effects: Delete a CI from the catalog.  Since CI's are supposed to be
  2661. --| almost permanent this is a privileged operation.  In this way only
  2662. --| someone cleaning up the database would be allowed to delete CI's.
  2663.  
  2664.  
  2665. end catalog_manager;
  2666. ::::::::::::::
  2667. chconsist.ada
  2668. ::::::::::::::
  2669.  
  2670. --------- SPEC ----------------------------------------------------------
  2671.  
  2672. function check_consistency return INTEGER;
  2673.  
  2674. --------- BODY ----------------------------------------------------------
  2675.  
  2676. with Standard_Interface;
  2677. with Tool_Identifier;
  2678. with String_Pkg;
  2679. with Host_Lib;
  2680. with paginated_output;
  2681. with catalog_interface;
  2682.  
  2683. function check_consistency return INTEGER is
  2684.  
  2685.     package SP renames String_Pkg;
  2686.     package CI renames catalog_interface;
  2687.     package SI renames Standard_Interface;
  2688.  
  2689.     package input is new SI.String_Argument(        -- instantiate with
  2690.     String_Type_Name => "string");            -- subtype string
  2691.  
  2692.  
  2693.     process      : SI.Process_Handle;    -- handle to process structure
  2694.     catalog     : SP.string_type;    -- name of the catalog
  2695.     output     : SP.string_type;    -- name of the output file
  2696.  
  2697. begin
  2698.  
  2699.     SI.set_tool_identifier (Tool_Identifier);
  2700.     SI.Define_Process(            -- define this process
  2701.     Name    => "check_consistency",    -- name of the process
  2702.     Help    => "Check the consistency of the information in a catalog",
  2703.     Proc    => process);        -- handle to be returned
  2704.  
  2705.     Input.Define_Argument(    -- define the first argument
  2706.     Proc => Process,        -- process 
  2707.     Name => "catalog_name",        -- name of the argument
  2708.     Help => "Name of the catalog to be checked");
  2709.  
  2710.     Input.Define_Argument(    -- define the second argument
  2711.     Proc => Process,        -- process 
  2712.     Name => "output_file",        -- name of the argument
  2713.     Help => "Name of the output file for the consistency report");
  2714.  
  2715.     SI.define_help (process,
  2716.     "Produces a report of the consistency of a given catalog");
  2717.     SI.append_help (process,
  2718.     "The checks include: ");
  2719.     SI.append_help (process,
  2720.     "Checking that the information on a CI matches the information in");
  2721.     SI.append_help (process,
  2722.     "        the index.");
  2723.     SI.append_help (process,
  2724.     "Checking that CIs are complete.");
  2725.     SI.append_help (process,
  2726.     "Checking that all the locks are current.");
  2727.     SI.append_help (process,
  2728.     "Checking that there is only one password");
  2729.     SI.append_help (process,
  2730.     "The user must be a document manager system user to use this tool");
  2731.     SI.append_help (process,
  2732.     "(see Add_User). ");
  2733.  
  2734.     SI.Parse_Line(Process);        -- parse the command line
  2735.  
  2736.     catalog := Input.Get_Argument(    -- get the first argument
  2737.             Proc => Process,
  2738.             Name => "catalog_name");
  2739.  
  2740.     output := Input.Get_Argument(    -- get the second argument
  2741.             Proc => Process,
  2742.             Name => "output_file");
  2743.  
  2744.     SI.Define_Output(                -- define paginated output
  2745.     Proc      => process,            -- process
  2746.     File_Name => SP.Value(Output));        -- file name 
  2747.  
  2748.     CI.check_consistency (catalog, output);
  2749.  
  2750.     SI.Undefine_Process(Proc => Process);    -- destroy the process block
  2751.  
  2752.     return Host_Lib.Return_Code(Host_Lib.SUCCESS);-- return successful return code
  2753.  
  2754. exception
  2755.  
  2756.     when SI.Process_Help =>
  2757.     --
  2758.     -- Help message was printed
  2759.     --
  2760.     return Host_Lib.Return_Code(Host_Lib.INFORMATION);
  2761.  
  2762.     when SI.Abort_Process =>
  2763.     --
  2764.     -- Parse error
  2765.     --
  2766.     return Host_Lib.Return_Code(Host_Lib.ERROR);
  2767.  
  2768.     when Paginated_Output.File_Already_Open =>
  2769.     --
  2770.     -- Process output file error
  2771.     --
  2772.     return Host_Lib.Return_Code(Host_Lib.ERROR);
  2773.  
  2774.     when Paginated_Output.File_Error =>
  2775.     --
  2776.     -- Process output file error
  2777.     --
  2778.     return Host_Lib.Return_Code(Host_Lib.ERROR);
  2779.  
  2780. end check_consistency;
  2781. ::::::::::::::
  2782. ciid.bdy
  2783. ::::::::::::::
  2784. with string_utilities;
  2785.  
  2786. package body ci_ids is
  2787.  
  2788. --| Overview
  2789. --|
  2790. --| A ci_id is an idenitfier that uniquely identifies a configuration item (CI)
  2791. --| It has two parts: a name which is an Ada identifier and a version number.
  2792. --| The syntax for a ci_id follows:
  2793. --| -
  2794. --| ci_id     ::= name version
  2795. --| name      ::= letter [[underline] letter_or_digit]
  2796. --| letter_or_digit ::= letter | digit
  2797. --| version     ::= [number . number .] number
  2798. --| number     ::= digit [digit]
  2799. --| +
  2800. --| The name of a ci_id will identify all CIs which are versions derived from
  2801. --| a single parent.  The version uniquely identifies which version among
  2802. --| those is being referred to.
  2803.  
  2804. ---- package renames and uses:
  2805.  
  2806. package SU renames string_utilities;
  2807. use SP;                    -- for "&" infix notation
  2808.  
  2809. ---- Package instantiations:
  2810. package SS is new SU.generic_string_utilities(SP.string_type, 
  2811.                           SP.make_persistent,
  2812.                           SP.value);
  2813.  
  2814. ---- Local type declarations:
  2815.  
  2816. type compare_type is (less, same, more);
  2817.  
  2818. ---- Local subprogram declarations:
  2819.  
  2820.  
  2821. function compare (        --| Compare two version lists
  2822.     v1 : in v_list;        --| first list
  2823.     v2 : in v_list        --| second version list
  2824.     ) return compare_type;
  2825.  
  2826. --| Effects: compares two version lists.  If the first is less than the
  2827. --| second it returns LESS, if they are equal it returns SAME, 
  2828. --| and if it is greater compare returns MORE.
  2829.  
  2830. function parse_dotted_num (    --| parse the version number from an input
  2831.                 --| string
  2832.     s : in SU.scanner        --| input string
  2833.     ) return v_list;
  2834.  
  2835. --| Effects: Parses the remainder of the string (after the identifier is
  2836. --| stripped off) for a valid version number.  It is a dotted number which
  2837. --| should have and odd number of components.
  2838.  
  2839. function make_hif_path (    --| create a hif path from the ci name and
  2840.                 --| the ci version
  2841.     name    : in SP.string_type;    
  2842.     version : in v_list
  2843.     ) return SP.string_type;
  2844.  
  2845. --| Effects: Creates a hif path for the node refered to by this ci_id.
  2846. --| The path is relative to the root node of the catalog.  So this
  2847. --| path will only work when the current node is set to be the current
  2848. --| catalog node.
  2849.  
  2850. ---- Global Operations:
  2851.  
  2852.     function get_ci_id (    --| returns a ci_id from a string in the right
  2853.                 --| format
  2854.     s : in string        --| string to parse for a ci_id
  2855.         ) return ci_id_type is
  2856.     --| Raises: invalid_ci_id
  2857.  
  2858.     --| Effects: Reads in a string and parses it into a ci_id_type.  All 
  2859.     --| characters
  2860.     --| up to a space are considered the name.  Characters following the space
  2861.     --| will be interpreted as the version.  If the string 
  2862.     --| cannot be interpreted in this way the exception invalid_ci_id is 
  2863.     --| raised.  Numbers before the space will be a part of the name string.
  2864.     --| For this reason there must be a space between the name part and the
  2865.     --| version.
  2866.     scan  : SU.scanner;
  2867.     ci_id : ci_id_type;
  2868.     found : boolean;
  2869.     skip  : boolean := true;
  2870.  
  2871.     begin
  2872.         ci_id.quoted := SP.make_persistent (s);
  2873.         -- save a copy of the id as input for writing out
  2874.  
  2875.         scan := SS.make_scanner (ci_id.quoted);
  2876.         SS.scan_ada_id (scan, found, ci_id.name, skip);
  2877.         -- scan the string for an ada identifier which is the ci name
  2878.          -- if there isn't an identifier raise invalid_ci_id
  2879.         if not found then
  2880.         raise invalid_ci_id;
  2881.         end if;
  2882.         ci_id.name := SP.make_persistent (SP.upper (ci_id.name));
  2883.         -- the name has to be upper for testing of equality
  2884.  
  2885.         ci_id.version := parse_dotted_num (scan);
  2886.         -- parse_dotted_num raises invalid_ci_id if the version is not
  2887.         -- in the right format.
  2888.  
  2889.         ci_id.hif_path := make_hif_path (ci_id.name, ci_id.version);
  2890.         return ci_id;
  2891.     end get_ci_id;
  2892.  
  2893.     function get_ci_id (    --| returns a ci_id from a string in the right
  2894.                 --| format
  2895.     s : in SP.string_type    --| string to parse for a ci_id
  2896.         ) return ci_id_type is
  2897.     --| Raises: invalid_ci_id
  2898.  
  2899.     scan  : SU.scanner;
  2900.     ci_id : ci_id_type;
  2901.     found : boolean;
  2902.     skip  : boolean := true;
  2903.  
  2904.     begin
  2905.         -- Every thing is basically the same as above, only I don't
  2906.         -- need to make the input a string type before starting because
  2907.         -- it already is one.  
  2908.         ci_id.quoted := SP.make_persistent (s);
  2909.         scan := SS.make_scanner (ci_id.quoted);
  2910.         SS.scan_ada_id (scan, found, ci_id.name, skip);
  2911.         if not found then
  2912.         raise invalid_ci_id;
  2913.         end if;
  2914.         ci_id.name := SP.make_persistent (SP.upper (ci_id.name));
  2915.         ci_id.version := parse_dotted_num (scan);
  2916.         -- parse_dotted_num raises invalid_ci_id if the version is not
  2917.         -- in the right format.
  2918.         ci_id.hif_path := make_hif_path (ci_id.name, ci_id.version);
  2919.         return ci_id;
  2920.     end get_ci_id;
  2921.  
  2922.     function  image (        --| returns a string representation
  2923.                 --| of a ci_id_type
  2924.     n : in ci_id_type    --| ci_id_type to translate
  2925.     ) return string is
  2926.  
  2927.     --| Effects: Takes a ci_id_type and translates it into a string
  2928.     --| in the ci_id format.
  2929.     begin
  2930.         return SP.value (n.quoted);
  2931.     end image;
  2932.  
  2933.     function  image (        --| returns a string representation
  2934.                 --| of a ci_id_type
  2935.     n : in ci_id_type    --| ci_id_type to translate
  2936.     ) return SP.string_type is
  2937.  
  2938.     --| Effects: Takes a ci_id_type and translates it into a string
  2939.     --| in the ci_id format.
  2940.     begin
  2941.         return n.quoted;
  2942.     end image;
  2943.  
  2944.     function get_name (        --| returns the string which is the name
  2945.                 --| part of a ci_id_type
  2946.       n : in ci_id_type
  2947.     ) return string is
  2948.  
  2949.     --| Effects: Takes a ci_id_type and returns the name part as a string.
  2950.     begin
  2951.         return SP.value (n.name);
  2952.     end get_name;
  2953.  
  2954.     function get_name (        --| returns the string which is the name
  2955.                 --| part of a ci_id_type
  2956.       n : in ci_id_type
  2957.     ) return SP.string_type is
  2958.  
  2959.     --| Effects: Takes a ci_id_type and returns the name part as a string_type.
  2960.     begin
  2961.         return n.name;
  2962.     end get_name;
  2963.  
  2964.     function get_version(    --| returns the string which is the version
  2965.                 --| part of a ci_id_type
  2966.       n : in ci_id_type
  2967.     ) return string is
  2968.  
  2969.     --| Effects: Takes a ci_id_type and returns the version number as a string.
  2970.  
  2971.     i : VL.listiter := VL.makelistiter (n.version);
  2972.     s : SP.string_type;
  2973.     num : integer;
  2974.  
  2975.     begin
  2976.         -- There always has to be at least one component in the
  2977.         -- version list, so start the string with that one and loop
  2978.         -- for the rest.
  2979.         -- don't worry about there being an odd number of components in
  2980.         -- the id because that would have been checked when it was made
  2981.         -- a ci id type
  2982.         SP.mark;
  2983.         VL.next (i, num);
  2984.         s := SS.image (num);
  2985.         loop
  2986.         exit when not VL.more (i);
  2987.         VL.next (i, num);
  2988.         s := s & "." & SS.image(num);
  2989.         end loop;
  2990.         declare
  2991.         new_s : string (1..SP.length(s));
  2992.         begin
  2993.         new_s := SP.value (s);
  2994.         SP.release;
  2995.         return new_s;
  2996.         end;
  2997.     end get_version;
  2998.  
  2999.     function get_version(    --| returns the string which is the version
  3000.                 --| part of a ci_id_type
  3001.       n : in ci_id_type
  3002.     ) return SP.string_type is
  3003.  
  3004.     --| Effects: Takes a ci_id_type and returns the version number as a 
  3005.     --| string_type.
  3006.  
  3007.     i : VL.listiter := VL.makelistiter (n.version);
  3008.     s : SP.string_type;
  3009.     s1 : SP.string_type;
  3010.     num : integer;
  3011.  
  3012.     begin
  3013.         -- There always has to be at least one component in the
  3014.         -- version list, so start the string with that one and loop
  3015.         -- for the rest.
  3016.         SP.mark;
  3017.         VL.next (i, num);
  3018.         s := SS.image (num);
  3019.         while VL.more (i) loop
  3020.         VL.next (i, num);
  3021.         s := s & "." & SS.image(num);
  3022.         end loop;
  3023.         s := SP.make_persistent(s);
  3024.         SP.release;
  3025.         -- I don't want to return a persistent string because it will
  3026.         -- probably never be flushed, so I create a new string (after the
  3027.         -- release for this procedure) that is the same as the other
  3028.         -- and explicitly flush the first string.  The second 
  3029.         -- non-persistent string is returned.
  3030.         s1 := SP.create (SP.value (s));
  3031.         SP.flush (s);
  3032.         return s1;
  3033.     end get_version;
  3034.  
  3035.     function get_version(    --| returns the string which is the version
  3036.                 --| part of a ci_id_type
  3037.       n : in ci_id_type
  3038.     ) return VL.list is
  3039.  
  3040.      begin
  3041.     return n.version;
  3042.      end get_version;
  3043.  
  3044.     --| Effects: Takes a ci_id_type and returns the version number as a list.
  3045.  
  3046.     function get_hif_path (    --| returns a string which is a valid hif
  3047.                 --| path string for this ci.
  3048.         n : in ci_id_type
  3049.     ) return string is
  3050.  
  3051.     --| Effects: Takes a ci_id_type and returns the hif path for the node
  3052.     --| which corresponds to the hif node for this ci.
  3053.     begin
  3054.         return SP.value (n.hif_path);
  3055.     end get_hif_path;
  3056.  
  3057.     function get_hif_path (    --| returns a string which is a valid hif
  3058.                 --| path string for this ci.
  3059.         n : in ci_id_type
  3060.     ) return SP.string_type is
  3061.  
  3062.     --| Effects: Takes a ci_id_type and returns the hif path for the node
  3063.     --| which corresponds to the hif node for this ci.
  3064.     begin
  3065.         return n.hif_path;
  3066.     end get_hif_path;
  3067.  
  3068.     function increment_ci_id (    --| returns a ci_id that is one more than
  3069.                 --| the given ci_id assuming no branching.
  3070.     id : in ci_id_type    --| ci_id to increment
  3071.     ) return ci_id_type is
  3072.  
  3073.     --| Effects:  Increments the version of the ci_id.  So for example,
  3074.     --| if the ci_id was "abs 1.1.1" the new one would be "abs 1.1.2".
  3075.     --| It always just increments the last number in the tuple.
  3076.     ver   : SP.string_type;
  3077.     start : positive := 1;
  3078.     index : natural;
  3079.     len   : natural;
  3080.     last  : natural;
  3081.     begin
  3082.     ver := get_version (id);
  3083.     if SP.match_c (ver, '.', start) /= 0 then
  3084.         loop
  3085.         index := match_c (ver, '.', start);
  3086.         exit when index = 0;
  3087.         start := index + 1;
  3088.         end loop;
  3089.         -- start is now at the character past the last '.'
  3090.         len := SP.length(ver);
  3091.         last := SU.value (SP.value(SP.substr (ver, 
  3092.                               start, 
  3093.                               (len-start)+1))) + 1;
  3094.         return (get_ci_id(string'(get_name (id)) & " "
  3095.                         & SP.value (SP.substr(ver,
  3096.                               1,
  3097.                                len-(len-(start-1))))
  3098.                         & SU.image(last)));
  3099.     else
  3100.         return (get_ci_id (string'(get_name(id)) & " " 
  3101.                        & SU.image((SU.value(SP.value(ver)))
  3102.                               + 1)));
  3103.     end if;
  3104.     end;
  3105.  
  3106.     function equal (        --| returns true if the two ci_id_types
  3107.                 --| are equal
  3108.     n1 : in ci_id_type;
  3109.     n2 : in ci_id_type
  3110.         ) return boolean is
  3111.  
  3112.     --| Effects: compares the names and versions of each ci_id_type and
  3113.     --| returns true if both parts are the same.
  3114.     begin
  3115.         return (SP.equal (n1.name, n2.name) and 
  3116.                 (compare (n1.version, n2.version) = same));
  3117.     end equal;
  3118.  
  3119.     function similar (        --| returns true if the name part of
  3120.                 --| the ci_id_types are the same.  The versions
  3121.                 --| may be different
  3122.     n1 : in ci_id_type;
  3123.     n2 : in ci_id_type
  3124.          ) return boolean is
  3125.  
  3126.     --| Effects: Compares the names of each ci_id_type and returns true
  3127.     --| if they are the same.  In this way you can find out if two ci_id_types
  3128.     --| refer to different versions of the same CI.
  3129.     begin
  3130.         return SP.equal (n1.name, n2.name);
  3131.     end similar;
  3132.  
  3133.     function "<" (        --| returns true if name1 is less than name2
  3134.     n1 : in ci_id_type;
  3135.     n2 : in ci_id_type
  3136.         ) return boolean is
  3137.  
  3138.     --| Effects: compares the two ci_id_types given and returns true if name1
  3139.     --| is less than name2.  The name part is compared lexicographically,
  3140.     --| and the version number is compared in the following manner:
  3141.     --| compare each integer component of the versions in turn, the first
  3142.     --| version to have a number less than the other in the same component
  3143.     --| of the versions is the lower number.  A null component is less than
  3144.     --| anything. For example:
  3145.     --| 1 < 1.1.1 < 1.1.4 < 1.2.1 < 2.1.1 < 2.1.6 < 2.4.1 
  3146.     begin
  3147.         if not SP.equal (n1.name, n2.name) then
  3148.         return SP."<"(n1.name, n2.name);
  3149.         else
  3150.         return (compare (n1.version, n2.version) = less);
  3151.         end if;
  3152.     end "<";
  3153.  
  3154.     function ">" (        --| returns true if name1 is greater than name2
  3155.     n1 : in ci_id_type;
  3156.     n2 : in ci_id_type
  3157.         ) return boolean is
  3158.  
  3159.     --| Effects: Compares two ci_id_types and returns true if the first one is 
  3160.     --| greater than the second. The rules for comparison are discussed above.
  3161.     begin 
  3162.         if not SP.equal (n1.name, n2.name) then
  3163.         return not SP."<="(n1.name, n2.name);
  3164.         else
  3165.         return (compare (n1.version, n2.version) = more);
  3166.         end if;
  3167.     end ">";
  3168.  
  3169.     function "<=" (        --| returns true if name1 is less than or 
  3170.                 --| equal to name2
  3171.     n1 : in ci_id_type;
  3172.     n2 : in ci_id_type
  3173.         ) return boolean is
  3174.  
  3175.     --| Effects: Compares two ci_id_types and returns true if the first one is
  3176.     --|  less than or equal to the second.  Rules for comparison are above.
  3177.     begin
  3178.         if not SP.equal (n1.name, n2.name) then
  3179.         return SP."<="(n1.name, n2.name);
  3180.         else
  3181.         return (compare (n1.version, n2.version) = less or
  3182.             compare (n1.version, n2.version) = same);
  3183.         end if;
  3184.     end "<=";
  3185.  
  3186.     function ">=" (        --| returns true if name1 is greater than or
  3187.                 --| equal to name2
  3188.     n1 : in ci_id_type;
  3189.     n2 : in ci_id_type
  3190.         ) return boolean is
  3191.  
  3192.     --| Effects: Compares two ci_id_types and returns true if the first one is
  3193.     --| greater than or equal to the second.  Rules for comparison are above.
  3194.     begin
  3195.         if not SP.equal (n1.name, n2.name) then
  3196.         return not SP."<"(n1.name, n2.name);
  3197.         else
  3198.         return (compare (n1.version, n2.version) = more or
  3199.             compare (n1.version, n2.version) = same);
  3200.         end if;
  3201.     end ">=";
  3202.  
  3203. ---- Local Subprogram bodies:
  3204.  
  3205. function compare (        --| Compare two version lists
  3206.     v1 : in v_list;        --| first list
  3207.     v2 : in v_list        --| second version list
  3208.     ) return compare_type is
  3209.  
  3210.     i1 : VL.listiter := VL.makelistiter (v1);
  3211.     i2 : VL.listiter := VL.makelistiter (v2);
  3212.     num1 : integer;
  3213.     num2 : integer;
  3214.  
  3215.     -- compare returns less if v1 < v2, same if v1 = v2 and more if v1 > v2
  3216.     begin
  3217.     -- first check for a simple case of comparing numbers to see if
  3218.     -- one is less than the other.  As long as they're equal go on to
  3219.     -- the next one in the version.
  3220.     while VL.more (i1) and VL.more (i2) loop
  3221.         VL.next (i1, num1);
  3222.         VL.next (i2, num2);
  3223.         if num1 < num2 then
  3224.         return less;
  3225.         elsif num1 > num2 then
  3226.         return more;
  3227.         end if;
  3228.     end loop;
  3229.     -- At this point either one of the lists has run out of numbers in
  3230.     -- the version list (in which case it is less), or both of them
  3231.     -- have run out of version numbers (in which case they're equal).
  3232.     if VL.more (i1) and not VL.more (i2) then
  3233.         --  i1 is greater
  3234.         return more;
  3235.     elsif not VL.more (i1) and VL.more (i2) then
  3236.         -- i2 is greater
  3237.         return less;
  3238.     else    -- they are equal
  3239.         return same;
  3240.     end if;
  3241.     end compare;
  3242.  
  3243. function parse_dotted_num (    --| parse the version number from an input
  3244.                 --| string
  3245.     s : in SU.scanner        --| input string
  3246.     ) return v_list is
  3247.  
  3248.     found  : boolean;
  3249.     skip   : boolean := true;
  3250.     result : integer;
  3251.     char   : character;
  3252.     odd       : boolean := false;
  3253.     ver       : v_list := VL.create;
  3254.  
  3255.     --| Algorithm: The format of a dotted number is an odd number of 
  3256.     --| integer components separated by periods.  It must begin and end 
  3257.     --| with an integer.  So the plan is to scan the first number as there
  3258.     --| must always be at least one for it to be valid, and add that to 
  3259.     --| the list.  If the first scan number fails raise invalid_ci_id.
  3260.     --| flip the odd indicator and then begin to loop. As long as the
  3261.     --| next character is a space continue to loop.  If it's a period
  3262.     --| recursively call parse_dotted_num to get the next number, and 
  3263.     --| if it's anything else raise invalid ci id.
  3264.     begin
  3265.     loop
  3266.         SU.scan_number (s, found,  result, skip);
  3267.         if not found then
  3268.             raise invalid_ci_id;
  3269.         end if;
  3270.         odd := not odd;
  3271.             VL.attach (ver, result);
  3272.         exit when not SU.more (s);
  3273.         SU.next (s, char);
  3274.         if char /= '.' then
  3275.         raise invalid_ci_id;
  3276.         end if;
  3277.     end loop;
  3278.     if not odd then
  3279.         raise invalid_ci_id;
  3280.     end if;
  3281.     return ver;
  3282.     end parse_dotted_num;
  3283.     
  3284. function make_hif_path (    --| create a hif path from the ci name and
  3285.                 --| the ci version
  3286.     name    : in SP.string_type;    
  3287.     version : in v_list
  3288.     ) return SP.string_type is
  3289.  
  3290.     temp : SP.string_type;
  3291.     path : SP.string_type;
  3292.     iter : VL.listiter := VL.makelistiter (version);
  3293.     num  : integer;
  3294.     begin
  3295.     SP.mark;
  3296.     temp := SP.create ("'current_node'ci_root(");
  3297.     
  3298.     -- Note that for parse dotted num to have completed sucessfully there
  3299.     -- has to have been at least one number in the list so begin the hif
  3300.     -- path with that one and then do the rest in pairs.
  3301.     temp := temp & name & ")";
  3302.     VL.next (iter, num);
  3303.     temp := temp & "'trunk(v" & SS.image(num) & ")";
  3304.     while VL.more (iter) loop
  3305.         -- we can do both a trunk and a branch at the same time because
  3306.         -- there has to be an odd number of components to the version
  3307.         -- number.
  3308.         VL.next (iter, num);
  3309.         temp := temp & "'branch(v" & SS.image(num) & ")";
  3310.         VL.next (iter, num);
  3311.         temp := temp & "'trunk(v" & SS.image(num) & ")";
  3312.     end loop;
  3313.     path := SP.make_persistent (temp);
  3314.     SP.release;
  3315.     return path;
  3316.     end make_hif_path;
  3317.  
  3318. end ci_ids;
  3319. ::::::::::::::
  3320. ciid.spc
  3321. ::::::::::::::
  3322. with string_pkg;
  3323. with version_lists;
  3324.  
  3325. package ci_ids is
  3326.  
  3327. --| Overview
  3328. --|
  3329. --| A ci_id is an idenitfier that uniquely identifies a configuration item (CI)
  3330. --| It has two parts: a name which is an Ada identifier and a version number.
  3331. --| The syntax for a ci_id follows:
  3332. --| -
  3333. --| ci_id     ::= name version
  3334. --| name      ::= letter [[underline] letter_or_digit]
  3335. --| letter_or_digit ::= letter | digit
  3336. --| version     ::= [number . number .] number
  3337. --| number     ::= digit [digit]
  3338. --| +
  3339. --| The name of a ci_id will identify all CIs which are versions derived from
  3340. --| a single parent.  The version uniquely identifies which version among
  3341. --| those is being referred to.
  3342.  
  3343.     package SP renames string_pkg;
  3344.     package VL renames version_lists;
  3345.     subtype v_list is VL.list;
  3346.  
  3347.     type ci_id_type is private;
  3348.  
  3349.     invalid_ci_id : exception;        -- raised when a string has the wrong
  3350.                     -- format
  3351.  
  3352.     function get_ci_id (    --| returns a ci_id from a string in the right
  3353.                 --| format
  3354.     s : in string        --| string to parse for a ci_id
  3355.         ) return ci_id_type;
  3356.     --| Raises: invalid_ci_id
  3357.  
  3358.     --| Effects: Reads in a string and parses it into a ci_id_type.  All 
  3359.     --| characters
  3360.     --| up to a space are considered the name.  Characters following the space
  3361.     --| will be interpreted as the version.  If the string 
  3362.     --| cannot be interpreted in this way the exception invalid_ci_id is 
  3363.     --| raised.  Numbers before the space will be a part of the name string.
  3364.     --| For this reason there must be a space between the name part and the
  3365.     --| version.
  3366.  
  3367.     function get_ci_id (    --| returns a ci_id from a string in the right
  3368.                 --| format
  3369.     s : in SP.string_type    --| string to parse for a ci_id
  3370.         ) return ci_id_type;
  3371.     --| Raises: invalid_ci_id
  3372.  
  3373.     --| Effects: Reads in a string_type and parses it into a ci_id_type.  All 
  3374.     --| characters
  3375.     --| up to a space are considered the name.  Characters following the space
  3376.     --| will be interpreted as the version.  If the string 
  3377.     --| cannot be interpreted in this way the exception invalid_ci_id is 
  3378.     --| raised.  Numbers before the space will be a part of the name string.
  3379.     --| For this reason there must be a space between the name part and the
  3380.     --| version.
  3381.  
  3382.     function  image (        --| returns a string representation
  3383.                 --| of a ci_id_type
  3384.     n : in ci_id_type    --| ci_id_type to translate
  3385.     ) return string;
  3386.  
  3387.     --| Effects: Takes a ci_id_type and translates it into a string
  3388.     --| in the ci_id format.
  3389.  
  3390.     function  image (        --| returns a string representation
  3391.                 --| of a ci_id_type
  3392.     n : in ci_id_type    --| ci_id_type to translate
  3393.     ) return SP.string_type;
  3394.  
  3395.     --| Effects: Takes a ci_id_type and translates it into a string
  3396.     --| in the ci_id format.
  3397.  
  3398.     function get_name (        --| returns the string which is the name
  3399.                 --| part of a ci_id_type
  3400.       n : in ci_id_type
  3401.     ) return string;
  3402.  
  3403.     --| Effects: Takes a ci_id_type and returns the name part as a string.
  3404.  
  3405.     function get_name (        --| returns the string which is the name
  3406.                 --| part of a ci_id_type
  3407.       n : in ci_id_type
  3408.     ) return SP.string_type;
  3409.  
  3410.     --| Effects: Takes a ci_id_type and returns the name part as a string.
  3411.  
  3412.     function get_version(    --| returns the string which is the version
  3413.                 --| part of a ci_id_type
  3414.       n : in ci_id_type
  3415.     ) return string;
  3416.  
  3417.     --| Effects: Takes a ci_id_type and returns the version number as a string.
  3418.  
  3419.     function get_version(    --| returns the string which is the version
  3420.                 --| part of a ci_id_type
  3421.       n : in ci_id_type
  3422.     ) return SP.string_type;
  3423.  
  3424.     --| Effects: Takes a ci_id_type and returns the version number as a string.
  3425.  
  3426.     function get_version(    --| returns the string which is the version
  3427.                 --| part of a ci_id_type
  3428.       n : in ci_id_type
  3429.     ) return VL.list;
  3430.  
  3431.     --| Effects: Takes a ci_id_type and returns the version number as a list.
  3432.  
  3433.     function get_hif_path (    --| returns a string which is a valid hif
  3434.                 --| path string for this ci.
  3435.         n : in ci_id_type
  3436.     ) return string;
  3437.  
  3438.     --| Effects: Takes a ci_id_type and returns the hif path for the node
  3439.     --| which corresponds to the hif node for this ci.
  3440.  
  3441.     function get_hif_path (    --| returns a string which is a valid hif
  3442.                 --| path string for this ci.
  3443.         n : in ci_id_type
  3444.     ) return SP.string_type;
  3445.  
  3446.     --| Effects: Takes a ci_id_type and returns the hif path for the node
  3447.     --| which corresponds to the hif node for this ci.
  3448.  
  3449.     function increment_ci_id (    --| returns a ci_id that is one more than
  3450.                 --| the given ci_id assuming no branching.
  3451.     id : in ci_id_type    --| ci_id to increment
  3452.     ) return ci_id_type;
  3453.  
  3454.     --| Effects:  Increments the version of the ci_id.  So for example,
  3455.     --| if the ci_id was "abs 1.1.1" the new one would be "abs 1.1.2".
  3456.     --| It always just increments the last number in the tuple.
  3457.  
  3458.     function equal (        --| returns true if the two ci_id_types
  3459.                 --| are equal
  3460.     n1 : in ci_id_type;
  3461.     n2 : in ci_id_type
  3462.         ) return boolean;
  3463.  
  3464.     --| Effects: compares the names and versions of each ci_id_type and
  3465.     --| returns true if both parts are the same.
  3466.  
  3467.     function similar (        --| returns true if the name part of
  3468.                 --| the ci_id_types are the same.  The versions
  3469.                 --| may be different
  3470.     n1 : in ci_id_type;
  3471.     n2 : in ci_id_type
  3472.          ) return boolean;
  3473.  
  3474.     --| Effects: Compares the names of each ci_id_type and returns true
  3475.     --| if they are the same.  In this way you can find out if two ci_id_types
  3476.     --| refer to different versions of the same CI.
  3477.  
  3478.     function "<" (        --| returns true if name1 is less than name2
  3479.     n1 : in ci_id_type;
  3480.     n2 : in ci_id_type
  3481.         ) return boolean;
  3482.  
  3483.     --| Effects: compares the two ci_id_types given and returns true if name1
  3484.     --| is less than name2.  The name part is compared lexicographically,
  3485.     --| and the version number is compared in the following manner:
  3486.     --| compare each integer component of the versions in turn, the first
  3487.     --| version to have a number less than the other in the same component
  3488.     --| of the versions is the lower number.  A null component is less than
  3489.     --| anything. For example:
  3490.     --| 1 < 1.1.1 < 1.1.4 < 1.2.1 < 2.1.1 < 2.1.6 < 2.4.1 
  3491.  
  3492.     function ">" (        --| returns true if name1 is greater than name2
  3493.     n1 : in ci_id_type;
  3494.     n2 : in ci_id_type
  3495.         ) return boolean;
  3496.  
  3497.     --| Effects: Compares two ci_id_types and returns true if the first one is 
  3498.     --| greater than the second. The rules for comparison are discussed above.
  3499.  
  3500.     function "<=" (        --| returns true if name1 is less than or 
  3501.                 --| equal to name2
  3502.     n1 : in ci_id_type;
  3503.     n2 : in ci_id_type
  3504.         ) return boolean;
  3505.  
  3506.     --| Effects: Compares two ci_id_types and returns true if the first one is
  3507.     --|  less than or equal to the second.  Rules for comparison are above.
  3508.  
  3509.     function ">=" (        --| returns true if name1 is greater than or
  3510.                 --| equal to name2
  3511.     n1 : in ci_id_type;
  3512.     n2 : in ci_id_type
  3513.         ) return boolean;
  3514.  
  3515.     --| Effects: Compares two ci_id_types and returns true if the first one is
  3516.     --| greater than or equal to the second.  Rules for comparison are above.
  3517.  
  3518.   private
  3519.  
  3520.  
  3521.     -- the ci_id_type type is a record which keeps the different 
  3522.     -- representations of the ci_id_type in its fields.  
  3523.     -- The first two fields together make up the
  3524.     -- ci_id.  name is the name part of the ci_id and version is a list of
  3525.     -- the version numbers.  quoted is the ci_id as a plain old string.
  3526.     -- hif_path is a string representing the hif pathname for the node this
  3527.     -- ci_id refers to.
  3528.  
  3529.     type ci_id_type is
  3530.     record
  3531.     name       : SP.string_type;
  3532.     version   : v_list;
  3533.     quoted    : SP.string_type;
  3534.         hif_path  : SP.string_type;
  3535.     end record;
  3536.     
  3537. end ci_ids;
  3538. ::::::::::::::
  3539. ciindex.bdy
  3540. ::::::::::::::
  3541. with Hif_node_defs;    use Hif_node_defs;    -- for definitions of types
  3542. with hif_attributes;
  3543. with Hif_node_management;
  3544. with Hif_list_utils;
  3545. with hif_utils;
  3546. with catalog_locks;
  3547.  
  3548. package body ci_index_mgr is
  3549.  
  3550. --| Overview
  3551. --| 
  3552. --| This package provides the interface to the keyword index of a catalog.
  3553. --| The index relies on the fact that there are a limited number of
  3554. --| keywords allowed.  For each keyword there are unlimited values, so a 
  3555. --| configuration item in the catalog will be associated with a keyword and
  3556. --| a value for that keyword.  This interface handles putting this information
  3557. --| in the index and looking it up given the keyword and value to look
  3558. --| under.
  3559. --| The operations possible are:
  3560. --| -
  3561. --| define_keyword    adds a keyword to the set of keywords
  3562. --| list_keywords    list all the keywords and their statuses
  3563. --| add_ci        adds a CI to the index under it's keyword,value
  3564. --| delete_ci        deletes a CI from the list of CI's for a keyword,value
  3565. --| lookup_ci        returns a set of CI's which all have the same 
  3566. --|            keyword,value.
  3567. --| is_keyword        checks that a string is a keyword
  3568. --| is_required_keyword checks that a string is a required keyword
  3569. --| is_valid_keyword    checks that a string is a valid keyword
  3570. --| check_required    checks that the given set of keywords includes all 
  3571. --|             required ones
  3572. --| lock_index        lock a particular index for read or write
  3573. --| unlock_index    unlock an index
  3574. --| is_locked        checks whether an index is locked
  3575. --| +
  3576.  
  3577.   use string_pkg;    -- used only to allow infix notation of &
  3578.   use catalog_decls;    -- used so CI_sets operations aren't CD.CI_sets.op ();
  3579.   package Attr renames Hif_attributes;
  3580.   package ND renames Hif_node_defs;
  3581.   package NM renames Hif_node_management;
  3582.   package LU renames Hif_list_utils;
  3583.   package SS renames CD.string_sets;
  3584.   package HU renames hif_utils;
  3585.   package CL renames catalog_locks;
  3586.  
  3587. procedure define_keyword (    --| add a new keyword to the index set
  3588.     keyword : in SP.string_type;--| the keyword to add
  3589.     status  : in proper_status    --| the status the keyword has.   
  3590.     := optional
  3591.     ) is
  3592.  
  3593.     path : SP.string_type;
  3594.     list : LU.list_type;
  3595.     wait : duration := 0.0;
  3596.  
  3597.     begin
  3598.     --| Algorithm
  3599.     --| Add the keyword to the root node with the given status.  If it is not
  3600.     --| already a keyword (ie this can be used to change the status of a 
  3601.     --| keyword) then make a node for it off the database node.
  3602.     --| note that the current_node is the root node, so everything can be done
  3603.     --| relative to this.
  3604.     LU.init_list (list);
  3605.     SP.mark;
  3606.     if CL.upgrade_lock (wait) then
  3607.         --? lock index, with a write lock (or lock catalog)
  3608.         if not is_keyword (keyword) then
  3609.         begin
  3610.                 NM.create_node (
  3611.                SP.value ("'current_node'index(" & keyword & ")"));
  3612.         exception when  ND.name_error =>
  3613.             CL.remove_write;
  3614.             raise invalid_keyword;
  3615.         end;
  3616.         end if;
  3617.             LU.add_positional (list, status_type'image(status));
  3618.          Attr.set_node_attribute(current_node,
  3619.                     SP.value(keyword),
  3620.                     list);
  3621.         CL.remove_write;
  3622.         --? unlock
  3623.     else
  3624.         raise unable_to_lock;
  3625.     end if;
  3626.     SP.release;
  3627.     end define_keyword;
  3628.  
  3629.  
  3630. function list_keywords        --| List the set of keywords indicating
  3631.                 --| what the status of the keyword is.
  3632.     return SL.list is
  3633.  
  3634.     --| Algorithm:  Iterate over the attributes on the root node putting them
  3635.     --| in a list with their status.
  3636.  
  3637.     list : SL.list;
  3638.     iter : Attr.attrib_iterator;
  3639.     attrib : Attrib_name (1..256);
  3640.     attrib_last : natural;
  3641.     value  : LU.list_type;
  3642.     keyword : SP.string_type;
  3643.  
  3644.     begin
  3645.     -- make an iterator with the pattern to match being the default '*'
  3646.     --? read lock on the catalog
  3647.     Attr.node_attribute_iterate(iter, current_node);
  3648.     while Attr.more (iter) loop
  3649.         Attr.get_next (iter, attrib, attrib_last, value);
  3650.         keyword := SP.create (attrib(1..attrib_last) & " "
  3651.                  & LU.list_image(value));
  3652.         SL.attach (list, keyword);
  3653.     end loop;
  3654.     --? unlock
  3655.     return list;
  3656.     
  3657.     end list_keywords;
  3658.  
  3659.  
  3660. procedure add_ci (        --| add a CI under it's appropriate 
  3661.                 --| keyword,value
  3662.     keyword : in SP.string_type;--| the keyword to put it under
  3663.     value   : in SP.string_type;--| the value to put it under
  3664.     CI_name : in ID.ci_id_type  --| the CI's name
  3665.     ) is
  3666.  
  3667.     keywd_path : SP.string_type;
  3668.     list : LU.list_type;
  3669.     begin
  3670.     --| Algorithm
  3671.     --| The way to store the data (considering that the values of attribs
  3672.     --| are Hif lists and very inconvenient) is to first get the value of
  3673.     --| the attrib as a hif list and then to add the new CI to the list
  3674.     --| and finally put it back as the value for the list. 
  3675.     --| A ci id cannot be added with a keyword that isn't valid.  And if
  3676.     --| the value isn't an ada identifier it also fails.
  3677.  
  3678.     -- Note that since hif lists are completely useless there is no way
  3679.     -- to raise any kind of error if you are adding a ci id which is
  3680.     -- already on the list.  Luckily this has no effect on lookup_ci
  3681.          
  3682.     
  3683.     SP.mark;
  3684.     if is_valid_keyword (keyword) then
  3685.     --? lock index with write
  3686.     keywd_path := current_node & "'index(" & keyword & ")";
  3687.     begin
  3688.         attr.get_node_attribute (SP.value(keywd_path),
  3689.                      SP.value(value),
  3690.                      list);
  3691.         exception when ND.name_error =>
  3692.         SP.release;
  3693.         raise invalid_value;
  3694.     end;
  3695.     LU.add_positional (list, 
  3696.                LU.to_item (HU.enquote (ID.image(CI_name))));
  3697.     attr.set_node_attribute (SP.value(keywd_path),
  3698.                  SP.value(value),
  3699.                  list);
  3700.     --? unlock
  3701.     else
  3702.     SP.release;
  3703.     raise invalid_keyword;
  3704.     end if;
  3705.     SP.release;
  3706.     
  3707.     exception 
  3708.     when ND.name_error =>
  3709.         SP.release;
  3710.         raise invalid_keyword;
  3711.     end add_ci;
  3712.  
  3713. procedure delete_ci (        --| delete the given CI under the given
  3714.                 --| keyword and value
  3715.     keyword : in SP.string_type;--| keyword to find the CI under
  3716.     value   : in SP.string_type;--| value to fine the CI under
  3717.     CI_name : in ID.ci_id_type  --| CI to delete from the list
  3718.     ) is
  3719.  
  3720.     keywd_path : SP.string_type;
  3721.     list : LU.list_type;
  3722.     new_list : LU.list_type;
  3723.     item : LU.item_type;
  3724.     index : LU.count;
  3725.     i : LU.count;
  3726.     begin
  3727.     --| Algorithm
  3728.     --| This is not as easy as it looks because hif lists do not have
  3729.     --| a way to delete an item.  So what we have to do is iterate over
  3730.     --| the list associated with a property.  Compare each element of the
  3731.     --| list with the ci id, and if it is not the same put it in a new list.
  3732.     --| This takes care of the case in add_ci where the same ci is added
  3733.     --| twice. There is one problem, when the ci to delete isn't in the 
  3734.     --| list no error is raised.
  3735.  
  3736.     SP.mark;
  3737.     if is_keyword (keyword) and then not SP.equal (value, "") then
  3738.     --? lock for write 
  3739.     keywd_path := current_node & "'index(" & keyword & ")";
  3740.     begin
  3741.         attr.get_node_attribute (SP.value(keywd_path),
  3742.                       SP.value(value),
  3743.                       list);
  3744.     exception when ND.name_error =>
  3745.         SP.release;
  3746.         raise invalid_value;
  3747.     end;
  3748.         LU.init_list (new_list);
  3749.     index := LU.num_positional (list);
  3750.     -- Since hif lists don't have delete item loop through the list
  3751.      -- putting the values in a new list.  If the value is the one 
  3752.     -- we want to delete don't add it to the new list.
  3753.     for i in 1..index loop
  3754.         LU.get_positional (list, item, i);
  3755.         if not LU."=" (item, LU.to_item (HU.enquote(ID.image(CI_name))))
  3756.           then
  3757.         LU.add_positional (new_list, item);
  3758.         end if;
  3759.     end loop;
  3760.     attr.set_node_attribute (SP.value(keywd_path),
  3761.                  SP.value(value),
  3762.                  new_list);
  3763.     --? unlock
  3764.     else 
  3765.     if not SP.equal (value, "") then
  3766.         SP.release;
  3767.         raise invalid_keyword;
  3768.     end if;
  3769.     end if;
  3770.     SP.release;
  3771.  
  3772.     exception when ND.name_error =>
  3773.     SP.release;
  3774.     raise invalid_keyword;
  3775.     end delete_ci;
  3776.  
  3777. function lookup_CI (        --| lookup the CI's associated with a 
  3778.                 --| particular keyword and value
  3779.     keyword : in SP.string_type;--| keyword to lookup under
  3780.     value   : in SP.string_type --| value  to lookup under
  3781.     ) return CD.CI_set is
  3782.  
  3783.     keywd_path : SP.string_type;
  3784.     list : LU.list_type;
  3785.     list_item : LU.item_type;
  3786.     index : LU.count;
  3787.     item : SP.string_type;
  3788.     CIs : CD.CI_set := CI_sets.create;
  3789.     begin
  3790.     SP.mark;
  3791.     --| Algorithm
  3792.     --| Get the list associated with the attribute and read it into a CI_set
  3793.     --| to return it.
  3794.     if is_keyword (keyword) then
  3795.     --? lock index for read
  3796.     keywd_path := current_node & "'index(" & keyword & ")";
  3797.     begin
  3798.         attr.get_node_attribute (SP.value(keywd_path),
  3799.                      SP.value(value),
  3800.                      list);
  3801.     exception when ND.name_error =>
  3802.         SP.release;
  3803.         raise invalid_value;
  3804.     end;
  3805.     index := LU.num_positional (list);
  3806.     for i in 1..index loop
  3807.             LU.get_positional (list, list_item, i);
  3808.           if LU.quoted_string (list_item) /= "" then
  3809.            CI_sets.insert(CIs, 
  3810.                     ID.get_ci_id (
  3811.                     LU.quoted_string(list_item)));
  3812.         end if;
  3813.     end loop;
  3814.     else
  3815.     SP.release;
  3816.     raise invalid_keyword;
  3817.     end if;
  3818.     SP.release;
  3819.     --? unlock
  3820.     return CIs;
  3821.  
  3822.     exception when ND.name_error =>
  3823.     SP.release;
  3824.     raise invalid_keyword;
  3825.  
  3826.     end lookup_ci;
  3827.  
  3828. function is_keyword (        --| is the given string a keyword at all
  3829.     keyword : in SP.string_type --| string to look up
  3830.     ) return boolean is
  3831.  
  3832.     --| Algorithm: Get the value for that keyword and return true if the
  3833.     --| list returned isn't empty.
  3834.     list : LU.list_type;
  3835.     item : LU.item_type;
  3836.     begin
  3837.     SP.mark;
  3838.      Attr.get_node_attribute (current_node, SP.value(keyword), list);
  3839.     SP.release;
  3840.     return not LU.empty(list);
  3841.     exception when ND.name_error =>
  3842.     return false;
  3843.     end is_keyword;
  3844.  
  3845.  
  3846. function is_required_keyword (    --| is the given keyword a required one
  3847.     keyword : in SP.string_type --| string to look up
  3848.     ) return boolean is
  3849.  
  3850.     --| Algorithm: Get the value for the given key word and check its status
  3851.     list : LU.list_type;
  3852.     begin
  3853.     SP.mark;
  3854.      Attr.get_node_attribute (current_node, SP.value(keyword), list);
  3855.     SP.release;
  3856.     return (not LU.empty (list) and then
  3857.            (status_type'value(LU.identifier(LU.positional(list,1)))=required));
  3858.     exception
  3859.         when ND.name_error =>
  3860.         -- keyword probably doesn't exist and the list was null;
  3861.         SP.release;
  3862.         return false;
  3863.     end is_required_keyword;
  3864.  
  3865.  
  3866. function is_valid_keyword (    --| is the given keyword a valid one
  3867.     keyword : in SP.string_type --| string to look up
  3868.     ) return boolean is
  3869.  
  3870.     --| Algorithm: Get the value for the given key word and check its status
  3871.     list : LU.list_type;
  3872.     begin
  3873.     SP.mark;
  3874.      Attr.get_node_attribute (current_node, SP.value(keyword), list);
  3875.     SP.release;
  3876.     return (not LU.empty (list) and then
  3877.       ((status_type'value(LU.identifier(LU.positional(list,1))) = required)
  3878.       or else
  3879.       (status_type'value(LU.identifier(LU.positional(list,1)))=optional)));
  3880.     exception
  3881.         when ND.name_error =>
  3882.         -- keyword probably doesn't exist and the list was null;
  3883.         SP.release;
  3884.         return false;
  3885.     end is_valid_keyword;
  3886.  
  3887. function check_required (    --| check that the given set of keywords
  3888.                 --| contains all the required ones
  3889.     set : in CD.string_set    --| set to check
  3890.     ) return CD.string_set is
  3891.  
  3892.     --| Algorithm: Iterate over the keywords at this time putting required
  3893.     --| ones in a set.  When the set is complete make sure that the
  3894.     --| intersection of the required set and the input set is equal to the
  3895.     --| required set.  Otherwise the input set didn't contain all the 
  3896.     --| required keywords and so check_required returns false.
  3897.  
  3898.     iter : Attr.attrib_iterator;
  3899.     attrib : attrib_name (1..256);
  3900.     attrib_last : natural;
  3901.     list : LU.list_type;
  3902.     req_set : CD.string_set;
  3903.     union : CD.string_set;
  3904.     key : SP.string_type;
  3905.     i : SS.members_iter;
  3906.         
  3907.     begin
  3908.     --? lock index for read
  3909.     -- SP.mark;    -- the mark is commented because the release is after
  3910.             -- the return and so is not executed.
  3911.     Attr.Node_Attribute_Iterate (iter, current_node);
  3912.     -- let the pattern default to "*"
  3913.     while Attr.more (iter) loop
  3914.         Attr.get_next (iter, attrib, attrib_last, list);
  3915.         if status_type'value(LU.identifier(LU.positional(list,1)))
  3916.            = required then
  3917.         SS.insert (req_set, SP.create (attrib (1..attrib_last)));
  3918.         end if;
  3919.     end loop;
  3920.     union := SS.union (req_set, set);
  3921.     i := SS.make_members_iter (set);
  3922.     while SS.more (i) loop
  3923.         SS.next (i, key);
  3924.         SS.delete (union, key);
  3925.     end loop;
  3926.     return union;
  3927.         -- SP.release;    -- commented out because after the return it is no use
  3928.     --? unlock
  3929.     end check_required;
  3930.  
  3931. function lock_index (        --| lock the given index for read or write
  3932.     keyword : in SP.string_type;--| key for the index to lock
  3933.     lock    : in lock_type    --| kind of lock
  3934.     ) return boolean is
  3935.  
  3936.     --| Algorithm: This is a null program until we actually implement locking
  3937.     --| on a more complex level than just locking the whole catalog.
  3938.     begin
  3939.     return true;
  3940.     end lock_index;
  3941.  
  3942. function unlock_index (        --| unlock the given index
  3943.     keyword : in SP.string_type --| key for the index to unlock
  3944.     ) return boolean is
  3945.  
  3946.     --| Algorithm: This is a null program until we actually implement locking
  3947.     --| on a more complex level than just locking the whole catalog.
  3948.  
  3949.     begin
  3950.     return true;
  3951.     end unlock_index;
  3952.  
  3953. function is_locked (        --| returns true if the index is locked
  3954.     keyword : in SP.string_type --| key for the index to check
  3955.     ) return boolean is
  3956.  
  3957.     --| Algorithm: This is a null program until we actually implement locking
  3958.     --| on a more complex level than just locking the whole catalog.
  3959.  
  3960.     begin
  3961.     return true;
  3962.     end is_locked;
  3963.  
  3964. end ci_index_mgr;
  3965. ::::::::::::::
  3966. ciindex.spc
  3967. ::::::::::::::
  3968. with catalog_decls;
  3969. with string_pkg; 
  3970. with string_lists;
  3971. with ci_ids;
  3972.  
  3973. package ci_index_mgr is
  3974.  
  3975. --| Overview
  3976. --| 
  3977. --| This package provides the interface to the keyword index of a catalog.
  3978. --| The index relies on the fact that there are a limited number of
  3979. --| keywords allowed.  For each keyword there are unlimited values, so a 
  3980. --| configuration item in the catalog will be associated with a keyword and
  3981. --| a value for that keyword.  This interface handles putting this information
  3982. --| in the index and looking it up given the keyword and value to look
  3983. --| under.
  3984. --| The operations possible are:
  3985. --| -
  3986. --| define_keyword    adds a keyword to the set of keywords
  3987. --| list_keywords    list all the keywords and their statuses
  3988. --| add_ci        adds a CI to the index under it's keyword,value
  3989. --| delete_ci        deletes a CI from the list of CI's for a keyword,value
  3990. --| lookup_ci        returns a set of CI's which all have the same 
  3991. --|            keyword,value.
  3992. --| is_keyword        checks that a string is a keyword
  3993. --| is_required_keyword checks that a string is a required keyword
  3994. --| is_valid_keyword    checks that a string is a valid keyword
  3995. --| check_required    checks that the given set of keywords includes all 
  3996. --|             required ones
  3997. --| lock_index        lock a particular index for read or write
  3998. --| unlock_index    unlock an index
  3999. --| is_locked        checks whether an index is locked
  4000. --| +
  4001.  
  4002.   package SP renames string_pkg;
  4003.   package CD renames catalog_decls;
  4004.   package SL renames string_lists;
  4005.   package ID renames ci_ids;
  4006.  
  4007.   type status_type         is (optional, required, invalid, undefined);
  4008.   subtype proper_status         is status_type range optional .. invalid;
  4009.   type lock_type          is (read, write);
  4010.  
  4011.   invalid_keyword : exception;    -- raised when the keyword is not valid
  4012.   invalid_value : exception;    -- raised when the value is not valid
  4013.   unable_to_lock : exception;    -- raised when the catalog cannot be locked
  4014.  
  4015. procedure define_keyword (    --| add a new keyword to the index set
  4016.     keyword : in SP.string_type;--| the keyword to add
  4017.     status  : in proper_status    --| the mode the keyword has.   
  4018.     := optional
  4019.     );
  4020.  
  4021. --| Effects: defines a keyword and its status.  If the keyword already exists
  4022. --| it changes its status to the given status.  If it does not exist in the
  4023. --| catalog the keyword is added with the given status.  The possibilities for
  4024. --| status are: optional, required, and invalid.  Invalid indicates that it is
  4025. --| no longer valid to give new CI's this property when they are stored, but it
  4026. --| is still possible to select CI's with this property.  Required indicates 
  4027. --| that every CI being stored must have this property.  The default is 
  4028. --| optional which means the property is valid, but it is not requred
  4029. --| on every CI stored. To change an invalid keyword back to valid one
  4030. --| would just define it with the status => optional and the keyword would
  4031. --| be changed from invalid to optional.
  4032.  
  4033. function list_keywords         --| List the set of keywords indicating
  4034.                 --| what the status of the keyword is.
  4035.     return SL.list;
  4036.  
  4037. --| Effects: Each of the keywords in the catalog is listed with its
  4038. --| current status.  The output is a string_list
  4039.  
  4040.  
  4041. procedure add_ci (        --| add a CI under it's appropriate 
  4042.                 --| keyword,value
  4043.     keyword : in SP.string_type;--| the keyword to put it under
  4044.     value   : in SP.string_type;--| the value to put it under
  4045.     CI_name : in ID.ci_id_type --| the CI's name
  4046.     );
  4047.  
  4048. --| Effects: Adds CI_name to the list of values for the attribute off the
  4049. --| keyword node with the name value.  If no attribute with that name
  4050. --| exists a new one is created with value as its name.
  4051.  
  4052. procedure delete_ci (        --| delete the given CI under the given
  4053.                 --| keyword and value
  4054.     keyword : in SP.string_type;--| keyword to find the CI under
  4055.     value   : in SP.string_type;--| value to fine the CI under
  4056.     CI_name : in ID.ci_id_type  --| CI to delete from the list
  4057.     );
  4058.  
  4059. --| Effects: Delete the CI given from the list of names associated with the
  4060. --| value parameter under the keyword given.  Other keywords and values that
  4061. --| this CI is classified under remain the same unless changed by another
  4062. --| call to this routine explicitly naming them.
  4063.  
  4064. function lookup_CI (        --| lookup the CI's associated with a 
  4065.                 --| particular keyword and value
  4066.     keyword : in SP.string_type;--| keyword to lookup under
  4067.     value   : in SP.string_type --| value  to lookup under
  4068.     ) return CD.CI_set;
  4069.  
  4070. --| Effects: Returns the set of CI's which have that keyword associated 
  4071. --| with that value.
  4072.  
  4073. function is_keyword (        --| is the given string a keyword at all
  4074.     keyword : in SP.string_type --| string to look up
  4075.     ) return boolean;
  4076.  
  4077. function is_required_keyword (    --| is the given keyword a required one
  4078.     keyword : in SP.string_type --| string to look up
  4079.     ) return boolean;
  4080.  
  4081. function is_valid_keyword (    --| is the given keyword a valid one
  4082.     keyword : in SP.string_type --| string to look up
  4083.     ) return boolean;
  4084.  
  4085. function check_required (    --| check that the given set of keywords
  4086.                 --| contains all the required ones
  4087.     set : in CD.string_set    --| set to check
  4088.     ) return CD.string_set;
  4089.  
  4090. --| Effects: Returns true if all the required keywords are included in the
  4091. --| given set.
  4092.  
  4093. function lock_index (        --| lock the given index for read or write
  4094.     keyword : in SP.string_type;--| key for the index to lock
  4095.     lock    : in lock_type    --| kind of lock
  4096.     ) return boolean;
  4097.  
  4098. --| Effects: Tries to lock the given index with the type of lock specified.
  4099. --| Normal completion will return true.  If the lock cannot be set the
  4100. --| function will return false.  
  4101.  
  4102. function unlock_index (        --| unlock the given index
  4103.     keyword : in SP.string_type --| key for the index to unlock
  4104.     ) return boolean;
  4105.  
  4106. --| Effects: Unlocks the index indicated and returns true if it completes
  4107. --| successfully.  If the person does not own the lock or if the index is
  4108. --| not locked false will be returned.
  4109.  
  4110. function is_locked (        --| returns true if the index is locked
  4111.     keyword : in SP.string_type --| key for the index to check
  4112.     ) return boolean;
  4113.  
  4114. --| Effects: Returns true if the index is locked false other wise.
  4115.  
  4116. end ci_index_mgr;
  4117. ::::::::::::::
  4118. command.bdy
  4119. ::::::::::::::
  4120. with rd_parser;
  4121. with string_pkg;
  4122. with string_lists;
  4123. with standard_interface;
  4124. with tool_identifier;
  4125. with catalog_manager;    use catalog_manager;    -- for visible "="
  4126. with catalog_decls;
  4127. with ci_index_mgr;
  4128. with ci_ids;
  4129. with library_declarations;
  4130. with text_io;
  4131. with property_set;
  4132. with host_lib;
  4133. with string_utilities;
  4134. with catalog_locks;
  4135. with properties;
  4136. with Library_Manager_Interface;
  4137.  
  4138. package body interpret is
  4139.  
  4140. ---- Package renames:
  4141.  
  4142. package SP renames string_pkg;
  4143. package SL renames string_lists;
  4144. package SI renames standard_interface;
  4145. package CM renames catalog_manager;
  4146. package CD renames catalog_decls;
  4147. package IM renames ci_index_mgr;
  4148. package ID renames ci_ids;
  4149. package LD renames library_declarations;
  4150. package PS renames property_set;
  4151. package HL renames host_lib;
  4152. package SU renames string_utilities;
  4153. package CL renames catalog_locks;
  4154.  
  4155. package TIO renames text_io;
  4156.  
  4157. ---- Package instantiations:
  4158.  
  4159. package string_arg is new SI.string_argument("string");
  4160. package lib_name is new SI.string_argument("library_name");
  4161. package ci_arg is new SI.string_argument("ci_id");
  4162. package fetch_arg  is new SI.enumerated_argument (LD.fetch_type, "fetch_type");
  4163. package lock_arg   is new SI.enumerated_argument (CM.lock_type, "lock_type");
  4164. package node_arg   is new SI.enumerated_argument (CM.node_type, "node_type");
  4165. package update_arg is new SI.enumerated_argument (CM.ci_type, "ci_type");
  4166. package status_arg is new SI.enumerated_argument (IM.proper_status, 
  4167.                           "proper_status");
  4168. package delete_arg is new SI.enumerated_argument (CM.delete_type, 
  4169.                           "delete_type");
  4170. package s_list_arg is new SI.string_list_argument ("string", 
  4171.                            "string_list");
  4172.  
  4173. package SS is new SU.generic_string_utilities(SP.string_type, 
  4174.                           SP.create,
  4175.                           SP.value);
  4176.  
  4177.  
  4178. ---- Type definitions:
  4179.  
  4180. type command is (select_cis, clear_selected_set, print_set, 
  4181.     list_cis, change_password, define_keyword, list_keywords,    
  4182.     create_ci, store, fetch, cancel, delete, 
  4183.     modify_property, describe, history, list_versions, list_components,
  4184.     remove_lock, library_manager); 
  4185.  
  4186. package SC is new SI.command_line (command);
  4187.  
  4188. procedure init_processes (processes : in out SC.process_handle_array);
  4189.  
  4190. procedure print_list (
  4191.     list : in  SL.list 
  4192.     );
  4193.  
  4194. procedure print_sel_set (
  4195.     set : in CD.ci_set
  4196.     );
  4197.  
  4198. procedure print_string_set (
  4199.     set : in CD.string_set
  4200.     );
  4201.  
  4202. procedure print_property_set (
  4203.     set : in PS.set
  4204.     );
  4205.  
  4206. procedure print_item_list (
  4207.     set : in LD.LL.list 
  4208.     );
  4209.  
  4210. procedure print_hist_list (
  4211.     list : in  CD.hist_list
  4212.     );
  4213.  
  4214. procedure print_errors ;
  4215.  
  4216. procedure command_interpreter is
  4217.  
  4218. cmd   : command;
  4219. rest  : SP.string_type;
  4220. input : string (1..256);    -- 256 is an arbitrary limit
  4221. last  : natural;
  4222.  
  4223. -- all the list types returned by query procedures.  
  4224. s_list  : SL.list;
  4225. p_set   : PS.set;
  4226. i_list  : LD.LL.list;
  4227. h_list  : CD.hist_list;
  4228.  
  4229. abbreviation : SC.Command_Abbreviation_Array :=
  4230.     (select_cis         => 3,
  4231.      clear_selected_set => 2,
  4232.      print_set          => 2,
  4233.      list_cis           => 6,
  4234.      change_password    => 2,
  4235.      define_keyword     => 3,
  4236.      list_keywords      => 6,    
  4237.      create_ci          => 2,
  4238.      store              => 1,
  4239.      fetch              => 1,
  4240.      cancel             => 3,
  4241.      delete             => 3,
  4242.      modify_property    => 3,
  4243.      describe           => 4,
  4244.      history            => 4,
  4245.      list_versions      => 6,
  4246.      list_components    => 7,
  4247.      remove_lock        => 3,
  4248.      library_manager    => 3);
  4249.  
  4250. processes  : SC.process_handle_array;
  4251. name       : SP.string_type;
  4252. key        : SP.string_type;
  4253. val        : SP.string_type;
  4254. lib        : SP.string_type;
  4255. prompt     : SP.string_type;
  4256. hist       : SP.string_type;
  4257. arg1       : SP.string_type;
  4258. arg2       : SP.string_type;
  4259. arg3       : SP.string_type;
  4260. wait       : duration := 0.0;
  4261. user1      : SP.string_type;
  4262. user2      : SP.string_type;
  4263. old_pass   : SP.string_type;
  4264. new_pass1  : SP.string_type;
  4265. new_pass2  : SP.string_type;
  4266. key_list   : SL.list;
  4267. iter       : SL.listiter;
  4268. status     : CM.status_type;
  4269. s_code     : HL.severity_code;
  4270. privileged : boolean := false;    -- flag which indicates whether the current
  4271.                 -- user is privileged.  Set upon entry.
  4272.  
  4273. begin
  4274.     SI.set_tool_identifier (tool_identifier);
  4275.     init_processes (processes);
  4276.     SP.set_comparison_option (SP.case_insensitive);
  4277. --    SI.action_switches (SI.echo_command) := SI.off;
  4278.     SI.parsing_switches (SI.argument_enclosure) := SI.on;
  4279.     SC.define_command_abbreviation (abbreviation, Check_Conflict => TRUE);
  4280.     TIO.put ("Enter password for privileges or return for none: ");
  4281.     if CM.verify_password (SS.strip (HL.read_no_echo(""))) then
  4282.     privileged := true;
  4283.     TIO.put_line ("You are entering as a privileged user");
  4284.     else
  4285.     TIO.put_line ("You are entering as a regular user");
  4286.     end if;
  4287.     loop
  4288.     -- the loop is exited when the user enters exit to the command line.
  4289.     -- Standard_Interface raises an exception which is handled at the
  4290.     -- end of the loop and it contains the statement to exit the loop.
  4291.     begin
  4292.         TIO.new_line (1);
  4293.         TIO.put ("Catalog> ");
  4294.         TIO.get_line (input, last);
  4295.         cmd := SC.parse_command_line (processes, input(1..last));
  4296.         case cmd is
  4297.         -- for each command parse the command line even if it doesn't
  4298.         -- have any parameters just to make sure it does the syntax
  4299.         -- checking.  Of course if it does a parse_line it must do a
  4300.         -- redefine_process immediately afterwards for the next time 
  4301.         -- the procedure is called.
  4302.         when select_cis =>
  4303.             SP.mark;
  4304.             arg1 := string_arg.get_argument (
  4305.                     processes(select_cis),
  4306.                     "criteria");
  4307.             begin
  4308.                 rd_parser.parse (arg1);
  4309.                 if CD.ci_sets.is_empty (rd_parser.current_set) then
  4310.                 TIO.put_line ("Selected set is empty");
  4311.                 else
  4312.                     TIO.put_line ("Selected Set:");
  4313.                     print_sel_set (rd_parser.current_set);
  4314.                 end if;
  4315.             exception when rd_parser.parse_error =>
  4316.             TIO.put_line ("The syntax of the selection criteria " &
  4317.                     "is incorrect.  Try again.");
  4318.             end;
  4319.             SI.redefine_process (processes(select_cis));
  4320.             SP.flush (arg1);
  4321.             SP.release;
  4322.         when clear_selected_set =>
  4323.             SP.mark;
  4324.             SI.redefine_process (processes(clear_selected_set));
  4325.             rd_parser.clear_set;
  4326.             TIO.put_line ("Selected set cleared");
  4327.             SP.release;
  4328.         when print_set =>
  4329.             SP.mark;
  4330.             SI.redefine_process (processes(print_set));
  4331.             if CD.ci_sets.is_empty (rd_parser.current_set) then
  4332.             TIO.put_line ("Current selected set is empty");
  4333.             else
  4334.                 TIO.put_line ("Current Selected Set:");
  4335.                 print_sel_set (rd_parser.current_set);
  4336.             end if;
  4337.             SP.release;
  4338.         when list_cis =>
  4339.             SP.mark;
  4340.             arg1 := string_arg.get_argument (processes(list_cis),
  4341.                              "cis");
  4342.             s_list := CM.list_cis (arg1);
  4343.             if SL.isempty(s_list) then
  4344.             TIO.put_line ("Catalog is empty");
  4345.             else
  4346.                 TIO.put_line ("Catalog List:");
  4347.                 print_list (s_list);
  4348.             SL.destroy (s_list);
  4349.             end if;
  4350.             SI.redefine_process (processes(list_cis));
  4351.             SP.flush (arg1);
  4352.             SP.release;
  4353.         when change_password =>
  4354.             SP.mark;
  4355.             SI.redefine_process (processes(change_password));
  4356.             TIO.put ("Enter old password: ");
  4357.             old_pass := SS.strip (HL.read_no_echo(""));
  4358.             TIO.put ("Enter new password: ");
  4359.             new_pass1 := SS.strip (HL.read_no_echo(""));
  4360.             TIO.put ("Retype new password: ");
  4361.             new_pass2 := SS.strip (HL.read_no_echo(""));
  4362.             if SP.equal (new_pass1, new_pass2) then
  4363.             CM.set_password (new_pass1, old_pass);
  4364.             else
  4365.             TIO.put_line ("New password not verified, try again");
  4366.             end if;
  4367.             SP.release;
  4368.         when define_keyword =>
  4369.             SP.mark;
  4370.             if privileged then
  4371.             begin
  4372.                 key := string_arg.get_argument
  4373.                         (processes(define_keyword),
  4374.                           "keyword");
  4375.                     IM.define_keyword (key,
  4376.                                    status_arg.get_argument
  4377.                         (processes(define_keyword),
  4378.                           "status"));
  4379.                 TIO.put_line ("Defined keyword " & SP.value(key));
  4380.                 SP.flush (key);
  4381.             exception when IM.unable_to_lock =>
  4382.                 TIO.put_line ("Catalog cannot be locked for " &
  4383.                         "this operation");
  4384.                 SP.flush (key);
  4385.             end;
  4386.             else
  4387.                 raise CM.invalid_password;
  4388.             end if;
  4389.             SI.redefine_process (processes(define_keyword));
  4390.             SP.release;
  4391.         when list_keywords =>
  4392.             SP.mark;
  4393.             SI.redefine_process (processes(list_keywords));
  4394.             s_list := IM.list_keywords;
  4395.             if SL.isempty (s_list) then
  4396.             TIO.put_line ("No keywords are defined");
  4397.             else
  4398.                 TIO.put_line ("Catalog Keywords:");
  4399.                 print_list (s_list);
  4400.             SL.destroy (s_list);
  4401.             end if;
  4402.             SP.release;
  4403.         when create_ci =>
  4404.             SP.mark;
  4405.             if privileged then
  4406.                 begin
  4407.                 name := ci_arg.get_argument (processes(create_ci),
  4408.                              "name");
  4409.                 lib  := string_arg.get_argument (processes(create_ci),
  4410.                              "library");
  4411.                 hist := string_arg.get_argument (processes(create_ci),
  4412.                              "history");
  4413.                 status := CM.create_ci (name,
  4414.                             lib,
  4415.                                 hist);
  4416.                 if status = CM.error then
  4417.                TIO.put_line ("creation not completed due to errors");
  4418.                print_errors;
  4419.                 else
  4420.                 TIO.put_line ("Created CI " & SP.value(name) & " 1");
  4421.                 end if;
  4422.                 exception 
  4423.             when CM.library_locked =>
  4424.                 TIO.put_line ("Unable to complete operation due "
  4425.                 & "to the library being locked");
  4426.                 TIO.put_line ("Incomplete error checking done");
  4427.                 print_errors;
  4428.             when CM.library_nonexistent =>
  4429.                 TIO.put_line ("Unable to complete operation due "
  4430.                 & "to the library not existing");
  4431.                 print_errors;
  4432.             when CM.invalid_library =>
  4433.                 TIO.put_line ("Unable to complete operation due "
  4434.                 & "to an invalid library");
  4435.                 print_errors;
  4436.                 end;
  4437.                 SP.flush (lib);
  4438.                 SP.flush (hist);
  4439.                 SP.flush (name);
  4440.             else
  4441.             raise CM.invalid_password;
  4442.             end if;
  4443.             SI.redefine_process (processes(create_ci));
  4444.             SP.release;
  4445.         when store =>
  4446.             SP.mark;
  4447.             if privileged then
  4448.                 begin
  4449.                 lib  := string_arg.get_argument (processes(store),
  4450.                              "library");
  4451.                 hist := string_arg.get_argument (processes(store),
  4452.                              "history");
  4453.                 status := CM.store (lib,
  4454.                               hist);
  4455.                 if status = CM.error then
  4456.                 TIO.put_line ("Store not performed due to errors");
  4457.                 print_errors;
  4458.                 else
  4459.                 TIO.put_line ("Stored library " & SP.value(lib) );
  4460.                 end if;
  4461.                 exception 
  4462.             when CM.library_locked =>
  4463.                 TIO.put_line ("Unable to complete operation due "
  4464.                 & "to the library being locked");
  4465.                 TIO.put_line ("Incomplete error checking done");
  4466.                 print_errors;
  4467.             when CM.library_nonexistent =>
  4468.                 TIO.put_line ("Unable to complete operation due "
  4469.                 & "to the library not existing");
  4470.                 print_errors;
  4471.             when CM.invalid_library =>
  4472.                 TIO.put_line ("Unable to complete operation due "
  4473.                 & "to an invalid library");
  4474.                 print_errors;
  4475.                 end;
  4476.                 SP.flush (lib);
  4477.                 SP.flush (hist);
  4478.             else
  4479.             raise CM.invalid_password;
  4480.             end if;
  4481.             SI.redefine_process (processes(store));
  4482.             SP.release;
  4483.         when fetch =>
  4484.             SP.mark;
  4485.             begin
  4486.             name := ci_arg.get_argument (processes(fetch),
  4487.                                     "name");
  4488.             lib  := string_arg.get_argument (processes(fetch),
  4489.                                  "library");
  4490.             arg3 := string_arg.get_argument (processes(fetch),
  4491.                                  "directory");
  4492.                 CM.fetch (name,
  4493.                              lib,
  4494.                              arg3,
  4495.                             fetch_arg.get_argument (processes(fetch),
  4496.                                   "mode"));
  4497.             TIO.put_line ("Fetched CI " & SP.value(name) &
  4498.                 " into library " & SP.value(lib));
  4499.             exception when CM.invalid_library =>
  4500.             TIO.put_line ("Unable to complete the fetch since "
  4501.                 & "the library name given is invalid");
  4502.             end;
  4503.             SI.redefine_process (processes(fetch));
  4504.             SP.flush (name);
  4505.             SP.flush (lib);
  4506.             SP.flush (arg3);
  4507.             SP.release;
  4508.         when cancel  =>
  4509.             SP.mark;
  4510.             user1 := SP.create (HL.get_item(HL.user_name));
  4511.             user2 := string_arg.get_argument (processes(cancel),
  4512.                               "user");
  4513.             if not SP.equal (user1, user2) then
  4514.             if not privileged then
  4515.                 raise CM.invalid_password;
  4516.             end if;
  4517.             end if;
  4518.             CM.cancel (string_arg.get_argument (processes(cancel),
  4519.                                 "library"),
  4520.                    user2);
  4521.             TIO.put_line ("Fetch is cancelled");
  4522.             SI.redefine_process (processes(cancel));
  4523.             SP.flush (user2);
  4524.             SP.release;
  4525.         when delete =>
  4526.             SP.mark;
  4527.             if privileged then
  4528.             name := ci_arg.get_argument (processes(delete),
  4529.                                  "name");
  4530.                 CM.delete (name,
  4531.                    delete_arg.get_argument (processes(delete),
  4532.                                 "mode"));
  4533.             TIO.put_line ("CI " & SP.value(name) & " is deleted");
  4534.             SP.flush (name);
  4535.             else
  4536.                 raise CM.invalid_password;
  4537.             end if;
  4538.             SI.redefine_process (processes(delete));
  4539.             SP.release;
  4540.           when modify_property =>
  4541.             SP.mark;
  4542.             name := ci_arg.get_argument (processes(modify_property),
  4543.                              "name");
  4544.             key := string_arg.get_argument (processes(modify_property),
  4545.                             "keyword");
  4546.             val := string_arg.get_argument (processes(modify_property),
  4547.                             "value");
  4548.             begin
  4549.                 CM.modify_property (name, key, val);
  4550.                 TIO.put_line ("Property modified");
  4551.             exception when CM.deleted_ci =>
  4552.             TIO.put_line ("You can't modify the proerties of a " &
  4553.                     "deleted CI");
  4554.             end;
  4555.             SI.redefine_process (processes(modify_property));
  4556.             SP.flush (name);
  4557.             SP.flush (key);
  4558.             SP.flush (val);
  4559.             SP.release;
  4560.         when describe =>
  4561.             SP.mark;
  4562.             name := ci_arg.get_argument (processes(describe),
  4563.                              "name");
  4564.             key_list := s_list_arg.get_argument (processes(describe),
  4565.                                   "keywords");
  4566.             -- iterate over the node expanding the keys given in 
  4567.             -- key_list
  4568.             begin
  4569.                 p_set := CM.match_keys (name, key_list);
  4570.                 if (PS.cardinality (p_set) = 0) then
  4571.                 TIO.put_line (SP.value(name) & " has no properties"
  4572.                 & " that match the list");
  4573.                 else
  4574.                 TIO.put_line ("Properties of " & SP.value (name));
  4575.                     print_property_set (p_set);
  4576.                 end if;
  4577.             exception when CM.deleted_ci =>
  4578.             TIO.put_line ("You cannot describe a deleted CI.");
  4579.             end;
  4580.             SI.redefine_process (processes(describe));
  4581.             SP.flush (name);        
  4582.             SP.release;
  4583.         when history =>
  4584.             SP.mark;
  4585.             name := ci_arg.get_argument(processes(history),
  4586.                             "name");
  4587.             h_list := CM.history (name);
  4588.             TIO.put_line ("History of " & SP.value(name));
  4589.             print_hist_list (h_list);
  4590.             CD.hist_lists.destroy (h_list);
  4591.             SI.redefine_process (processes(history));
  4592.             SP.flush (name);        
  4593.             SP.release;
  4594.             when list_versions =>
  4595.             SP.mark;
  4596.             name := ci_arg.get_argument(processes(list_versions),
  4597.                             "name");
  4598.         -- the temp s_list is used so that the header isn't printed
  4599.         -- and then an error message.  If there is an exception the
  4600.         -- put line is not executed.
  4601.             s_list := CM.list_versions (name);
  4602.             TIO.put_line ("Versions of " & SP.value(name));
  4603.             print_list (s_list);
  4604.             SL.destroy (s_list);
  4605.             SI.redefine_process (processes(list_versions));
  4606.             SP.flush (name);        
  4607.             SP.release;
  4608.         when list_components =>
  4609.             SP.mark;
  4610.             name := ci_arg.get_argument(processes(list_components),
  4611.                             "name");
  4612.             begin
  4613.                 i_list := CM.list_components(name);
  4614.                 if LD.LL.isempty (i_list) then
  4615.               TIO.put_line (SP.value(name) & " has no components");
  4616.                 else
  4617.                   TIO.put_line ("Components of " & SP.value(name));
  4618.                   print_item_list (i_list);
  4619.               LD.LL.destroy (i_list);
  4620.                 end if;
  4621.             exception when CM.deleted_ci =>
  4622.             TIO.put_line ("CI has been deleted - no components.");
  4623.             end;
  4624.             SI.redefine_process (processes(list_components));
  4625.             SP.flush (name);        
  4626.             SP.release;
  4627.         when remove_lock =>
  4628.             SP.mark;
  4629.             if privileged then
  4630.             name := string_arg.get_argument 
  4631.                                (processes(remove_lock),
  4632.                         "name");
  4633.             arg3 := string_arg.get_argument
  4634.                                (processes(remove_lock),
  4635.                         "node_name");
  4636.                 CM.remove_lock (name,
  4637.                         lock_arg.get_argument
  4638.                             (processes(remove_lock),
  4639.                         "lock"),
  4640.                         arg3,
  4641.                         node_arg.get_argument
  4642.                                (processes(remove_lock),
  4643.                         "node"));
  4644.             TIO.put_line ("Lock removed");
  4645.                 SP.flush (name);        
  4646.                 SP.flush (arg3);        
  4647.             else
  4648.                 raise CM.invalid_password;
  4649.             end if;
  4650.             SI.redefine_process (processes(remove_lock));
  4651.             SP.release;
  4652.         when library_manager =>
  4653.             lib := lib_name.get_argument 
  4654.                 (processes(library_manager),
  4655.                 "library");
  4656.             prompt := string_arg.get_argument 
  4657.                 (processes(library_manager),
  4658.                 "prompt");
  4659.             s_code := Library_Manager_Interface(lib, prompt);
  4660.             SI.redefine_process (processes(library_manager));
  4661.         end case;
  4662.     exception
  4663.         when constraint_error =>
  4664.         TIO.put_line ("Constraint error");
  4665.         SI.redefine_process(processes(cmd));
  4666.             SP.release;
  4667.         when SI.process_help =>
  4668.         null;
  4669.          when SI.abort_process =>
  4670.         null;
  4671.         when SI.abort_command =>
  4672.         TIO.new_line(1);
  4673.         TIO.put ("Errors in command.  Enter command name with no");
  4674.         TIO.put_line ("parameters for help");
  4675.         when SI.command_help =>
  4676.         null;
  4677.         when SI.command_exit =>
  4678.         Exit;
  4679.         when SI.no_command =>
  4680.         TIO.put_line ("Enter 'help' for information about the commands");
  4681.         when CM.invalid_password =>
  4682.         TIO.put_line ("Sorry, you are not a privileged user.");
  4683.         SI.redefine_process(processes(cmd));
  4684.             SP.release;
  4685.         when CM.cant_lock =>
  4686.         TIO.put_line ("The catalog cannot be locked for that " &
  4687.             "operation, try again later");
  4688.         SI.redefine_process(processes(cmd));
  4689.             SP.release;
  4690.         when CM.no_lock =>
  4691.         TIO.put_line ("That lock doesn't exist");
  4692.         SI.redefine_process(processes(cmd));
  4693.             SP.release;
  4694.         when CM.library_locked =>
  4695.         TIO.put_line ("The library is locked against this operation");
  4696.         SI.redefine_process(processes(cmd));
  4697.             SP.release;
  4698.         when CM.no_such_ci =>
  4699.         TIO.put_line ("The named CI does not exist in this Catalog");
  4700.         SI.redefine_process(processes(cmd));
  4701.             SP.release;
  4702.         when CM.already_fetched =>
  4703.         TIO.put_line ("The CI named has already been fetched for update");
  4704.         SI.redefine_process(processes(cmd));
  4705.             SP.release;
  4706.         when CM.already_updated =>
  4707.         TIO.put_line ("An update already exists for the given CI");
  4708.         SI.redefine_process(processes(cmd));
  4709.             SP.release;
  4710.         when CM.invalid_ci_id =>
  4711.         TIO.put_line ("The format of the CI id is incorrect");
  4712.         SI.redefine_process(processes(cmd));
  4713.             SP.release;
  4714.         when CM.invalid_ci_name =>
  4715.         TIO.put_line ("The name of the CI is not an ada identifier");
  4716.         SI.redefine_process(processes(cmd));
  4717.         SP.release;
  4718.         when CM.incorrect_person =>
  4719.         TIO.put_line ("You are not authorized to store or cancel this"
  4720.             & " fetch");
  4721.         SI.redefine_process(processes(cmd));
  4722.             SP.release;
  4723.         when CM.is_checked_out =>
  4724.         TIO.put_line ("The CI named is fetched and cannot be deleted");
  4725.         SI.redefine_process(processes(cmd));
  4726.             SP.release;
  4727.         when CM.deleted_ci =>
  4728.         TIO.put_line ("You cannot fetch a CI that has been deleted");
  4729.         SI.redefine_process(processes(cmd));
  4730.             SP.release;
  4731.         when CM.incomplete_store =>
  4732.         TIO.put_line ("The store for this CI was not completed.");
  4733.         TIO.put_line ("Before fetching the store must be fixed up by"
  4734.             & " deleting and retrying the store");
  4735.         SI.redefine_process(processes(cmd));
  4736.             SP.release;
  4737.         when CM.invalid_key_or_val =>
  4738.         TIO.put_line ("One of the keyword or value is invalid");
  4739.         SI.redefine_process(processes(cmd));
  4740.             SP.release;
  4741.         when CM.required_keyword =>
  4742.         TIO.put_line ("You cannot modify a required property to " &
  4743.                 "have no value");
  4744.         SI.redefine_process(processes(cmd));
  4745.             SP.release;
  4746.         when CM.ci_not_fetched =>
  4747.         TIO.put_line ("No CI with this name was fetched from the"
  4748.             & " catalog");
  4749.         SI.redefine_process(processes(cmd));
  4750.             SP.release;
  4751.         when CM.invalid_mode =>
  4752.         TIO.put_line ("This is an invalid or corrupted library"
  4753.             & " because its mode is unknown");
  4754.         SI.redefine_process(processes(cmd));
  4755.             SP.release;
  4756.         when CM.update_already_exists =>
  4757.         TIO.put_line ("The update to this CI already exists.  If you" &
  4758.             " validly fetched it from this catalog,");
  4759.         TIO.put_line ("you will have to fetch the new update to " &
  4760.             "compare with yours, and store the appropriate");
  4761.         TIO.put_line ("contents.  Don't forget to cancel the old " &
  4762.             "library so you can delete it");
  4763.         SI.redefine_process(processes(cmd));
  4764.             SP.release;
  4765.         when CM.library_nonexistent =>
  4766.         TIO.put_line ("The given library does not exist.");
  4767.         SI.redefine_process(processes(cmd));
  4768.         SP.release;
  4769.         when CM.invalid_library =>
  4770.         TIO.put_line ("The given library name is invalid.");
  4771.         SI.redefine_process(processes(cmd));
  4772.         SP.release;
  4773.         when ID.invalid_ci_id =>
  4774.         TIO.put_line ("The format of the CI id is incorrect");
  4775.         SI.redefine_process(processes(cmd));
  4776.             SP.release;
  4777.         when IM.invalid_keyword =>
  4778.         TIO.put_line ("The keyword given is either not a valid one " &
  4779.             "or it is not an ada identifier");
  4780.         SI.redefine_process(processes(cmd));
  4781.             SP.release;
  4782.         when IM.invalid_value =>
  4783.         TIO.put_line ("The value given is either not a valid one " &
  4784.             "or it is not an ada identifier");
  4785.         SI.redefine_process(processes(cmd));
  4786.             SP.release;
  4787.         when CL.unauthorized | CL.lock_doesnt_exist =>
  4788.         TIO.put_line ("Your locks have been lost. ");
  4789.         TIO.put_line ("Please exit the catalog and restart your " &
  4790.             "session.");
  4791.         SI.redefine_process(processes(cmd));
  4792.             SP.release;
  4793.         when LD.directory_already_exists =>
  4794.         TIO.put_line ("The given directory already exists. The " &
  4795.             " catalog cannot");
  4796.         TIO.put_line ("create a library there.");
  4797.         SI.redefine_process(processes(cmd));
  4798.             SP.release;
  4799.         when LD.library_already_exists =>
  4800.         TIO.put_line ("A library with that name already exists.  " &
  4801.             "Please try with another name");
  4802.         SI.redefine_process(processes(cmd));
  4803.             SP.release;
  4804.         when LD.invalid_directory_name =>
  4805.         TIO.put_line ("The specification of the directory is " &
  4806.             "incorrect");
  4807.         SI.redefine_process(processes(cmd));
  4808.             SP.release;
  4809.     end;
  4810.     end loop;            
  4811.     TIO.put_line ("Exiting the catalog manager");
  4812. end command_interpreter;
  4813.  
  4814. procedure init_processes (processes : in out SC.process_handle_array) is
  4815.  
  4816.  
  4817. begin
  4818. -- do not define process help since the standard interface will do what you 
  4819. -- want.
  4820. --    SI.define_process ("help",
  4821. --               "General help about the catalog",
  4822. --               processes(help));
  4823. --    -- help has no parameters
  4824. --    SI.append_process_help (processes(help),
  4825. --    "The catalog is an interactive tool that allows a user to select");
  4826. --    SI.append_process_help (processes(help),
  4827. --    "configuration items (CIs) according certain properties, and then to");
  4828. --    SI.append_process_help (processes(help),
  4829. --    "get more information about each CI.  The user can then having");
  4830. --    SI.append_process_help (processes(help),
  4831. --    "picked a certain CI fetch it for study or modification.  The ");
  4832. --    SI.append_process_help (processes(help),
  4833. --    "commands recognised are: help, done, clear_selected_set, print_set");
  4834. --    SI.append_process_help (processes(help),
  4835. --    "list_cis, change_password *, define_keyword *, list_keywords,");
  4836. --    SI.append_process_help (processes(help),
  4837. --    "create_ci, store, fetch, cancel, delete *, modify_property, ");
  4838. --    SI.append_process_help (processes(help),
  4839. --    "describe, history, list_versions, list_components, remove_lock *. ");
  4840. --    SI.append_process_help (processes(help),
  4841. --     "The words followed by '*' are privileged operation for which you");
  4842. --    SI.append_process_help (processes(help),
  4843. --    "need to know the catalog password.  Operations not described here");
  4844. --    SI.append_process_help (processes(help),
  4845. --    "will give more help if entered with no parameters.  ");
  4846. --    SI.append_process_help (processes(help),
  4847. --    "Help puts out this message, done exits the user from the catalog,");
  4848. --    SI.append_process_help (processes(help),
  4849. --    "clear_selected_set empties the current set, print_set will print ");
  4850. --    SI.append_process_help (processes(help),
  4851. --    "the current_set, change_password prompts for a new password,");
  4852. --    SI.append_process_help (processes(help),
  4853. --    "and list_keywords lists the keywords and their current status.");
  4854.  
  4855.  
  4856.     SI.define_process ("select_cis",
  4857.                "Selects a set of CIs according to"
  4858.             & " the selection criteria given",
  4859.                processes(select_cis));
  4860.     -- define select_cis parameters
  4861.     string_arg.define_argument (processes(select_cis),
  4862.                 "criteria",
  4863.                 "A string in selection syntax giving the " &
  4864.     "criteria to");
  4865.     string_arg.append_argument_help (processes(select_cis),
  4866.                      "criteria",
  4867.     "select by.  The operators recognized are & and |.  Parentheses");
  4868.     string_arg.append_argument_help (processes(select_cis),
  4869.                      "criteria",
  4870.     "can be used to indicate precedence.  & does intersections,");
  4871.     string_arg.append_argument_help (processes(select_cis),
  4872.                      "criteria",
  4873.     "and | does unions. The expressions are evaluated from left");
  4874.     string_arg.append_argument_help (processes(select_cis),
  4875.                      "criteria",
  4876.                      "to right");
  4877.  
  4878.     SI.define_process ("clear_selected_set",
  4879.                "Make the current selected set be the empty set.",
  4880.                processes(clear_selected_set));
  4881.     -- clear_selected_set has no parameters
  4882.  
  4883.     SI.define_process ("print_set",
  4884.                "Print the contents of the currently selected set.",
  4885.                processes(print_set));
  4886.     -- print_set has no parameters
  4887.  
  4888.     SI.define_process ("list_cis",
  4889.                "Lists the contents of the catalog by name.",
  4890.                processes(list_cis));
  4891.     -- define list catalog argument
  4892.     string_arg.define_argument (processes(list_cis),
  4893.                 "cis",
  4894.                 "*",
  4895.                 "Name string to match, * matches all strings");
  4896.     SI.define_help (processes(list_cis),
  4897.     "This will only list the name part of a configuration item id. To");
  4898.     SI.append_help (processes(list_cis),
  4899.     "see the different versions of a CI use LIST_VERSIONS.");
  4900.  
  4901.     SI.define_process ("change_password",
  4902.                "Changes the privileged user password.",
  4903.                processes(change_password));
  4904.     SI.append_process_help (processes(change_password),
  4905.                 "This is a privileged operation");
  4906.     -- change_password could have parameters, but it would be a security hole.
  4907.     SI.define_help (processes(change_password),
  4908.     "To change the password the user must know the old password.");
  4909.     SI.append_help (processes(change_password),
  4910.     "The user will prompted for the old password and then the new");
  4911.     SI.append_help (processes(change_password),
  4912.     "password twice to verify that it was typed correctly.");
  4913.  
  4914.     SI.define_process ("define_keyword",
  4915.                "Define a new keyword, or change the status of an",
  4916.                processes(define_keyword));
  4917.     SI.append_process_help (processes(define_keyword),
  4918.                 "existing one.");
  4919.     SI.append_process_help (processes(define_keyword),
  4920.                 "This is a privileged operation");
  4921.     string_arg.define_argument (processes(define_keyword),
  4922.                 "keyword",
  4923.                 "name of the keyword to define");
  4924.     status_arg.define_argument (processes(define_keyword),
  4925.                 "status",
  4926.                 IM.optional,
  4927.                  "status of the keyword");
  4928.     SI.define_help (processes(define_keyword),
  4929.     "Keywords are defined so that information about CIs can be stored");
  4930.     SI.append_help (processes(define_keyword),
  4931.     "in the database.  A required keyword must always be included on");
  4932.     SI.append_help (processes(define_keyword),
  4933.     "any CI stored.  Optional keywords are just that, optional.");
  4934.     SI.append_help (processes(define_keyword),
  4935.     "Invalid keywords are ones that may at one time have been valid,");
  4936.     SI.append_help (processes(define_keyword),
  4937.     "but can no longer be used to store CIs.  They can still be used");
  4938.     SI.append_help (processes(define_keyword),
  4939.     "for lookup since CIs added with a keyword before it was made ");
  4940.     SI.append_help (processes(define_keyword),
  4941.     "invalid are not changed.");
  4942.  
  4943.     SI.define_process ("list_keywords",
  4944.                "List all the keywords and their status.",
  4945.                processes(list_keywords));
  4946.     SI.define_help (processes(list_keywords),
  4947.     "The possible values for the status of a keyword are REQUIRED,");
  4948.     SI.append_help (processes(list_keywords),
  4949.     "OPTIONAL and INVALID.  REQUIRED keywords mean that a property");
  4950.     SI.append_help (processes(list_keywords),
  4951.     "with that keyword must be on all libraries being stored in the");
  4952.     SI.append_help (processes(list_keywords),
  4953.     "catalog as CIs.  OPTIONAL keywords mean a library with that");
  4954.     SI.append_help (processes(list_keywords),
  4955.     "property may be stored in the catalog.  A library can not be");
  4956.     SI.append_help (processes(list_keywords),
  4957.     "stored with an INVALID property keyword.  CIs may be selected");
  4958.     SI.append_help (processes(list_keywords),
  4959.     "by any keyword (see SELECT_CIS).");
  4960.     -- list keywords has no parameters
  4961.  
  4962.     SI.define_process ("create_ci",
  4963.                "create a new configuration item (CI) in the catalog",
  4964.                processes(create_ci));
  4965.     ci_arg.define_argument (processes(create_ci),
  4966.                 "name",
  4967.                 "Name of the new ci to create");
  4968.     string_arg.define_argument (processes(create_ci),
  4969.                 "library",
  4970.                 "Name of the item library to"
  4971.                  & " create the CI from");
  4972.     string_arg.define_argument (processes(create_ci),
  4973.                 "history",
  4974.                 "Brief description of the new CI");
  4975.     SI.define_help (processes(create_ci),
  4976.     "Any errors encountered will be reported to the user and the");
  4977.     SI.append_help (processes(create_ci),
  4978.     "creation will not take place.  In addition to having the correct");
  4979.     SI.append_help (processes(create_ci),
  4980.     "status, the keywords on the library must be both valid, and");
  4981.     SI.append_help (processes(create_ci),
  4982.     "include all the required ones.  The history parameter will be");
  4983.     SI.append_help (processes(create_ci),
  4984.     "stored on the new CI along with the creator and date.  This");
  4985.     SI.append_help (processes(create_ci),
  4986.     "information can be seen with the HISTORY command.");
  4987.  
  4988.     SI.define_process ("store",
  4989.                "Store a new version of an already existing CI",
  4990.                processes(store));
  4991.     string_arg.define_argument (processes(store),
  4992.                 "library",
  4993.                 "Name of the item library to get the CI from");
  4994.     string_arg.define_argument (processes(store),
  4995.                 "history",
  4996.                 "Description of the changes made"
  4997.                   & " to the new CI");
  4998.     SI.define_help (processes(store),
  4999.     "Any errors encountered will be reported to the user and the");
  5000.     SI.append_help (processes(store),
  5001.     "store will not take place.  In addition to being fetched");
  5002.     SI.append_help (processes(store),
  5003.     "correctly, the keywords on the library must be both valid,");
  5004.     SI.append_help (processes(store),
  5005.     "and include all the required ones.  The history parameter will");
  5006.     SI.append_help (processes(store),
  5007.     "be stored along with the creator and date and can be accessed");
  5008.     SI.append_help (processes(store),
  5009.     "with the history command.");
  5010.  
  5011.     SI.define_process ("fetch",
  5012.                "Fetch a specified CI and put it in an item library.",
  5013.                processes(fetch));
  5014.     ci_arg.define_argument (processes(fetch),
  5015.                 "name",
  5016.                 "Name of the ci to fetch");
  5017.     string_arg.define_argument (processes(fetch),
  5018.                 "library",
  5019.                 "Name of the item library to put the CI in");
  5020.     string_arg.define_argument (processes(fetch),
  5021.                 "directory",
  5022.                 "Name of the directory to create the item" &
  5023.                 "library in");
  5024.     fetch_arg.define_argument (processes(fetch),
  5025.                    "mode",
  5026.                    LD.no_update,
  5027.                    "Indicates what type of update the fetch"
  5028.                   & " is allowing");
  5029.     SI.define_help (processes(fetch),
  5030.     "Fetch will put a specified CI in an item library for the user.");
  5031.     SI.append_help (processes(fetch),
  5032.     "If the mode is UPDATE or BRANCH the user can modify the CI and");
  5033.     SI.append_help (processes(fetch),
  5034.     "STORE it as a new version.  If the mode is NO_UPDATE (default)");
  5035.     SI.append_help (processes(fetch),
  5036.     "the user is still free to modify the library, but it may NOT be");
  5037.     SI.append_help (processes(fetch),
  5038.     "returned to the catalog as a new version.  When a CI is fetched");
  5039.     SI.append_help (processes(fetch),
  5040.     "for UPDATE checks are made to make sure that no one else is");
  5041.     SI.append_help (processes(fetch),
  5042.     "updating the same CI");
  5043.  
  5044.     SI.define_process ("cancel",
  5045.                "Cancel a fetch that was made with the mode update",
  5046.                processes(cancel));
  5047.     string_arg.define_argument (processes(cancel),
  5048.                 "library",
  5049.                 "Name of the item library the fetched"
  5050.                   & " CI is in");
  5051.     string_arg.define_argument (processes(cancel),
  5052.                 "user",
  5053.                 HL.get_item(HL.user_name),
  5054.                 "Name of the person who did the fetch");
  5055.     string_arg.append_argument_help (processes(cancel),
  5056.                 "user",
  5057.                 "Default is the current user");
  5058.     SI.define_help (processes(cancel),
  5059.     "Any user can cancel a fetch that he or she made, but only a");
  5060.     SI.append_help (processes(cancel),
  5061.     "privileged user may cancel someone else's.  So if the name given");
  5062.     SI.append_help (processes(cancel),
  5063.     "does not match the current user the catalog password will be ");
  5064.     SI.append_help (processes(cancel),
  5065.     "asked for.");
  5066.  
  5067.     SI.define_process ("delete",
  5068.                "Delete a configuration item that is in the catalog.",
  5069.                 processes(delete));
  5070.     SI.append_process_help (processes(delete),
  5071.                 "This is a privileged operation.");
  5072.     ci_arg.define_argument (processes(delete),
  5073.                 "name",
  5074.                 "Name of the configuration item to delete");
  5075.     delete_arg.define_argument (processes(delete),
  5076.                 "mode",
  5077.                 CM.clean_up,
  5078.                 "What type of delete is to be done");
  5079.     SI.define_help (processes(delete),
  5080.     "There are two types of deletion that may take place.  Deletion of a");
  5081.     SI.append_help (processes(delete),
  5082.     "CI that is out of date and not needed, and deletion of a CI where");
  5083.     SI.append_help (processes(delete),
  5084.     "the store only partially completed for some reason.  The former is");
  5085.     SI.append_help (processes(delete),
  5086.     "clean_up and the latter is fix_up.  When cleaning up, the catalog ");
  5087.     SI.append_help (processes(delete),
  5088.     "manager checks that the CI is not currently fetched.  In fix up the");
  5089.     SI.append_help (processes(delete),
  5090.     "store was incomplete and so by definition the CI will still appear");
  5091.     SI.append_help (processes(delete),
  5092.     "to be fetched.");
  5093.  
  5094.     SI.define_process ("modify_property",
  5095.                       "Modify the value associated with the given keyword",
  5096.                processes(modify_property));
  5097.     SI.append_process_help (processes(modify_property),
  5098.             "on the specified CI");
  5099.     ci_arg.define_argument (processes(modify_property),
  5100.                    "name",
  5101.                 "Name of the CI with the property to be"
  5102.                   & " changed");
  5103.     string_arg.define_argument (processes(modify_property),
  5104.                 "keyword",
  5105.                 "name of the keyword to change the value of");
  5106.     string_arg.define_argument (processes(modify_property),
  5107.                 "value",
  5108.                 "New value for the keyword");
  5109.     SI.define_help (processes(modify_property),
  5110.     "Modify_property will change the value associated with a keyword");
  5111.     SI.append_help (processes(modify_property),
  5112.     "on a CI.  The property can not be added if the keyword is");
  5113.     SI.append_help (processes(modify_property),
  5114.     "invalid and a property can not be removed if it is required.");
  5115.     SI.append_help (processes(modify_property),
  5116.     "To remove a property simply give it a null string for a new");
  5117.     SI.append_help (processes(modify_property),
  5118.     "value.  This change has no effect on other CIs with the same");
  5119.     SI.append_help (processes(modify_property),
  5120.     "name.");
  5121.  
  5122.     SI.define_process ("describe",
  5123.                "Show the values of the given keywords",
  5124.                processes(describe));
  5125.     ci_arg.define_argument (processes(describe),
  5126.                 "name",
  5127.                 "Name of the CI to describe");
  5128.     s_list_arg.define_argument (processes(describe),
  5129.                 "keywords",
  5130.                 SL.makelist (SP.create ("*")),
  5131.                 "List of keywords to lookup the values of");
  5132.     s_list_arg.append_argument_help (processes(describe),
  5133.                      "keywords",
  5134.      "The default (*) matches all properties on a CI");
  5135.     SI.define_help (processes(describe),
  5136.     "Describe does not list the creator or creation date see HISTORY");
  5137.     SI.append_help (processes(describe),
  5138.     "for that information.");
  5139.  
  5140.     SI.define_process ("history",
  5141.                "Give the history of the named CI",
  5142.                processes(history));
  5143.     ci_arg.define_argument (processes(history),
  5144.                 "name",
  5145.                 "Name of the CI of which to give the history");
  5146.     SI.define_help (processes(history),
  5147.     "The history of a CI is the history comments stored when each of its");
  5148.     SI.append_help (processes(history),
  5149.     "predecessors was stored.  The comments will be printed out in ");
  5150.     SI.append_help (processes(history),
  5151.     "reverse order, that is, from the most recent version to the first");
  5152.     SI.append_help (processes(history),
  5153.     "version of the CI with that name.");
  5154.  
  5155.     SI.define_process ("list_versions",
  5156.                "List the versions of a named CI",
  5157.                processes(list_versions));
  5158.     string_arg.define_argument (processes(list_versions),
  5159.                    "name",
  5160.                 "Name of the CI to list");
  5161.     SI.define_help (processes(list_versions),
  5162.     "LIST_VERSIONS lists the versions of a CI with the same name.  The");
  5163.     SI.append_help (processes(list_versions),
  5164.     "name given should be an ada identifier.  The list will be from");
  5165.     SI.append_help (processes(list_versions),
  5166.     "oldest to newest.");
  5167.  
  5168.     SI.define_process ("list_components",
  5169.                "List the components of the given CI",
  5170.                processes(list_components));
  5171.     ci_arg.define_argument (processes(list_components),
  5172.                    "name",
  5173.                 "Name of the CI to list");
  5174.     SI.define_help (processes(list_components),
  5175.     "The listing will consist of the file items that make up the");
  5176.     SI.append_help (processes(list_components),
  5177.     "CI.  It will be in the same format as a component list from");
  5178.     SI.append_help (processes(list_components),
  5179.     "the Item Library Manager");
  5180.  
  5181.     SI.define_process ("remove_lock",
  5182.                "Remove a lock that was left by a user aborting" 
  5183.             & " a session",
  5184.                processes(remove_lock));
  5185.     SI.append_process_help (processes(remove_lock),
  5186.                 "This is a privileged operation");
  5187.     string_arg.define_argument (processes(remove_lock),
  5188.                 "name",
  5189.                 "Name of the person owning the lock");
  5190.     lock_arg.define_argument (processes(remove_lock),
  5191.                   "lock",
  5192.                   "Type of lock that is to be removed");
  5193.     -- Note: the following two arguments default because for the time being
  5194.     -- they are completely useless.  If and when locking on a node by node
  5195.     -- basis is done both of these parameters will have to be specified.
  5196.     -- It may be that "current_catalog" and catalog are reasonable defaults
  5197.     -- (this is what I hope) in which case this interface won't have to be
  5198.     -- changed.  But it is important to realize that in the code I will 
  5199.     -- write these two variables will not even be looked at  and they can
  5200.     -- be nonsense as far as I'm concerned.  The reason for putting in these
  5201.     -- parameters now is so that the interfaces do not need to be changed
  5202.     -- (or changed minimally) if the node by node looking is done.
  5203.     string_arg.define_argument (processes(remove_lock),
  5204.                 "node_name", 
  5205.                 "current_catalog",
  5206.                 "Name of the node to be unlocked");
  5207.     node_arg.define_argument (processes(remove_lock),
  5208.                   "node",
  5209.                   CM.catalog_node,
  5210.                   "Type of node to be unlocked");
  5211.  
  5212.     SI.define_process ("library_manager",
  5213.                "Interactive Library Manager",
  5214.                processes(library_manager));
  5215.     lib_name.define_argument (processes(library_manager),
  5216.                   "library",
  5217.                   "Name of the item library");
  5218.     string_arg.define_argument (processes(library_manager),
  5219.                 "prompt",
  5220.                 "",
  5221.                 "Prompt (null string implies library name)");
  5222.  
  5223.     end init_processes;
  5224.  
  5225. procedure print_list (list : in SL.list) is
  5226.   i : SL.listiter;
  5227.   s : SP.string_type;
  5228.   begin
  5229.     i := SL.makelistiter (list);
  5230.     while SL.more (i) loop
  5231.       SL.next (i, s);
  5232.       text_io.put_line (SP.value (s));
  5233.     end loop;
  5234.   end print_list;
  5235.  
  5236. procedure print_sel_set (set : in CD.ci_set) is
  5237.  
  5238. package ci_sets renames catalog_decls.ci_sets;
  5239.  
  5240.   i : ci_sets.members_iter;
  5241.   c : ID.ci_id_type;
  5242.   begin
  5243.     i := ci_sets.make_members_iter (set);
  5244.     while ci_sets.more (i) loop
  5245.       ci_sets.next (i, c);
  5246.       text_io.put_line (ID.image(c));
  5247.     end loop;
  5248.   end print_sel_set;
  5249.  
  5250. procedure print_string_set (
  5251.     set : in CD.string_set
  5252.     ) is
  5253.  
  5254. package SS renames catalog_decls.string_sets;
  5255.  
  5256.   i : SS.members_iter;
  5257.   s : SP.string_type;
  5258.   begin
  5259.     i := SS.make_members_iter (set);
  5260.     while SS.more (i) loop
  5261.       SS.next (i, s);
  5262.       text_io.put_line (SP.value(s));
  5263.     end loop;
  5264.   end print_string_set;
  5265.  
  5266. procedure print_property_set (
  5267.     set : in PS.set
  5268.     ) is
  5269.  
  5270.   i : PS.setiter;
  5271.   p : properties.property;
  5272.   begin
  5273.     i := PS.makesetiter (set);
  5274.     while PS.more (i) loop
  5275.       PS.next (i, p);
  5276.       text_io.put_line (properties.image(p));
  5277.     end loop;
  5278.   end print_property_set;
  5279.  
  5280. procedure print_item_list (
  5281.     set : in LD.LL.list 
  5282.     ) is
  5283.   i : LD.LL.listiter;
  5284.   l : SL.list;
  5285.   begin
  5286.     i := LD.LL.makelistiter (set);
  5287.     while LD.LL.more (i) loop
  5288.       LD.LL.next (i, l);
  5289.       text_io.put_line (SP.value (SL.firstvalue (l)));
  5290.     end loop;
  5291.   end print_item_list;
  5292.  
  5293. procedure print_hist_list (
  5294.     list : in  CD.hist_list
  5295.     ) is
  5296.   package CHL renames CD.hist_lists;
  5297.   i : CHL.listiter;
  5298.   h : CD.hist_record;
  5299.   begin
  5300.   i := CHL.makelistiter(list);
  5301.   while CHL.more (i) loop
  5302.     CHL.next (i, h);
  5303.     text_io.put_line ("Name      : " & SP.value (h.name));
  5304.     text_io.put_line ("Creator   : " & SP.value (h.creator));
  5305.     text_io.put_line ("Date      : " & SP.value (h.date));
  5306.     text_io.put_line ("History   : " & SP.value (h.history));
  5307.     text_io.put_line ("Submitter : " & SP.value (h.submit));
  5308.     if not SP.is_empty (h.delete) then
  5309.       text_io.put_line ("Deleted by " & SP.value (h.delete));
  5310.     end if;
  5311.   end loop;
  5312.   end print_hist_list;
  5313.  
  5314. procedure print_errors is
  5315.  
  5316. error : CM.error_type;
  5317.  
  5318.     begin
  5319.         for error in CM.error_type'first .. CM.error_type'last loop
  5320.         if CM.errors(error) = true then
  5321.         case error is
  5322.         when CM.required =>
  5323.             TIO.put_line(SP.value(CM.messages(error)));
  5324.             -- loop putting out the contents of required
  5325.             print_string_set (CM.missing);
  5326.         when CM.person =>
  5327.             TIO.put_line (SP.value(CM.messages(error))
  5328.             & SP.value(CM.fetchee));
  5329.         when CM.keywords =>
  5330.             TIO.put_line(SP.value(CM.messages(error)));
  5331.             print_list (CM.invalid);
  5332.         when others =>
  5333.             TIO.put_line(SP.value(CM.messages(error)));
  5334.         end case;
  5335.         end if;
  5336.     end loop;
  5337.     CM.errors := (others => false);
  5338.     CD.string_sets.destroy (CM.missing);
  5339.     CM.invalid := CM.empty_list;
  5340.     end;
  5341.  
  5342. end interpret;
  5343.  
  5344. ::::::::::::::
  5345. command.spc
  5346. ::::::::::::::
  5347. package interpret is
  5348.  
  5349. --| Overview: This package contains the procedure to interpret the commands
  5350. --| entered by the user.
  5351.  
  5352. procedure command_interpreter;
  5353.  
  5354. --| Effects: prompts for and interprets the commands entered by the user.
  5355. --| When a command has been interpreted it calls the appropriate catalog
  5356. --| subprogram to make the changes, or provide the information asked for.
  5357.  
  5358. end interpret;
  5359. ::::::::::::::
  5360. copyl.ada
  5361. ::::::::::::::
  5362. with Standard_Interface;
  5363. with String_Pkg;
  5364. with Host_Lib;
  5365. with Tool_Identifier;
  5366. with Library_Errors;
  5367. with Library_Declarations;
  5368. with Copy_Library_Interface;
  5369.  
  5370. function Copy_Library return INTEGER is
  5371.  
  5372.     package SI  renames Standard_Interface;
  5373.     package SP  renames String_Pkg;
  5374.     package HL  renames Host_Lib;
  5375.     package LE  renames Library_Errors;
  5376.     package LD  renames Library_Declarations;
  5377.     package LIB is new SI.String_Argument(String_Type_Name => "library_name");
  5378.     package DIR is new SI.String_Argument(String_Type_Name => "directory_spec");
  5379.     package CLM is new SI.Enumerated_Argument(Enum_Type      => LD.Copy_Mode,
  5380.                           Enum_Type_Name => "copy_mode");
  5381.  
  5382.     Copy_Library_Process   : SI.Process_Handle;
  5383.     To_Library             : SP.String_Type;
  5384.     Directory              : SP.String_Type;
  5385.     From_Library           : SP.String_Type;
  5386.     Copy_Library_Mode      : LD.Copy_Mode;
  5387.  
  5388. begin
  5389.  
  5390.     SP.Mark;
  5391.  
  5392.     SI.Set_Tool_Identifier(Identifier => Tool_Identifier);
  5393.  
  5394.     SI.Define_Process(
  5395.     Proc    => Copy_Library_Process,
  5396.     Name    => "Copy_Library",
  5397.     Help    => "Copy an Item Library to Another Item Library");
  5398.  
  5399.     LIB.Define_Argument(
  5400.     Proc => Copy_Library_Process,
  5401.     Name => "From_Library",
  5402.     Help => "Name of the item library to be copied");
  5403.  
  5404.     LIB.Define_Argument(
  5405.     Proc => Copy_Library_Process,
  5406.     Name => "To_Library",
  5407.     Help => "Name of the new item library");
  5408.  
  5409.     DIR.Define_Argument(
  5410.     Proc => Copy_Library_Process,
  5411.     Name => "to_directory",
  5412.     Help => "Name of directory to be used by the new library");
  5413.  
  5414.     CLM.Define_Argument(
  5415.     Proc    => Copy_Library_Process,
  5416.     Name    => "mode",
  5417.     Default => LD.CURRENT,
  5418.     Help    => "Copy option:");
  5419.  
  5420.     CLM.Append_Argument_Help(
  5421.     Proc    => Copy_Library_Process,
  5422.     Name    => "mode",
  5423.     Help    => "   CURRENT : copy only the current version of items");
  5424.  
  5425.     CLM.Append_Argument_Help(
  5426.     Proc    => Copy_Library_Process,
  5427.     Name    => "mode",
  5428.     Help    => "   FULL    : copy all versions of items");
  5429.  
  5430.     SI.Parse_Line(Copy_Library_Process);
  5431.  
  5432.     From_Library := LIB.Get_Argument(
  5433.             Proc => Copy_Library_Process,
  5434.             Name => "From_Library");
  5435.  
  5436.     To_Library := LIB.Get_Argument(
  5437.             Proc => Copy_Library_Process,
  5438.             Name => "To_Library");
  5439.  
  5440.     Directory := DIR.Get_Argument(
  5441.             Proc => Copy_Library_Process,
  5442.             Name => "to_directory");
  5443.  
  5444.     Copy_Library_Mode := CLM.Get_Argument(
  5445.             Proc => Copy_Library_Process,
  5446.             Name => "mode");
  5447.  
  5448.     return HL.Return_Code(
  5449.     Copy_Library_Interface(From_Library, To_Library, Directory, Copy_Library_Mode));
  5450.  
  5451. exception
  5452.  
  5453.     when SI.Process_Help =>
  5454.     return HL.Return_Code(HL.INFORMATION);
  5455.  
  5456.     when SI.Abort_Process =>
  5457.     return HL.Return_Code(HL.ERROR);
  5458.  
  5459.     when others =>
  5460.     LE.Report_Error(LE.Internal_Error, SP.Create(""));
  5461.     return HL.Return_Code(HL.SEVERE);
  5462.  
  5463. end Copy_Library;
  5464.                                                                     pragma page;
  5465. ::::::::::::::
  5466. copyl.bdy
  5467. ::::::::::::::
  5468. with Library_Declarations;            use Library_Declarations;
  5469. with Library_Errors;
  5470. with Library_Utilities;
  5471. with HIF_Node_Defs;
  5472. with HIF_Node_Management;
  5473. with HIF_Attributes;
  5474. with HIF_List_Utils;
  5475.  
  5476. function Copy_Library_Interface(
  5477.     From_Library : in String_Pkg.String_Type;
  5478.     To_Library   : in String_Pkg.String_Type;
  5479.     To_Directory : in String_Pkg.String_Type;
  5480.     Mode         : in Copy_Mode := CURRENT
  5481.     ) return Host_Lib.Severity_Code is
  5482.  
  5483.     package SP  renames String_Pkg;
  5484.     package HL  renames Host_Lib;
  5485.     package LE  renames Library_Errors;
  5486.     package LU  renames Library_Utilities;
  5487.     package HND renames HIF_Node_Defs;
  5488.     package HNM renames HIF_Node_Management;
  5489.     package HA  renames HIF_Attributes;
  5490.     package HLU renames HIF_List_Utils;
  5491.  
  5492.     Library_Node     : HND.Node_Type;
  5493.     IL_Node          : HND.Node_Type;
  5494.     Iterator         : HA.Attrib_Iterator;
  5495.     Property_List    : HLU.List_Type;
  5496.     Attribute_Value  : STRING(1 .. 64);
  5497.     Attribute_Length : INTEGER;
  5498.     List_of_Lists    : LL.List;
  5499.     Trap             : HL.Interrupt_State := HL.Get_Interrupt_State;
  5500.  
  5501. begin
  5502.  
  5503.     if HL."="(Trap, HL.DISABLED) then
  5504.     HL.Enable_Interrupt_Trap;
  5505.     end if;
  5506.     begin
  5507.     if not LU.Lock_Library(From_Library, READ_LOCK) then
  5508.         LE.Report_Error(LE.Library_Read_Locked, From_Library);
  5509.         HL.Set_Interrupt_State(Trap);
  5510.         return HL.ERROR;
  5511.     end if;
  5512.     exception
  5513.     when Invalid_Library_Name =>
  5514.         LE.Report_Error(LE.Invalid_Library_Name, From_Library);
  5515.         HL.Set_Interrupt_State(Trap);
  5516.         return HL.ERROR;
  5517.     when Library_Does_Not_Exist =>
  5518.         LE.Report_Error(LE.Library_Does_Not_Exist, From_Library);
  5519.         HL.Set_Interrupt_State(Trap);
  5520.         return HL.ERROR;
  5521.     when Library_Master_Locked =>
  5522.         LE.Report_Error(LE.Library_Master_Locked, From_Library);
  5523.         HL.Set_Interrupt_State(Trap);
  5524.         return HL.ERROR;
  5525.     end;
  5526.     if LU.Is_Item_Checked_Out(From_Library) then
  5527.     LU.Unlock_Library(From_Library, READ_LOCK);
  5528.     LE.Report_Error(LE.Library_Incomplete, From_Library);
  5529.         HL.Set_Interrupt_State(Trap);
  5530.     return HL.ERROR;
  5531.     end if;
  5532.  
  5533.     HNM.Open_Node_Handle(Library_Node, 
  5534.              SP.Value(LU.Node_Name(From_Library, SP.Create("*"))));
  5535.     LU.Create_Library(Library   => To_Library,
  5536.               Directory => To_Directory,
  5537.               Mode      => NO_UPDATE,
  5538.               Node      => Library_Node,
  5539.               Locked    => TRUE);
  5540.     HNM.Close_Node_Handle(Library_Node);
  5541.     LU.Unlock_Library(From_Library, READ_LOCK);
  5542.     if Mode = CURRENT then
  5543.     LU.Purge(Library   => To_Library,
  5544.          Privilege => WORLD,
  5545.          Remainder => List_of_Lists);
  5546.     end if;
  5547.  
  5548.     begin
  5549.     LU.Open_Property_Node(To_Library, SP.Create(""), SP.Create(""), LIST, IL_Node);
  5550.     HA.Node_Attribute_Iterate(Iterator, IL_Node, "*");
  5551.     while HA.More(Iterator) loop
  5552.         HA.Get_Next(Iterator, Attribute_Value, Attribute_Length, Property_List);
  5553.         HA.Set_Node_Attribute(Node   => IL_Node,
  5554.                   Attrib => Attribute_Value(1 .. Attribute_Length),
  5555.                   Value  => "");
  5556.     end loop;
  5557.     HNM.Close_Node_Handle(IL_Node);
  5558.     exception
  5559.     when others =>
  5560.         HNM.Close_Node_Handle(IL_Node);
  5561.     end;
  5562.  
  5563.     LU.Unlock_Library(To_Library, WRITE_LOCK);
  5564.     if Message_on_Completion then
  5565.     HL.Put_Message_Line(
  5566.         "Library " & SP.Value(SP.Upper(From_Library)) &
  5567.         " copied to " & SP.Value(SP.Upper(To_Library)) & '.');
  5568.     end if;
  5569.     if not LL.IsEmpty(List_of_Lists) and then Message_on_Error then
  5570.     LU.Display_List(List_of_Lists, "Item/Version not purged");
  5571.     end if;
  5572.     Destroy_List_of_Lists(List_of_Lists);
  5573.     HL.Set_Interrupt_State(Trap);
  5574.     return HL.SUCCESS;
  5575.  
  5576. exception
  5577.  
  5578.     when Invalid_Library_Name | Invalid_External_Name =>
  5579.     LU.Unlock_Library(From_Library, READ_LOCK);
  5580.     LE.Report_Error(LE.Invalid_Library_Name, To_Library);
  5581.     HL.Set_Interrupt_State(Trap);
  5582.     return HL.ERROR;
  5583.  
  5584.     when Library_Already_Exists =>
  5585.     LU.Unlock_Library(From_Library, READ_LOCK);
  5586.     LE.Report_Error(LE.Library_Already_Exists, To_Library);
  5587.     HL.Set_Interrupt_State(Trap);
  5588.     return HL.ERROR;
  5589.  
  5590.     when Invalid_Directory_Name =>
  5591.     LU.Unlock_Library(From_Library, READ_LOCK);
  5592.     LE.Report_Error(LE.Invalid_Directory_Name, To_Directory);
  5593.     HL.Set_Interrupt_State(Trap);
  5594.     return HL.ERROR;
  5595.  
  5596.     when Directory_Already_Exists =>
  5597.     LU.Unlock_Library(From_Library, READ_LOCK);
  5598.     LE.Report_Error(LE.Directory_Already_Exists, To_Directory);
  5599.     HL.Set_Interrupt_State(Trap);
  5600.     return HL.ERROR;
  5601.  
  5602.     when Set_Protection_Error =>
  5603.     LU.Unlock_Library(From_Library, READ_LOCK);
  5604.     LE.Report_Error(LE.Set_Protection_Error, SP.Create("directory file"));
  5605.     HL.Set_Interrupt_State(Trap);
  5606.     return HL.ERROR;
  5607.  
  5608.     when HL.Interrupt_Encountered =>
  5609.     begin
  5610.         LU.Unlock_Library(From_Library, READ_LOCK);
  5611.     exception
  5612.         when others =>
  5613.         null;
  5614.     end;
  5615.     if HL."="(Trap, HL.ENABLED) then
  5616.         raise HL.Interrupt_Encountered;
  5617.     end if;
  5618.     LE.Report_Error(LE.Process_Interrupted, SP.Create("Copy_Library"));
  5619.     HL.Set_Interrupt_State(Trap);
  5620.     return HL.WARNING;
  5621.  
  5622.     when others =>
  5623.     begin
  5624.         LU.Unlock_Library(From_Library, READ_LOCK);
  5625.     exception
  5626.         when others =>
  5627.         null;
  5628.     end;
  5629.     LE.Report_Error(LE.Internal_Error, SP.Create("Copy_Library"));
  5630.     HL.Set_Interrupt_State(Trap);
  5631.     return HL.SEVERE;
  5632.  
  5633. end Copy_Library_Interface;
  5634.                                                                     pragma page;
  5635. ::::::::::::::
  5636. copyl.spc
  5637. ::::::::::::::
  5638. with String_Pkg;
  5639. with Host_Lib;
  5640. with Library_Declarations;
  5641.  
  5642. function Copy_Library_Interface(        --| Copy an Item Library
  5643.    From_Library : in String_Pkg.String_Type;    --| Item library to be copied
  5644.    To_Library   : in String_Pkg.String_Type;    --| New item library
  5645.    To_Directory : in String_Pkg.String_Type;    --| Directory for new library
  5646.    Mode         : in Library_Declarations.Copy_Mode := Library_Declarations.CURRENT
  5647.                         --| Copy option (CURRENT/FULL)
  5648.    ) return Host_Lib.Severity_Code;
  5649.  
  5650. --| Requires:
  5651. --| Name of the library to copy from and the name and the directory of the
  5652. --| new library
  5653.  
  5654. --| Effects:
  5655. --| Copies all the contents (but not the properties) of a item library to
  5656. --| another.  The copy option specifies current version or all versions copy
  5657.  
  5658. --| N/A: Modifies, Raises, Errors
  5659.                                                                     pragma page;
  5660. ::::::::::::::
  5661. createcat.ada
  5662. ::::::::::::::
  5663.  
  5664. --------- SPEC ----------------------------------------------------------
  5665.  
  5666. function create_catalog return INTEGER;
  5667.  
  5668. --------- BODY ----------------------------------------------------------
  5669.  
  5670. with Standard_Interface;
  5671. with Tool_Identifier;
  5672. with String_Pkg;
  5673. with Host_Lib;
  5674. with catalog_interface;
  5675.  
  5676. function create_catalog return INTEGER is
  5677.  
  5678.     package SP renames String_Pkg;
  5679.     package CI renames catalog_interface;
  5680.     package SI renames Standard_Interface;
  5681.  
  5682.     package input is new SI.String_Argument(        -- instantiate with
  5683.     String_Type_Name => "string");        -- subtype output_file
  5684.  
  5685.  
  5686.     process      : SI.Process_Handle;    -- handle to process structure
  5687.     catalog     : SP.string_type;    -- name of the catalog
  5688.     directory     : SP.string_type;    -- name of the directory to put 
  5689.                     -- partition in
  5690.  
  5691. begin
  5692.  
  5693.     SI.set_tool_identifier (Tool_Identifier);
  5694.     SI.Define_Process(            -- define this process
  5695.     Name    => "create_catalog",    -- name of the process
  5696.     Help    => "Create a new configuration item catalog",
  5697.     Proc    => process);        -- handle to be returned
  5698.  
  5699.     Input.Define_Argument(    -- define the first argument
  5700.     Proc => Process,        -- process 
  5701.     Name => "catalog_name",        -- name of the argument
  5702.     Help => "Name of the catalog to be created");
  5703.  
  5704.     Input.Define_Argument(        -- define the second argument
  5705.     Proc    => Process,        -- process
  5706.     Name    => "directory_spec",    -- name of the argument
  5707.     Help    => "Name of the directory to create the catalog in"); 
  5708.  
  5709.     SI.define_help (process,
  5710.     "Creates a new configuration item catalog.  The name of the catalog");
  5711.     SI.append_help (process,
  5712.     "must be and ada identifier and the directory should not already");
  5713.     SI.append_help (process,
  5714.     "exist.  The user will be prompted for a privileged user password");
  5715.     SI.append_help (process,
  5716.     "when the catalog is created.  The user must be a document manager");
  5717.     SI.append_help (process,
  5718.     "system user to be able to run this tool (see Add_User).");
  5719.  
  5720.     SI.Parse_Line(Process);        -- parse the command line
  5721.  
  5722.     catalog := Input.Get_Argument(    -- get the first argument
  5723.             Proc => Process,
  5724.             Name => "catalog_name");
  5725.  
  5726.     directory := Input.Get_Argument(    -- get the second argument
  5727.             Proc => Process,
  5728.             Name => "directory_spec");
  5729.  
  5730.     SI.Undefine_Process(Proc => Process);    -- destroy the process block
  5731.  
  5732.     CI.create_catalog (catalog, directory);
  5733.  
  5734.     return Host_Lib.Return_Code(Host_Lib.SUCCESS);-- return successful return code
  5735.  
  5736. exception
  5737.  
  5738.     when SI.Process_Help =>
  5739.     --
  5740.     -- Help message was printed
  5741.     --
  5742.     return Host_Lib.Return_Code(Host_Lib.INFORMATION);
  5743.  
  5744.     when SI.Abort_Process =>
  5745.     --
  5746.     -- Parse error
  5747.     --
  5748.     return Host_Lib.Return_Code(Host_Lib.ERROR);
  5749.  
  5750. end create_catalog;
  5751. ::::::::::::::
  5752. createi.ada
  5753. ::::::::::::::
  5754. with Standard_Interface;
  5755. with String_Pkg;
  5756. with Host_Lib;
  5757. with Tool_Identifier;
  5758. with Library_Errors;
  5759. with Create_Item_Interface;
  5760.  
  5761. function Create_Item return INTEGER is
  5762.  
  5763.     package SI  renames Standard_Interface;
  5764.     package SP  renames String_Pkg;
  5765.     package HL  renames Host_Lib;
  5766.     package LE  renames Library_Errors;
  5767.     package LIB is new SI.String_Argument(
  5768.                 String_Type_Name => "library_name");
  5769.     package FN  is new SI.String_Argument(
  5770.                 String_Type_Name => "file_name");
  5771.     package STR is new SI.String_Argument(
  5772.                 String_Type_Name => "string");
  5773.  
  5774.     Create_Item_Process : SI.Process_Handle;
  5775.     Library             : SP.String_Type;
  5776.     File_Name           : SP.String_Type;
  5777.     History             : SP.String_Type;
  5778.     
  5779. begin
  5780.  
  5781.     SP.Mark;
  5782.  
  5783.     SI.Set_Tool_Identifier(Identifier => Tool_Identifier);
  5784.  
  5785.     SI.Define_Process(
  5786.     Proc    => Create_Item_Process,
  5787.     Name    => "Create_Item",
  5788.     Help    => "Create an Item in the Item Library");
  5789.  
  5790.     LIB.Define_Argument(
  5791.     Proc => Create_Item_Process,
  5792.     Name => "library",
  5793.     Help => "Name of the item library");
  5794.  
  5795.     FN.Define_Argument(
  5796.     Proc => Create_Item_Process,
  5797.     Name => "file",
  5798.     Help => "Name of the file to be checked into the item library");
  5799.  
  5800.     STR.Define_Argument(
  5801.     Proc => Create_Item_Process,
  5802.     Name => "history",
  5803.     Help => "Description/reason for this item");
  5804.  
  5805.     SP.Release;
  5806.  
  5807.     SI.Parse_Line(Create_Item_Process);
  5808.     
  5809.     Library := LIB.Get_Argument(
  5810.             Proc => Create_Item_Process,
  5811.             Name => "library");
  5812.  
  5813.     File_Name := FN.Get_Argument(
  5814.             Proc => Create_Item_Process,
  5815.             Name => "file");
  5816.  
  5817.     History := STR.Get_Argument(
  5818.             Proc => Create_Item_Process,
  5819.             Name => "history");
  5820.  
  5821.     return HL.Return_Code(Create_Item_Interface(Library, File_Name, History));
  5822.  
  5823. exception
  5824.  
  5825.     when SI.Process_Help =>
  5826.     return HL.Return_Code(HL.INFORMATION);
  5827.  
  5828.     when SI.Abort_Process =>
  5829.     return HL.Return_Code(HL.ERROR);
  5830.  
  5831.     when others =>
  5832.     LE.Report_Error(LE.Internal_Error, SP.Create(""));
  5833.     return HL.Return_Code(HL.SEVERE);
  5834.  
  5835. end Create_Item;
  5836.                                                                     pragma page;
  5837. ::::::::::::::
  5838. createi.bdy
  5839. ::::::::::::::
  5840. with Library_Declarations;            use Library_Declarations;
  5841. with Library_Errors;
  5842. with Library_Utilities;
  5843. with File_Manager;
  5844.  
  5845. function Create_Item_Interface(
  5846.     Library : in String_Pkg.String_Type;
  5847.     File    : in String_Pkg.String_Type;
  5848.     History : in String_Pkg.String_Type
  5849.     ) return Host_Lib.Severity_Code is
  5850.  
  5851.     package SP  renames String_Pkg;
  5852.     package HL  renames Host_Lib;
  5853.     package LE  renames Library_Errors;
  5854.     package LU  renames Library_Utilities;
  5855.     package FM  renames File_Manager;
  5856.  
  5857.     Item_Value         : SP.String_Type;
  5858.     Checked_In_Version : SP.String_Type;
  5859.     Trap               : HL.Interrupt_State := HL.Get_Interrupt_State;
  5860.  
  5861. begin
  5862.  
  5863.     if HL."="(Trap, HL.DISABLED) then
  5864.     HL.Enable_Interrupt_Trap;
  5865.     end if;
  5866.     if not LU.Lock_Library(Library, WRITE_LOCK) then
  5867.     raise Library_Write_Locked;
  5868.     end if;
  5869.     Item_Value := SP.Create(FM.Parse_Filename(SP.Value(File), FM.FILE_ONLY));
  5870.     LU.Check_In_Item(Library, File, History, CREATE_ITEM, Checked_In_Version);
  5871.     LU.Unlock_Library(Library, WRITE_LOCK);
  5872.     if Message_on_Completion then
  5873.     HL.Put_Message_Line(
  5874.         "Item " & SP.Value(SP.Upper(Item_Value)) & '/' & SP.Value(Checked_In_Version) &
  5875.         " created in library " & SP.Value(SP.Upper(Library)) & '.');
  5876.     end if;
  5877.     HL.Set_Interrupt_State(Trap);
  5878.     return HL.SUCCESS;
  5879.  
  5880. exception
  5881.  
  5882.     when Invalid_Library_Name =>
  5883.     LE.Report_Error(LE.Invalid_Library_Name, Library);
  5884.     HL.Set_Interrupt_State(Trap);
  5885.     return HL.ERROR;
  5886.  
  5887.     when Library_Does_Not_Exist =>
  5888.     LE.Report_Error(LE.Library_Does_Not_Exist, Library);
  5889.     HL.Set_Interrupt_State(Trap);
  5890.     return HL.ERROR;
  5891.  
  5892.     when Library_Master_Locked =>
  5893.     LE.Report_Error(LE.Library_Master_Locked, Library);
  5894.     HL.Set_Interrupt_State(Trap);
  5895.     return HL.ERROR;
  5896.  
  5897.     when Library_Write_Locked =>
  5898.     LE.Report_Error(LE.Library_Write_Locked, Library);
  5899.     HL.Set_Interrupt_State(Trap);
  5900.     return HL.ERROR;
  5901.  
  5902.     when FM.Parse_Error | Invalid_External_Name =>
  5903.     LU.Unlock_Library(Library, WRITE_LOCK);
  5904.     LE.Report_Error(LE.Invalid_External_Name, File);
  5905.     HL.Set_Interrupt_State(Trap);
  5906.     return HL.ERROR;
  5907.  
  5908.     when File_Not_Found =>
  5909.     LU.Unlock_Library(Library, WRITE_LOCK);
  5910.     LE.Report_Error(LE.File_Not_Found, File);
  5911.     HL.Set_Interrupt_State(Trap);
  5912.     return HL.ERROR;
  5913.  
  5914.     when Item_Already_Exists =>
  5915.     LU.Unlock_Library(Library, WRITE_LOCK);
  5916.     LE.Report_Error(LE.Item_Already_Exists, Item_Value);
  5917.     HL.Set_Interrupt_State(Trap);
  5918.     return HL.ERROR;
  5919.  
  5920.     when Item_Not_Created =>
  5921.     LU.Unlock_Library(Library, WRITE_LOCK);
  5922.     LE.Report_Error(LE.Item_Not_Created, Item_Value);
  5923.     HL.Set_Interrupt_State(Trap);
  5924.     return HL.ERROR;
  5925.  
  5926.     when Set_Protection_Error =>
  5927.     LU.Unlock_Library(Library, WRITE_LOCK);
  5928.     LE.Report_Error(LE.Set_Protection_Error, Item_Value);
  5929.     HL.Set_Interrupt_State(Trap);
  5930.     return HL.ERROR;
  5931.  
  5932.     when HL.Interrupt_Encountered =>
  5933.     begin
  5934.         LU.Unlock_Library(Library, WRITE_LOCK);
  5935.     exception
  5936.         when others => null;
  5937.     end;
  5938.     if HL."="(Trap, HL.ENABLED) then
  5939.         raise HL.Interrupt_Encountered;
  5940.     end if;
  5941.     LE.Report_Error(LE.Process_Interrupted, SP.Create("Create_Item"));
  5942.     HL.Set_Interrupt_State(Trap);
  5943.     return HL.WARNING;
  5944.  
  5945.     when others =>
  5946.     begin
  5947.         LU.Unlock_Library(Library, WRITE_LOCK);
  5948.     exception
  5949.         when others => null;
  5950.     end;
  5951.     LE.Report_Error(LE.Internal_Error, SP.Create("Create_Item"));
  5952.     HL.Set_Interrupt_State(Trap);
  5953.     return HL.SEVERE;
  5954.  
  5955. end Create_Item_Interface;
  5956.                                                                     pragma page;
  5957. ::::::::::::::
  5958. createi.spc
  5959. ::::::::::::::
  5960. with String_Pkg;
  5961. with Host_Lib;
  5962.  
  5963. function Create_Item_Interface(            --| Create an Item
  5964.    Library : in String_Pkg.String_Type;        --| Item library
  5965.    File    : in String_Pkg.String_Type;        --| File to be checked in
  5966.    History : in String_Pkg.String_Type        --| Description/reason
  5967.    ) return Host_Lib.Severity_Code;
  5968.  
  5969. --| Requires:
  5970. --| Name of the library, name file to be created as an item in the library,
  5971. --| and a description of the item to be created
  5972.  
  5973. --| Effects:
  5974. --| Creates an item from a given file in the named library
  5975.  
  5976. --| N/A: Modifies, Raises, Errors
  5977.                                                                     pragma page;
  5978. ::::::::::::::
  5979. createl.ada
  5980. ::::::::::::::
  5981. with Standard_Interface;
  5982. with String_Pkg;
  5983. with Host_Lib;
  5984. with Tool_Identifier;
  5985. with Library_Errors;
  5986. with Create_Library_Interface;
  5987.  
  5988. function Create_Library return INTEGER is
  5989.  
  5990.     package SI   renames Standard_Interface;
  5991.     package SP   renames String_Pkg;
  5992.     package HL   renames Host_Lib;
  5993.     package LE   renames Library_Errors;
  5994.     package LIB  is new SI.String_Argument(String_Type_Name => "library_name");
  5995.     package DIR  is new SI.String_Argument(String_Type_Name => "directory_spec");
  5996.  
  5997.     Create_Library_Process : SI.Process_Handle;
  5998.     Library                : SP.String_Type;
  5999.     Directory              : SP.String_Type;
  6000.  
  6001. begin
  6002.  
  6003.     SP.Mark;
  6004.  
  6005.     SI.Set_Tool_Identifier(Identifier => Tool_Identifier);
  6006.  
  6007.     SI.Define_Process(
  6008.     Proc    => Create_Library_Process,
  6009.     Name    => "Create_Library",
  6010.     Help    => "Create an Item Library");
  6011.  
  6012.     LIB.Define_Argument(
  6013.     Proc => Create_Library_Process,
  6014.     Name => "library",
  6015.     Help => "Name of the item library to be created");
  6016.  
  6017.     DIR.Define_Argument(
  6018.     Proc => Create_Library_Process,
  6019.     Name => "directory",
  6020.     Help => "Name of directory to be used by this library");
  6021.  
  6022.     SP.Release;
  6023.  
  6024.     SI.Parse_Line(Create_Library_Process);
  6025.  
  6026.     Library   := LIB.Get_Argument(
  6027.             Proc => Create_Library_Process,
  6028.             Name => "library");
  6029.  
  6030.     Directory := DIR.Get_Argument(
  6031.             Proc => Create_Library_Process,
  6032.             Name => "directory");
  6033.  
  6034.     return HL.Return_Code(Create_Library_Interface(Library, Directory));
  6035.  
  6036. exception
  6037.  
  6038.     when SI.Process_Help =>
  6039.     return HL.Return_Code(HL.INFORMATION);
  6040.  
  6041.     when SI.Abort_Process =>
  6042.     return HL.Return_Code(HL.ERROR);
  6043.  
  6044.     when others =>
  6045.     LE.Report_Error(LE.Internal_Error, SP.Create(""));
  6046.     return HL.Return_Code(HL.SEVERE);
  6047.  
  6048. end Create_Library;
  6049.                                                                     pragma page;
  6050. ::::::::::::::
  6051. createl.bdy
  6052. ::::::::::::::
  6053. with Library_Declarations;            use Library_Declarations;
  6054. with Library_Errors;
  6055. with Library_Utilities;
  6056. with HIF_Node_Defs;
  6057. with HIF_Node_Management;
  6058.  
  6059. function Create_Library_Interface(
  6060.     Library   : in String_Pkg.String_Type;
  6061.     Directory : in String_Pkg.String_Type
  6062.     ) return Host_Lib.Severity_Code is
  6063.  
  6064.     package SP  renames String_Pkg;
  6065.     package HL  renames Host_Lib;
  6066.     package LE  renames Library_Errors;
  6067.     package LU  renames Library_Utilities;
  6068.     package HND renames HIF_Node_Defs;
  6069.     package HNM renames HIF_Node_Management;
  6070.  
  6071.     Library_Node : HND.Node_Type;
  6072.     DOCMGR_Node  : HND.Node_Type;
  6073.     Lock         : BOOLEAN;
  6074.     Trap         : HL.Interrupt_State := HL.Get_Interrupt_State;
  6075.  
  6076. begin
  6077.  
  6078.     if HL."="(Trap, HL.DISABLED) then
  6079.     HL.Enable_Interrupt_Trap;
  6080.     end if;
  6081.     HNM.Close_Node_Handle(Node => Library_Node);
  6082.     LU.Create_Library(Library   => Library,
  6083.               Directory => Directory,
  6084.               CI        => SP.Create(""),
  6085.               Mode      => NO_UPDATE,
  6086.               Node      => Library_Node,
  6087.               Locked    => FALSE);
  6088.     if Message_on_Completion then
  6089.     HL.Put_Message_Line("Library " & SP.Value(SP.Upper(Library)) & " created.");
  6090.     end if;
  6091.     HL.Set_Interrupt_State(Trap);
  6092.     return HL.SUCCESS;
  6093.  
  6094. exception
  6095.  
  6096.     when Invalid_Library_Name | Invalid_External_Name =>
  6097.     LE.Report_Error(LE.Invalid_Library_Name, Library);
  6098.     HL.Set_Interrupt_State(Trap);
  6099.     return HL.ERROR;
  6100.  
  6101.     when Library_Already_Exists =>
  6102.     LE.Report_Error(LE.Library_Already_Exists, Library);
  6103.     HL.Set_Interrupt_State(Trap);
  6104.     return HL.ERROR;
  6105.  
  6106.     when Invalid_Directory_Name =>
  6107.     LE.Report_Error(LE.Invalid_Directory_Name, Directory);
  6108.     HL.Set_Interrupt_State(Trap);
  6109.     return HL.ERROR;
  6110.  
  6111.     when Directory_Already_Exists =>
  6112.     LE.Report_Error(LE.Directory_Already_Exists, Directory);
  6113.     HL.Set_Interrupt_State(Trap);
  6114.     return HL.ERROR;
  6115.  
  6116.     when Set_Protection_Error =>
  6117.     LE.Report_Error(LE.Set_Protection_Error, SP.Create("directory file"));
  6118.     HL.Set_Interrupt_State(Trap);
  6119.     return HL.ERROR;
  6120.  
  6121.     when HL.Interrupt_Encountered =>
  6122.     if HL."="(Trap, HL.ENABLED) then
  6123.         raise HL.Interrupt_Encountered;
  6124.     end if;
  6125.     LE.Report_Error(LE.Process_Interrupted, SP.Create("Create_Library"));
  6126.     HL.Set_Interrupt_State(Trap);
  6127.     return HL.WARNING;
  6128.  
  6129.     when others =>
  6130.     begin
  6131.         LU.Unlock_Library(Library, WRITE_LOCK);
  6132.     exception
  6133.         when others => null;
  6134.     end;
  6135.     LE.Report_Error(LE.Internal_Error, SP.Create("Create_Library"));
  6136.     HL.Set_Interrupt_State(Trap);
  6137.     return HL.SEVERE;
  6138.  
  6139. end Create_Library_Interface;
  6140.                                                                     pragma page;
  6141. ::::::::::::::
  6142. createl.spc
  6143. ::::::::::::::
  6144. with String_Pkg;
  6145. with Host_Lib;
  6146.  
  6147. function Create_Library_Interface(        --| Create an Item Library
  6148.    Library   : in String_Pkg.String_Type;    --| Item library to be created
  6149.    Directory : in String_Pkg.String_Type    --| Directory for the library
  6150.    ) return Host_Lib.Severity_Code;
  6151.  
  6152. --| Requires:
  6153. --| Name of the library to be created and the directory for the library
  6154.  
  6155. --| Effects:
  6156. --| Creates a new library
  6157.  
  6158. --| N/A: Modifies, Raises, Errors
  6159.                                                                     pragma page;
  6160. ::::::::::::::
  6161. createrm.ada
  6162. ::::::::::::::
  6163. With Hif_System_Management ;
  6164.      
  6165. Procedure Cre_RM is
  6166.       Package SYS renames Hif_System_Management;
  6167. begin
  6168.     SYS.Create_RootMap ;
  6169. end ;
  6170. ::::::::::::::
  6171. createrp.ada
  6172. ::::::::::::::
  6173. -- $Source: /usr8/pif/hif/newer/RCS/cre_rp.ada,v $
  6174. -- $Revision: 1.1 $ -- $Date: 85/04/18 13:26:59 $ -- $Author: fitch $
  6175.      
  6176. with Hif_Keyed_IO; use Hif_Keyed_IO;
  6177. with Hif_Keyed_IO_Defs;
  6178. with Hif_Debug;
  6179. with Hif_Partition_Elements;
  6180. with Hif_Partition_Mapping;
  6181. with Hif_Defs;
  6182.      
  6183. procedure cre_rp is
  6184.      
  6185.     package PELT renames Hif_Partition_Elements;
  6186.     package DEFS renames Hif_Defs;
  6187.     package KIODEFS renames Hif_Keyed_IO_Defs;
  6188.      
  6189.     File:   File_Type;
  6190.     Key:    PELT.Key_Type;
  6191.     Data:   PELT.Data_Type;
  6192.      
  6193.     s: KIODEFS.Status_Type;
  6194.     Hif_Directory : constant string := "HIF_DIRECTORY:";
  6195.     -- logical name of the directory that contains the root partition
  6196. begin
  6197.     Create(s,File, Hif_Partition_Mapping.Host_Partition_Mapping.
  6198.       Make_Repository_Name(Hif_Directory));
  6199.     if kiodefs."/="(s,kiodefs.success) then
  6200.         hif_debug.unexpected_status(s);
  6201.     end if;
  6202.     Write(s,File, PELT.Null_Item_Id,
  6203.                 PELT.First_Item_Id);
  6204.     --
  6205.     if kiodefs."/="(s,kiodefs.success) then
  6206.         hif_debug.unexpected_status(s);
  6207.     end if;
  6208.     pelt.make_key(key,PELT.First_Item_Id);
  6209.     pelt.make_data(Data, DEFS.Structural);
  6210.     Write(s,File, PELT.Image(Key), PELT.Image(Data));
  6211.     if kiodefs."/="(s,kiodefs.success) then
  6212.         hif_debug.unexpected_status(s);
  6213.     end if;
  6214.     Close(File);
  6215. end cre_rp;
  6216. ::::::::::::::
  6217. deletei.ada
  6218. ::::::::::::::
  6219. with Standard_Interface;
  6220. with String_Pkg;
  6221. with Host_Lib;
  6222. with Item_Library_Manager;
  6223. with Item_Library_Manager_Utilities;
  6224. with Item_Library_Manager_Declarations;
  6225.  
  6226. function Delete_Item return INTEGER is
  6227.  
  6228.     package SI  renames Standard_Interface;
  6229.     package SP  renames String_Pkg;
  6230.     package HL  renames Host_Lib;
  6231.     package ILM renames Item_Library_Manager;
  6232.     package ILU renames Item_Library_Manager_Utilities;
  6233.     package ILD renames Item_Library_Manager_Declarations;
  6234.  
  6235.     package LIB is new SI.String_Argument(
  6236.                 String_Type_Name => "library_name");
  6237.     package ITM is new SI.String_Argument(
  6238.                 String_Type_Name => "item_name");
  6239.     package VER is new SI.String_Argument(
  6240.                 String_Type_Name => "version");
  6241.  
  6242.     Delete_Item_Process : SI.Process_Handle;
  6243.     Library             : SP.String_Type;
  6244.     Item                : SP.String_Type;
  6245.     Version             : SP.String_Type;
  6246.     List                : ILD.LL.List;
  6247.  
  6248. begin
  6249.  
  6250.     SP.Mark;
  6251.  
  6252.     SI.Set_Tool_Identifier(Identifier => "1.0");
  6253.  
  6254.     SI.Define_Process(
  6255.     Proc    => Delete_Item_Process,
  6256.     Name    => "Delete_Item",
  6257.     Help    => "Delete Item(s) in an Item Library");
  6258.  
  6259.     LIB.Define_Argument(
  6260.     Proc => Delete_Item_Process,
  6261.     Name => "library",
  6262.     Help => "Name of the item library");
  6263.  
  6264.     ITM.Define_Argument(
  6265.     Proc => Delete_Item_Process,
  6266.     Name => "item",
  6267.     Help => "Name of the item(s) to be deleted in the item library");
  6268.  
  6269.     VER.Define_Argument(
  6270.     Proc    => Delete_Item_Process,
  6271.     Name    => "version",
  6272.     Default => "",
  6273.     Help    => "Version specification");
  6274.  
  6275.     SP.Release;
  6276.  
  6277.     SI.Parse_Line(Delete_Item_Process);
  6278.  
  6279.     Library := LIB.Get_Argument(
  6280.             Proc => Delete_Item_Process,
  6281.             Name => "library");
  6282.  
  6283.     Item := ITM.Get_Argument(
  6284.             Proc => Delete_Item_Process,
  6285.             Name => "item");
  6286.  
  6287.     Version := VER.Get_Argument(
  6288.             Proc => Delete_Item_Process,
  6289.             Name => "version");
  6290.  
  6291.     ILM.Delete_Item(Library   => Library,
  6292.             Item      => Item,
  6293.             Version   => Version,
  6294.             Privilege => ILD.OWNER,
  6295.             Remainder => List);
  6296.  
  6297.     if not ILD.LL.IsEmpty(List) then
  6298.     ILU.Display_List(List, "Item/Version not deleted");
  6299.     ILD.Destroy_List_of_Lists(List);
  6300.     else
  6301.         HL.Put_Message("Item """ & SP.Value(SP.Upper(Item)));
  6302.     if not SP.Is_Empty(Version) then
  6303.         HL.Put_Message('/' & SP.Value(Version));
  6304.     end if;
  6305.     HL.Put_Message_Line(""" deleted.");
  6306.     end if;
  6307.     return HL.Return_Code(HL.SUCCESS);
  6308.  
  6309. exception
  6310.  
  6311.     when SI.Process_Help =>
  6312.     return HL.Return_Code(HL.INFORMATION);
  6313.  
  6314.     when SI.Abort_Process =>
  6315.     return HL.Return_Code(HL.SUCCESS);
  6316.  
  6317.     when ILD.Library_Does_Not_Exist =>
  6318.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ does not exist.");
  6319.     return HL.Return_Code(HL.ERROR);
  6320.  
  6321.     when ILD.Library_Master_Locked =>
  6322.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is master locked.");
  6323.     return HL.Return_Code(HL.ERROR);
  6324.  
  6325.     when ILD.Library_Write_Locked =>
  6326.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is write locked.");
  6327.     return HL.Return_Code(HL.ERROR);
  6328.  
  6329.     when ILD.Library_Read_Locked =>
  6330.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is read locked.");
  6331.     return HL.Return_Code(HL.ERROR);
  6332.  
  6333.     when ILD.Item_Not_Found =>
  6334.     HL.Put_Error("Item """ & SP.Value(SP.Upper(Item)) & """ not found.");
  6335.     return HL.Return_Code(HL.ERROR);
  6336.  
  6337.     when ILD.Item_Checked_Out =>
  6338.     HL.Put_Error("Item """ & SP.Value(SP.Upper(Item)) & """ checked out.");
  6339.     return HL.Return_Code(HL.ERROR);
  6340.  
  6341.     when ILD.Invalid_Version =>
  6342.     HL.Put_Error("Invalid version specification.");
  6343.     return HL.Return_Code(HL.ERROR);
  6344.  
  6345.     when ILD.Version_Not_Found =>
  6346.     HL.Put_Error("Version not found.");
  6347.     return HL.Return_Code(HL.ERROR);
  6348.  
  6349.     when ILD.Not_Authorized =>
  6350.     HL.Put_Error("Not authorized.");
  6351.     return HL.Return_Code(HL.ERROR);
  6352.  
  6353.     when ILD.No_Privilege =>
  6354.     HL.Put_Error("No privilege for attempted operation.");
  6355.     return HL.Return_Code(HL.ERROR);
  6356.  
  6357.     when others =>
  6358.     HL.Put_Error("Delete Item internal error.");
  6359.     return HL.Return_Code(HL.SEVERE);
  6360.  
  6361. end Delete_Item;
  6362.  
  6363. ::::::::::::::
  6364. deletei.bdy
  6365. ::::::::::::::
  6366. with Library_Errors;
  6367. with Library_Utilities;
  6368. with HIF_Node_Defs;
  6369. with HIF_Node_Management;
  6370.  
  6371. function Delete_Item_Interface(
  6372.     Library   : in String_Pkg.String_Type;
  6373.     Item      : in String_Pkg.String_Type;
  6374.     Version   : in String_Pkg.String_Type;
  6375.     Privilege : in Privilege_Type := WORLD
  6376.     ) return Host_Lib.Severity_Code is
  6377.  
  6378.     package SP  renames String_Pkg;
  6379.     package HL  renames Host_Lib;
  6380.     package LE  renames Library_Errors;
  6381.     package LU  renames Library_Utilities;
  6382.     package HND renames HIF_Node_Defs;
  6383.     package HNM renames HIF_Node_Management;
  6384.  
  6385.     List_of_Lists    : LL.List;
  6386.     Item_Node        : HND.Node_Type;
  6387.     Item_Iterator    : HNM.Node_Iterator;
  6388.     Version_Iterator : SL.ListIter;
  6389.     Versions         : SL.List;
  6390.     Undeleted        : SL.List;
  6391.     Trap             : HL.Interrupt_State := HL.Get_Interrupt_State;
  6392.  
  6393. begin
  6394.  
  6395.     if HL."="(Trap, HL.DISABLED) then
  6396.     HL.Enable_Interrupt_Trap;
  6397.     end if;
  6398.     if not LU.Lock_Library(Library, WRITE_LOCK) then
  6399.     raise Library_Write_Locked;
  6400.     end if;
  6401.     LU.Iterate_Item(Library, Item, Item_Iterator);
  6402.     while HNM.More(Item_Iterator) loop
  6403.     HNM.Get_Next(Item_Iterator, Item_Node);
  6404.     Versions := LU.Get_Version(Item_Node, Version);
  6405.     LU.Delete(Item_Node, Versions, Privilege, List_of_Lists);
  6406.     Destroy_String_List(Versions);
  6407.     HNM.Close_Node_Handle(Item_Node);
  6408.     end loop;
  6409.     LU.Unlock_Library(Library, WRITE_LOCK);
  6410.     if not LL.IsEmpty(List_of_Lists) then
  6411.     if Message_on_Error then
  6412.         LU.Display_List(List_of_Lists, "Item/Version not deleted");
  6413.     end if;
  6414.     elsif Message_on_Completion then
  6415.         HL.Put_Message("Item " & SP.Value(SP.Upper(Item)));
  6416.     if not SP.Is_Empty(Version) then
  6417.         HL.Put_Message('/' & SP.Value(Version));
  6418.     end if;
  6419.     HL.Put_Message_Line(" deleted from library " & 
  6420.                 SP.Value(SP.Upper(Library)) & '.');
  6421.     end if;
  6422.     HL.Set_Interrupt_State(Trap);
  6423.     return HL.SUCCESS;
  6424.  
  6425. exception
  6426.  
  6427.     when Invalid_Library_Name =>
  6428.     LE.Report_Error(LE.Invalid_Library_Name, Library);
  6429.     HL.Set_Interrupt_State(Trap);
  6430.     return HL.ERROR;
  6431.  
  6432.     when Library_Does_Not_Exist =>
  6433.     LE.Report_Error(LE.Library_Does_Not_Exist, Library);
  6434.     HL.Set_Interrupt_State(Trap);
  6435.     return HL.ERROR;
  6436.  
  6437.     when Library_Master_Locked =>
  6438.     LE.Report_Error(LE.Library_Master_Locked, Library);
  6439.     HL.Set_Interrupt_State(Trap);
  6440.     return HL.ERROR;
  6441.  
  6442.     when Library_Write_Locked =>
  6443.     LE.Report_Error(LE.Library_Write_Locked, Library);
  6444.     HL.Set_Interrupt_State(Trap);
  6445.     return HL.ERROR;
  6446.  
  6447.     when Item_Not_Found =>
  6448.     LU.Unlock_Library(Library, WRITE_LOCK);
  6449.     LE.Report_Error(LE.Item_Not_Found, Item);
  6450.     HL.Set_Interrupt_State(Trap);
  6451.     return HL.ERROR;
  6452.  
  6453.     when Invalid_Version =>
  6454.     LU.Unlock_Library(Library, WRITE_LOCK);
  6455.     LE.Report_Error(LE.Invalid_Version, Version);
  6456.     HL.Set_Interrupt_State(Trap);
  6457.     return HL.ERROR;
  6458.  
  6459.     when Version_Not_Found =>
  6460.     LU.Unlock_Library(Library, WRITE_LOCK);
  6461.     LE.Report_Error(LE.Version_Not_Found, Version);
  6462.     HL.Set_Interrupt_State(Trap);
  6463.     return HL.ERROR;
  6464.  
  6465.     when No_Privilege =>
  6466.     LU.Unlock_Library(Library, WRITE_LOCK);
  6467.     LE.Report_Error(LE.No_Privilege, Library, SP.Create(LU.Get_Library_Attribute(Library, "OWNER")));
  6468.     HL.Set_Interrupt_State(Trap);
  6469.     return HL.ERROR;
  6470.  
  6471.     when HL.Interrupt_Encountered =>
  6472.     begin
  6473.         LU.Unlock_Library(Library, WRITE_LOCK);
  6474.     exception
  6475.         when others => null;
  6476.     end;
  6477.     if HL."="(Trap, HL.ENABLED) then
  6478.         raise HL.Interrupt_Encountered;
  6479.     end if;
  6480.     LE.Report_Error(LE.Process_Interrupted, SP.Create("Delete_Item"));
  6481.     HL.Set_Interrupt_State(Trap);
  6482.     return HL.WARNING;
  6483.  
  6484.     when others =>
  6485.     begin
  6486.         LU.Unlock_Library(Library, WRITE_LOCK);
  6487.     exception
  6488.         when others => null;
  6489.     end;
  6490.     LE.Report_Error(LE.Internal_Error, SP.Create("Delete_Item"));
  6491.     HL.Set_Interrupt_State(Trap);
  6492.     return HL.SEVERE;
  6493.  
  6494. end Delete_Item_Interface;
  6495.                                                                     pragma page;
  6496. ::::::::::::::
  6497. deletei.spc
  6498. ::::::::::::::
  6499. with Library_Declarations;            use Library_Declarations;
  6500. with String_Pkg;
  6501. with Host_Lib;
  6502.  
  6503. function Delete_Item_Interface(                --| Delete Item(s)
  6504.     Library   : in String_Pkg.String_Type;        --| Item library
  6505.     Item      : in String_Pkg.String_Type;        --| Item(s) to be deleted
  6506.     Version   : in String_Pkg.String_Type;        --| Version specification
  6507.     Privilege : in Privilege_Type := WORLD        --| Delete privilege
  6508.     ) return Host_Lib.Severity_Code;
  6509.  
  6510. --| Requires:
  6511. --| Name of the libray, name of the item, and the version specification
  6512.  
  6513. --| Effects:
  6514. --| Deletes the specified version(s) of item(s) in the library
  6515.  
  6516. --| N/A: Modifies, Raises, Errors
  6517.                                                                     pragma page;
  6518. ::::::::::::::
  6519. deletel.ada
  6520. ::::::::::::::
  6521. with Standard_Interface;
  6522. with String_Pkg;
  6523. with Host_Lib;
  6524. with Tool_Identifier;
  6525. with Library_Declarations;
  6526. with Library_Errors;
  6527. with Delete_Library_Interface;
  6528.  
  6529. function Delete_Library return INTEGER is
  6530.  
  6531.     package SI  renames Standard_Interface;
  6532.     package SP  renames String_Pkg;
  6533.     package HL  renames Host_Lib;
  6534.     package LE  renames Library_Errors;
  6535.     package LD  renames Library_Declarations;
  6536.     package LIB is new SI.String_Argument(String_Type_Name => "library_name");
  6537.  
  6538.     Delete_Library_Process : SI.Process_Handle;
  6539.     Library                : SP.String_Type;
  6540.  
  6541. begin
  6542.  
  6543.     SP.Mark;
  6544.  
  6545.     SI.Set_Tool_Identifier(Identifier => Tool_Identifier);
  6546.  
  6547.     SI.Define_Process(
  6548.     Proc    => Delete_Library_Process,
  6549.     Name    => "Delete_Library",
  6550.     Help    => "Delete an Item Library");
  6551.  
  6552.     LIB.Define_Argument(
  6553.     Proc    => Delete_Library_Process,
  6554.     Name => "library",
  6555.     Help => "Name of the item library to be deleted");
  6556.  
  6557.     SP.Release;
  6558.  
  6559.     SI.Parse_Line(Delete_Library_Process);
  6560.  
  6561.     Library := LIB.Get_Argument(
  6562.             Proc => Delete_Library_Process,
  6563.             Name => "library");
  6564.  
  6565.     return HL.Return_Code(Delete_Library_Interface(Library, LD.Delete_Library_Privilege));
  6566.  
  6567. exception
  6568.  
  6569.     when SI.Process_Help =>
  6570.     return HL.Return_Code(HL.INFORMATION);
  6571.  
  6572.     when SI.Abort_Process =>
  6573.     return HL.Return_Code(HL.ERROR);
  6574.  
  6575.     when others =>
  6576.     LE.Report_Error(LE.Internal_Error, SP.Create(""));
  6577.     return HL.Return_Code(HL.SEVERE);
  6578.  
  6579. end Delete_Library;
  6580.                                                                     pragma page;
  6581. ::::::::::::::
  6582. deletel.bdy
  6583. ::::::::::::::
  6584. with Library_Errors;
  6585. with Library_Utilities;
  6586. with Hif_Node_Defs;
  6587.  
  6588. function Delete_Library_Interface(
  6589.     Library   : in String_Pkg.String_Type;
  6590.     Privilege : in Privilege_Type := WORLD
  6591.     ) return Host_Lib.Severity_Code is
  6592.  
  6593.     package SP  renames String_Pkg;
  6594.     package HL  renames Host_Lib;
  6595.     package LE  renames Library_Errors;
  6596.     package LU  renames Library_Utilities;
  6597.     package HND renames Hif_Node_Defs;
  6598.  
  6599.     Trap : HL.Interrupt_State := HL.Get_Interrupt_State;
  6600.  
  6601. begin
  6602.  
  6603.     HL.Ignore_Interrupts;
  6604.     if not LU.Lock_Library(Library, WRITE_LOCK) then
  6605.     raise Library_Write_Locked;
  6606.     end if;
  6607.     LU.Delete_Library(Library, Privilege);
  6608.     if HL.Interrupts_Ignored then
  6609.     if HL."="(Trap, HL.ENABLED) then
  6610.         raise HL.Interrupt_Encountered;
  6611.     else
  6612.         raise Process_Interrupted;
  6613.     end if;
  6614.     end if;
  6615.     if Message_on_Completion then
  6616.     HL.Put_Message_Line("Library " & SP.Value(SP.Upper(Library)) & " deleted.");
  6617.     end if;
  6618.     HL.Set_Interrupt_State(Trap);
  6619.     return HL.SUCCESS;
  6620.  
  6621. exception
  6622.  
  6623.     when Invalid_Library_Name | Invalid_External_Name =>
  6624.     LE.Report_Error(LE.Invalid_Library_Name, Library);
  6625.     HL.Set_Interrupt_State(Trap);
  6626.     return HL.ERROR;
  6627.  
  6628.     when Library_Does_Not_Exist =>
  6629.     LE.Report_Error(LE.Library_Does_Not_Exist, Library);
  6630.     HL.Set_Interrupt_State(Trap);
  6631.     return HL.ERROR;
  6632.  
  6633.     when Library_Master_Locked =>
  6634.     LE.Report_Error(LE.Library_Master_Locked, Library);
  6635.     HL.Set_Interrupt_State(Trap);
  6636.     return HL.ERROR;
  6637.  
  6638.     when Library_Write_Locked =>
  6639.     LE.Report_Error(LE.Library_Write_Locked, Library);
  6640.     HL.Set_Interrupt_State(Trap);
  6641.     return HL.ERROR;
  6642.  
  6643.     when No_Privilege =>
  6644.     LU.Unlock_Library(Library, WRITE_LOCK);
  6645.     LE.Report_Error(LE.No_Privilege, Library, SP.Create(LU.Get_Library_Attribute(Library, "OWNER")));
  6646.     HL.Set_Interrupt_State(Trap);
  6647.     return HL.ERROR;
  6648.  
  6649.     when Library_Pending_Return =>
  6650.     LU.Unlock_Library(Library, WRITE_LOCK);
  6651.     LE.Report_Error(LE.Library_Pending_Return, Library, SP.Create(LU.Get_Library_Attribute(Library, "CI")));
  6652.     HL.Set_Interrupt_State(Trap);
  6653.     return HL.ERROR;
  6654.  
  6655.     when Process_Interrupted =>
  6656.     LE.Report_Error(LE.Process_Interrupted, SP.Create("Delete_Library"));
  6657.     HL.Set_Interrupt_State(Trap);
  6658.     return HL.WARNING;
  6659.  
  6660.     when HL.Interrupt_Encountered =>
  6661.     raise HL.Interrupt_Encountered;
  6662.  
  6663.     when others =>
  6664.     begin
  6665.         LU.Unlock_Library(Library, WRITE_LOCK);
  6666.     exception
  6667.         when others => null;
  6668.     end;
  6669.     LE.Report_Error(LE.Internal_Error, SP.Create("Delete_Library"));
  6670.     HL.Set_Interrupt_State(Trap);
  6671.     return HL.SEVERE;
  6672.  
  6673. end Delete_Library_Interface;
  6674.                                                                     pragma page;
  6675. ::::::::::::::
  6676. deletel.spc
  6677. ::::::::::::::
  6678. with Library_Declarations;            use Library_Declarations;
  6679. with String_Pkg;
  6680. with Host_Lib;
  6681.  
  6682. function Delete_Library_Interface(        --| Delete an Item Library
  6683.     Library   : in String_Pkg.String_Type;    --| Item library to be deleted
  6684.     Privilege : in Privilege_Type := WORLD    --| Delete privilege
  6685.     ) return Host_Lib.Severity_Code;
  6686.  
  6687. --| Requires:
  6688. --| Name of the library to be deleted
  6689.  
  6690. --| Effects:
  6691. --| Delete a library
  6692.  
  6693. --| N/A: Modifies, Raises, Errors
  6694.                                                                     pragma page;
  6695. ::::::::::::::
  6696. deletep.ada
  6697. ::::::::::::::
  6698. with Standard_Interface;
  6699. with String_Pkg;
  6700. with Host_Lib;
  6701. with Item_Library_Manager;
  6702. with Item_Library_Manager_Declarations;
  6703.  
  6704. function Delete_Property return INTEGER is
  6705.  
  6706.     package SI  renames Standard_Interface;
  6707.     package SP  renames String_Pkg;
  6708.     package HL  renames Host_Lib;
  6709.     package ILM renames Item_Library_Manager;
  6710.     package ILD renames Item_Library_Manager_Declarations;
  6711.  
  6712.     package LIB is new SI.String_Argument(
  6713.                 String_Type_Name => "library_name");
  6714.     package STR is new SI.String_Argument(
  6715.                 String_Type_Name => "string");
  6716.  
  6717.     Delete_Property_Process : SI.Process_Handle;
  6718.     Library                 : SP.String_Type;
  6719.     Keyword                 : SP.String_Type;
  6720.  
  6721. begin
  6722.  
  6723.     SP.Mark;
  6724.  
  6725.     SI.Set_Tool_Identifier(Identifier => "1.0");
  6726.  
  6727.     SI.Define_Process(
  6728.     Proc    => Delete_Property_Process,
  6729.     Name    => "Delete_Property",
  6730.     Help    => "Delete a Property Keyword from the Item Library");
  6731.  
  6732.     LIB.Define_Argument(
  6733.     Proc => Delete_Property_Process,
  6734.     Name => "library",
  6735.     Help => "Name of the item library");
  6736.  
  6737.     STR.Define_Argument(
  6738.     Proc    => Delete_Property_Process,
  6739.     Name    => "keyword",
  6740.     Help    => "Property keyword");
  6741.  
  6742.     SP.Release;
  6743.  
  6744.     SI.Parse_Line(Delete_Property_Process);
  6745.  
  6746.     Library := LIB.Get_Argument(
  6747.             Proc => Delete_Property_Process,
  6748.             Name => "library");
  6749.  
  6750.     Keyword := STR.Get_Argument(
  6751.             Proc => Delete_Property_Process,
  6752.             Name => "keyword");
  6753.  
  6754.     ILM.Delete_Property(Library   => Library,
  6755.             Keyword   => Keyword,
  6756.             Privilege => ILD.OWNER);
  6757.     return HL.Return_Code(HL.SUCCESS);
  6758.  
  6759. exception
  6760.  
  6761.     when SI.Process_Help =>
  6762.     return HL.Return_Code(HL.INFORMATION);
  6763.  
  6764.     when SI.Abort_Process =>
  6765.     return HL.Return_Code(HL.SUCCESS);
  6766.  
  6767.     when ILD.Library_Does_Not_Exist =>
  6768.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ does not exist.");
  6769.     return HL.Return_Code(HL.ERROR);
  6770.  
  6771.     when ILD.Library_Master_Locked =>
  6772.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is master locked.");
  6773.     return HL.Return_Code(HL.ERROR);
  6774.  
  6775.     when ILD.Library_Write_Locked =>
  6776.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is write locked.");
  6777.     return HL.Return_Code(HL.ERROR);
  6778.  
  6779.     when ILD.Library_Read_Locked =>
  6780.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is read locked.");
  6781.     return HL.Return_Code(HL.ERROR);
  6782.  
  6783.     when ILD.Invalid_Keyword =>
  6784.         HL.Put_Error("Property keyword """ & SP.Value(SP.Upper(Keyword)) & """ invalid.");
  6785.     return HL.Return_Code(HL.ERROR);
  6786.  
  6787.     when ILD.Keyword_Not_Found =>
  6788.         HL.Put_Error("Property keyword """ & SP.Value(SP.Upper(Keyword)) &
  6789.              """ not found.");
  6790.     return HL.Return_Code(HL.ERROR);
  6791.  
  6792.     when ILD.Not_Authorized =>
  6793.     HL.Put_Error("Not authorized.");
  6794.     return HL.Return_Code(HL.ERROR);
  6795.  
  6796.     when ILD.No_Privilege =>
  6797.     HL.Put_Error("No privilege for attempted operation.");
  6798.     return HL.Return_Code(HL.ERROR);
  6799.  
  6800.     when others =>
  6801.     HL.Put_Error("Delete Property internal error.");
  6802.     return HL.Return_Code(HL.SEVERE);
  6803.  
  6804. end Delete_Property;
  6805.  
  6806. ::::::::::::::
  6807. deletep.bdy
  6808. ::::::::::::::
  6809. with Library_Errors;
  6810. with Library_Utilities;
  6811. with HIF_Node_Defs;
  6812. with HIF_Node_Management;
  6813. with HIF_Attributes;
  6814.  
  6815. function Delete_Property_Interface(
  6816.     Library   : in String_Pkg.String_Type;
  6817.     Keyword   : in String_Pkg.String_Type;
  6818.     Privilege : in Privilege_Type := WORLD
  6819.     ) return Host_Lib.Severity_Code is
  6820.  
  6821.     package SP  renames String_Pkg;
  6822.     package HL  renames Host_Lib;
  6823.     package LE  renames Library_Errors;
  6824.     package LU  renames Library_Utilities;
  6825.     package HND renames HIF_Node_Defs;
  6826.     package HNM renames HIF_Node_Management;
  6827.     package HA  renames HIF_Attributes;
  6828.  
  6829.     Node : HND.Node_Type;
  6830.     Trap : HL.Interrupt_State := HL.Get_Interrupt_State;
  6831.  
  6832. begin
  6833.  
  6834.     if HL."="(Trap, HL.DISABLED) then
  6835.     HL.Enable_Interrupt_Trap;
  6836.     end if;
  6837.     if not LU.Lock_Library(Library, WRITE_LOCK) then
  6838.     raise Library_Write_Locked;
  6839.     end if;
  6840.     if not LU.Privileged(Privilege, Library) then
  6841.     raise No_Privilege; 
  6842.     end if;
  6843.     LU.Open_Property_Node(Library, Keyword, SP.Create(""), DELETE, Node);
  6844.     HA.Set_Node_Attribute(Node   => Node,
  6845.               Attrib => SP.Value(Keyword),
  6846.               Value  => "");
  6847.     HNM.Close_Node_Handle(Node);
  6848.     LU.Unlock_Library(Library, WRITE_LOCK);
  6849.     if Message_on_Completion then
  6850.     HL.Put_Message_Line(
  6851.         "Property " & SP.Value(SP.Upper(Keyword)) &
  6852.         " deleted from for library " & SP.Value(SP.Upper(Library)) & '.');
  6853.     end if;
  6854.     HL.Set_Interrupt_State(Trap);
  6855.     return HL.SUCCESS;
  6856.  
  6857. exception
  6858.  
  6859.     when Invalid_Library_Name =>
  6860.     LE.Report_Error(LE.Invalid_Library_Name, Library);
  6861.     HL.Set_Interrupt_State(Trap);
  6862.     return HL.ERROR;
  6863.  
  6864.     when Library_Does_Not_Exist =>
  6865.     LE.Report_Error(LE.Library_Does_Not_Exist, Library);
  6866.     HL.Set_Interrupt_State(Trap);
  6867.     return HL.ERROR;
  6868.  
  6869.     when Library_Master_Locked =>
  6870.     LE.Report_Error(LE.Library_Master_Locked, Library);
  6871.     HL.Set_Interrupt_State(Trap);
  6872.     return HL.ERROR;
  6873.  
  6874.     when Library_Write_Locked =>
  6875.     LE.Report_Error(LE.Library_Write_Locked, Library);
  6876.     HL.Set_Interrupt_State(Trap);
  6877.     return HL.ERROR;
  6878.  
  6879.     when Invalid_Keyword =>
  6880.     LU.Unlock_Library(Library, WRITE_LOCK);
  6881.     LE.Report_Error(LE.Invalid_Keyword, Keyword);
  6882.     HL.Set_Interrupt_State(Trap);
  6883.     return HL.ERROR;
  6884.  
  6885.     when Keyword_Not_Found =>
  6886.     LU.Unlock_Library(Library, WRITE_LOCK);
  6887.     LE.Report_Error(LE.Keyword_Not_Found, Keyword);
  6888.     HL.Set_Interrupt_State(Trap);
  6889.     return HL.ERROR;
  6890.  
  6891.     when No_Privilege =>
  6892.     LU.Unlock_Library(Library, WRITE_LOCK);
  6893.     LE.Report_Error(LE.No_Privilege, Library, SP.Create(LU.Get_Library_Attribute(Library, "OWNER")));
  6894.     HL.Set_Interrupt_State(Trap);
  6895.     return HL.ERROR;
  6896.  
  6897.     when HL.Interrupt_Encountered =>
  6898.     begin
  6899.         LU.Unlock_Library(Library, WRITE_LOCK);
  6900.     exception
  6901.         when others => null;
  6902.     end;
  6903.     if HL."="(Trap, HL.ENABLED) then
  6904.         raise HL.Interrupt_Encountered;
  6905.     end if;
  6906.     LE.Report_Error(LE.Process_Interrupted, SP.Create("Delete_Property"));
  6907.     HL.Set_Interrupt_State(Trap);
  6908.     return HL.WARNING;
  6909.  
  6910.     when others =>
  6911.     begin
  6912.         LU.Unlock_Library(Library, WRITE_LOCK);
  6913.     exception
  6914.         when others => null;
  6915.     end;
  6916.     LE.Report_Error(LE.Internal_Error, SP.Create("Delete_Property"));
  6917.     HL.Set_Interrupt_State(Trap);
  6918.     return HL.SEVERE;
  6919.  
  6920. end Delete_Property_Interface;
  6921.                                                                     pragma page;
  6922. ::::::::::::::
  6923. deletep.spc
  6924. ::::::::::::::
  6925. with Library_Declarations;            use Library_Declarations;
  6926. with String_Pkg;
  6927. with Host_Lib;
  6928.  
  6929. function Delete_Property_Interface(        --| Delete Property Keyword
  6930.     Library   : in String_Pkg.String_Type;    --| Item library
  6931.     Keyword   : in String_Pkg.String_Type;    --| Property keyword
  6932.     Privilege : in Privilege_Type := WORLD    --| Delete privilege
  6933.     ) return Host_Lib.Severity_Code;
  6934.  
  6935. --| Requires:
  6936. --| The names of the library and the keyword.
  6937.  
  6938. --| Effects:
  6939. --| Keyword associated with the library is deleted.
  6940.  
  6941. --| N/A: Modifies, Raises, Errors
  6942.                                                                     pragma page;
  6943. ::::::::::::::
  6944. delhuser.bdy
  6945. ::::::::::::::
  6946. with HIF_System_Management;
  6947. with HIF_Node_management;
  6948. with HIF_Node_Defs;
  6949. with Document_Manager_Declarations;
  6950.      
  6951. function Delete_HIF_User_Interface(
  6952.     User : String_Pkg.String_Type
  6953.     ) return Host_Lib.Severity_Code is
  6954.  
  6955.     package SP  renames String_Pkg;
  6956.     package HL  renames Host_Lib;
  6957.     package HNM renames HIF_Node_Management;
  6958.     package HND renames HIF_Node_Defs;
  6959.     package HSM renames HIF_System_Management;
  6960.     package DMD renames Document_Manager_Declarations;
  6961.  
  6962.     DOCMGR_Node : HND.Node_Type;
  6963.  
  6964. begin
  6965.  
  6966.     begin
  6967.     HNM.Open_Node_Handle(DOCMGR_Node, DMD.Document_Manager_List_Path);
  6968.  
  6969.     -- In case this user is a catalog or library try and unlink it from
  6970.     -- the docmgr list node before deleting the user.  Notice that if the link
  6971.     -- doesn't exist and name error is raised nothing happens.
  6972.  
  6973.     begin
  6974.         HNM.Unlink(Base     => DOCMGR_Node,
  6975.                Key      => SP.Value(User),
  6976.                Relation => "CATALOG");    
  6977.     exception
  6978.         when HND.Name_Error => null;
  6979.     end;
  6980.     begin
  6981.         HNM.Unlink(Base     => DOCMGR_Node,
  6982.                Key      => SP.Value(User),
  6983.                Relation => "LIBRARY");    
  6984.     exception
  6985.         when HND.Name_Error => null;
  6986.     end;
  6987.     exception
  6988.     when HND.Name_Error => null;
  6989.     end;
  6990.     begin
  6991.     HSM.Delete_User(User_Name =>SP.Value(User));
  6992.     exception
  6993.     when HND.Name_Error => null;
  6994.     end;
  6995.     HNM.Close_Node_Handle(DOCMGR_Node);
  6996.  
  6997.     return HL.SUCCESS;
  6998.  
  6999. exception
  7000.     when others =>
  7001.     HL.Put_Error("Fatal error in delete");
  7002.     return HL.SEVERE;
  7003.  
  7004. end Delete_HIF_User_Interface;
  7005.                                                                     pragma page;
  7006. ::::::::::::::
  7007. delhuser.spc
  7008. ::::::::::::::
  7009. with String_Pkg;
  7010. with Host_Lib;
  7011.      
  7012. function Delete_HIF_User_Interface(        --| Delete a HIF user
  7013.     User : String_Pkg.String_Type        --| User to be deleted
  7014.     ) return Host_Lib.Severity_Code;
  7015.  
  7016. --| Requires:
  7017. --| Name of the user to be deleted
  7018.  
  7019. --| Effects:
  7020. --| Delete a HIF user
  7021.  
  7022. --| N/A: Modifies, Raises, Errors
  7023.                                                                     pragma page;
  7024. ::::::::::::::
  7025. deluser.ada
  7026. ::::::::::::::
  7027. with Host_Lib;
  7028. with String_pkg;
  7029. with Standard_Interface;
  7030. with Tool_Identifier;
  7031. with Delete_HIF_User_Interface;
  7032.      
  7033. function Delete_User return INTEGER is
  7034.  
  7035.     package HL  renames Host_Lib;
  7036.     package SP  renames String_pkg;
  7037.     package SI  renames Standard_Interface;
  7038.  
  7039.     Process  : SI.Process_Handle;
  7040.  
  7041. begin
  7042.     SI.Set_Tool_Identifier(Tool_Identifier);
  7043.     SI.Define_Process("delete_user",
  7044.                "Delete yourself as a documentation system user",
  7045.                Process);
  7046.     SI.Parse_Line(Process);
  7047.     return HL.Return_Code(Delete_HIF_User_Interface(SP.Create(HL.Get_Item(HL.USER_NAME))));
  7048.  
  7049. exception
  7050.  
  7051.     when SI.Process_Help =>
  7052.     return HL.Return_Code(HL.INFORMATION);
  7053.     when SI.Abort_Process =>
  7054.     return HL.Return_Code(HL.ERROR);
  7055.     when others =>
  7056.     HL.Put_Error("Fatal error in Delete_User");
  7057.     return HL.Return_Code(HL.SEVERE);
  7058.  
  7059. end Delete_User;
  7060.                                                                     pragma page;
  7061. ::::::::::::::
  7062. docmgr.dat
  7063. ::::::::::::::
  7064.  
  7065. package Document_Manager_Declarations is
  7066.  
  7067. --------------------------------------------------------------------------------
  7068. --    Change Document_Manager_List to alter the document manager's          --
  7069. --    list root node name  (No need to alter Document_Manager_List_Path).   --
  7070. --------------------------------------------------------------------------------
  7071.  
  7072. Document_Manager_List      : constant STRING := "DOCMGR";
  7073. Document_Manager_List_Path : constant STRING := "'USER(" & Document_Manager_List & ')';
  7074.  
  7075. end Document_Manager_Declarations;
  7076.  
  7077. ::::::::::::::
  7078. fetchi.ada
  7079. ::::::::::::::
  7080. with Standard_Interface;
  7081. with String_Pkg;
  7082. with Host_Lib;
  7083. with Tool_Identifier;
  7084. with Library_Errors;
  7085. with Library_Declarations;
  7086. with Fetch_Item_Interface;
  7087.  
  7088. function Fetch_Item return INTEGER is
  7089.  
  7090.     package SI  renames Standard_Interface;
  7091.     package SP  renames String_Pkg;
  7092.     package HL  renames Host_Lib;
  7093.     package LE  renames Library_Errors;
  7094.     package ILD renames Library_Declarations;
  7095.     package LIB is new SI.String_Argument(String_Type_Name => "library_name");
  7096.     package ITM is new SI.String_Argument(String_Type_Name => "item_name");
  7097.     package VER is new SI.String_Argument(String_Type_Name => "version");
  7098.     package FIM is new SI.Enumerated_Argument(Enum_Type      => ILD.State_Type,
  7099.                           Enum_Type_Name => "fetch_mode");
  7100.  
  7101.     Fetch_Item_Process  : SI.Process_Handle;
  7102.     Library             : SP.String_Type;
  7103.     Item                : SP.String_Type;
  7104.     Version             : SP.String_Type;
  7105.     Fetch_Item_Mode     : ILD.State_Type;
  7106.  
  7107. begin
  7108.  
  7109.     SP.Mark;
  7110.  
  7111.     SI.Set_Tool_Identifier(Identifier => "1.0");
  7112.  
  7113.     SI.Define_Process(
  7114.     Proc    => Fetch_Item_Process,
  7115.     Name    => "Fetch_Item",
  7116.     Help    => "Fetch an Item from an Item Library");
  7117.  
  7118.     LIB.Define_Argument(
  7119.     Proc => Fetch_Item_Process,
  7120.     Name => "library",
  7121.     Help => "Name of the item library");
  7122.  
  7123.     ITM.Define_Argument(
  7124.     Proc => Fetch_Item_Process,
  7125.     Name => "item",
  7126.     Help => "Name of the item to be fetched from the item library");
  7127.  
  7128.     VER.Define_Argument(
  7129.     Proc    => Fetch_Item_Process,
  7130.     Name    => "version",
  7131.     Default => "",
  7132.     Help    => "Version specification");
  7133.  
  7134.     FIM.Define_Argument(
  7135.     Proc    => Fetch_Item_Process,
  7136.     Name    => "mode",
  7137.     Default => ILD.NO_UPDATE,
  7138.     Help    => "Fetch mode:");
  7139.  
  7140.     FIM.Append_Argument_Help(
  7141.     Proc    => Fetch_Item_Process,
  7142.     Name    => "mode",
  7143.     Help    => "   NO_UPDATE : check out an item for read only");
  7144.  
  7145.     FIM.Append_Argument_Help(
  7146.     Proc    => Fetch_Item_Process,
  7147.     Name    => "mode",
  7148.     Help    => "   UPDATE    : check out an item for update");
  7149.  
  7150.     SP.Release;
  7151.  
  7152.     SI.Parse_Line(Fetch_Item_Process);
  7153.     
  7154.     Library := LIB.Get_Argument(
  7155.             Proc => Fetch_Item_Process,
  7156.             Name => "library");
  7157.  
  7158.     Item := ITM.Get_Argument(
  7159.             Proc => Fetch_Item_Process,
  7160.             Name => "item");
  7161.  
  7162.     Version := VER.Get_Argument(
  7163.             Proc => Fetch_Item_Process,
  7164.             Name => "version");
  7165.  
  7166.     Fetch_Item_Mode := FIM.Get_Argument(
  7167.             Proc => Fetch_Item_Process,
  7168.             Name => "mode");
  7169.  
  7170.     return HL.Return_Code(Fetch_Item_Interface(Library, Item, Version, Fetch_Item_Mode));
  7171.  
  7172. exception
  7173.  
  7174.     when SI.Process_Help =>
  7175.     return HL.Return_Code(HL.INFORMATION);
  7176.  
  7177.     when SI.Abort_Process =>
  7178.     return HL.Return_Code(HL.ERROR);
  7179.  
  7180.     when others =>
  7181.     LE.Report_Error(LE.Internal_Error, SP.Create(""));
  7182.     return HL.Return_Code(HL.SEVERE);
  7183.  
  7184. end Fetch_Item;
  7185.                                                                     pragma page;
  7186. ::::::::::::::
  7187. fetchi.bdy
  7188. ::::::::::::::
  7189. with Library_Declarations;            use Library_Declarations;
  7190. with Library_Errors;
  7191. with Library_Utilities;
  7192. with TEXT_IO;
  7193. with HIF_Utils;
  7194. with HIF_Node_Defs;
  7195. with HIF_Node_Management;
  7196. with HIF_Attributes;
  7197. with File_Manager;
  7198.  
  7199. function Fetch_Item_Interface(
  7200.     Library : in String_Pkg.String_Type;
  7201.     Item    : in String_Pkg.String_Type;
  7202.     Version : in String_Pkg.String_Type;
  7203.     Mode    : in State_Type := NO_UPDATE
  7204.     ) return Host_Lib.Severity_Code is
  7205.  
  7206.     package SP  renames String_Pkg;
  7207.     package HL  renames Host_Lib;
  7208.     package LE  renames Library_Errors;
  7209.     package LU  renames Library_Utilities;
  7210.     package TIO renames TEXT_IO;
  7211.     package HU  renames HIF_Utils;
  7212.     package HND renames HIF_Node_Defs;
  7213.     package HNM renames HIF_Node_Management;
  7214.     package HA  renames HIF_Attributes;
  7215.     package FM  renames File_Manager;
  7216.  
  7217.     Library_Node        : HND.Node_Type;
  7218.     Item_Node           : HND.Node_Type;
  7219.     Full_Item_Name      : SP.String_Type;
  7220.     Full_Item_Node      : HND.Node_Type;
  7221.     Versions            : SL.List;
  7222.     Version_Number      : SP.String_Type;
  7223.     File_Handle         : TIO.File_Type;
  7224.     Attribute_Value     : STRING(1 .. 16);
  7225.     Attribute_Length    : INTEGER;
  7226.     Check_Out_Count     : NATURAL;
  7227.     Checked_Out_Version : SP.String_Type;
  7228.     Trap                : HL.Interrupt_State := HL.Get_Interrupt_State;
  7229.  
  7230. begin
  7231.  
  7232.     if HL."="(Trap, HL.DISABLED) then
  7233.     HL.Enable_Interrupt_Trap;
  7234.     end if;
  7235.     if Mode = UPDATE then
  7236.     if not LU.Lock_Library(Library, WRITE_LOCK) then
  7237.         raise Library_Write_Locked;
  7238.     end if;
  7239.     else
  7240.     if not LU.Lock_Library(Library, READ_LOCK) then
  7241.         raise Library_Read_Locked;
  7242.     end if;
  7243.     end if;
  7244.     LU.Is_Item(Item_Node, Library, Item);
  7245.     if not HNM.Is_Open(Item_Node) then
  7246.     raise Item_Not_Found;
  7247.     end if;
  7248.     if Mode = UPDATE then
  7249.     Checked_Out_Version := SP.Make_Persistent(LU.Checked_Out_By(Item_Node));
  7250.     if not SP.Is_Empty(Checked_Out_Version) then
  7251.         HNM.Close_Node_Handle(Item_Node);
  7252.         raise Item_Checked_Out;
  7253.     end if;
  7254.     end if;
  7255.     Versions := LU.Get_Version(Item_Node, Version);
  7256.     Version_Number := SL.FirstValue(Versions);
  7257.     HU.Get_Node_Attribute(Node       => Item_Node,
  7258.               Attrib     => "V",
  7259.               Value      => Attribute_Value,
  7260.               Value_Last => Attribute_Length);
  7261.     if Mode = UPDATE and 
  7262.        Attribute_Value(1 .. Attribute_Length) /= SP.Value(Version_Number) then
  7263.     Destroy_String_List(Versions);
  7264.     HNM.Close_Node_Handle(Item_Node);
  7265.     raise Invalid_Operation;
  7266.     end if;
  7267.     Full_Item_Name := LU.Node_Name(Library, Item, SP.Value(Version_Number));
  7268.     Checked_Out_Version := SP.Make_Persistent(SP.Value(Version_Number));
  7269.     Destroy_String_List(Versions);
  7270.     LU.Is_Node(Full_Item_Node, Full_Item_Name);
  7271.     if not HNM.Is_Open(Full_Item_Node) then
  7272.     HNM.Close_Node_Handle(Item_Node);
  7273.     raise Internal_Error;
  7274.     end if;
  7275.     begin
  7276.     FM.Copy(HNM.Host_File_Name(Full_Item_Node),
  7277.         SP.Value(Item));
  7278.     exception
  7279.     when others =>
  7280.         HNM.Close_Node_Handle(Full_Item_Node);
  7281.         HNM.Close_Node_Handle(Item_Node);
  7282.         raise File_Not_Created;
  7283.     end;
  7284.     HNM.Close_Node_Handle(Full_Item_Node);
  7285.     if Mode = UPDATE then
  7286.     HA.Set_Node_Attribute(Node   => Item_Node,
  7287.                   Attrib => "CHECKED_OUT",
  7288.                   Value  => HL.Get_Item(HL.USER_NAME));
  7289.     LU.Change_Checked_Out_Count(Library, +1);
  7290.     LU.Unlock_Library(Library, WRITE_LOCK);
  7291.     else
  7292.     LU.Unlock_Library(Library, READ_LOCK);
  7293.     end if;
  7294.     HNM.Close_Node_Handle(Item_Node);
  7295.     if Message_on_Completion then
  7296.     HL.Put_Message_Line(
  7297.         "Item " & SP.Value(SP.Upper(Item)) & '/' & SP.Value(Checked_Out_Version) &
  7298.         " fetched from library " & SP.Value(SP.Upper(Library)) & '.');
  7299.     end if;
  7300.     HL.Set_Interrupt_State(Trap);
  7301.     return HL.SUCCESS;
  7302.  
  7303. exception
  7304.  
  7305.     when Invalid_Library_Name =>
  7306.     LE.Report_Error(LE.Invalid_Library_Name, Library);
  7307.     HL.Set_Interrupt_State(Trap);
  7308.     return HL.ERROR;
  7309.  
  7310.     when Library_Does_Not_Exist =>
  7311.     LE.Report_Error(LE.Library_Does_Not_Exist, Library);
  7312.     HL.Set_Interrupt_State(Trap);
  7313.     return HL.ERROR;
  7314.  
  7315.     when Library_Master_Locked =>
  7316.     LE.Report_Error(LE.Library_Master_Locked, Library);
  7317.     HL.Set_Interrupt_State(Trap);
  7318.     return HL.ERROR;
  7319.  
  7320.     when Library_Write_Locked =>
  7321.     LE.Report_Error(LE.Library_Write_Locked, Library);
  7322.     HL.Set_Interrupt_State(Trap);
  7323.     return HL.ERROR;
  7324.  
  7325.     when Library_Read_Locked =>
  7326.     LE.Report_Error(LE.Library_Read_Locked, Library);
  7327.     HL.Set_Interrupt_State(Trap);
  7328.     return HL.ERROR;
  7329.  
  7330.     when Item_Not_Found =>
  7331.     LU.Unlock_Library(Library, WRITE_LOCK);
  7332.     LE.Report_Error(LE.Item_Not_Found, Item);
  7333.     HL.Set_Interrupt_State(Trap);
  7334.     return HL.ERROR;
  7335.  
  7336.     when File_Not_Created =>
  7337.     LU.Unlock_Library(Library, WRITE_LOCK);
  7338.     LE.Report_Error(LE.File_Not_Created, Item);
  7339.     HL.Set_Interrupt_State(Trap);
  7340.     return HL.ERROR;
  7341.  
  7342.     when Set_Protection_Error =>
  7343.     LU.Unlock_Library(Library, WRITE_LOCK);
  7344.     LE.Report_Error(LE.Set_Protection_Error, Item);
  7345.     HL.Set_Interrupt_State(Trap);
  7346.     return HL.ERROR;
  7347.  
  7348.     when Item_Checked_Out =>
  7349.     LU.Unlock_Library(Library, WRITE_LOCK);
  7350.     LE.Report_Error(LE.Item_Checked_Out, Item);
  7351.     HL.Set_Interrupt_State(Trap);
  7352.     return HL.ERROR;
  7353.  
  7354.     when Invalid_Operation =>
  7355.     LU.Unlock_Library(Library, WRITE_LOCK);
  7356.     LE.Report_Error(LE.Invalid_Operation, Version);
  7357.     HL.Set_Interrupt_State(Trap);
  7358.     return HL.ERROR;
  7359.  
  7360.     when Invalid_Version =>
  7361.     LU.Unlock_Library(Library, WRITE_LOCK);
  7362.     LE.Report_Error(LE.Invalid_Version, Version);
  7363.     HL.Set_Interrupt_State(Trap);
  7364.     return HL.ERROR;
  7365.  
  7366.     when Version_Not_Found =>
  7367.     LU.Unlock_Library(Library, WRITE_LOCK);
  7368.     LE.Report_Error(LE.Version_Not_Found, Version);
  7369.     HL.Set_Interrupt_State(Trap);
  7370.     return HL.ERROR;
  7371.  
  7372.     when HL.Interrupt_Encountered =>
  7373.     begin
  7374.         LU.Unlock_Library(Library, WRITE_LOCK);
  7375.     exception
  7376.         when others => null;
  7377.     end;
  7378.     if HL."="(Trap, HL.ENABLED) then
  7379.         raise HL.Interrupt_Encountered;
  7380.     end if;
  7381.     LE.Report_Error(LE.Process_Interrupted, SP.Create("Fetch_Item"));
  7382.     HL.Set_Interrupt_State(Trap);
  7383.     return HL.WARNING;
  7384.  
  7385.     when others =>
  7386.     begin
  7387.         LU.Unlock_Library(Library, WRITE_LOCK);
  7388.     exception
  7389.         when others => null;
  7390.     end;
  7391.     LE.Report_Error(LE.Internal_Error, SP.Create("Fetch_Item"));
  7392.     HL.Set_Interrupt_State(Trap);
  7393.     return HL.SEVERE;
  7394.  
  7395. end Fetch_Item_Interface;
  7396.                                                                     pragma page;
  7397. ::::::::::::::
  7398. fetchi.spc
  7399. ::::::::::::::
  7400. with String_Pkg;
  7401. with Host_Lib;
  7402. with Library_Declarations;
  7403.  
  7404. function Fetch_Item_Interface(            --| Fetch an Item
  7405.    Library : in String_Pkg.String_Type;        --| Item library
  7406.    Item    : in String_Pkg.String_Type;        --| Item to be fetched
  7407.    Version : in String_Pkg.String_Type;        --| Version specification
  7408.    Mode    : in Library_Declarations.State_Type := Library_Declarations.NO_UPDATE
  7409.                         --| Fetch mode: (NO_UPDATE/UPDATE)
  7410.    ) return Host_Lib.Severity_Code;
  7411.  
  7412. --| Requires:
  7413. --| Name of the library, item name to be fetched from the library, and version
  7414. --| specification of the item to be fetched
  7415.  
  7416. --| Effects:
  7417. --| Creates a file (in the external file system) from the named version of
  7418. --| the named item in the named library
  7419.  
  7420. --| N/A: Modifies, Raises, Errors
  7421.                                                                     pragma page;
  7422. ::::::::::::::
  7423. fgen.bdy
  7424. ::::::::::::::
  7425.  
  7426. with String_Pkg;
  7427. with String_Utilities; use String_Utilities;
  7428. with Text_IO;
  7429. with Catalog_Manager;
  7430. with CI_Ids;
  7431. with Item_Library_Manager_Utilities;
  7432. with Host_Dependencies; 
  7433. with Stack_Pkg;
  7434. with Labeled_Binary_Trees_Pkg;
  7435. with Case_Insensitive_String_Comparison;
  7436. with File_Manager;
  7437. with Item_Library_Manager_Declarations;
  7438.  
  7439. package body Process_File is
  7440.  
  7441. ---------------------------------------------------
  7442.  
  7443. -- package SP renames String_Pkg;
  7444. package CISC renames Case_Insensitive_String_Comparison;
  7445. package FM renames File_Manager;
  7446. package ILMD renames Item_Library_Manager_Declarations;
  7447. package CM renames Catalog_Manager;
  7448.  
  7449. ---------------------------------------------------
  7450.  
  7451.     Line_Mark: constant character:= '#';
  7452.  
  7453.     Curr_Catalog: SP.String_Type; -- Catalog containing source file.
  7454.  
  7455.     function Compare(x,y: SP.String_Type) return INTEGER;
  7456.  
  7457.     package VL is new Labeled_Binary_Trees_Pkg(
  7458.                 Label_Type => SP.String_Type,
  7459.                 Value_Type => SP.String_Type,
  7460.                 Difference => Compare);
  7461.  
  7462.     -- handling a number of files:
  7463.     type File_Kind_Type is (Cat_File, Lib_File, Arbitrary_File);
  7464.  
  7465.     type File_Info_Type(File_Kind : File_Kind_Type) is record
  7466.     Full_File_Name    : SP.String_Type;
  7467.     My_Variables    : VL.tree;
  7468.     Line_Number    : INTEGER;
  7469.     case File_Kind is
  7470.         when Cat_File =>
  7471.         CI_Name        : SP.String_Type;
  7472.         Comp_Name    : SP.String_Type;
  7473.         CI_Version    : SP.String_Type;
  7474.         when Lib_File =>
  7475.         Lib_Name    : SP.String_Type;
  7476.         Item_Name    : SP.String_Type;
  7477.         Item_Version    : SP.String_Type;
  7478.         when Arbitrary_File =>
  7479.         NULL;
  7480.  
  7481.       end case;
  7482.     
  7483.     end record;
  7484.  
  7485.     type File_Info_Ptr is access File_Info_Type;
  7486.     Curr_File_Info    : File_Info_Ptr := Null;
  7487.  
  7488.     package ST is new Stack_Pkg(File_Info_Ptr);
  7489.  
  7490.     File_Stack        : ST.Stack := ST.Create;
  7491.  
  7492.     -- to prosess a directive line
  7493.     package SU is new String_Utilities.Generic_String_Utilities(
  7494.                 Generic_String_Type => SP.String_Type,
  7495.                 To_Generic => SP.Create,
  7496.                 From_Generic => SP.Value);
  7497.     use SU;
  7498.  
  7499.     
  7500. -- local procedures
  7501. ----------------------------------------------------------------
  7502.    
  7503. procedure Scan_File_And_Copy(
  7504.         Full_File_Name    : in out SP.String_Type;
  7505.         File_Kind    : File_Kind_Type;
  7506.         CI_Or_Lib_Name    : SP.String_Type;
  7507.         Comp_Or_Item_Name : SP.String_Type;    
  7508.         Version        : SP.String_Type);
  7509.  
  7510. -----------------------------------------------------------------
  7511.  
  7512. procedure Process_Directive(
  7513.         S    : Scanner);
  7514.  
  7515. ----------------------------------------------------------------
  7516.  
  7517. procedure Process_Variable_Def(
  7518.         S    : Scanner);
  7519.  
  7520. --------------------------------------------------------------
  7521.  
  7522. procedure Process_Include(
  7523.         S    : Scanner);
  7524.  
  7525. -------------------------------------------------------------
  7526.  
  7527. procedure Process_Substitution(
  7528.         S    : Scanner);
  7529. -----------------------------------------------------------------
  7530.  
  7531. function Process_Primary(
  7532.         S    : Scanner) return SP.String_Type;
  7533.  
  7534. -----------------------------------------------------------------
  7535.  
  7536. procedure Init_Variables;
  7537.  
  7538. -----------------------------------------------------------------
  7539.  
  7540. procedure Put_Location;
  7541.  
  7542. -----------------------------------------------------------------
  7543.  
  7544. function Check_Cycle(
  7545.         Full_File_Name    : SP.String_Type;
  7546.         File_Kind    : File_Kind_Type;
  7547.         CI_Or_Lib_Name    : SP.String_Type;
  7548.         Comp_Or_Item_Name : SP.String_Type;    
  7549.         Version        : SP.String_Type) return boolean;
  7550.  
  7551. -----------------------------------------------------------------
  7552.  
  7553. procedure Check_Nothing_Or_Comment_Left(
  7554.         S    : Scanner);
  7555.  
  7556. -----------------------------------------------------------------
  7557.  
  7558. function Compare(
  7559.     X,Y    : SP.String_Type) return INTEGER is
  7560.  
  7561.     Result    : INTEGER;
  7562. begin
  7563.  
  7564.     return CISC.Compare(SP.Value(X), SP.Value(Y));
  7565.  
  7566. end Compare;
  7567.  
  7568. --------------------------------------------------------------
  7569.  
  7570. procedure File_Gen(
  7571.     Source_File    : SP.String_Type;
  7572.     Result_File    : SP.String_Type;
  7573.     Catalog    : SP.String_Type;
  7574.     CI_Name_Ver    : SP.String_Type) is
  7575.  
  7576.     Full_File_Name : SP.String_Type;
  7577.     File_From_Cat : boolean;
  7578.     Id        : CI_Ids.CI_Id_Type;
  7579.     Output_File    : Text_IO.File_Type;
  7580.  
  7581. begin
  7582.     Curr_Catalog := Catalog;
  7583.  
  7584.     -- open the input and output files; set them to the standard
  7585.     -- input and output files
  7586.     File_From_Cat := not SP.Is_Empty(CI_Name_Ver);
  7587.     if not File_From_Cat then
  7588.     Full_File_Name := SP.Create(FM.Parse_Filename(SP.Value(Source_File)));
  7589.                     --now the name is a full path name
  7590.  
  7591.     else
  7592.     Full_File_Name := CM.Get_Hif_File_Name
  7593.                 (Catalog, CI_Name_Ver, Source_File);
  7594.  
  7595.     end if;
  7596.  
  7597.     if not SP.Is_Empty(Result_File) then
  7598.       begin
  7599.         Text_IO.Create(Output_File, Text_IO.Out_File, SP.Value(Result_File));
  7600.     Text_IO.Set_Output(Output_File);
  7601.       exception
  7602.     when Text_IO.Status_Error | Text_IO.Name_Error | Text_IO.Use_Error =>
  7603.       text_IO.put_Line("?? Unable to open " & SP.Value(Result_File)
  7604.             & " for output");
  7605.       raise abort_filegen;
  7606.       end;
  7607.     end if;
  7608.  
  7609.     -- do the work
  7610.     if not File_From_Cat then
  7611.     Scan_File_And_Copy(Full_File_Name, Arbitrary_File, SP.Create(""),
  7612.                SP.Create(""), SP.Create(""));
  7613.  
  7614.     else
  7615.     Id := CI_Ids.Get_CI_Id(CI_Name_Ver);
  7616.     Scan_File_And_Copy(Full_File_Name, Cat_File, CI_Ids.Get_Name(Id),
  7617.                Source_File, CI_Ids.Get_Version(Id));
  7618.  
  7619.     end if;
  7620.  
  7621.     if not SP.Is_Empty(Result_File) then
  7622.         Text_IO.Close(Output_File);
  7623.  
  7624.     end if;
  7625.  
  7626. exception
  7627.     when FM.Parse_Error =>
  7628.     Text_IO.Put_Line(SP.Value(Source_File) & " is illegal file name");
  7629.     raise abort_filegen;
  7630.  
  7631.     when CM.No_Such_Catalog =>
  7632.     Text_IO.Put_Line("No such catalog " & SP.Value(Catalog));
  7633.     raise abort_filegen;
  7634.  
  7635.     when CM.No_Such_Ci | CM.invalid_ci_id | CM.deleted_ci =>
  7636.     Text_IO.Put_Line("No such ci item " & SP.Value(CI_Name_Ver));
  7637.     raise abort_filegen;
  7638.  
  7639.     when CM.No_Such_Component | CM.invalid_ci_name =>
  7640.     Text_IO.Put_Line("No such ci component " & SP.Value(Source_File));
  7641.     raise abort_filegen;
  7642.  
  7643. end file_gen;
  7644.  
  7645. -----------------------------------------------------------------
  7646.  
  7647. procedure Scan_File_And_Copy(
  7648.         Full_File_Name    : in out SP.String_Type;
  7649.         File_Kind    : File_Kind_Type;
  7650.         CI_Or_Lib_Name    : SP.String_Type;
  7651.         Comp_Or_Item_Name : SP.String_Type;    
  7652.         Version        : SP.String_Type) is
  7653.  
  7654.     Input_File    : Text_IO.File_Type;
  7655.     Line    : string(1..256);    -- This can be changed
  7656.     Length    : INTEGER;
  7657.     called_1st_time: boolean := False;
  7658.  
  7659. begin
  7660.     -- all SP strings created in the processing of a file will
  7661.     -- be released at the end of this procedure
  7662. --xx    SP.mark;
  7663.  
  7664.     -- handle the existence of the new file
  7665.     if Curr_File_Info = Null then
  7666.         called_1st_time := TRUE;
  7667.  
  7668.     else
  7669.     if Check_Cycle(Full_File_Name, File_Kind, CI_Or_Lib_Name,
  7670.                Comp_Or_Item_Name, Version) then
  7671. --xx        SP.Release;
  7672.         return;
  7673.  
  7674.     else
  7675.             -- everything went fine
  7676.         ST.Push(File_Stack, Curr_File_Info);
  7677.  
  7678.     end if;
  7679.  
  7680.     end if;
  7681.  
  7682.     Text_IO.Open(Input_File, Text_IO.In_File, SP.Value(Full_File_Name));
  7683.  
  7684.     case File_Kind is
  7685.     when Cat_File =>
  7686.             Curr_File_Info := new File_Info_Type(Cat_File);
  7687.         Curr_File_Info.CI_Name := CI_Or_Lib_Name;
  7688.         Curr_File_Info.Comp_Name := Comp_Or_Item_Name;
  7689.         Curr_File_Info.CI_Version := Version;
  7690.     
  7691.     when Lib_File =>
  7692.             Curr_File_Info := new File_Info_Type(Lib_File);
  7693.         Curr_File_Info.Lib_Name := CI_Or_Lib_Name;
  7694.         Curr_File_Info.Item_Name := Comp_Or_Item_Name;
  7695.         Curr_File_Info.Item_Version := Version;
  7696.     
  7697.     when Arbitrary_File =>
  7698.             Curr_File_Info := new File_Info_Type(Arbitrary_File);
  7699.         Full_File_Name := SP.Create(FM.Parse_Filename(SP.Value(Full_File_Name)));
  7700.                 --now the name is a full path name
  7701.  
  7702.     end case;
  7703.  
  7704.     Curr_File_Info.Full_File_Name := Full_File_Name;
  7705.     Curr_File_Info.My_Variables := VL.Create;
  7706.     Curr_File_Info.Line_Number := 0;
  7707.  
  7708.     -- put values of the predefined variables (i.e. date, CI
  7709.     -- ITEM, Version) into the tree  
  7710.     Init_Variables;
  7711.  
  7712.  
  7713.     -- read lines and process them
  7714.     while not Text_IO.End_Of_File(Input_File) loop
  7715.     Text_IO.Get_Line(Input_File, Line(1..Line'Last), Length);
  7716.     Curr_File_Info.Line_Number := Curr_File_Info.Line_Number + 1;
  7717.  
  7718.     if Length > 0 and then Line(1) = Line_Mark then
  7719.         -- if the 2nd is also Line_Mark just copy the line
  7720.         -- stripping the 1st Line_mark
  7721.         if Line(2) = Line_Mark then
  7722.         Text_IO.Put_Line(Line(2..Length));
  7723.  
  7724.         else
  7725.         Process_Directive(SU.Make_Scanner(SP.Create(Line(2..Length))));
  7726.  
  7727.         end if;
  7728.  
  7729.     else
  7730.         Text_IO.Put_Line(Line(1..Length));
  7731.  
  7732.     end if;
  7733.  
  7734.     end loop;
  7735.  
  7736. --xx    SP.Release;
  7737.  
  7738.     if not called_1st_time then
  7739.     ST.Pop(File_Stack, Curr_File_Info);
  7740.  
  7741.     end if;
  7742.  
  7743.     Text_IO.Close(Input_File);
  7744.  
  7745.     return;
  7746.  
  7747. exception
  7748.     when Text_IO.Status_Error | Text_IO.Name_Error | Text_IO.Use_Error =>
  7749.         if not called_1st_time then
  7750.         ST.Pop(File_Stack, Curr_File_Info);
  7751.  
  7752.         Put_Location;
  7753.             -- this exception can happen only when opening
  7754.             -- an arbitrary file;
  7755.             -- location is of a file which
  7756.             -- includes a file
  7757.         end if;
  7758.     Text_IO.Put_Line("    Error opening file " & SP.Value(Full_File_Name));
  7759.     return;
  7760.  
  7761. end Scan_File_And_Copy;
  7762.  
  7763. -------------------------------------------------------------------------
  7764.  
  7765. procedure Process_Directive(
  7766.     S    : Scanner) is
  7767.  
  7768.     C    : Character;
  7769.     Found    : boolean;
  7770.     Word    : SP.String_Type;
  7771.  
  7772. begin
  7773.     if not More(S) then
  7774.     return;
  7775.  
  7776.     end if;
  7777.  
  7778.     Mark(S);
  7779.  
  7780.     Skip_Space(S);
  7781.  
  7782.     Scan_Ada_Id(S, Found, Word, True);
  7783.  
  7784.     SP.Set_Comparison_Option(SP.Case_Insensitive);
  7785.  
  7786.     If Found and then SP.Equal(Word, "set") then
  7787.     Process_Variable_Def(S);
  7788.  
  7789.     elsif Found and then SP.Equal(Word, "include") then
  7790.     Process_Include(S);
  7791.  
  7792.     else
  7793.     --it must be a substitution or a comment; go back one word.
  7794.     Restore(S);
  7795.     Process_Substitution(S);
  7796.  
  7797.     end if;
  7798.  
  7799.  
  7800.     return;
  7801.  
  7802. end Process_Directive;
  7803.  
  7804. ---------------------------------------------------------------
  7805.  
  7806. procedure Process_Variable_Def(
  7807.         S    : Scanner) is
  7808.  
  7809.         Var    : SP.String_Type;
  7810.         Found    : boolean;
  7811.          C    : character;
  7812.         Val    : SP.String_Type;
  7813.                 -- value of a primary expr
  7814.         Dupl    : SP.String_Type;
  7815.  
  7816. begin
  7817.     -- Var := Primary expr
  7818.     Scan_ADA_Id(S, Found, Var, True);
  7819.     if not Found then
  7820.     --illegal directive
  7821.     Put_Location;
  7822.     Text_IO.Put_Line("    In ""Set Variable"" Variable must be an ADA id.");
  7823.     Return;
  7824.  
  7825.     end if;
  7826.  
  7827.     Skip_Space(S);
  7828.     Next(S,C);
  7829.     if  C /= ':' then
  7830.     --illegal directive
  7831.     Put_Location;
  7832.     Text_IO.Put_Line("    To define a variable: Set Variable := Primary Expr.");
  7833.     Return;
  7834.  
  7835.     end if;
  7836.  
  7837.     Skip_Space(S);
  7838.     Next(S,C);
  7839.     if C /= '=' then
  7840.     --illegal directive
  7841.     Put_Location;
  7842.     Text_IO.Put_Line("    To define a variable: Set Variable := Primary Expr.");
  7843.     Return;
  7844.  
  7845.     end if;
  7846.     
  7847.     Skip_Space(S);
  7848.     Val := Process_Primary(S);
  7849.     VL.Insert_If_Not_Found(Var, Val, Curr_File_Info.My_Variables,
  7850.                Found, Dupl);
  7851.  
  7852.     if Found then
  7853.     -- multiple definition of a variable
  7854.     Put_Location;
  7855.     Text_IO.Put_Line("    Multiple definitions of the variable " &
  7856.              SP.Value(Var));    
  7857.     Return;
  7858.  
  7859.     end if;
  7860.  
  7861.     Check_Nothing_Or_Comment_Left(S);
  7862.  
  7863.     return;
  7864.  
  7865. end Process_Variable_Def;
  7866.  
  7867. --------------------------------------------------------------
  7868.  
  7869. procedure Process_Include(
  7870.         S    : Scanner) is
  7871.  
  7872.         Found    : boolean;
  7873.         Word    : SP.String_Type;
  7874.         C    : Character;
  7875.         CI_Or_IL: SP.String_Type;
  7876.         Item    : SP.String_Type;
  7877.         Version    : SP.String_Type;
  7878.         Full_File_Name : SP.String_Type;
  7879.         CI_Name_Ver : SP.String_Type;
  7880.                 -- CI version
  7881.         File_Name : SP.String_Type;
  7882.  
  7883. begin
  7884.  
  7885.     -- Syntax to scan:
  7886.     -- "File" Primary expr
  7887.     -- "CI_comp" Primary expr "," Primary expr "," Primary expr
  7888.     -- "IL_item" Primary expr "," Primary expr "," Primary expr
  7889.     Scan_ADA_Id(S, Found, Word, True);
  7890.     if not Found then
  7891.     --illegal directive
  7892.     Put_Location;
  7893.     Text_IO.Put_Line("    To include a file: Include File Primary expr or");        
  7894.     Text_IO.Put_Line("    Include CI_Comp | IL_Item Primary expr, Primary expr, Primary exp");
  7895.     Return;
  7896.  
  7897.     end if;
  7898.  
  7899.     -- the following comparisons are case insensitive
  7900.     if SP.Equal(Word,"file") then
  7901.     File_Name := Process_Primary(S);
  7902.     Full_File_Name := SP.Create(FM.Parse_Filename(SP.Value(File_Name)));
  7903.                 --now the name is a full path name
  7904.         Scan_File_And_Copy(Full_File_Name, Arbitrary_File, SP.Create(""), 
  7905.                SP.Create(""), SP.Create(""));
  7906.  
  7907.     elsif SP.Equal(Word, "ci_comp") or SP.Equal(Word, "il_item") then
  7908.     CI_Or_IL := Process_Primary(S);
  7909.     Skip_Space(S);
  7910.     Next(S,C);
  7911.     if C /=',' then
  7912.         -- illegal directive
  7913.           Put_Location;
  7914.          Text_IO.Put_Line("    To include a file: Include File Primary expr or");        
  7915.         Text_IO.Put_Line("    Include CI_Comp | IL_Item Primary expr, Primary expr, Primary exp");
  7916.         Return;
  7917.  
  7918.     end if;
  7919.  
  7920.     Item := Process_Primary(S);
  7921.     Skip_Space(S);
  7922.     Next(S,C);
  7923.     if C /=',' then
  7924.         -- illegal directive
  7925.           Put_Location;
  7926.          Text_IO.Put_Line("    To include a file: Include File Primary expr or");        
  7927.         Text_IO.Put_Line("    Include CI_Comp | IL_Item Primary expr, Primary expr, Primary exp");
  7928.         Return;
  7929.  
  7930.     end if;
  7931.  
  7932.     Version := Process_Primary(S);
  7933.  
  7934.     if SP.Equal(Word, "ci_comp") then
  7935.         CI_Name_Ver := SP.Create(SP.Value(CI_Or_IL) & " " & SP.Value(Version));
  7936.         Full_File_Name := CM.Get_Hif_File_Name
  7937.                     (Curr_Catalog, CI_Name_Ver, Item);
  7938.         Scan_File_And_Copy(Full_File_Name, Cat_File, CI_Or_IL, Item,
  7939.                    Version);
  7940.  
  7941.     else
  7942.         Full_File_Name := Item_Library_Manager_Utilities.Get_Hif_File_Name
  7943.                 (CI_Or_IL, Item, Version);
  7944.         Scan_File_And_Copy(Full_File_Name, Lib_File, CI_Or_IL, Item,
  7945.                    Version);
  7946.  
  7947.     end if;
  7948.  
  7949.     else
  7950.     -- illegal directive
  7951.       Put_Location;
  7952.     Text_IO.Put_Line("    To include a file: Include File Primary expr or");        
  7953.     Text_IO.Put_Line("    Include CI_Comp | IL_Item Primary expr, Primary expr, Primary exp");
  7954.     Return;
  7955.  
  7956.     end if;
  7957.  
  7958.     Check_Nothing_Or_Comment_Left(S);
  7959.  
  7960.     return;
  7961.  
  7962. exception
  7963.     when FM.Parse_Error =>
  7964.     Put_Location;
  7965.     Text_IO.Put_Line("    " & SP.Value(File_Name) & " is illegal file name");
  7966.     return;
  7967.  
  7968. -- the following two exceptions do not exist at this time but will be added
  7969. --    when CM.No_Such_Catalog =>
  7970. --    Put_Location;
  7971. --    Text_IO.Put_Line("    No such catalog " & SP.Value(Curr_Catalog));
  7972. --    return;
  7973.  
  7974.     when CM.No_Such_Ci =>
  7975.     Put_location;
  7976.     Text_IO.Put_Line("    No such ci item " & SP.Value(CI_Name_Ver));
  7977.     return;
  7978.  
  7979. --    when CM.No_Such_Component =>
  7980. --    Put_location;
  7981. --    Text_IO.Put_Line("    No such ci component " & SP.Value(Item));
  7982. --    return;
  7983.  
  7984.     when ILMD.Invalid_Library_Name | ILMD.Library_Does_Not_Exist =>
  7985.     Put_location;
  7986.     Text_IO.Put_Line("    No such ci library " & SP.Value(CI_Or_IL));
  7987.     return;
  7988.  
  7989.     when ILMD.Item_Not_Found =>
  7990.     Put_location;
  7991.     Text_IO.Put_Line("    No such library item " & SP.Value(Item));
  7992.     return;
  7993.  
  7994.     when ILMD.Invalid_Version | ILMD.Version_Not_Found =>
  7995.     Put_location;
  7996.     Text_IO.Put_Line("    No such item version " & SP.Value(Version));
  7997.     return;
  7998.  
  7999. end Process_Include;
  8000.  
  8001. -------------------------------------------------------------
  8002.  
  8003. procedure Process_Substitution(
  8004.         S    : Scanner) is
  8005.  
  8006.         C    : Character;
  8007.         Found    : boolean;
  8008.         Result    : SP.String_Type := SP.Create("");
  8009.         Spaces    : SP.String_Type;
  8010.         Just_Comment : boolean := TRUE;
  8011.  
  8012. begin
  8013.  
  8014.     while More(S) loop
  8015.  
  8016.     --get the leading spaces
  8017.     Scan_Space(S, Found, Spaces);
  8018.     if Found then
  8019.         Result := SP."&"(Result, Spaces);
  8020.  
  8021.     end if;
  8022.  
  8023.         --recognise "--" 
  8024.         if Get(S) = '-' then
  8025.         --throw away the first "-"
  8026.         Next(S,C);   
  8027.         if More(S) and then Get(S) /= '-' then
  8028.         --illegal directive
  8029.             Put_Location;
  8030.             Text_IO.Put_Line("    Illegal directive.");
  8031.  
  8032.         end if;
  8033.         if Just_Comment then
  8034.                 return;
  8035.  
  8036.         else
  8037.         exit;
  8038.  
  8039.         end if;
  8040.  
  8041.         end if;
  8042.  
  8043.     Just_Comment := False;
  8044.  
  8045.     Result := SP."&"(Result, Process_Primary(S));
  8046.     if More(S) then
  8047.         Scan_Space(S, Found, Spaces);
  8048.         if not Found then
  8049.         --illegal directive
  8050.         Put_Location;
  8051.         Text_IO.Put_Line("    Illegal syntax for substitution.");
  8052.         return;
  8053.    
  8054.         end if;
  8055.         Result := SP."&"(Result, Spaces);
  8056.     
  8057.     end if;
  8058.  
  8059.     end loop;
  8060.  
  8061.     if not SP.Is_Empty(Result) then
  8062.         Text_IO.Put_Line(SP.Value(Result));
  8063.  
  8064.     end if;
  8065.  
  8066.     return;
  8067.  
  8068. end Process_Substitution;
  8069.  
  8070. -------------------------------------------------------------
  8071.  
  8072. function Process_Primary(
  8073.         S    : Scanner) return SP.String_Type is
  8074.  
  8075.         Found    : boolean;
  8076.         String_Val : SP.String_Type;
  8077.         Var    : SP.String_Type;
  8078.         Var_Val    : SP.String_Type;
  8079.  
  8080. begin
  8081.  
  8082.     Skip_Space(S);
  8083.  
  8084.     if Get(S) = '"' then
  8085.     --this must be a string
  8086.     Scan_Quoted(S, Found, String_Val, True);
  8087.     if not Found then
  8088.         -- illegal directive
  8089.         Put_Location;
  8090.         Text_IO.Put_Line("    Illegal string in a Primary expr.");
  8091.         return SP.Create("");
  8092.     
  8093.     end if;
  8094.     return String_Val;
  8095.  
  8096.     else
  8097.     Scan_ADA_Id(S, Found, Var, True);
  8098.     if not Found then
  8099.         --illegal directive
  8100.         Put_Location;
  8101.         Text_IO.Put_Line("    Illegal Primary expr.");
  8102.         return SP.Create("");
  8103.  
  8104.         end if;
  8105.  
  8106.     -- find a value of the variable
  8107.     VL.Find(Var, Curr_File_Info.My_Variables, Found, Var_Val);
  8108.     if not Found then
  8109.         -- variable is not defined
  8110.         Put_Location;
  8111.         Text_IO.Put_Line("    Variable " & SP.Value(Var) & 
  8112.                  " is not defined.");
  8113.         return SP.Create("");
  8114.  
  8115.     end if;
  8116.  
  8117.     Return Var_Val;
  8118.  
  8119.     end if;
  8120.  
  8121. end Process_Primary;
  8122.     
  8123. --------------------------------------------------------------
  8124.  
  8125. procedure Init_Variables is
  8126.  
  8127.         CI    : SP.String_Type;
  8128.         Version    : SP.String_Type;
  8129.         Comp_Name : SP.String_Type;
  8130.         Date    : SP.String_Type;
  8131. begin
  8132.  
  8133.  
  8134.     if Curr_File_Info.File_Kind = Cat_File then
  8135.     CI := Curr_File_Info.CI_Name;
  8136.     Comp_Name := Curr_File_Info.Comp_Name;
  8137.     Version := Curr_File_Info.CI_Version;
  8138.     Date := CM.Ci_Date_Time(Curr_Catalog, CI, Version);
  8139.  
  8140.     else
  8141.     CI := SP.Create("CI?");
  8142.     Version := SP.Create("Version?");
  8143.     Comp_Name := SP.Create("COMP?");
  8144.     if Curr_File_Info.File_Kind = Lib_File then
  8145.         Date := SP.Create(Item_Library_Manager_Utilities.Get_Item_Date_Time
  8146.                    (Curr_File_Info.Lib_Name, Curr_File_Info.Item_Name,
  8147.                 Curr_File_Info.Item_Version));
  8148.  
  8149.        else
  8150.         Date := SP.Create(FM.Modification_Date(
  8151.                   SP.Value(Curr_File_Info.Full_File_Name)));
  8152.  
  8153.          end if;        
  8154.  
  8155.     end if;
  8156.  
  8157.     VL.Insert(SP.Create("ci"), CI, Curr_File_Info.My_Variables);
  8158.     VL.Insert(SP.Create("comp"), Comp_Name, Curr_File_Info.My_Variables);
  8159.     VL.Insert(SP.Create("version"), Version, Curr_File_Info.My_Variables);
  8160.     VL.Insert(SP.Create("date"), Date, Curr_File_Info.My_Variables);
  8161.  
  8162.     return;
  8163.  
  8164. end Init_Variables;
  8165.  
  8166. ---------------------------------------------------------------
  8167.  
  8168. procedure Put_Location is
  8169.  
  8170. begin
  8171.  
  8172.     case Curr_File_Info.File_Kind is
  8173.     when Cat_File =>
  8174.         Text_IO.Put("ERROR: CI " & SP.Value(Curr_File_Info.CI_Name) &
  8175.                  ", Comp " & SP.Value(Curr_File_Info.Comp_Name) &
  8176.                  ", Version " & SP.Value(Curr_File_Info.CI_Version) &
  8177.                  ":");
  8178.  
  8179.     when Lib_File =>
  8180.         Text_IO.Put("ERROR: Lib " & SP.Value(Curr_File_Info.Lib_Name) &
  8181.                  ", Item " & SP.Value(Curr_File_Info.Item_Name) &
  8182.                  ", Version " & SP.Value(Curr_File_Info.Item_Version) &
  8183.                  ":");
  8184.  
  8185.     when Arbitrary_File =>
  8186.         Text_IO.Put("ERROR: File " & SP.Value(Curr_File_Info.Full_File_Name) & ":");
  8187.  
  8188.     end case;
  8189.  
  8190.     Text_IO.Put_Line(" line " & INTEGER'Image(Curr_File_Info.Line_Number) & ":");
  8191.  
  8192.     return;
  8193.  
  8194. end Put_Location;
  8195.  
  8196. ----------------------------------------------------------------
  8197.  
  8198. function Check_Cycle(
  8199.         Full_File_Name    : SP.String_Type;
  8200.         File_Kind    : File_Kind_Type;
  8201.         CI_Or_Lib_Name    : SP.String_Type;
  8202.         Comp_Or_Item_Name : SP.String_Type;
  8203.         Version        : SP.String_Type) return boolean is
  8204.  
  8205.         Temp_Stack    : ST.Stack;
  8206.         Ptr        : File_Info_Ptr;
  8207.  
  8208. begin
  8209.  
  8210.     -- check whether the file (passed as the set of arguments
  8211.     -- to this function) is already in the list of files currently
  8212.     -- being included
  8213.     Temp_Stack := ST.Copy(File_Stack);
  8214.     --all files are in the stack except for the last one;
  8215.     -- so to make all cases similar put the last file which
  8216.     -- is still in curr_file_info into the stack
  8217.     ST.Push(Temp_Stack, Curr_File_Info);
  8218.  
  8219.     SP.Set_Comparison_Option(SP.Case_Insensitive);
  8220.  
  8221.     while not ST.Is_Empty(Temp_Stack) loop
  8222.     ST.Pop(Temp_Stack, Ptr);
  8223.     if File_Kind = Ptr.File_Kind then
  8224.         if SP.Equal(Full_File_Name, Ptr.Full_File_Name) then
  8225.             case File_Kind is
  8226.             when Cat_File =>
  8227.                 Text_IO.Put_Line(
  8228.                  "ERROR: CI " & SP.Value(CI_Or_Lib_Name) &
  8229.                  ", Comp " & SP.Value(Comp_Or_Item_Name) &
  8230.                  ", Version " & SP.Value(Version) &
  8231.                  ":");
  8232.  
  8233.                 when Lib_File =>
  8234.                 Text_IO.Put_Line(
  8235.                 "ERROR: Lib " & SP.Value(CI_Or_Lib_Name) &
  8236.                  ", Item " & SP.Value(Comp_Or_Item_Name) &
  8237.                  ", Version " & SP.Value(Version) &
  8238.                  ":");
  8239.  
  8240.             when Arbitrary_File =>
  8241.                 Text_IO.Put_Line(
  8242.                 "ERROR: File " & SP.Value(Full_File_Name) & ":");
  8243.  
  8244.             end case;
  8245.                 Text_IO.Put_Line("    Includes itself either directly or indirectly");
  8246.         SP.Set_Comparison_Option(SP.Case_Sensitive);
  8247.         return TRUE;
  8248.  
  8249.         end if;
  8250.  
  8251.     end if;
  8252.  
  8253.     end loop;
  8254.  
  8255.     ST.Destroy(Temp_Stack);
  8256.  
  8257.     SP.Set_Comparison_Option(SP.Case_Sensitive);
  8258.  
  8259.     return FALSE;
  8260.  
  8261. end Check_Cycle;
  8262.  
  8263. -----------------------------------------------------------
  8264.  
  8265. procedure Check_Nothing_Or_Comment_Left(
  8266.         S    : Scanner) is
  8267.  
  8268.         C    : character;
  8269.  
  8270. begin
  8271.     --check that there is nothing or only a comment left
  8272.     if More(S) then
  8273.     Skip_Space(S);
  8274.     if More(S) then
  8275.         Next(S,C);
  8276.         if C = '-' and then More(S) then
  8277.         Next(S,C);
  8278.         if C /= '-' then
  8279.             -- illegal directive
  8280.             Put_Location;
  8281.             Text_IO.Put_Line("    Illegal directive");
  8282.  
  8283.         end if;
  8284.         else
  8285.         -- illegal directive
  8286.         Put_Location;
  8287.         Text_IO.Put_Line("    Illegal directive");
  8288.  
  8289.         end if;
  8290.  
  8291.        end if;
  8292.  
  8293.     end if;
  8294.  
  8295. end Check_Nothing_Or_Comment_Left;
  8296.  
  8297. end Process_File;
  8298. ::::::::::::::
  8299. fgen.spc
  8300. ::::::::::::::
  8301. with String_Pkg;
  8302.  
  8303. package Process_File is
  8304.  
  8305. package SP renames String_Pkg;
  8306.  
  8307. abort_filegen: exception;
  8308.  
  8309. procedure File_Gen(
  8310.     Source_File    : SP.String_Type;
  8311.     Result_File    : SP.String_Type;
  8312.     Catalog        : SP.String_Type;
  8313.     CI_Name_Ver    : SP.String_Type);
  8314.  
  8315. end Process_File;
  8316. ::::::::::::::
  8317. filegen.ada
  8318. ::::::::::::::
  8319. function fileGen return INTEGER;
  8320.  
  8321.  
  8322. with Standard_Interface; use Standard_Interface;
  8323. with String_pkg;
  8324. with Host_Lib;
  8325. with Process_File;
  8326. with Text_IO;
  8327.  
  8328. function fileGen return INTEGER is
  8329.  
  8330.     package SP renames String_pkg;
  8331.  
  8332.     package Str_Arg is new String_Argument(
  8333.     String_Type_Name => "STRING");
  8334.  
  8335.     fgen    : Process_Handle;
  8336.     Source_File    : SP.String_Type;
  8337.     Output_File    : SP.String_Type;
  8338.     Catalog    : SP.String_Type;
  8339.     CI_Name    : SP.String_Type;
  8340.  
  8341. begin
  8342.  
  8343.     Host_Lib.Set_Error;
  8344.     Set_Tool_Identifier("1.0");
  8345.  
  8346.     Define_Process(
  8347.     Name => "fileGen",
  8348.     Help => "Includes files; simple substitutions.",
  8349.     Proc => fgen);   
  8350.  
  8351.     Str_Arg.Define_Argument(
  8352.         Proc => fgen,
  8353.     Name => "Source",
  8354.     Help => "Source file (or a CI component) to process");
  8355.  
  8356.     Str_Arg.Define_Argument(
  8357.         Proc => fgen,
  8358.     Name => "Output",
  8359.     Default => "",
  8360.     Help => "Output file (default is standard output)");
  8361.  
  8362.     Str_Arg.Define_Argument(
  8363.         Proc => fgen,
  8364.     Name => "Catalog",
  8365.     Default => "",
  8366.     Help => "Catalog name (default is no catalog)");
  8367.  
  8368.     Str_Arg.Define_Argument(
  8369.         Proc => fgen,
  8370.     Name => "CI_Name",
  8371.     Default => "",
  8372.     Help => "CI name (default is no CI)");
  8373.  
  8374.     --get arguments
  8375.     Parse_Line(fgen);
  8376.  
  8377.     Source_File := Str_Arg.Get_Argument(
  8378.             Proc => fgen,
  8379.             Name => "Source");
  8380.  
  8381.     Output_File := Str_Arg.Get_Argument(
  8382.             Proc => fgen,
  8383.             Name => "Output");
  8384.  
  8385.     Catalog := Str_Arg.Get_Argument(
  8386.             Proc => fgen,
  8387.             Name => "Catalog");
  8388.  
  8389.     CI_Name := Str_Arg.Get_Argument(
  8390.             Proc => fgen,
  8391.             Name => "CI_name");
  8392.  
  8393.     Process_File.File_gen(Source_File, Output_File, Catalog, CI_Name);
  8394.  
  8395.     return Host_Lib.Return_Code(Host_Lib.Success);
  8396.  
  8397. exception
  8398.     when Process_File.abort_FileGen =>
  8399.     -- Error message was already printed when exception was raised
  8400.     return Host_Lib.Return_Code(Host_Lib.Error);
  8401.  
  8402.     when Process_Help =>
  8403.     return Host_Lib.Return_Code(Host_Lib.Information);
  8404.  
  8405.     when Abort_Process =>
  8406.     return Host_Lib.Return_Code(Host_Lib.Error);
  8407.  
  8408. --x    when others =>
  8409. --x    Text_IO.Put_Line("File Generator internal Error");
  8410. --x    return Host_Lib.Return_Code(Host_Lib.Error);
  8411.  
  8412. end fileGen;
  8413. ::::::::::::::
  8414. hifutil.bdy
  8415. ::::::::::::::
  8416. with hif_attributes;
  8417.  
  8418. package body hif_utils is
  8419.  
  8420. --| Overview: This package contains subprograms which will aid in the
  8421. --| interface to the HIF.
  8422.  
  8423. package HA renames hif_attributes;
  8424.  
  8425. function enquote (    --| Puts a string in the right format  to be a 
  8426.             --| hif list quoted string
  8427.     s : in string_type     --| string to enquote
  8428.     ) return string is
  8429.     begin
  8430.     return value ( """" & s & """");
  8431.     end;
  8432.  
  8433. function enquote (    --| Puts a string in the right format  to be a 
  8434.             --| hif list quoted string
  8435.     s : in string_type     --| string to enquote
  8436.     ) return string_type is
  8437.     begin
  8438.     return """" & s & """";
  8439.     end;
  8440.  
  8441.  
  8442. procedure get_node_attribute (    --| Strips off the parens returned on an
  8443.                 --| attribute.
  8444.     node : in ND.node_type;
  8445.     attrib : in ND.attrib_name;
  8446.     value : in out ND.value_string;
  8447.     value_last : out ND.value_string_range
  8448.     ) is
  8449.     length : ND.value_string_range;
  8450.     begin
  8451.     HA.get_node_attribute (node, attrib, value, length);
  8452.     if value(1..length) = "()" then
  8453.         value_last := 0;
  8454.     else
  8455.         value_last := length;
  8456.     end if;
  8457.     end get_node_attribute;
  8458.  
  8459. procedure get_path_attribute (    --| Strips off the parens returned on an
  8460.                 --| attribute.
  8461.     node : in ND.node_type;
  8462.     attrib : in ND.attrib_name;
  8463.     value : in out ND.value_string;
  8464.     value_last : out ND.value_string_range
  8465.     ) is
  8466.     length : ND.value_string_range;
  8467.     begin
  8468.     HA.get_path_attribute (node, attrib, value, length);
  8469.     if value(1..length) = "()" then
  8470.         value_last := 0;
  8471.     else
  8472.         value_last := length;
  8473.     end if;
  8474.     end get_path_attribute;
  8475.  
  8476. end hif_utils;
  8477. ::::::::::::::
  8478. hifutil.spc
  8479. ::::::::::::::
  8480. with string_pkg;  use string_pkg;
  8481. with hif_node_defs;
  8482.  
  8483. package hif_utils is
  8484.  
  8485. --| Overview: This package contains subprograms which will aid in the
  8486. --| interface to the HIF.
  8487.  
  8488. package ND renames hif_node_defs;
  8489.  
  8490. function enquote (    --| Puts a string in the right format  to be a 
  8491.             --| hif list quoted string
  8492.     s : in string_type     --| string to enquote
  8493.     ) return string;
  8494.  
  8495. function enquote (    --| Puts a string in the right format  to be a 
  8496.             --| hif list quoted string
  8497.     s : in string_type     --| string to enquote
  8498.     ) return string_type;
  8499.  
  8500. procedure get_node_attribute (    --| Strips off the parens returned on an
  8501.                 --| attribute.
  8502.     node : in ND.node_type;
  8503.     attrib : in ND.attrib_name;
  8504.     value : in out ND.value_string;
  8505.     value_last : out ND.value_string_range
  8506.     );
  8507.  
  8508. procedure get_path_attribute (    --| Strips off the parens returned on an
  8509.                 --| attribute.
  8510.     node : in ND.node_type;
  8511.     attrib : in ND.attrib_name;
  8512.     value : in out ND.value_string;
  8513.     value_last : out ND.value_string_range
  8514.     );
  8515.  
  8516. end hif_utils;
  8517. ::::::::::::::
  8518. interface.bdy
  8519. ::::::::::::::
  8520. with hif_node_management;
  8521. with hif_node_defs; use hif_node_defs;
  8522. with hif_list_utils;
  8523. with hif_attributes;
  8524. with catalog_locks;
  8525. with text_io;
  8526. with hif_system_management;
  8527. with catalog_manager;
  8528. with interpret;
  8529. with file_manager;
  8530. with string_utilities;
  8531. with lists;
  8532. with host_lib;
  8533. with document_manager_declarations;
  8534. with catalog_decls;
  8535. with ci_index_mgr;
  8536. with ci_ids;
  8537. with paginated_output;
  8538. with hif_utils;
  8539.  
  8540. package body catalog_interface is
  8541.  
  8542. --| Overview
  8543. --| 
  8544. --| This package contains the procedures which  control input to the
  8545. --| catalog.  The two main procedures are those  that are the interactive
  8546. --| interface to the catalog routines.  Any other catalog functions that
  8547. --| are invoked from the command line will also be in this package.
  8548. --| There are two of these, namely, check_consistency and list_catalogs.
  8549.  
  8550. package NM renames hif_node_management;
  8551. package ND renames hif_node_defs;
  8552. package LU renames hif_list_utils;
  8553. package ATT renames hif_attributes;
  8554. package CL renames catalog_locks;
  8555. package TIO renames text_io;
  8556. package SM renames hif_system_management;
  8557. package CM renames catalog_manager;
  8558. package FM renames file_manager;
  8559. package SU renames string_utilities;
  8560. package HL renames host_lib;
  8561. package DMD renames document_manager_declarations;
  8562. package CD renames catalog_decls;
  8563. package IM renames ci_index_mgr;
  8564. package ID renames ci_ids;
  8565. package PG renames paginated_output;
  8566. package HU renames hif_utils;
  8567.  
  8568. package SS is new SU.generic_string_utilities(SP.string_type, 
  8569.                           SP.create,
  8570.                           SP.value);
  8571. use string_pkg;        -- for visiblity of "&"
  8572.  
  8573. ---- Local operations:
  8574.  
  8575. function name_of (            --| figure out the ci id of a node
  8576.     node : ND.node_type
  8577.     ) return string;
  8578.  
  8579. procedure report (            --| write a diagnostic to the report
  8580.     line : string
  8581.     );
  8582.  
  8583. procedure check_root (            --| check the information on the
  8584.                     --| trunk node.
  8585.     node : ND.node_type;
  8586.     name : string
  8587.     );
  8588.  
  8589. procedure check_trunk_node (        --| do all the checks required for a 
  8590.                     --| trunk node.
  8591.     node : ND.node_type
  8592.     );
  8593.  
  8594. procedure check_ci_node (        --| check the properties on a CI node
  8595.     node : ND.node_type;
  8596.     name : string
  8597.     );
  8598.  
  8599. procedure check_branch_node (        --| the branch attributes
  8600.     node : ND.node_type
  8601.     );
  8602.  
  8603. ---- Local variables:
  8604. max_wait : duration    -- how long to wait for locks.  Not yet implemented
  8605.     := 0.0;
  8606. version         : SP.string_type;        -- all these are for check consistency
  8607. output_file  : PG.paginated_file_handle;
  8608.  
  8609. ---- Global operations:
  8610.  
  8611. procedure open_catalog (    --| Open a catalog with the given name
  8612.     catalog_name : SP.string_type    --| Name of the catalog
  8613.     ) is
  8614.  
  8615.     user : SP.string_type;
  8616.  
  8617.     --| Algorithm: The first thing to do is set the current node as every
  8618.     --| other package will depend on this being set correctly (including the
  8619.     --| locking package).
  8620.     --| Before getting the read lock it has to check that the password
  8621.     --| relation exists for the catalog node.  Otherwise the odd situation
  8622.     --| can occur during write where the catalog has just been created, but
  8623.     --| not locked and another user getting a read lock in the middle of
  8624.     --| this would cause the create to fail.
  8625.     --| The default upon opening a catalog is a read lock.  Many users can
  8626.     --| have read locks on a catalog at the same time as they will not be
  8627.     --| doing anything that will interfere with anyone.  If a user wants to 
  8628.     --| perform an operation that takes a write lock the read lock can be
  8629.     --| upgraded, but the rules for write locks apply.
  8630.     --| If the read lock is obtained (i.e. read_lock returns true) then invoke
  8631.     --| command interpreter and continue until they exit.  When they exit
  8632.     --| remove the read lock.
  8633.     --| If the read lock returns false it is because some one has locked the
  8634.     --| catalog to write.  The user gets a message with the other user's id
  8635.     --| indicating who has the lock.  This is in order that should someone
  8636.     --| accidentally abort out of the catalog leaving a lock behind other
  8637.     --| users can tell if a write lock for a single person has been on an
  8638.     --| especially long time.
  8639.  
  8640.     ans  : string (1..1);    -- answer to a yes/no prompt
  8641.     word : SP.string_type;    -- word is answer to a password prompt
  8642.     last : natural;
  8643.     node : node_type;
  8644.     iter : NM.node_iterator;
  8645.  
  8646.     begin
  8647.     NM.set_current_node ("'user(" & SP.value(catalog_name) & ")");
  8648.     NM.get_current_node (node);
  8649.     begin
  8650.         -- the only way to see if the password path exists is to
  8651.         -- iterate over the relations emanting from the current node.
  8652.         NM.iterate (iter, node, relation=>"password", primary_only=>false);
  8653.         if not NM.more (iter) then
  8654.         Text_io.put_line ("Catalog not yet created");
  8655.             return;
  8656.         end if;
  8657.     end;
  8658.     if CL.read_lock (max_wait) then
  8659.         interpret.command_interpreter;
  8660.         CL.remove_read;
  8661.     else
  8662.         CL.get_write_user (user);
  8663.         TIO.put_line 
  8664.          ("The user " & SP.value(user) & " has the catalog write locked");
  8665.         -- The following code is for the special case where a user has
  8666.         -- aborted out of a catalog session and left a write lock behind.
  8667.         -- There has to be a way for a super user to get into the catalog
  8668.         -- to run remove_lock, but they can't if this open won't let them
  8669.         -- into the catalog, so ther is this override code.
  8670.         TIO.put ("Do you wish to override? [y/n]: ");
  8671.         TIO.get_line (ans, last);
  8672.         if ans = "y" or ans = "Y" then
  8673.         TIO.put ("Enter password to override: ");
  8674.         word := SS.strip(HL.read_no_echo(""));
  8675.         if CM.verify_password (word) then
  8676.             TIO.put_line 
  8677.            ("Remember that you have no locks, but you can fix up the catalog");
  8678.             interpret.command_interpreter;
  8679.            else
  8680.             TIO.put_line ("Incorrect password");
  8681.         end if;
  8682.         end if;
  8683.     end if;
  8684.     exception
  8685.     when name_error =>
  8686.         TIO.put_line ("Catalog doesn't exist, use Create_catalog " &
  8687.         "to create it");
  8688.     when CL.lock_already_exists =>
  8689.         TIO.put_line ("You are already using the catalog as a read lock " &
  8690.         "already exists");
  8691.     end open_catalog;
  8692.  
  8693. procedure create_catalog (    --| Create a catalog with the given name
  8694.     catalog_name : in SP.string_type;    --| Name of the catalog to create
  8695.     directory    : in SP.string_type    --| Name of the directory where the 
  8696.                     --| catalog will be stored
  8697.     ) is
  8698.  
  8699.     dir         : SP.string_type;
  8700.     node     : node_type;
  8701.     list_node: node_type;
  8702.  
  8703.     --| Algorithm:  First check that the name is not alredy in the database.
  8704.     --| To do this try to open the node with that name.  If it is successful
  8705.     --| it already exists, so close it and print the error.  If it doesn't
  8706.     --| exist the exception name_error will be raised.  In this case the
  8707.     --| exception handler for name_error is the code to create the catalog,
  8708.     --| as follows:
  8709.     --| Add the user node and set the current node to be that one.
  8710.     --| If the write lock is obtained prompt for the password and store it
  8711.     --| in the appropriate place.  When this is done creation is complete
  8712.     --| so give a messge this effect and exit.
  8713.     --| In the event that the write lock cannot be obtained delete the
  8714.     --| user node and print out an error message.
  8715.  
  8716. begin
  8717.     if SU.is_ada_id (SU.make_scanner(SP.value(catalog_name))) then
  8718.         NM.open_node_handle (node, "'user(" & SP.value(catalog_name) & ")");
  8719.         NM.close_node_handle (node);
  8720.         TIO.put_line ("Error: That name has already been used");
  8721.     else
  8722.     TIO.put_line ("Error: Name must be an ada id");
  8723.     end if;
  8724. exception
  8725.     when name_error =>         -- that name is not yet used
  8726.     -- first check  that the directory where the repository will be does
  8727.     -- not exist.  This is to prevent the case where someone creates a
  8728.     -- catalog with a diferent name but in the same directory which would
  8729.     -- result in the first catalog being wiped out.
  8730.     if FM.is_directory (SP.value(directory)) then
  8731.         TIO.put_line ("Error: Catalog directory already exists");
  8732.         return;
  8733.        end if;
  8734.         dir := SP.create(FM.path_name (directory => SP.value (directory),
  8735.                        file      => "",
  8736.                        absolute  => true));
  8737.     SM.add_user (SP.value(catalog_name), SP.value(dir));
  8738.     NM.set_current_node ("'user(" & SP.value(catalog_name) & ")");
  8739.     if CL.write_lock (max_wait) then
  8740.             NM.get_current_node (node);
  8741.         NM.open_node_handle(node => list_node,
  8742.                  name => DMD.document_manager_list_path);
  8743.         NM.link(to_node  => node,
  8744.              new_base => list_node,
  8745.              relation => "CATALOG",
  8746.              key      => SP.value(catalog_name));
  8747.         NM.close_node_handle(list_node);
  8748.         loop
  8749.          begin
  8750.                 TIO.put ("Enter password: ");
  8751.                 NM.link (node, 
  8752.                  node, 
  8753.                  HL.read_no_echo(""),
  8754.                       "password", 
  8755.                       must_not_exist);
  8756.             exit;
  8757.         exception
  8758.             when ND.name_error =>
  8759.             TIO.put_line ("Not a valid password, password must be"
  8760.                 & " an ada id");
  8761.         end;
  8762.         end loop;
  8763.         NM.close_node_handle(node);
  8764.         CL.remove_write;
  8765.         TIO.put_line ("Creation complete");
  8766.     else
  8767.     -- the open catalog command checks that the password relation exists
  8768.     -- for the catalog before placing a read lock.  Since the password
  8769.     -- relation is only created after the write lock is in place this 
  8770.     -- should work to exclude people reading the catalog before it is
  8771.     -- fully created.
  8772.     -- In the highly unlikely event that the write lock does fail for 
  8773.     -- some reason we stil have to decide what to do.  Since this is 
  8774.     -- very unlikely to happen I think an unfriendly solution is 
  8775.     -- sufficient.
  8776.  
  8777.         SM.delete_user (SP.value(catalog_name));
  8778.         TIO.put_line 
  8779.          ("Unable to create catalog: Another user has locked the catalog");
  8780.     end if;
  8781. end create_catalog;
  8782.  
  8783.  
  8784. procedure check_consistency (    --| check the consistency of a catalog
  8785.                 --| producing a written report
  8786.     name   : in SP.string_type;        --| catalog name
  8787.     output : in SP.string_type        --| the name of the output file
  8788.     ) is
  8789.  
  8790.     root     : ND.node_type;
  8791.     node     : ND.node_type;
  8792.     trunk    : ND.node_type;
  8793.     i1        : NM.node_iterator;
  8794.     i2        : NM.node_iterator;
  8795.     num_trunks    : natural;
  8796.  
  8797.     begin
  8798.     -- set the local variable with the catalog name
  8799.     -- set up the output file first:
  8800.     PG.create_paginated_file (SP.value(output), output_file);
  8801.     PG.set_header (output_file, 2,
  8802.     "Consistency check for Catalog " & SP.value(name) & 
  8803.             " page ~p(R4)");
  8804.     PG.set_header (output_file, 3, "~c ~t");
  8805.     -- Use set_current node so that the rest of the catalog functions
  8806.     -- that are userd for checking don't bomb out.
  8807.     NM.set_current_node ("'user(" & SP.value(name) & ")");
  8808.     NM.get_current_node (root);
  8809.     check_root (root, SP.value(name));
  8810.     NM.iterate (i1, root, relation=>"ci_root");
  8811.     while NM.more(i1) loop
  8812.         NM.get_next (i1, node);
  8813.         num_trunks := 0;
  8814.         NM.iterate (i2, node, relation=>"trunk");
  8815.         while NM.more(i2) loop
  8816.         NM.get_next (i2, trunk);
  8817.         num_trunks := num_trunks + 1;
  8818.         check_trunk_node (trunk);
  8819.         end loop;
  8820.         if num_trunks < 1 then
  8821.         report ("CI " & name_of(node) & " has no versions at all.");
  8822.         end if;
  8823.     end loop;
  8824.  
  8825.     -- report that the check is done so that at least there is some output
  8826.     -- to the output file even if there are no problems.
  8827.         report ("Check consistency of " & SP.value(name) & " is complete.");
  8828.  
  8829.     end check_consistency;
  8830.  
  8831. procedure list_catalogs (    --| List the names of all catalogs on the
  8832.                 --| system
  8833.     catalogs : in SP.string_type
  8834.     := SP.create("*")    --| String to match for catalog names
  8835.     ) is
  8836.  
  8837. list_node    : node_type;
  8838. ci_node        : node_type;
  8839. iterator    : NM.node_iterator;
  8840.  
  8841. begin
  8842.  
  8843.     SP.mark;
  8844.     NM.open_node_handle(node => list_node,
  8845.              name => DMD.document_manager_list_path);
  8846.     SP.release;
  8847.     NM.iterate(iterator     => iterator,
  8848.         node         => list_node,
  8849.         key          => SP.value(catalogs),
  8850.         relation     => "CATALOG",
  8851.         primary_only => false);
  8852.     while NM.more(iterator) loop
  8853.     NM.get_next(iterator, ci_node);
  8854.     TIO.put_line (NM.path_key(ci_node));
  8855.     end loop;
  8856. end list_catalogs;
  8857.  
  8858. -- Local Operation Bodies:
  8859. function name_of (            --| figure out the ci id of a node
  8860.     node : ND.node_type
  8861.     ) return string is
  8862.  
  8863.     name : SP.string_type;
  8864.     temp : SP.string_type;
  8865.     scan : SU.scanner;
  8866.     found: boolean;
  8867.  
  8868.     begin
  8869.     scan := SU.make_scanner (NM.primary_name(node));
  8870.     SS.scan_not_literal ("(", scan, found, temp);    -- scan through
  8871.                             -- 'user(
  8872.     if not found then
  8873.         SU.destroy_scanner (scan);
  8874.         return "";
  8875.     end if;
  8876.      SU.forward (scan);
  8877.     SS.scan_not_literal ("(", scan, found, temp);    -- scan through
  8878.                             -- xxx)'ci_root(
  8879.     if not found then
  8880.         SU.destroy_scanner (scan);
  8881.         return "";
  8882.     end if;
  8883.     SS.scan_enclosed ('(', ')', scan, found, temp); -- get ci name
  8884.     if not found then
  8885.         SU.destroy_scanner (scan);
  8886.         return "";
  8887.     end if;
  8888.     name := temp & " ";
  8889.     SS.scan_not_literal ("(", scan, found, temp);    -- scan 'trunk(
  8890.     if not found then
  8891.         SU.destroy_scanner (scan);
  8892.         return SP.value(name);
  8893.     end if;
  8894.     SS.scan_enclosed ('(', ')', scan, found, temp);    -- get version
  8895.     if not found then
  8896.         SU.destroy_scanner (scan);
  8897.         return SP.value(name);
  8898.     end if;
  8899.     -- temp = "Vnumber" so strip off the V
  8900.     name := name & SP.substr(temp, 2, SP.length(temp)-1);
  8901.     while SU.more(scan) loop
  8902.         SS.scan_not_literal ("(", scan, found, temp); --scan 'branch( or
  8903.         if not found then                  -- 'trunk( or 'DOT(
  8904.             SU.destroy_scanner (scan);
  8905.             return SP.value(name);
  8906.         elsif SP.equal (temp, "'DOT") then
  8907.         -- we are at a ".CI" part and therefore done.
  8908.         return SP.value(name);
  8909.         end if;
  8910.         SS.scan_enclosed ('(', ')', scan, found, temp); --get version
  8911.         if not found then
  8912.             SU.destroy_scanner (scan);
  8913.             return SP.value(name);
  8914.         end if;
  8915.         -- temp = "Vnumber" so strip off the V
  8916.         name := name & "." & SP.substr(temp, 2, SP.length(temp)-1);
  8917.     end loop;
  8918.     return SP.value(name);
  8919.     end name_of;
  8920.  
  8921. procedure report (            --| write a diagnostic to the report
  8922.     line : string
  8923.     ) is
  8924.  
  8925.     begin
  8926.         PG.put_line (output_file, line);
  8927.     end;
  8928.  
  8929. procedure check_root (            --| check the information on the
  8930.                     --| trunk node.
  8931.     node : ND.node_type;
  8932.     name : string
  8933.     ) is
  8934.  
  8935.     i1         : NM.node_iterator;
  8936.     i2        : NM.node_iterator;
  8937.     temp    : ND.node_type;
  8938.     index_node    : ND.node_type;
  8939.     ai        : ATT.attrib_iterator;
  8940.     num_pass    : natural := 0;
  8941.     last    : natural;
  8942.     attrib    : string(1..80);
  8943.     list    : LU.list_type;
  8944.  
  8945.     begin
  8946.     NM.iterate (i1, node, relation=>"password", primary_only=>false);
  8947.     while NM.more(i1) loop
  8948.         NM.get_next (i1, temp);
  8949.         num_pass := num_pass + 1;
  8950.     end loop;
  8951.     if num_pass > 1 then
  8952.         report ("Catalog has too many passwords: " & 
  8953.                 integer'image(num_pass));
  8954.     end if;
  8955.     begin
  8956.         ATT.get_path_attribute ("'user(" & name & ")" 
  8957.                         & "'write_lock", 
  8958.                     "userid", 
  8959.                     list);
  8960.         if not LU.empty(list) then
  8961.                 report (LU.identifier (LU.positional (list, 1)) & " has the " &
  8962.                 "catalog write locked.");
  8963.         end if;
  8964.         LU.free_list(list);
  8965.     exception when ND.name_error =>
  8966.         -- it's ok if there's no write lock
  8967.         null;
  8968.     end;
  8969.     NM.iterate (i2, node, relation=>"read_lock", primary_only=>false);
  8970.     while NM.more(i2) loop
  8971.         NM.get_next (i2, temp);
  8972.         report (NM.path_relation(temp) & " has the catalog read locked.");
  8973.     end loop;
  8974.     ATT.node_attribute_iterate (ai, node, "*");
  8975.     while ATT.more(ai) loop
  8976.         ATT.get_next (ai, attrib, last, list);
  8977.         begin
  8978.         NM.open_node_handle (    index_node,
  8979.                     base=>node,
  8980.                     relation=>"index",
  8981.                     key=>attrib(1..last));
  8982.         NM.close_node_handle (index_node);
  8983.         exception when ND.name_error =>
  8984.         report ("The catalog is missing the information node for " &
  8985.             "keyword " & attrib(1..last) & ".");
  8986.         end;
  8987.         LU.free_list (list);
  8988.     end loop;
  8989.  
  8990.     end check_root;
  8991.  
  8992. procedure check_trunk_node (        --| do all the checks required for a 
  8993.                     --| trunk node.
  8994.     node : ND.node_type
  8995.     ) is
  8996.  
  8997.  
  8998.     attrib    : string (1..80);
  8999.     last    : natural;
  9000.     ci_node    : ND.node_type;
  9001.     branch    : ND.node_type;
  9002.     iter    : NM.node_iterator;
  9003.     branches    : natural := 0;
  9004.     num_branch    : natural := 0;
  9005.     list    : LU.list_type;
  9006.     count    : LU.count := 0;
  9007.     index    : LU.positive_count;
  9008.     name    : SP.string_type;
  9009.     
  9010.     begin
  9011.     name := SP.create (name_of(node));
  9012.     HU.get_node_attribute (node, "deleted", attrib, last);
  9013.     if last = 0 then
  9014.         begin
  9015.         NM.open_node_handle (    ci_node, 
  9016.                          base=>node,
  9017.                     relation=>"DOT",
  9018.                     key=>"CI");
  9019.         check_ci_node (ci_node, SP.value(name));
  9020.         NM.close_node_handle (ci_node);
  9021.         exception when ND.name_error =>
  9022.         report ("CI " & SP.value(name) & " has no contents.");
  9023.         end;
  9024.     else
  9025.         begin
  9026.         NM.open_node_handle (    ci_node,
  9027.                     base=>node,
  9028.                     relation=>"DOT",
  9029.                     key=>"CI");
  9030.         NM.close_node_handle (ci_node);
  9031.         report ("CI " & SP.value(name) & " that was deleted by " &
  9032.             attrib(1..last) & " still has contents when it should"
  9033.             & " be empty.");
  9034.         exception when ND.name_error =>
  9035.         -- this is what is supposed to happen
  9036.         null;
  9037.         end;
  9038.     end if;
  9039.     -- report who has a CI fetched.
  9040.     HU.get_node_attribute (node, "updating", attrib, last);
  9041.     if last /= 0 then
  9042.         report (attrib(1..last) & " has " & SP.value(name) & 
  9043.             " fetched for update.");
  9044.     end if;
  9045.     ATT.get_node_attribute (node, "branching", list);
  9046.     count := LU.num_positional(list);
  9047.     for index in 1..count loop
  9048.         report (LU.identifier(LU.positional(list,index)) & " has " &
  9049.             SP.value(name) & " fetched for branching.");
  9050.     end loop;
  9051.     LU.free_list (list);
  9052.     NM.iterate (iter, node, relation=>"branch", key=>"*");
  9053.     while NM.more(iter) loop
  9054.         num_branch := num_branch + 1;
  9055.         NM.get_next (iter, branch);
  9056.         check_branch_node (branch);
  9057.     end loop;
  9058.     HU.get_node_attribute (node, "branches", attrib, last);
  9059.     branches := integer'value (attrib(1..last));
  9060.     if num_branch > branches then
  9061.        report("There are more branches than recorded for " & 
  9062.             SP.value(name) & ":");
  9063.        report("This will get fixed next time there is a store.");
  9064.     elsif num_branch < branches then
  9065.        report("There are fewer branches than recorded for " &
  9066.             SP.value(name) & ":");
  9067.        report("There must be an internal error in the catalog_manager to "
  9068.             & "cause this.");
  9069.     end if;
  9070.  
  9071.     end check_trunk_node;
  9072.  
  9073. procedure check_ci_node (        --| check the properties on a CI node
  9074.     node : ND.node_type;
  9075.     name : string
  9076.     ) is
  9077.  
  9078.     ai        : ATT.attrib_iterator;
  9079.     attrib    : string(1..80);
  9080.     last    : natural;
  9081.     list    : LU.list_type;
  9082.     set        : CD.CI_set;
  9083.     ci_id     : ID.ci_id_type;
  9084.     
  9085.     begin
  9086.     ATT.node_attribute_iterate (ai, node, "*");
  9087.     ci_id := ID.get_ci_id (name);
  9088.     while ATT.more(ai) loop
  9089.         ATT.get_next(ai, attrib, last, list);
  9090.         begin
  9091.             set := IM.lookup_ci (SP.create(attrib(1..last)), 
  9092.              SP.create(LU.identifier(LU.positional(list,1))));
  9093.         exception when IM.invalid_value =>
  9094.         report ("Unable to check keyword" & attrib(1..last) &
  9095.             " for " & name & "because the index is missing.");
  9096.         end;
  9097.         if not CD.CI_sets.is_member (set, ci_id) then
  9098.  
  9099.         report ("Property " & attrib(1..last) & "-" & 
  9100.                 LU.identifier(LU.positional(list,1)) & 
  9101.             " is missing from the index for " & name);
  9102.         end if;
  9103.     end loop;
  9104.     end check_ci_node;
  9105.  
  9106. procedure check_branch_node (        --| the branch attributes
  9107.     node : ND.node_type
  9108.     ) is
  9109.  
  9110.     iter    : NM.node_iterator;
  9111.     trunk    : ND.node_type;
  9112.     num_trunks  : natural := 0;
  9113.  
  9114.     begin
  9115.     NM.iterate (iter, node, relation=>"trunk", key=>"*");
  9116.     while NM.more(iter) loop
  9117.         num_trunks := num_trunks + 1;
  9118.         NM.get_next (iter, trunk);
  9119.         check_trunk_node (trunk);
  9120.     end loop;
  9121.     if num_trunks = 0 then
  9122.         report ("Branch " & name_of (node) & " does not have at least " &
  9123.             "one trunk CI");
  9124.     end if;
  9125.     end check_branch_node;
  9126.  
  9127. end catalog_interface;
  9128.  
  9129. ::::::::::::::
  9130. interface.spc
  9131. ::::::::::::::
  9132. with string_pkg;
  9133.  
  9134. package catalog_interface is
  9135.  
  9136. --| Overview
  9137. --| 
  9138. --| This package contains the procedures which  control input to the
  9139. --| catalog.  The two main procedures are those  that are the interactive
  9140. --| interface to the catalog routines.  Any other catalog functions that
  9141. --| are invoked from the command line will also be in this package.
  9142. --| There is one of these, namely, check_consistency.
  9143.  
  9144. package SP renames string_pkg;
  9145.  
  9146. procedure open_catalog (    --| Open a catalog with the given name
  9147.     catalog_name : SP.string_type    --| Name of the catalog
  9148.     );
  9149.  
  9150. --| Effects: Opens a catalog with the given name.  If the catalog does
  9151. --| not exist an error message is printed out to the user to use the
  9152. --| operation create_catalog which creates a new catalog.
  9153. --| If the catalog does exist it places the user in interactive mode 
  9154. --| with the catalog in order to query the contents.
  9155.  
  9156. procedure create_catalog (    --| Create a catalog with the given name
  9157.     catalog_name : in SP.string_type;    --| Name of the catalog to create
  9158.     directory    : in SP.string_type    --| Name of the directory where the 
  9159.                     --| catalog will be stored
  9160.     );
  9161.  
  9162. --| Effects: Creates a catalog with the given name.  The catalog is empty, but
  9163. --| the user is left in interactive mode.  The person will be prompted for a
  9164. --| password for the catalog to use with privileged operations.  Before
  9165. --| leaving the catalog manger the person should also define a set of 
  9166. --| valid keywords for the database.
  9167.  
  9168. --| Notes: The above procedures open_catalog, and create_catalog put the
  9169. --| user in interactive mode with the catalog manager.  
  9170. --| The operations which the catalog
  9171. --| manager provides in interactive mode are summarized below.
  9172. --|-
  9173. --| Catalog Manager operations:
  9174. --| help            gives help about the interactive commands
  9175. --| exit            exit the catalog manager
  9176.  
  9177. --| Operations on the catalog:
  9178. --| select_CIs            select CI's matching keyword values given
  9179. --| clear_selected_set        make the current selected set of CIs empty
  9180. --| print_set            prints out the current selected set
  9181. --| list_catalog        list all the CI's in the cpcicat
  9182. --| change_password (*)        change the privileged user password
  9183.  
  9184. --| Operations on the list of keywords:
  9185. --| define_keyword (*)        define a keyword and its status.
  9186. --| list_keywords        list all valid keywords
  9187.  
  9188. --| Operations on a configuration item:
  9189. --| store            add a new configuration item from an itemlib
  9190. --| fetch            fetch an itemlib from the catalog
  9191. --| archive (*)            archive a CI
  9192. --| retrieve (*)        retrieve an archived CI
  9193. --| modify_property         change the value associated with a property
  9194. --| describe            list all the properties for a CI, (or the
  9195. --|                selected_set) and other information
  9196. --|                like history as asked for.
  9197. --| list_components        list the components of a CI
  9198.  
  9199. --| Operations to allow a privileged user to clean up the database:
  9200. --| remove_lock (*)        removes a temporary lock on a CI
  9201. --| delete (*)            delete a CI
  9202. --| 
  9203. --|+
  9204. --| (*) indicates a privileged operation.
  9205.  
  9206. procedure check_consistency (    --| check the consistency of a catalog
  9207.                 --| producing a written report
  9208.     name   : in SP.string_type;        --| catalog name
  9209.     output : in SP.string_type        --| the name of the output file
  9210.     );
  9211.  
  9212. --| Effects: Runs over the whole catalog noting whether the properties on
  9213. --| CIs match what the database contains and reporting locks that have been
  9214. --| left on a CI, or property more than a day.  The report is put in the
  9215. --| output file given by the user.  A privileged user can then fix up the
  9216. --| inconsistencies (if there are any) using remove_lock and delete.  
  9217. --| In general a read lock can just be removed, but the privileged user
  9218. --| probably ought to tell the user the lock belonged to that the copy
  9219. --| they have if any is not considered checked out.  With a write lock 
  9220. --| the half written CI probably needs to be deleted too.  Again, probably
  9221. --| a check with the user to see if the itemlibrary is still around is
  9222. --| a good idea.  Also, it is expected that running this procedure will
  9223. --| be quite time consuming and probably ought to be run in batch 
  9224. --| overnight, or over a weekend (depending on the size of the catalog).
  9225.  
  9226. procedure list_catalogs (    --| List the names of all catalogs on the
  9227.                 --| system
  9228.     catalogs : in SP.string_type
  9229.     := SP.create("*")    --| String to match for catalog names
  9230.     );
  9231.  
  9232. --| Effects: Lists the names of catalogs in the hif.  It can only find
  9233. --| catalogs in the one hif that is defined since only one hif can be
  9234. --| defined at a time.  In the cases where someone has forgotten the
  9235. --| name of a catalog they created they can do a listing of all catalogs
  9236. --| and try to figure it out that way.
  9237.  
  9238. end catalog_interface;
  9239.  
  9240. -- Note:  There will be drivers for each of these subprograms that use the
  9241. -- standard interface and read the parameters off the command line.  It 
  9242. -- seems unnecessary to make specs for them since they will have very
  9243. -- boring specs.
  9244.  
  9245. -- The following subprograms will be taken care of entirely with in the 
  9246. -- body of the interface:
  9247. -- clear_selected_set      since this is just one set operation
  9248. -- print_set        since this is just an output operation
  9249. -- 
  9250. -- The syntax of the select_CIs operation will also be taken care of within
  9251. -- the body of the interface.  The operation in the catalog manager which
  9252. -- selects CIs will take just one keyword and value and return a set.  The
  9253. -- interface will have to take care of the merging and intersection as 
  9254. -- needed.
  9255. ::::::::::::::
  9256. liberr.bdy
  9257. ::::::::::::::
  9258. with Host_Lib;
  9259. with Library_Declarations;
  9260.  
  9261. package body Library_Errors is
  9262.  
  9263. --------------------------------------------------------------------------------
  9264.  
  9265.     package HL renames Host_Lib;
  9266.     package LD renames Library_Declarations;
  9267.  
  9268. --------------------------------------------------------------------------------
  9269.  
  9270.     Errors : constant array (Error_Type) of SP.String_Type :=
  9271.        (Directory_Already_Exists =>
  9272.         SP.Make_Persistent("Directory ~S already exists."),
  9273.     File_Not_Created =>
  9274.         SP.Make_Persistent("File ~S not created."),
  9275.     File_Not_Found =>
  9276.         SP.Make_Persistent("File ~S not found."),
  9277.     Internal_Error =>
  9278.         SP.Make_Persistent("<<< ~S Internal Error >>>"),
  9279.     Interrupt_Encountered =>
  9280.         SP.Make_Persistent("Command ~S aborted by user interrupt."),
  9281.     Invalid_Directory_Name =>
  9282.         SP.Make_Persistent("Invalid directory specificaton ~S."),
  9283.     Invalid_Downgrade =>
  9284.         SP.Make_Persistent("Invalid lock downgrade for library ~S."),
  9285.     Invalid_External_Name =>
  9286.         SP.Make_Persistent("Invalid file name ~S."),
  9287.     Invalid_Keyword =>
  9288.         SP.Make_Persistent("Property keyword ~S invalid."),
  9289.     Invalid_Library_Name =>
  9290.         SP.Make_Persistent("Invalid library name ~S."),
  9291.     Invalid_Operation =>
  9292.         SP.Make_Persistent("Fetch mode UPDATE not allowed for version ~S."),
  9293.     Invalid_Upgrade =>
  9294.         SP.Make_Persistent("Invalid lock upgrade for library ~S."),
  9295.     Invalid_Value =>
  9296.         SP.Make_Persistent("Property value ~S invalid."),
  9297.     Invalid_Version =>
  9298.         SP.Make_Persistent("Invalid version specification ~S."),
  9299.     Item_Already_Exists =>
  9300.         SP.Make_Persistent("Item ~S already exists."),
  9301.     Item_Checked_Out =>
  9302.         SP.Make_Persistent("Item ~S checked out by ~T."),
  9303.     Item_Not_Checked_Out =>
  9304.         SP.Make_Persistent("Item ~S not checked out."),
  9305.     Item_Not_Created =>
  9306.         SP.Make_Persistent("Item ~S not created."),
  9307.     Item_Not_Found =>
  9308.         SP.Make_Persistent("Item ~S not found."),
  9309.     Keyword_Already_Exists =>
  9310.         SP.Make_Persistent("Property keyword ~S already exists."),
  9311.     Keyword_Not_Found =>
  9312.         SP.Make_Persistent("Property keyword ~S not found."),
  9313.     Library_Already_Exists =>
  9314.         SP.Make_Persistent("Library ~S already exists"),
  9315.     Library_Does_Not_Exist =>
  9316.         SP.Make_Persistent("Library ~S does not exist."),
  9317.     Library_Incomplete =>
  9318.         SP.Make_Persistent("Item(s) currently checked out from library ~S."),
  9319.     Library_Master_Locked =>
  9320.         SP.Make_Persistent("Library ~S is master locked."),
  9321.     Library_Pending_Return =>
  9322.         SP.Make_Persistent("Library ~S pending return to CI ~T."),
  9323.     Library_Read_Locked =>
  9324.         SP.Make_Persistent("Unable to open library ~S for read."),
  9325.     Library_Write_Locked =>
  9326.         SP.Make_Persistent("Unable to open library ~S for write."),
  9327.     No_Privilege =>
  9328.         SP.Make_Persistent("No privilege for operation on ~S owned by ~T."),
  9329.     Not_Authorized =>
  9330.         SP.Make_Persistent("Unauthorized unlocking attempt on library ~S."),
  9331.     Process_Interrupted =>
  9332.         SP.Make_Persistent("Process ~S interrupted."),
  9333.     Set_Protection_Error =>
  9334.         SP.Make_Persistent("Proper protection not set for ~S."),
  9335.     Version_Not_Found =>
  9336.         SP.Make_Persistent("Version ~S not found."));
  9337.  
  9338. --------------------------------------------------------------------------------
  9339.  
  9340.     procedure Report_Error(
  9341.     Kind : in Error_Type;
  9342.     Sub1 : in SP.String_Type := SP.Create("");
  9343.     Sub2 : in SP.String_Type := SP.Create("")
  9344.     ) is
  9345.  
  9346.     S_Str : SP.String_Type;
  9347.     Num   : NATURAL;
  9348.  
  9349.     begin
  9350.  
  9351.     if not LD.Message_on_Error then
  9352.         return;
  9353.     end if;
  9354.     SP.Mark;
  9355.     S_Str := SP.Create(SP.Value(Errors(Kind)));
  9356.     loop
  9357.         Num := SP.Match_S(S_Str, "~S");
  9358.         exit when Num = 0;
  9359.         if SP.Is_Empty(Sub1) then
  9360.         if Num = 1 then
  9361.             S_Str := SP.Splice(S_Str, Num, 3);
  9362.         else
  9363.             S_Str := SP.Splice(S_Str, Num-1, 3);
  9364.         end if;
  9365.         else
  9366.         S_Str := SP.Splice(S_Str, Num, 2);
  9367.         S_Str := SP.Insert(S_Str, SP.Upper(Sub1), Num);
  9368.         end if;
  9369.     end loop;
  9370.  
  9371.     loop
  9372.         Num := SP.Match_S(S_Str, "~T");
  9373.         exit when Num = 0;
  9374.         if SP.Is_Empty(Sub2) then
  9375.         if Num = 1 then
  9376.             S_Str := SP.Splice(S_Str, Num, 3);
  9377.         else
  9378.             S_Str := SP.Splice(S_Str, Num-1, 3);
  9379.         end if;
  9380.         else
  9381.         S_Str := SP.Splice(S_Str, Num, 2);
  9382.         S_Str := SP.Insert(S_Str, SP.Upper(Sub2), Num);
  9383.         end if;
  9384.     end loop;
  9385.  
  9386.     HL.Put_Error(SP.Value(S_Str));
  9387.     SP.Release;
  9388.  
  9389.     end Report_Error;
  9390.  
  9391. end Library_Errors;
  9392.                                                                     pragma page;
  9393. ::::::::::::::
  9394. liberr.spc
  9395. ::::::::::::::
  9396. with String_Pkg;
  9397.  
  9398. package Library_Errors is
  9399.  
  9400. --------------------------------------------------------------------------------
  9401.  
  9402.     package SP renames String_Pkg;
  9403.  
  9404. --------------------------------------------------------------------------------
  9405.  
  9406.     type Error_Type is (Directory_Already_Exists,
  9407.             File_Not_Created,
  9408.             File_Not_Found,
  9409.             Internal_Error,
  9410.             Interrupt_Encountered,
  9411.             Invalid_Directory_Name,
  9412.             Invalid_Downgrade,
  9413.             Invalid_External_Name,
  9414.             Invalid_Keyword,
  9415.             Invalid_Library_Name,
  9416.             Invalid_Operation,
  9417.             Invalid_Upgrade,
  9418.             Invalid_Value,
  9419.             Invalid_Version,
  9420.             Item_Already_Exists,
  9421.             Item_Checked_Out,
  9422.             Item_Not_Checked_Out,
  9423.             Item_Not_Created,
  9424.             Item_Not_Found,
  9425.             Keyword_Already_Exists,
  9426.             Keyword_Not_Found,
  9427.             Library_Already_Exists,
  9428.             Library_Does_Not_Exist,
  9429.             Library_Incomplete,
  9430.             Library_Master_Locked,
  9431.             Library_Pending_Return,
  9432.             Library_Read_Locked,
  9433.             Library_Write_Locked,
  9434.             No_Privilege,
  9435.             Not_Authorized,
  9436.             Process_Interrupted,
  9437.             Set_Protection_Error,
  9438.             Version_Not_Found);
  9439.  
  9440. --------------------------------------------------------------------------------
  9441.  
  9442. procedure Report_Error(
  9443.     Kind : in Error_Type;
  9444.     Sub1 : in SP.String_Type := SP.Create("");
  9445.     Sub2 : in SP.String_Type := SP.Create("")
  9446.     );
  9447.  
  9448. --------------------------------------------------------------------------------
  9449.  
  9450. end Library_Errors;
  9451.                                                                     pragma page;
  9452. ::::::::::::::
  9453. libmgr.ada
  9454. ::::::::::::::
  9455. with Standard_Interface;
  9456. with String_Pkg;
  9457. with Host_Lib;
  9458. with Tool_Identifier;
  9459. with Library_Errors;
  9460. with Library_Manager_Interface;
  9461.  
  9462. function Library_Manager return INTEGER is
  9463.  
  9464.     package SI  renames Standard_Interface;
  9465.     package SP  renames String_Pkg;
  9466.     package HL  renames Host_Lib;
  9467.     package LE  renames Library_Errors;
  9468.     package LIB is new SI.String_Argument(String_Type_Name => "library_name");
  9469.     package STR is new SI.String_Argument(String_Type_Name => "string");
  9470.  
  9471.     Library_Manager_Process : SI.Process_Handle;
  9472.     Library                 : SP.String_Type;
  9473.     Prompt                  : SP.String_Type;
  9474.  
  9475. begin
  9476.  
  9477.     SP.Mark;
  9478.  
  9479.     SI.Set_Tool_Identifier(Identifier => Tool_Identifier);
  9480.  
  9481.     SI.Define_Process(
  9482.     Proc    => Library_Manager_Process,
  9483.     Name    => "Library_Manager",
  9484.     Help    => "Interactive Library Manager");
  9485.  
  9486.     LIB.Define_Argument(
  9487.     Proc    => Library_Manager_Process,
  9488.     Name    => "library",
  9489.     Default => "",
  9490.     Help    => "Name of the item library");
  9491.  
  9492.     STR.Define_Argument(
  9493.     Proc    => Library_Manager_Process,
  9494.     Name    => "prompt",
  9495.     Default => "",
  9496.     Help    => "Prompt (null string implies library name)");
  9497.  
  9498.     SP.Release;
  9499.  
  9500.     SI.Parse_Line(Library_Manager_Process);
  9501.  
  9502.     Library := LIB.Get_Argument(Proc => Library_Manager_Process,
  9503.                 Name => "library");
  9504.  
  9505.     Prompt := STR.Get_Argument(Proc => Library_Manager_Process,
  9506.                    Name => "prompt");
  9507.  
  9508.     return HL.Return_Code(Library_Manager_Interface(Library, Prompt));
  9509.  
  9510. exception
  9511.  
  9512.     when SI.Process_Help =>
  9513.     return HL.Return_Code(HL.INFORMATION);
  9514.  
  9515.     when SI.Abort_Process =>
  9516.     return HL.Return_Code(HL.ERROR);
  9517.  
  9518.     when others =>
  9519.     LE.Report_Error(LE.Internal_Error, SP.Create(""));
  9520.     return HL.Return_Code(HL.SEVERE);
  9521.  
  9522. end Library_Manager;
  9523.                                                                     pragma page;
  9524. ::::::::::::::
  9525. libmgr.bdy
  9526. ::::::::::::::
  9527. with TEXT_IO;
  9528. with Standard_Interface;
  9529. with Tool_Identifier;
  9530. with Library_Errors;
  9531. with Library_Declarations;
  9532. with Add_Property_Interface;
  9533. with Cancel_Item_Interface;
  9534. with Copy_Library_Interface;
  9535. with Create_Item_Interface;
  9536. with Create_Library_Interface;
  9537. with Delete_Item_Interface;
  9538. with Delete_Library_Interface;
  9539. with Delete_Property_Interface;
  9540. with Fetch_Item_Interface;
  9541. with Library_Manager_Interface;
  9542. with List_Item_Interface;
  9543. with List_Library_Interface;
  9544. with List_Property_Interface;
  9545. with Modify_Property_Interface;
  9546. with Purge_Item_Interface;
  9547. with Rename_Item_Interface;
  9548. with Rename_Version_Interface;
  9549. with Return_Item_Interface;
  9550. with Show_History_Interface;
  9551.  
  9552. function Library_Manager_Interface(
  9553.     Library : in String_Pkg.String_Type;
  9554.     Prompt  : in String_Pkg.String_Type
  9555.     ) return Host_Lib.Severity_Code is
  9556.  
  9557.     package SP   renames String_Pkg;
  9558.     package HL   renames Host_Lib;
  9559.     package TIO  renames TEXT_IO;
  9560.     package SI   renames Standard_Interface;
  9561.     package LE   renames Library_Errors;
  9562.     package LD   renames Library_Declarations;
  9563.     package LIB  is new SI.String_Argument(String_Type_Name => "library_name");
  9564.     package DIR  is new SI.String_Argument(String_Type_Name => "directory_spec");
  9565.     package USER is new SI.String_Argument(String_Type_Name => "user_name");
  9566.     package FN   is new SI.String_Argument(String_Type_Name => "file_name");
  9567.     package ITM  is new SI.String_Argument(String_Type_Name => "item_name");
  9568.     package STR  is new SI.String_Argument(String_Type_Name => "string");
  9569.     package VER  is new SI.String_Argument(String_Type_Name => "version");
  9570.     package LIM  is new SI.Enumerated_Argument(Enum_Type      => LD.List_Mode,
  9571.                            Enum_Type_Name => "list_mode");
  9572.     package FIM  is new SI.Enumerated_Argument(Enum_Type      => LD.State_Type,
  9573.                            Enum_Type_Name => "fetch_mode");
  9574.     package CLM  is new SI.Enumerated_Argument(Enum_Type      => LD.Copy_Mode,
  9575.                            Enum_Type_Name => "copy_mode");
  9576.  
  9577.     type Commands is (
  9578.     Create_Library,
  9579.     Delete_Library,
  9580.     Copy_Library,
  9581.     List_Library,
  9582.     Create_Item,
  9583.     Fetch_Item,
  9584.     Return_Item,
  9585.     Cancel_Item,
  9586.     List_Item,
  9587.     Delete_Item,
  9588.     Purge_Item,
  9589.     Rename_Item,
  9590.     Rename_Version,
  9591.     Show_History,
  9592.     Add_Property,
  9593.     Delete_Property,
  9594.     Modify_Property,
  9595.     List_Property,
  9596. --    Escape,
  9597.     Enter_Library);
  9598.  
  9599.     package CMD is new SI.Command_Line(Command_Enumeration => Commands);
  9600.  
  9601.     Abbreviation : CMD.Command_Abbreviation_Array :=
  9602.     (Create_Library  => 8,
  9603.      Delete_Library  => 8,
  9604.      Copy_Library    => 6,
  9605.      List_Library    => 6,
  9606.      Create_Item     => 2,
  9607.      Fetch_Item      => 3,
  9608.      Return_Item     => 3,
  9609.      Cancel_Item     => 3,
  9610.      List_Item       => 4,
  9611.      Delete_Item     => 3,
  9612.      Purge_Item      => 3,
  9613.      Rename_Item     => 3,
  9614.      Rename_Version  => 8,
  9615.      Show_History    => 4,
  9616.      Add_Property    => 5,
  9617.      Delete_Property => 8,
  9618.      Modify_Property => 8,
  9619.      List_Property   => 6,
  9620. --     Escape          => 3,
  9621.      Enter_Library   => 5);
  9622.  
  9623.     Command_Array     : CMD.Process_Handle_Array;
  9624.     Command           : Commands;
  9625.     Default_Library   : SP.String_Type;
  9626.     Current_Library   : SP.String_Type;
  9627.     Default_Prompt    : SP.String_Type;
  9628.     Current_Prompt    : SP.String_Type;
  9629.     Library_Name      : SP.String_Type;
  9630.     To_Library_Name   : SP.String_Type;
  9631.     Directory         : SP.String_Type;
  9632.     Owner_Name        : SP.String_Type;
  9633.     Item_Name         : SP.String_Type;
  9634.     To_Item_Name      : SP.String_Type;
  9635.     Version_Name      : SP.String_Type;
  9636.     To_Version_Name   : SP.String_Type;
  9637.     File_Name         : SP.String_Type;
  9638.     Keyword           : SP.String_Type;
  9639.     Value             : SP.String_Type;
  9640.     System_Command    : SP.String_Type;
  9641.     History           : SP.String_Type;
  9642.     Fetch_Item_Mode   : LD.State_Type;
  9643.     List_Item_Mode    : LD.List_Mode;
  9644.     Copy_Library_Mode : LD.Copy_Mode;
  9645.     Input_Line        : STRING(1..256);
  9646.     Input_Line_Length : INTEGER;
  9647.     Return_Code       : HL.Severity_Code := HL.SUCCESS;
  9648.  
  9649. begin
  9650.  
  9651.     SP.Mark;
  9652.  
  9653.     SI.Set_Tool_Identifier(Identifier => Tool_Identifier);
  9654.  
  9655. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  9656.  
  9657.     SI.Define_Process(
  9658.     Proc => Command_Array(Create_Library),
  9659.     Name => "Create_Library",
  9660.     Help => "Create an Item Library");
  9661.  
  9662.     LIB.Define_Argument(
  9663.     Proc => Command_Array(Create_Library),
  9664.     Name => "library",
  9665.     Help => "Name of the item library to be created");
  9666.  
  9667.     DIR.Define_Argument(
  9668.     Proc => Command_Array(Create_Library),
  9669.     Name => "directory",
  9670.     Help => "Name of directory to be used by this library");
  9671.  
  9672. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  9673.  
  9674.     SI.Define_Process(
  9675.     Proc => Command_Array(Delete_Library),
  9676.     Name => "Delete_Library",
  9677.     Help => "Delete an Item Library");
  9678.  
  9679.     LIB.Define_Argument(
  9680.     Proc => Command_Array(Delete_Library),
  9681.     Name => "library",
  9682.     Help => "Name of the item library to be deleted");
  9683.  
  9684. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  9685.  
  9686.     SI.Define_Process(
  9687.     Proc => Command_Array(Copy_Library),
  9688.     Name => "Copy_Library",
  9689.     Help => "Copy an Item Library to Another Item Library");
  9690.  
  9691.     LIB.Define_Argument(
  9692.     Proc => Command_Array(Copy_Library),
  9693.     Name => "from_library",
  9694.     Help => "Name of the item library to be copied");
  9695.  
  9696.     LIB.Define_Argument(
  9697.     Proc => Command_Array(Copy_Library),
  9698.     Name => "to_library",
  9699.     Help => "Name of the new item library");
  9700.  
  9701.     DIR.Define_Argument(
  9702.     Proc => Command_Array(Copy_Library),
  9703.     Name => "to_directory",
  9704.     Help => "Name of directory to be used by the new library");
  9705.  
  9706.     CLM.Define_Argument(
  9707.     Proc   => Command_Array(Copy_Library),
  9708.     Name    => "mode",
  9709.     Default => LD.CURRENT,
  9710.     Help    => "Copy option:");
  9711.  
  9712.     CLM.Append_Argument_Help(
  9713.     Proc => Command_Array(Copy_Library),
  9714.     Name => "mode",
  9715.     Help => "   CURRENT : copy only the current version of items");
  9716.  
  9717.     CLM.Append_Argument_Help(
  9718.     Proc => Command_Array(Copy_Library),
  9719.     Name => "mode",
  9720.     Help => "   FULL    : copy all versions of items");
  9721.  
  9722. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  9723.  
  9724.     SI.Define_Process(
  9725.     Proc => Command_Array(List_Library),
  9726.     Name => "List_Library",
  9727.     Help => "List Libraries Owned by User");
  9728.  
  9729.     USER.Define_Argument(
  9730.     Proc    => Command_Array(List_Library),
  9731.     Name    => "owner",
  9732.     Default => HL.Get_Item(HL.USER_NAME),
  9733.     Help    => "Name of the library owner");
  9734.  
  9735.     LIB.Define_Argument(
  9736.     Proc    => Command_Array(List_Library),
  9737.     Name    => "library",
  9738.     Default => "*",
  9739.     Help    => "Name of the library");
  9740.  
  9741. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  9742.  
  9743.     SI.Define_Process(
  9744.     Proc    => Command_Array(Create_Item),
  9745.     Name    => "Create_Item",
  9746.     Help    => "Create an Item in the Item Library");
  9747.  
  9748.     FN.Define_Argument(
  9749.     Proc => Command_Array(Create_Item),
  9750.     Name => "file",
  9751.     Help => "Name of the file to be checked into the item library");
  9752.  
  9753.     STR.Define_Argument(
  9754.     Proc => Command_Array(Create_Item),
  9755.     Name => "history",
  9756.     Help => "Description/reason for this item");
  9757.  
  9758. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  9759.  
  9760.     SI.Define_Process(
  9761.     Proc    => Command_Array(Fetch_Item),
  9762.     Name    => "Fetch_Item",
  9763.     Help    => "Fetch an Item from an Item Library");
  9764.  
  9765.     ITM.Define_Argument(
  9766.     Proc => Command_Array(Fetch_Item),
  9767.     Name => "item",
  9768.     Help => "Name of the item to be fetched from the item library");
  9769.  
  9770.     VER.Define_Argument(
  9771.     Proc    => Command_Array(Fetch_Item),
  9772.     Name    => "version",
  9773.     Default => "",
  9774.     Help    => "Version specification");
  9775.  
  9776.     FIM.Define_Argument(
  9777.     Proc    => Command_Array(Fetch_Item),
  9778.     Name    => "mode",
  9779.     Default => LD.NO_UPDATE,
  9780.     Help    => "Fetch mode:");
  9781.  
  9782.     FIM.Append_Argument_Help(
  9783.     Proc    => Command_Array(Fetch_Item),
  9784.     Name    => "mode",
  9785.     Help    => "   NO_UPDATE : check out an item for read only");
  9786.  
  9787.     FIM.Append_Argument_Help(
  9788.     Proc    => Command_Array(Fetch_Item),
  9789.     Name    => "mode",
  9790.     Help    => "   UPDATE    : check out an item for update");
  9791.  
  9792. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  9793.  
  9794.     SI.Define_Process(
  9795.     Proc    => Command_Array(Cancel_Item),
  9796.     Name    => "Cancel_Item",
  9797.     Help    => "Cancel a Pending Return for an Item in the Item Library");
  9798.  
  9799.     ITM.Define_Argument(
  9800.     Proc => Command_Array(Cancel_Item),
  9801.     Name => "item",
  9802.     Help => "Name of the item to cancel the pending return");
  9803.  
  9804. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  9805.  
  9806.     SI.Define_Process(
  9807.     Proc    => Command_Array(Return_Item),
  9808.     Name    => "Return_Item",
  9809.     Help    => "Return a File to an Item Library");
  9810.  
  9811.     FN.Define_Argument(
  9812.     Proc => Command_Array(Return_Item),
  9813.     Name => "file",
  9814.     Help => "Name of the file to be returned to the item library");
  9815.  
  9816.     STR.Define_Argument(
  9817.     Proc => Command_Array(Return_Item),
  9818.     Name => "history",
  9819.     Help => "Description/reason for the change(s) in this item");
  9820.  
  9821. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  9822.  
  9823.     SI.Define_Process(
  9824.     Proc    => Command_Array(Delete_Item),
  9825.     Name    => "Delete_Item",
  9826.     Help    => "Delete Item(s) in an Item Library");
  9827.  
  9828.     ITM.Define_Argument(
  9829.     Proc => Command_Array(Delete_Item),
  9830.     Name => "item",
  9831.     Help => "Name of the item(s) to be deleted in the item library");
  9832.  
  9833.     VER.Define_Argument(
  9834.     Proc    => Command_Array(Delete_Item),
  9835.     Name    => "version",
  9836.     Default => "",
  9837.     Help    => "Version specification");
  9838.  
  9839. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  9840.  
  9841.     SI.Define_Process(
  9842.     Proc    => Command_Array(Purge_Item),
  9843.     Name    => "Purge_Item",
  9844.     Help    => "Purge Item(s) in an Item Library");
  9845.  
  9846.     ITM.Define_Argument(
  9847.     Proc => Command_Array(Purge_Item),
  9848.     Name => "item",
  9849.     Help => "Name of the item(s) to be purged in the item library");
  9850.  
  9851. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  9852.  
  9853.     SI.Define_Process(
  9854.     Proc    => Command_Array(Rename_Item),
  9855.     Name    => "Rename_Item",
  9856.     Help    => "Rename an Item in an Item Library");
  9857.  
  9858.     ITM.Define_Argument(
  9859.     Proc => Command_Array(Rename_Item),
  9860.     Name => "from_item",
  9861.     Help => "Name of the item to be renamed in the item library");
  9862.  
  9863.     ITM.Define_Argument(
  9864.     Proc => Command_Array(Rename_Item),
  9865.     Name => "to_item",
  9866.     Help => "New item name");
  9867.  
  9868. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  9869.  
  9870.     SI.Define_Process(
  9871.     Proc    => Command_Array(Rename_Version),
  9872.     Name    => "Rename_Version",
  9873.     Help    => "Rename Version of Item(s) in an Item Library");
  9874.  
  9875.     ITM.Define_Argument(
  9876.     Proc => Command_Array(Rename_Version),
  9877.     Name => "item",
  9878.     Help => "Name of the item(s) to be renamed in the item library");
  9879.  
  9880.     VER.Define_Argument(
  9881.     Proc => Command_Array(Rename_Version),
  9882.     Name => "from_version",
  9883.     Help => "Version of item(s) to be renamed");
  9884.  
  9885.     VER.Define_Argument(
  9886.     Proc => Command_Array(Rename_Version),
  9887.     Name => "to_version",
  9888.     Help => "New version of item(s)");
  9889.  
  9890. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  9891.  
  9892.     SI.Define_Process(
  9893.     Proc    => Command_Array(List_Item),
  9894.     Name    => "List_Item",
  9895.     Help    => "List Item(s) in the Item Library");
  9896.  
  9897.     ITM.Define_Argument(
  9898.     Proc    => Command_Array(List_Item),
  9899.     Name    => "item",
  9900.     Default => "*",
  9901.     Help    => "Name of the item to list");
  9902.  
  9903.     VER.Define_Argument(
  9904.     Proc    => Command_Array(List_Item),
  9905.     Name    => "version",
  9906.     Default => "",
  9907.     Help    => "Version specification");
  9908.  
  9909.     LIM.Define_Argument(
  9910.     Proc    => Command_Array(List_Item),
  9911.     Name    => "mode",
  9912.     Default => LD.SHORT,
  9913.     Help    => "List mode:");
  9914.  
  9915.     LIM.Append_Argument_Help(
  9916.     Proc    => Command_Array(List_Item),
  9917.     Name    => "mode",
  9918.     Help    => "   SHORT : list item/version name(s) only");
  9919.  
  9920.     LIM.Append_Argument_Help(
  9921.     Proc    => Command_Array(List_Item),
  9922.     Name    => "mode",
  9923.     Help    => "   LONG  : list attributes as well as item/version name(s)");
  9924.  
  9925. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  9926.  
  9927.     SI.Define_Process(
  9928.     Proc    => Command_Array(Show_History),
  9929.     Name    => "Show_History",
  9930.     Help    => "Show History of Item(s) in an Item Library");
  9931.  
  9932.     ITM.Define_Argument(
  9933.     Proc    => Command_Array(Show_History),
  9934.     Name    => "item",
  9935.     Default => "*",
  9936.     Help    => "Name of the item to list");
  9937.  
  9938.     VER.Define_Argument(
  9939.     Proc    => Command_Array(Show_History),
  9940.     Name    => "version",
  9941.     Default => "",
  9942.     Help    => "Version specification");
  9943.  
  9944. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  9945.  
  9946.     SI.Define_Process(
  9947.     Proc    => Command_Array(Add_Property),
  9948.     Name    => "Add_Property",
  9949.     Help    => "Add a Property Keyword/Value to the Item Library");
  9950.  
  9951.     STR.Define_Argument(
  9952.     Proc    => Command_Array(Add_Property),
  9953.     Name    => "keyword",
  9954.     Help    => "Property keyword");
  9955.  
  9956.     STR.Define_Argument(
  9957.     Proc    => Command_Array(Add_Property),
  9958.     Name    => "value",
  9959.     Help    => "Property value");
  9960.  
  9961. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  9962.  
  9963.     SI.Define_Process(
  9964.     Proc    => Command_Array(Delete_Property),
  9965.     Name    => "Delete_Property",
  9966.     Help    => "Delete a Property Keyword from the Item Library");
  9967.  
  9968.     STR.Define_Argument(
  9969.     Proc    => Command_Array(Delete_Property),
  9970.     Name    => "keyword",
  9971.     Help    => "Property keyword");
  9972.  
  9973. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  9974.  
  9975.     SI.Define_Process(
  9976.     Proc    => Command_Array(Modify_Property),
  9977.     Name    => "Modify_Property",
  9978.     Help    => "Change a Property Keyword/Value in the Item Library");
  9979.  
  9980.     STR.Define_Argument(
  9981.     Proc    => Command_Array(Modify_Property),
  9982.     Name    => "keyword",
  9983.     Help    => "Property keyword");
  9984.  
  9985.     STR.Define_Argument(
  9986.     Proc    => Command_Array(Modify_Property),
  9987.     Name    => "value",
  9988.     Help    => "Property value");
  9989.  
  9990. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  9991.  
  9992.     SI.Define_Process(
  9993.     Proc    => Command_Array(List_Property),
  9994.     Name    => "List_Property",
  9995.     Help    => "List Property Keyword/Value in the Item Library");
  9996.  
  9997.     STR.Define_Argument(
  9998.     Proc    => Command_Array(List_Property),
  9999.     Name    => "keyword",
  10000.     Default => "*",
  10001.     Help    => "Property keyword");
  10002.  
  10003. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  10004. --
  10005. --    SI.Define_Process(
  10006. --    Proc    => Command_Array(Escape),
  10007. --    Name    => "Escape",
  10008. --    Help    => "Execute System Command");
  10009. --
  10010. --    STR.Define_Argument(
  10011. --    Proc    => Command_Array(Escape),
  10012. --    Name    => "command",
  10013. --    Help    => "System Command");
  10014. --
  10015. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  10016.  
  10017.     SI.Define_Process(
  10018.     Proc    => Command_Array(Enter_Library),
  10019.     Name    => "Enter_Library",
  10020.     Help    => "Enter a Given Item Library");
  10021.  
  10022.     LIB.Define_Argument(
  10023.     Proc    => Command_Array(Enter_Library),
  10024.     Name    => "library",
  10025.     Help    => "Name of the library");
  10026.  
  10027. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  10028.  
  10029.     CMD.Define_Command_Abbreviation(
  10030.     Abbreviation   => Abbreviation,
  10031.     Check_Conflict => TRUE);
  10032.  
  10033. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  10034.  
  10035.     SP.Release;
  10036.  
  10037.     Default_Library := SP.Make_Persistent(Library);
  10038.     if SP.Is_Empty(Prompt) then
  10039.     Default_Prompt := SP.Make_Persistent(SP."&"(SP.Upper(Default_Library), ">"));
  10040.     else
  10041.     Default_Prompt := SP.Make_Persistent(Prompt);
  10042.     end if;
  10043.  
  10044.     Current_Library := SP.Make_Persistent(Default_Library);
  10045.     Current_Prompt  := SP.Make_Persistent(Default_Prompt);
  10046.  
  10047.     loop
  10048.  
  10049.     begin
  10050.     TIO.NEW_LINE(1);
  10051.     TIO.PUT(SP.Value(Current_Prompt) & ' ');
  10052.     TIO.GET_LINE(Input_Line, Input_Line_Length);
  10053.  
  10054.     Command := CMD.Parse_Command_Line(Handles => Command_Array,
  10055.                       Line    => Input_Line(1..Input_Line_Length));
  10056.  
  10057.     case Command is
  10058.  
  10059. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  10060.  
  10061.     when Create_Library =>
  10062.  
  10063.         Library_Name := LIB.Get_Argument(
  10064.         Proc => Command_Array(Create_Library),
  10065.         Name => "library");
  10066.  
  10067.         Directory := DIR.Get_Argument(
  10068.         Proc => Command_Array(Create_Library),
  10069.         Name => "directory");
  10070.  
  10071.         Return_Code := Create_Library_Interface(
  10072.                 Library   => Library_Name,
  10073.                 Directory => Directory);
  10074.  
  10075.         SP.Flush(Library_Name);
  10076.         SP.Flush(Directory);
  10077.  
  10078. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  10079.  
  10080.     when Delete_Library =>
  10081.  
  10082.         Library_Name := LIB.Get_Argument(
  10083.         Proc => Command_Array(Delete_Library),
  10084.         Name => "library");
  10085.  
  10086.         Return_Code := Delete_Library_Interface(
  10087.                 Library   => Library_Name,
  10088.                 Privilege => LD.Delete_Library_Privilege);
  10089.  
  10090.         SP.Flush(Library_Name);
  10091.         SP.Flush(Directory);
  10092.  
  10093. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  10094.  
  10095.     when Copy_Library =>
  10096.  
  10097.         Library_Name := LIB.Get_Argument(
  10098.         Proc => Command_Array(Copy_Library),
  10099.         Name => "from_library");
  10100.  
  10101.         To_Library_Name := LIB.Get_Argument(
  10102.         Proc => Command_Array(Copy_Library),
  10103.         Name => "to_library");
  10104.  
  10105.         Directory := DIR.Get_Argument(
  10106.         Proc => Command_Array(Copy_Library),
  10107.         Name => "to_directory");
  10108.  
  10109.         Copy_Library_Mode := CLM.Get_Argument(
  10110.         Proc => Command_Array(Copy_Library),
  10111.         Name => "mode");
  10112.  
  10113.         Return_Code := Copy_Library_Interface(
  10114.                 From_Library => Library_Name,
  10115.                 To_Library   => To_Library_Name,
  10116.                 To_Directory => Directory,
  10117.                 Mode         => Copy_Library_Mode);
  10118.  
  10119.         SP.Flush(Library_Name);
  10120.         SP.Flush(To_Library_Name);
  10121.         SP.Flush(Directory);
  10122.  
  10123. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  10124.  
  10125.     when List_Library =>
  10126.  
  10127.         Owner_Name := USER.Get_Argument(
  10128.         Proc => Command_Array(List_Library),
  10129.         Name => "owner");
  10130.  
  10131.         Library_Name := LIB.Get_Argument(
  10132.         Proc => Command_Array(List_Library),
  10133.         Name => "library");
  10134.  
  10135.         Return_Code := List_Library_Interface(
  10136.                 User    => Owner_Name,
  10137.                 Library => Library_Name);
  10138.  
  10139.         SP.Flush(Owner_Name);
  10140.         SP.Flush(Library_Name);
  10141.  
  10142. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  10143.  
  10144.     when Create_Item =>
  10145.  
  10146.         File_Name := FN.Get_Argument(
  10147.         Proc => Command_Array(Create_Item),
  10148.         Name => "file");
  10149.  
  10150.         History := STR.Get_Argument(
  10151.         Proc => Command_Array(Create_Item),
  10152.         Name => "history");
  10153.  
  10154.         Return_Code := Create_Item_Interface(
  10155.                 Library => Current_Library,
  10156.                 File    => File_Name,
  10157.                 History => History);
  10158.  
  10159.         SP.Flush(File_Name);
  10160.         SP.Flush(History);
  10161.  
  10162. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  10163.  
  10164.     when Fetch_Item =>
  10165.  
  10166.         Item_Name := ITM.Get_Argument(
  10167.         Proc => Command_Array(Fetch_Item),
  10168.         Name => "item");
  10169.  
  10170.         Version_Name := VER.Get_Argument(
  10171.         Proc => Command_Array(Fetch_Item),
  10172.         Name => "version");
  10173.  
  10174.         Fetch_Item_Mode := FIM.Get_Argument(
  10175.         Proc => Command_Array(Fetch_Item),
  10176.         Name => "mode");
  10177.  
  10178.         Return_Code := Fetch_Item_Interface(
  10179.                 Library => Current_Library,
  10180.                 Item    => Item_Name,
  10181.                 Version => Version_Name,
  10182.                 Mode    => Fetch_Item_Mode);
  10183.  
  10184.         SP.Flush(Item_Name);
  10185.         SP.Flush(Version_Name);
  10186.  
  10187. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  10188.  
  10189.     when Cancel_Item =>
  10190.  
  10191.         Item_Name := ITM.Get_Argument(
  10192.         Proc => Command_Array(Cancel_Item),
  10193.         Name => "item");
  10194.  
  10195.         Return_Code := Cancel_Item_Interface(
  10196.                 Library => Current_Library,
  10197.                 Item    => Item_Name);
  10198.  
  10199.         SP.Flush(Item_Name);
  10200.  
  10201. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  10202.  
  10203.     when Return_Item =>
  10204.  
  10205.         File_Name := FN.Get_Argument(
  10206.         Proc => Command_Array(Return_Item),
  10207.         Name => "file");
  10208.  
  10209.         History := STR.Get_Argument(
  10210.         Proc => Command_Array(Return_Item),
  10211.         Name => "history");
  10212.  
  10213.         Return_Code := Return_Item_Interface(
  10214.                 Library => Current_Library,
  10215.                 File    => File_Name,
  10216.                 History => History);
  10217.  
  10218.         SP.Flush(File_Name);
  10219.         SP.Flush(History);
  10220.  
  10221. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  10222.  
  10223.     when Delete_Item =>
  10224.  
  10225.         Item_Name := ITM.Get_Argument(
  10226.         Proc => Command_Array(Delete_Item),
  10227.         Name => "item");
  10228.  
  10229.         Version_Name := VER.Get_Argument(
  10230.         Proc => Command_Array(Delete_Item),
  10231.         Name => "version");
  10232.  
  10233.         Return_Code := Delete_Item_Interface(
  10234.                 Library   => Current_Library,
  10235.                 Item      => Item_Name,
  10236.                 Version   => Version_Name,
  10237.                 Privilege => LD.Delete_Item_Privilege);
  10238.  
  10239.         SP.Flush(Item_Name);
  10240.         SP.Flush(Version_Name);
  10241.  
  10242. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  10243.  
  10244.     when Purge_Item =>
  10245.  
  10246.         Item_Name := ITM.Get_Argument(
  10247.         Proc => Command_Array(Purge_Item),
  10248.         Name => "item");
  10249.  
  10250.         Return_Code := Purge_Item_Interface(
  10251.                 Library   => Current_Library,
  10252.                 Item      => Item_Name,
  10253.                 Privilege => LD.Purge_Item_Privilege);
  10254.     
  10255.         SP.Flush(Item_Name);
  10256.  
  10257. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  10258.  
  10259.     when Rename_Item =>
  10260.  
  10261.         Item_Name := ITM.Get_Argument(
  10262.         Proc => Command_Array(Rename_Item),
  10263.         Name => "from_item");
  10264.  
  10265.         To_Item_Name := ITM.Get_Argument(
  10266.         Proc => Command_Array(Rename_Item),
  10267.         Name => "to_item");
  10268.  
  10269.         Return_Code := Rename_Item_Interface(
  10270.                 Library   => Current_Library,
  10271.                 From_Item => Item_Name,
  10272.                 To_Item   => To_Item_Name,
  10273.                 Privilege => LD.Rename_Item_Privilege);
  10274.     
  10275.         SP.Flush(Item_Name);
  10276.         SP.Flush(To_Item_Name);
  10277.  
  10278. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  10279.  
  10280.     when Rename_Version =>
  10281.  
  10282.         Item_Name := ITM.Get_Argument(
  10283.         Proc => Command_Array(Rename_Version),
  10284.         Name => "item");
  10285.  
  10286.         Version_Name := VER.Get_Argument(
  10287.         Proc => Command_Array(Rename_Version),
  10288.         Name => "from_version");
  10289.  
  10290.         To_Version_Name := VER.Get_Argument(
  10291.         Proc => Command_Array(Rename_Version),
  10292.         Name => "to_version");
  10293.  
  10294.         Return_Code := Rename_Version_Interface(
  10295.                 Library      => Current_Library,
  10296.                 Item         => Item_Name,
  10297.                 From_Version => Version_Name,
  10298.                 To_Version   => To_Version_Name,
  10299.                 Privilege    => LD.Rename_Version_Privilege);
  10300.  
  10301.         SP.Flush(Item_Name);
  10302.         SP.Flush(Version_Name);
  10303.         SP.Flush(To_Version_Name);
  10304.  
  10305. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  10306.  
  10307.     when List_Item =>
  10308.  
  10309.         Item_Name := ITM.Get_Argument(
  10310.         Proc => Command_Array(List_Item),
  10311.         Name => "item");
  10312.  
  10313.         Version_Name := VER.Get_Argument(
  10314.         Proc => Command_Array(List_Item),
  10315.         Name => "version");
  10316.  
  10317.         List_Item_Mode := LIM.Get_Argument(
  10318.         Proc => Command_Array(List_Item),
  10319.         Name => "mode");
  10320.  
  10321.         Return_Code := List_Item_Interface(
  10322.                 Library => Current_Library,
  10323.                 Item    => Item_Name,
  10324.                 Version => Version_Name,
  10325.                 Mode    => List_Item_Mode);
  10326.  
  10327.         SP.Flush(Item_Name);
  10328.         SP.Flush(Version_Name);
  10329.  
  10330. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  10331.  
  10332.     when Show_History =>
  10333.  
  10334.         Item_Name := ITM.Get_Argument(
  10335.         Proc => Command_Array(Show_History),
  10336.         Name => "item");
  10337.  
  10338.         Version_Name := VER.Get_Argument(
  10339.         Proc => Command_Array(Show_History),
  10340.         Name => "version");
  10341.  
  10342.         Return_Code := Show_History_Interface(
  10343.                 Library => Current_Library,
  10344.                 Item    => Item_Name,
  10345.                 Version => Version_Name);
  10346.  
  10347.         SP.Flush(Item_Name);
  10348.         SP.Flush(Version_Name);
  10349.  
  10350. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  10351.  
  10352.     when Add_Property =>
  10353.  
  10354.         Keyword := STR.Get_Argument(
  10355.         Proc => Command_Array(Add_Property),
  10356.         Name => "keyword");
  10357.  
  10358.         Value := STR.Get_Argument(
  10359.         Proc => Command_Array(Add_Property),
  10360.         Name => "value");
  10361.  
  10362.         Return_Code := Add_Property_Interface(
  10363.                 Library   => Current_Library,
  10364.                 Keyword   => Keyword,
  10365.                 Value     => Value,
  10366.                 Privilege => LD.Add_Property_Privilege);
  10367.  
  10368.         SP.Flush(Keyword);
  10369.         SP.Flush(Value);
  10370.  
  10371. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  10372.  
  10373.     when Delete_Property =>
  10374.  
  10375.         Keyword := STR.Get_Argument(
  10376.         Proc => Command_Array(Delete_Property),
  10377.         Name => "keyword");
  10378.  
  10379.         Return_Code := Delete_Property_Interface(
  10380.                 Library   => Current_Library,
  10381.                 Keyword   => Keyword,
  10382.                 Privilege => LD.Delete_Property_Privilege);
  10383.  
  10384.         SP.Flush(Keyword);
  10385.  
  10386. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  10387.  
  10388.     when Modify_Property =>
  10389.  
  10390.         Keyword := STR.Get_Argument(
  10391.         Proc => Command_Array(Modify_Property),
  10392.         Name => "keyword");
  10393.  
  10394.         Value := STR.Get_Argument(
  10395.         Proc => Command_Array(Modify_Property),
  10396.         Name => "value");
  10397.  
  10398.         Return_Code := Modify_Property_Interface(
  10399.                 Library   => Current_Library,
  10400.                 Keyword   => Keyword,
  10401.                 Value     => Value,
  10402.                 Privilege => LD.Modify_Property_Privilege);
  10403.  
  10404.         SP.Flush(Keyword);
  10405.         SP.Flush(Value);
  10406.  
  10407. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  10408.  
  10409.     when List_Property =>
  10410.  
  10411.         Keyword := STR.Get_Argument(
  10412.         Proc => Command_Array(List_Property),
  10413.         Name => "keyword");
  10414.  
  10415.         Return_Code := List_Property_Interface(
  10416.                 Library   => Current_Library,
  10417.                 Keyword   => Keyword);
  10418.  
  10419.         SP.Flush(Keyword);
  10420.  
  10421. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  10422. --
  10423. --    when Escape =>
  10424. --
  10425. --        System_Command := STR.Get_Argument(
  10426. --        Proc => Command_Array(Escape),
  10427. --        Name => "command");
  10428. --
  10429. --        HL.Invoke(SP.Value(System_Command), Return_Code);
  10430. --
  10431. --        SP.Flush(System_Command);
  10432. --
  10433. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  10434.  
  10435.     when Enter_Library =>
  10436.  
  10437.         SP.Flush(Current_Library);
  10438.         SP.Flush(Current_Prompt);
  10439.  
  10440.         Current_Library := LIB.Get_Argument(
  10441.         Proc => Command_Array(Enter_Library),
  10442.         Name => "library");
  10443.  
  10444.         if SP.Is_Empty(Current_Library) then
  10445.         Current_Library := SP.Make_Persistent(Default_Library);
  10446.         Current_Prompt  := SP.Make_Persistent(Default_Prompt);
  10447.         else
  10448.         Current_Prompt := SP.Make_Persistent(SP."&"(SP.Upper(Current_Library), ">"));
  10449.         end if;
  10450.  
  10451. --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
  10452.  
  10453.     end case;
  10454.  
  10455.     if HL."="(Return_Code, HL.SEVERE) then
  10456.         return HL.SEVERE;
  10457.     end if;
  10458.  
  10459.     SI.Redefine_Process(Command_Array(Command));
  10460.  
  10461.     exception
  10462.     when SI.Process_Help =>
  10463.         null;
  10464.     when SI.Abort_Process =>
  10465.         null;
  10466.     when SI.No_Command =>
  10467.         null;
  10468.     when SI.Abort_Command =>
  10469.         null;
  10470.     when SI.Command_Help =>
  10471.         null;
  10472.     when SI.Command_Exit =>
  10473.         return HL.SUCCESS;
  10474.     when others =>
  10475.         LE.Report_Error(LE.Internal_Error, SP.Create("Library_Manager"));
  10476.         return HL.SEVERE;
  10477.     end;
  10478.  
  10479.     end loop;
  10480.  
  10481. end Library_Manager_Interface;
  10482.                                                                     pragma page;
  10483. ::::::::::::::
  10484. libmgr.dat
  10485. ::::::::::::::
  10486. with Lists;
  10487. with String_Pkg;
  10488. with String_Lists;
  10489.  
  10490. package Library_Declarations is
  10491.  
  10492.  
  10493. --------------------------------------------------------------------------------
  10494. --                              Exceptions                                    --
  10495. --------------------------------------------------------------------------------
  10496.  
  10497. Invalid_Library_Name     : exception;    --| Library name not an Ada identifier
  10498. Library_Does_Not_Exist   : exception;    --| Library specified does not exist
  10499. Library_Already_Exists   : exception;    --| Library specified already exist
  10500. Library_Pending_Return   : exception;    --| Library pending return to catalog
  10501. Library_Master_Locked    : exception;    --| Library is locked by a master lock
  10502. Library_Write_Locked     : exception;    --| Library is locked for update
  10503. Library_Read_Locked      : exception;    --| Library is locked for read
  10504. Not_Authorized           : exception;    --| Non authorized unlocking attempt
  10505. Invalid_Upgrade          : exception;    --| Lock upgrade invalid
  10506. Invalid_Downgrade        : exception;    --| Lock downgrade invalid
  10507.  
  10508. Item_Not_Found           : exception;    --| Item does not exist
  10509. Item_Already_Exists      : exception;    --| Item is already in the library
  10510. Item_Checked_Out         : exception;    --| Item is currently checked out
  10511. Item_Not_Checked_Out     : exception;    --| Item is not checked out
  10512. Item_Not_Created         : exception;    --| Item is not created on return
  10513.  
  10514. Invalid_Version          : exception;    --| Invalid version specification
  10515. Version_Not_Found        : exception;    --| Version of item does not exist 
  10516.  
  10517. Invalid_Keyword          : exception;    --| Invalid property keyword specified
  10518. Invalid_Value            : exception;    --| Invalid value for keyword specified
  10519. Keyword_Already_Exists   : exception;    --| Keyword-value pair already exists
  10520. Keyword_Not_Found        : exception;    --| Keyword not associated with item
  10521.  
  10522. Invalid_Directory_Name   : exception;    --| Directory name not valid for system
  10523. Directory_Already_Exists : exception;    --| Directory specified already exist
  10524.  
  10525. File_Not_Found           : exception;    --| File is not found
  10526. File_Not_Created         : exception;    --| File is not created on fetch
  10527. Set_Protection_Error     : exception;    --| Error while setting file protection
  10528.  
  10529. Invalid_External_Name    : exception;    --| Specified external name invalid
  10530. Invalid_Operation        : exception;    --| Specified operation cannot be performed
  10531. No_Privilege             : exception;    --| No privilege for attempted operation
  10532. Process_Interrupted      : exception;    --| Process is terminated by interrupt
  10533.  
  10534. Internal_Error           : exception;    --| Library manager internal error
  10535.  
  10536.  
  10537. --------------------------------------------------------------------------------
  10538. --                        Packages and Procedures                             --
  10539. --------------------------------------------------------------------------------
  10540.  
  10541. package SP renames String_Pkg;
  10542.  
  10543. package SL renames String_Lists;
  10544.  
  10545. package LL is new Lists(SL.List, SL.Equal);
  10546.  
  10547. procedure Destroy_String_List is new
  10548.             SL.DestroyDeep(Dispose => SP.Flush);
  10549.  
  10550. procedure Destroy_List_Of_Lists is new
  10551.             LL.DestroyDeep(Dispose => Destroy_String_List);
  10552.  
  10553.  
  10554. --------------------------------------------------------------------------------
  10555. --                               Types                                        --
  10556. --------------------------------------------------------------------------------
  10557.  
  10558. type    Copy_Mode      is (CURRENT, FULL);
  10559.                     --| Library copy mode
  10560. type    Fetch_Type     is (NO_UPDATE, UPDATE, BRANCH);
  10561.                     --| Check out/Return mode
  10562. subtype State_Type is Fetch_Type range NO_UPDATE .. UPDATE;
  10563.                     --| Item state type
  10564. type    List_Mode      is (LONG, SHORT);
  10565.                     --| List items in full/terse form
  10566. type    Lock_Type      is (READ_LOCK, WRITE_LOCK, MASTER_LOCK);
  10567.                     --| Types of lock
  10568. type    Edit_Mode      is (ADD, DELETE, MODIFY, LIST);
  10569.                     --| Edit mode
  10570. type    Operation_Type is (CREATE_ITEM, RETURN_ITEM, CANCEL_ITEM);
  10571.                     --| Check-in operation type
  10572. type    Privilege_Type is (OWNER, GROUP, WORLD);
  10573.  
  10574.  
  10575. --------------------------------------------------------------------------------
  10576. --                               Values                                       --
  10577. --------------------------------------------------------------------------------
  10578.  
  10579. Message_on_Completion : BOOLEAN := TRUE;
  10580.  
  10581. Message_on_Error      : BOOLEAN := TRUE;
  10582.  
  10583.  
  10584. --------------------------------------------------------------------------------
  10585. --                             Constants                                      --
  10586. --------------------------------------------------------------------------------
  10587.  
  10588. Separator                 : constant STRING (1 .. 80) := (others => '-');
  10589.  
  10590. Maximum_Library_Name      : constant INTEGER          := 20;
  10591.  
  10592. Maximum_Owner_Name        : constant INTEGER          := 12;
  10593.  
  10594. Maximum_Group_Name        : constant INTEGER          := 12;
  10595.  
  10596. Maximum_CI_Name           : constant INTEGER          := 20;
  10597.  
  10598. Maximum_Item_Name         : constant INTEGER          := 28;
  10599.  
  10600. Maximum_Line_Size         : constant INTEGER          := 80;
  10601.  
  10602. Maximum_Keyword           : constant INTEGER          := 36;
  10603.  
  10604. Retry_Count               : constant INTEGER          :=  1;
  10605.  
  10606. Delay_Interval            : constant DURATION         := 10.00;
  10607.  
  10608. Delete_Library_Privilege  : constant Privilege_Type   := OWNER;
  10609.  
  10610. Delete_Item_Privilege     : constant Privilege_Type   := OWNER;
  10611.  
  10612. Purge_Item_Privilege      : constant Privilege_Type   := OWNER;
  10613.  
  10614. Rename_Item_Privilege     : constant Privilege_Type   := OWNER;
  10615.  
  10616. Rename_Version_Privilege  : constant Privilege_Type   := OWNER;
  10617.  
  10618. Add_Property_Privilege    : constant Privilege_Type   := OWNER;
  10619.  
  10620. Delete_Property_Privilege : constant Privilege_Type   := OWNER;
  10621.  
  10622. Modify_Property_Privilege : constant Privilege_Type   := OWNER;
  10623.  
  10624. end Library_Declarations;
  10625.                                                                     pragma page;
  10626. ::::::::::::::
  10627. libmgr.spc
  10628. ::::::::::::::
  10629. with String_Pkg;
  10630. with Host_Lib;
  10631.  
  10632. function Library_Manager_Interface(        --| Interactive library manager
  10633.     Library : in String_Pkg.String_Type;    --| Item library to be created
  10634.     Prompt  : in String_Pkg.String_Type        --| Prompt
  10635.     ) return Host_Lib.Severity_Code;
  10636.  
  10637. --| Requires:
  10638. --| Name of the library
  10639.  
  10640. --| Effects:
  10641. --| Enter an interactive library manager for a given library
  10642.  
  10643. --| N/A: Modifies, Raises, Errors
  10644.                                                                     pragma page;
  10645. ::::::::::::::
  10646. libutl.bdy
  10647. ::::::::::::::
  10648. with String_Utilities;
  10649. with HIF_Attributes;
  10650. with HIF_List_Utils;
  10651. with Host_Lib;
  10652. with File_Manager;
  10653. with Document_Manager_Declarations;
  10654. with HIF_Utils;
  10655. with HIF_System_Management;
  10656.  
  10657. package body Library_Utilities is
  10658.  
  10659.     package SU  renames String_Utilities;
  10660.     package SS  is new SU.Generic_String_Utilities(
  10661.             SP.String_Type,
  10662.             SP.Make_Persistent,
  10663.             SP.Value);
  10664.     package FM  renames File_Manager;
  10665.     package DMD renames Document_Manager_Declarations;
  10666.     package HA  renames HIF_Attributes;
  10667.     package HLU renames HIF_List_Utils;
  10668.     package HL  renames Host_Lib;
  10669.     package HU  renames HIF_Utils;
  10670.     package HSM renames HIF_System_Management;
  10671.  
  10672.     subtype Valid_Character      is CHARACTER range ' ' .. '~';
  10673.     subtype Digit                is CHARACTER range '0' .. '9';
  10674.     subtype Lower_Alphabet       is CHARACTER range 'a' .. 'z';
  10675.     subtype Upper_Alphabet       is CHARACTER range 'A' .. 'Z';
  10676.     
  10677.     Substitute_Character    : constant CHARACTER := 'Z';
  10678.  
  10679.     Privilege_Reason        : constant STRING    := "PRIVILEGE";
  10680.     Version_Exists_Reason   : constant STRING    := "NAME_CONFLICT";
  10681.     Item_Checked_Out_Reason : constant STRING    := "CHECKED_OUT";
  10682.     Regression_Reason       : constant STRING    := "REGRESSION";
  10683.  
  10684. --------------------------------------------------------------------------------
  10685.  
  10686.     function Internal_Name(
  10687.     External_Name : in SP.String_Type;
  10688.     Exclude       : in STRING := ""
  10689.     ) return STRING is
  10690.  
  10691.     Translate           : BOOLEAN;
  10692.     Internal_Name       : STRING(1 .. 256) := (others => ' ');
  10693.     Internal_Name_Index : INTEGER := 1;
  10694.     External_Character  : Valid_Character;
  10695.  
  10696.     begin
  10697.  
  10698.     for i in 1 .. SP.Length(External_Name) loop
  10699.         begin
  10700.         External_Character := SP.Fetch(External_Name, i);
  10701.         exception
  10702.         when CONSTRAINT_ERROR =>
  10703.             raise Invalid_External_Name;
  10704.         end;
  10705.  
  10706.         Translate := TRUE;
  10707.  
  10708.         begin
  10709.         External_Character := Digit'(External_Character);
  10710.         Translate := FALSE;
  10711.         if i = 1 then
  10712.             Internal_Name(1 .. 3) := Substitute_Character & "00";
  10713.             Internal_Name_Index := 4;
  10714.         end if;
  10715.         exception
  10716.         when CONSTRAINT_ERROR => null;
  10717.         end;
  10718.  
  10719.         if Translate then
  10720.         begin
  10721.             External_Character := Lower_Alphabet'(External_Character);
  10722.             Translate := FALSE;
  10723.         exception
  10724.             when CONSTRAINT_ERROR => null;
  10725.         end;
  10726.         end if;
  10727.  
  10728.         if Translate then
  10729.         begin
  10730.             External_Character := Upper_Alphabet'(External_Character);
  10731.             Translate := FALSE;
  10732.         exception
  10733.             when CONSTRAINT_ERROR => null;
  10734.         end;
  10735.         end if;
  10736.  
  10737.         if Translate then
  10738.         for k in Exclude'range loop
  10739.             if External_Character = Exclude(k) then
  10740.             Translate := FALSE;
  10741.             exit;
  10742.             end if;
  10743.         end loop;
  10744.         end if;
  10745.  
  10746.         if Translate then
  10747.         Internal_Name(Internal_Name_Index .. Internal_Name_Index+2) := 
  10748.             Substitute_Character &
  10749.             SU.Image(
  10750.             CHARACTER'pos(External_Character) - CHARACTER'pos(Valid_Character'first) + 1,
  10751.             2,
  10752.             '0');
  10753.         Internal_Name_Index := Internal_Name_Index + 3;
  10754.         else
  10755.         Internal_Name(Internal_Name_Index) := External_Character;
  10756.         Internal_Name_Index := Internal_Name_Index + 1;
  10757.         end if;
  10758.     end loop;
  10759.     return Internal_Name(1 .. Internal_Name_Index-1);
  10760.  
  10761.     end Internal_Name;
  10762.  
  10763. --------------------------------------------------------------------------------
  10764.  
  10765.     function External_Name(
  10766.     Internal_Name : in STRING
  10767.     ) return STRING is
  10768.  
  10769.     External_Name       : STRING(1 .. 256) := (others => ' ');
  10770.     External_Name_Index : INTEGER := 1;
  10771.     Internal_Name_Index : INTEGER := Internal_Name'first;
  10772.  
  10773.     begin
  10774.  
  10775.     while Internal_Name_Index <= Internal_Name'last loop
  10776.         if Internal_Name(Internal_Name_Index) = Substitute_Character then
  10777.         begin
  10778.             if NATURAL'value(Internal_Name(Internal_Name_Index+1 .. Internal_Name_Index+2)) /= 0 then
  10779.             External_Name(External_Name_Index) :=
  10780.                 Valid_Character'val(
  10781.                 NATURAL'value(
  10782.                     Internal_Name(Internal_Name_Index+1 .. Internal_Name_Index+2)) +
  10783.                     CHARACTER'pos(Valid_Character'first) -
  10784.                     1);
  10785.             External_Name_Index := External_Name_Index + 1;
  10786.             end if;
  10787.             Internal_Name_Index := Internal_Name_Index + 2;
  10788.         exception
  10789.             when CONSTRAINT_ERROR =>
  10790.             External_Name(External_Name_Index) := Substitute_Character;
  10791.             External_Name_Index := External_Name_Index + 1;
  10792.         end;
  10793.         else
  10794.         External_Name(External_Name_Index) :=
  10795.             Internal_Name(Internal_Name_Index);
  10796.         External_Name_Index := External_Name_Index + 1;
  10797.         end if;
  10798.         Internal_Name_Index := Internal_Name_Index + 1;
  10799.     end loop;
  10800.     return External_Name(1 .. External_Name_Index-1);
  10801.  
  10802.     end External_Name;
  10803.  
  10804. --------------------------------------------------------------------------------
  10805.  
  10806.     procedure Is_Node(
  10807.     Node : in out HND.Node_Type;
  10808.     Name : in     SP.String_Type
  10809.     ) is
  10810.  
  10811.  
  10812.     begin
  10813.  
  10814.     if HNM.Is_Open(Node) then
  10815.         HNM.Close_Node_Handle(Node);
  10816.     end if;
  10817.     HNM.Open_Node_Handle(Node => Node,
  10818.                  Name => SP.Value(Name));
  10819.  
  10820.     exception
  10821.     when others =>
  10822.         HNM.Close_Node_Handle(Node);
  10823.  
  10824.     end Is_Node;
  10825.  
  10826. --------------------------------------------------------------------------------
  10827.  
  10828.     function Node_Name(
  10829.     Library : in SP.String_Type;
  10830.     Item    : in SP.String_Type := SP.Create("");
  10831.     Version : in STRING := ""
  10832.     ) return SP.String_Type is
  10833.  
  10834.     begin
  10835.  
  10836.     if SP.Equal(Item, "") then
  10837.         return SP.Create("'USER(" &
  10838.                  Internal_Name(Library) &
  10839.                  ')');
  10840.     elsif SP.Equal(Item, "*") then
  10841.         return SP.Create("'USER(" &
  10842.                  Internal_Name(Library) &
  10843.                  ").IL");
  10844.     elsif Version = "" then
  10845.         return SP.Create("'USER(" &
  10846.                  Internal_Name(Library) &
  10847.                  ").IL." &
  10848.                  Internal_Name(Item));
  10849.     else
  10850.         return SP.Create("'USER(" &
  10851.                  Internal_Name(Library) &
  10852.                  ").IL." &
  10853.                  Internal_Name(Item) &
  10854.                  ".V" & Version);
  10855.     end if;
  10856.  
  10857.     end Node_Name;
  10858.  
  10859. --------------------------------------------------------------------------------
  10860.  
  10861.     procedure Parse_Node(
  10862.     Node    : in     HND.Node_Type;
  10863.     Library :    out SP.String_Type;
  10864.     Item    :    out SP.String_Type;
  10865.     Version :    out SP.String_Type
  10866.     ) is
  10867.  
  10868.     Scanner : SU.Scanner;
  10869.     Temp    : SP.String_Type;
  10870.     Found   : BOOLEAN;
  10871.  
  10872.     begin
  10873.  
  10874.     Scanner := SS.Make_Scanner(SP.Upper(HNM.Primary_Name(Node)));
  10875.  
  10876.     SS.Scan_Literal("'USER", Scanner, Found);
  10877.     if not Found then
  10878.         SU.Destroy_Scanner(Scanner);
  10879.         return;
  10880.     end if;
  10881.     SS.Scan_Enclosed('(', ')', Scanner, Found, Temp);
  10882.     if not Found then
  10883.         SU.Destroy_Scanner(Scanner);
  10884.         return;
  10885.     end if;
  10886.     Library := SP.Make_Persistent(External_Name(SP.Value(Temp)));
  10887.     SP.Flush(Temp);
  10888.  
  10889.     SU.Backward(Scanner);
  10890.     SS.Scan_Not_Literal("'DOT(IL)", Scanner, Found, Temp);
  10891.     if not Found then
  10892.         SS.Scan_Not_Literal("'DOT(CI)", Scanner, Found, Temp);
  10893.         if not Found then
  10894.         SU.Destroy_Scanner(Scanner);
  10895.         return;
  10896.         else
  10897.         SS.Scan_Literal("'DOT(CI)", Scanner, Found);
  10898.         end if;
  10899.     else
  10900.         SS.Scan_Literal("'DOT(IL)", Scanner, Found);
  10901.     end if;
  10902.     SP.Flush(Temp);
  10903.  
  10904.     SS.Scan_Not_Literal("(", Scanner, Found, Temp);
  10905.     if not Found then
  10906.         SU.Destroy_Scanner(Scanner);
  10907.         return;
  10908.     end if;
  10909.     SP.Flush(Temp);
  10910.     SS.Scan_Enclosed('(', ')', Scanner, Found, Temp);
  10911.     if not Found then
  10912.         SU.Destroy_Scanner(Scanner);
  10913.         return;
  10914.     end if;
  10915.     Item := SP.Make_Persistent(External_Name(SP.Value(Temp)));
  10916.     SP.Flush(Temp);
  10917.  
  10918.     SS.Scan_Not_Literal("(", Scanner, Found, Temp);
  10919.     if not Found then
  10920.         SU.Destroy_Scanner(Scanner);
  10921.         return;
  10922.     end if;
  10923.     SP.Flush(Temp);
  10924.     SS.Scan_Enclosed('(', ')', Scanner, Found, Temp);
  10925.     if not Found then
  10926.         SU.Destroy_Scanner(Scanner);
  10927.         return;
  10928.     end if;
  10929.     Version := SP.Make_Persistent(SP.Substr(Temp, 2, SP.Length(Temp)-1));
  10930.     SP.Flush(Temp);
  10931.     SU.Destroy_Scanner(Scanner);
  10932.  
  10933.     end Parse_Node;
  10934.  
  10935. --------------------------------------------------------------------------------
  10936.  
  10937.     function Is_Ada_Id(
  10938.     Value : in SP.String_Type
  10939.     ) return BOOLEAN is
  10940.  
  10941.     Scanner : SU.Scanner;
  10942.     Ada_Id  : SP.String_Type;
  10943.     Found   : BOOLEAN;
  10944.  
  10945.     begin
  10946.  
  10947.     Scanner := SS.Make_Scanner(Value);
  10948.     SS.Scan_Ada_Id(Scanner, Found, Ada_Id, Skip => FALSE);
  10949.     SP.Flush(Ada_Id);
  10950.     Found := Found and not SU.More(Scanner);
  10951.     SU.Destroy_Scanner(Scanner);
  10952.     return Found;
  10953.  
  10954.     end Is_Ada_Id;
  10955.  
  10956. --------------------------------------------------------------------------------
  10957.  
  10958.     procedure Is_Library(
  10959.     Node    : in out HND.Node_Type;
  10960.     Library : in     SP.String_Type
  10961.     ) is
  10962.  
  10963.     Owner_Value  : STRING(1 .. Maximum_Owner_Name);
  10964.     Owner_Length : INTEGER;
  10965.  
  10966.  
  10967.     begin
  10968.  
  10969.     if not Is_Ada_Id(Library) then
  10970.         raise Invalid_Library_Name;
  10971.     end if;
  10972.     Is_Node(Node, Node_Name(Library));
  10973.     if not HNM.Is_Open(Node) then
  10974.         return;
  10975.     end if;
  10976.     HU.Get_Node_Attribute(Node       => Node,
  10977.                   Attrib     => "OWNER",
  10978.                   Value      => Owner_Value,
  10979.                   Value_Last => Owner_Length);
  10980.     if Owner_Length = 0 then
  10981.         HNM.Close_Node_Handle(Node);
  10982.     end if;
  10983.  
  10984.     end Is_Library;
  10985.  
  10986. --------------------------------------------------------------------------------
  10987.  
  10988.     procedure Is_Item(
  10989.     Node    : in out HND.Node_Type;
  10990.     Library : in     SP.String_Type;
  10991.     Item    : in     SP.String_Type
  10992.     ) is
  10993.  
  10994.     begin
  10995.  
  10996.     Is_Library(Node, Library);
  10997.     if not HNM.Is_Open(Node) then
  10998.         raise Library_Does_Not_Exist;
  10999.     end if;
  11000.     Is_Node(Node, Node_Name(Library, Item));
  11001.  
  11002.     end Is_Item;
  11003.  
  11004. --------------------------------------------------------------------------------
  11005.  
  11006.     procedure Is_Version(
  11007.     Node    : in out HND.Node_Type;
  11008.     Library : in     SP.String_Type;
  11009.     Item    : in     SP.String_Type;
  11010.     Version : in     SP.String_Type
  11011.     ) is
  11012.  
  11013.     Found     : BOOLEAN;
  11014.     Versions  : SL.List := SL.Create;
  11015.  
  11016.     begin
  11017.  
  11018.     Is_Node(Node, Node_Name(Library, Item));
  11019.     if not HNM.Is_Open(Node) then
  11020.         raise Item_Not_Found;
  11021.     end if;
  11022.     Versions := Get_Version(Node, Version);
  11023.     if SL.Length(Versions) = 1 then
  11024.         Is_Node(Node,
  11025.             Node_Name(Library,
  11026.                   Item,
  11027.                   SP.Value(SL.FirstValue(Versions))));
  11028.     else
  11029.         HNM.Close_Node_Handle(Node);
  11030.     end if;
  11031.     Destroy_String_List(Versions);
  11032.  
  11033.     end Is_Version;
  11034.  
  11035. --------------------------------------------------------------------------------
  11036.  
  11037.     function Is_Checked_Out(
  11038.     Item_Node : in HND.Node_Type
  11039.     ) return BOOLEAN is
  11040.  
  11041.     begin
  11042.  
  11043.     return Checked_Out_By(Item_Node) /= "";
  11044.  
  11045.     end Is_Checked_Out;
  11046.  
  11047. --------------------------------------------------------------------------------
  11048.  
  11049.     function Checked_Out_By(
  11050.     Item_Node : in HND.Node_Type
  11051.     ) return STRING is
  11052.  
  11053.     Attribute_Value  : STRING(1 .. 16);
  11054.     Attribute_Length : INTEGER;
  11055.  
  11056.     begin
  11057.  
  11058.     HU.Get_Node_Attribute(Node       => Item_Node,
  11059.                   Attrib     => "CHECKED_OUT",
  11060.                   Value      => Attribute_Value,
  11061.                   Value_Last => Attribute_Length);
  11062.     return Attribute_Value(1 .. Attribute_Length);
  11063.  
  11064.     end Checked_Out_By;
  11065.  
  11066. --------------------------------------------------------------------------------
  11067.  
  11068.     procedure Wait is
  11069.  
  11070.     begin
  11071.                 -- Place waiting algorithm here
  11072.     null;            -- (use constant Delay_Interval in
  11073.                 --  Library_Declarations)
  11074.     end Wait;
  11075.  
  11076. --------------------------------------------------------------------------------
  11077.  
  11078.     procedure Check_Master_Lock(
  11079.     Node : in HND.Node_Type
  11080.     ) is
  11081.  
  11082.     begin
  11083.  
  11084.     begin
  11085.         HNM.Link(To_Node  => Node,
  11086.              New_Base => Node,
  11087.              Relation => Lock_Type'image(MASTER_LOCK));
  11088.     exception
  11089.         when others =>
  11090.         raise Library_Master_Locked;
  11091.     end;
  11092.  
  11093.     begin
  11094.         HNM.Unlink(Base     => Node,
  11095.                Relation => Lock_Type'image(MASTER_LOCK));
  11096.     exception
  11097.         when others =>
  11098.         null;
  11099.     end;
  11100.  
  11101.     end Check_Master_Lock;
  11102.  
  11103. --------------------------------------------------------------------------------
  11104.  
  11105.     function Lock_Library(
  11106.     Node : in HND.Node_Type;
  11107.     Lock : in Lock_Type
  11108.     ) return BOOLEAN is
  11109.  
  11110.     Was_Locked : BOOLEAN;
  11111.     Iterator   : HNM.Node_Iterator;
  11112.  
  11113.     begin
  11114.  
  11115.     if Lock = MASTER_LOCK then
  11116.         begin
  11117.         HNM.Link(To_Node  => Node,
  11118.              New_Base => Node,
  11119.              Relation => Lock_Type'image(Lock));
  11120.         exception
  11121.         when others =>
  11122.             raise Library_Master_Locked;
  11123.         end;
  11124.         Set_Lock_Attributes(Node, Lock, "");
  11125.         return TRUE;
  11126.     end if;
  11127.  
  11128.     Check_Master_Lock(Node);
  11129.  
  11130.     Was_Locked := TRUE;
  11131.     for i in 1 .. Retry_Count loop
  11132.         begin
  11133.         HNM.Link(To_Node  => Node,
  11134.              New_Base => Node,
  11135.              Relation => Lock_Type'image(WRITE_LOCK));
  11136.         Was_Locked := FALSE;
  11137.         exit;
  11138.         exception
  11139.         when others =>
  11140.             Wait;
  11141.         end;
  11142.     end loop;
  11143.  
  11144.     if Was_Locked then
  11145.         return FALSE;
  11146.     end if;
  11147.  
  11148.     if Lock = WRITE_LOCK then
  11149.         HNM.Iterate(Iterator     => Iterator, 
  11150.             Node         => Node,
  11151.             Relation     => Lock_Type'image(READ_LOCK),
  11152.             Primary_Only => FALSE);
  11153.         if HNM.More(Iterator) then
  11154.         begin
  11155.             HNM.Unlink(Base     => Node,
  11156.                    Relation => Lock_Type'image(Lock));
  11157.         exception
  11158.             when others =>
  11159.             null;
  11160.         end;
  11161.         return FALSE;
  11162.         end if;
  11163.         Set_Lock_Attributes(Node, Lock, "");
  11164.         return TRUE;
  11165.     end if;
  11166.  
  11167.     Was_Locked := TRUE;
  11168.     for i in 1 .. Retry_Count loop
  11169.         begin
  11170.         HNM.Link(To_Node  => Node,
  11171.              New_Base => Node,
  11172.              Relation => Lock_Type'image(Lock),
  11173.              Key      => HL.Get_Item(HL.USER_NAME));
  11174.         Was_Locked := FALSE;
  11175.         exit;
  11176.         exception
  11177.         when others =>
  11178.             Wait;
  11179.         end;
  11180.     end loop;
  11181.  
  11182.     begin
  11183.         HNM.Unlink(Base     => Node,
  11184.                Relation => Lock_Type'image(WRITE_LOCK));
  11185.     exception
  11186.         when others =>
  11187.         null;
  11188.     end;
  11189.  
  11190.     if Was_Locked then
  11191.         return FALSE;
  11192.     end if;
  11193.     Set_Lock_Attributes(Node, Lock, HL.Get_Item(HL.USER_NAME));
  11194.  
  11195.     return TRUE;
  11196.  
  11197.     end Lock_Library;
  11198.  
  11199. --------------------------------------------------------------------------------
  11200.  
  11201.     function Lock_Library(
  11202.     Library : in SP.String_Type;
  11203.     Lock    : in Lock_Type
  11204.     ) return BOOLEAN is
  11205.  
  11206.     Node   : HND.Node_Type;
  11207.     Locked : BOOLEAN;
  11208.  
  11209.     begin
  11210.  
  11211.     Is_Library(Node, Library);
  11212.     if not HNM.Is_Open(Node) then
  11213.         raise Library_Does_Not_Exist;
  11214.     end if;
  11215.     Locked := Lock_Library(Node, Lock);
  11216.     HNM.Close_Node_Handle(Node);
  11217.     return Locked;
  11218.  
  11219.     end Lock_Library;
  11220.  
  11221. --------------------------------------------------------------------------------
  11222.  
  11223.     procedure Unlock_Library(
  11224.     Node  : in HND.Node_Type;
  11225.     Lock  : in Lock_Type
  11226.     ) is
  11227.  
  11228.     Owner : SP.String_Type;
  11229.     Group : SP.String_Type;
  11230.     Date  : SP.String_Type;
  11231.     Time  : SP.String_Type;
  11232.  
  11233.     begin
  11234.  
  11235.     if Lock = MASTER_LOCK then
  11236.         begin
  11237.         Get_Lock_Attributes(Node, Lock, "", Owner, Group, Date, Time);
  11238.         if SP.Value(Owner) /= HL.Get_Item(HL.USER_NAME) then 
  11239.             raise Not_Authorized; 
  11240.         else
  11241.             begin
  11242.             HNM.Unlink(Base     => Node,
  11243.                    Relation => Lock_Type'image(Lock));
  11244.             exception
  11245.             when others =>
  11246.                 null;
  11247.             end;
  11248.             return;
  11249.         end if;
  11250.         exception
  11251.         when others =>
  11252.             return;
  11253.         end;
  11254.     end if;
  11255.  
  11256.     if Lock = WRITE_LOCK then
  11257.         begin
  11258.         Get_Lock_Attributes(Node, Lock, "", Owner, Group, Date, Time);
  11259.         if SP.Value(Owner) /= HL.Get_Item(HL.USER_NAME) then 
  11260.             raise Not_Authorized; 
  11261.         else
  11262.             begin
  11263.             HNM.Unlink(Base     => Node,
  11264.                    Relation => Lock_Type'image(Lock));
  11265.             exception
  11266.             when others =>
  11267.                 null;
  11268.             end;
  11269.             return;
  11270.         end if;
  11271.         exception
  11272.         when others =>
  11273.             return;
  11274.         end;
  11275.     end if;
  11276.  
  11277.     begin
  11278.         HNM.Unlink(Base     => Node,
  11279.                Relation => Lock_Type'image(Lock),
  11280.                Key      => HL.Get_Item(HL.USER_NAME));
  11281.     exception
  11282.         when others =>
  11283.         null;
  11284.     end;
  11285.  
  11286.     end Unlock_Library;
  11287.  
  11288. --------------------------------------------------------------------------------
  11289.  
  11290.     procedure Unlock_Library(
  11291.     Library : in SP.String_Type;
  11292.     Lock    : in Lock_Type
  11293.     ) is
  11294.  
  11295.     Node  : HND.Node_Type;
  11296.     Owner : SP.String_Type;
  11297.     Date  : SP.String_Type;
  11298.     Time  : SP.String_Type;
  11299.  
  11300.     begin
  11301.  
  11302.     Is_Library(Node, Library);
  11303.     if not HNM.Is_Open(Node) then
  11304.         raise Library_Does_Not_Exist;
  11305.     end if;
  11306.     Unlock_Library(Node, Lock);
  11307.     HNM.Close_Node_Handle(Node);
  11308.  
  11309.     end Unlock_Library;
  11310.  
  11311. --------------------------------------------------------------------------------
  11312.  
  11313.     function Upgrade_Lock(
  11314.     Node  : in HND.Node_Type
  11315.     ) return BOOLEAN is
  11316.  
  11317.     Was_Locked : BOOLEAN;
  11318.     Iterator   : HNM.Node_Iterator;
  11319.     Temp_Node  : HND.Node_Type;
  11320.  
  11321.     begin
  11322.  
  11323.     Check_Master_Lock(Node);
  11324.     begin
  11325.         HNM.Link(To_Node  => Node,
  11326.              New_Base => Node,
  11327.              Relation => Lock_Type'image(READ_LOCK),
  11328.              Key      => HL.Get_Item(HL.USER_NAME));
  11329.         Was_Locked := FALSE;
  11330.     exception
  11331.         when others =>
  11332.         Was_Locked := TRUE;
  11333.     end;
  11334.  
  11335.     if not Was_Locked then
  11336.         begin
  11337.         HNM.Unlink(Base     => Node,
  11338.                Relation => Lock_Type'image(READ_LOCK),
  11339.                Key      => HL.Get_Item(HL.USER_NAME));
  11340.         exception
  11341.         when others =>
  11342.             null;
  11343.         end;
  11344.         raise Invalid_Upgrade;
  11345.     end if;
  11346.         
  11347.     Check_Master_Lock(Node);
  11348.     begin
  11349.         HNM.Link(To_Node  => Node,
  11350.              New_Base => Node,
  11351.              Relation => Lock_Type'image(WRITE_LOCK));
  11352.     exception
  11353.         when others =>
  11354.         raise Internal_Error;
  11355.     end;
  11356.  
  11357.     HNM.Iterate(Iterator     => Iterator, 
  11358.             Node         => Node,
  11359.             Relation     => Lock_Type'image(READ_LOCK),
  11360.             Primary_Only => FALSE);
  11361.     while HNM.More(Iterator) loop
  11362.         HNM.Get_Next(Iterator, Temp_Node);
  11363.         if HNM.Path_Key(Temp_Node) /= HL.Get_Item(HL.USER_NAME) then
  11364.         begin
  11365.             HNM.Unlink(Base     => Node,
  11366.                    Relation => Lock_Type'image(WRITE_LOCK));
  11367.         exception
  11368.             when others =>
  11369.             null;
  11370.         end;
  11371.         return FALSE;
  11372.         end if;
  11373.         HNM.Close_Node_Handle(Temp_Node);
  11374.     end loop;
  11375.  
  11376.     Set_Lock_Attributes(Node, WRITE_LOCK, "");
  11377.  
  11378.     begin
  11379.         HNM.Unlink(Base     => Node,
  11380.                Relation => Lock_Type'image(READ_LOCK),
  11381.                Key      => HL.Get_Item(HL.USER_NAME));
  11382.     exception
  11383.         when others =>
  11384.         null;
  11385.     end;
  11386.     return TRUE;
  11387.  
  11388.     end Upgrade_Lock;
  11389.  
  11390. --------------------------------------------------------------------------------
  11391.  
  11392.     function Upgrade_Lock(
  11393.     Library : in SP.String_Type
  11394.     ) return BOOLEAN is
  11395.  
  11396.     Node   : HND.Node_Type;
  11397.     Locked : BOOLEAN;
  11398.  
  11399.     begin
  11400.  
  11401.     Is_Library(Node, Library);
  11402.     if not HNM.Is_Open(Node) then
  11403.         raise Invalid_Library_Name;
  11404.     end if;
  11405.     Locked := Upgrade_Lock(Node);
  11406.     HNM.Close_Node_Handle(Node);
  11407.     return Locked;
  11408.  
  11409.     end Upgrade_Lock;
  11410.  
  11411. --------------------------------------------------------------------------------
  11412.  
  11413.     procedure Downgrade_Lock(
  11414.     Node  : in HND.Node_Type
  11415.     ) is
  11416.  
  11417.     Was_Locked : BOOLEAN;
  11418.     Owner      : SP.String_Type;
  11419.     Group      : SP.String_Type;
  11420.     Date       : SP.String_Type;
  11421.     Time       : SP.String_Type;
  11422.  
  11423.     begin
  11424.  
  11425.     Check_Master_Lock(Node);
  11426.     begin
  11427.         HNM.Link(To_Node  => Node,
  11428.              New_Base => Node,
  11429.              Relation => Lock_Type'image(WRITE_LOCK));
  11430.         Was_Locked := FALSE;
  11431.     exception
  11432.         when others =>
  11433.         Was_Locked := TRUE;
  11434.     end;
  11435.  
  11436.     if Was_Locked then
  11437.         Get_Lock_Attributes(Node, WRITE_LOCK, "", Owner, Group, Date, Time);
  11438.         if SP.Value(Owner) /= HL.Get_Item(HL.USER_NAME) then 
  11439.         raise Invalid_Downgrade;
  11440.         end if;
  11441.     end if;
  11442.  
  11443.     if not Was_Locked then
  11444.         begin
  11445.         HNM.Unlink(Base     => Node,
  11446.                Relation => Lock_Type'image(WRITE_LOCK));
  11447.         exception
  11448.         when others =>
  11449.             null;
  11450.         end;
  11451.         raise Invalid_Downgrade;
  11452.     end if;
  11453.         
  11454.     Check_Master_Lock(Node);
  11455.     begin
  11456.         HNM.Link(To_Node  => Node,
  11457.              New_Base => Node,
  11458.              Relation => Lock_Type'image(READ_LOCK),
  11459.              Key      => HL.Get_Item(HL.USER_NAME));
  11460.         Set_Lock_Attributes(Node, READ_LOCK, "");
  11461.     exception
  11462.         when others =>
  11463.         raise Internal_Error;
  11464.     end;
  11465.  
  11466.     begin
  11467.         HNM.Unlink(Base     => Node,
  11468.                Relation => Lock_Type'image(WRITE_LOCK));
  11469.     exception
  11470.         when others =>
  11471.         null;
  11472.     end;
  11473.  
  11474.     end Downgrade_Lock;
  11475.  
  11476. --------------------------------------------------------------------------------
  11477.  
  11478.     procedure Downgrade_Lock(
  11479.     Library : in SP.String_Type
  11480.     ) is
  11481.  
  11482.     Node : HND.Node_Type;
  11483.  
  11484.     begin
  11485.  
  11486.     Is_Library(Node, Library);
  11487.     if not HNM.Is_Open(Node) then
  11488.         raise Invalid_Library_Name;
  11489.     end if;
  11490.     Downgrade_Lock(Node);
  11491.     HNM.Close_Node_Handle(Node);
  11492.  
  11493.     end Downgrade_Lock;
  11494.  
  11495. --------------------------------------------------------------------------------
  11496.  
  11497.     function Get_Library_Attribute(
  11498.     Library   : in SP.String_Type;
  11499.     Attribute : in STRING
  11500.     ) return STRING is
  11501.  
  11502.     Library_Node     : HND.Node_Type;
  11503.     Attribute_Value  : STRING(1 .. 64);
  11504.     Attribute_Length : INTEGER;
  11505.  
  11506.     begin
  11507.  
  11508.     Is_Library(Library_Node, Library);
  11509.     if not HNM.Is_Open(Library_Node) then
  11510.         raise Library_Does_Not_Exist;
  11511.     end if;
  11512.     HU.Get_Node_Attribute(Node       => Library_Node,
  11513.                   Attrib     => Attribute,
  11514.                   Value      => Attribute_Value,
  11515.                   Value_Last => Attribute_Length);
  11516.     HNM.Close_Node_Handle(Library_Node);
  11517.     return Attribute_Value(1 .. Attribute_Length);
  11518.  
  11519.     end Get_Library_Attribute;
  11520.  
  11521. --------------------------------------------------------------------------------
  11522.  
  11523.     procedure Set_Library_Attribute(
  11524.     Library   : in SP.String_Type;
  11525.     Attribute : in STRING;
  11526.     Value     : in STRING
  11527.     ) is
  11528.  
  11529.     Library_Node : HND.Node_Type;
  11530.  
  11531.     begin
  11532.  
  11533.     Is_Library(Library_Node, Library);
  11534.     if not HNM.Is_Open(Library_Node) then
  11535.         raise Library_Does_Not_Exist;
  11536.     end if;
  11537.     HA.Set_Node_Attribute(Node   => Library_Node,
  11538.                   Attrib => Attribute,
  11539.                   Value  => Value);
  11540.     HNM.Close_Node_Handle(Library_Node);
  11541.  
  11542.     end Set_Library_Attribute;
  11543.  
  11544. --------------------------------------------------------------------------------
  11545.  
  11546.     procedure Open_Standard_Node_Handle(
  11547.     Node : in out HND.Node_Type;
  11548.     Name : in     SP.String_Type
  11549.     ) is
  11550.  
  11551.     begin
  11552.  
  11553.     if HNM.Is_Open(Node) then
  11554.         HNM.Close_Node_Handle(Node);
  11555.     end if;
  11556.     HNM.Open_Node_Handle(Node => Node,
  11557.                  Name => SP.Value(Name));
  11558.     Set_Standard_Attributes(Node);
  11559.  
  11560.     end Open_Standard_Node_Handle;
  11561.  
  11562. --------------------------------------------------------------------------------
  11563.  
  11564.     procedure Set_Standard_Attributes(
  11565.     Node : in HND.Node_Type
  11566.     ) is
  11567.  
  11568.     Time : HL.Time_Value;
  11569.  
  11570.     begin
  11571.  
  11572.     HA.Set_Node_Attribute(Node   => Node,
  11573.                   Attrib => "OWNER",
  11574.                   Value  => HL.Get_Item(HL.USER_NAME));
  11575.     HA.Set_Node_Attribute(Node   => Node,
  11576.                   Attrib => "GROUP",
  11577.                   Value  => HL.Get_Item(HL.ACCOUNT));
  11578.     HL.Get_Time(Time);
  11579.     HA.Set_Node_Attribute(Node   => Node,
  11580.                   Attrib => "DATE",
  11581.                   Value  => HL.Date(Time));
  11582.     HA.Set_Node_Attribute(Node   => Node,
  11583.                   Attrib => "TIME",
  11584.                   Value  => HL.Time(Time));
  11585.  
  11586.     end Set_Standard_Attributes;
  11587.  
  11588. --------------------------------------------------------------------------------
  11589.  
  11590.     procedure Set_Lock_Attributes(
  11591.     Node  : in HND.Node_Type;
  11592.     Lock  : in Lock_Type;
  11593.     Key   : in STRING
  11594.     ) is
  11595.  
  11596.     Time      : HL.Time_Value;
  11597.     Lock_Node : HND.Node_Type;
  11598.  
  11599.     begin
  11600.  
  11601.     HNM.Open_Node_Handle(Node => Lock_Node,
  11602.                  Base => Node,
  11603.                  Name => ''' & Lock_Type'image(Lock) & '(' & Key & ')');
  11604.     HA.Set_Path_Attribute(Node   => Lock_Node,
  11605.                   Attrib => "OWNER",
  11606.                   Value  => HL.Get_Item(HL.USER_NAME));
  11607.     HA.Set_Path_Attribute(Node   => Lock_Node,
  11608.                   Attrib => "GROUP",
  11609.                   Value  => HL.Get_Item(HL.ACCOUNT));
  11610.     HL.Get_Time(Time);
  11611.     HA.Set_Path_Attribute(Node   => Lock_Node,
  11612.                   Attrib => "DATE",
  11613.                   Value  => HL.Date(Time));
  11614.     HA.Set_Path_Attribute(Node   => Lock_Node,
  11615.                   Attrib => "TIME",
  11616.                   Value  => HL.Time(Time));
  11617.     HNM.Close_Node_Handle(Lock_Node);
  11618.  
  11619.     end Set_Lock_Attributes;
  11620.  
  11621. --------------------------------------------------------------------------------
  11622.  
  11623.     procedure Get_Lock_Attributes(
  11624.     Node       : in     HND.Node_Type;
  11625.     Lock       : in     Lock_Type;
  11626.     Key        : in     STRING;
  11627.     Owner      : in out SP.String_Type;
  11628.     Group      : in out SP.String_Type;
  11629.     Date       : in out SP.String_Type;
  11630.     Time       : in out SP.String_Type
  11631.     ) is
  11632.  
  11633.     Lock_Node        : HND.Node_Type;
  11634.     Attribute_Value  : STRING(1 .. Maximum_Owner_Name);
  11635.     Attribute_Length : INTEGER;
  11636.  
  11637.     begin
  11638.  
  11639.     HNM.Open_Node_Handle(Node => Lock_Node,
  11640.                  Base => Node,
  11641.                  Name => ''' & Lock_Type'image(Lock) & '(' & Key & ')');
  11642.     HU.Get_Path_Attribute(Node       => Lock_Node,
  11643.                   Attrib     => "OWNER",
  11644.                   Value      => Attribute_Value,
  11645.                   Value_Last => Attribute_Length);
  11646.     Owner := SP.Create(Attribute_Value(1 .. Attribute_Length));
  11647.     HU.Get_Path_Attribute(Node       => Lock_Node,
  11648.                   Attrib     => "GROUP",
  11649.                   Value      => Attribute_Value,
  11650.                   Value_Last => Attribute_Length);
  11651.     Group := SP.Create(Attribute_Value(1 .. Attribute_Length));
  11652.     HU.Get_Path_Attribute(Node       => Lock_Node,
  11653.                   Attrib     => "DATE",
  11654.                   Value      => Attribute_Value,
  11655.                   Value_Last => Attribute_Length);
  11656.     Date := SP.Create(Attribute_Value(1 .. Attribute_Length));
  11657.     HU.Get_Path_Attribute(Node       => Lock_Node,
  11658.                   Attrib     => "TIME",
  11659.                   Value      => Attribute_Value,
  11660.                   Value_Last => Attribute_Length);
  11661.     Time := SP.Create(Attribute_Value(1 .. Attribute_Length));
  11662.     HNM.Close_Node_Handle(Lock_Node);
  11663.  
  11664.     end Get_Lock_Attributes;
  11665.  
  11666. --------------------------------------------------------------------------------
  11667.  
  11668.     function Get_Item_Date_Time(
  11669.     Library : in SP.String_Type;
  11670.     Item    : in SP.String_Type;
  11671.     Version : in SP.String_Type
  11672.     ) return STRING is
  11673.  
  11674.     Node      : HND.Node_Type;
  11675.     Date_Attr : STRING(1 .. 8);
  11676.     Date_Len  : INTEGER;
  11677.     Time_Attr : STRING(1 .. 8);
  11678.     Time_Len  : INTEGER;
  11679.  
  11680.     begin
  11681.  
  11682.     Is_Version(Node, Library, Item, Version);
  11683.     if not HNM.Is_Open(Node) then
  11684.         raise Version_Not_Found;
  11685.     end if;
  11686.     HU.Get_Node_Attribute(Node       => Node,
  11687.                   Attrib     => "DATE",
  11688.                   Value      => Date_Attr,
  11689.                   Value_Last => Date_Len);
  11690.     HU.Get_Node_Attribute(Node       => Node,
  11691.                   Attrib     => "TIME",
  11692.                   Value      => Time_Attr,
  11693.                   Value_Last => Time_Len);
  11694.     HNM.Close_Node_Handle(Node);
  11695.     return Date_Attr(1 .. Date_Len) & ' ' & Time_Attr(1 .. Time_Len);
  11696.  
  11697.     end Get_Item_Date_Time;
  11698.  
  11699. --------------------------------------------------------------------------------
  11700.  
  11701.     function Get_Current_Version(
  11702.     Node : in HND.Node_Type
  11703.     ) return STRING is
  11704.  
  11705.     Iterator     : HNM.Node_Iterator;
  11706.     Version_Node : HND.Node_Type;
  11707.     Library      : SP.String_Type;
  11708.     Item         : SP.String_Type;
  11709.     Version      : SP.String_Type;
  11710.  
  11711.     begin
  11712.  
  11713.     HNM.Iterate(Iterator     => Iterator,
  11714.             Node         => Node,
  11715.             Relation     => "DOT",
  11716.             Key          => "V*",
  11717.             Primary_Only => TRUE);
  11718.     if not HNM.More(Iterator) then
  11719.         raise Version_Not_Found;
  11720.     end if;
  11721.     while HNM.More(Iterator) loop
  11722.         HNM.Close_Node_Handle(Version_Node);
  11723.         HNM.Get_Next(Iterator, Version_Node);
  11724.     end loop;
  11725.     Parse_Node(Version_Node, Library, Item, Version);
  11726.     SP.Flush(Library);
  11727.     SP.Flush(Item);
  11728.     declare
  11729.         Version_Number : STRING (1 .. SP.Length(Version)) := SP.Value(Version);
  11730.     begin
  11731.         SP.Flush(Item);
  11732.         return Version_Number;
  11733.     end;
  11734.  
  11735.     end Get_Current_Version;
  11736.  
  11737. --------------------------------------------------------------------------------
  11738.  
  11739.     function Get_Version(
  11740.     Node    : in HND.Node_Type;
  11741.     Version : in SP.String_Type
  11742.     ) return SL.List is
  11743.  
  11744.     Version_Number  : INTEGER := 0;
  11745.     Current_Version : INTEGER;
  11746.     List            : SL.List;
  11747.     Version_Value   : STRING(1 .. 16);
  11748.     Version_Length  : INTEGER;
  11749.     Temp_Node       : HND.Node_Type;
  11750.     Temp_Str        : SP.String_Type;
  11751.  
  11752.     begin
  11753.  
  11754.     if not SP.Equal(Version, "") and then SP.Match_C(Version, '*') = 0 then
  11755.         begin
  11756.         Version_Number := INTEGER'value(SP.Value(Version));
  11757.         exception
  11758.         when others =>
  11759.             raise Invalid_Version;
  11760.         end;
  11761.         if Version_Number > 0 then
  11762.             begin
  11763.             HNM.Open_Node_Handle(Node => Temp_Node,
  11764.                      Base => Node,
  11765.                      Name => ".V" & SU.Image(Version_Number));
  11766.             HNM.Close_Node_Handle(Temp_Node);
  11767.         exception
  11768.             when others =>
  11769.             raise Version_Not_Found;
  11770.         end;
  11771.         return SL.MakeList(SS.Image(Version_Number));
  11772.         end if;
  11773.     end if;
  11774.  
  11775.     HU.Get_Node_Attribute(Node       => Node,
  11776.                   Attrib     => "V",
  11777.                   Value      => Version_Value,
  11778.                   Value_Last => Version_Length);
  11779.     if Version_Value(1 .. Version_Length) = "0" then
  11780.         Current_Version := INTEGER'value(Get_Current_Version(Node));
  11781.         HA.Set_Node_Attribute(Node   => Node,
  11782.                   Attrib => "V",
  11783.                   Value  => SU.Image(Current_Version));
  11784.     else
  11785.         Current_Version := INTEGER'value(Version_Value(1 .. Version_Length));
  11786.     end if;
  11787.     if SP.Match_C(Version, '*') = 0 then
  11788.         Version_Number := Current_Version + Version_Number;
  11789.         if Version_Number <= 0 then
  11790.         raise Version_Not_Found;
  11791.         end if;
  11792.         return SL.MakeList(SS.Image(Version_Number));
  11793.     else
  11794.         List := SL.Create;
  11795.         for i in reverse 1 .. Current_Version loop
  11796.         begin
  11797.             HNM.Open_Node_Handle(Node => Temp_Node,
  11798.                      Base => Node,
  11799.                      Name => ".V" & SU.Image(i));
  11800.             Temp_Str := SS.Image(i);
  11801.             if SS.Match(Version, Temp_Str) then
  11802.             SL.Attach(List, Temp_Str);
  11803.             else
  11804.             SP.Flush(Temp_Str);
  11805.             end if;
  11806.             HNM.Close_Node_Handle(Temp_Node);
  11807.         exception
  11808.             when others =>
  11809.             null;
  11810.         end;
  11811.         end loop;
  11812.         return List;
  11813.     end if;
  11814.  
  11815.     end Get_Version;
  11816.  
  11817. --------------------------------------------------------------------------------
  11818.  
  11819.     procedure Iterate_Item(
  11820.     Library  : in     SP.String_Type;
  11821.     Item     : in     SP.String_Type;
  11822.     Iterator : in out HNM.Node_Iterator
  11823.     ) is
  11824.  
  11825.     Node : HND.Node_Type;
  11826.  
  11827.     begin
  11828.  
  11829.     Is_Library(Node, Library);
  11830.     if not HNM.Is_Open(Node) then
  11831.         raise Library_Does_Not_Exist;
  11832.     end if;
  11833.     HNM.Close_Node_Handle(Node);
  11834.     HNM.Open_Node_Handle(Node => Node,
  11835.                  Name => SP.Value(Node_Name(Library, SP.Create("*"))));
  11836.     begin
  11837.         HNM.Iterate(Iterator     => Iterator,
  11838.             Node         => Node,
  11839.             Relation     => "DOT",
  11840.             Key          => Internal_Name(Item, "*"),
  11841.             Primary_Only => TRUE);
  11842.         HNM.Close_Node_Handle(Node);
  11843.     exception
  11844.         when others =>
  11845.         HNM.Close_Node_Handle(Node);
  11846.         raise Item_Not_Found;
  11847.     end;
  11848.  
  11849.     end Iterate_Item; 
  11850.  
  11851. --------------------------------------------------------------------------------
  11852.  
  11853.     procedure Open_Property_Node(
  11854.     Library : in     SP.String_Type;
  11855.     Keyword : in     SP.String_Type;
  11856.     Value   : in     SP.String_Type;
  11857.     Mode    : in     Edit_Mode;
  11858.     Node    : in out HND.Node_Type
  11859.     ) is
  11860.  
  11861.     Property_List    : HLU.List_Type;
  11862.  
  11863.     begin
  11864.  
  11865.     Is_Library(Node, Library);
  11866.     if not HNM.Is_Open(Node) then
  11867.         raise Library_Does_Not_Exist;
  11868.     end if;
  11869.     HNM.Close_Node_Handle(Node);
  11870.     if Mode /= LIST then
  11871.         if SP.Equal(Keyword, "") or else not Is_Ada_Id(Keyword) then
  11872.         raise Invalid_Keyword;
  11873.         end if;
  11874.     end if;
  11875.     if Mode = ADD or Mode = MODIFY then
  11876.         if SP.Equal(Value, "") or else not Is_Ada_Id(Value) then
  11877.         raise Invalid_Value;
  11878.         end if;
  11879.     end if;
  11880.     HNM.Open_Node_Handle(Node => Node,
  11881.                  Name => SP.Value(Node_Name(Library, SP.Create("*"))));
  11882.     if Mode /= LIST then
  11883.         HA.Get_Node_Attribute(Node       => Node,
  11884.                   Attrib     => SP.Value(Keyword),
  11885.                   Value      => Property_List);
  11886.         if (Mode = DELETE or Mode = MODIFY) and HLU.Empty(Property_List) then
  11887.         HLU.Free_List(Property_List);
  11888.         raise Keyword_Not_Found;
  11889.         end if;
  11890.         if Mode = ADD and not HLU.Empty(Property_List) then
  11891.         HLU.Free_List(Property_List);
  11892.         raise Keyword_Already_Exists;
  11893.         end if;
  11894.         HLU.Free_List(Property_List);
  11895.     end if;
  11896.  
  11897.     end Open_Property_Node;
  11898.  
  11899. --------------------------------------------------------------------------------
  11900.  
  11901.     procedure Delete(
  11902.     Item_Node : in out HND.Node_Type;
  11903.     Versions  : in     SL.List;
  11904.     Privilege : in     Privilege_Type;
  11905.     Remainder : in out LL.List
  11906.     ) is
  11907.  
  11908.     Version_Iterator : SL.ListIter;
  11909.     Version_Number   : SP.String_Type;
  11910.     Version_Node     : HND.Node_Type;
  11911.     All_Version      : SL.List;
  11912.     Library          : SP.String_Type;
  11913.     Item             : SP.String_Type;
  11914.     Version          : SP.String_Type;
  11915.     Remainder_List   : SL.List;
  11916.     Delete           : BOOLEAN := FALSE; 
  11917.     Current_Version  : INTEGER;
  11918.     Interrupt        : HL.Interrupt_State;
  11919.  
  11920.     begin
  11921.  
  11922.     if SL.IsEmpty(Versions) then
  11923.         return;
  11924.     end if;
  11925.     Parse_Node(Node    => Item_Node,
  11926.            Library => Library,
  11927.            Item    => Item,
  11928.            Version => Version);
  11929.     if Privileged(Privilege, Library, Item) then
  11930.         All_Version := Get_Version(Item_Node, SP.Create("*"));
  11931.         if SL.Equal(All_Version, Versions) then
  11932.         Interrupt := HL.Get_Interrupt_State;
  11933.         HL.Ignore_Interrupts;
  11934.         Destroy_String_List(All_Version);
  11935.         if Is_Checked_Out(Item_Node) then
  11936.             Change_Checked_Out_Count(Library, -1);
  11937.         end if;            
  11938.         HNM.Delete_Tree(Item_Node);
  11939.         HL.Set_Interrupt_State(Interrupt);
  11940.         return;
  11941.         else
  11942.         Destroy_String_List(All_Version);
  11943.         Delete := TRUE;
  11944.         end if;
  11945.     end if;
  11946.     SP.Flush(Library);
  11947.     SP.Flush(Item);
  11948.     SP.Flush(Version);
  11949.     Current_Version := INTEGER'value(Get_Current_Version(Item_Node));
  11950.     HA.Set_Node_Attribute(Node   => Item_Node,
  11951.                   Attrib => "V",
  11952.                   Value  => "0");
  11953.     Version_Iterator := SL.MakeListIter(Versions);
  11954.     while SL.More(Version_Iterator) loop
  11955.         SL.Next(Version_Iterator, Version_Number);
  11956.         HNM.Open_Node_Handle(Node         => Version_Node,
  11957.                  Base         => Item_Node,
  11958.                  Relation     => "DOT",
  11959.                  Key          => 'V' & SP.Value(Version_Number));
  11960.         Parse_Node(Node    => Version_Node,
  11961.                Library => Library,
  11962.                Item    => Item,
  11963.                Version => Version);
  11964.         if Delete then
  11965.         Interrupt := HL.Get_Interrupt_State;
  11966.         HL.Ignore_Interrupts;
  11967.         HNM.Delete_Tree(Version_Node);
  11968.         if INTEGER'value(SP.Value(Version_Number)) = Current_Version and then
  11969.            Is_Checked_Out(Item_Node) then
  11970.             Change_Checked_Out_Count(Library, -1);
  11971.         end if;            
  11972.         HL.Set_Interrupt_State(Interrupt);
  11973.         SP.Flush(Library);
  11974.         SP.Flush(Item);
  11975.         SP.Flush(Version);
  11976.         else
  11977.         if Privileged(Privilege, Library, Item, SP.Value(Version)) then
  11978.             Interrupt := HL.Get_Interrupt_State;
  11979.             HL.Ignore_Interrupts;
  11980.             HNM.Delete_Tree(Version_Node);
  11981.             if INTEGER'value(SP.Value(Version_Number)) = Current_Version and then
  11982.                Is_Checked_Out(Item_Node) then
  11983.             Change_Checked_Out_Count(Library, -1);
  11984.             end if;            
  11985.             HL.Set_Interrupt_State(Interrupt);
  11986.             SP.Flush(Library);
  11987.             SP.Flush(Item);
  11988.             SP.Flush(Version);
  11989.         else
  11990.             Remainder_List := SL.MakeList(Library);    
  11991.             SL.Attach(Remainder_List, Item);
  11992.             SL.Attach(Remainder_List, Version);
  11993.             SL.Attach(Remainder_List, SP.Make_Persistent(Privilege_Reason));
  11994.             LL.Attach(Remainder, Remainder_List);
  11995.         end if;
  11996.         end if;
  11997.         HNM.Close_Node_Handle(Version_Node);
  11998.     end loop;
  11999.     begin
  12000.         HA.Set_Node_Attribute(Node   => Item_Node,
  12001.                   Attrib => "V",
  12002.                   Value  => Get_Current_Version(Item_Node));
  12003.     exception
  12004.         when Version_Not_Found =>
  12005.         HNM.Delete_Tree(Item_Node);
  12006.     end;
  12007.  
  12008.     exception
  12009.     when others =>
  12010.         HNM.Close_Node_Handle(Version_Node);
  12011.         raise;
  12012.  
  12013.     end Delete;
  12014.  
  12015. --------------------------------------------------------------------------------
  12016.  
  12017.     procedure Purge(
  12018.     Library   : in     SP.String_Type;
  12019.     Item      : in     SP.String_Type := SP.Create("*");
  12020.     Privilege : in     Privilege_Type;
  12021.     Remainder : in out LL.List
  12022.     ) is
  12023.  
  12024.     Item_Node        : HND.Node_Type;
  12025.     Item_Iterator    : HNM.Node_Iterator;
  12026.     Versions         : SL.List;
  12027.  
  12028.     begin
  12029.  
  12030.     Iterate_Item(Library, Item, Item_Iterator);
  12031.     while HNM.More(Item_Iterator) loop
  12032.         HNM.Get_Next(Item_Iterator, Item_Node);
  12033.         Versions := Get_Version(Item_Node, SP.Create("*"));
  12034.         SL.DeleteHead(Versions);
  12035.         Delete(Item_Node, Versions, Privilege, Remainder);
  12036.         Destroy_String_List(Versions);
  12037.         HNM.Close_Node_Handle(Item_Node);
  12038.     end loop;
  12039.  
  12040.     exception
  12041.     when others =>
  12042.         HNM.Close_Node_Handle(Item_Node);
  12043.         raise;
  12044.  
  12045.     end Purge;
  12046.  
  12047. --------------------------------------------------------------------------------
  12048.  
  12049.     procedure Rename_Item(
  12050.     Library   : in SP.String_Type;
  12051.     From_Item : in SP.String_Type;
  12052.     To_Item   : in SP.String_Type;
  12053.     Privilege : in Privilege_Type;
  12054.     Remainder : in out LL.List
  12055.     ) is
  12056.  
  12057.     Item_Node      : HND.Node_Type;
  12058.     Remainder_List : SL.List;
  12059.  
  12060.     begin
  12061.  
  12062.     Is_Item(Item_Node, Library, To_Item);
  12063.     if HNM.Is_Open(Item_Node) then
  12064.         HNM.Close_Node_Handle(Item_Node);
  12065.         raise Item_Already_Exists;
  12066.     end if;
  12067.     Is_Item(Item_Node, Library, From_Item);
  12068.     if not HNM.Is_Open(Item_Node) then
  12069.         raise Item_Not_Found;
  12070.     end if;
  12071.     if Is_Checked_Out(Item_Node) then
  12072.         HNM.Close_Node_Handle(Item_Node);
  12073.         raise Item_Checked_Out;
  12074.     end if;
  12075.     if not Privileged(Privilege, Library, From_Item) then
  12076.         Remainder_List := SL.MakeList(SP.Make_Persistent(Library));    
  12077.         SL.Attach(Remainder_List, SP.Make_Persistent(From_Item));
  12078.         SL.Attach(Remainder_List, SP.Make_Persistent(""));
  12079.         SL.Attach(Remainder_List, SP.Make_Persistent(Privilege_Reason));
  12080.         LL.Attach(Remainder, Remainder_List);
  12081.         return;
  12082.     end if;
  12083.     HNM.Rename(Node     => Item_Node,
  12084.            New_Name => SP.Value(Node_Name(Library, To_Item)));
  12085.     HNM.Close_Node_Handle(Item_Node);
  12086.  
  12087.     exception
  12088.     when others =>
  12089.         HNM.Close_Node_Handle(Item_Node);
  12090.         raise;
  12091.  
  12092.     end Rename_Item;
  12093.  
  12094. --------------------------------------------------------------------------------
  12095.  
  12096.     procedure Rename_Version(
  12097.     Library      : in     SP.String_Type;
  12098.     Item         : in     SP.String_Type;
  12099.     From_Version : in     SP.String_Type;
  12100.     To_Version   : in     SP.String_Type;
  12101.     Privilege    : in     Privilege_Type;
  12102.     Remainder    : in out LL.List
  12103.     ) is
  12104.  
  12105.     Library_Name        : SP.String_Type;
  12106.     Item_Name           : SP.String_Type;
  12107.     Version_Name        : SP.String_Type;
  12108.     Reason              : SP.String_Type;
  12109.     Version_Node        : HND.Node_Type;
  12110.     Item_Node           : HND.Node_Type;
  12111.     Item_Iterator       : HNM.Node_Iterator;
  12112.     Full_Version_List   : SL.List;
  12113.     List_Iterator       : SL.ListIter;
  12114.     Version             : SP.String_Type;
  12115.     From_Version_List   : SL.List;
  12116.     To_Version_List     : SL.List;
  12117.     Remainder_List      : SL.List;
  12118.     Add_To_List         : BOOLEAN;
  12119.     From_Version_Num    : INTEGER;
  12120.     To_Version_Num      : INTEGER;
  12121.  
  12122.     begin
  12123.  
  12124.     begin
  12125.         From_Version_Num := INTEGER'value(SP.Value(From_Version));
  12126.     exception
  12127.         when others =>
  12128.         if not SP.Is_Empty(From_Version) then
  12129.             raise Invalid_Version;
  12130.         end if;
  12131.     end;
  12132.     begin
  12133.         To_Version_Num := INTEGER'value(SP.Value(To_Version));
  12134.     exception
  12135.         when others =>
  12136.         if not SP.Is_Empty(To_Version) then
  12137.             raise Invalid_Version;
  12138.         end if;
  12139.     end;
  12140.     Iterate_Item(Library, Item, Item_Iterator);
  12141.     while HNM.More(Item_Iterator) loop
  12142.         HNM.Get_Next(Item_Iterator, Item_Node);
  12143.         if not Is_Checked_Out(Item_Node) then
  12144.         Parse_Node(Item_Node, Library_Name, Item_Name, Version_Name);
  12145.         SP.Flush(Version_Name);
  12146.         From_Version_List := Get_Version(Item_Node, From_Version);
  12147.         From_Version_Num := INTEGER'value(SP.Value(SL.FirstValue(From_Version_List)));
  12148.         Destroy_String_List(From_Version_List);
  12149.         Is_Version(Version_Node,
  12150.                Library_Name,
  12151.                Item_Name, 
  12152.                SS.Image(From_Version_Num));
  12153.         Add_To_List := FALSE;
  12154.         begin
  12155.             To_Version_List := Get_Version(Item_Node, To_Version);
  12156.             To_Version_Num := INTEGER'value(SP.Value(SL.FirstValue(To_Version_List)));
  12157.             Destroy_String_List(To_Version_List);
  12158.             if From_Version_Num /= To_Version_Num then
  12159.             Add_To_List := TRUE;
  12160.             Reason := SP.Make_Persistent(Version_Exists_Reason);
  12161.             end if;
  12162.         exception
  12163.             when Version_Not_Found =>
  12164.             if To_Version_Num <= 0 then
  12165.                 SP.Mark;
  12166.                 To_Version_List := Get_Version(Item_Node, SP.Create("0"));
  12167.                 To_Version_Num := INTEGER'value(SP.Value(SL.FirstValue(To_Version_List))) + To_Version_Num;
  12168.                 Destroy_String_List(To_Version_List);
  12169.                 SP.Release;
  12170.             end if;
  12171.             Full_Version_List := Get_Version(Item_Node, SP.Create("*"));
  12172.             List_Iterator := SL.MakeListIter(Full_Version_List);
  12173.             if From_Version_Num > To_Version_Num then
  12174.                 while SL.More(List_Iterator) loop
  12175.                 SL.Next(List_Iterator, Version);
  12176.                 if From_Version_Num = INTEGER'value(SP.Value(Version)) then
  12177.                     if SL.More(List_Iterator) and then
  12178.                        To_Version_Num <= INTEGER'value(SP.Value(SL.CellValue(List_Iterator))) then
  12179.                     Add_To_List := TRUE;
  12180.                     Reason := SP.Make_Persistent(Regression_Reason);
  12181.                     end if;
  12182.                     exit;
  12183.                 end if;
  12184.                 end loop;
  12185.             else        
  12186.                 while SL.More(List_Iterator) loop
  12187.                 SL.Next(List_Iterator, Version);
  12188.                 if To_Version_Num > INTEGER'value(SP.Value(Version)) then
  12189.                     if From_Version_Num /= INTEGER'value(SP.Value(Version)) then
  12190.                     Add_To_List := TRUE;
  12191.                     Reason := SP.Make_Persistent(Regression_Reason);
  12192.                     end if;
  12193.                     exit;
  12194.                 end if;
  12195.                 end loop;
  12196.             end if;
  12197.             Destroy_String_List(Full_Version_List);
  12198.             if not Add_To_List then
  12199.                 if Privileged(Privilege,
  12200.                       Library_Name,
  12201.                       Item_Name, 
  12202.                       SU.Image(From_Version_Num)) then
  12203.                 HA.Set_Node_Attribute(Node   => Item_Node,
  12204.                               Attrib => "V",
  12205.                               Value  => "0");
  12206.                 HNM.Rename(Node     => Version_Node,
  12207.                        New_Name => SP.Value(Node_Name(Library_Name, Item_Name, SU.Image(To_Version_Num))));
  12208.                 HA.Set_Node_Attribute(Node   => Item_Node,
  12209.                               Attrib => "V",
  12210.                               Value  => Get_Current_Version(Item_Node));
  12211.                 else
  12212.                 Add_To_List := TRUE;
  12213.                 Reason := SP.Make_Persistent(Privilege_Reason);
  12214.                 end if;
  12215.             end if;
  12216.         end;
  12217.         HNM.Close_Node_Handle(Version_Node);
  12218.         HNM.Close_Node_Handle(Item_Node);
  12219.         else
  12220.         Add_To_List :=TRUE;
  12221.         Reason := SP.Make_Persistent(Item_Checked_Out_Reason);
  12222.         end if;
  12223.         if Add_To_List then
  12224.         Remainder_List := SL.MakeList(SP.Make_Persistent(Library));    
  12225.         SL.Attach(Remainder_List, SP.Make_Persistent(Item_Name));
  12226.         SL.Attach(Remainder_List, SS.Image(From_Version_Num));
  12227.         SL.Attach(Remainder_List, Reason);
  12228.         LL.Attach(Remainder, Remainder_List);
  12229.         end if;
  12230.     end loop;    
  12231.  
  12232.     exception
  12233.     when others =>
  12234.         HNM.Close_Node_Handle(Version_Node);
  12235.         HNM.Close_Node_Handle(Item_Node);
  12236.         raise;
  12237.  
  12238.     end Rename_Version;
  12239.  
  12240. --------------------------------------------------------------------------------
  12241.  
  12242.     function Privileged(
  12243.     Privilege : in Privilege_Type;
  12244.     Node      : in HND.Node_Type
  12245.     ) return BOOLEAN is
  12246.  
  12247.     Attribute_Value  : STRING(1 .. 64);
  12248.     Attribute_Length : INTEGER;
  12249.  
  12250.     begin
  12251.  
  12252.     case Privilege is
  12253.         when WORLD =>
  12254.         return TRUE;
  12255.         when GROUP =>
  12256.         HU.Get_Node_Attribute(Node       => Node,
  12257.                       Attrib     => "GROUP",
  12258.                       Value      => Attribute_Value,
  12259.                       Value_Last => Attribute_Length);
  12260.         if Attribute_Value(1 .. Attribute_Length) = "" then
  12261.             return TRUE;
  12262.         else
  12263.             return Attribute_Value(1 .. Attribute_Length) = HL.Get_Item(HL.ACCOUNT);
  12264.         end if;
  12265.         when OWNER =>
  12266.         HU.Get_Node_Attribute(Node       => Node,
  12267.                       Attrib     => "OWNER",
  12268.                       Value      => Attribute_Value,
  12269.                       Value_Last => Attribute_Length);
  12270.         if Attribute_Value(1 .. Attribute_Length) = "" then
  12271.             return TRUE;
  12272.         else
  12273.             return Attribute_Value(1 .. Attribute_Length) = HL.Get_Item(HL.USER_NAME);
  12274.         end if;
  12275.     end case;
  12276.  
  12277.     exception
  12278.     when HND.Name_Error =>
  12279.         raise Internal_Error;
  12280.  
  12281.     end Privileged;
  12282.  
  12283. --------------------------------------------------------------------------------
  12284.  
  12285.     function Privileged(
  12286.     Privilege : in Privilege_Type;
  12287.     Library   : in SP.String_Type;
  12288.     Item      : in SP.String_Type := SP.Create("");
  12289.     Version   : in STRING := ""
  12290.     ) return BOOLEAN is
  12291.  
  12292.     Node  : HND.Node_Type;
  12293.     Owned : BOOLEAN := FALSE;
  12294.  
  12295.     begin
  12296.  
  12297.     if Version /= "" then
  12298.         Is_Node(Node, Node_Name(Library, Item, Version));
  12299.         if not HNM.Is_Open(Node) then
  12300.         raise Internal_Error;
  12301.         end if;
  12302.         Owned := Privileged(Privilege, Node);
  12303.         HNM.Close_Node_Handle(Node);
  12304.     end if;
  12305.     if Owned then
  12306.         return TRUE;
  12307.     end if;
  12308.  
  12309.     if not SP.Is_Empty(Item) then
  12310.         Is_Node(Node, Node_Name(Library, Item));
  12311.         if not HNM.Is_Open(Node) then
  12312.         raise Internal_Error;
  12313.         end if;
  12314.         Owned := Privileged(Privilege, Node);
  12315.         HNM.Close_Node_Handle(Node);
  12316.     end if;
  12317.     if Owned then
  12318.         return TRUE;
  12319.     end if;
  12320.  
  12321.     Is_Node(Node, Node_Name(Library));
  12322.     if not HNM.Is_Open(Node) then
  12323.         raise Library_Does_Not_Exist;
  12324.     end if;
  12325.     Owned := Privileged(Privilege, Node);
  12326.     HNM.Close_Node_Handle(Node);
  12327.     return Owned;    
  12328.  
  12329.     end Privileged;
  12330.  
  12331. --------------------------------------------------------------------------------
  12332.  
  12333.     function Get_Hif_File_Name(
  12334.     Lib_Name : in SP.String_Type;
  12335.     Item     : in SP.String_Type;
  12336.     Version  : in SP.String_Type
  12337.     ) return SP.String_Type is
  12338.  
  12339.     Node : HND.Node_Type;
  12340.     Path : SP.String_Type;
  12341.     File : SP.String_Type;
  12342.  
  12343.     begin
  12344.  
  12345.     SP.Mark;
  12346.     HNM.Open_Node_Handle(Node, SP.Value(Node_Name(Lib_Name, Item, SP.Value(Version))));
  12347.     File := SP.Make_Persistent(HNM.Host_File_Name(Node));
  12348.     SP.Release;
  12349.     HNM.Close_Node_Handle(Node);
  12350.     return File;
  12351.  
  12352.     end Get_Hif_File_Name;
  12353.  
  12354. --------------------------------------------------------------------------------
  12355.  
  12356.     function Is_Item_Checked_Out(
  12357.     Library : in SP.String_Type
  12358.     ) return BOOLEAN is
  12359.  
  12360.     Node             : HND.Node_Type;
  12361.     Attribute_Value  : STRING(1 .. 16);
  12362.     Attribute_Length : INTEGER;
  12363.     Check_Out_Count  : NATURAL;
  12364.  
  12365.     begin
  12366.  
  12367.     Is_Library(Node, Library);
  12368.     if not HNM.Is_Open(Node) then
  12369.         raise Library_Does_Not_Exist;
  12370.     end if;
  12371.     HU.Get_Node_Attribute(Node       => Node,
  12372.                   Attrib     => "CHECKED_OUT",
  12373.                   Value      => Attribute_Value,
  12374.                   Value_Last => Attribute_Length);
  12375.     HNM.Close_Node_Handle(Node);
  12376.     begin
  12377.         Check_Out_Count := NATURAL'value(Attribute_Value(1 .. Attribute_Length));    
  12378.     exception
  12379.         when CONSTRAINT_ERROR =>
  12380.         Check_Out_Count := 0;
  12381.     end;
  12382.     return Check_Out_Count /= 0;
  12383.  
  12384.     end Is_Item_Checked_Out;
  12385.  
  12386. --------------------------------------------------------------------------------
  12387.  
  12388.     procedure Display_List(
  12389.     List   : in out LL.List;
  12390.     Header : in     STRING
  12391.     ) is
  12392.  
  12393.     List_Iter   : LL.ListIter;
  12394.     Value_List  : SL.List;
  12395.     Value_Iter  : SL.ListIter;
  12396.     Value       : SP.String_Type;
  12397.     Work_String : SP.String_Type;
  12398.  
  12399.     begin
  12400.  
  12401.     List_Iter := LL.MakeListIter(List);
  12402.     HL.Put_Message_Line(SU.Left_Justify(Header, Maximum_Item_Name) & " Reason");
  12403.     HL.Put_Message_Line(Separator);
  12404.     while LL.More(List_Iter) loop
  12405.         LL.Next(List_Iter, Value_List);
  12406.         Value_Iter := SL.MakeListIter(Value_List);
  12407.         SP.Mark;
  12408.         SL.Forward(Value_Iter);
  12409.         SL.Next(Value_Iter, Value);
  12410.         Work_String := Value;
  12411.         Work_String := SP."&"(Work_String, "/");
  12412.         SL.Next(Value_Iter, Value);
  12413.         Work_String := SP."&"(Work_String, Value);
  12414.         SL.Next(Value_Iter, Value);
  12415.         HL.Put_Message_Line(SS.Left_Justify(Work_String, Maximum_Item_Name) & ' ' & SP.Value(Value));
  12416.         SP.Release;
  12417.     end loop;
  12418.  
  12419.     end Display_List;
  12420.  
  12421. --------------------------------------------------------------------------------
  12422.  
  12423.     procedure Change_Checked_Out_Count(
  12424.     Library : SP.String_Type;
  12425.     Count   : INTEGER
  12426.     ) is
  12427.  
  12428.     Node              : HND.Node_Type;
  12429.     Attribute_Value   : STRING(1 .. Maximum_Owner_Name);
  12430.     Attribute_Length  : INTEGER;
  12431.     Checked_Out_Count : NATURAL;
  12432.  
  12433.     begin
  12434.  
  12435.     Is_Library(Node, Library);
  12436.     if not HNM.Is_Open(Node) then
  12437.         raise Library_Does_Not_Exist;
  12438.     end if;
  12439.     HU.Get_Node_Attribute(Node       => Node,
  12440.                   Attrib     => "CHECKED_OUT",
  12441.                   Value      => Attribute_Value,
  12442.                   Value_Last => Attribute_Length);
  12443.     begin
  12444.         Checked_Out_Count :=
  12445.         NATURAL'value(Attribute_Value(1 .. Attribute_Length)) + Count;    
  12446.     exception
  12447.         when CONSTRAINT_ERROR =>
  12448.         Checked_Out_Count := 0;
  12449.     end;
  12450.     HA.Set_Node_Attribute(Node       => Node,
  12451.                   Attrib     => "CHECKED_OUT",
  12452.                   Value      => SU.Image(Checked_Out_Count));
  12453.     HNM.Close_Node_Handle(Node);
  12454.  
  12455.     end Change_Checked_Out_Count;
  12456.  
  12457. --------------------------------------------------------------------------------
  12458.  
  12459.     procedure Check_In_Item(
  12460.     Library   : in     SP.String_Type;
  12461.     File      : in     SP.String_Type;
  12462.     History   : in     SP.String_Type;
  12463.     Operation : in     Operation_Type;
  12464.     Returned  : in out SP.String_Type
  12465.     ) is
  12466.     
  12467.     Item_Name        : SP.String_Type;
  12468.     Item_Node        : HND.Node_Type;
  12469.     Full_Item_Name   : SP.String_Type;
  12470.     Full_Item_Node   : HND.Node_Type;
  12471.     Attribute_Value  : STRING(1 .. 64);
  12472.     Attribute_Length : INTEGER;
  12473.     Version          : POSITIVE;
  12474.     History_Index    : POSITIVE;
  12475.     History_List     : HLU.List_Type;
  12476.     Check_Out_Count  : NATURAL;
  12477.  
  12478.     begin
  12479.  
  12480.     if Operation = CREATE_ITEM or Operation = RETURN_ITEM then
  12481.         begin
  12482.         if not FM.Is_File(SP.Value(File)) then
  12483.             raise File_Not_Found;
  12484.         end if;
  12485.         exception
  12486.         when FM.Parse_Error =>
  12487.             raise Invalid_External_Name;
  12488.         when others =>
  12489.             raise;
  12490.         end;
  12491.     end if;
  12492.     Item_Name := Node_Name(Library, SP.Create(FM.Parse_Filename(SP.Value(File), FM.FILE_ONLY)));
  12493.     Is_Node(Item_Node, Item_Name);
  12494.     if not HNM.Is_Open(Item_Node) then
  12495.         if Operation = CREATE_ITEM then
  12496.         HNM.Create_Node(Name => SP.Value(Item_Name));
  12497.         History_Index := 1;
  12498.         Version := 1;
  12499.         HLU.Init_List(History_List);
  12500.         else
  12501.         raise Item_Not_Found;
  12502.         end if;
  12503.     else
  12504.         if Operation = CREATE_ITEM then
  12505.         HNM.Close_Node_Handle(Item_Node);
  12506.         raise Item_Already_Exists;
  12507.         elsif Operation = RETURN_ITEM then
  12508.         Version := NATURAL'value(Get_Current_Version(Item_Node)) + 1;
  12509.         end if;
  12510.     end if;
  12511.  
  12512.     if Operation = CREATE_ITEM or Operation = RETURN_ITEM then
  12513.         if HNM.Is_Open(Item_Node) then
  12514.         Returned := SP.Make_Persistent(Checked_Out_By(Item_Node));
  12515.         if SP.Is_Empty(Returned) then
  12516.             HNM.Close_Node_Handle(Item_Node);
  12517.             raise Item_Not_Checked_Out;
  12518.         end if;
  12519.         if SP.Value(Returned) /= HL.Get_Item(HL.USER_NAME) then
  12520.             HNM.Close_Node_Handle(Item_Node);
  12521.             raise Item_Checked_Out;
  12522.         end if;
  12523.         SP.Flush(Returned);
  12524.         HU.Get_Node_Attribute(Node       => Item_Node,
  12525.                       Attrib     => "HISTORY_INDEX",
  12526.                       Value      => Attribute_Value,
  12527.                       Value_Last => Attribute_Length);
  12528.         History_Index := NATURAL'value(Attribute_Value(1 .. Attribute_Length)) + 1; 
  12529.         HA.Get_Node_Attribute(Node   => Item_Node,
  12530.                       Attrib => "HISTORY",
  12531.                       Value  => History_List);
  12532.         else
  12533.         Open_Standard_Node_Handle(Item_Node, Item_Name);
  12534.         end if;
  12535.         Full_Item_Name := SP."&"(Item_Name, ".V" & SU.Image(Version));
  12536.         HNM.Create_Node(Node         => Full_Item_Node,
  12537.                 Name         => SP.Value(Full_Item_Name),
  12538.                 Kind_Of_Node => HND.File);
  12539.         begin
  12540.         FM.Copy(SP.Value(File),
  12541.             HNM.Host_File_Name(Full_Item_Node));
  12542.         exception
  12543.         when others =>
  12544.             if Version = 1 then
  12545.             HNM.Delete_Tree(Item_Node);
  12546.             else
  12547.             HNM.Delete_Tree(Full_Item_Node);
  12548.             end if;
  12549.             raise Item_Not_Created;
  12550.         end;
  12551.         begin  
  12552.         FM.Set_File_Protection(
  12553.             HNM.Host_File_Name(Full_Item_Node));
  12554.         exception
  12555.         when others =>
  12556.             if Version = 1 then
  12557.             HNM.Delete_Tree(Item_Node);
  12558.             else
  12559.             HNM.Delete_Tree(Full_Item_Node);
  12560.             end if;
  12561.             raise Set_Protection_Error;
  12562.         end;
  12563.         HA.Set_Node_Attribute(Node   => Item_Node,
  12564.                   Attrib => "V",
  12565.                   Value  => SU.Image(Version));
  12566.         HA.Set_Node_Attribute(Node   => Item_Node,
  12567.               Attrib => "HISTORY_INDEX",
  12568.               Value  => SU.Image(History_Index));
  12569.         HLU.Add_Positional(History_List, '"' & SP.Value(History) & '"');
  12570.         HA.Set_Node_Attribute(Node   => Item_Node,
  12571.                   Attrib => "HISTORY",
  12572.                   Value  => History_List);
  12573.         HLU.Free_List(History_List);
  12574.         Set_Standard_Attributes(Full_Item_Node);
  12575.         HA.Set_Node_Attribute(Node   => Full_Item_Node,
  12576.                   Attrib => "HISTORY_INDEX",
  12577.                   Value  => SU.Image(History_Index));
  12578.         HNM.Close_Node_Handle(Full_Item_Node);
  12579.     else
  12580.         Returned := SP.Make_Persistent(Checked_Out_By(Item_Node));
  12581.         if SP.Is_Empty(Returned) then
  12582.         HNM.Close_Node_Handle(Item_Node);
  12583.         raise Item_Not_Checked_Out;
  12584.         end if;
  12585.         if SP.Value(Returned) /= HL.Get_Item(HL.USER_NAME) then
  12586.         HNM.Close_Node_Handle(Item_Node);
  12587.         raise Item_Checked_Out;
  12588.         end if;
  12589.         SP.Flush(Returned);
  12590.     end if;
  12591.  
  12592.     HA.Set_Node_Attribute(Node   => Item_Node,
  12593.                   Attrib => "CHECKED_OUT",
  12594.                   Value  => "");
  12595.     Change_Checked_Out_Count(Library, -1);
  12596.     Returned := SP.Make_Persistent(Get_Current_Version(Item_Node));
  12597.     HNM.Close_Node_Handle(Item_Node);
  12598.  
  12599.     end Check_In_Item;
  12600.  
  12601. --------------------------------------------------------------------------------
  12602.  
  12603.     procedure Create_Library(
  12604.     Library   : in SP.String_Type;
  12605.     Directory : in SP.String_Type;
  12606.     CI        : in SP.String_Type := SP.Create("");
  12607.     Mode      : in Fetch_Type;
  12608.     Node      : in HND.Node_Type;
  12609.     Locked    : in BOOLEAN := FALSE
  12610.     ) is
  12611.  
  12612.     Library_Node : HND.Node_Type;
  12613.     DOCMGR_Node  : HND.Node_Type;
  12614.     Lock         : BOOLEAN;
  12615.  
  12616.     begin
  12617.  
  12618.     if FM.Is_Directory(SP.Value(Directory)) then
  12619.         raise Directory_Already_Exists;
  12620.     end if;
  12621.     Is_Node(Library_Node, Node_Name(Library));
  12622.     if HNM.Is_Open(Library_Node) then
  12623.         HNM.Close_Node_Handle(Library_Node);
  12624.         raise Library_Already_Exists;
  12625.     end if;
  12626.     HSM.Add_User(User_Name      => Internal_Name(Library),
  12627.              Partition_Name => FM.Path_Name(SP.Value(Directory),
  12628.                             "",
  12629.                             Absolute => TRUE));
  12630.     Is_Node(Library_Node, Node_Name(Library));
  12631.     if not HNM.Is_Open(Library_Node) then
  12632.         raise Internal_Error;
  12633.     end if;
  12634.     Lock := Lock_Library(Library_Node, WRITE_LOCK);
  12635.     Set_Standard_Attributes(Library_Node);
  12636.     HA.Set_Node_Attribute(Node   => Library_Node,
  12637.                   Attrib => "CI",
  12638.                   Value  => SP.Value(CI));
  12639.     HA.Set_Node_Attribute(Node   => Library_Node,
  12640.                   Attrib => "MODE",
  12641.                   Value  => Fetch_Type'image(Mode));
  12642.     HA.Set_Node_Attribute(Node   => Library_Node,
  12643.                   Attrib => "CHECKED_OUT",
  12644.                   Value  => "0");
  12645.     if HNM.Is_Open(Node) then
  12646.         HNM.Copy_Tree(From    => Node,
  12647.               To_Base => Library_Node,
  12648.               To_Key  => "IL");
  12649.     else
  12650.         HNM.Create_Node (Base => Library_Node,
  12651.                  Key  => "IL",
  12652.                  Form => "");
  12653.     end if;
  12654.     begin
  12655.         FM.Set_File_Protection(FM.Directory_Name(SP.Value(Directory)));
  12656.     exception
  12657.         when others =>
  12658.         raise Set_Protection_Error;
  12659.     end;
  12660.     HNM.Open_Node_Handle(Node => DOCMGR_Node,
  12661.                  Name => DMD.Document_Manager_List_Path);
  12662.     HNM.Link(To_Node  => Library_Node,
  12663.          New_Base => DOCMGR_Node,
  12664.          Relation => "LIBRARY",
  12665.          Key      => Internal_Name(Library));
  12666.     HNM.Close_Node_Handle(DOCMGR_Node);
  12667.     if not Locked then
  12668.         Unlock_Library(Library_Node, WRITE_LOCK);
  12669.     end if;
  12670.     HNM.Close_Node_Handle(Library_Node);
  12671.  
  12672.     exception
  12673.  
  12674.     when FM.Parse_Error =>
  12675.         raise Invalid_Directory_Name;
  12676.     when Directory_Already_Exists | Library_Already_Exists =>
  12677.         raise;
  12678.     when others =>
  12679.         begin
  12680.         if not HNM.Is_Open(DOCMGR_Node) then
  12681.             HNM.Open_Node_Handle(Node => DOCMGR_Node,
  12682.                      Name => DMD.Document_Manager_List_Path);
  12683.         end if;
  12684.         HNM.Unlink(Base     => DOCMGR_Node,
  12685.                Relation => "LIBRARY",
  12686.                Key      => Internal_Name(Library));
  12687.         exception
  12688.         when others =>
  12689.             null;
  12690.         end;
  12691.         HNM.Close_Node_Handle(DOCMGR_Node);
  12692.         begin
  12693.         HSM.Delete_User(Internal_Name(Library));
  12694.         exception
  12695.         when others =>
  12696.             null;
  12697.         end;
  12698.         raise;
  12699.  
  12700.     end Create_Library;
  12701.  
  12702. --------------------------------------------------------------------------------
  12703.  
  12704.     procedure Delete_Library(
  12705.     Library   : in SP.String_Type;
  12706.     Privilege : in Privilege_Type := WORLD
  12707.     ) is
  12708.  
  12709.     DOCMGR_Node  : HND.Node_Type;
  12710.  
  12711.     begin
  12712.  
  12713.     if not Privileged(Privilege, Library) then
  12714.         raise No_Privilege; 
  12715.     end if;
  12716.     if Get_Library_Attribute(Library, "MODE") = Fetch_Type'image(UPDATE) or
  12717.        Get_Library_Attribute(Library, "MODE") = Fetch_Type'image(BRANCH) then
  12718.         raise Library_Pending_Return;
  12719.     end if;
  12720.     HNM.Open_Node_Handle(Node => DOCMGR_Node,
  12721.                  Name => DMD.Document_Manager_List_Path);
  12722.     begin
  12723.         HNM.Unlink(Base     => DOCMGR_Node,
  12724.                Relation => "LIBRARY",
  12725.                Key      => Internal_Name(Library));
  12726.     exception
  12727.         when others =>
  12728.         null;
  12729.     end;
  12730.     HNM.Close_Node_Handle(DOCMGR_Node);
  12731.     HSM.Delete_User(Internal_Name(Library));
  12732.  
  12733.     end Delete_Library;
  12734.  
  12735. --------------------------------------------------------------------------------
  12736.  
  12737.     function List_Item(
  12738.     Node    : in HND.Node_Type;
  12739.     Item    : in SP.String_Type := SP.Create("*");
  12740.     Version : in SP.String_Type := SP.Create("*");
  12741.     Mode    : in List_Mode := SHORT
  12742.     ) return LL.List is
  12743.  
  12744.     Item_Node        : HND.Node_Type;
  12745.     Item_Attributes  : SL.List;
  12746.     Versions         : SL.List;
  12747.     Version_Node     : HND.Node_Type;
  12748.     Version_Iterator : SL.ListIter;
  12749.     Current_Version  : SP.String_Type;
  12750.     List_of_Lists    : LL.List := LL.Create;
  12751.     Attribute_Value  : STRING(1 .. 64);
  12752.     Attribute_Length : INTEGER;
  12753.     Item_Iterator    : HNM.Node_Iterator;
  12754.     Library_Name     : SP.String_Type;
  12755.     Item_Name        : SP.String_Type;
  12756.     Version_Name     : SP.String_Type;
  12757.  
  12758.     begin
  12759.  
  12760.     HNM.Iterate(Iterator     => Item_Iterator,
  12761.             Node         => Node,
  12762.             Relation     => "DOT",
  12763.             Key          => Internal_Name(Item, "*"),
  12764.             Primary_Only => TRUE);
  12765.     while HNM.More(Item_Iterator) loop
  12766.         HNM.Get_Next(Item_Iterator, Item_Node);
  12767.         Current_Version := SP.Create(Get_Current_Version(Item_Node));
  12768.         Versions := Get_Version(Item_Node, Version);
  12769.         Version_Iterator := SL.MakeListIter(Versions);
  12770.         while SL.More(Version_Iterator) loop
  12771.         HNM.Open_Node_Handle(Node         => Version_Node,
  12772.                      Base         => Item_Node,
  12773.                      Relation     => "DOT",
  12774.                      Key          => 'V' & SP.Value(SL.CellValue(Version_Iterator)));
  12775.         Parse_Node(Item_Node, Library_Name, Item_Name, Version_Name);
  12776.         Item_Attributes := SL.MakeList(
  12777.                      SP.Make_Persistent(
  12778.                        External_Name(
  12779.                          SP.Value(Item_Name))));
  12780.         SL.Attach(Item_Attributes, SP.Make_Persistent(SL.CellValue(Version_Iterator)));
  12781.         if Mode = LONG then
  12782.             HU.Get_Node_Attribute(Version_Node, "OWNER", Attribute_Value, Attribute_Length);
  12783.             SL.Attach(Item_Attributes, SP.Make_Persistent(Attribute_Value(1 .. Attribute_Length)));
  12784.             HU.Get_Node_Attribute(Version_Node, "GROUP", Attribute_Value, Attribute_Length);
  12785.             SL.Attach(Item_Attributes, SP.Make_Persistent(Attribute_Value(1 .. Attribute_Length)));
  12786.             HU.Get_Node_Attribute(Version_Node, "DATE", Attribute_Value, Attribute_Length);
  12787.             SL.Attach(Item_Attributes, SP.Make_Persistent(Attribute_Value(1 .. Attribute_Length)));
  12788.             HU.Get_Node_Attribute(Version_Node, "TIME", Attribute_Value, Attribute_Length);
  12789.             SL.Attach(Item_Attributes, SP.Make_Persistent(Attribute_Value(1 .. Attribute_Length)));
  12790.             if SP.Equal(Current_Version, SL.CellValue(Version_Iterator)) then
  12791.             SL.Attach(Item_Attributes, SP.Make_Persistent(Checked_Out_By(Item_Node)));
  12792.             else
  12793.             SL.Attach(Item_Attributes, SP.Make_Persistent(""));
  12794.             end if;
  12795.         end if;
  12796.         HNM.Close_Node_Handle(Version_Node);
  12797.         LL.Attach(List_of_Lists, Item_Attributes);
  12798.         SL.Forward(Version_Iterator);
  12799.         end loop;
  12800.         Destroy_String_List(Versions);
  12801.         HNM.Close_Node_Handle(Item_Node);
  12802.     end loop;
  12803.     if LL.IsEmpty(List_of_Lists) then
  12804.         raise Item_Not_Found;
  12805.     end if;
  12806.     return List_of_Lists;
  12807.  
  12808.     exception
  12809.  
  12810.     when others =>
  12811.         begin
  12812.         Destroy_List_Of_Lists(List_Of_Lists);
  12813.         HNM.Close_Node_Handle(Item_Node);
  12814.         exception
  12815.         when others =>
  12816.             HNM.Close_Node_Handle(Item_Node);
  12817.         end;
  12818.         raise;
  12819.  
  12820.     end List_Item;
  12821.  
  12822. --------------------------------------------------------------------------------
  12823.  
  12824.  
  12825. end Library_Utilities;
  12826.                                                                     pragma page;
  12827. ::::::::::::::
  12828. libutl.spc
  12829. ::::::::::::::
  12830. with Library_Declarations;        use Library_Declarations;
  12831. with String_Pkg;
  12832. with HIF_Node_Defs;
  12833. with HIF_Node_Management;
  12834. with String_Lists;
  12835.  
  12836. package Library_Utilities is
  12837.  
  12838.     package SP  renames String_Pkg;
  12839.     package HND renames HIF_Node_Defs;
  12840.     package HNM renames HIF_Node_Management;
  12841.     package SL  renames String_Lists;
  12842.  
  12843. --------------------------------------------------------------------------------
  12844.  
  12845.     function Internal_Name(
  12846.     External_Name : in SP.String_Type;
  12847.     Exclude       : in STRING := ""
  12848.     ) return STRING;
  12849.  
  12850. --| Raises:
  12851. --| Invalid_External_Name
  12852.  
  12853. --| Effects:
  12854. --| Translate representation internal to the Library Manager to its
  12855. --| external representation.  (Needed to satisfy the condition that
  12856. --| node names be Ada identifiers) 
  12857.  
  12858. --------------------------------------------------------------------------------
  12859.  
  12860.     function External_Name(
  12861.     Internal_Name : in STRING
  12862.     ) return STRING;
  12863.  
  12864. --| Effects:
  12865. --| Translate external representation to the Library Manager
  12866. --| external representation.
  12867.  
  12868. --------------------------------------------------------------------------------
  12869.  
  12870.     procedure Is_Node(
  12871.     Node : in out HND.Node_Type;
  12872.     Name : in     SP.String_Type
  12873.     );
  12874.  
  12875. --| Effects:
  12876. --| Verifies that the given node name is indeed a node and if so opens
  12877. --| the node for processing.  Otherwise the node is closed.
  12878.  
  12879. --------------------------------------------------------------------------------
  12880.  
  12881.     function Node_Name(
  12882.     Library : in SP.String_Type;
  12883.     Item    : in SP.String_Type := SP.Create("");
  12884.     Version : in STRING := ""
  12885.     ) return SP.String_Type;
  12886.  
  12887. --| Effects:
  12888. --| Creates a node name representation of a library, item in a library, or
  12889. --| a version of an item in a library
  12890.  
  12891. --------------------------------------------------------------------------------
  12892.  
  12893.     procedure Parse_Node(
  12894.     Node    : in     HND.Node_Type;
  12895.     Library :    out SP.String_Type;
  12896.     Item    :    out SP.String_Type;
  12897.     Version :    out SP.String_Type
  12898.     );
  12899.  
  12900. --| Effects:
  12901. --| Given a node handle, parses the node name into library name, item name,
  12902. --| and version number
  12903.  
  12904. --------------------------------------------------------------------------------
  12905.  
  12906.     function Is_Ada_Id(
  12907.     Value : in SP.String_Type
  12908.     ) return BOOLEAN;
  12909.  
  12910. --| Effects:
  12911. --| Verifies that th e given value is an Ada identifier
  12912.  
  12913. --------------------------------------------------------------------------------
  12914.  
  12915.     procedure Is_Library(
  12916.     Node    : in out HND.Node_Type;
  12917.     Library : in     SP.String_Type
  12918.     );
  12919.  
  12920. --| Raises:
  12921. --| Invalid_Library_Name
  12922.  
  12923. --| Effects:
  12924. --| Verifies that the given library exists and opens the node handle to
  12925. --| the library.  Otherwise the node is not opened.
  12926.  
  12927. --------------------------------------------------------------------------------
  12928.  
  12929.     procedure Is_Item(
  12930.     Node    : in out HND.Node_Type;
  12931.     Library : in     SP.String_Type;
  12932.     Item    : in     SP.String_Type
  12933.     );
  12934.  
  12935. --| Raises:
  12936. --| Invalid_Library_Name, Library_Does_Not_Exist
  12937.  
  12938. --| Effects:
  12939. --| Verifies that the given item exists and opens the node handle to
  12940. --| the item. Otherwise the node is not opened.
  12941.  
  12942. --------------------------------------------------------------------------------
  12943.  
  12944.     procedure Is_Version(
  12945.     Node    : in out HND.Node_Type;
  12946.     Library : in     SP.String_Type;
  12947.     Item    : in     SP.String_Type;
  12948.     Version : in     SP.String_Type
  12949.     );
  12950.  
  12951. --| Raises:
  12952. --| Invalid_Library_Name, Library_Does_Not_Exist, Item_Not_Found,
  12953. --| Invalid_Version, Version_Not_Found
  12954.  
  12955. --| Effects:
  12956. --| Verifies that the version of an item exists and opens the node handle to
  12957. --| the version of the item.  Otherwise the node is not opened.
  12958.  
  12959. --------------------------------------------------------------------------------
  12960.  
  12961.     function Is_Checked_Out(
  12962.     Item_Node : in HND.Node_Type
  12963.     ) return BOOLEAN;
  12964.  
  12965. --| Effects:
  12966. --| Verifies that the item (given as a node handle) is checked out for
  12967. --| update.
  12968.  
  12969. --------------------------------------------------------------------------------
  12970.  
  12971.     function Checked_Out_By(
  12972.     Item_Node : in HND.Node_Type
  12973.     ) return STRING;
  12974.  
  12975. --| Effects:
  12976. --| Returns the name who has the item checked out (null string if item is
  12977. --| not checked out.
  12978.  
  12979. --------------------------------------------------------------------------------
  12980.  
  12981.     procedure Wait;
  12982.  
  12983. --| Effects:
  12984. --| Delays execution by a predefined interval
  12985.  
  12986. --------------------------------------------------------------------------------
  12987.  
  12988.     function Lock_Library(
  12989.     Node : in HND.Node_Type;
  12990.     Lock : in Lock_Type
  12991.     ) return BOOLEAN;
  12992.  
  12993. --| Raises:
  12994. --| Library_Master_Locked
  12995.  
  12996. --| Effects:
  12997. --| Locks the library (given as a node handle) with the appropriate Lock_Type.
  12998. --| Returns TRUE iff the locking was successful.
  12999.  
  13000. --------------------------------------------------------------------------------
  13001.  
  13002.     function Lock_Library(
  13003.     Library : in SP.String_Type;
  13004.     Lock    : in Lock_Type
  13005.     ) return BOOLEAN;
  13006.  
  13007. --| Raises:
  13008. --| Invalid_Library_Name. Library_Does_Not_Exist. Library_Master_Locked
  13009.  
  13010. --| Effects:
  13011. --| Locks the library (given as a library name) with the appropriate
  13012. --| Lock_Type.  Returns TRUE iff the locking was successful.
  13013.  
  13014. --------------------------------------------------------------------------------
  13015.  
  13016.     procedure Unlock_Library(
  13017.     Node  : in HND.Node_Type;
  13018.     Lock  : in Lock_Type
  13019.     );
  13020.  
  13021. --| Raises:
  13022. --| Not_Authorized
  13023.  
  13024. --| Effects:
  13025. --| Unlocks the library (given as a node handle).
  13026.  
  13027. --------------------------------------------------------------------------------
  13028.  
  13029.     procedure Unlock_Library(
  13030.     Library : in SP.String_Type;
  13031.     Lock    : in Lock_Type
  13032.     );
  13033.  
  13034. --| Raises:
  13035. --| Invalid_Library_Name, Library_Does_Not_Exist, Not_Authorized
  13036.  
  13037. --| Effects:
  13038. --| Unlocks the library (given as a library name).
  13039.  
  13040. --------------------------------------------------------------------------------
  13041.  
  13042.     function Upgrade_Lock(
  13043.     Node  : in HND.Node_Type
  13044.     ) return BOOLEAN;
  13045.  
  13046. --| Raises:
  13047. --| Library_Master_Locked, Invalid_Upgrade
  13048.  
  13049. --| Effects:
  13050. --| Upgrades the library lock to a write lock.
  13051.  
  13052. --------------------------------------------------------------------------------
  13053.  
  13054.     function Upgrade_Lock(
  13055.     Library : in SP.String_Type
  13056.     ) return BOOLEAN;
  13057.  
  13058. --| Raises:
  13059. --| Invalid_Library_Name, Library_Does_Not_Exist, Library_Master_Locked,
  13060. --| Invalid_Upgrade
  13061.  
  13062. --| Effects:
  13063. --| Upgrades the library lock to a write lock.
  13064.  
  13065. --------------------------------------------------------------------------------
  13066.  
  13067.     procedure Downgrade_Lock(
  13068.     Node  : in HND.Node_Type
  13069.     );
  13070.  
  13071. --| Raises:
  13072. --| Library_Master_Locked, Invalid_Downgrade
  13073.  
  13074. --| Effects:
  13075. --| Downgrades the library lock to a read lock.
  13076.  
  13077. --------------------------------------------------------------------------------
  13078.  
  13079.     procedure Downgrade_Lock(
  13080.     Library : in SP.String_Type
  13081.     );
  13082.  
  13083. --| Raises:
  13084. --| Invalid_Library_Name, Library_Does_Not_Exist, Library_Master_Locked,
  13085. --| Invalid_Downgrade
  13086.  
  13087. --| Effects:
  13088. --| Downgrades the library lock to a read lock.
  13089.  
  13090. --------------------------------------------------------------------------------
  13091.  
  13092.     function Get_Library_Attribute(
  13093.     Library   : in SP.String_Type;
  13094.     Attribute : in STRING
  13095.     ) return STRING;
  13096.  
  13097. --| Raises:
  13098. --| Invalid_Library_Name, Library_Does_Not_Exist
  13099.  
  13100. --| Effects:
  13101. --| Returns the value of a given attribute associated with the library
  13102.  
  13103. --------------------------------------------------------------------------------
  13104.  
  13105.     procedure Set_Library_Attribute(
  13106.     Library   : in SP.String_Type;
  13107.     Attribute : in STRING;
  13108.     Value     : in STRING
  13109.     );
  13110.  
  13111. --| Raises:
  13112. --| Invalid_Library_Name, Library_Does_Not_Exist
  13113.  
  13114. --| Effects:
  13115. --| Sets the value of a given attribute associated with the library
  13116.  
  13117. --------------------------------------------------------------------------------
  13118.  
  13119.     procedure Open_Standard_Node_Handle(
  13120.     Node : in out HND.Node_Type;
  13121.     Name : in     SP.String_Type
  13122.     );
  13123.  
  13124. --| Effects:
  13125. --| Open the node handle associated with a given node name and set the
  13126. --| standard attributes for this node.
  13127.  
  13128. --------------------------------------------------------------------------------
  13129.  
  13130.     procedure Set_Standard_Attributes(
  13131.     Node : in HND.Node_Type
  13132.     );
  13133.  
  13134. --| Effects:
  13135. --| Set the common attributes (eg. OWNER, DATE) of a given node.
  13136.  
  13137. --------------------------------------------------------------------------------
  13138.  
  13139.     procedure Set_Lock_Attributes(
  13140.     Node  : in HND.Node_Type;
  13141.     Lock  : in Lock_Type;
  13142.     Key   : in STRING
  13143.     );
  13144.  
  13145. --| Effects:
  13146. --| Set the common lock attributes (eg. DATE).
  13147.  
  13148. --------------------------------------------------------------------------------
  13149.  
  13150.     procedure Get_Lock_Attributes(
  13151.     Node       : in     HND.Node_Type;
  13152.     Lock       : in     Lock_Type;
  13153.     Key        : in     STRING;
  13154.     Owner      : in out SP.String_Type;
  13155.     Group      : in out SP.String_Type;
  13156.     Date       : in out SP.String_Type;
  13157.     Time       : in out SP.String_Type
  13158.     );
  13159.  
  13160. --| Effects:
  13161. --| Get the values of common lock attributes.
  13162.  
  13163. --------------------------------------------------------------------------------
  13164.  
  13165.     function Get_Item_Date_Time(
  13166.     Library : in SP.String_Type;
  13167.     Item    : in SP.String_Type;
  13168.     Version : in SP.String_Type
  13169.     ) return STRING;
  13170.  
  13171. --| Raises:
  13172. --| Invalid_Library_Name, Library_Does_Not_Exist, Item_Not_Found,
  13173. --| Invalid_Version, Version_Not_Found
  13174.  
  13175. --| Effects:
  13176. --| Return the create date and time (MM/DD/YY HH:MM:SS format) associated
  13177. --| with a version of an item in a library.
  13178.  
  13179. --------------------------------------------------------------------------------
  13180.  
  13181.     function Get_Current_Version(
  13182.     Node : in HND.Node_Type
  13183.     ) return STRING;
  13184.  
  13185. --| Raises:
  13186. --| Version_Not_Found
  13187.  
  13188. --| Effects:
  13189. --| Return a string of the current version number.
  13190.  
  13191. --------------------------------------------------------------------------------
  13192.  
  13193.     function Get_Version(
  13194.     Node    : in HND.Node_Type;
  13195.     Version : in SP.String_Type
  13196.     ) return SL.List;
  13197.  
  13198. --| Raises:
  13199. --| Invalid_Version, Version_Not_Found
  13200.  
  13201. --| Effects:
  13202. --| Return a list of version numbers of an item satifying the given condition.
  13203.  
  13204. --------------------------------------------------------------------------------
  13205.  
  13206.     procedure Iterate_Item(
  13207.     Library  : in     SP.String_Type;
  13208.     Item     : in     SP.String_Type;
  13209.     Iterator : in out HNM.Node_Iterator
  13210.     );
  13211.  
  13212. --| Raises:
  13213. --| Invalid_Library_Name, Library_Does_Not_Exist, Item_Not_Found
  13214.  
  13215. --| Effects:
  13216. --| Creates an iterator over all items satisfying the given codition. 
  13217.  
  13218. --------------------------------------------------------------------------------
  13219.  
  13220.     procedure Open_Property_Node(
  13221.     Library : in     SP.String_Type;
  13222.     Keyword : in     SP.String_Type;
  13223.     Value   : in     SP.String_Type;
  13224.     Mode    : in     Edit_Mode;
  13225.     Node    : in out HND.Node_Type
  13226.     );
  13227.  
  13228. --| Raises:
  13229. --| Invalid_Library_Name, Library_Does_Not_Exist, Invalid_Keyword,
  13230. --| Invalid_Value, Keyword_Not_Found, Keyword_Already_Exists
  13231.  
  13232. --| Effects:
  13233. --| Open the node handle for a node which has properties associated with it
  13234. --| for the given library
  13235.  
  13236. --------------------------------------------------------------------------------
  13237.  
  13238.     procedure Delete(
  13239.     Item_Node : in out HND.Node_Type;
  13240.     Versions  : in     SL.List;
  13241.     Privilege : in     Privilege_Type;
  13242.     Remainder : in out LL.List
  13243.     );
  13244.  
  13245. --| Raises:
  13246. --| Invalid_Version, Version_Not_Found
  13247.  
  13248.  
  13249. --| Effects:
  13250. --| Delete the given version(s) of an item (given as a node handle).  Return
  13251. --| a list of list(s) containing item and version number that were not deleted.
  13252.  
  13253. --------------------------------------------------------------------------------
  13254.  
  13255.     procedure Purge(
  13256.     Library   : in     SP.String_Type;
  13257.     Item      : in     SP.String_Type := SP.Create("*");
  13258.     Privilege : in     Privilege_Type;
  13259.     Remainder : in out LL.List
  13260.     );
  13261.  
  13262. --| Raises:
  13263. --| Invalid_Library_Name, Library_Does_Not_Exist, Item_Not_Found,
  13264. --| Invalid_Version, Version_Not_Found
  13265.  
  13266. --| Effects:
  13267. --| Purge the given item. Return a list of list(s) containing item and version
  13268. --| number that were not purged.
  13269.  
  13270. --------------------------------------------------------------------------------
  13271.  
  13272.     procedure Rename_Item(
  13273.     Library   : in SP.String_Type;
  13274.     From_Item : in SP.String_Type;
  13275.     To_Item   : in SP.String_Type;
  13276.     Privilege : in Privilege_Type;
  13277.     Remainder : in out LL.List
  13278.     );
  13279.  
  13280. --| Raises:
  13281. --| Invalid_Library_Name, Library_Does_Not_Exist, Item_Already_Exists,
  13282. --| Item_Not_Found, Item_Checked_Out
  13283.  
  13284. --| Effects:
  13285. --| Renames a given item in the item library.  Remainder is a list of lists
  13286. --| containing item/version of entities not renamed together with the reason.
  13287.  
  13288. --------------------------------------------------------------------------------
  13289.  
  13290.     procedure Rename_Version(
  13291.     Library      : in     SP.String_Type;
  13292.     Item         : in     SP.String_Type;
  13293.     From_Version : in     SP.String_Type;
  13294.     To_Version   : in     SP.String_Type;
  13295.     Privilege    : in     Privilege_Type;
  13296.     Remainder    : in out LL.List
  13297.     );
  13298.  
  13299. --| Raises:
  13300. --| Invalid_Library_Name, Library_Does_Not_Exist, Item_Not_Found,
  13301. --| Invalid_Version, Version_Not_Found
  13302.  
  13303. --| Effects:
  13304. --| Renames a given version of item(s) in the item library.  Remainder is a
  13305. --| list of lists containing item/version of entities not renamed together
  13306. --| with the reason.
  13307.  
  13308. --------------------------------------------------------------------------------
  13309.  
  13310.     function Privileged(
  13311.     Privilege : in Privilege_Type;
  13312.     Node      : in HND.Node_Type
  13313.     ) return BOOLEAN;
  13314.  
  13315. --| Effects:
  13316. --| Verify that the given node may be deleted (purged) in terms of 
  13317. --| ownership privileges.
  13318.  
  13319. --------------------------------------------------------------------------------
  13320.  
  13321.     function Privileged(
  13322.     Privilege : in Privilege_Type;
  13323.     Library   : in SP.String_Type;
  13324.     Item      : in SP.String_Type := SP.Create("");
  13325.     Version   : in STRING := ""
  13326.     ) return BOOLEAN;
  13327.  
  13328. --| Effects:
  13329. --| Verify that the given library, item in a library or a version of an item
  13330. --| in a library may be deleted (purged) in terms of ownership privileges.
  13331.  
  13332. --------------------------------------------------------------------------------
  13333.  
  13334.     function Get_Hif_File_Name(        --| return the hif file name for a Lib item
  13335.     Lib_Name : in SP.String_Type;    --| name of the Lib
  13336.     Item     : in SP.String_Type;    --| name of the item in the Lib
  13337.     Version  : in SP.String_Type    --| version number
  13338.     ) return SP.String_Type;
  13339.  
  13340. --| Effects:
  13341. --| Return the Hif file name for a particular version of a given item
  13342. --| in an item library.
  13343.  
  13344. --------------------------------------------------------------------------------
  13345.  
  13346.     function Is_Item_Checked_Out(    --| check if any items are checked out
  13347.     Library : in SP.String_Type    --| name of the library
  13348.     ) return BOOLEAN;
  13349.  
  13350. --| Raises:
  13351. --| Invalid_Library_Name, Library_Does_Not_Exist
  13352.  
  13353. --| Effects:
  13354. --| Return TRUE if any item is checked out for update in the specified library.
  13355.  
  13356. --------------------------------------------------------------------------------
  13357.  
  13358.     procedure Display_List(        --| display a list of lists
  13359.     List   : in out LL.List;    --| list of lists
  13360.     Header : in     STRING        --| display header
  13361.     );
  13362.  
  13363. --| Effects:
  13364. --| Write Header and contents of a list of lists
  13365.  
  13366. --------------------------------------------------------------------------------
  13367.  
  13368.     procedure Change_Checked_Out_Count(
  13369.     Library : SP.String_Type;
  13370.     Count   : INTEGER
  13371.     );
  13372.  
  13373. --| Effects:
  13374. --| Changes the checked out count
  13375.  
  13376. --------------------------------------------------------------------------------
  13377.  
  13378.     procedure Check_In_Item(
  13379.     Library   : in     SP.String_Type;
  13380.     File      : in     SP.String_Type;
  13381.     History   : in     SP.String_Type;
  13382.     Operation : in     Operation_Type;
  13383.     Returned  : in out SP.String_Type
  13384.     );
  13385.  
  13386. --| Effects:
  13387. --| Create/return/cancel an item checked out of the library
  13388.  
  13389. --------------------------------------------------------------------------------
  13390.  
  13391.     procedure Create_Library(
  13392.     Library   : in SP.String_Type;
  13393.     Directory : in SP.String_Type;
  13394.     CI        : in SP.String_Type := SP.Create("");
  13395.     Mode      : in Fetch_Type;
  13396.     Node      : in HND.Node_Type;
  13397.     Locked    : in BOOLEAN := FALSE
  13398.     );
  13399.  
  13400. --| Effects:
  13401. --| Create an item library
  13402.  
  13403. --------------------------------------------------------------------------------
  13404.  
  13405.     procedure Delete_Library(
  13406.     Library   : in SP.String_Type;
  13407.     Privilege : in Privilege_Type := WORLD
  13408.     );
  13409.  
  13410. --| Effects:
  13411. --| Delete an item library
  13412.  
  13413. --------------------------------------------------------------------------------
  13414.  
  13415.     function List_Item(
  13416.     Node    : in HND.Node_Type;
  13417.     Item    : in SP.String_Type := SP.Create("*");
  13418.     Version : in SP.String_Type := SP.Create("*");
  13419.     Mode    : in List_Mode := SHORT
  13420.     ) return LL.List;
  13421.  
  13422. --| Effects:
  13423. --| List item(s) of an item library
  13424.  
  13425. --------------------------------------------------------------------------------
  13426.  
  13427. end Library_Utilities;
  13428.                                                                     pragma page;
  13429. ::::::::::::::
  13430. listcat.ada
  13431. ::::::::::::::
  13432.  
  13433. --------- SPEC ----------------------------------------------------------
  13434.  
  13435. function list_catalogs return INTEGER;
  13436.  
  13437. --------- BODY ----------------------------------------------------------
  13438.  
  13439. with Standard_Interface;
  13440. with Tool_Identifier;
  13441. with String_Pkg;
  13442. with Host_Lib;
  13443. with catalog_interface;
  13444.  
  13445. function list_catalogs return INTEGER is
  13446.  
  13447.     package SP renames String_Pkg;
  13448.     package CI renames catalog_interface;
  13449.     package SI renames Standard_Interface;
  13450.  
  13451.     package input is new SI.String_Argument(    
  13452.     String_Type_Name => "string");        
  13453.  
  13454.  
  13455.     process      : SI.Process_Handle;    -- handle to process structure
  13456.     catalogs     : SP.string_type;    -- name of the catalog
  13457.  
  13458. begin
  13459.  
  13460.     SI.set_tool_identifier (Tool_Identifier);
  13461.     SI.Define_Process(            -- define this process
  13462.     Name    => "list_catalogs",    -- name of the process
  13463.     Help    => "List the names of all the catalogs in the document system",
  13464.     Proc    => process);        -- handle to be returned
  13465.  
  13466.     Input.Define_Argument(    -- define the first argument
  13467.     Proc     => Process,        -- process 
  13468.     Name     => "catalogs",        -- name of the argument
  13469.     Default => "*",
  13470.     Help     => "Search string for the name to match");
  13471.  
  13472.     SI.define_help (process,
  13473.     "A list of all the catalogs in the current document manager system");
  13474.     SI.append_help (process,
  13475.     "is produced.  The default is to list all catalogs, but a subset may");
  13476.     SI.append_help (process,
  13477.     "be selected by giving a pattern to match for catalogs.  The user");
  13478.     SI.append_help (process,
  13479.     "must be a document manager system user to run this tool (see Add_User)");
  13480.  
  13481.     SI.Parse_Line(Process);        -- parse the command line
  13482.  
  13483.     catalogs := Input.Get_Argument(    -- get the first argument
  13484.             Proc => Process,
  13485.             Name => "catalogs");
  13486.  
  13487.     SI.Undefine_Process(Proc => Process);    -- destroy the process block
  13488.  
  13489.     CI.list_catalogs (catalogs);
  13490.  
  13491.     return Host_Lib.Return_Code(Host_Lib.SUCCESS);-- return successful return code
  13492.  
  13493. exception
  13494.  
  13495.     when SI.Process_Help =>
  13496.     -- Help message was printed
  13497.     return Host_Lib.Return_Code(Host_Lib.INFORMATION);
  13498.     when SI.Abort_Process =>
  13499.     -- Parse error
  13500.     return Host_Lib.Return_Code(Host_Lib.ERROR);
  13501.  
  13502. end list_catalogs;
  13503. ::::::::::::::
  13504. listi.ada
  13505. ::::::::::::::
  13506. with Standard_Interface;
  13507. with String_Pkg;
  13508. with Host_Lib;
  13509. with Tool_Identifier;
  13510. with Library_Errors;
  13511. with Library_Declarations;
  13512. with List_Item_Interface;
  13513.  
  13514. function List_Item return INTEGER is
  13515.  
  13516.     package SI  renames Standard_Interface;
  13517.     package SP  renames String_Pkg;
  13518.     package HL  renames Host_Lib;
  13519.     package LE  renames Library_Errors;
  13520.     package LD  renames Library_Declarations;
  13521.     package LIB is new SI.String_Argument(String_Type_Name => "library_name");
  13522.     package ITM is new SI.String_Argument(String_Type_Name => "item_name");
  13523.     package VER is new SI.String_Argument(String_Type_Name => "version");
  13524.     package LIM is new SI.Enumerated_Argument(Enum_Type      => LD.List_Mode,
  13525.                           Enum_Type_Name => "list_mode");
  13526.  
  13527.     List_Item_Process : SI.Process_Handle;
  13528.     Library           : SP.String_Type;
  13529.     Item              : SP.String_Type;
  13530.     Version           : SP.String_Type;
  13531.     List_Item_Mode    : LD.List_Mode;
  13532.  
  13533. begin
  13534.  
  13535.     SP.Mark;
  13536.  
  13537.     SI.Set_Tool_Identifier(Identifier => Tool_Identifier);
  13538.  
  13539.     SI.Define_Process(
  13540.     Proc    => List_Item_Process,
  13541.     Name    => "List_Item",
  13542.     Help    => "List Item(s) in the Item Library");
  13543.  
  13544.     LIB.Define_Argument(
  13545.     Proc => List_Item_Process,
  13546.     Name => "library",
  13547.     Help => "Name of the item library");
  13548.  
  13549.     ITM.Define_Argument(
  13550.     Proc    => List_Item_Process,
  13551.     Name    => "item",
  13552.     Default => "*",
  13553.     Help    => "Name of the item to list");
  13554.  
  13555.     VER.Define_Argument(
  13556.     Proc    => List_Item_Process,
  13557.     Name    => "version",
  13558.     Default => "",
  13559.     Help    => "Version specification");
  13560.  
  13561.     LIM.Define_Argument(
  13562.     Proc    => List_Item_Process,
  13563.     Name    => "mode",
  13564.     Default => LD.SHORT,
  13565.     Help    => "List mode:");
  13566.  
  13567.     LIM.Append_Argument_Help(
  13568.     Proc    => List_Item_Process,
  13569.     Name    => "mode",
  13570.     Help    => "   SHORT : list item/version name(s) only");
  13571.  
  13572.     LIM.Append_Argument_Help(
  13573.     Proc    => List_Item_Process,
  13574.     Name    => "mode",
  13575.     Help    => "   LONG  : list attributes as well as item/version name(s)");
  13576.  
  13577.     SP.Release;
  13578.  
  13579.     SI.Parse_Line(List_Item_Process);
  13580.  
  13581.     Library := LIB.Get_Argument(
  13582.             Proc => List_Item_Process,
  13583.             Name => "library");
  13584.  
  13585.     Item := ITM.Get_Argument(
  13586.             Proc => List_Item_Process,
  13587.             Name => "item");
  13588.  
  13589.     Version := VER.Get_Argument(
  13590.             Proc => List_Item_Process,
  13591.             Name => "version");
  13592.  
  13593.     List_Item_Mode := LIM.Get_Argument(
  13594.             Proc => List_Item_Process,
  13595.             Name => "mode");
  13596.  
  13597.     return HL.Return_Code(List_Item_Interface(Library, Item, Version, List_Item_Mode));
  13598.  
  13599. exception
  13600.  
  13601.     when SI.Process_Help =>
  13602.     return HL.Return_Code(HL.INFORMATION);
  13603.  
  13604.     when SI.Abort_Process =>
  13605.     return HL.Return_Code(HL.ERROR);
  13606.  
  13607.     when others =>
  13608.     LE.Report_Error(LE.Internal_Error, SP.Create(""));
  13609.     return HL.Return_Code(HL.SEVERE);
  13610.  
  13611. end List_Item;
  13612.                                                                     pragma page;
  13613. ::::::::::::::
  13614. listi.bdy
  13615. ::::::::::::::
  13616. with Library_Declarations;            use Library_Declarations;
  13617. with Library_Errors;
  13618. with Library_Utilities;
  13619. with String_Lists;
  13620. with String_Utilities;
  13621. with HIF_Node_Defs;
  13622. with HIF_Node_Management;
  13623.  
  13624. function List_Item_Interface(
  13625.     Library : in String_Pkg.String_Type;
  13626.     Item    : in String_Pkg.String_Type;
  13627.     Version : in String_Pkg.String_Type;
  13628.     Mode    : in List_Mode := SHORT
  13629.     ) return Host_Lib.Severity_Code is
  13630.  
  13631.     package SP  renames String_Pkg;
  13632.     package HL  renames Host_Lib;
  13633.     package LE  renames Library_Errors;
  13634.     package LU  renames Library_Utilities;
  13635.     package SL  renames String_Lists;
  13636.     package SU  renames String_Utilities;
  13637.     package HND renames HIF_Node_Defs;
  13638.     package HNM renames HIF_Node_Management;
  13639.  
  13640.     IL_Node        : HND.Node_Type;
  13641.     List_of_Lists  : LL.List;
  13642.     List_Iter      : LL.ListIter;
  13643.     Value_List     : SL.List;
  13644.     Value_Iter     : SL.ListIter;
  13645.     Item_Value     : SP.String_Type;
  13646.     Version_Value  : SP.String_Type;
  13647.     Owner_Value    : SP.String_Type;
  13648.     Date_Value     : SP.String_Type;
  13649.     Time_Value     : SP.String_Type;
  13650.     Group_Value    : SP.String_Type;
  13651.     Status_Value   : SP.String_Type;
  13652.     Work_String    : SP.String_Type;
  13653.     Trap           : HL.Interrupt_State := HL.Get_Interrupt_State;
  13654.  
  13655. begin
  13656.  
  13657.     if HL."="(Trap, HL.DISABLED) then
  13658.     HL.Enable_Interrupt_Trap;
  13659.     end if;
  13660.     if not LU.Lock_Library(Library, READ_LOCK) then
  13661.     raise Library_Read_Locked;
  13662.     end if;
  13663.     HNM.Open_Node_Handle(Node => IL_Node,
  13664.              Name => SP.Value(LU.Node_Name(Library, SP.Create("*"))));
  13665.     begin
  13666.     List_of_Lists := LU.List_Item(IL_Node, Item, Version, Mode);
  13667.     exception
  13668.     when Item_Not_Found | Version_Not_Found =>
  13669.         null;
  13670.     end;
  13671.     LU.Unlock_Library(Library, READ_LOCK);
  13672.     HNM.Close_Node_Handle(IL_Node);
  13673.     if LL.IsEmpty(List_of_Lists) then
  13674.     if Message_on_Error then
  13675.         HL.Put_Message_Line("No item(s) found.");
  13676.     end if;
  13677.     HL.Set_Interrupt_State(Trap);
  13678.     return HL.SUCCESS;
  13679.     end if;
  13680.     if List_Mode'image(Mode) = "LONG" then
  13681.     HL.Put_Message_Line(
  13682.         SU.Left_Justify("Item Name/Version", Maximum_Item_Name) & ' ' &
  13683.         SU.Left_Justify("Owner", Maximum_Owner_Name) & ' ' &
  13684.         SU.Left_Justify("Group", Maximum_Group_Name) & ' ' &
  13685.         "Date    " & ' ' &
  13686.         "Time    " & ' ' &
  13687.         "Out");
  13688.     HL.Put_Message_Line(Separator);
  13689.     end if;
  13690.     List_Iter := LL.MakeListIter(List_of_Lists);
  13691.     while LL.More(List_Iter) loop
  13692.     LL.Next(List_Iter, Value_List);
  13693.     Value_Iter := SL.MakeListIter(Value_List);
  13694.     SP.Mark;
  13695.     SL.Next(Value_Iter, Item_Value);
  13696.     SL.Next(Value_Iter, Version_Value);
  13697.     Work_String := SP."&"(SP.Upper(Item_Value), "/");
  13698.     Work_String := SP."&"(Work_String, Version_Value);
  13699.     if List_Mode'image(Mode) = "LONG" then
  13700.         SL.Next(Value_Iter, Owner_Value);
  13701.         SL.Next(Value_Iter, Group_Value);
  13702.         SL.Next(Value_Iter, Date_Value);
  13703.         SL.Next(Value_Iter, Time_Value);
  13704.         SL.Next(Value_Iter, Status_Value);
  13705.         HL.Put_Message_Line(
  13706.         SU.Left_Justify(SP.Value(Work_String), Maximum_Item_Name) & ' ' &
  13707.         SU.Left_Justify(SP.Value(Owner_Value), Maximum_Owner_Name) & ' ' &
  13708.         SU.Left_Justify(SP.Value(Group_Value), Maximum_Group_Name) & ' ' &
  13709.         SP.Value(Date_Value) & ' ' &
  13710.         SP.Value(Time_Value) & ' ' &
  13711.         SP.Value(Status_Value));
  13712.     else
  13713.         HL.Put_Message_Line(SP.Value(Work_String));
  13714.     end if;
  13715.     SP.Release;
  13716.     end loop;
  13717.     Destroy_List_of_Lists(List_of_Lists);
  13718.     HL.Set_Interrupt_State(Trap);
  13719.     return HL.SUCCESS;
  13720.  
  13721. exception
  13722.  
  13723.     when Invalid_Library_Name =>
  13724.     LE.Report_Error(LE.Invalid_Library_Name, Library);
  13725.     HL.Set_Interrupt_State(Trap);
  13726.     return HL.ERROR;
  13727.  
  13728.     when Library_Does_Not_Exist =>
  13729.     LE.Report_Error(LE.Library_Does_Not_Exist, Library);
  13730.     HL.Set_Interrupt_State(Trap);
  13731.     return HL.ERROR;
  13732.  
  13733.     when Library_Master_Locked =>
  13734.     LE.Report_Error(LE.Library_Master_Locked, Library);
  13735.     HL.Set_Interrupt_State(Trap);
  13736.     return HL.ERROR;
  13737.  
  13738.     when Library_Read_Locked =>
  13739.     LE.Report_Error(LE.Library_Read_Locked, Library);
  13740.     HL.Set_Interrupt_State(Trap);
  13741.     return HL.ERROR;
  13742.  
  13743.     when Item_Not_Found =>
  13744.     LU.Unlock_Library(Library, READ_LOCK);
  13745.     HNM.Close_Node_Handle(IL_Node);
  13746.     LE.Report_Error(LE.Item_Not_Found, Item);
  13747.     HL.Set_Interrupt_State(Trap);
  13748.     return HL.ERROR;
  13749.  
  13750.     when Invalid_Version =>
  13751.     LU.Unlock_Library(Library, READ_LOCK);
  13752.     HNM.Close_Node_Handle(IL_Node);
  13753.     LE.Report_Error(LE.Invalid_Version, Version);
  13754.     HL.Set_Interrupt_State(Trap);
  13755.     return HL.ERROR;
  13756.  
  13757.     when Version_Not_Found =>
  13758.     LU.Unlock_Library(Library, READ_LOCK);
  13759.     HNM.Close_Node_Handle(IL_Node);
  13760.     LE.Report_Error(LE.Version_Not_Found, Version);
  13761.     HL.Set_Interrupt_State(Trap);
  13762.     return HL.ERROR;
  13763.  
  13764.     when HL.Interrupt_Encountered =>
  13765.     begin
  13766.         LU.Unlock_Library(Library, WRITE_LOCK);
  13767.     exception
  13768.         when others => null;
  13769.     end;
  13770.     if HL."="(Trap, HL.ENABLED) then
  13771.         raise HL.Interrupt_Encountered;
  13772.     end if;
  13773.     LE.Report_Error(LE.Process_Interrupted, SP.Create("List_Item"));
  13774.     HL.Set_Interrupt_State(Trap);
  13775.     return HL.WARNING;
  13776.  
  13777.     when others =>
  13778.     HNM.Close_Node_Handle(IL_Node);
  13779.     begin
  13780.         LU.Unlock_Library(Library, READ_LOCK);
  13781.     exception
  13782.         when others => null;
  13783.     end;
  13784.     LE.Report_Error(LE.Internal_Error, SP.Create("List_Item"));
  13785.     HL.Set_Interrupt_State(Trap);
  13786.     return HL.SEVERE;
  13787.  
  13788. end List_Item_Interface;
  13789.                                                                     pragma page;
  13790. ::::::::::::::
  13791. listi.spc
  13792. ::::::::::::::
  13793. with String_Pkg;
  13794. with Host_Lib;
  13795. with Library_Declarations;
  13796.  
  13797. function List_Item_Interface(            --| List Item(s)
  13798.    Library : in String_Pkg.String_Type;        --| Item library
  13799.    Item    : in String_Pkg.String_Type;        --| Item(s) to list
  13800.    Version : in String_Pkg.String_Type;        --| Version specification
  13801.    Mode    : in Library_Declarations.List_Mode := Library_Declarations.SHORT
  13802.                         --| List mode: (SHORT/LONG)
  13803.    ) return Host_Lib.Severity_Code;
  13804.  
  13805. --| Requires:
  13806. --| Name of the library, name of the item, and version specification
  13807.  
  13808. --| Effects:
  13809. --| List all items that satisfy the item and version specification in the
  13810. --| library.  List mode specifies a terse or a full listing
  13811.  
  13812. --| N/A: Modifies, Raises, Errors
  13813.                                                                     pragma page;
  13814. ::::::::::::::
  13815. listl.ada
  13816. ::::::::::::::
  13817. with Standard_Interface;
  13818. with String_Pkg;
  13819. with Host_Lib;
  13820. with Tool_Identifier;
  13821. with Library_Errors;
  13822. with List_Library_Interface;
  13823.  
  13824. function List_Library return INTEGER is
  13825.  
  13826.     package SI   renames Standard_Interface;
  13827.     package SP   renames String_Pkg;
  13828.     package HL   renames Host_Lib;
  13829.     package LE  renames Library_Errors;
  13830.     package LIB  is new SI.String_Argument(String_Type_Name => "library_name");
  13831.     package USER is new SI.String_Argument(String_Type_Name => "user_name");
  13832.  
  13833.     List_Library_Process   : SI.Process_Handle;
  13834.     Owner_Name             : SP.String_Type;
  13835.     Library                : SP.String_Type;
  13836.  
  13837. begin
  13838.  
  13839.     SP.Mark;
  13840.  
  13841.     SI.Set_Tool_Identifier(Identifier => Tool_Identifier);
  13842.  
  13843.     SI.Define_Process(
  13844.     Proc    => List_Library_Process,
  13845.     Name    => "List_Library",
  13846.     Help    => "List Libraries Owned by User");
  13847.  
  13848.     USER.Define_Argument(
  13849.     Proc    => List_Library_Process,
  13850.     Name    => "owner",
  13851.     Default => HL.Get_Item(HL.USER_NAME),
  13852.     Help    => "Name of the library owner");
  13853.  
  13854.     LIB.Define_Argument(
  13855.     Proc    => List_Library_Process,
  13856.     Name    => "library",
  13857.     Default => "*",
  13858.     Help    => "Name of the library");
  13859.  
  13860.     SI.Parse_Line(List_Library_Process);
  13861.  
  13862.     Owner_Name := USER.Get_Argument(
  13863.             Proc => List_Library_Process,
  13864.             Name => "owner");
  13865.  
  13866.     Library := LIB.Get_Argument(
  13867.             Proc => List_Library_Process,
  13868.             Name => "library");
  13869.  
  13870.     return HL.Return_Code(List_Library_Interface(Owner_Name, Library));
  13871.  
  13872. exception
  13873.  
  13874.     when SI.Process_Help =>
  13875.     return HL.Return_Code(HL.INFORMATION);
  13876.  
  13877.     when SI.Abort_Process =>
  13878.     return HL.Return_Code(HL.ERROR);
  13879.  
  13880.     when others =>
  13881.     LE.Report_Error(LE.Internal_Error, SP.Create(""));
  13882.     return HL.Return_Code(HL.SEVERE);
  13883.  
  13884. end List_Library;
  13885.                                                                     pragma page;
  13886. ::::::::::::::
  13887. listl.bdy
  13888. ::::::::::::::
  13889. with Library_Declarations;            use Library_Declarations;
  13890. with Library_Errors;
  13891. with Library_Utilities;
  13892. with String_Utilities;
  13893. with HIF_Utils;
  13894. with HIF_Node_Defs;
  13895. with HIF_Node_Management;
  13896. with HIF_Attributes;
  13897. with Document_Manager_Declarations;
  13898.  
  13899. function List_Library_Interface(
  13900.     User    : in String_Pkg.String_Type;
  13901.     Library : in String_Pkg.String_Type
  13902.     ) return Host_Lib.Severity_Code is
  13903.  
  13904.     package SP  renames String_Pkg;
  13905.     package HL  renames Host_Lib;
  13906.     package LE  renames Library_Errors;
  13907.     package LU  renames Library_Utilities;
  13908.     package SU  renames String_Utilities;
  13909.     package HU  renames HIF_Utils;
  13910.     package HND renames HIF_Node_Defs;
  13911.     package HNM renames HIF_Node_Management;
  13912.     package HA  renames HIF_Attributes;
  13913.     package DMD renames Document_Manager_Declarations;
  13914.  
  13915.     DOCMGR_Iterator     : HNM.Node_Iterator;
  13916.     DOCMGR_Node         : HND.Node_Type;
  13917.     Library_Node        : HND.Node_Type;
  13918.     Attribute_Value     : STRING(1 .. 64);
  13919.     Attribute_Length    : INTEGER;
  13920.     Mode_Value          : STRING(1 .. 64);
  13921.     Mode_Length         : INTEGER;
  13922.     Library_Name        : SP.String_Type;
  13923.     Item_Name           : SP.String_Type;
  13924.     Version_Name        : SP.String_Type;
  13925.     First               : BOOLEAN := TRUE;
  13926.     Trap                : HL.Interrupt_State := HL.Get_Interrupt_State;
  13927.  
  13928. begin
  13929.  
  13930.     if HL."="(Trap, HL.DISABLED) then
  13931.     HL.Enable_Interrupt_Trap;
  13932.     end if;
  13933.     HNM.Open_Node_Handle(Node => DOCMGR_Node,
  13934.              Name => DMD.Document_Manager_List_Path);
  13935.     HNM.Iterate(Iterator     => DOCMGR_Iterator,
  13936.         Node         => DOCMGR_Node,
  13937.         Relation     => "LIBRARY",
  13938.         Primary_Only => FALSE);
  13939.     while HNM.More(DOCMGR_Iterator) loop
  13940.     HNM.Get_Next(DOCMGR_Iterator, Library_Node);
  13941.     HU.Get_Node_Attribute(Library_Node, "OWNER", Attribute_Value, Attribute_Length);
  13942.     if SU.Match(SP.Value(User), Attribute_Value(1 .. Attribute_Length), Comparison => SP.CASE_INSENSITIVE) then
  13943.         LU.Parse_Node(Library_Node, Library_Name, Item_Name, Version_Name);
  13944.         if SU.Match(SP.Value(Library),
  13945.             LU.External_Name(SP.Value(Library_Name)),
  13946.             Comparison => SP.CASE_INSENSITIVE) then
  13947.         if First then
  13948.             HL.Put_Message_Line(
  13949.             SU.Left_Justify("Library Name", Maximum_Library_Name) & ' ' &
  13950.             SU.Left_Justify("Owner", Maximum_Owner_Name) & ' ' &
  13951.             "Date    " & ' ' &
  13952.             "Time    " & ' ' &
  13953.             SU.Left_Justify("CI Name", Maximum_CI_Name) & ' ' &
  13954.             "Mode");
  13955.             HL.Put_Message_Line(Separator);
  13956.             First := FALSE;
  13957.         end if;
  13958.         HL.Put_Message(SU.Left_Justify(LU.External_Name(SP.Value(Library_Name)), Maximum_Library_Name) & ' ');
  13959.         HL.Put_Message(SU.Left_Justify(Attribute_Value(1 .. Attribute_Length), Maximum_Owner_Name) & ' ');
  13960.         HU.Get_Node_Attribute(Library_Node, "DATE", Attribute_Value, Attribute_Length);
  13961.         HL.Put_Message(Attribute_Value(1 .. Attribute_Length) & ' ');
  13962.         HU.Get_Node_Attribute(Library_Node, "TIME", Attribute_Value, Attribute_Length);
  13963.         HL.Put_Message(Attribute_Value(1 .. Attribute_Length) & ' ');
  13964.         HU.Get_Node_Attribute(Library_Node, "CI", Attribute_Value, Attribute_Length);
  13965.         HU.Get_Node_Attribute(Library_Node, "MODE", Mode_Value, Mode_Length);
  13966.         if Fetch_Type'value(Mode_Value(1 .. Mode_Length)) = NO_UPDATE then
  13967.             HL.Put_Message_Line("");
  13968.         else
  13969.             HL.Put_Message(SU.Left_Justify(Attribute_Value(1 .. Attribute_Length), Maximum_CI_Name) & ' ');
  13970.             if Fetch_Type'value(Mode_Value(1 .. Mode_Length)) = UPDATE then
  13971.             HL.Put_Message_Line("TRUNK");
  13972.             else
  13973.             HL.Put_Message_Line("BRANCH");
  13974.             end if;
  13975.         end if;
  13976.         end if;
  13977.     end if;
  13978.     HNM.Close_Node_Handle(Library_Node);
  13979.     end loop;
  13980.     HNM.Close_Node_Handle(DOCMGR_Node);
  13981.     if First and then Message_on_Error then
  13982.     HL.Put_Message_Line(
  13983.         "No libraries " & SP.Value(SP.Upper(Library)) &
  13984.         " found for user " & SP.Value(SP.Upper(User)) & '.');
  13985.     end if;
  13986.     HL.Set_Interrupt_State(Trap);
  13987.     return HL.SUCCESS;
  13988.  
  13989. exception
  13990.  
  13991.     when HL.Interrupt_Encountered =>
  13992.     HNM.Close_Node_Handle(Library_Node);
  13993.     HNM.Close_Node_Handle(DOCMGR_Node);
  13994.     if HL."="(Trap, HL.ENABLED) then
  13995.         raise HL.Interrupt_Encountered;
  13996.     end if;
  13997.     LE.Report_Error(LE.Process_Interrupted, SP.Create("List_Library"));
  13998.     HL.Set_Interrupt_State(Trap);
  13999.     return HL.WARNING;
  14000.  
  14001.     when others =>
  14002.     HNM.Close_Node_Handle(Library_Node);
  14003.     HNM.Close_Node_Handle(DOCMGR_Node);
  14004.     LE.Report_Error(LE.Internal_Error, SP.Create("List_Library"));
  14005.     HL.Set_Interrupt_State(Trap);
  14006.     return HL.SEVERE;
  14007.  
  14008. end List_Library_Interface;
  14009.                                                                     pragma page;
  14010. ::::::::::::::
  14011. listl.spc
  14012. ::::::::::::::
  14013. with String_Pkg;
  14014. with Host_Lib;
  14015.  
  14016. function List_Library_Interface(        --| List Libraries Owned by User
  14017.    User    : in String_Pkg.String_Type;        --| Name of the library owner
  14018.    Library : in String_Pkg.String_Type        --| Name of the library
  14019.    ) return Host_Lib.Severity_Code;
  14020.  
  14021. --| Requires:
  14022. --| Name of the library and the owner
  14023.  
  14024. --| Effects:
  14025. --| List all libraries that satisfies the owner and library name specification 
  14026.  
  14027. --| N/A: Modifies, Raises, Errors
  14028.                                                                     pragma page;
  14029. ::::::::::::::
  14030. listp.ada
  14031. ::::::::::::::
  14032. with Standard_Interface;
  14033. with String_Pkg;
  14034. with Host_Lib;
  14035. with Item_Library_Manager;
  14036. with Item_Library_Manager_Declarations;
  14037. with String_Utilities;
  14038. with String_Lists;
  14039.  
  14040. function List_Property return INTEGER is
  14041.  
  14042.     package SI  renames Standard_Interface;
  14043.     package SP  renames String_Pkg;
  14044.     package SL  renames String_Lists;
  14045.     package HL  renames Host_Lib;
  14046.     package ILM renames Item_Library_Manager;
  14047.     package ILD renames Item_Library_Manager_Declarations;
  14048.     package SU  renames String_Utilities;
  14049.     package GSU is new SU.Generic_String_Utilities(SP.String_Type,
  14050.                            SP.Create,
  14051.                            SP.Value);
  14052.  
  14053.     package LIB is new SI.String_Argument(
  14054.                 String_Type_Name => "library_name");
  14055.     package STR is new SI.String_Argument(
  14056.                 String_Type_Name => "string");
  14057.  
  14058.     List_Property_Process : SI.Process_Handle;
  14059.     Library                : SP.String_Type;
  14060.     Keyword                : SP.String_Type;
  14061.     List                   : ILD.LL.List;
  14062.     List_Iter              : ILD.LL.ListIter;
  14063.     Value_List             : SL.List;
  14064.     Value_Iter             : SL.ListIter;
  14065.     Work_String            : SP.String_Type;
  14066.  
  14067. begin
  14068.  
  14069.     SP.Mark;
  14070.  
  14071.     SI.Set_Tool_Identifier(Identifier => "1.0");
  14072.  
  14073.     SI.Define_Process(
  14074.     Proc    => List_Property_Process,
  14075.     Name    => "List_Property",
  14076.     Help    => "List Property Keyword/Value in the Item Library");
  14077.  
  14078.     LIB.Define_Argument(
  14079.     Proc => List_Property_Process,
  14080.     Name => "library",
  14081.     Help => "Name of the item library");
  14082.  
  14083.     STR.Define_Argument(
  14084.     Proc    => List_Property_Process,
  14085.     Name    => "keyword",
  14086.     Default => "*",
  14087.     Help    => "Property keyword");
  14088.  
  14089.     SP.Release;
  14090.  
  14091.     SI.Parse_Line(List_Property_Process);
  14092.  
  14093.     Library := LIB.Get_Argument(
  14094.             Proc => List_Property_Process,
  14095.             Name => "library");
  14096.  
  14097.     Keyword := STR.Get_Argument(
  14098.             Proc => List_Property_Process,
  14099.             Name => "keyword");
  14100.  
  14101.     List := ILM.List_Property(Library, Keyword);
  14102.  
  14103.     List_Iter := ILD.LL.MakeListIter(List);
  14104.     while ILD.LL.More(List_Iter) loop
  14105.     ILD.LL.Next(List_Iter, Value_List);
  14106.     Value_Iter := SL.MakeListIter(Value_List);
  14107.     SP.Mark;
  14108.     SL.Next(Value_Iter, Work_String);
  14109.     HL.Put_Message(GSU.Left_Justify(Work_String, ILD.Maximum_Keyword));
  14110.     HL.Put_Message(" : ");
  14111.     SL.Next(Value_Iter, Work_String);
  14112.     HL.Put_Message_Line(SP.Value(Work_String));
  14113.     SP.Release;
  14114.     end loop;
  14115.     ILD.Destroy_List_of_Lists(List);
  14116.     return HL.Return_Code(HL.SUCCESS);
  14117.  
  14118. exception
  14119.  
  14120.     when SI.Process_Help =>
  14121.     return HL.Return_Code(HL.INFORMATION);
  14122.  
  14123.     when SI.Abort_Process =>
  14124.     return HL.Return_Code(HL.SUCCESS);
  14125.  
  14126.     when ILD.Library_Does_Not_Exist =>
  14127.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ does not exist.");
  14128.     return HL.Return_Code(HL.ERROR);
  14129.  
  14130.     when ILD.Library_Master_Locked =>
  14131.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is master locked.");
  14132.     return HL.Return_Code(HL.ERROR);
  14133.  
  14134.     when ILD.Library_Write_Locked =>
  14135.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is write locked.");
  14136.     return HL.Return_Code(HL.ERROR);
  14137.  
  14138.     when ILD.Library_Read_Locked =>
  14139.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is read locked.");
  14140.     return HL.Return_Code(HL.ERROR);
  14141.  
  14142.     when ILD.Invalid_Keyword =>
  14143.         HL.Put_Error("Property keyword """ & SP.Value(SP.Upper(Keyword)) & """ invalid.");
  14144.     return HL.Return_Code(HL.ERROR);
  14145.  
  14146.     when ILD.Keyword_Not_Found =>
  14147.         HL.Put_Error("Property keyword """ & SP.Value(SP.Upper(Keyword)) &
  14148.              """ not found.");
  14149.     return HL.Return_Code(HL.ERROR);
  14150.  
  14151.     when ILD.Not_Authorized =>
  14152.     HL.Put_Error("Not authorized.");
  14153.     return HL.Return_Code(HL.ERROR);
  14154.  
  14155.     when ILD.No_Privilege =>
  14156.     HL.Put_Error("No privilege for attempted operation.");
  14157.     return HL.Return_Code(HL.ERROR);
  14158.  
  14159.     when others =>
  14160.     HL.Put_Error("List Property internal error.");
  14161.     return HL.Return_Code(HL.SEVERE);
  14162.  
  14163. end List_Property;
  14164.  
  14165. ::::::::::::::
  14166. listp.bdy
  14167. ::::::::::::::
  14168. with Library_Declarations;            use Library_Declarations;
  14169. with Library_Errors;
  14170. with Library_Utilities;
  14171. with String_Utilities;
  14172. with HIF_Node_Defs;
  14173. with HIF_Node_Management;
  14174. with HIF_Attributes;
  14175. with HIF_List_Utils;
  14176.  
  14177. function List_Property_Interface(
  14178.     Library : in String_Pkg.String_Type;
  14179.     Keyword : in String_Pkg.String_Type
  14180.     ) return Host_Lib.Severity_Code is
  14181.  
  14182.     package SP  renames String_Pkg;
  14183.     package HL  renames Host_Lib;
  14184.     package LE  renames Library_Errors;
  14185.     package LU  renames Library_Utilities;
  14186.     package SU  renames String_Utilities;
  14187.     package HND renames HIF_Node_Defs;
  14188.     package HNM renames HIF_Node_Management;
  14189.     package HA  renames HIF_Attributes;
  14190.     package HLU renames HIF_List_Utils;
  14191.  
  14192.     Node             : HND.Node_Type;
  14193.     Iterator         : HA.Attrib_Iterator;
  14194.     Property_List    : HLU.List_Type;
  14195.     Attribute_Value  : STRING(1 .. 64);
  14196.     Attribute_Length : INTEGER;
  14197.     Trap             : HL.Interrupt_State := HL.Get_Interrupt_State;
  14198.  
  14199. begin
  14200.  
  14201.     if HL."="(Trap, HL.DISABLED) then
  14202.     HL.Enable_Interrupt_Trap;
  14203.     end if;
  14204.     if not LU.Lock_Library(Library, READ_LOCK) then
  14205.     raise Library_Read_Locked;
  14206.     end if;
  14207.     LU.Open_Property_Node(Library, SP.Create(""), SP.Create(""), LIST, Node);
  14208.  
  14209.     begin
  14210.     HA.Node_Attribute_Iterate(Iterator, Node, SP.Value(Keyword));
  14211.     exception
  14212.     when HND.Name_Error =>
  14213.         raise Invalid_Keyword;
  14214.     end;
  14215.  
  14216.     HNM.Close_Node_Handle(Node);
  14217.  
  14218.     if HA.More(Iterator) then
  14219.     HL.Put_Message(SU.Left_Justify("Keyword", Maximum_Keyword));
  14220.     HL.Put_Message_Line("   Value");
  14221.     HL.Put_Message_Line(Separator);
  14222.     elsif Message_on_Error then
  14223.     HL.Put_Message_Line("Propery " &
  14224.                 SU.Left_Justify("Keyword", Maximum_Keyword) &
  14225.                 " not found.");
  14226.     LU.Unlock_Library(Library, READ_LOCK);
  14227.     HL.Set_Interrupt_State(Trap);
  14228.     return HL.SUCCESS;
  14229.     end if;
  14230.  
  14231.     while HA.More(Iterator) loop
  14232.     HA.Get_Next(Iterator, Attribute_Value, Attribute_Length, Property_List);
  14233.     HL.Put_Message(SU.Left_Justify(
  14234.         Attribute_Value(1 .. Attribute_Length), Maximum_Keyword));
  14235.     HL.Put_Message(" : ");
  14236.     HL.Put_Message_Line(HLU.Item_Image(
  14237.         HLU.Positional(Property_List, HLU.Positive_Count(1))));
  14238.     end loop;
  14239.     LU.Unlock_Library(Library, READ_LOCK);
  14240.     HL.Set_Interrupt_State(Trap);
  14241.     return HL.SUCCESS;
  14242.  
  14243. exception
  14244.  
  14245.     when Invalid_Library_Name =>
  14246.     LE.Report_Error(LE.Invalid_Library_Name, Library);
  14247.     HL.Set_Interrupt_State(Trap);
  14248.     return HL.ERROR;
  14249.  
  14250.     when Library_Does_Not_Exist =>
  14251.     LE.Report_Error(LE.Library_Does_Not_Exist, Library);
  14252.     HL.Set_Interrupt_State(Trap);
  14253.     return HL.ERROR;
  14254.  
  14255.     when Library_Master_Locked =>
  14256.     LE.Report_Error(LE.Library_Master_Locked, Library);
  14257.     HL.Set_Interrupt_State(Trap);
  14258.     return HL.ERROR;
  14259.  
  14260.     when Library_Read_Locked =>
  14261.     LE.Report_Error(LE.Library_Read_Locked, Library);
  14262.     HL.Set_Interrupt_State(Trap);
  14263.     return HL.ERROR;
  14264.  
  14265.     when Invalid_Keyword =>
  14266.     LU.Unlock_Library(Library, WRITE_LOCK);
  14267.     LE.Report_Error(LE.Invalid_Keyword, Keyword);
  14268.     HL.Set_Interrupt_State(Trap);
  14269.     return HL.ERROR;
  14270.  
  14271.     when No_Privilege =>
  14272.     LU.Unlock_Library(Library, WRITE_LOCK);
  14273.     LE.Report_Error(LE.No_Privilege, Library, SP.Create(LU.Get_Library_Attribute(Library, "OWNER")));
  14274.     HL.Set_Interrupt_State(Trap);
  14275.     return HL.ERROR;
  14276.  
  14277.     when HL.Interrupt_Encountered =>
  14278.     begin
  14279.         LU.Unlock_Library(Library, WRITE_LOCK);
  14280.     exception
  14281.         when others => null;
  14282.     end;
  14283.     if HL."="(Trap, HL.ENABLED) then
  14284.         raise HL.Interrupt_Encountered;
  14285.     end if;
  14286.     LE.Report_Error(LE.Process_Interrupted, SP.Create("List_Property"));
  14287.     HL.Set_Interrupt_State(Trap);
  14288.     return HL.WARNING;
  14289.  
  14290.     when others =>
  14291.     begin
  14292.         LU.Unlock_Library(Library, WRITE_LOCK);
  14293.     exception
  14294.         when others => null;
  14295.     end;
  14296.     LE.Report_Error(LE.Internal_Error, SP.Create("List_Property"));
  14297.     HL.Set_Interrupt_State(Trap);
  14298.     return HL.SEVERE;
  14299.  
  14300. end List_Property_Interface;
  14301.                                                                     pragma page;
  14302. ::::::::::::::
  14303. listp.spc
  14304. ::::::::::::::
  14305. with String_Pkg;
  14306. with Host_Lib;
  14307.  
  14308. function List_Property_Interface(        --| List Property Keyword/Value in the Item Library
  14309.     Library : in String_Pkg.String_Type;    --| Item library
  14310.     Keyword : in String_Pkg.String_Type        --| Property keyword
  14311.     ) return Host_Lib.Severity_Code;
  14312.  
  14313. --| Requires:
  14314. --| The names of the library, and the keyword.
  14315.  
  14316. --| Effects:
  14317. --| Returns the value associated with the keyword.
  14318. --| If any wildcard characters are specified in the keyword, all keyword
  14319. --| value pairs satisfying the specification are returned.
  14320.  
  14321. --| N/A: Modifies, Raises, Errors
  14322.                                                                     pragma page;
  14323. ::::::::::::::
  14324. lmutils.bdy
  14325. ::::::::::::::
  14326. with String_Utilities;
  14327. with HIF_Attributes;
  14328. with HIF_List_Utils;
  14329. with Host_Lib;
  14330. with Hif_Host_File_Management;
  14331.  
  14332. package body Item_Library_Manager_Utilities is
  14333.  
  14334.     package SU  renames String_Utilities;
  14335.     package SS  is new SU.Generic_String_Utilities(
  14336.             SP.String_Type,
  14337.             SP.Make_Persistent,
  14338.             SP.Value);
  14339.     package HA  renames HIF_Attributes;
  14340.     package HLU renames HIF_List_Utils;
  14341.     package HL  renames Host_Lib;
  14342.     package HFM renames Hif_Host_File_Management;
  14343.  
  14344.     subtype Valid_Character      is CHARACTER range ' ' .. '~';
  14345.     subtype Digit                is CHARACTER range '0' .. '9';
  14346.     subtype Lower_Alphabet       is CHARACTER range 'a' .. 'z';
  14347.     subtype Upper_Alphabet       is CHARACTER range 'A' .. 'Z';
  14348.     
  14349.     Substitute_Character    : constant CHARACTER := 'Z';
  14350.     Privilege_Reason        : constant STRING    := "PRIVILEGE";
  14351.     Version_Exists_Reason   : constant STRING    := "NAME_CONFLICT";
  14352.     Item_Checked_Out_Reason : constant STRING    := "CHECKED_OUT";
  14353.  
  14354. --------------------------------------------------------------------------------
  14355.  
  14356.     function Internal_Name(
  14357.     External_Name : in SP.String_Type;
  14358.     Exclude       : in STRING := ""
  14359.     ) return STRING is
  14360.  
  14361.     Translate           : BOOLEAN;
  14362.     Internal_Name       : STRING(1 .. 256) := (others => ' ');
  14363.     Internal_Name_Index : INTEGER := 1;
  14364.     External_Character  : Valid_Character;
  14365.  
  14366.     begin
  14367.  
  14368.     for i in 1 .. SP.Length(External_Name) loop
  14369.         begin
  14370.         External_Character := SP.Fetch(External_Name, i);
  14371.         exception
  14372.         when CONSTRAINT_ERROR =>
  14373.             raise Invalid_External_Name;
  14374.         end;
  14375.  
  14376.         Translate := TRUE;
  14377.  
  14378.         begin
  14379.         External_Character := Digit'(External_Character);
  14380.         Translate := FALSE;
  14381.         if i = 1 then
  14382.             Internal_Name(1 .. 3) := Substitute_Character & "00";
  14383.             Internal_Name_Index := 4;
  14384.         end if;
  14385.         exception
  14386.         when CONSTRAINT_ERROR => null;
  14387.         end;
  14388.  
  14389.         if Translate then
  14390.         begin
  14391.             External_Character := Lower_Alphabet'(External_Character);
  14392.             Translate := FALSE;
  14393.         exception
  14394.             when CONSTRAINT_ERROR => null;
  14395.         end;
  14396.         end if;
  14397.  
  14398.         if Translate then
  14399.         begin
  14400.             External_Character := Upper_Alphabet'(External_Character);
  14401.             Translate := FALSE;
  14402.         exception
  14403.             when CONSTRAINT_ERROR => null;
  14404.         end;
  14405.         end if;
  14406.  
  14407.         if Translate then
  14408.         for k in Exclude'range loop
  14409.             if External_Character = Exclude(k) then
  14410.             Translate := FALSE;
  14411.             exit;
  14412.             end if;
  14413.         end loop;
  14414.         end if;
  14415.  
  14416.         if Translate then
  14417.         Internal_Name(Internal_Name_Index .. Internal_Name_Index+2) := 
  14418.             Substitute_Character &
  14419.             SU.Image(
  14420.             CHARACTER'pos(External_Character) - CHARACTER'pos(Valid_Character'first) + 1,
  14421.             2,
  14422.             '0');
  14423.         Internal_Name_Index := Internal_Name_Index + 3;
  14424.         else
  14425.         Internal_Name(Internal_Name_Index) := External_Character;
  14426.         Internal_Name_Index := Internal_Name_Index + 1;
  14427.         end if;
  14428.     end loop;
  14429.     return Internal_Name(1 .. Internal_Name_Index-1);
  14430.  
  14431.     end Internal_Name;
  14432.  
  14433. --------------------------------------------------------------------------------
  14434.  
  14435.     function External_Name(
  14436.     Internal_Name : in STRING
  14437.     ) return STRING is
  14438.  
  14439.     External_Name       : STRING(1 .. 256) := (others => ' ');
  14440.     External_Name_Index : INTEGER := 1;
  14441.     Internal_Name_Index : INTEGER := Internal_Name'first;
  14442.  
  14443.     begin
  14444.  
  14445.     while Internal_Name_Index <= Internal_Name'last loop
  14446.         if Internal_Name(Internal_Name_Index) = Substitute_Character then
  14447.         begin
  14448.             if NATURAL'value(Internal_Name(Internal_Name_Index+1 .. Internal_Name_Index+2)) /= 0 then
  14449.             External_Name(External_Name_Index) :=
  14450.                 Valid_Character'val(
  14451.                 NATURAL'value(
  14452.                     Internal_Name(Internal_Name_Index+1 .. Internal_Name_Index+2)) +
  14453.                     CHARACTER'pos(Valid_Character'first) -
  14454.                     1);
  14455.             External_Name_Index := External_Name_Index + 1;
  14456.             end if;
  14457.             Internal_Name_Index := Internal_Name_Index + 2;
  14458.         exception
  14459.             when CONSTRAINT_ERROR =>
  14460.             External_Name(External_Name_Index) := Substitute_Character;
  14461.             External_Name_Index := External_Name_Index + 1;
  14462.         end;
  14463.         else
  14464.         External_Name(External_Name_Index) :=
  14465.             Internal_Name(Internal_Name_Index);
  14466.         External_Name_Index := External_Name_Index + 1;
  14467.         end if;
  14468.         Internal_Name_Index := Internal_Name_Index + 1;
  14469.     end loop;
  14470.     return External_Name(1 .. External_Name_Index-1);
  14471.  
  14472.     end External_Name;
  14473.  
  14474. --------------------------------------------------------------------------------
  14475.  
  14476.     procedure Is_Node(
  14477.     Node : in out HND.Node_Type;
  14478.     Name : in     SP.String_Type
  14479.     ) is
  14480.  
  14481.  
  14482.     begin
  14483.  
  14484.     if HNM.Is_Open(Node) then
  14485.         HNM.Close_Node_Handle(Node => Node);
  14486.     end if;
  14487.     HNM.Open_Node_Handle(Node => Node,
  14488.                  Name => SP.Value(Name));
  14489.  
  14490.     exception
  14491.     when others =>
  14492.         HNM.Close_Node_Handle(Node => Node);
  14493.  
  14494.     end Is_Node;
  14495.  
  14496. --------------------------------------------------------------------------------
  14497.  
  14498.     function Node_Name(
  14499.     Library : in SP.String_Type;
  14500.     Item    : in SP.String_Type := SP.Create("");
  14501.     Version : in STRING := ""
  14502.     ) return SP.String_Type is
  14503.  
  14504.     begin
  14505.  
  14506.     if SP.Equal(Item, "") then
  14507.         return SP.Create("'USER(" &
  14508.                  Internal_Name(Library) &
  14509.                  ')');
  14510.     elsif SP.Equal(Item, "*") then
  14511.         return SP.Create("'USER(" &
  14512.                  Internal_Name(Library) &
  14513.                  ").IL");
  14514.     elsif Version = "" then
  14515.         return SP.Create("'USER(" &
  14516.                  Internal_Name(Library) &
  14517.                  ").IL." &
  14518.                  Internal_Name(Item));
  14519.     else
  14520.         return SP.Create("'USER(" &
  14521.                  Internal_Name(Library) &
  14522.                  ").IL." &
  14523.                  Internal_Name(Item) &
  14524.                  ".V" & Version);
  14525.     end if;
  14526.  
  14527.     end Node_Name;
  14528.  
  14529. --------------------------------------------------------------------------------
  14530.  
  14531.     procedure Parse_Node(
  14532.     Node    : in     HND.Node_Type;
  14533.     Library :    out SP.String_Type;
  14534.     Item    :    out SP.String_Type;
  14535.     Version :    out SP.String_Type
  14536.     ) is
  14537.  
  14538.     Scanner : SU.Scanner;
  14539.     Temp    : SP.String_Type;
  14540.     Found   : BOOLEAN;
  14541.  
  14542.     begin
  14543.  
  14544.     Scanner := SS.Make_Scanner(SP.Upper(HNM.Primary_Name(Node)));
  14545.  
  14546.     SS.Scan_Literal("'USER", Scanner, Found);
  14547.     if not Found then
  14548.         SU.Destroy_Scanner(Scanner);
  14549.         return;
  14550.     end if;
  14551.     SS.Scan_Enclosed('(', ')', Scanner, Found, Temp);
  14552.     if not Found then
  14553.         SU.Destroy_Scanner(Scanner);
  14554.         return;
  14555.     end if;
  14556.     Library := SP.Make_Persistent(External_Name(SP.Value(Temp)));
  14557.     SP.Flush(Temp);
  14558.  
  14559.     SU.Backward(Scanner);
  14560.     SS.Scan_Not_Literal("'DOT(IL)", Scanner, Found, Temp);
  14561.     if not Found then
  14562.         SS.Scan_Not_Literal("'DOT(CI)", Scanner, Found, Temp);
  14563.         if not Found then
  14564.         SU.Destroy_Scanner(Scanner);
  14565.         return;
  14566.         else
  14567.         SS.Scan_Literal("'DOT(CI)", Scanner, Found);
  14568.         end if;
  14569.     else
  14570.         SS.Scan_Literal("'DOT(IL)", Scanner, Found);
  14571.     end if;
  14572.     SP.Flush(Temp);
  14573.  
  14574.     SS.Scan_Not_Literal("(", Scanner, Found, Temp);
  14575.     if not Found then
  14576.         SU.Destroy_Scanner(Scanner);
  14577.         return;
  14578.     end if;
  14579.     SP.Flush(Temp);
  14580.     SS.Scan_Enclosed('(', ')', Scanner, Found, Temp);
  14581.     if not Found then
  14582.         SU.Destroy_Scanner(Scanner);
  14583.         return;
  14584.     end if;
  14585.     Item := SP.Make_Persistent(External_Name(SP.Value(Temp)));
  14586.     SP.Flush(Temp);
  14587.  
  14588.     SS.Scan_Not_Literal("(", Scanner, Found, Temp);
  14589.     if not Found then
  14590.         SU.Destroy_Scanner(Scanner);
  14591.         return;
  14592.     end if;
  14593.     SP.Flush(Temp);
  14594.     SS.Scan_Enclosed('(', ')', Scanner, Found, Temp);
  14595.     if not Found then
  14596.         SU.Destroy_Scanner(Scanner);
  14597.         return;
  14598.     end if;
  14599.     Version := SP.Make_Persistent(SP.Substr(Temp, 2, SP.Length(Temp)-1));
  14600.     SP.Flush(Temp);
  14601.     SU.Destroy_Scanner(Scanner);
  14602.  
  14603.     end Parse_Node;
  14604.  
  14605. --------------------------------------------------------------------------------
  14606.  
  14607.     function Is_Ada_Id(
  14608.     Value : in SP.String_Type
  14609.     ) return BOOLEAN is
  14610.  
  14611.     Scanner : SU.Scanner;
  14612.     Ada_Id  : SP.String_Type;
  14613.     Found   : BOOLEAN;
  14614.  
  14615.     begin
  14616.  
  14617.     Scanner := SS.Make_Scanner(Value);
  14618.     SS.Scan_Ada_Id(Scanner, Found, Ada_Id, Skip => FALSE);
  14619.     SP.Flush(Ada_Id);
  14620.     Found := Found and not SU.More(Scanner);
  14621.     SU.Destroy_Scanner(Scanner);
  14622.     return Found;
  14623.  
  14624.     end Is_Ada_Id;
  14625.  
  14626. --------------------------------------------------------------------------------
  14627.  
  14628.     procedure Is_Library(
  14629.     Node    : in out HND.Node_Type;
  14630.     Library : in     SP.String_Type
  14631.     ) is
  14632.  
  14633.     Owner_Value  : STRING(1 .. Maximum_Owner_Name);
  14634.     Owner_Length : INTEGER;
  14635.  
  14636.  
  14637.     begin
  14638.  
  14639.     if not Is_Ada_Id(Library) then
  14640.         raise Invalid_Library_Name;
  14641.     end if;
  14642.     Is_Node(Node, Node_Name(Library));
  14643.     if not HNM.Is_Open(Node) then
  14644.         return;
  14645.     end if;
  14646.     HA.Get_Node_Attribute(Node       => Node,
  14647.                   Attrib     => "OWNER",
  14648.                   Value      => Owner_Value,
  14649.                   Value_Last => Owner_Length);
  14650.     if Owner_Length = 0 then
  14651.         HNM.Close_Node_Handle(Node);
  14652.     end if;
  14653.  
  14654.     end Is_Library;
  14655.  
  14656. --------------------------------------------------------------------------------
  14657.  
  14658.     procedure Is_Item(
  14659.     Node    : in out HND.Node_Type;
  14660.     Library : in     SP.String_Type;
  14661.     Item    : in     SP.String_Type
  14662.     ) is
  14663.  
  14664.     begin
  14665.  
  14666.     Is_Library(Node, Library);
  14667.     if not HNM.Is_Open(Node) then
  14668.         raise Library_Does_Not_Exist;
  14669.     end if;
  14670.     Is_Node(Node, Node_Name(Library, Item));
  14671.  
  14672.     end Is_Item;
  14673.  
  14674. --------------------------------------------------------------------------------
  14675.  
  14676.     procedure Is_Version(
  14677.     Node    : in out HND.Node_Type;
  14678.     Library : in     SP.String_Type;
  14679.     Item    : in     SP.String_Type;
  14680.     Version : in     SP.String_Type
  14681.     ) is
  14682.  
  14683.     Found     : BOOLEAN;
  14684.     Versions  : SL.List := SL.Create;
  14685.  
  14686.     begin
  14687.  
  14688.     Is_Node(Node, Node_Name(Library, Item));
  14689.     if not HNM.Is_Open(Node) then
  14690.         raise Item_Not_Found;
  14691.     end if;
  14692.     Versions := Get_Version(Node, Version);
  14693.     if SL.Length(Versions) = 1 then
  14694.         Is_Node(Node,
  14695.             Node_Name(Library,
  14696.                   Item,
  14697.                   SP.Value(SL.FirstValue(Versions))));
  14698.     else
  14699.         HNM.Close_Node_Handle(Node => Node);
  14700.     end if;
  14701.     Destroy_String_List(Versions);
  14702.  
  14703.     end Is_Version;
  14704.  
  14705. --------------------------------------------------------------------------------
  14706.  
  14707.     function Is_Checked_Out(
  14708.     Item_Node : in HND.Node_Type
  14709.     ) return BOOLEAN is
  14710.  
  14711.     Attribute_Value  : STRING(1 .. 16);
  14712.     Attribute_Length : INTEGER;
  14713.  
  14714.     begin
  14715.  
  14716.     HA.Get_Node_Attribute(Node       => Item_Node,
  14717.                   Attrib     => "MODE",
  14718.                   Value      => Attribute_Value,
  14719.                   Value_Last => Attribute_Length);
  14720.     return Attribute_Value(1 .. Attribute_Length) = State_Type'image(UPDATE);
  14721.  
  14722.     end;
  14723.  
  14724. --------------------------------------------------------------------------------
  14725.  
  14726.     function Lock_Library(
  14727.     Node : in HND.Node_Type;
  14728.     Lock : in Lock_Type
  14729.     ) return BOOLEAN is
  14730.  
  14731.     Was_Locked : BOOLEAN;
  14732.     Iterator   : HNM.Node_Iterator;
  14733.  
  14734.     begin
  14735.  
  14736.     if Lock = MASTER_LOCK then
  14737.         begin
  14738.         HNM.Link(To_Node  => Node,
  14739.              New_Base => Node,
  14740.              Relation => Lock_Type'image(Lock));
  14741.         exception
  14742.         when others =>
  14743.             raise Library_Master_Locked;
  14744.         end;
  14745.         Set_Lock_Attributes(Node, Lock, "");
  14746.         return TRUE;
  14747.     end if;
  14748.  
  14749.     begin
  14750.         HNM.Link(To_Node  => Node,
  14751.              New_Base => Node,
  14752.              Relation => Lock_Type'image(MASTER_LOCK));
  14753.     exception
  14754.         when others =>
  14755.         raise Library_Master_Locked;
  14756.     end;
  14757.  
  14758.     begin
  14759.         HNM.Unlink(Base     => Node,
  14760.                Relation => Lock_Type'image(MASTER_LOCK));
  14761.     exception
  14762.         when others =>
  14763.         null;
  14764.     end;
  14765.  
  14766.     Was_Locked := TRUE;
  14767.     for i in 1 .. Retry_Count loop
  14768.         begin
  14769.         HNM.Link(To_Node  => Node,
  14770.              New_Base => Node,
  14771.              Relation => Lock_Type'image(WRITE_LOCK));
  14772.         Was_Locked := FALSE;
  14773.         exit;
  14774.         exception
  14775.         when others =>
  14776.             null;
  14777.         end;
  14778.     end loop;
  14779.  
  14780.     if Was_Locked then
  14781.         return FALSE;
  14782.     end if;
  14783.  
  14784.     if Lock = WRITE_LOCK then
  14785.         HNM.Iterate(Iterator     => Iterator, 
  14786.             Node         => Node,
  14787.             Relation     => Lock_Type'image(READ_LOCK),
  14788.             Primary_Only => FALSE);
  14789.         if HNM.More(Iterator) then
  14790.         begin
  14791.             HNM.Unlink(Base     => Node,
  14792.                    Relation => Lock_Type'image(Lock));
  14793.         exception
  14794.             when others =>
  14795.             null;
  14796.         end;
  14797.         return FALSE;
  14798.         end if;
  14799.         Set_Lock_Attributes(Node, Lock, "");
  14800.         return TRUE;
  14801.     end if;
  14802.  
  14803.     Was_Locked := TRUE;
  14804.     for i in 1 .. Retry_Count loop
  14805.         begin
  14806.         HNM.Link(To_Node  => Node,
  14807.              New_Base => Node,
  14808.              Relation => Lock_Type'image(Lock),
  14809.              Key      => HL.Get_Item(HL.USER_NAME));
  14810.         Was_Locked := FALSE;
  14811.         exit;
  14812.         exception
  14813.         when others =>
  14814.             null;
  14815.         end;
  14816.     end loop;
  14817.  
  14818.     begin
  14819.         HNM.Unlink(Base     => Node,
  14820.                Relation => Lock_Type'image(WRITE_LOCK));
  14821.     exception
  14822.         when others =>
  14823.         null;
  14824.     end;
  14825.  
  14826.     if Was_Locked then
  14827.         return FALSE;
  14828.     end if;
  14829.     Set_Lock_Attributes(Node, Lock, HL.Get_Item(HL.USER_NAME));
  14830.  
  14831.     return TRUE;
  14832.  
  14833.     end Lock_Library;
  14834.  
  14835. --------------------------------------------------------------------------------
  14836.  
  14837.     function Lock_Library(
  14838.     Library : in SP.String_Type;
  14839.     Lock    : in Lock_Type
  14840.     ) return BOOLEAN is
  14841.  
  14842.     Node   : HND.Node_Type;
  14843.     Locked : BOOLEAN;
  14844.  
  14845.     begin
  14846.  
  14847.     Is_Library(Node, Library);
  14848.     if not HNM.Is_Open(Node) then
  14849.         raise Library_Does_Not_Exist;
  14850.     end if;
  14851.     Locked := Lock_Library(Node, Lock);
  14852.     HNM.Close_Node_Handle(Node);
  14853.     return Locked;
  14854.  
  14855.     end Lock_Library;
  14856.  
  14857. --------------------------------------------------------------------------------
  14858.  
  14859.     procedure Unlock_Library(
  14860.     Node  : in HND.Node_Type;
  14861.     Lock  : in Lock_Type
  14862.     ) is
  14863.  
  14864.     Owner : SP.String_Type;
  14865.     Group : SP.String_Type;
  14866.     Date  : SP.String_Type;
  14867.     Time  : SP.String_Type;
  14868.  
  14869.     begin
  14870.  
  14871.     if Lock = MASTER_LOCK then
  14872.         begin
  14873.         Get_Lock_Attributes(Node, Lock, "", Owner, Group, Date, Time);
  14874.         if SP.Value(Owner) /= HL.Get_Item(HL.USER_NAME) then 
  14875.             raise Not_Authorized; 
  14876.         else
  14877.             begin
  14878.             HNM.Unlink(Base     => Node,
  14879.                    Relation => Lock_Type'image(Lock));
  14880.             exception
  14881.             when others =>
  14882.                 null;
  14883.             end;
  14884.             return;
  14885.         end if;
  14886.         exception
  14887.         when others =>
  14888.             return;
  14889.         end;
  14890.     end if;
  14891.  
  14892.     if Lock = WRITE_LOCK then
  14893.         begin
  14894.         Get_Lock_Attributes(Node, Lock, "", Owner, Group, Date, Time);
  14895.         if SP.Value(Owner) /= HL.Get_Item(HL.USER_NAME) then 
  14896.             raise Not_Authorized; 
  14897.         else
  14898.             begin
  14899.             HNM.Unlink(Base     => Node,
  14900.                    Relation => Lock_Type'image(Lock));
  14901.             exception
  14902.             when others =>
  14903.                 null;
  14904.             end;
  14905.             return;
  14906.         end if;
  14907.         exception
  14908.         when others =>
  14909.             return;
  14910.         end;
  14911.     end if;
  14912.  
  14913.     begin
  14914.         HNM.Unlink(Base     => Node,
  14915.                Relation => Lock_Type'image(Lock),
  14916.                Key      => HL.Get_Item(HL.USER_NAME));
  14917.     exception
  14918.         when others =>
  14919.         null;
  14920.     end;
  14921.  
  14922.     end Unlock_Library;
  14923.  
  14924. --------------------------------------------------------------------------------
  14925.  
  14926.     procedure Unlock_Library(
  14927.     Library : in SP.String_Type;
  14928.     Lock    : in Lock_Type
  14929.     ) is
  14930.  
  14931.     Node  : HND.Node_Type;
  14932.     Owner : SP.String_Type;
  14933.     Date  : SP.String_Type;
  14934.     Time  : SP.String_Type;
  14935.  
  14936.     begin
  14937.  
  14938.     Is_Library(Node, Library);
  14939.     if not HNM.Is_Open(Node) then
  14940.         raise Library_Does_Not_Exist;
  14941.     end if;
  14942.     Unlock_Library(Node, Lock);
  14943.     HNM.Close_Node_Handle(Node);
  14944.  
  14945.     end Unlock_Library;
  14946.  
  14947. --------------------------------------------------------------------------------
  14948.  
  14949.     procedure Check_Master_Lock(
  14950.     Node : in HND.Node_Type
  14951.     ) is
  14952.  
  14953.     begin
  14954.  
  14955.     begin
  14956.         HNM.Link(To_Node  => Node,
  14957.              New_Base => Node,
  14958.              Relation => Lock_Type'image(MASTER_LOCK));
  14959.     exception
  14960.         when others =>
  14961.         raise Library_Master_Locked;
  14962.     end;
  14963.  
  14964.     begin
  14965.         HNM.Unlink(Base     => Node,
  14966.                Relation => Lock_Type'image(MASTER_LOCK));
  14967.     exception
  14968.         when others =>
  14969.         null;
  14970.     end;
  14971.  
  14972.     end Check_Master_Lock;
  14973.  
  14974. --------------------------------------------------------------------------------
  14975.  
  14976.     function Upgrade_Lock(
  14977.     Node  : in HND.Node_Type
  14978.     ) return BOOLEAN is
  14979.  
  14980.     Was_Locked : BOOLEAN;
  14981.     Iterator   : HNM.Node_Iterator;
  14982.     Temp_Node  : HND.Node_Type;
  14983.  
  14984.     begin
  14985.  
  14986.     Check_Master_Lock(Node);
  14987.     begin
  14988.         HNM.Link(To_Node  => Node,
  14989.              New_Base => Node,
  14990.              Relation => Lock_Type'image(READ_LOCK),
  14991.              Key      => HL.Get_Item(HL.USER_NAME));
  14992.         Was_Locked := FALSE;
  14993.     exception
  14994.         when others =>
  14995.         Was_Locked := TRUE;
  14996.     end;
  14997.  
  14998.     if not Was_Locked then
  14999.         begin
  15000.         HNM.Unlink(Base     => Node,
  15001.                Relation => Lock_Type'image(READ_LOCK),
  15002.                Key      => HL.Get_Item(HL.USER_NAME));
  15003.         exception
  15004.         when others =>
  15005.             null;
  15006.         end;
  15007.         raise Invalid_Upgrade;
  15008.     end if;
  15009.         
  15010.     Check_Master_Lock(Node);
  15011.     begin
  15012.         HNM.Link(To_Node  => Node,
  15013.              New_Base => Node,
  15014.              Relation => Lock_Type'image(WRITE_LOCK));
  15015.     exception
  15016.         when others =>
  15017.         raise Internal_Error;
  15018.     end;
  15019.  
  15020.     HNM.Iterate(Iterator     => Iterator, 
  15021.             Node         => Node,
  15022.             Relation     => Lock_Type'image(READ_LOCK),
  15023.             Primary_Only => FALSE);
  15024.     while HNM.More(Iterator) loop
  15025.         HNM.Get_Next(Iterator, Temp_Node);
  15026.         if HNM.Path_Key(Temp_Node) /= HL.Get_Item(HL.USER_NAME) then
  15027.         begin
  15028.             HNM.Unlink(Base     => Node,
  15029.                    Relation => Lock_Type'image(WRITE_LOCK));
  15030.         exception
  15031.             when others =>
  15032.             raise Internal_Error;
  15033.         end;
  15034.         return FALSE;
  15035.         end if;
  15036.         HNM.Close_Node_Handle(Node => Temp_Node);
  15037.     end loop;
  15038.  
  15039.     Set_Lock_Attributes(Node, WRITE_LOCK, "");
  15040.  
  15041.     begin
  15042.         HNM.Unlink(Base     => Node,
  15043.                Relation => Lock_Type'image(READ_LOCK),
  15044.                Key      => HL.Get_Item(HL.USER_NAME));
  15045.     exception
  15046.         when others =>
  15047.         raise Internal_Error;
  15048.     end;
  15049.     return TRUE;
  15050.  
  15051.     end Upgrade_Lock;
  15052.  
  15053. --------------------------------------------------------------------------------
  15054.  
  15055.     function Upgrade_Lock(
  15056.     Library : in SP.String_Type
  15057.     ) return BOOLEAN is
  15058.  
  15059.     Node   : HND.Node_Type;
  15060.     Locked : BOOLEAN;
  15061.  
  15062.     begin
  15063.  
  15064.     Is_Library(Node, Library);
  15065.     if not HNM.Is_Open(Node) then
  15066.         raise Invalid_Library_Name;
  15067.     end if;
  15068.     Locked := Upgrade_Lock(Node);
  15069.     HNM.Close_Node_Handle(Node);
  15070.     return Locked;
  15071.  
  15072.     end Upgrade_Lock;
  15073.  
  15074. --------------------------------------------------------------------------------
  15075.  
  15076.     procedure Downgrade_Lock(
  15077.     Node  : in HND.Node_Type
  15078.     ) is
  15079.  
  15080.     Was_Locked : BOOLEAN;
  15081.     Owner      : SP.String_Type;
  15082.     Group      : SP.String_Type;
  15083.     Date       : SP.String_Type;
  15084.     Time       : SP.String_Type;
  15085.  
  15086.     begin
  15087.  
  15088.     Check_Master_Lock(Node);
  15089.     begin
  15090.         HNM.Link(To_Node  => Node,
  15091.              New_Base => Node,
  15092.              Relation => Lock_Type'image(WRITE_LOCK));
  15093.         Was_Locked := FALSE;
  15094.     exception
  15095.         when others =>
  15096.         Was_Locked := TRUE;
  15097.     end;
  15098.  
  15099.     if Was_Locked then
  15100.         Get_Lock_Attributes(Node, WRITE_LOCK, "", Owner, Group, Date, Time);
  15101.         if SP.Value(Owner) /= HL.Get_Item(HL.USER_NAME) then 
  15102.         raise Invalid_Downgrade;
  15103.         end if;
  15104.     end if;
  15105.  
  15106.     if not Was_Locked then
  15107.         begin
  15108.         HNM.Unlink(Base     => Node,
  15109.                Relation => Lock_Type'image(WRITE_LOCK));
  15110.         exception
  15111.         when others =>
  15112.             null;
  15113.         end;
  15114.         raise Invalid_Downgrade;
  15115.     end if;
  15116.         
  15117.     Check_Master_Lock(Node);
  15118.     begin
  15119.         HNM.Link(To_Node  => Node,
  15120.              New_Base => Node,
  15121.              Relation => Lock_Type'image(READ_LOCK),
  15122.              Key      => HL.Get_Item(HL.USER_NAME));
  15123.         Set_Lock_Attributes(Node, READ_LOCK, "");
  15124.     exception
  15125.         when others =>
  15126.         raise Internal_Error;
  15127.     end;
  15128.  
  15129.     begin
  15130.         HNM.Unlink(Base     => Node,
  15131.                Relation => Lock_Type'image(WRITE_LOCK));
  15132.     exception
  15133.         when others =>
  15134.         raise Internal_Error;
  15135.     end;
  15136.  
  15137.     end Downgrade_Lock;
  15138.  
  15139. --------------------------------------------------------------------------------
  15140.  
  15141.     procedure Downgrade_Lock(
  15142.     Library : in SP.String_Type
  15143.     ) is
  15144.  
  15145.     Node : HND.Node_Type;
  15146.  
  15147.     begin
  15148.  
  15149.     Is_Library(Node, Library);
  15150.     if not HNM.Is_Open(Node) then
  15151.         raise Invalid_Library_Name;
  15152.     end if;
  15153.     Downgrade_Lock(Node);
  15154.     HNM.Close_Node_Handle(Node);
  15155.  
  15156.     end Downgrade_Lock;
  15157.  
  15158. --------------------------------------------------------------------------------
  15159.  
  15160.     function Get_Library_Attribute(
  15161.     Library   : in SP.String_Type;
  15162.     Attribute : in STRING
  15163.     ) return STRING is
  15164.  
  15165.     Library_Node     : HND.Node_Type;
  15166.     Attribute_Value  : STRING(1 .. 64);
  15167.     Attribute_Length : INTEGER;
  15168.  
  15169.     begin
  15170.  
  15171.     Is_Library(Library_Node, Library);
  15172.     if not HNM.Is_Open(Library_Node) then
  15173.         raise Library_Does_Not_Exist;
  15174.     end if;
  15175.     HA.Get_Node_Attribute(Node       => Library_Node,
  15176.                   Attrib     => Attribute,
  15177.                   Value      => Attribute_Value,
  15178.                   Value_Last => Attribute_Length);
  15179.     HNM.Close_Node_Handle(Library_Node);
  15180.     return Attribute_Value(1 .. Attribute_Length);
  15181.  
  15182.     end Get_Library_Attribute;
  15183.  
  15184. --------------------------------------------------------------------------------
  15185.  
  15186.     procedure Set_Library_Attribute(
  15187.     Library   : in SP.String_Type;
  15188.     Attribute : in STRING;
  15189.     Value     : in STRING
  15190.     ) is
  15191.  
  15192.     Library_Node : HND.Node_Type;
  15193.  
  15194.     begin
  15195.  
  15196.     Is_Library(Library_Node, Library);
  15197.     if not HNM.Is_Open(Library_Node) then
  15198.         raise Library_Does_Not_Exist;
  15199.     end if;
  15200.     HA.Set_Node_Attribute(Node   => Library_Node,
  15201.                   Attrib => Attribute,
  15202.                   Value  => Value);
  15203.     HNM.Close_Node_Handle(Library_Node);
  15204.  
  15205.     end Set_Library_Attribute;
  15206.  
  15207. --------------------------------------------------------------------------------
  15208.  
  15209.     procedure Open_Standard_Node_Handle(
  15210.     Node : in out HND.Node_Type;
  15211.     Name : in     SP.String_Type
  15212.     ) is
  15213.  
  15214.     begin
  15215.  
  15216.     if HNM.Is_Open(Node) then
  15217.         HNM.Close_Node_Handle(Node => Node);
  15218.     end if;
  15219.     HNM.Open_Node_Handle(Node => Node,
  15220.                  Name => SP.Value(Name));
  15221.     Set_Standard_Attributes(Node);
  15222.  
  15223.     end Open_Standard_Node_Handle;
  15224.  
  15225. --------------------------------------------------------------------------------
  15226.  
  15227.     procedure Set_Standard_Attributes(
  15228.     Node : in HND.Node_Type
  15229.     ) is
  15230.  
  15231.     Time : HL.Time_Value;
  15232.  
  15233.     begin
  15234.  
  15235.     HA.Set_Node_Attribute(Node   => Node,
  15236.                   Attrib => "OWNER",
  15237.                   Value  => HL.Get_Item(HL.USER_NAME));
  15238.     HA.Set_Node_Attribute(Node   => Node,
  15239.                   Attrib => "GROUP",
  15240.                   Value  => HL.Get_Item(HL.ACCOUNT));
  15241.     HL.Get_Time(Time);
  15242.     HA.Set_Node_Attribute(Node   => Node,
  15243.                   Attrib => "DATE",
  15244.                   Value  => HL.Date(Time));
  15245.     HA.Set_Node_Attribute(Node   => Node,
  15246.                   Attrib => "TIME",
  15247.                   Value  => HL.Time(Time));
  15248.  
  15249.     end Set_Standard_Attributes;
  15250.  
  15251. --------------------------------------------------------------------------------
  15252.  
  15253.     procedure Set_Lock_Attributes(
  15254.     Node  : in HND.Node_Type;
  15255.     Lock  : in Lock_Type;
  15256.     Key   : in STRING
  15257.     ) is
  15258.  
  15259.     Time      : HL.Time_Value;
  15260.     Lock_Node : HND.Node_Type;
  15261.  
  15262.     begin
  15263.  
  15264.     HNM.Open_Node_Handle(Node => Lock_Node,
  15265.                  Base => Node,
  15266.                  Name => ''' & Lock_Type'image(Lock) & '(' & Key & ')');
  15267.     HA.Set_Path_Attribute(Node   => Lock_Node,
  15268.                   Attrib => "OWNER",
  15269.                   Value  => HL.Get_Item(HL.USER_NAME));
  15270.     HA.Set_Path_Attribute(Node   => Lock_Node,
  15271.                   Attrib => "GROUP",
  15272.                   Value  => HL.Get_Item(HL.ACCOUNT));
  15273.     HL.Get_Time(Time);
  15274.     HA.Set_Path_Attribute(Node   => Lock_Node,
  15275.                   Attrib => "DATE",
  15276.                   Value  => HL.Date(Time));
  15277.     HA.Set_Path_Attribute(Node   => Lock_Node,
  15278.                   Attrib => "TIME",
  15279.                   Value  => HL.Time(Time));
  15280.     HNM.Close_Node_Handle(Lock_Node);
  15281.  
  15282.     end Set_Lock_Attributes;
  15283.  
  15284. --------------------------------------------------------------------------------
  15285.  
  15286.     procedure Get_Lock_Attributes(
  15287.     Node       : in     HND.Node_Type;
  15288.     Lock       : in     Lock_Type;
  15289.     Key        : in     STRING;
  15290.     Owner      : in out SP.String_Type;
  15291.     Group      : in out SP.String_Type;
  15292.     Date       : in out SP.String_Type;
  15293.     Time       : in out SP.String_Type
  15294.     ) is
  15295.  
  15296.     Lock_Node        : HND.Node_Type;
  15297.     Attribute_Value  : STRING(1 .. Maximum_Owner_Name);
  15298.     Attribute_Length : INTEGER;
  15299.  
  15300.     begin
  15301.  
  15302.     HNM.Open_Node_Handle(Node => Lock_Node,
  15303.                  Base => Node,
  15304.                  Name => ''' & Lock_Type'image(Lock) & '(' & Key & ')');
  15305.     HA.Get_Path_Attribute(Node       => Lock_Node,
  15306.                   Attrib     => "OWNER",
  15307.                   Value      => Attribute_Value,
  15308.                   Value_Last => Attribute_Length);
  15309.     Owner := SP.Create(Attribute_Value(1 .. Attribute_Length));
  15310.     HA.Get_Path_Attribute(Node       => Lock_Node,
  15311.                   Attrib     => "GROUP",
  15312.                   Value      => Attribute_Value,
  15313.                   Value_Last => Attribute_Length);
  15314.     Group := SP.Create(Attribute_Value(1 .. Attribute_Length));
  15315.     HA.Get_Path_Attribute(Node       => Lock_Node,
  15316.                   Attrib     => "DATE",
  15317.                   Value      => Attribute_Value,
  15318.                   Value_Last => Attribute_Length);
  15319.     Date := SP.Create(Attribute_Value(1 .. Attribute_Length));
  15320.     HA.Get_Path_Attribute(Node       => Lock_Node,
  15321.                   Attrib     => "TIME",
  15322.                   Value      => Attribute_Value,
  15323.                   Value_Last => Attribute_Length);
  15324.     Time := SP.Create(Attribute_Value(1 .. Attribute_Length));
  15325.     HNM.Close_Node_Handle(Lock_Node);
  15326.  
  15327.     end Get_Lock_Attributes;
  15328.  
  15329. --------------------------------------------------------------------------------
  15330.  
  15331.     function Get_Item_Date_Time(
  15332.     Library : in SP.String_Type;
  15333.     Item    : in SP.String_Type;
  15334.     Version : in SP.String_Type
  15335.     ) return STRING is
  15336.  
  15337.     Node      : HND.Node_Type;
  15338.     Date_Attr : STRING(1 .. 8);
  15339.     Date_Len  : INTEGER;
  15340.     Time_Attr : STRING(1 .. 8);
  15341.     Time_Len  : INTEGER;
  15342.  
  15343.     begin
  15344.  
  15345.     Is_Version(Node, Library, Item, Version);
  15346.     if not HNM.Is_Open(Node) then
  15347.         raise Version_Not_Found;
  15348.     end if;
  15349.     HA.Get_Node_Attribute(Node       => Node,
  15350.                   Attrib     => "DATE",
  15351.                   Value      => Date_Attr,
  15352.                   Value_Last => Date_Len);
  15353.     HA.Get_Node_Attribute(Node       => Node,
  15354.                   Attrib     => "TIME",
  15355.                   Value      => Time_Attr,
  15356.                   Value_Last => Time_Len);
  15357.     HNM.Close_Node_Handle(Node);
  15358.     return Date_Attr(1 .. Date_Len) & ' ' & Time_Attr(1 .. Time_Len);
  15359.  
  15360.     end Get_Item_Date_Time;
  15361.  
  15362. --------------------------------------------------------------------------------
  15363.  
  15364.     function Get_Version(
  15365.     Node    : in HND.Node_Type;
  15366.     Version : in SP.String_Type
  15367.     ) return SL.List is
  15368.  
  15369.     Version_Number  : INTEGER := 0;
  15370.     Current_Version : INTEGER;
  15371.     List            : SL.List;
  15372.     Version_Value   : STRING(1 .. 16);
  15373.     Version_Length  : INTEGER;
  15374.     Temp_Node       : HND.Node_Type;
  15375.     Temp_Str        : SP.String_Type;
  15376.  
  15377.     begin
  15378.  
  15379.     if not SP.Equal(Version, "") and then SP.Match_C(Version, '*') = 0 then
  15380.         begin
  15381.         Version_Number := INTEGER'value(SP.Value(Version));
  15382.         exception
  15383.         when others =>
  15384.             raise Invalid_Version;
  15385.         end;
  15386.         if Version_Number > 0 then
  15387.             begin
  15388.             HNM.Open_Node_Handle(Node => Temp_Node,
  15389.                      Base => Node,
  15390.                      Name => ".V" & SU.Image(Version_Number));
  15391.             HNM.Close_Node_Handle(Temp_Node);
  15392.         exception
  15393.             when others =>
  15394.             raise Version_Not_Found;
  15395.         end;
  15396.         return SL.MakeList(SS.Image(Version_Number));
  15397.         end if;
  15398.     end if;
  15399.  
  15400.     HA.Get_Node_Attribute(Node       => Node,
  15401.                   Attrib     => "V",
  15402.                   Value      => Version_Value,
  15403.                   Value_Last => Version_Length);
  15404.     Current_Version := INTEGER'value(Version_Value(1 .. Version_Length));
  15405.     if SP.Match_C(Version, '*') = 0 then
  15406.         Version_Number := Current_Version + Version_Number;
  15407.         if Version_Number <= 0 then
  15408.         raise Version_Not_Found;
  15409.         end if;
  15410.         return SL.MakeList(SS.Image(Version_Number));
  15411.     else
  15412.         List := SL.Create;
  15413.         for i in reverse 1 .. Current_Version loop
  15414.         begin
  15415.             HNM.Open_Node_Handle(Node => Temp_Node,
  15416.                      Base => Node,
  15417.                      Name => ".V" & SU.Image(i));
  15418.             Temp_Str := SS.Image(i);
  15419.             if SS.Match(Version, Temp_Str) then
  15420.             SL.Attach(List, Temp_Str);
  15421.             else
  15422.             SP.Flush(Temp_Str);
  15423.             end if;
  15424.             HNM.Close_Node_Handle(Temp_Node);
  15425.         exception
  15426.             when others =>
  15427.             null;
  15428.         end;
  15429.         end loop;
  15430.         return List;
  15431.     end if;
  15432.  
  15433.     end Get_Version;
  15434.  
  15435. --------------------------------------------------------------------------------
  15436.  
  15437.     procedure Iterate_Item(
  15438.     Library  : in     SP.String_Type;
  15439.     Item     : in     SP.String_Type;
  15440.     Iterator : in out HNM.Node_Iterator
  15441.     ) is
  15442.  
  15443.     Node : HND.Node_Type;
  15444.  
  15445.     begin
  15446.  
  15447.     Is_Library(Node, Library);
  15448.     if not HNM.Is_Open(Node) then
  15449.         raise Library_Does_Not_Exist;
  15450.     end if;
  15451.     HNM.Close_Node_Handle(Node => Node);
  15452.     HNM.Open_Node_Handle(Node => Node,
  15453.                  Name => SP.Value(Node_Name(Library, SP.Create("*"))));
  15454.     begin
  15455.         HNM.Iterate(Iterator     => Iterator,
  15456.             Node         => Node,
  15457.             Relation     => "DOT",
  15458.             Key          => Internal_Name(Item, "*"),
  15459.             Primary_Only => TRUE);
  15460.         HNM.Close_Node_Handle(Node);
  15461.     exception
  15462.         when others =>
  15463.         HNM.Close_Node_Handle(Node);
  15464.         raise Item_Not_Found;
  15465.     end;
  15466.  
  15467.     end Iterate_Item; 
  15468.  
  15469. --------------------------------------------------------------------------------
  15470.  
  15471.     procedure Open_Property_Node(
  15472.     Library : in     SP.String_Type;
  15473.     Keyword : in     SP.String_Type;
  15474.     Value   : in     SP.String_Type;
  15475.     Mode    : in     Edit_Mode;
  15476.     Node    : in out HND.Node_Type
  15477.     ) is
  15478.  
  15479.     Property_List    : HLU.List_Type;
  15480.  
  15481.     begin
  15482.  
  15483.     Is_Library(Node, Library);
  15484.     if not HNM.Is_Open(Node) then
  15485.         raise Library_Does_Not_Exist;
  15486.     end if;
  15487.     HNM.Close_Node_Handle(Node => Node);
  15488.     if Mode /= LIST then
  15489.         if SP.Equal(Keyword, "") or else not Is_Ada_Id(Keyword) then
  15490.         raise Invalid_Keyword;
  15491.         end if;
  15492.     end if;
  15493.     if Mode = ADD or Mode = MODIFY then
  15494.         if SP.Equal(Value, "") or else not Is_Ada_Id(Value) then
  15495.         raise Invalid_Value;
  15496.         end if;
  15497.     end if;
  15498.     HNM.Open_Node_Handle(Node => Node,
  15499.                  Name => SP.Value(Node_Name(Library, SP.Create("*"))));
  15500.     if Mode /= LIST then
  15501.         HA.Get_Node_Attribute(Node       => Node,
  15502.                   Attrib     => SP.Value(Keyword),
  15503.                   Value      => Property_List);
  15504.         if (Mode = DELETE or Mode = MODIFY) and HLU.Empty(Property_List) then
  15505.         HLU.Free_List(Property_List);
  15506.         raise Keyword_Not_Found;
  15507.         end if;
  15508.         if Mode = ADD and not HLU.Empty(Property_List) then
  15509.         HLU.Free_List(Property_List);
  15510.         raise Keyword_Already_Exists;
  15511.         end if;
  15512.         HLU.Free_List(Property_List);
  15513.     end if;
  15514.  
  15515.     end Open_Property_Node;
  15516.  
  15517. --------------------------------------------------------------------------------
  15518.  
  15519.     procedure Delete(
  15520.     Item_Node : in out HND.Node_Type;
  15521.     Versions  : in     SL.List;
  15522.     Privilege : in     Privilege_Type;
  15523.     Remainder : in out LL.List
  15524.     ) is
  15525.  
  15526.     Version_Iterator : SL.ListIter;
  15527.     Version_Number   : SP.String_Type;
  15528.     Version_Node     : HND.Node_Type;
  15529.     Current_Version  : SL.List;
  15530.     All_Version      : SL.List;
  15531.     Library          : SP.String_Type;
  15532.     Item             : SP.String_Type;
  15533.     Version          : SP.String_Type;
  15534.     Remainder_List   : SL.List;
  15535.     Delete           : BOOLEAN := FALSE; 
  15536.  
  15537.     begin
  15538.  
  15539.     if SL.IsEmpty(Versions) then
  15540.         return;
  15541.     end if;
  15542.     Parse_Node(Node    => Item_Node,
  15543.            Library => Library,
  15544.            Item    => Item,
  15545.            Version => Version);
  15546.     if Privileged(Privilege, Library, Item) then
  15547.         All_Version := Get_Version(Item_Node, SP.Create("*"));
  15548.         if SL.Equal(All_Version, Versions) then
  15549.         Destroy_String_List(All_Version);
  15550.         HNM.Delete_Tree(Item_Node);
  15551.         return;
  15552.         end if;
  15553.         Destroy_String_List(All_Version);
  15554.         Delete := TRUE;
  15555.     end if;
  15556.     Version_Iterator := SL.MakeListIter(Versions);
  15557.     while SL.More(Version_Iterator) loop
  15558.         SL.Next(Version_Iterator, Version_Number);
  15559.         HNM.Open_Node_Handle(Node         => Version_Node,
  15560.                  Base         => Item_Node,
  15561.                  Relation     => "DOT",
  15562.                  Key          => 'V' & SP.Value(Version_Number));
  15563.         if Delete then
  15564.         HNM.Delete_Tree(Version_Node);
  15565.         else
  15566.         Parse_Node(Node    => Version_Node,
  15567.                Library => Library,
  15568.                Item    => Item,
  15569.                Version => Version);
  15570.         if Privileged(Privilege, Library, Item, SP.Value(Version)) then
  15571.             HNM.Delete_Tree(Version_Node);
  15572.         else
  15573.             Remainder_List := SL.MakeList(Library);    
  15574.             SL.Attach(Remainder_List, Item);
  15575.             SL.Attach(Remainder_List, Version);
  15576.             SL.Attach(Remainder_List, SP.Make_Persistent(Privilege_Reason));
  15577.             LL.Attach(Remainder, Remainder_List);
  15578.         end if;
  15579.         end if;
  15580.         HNM.Close_Node_Handle(Version_Node);
  15581.     end loop;
  15582.     Current_Version := Get_Version(Item_Node, SP.Create("*"));
  15583.     if not SL.IsEmpty(Current_Version) then
  15584.         HA.Set_Node_Attribute(Node   => Item_Node,
  15585.                   Attrib => "V",
  15586.                   Value  => SP.Value(SL.FirstValue(Current_Version)));
  15587.     else
  15588.         HNM.Delete_Tree(Item_Node);
  15589.     end if;
  15590.     Destroy_String_List(Current_Version);
  15591.  
  15592.     exception
  15593.     when others =>
  15594.         HNM.Close_Node_Handle(Version_Node);
  15595.         raise;
  15596.  
  15597.     end Delete;
  15598.  
  15599. --------------------------------------------------------------------------------
  15600.  
  15601.     procedure Purge(
  15602.     Library   : in     SP.String_Type;
  15603.     Item      : in     SP.String_Type := SP.Create("*");
  15604.     Privilege : in     Privilege_Type;
  15605.     Remainder : in out LL.List
  15606.     ) is
  15607.  
  15608.     Item_Node        : HND.Node_Type;
  15609.     Item_Iterator    : HNM.Node_Iterator;
  15610.     Versions         : SL.List;
  15611.  
  15612.     begin
  15613.  
  15614.     Iterate_Item(Library, Item, Item_Iterator);
  15615.     while HNM.More(Item_Iterator) loop
  15616.         HNM.Get_Next(Item_Iterator, Item_Node);
  15617.         Versions := Get_Version(Item_Node, SP.Create("*"));
  15618.         SL.DeleteHead(Versions);
  15619.         Delete(Item_Node, Versions, Privilege, Remainder);
  15620.         Destroy_String_List(Versions);
  15621.         HNM.Close_Node_Handle(Item_Node);
  15622.     end loop;
  15623.  
  15624.     exception
  15625.     when others =>
  15626.         HNM.Close_Node_Handle(Item_Node);
  15627.         raise;
  15628.  
  15629.     end Purge;
  15630.  
  15631. --------------------------------------------------------------------------------
  15632.  
  15633.     procedure Rename_Item(
  15634.     Library   : in SP.String_Type;
  15635.     From_Item : in SP.String_Type;
  15636.     To_Item   : in SP.String_Type;
  15637.     Privilege : in Privilege_Type;
  15638.     Remainder : in out LL.List
  15639.     ) is
  15640.  
  15641.     Item_Node      : HND.Node_Type;
  15642.     Remainder_List : SL.List;
  15643.  
  15644.     begin
  15645.  
  15646.     Is_Item(Item_Node, Library, To_Item);
  15647.     if HNM.Is_Open(Item_Node) then
  15648.         HNM.Close_Node_Handle(Item_Node);
  15649.         raise Item_Already_Exists;
  15650.     end if;
  15651.     Is_Item(Item_Node, Library, From_Item);
  15652.     if not HNM.Is_Open(Item_Node) then
  15653.         raise Item_Not_Found;
  15654.     end if;
  15655.     if Is_Checked_Out(Item_Node) then
  15656.         HNM.Close_Node_Handle(Item_Node);
  15657.         raise Item_Checked_Out;
  15658.     end if;
  15659.     if not Privileged(Privilege, Library, From_Item) then
  15660.         Remainder_List := SL.MakeList(Library);    
  15661.         SL.Attach(Remainder_List, From_Item);
  15662.         SL.Attach(Remainder_List, SP.Make_Persistent(""));
  15663.         SL.Attach(Remainder_List, SP.Make_Persistent(Privilege_Reason));
  15664.         LL.Attach(Remainder, Remainder_List);
  15665.         return;
  15666.     end if;
  15667.     HNM.Rename(Node     => Item_Node,
  15668.            New_Name => SP.Value(Node_Name(Library, To_Item)));
  15669.     HNM.Close_Node_Handle(Item_Node);
  15670.  
  15671.     exception
  15672.     when others =>
  15673.         HNM.Close_Node_Handle(Item_Node);
  15674.         raise;
  15675.  
  15676.     end Rename_Item;
  15677.  
  15678. --------------------------------------------------------------------------------
  15679.  
  15680.     procedure Rename_Version(
  15681.     Library      : in     SP.String_Type;
  15682.     Item         : in     SP.String_Type;
  15683.     From_Version : in     SP.String_Type;
  15684.     To_Version   : in     SP.String_Type;
  15685.     Privilege    : in     Privilege_Type;
  15686.     Remainder    : in out LL.List
  15687.     ) is
  15688.  
  15689.     Library_Name      : SP.String_Type;
  15690.     Item_Name         : SP.String_Type;
  15691.     Version_Name      : SP.String_Type;
  15692.     Reason            : SP.String_Type;
  15693.     Version_Node      : HND.Node_Type;
  15694.     Item_Node         : HND.Node_Type;
  15695.     Item_Iterator     : HNM.Node_Iterator;
  15696.     From_Version_List : SL.List;
  15697.     To_Version_List   : SL.List;
  15698.     Remainder_List    : SL.List;
  15699.     Add_To_List       : BOOLEAN;
  15700.  
  15701.     begin
  15702.  
  15703.     if SP.Match_C(From_Version, '*') /= 0 then
  15704.         raise Invalid_Version;
  15705.     end if;
  15706.     if SP.Match_C(To_Version, '*') /= 0 then
  15707.         raise Invalid_Version;
  15708.     end if;
  15709.     Iterate_Item(Library, Item, Item_Iterator);
  15710.     while HNM.More(Item_Iterator) loop
  15711.         HNM.Get_Next(Item_Iterator, Item_Node);
  15712.         if not Is_Checked_Out(Item_Node) then
  15713.         Parse_Node(Item_Node, Library_Name, Item_Name, Version_Name);
  15714.         SP.Flush(Version_Name);
  15715.         From_Version_List := Get_Version(Item_Node, From_Version);
  15716.         Is_Version(Version_Node,
  15717.                Library_Name,
  15718.                Item_Name, 
  15719.                SL.FirstValue(From_Version_List));
  15720.         Add_To_List := FALSE;
  15721.         begin
  15722.             To_Version_List := Get_Version(Item_Node, To_Version);
  15723.             if not SP.Equal(SL.FirstValue(From_Version_List),
  15724.                SL.FirstValue(To_Version_List)) then
  15725.             Add_To_List := TRUE;
  15726.             Reason := SP.Make_Persistent(Version_Exists_Reason);
  15727.             end if;
  15728.         exception
  15729.             when Version_Not_Found =>
  15730.             if Privileged(Privilege,
  15731.                       Library_Name,
  15732.                       Item_Name, 
  15733.                       SP.Value(SL.FirstValue(From_Version_List))) then
  15734.                 HNM.Rename(Node     => Version_Node,
  15735.                        New_Name => SP.Value(Node_Name(Library_Name, Item_Name, SP.Value(To_Version))));
  15736.             else
  15737.                 Add_To_List := TRUE;
  15738.                 Reason := SP.Make_Persistent(Privilege_Reason);
  15739.             end if;
  15740.         end;
  15741.         Destroy_String_List(From_Version_List);
  15742.         Destroy_String_List(To_Version_List);
  15743.         HNM.Close_Node_Handle(Version_Node);
  15744.         HNM.Close_Node_Handle(Item_Node);
  15745.         else
  15746.         Add_To_List :=TRUE;
  15747.         Reason := SP.Make_Persistent(Item_Checked_Out_Reason);
  15748.         end if;
  15749.         if Add_To_List then
  15750.         Remainder_List := SL.MakeList(Library);    
  15751.         SL.Attach(Remainder_List, Item_Name);
  15752.         SL.Attach(Remainder_List, From_Version);
  15753.         SL.Attach(Remainder_List, Reason);
  15754.         LL.Attach(Remainder, Remainder_List);
  15755.         end if;
  15756.     end loop;    
  15757.  
  15758.     exception
  15759.     when others =>
  15760.         HNM.Close_Node_Handle(Version_Node);
  15761.         HNM.Close_Node_Handle(Item_Node);
  15762.         raise;
  15763.  
  15764.     end Rename_Version;
  15765.  
  15766. --------------------------------------------------------------------------------
  15767.  
  15768.     function Privileged(
  15769.     Privilege : in Privilege_Type;
  15770.     Node      : in HND.Node_Type
  15771.     ) return BOOLEAN is
  15772.  
  15773.     Attribute_Value  : STRING(1 .. 64);
  15774.     Attribute_Length : INTEGER;
  15775.  
  15776.     begin
  15777.  
  15778.     case Privilege is
  15779.         when WORLD =>
  15780.         return TRUE;
  15781.         when GROUP =>
  15782.         HA.Get_Node_Attribute(Node       => Node,
  15783.                       Attrib     => "GROUP",
  15784.                       Value      => Attribute_Value,
  15785.                       Value_Last => Attribute_Length);
  15786.         return Attribute_Value(1 .. Attribute_Length) = HL.Get_Item(HL.ACCOUNT);
  15787.         when OWNER =>
  15788.         HA.Get_Node_Attribute(Node       => Node,
  15789.                       Attrib     => "OWNER",
  15790.                       Value      => Attribute_Value,
  15791.                       Value_Last => Attribute_Length);
  15792.         return Attribute_Value(1 .. Attribute_Length) = HL.Get_Item(HL.USER_NAME);
  15793.     end case;
  15794.  
  15795.     exception
  15796.     when HND.Name_Error =>
  15797.         raise Internal_Error;
  15798.  
  15799.     end Privileged;
  15800.  
  15801. --------------------------------------------------------------------------------
  15802.  
  15803.     function Privileged(
  15804.     Privilege : in Privilege_Type;
  15805.     Library   : in SP.String_Type;
  15806.     Item      : in SP.String_Type := SP.Create("");
  15807.     Version   : in STRING := ""
  15808.     ) return BOOLEAN is
  15809.  
  15810.     Node  : HND.Node_Type;
  15811.     Owned : BOOLEAN := FALSE;
  15812.  
  15813.     begin
  15814.  
  15815.     if Version /= "" then
  15816.         Is_Node(Node, Node_Name(Library, Item, Version));
  15817.         if not HNM.Is_Open(Node) then
  15818.         raise Internal_Error;
  15819.         end if;
  15820.         Owned := Privileged(Privilege, Node);
  15821.         HNM.Close_Node_Handle(Node);
  15822.     end if;
  15823.     if Owned then
  15824.         return TRUE;
  15825.     end if;
  15826.  
  15827.     if not SP.Is_Empty(Item) then
  15828.         Is_Node(Node, Node_Name(Library, Item));
  15829.         if not HNM.Is_Open(Node) then
  15830.         raise Internal_Error;
  15831.         end if;
  15832.         Owned := Privileged(Privilege, Node);
  15833.         HNM.Close_Node_Handle(Node);
  15834.     end if;
  15835.     if Owned then
  15836.         return TRUE;
  15837.     end if;
  15838.  
  15839.     Is_Node(Node, Node_Name(Library));
  15840.     if not HNM.Is_Open(Node) then
  15841.         raise Internal_Error;
  15842.     end if;
  15843.     Owned := Privileged(Privilege, Node);
  15844.     HNM.Close_Node_Handle(Node);
  15845.     return Owned;    
  15846.  
  15847.     end Privileged;
  15848.  
  15849. --------------------------------------------------------------------------------
  15850.  
  15851.     function Get_Hif_File_Name(
  15852.     Lib_Name : in SP.String_Type;
  15853.     Item     : in SP.String_Type;
  15854.     Version  : in SP.String_Type
  15855.     ) return SP.String_Type is
  15856.  
  15857.     Node : HND.Node_Type;
  15858.     Path : SP.String_Type;
  15859.     File : SP.String_Type;
  15860.  
  15861.     begin
  15862.  
  15863.     SP.Mark;
  15864.     HNM.Open_Node_Handle(Node, SP.Value(Node_Name(Lib_Name, Item, SP.Value(Version))));
  15865.     File := SP.Make_Persistent(HFM.Host_File_Name(Node));
  15866.     SP.Release;
  15867.     HNM.Close_Node_Handle(Node);
  15868.     return File;
  15869.  
  15870.     end Get_Hif_File_Name;
  15871.  
  15872. --------------------------------------------------------------------------------
  15873.  
  15874.     function Is_Item_Checked_Out(
  15875.     Library : in SP.String_Type
  15876.     ) return BOOLEAN is
  15877.  
  15878.     Node             : HND.Node_Type;
  15879.     Attribute_Value  : STRING(1 .. 16);
  15880.     Attribute_Length : INTEGER;
  15881.     Check_Out_Count  : NATURAL;
  15882.  
  15883.     begin
  15884.  
  15885.     Is_Library(Node, Library);
  15886.     if not HNM.Is_Open(Node) then
  15887.         raise Library_Does_Not_Exist;
  15888.     end if;
  15889.     HA.Get_Node_Attribute(Node       => Node,
  15890.                   Attrib     => "CHECKED_OUT",
  15891.                   Value      => Attribute_Value,
  15892.                   Value_Last => Attribute_Length);
  15893.     HNM.Close_Node_Handle(Node);
  15894.     begin
  15895.         Check_Out_Count := NATURAL'value(Attribute_Value(1 .. Attribute_Length));    
  15896.     exception
  15897.         when CONSTRAINT_ERROR =>
  15898.         Check_Out_Count := 0;
  15899.     end;
  15900.     return Check_Out_Count /= 0;
  15901.  
  15902.     end Is_Item_Checked_Out;
  15903.  
  15904. --------------------------------------------------------------------------------
  15905.  
  15906.     procedure Display_List(
  15907.     List   : in out LL.List;
  15908.     Header : in     STRING
  15909.     ) is
  15910.  
  15911.     List_Iter   : LL.ListIter;
  15912.     Value_List  : SL.List;
  15913.     Value_Iter  : SL.ListIter;
  15914.     Value       : SP.String_Type;
  15915.     Work_String : SP.String_Type;
  15916.  
  15917.     begin
  15918.  
  15919.     List_Iter := LL.MakeListIter(List);
  15920.     HL.Put_Message_Line(SU.Left_Justify(Header, Maximum_Item_Name) & " Reason");
  15921.     HL.Put_Message_Line(Separator);
  15922.     while LL.More(List_Iter) loop
  15923.         LL.Next(List_Iter, Value_List);
  15924.         Value_Iter := SL.MakeListIter(Value_List);
  15925.         SP.Mark;
  15926.         SL.Forward(Value_Iter);
  15927.         SL.Next(Value_Iter, Value);
  15928.         Work_String := Value;
  15929.         Work_String := SP."&"(Work_String, "/");
  15930.         SL.Next(Value_Iter, Value);
  15931.         Work_String := SP."&"(Work_String, Value);
  15932.         SL.Next(Value_Iter, Value);
  15933.         HL.Put_Message_Line(SS.Left_Justify(Work_String, Maximum_Item_Name) & ' ' & SP.Value(Value));
  15934.         SP.Release;
  15935.     end loop;
  15936.  
  15937.     end Display_List;
  15938.  
  15939. --------------------------------------------------------------------------------
  15940.  
  15941. end Item_Library_Manager_Utilities;
  15942.                                                                     pragma page;
  15943. ::::::::::::::
  15944. lmutils.spc
  15945. ::::::::::::::
  15946. with Item_Library_Manager_Declarations;    use Item_Library_Manager_Declarations;
  15947. with String_Pkg;
  15948. with HIF_Node_Defs;
  15949. with HIF_Node_Management;
  15950. with String_Lists;
  15951.  
  15952. package Item_Library_Manager_Utilities is
  15953.  
  15954.     package SP  renames String_Pkg;
  15955.     package HND renames HIF_Node_Defs;
  15956.     package HNM renames HIF_Node_Management;
  15957.     package SL  renames String_Lists;
  15958.  
  15959. --------------------------------------------------------------------------------
  15960.  
  15961.     function Internal_Name(
  15962.     External_Name : in SP.String_Type;
  15963.     Exclude       : in STRING := ""
  15964.     ) return STRING;
  15965.  
  15966. --| Effects:
  15967. --| Translate representation internal to the Library Manager to its
  15968. --| external representation.  (Needed to satisfy the condition that
  15969. --| node names be Ada identifiers) 
  15970.  
  15971. --------------------------------------------------------------------------------
  15972.  
  15973.     function External_Name(
  15974.     Internal_Name : in STRING
  15975.     ) return STRING;
  15976.  
  15977. --| Effects:
  15978. --| Translate external representation to the Library Manager
  15979. --| external representation.
  15980.  
  15981. --------------------------------------------------------------------------------
  15982.  
  15983.     procedure Is_Node(
  15984.     Node : in out HND.Node_Type;
  15985.     Name : in     SP.String_Type
  15986.     );
  15987.  
  15988. --| Effects:
  15989. --| Verifies that the given node name is indeed a node and if so opens
  15990. --| the node for processing.  Otherwise the node is closed.
  15991.  
  15992. --------------------------------------------------------------------------------
  15993.  
  15994.     function Node_Name(
  15995.     Library : in SP.String_Type;
  15996.     Item    : in SP.String_Type := SP.Create("");
  15997.     Version : in STRING := ""
  15998.     ) return SP.String_Type;
  15999.  
  16000. --| Effects:
  16001. --| Creates a node name representation of a library, item in a library, or
  16002. --| a version of an item in a library
  16003.  
  16004. --------------------------------------------------------------------------------
  16005.  
  16006.     procedure Parse_Node(
  16007.     Node    : in     HND.Node_Type;
  16008.     Library :    out SP.String_Type;
  16009.     Item    :    out SP.String_Type;
  16010.     Version :    out SP.String_Type
  16011.     );
  16012.  
  16013. --| Effects:
  16014. --| Given a node handle, parses the node name into library name, item name,
  16015. --| and version number
  16016.  
  16017. --------------------------------------------------------------------------------
  16018.  
  16019.     function Is_Ada_Id(
  16020.     Value : in SP.String_Type
  16021.     ) return BOOLEAN;
  16022.  
  16023. --| Effects:
  16024. --| Verifies that th e given value is an Ada identifier
  16025.  
  16026. --------------------------------------------------------------------------------
  16027.  
  16028.     procedure Is_Library(
  16029.     Node    : in out HND.Node_Type;
  16030.     Library : in     SP.String_Type
  16031.     );
  16032.  
  16033. --| Effects:
  16034. --| Verifies that the given library exists and opens the node handle to
  16035. --| the library.  Otherwise the node is not opened.
  16036.  
  16037. --------------------------------------------------------------------------------
  16038.  
  16039.     procedure Is_Item(
  16040.     Node    : in out HND.Node_Type;
  16041.     Library : in     SP.String_Type;
  16042.     Item    : in     SP.String_Type
  16043.     );
  16044.  
  16045. --| Effects:
  16046. --| Verifies that the given item exists and opens the node handle to
  16047. --| the item. Otherwise the node is not opened.
  16048.  
  16049. --------------------------------------------------------------------------------
  16050.  
  16051.     procedure Is_Version(
  16052.     Node    : in out HND.Node_Type;
  16053.     Library : in     SP.String_Type;
  16054.     Item    : in     SP.String_Type;
  16055.     Version : in     SP.String_Type
  16056.     );
  16057.  
  16058. --| Effects:
  16059. --| Verifies that the version of an item exists and opens the node handle to
  16060. --| the version of the item.  Otherwise the node is not opened.
  16061.  
  16062. --------------------------------------------------------------------------------
  16063.  
  16064.     function Is_Checked_Out(
  16065.     Item_Node : in HND.Node_Type
  16066.     ) return BOOLEAN;
  16067.  
  16068. --| Effects:
  16069. --| Verifies that the item (given as a node handle) is checked out for
  16070. --| update.
  16071.  
  16072. --------------------------------------------------------------------------------
  16073.  
  16074.     function Lock_Library(
  16075.     Node : in HND.Node_Type;
  16076.     Lock : in Lock_Type
  16077.     ) return BOOLEAN;
  16078.  
  16079. --| Effects:
  16080. --| Locks the library (given as a node handle) with the appropriate Lock_Type.
  16081. --| Returns TRUE iff the locking was successful.
  16082.  
  16083. --------------------------------------------------------------------------------
  16084.  
  16085.     function Lock_Library(
  16086.     Library : in SP.String_Type;
  16087.     Lock    : in Lock_Type
  16088.     ) return BOOLEAN;
  16089.  
  16090. --| Effects:
  16091. --| Locks the library (given as a library name) with the appropriate
  16092. --| Lock_Type.  Returns TRUE iff the locking was successful.
  16093.  
  16094. --------------------------------------------------------------------------------
  16095.  
  16096.     procedure Unlock_Library(
  16097.     Node  : in HND.Node_Type;
  16098.     Lock  : in Lock_Type
  16099.     );
  16100.  
  16101. --| Effects:
  16102. --| Unlocks the library (given as a node handle).
  16103.  
  16104. --------------------------------------------------------------------------------
  16105.  
  16106.     procedure Unlock_Library(
  16107.     Library : in SP.String_Type;
  16108.     Lock    : in Lock_Type
  16109.     );
  16110.  
  16111. --| Effects:
  16112. --| Unlocks the library (given as a library name).
  16113.  
  16114. --------------------------------------------------------------------------------
  16115.  
  16116.     function Upgrade_Lock(
  16117.     Node  : in HND.Node_Type
  16118.     ) return BOOLEAN;
  16119.  
  16120. --| Effects:
  16121. --| Upgrades the library lock to a write lock.
  16122.  
  16123. --------------------------------------------------------------------------------
  16124.  
  16125.     function Upgrade_Lock(
  16126.     Library : in SP.String_Type
  16127.     ) return BOOLEAN;
  16128.  
  16129. --| Effects:
  16130. --| Upgrades the library lock to a write lock.
  16131.  
  16132. --------------------------------------------------------------------------------
  16133.  
  16134.     procedure Downgrade_Lock(
  16135.     Node  : in HND.Node_Type
  16136.     );
  16137.  
  16138. --| Effects:
  16139. --| Downgrades the library lock to a read lock.
  16140.  
  16141. --------------------------------------------------------------------------------
  16142.  
  16143.     procedure Downgrade_Lock(
  16144.     Library : in SP.String_Type
  16145.     );
  16146.  
  16147. --| Effects:
  16148. --| Downgrades the library lock to a read lock.
  16149.  
  16150. --------------------------------------------------------------------------------
  16151.  
  16152.     function Get_Library_Attribute(
  16153.     Library   : in SP.String_Type;
  16154.     Attribute : in STRING
  16155.     ) return STRING;
  16156.  
  16157. --| Effects:
  16158. --| Returns the value of a given attribute associated with the library
  16159.  
  16160. --------------------------------------------------------------------------------
  16161.  
  16162.     procedure Set_Library_Attribute(
  16163.     Library   : in SP.String_Type;
  16164.     Attribute : in STRING;
  16165.     Value     : in STRING
  16166.     );
  16167.  
  16168. --| Effects:
  16169. --| Sets the value of a given attribute associated with the library
  16170.  
  16171. --------------------------------------------------------------------------------
  16172.  
  16173.     procedure Open_Standard_Node_Handle(
  16174.     Node : in out HND.Node_Type;
  16175.     Name : in     SP.String_Type
  16176.     );
  16177.  
  16178. --| Effects:
  16179. --| Open the node handle associated with a given node name and set the
  16180. --| standard attributes for this node.
  16181.  
  16182. --------------------------------------------------------------------------------
  16183.  
  16184.     procedure Set_Standard_Attributes(
  16185.     Node : in HND.Node_Type
  16186.     );
  16187.  
  16188. --| Effects:
  16189. --| Set the common attributes (eg. OWNER, DATE) of a given node.
  16190.  
  16191. --------------------------------------------------------------------------------
  16192.  
  16193.     procedure Set_Lock_Attributes(
  16194.     Node  : in HND.Node_Type;
  16195.     Lock  : in Lock_Type;
  16196.     Key   : in STRING
  16197.     );
  16198.  
  16199. --| Effects:
  16200. --| Set the common lock attributes (eg. DATE).
  16201.  
  16202. --------------------------------------------------------------------------------
  16203.  
  16204.     procedure Get_Lock_Attributes(
  16205.     Node       : in     HND.Node_Type;
  16206.     Lock       : in     Lock_Type;
  16207.     Key        : in     STRING;
  16208.     Owner      : in out SP.String_Type;
  16209.     Group      : in out SP.String_Type;
  16210.     Date       : in out SP.String_Type;
  16211.     Time       : in out SP.String_Type
  16212.     );
  16213.  
  16214. --| Effects:
  16215. --| Get the values of common lock attributes.
  16216.  
  16217. --------------------------------------------------------------------------------
  16218.  
  16219.     function Get_Item_Date_Time(
  16220.     Library : in SP.String_Type;
  16221.     Item    : in SP.String_Type;
  16222.     Version : in SP.String_Type
  16223.     ) return STRING;
  16224.  
  16225. --| Effects:
  16226. --| Return the create date and time (MM/DD/YY HH:MM:SS format) associated
  16227. --| with a version of an item in a library.
  16228.  
  16229. --------------------------------------------------------------------------------
  16230.  
  16231.     function Get_Version(
  16232.     Node    : in HND.Node_Type;
  16233.     Version : in SP.String_Type
  16234.     ) return SL.List;
  16235.  
  16236. --| Effects:
  16237. --| Return a list of version numbers of an item satifying the given condition.
  16238.  
  16239. --------------------------------------------------------------------------------
  16240.  
  16241.     procedure Iterate_Item(
  16242.     Library  : in     SP.String_Type;
  16243.     Item     : in     SP.String_Type;
  16244.     Iterator : in out HNM.Node_Iterator
  16245.     );
  16246.  
  16247. --| Effects:
  16248. --| Creates an iterator over all items satisfying the given codition. 
  16249.  
  16250. --------------------------------------------------------------------------------
  16251.  
  16252.     procedure Open_Property_Node(
  16253.     Library : in     SP.String_Type;
  16254.     Keyword : in     SP.String_Type;
  16255.     Value   : in     SP.String_Type;
  16256.     Mode    : in     Edit_Mode;
  16257.     Node    : in out HND.Node_Type
  16258.     );
  16259.  
  16260. --| Effects:
  16261. --| Open the node handle for a node which has properties associated with it
  16262. --| for the given library
  16263.  
  16264. --------------------------------------------------------------------------------
  16265.  
  16266.     procedure Delete(
  16267.     Item_Node : in out HND.Node_Type;
  16268.     Versions  : in     SL.List;
  16269.     Privilege : in     Privilege_Type;
  16270.     Remainder : in out LL.List
  16271.     );
  16272.  
  16273. --| Effects:
  16274. --| Delete the given version(s) of an item (given as a node handle).  Return
  16275. --| a list of list(s) containing item and version number that were not deleted.
  16276.  
  16277. --------------------------------------------------------------------------------
  16278.  
  16279.     procedure Purge(
  16280.     Library   : in     SP.String_Type;
  16281.     Item      : in     SP.String_Type := SP.Create("*");
  16282.     Privilege : in     Privilege_Type;
  16283.     Remainder : in out LL.List
  16284.     );
  16285.  
  16286. --| Effects:
  16287. --| Purge the given item. Return a list of list(s) containing item and version
  16288. --| number that were not purged.
  16289.  
  16290. --------------------------------------------------------------------------------
  16291.  
  16292.     procedure Rename_Item(
  16293.     Library   : in SP.String_Type;
  16294.     From_Item : in SP.String_Type;
  16295.     To_Item   : in SP.String_Type;
  16296.     Privilege : in Privilege_Type;
  16297.     Remainder : in out LL.List
  16298.     );
  16299.  
  16300. --| Effects:
  16301. --| Renames a given item in the item library.  Remainder is a list of lists
  16302. --| containing item/version of entities not renamed together with the reason.
  16303.  
  16304. --------------------------------------------------------------------------------
  16305.  
  16306.     procedure Rename_Version(
  16307.     Library      : in     SP.String_Type;
  16308.     Item         : in     SP.String_Type;
  16309.     From_Version : in     SP.String_Type;
  16310.     To_Version   : in     SP.String_Type;
  16311.     Privilege    : in     Privilege_Type;
  16312.     Remainder    : in out LL.List
  16313.     );
  16314.  
  16315. --| Effects:
  16316. --| Renames a given version of item(s) in the item library.  Remainder is a
  16317. --| list of lists containing item/version of entities not renamed together
  16318. --| with the reason.
  16319.  
  16320. --------------------------------------------------------------------------------
  16321.  
  16322.     function Privileged(
  16323.     Privilege : in Privilege_Type;
  16324.     Node      : in HND.Node_Type
  16325.     ) return BOOLEAN;
  16326.  
  16327. --| Effects:
  16328. --| Verify that the given node may be deleted (purged) in terms of 
  16329. --| ownership privileges.
  16330.  
  16331. --------------------------------------------------------------------------------
  16332.  
  16333.     function Privileged(
  16334.     Privilege : in Privilege_Type;
  16335.     Library   : in SP.String_Type;
  16336.     Item      : in SP.String_Type := SP.Create("");
  16337.     Version   : in STRING := ""
  16338.     ) return BOOLEAN;
  16339.  
  16340. --| Effects:
  16341. --| Verify that the given library, item in a library or a version of an item
  16342. --| in a library may be deleted (purged) in terms of ownership privileges.
  16343.  
  16344. --------------------------------------------------------------------------------
  16345.  
  16346.     function Get_Hif_File_Name(        --| return the hif file name for a Lib item
  16347.     Lib_Name : in SP.String_Type;    --| name of the Lib
  16348.     Item     : in SP.String_Type;    --| name of the item in the Lib
  16349.     Version  : in SP.String_Type    --| version number
  16350.     ) return SP.String_Type;
  16351.  
  16352. --| Effects:
  16353. --| Return the Hif file name for a particular version of a given item
  16354. --| in an item library.
  16355.  
  16356. --------------------------------------------------------------------------------
  16357.  
  16358.     function Is_Item_Checked_Out(    --| check if any items are checked out
  16359.     Library : in SP.String_Type    --| name of the library
  16360.     ) return BOOLEAN;
  16361.  
  16362. --| Effects:
  16363. --| Return TRUE if any item is checked out for update in the specified library.
  16364.  
  16365. --------------------------------------------------------------------------------
  16366.  
  16367.     procedure Display_List(        --| display a list of lists
  16368.     List   : in out LL.List;    --| list of lists
  16369.     Header : in     STRING        --| display header
  16370.     );
  16371.  
  16372. --| Effects:
  16373. --| Write Header and contents of a list of lists
  16374.  
  16375. --------------------------------------------------------------------------------
  16376.  
  16377. end Item_Library_Manager_Utilities;
  16378.                                                                     pragma page;
  16379. ::::::::::::::
  16380. lock.bdy
  16381. ::::::::::::::
  16382. with hif_node_management;
  16383. with hif_node_defs; use hif_node_defs;
  16384. with hif_attributes;
  16385. with hif_list_utils;
  16386. with host_system_calls;
  16387.  
  16388. package body catalog_locks is
  16389.  
  16390. --| Note: At this time the parameter max_wait on each of the locking
  16391. --| programs is not used.  It is in the spec in order to eliminate a lot
  16392. --| of modifications to other packages when a waiting procedure is
  16393. --| implemented.
  16394.  
  16395. package NM renames hif_node_management;
  16396. package ND renames hif_node_defs;
  16397. package Attr renames hif_attributes;
  16398. package LU renames hif_list_utils;
  16399. package HS renames host_system_calls;
  16400.  
  16401. function write_lock (
  16402.     max_wait : duration
  16403.     ) return boolean is
  16404.  
  16405. --| Effects: Puts a write lock on the root of the catalog and returns true
  16406. --| if the lock is able to be set.  It returns false if for any reason the
  16407. --| lock cannot be set.  No operations can be performed if the lock is not
  16408. --| set.  This is the default lock for creating a catalog.
  16409.     node : node_type;
  16410.     list : LU.list_type;
  16411.     user : string (1..20);    -- picked 20 as I don't think there are any
  16412.                 -- operating systems that allow user ids longer
  16413.     last : natural;
  16414.     iter : NM.node_iterator;
  16415.  
  16416.     begin
  16417.     NM.get_current_node (node);
  16418.     -- node is the current node.  The write lock will be a relation from
  16419.     -- this node to itself with the name write lock.  The key will be 
  16420.     -- empty and it must not already exist.
  16421.     NM.link (to_node => node,
  16422.          new_base => node,
  16423.          key => "",
  16424.          relation => "write_lock",
  16425.            requirement => must_not_exist);
  16426.     LU.init_list (list);
  16427.     -- put the user id of the person setting the lock as an attribute on 
  16428.     -- the lock path itself.
  16429.     HS.get_username (user, last);
  16430.     LU.add_positional (list, user (1..last));
  16431.     Attr.set_path_attribute (current_node & "'write_lock()",
  16432.                  "userid",
  16433.                  list);
  16434.     -- At this point the write lock is set.  If there was already a
  16435.     -- write lock the link would have failed, and once the link is there
  16436.     -- another cannot be put on.  However, the presence of read_locks
  16437.     -- would make the write lock invalid.  So make an iterator of
  16438.     -- relations with the name "read_lock" and if there are any remove 
  16439.     -- the write lock.
  16440.     NM.iterate(iter, node, relation => "read_lock", primary_only => false);
  16441.     if NM.more (iter) then
  16442.         NM.unlink (node, relation => "write_lock");
  16443.         return false;
  16444.     end if;
  16445.     -- ok the write lock is set, there are no read_locks so true can 
  16446.     -- be returned.
  16447.     return true;
  16448.     exception
  16449.         when ND.name_error =>
  16450.     -- the relation already existed, so the new one couldn't be made
  16451.         return false;
  16452.     end;
  16453.  
  16454. function read_lock (
  16455.     max_wait : duration
  16456.     ) return boolean is
  16457.  
  16458. --| Effects: Puts a read lock on the root of the catalog and returns true
  16459. --| if the lock is able to be set.  It returns false if for any reason the
  16460. --| lock cannot be set.  No operations can be performed if the lock is not
  16461. --| set.  The default when entering the catalog is a read lock.
  16462.  
  16463.     node : node_type;
  16464.     list : LU.list_type;
  16465.     user : string (1..20);    -- picked 20 as I don't think there are any
  16466.                 -- operating systems that allow user ids longer
  16467.     last : natural;
  16468.  
  16469.     begin
  16470.     --| Algorithm: First it must set a temporary write lock so that some
  16471.     --| one trying to get a write lock at the same time won't mess things
  16472.     --| up.  When the write lock is in place add a read_lock.  When the
  16473.     --| read lock is set release the write lock.
  16474.     NM.get_current_node (node);
  16475.     -- node is the current node.  The write lock will be a relation from
  16476.     -- this node to itself with the name write lock.  The key will be 
  16477.     -- empty and it must not already exist.
  16478.     NM.link (to_node => node,
  16479.          new_base => node,
  16480.          key => "",
  16481.          relation => "write_lock",
  16482.            requirement => must_not_exist);
  16483.     LU.init_list (list);
  16484.     HS.get_username (user, last);
  16485.     LU.add_positional (list, user (1..last));
  16486.     Attr.set_path_attribute (current_node & "'write_lock()",
  16487.                  "userid",
  16488.                  list);
  16489.     -- The write lock is set.
  16490.     begin
  16491.         NM.link (to_node => node,
  16492.          new_base => node,
  16493.          key => user (1..last),
  16494.          relation => "read_lock",
  16495.          requirement => must_not_exist);
  16496.     exception
  16497.         when ND.name_error =>
  16498.         -- this name error occurs when the relation read_lock(user) for 
  16499.         -- this user already exists
  16500.         NM.unlink (node, relation => "write_lock");
  16501.         raise lock_already_exists;
  16502.     end;
  16503.     -- the read_lock is set
  16504.     NM.unlink (node, relation => "write_lock");
  16505.     return true;
  16506.     -- the read_lock is set, the temporary write lock removed so 
  16507.     -- everything is done.
  16508.     exception
  16509.     when ND.name_error =>
  16510.         -- the write lock failed so someone else has a write lock and
  16511.         -- this user cannot have a read_lock anyway.
  16512.         return false;
  16513.     end read_lock;
  16514.  
  16515. function upgrade_lock (
  16516.     max_wait : duration
  16517.     ) return boolean is
  16518.  
  16519. --| Effects: Upgrades a read lock by a person to a write lock.  Since the
  16520. --| default lock for the catalog is the read lock there needs to be some
  16521. --| way to upgrade to a write lock when the user tries to perform an
  16522. --| operation which requires a write lock.  This function returns true if
  16523. --| the lcok can be placed, and false if for any reason the lock fails.
  16524. --| The read lock cannot be upgraded if any other user has a read lock.
  16525.     node : node_type;
  16526.     list : LU.list_type;
  16527.     user : string (1..20);    -- picked 20 as I don't think there are any
  16528.                 -- operating systems that allow user ids longer
  16529.     last : natural;
  16530.     iter : NM.node_iterator;
  16531.     read_node : node_type;
  16532.  
  16533.     begin
  16534.     NM.get_current_node (node);
  16535.     -- node is the current node.  The write lock will be a relation from
  16536.     -- this node to itself with the name write lock.  The key will be 
  16537.     -- empty and it must not already exist.
  16538.     NM.link (to_node => node,
  16539.          new_base => node,
  16540.          key => "",
  16541.          relation => "write_lock",
  16542.            requirement => must_not_exist);
  16543.     LU.init_list (list);
  16544.     HS.get_username (user, last);
  16545.     LU.add_positional (list, user (1..last));
  16546.     Attr.set_path_attribute (current_node & "'write_lock()",
  16547.                  "userid",
  16548.                  list);
  16549.     -- Note that if anyone other than the current user has a read lock the
  16550.     -- write lock is invalid.  So iterate over the current read locks and
  16551.     -- remove the write lock if any is not the same as the current user.
  16552.     NM.iterate(iter, node, relation => "read_lock", primary_only => false);
  16553.     while NM.more (iter) loop    
  16554.         NM.get_next (iter, read_node);
  16555.         if NM.path_key (read_node) /= user (1..last) then
  16556.         -- you can't have a write lock if some one else has a read_lock
  16557.         NM.unlink (node, relation => "write_lock");
  16558.         return false;
  16559.         end if;
  16560.     end loop;
  16561.     -- the write lock is set.  The current user is the only one with a
  16562.     -- read lock so the write lock is ok.
  16563.     return true;
  16564.     exception 
  16565.     when ND.name_error =>
  16566.         -- write lock is not unique
  16567.         return false;
  16568.     end upgrade_lock;
  16569.  
  16570.     procedure remove_write is
  16571.  
  16572.     node : node_type;
  16573.     list : LU.list_type;
  16574.     user : string (1..20);    -- picked 20 as I don't think there are any
  16575.                 -- operating systems that allow user ids longer
  16576.     last : natural;
  16577.  
  16578.     begin
  16579.     -- This would just be a simple unlink except that a user shouldn't be
  16580.     -- able to remove another person's lock.  So first get all the 
  16581.     -- information from the path and check it.
  16582.     NM.get_current_node (node);
  16583.     HS.get_username (user, last);
  16584.     Attr.get_path_attribute (current_node & "'write_lock", "userid", list);
  16585.     if LU.identifier(LU.positional(list, 1)) /= user (1..last) then
  16586.     -- if the userid on the lock doesn't match the current user this
  16587.     -- user cannot remove the lock
  16588.         raise unauthorized;
  16589.     end if;
  16590.     NM.unlink (node, relation => "write_lock");
  16591.     exception 
  16592.     when ND.name_error =>
  16593.         raise lock_doesnt_exist;
  16594.     end remove_write;
  16595.  
  16596.     procedure remove_read is
  16597.  
  16598.     node : node_type;
  16599.     user : string (1..20);    -- picked 20 as I don't think there are any
  16600.                 -- operating systems that allow user ids longer
  16601.     last : natural;
  16602.  
  16603.     begin
  16604.     NM.get_current_node (node);
  16605.     HS.get_username (user, last);
  16606.     NM.unlink (node, key => user(1..last), relation => "read_lock");
  16607.     exception 
  16608.     when ND.name_error =>
  16609.         raise lock_doesnt_exist;
  16610.     end remove_read;
  16611.  
  16612. procedure get_write_user (    --| Get the name of the user that owns the
  16613.                 --| write lock
  16614.     user : in out SP.string_type--| name of the user
  16615.     ) is
  16616.  
  16617.     list : LU.list_type;
  16618.  
  16619.     begin
  16620.     Attr.get_path_attribute (current_node & "'write_lock", "userid", list);
  16621.         user := SP.create (LU.identifier (LU.positional (list, 1)));
  16622.     end get_write_user;
  16623.  
  16624. end catalog_locks;
  16625. ::::::::::::::
  16626. lock.spc
  16627. ::::::::::::::
  16628. with string_pkg;
  16629.  
  16630. package  catalog_locks is
  16631.  
  16632. ---- Package renames:
  16633.  
  16634. package SP renames string_pkg;
  16635.  
  16636. ---- Exception declarations:
  16637.  
  16638. unauthorized : exception;    -- raised when someone tries to remove a 
  16639.                 -- write lock they don't own
  16640. lock_doesnt_exist : exception;    -- raised when the lock doesn't exist
  16641. lock_already_exists : exception;-- raised when the lock already exists
  16642.  
  16643. ---- Declarations of visible subprograms:
  16644.  
  16645. function write_lock (
  16646.     max_wait : duration
  16647.     ) return boolean;
  16648.  
  16649. --| Effects: Puts a write lock on the root of the catalog and returns true
  16650. --| if the lock is able to be set.  It returns false if for any reason the
  16651. --| lock cannot be set.  No operations can be performed if the lock is not
  16652. --| set.  This is the default lock for creating a catalog.
  16653.  
  16654. function read_lock (
  16655.     max_wait : duration
  16656.     ) return boolean;
  16657.  
  16658. --| Effects: Puts a read lock on the root of the catalog and returns true
  16659. --| if the lock is able to be set.  It returns false if for any reason the
  16660. --| lock cannot be set.  No operations can be performed if the lock is not
  16661. --| set.  The default when entering the catalog is a read lock.
  16662.  
  16663. function upgrade_lock (
  16664.     max_wait : duration
  16665.     ) return boolean;
  16666.  
  16667. --| Effects: Upgrades a read lock by a person to a write lock.  Since the
  16668. --| default lock for the catalog is the read lock there needs to be some
  16669. --| way to upgrade to a write lock when the user tries to perform an
  16670. --| operation which requires a write lock.  This function returns true if
  16671. --| the lcok can be placed, and false if for any reason the lock fails.
  16672. --| The read lock cannot be upgraded if any other user has a read lock.
  16673.  
  16674. procedure remove_write;
  16675.  
  16676. --| Effects: removes a write lock owned by the person invcoking it.
  16677. --| raises unauthorized if the person doesn't own the write lock.
  16678. --| Also, it just removes the write lock, so someone that upgraded
  16679. --| a read to a write still has the read lock in place.
  16680.  
  16681. procedure remove_read;
  16682.  
  16683. --| Effects: removes a read lock belonging to the current user.  If the
  16684. --| person does not have a read lock, lock_doesnt_exist is raised.
  16685.  
  16686. procedure get_write_user (    --| Get the name of the user that owns the
  16687.                 --| write lock
  16688.     user : in out SP.string_type--| name of the user
  16689.     );
  16690.  
  16691. end catalog_locks;
  16692. ::::::::::::::
  16693. modifyp.ada
  16694. ::::::::::::::
  16695. with Standard_Interface;
  16696. with String_Pkg;
  16697. with Host_Lib;
  16698. with Item_Library_Manager;
  16699. with Item_Library_Manager_Declarations;
  16700.  
  16701. function Modify_Property return INTEGER is
  16702.  
  16703.     package SI  renames Standard_Interface;
  16704.     package SP  renames String_Pkg;
  16705.     package HL  renames Host_Lib;
  16706.     package ILM renames Item_Library_Manager;
  16707.     package ILD renames Item_Library_Manager_Declarations;
  16708.  
  16709.     package LIB is new SI.String_Argument(
  16710.                 String_Type_Name => "library_name");
  16711.     package STR is new SI.String_Argument(
  16712.                 String_Type_Name => "string");
  16713.  
  16714.     Modify_Property_Process : SI.Process_Handle;
  16715.     Library                 : SP.String_Type;
  16716.     Keyword                 : SP.String_Type;
  16717.     Value                   : SP.String_Type;
  16718.  
  16719. begin
  16720.  
  16721.     SP.Mark;
  16722.  
  16723.     SI.Set_Tool_Identifier(Identifier => "1.0");
  16724.  
  16725.     SI.Define_Process(
  16726.     Proc    => Modify_Property_Process,
  16727.     Name    => "Modify_Property",
  16728.     Help    => "Change a Property Keyword/Value in the Item Library");
  16729.  
  16730.     LIB.Define_Argument(
  16731.     Proc => Modify_Property_Process,
  16732.     Name => "library",
  16733.     Help => "Name of the item library");
  16734.  
  16735.     STR.Define_Argument(
  16736.     Proc    => Modify_Property_Process,
  16737.     Name    => "keyword",
  16738.     Help    => "Property keyword");
  16739.  
  16740.     STR.Define_Argument(
  16741.     Proc    => Modify_Property_Process,
  16742.     Name    => "value",
  16743.     Help    => "Property value");
  16744.  
  16745.     SP.Release;
  16746.  
  16747.     SI.Parse_Line(Modify_Property_Process);
  16748.  
  16749.     Library := LIB.Get_Argument(
  16750.             Proc => Modify_Property_Process,
  16751.             Name => "library");
  16752.  
  16753.     Keyword := STR.Get_Argument(
  16754.             Proc => Modify_Property_Process,
  16755.             Name => "keyword");
  16756.  
  16757.     Value := STR.Get_Argument(
  16758.             Proc => Modify_Property_Process,
  16759.             Name => "value");
  16760.  
  16761.     ILM.Modify_Property(Library   => Library,
  16762.             Keyword   => Keyword,
  16763.             Value     => Value,
  16764.             Privilege => ILD.OWNER);
  16765.     return HL.Return_Code(HL.SUCCESS);
  16766.  
  16767. exception
  16768.  
  16769.     when SI.Process_Help =>
  16770.     return HL.Return_Code(HL.INFORMATION);
  16771.  
  16772.     when SI.Abort_Process =>
  16773.     return HL.Return_Code(HL.SUCCESS);
  16774.  
  16775.     when ILD.Library_Does_Not_Exist =>
  16776.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ does not exist.");
  16777.     return HL.Return_Code(HL.ERROR);
  16778.  
  16779.     when ILD.Library_Master_Locked =>
  16780.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is master locked.");
  16781.     return HL.Return_Code(HL.ERROR);
  16782.  
  16783.     when ILD.Library_Write_Locked =>
  16784.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is write locked.");
  16785.     return HL.Return_Code(HL.ERROR);
  16786.  
  16787.     when ILD.Library_Read_Locked =>
  16788.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is read locked.");
  16789.     return HL.Return_Code(HL.ERROR);
  16790.  
  16791.     when ILD.Invalid_Keyword =>
  16792.         HL.Put_Error("Property keyword """ & SP.Value(SP.Upper(Keyword)) & """ invalid.");
  16793.     return HL.Return_Code(HL.ERROR);
  16794.  
  16795.     when ILD.Invalid_Value =>
  16796.         HL.Put_Error("Property value """ & SP.Value(SP.Upper(Value)) & """ invalid.");
  16797.     return HL.Return_Code(HL.ERROR);
  16798.  
  16799.     when ILD.Keyword_Not_Found =>
  16800.         HL.Put_Error("Property keyword """ & SP.Value(SP.Upper(Keyword)) &
  16801.              """ not found.");
  16802.     return HL.Return_Code(HL.ERROR);
  16803.  
  16804.     when ILD.Not_Authorized =>
  16805.     HL.Put_Error("Not authorized.");
  16806.     return HL.Return_Code(HL.ERROR);
  16807.  
  16808.     when ILD.No_Privilege =>
  16809.     HL.Put_Error("No privilege for attempted operation.");
  16810.     return HL.Return_Code(HL.ERROR);
  16811.  
  16812.     when others =>
  16813.     HL.Put_Error("Modify Property internal error.");
  16814.     return HL.Return_Code(HL.SEVERE);
  16815.  
  16816. end Modify_Property;
  16817.  
  16818. ::::::::::::::
  16819. modifyp.bdy
  16820. ::::::::::::::
  16821. with Library_Errors;
  16822. with Library_Utilities;
  16823. with HIF_Node_Defs;
  16824. with HIF_Node_Management;
  16825. with HIF_Attributes;
  16826. with HIF_List_Utils;
  16827.  
  16828. function Modify_Property_Interface(
  16829.     Library   : in String_Pkg.String_Type;
  16830.     Keyword   : in String_Pkg.String_Type;
  16831.     Value     : in String_Pkg.String_Type;
  16832.     Privilege : in Privilege_Type := WORLD
  16833.     ) return Host_Lib.Severity_Code is
  16834.  
  16835.     package SP  renames String_Pkg;
  16836.     package HL  renames Host_Lib;
  16837.     package LE  renames Library_Errors;
  16838.     package LU  renames Library_Utilities;
  16839.     package HND renames HIF_Node_Defs;
  16840.     package HNM renames HIF_Node_Management;
  16841.     package HA  renames HIF_Attributes;
  16842.     package HLU renames HIF_List_Utils;
  16843.  
  16844.     Node : HND.Node_Type;
  16845.     Trap : HL.Interrupt_State := HL.Get_Interrupt_State;
  16846.  
  16847. begin
  16848.  
  16849.     if HL."="(Trap, HL.DISABLED) then
  16850.     HL.Enable_Interrupt_Trap;
  16851.     end if;
  16852.     if not LU.Lock_Library(Library, WRITE_LOCK) then
  16853.     raise Library_Write_Locked;
  16854.     end if;
  16855.     if not LU.Privileged(Privilege, Library) then
  16856.     raise No_Privilege; 
  16857.     end if;
  16858.     LU.Open_Property_Node(Library, Keyword, Value, MODIFY, Node);
  16859.     HA.Set_Node_Attribute(Node   => Node,
  16860.               Attrib => SP.Value(Keyword),
  16861.               Value  => HLU.To_List(SP.Value(Value)));
  16862.     HNM.Close_Node_Handle(Node);
  16863.     LU.Unlock_Library(Library, WRITE_LOCK);
  16864.     if Message_on_Completion then
  16865.     HL.Put_Message_Line(
  16866.         "Property " & SP.Value(SP.Upper(Keyword)) &
  16867.         " changed to value " & SP.Value(SP.Upper(Value)) &
  16868.         " for library " & SP.Value(SP.Upper(Library)) & '.');
  16869.     end if;
  16870.     HL.Set_Interrupt_State(Trap);
  16871.     return HL.SUCCESS;
  16872.  
  16873. exception
  16874.  
  16875.     when Invalid_Library_Name =>
  16876.     LE.Report_Error(LE.Invalid_Library_Name, Library);
  16877.     HL.Set_Interrupt_State(Trap);
  16878.     return HL.ERROR;
  16879.  
  16880.     when Library_Does_Not_Exist =>
  16881.     LE.Report_Error(LE.Library_Does_Not_Exist, Library);
  16882.     HL.Set_Interrupt_State(Trap);
  16883.     return HL.ERROR;
  16884.  
  16885.     when Library_Master_Locked =>
  16886.     LE.Report_Error(LE.Library_Master_Locked, Library);
  16887.     HL.Set_Interrupt_State(Trap);
  16888.     return HL.ERROR;
  16889.  
  16890.     when Library_Write_Locked =>
  16891.     LE.Report_Error(LE.Library_Write_Locked, Library);
  16892.     HL.Set_Interrupt_State(Trap);
  16893.     return HL.ERROR;
  16894.  
  16895.     when Invalid_Keyword =>
  16896.     LU.Unlock_Library(Library, WRITE_LOCK);
  16897.     LE.Report_Error(LE.Invalid_Keyword, Keyword);
  16898.     HL.Set_Interrupt_State(Trap);
  16899.     return HL.ERROR;
  16900.  
  16901.     when Invalid_Value =>
  16902.     LU.Unlock_Library(Library, WRITE_LOCK);
  16903.     LE.Report_Error(LE.Invalid_Value, Value);
  16904.     HL.Set_Interrupt_State(Trap);
  16905.     return HL.ERROR;
  16906.  
  16907.     when Keyword_Not_Found =>
  16908.     LU.Unlock_Library(Library, WRITE_LOCK);
  16909.     LE.Report_Error(LE.Keyword_Not_Found, Keyword);
  16910.     HL.Set_Interrupt_State(Trap);
  16911.     return HL.ERROR;
  16912.  
  16913.     when No_Privilege =>
  16914.     LU.Unlock_Library(Library, WRITE_LOCK);
  16915.     LE.Report_Error(LE.No_Privilege, Library, SP.Create(LU.Get_Library_Attribute(Library, "OWNER")));
  16916.     HL.Set_Interrupt_State(Trap);
  16917.     return HL.ERROR;
  16918.  
  16919.     when HL.Interrupt_Encountered =>
  16920.     begin
  16921.         LU.Unlock_Library(Library, WRITE_LOCK);
  16922.     exception
  16923.         when others => null;
  16924.     end;
  16925.     if HL."="(Trap, HL.ENABLED) then
  16926.         raise HL.Interrupt_Encountered;
  16927.     end if;
  16928.     LE.Report_Error(LE.Process_Interrupted, SP.Create("Modify_Property"));
  16929.     HL.Set_Interrupt_State(Trap);
  16930.     return HL.WARNING;
  16931.  
  16932.     when others =>
  16933.     begin
  16934.         LU.Unlock_Library(Library, WRITE_LOCK);
  16935.     exception
  16936.         when others => null;
  16937.     end;
  16938.     LE.Report_Error(LE.Internal_Error, SP.Create("Modify_Property"));
  16939.     HL.Set_Interrupt_State(Trap);
  16940.     return HL.SEVERE;
  16941.  
  16942. end Modify_Property_Interface;
  16943.                                                                     pragma page;
  16944. ::::::::::::::
  16945. modifyp.spc
  16946. ::::::::::::::
  16947. with Library_Declarations;            use Library_Declarations;
  16948. with String_Pkg;
  16949. with Host_Lib;
  16950.  
  16951. function Modify_Property_Interface(        --| Change Property Keyword/Value
  16952.     Library   : in String_Pkg.String_Type;    --| Item library
  16953.     Keyword   : in String_Pkg.String_Type;    --| Property keyword
  16954.     Value     : in String_Pkg.String_Type;    --| Property value
  16955.     Privilege : in Privilege_Type := WORLD    --| Modify privilege
  16956.     ) return Host_Lib.Severity_Code;
  16957.  
  16958. --| Requires:
  16959. --| The names of the library, and the keyword-value pair.
  16960.  
  16961. --| Effects:
  16962. --| The value of the keyword-value pair associated with the specified item
  16963. --| in the library is changed.
  16964.  
  16965. --| N/A: Modifies, Raises, Errors
  16966.                                                                     pragma page;
  16967. ::::::::::::::
  16968. opencat.ada
  16969. ::::::::::::::
  16970.  
  16971. --------- SPEC ----------------------------------------------------------
  16972.  
  16973. function open_catalog return INTEGER;
  16974.  
  16975. --------- BODY ----------------------------------------------------------
  16976.  
  16977. with Standard_Interface;
  16978. with Tool_Identifier;
  16979. with String_Pkg;
  16980. with Host_Lib;
  16981. with catalog_interface;
  16982.  
  16983. function open_catalog return INTEGER is
  16984.  
  16985.     package SP renames String_Pkg;
  16986.     package CI renames catalog_interface;
  16987.     package SI renames Standard_Interface;
  16988.  
  16989.     package input is new SI.String_Argument(        -- instantiate with
  16990.     String_Type_Name => "string");            -- subtype string
  16991.  
  16992.  
  16993.     process      : SI.Process_Handle;    -- handle to process structure
  16994.     catalog     : SP.string_type;    -- name of the catalog
  16995.  
  16996. begin
  16997.  
  16998.     SI.set_tool_identifier (Tool_Identifier);
  16999.     SI.Define_Process(            -- define this process
  17000.     Name    => "open_catalog",    -- name of the process
  17001.     Help    => "Open a configuration item catalog",
  17002.     Proc    => process);        -- handle to be returned
  17003.  
  17004.     Input.Define_Argument(    -- define the first argument
  17005.     Proc => Process,        -- process 
  17006.     Name => "catalog_name",        -- name of the argument
  17007.     Help => "Name of the catalog to be opened");
  17008.  
  17009.     SI.define_help (process,
  17010.     "Opens the specified catalog and places the user in interactive");
  17011.     SI.append_help (process,
  17012.     "mode.  The name given must belong to an existent catalog.");
  17013.     SI.append_help (process,
  17014.     "Create_Catalog should be run first if the catalog does not exist");
  17015.     SI.append_help (process,
  17016.     "The user must be a document system manager user to run this tool");
  17017.     SI.append_help (process,
  17018.     "(see Add_User).");
  17019.  
  17020.     SI.Parse_Line(Process);        -- parse the command line
  17021.  
  17022.     catalog := Input.Get_Argument(    -- get the first argument
  17023.             Proc => Process,
  17024.             Name => "catalog_name");
  17025.  
  17026.     SI.Undefine_Process(Proc => Process);    -- destroy the process block
  17027.  
  17028.     CI.open_catalog (catalog);
  17029.  
  17030.     return Host_Lib.Return_Code(Host_Lib.SUCCESS);-- return successful return code
  17031.  
  17032. exception
  17033.  
  17034.     when SI.Process_Help =>
  17035.     --
  17036.     -- Help message was printed
  17037.     --
  17038.     return Host_Lib.Return_Code(Host_Lib.INFORMATION);
  17039.  
  17040.     when SI.Abort_Process =>
  17041.     --
  17042.     -- Parse error
  17043.     --
  17044.     return Host_Lib.Return_Code(Host_Lib.ERROR);
  17045.  
  17046. end open_catalog;
  17047. ::::::::::::::
  17048. paginate.ada
  17049. ::::::::::::::
  17050. with TEXT_IO;
  17051. with Standard_Interface;
  17052. with String_Pkg;
  17053. with String_Lists;
  17054. with String_Utilities;
  17055. with File_Manager;
  17056. with Paginated_Output;
  17057. with Host_Lib;
  17058.  
  17059.  
  17060. function Paginate return INTEGER is
  17061.  
  17062.     subtype Page_Number is INTEGER range 1 .. 999;
  17063.     subtype Margin_Number is INTEGER range 0 .. 20;
  17064.     type Switch is (ON, OFF);
  17065.  
  17066.     package TIO        renames TEXT_IO;
  17067.     package SP         renames String_Pkg;
  17068.     package SL         renames STRING_Lists;
  17069.     package SU         renames String_Utilities;
  17070.     package FM         renames File_Manager;
  17071.     package PO         renames Paginated_Output;
  17072.     package HL         renames Host_Lib;
  17073.     package Sources    is new Standard_Interface.String_List_Argument(
  17074.                 String_Type_Name => "file_name",
  17075.                 String_Type_List => "source_list");
  17076.     package Output     is new Standard_Interface.String_Argument(
  17077.                 String_Type_Name => "file_name");
  17078.     package Stringtype is new Standard_Interface.String_Argument(
  17079.                 String_Type_Name => "string");
  17080.     package Pagetype   is new Standard_Interface.Integer_Argument(
  17081.                 Integer_Type      =>  Page_Number,
  17082.                 Integer_Type_Name => "page_type");
  17083.     package Margintype is new Standard_Interface.Integer_Argument(
  17084.                 Integer_Type      =>  Margin_Number,
  17085.                 Integer_Type_Name => "margin_type");
  17086.     package Numbertype is new Standard_Interface.Enumerated_Argument(
  17087.                 Enum_Type      =>  Switch,
  17088.                 Enum_Type_Name => "switch");
  17089.  
  17090.  
  17091.     Paginate_Process : Standard_Interface.Process_Handle;
  17092.     Found            : BOOLEAN;
  17093.     Files            : SL.List;
  17094.     File_List        : SL.List := SL.Create;
  17095.     File_Name        : SP.String_Type;
  17096.     File_Iter        : SL.ListIter;
  17097.     Out_File         : SP.String_Type;
  17098.     Out_Handle       : PO.Paginated_File_Handle;
  17099.     Header           : SP.String_Type;
  17100.     Footer           : SP.String_Type;
  17101.     Page             : INTEGER;
  17102.     Margin           : INTEGER;
  17103.     Input_Line       : STRING (1 .. 512);
  17104.     Input_Len        : INTEGER;
  17105.     File_Type        : TIO.FILE_TYPE;
  17106.     File_Mode        : TIO.FILE_MODE    := TIO.IN_FILE;
  17107.     Line_Num         : NATURAL;
  17108.     Numbering        : Switch;
  17109.     Status           : HL.Severity_Code := HL.SUCCESS;
  17110.                                                                     pragma page;
  17111. begin  -- procedure MAIN
  17112.  
  17113.     SP.Mark;
  17114.  
  17115.     Standard_Interface.Set_Tool_Identifier(
  17116.     Identifier => "1.00");
  17117.  
  17118.     Standard_Interface.Define_Process(
  17119.     Proc    => Paginate_Process,
  17120.     Name    => "Paginate",
  17121.     Help    => "Formats file(s) as specified");
  17122.  
  17123.     Sources.Define_Argument(
  17124.     Proc => Paginate_Process,
  17125.     Name => "source_list",
  17126.     Help => "List of file name(s) to be formatted");
  17127.  
  17128.     Output.Define_Argument(
  17129.     Proc => Paginate_Process,
  17130.     Name => "output",
  17131.     Help => "Output file name (defaults to standard output)");
  17132.  
  17133.     Stringtype.Define_Argument(
  17134.     Proc    => Paginate_Process,
  17135.     Name    => "header",
  17136.     Default => "~F(L50) ~D  ~T   Page ~P(R3)",
  17137.     Help    => "Header text");
  17138.  
  17139.     Stringtype.Define_Argument(
  17140.     Proc    => Paginate_Process,
  17141.     Name    => "footer",
  17142.     Default => "",
  17143.     Help    => "Footer text");
  17144.  
  17145.     Pagetype.Define_Argument(
  17146.     Proc    => Paginate_Process,
  17147.     Name    => "page",
  17148.     Default => 60,
  17149.     Help    => "Number of lines per page (excluding header/footer)");
  17150.  
  17151.     Margintype.Define_Argument(
  17152.     Proc    => Paginate_Process,
  17153.     Name    => "margin",
  17154.     Default => 0,
  17155.     Help    => "Left margin size");
  17156.  
  17157.     Numbertype.Define_Argument(
  17158.     Proc    => Paginate_Process,
  17159.     Name    => "number",
  17160.     Default => off,
  17161.     Help    => "Line numbering");
  17162.  
  17163.     Standard_Interface.Parse_Line(Paginate_Process);
  17164.  
  17165.     Files    := Sources.Get_Argument(
  17166.             Proc => Paginate_Process,
  17167.             Name => "source_list");
  17168.  
  17169.     Out_File := Output.Get_Argument(
  17170.             Proc => Paginate_Process,
  17171.             Name => "output");
  17172.  
  17173.     Page     := Pagetype.Get_Argument(
  17174.             Proc => Paginate_Process,
  17175.             Name => "page");
  17176.  
  17177.     Margin   := Margintype.Get_Argument(
  17178.             Proc => Paginate_Process,
  17179.             Name => "margin");
  17180.  
  17181.     Header   := Stringtype.Get_Argument(
  17182.             Proc => Paginate_Process,
  17183.             Name => "header");
  17184.  
  17185.     Footer   := Stringtype.Get_Argument(
  17186.             Proc => Paginate_Process,
  17187.             Name => "footer");
  17188.  
  17189.     Numbering := Numbertype.Get_Argument(
  17190.             Proc => Paginate_Process,
  17191.             Name => "number");
  17192.  
  17193.     SP.Release;
  17194.  
  17195.     HL.Set_Error;
  17196.  
  17197.     File_Iter := SL.MakeListIter(Files);
  17198.     while SL.More(File_Iter) loop
  17199.     SP.Mark;
  17200.     SL.Next(File_Iter, File_Name);
  17201.     begin
  17202.         SL.Attach(File_List, FM.Expand(SP.Value(File_Name)));
  17203.     exception
  17204.         when FM.Directory_Not_Found |
  17205.          FM.Expand_Error        |
  17206.          FM.File_Name_Error     |
  17207.          FM.Parse_Error         =>
  17208.         HL.Put_Message_Line("Warning : Invalid file name " & SP.Value(File_Name) & ".");
  17209.         Status := HL.WARNING;
  17210.         when FM.File_Not_Found =>
  17211.         HL.Put_Message_Line("Warning : Input file " & SP.Value(File_Name) & " not found.");
  17212.         Status := HL.WARNING;
  17213.     end;
  17214.     SP.Release;
  17215.     end loop;
  17216.  
  17217.     if not SL.IsEmpty(File_List) then
  17218.     PO.Create_Paginated_File(SP.Value(Out_File), Out_Handle, Page+6, 3, 3);
  17219.     PO.Set_Header(Out_Handle, 2, Header);
  17220.     PO.Set_Footer(Out_Handle, 2, Footer);
  17221.     else
  17222.     HL.Put_Error("No input files to print.");
  17223.     Status := HL.ERROR;
  17224.     end if;
  17225.  
  17226.     File_Iter := SL.MakeListIter(File_List);
  17227.     while SL.More(File_Iter) loop
  17228.     SP.Mark;
  17229.     SL.Next(File_Iter, File_Name);
  17230.     TIO.Open(File_Type, File_Mode, SP.Value(File_Name), "");
  17231.     PO.Set_File_Name(Out_Handle, SP.Value(File_Name));
  17232.     SP.Release;
  17233.     Line_Num := 1;
  17234.     begin
  17235.         loop
  17236.         PO.Space(Out_Handle, Margin);
  17237.         if Numbering = ON then
  17238.             PO.Put(Out_Handle, STRING'(SU.Image(Line_Num, 5)));
  17239.             PO.Space(Out_Handle, 3);
  17240.             Line_Num := Line_Num + 1;        
  17241.         end if;
  17242.         TIO.Get_Line(File_Type, Input_Line, Input_Len);
  17243.          PO.Put_Line(Out_Handle, Input_Line(1 .. Input_Len));
  17244.         end loop;
  17245.     exception
  17246.         when TIO.End_Error =>
  17247.         TIO.Close(File_Type);
  17248.         PO.Put_Page(Out_Handle);
  17249.     end;
  17250.     end loop;
  17251.  
  17252.     return HL.Return_Code(Status);
  17253.  
  17254. exception
  17255.  
  17256.     when TIO.Status_Error =>
  17257.         HL.Put_Error("File " & SP.Value(File_Name) & " already open.");
  17258.     return HL.Return_Code(HL.ERROR);
  17259.  
  17260.     when TIO.Name_Error =>
  17261.         HL.Put_Error("Unable to open file " & SP.Value(File_Name) & " for input.");
  17262.     return HL.Return_Code(HL.ERROR);
  17263.  
  17264.     when TIO.Use_Error =>
  17265.         HL.Put_Error("Invalid file name " & SP.Value(File_Name) & ".");
  17266.     return HL.Return_Code(HL.ERROR);
  17267.  
  17268.     when PO.File_Already_Open =>
  17269.         HL.Put_Error("File " & SP.Value(Out_File) & " already open.");
  17270.     return HL.Return_Code(HL.ERROR);
  17271.  
  17272.     when PO.File_Error =>
  17273.         HL.Put_Error("Unable to open " & SP.Value(Out_File) & " for output.");
  17274.     return HL.Return_Code(HL.ERROR);
  17275.  
  17276.     when Standard_Interface.Process_Help =>
  17277.     return HL.Return_Code(HL.INFORMATION);
  17278.  
  17279.     when Standard_Interface.Abort_Process =>
  17280.     return HL.Return_Code(HL.ERROR);
  17281.  
  17282.     when others =>
  17283.     HL.Put_Error("Paginate internal error.");
  17284.     return HL.Return_Code(HL.SEVERE);
  17285.  
  17286. end Paginate;
  17287.                                                                     pragma page;
  17288. ::::::::::::::
  17289. prop.bdy
  17290. ::::::::::::::
  17291.  
  17292. package body properties is
  17293.  
  17294. use string_pkg;
  17295.  
  17296. function "<" (        --| returns true if two properties have the same 
  17297.             --| keyword.
  17298.     p1 : in property;    
  17299.     p2 : in property
  17300.     ) return boolean is
  17301.  
  17302.     begin
  17303.     return (p1.key < p2.key);
  17304.     end "<";
  17305.  
  17306. function image (    --| returns a string representation of the property.
  17307.             --| keyword first, value second
  17308.     p : in property
  17309.     ) return string is
  17310.  
  17311.     s : SP.string_type;
  17312.     begin
  17313.     s := p.key & " - " & p.val;
  17314.     return SP.value (s);
  17315.     end image;
  17316.  
  17317. end properties;
  17318. ::::::::::::::
  17319. prop.spc
  17320. ::::::::::::::
  17321. with string_pkg;
  17322.  
  17323. package properties is
  17324.  
  17325. package SP renames string_pkg;
  17326.  
  17327. type property is 
  17328.     record
  17329.     key : SP.string_type;
  17330.     val : SP.string_type;
  17331.     end record;
  17332.  
  17333. function "<" (        --| returns true if two properties have the same 
  17334.             --| keyword.
  17335.     p1 : in property;    
  17336.     p2 : in property
  17337.     ) return boolean;
  17338.  
  17339. function image (    --| returns a string representation of the property.
  17340.             --| keyword first, value second
  17341.     p : in property
  17342.     ) return string;
  17343.  
  17344. end properties;
  17345.  
  17346. with orderedsets;
  17347. with properties;
  17348.  
  17349. package property_set is new orderedsets (properties.property, properties."<");
  17350. ::::::::::::::
  17351. purgei.ada
  17352. ::::::::::::::
  17353. with Standard_Interface;
  17354. with String_Pkg;
  17355. with Host_Lib;
  17356. with Item_Library_Manager;
  17357. with Item_Library_Manager_Utilities;
  17358. with Item_Library_Manager_Declarations;
  17359.  
  17360. function Purge_Item return INTEGER is
  17361.  
  17362.     package SI  renames Standard_Interface;
  17363.     package SP  renames String_Pkg;
  17364.     package HL  renames Host_Lib;
  17365.     package ILM renames Item_Library_Manager;
  17366.     package ILU renames Item_Library_Manager_Utilities;
  17367.     package ILD renames Item_Library_Manager_Declarations;
  17368.  
  17369.     package LIB is new SI.String_Argument(
  17370.                 String_Type_Name => "library_name");
  17371.     package ITM is new SI.String_Argument(
  17372.                 String_Type_Name => "item_name");
  17373.  
  17374.     Purge_Item_Process : SI.Process_Handle;
  17375.     Library            : SP.String_Type;
  17376.     Item               : SP.String_Type;
  17377.     List               : ILD.LL.List;
  17378.  
  17379. begin
  17380.  
  17381.     SP.Mark;
  17382.  
  17383.     SI.Set_Tool_Identifier(Identifier => "1.0");
  17384.  
  17385.     SI.Define_Process(
  17386.     Proc    => Purge_Item_Process,
  17387.     Name    => "Purge_Item",
  17388.     Help    => "Purge Item(s) in an Item Library");
  17389.  
  17390.     LIB.Define_Argument(
  17391.     Proc => Purge_Item_Process,
  17392.     Name => "library",
  17393.     Help => "Name of the item library");
  17394.  
  17395.     ITM.Define_Argument(
  17396.     Proc => Purge_Item_Process,
  17397.     Name => "item",
  17398.     Help => "Name of the item(s) to be purged in the item library");
  17399.  
  17400.     SP.Release;
  17401.  
  17402.     SI.Parse_Line(Purge_Item_Process);
  17403.  
  17404.     Library := LIB.Get_Argument(
  17405.             Proc => Purge_Item_Process,
  17406.             Name => "library");
  17407.  
  17408.     Item := ITM.Get_Argument(
  17409.             Proc => Purge_Item_Process,
  17410.             Name => "item");
  17411.  
  17412.     ILM.Purge_Item(Library   => Library,
  17413.            Item      => Item,
  17414.            Privilege => ILD.OWNER,
  17415.            Remainder => List);
  17416.  
  17417.     if not ILD.LL.IsEmpty(List) then
  17418.     ILU.Display_List(List, "Item/Version not purged");
  17419.     ILD.Destroy_List_of_Lists(List);
  17420.     else
  17421.         HL.Put_Message_Line("Item """ & SP.Value(SP.Upper(Item)) & """ purged.");
  17422.     end if;
  17423.     return HL.Return_Code(HL.SUCCESS);
  17424.     
  17425. exception
  17426.  
  17427.     when SI.Process_Help =>
  17428.     return HL.Return_Code(HL.INFORMATION);
  17429.  
  17430.     when SI.Abort_Process =>
  17431.     return HL.Return_Code(HL.SUCCESS);
  17432.  
  17433.     when ILD.Library_Does_Not_Exist =>
  17434.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ does not exist.");
  17435.     return HL.Return_Code(HL.ERROR);
  17436.  
  17437.     when ILD.Library_Master_Locked =>
  17438.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is master locked.");
  17439.     return HL.Return_Code(HL.ERROR);
  17440.  
  17441.     when ILD.Library_Write_Locked =>
  17442.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is write locked.");
  17443.     return HL.Return_Code(HL.ERROR);
  17444.  
  17445.     when ILD.Library_Read_Locked =>
  17446.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is read locked.");
  17447.     return HL.Return_Code(HL.ERROR);
  17448.  
  17449.     when ILD.Item_Not_Found =>
  17450.     HL.Put_Error("Item """ & SP.Value(SP.Upper(Item)) & """ not found.");
  17451.     return HL.Return_Code(HL.ERROR);
  17452.  
  17453.     when ILD.Item_Checked_Out =>
  17454.     HL.Put_Error("Item """ & SP.Value(SP.Upper(Item)) & """ checked out.");
  17455.     return HL.Return_Code(HL.ERROR);
  17456.  
  17457.     when ILD.Not_Authorized =>
  17458.     HL.Put_Error("Not authorized.");
  17459.     return HL.Return_Code(HL.ERROR);
  17460.  
  17461.     when ILD.No_Privilege =>
  17462.     HL.Put_Error("No privilege for attempted operation.");
  17463.     return HL.Return_Code(HL.ERROR);
  17464.  
  17465.     when others =>
  17466.     HL.Put_Error("Purge Item internal error.");
  17467.     return HL.Return_Code(HL.SEVERE);
  17468.  
  17469. end Purge_Item;
  17470.  
  17471. ::::::::::::::
  17472. purgei.bdy
  17473. ::::::::::::::
  17474. with Library_Errors;
  17475. with Library_Utilities;
  17476.  
  17477. function Purge_Item_Interface(
  17478.     Library   : in String_Pkg.String_Type;
  17479.     Item      : in String_Pkg.String_Type;
  17480.     Privilege : in Privilege_Type := WORLD
  17481.     ) return Host_Lib.Severity_Code is
  17482.  
  17483.     package SP  renames String_Pkg;
  17484.     package HL  renames Host_Lib;
  17485.     package LE  renames Library_Errors;
  17486.     package LU  renames Library_Utilities;
  17487.  
  17488.     List_of_Lists : LL.List;
  17489.     Trap          : HL.Interrupt_State := HL.Get_Interrupt_State;
  17490.  
  17491. begin
  17492.  
  17493.     if HL."="(Trap, HL.DISABLED) then
  17494.     HL.Enable_Interrupt_Trap;
  17495.     end if;
  17496.     if not LU.Lock_Library(Library, WRITE_LOCK) then
  17497.     raise Library_Write_Locked;
  17498.     end if;
  17499.     LU.Purge(Library, Item, Privilege, List_of_Lists);
  17500.     LU.Unlock_Library(Library, WRITE_LOCK);
  17501.     if not LL.IsEmpty(List_of_Lists) then
  17502.     if Message_on_Error then
  17503.         LU.Display_List(List_of_Lists, "Item/Version not purged");
  17504.     end if;
  17505.     elsif Message_on_Completion then
  17506.         HL.Put_Message_Line(
  17507.         "Item " & SP.Value(SP.Upper(Item)) &
  17508.         " purged in library " & SP.Value(SP.Upper(Library)) & '.');
  17509.     end if;
  17510.     HL.Set_Interrupt_State(Trap);
  17511.     return HL.SUCCESS;
  17512.  
  17513. exception
  17514.  
  17515.     when Invalid_Library_Name =>
  17516.     LE.Report_Error(LE.Invalid_Library_Name, Library);
  17517.     HL.Set_Interrupt_State(Trap);
  17518.     return HL.ERROR;
  17519.  
  17520.     when Library_Does_Not_Exist =>
  17521.     LE.Report_Error(LE.Library_Does_Not_Exist, Library);
  17522.     HL.Set_Interrupt_State(Trap);
  17523.     return HL.ERROR;
  17524.  
  17525.     when Library_Master_Locked =>
  17526.     LE.Report_Error(LE.Library_Master_Locked, Library);
  17527.     HL.Set_Interrupt_State(Trap);
  17528.     return HL.ERROR;
  17529.  
  17530.     when Library_Write_Locked =>
  17531.     LE.Report_Error(LE.Library_Write_Locked, Library);
  17532.     HL.Set_Interrupt_State(Trap);
  17533.     return HL.ERROR;
  17534.  
  17535.     when Item_Not_Found =>
  17536.     LU.Unlock_Library(Library, WRITE_LOCK);
  17537.     LE.Report_Error(LE.Item_Not_Found, Item);
  17538.     HL.Set_Interrupt_State(Trap);
  17539.     return HL.ERROR;
  17540.  
  17541.     when Item_Checked_Out =>
  17542.     LU.Unlock_Library(Library, WRITE_LOCK);
  17543.     LE.Report_Error(LE.Item_Checked_Out, Item);
  17544.     HL.Set_Interrupt_State(Trap);
  17545.     return HL.ERROR;
  17546.  
  17547.     when No_Privilege =>
  17548.     LU.Unlock_Library(Library, WRITE_LOCK);
  17549.     LE.Report_Error(LE.No_Privilege, Library, SP.Create(LU.Get_Library_Attribute(Library, "OWNER")));
  17550.     HL.Set_Interrupt_State(Trap);
  17551.     return HL.ERROR;
  17552.  
  17553.     when HL.Interrupt_Encountered =>
  17554.     begin
  17555.         LU.Unlock_Library(Library, WRITE_LOCK);
  17556.     exception
  17557.         when others => null;
  17558.     end;
  17559.     if HL."="(Trap, HL.ENABLED) then
  17560.         raise HL.Interrupt_Encountered;
  17561.     end if;
  17562.     LE.Report_Error(LE.Process_Interrupted, SP.Create("Purge_Item"));
  17563.     HL.Set_Interrupt_State(Trap);
  17564.     return HL.WARNING;
  17565.  
  17566.     when others =>
  17567.     begin
  17568.         LU.Unlock_Library(Library, WRITE_LOCK);
  17569.     exception
  17570.         when others => null;
  17571.     end;
  17572.     LE.Report_Error(LE.Internal_Error, SP.Create("Purge_Item"));
  17573.     HL.Set_Interrupt_State(Trap);
  17574.     return HL.SEVERE;
  17575.  
  17576. end Purge_Item_Interface;
  17577.                                                                     pragma page;
  17578. ::::::::::::::
  17579. purgei.spc
  17580. ::::::::::::::
  17581. with Library_Declarations;            use Library_Declarations;
  17582. with String_Pkg;
  17583. with Host_Lib;
  17584.  
  17585. function Purge_Item_Interface(            --| Purge Item(s)
  17586.     Library   : in String_Pkg.String_Type;    --| Item library
  17587.     Item      : in String_Pkg.String_Type;    --| Item (s) to be purged
  17588.     Privilege : in Privilege_Type := WORLD    --| Purge privilege
  17589.     ) return Host_Lib.Severity_Code;
  17590.  
  17591. --| Requires:
  17592. --| Name of the libray, and name of the item
  17593.  
  17594. --| Effects:
  17595. --| Purges (delete all but the current version) item(s) of the library
  17596.  
  17597. --| N/A: Modifies, Raises, Errors
  17598.                                                                     pragma page;
  17599. ::::::::::::::
  17600. rdparser.bdy
  17601. ::::::::::::::
  17602. with ci_index_mgr;
  17603.  
  17604. package body rd_parser is
  17605.  
  17606. package CI renames ci_index_mgr;
  17607.  
  17608. procedure parse (s : in string_pkg.string_type) is
  17609.  
  17610.     set1 : ci_set;
  17611.     begin
  17612.     scan := SS.make_scanner (s);
  17613.     advance;
  17614.     expression (set1);
  17615.     -- when expression gets done the whole expression should have been
  17616.     -- evaluated so set1 is the final result.  Set1 should then be made 
  17617.     -- the current_set.  If the whole expression was not evaluated it is
  17618.     -- a parse_error
  17619.     if token.term /= EOS then
  17620.         raise parse_error;
  17621.        end if;
  17622.     current_set := CS.copy(set1);
  17623.     CS.destroy (set1);
  17624.     end parse;
  17625.  
  17626. procedure clear_set is
  17627.     begin
  17628.     CS.destroy (current_set);
  17629.     end clear_set;
  17630.  
  17631. procedure expression (set : in out ci_set) is
  17632.  
  17633.     set2 : ci_set;
  17634.     begin
  17635.     factor (set);
  17636.     expression_prime (set, set2);
  17637.     end expression;
  17638.  
  17639. procedure expression_prime (
  17640.     set1 : in out ci_set;
  17641.     set2 : in out ci_set
  17642.     ) is
  17643.  
  17644.     operation   : op_type;
  17645.     begin
  17646.  
  17647.     if token.term = intersect or token.term = union then
  17648.         operation := token.term;
  17649.         advance;
  17650.         expression (set2);
  17651.         eval_operation (set1, set2, operation);
  17652.         expression_prime (set1, set2);
  17653.     end if;
  17654.     end expression_prime;
  17655.  
  17656. procedure factor (
  17657.     set : in out ci_set
  17658.     ) is
  17659.    
  17660.     begin
  17661.     if token.term = terminal then
  17662.         set := CS.copy(token.set);
  17663.         advance;
  17664.     elsif token.term = left_paren then
  17665.         advance;
  17666.         expression (set);
  17667.         if token.term = right_paren then
  17668.         advance;
  17669.         else
  17670.         raise parse_error;
  17671.         end if;
  17672.     else
  17673.         raise parse_error;
  17674.     end if;
  17675.     end factor;
  17676.  
  17677. procedure advance is
  17678.  
  17679.     char : character;
  17680.     begin
  17681.     if SU.more(scan) then
  17682.     SU.skip_space(scan);
  17683.     char := SU.get (scan);
  17684.     case char is
  17685.         when '(' =>
  17686.         token.term := left_paren;
  17687.         SU.forward (scan);
  17688.         when ')' =>
  17689.         token.term := right_paren;
  17690.         SU.forward (scan);
  17691.         when '&' =>
  17692.         token.term := intersect;
  17693.         SU.forward (scan);
  17694.         when '|' =>
  17695.         token.term := union;
  17696.         SU.forward (scan);
  17697.         when others =>
  17698.         token.set := scan_phrase;
  17699.         token.term := terminal;
  17700.     end case;
  17701.     else
  17702.     token.term := EOS;    -- end of string
  17703.     end if;
  17704.     end advance;
  17705.  
  17706. function scan_phrase return ci_set is
  17707.  
  17708.     key   : SP.string_type;
  17709.     value : SP.string_type;
  17710.     found : boolean;
  17711.     skip  : boolean := true;
  17712.     char  : character;
  17713.     begin
  17714.     SS.scan_ada_id (scan, found, key, skip);
  17715.     -- the first ada id can either be the reserved word CURRENT_SET or
  17716.     -- the keyword in a phrase like "language = ada"
  17717.     if not found then
  17718.         raise parse_error;
  17719.     end if;
  17720.     if SP.equal(SP.upper(key),SP.create("CURRENT_SET")) then
  17721.         -- if the id is CURRENT_SET then return current set.
  17722.         return current_set;
  17723.     else
  17724.         -- otherwise scan the rest of the string for the rest of the phrase
  17725.         -- if at any point it finds anything other than an '=' or an ada id
  17726.         -- it is a parse_error.
  17727.         while SU.more (scan) loop
  17728.         SU.next (scan, char);
  17729.         exit when char = '=';
  17730.         if char /= ' ' then
  17731.             raise parse_error;
  17732.         end if;
  17733.         end loop;
  17734.         SS.scan_ada_id (scan, found, value, skip);
  17735.         if not found then
  17736.         raise parse_error;
  17737.         end if;
  17738.         return CI.lookup_ci(key, value);
  17739.     end if;
  17740.     end scan_phrase;
  17741.  
  17742. procedure eval_operation (
  17743.     set1 : in out ci_set;
  17744.     set2 : in out ci_set;
  17745.     operation : in op_type
  17746.     ) is
  17747.  
  17748.     begin
  17749.     if operation = intersect then
  17750.         set1 := CS.intersect(set1, set2);
  17751.         CS.destroy (set2);
  17752.     else
  17753.         set1 := CS.union (set1, set2);
  17754.         CS.destroy (set2);
  17755.     end if;
  17756.     end eval_operation;
  17757.  
  17758. end rd_parser;
  17759. ::::::::::::::
  17760. rdparser.spc
  17761. ::::::::::::::
  17762. with string_pkg;
  17763. with catalog_decls;  use catalog_decls;
  17764. with string_utilities;
  17765.  
  17766. package rd_parser is
  17767.  
  17768. -- This is the grammar for the following procedures
  17769. -- terminal     ::= phrase or CURRENT_SET
  17770. -- op       ::= &  or  |
  17771. -- factor     ::= terminal or ( expression )
  17772. -- expression   ::= factor expression'
  17773. -- expression'  ::= op expression expression'  or  null
  17774.  
  17775. package SU renames string_utilities;
  17776. package SP renames string_pkg;
  17777. package CS renames ci_sets;        -- a type in catalog_decls
  17778.  
  17779. package SS is new SU.generic_string_utilities (SP.string_type,
  17780.                            SP.make_persistent,
  17781.                            SP.value);
  17782.  
  17783. type token_type is (terminal, union, intersect, left_paren, right_paren, eos);
  17784. subtype op_type is token_type range union..intersect;
  17785. type terminal_type is
  17786.     record 
  17787.     term : token_type;
  17788.     set  : ci_set;
  17789.     end record;
  17790.  
  17791. parse_error : exception;    -- raised when ever there is an error
  17792.  
  17793. token         : terminal_type;
  17794. scan          : SU.scanner;
  17795. current_set : ci_set;
  17796.  
  17797. procedure parse (s : in string_pkg.string_type);
  17798.  
  17799. procedure clear_set;
  17800.  
  17801. procedure expression (    --| Parses a selection criteria expression
  17802.     set : in out ci_set
  17803.     );
  17804.  
  17805. procedure expression_prime (    --| Parses a prime expression
  17806.     set1 : in out ci_set;
  17807.     set2 : in out ci_set
  17808.     );
  17809.  
  17810. procedure factor (    --| Parses a factor 
  17811.     set : in out ci_set
  17812.     );
  17813.  
  17814. procedure advance;    --| advances to the next token
  17815.  
  17816. function scan_phrase return ci_set;
  17817.             --| scans a phrase and returns the set indicated by the
  17818.             --| phrase
  17819.  
  17820. procedure eval_operation (    --| evaluates an expression according to the
  17821.                 --| operation indicated and the two sets
  17822.     set1 : in out ci_set;
  17823.     set2 : in out ci_set;
  17824.     operation : in op_type
  17825.     );
  17826.  
  17827. end rd_parser;
  17828.  
  17829. ::::::::::::::
  17830. renamei.ada
  17831. ::::::::::::::
  17832. with Standard_Interface;
  17833. with String_Pkg;
  17834. with Host_Lib;
  17835. with Item_Library_Manager;
  17836. with Item_Library_Manager_Utilities;
  17837. with Item_Library_Manager_Declarations;
  17838.  
  17839. function Rename_Item return INTEGER is
  17840.  
  17841.     package SI  renames Standard_Interface;
  17842.     package SP  renames String_Pkg;
  17843.     package HL  renames Host_Lib;
  17844.     package ILM renames Item_Library_Manager;
  17845.     package ILU renames Item_Library_Manager_Utilities;
  17846.     package ILD renames Item_Library_Manager_Declarations;
  17847.  
  17848.     package LIB is new SI.String_Argument(
  17849.                 String_Type_Name => "library_name");
  17850.     package ITM is new SI.String_Argument(
  17851.                 String_Type_Name => "item_name");
  17852.  
  17853.     Rename_Item_Process : SI.Process_Handle;
  17854.     Library             : SP.String_Type;
  17855.     From_Item           : SP.String_Type;
  17856.     To_Item             : SP.String_Type;
  17857.     List                : ILD.LL.List;
  17858.  
  17859. begin
  17860.  
  17861.     SP.Mark;
  17862.  
  17863.     SI.Set_Tool_Identifier(Identifier => "1.0");
  17864.  
  17865.     SI.Define_Process(
  17866.     Proc    => Rename_Item_Process,
  17867.     Name    => "Rename_Item",
  17868.     Help    => "Rename an Item in an Item Library");
  17869.  
  17870.     LIB.Define_Argument(
  17871.     Proc => Rename_Item_Process,
  17872.     Name => "library",
  17873.     Help => "Name of the item library");
  17874.  
  17875.     ITM.Define_Argument(
  17876.     Proc => Rename_Item_Process,
  17877.     Name => "from_item",
  17878.     Help => "Name of the item to be renamed in the item library");
  17879.  
  17880.     ITM.Define_Argument(
  17881.     Proc => Rename_Item_Process,
  17882.     Name => "to_item",
  17883.     Help => "New item name");
  17884.  
  17885.     SP.Release;
  17886.  
  17887.     SI.Parse_Line(Rename_Item_Process);
  17888.  
  17889.     Library := LIB.Get_Argument(
  17890.             Proc => Rename_Item_Process,
  17891.             Name => "library");
  17892.  
  17893.     From_Item := ITM.Get_Argument(
  17894.             Proc => Rename_Item_Process,
  17895.             Name => "from_item");
  17896.  
  17897.     To_Item := ITM.Get_Argument(
  17898.             Proc => Rename_Item_Process,
  17899.             Name => "to_item");
  17900.  
  17901.     ILM.Rename_Item(Library   => Library,
  17902.             From_Item => From_Item,
  17903.             To_Item   => To_Item,
  17904.             Privilege => ILD.OWNER,
  17905.             Remainder => List);
  17906.  
  17907.     if not ILD.LL.IsEmpty(List) then
  17908.     ILU.Display_List(List, "Item/Version not renamed");
  17909.     ILD.Destroy_List_of_Lists(List);
  17910.     else
  17911.         HL.Put_Message_Line("Item """ & SP.Value(SP.Upper(From_Item)) &
  17912.              """ renamed to """ & SP.Value(SP.Upper(To_Item)) &
  17913.              """.");
  17914.     end if;
  17915.     return HL.Return_Code(HL.SUCCESS);
  17916.     
  17917. exception
  17918.  
  17919.     when SI.Process_Help =>
  17920.     return HL.Return_Code(HL.INFORMATION);
  17921.  
  17922.     when SI.Abort_Process =>
  17923.     return HL.Return_Code(HL.SUCCESS);
  17924.  
  17925.     when ILD.Library_Does_Not_Exist =>
  17926.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ does not exist.");
  17927.     return HL.Return_Code(HL.ERROR);
  17928.  
  17929.     when ILD.Library_Master_Locked =>
  17930.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is master locked.");
  17931.     return HL.Return_Code(HL.ERROR);
  17932.  
  17933.     when ILD.Library_Write_Locked =>
  17934.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is write locked.");
  17935.     return HL.Return_Code(HL.ERROR);
  17936.  
  17937.     when ILD.Library_Read_Locked =>
  17938.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is read locked.");
  17939.     return HL.Return_Code(HL.ERROR);
  17940.  
  17941.     when ILD.Item_Not_Found =>
  17942.     HL.Put_Error("Item """ & SP.Value(SP.Upper(From_Item)) & """ not found.");
  17943.     return HL.Return_Code(HL.ERROR);
  17944.  
  17945.     when ILD.Item_Checked_Out =>
  17946.     HL.Put_Error("Item """ & SP.Value(SP.Upper(From_Item)) & """ checked out.");
  17947.     return HL.Return_Code(HL.ERROR);
  17948.  
  17949.     when ILD.Item_Already_Exists =>
  17950.     HL.Put_Error("Item """ & SP.Value(SP.Upper(To_Item)) & """ already exists.");
  17951.     return HL.Return_Code(HL.ERROR);
  17952.  
  17953.     when ILD.Not_Authorized =>
  17954.     HL.Put_Error("Not authorized.");
  17955.     return HL.Return_Code(HL.ERROR);
  17956.  
  17957.     when ILD.No_Privilege =>
  17958.     HL.Put_Error("No privilege for attempted operation.");
  17959.     return HL.Return_Code(HL.ERROR);
  17960.  
  17961.     when others =>
  17962.     HL.Put_Error("Rename Item internal error.");
  17963.     return HL.Return_Code(HL.SEVERE);
  17964.  
  17965. end Rename_Item;
  17966.  
  17967. ::::::::::::::
  17968. renamei.bdy
  17969. ::::::::::::::
  17970. with Library_Errors;
  17971. with Library_Utilities;
  17972.  
  17973. function Rename_Item_Interface(
  17974.     Library   : in String_Pkg.String_Type;
  17975.     From_Item : in String_Pkg.String_Type;
  17976.     To_Item   : in String_Pkg.String_Type;
  17977.     Privilege : in Privilege_Type := WORLD
  17978.     ) return Host_Lib.Severity_Code is
  17979.  
  17980.     package SP  renames String_Pkg;
  17981.     package HL  renames Host_Lib;
  17982.     package LE  renames Library_Errors;
  17983.     package LU  renames Library_Utilities;
  17984.  
  17985.     List_of_Lists : LL.List;
  17986.     Trap          : HL.Interrupt_State := HL.Get_Interrupt_State;
  17987.  
  17988. begin
  17989.  
  17990.     if HL."="(Trap, HL.DISABLED) then
  17991.     HL.Enable_Interrupt_Trap;
  17992.     end if;
  17993.     if not LU.Lock_Library(Library, WRITE_LOCK) then
  17994.     raise Library_Write_Locked;
  17995.     end if;
  17996.     if not LU.Privileged(Privilege, Library) then
  17997.     raise No_Privilege;
  17998.     end if;
  17999.     LU.Rename_Item(Library, From_Item, To_Item, Privilege, List_of_Lists);
  18000.     LU.Unlock_Library(Library, WRITE_LOCK);
  18001.     if not LL.IsEmpty(List_of_Lists) then
  18002.     if Message_on_Error then
  18003.         LU.Display_List(List_of_Lists, "Item/Version not renamed");
  18004.     end if;
  18005.     elsif Message_on_Completion then
  18006.         HL.Put_Message_Line(
  18007.         "Item " & SP.Value(SP.Upper(From_Item)) &
  18008.         " renamed to " & SP.Value(SP.Upper(To_Item)) &
  18009.         " in library " & SP.Value(SP.Upper(Library)) & '.');
  18010.     end if;
  18011.     HL.Set_Interrupt_State(Trap);
  18012.     return HL.SUCCESS;
  18013.  
  18014. exception
  18015.  
  18016.     when Invalid_Library_Name =>
  18017.     LE.Report_Error(LE.Invalid_Library_Name, Library);
  18018.     HL.Set_Interrupt_State(Trap);
  18019.     return HL.ERROR;
  18020.  
  18021.     when Library_Does_Not_Exist =>
  18022.     LE.Report_Error(LE.Library_Does_Not_Exist, Library);
  18023.     HL.Set_Interrupt_State(Trap);
  18024.     return HL.ERROR;
  18025.  
  18026.     when Library_Master_Locked =>
  18027.     LE.Report_Error(LE.Library_Master_Locked, Library);
  18028.     HL.Set_Interrupt_State(Trap);
  18029.     return HL.ERROR;
  18030.  
  18031.     when Library_Write_Locked =>
  18032.     LE.Report_Error(LE.Library_Write_Locked, Library);
  18033.     HL.Set_Interrupt_State(Trap);
  18034.     return HL.ERROR;
  18035.  
  18036.     when Item_Not_Found =>
  18037.     LU.Unlock_Library(Library, WRITE_LOCK);
  18038.     LE.Report_Error(LE.Item_Not_Found, From_Item);
  18039.     HL.Set_Interrupt_State(Trap);
  18040.     return HL.ERROR;
  18041.  
  18042.     when Item_Checked_Out =>
  18043.     LU.Unlock_Library(Library, WRITE_LOCK);
  18044.     LE.Report_Error(LE.Item_Checked_Out, From_Item);
  18045.     HL.Set_Interrupt_State(Trap);
  18046.     return HL.ERROR;
  18047.  
  18048.     when Item_Already_Exists =>
  18049.     LU.Unlock_Library(Library, WRITE_LOCK);
  18050.     LE.Report_Error(LE.Item_Already_Exists, To_Item);
  18051.     HL.Set_Interrupt_State(Trap);
  18052.     return HL.ERROR;
  18053.  
  18054.     when No_Privilege =>
  18055.     LU.Unlock_Library(Library, WRITE_LOCK);
  18056.     LE.Report_Error(LE.No_Privilege, SP.Create(LU.Get_Library_Attribute(Library, "OWNER")));
  18057.     HL.Set_Interrupt_State(Trap);
  18058.     return HL.ERROR;
  18059.  
  18060.     when HL.Interrupt_Encountered =>
  18061.     begin
  18062.         LU.Unlock_Library(Library, WRITE_LOCK);
  18063.     exception
  18064.         when others => null;
  18065.     end;
  18066.     if HL."="(Trap, HL.ENABLED) then
  18067.         raise HL.Interrupt_Encountered;
  18068.     end if;
  18069.     LE.Report_Error(LE.Process_Interrupted, SP.Create("Rename_Item"));
  18070.     HL.Set_Interrupt_State(Trap);
  18071.     return HL.WARNING;
  18072.  
  18073.     when others =>
  18074.     begin
  18075.         LU.Unlock_Library(Library, WRITE_LOCK);
  18076.     exception
  18077.         when others => null;
  18078.     end;
  18079.     LE.Report_Error(LE.Internal_Error, SP.Create("Rename_Item"));
  18080.     HL.Set_Interrupt_State(Trap);
  18081.     return HL.SEVERE;
  18082.  
  18083. end Rename_Item_Interface;
  18084.                                                                     pragma page;
  18085. ::::::::::::::
  18086. renamei.spc
  18087. ::::::::::::::
  18088. with Library_Declarations;            use Library_Declarations;
  18089. with String_Pkg;
  18090. with Host_Lib;
  18091.  
  18092. function Rename_Item_Interface(            --| Rename Item
  18093.     Library   : in String_Pkg.String_Type;    --| Item library
  18094.     From_Item : in String_Pkg.String_Type;    --| Item to be renamed
  18095.     To_Item   : in String_Pkg.String_Type;    --| New item name
  18096.     Privilege : in Privilege_Type := WORLD    --| Rename privilege
  18097.     ) return Host_Lib.Severity_Code;
  18098.  
  18099. --| Requires:
  18100. --| Name of the libray, item name to be renamed, and the new item name
  18101.  
  18102. --| Effects:
  18103. --| Renames item in the library
  18104.  
  18105. --| N/A: Modifies, Raises, Errors
  18106.                                                                     pragma page;
  18107. ::::::::::::::
  18108. renamev.ada
  18109. ::::::::::::::
  18110. with Standard_Interface;
  18111. with String_Pkg;
  18112. with Host_Lib;
  18113. with Item_Library_Manager;
  18114. with Item_Library_Manager_Utilities;
  18115. with Item_Library_Manager_Declarations;
  18116.  
  18117. function Rename_Version return INTEGER is
  18118.  
  18119.     package SI  renames Standard_Interface;
  18120.     package SP  renames String_Pkg;
  18121.     package HL  renames Host_Lib;
  18122.     package ILM renames Item_Library_Manager;
  18123.     package ILU renames Item_Library_Manager_Utilities;
  18124.     package ILD renames Item_Library_Manager_Declarations;
  18125.  
  18126.     package LIB is new SI.String_Argument(
  18127.                 String_Type_Name => "library_name");
  18128.     package ITM is new SI.String_Argument(
  18129.                 String_Type_Name => "item_name");
  18130.     package VER is new SI.String_Argument(
  18131.                 String_Type_Name => "version");
  18132.  
  18133.     Rename_Version_Process : SI.Process_Handle;
  18134.     Library                : SP.String_Type;
  18135.     Item                   : SP.String_Type;
  18136.     From_Version           : SP.String_Type;
  18137.     To_Version             : SP.String_Type;
  18138.     List                   : ILD.LL.List;
  18139.  
  18140. begin
  18141.  
  18142.     SP.Mark;
  18143.  
  18144.     SI.Set_Tool_Identifier(Identifier => "1.0");
  18145.  
  18146.     SI.Define_Process(
  18147.     Proc    => Rename_Version_Process,
  18148.     Name    => "Rename_Version",
  18149.     Help    => "Rename Version of Item(s) in an Item Library");
  18150.  
  18151.     LIB.Define_Argument(
  18152.     Proc => Rename_Version_Process,
  18153.     Name => "library",
  18154.     Help => "Name of the item library");
  18155.  
  18156.     ITM.Define_Argument(
  18157.     Proc => Rename_Version_Process,
  18158.     Name => "item",
  18159.     Help => "Name of the item(s) to be renamed in the item library");
  18160.  
  18161.     VER.Define_Argument(
  18162.     Proc => Rename_Version_Process,
  18163.     Name => "from_version",
  18164.     Help => "Version of item(s) to be renamed");
  18165.  
  18166.     VER.Define_Argument(
  18167.     Proc => Rename_Version_Process,
  18168.     Name => "to_version",
  18169.     Help => "New version of item(s)");
  18170.  
  18171.     SP.Release;
  18172.  
  18173.     SI.Parse_Line(Rename_Version_Process);
  18174.  
  18175.     Library := LIB.Get_Argument(
  18176.             Proc => Rename_Version_Process,
  18177.             Name => "library");
  18178.  
  18179.     Item := ITM.Get_Argument(
  18180.             Proc => Rename_Version_Process,
  18181.             Name => "item");
  18182.  
  18183.     From_Version := VER.Get_Argument(
  18184.             Proc => Rename_Version_Process,
  18185.             Name => "from_version");
  18186.  
  18187.     To_Version := VER.Get_Argument(
  18188.             Proc => Rename_Version_Process,
  18189.             Name => "to_version");
  18190.  
  18191.     ILM.Rename_Version(Library      => Library,
  18192.                Item         => Item,
  18193.                From_Version => From_Version,
  18194.                To_Version   => To_Version,
  18195.                Privilege    => ILD.OWNER,
  18196.                Remainder    => List);
  18197.  
  18198.     if not ILD.LL.IsEmpty(List) then
  18199.     ILU.Display_List(List, "Item/Version not renamed");
  18200.     ILD.Destroy_List_of_Lists(List);
  18201.     else
  18202.         HL.Put_Message_Line("Item """ &
  18203.              SP.Value(SP.Upper(Item)) & '/' & SP.Value(SP.Upper(From_Version)) &
  18204.              """ renamed to """ &
  18205.              SP.Value(SP.Upper(Item)) & '/' & SP.Value(SP.Upper(To_Version)) &
  18206.              '.');
  18207.     end if;
  18208.     return HL.Return_Code(HL.SUCCESS);
  18209.  
  18210. exception
  18211.  
  18212.     when SI.Process_Help =>
  18213.     return HL.Return_Code(HL.INFORMATION);
  18214.  
  18215.     when SI.Abort_Process =>
  18216.     return HL.Return_Code(HL.SUCCESS);
  18217.  
  18218.     when ILD.Library_Does_Not_Exist =>
  18219.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ does not exist.");
  18220.     return HL.Return_Code(HL.ERROR);
  18221.  
  18222.     when ILD.Library_Master_Locked =>
  18223.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is master locked.");
  18224.     return HL.Return_Code(HL.ERROR);
  18225.  
  18226.     when ILD.Library_Write_Locked =>
  18227.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is write locked.");
  18228.     return HL.Return_Code(HL.ERROR);
  18229.  
  18230.     when ILD.Library_Read_Locked =>
  18231.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is read locked.");
  18232.     return HL.Return_Code(HL.ERROR);
  18233.  
  18234.     when ILD.Item_Not_Found =>
  18235.     HL.Put_Error("Item """ & SP.Value(SP.Upper(Item)) & """ not found.");
  18236.     return HL.Return_Code(HL.ERROR);
  18237.  
  18238.     when ILD.Item_Checked_Out =>
  18239.     HL.Put_Error("Item """ & SP.Value(SP.Upper(Item)) & """ checked out.");
  18240.     return HL.Return_Code(HL.ERROR);
  18241.  
  18242.     when ILD.Invalid_Version =>
  18243.     HL.Put_Error("Invalid version specification.");
  18244.     return HL.Return_Code(HL.ERROR);
  18245.  
  18246.     when ILD.Version_Not_Found =>
  18247.     HL.Put_Error("Version not found.");
  18248.     return HL.Return_Code(HL.ERROR);
  18249.  
  18250.     when ILD.Not_Authorized =>
  18251.     HL.Put_Error("Not authorized.");
  18252.     return HL.Return_Code(HL.ERROR);
  18253.  
  18254.     when ILD.No_Privilege =>
  18255.     HL.Put_Error("No privilege for attempted operation.");
  18256.     return HL.Return_Code(HL.ERROR);
  18257.  
  18258.     when others =>
  18259.     HL.Put_Error("Rename Version internal error.");
  18260.     return HL.Return_Code(HL.SEVERE);
  18261.  
  18262. end Rename_Version;
  18263.  
  18264. ::::::::::::::
  18265. renamev.bdy
  18266. ::::::::::::::
  18267. with Library_Errors;
  18268. with Library_Utilities;
  18269.  
  18270. function Rename_Version_Interface(
  18271.     Library      : in String_Pkg.String_Type;
  18272.     Item         : in String_Pkg.String_Type;
  18273.     From_Version : in String_Pkg.String_Type;
  18274.     To_Version   : in String_Pkg.String_Type;
  18275.     Privilege    : in Privilege_Type := WORLD
  18276.     ) return Host_Lib.Severity_Code is
  18277.  
  18278.     package SP  renames String_Pkg;
  18279.     package HL  renames Host_Lib;
  18280.     package LE  renames Library_Errors;
  18281.     package LU  renames Library_Utilities;
  18282.  
  18283.     List_of_Lists  : LL.List;
  18284.     Version_Number : INTEGER;
  18285.     Trap           : HL.Interrupt_State := HL.Get_Interrupt_State;
  18286.     
  18287. begin
  18288.  
  18289.     if HL."="(Trap, HL.DISABLED) then
  18290.     HL.Enable_Interrupt_Trap;
  18291.     end if;
  18292.     if not LU.Lock_Library(Library, WRITE_LOCK) then
  18293.     raise Library_Write_Locked;
  18294.     end if;
  18295.     if not LU.Privileged(Privilege, Library) then
  18296.     raise No_Privilege;
  18297.     end if;
  18298.     LU.Rename_Version(Library, Item, From_Version, To_Version, Privilege, List_of_Lists);
  18299.     LU.Unlock_Library(Library, WRITE_LOCK);
  18300.     if not LL.IsEmpty(List_of_Lists) then
  18301.     if Message_on_Error then
  18302.         LU.Display_List(List_of_Lists, "Item/Version not renamed");
  18303.     end if;
  18304.     elsif Message_on_Completion then
  18305.         HL.Put_Message_Line("Item(s) renamed to version " & SP.Value(To_Version) & '.');
  18306.     end if;
  18307.     HL.Set_Interrupt_State(Trap);
  18308.     return HL.SUCCESS;
  18309.  
  18310. exception
  18311.  
  18312.     when Invalid_Library_Name =>
  18313.     LE.Report_Error(LE.Invalid_Library_Name, Library);
  18314.     HL.Set_Interrupt_State(Trap);
  18315.     return HL.ERROR;
  18316.  
  18317.     when Library_Does_Not_Exist =>
  18318.     LE.Report_Error(LE.Library_Does_Not_Exist, Library);
  18319.     HL.Set_Interrupt_State(Trap);
  18320.     return HL.ERROR;
  18321.  
  18322.     when Library_Master_Locked =>
  18323.     LE.Report_Error(LE.Library_Master_Locked, Library);
  18324.     HL.Set_Interrupt_State(Trap);
  18325.     return HL.ERROR;
  18326.  
  18327.     when Library_Write_Locked =>
  18328.     LE.Report_Error(LE.Library_Write_Locked, Library);
  18329.     HL.Set_Interrupt_State(Trap);
  18330.     return HL.ERROR;
  18331.  
  18332.     when Item_Not_Found =>
  18333.     LU.Unlock_Library(Library, WRITE_LOCK);
  18334.     LE.Report_Error(LE.Item_Not_Found, Item);
  18335.     HL.Set_Interrupt_State(Trap);
  18336.     return HL.ERROR;
  18337.  
  18338.     when Invalid_Version =>
  18339.     LU.Unlock_Library(Library, WRITE_LOCK);
  18340.     begin
  18341.         Version_Number := INTEGER'value(SP.Value(From_Version));
  18342.     exception
  18343.         when others =>
  18344.         if not SP.Is_Empty(From_Version) then
  18345.             LE.Report_Error(LE.Invalid_Version, From_Version);
  18346.         end if;
  18347.     end;
  18348.     begin
  18349.         Version_Number := INTEGER'value(SP.Value(To_Version));
  18350.     exception
  18351.         when others =>
  18352.         if not SP.Is_Empty(To_Version) then
  18353.             LE.Report_Error(LE.Invalid_Version, To_Version);
  18354.         end if;
  18355.     end;
  18356.     HL.Set_Interrupt_State(Trap);
  18357.     return HL.ERROR;
  18358.  
  18359.     when Version_Not_Found =>
  18360.     LU.Unlock_Library(Library, WRITE_LOCK);
  18361.     LE.Report_Error(LE.Version_Not_Found, From_Version);
  18362.     HL.Set_Interrupt_State(Trap);
  18363.     return HL.ERROR;
  18364.  
  18365.     when No_Privilege =>
  18366.     LU.Unlock_Library(Library, WRITE_LOCK);
  18367.     LE.Report_Error(LE.No_Privilege, Library, SP.Create(LU.Get_Library_Attribute(Library, "OWNER")));
  18368.     HL.Set_Interrupt_State(Trap);
  18369.     return HL.ERROR;
  18370.  
  18371.     when HL.Interrupt_Encountered =>
  18372.     begin
  18373.         LU.Unlock_Library(Library, WRITE_LOCK);
  18374.     exception
  18375.         when others => null;
  18376.     end;
  18377.     if HL."="(Trap, HL.ENABLED) then
  18378.         raise HL.Interrupt_Encountered;
  18379.     end if;
  18380.     LE.Report_Error(LE.Process_Interrupted, SP.Create("Rename_Version"));
  18381.     HL.Set_Interrupt_State(Trap);
  18382.     return HL.WARNING;
  18383.  
  18384.     when others =>
  18385.     begin
  18386.         LU.Unlock_Library(Library, WRITE_LOCK);
  18387.     exception
  18388.         when others => null;
  18389.     end;
  18390.     LE.Report_Error(LE.Internal_Error, SP.Create("Rename_Version"));
  18391.     HL.Set_Interrupt_State(Trap);
  18392.     return HL.SEVERE;
  18393.  
  18394. end Rename_Version_Interface;
  18395.                                                                     pragma page;
  18396. ::::::::::::::
  18397. renamev.spc
  18398. ::::::::::::::
  18399. with Library_Declarations;            use Library_Declarations;
  18400. with String_Pkg;
  18401. with Host_Lib;
  18402.  
  18403. function Rename_Version_Interface(        --| Rename Version of Item(s)
  18404.     Library      : in String_Pkg.String_Type;    --| Item library
  18405.     Item         : in String_Pkg.String_Type;    --| Item(s) to be renamed
  18406.     From_Version : in String_Pkg.String_Type;    --| Version of item(s)
  18407.     To_Version   : in String_Pkg.String_Type;    --| New version of item(s)
  18408.     Privilege    : in Privilege_Type := WORLD    --| Rename privilege
  18409.    ) return Host_Lib.Severity_Code;
  18410.  
  18411. --| Requires:
  18412. --| Name of the libray, item name, version of the item to be renamed, and
  18413. --| the new version specification
  18414.  
  18415. --| Effects:
  18416. --| Renames the version specification of the given item in the library
  18417.  
  18418. --| N/A: Modifies, Raises, Errors
  18419.                                                                     pragma page;
  18420. ::::::::::::::
  18421. returni.ada
  18422. ::::::::::::::
  18423. with Standard_Interface;
  18424. with String_Pkg;
  18425. with Host_Lib;
  18426. with Tool_Identifier;
  18427. with Library_Errors;
  18428. with Return_Item_Interface;
  18429.  
  18430. function Return_Item return INTEGER is
  18431.  
  18432.     package SI  renames Standard_Interface;
  18433.     package SP  renames String_Pkg;
  18434.     package HL  renames Host_Lib;
  18435.     package LE  renames Library_Errors;
  18436.     package LIB is new SI.String_Argument(String_Type_Name => "library_name");
  18437.     package FN  is new SI.String_Argument(String_Type_Name => "file_name");
  18438.     package STR is new SI.String_Argument(String_Type_Name => "string");
  18439.  
  18440.     Return_Item_Process : SI.Process_Handle;
  18441.     Library             : SP.String_Type;
  18442.     File_Name           : SP.String_Type;
  18443.     History             : SP.String_Type;
  18444.  
  18445. begin
  18446.  
  18447.     SP.Mark;
  18448.  
  18449.     SI.Set_Tool_Identifier(Identifier => Tool_Identifier);
  18450.  
  18451.     SI.Define_Process(
  18452.     Proc    => Return_Item_Process,
  18453.     Name    => "Return_Item",
  18454.     Help    => "Return a File to an Item Library");
  18455.  
  18456.     LIB.Define_Argument(
  18457.     Proc => Return_Item_Process,
  18458.     Name => "library",
  18459.     Help => "Name of the item library");
  18460.  
  18461.     FN.Define_Argument(
  18462.     Proc => Return_Item_Process,
  18463.     Name => "file",
  18464.     Help => "Name of the file to be returned to the item library");
  18465.  
  18466.     STR.Define_Argument(
  18467.     Proc => Return_Item_Process,
  18468.     Name => "history",
  18469.     Help => "Description/reason for the change(s) in this item");
  18470.  
  18471.     SP.Release;
  18472.  
  18473.     SI.Parse_Line(Return_Item_Process);
  18474.  
  18475.     Library := LIB.Get_Argument(
  18476.             Proc => Return_Item_Process,
  18477.             Name => "library");
  18478.  
  18479.     File_Name := FN.Get_Argument(
  18480.             Proc => Return_Item_Process,
  18481.             Name => "file");
  18482.  
  18483.     History := STR.Get_Argument(
  18484.             Proc => Return_Item_Process,
  18485.             Name => "history");
  18486.  
  18487.     return HL.Return_Code(Return_Item_Interface(Library, File_Name, History));
  18488. exception
  18489.  
  18490.     when SI.Process_Help =>
  18491.     return HL.Return_Code(HL.INFORMATION);
  18492.  
  18493.     when SI.Abort_Process =>
  18494.     return HL.Return_Code(HL.ERROR);
  18495.  
  18496.     when others =>
  18497.     LE.Report_Error(LE.Internal_Error, SP.Create(""));
  18498.     return HL.Return_Code(HL.SEVERE);
  18499.  
  18500. end Return_Item;
  18501.                                                                     pragma page;
  18502. ::::::::::::::
  18503. returni.bdy
  18504. ::::::::::::::
  18505. with Library_Declarations;            use Library_Declarations;
  18506. with Library_Errors;
  18507. with Library_Utilities;
  18508. with File_Manager;
  18509.  
  18510. function Return_Item_Interface(
  18511.     Library : in String_Pkg.String_Type;
  18512.     File    : in String_Pkg.String_Type;
  18513.     History : in String_Pkg.String_Type
  18514.     ) return Host_Lib.Severity_Code is
  18515.  
  18516.     package SP  renames String_Pkg;
  18517.     package HL  renames Host_Lib;
  18518.     package LE  renames Library_Errors;
  18519.     package LU  renames Library_Utilities;
  18520.     package FM  renames File_Manager;
  18521.  
  18522.     Item_Value         : SP.String_Type;
  18523.     Checked_In_Version : SP.String_Type;
  18524.     Trap               : HL.Interrupt_State := HL.Get_Interrupt_State;
  18525.  
  18526. begin
  18527.  
  18528.     if HL."="(Trap, HL.DISABLED) then
  18529.     HL.Enable_Interrupt_Trap;
  18530.     end if;
  18531.     if not LU.Lock_Library(Library, WRITE_LOCK) then
  18532.     raise Library_Write_Locked;
  18533.     end if;
  18534.     Item_Value := SP.Create(FM.Parse_Filename(SP.Value(File), FM.FILE_ONLY));
  18535.     LU.Check_In_Item(Library, File, History, RETURN_ITEM, Checked_In_Version);
  18536.     LU.Unlock_Library(Library, WRITE_LOCK);
  18537.     if Message_on_Completion then
  18538.     HL.Put_Message_Line(
  18539.         "Item " & SP.Value(SP.Upper(Item_Value)) & '/' & SP.Value(Checked_In_Version) &
  18540.         " returned to library " &  SP.Value(SP.Upper(Library)) & '.');
  18541.     end if;
  18542.     HL.Set_Interrupt_State(Trap);
  18543.     return HL.SUCCESS;
  18544.  
  18545. exception
  18546.  
  18547.     when Library_Does_Not_Exist =>
  18548.     LE.Report_Error(LE.Library_Does_Not_Exist, Library);
  18549.     HL.Set_Interrupt_State(Trap);
  18550.     return HL.ERROR;
  18551.  
  18552.     when Library_Master_Locked =>
  18553.     LE.Report_Error(LE.Library_Master_Locked, Library);
  18554.     HL.Set_Interrupt_State(Trap);
  18555.     return HL.ERROR;
  18556.  
  18557.     when Library_Write_Locked =>
  18558.     LE.Report_Error(LE.Library_Write_Locked, Library);
  18559.     HL.Set_Interrupt_State(Trap);
  18560.     return HL.ERROR;
  18561.  
  18562.     when Item_Not_Found =>
  18563.     LU.Unlock_Library(Library, WRITE_LOCK);
  18564.     LE.Report_Error(LE.Item_Not_Found, Item_Value);
  18565.     HL.Set_Interrupt_State(Trap);
  18566.     return HL.ERROR;
  18567.  
  18568.     when Item_Not_Checked_Out =>
  18569.     LU.Unlock_Library(Library, WRITE_LOCK);
  18570.     LE.Report_Error(LE.Item_Not_Checked_Out, Item_Value);
  18571.     HL.Set_Interrupt_State(Trap);
  18572.     return HL.ERROR;
  18573.  
  18574.     when Invalid_External_Name =>
  18575.     LU.Unlock_Library(Library, WRITE_LOCK);
  18576.     LE.Report_Error(LE.Invalid_External_Name, Item_Value);
  18577.     HL.Set_Interrupt_State(Trap);
  18578.     return HL.ERROR;
  18579.  
  18580.     when File_Not_Found =>
  18581.     LU.Unlock_Library(Library, WRITE_LOCK);
  18582.     LE.Report_Error(LE.File_Not_Found, File);
  18583.     HL.Set_Interrupt_State(Trap);
  18584.     return HL.ERROR;
  18585.  
  18586.     when Item_Not_Created =>
  18587.     LU.Unlock_Library(Library, WRITE_LOCK);
  18588.     LE.Report_Error(LE.Item_Not_Created, Item_Value);
  18589.     HL.Set_Interrupt_State(Trap);
  18590.     return HL.ERROR;
  18591.  
  18592.     when Set_Protection_Error =>
  18593.     LU.Unlock_Library(Library, WRITE_LOCK);
  18594.     LE.Report_Error(LE.Set_Protection_Error, Item_Value);
  18595.     HL.Set_Interrupt_State(Trap);
  18596.     return HL.ERROR;
  18597.  
  18598.     when HL.Interrupt_Encountered =>
  18599.     begin
  18600.         LU.Unlock_Library(Library, WRITE_LOCK);
  18601.     exception
  18602.         when others => null;
  18603.     end;
  18604.     if HL."="(Trap, HL.ENABLED) then
  18605.         raise HL.Interrupt_Encountered;
  18606.     end if;
  18607.     LE.Report_Error(LE.Process_Interrupted, SP.Create("Return_Item"));
  18608.     HL.Set_Interrupt_State(Trap);
  18609.     return HL.WARNING;
  18610.  
  18611.     when others =>
  18612.     begin
  18613.         LU.Unlock_Library(Library, WRITE_LOCK);
  18614.     exception
  18615.         when others => null;
  18616.     end;
  18617.     LE.Report_Error(LE.Internal_Error, SP.Create("Return_Item"));
  18618.     HL.Set_Interrupt_State(Trap);
  18619.     return HL.SEVERE;
  18620.  
  18621. end Return_Item_Interface;
  18622.                                                                     pragma page;
  18623. ::::::::::::::
  18624. returni.spc
  18625. ::::::::::::::
  18626. with String_Pkg;
  18627. with Host_Lib;
  18628.  
  18629. function Return_Item_Interface(            --| Return a File
  18630.    Library : in String_Pkg.String_Type;        --| Item library
  18631.    File    : in String_Pkg.String_Type;        --| File to be returned
  18632.    History : in String_Pkg.String_Type        --| Description/reason
  18633.    ) return Host_Lib.Severity_Code;
  18634.  
  18635. --| Requires:
  18636. --| Name of the library, name of the file to be returned to the library, and
  18637. --| description of change(s)
  18638.  
  18639. --| Effects:
  18640. --| Returns a file back to the named library
  18641.  
  18642. --| N/A: Modifies, Raises, Errors
  18643.                                                                     pragma page;
  18644. ::::::::::::::
  18645. showhist.ada
  18646. ::::::::::::::
  18647. with Standard_Interface;
  18648. with String_Pkg;
  18649. with Host_Lib;
  18650. with Item_Library_Manager;
  18651. with Item_Library_Manager_Declarations;
  18652. with String_Lists;
  18653. with String_Utilities;
  18654.  
  18655. function Show_History return INTEGER is
  18656.  
  18657.     package SI  renames Standard_Interface;
  18658.     package SP  renames String_Pkg;
  18659.     package SL  renames String_Lists;
  18660.     package HL  renames Host_Lib;
  18661.     package SU  renames String_Utilities;
  18662.     package ILM renames Item_Library_Manager;
  18663.     package ILD renames Item_Library_Manager_Declarations;
  18664.  
  18665.     package LIB is new SI.String_Argument(
  18666.                 String_Type_Name => "library_name");
  18667.     package ITM is new SI.String_Argument(
  18668.                 String_Type_Name => "item_name");
  18669.     package VER is new SI.String_Argument(
  18670.                 String_Type_Name => "version");
  18671.  
  18672.     Show_History_Process : SI.Process_Handle;
  18673.     Library              : SP.String_Type;
  18674.     List                 : ILD.LL.List;
  18675.     List_Iter            : ILD.LL.ListIter;
  18676.     Value_List           : SL.List;
  18677.     Value_Iter           : SL.ListIter;
  18678.     History              : SP.String_Type;
  18679.     Item                 : SP.String_Type;
  18680.     Version              : SP.String_Type;
  18681.  
  18682. begin
  18683.  
  18684.     SP.Mark;
  18685.  
  18686.     SI.Set_Tool_Identifier(Identifier => "1.0");
  18687.  
  18688.     SI.Define_Process(
  18689.     Proc    => Show_History_Process,
  18690.     Name    => "Show_History",
  18691.     Help    => "Show History of Item(s) in an Item Library");
  18692.  
  18693.     LIB.Define_Argument(
  18694.     Proc => Show_History_Process,
  18695.     Name => "library",
  18696.     Help => "Name of the item library");
  18697.  
  18698.     ITM.Define_Argument(
  18699.     Proc    => Show_History_Process,
  18700.     Name    => "item",
  18701.     Default => "*",
  18702.     Help    => "Name of the item to list");
  18703.  
  18704.     VER.Define_Argument(
  18705.     Proc    => Show_History_Process,
  18706.     Name    => "version",
  18707.     Default => "",
  18708.     Help    => "Version specification");
  18709.  
  18710.     SP.Release;
  18711.  
  18712.     SI.Parse_Line(Show_History_Process);
  18713.  
  18714.     Library := LIB.Get_Argument(
  18715.             Proc => Show_History_Process,
  18716.             Name => "library");
  18717.  
  18718.     Item := ITM.Get_Argument(
  18719.             Proc => Show_History_Process,
  18720.             Name => "item");
  18721.  
  18722.     Version := VER.Get_Argument(
  18723.             Proc => Show_History_Process,
  18724.             Name => "version");
  18725.  
  18726.     List := ILM.Show_History(Library, Item, Version);
  18727.  
  18728.     List_Iter := ILD.LL.MakeListIter(List);
  18729.     while ILD.LL.More(List_Iter) loop
  18730.     ILD.LL.Next(List_Iter, Value_List);
  18731.     Value_Iter := SL.MakeListIter(Value_List);
  18732.     SP.Mark;
  18733.     SL.Next(Value_Iter, Item);
  18734.     SL.Next(Value_Iter, Version);
  18735.     HL.Put_Message_Line(SP.Value(Item) & '/' & SP.Value(Version));
  18736.     while SL.More(Value_Iter) loop 
  18737.         SP.Mark;
  18738.         SL.Next(Value_Iter, History);
  18739.         HL.Put_Message_Line("   * " & SP.Value(History));
  18740.         SP.Release;
  18741.     end loop;
  18742.     SP.Release;
  18743.     end loop;
  18744.     ILD.Destroy_List_of_Lists(List);
  18745.     return HL.Return_Code(HL.SUCCESS);
  18746.  
  18747. exception
  18748.  
  18749.     when SI.Process_Help =>
  18750.     return HL.Return_Code(HL.INFORMATION);
  18751.  
  18752.     when SI.Abort_Process =>
  18753.     return HL.Return_Code(HL.SUCCESS);
  18754.  
  18755.     when ILD.Library_Does_Not_Exist =>
  18756.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ does not exist.");
  18757.     return HL.Return_Code(HL.ERROR);
  18758.  
  18759.     when ILD.Library_Master_Locked =>
  18760.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is master locked.");
  18761.     return HL.Return_Code(HL.ERROR);
  18762.  
  18763.     when ILD.Library_Write_Locked =>
  18764.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is write locked.");
  18765.     return HL.Return_Code(HL.ERROR);
  18766.  
  18767.     when ILD.Library_Read_Locked =>
  18768.         HL.Put_Error("Library """ & SP.Value(SP.Upper(Library)) & """ is read locked.");
  18769.     return HL.Return_Code(HL.ERROR);
  18770.  
  18771.     when ILD.Item_Not_Found =>
  18772.     HL.Put_Error("Item """ & SP.Value(SP.Upper(Item)) & """ not found.");
  18773.     return HL.Return_Code(HL.ERROR);
  18774.  
  18775.     when ILD.Invalid_Version =>
  18776.     HL.Put_Error("Invalid version specification.");
  18777.     return HL.Return_Code(HL.ERROR);
  18778.  
  18779.     when ILD.Version_Not_Found =>
  18780.     HL.Put_Error("Version not found.");
  18781.     return HL.Return_Code(HL.ERROR);
  18782.  
  18783.     when ILD.Not_Authorized =>
  18784.     HL.Put_Error("Not authorized.");
  18785.     return HL.Return_Code(HL.ERROR);
  18786.  
  18787.     when ILD.No_Privilege =>
  18788.     HL.Put_Error("No privilege for attempted operation.");
  18789.     return HL.Return_Code(HL.ERROR);
  18790.  
  18791.     when others =>
  18792.     HL.Put_Error("Show History internal error.");
  18793.     return HL.Return_Code(HL.SEVERE);
  18794.  
  18795. end Show_History;
  18796.  
  18797. ::::::::::::::
  18798. showhist.bdy
  18799. ::::::::::::::
  18800. with Library_Declarations;            use Library_Declarations;
  18801. with Library_Errors;
  18802. with Library_Utilities;
  18803. with String_Lists;
  18804. with HIF_Utils;
  18805. with HIF_Node_Defs;
  18806. with HIF_Node_Management;
  18807. with HIF_Attributes;
  18808. with HIF_List_Utils;
  18809.  
  18810. function Show_History_Interface(
  18811.     Library : in String_Pkg.String_Type;
  18812.     Item    : in String_Pkg.String_Type;
  18813.     Version : in String_Pkg.String_Type
  18814.     ) return Host_Lib.Severity_Code is
  18815.  
  18816.     package SP  renames String_Pkg;
  18817.     package SL  renames String_Lists;
  18818.     package HL  renames Host_Lib;
  18819.     package LE  renames Library_Errors;
  18820.     package LU  renames Library_Utilities;
  18821.     package HU  renames HIF_Utils;
  18822.     package HND renames HIF_Node_Defs;
  18823.     package HNM renames HIF_Node_Management;
  18824.     package HA  renames HIF_Attributes;
  18825.     package HLU renames HIF_List_Utils;
  18826.  
  18827.     Item_Name        : SP.String_Type;
  18828.     Item_Node        : HND.Node_Type;
  18829.     Item_Iterator    : HNM.Node_Iterator;
  18830.     Versions         : SL.List;
  18831.     Version_Node     : HND.Node_Type;
  18832.     Version_Number   : SP.String_Type;
  18833.     Version_Iterator : SL.ListIter;
  18834.     History_List     : HLU.List_Type;
  18835.     L_Name           : SP.String_Type;
  18836.     I_Name           : SP.String_Type;
  18837.     V_Name           : SP.String_Type;
  18838.     Attribute_Value  : STRING(1 .. 16);
  18839.     Attribute_Length : INTEGER;
  18840.     Found            : BOOLEAN;
  18841.     Trap             : HL.Interrupt_State := HL.Get_Interrupt_State;
  18842.  
  18843.     procedure Error_Process is
  18844.  
  18845.     begin
  18846.  
  18847.     begin
  18848.         LU.Unlock_Library(Library, READ_LOCK);
  18849.     exception
  18850.         when others => null;
  18851.     end;
  18852.     HNM.Close_Node_Handle(Version_Node);
  18853.     HNM.Close_Node_Handle(Item_Node);
  18854.     Destroy_String_List(Versions);
  18855.  
  18856.     exception
  18857.     when others => null;
  18858.  
  18859.     end Error_Process;
  18860.  
  18861. begin
  18862.  
  18863.     if HL."="(Trap, HL.DISABLED) then
  18864.     HL.Enable_Interrupt_Trap;
  18865.     end if;
  18866.     if not LU.Lock_Library(Library, READ_LOCK) then
  18867.     raise Library_Read_Locked;
  18868.     end if;
  18869.     LU.Iterate_Item(Library, Item, Item_Iterator);
  18870.     while HNM.More(Item_Iterator) loop
  18871.     HNM.Get_Next(Item_Iterator, Item_Node);
  18872.     LU.Parse_Node(Item_Node, L_Name, I_Name, V_Name);
  18873.     Item_Name := SP.Create(LU.External_Name(SP.Value(I_Name)));
  18874.     HA.Get_Node_Attribute(Node   => Item_Node,
  18875.                   Attrib => "HISTORY",
  18876.                   Value  => History_List);
  18877.     begin
  18878.         Versions := LU.Get_Version(Item_Node, Version);
  18879.         Found := TRUE;
  18880.     exception
  18881.         when Version_Not_Found =>
  18882.         Found := FALSE;
  18883.     end;
  18884.     if Found then
  18885.         Version_Iterator := SL.MakeListIter(Versions);
  18886.         while SL.More(Version_Iterator) loop
  18887.         SL.Next(Version_Iterator, Version_Number);
  18888.         HL.Put_Message_Line(SP.Value(Item_Name) & '/' & SP.Value(Version_Number));
  18889.         HNM.Open_Node_Handle(Node         => Version_Node,
  18890.                      Base         => Item_Node,
  18891.                      Relation     => "DOT",
  18892.                      Key          => 'V' & SP.Value(Version_Number));
  18893.         HU.Get_Node_Attribute(Node       => Version_Node,
  18894.                       Attrib     => "HISTORY_INDEX",
  18895.                       Value      => Attribute_Value,
  18896.                       Value_Last => Attribute_Length);
  18897.         HNM.Close_Node_Handle(Version_Node);
  18898.         for i in reverse 1 .. INTEGER'value(Attribute_Value(1..Attribute_Length)) loop
  18899.             HL.Put_Message_Line("   * " &
  18900.                     HLU.Item_Image(HLU.Positional(History_List, HLU.Positive_Count(i)))
  18901.                         (HLU.Item_Image(HLU.Positional(History_List, HLU.Positive_Count(i)))'first + 1 ..
  18902.                          HLU.Item_Image(HLU.Positional(History_List, HLU.Positive_Count(i)))'last - 1));
  18903.         end loop;
  18904.         end loop;
  18905.         HNM.Close_Node_Handle(Item_Node);
  18906.         Destroy_String_List(Versions);
  18907.     end if;
  18908.     end loop;
  18909.     LU.Unlock_Library(Library, READ_LOCK);
  18910.     HL.Set_Interrupt_State(Trap);
  18911.     return HL.SUCCESS;
  18912.  
  18913. exception
  18914.  
  18915.     when Invalid_Library_Name =>
  18916.     Error_Process;
  18917.     LE.Report_Error(LE.Invalid_Library_Name, Library);
  18918.     HL.Set_Interrupt_State(Trap);
  18919.     return HL.ERROR;
  18920.  
  18921.     when Library_Does_Not_Exist =>
  18922.     Error_Process;
  18923.     LE.Report_Error(LE.Library_Does_Not_Exist, Library);
  18924.     HL.Set_Interrupt_State(Trap);
  18925.     return HL.ERROR;
  18926.  
  18927.     when Library_Master_Locked =>
  18928.     Error_Process;
  18929.     LE.Report_Error(LE.Library_Master_Locked, Library);
  18930.     HL.Set_Interrupt_State(Trap);
  18931.     return HL.ERROR;
  18932.  
  18933.     when Library_Read_Locked =>
  18934.     Error_Process;
  18935.     LE.Report_Error(LE.Library_Read_Locked, Library);
  18936.     HL.Set_Interrupt_State(Trap);
  18937.     return HL.ERROR;
  18938.  
  18939.     when Item_Not_Found =>
  18940.     Error_Process;
  18941.     LE.Report_Error(LE.Item_Not_Found, Item);
  18942.     HL.Set_Interrupt_State(Trap);
  18943.     return HL.ERROR;
  18944.  
  18945.     when Invalid_Version =>
  18946.     Error_Process;
  18947.     LE.Report_Error(LE.Invalid_Version, Version);
  18948.     HL.Set_Interrupt_State(Trap);
  18949.     return HL.ERROR;
  18950.  
  18951.     when Version_Not_Found =>
  18952.     Error_Process;
  18953.     LE.Report_Error(LE.Version_Not_Found, Version);
  18954.     HL.Set_Interrupt_State(Trap);
  18955.     return HL.ERROR;
  18956.  
  18957.     when HL.Interrupt_Encountered =>
  18958.     Error_Process;
  18959.     if HL."="(Trap, HL.ENABLED) then
  18960.         raise HL.Interrupt_Encountered;
  18961.     end if;
  18962.     LE.Report_Error(LE.Process_Interrupted, SP.Create("Show_History"));
  18963.     HL.Set_Interrupt_State(Trap);
  18964.     return HL.WARNING;
  18965.  
  18966.     when others =>
  18967.     Error_Process;
  18968.     LE.Report_Error(LE.Internal_Error, SP.Create("Show_History"));
  18969.     HL.Set_Interrupt_State(Trap);
  18970.     return HL.SEVERE;
  18971.  
  18972. end Show_History_Interface;
  18973.                                                                     pragma page;
  18974. ::::::::::::::
  18975. showhist.spc
  18976. ::::::::::::::
  18977. with String_Pkg;
  18978. with Host_Lib;
  18979.  
  18980. function Show_History_Interface(        --| Show History of Item(s)
  18981.     Library : in String_Pkg.String_Type;    --| Item library
  18982.     Item    : in String_Pkg.String_Type;    --| Item  to list
  18983.     Version : in String_Pkg.String_Type        --| Version specification
  18984.     ) return Host_Lib.Severity_Code;
  18985.  
  18986. --| Requires:
  18987. --| Library, item, and version names
  18988.  
  18989. --| Effects:
  18990. --| Displays the history (description) of the specified item/version in the
  18991. --| library
  18992.  
  18993. --| N/A: Modifies, Raises, Errors
  18994.                                                                     pragma page;
  18995. ::::::::::::::
  18996. srcfile
  18997. ::::::::::::::
  18998. ::::::::::::::
  18999. userutils.ada
  19000. ::::::::::::::
  19001. with Hif_System_Management;
  19002. with standard_interface;
  19003. with string_pkg;
  19004. with file_manager;
  19005. with text_io;
  19006. with host_lib;
  19007.      
  19008. procedure Add_User is
  19009.  
  19010. package SI renames standard_interface;
  19011. package SP renames string_pkg;
  19012. package HL renames host_lib;
  19013. package TIO renames text_io;
  19014.  
  19015. package string_arg is new SI.string_argument("string");
  19016.  
  19017.     directory_exists : exception;    -- raised when the directory to place
  19018.                     -- the repository in exists.
  19019.  
  19020.     process  : SI.process_handle;
  19021.     dir         : SP.string_type;
  19022.  
  19023. begin
  19024.     SI.set_tool_identifier ("1.0");
  19025.     SI.define_process ("add_user",
  19026.     "Adds the named user to the set of documentation system users",
  19027.     process);
  19028.     string_arg.define_argument (process,
  19029.                 "directory",
  19030.       "Name of the directory in which to store documentation information");
  19031.     string_arg.define_argument (process,
  19032.                 "user",
  19033.                 HL.get_item(HL.user_name),
  19034.                 "Name of the user to add");
  19035.     SI.define_help (process,
  19036.      "This procedure can be used to add any user to the set of documentation");
  19037.     SI.append_help (process,
  19038.      "system users.  If a person wants to be able to use the system they must");
  19039.      SI.append_help (process,
  19040.      "be entered in the system with the same user name as they have on the");
  19041.     SI.append_help (process,
  19042.      "host machine.  If this is not the case the person will not be recognized");
  19043.     SI.append_help (process,
  19044.      "as a documentation system user.  Each user name must be unique");
  19045.     SI.parse_line (process);
  19046.     dir := string_arg.get_argument(process, "directory");
  19047.     dir := SP.create (file_manager.path_name (directory => SP.value (dir),
  19048.                           file      => "",
  19049.                           absolute  => true));
  19050.     if file_manager.is_directory(SP.value(dir)) then
  19051.     raise directory_exists;
  19052.     end if;
  19053.     Hif_System_Management.Add_User(User_Name =>SP.value (
  19054.                            string_arg.get_argument(process,
  19055.                                        "user")),
  19056.                                    Host_File =>SP.value (dir));
  19057. exception 
  19058.     when file_manager.device_not_ready =>
  19059.     TIO.put_line ("Directory Error - device not ready");
  19060.     when file_manager.directory_not_found =>
  19061.     TIO.put_line ("Directory Error - directory not found");
  19062.     when file_manager.privilege_violation =>
  19063.     TIO.put_line ("Directory Error - privilege violation");
  19064.     when file_manager.parse_error =>
  19065.     TIO.put_line ("Directory Error - Incorrect syntax for a directory " &
  19066.             "specification");
  19067.     when directory_exists =>
  19068.     TIO.put_line ("Directory Error - Directory already exists");
  19069.     when SI.Process_Help =>
  19070.     --
  19071.     -- Help message was printed
  19072.     --
  19073.     null;
  19074.  
  19075.     when SI.Abort_Process =>
  19076.     --
  19077.     -- Parse error
  19078.     --
  19079.     null;
  19080.                            
  19081. end Add_User;
  19082.  
  19083. with Hif_System_Management;
  19084. with standard_interface;
  19085. with host_lib;     
  19086.      
  19087. procedure DELETE_USER is
  19088.  
  19089. package SI renames standard_interface;
  19090.  
  19091.     process  : SI.process_handle;
  19092.  
  19093. begin
  19094.     SI.set_tool_identifier ("1.0");
  19095.     SI.define_process ("delete_user",
  19096.                "Delete yourself as a documentation system user",
  19097.                process);
  19098.     SI.parse_line (process);
  19099.     Hif_System_Management.Remove_User(
  19100.         User_Name =>host_lib.get_item(host_lib.user_name));
  19101. exception
  19102.     when SI.Process_Help =>
  19103.     -- Help message was printed
  19104.     null;
  19105.     when SI.Abort_Process =>
  19106.     -- Parse error
  19107.     null;
  19108.                            
  19109. end DELETE_USER;
  19110.  
  19111. with Hif_System_Management;
  19112. with Hif_Node_management;
  19113. with Hif_Node_Defs;
  19114. with Document_Manager_Declarations;
  19115. with standard_interface;
  19116. with string_pkg;
  19117.      
  19118.      
  19119. procedure DELETE_HIF_USER is
  19120.  
  19121. package SI renames standard_interface;
  19122. package SP renames string_pkg;
  19123. package HNM renames Hif_Node_management;
  19124. package HND renames Hif_Node_Defs;
  19125. package DMD renames Document_Manager_Declarations;
  19126.  
  19127. package string_arg is new SI.string_argument("string");
  19128.     process  : SI.process_handle;
  19129.  
  19130. doc_node : HND.node_type;
  19131. name     : SP.string_type;
  19132.  
  19133. begin
  19134.     SI.set_tool_identifier ("1.0");
  19135.     SI.define_process ("delete_hif_user",
  19136.                "Delete a hif user",
  19137.                process);
  19138.     string_arg.define_argument (process,
  19139.                 "user",
  19140.                 "Name of the user to delete");
  19141.     SI.define_help (process,
  19142.      "This process can be used to delete any hif user in the documentation");
  19143.     SI.append_help (process,
  19144.      "system.  That includes catalogs and libraries as well as system users.");
  19145.     SI.append_help (process,
  19146.      "For this reason this executable should be used with extreme care.  To");
  19147.     SI.append_help (process,
  19148.      "delete a library or catalog instead of a user, simply give the name of");
  19149.     SI.append_help (process,
  19150.      "the library or catalog in place of the user name.");
  19151.     SI.parse_line (process);
  19152.     name := string_arg.get_argument (process, "user");
  19153.     HNM.open_node_handle (doc_node, DMD.document_manager_list_path);
  19154.  
  19155.     -- In case this user is a catalog or library try and unlink it from
  19156.     -- the docmgr list node before deleting the user.  Notice that if the link
  19157.     -- doesn't exist and name error is raised nothing happens.
  19158.     begin
  19159.     HNM.unlink (base     => doc_node,
  19160.             key      => SP.value(name),
  19161.             relation => "CATALOG");    
  19162.     exception when HND.name_error =>
  19163.     null;
  19164.     end;
  19165.     begin
  19166.     HNM.unlink (base     => doc_node,
  19167.             key      => SP.value(name),
  19168.             relation => "LIBRARY");    
  19169.     exception when HND.name_error =>
  19170.     null;
  19171.     end;
  19172.     Hif_System_Management.Remove_User(User_Name =>SP.value (name));
  19173.     HNM.close_node_handle (doc_node);
  19174. exception
  19175.     when SI.Process_Help =>
  19176.     -- Help message was printed
  19177.     null;
  19178.     when SI.Abort_Process =>
  19179.     -- Parse error
  19180.     null;
  19181.                            
  19182. end DELETE_HIF_USER;
  19183.  
  19184. ::::::::::::::
  19185. vlist.spc
  19186. ::::::::::::::
  19187. with Lists;
  19188. package version_lists is new Lists(positive);