Incompatibility - ytomino/drake GitHub Wiki
There is the list of ACATS violations, see status in drake-expected.txt.
Contents
Refer Ada Standards and ACATS.
This is a large violation of the standard. But I think it's usable and indispensable for real-world applications.
For example, String contains latin-1 characters in the standard.
But the encoding of modern operating systems is usually unicode.
By the way, you want to open a file. The Name parameter of Open is String.
Therefore you can not open a file named with unicode!
(Wide_Wide_Open is not existing. Also, if Wide_Wide_Open is existing, normal Open will be garbage...)
Next, you want to convert a line read from the file to upper case.
Ada.Characters.Handling.To_Upper converts all latin-1 alphabets including upper half characters(16#80#..16#ff#).
It means that To_Upper may break multi-byte characters in UTF-8.
You can't use standard library and have to write new function for case conversion yourself.
It's not possible to use almost all standard functions at all like this... if I keep the standard :-)
All functions of drake treat String as UTF-8, Wide_String as UTF-16, and Wide_Wide_String as UTF-32. No exception.
Conversely, you can't process latin-1 text in drake.
Note.
Form parameter will be used to specify UTF-8 file name in standard.
However, it's insufficient. Many functions does not have form parameter.
In addition, all functions in Ada.Characters and Ada.Strings,
and file name functions in Ada.Directories are still latin-1.
Probably, someone may break his file name or text data with these functions in the future.
Character'Image returns no ASCII names (e.g. "BPH" for 16#82#) but returns "Hex_82".
Character'Value does not parse ASCII names.
The functions in Ada.Characters.Conversions convert UTF-8/16/32.
They are same as Ada.Strings.UTF_Encoding.
Note, To_Wide_Character (Character'Val (16#c0#)) returns not 'À' but Substitute.
Because 16#c0# in UTF-8 is a part of multi-byte character. It's not able to exist in Wide_Character.
Ada.Characters.Handling and Ada.Strings.Maps.Constants have full Unicode Character Database.
The upper half characters of latin-1 declared in Ada.Characters.Latin_1 are redefined as UTF-8 String instead of latin-1 Character.
Ada.Strings.Maps.Character_Set and Character_Mapping are able to have all of UCS-4 characters.
Character_Set, Wide_Character_Set and Wide_Wide_Character_Set are actually same type.
All functions taking these types in Ada.Strings.Fixed, Ada.Strings.Bounded and Ada.Strings.Unbounded process by each code-points instead of each raw elements.
The functions in Ada.Wide_Text_IO/Wide_Wide_Text_IO convert between UTF-16 Wide_String (or UTF-32 Wide_Wide_String) and UTF-8 in a file.
Other Wide/Wide_Wide version functions (e.g. Ada.Exceptions.Wide_Exception_Name, Ada.Tags.Wide_Wide_Expanded_Name and etc...) returns UTF-16/32 converted from UTF-8 String.
These functions in Ada.Calendar calls POSIX time functions.
Unfortunately, the valid range of POSIX time is smaller than the range of the subtypes in Ada.Calendar in the standard.
These functions may cause a error when you gived a value that is out of POSIX time.
(It's not my policy. It's just my omission.)
Text_IO.End_Of_File shold return true over one end-of-line in the standard,
but this behavior has a little problem that it ignores the last empty line in a file.
Imagine a file containing 10 empty lines, and you are going to copy this file with Text_IO.
with Text_IO; use Text_IO;
with Ada.Command_Line;
procedure M is
S, D : File_Type;
begin
Open (S, Mode => In_File, Name => Ada.Command_Line.Argument (1));
Create (D, Mode => Out_File, Name => Ada.Command_Line.Argument (2));
while not End_Of_File (S) loop
Put_Line (D, Get_Line (S));
end loop;
Close (D);
Close (S);
end M;You may get a file containing 9 empty lines after one execution, and get a file containing 8 empty lines after twice execution, and get a file containing 7 empty lines...
Text_IO.End_Of_File of drake is strict.
It does not ignore any end-of-line, and you may get a file containing 10 lines.
It causes Tasking_Error (or dead-lock) like below:
with Text_IO; use Text_IO;
procedure M is
File_1, File_2 : File_Type;
begin
Create (File_1, Mode => Out_File, Name => "a"); -- acquiring exclusive-lock
Open (File_2, Mode => In_File, Name => "a"); -- trying to acquire shared-lock, and raising Tasking_Error !!
end M;It's able to switch to use no file locking.
Create (..., Form => "shared=yes");Some packages (e.g. Ada.Strings.Bounded and etc...) are separated since convenience of my implemetation like below:
with A_Impl_1;
with A_Impl_2;
package A is
subtype T is A_Impl_1.T;
function "=" (Lef, Right : T) return Boolean renames A_Impl_1."=";
procedure P renames A_Impl_2.P;
end A;Normally, it's no problem, of course. But it causes a little error on rare case.
with A;
procedure M is
use A;
use type A.T;
X, Y : T;
Z : Boolean;
begin
Z := X = Y; -- error !!
-- A."=" (introduced by use A) conflicts with A_Impl_1."=" (introduced by use type A.T)
end M;ACATS c41306a requires below:
function Make_The_Task return The_Task_Type is
begin
return Result_Task : The_Task_Type do
Result_Task.The_Entry; -- rendezvous before return
end return;
end Make_The_Task;But this test has been removed latest ACATS. Perhaps, because a task is activated at end of declaration part
declare
X : The_Task_Type := Make_The_Task;
begin -- <- X is activated in here!
...
end;It causes dead-lock in almost compilers including GNAT, in fact. However, this behavior is convenience a little. It's supported in drake. A rendezvous move up its activation of the task.
Many many features are unimplemented.
Refer GNAT reference manual.
Drake does not have any packages children of the package GNAT.
Ada standard contains good predefined libraries today, through Ada 2005 and 2012. The most part of GNAT library can be replaced with them. And also, drake contains different extended libraries.
| GNAT library | similar library in drake (or defined in the standard) |
|---|---|
| Ada.Characters.Wide_Latin_1 | Ada.Wide_Characters.Latin_1 |
| Ada.Characters.Wide_Wide_Latin_1 | Ada.Wide_Wide_Characters.Latin_1 |
| Ada.Command_Line.Environment | Ada.Environment_Variables |
| Ada.Containers.Formal_* | Ada.Containers.* |
| Ada.Strings.Unbounded.Text_IO | Ada.Text_IO.Unbounded |
| Ada.Wide_Characters.Unicode | Ada.Strings.Wide_Maps.Wide_Constants |
| Ada.Wide_Wide_Characters.Unicode | Ada.Strings.Wide_Wide_Maps.Wide_Wide_Constants |
| GNAT.Bubble_Sort (A/G) | Ada.Containers.Generic_Array_Sort [1] |
| GNAT.Byte_Order_Mark | Ada.Strings.UTF_Encoding |
| GNAT.Calendar | Ada.Calendar.Formatting |
| GNAT.Calendar.Time_IO | Ada.Calendar.Formatting |
| GNAT.Case_Util | Ada.Characters.ASCII.Handling |
| GNAT.Debug_Utilities | System.Storage_Elements.Formatting |
| GNAT.Decode_String | Ada.Characters.Conversions or Ada.Strings.UTF_Encoding |
| GNAT.Decode_UTF8_String | Ada.Characters.Conversions or Ada.Strings.UTF_Encoding |
| GNAT.Directory_Operations | Ada.Directories |
| GNAT.Directory_Operations.Iteration | Ada.Directories |
| GNAT.Dynamic_HTables | Ada.Containers.Hashed_Maps |
| GNAT.Dynamic_Tables | Ada.Containers.Vectors |
| GNAT.Encode_String | Ada.Characters.Conversions or Ada.Strings.UTF_Encoding |
| GNAT.Encode_UTF8_String | Ada.Characters.Conversions or Ada.Strings.UTF_Encoding |
| GNAT.Expect | Ada.Processes |
| GNAT.Heap_Sort (A/G) | Ada.Containers.Generic_Array_Sort [1] |
| GNAT.HTables | Ada.Containers.Hashed_Maps |
| GNAT.IO | Ada.Text_IO |
| GNAT.MBBS_Discrete_Random | Ada.Numerics.Discrete_Random [2] |
| GNAT.MBBS_Float_Random | Ada.Numerics.Float_Random [2] |
| GNAT.Random_Numbers | Ada.Numerics.MT19937 |
| GNAT.Source_Info | Ada.Debug |
| GNAT.Strings | Ada.Strings.Unbounded |
| GNAT.Tables | Ada.Containers.Vectors |
| GNAT.Time_Stamp | Ada.Calendar.Formatting |
| [1] | (1, 2) Ada.Containers.Generic_Array_Sort in drake is implemented with in-place merge sort. |
| [2] | (1, 2) Ada.Numerics.Discrete_Random and Float_Random in drake is implemented with MT19937. |
Some interface libraries for operating system or C runtime are able to be replaced with translated headers generated by headmaster.
| GNAT library | similar translated headers |
|---|---|
| GNAT.OS_Lib | C.time (time.h), C.stdlib (stdlib.h) or C.unistd (unistd.h) |
| GNAT.Threads | C.pthread (pthread.h) |
| GNAT.Signals | C.signal (signal.h) |
| Interfaces.C.Extensions | C |
| Interfaces.C.Streams | C.stdio (stdio.h) |
| GNAT library |
|---|
| Ada.Characters.Latin_9 |
| Ada.Characters.Wide_Latin_9 |
| Ada.Characters.Wide_Wide_Latin_9 |
GNAT has latin-9 packages. These are not supported in drake.
Excuse me, I have broken the rule, and might not have a right to pursues.
But I think... is RM A.3.3 really permit it?
It's consistent from start to finish in the standard that Character/String is latin-1, Wide_Character/Wide_String is UCS-2 and Wide_Wide_Character/Wide_Wide_String is UCS-4.
(RM 3.5.2 allows to make Character as EBCDIC by enumeration_representation_clause.
It means Character'Val and Character'Pos take a code as latin-1 as ever.)
Perhaps, this is a correct declaration:
Euro_Sign : constant Wide_Character := Wide_Character'Val (16#20AC#);
-- good, it represents one latin-9 character as UCS-2 Wide_Character.instead of the declaration in a-cwila9.ads.
Euro_Sign : constant Wide_Character := Wide_Character'Val (164);
-- bad, it breaks the rule that Wide_Character is UCS-2What do you think?
| GNAT library |
|---|
| Ada.Direct_IO.C_Streams |
| Ada.Streams.Stream_IO.C_Streams |
| Ada.Sequential_IO.C_Streams |
| Ada.Text_IO.C_Streams |
GNAT runtime provides C_Streams package to access FILE * of C runtime.
These I/O packages in drake use system calls directly. These do not use FILE *.
So, there is no way to access to FILE *.
If you want to use Text_IO.File_Type as a stream, use Ada.Text_IO.Text_Streams package.
If you want to do low-level operation, see Naked packages.
(Attention please. The packages named Naked are for implementation. I may change these more easily.)
Other many GNAT libraries are not supported.
GNAT runtime defines/refers some environment variables.
For example, GNAT$EXTENDED_FILE_SPECIFICATIONS, GNAT_FILE_NAME_CASE_SENSITIVE, GNAT_CODE_PAGE, GNAT_CCS_ENCODING, EH_DEBUG, GNAT_MEMORY_LIMIT, GNAT_STACK_LIMIT, etc...
(These are disagreeable because they make parent process to be able to control GNAT applications unexpectedly.)
These environment variables are no effect for drake.
Do not use prama Wide_Character_Encoding and/or -gnatW8.
Save your source code as UTF-8, and compile it while keeping the binary form by default -gnatWb.
Inevitably, the unicode identifier can not be used since the compiler don't think source code as UTF-8.
GNAT runtime does not follow the leap-seconds setting of the operating system, against AARM 9.6.1(89.b/2).
Instead, it follows the switch -y of gnatbind.
Drake follows the operating system.
The leap-second setting is included in the timezone setting in POSIX.
Or it is set by the command w32tm in Windows.
gnatbind -y is ignored.
The representation of Ada.Calendar.Time is shifted by whether the leap-seconds is enabled or not, on both runtimes.
So it should be careful for writing Time as binary to any file.
The representation of Ada.Calendar.Time is compatible on both runtimes when the leap-seconds are disabled.
A minor difference is existing, like below.
declare
Dest : String (1 .. 2);
begin
Ada.Strings.Fixed.Move (" ABCD ", Dest, Justify => Right, Drop => Right);
end;In GNAT, Dest will be " A" by Drop => Right, and Justify will be ignored.
In drake, Dest will be "AB", because the left spaces will be removed by Justify => Right at first, then, the right overflowed characters will be dropped by Drop => Right.
Both of them pass the tests of ACATS.
Image (Environment_Task) returns "main_task_XXXXXXXXXXXXXXXX" in GNAT.
It returns "*environment:XXXXXXXXXXXXXXXX" in drake.