1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129 | with Ada.Containers.Indefinite_Vectors;
with Ada.Directories;
with Ada.Strings.Unbounded;
with Ada.Text_IO;
package body Lined.Buffer is
type Line_Info (Length : Natural) is record
Mark : Boolean := False;
Line : String (1 .. Length);
end record;
package Line_Lists is new Ada.Containers.Indefinite_Vectors (Index_Type => Positive, Element_Type => Line_Info);
Line_List : Line_Lists.Vector;
File_Name : Ada.Strings.Unbounded.Unbounded_String;
procedure Clear is
-- Empty
begin -- Clear
Line_List.Clear;
end Clear;
procedure Mark (Number : in Positive; Status : in Boolean) is
procedure Update (Item : in out Line_Info);
-- Sets Item.Mark to Status
procedure Update (Item : in out Line_Info) is
-- Empty
begin -- Update
Item.Mark := Status;
end Update;
begin -- Mark
Line_List.Update_Element (Index => Number, Process => Update'Access);
end Mark;
function Marked (Number : Positive) return Boolean is (Line_List.Element (Number).Mark);
procedure Clear_Marks is
-- Empty
begin -- Clear_Marks
All_Lines : for I in 1 .. Line_List.Last_Index loop
Mark (Number => I, Status => False);
end loop All_Lines;
end Clear_Marks;
procedure Insert (Line : in String; Before : in Positive) is
-- Empty
begin -- Insert
Line_List.Insert (Before => Before, New_Item => (Length => Line'Length, Mark => False, Line => Line) );
end Insert;
procedure Delete (Number : in Positive) is
-- Empty
begin -- Delete
Line_List.Delete (Index => Number);
end Delete;
procedure Replace (Number : in Positive; Line : in String) is
-- Empty
begin -- Replace
Line_List.Replace_Element
(Index => Number, New_Item => (Length => Line'Length, Mark => Line_List.Element (Number).Mark, Line => Line) );
end Replace;
use Ada.Strings.Unbounded;
function Default_File return String is (To_String (File_Name) );
procedure Set_File (Name : in String) is
-- Empty
begin -- Set_File
File_Name := To_Unbounded_String (Name);
end Set_File;
procedure Load (File_Name : in String) is
File : Ada.Text_IO.File_Type;
begin -- Load
Buffer.File_Name := To_Unbounded_String (File_Name);
if not Ada.Directories.Exists (File_Name) then
return;
end if;
Clear;
Ada.Text_IO.Open (File => File, Mode => Ada.Text_IO.In_File, Name => File_Name);
Handle_EOF : declare
-- Empty
begin -- Handle_EOF
All_Lines : loop
Insert (Line => Ada.Text_IO.Get_Line (File), Before => Last + 1);
end loop All_Lines;
exception -- Handle_EOF
when Ada.Text_IO.End_Error =>
null;
end Handle_EOF;
Ada.Text_IO.Close (File => File);
end Load;
procedure Write (File_Name : in String := "") is
File : Ada.Text_IO.File_Type;
begin -- Write
if File_Name = "" and Buffer.File_Name = Null_Unbounded_String then
return;
end if;
if File_Name = "" then
Ada.Text_IO.Create (File => File, Name => To_String (Buffer.File_Name) );
else
Ada.Text_IO.Create (File => File, Name => File_Name);
Buffer.File_Name := To_Unbounded_String (File_Name);
end if;
All_Lines : for I in 1 .. Last loop
Ada.Text_IO.Put_Line (File => File, Item => Line (I) );
end loop All_Lines;
Ada.Text_IO.Close (File => File);
end Write;
function Last return Natural is (Line_List.Last_Index);
function Line (Number : Positive) return String is (Line_List.Element (Number).Line);
function Next (Number : Natural) return Positive is (if Number >= Last then 1 else Number + 1);
function Prev (Number : Natural) return Positive is (if Number < 2 then Last else Number - 1);
end Lined.Buffer;
|