9. Paragraph filling: formatting text¶
│ │ │ │The package GNATCOLL.Paragraph_Filling provides several algorithms for │ │ │ │ -filling paragraphs---formatting them to take up the minimal number of lines and │ │ │ │ +filling paragraphs—formatting them to take up the minimal number of lines and │ │ │ │ to look better. Knuth_Fill is based on an algorithm invented by Donald │ │ │ │ Knuth, and used in TeX. Pretty_Fill uses a different algorithm, which │ │ │ │ was judged by some to produce more aesthetically pleasing output.
│ │ │ │More detailed documentation may be found in the comments in the package spec.
│ │ │ │16. Geometry: primitive geometric operations¶
│ │ │ │GNATColl provides the package GNATCOLL.Geometry. This │ │ │ │ package includes a number of primitive operations on geometric figures │ │ │ │ like points, segments, lines, circles, rectangles and polygons. │ │ │ │ -In particular, you can compute their intersections, the distances,...
│ │ │ │ +In particular, you can compute their intersections, the distances,… │ │ │ │This package is generic, so that you can specify the type of coordinates │ │ │ │ you wish to handle:
│ │ │ │declare
│ │ │ │ package Float_Geometry is new GNATCOLL.Geometry (Float);
│ │ │ │ use Float_Geometry;
│ │ │ │
│ │ │ │ P1 : constant Point := (1.0, 1.0);
│ │ │ │ ├── html2text {}
│ │ │ │ │ @@ -12,15 +12,15 @@
│ │ │ │ │ * previous |
│ │ │ │ │ * GNATColl_0.0_documentation »
│ │ │ │ │ * 16. Geometry: primitive geometric operations
│ │ │ │ │ ****** 16. Geometry: primitive geometric operations¶ ******
│ │ │ │ │ GNATColl provides the packageGNATCOLL.Geometry. This package includes a number
│ │ │ │ │ of primitive operations on geometric figures like points, segments, lines,
│ │ │ │ │ circles, rectangles and polygons. In particular, you can compute their
│ │ │ │ │ -intersections, the distances,...
│ │ │ │ │ +intersections, the distances,â¦
│ │ │ │ │ This package is generic, so that you can specify the type of coordinates you
│ │ │ │ │ wish to handle:
│ │ │ │ │ declare
│ │ │ │ │ package Float_Geometry is new GNATCOLL.Geometry (Float);
│ │ │ │ │ use Float_Geometry;
│ │ │ │ │
│ │ │ │ │ P1 : constant Point := (1.0, 1.0);
│ │ │ ├── ./usr/share/doc/libgnatcoll-doc/html/json.html
│ │ │ │ @@ -41,15 +41,15 @@
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │ 21. JSON: handling JSON data¶
│ │ │ │ JSON is a format often used on the web
│ │ │ │ to communicate between a server and a browser, or between servers. It plays a
│ │ │ │ similar role to XML, but it has a much lighter syntax. On the other hand, it
│ │ │ │ -doesn't provide advanced features like validation, which XML provides.
│ │ │ │ +doesn’t provide advanced features like validation, which XML provides.
│ │ │ │ The GNATCOLL.JSON
package provides an Ada API to decode JSON data from
│ │ │ │ strings and to encode that data back to strings. It also allows one to create
│ │ │ │ and modify JSON data.
│ │ │ │
│ │ │ │ 21.1. API overview¶
│ │ │ │ The entry point for this API is the JSON_Value
data type. JSON values can
│ │ │ │ be any of:
│ │ │ │ @@ -108,17 +108,17 @@
│ │ │ │
│ │ │ │ -- Now serialize it. The call below will display:
│ │ │ │ -- {"field1": 1, "name": "thename"}
│ │ │ │ Put_Line (My_Obj.Write);
│ │ │ │ end JSON_Test;
│ │ │ │
│ │ │ │
│ │ │ │ -The above uses the Ada 2005 "dot notation" to call primitive operations
│ │ │ │ -(.Set_Field
, .Write
), but naturally the more traditional "prefix
│ │ │ │ -notation" is also available:
│ │ │ │ +The above uses the Ada 2005 “dot notation” to call primitive operations
│ │ │ │ +(.Set_Field
, .Write
), but naturally the more traditional “prefix
│ │ │ │ +notation” is also available:
│ │ │ │ Set_Field (My_Obj, "field1", Create (1));
│ │ │ │
│ │ │ │
│ │ │ │ It is also possible to create JSON arrays. These are not tagged types, so the
│ │ │ │ prefix notation has to be used. Here is a further example that sets another
│ │ │ │ field in the object we had before (My_Obj
):
│ │ │ │ declare
│ │ │ │ ├── html2text {}
│ │ │ │ │ @@ -11,15 +11,15 @@
│ │ │ │ │ * next |
│ │ │ │ │ * previous |
│ │ │ │ │ * GNATColl_0.0_documentation »
│ │ │ │ │ * 21. JSON: handling JSON data
│ │ │ │ │ ****** 21. JSON: handling JSON data¶ ******
│ │ │ │ │ JSON is a format often used on the web to communicate between a server and a
│ │ │ │ │ browser, or between servers. It plays a similar role to XML, but it has a much
│ │ │ │ │ -lighter syntax. On the other hand, it doesn't provide advanced features like
│ │ │ │ │ +lighter syntax. On the other hand, it doesnât provide advanced features like
│ │ │ │ │ validation, which XML provides.
│ │ │ │ │ The GNATCOLL.JSON package provides an Ada API to decode JSON data from strings
│ │ │ │ │ and to encode that data back to strings. It also allows one to create and
│ │ │ │ │ modify JSON data.
│ │ │ │ │ ***** 21.1. API overview¶ *****
│ │ │ │ │ The entry point for this API is the JSON_Value data type. JSON values can be
│ │ │ │ │ any of:
│ │ │ │ │ @@ -65,17 +65,17 @@
│ │ │ │ │ My_Obj.Set_Field ("field1", Create (1));
│ │ │ │ │ My_Obj.Set_Field ("name", "theName");
│ │ │ │ │
│ │ │ │ │ -- Now serialize it. The call below will display:
│ │ │ │ │ -- {"field1": 1, "name": "thename"}
│ │ │ │ │ Put_Line (My_Obj.Write);
│ │ │ │ │ end JSON_Test;
│ │ │ │ │ -The above uses the Ada 2005 "dot notation" to call primitive operations
│ │ │ │ │ -(.Set_Field, .Write), but naturally the more traditional "prefix notation" is
│ │ │ │ │ -also available:
│ │ │ │ │ +The above uses the Ada 2005 âdot notationâ to call primitive operations
│ │ │ │ │ +(.Set_Field, .Write), but naturally the more traditional âprefix notationâ
│ │ │ │ │ +is also available:
│ │ │ │ │ Set_Field (My_Obj, "field1", Create (1));
│ │ │ │ │ It is also possible to create JSON arrays. These are not tagged types, so the
│ │ │ │ │ prefix notation has to be used. Here is a further example that sets another
│ │ │ │ │ field in the object we had before (My_Obj):
│ │ │ │ │ declare
│ │ │ │ │ -- Create a JSON array
│ │ │ │ │ My_Arr : JSON_Array := Empty_Array;
│ │ │ ├── ./usr/share/doc/libgnatcoll-doc/html/mmap.html
│ │ │ │ @@ -65,29 +65,29 @@
│ │ │ │ by the system. To modify the file, you just modify the contents of the
│ │ │ │ memory, and do not worry about writing the file back to the disk.
│ │ │ │ When your application does not need to read the whole contents of the file,
│ │ │ │ the speed up can be several orders of magnitude faster than read().
│ │ │ │ Even when you need to read the whole contents, using mmap() is
│ │ │ │ still two or three times faster, which is especially interesting on big
│ │ │ │ files.
│ │ │ │ -GNATColl's GNATCOLL.Mmap package provides a high-level abstraction
│ │ │ │ +
GNATColl’s GNATCOLL.Mmap package provides a high-level abstraction
│ │ │ │ on top of the mmap system call. As for most other packages in
│ │ │ │ GNATColl, it also nicely handles the case where your system does not
│ │ │ │ actually support mmap, and will in that case fallback on using
│ │ │ │ read and write transparently. In such a case, your application
│ │ │ │ will perform a little slower, but you do not have to modify your code to
│ │ │ │ adapt it to the new system.
│ │ │ │ Due to the low-level C API that is needed underneath, the various subprograms
│ │ │ │ in this package do not directly manipulate Ada strings with valid bounds.
│ │ │ │ Instead, a new type Str_Access was defined. It does not contain the
│ │ │ │ bounds of the string, and therefore you cannot use the usual
│ │ │ │ -'First and 'Last attributes on that string. But there are other
│ │ │ │ +‘First and ‘Last attributes on that string. But there are other
│ │ │ │ subprograms that provide those values.
│ │ │ │ Here is how to read a whole file at once. This is what your code will use
│ │ │ │ -in most cases, unless you expect to read files bigger than Integer'Last
│ │ │ │ +in most cases, unless you expect to read files bigger than Integer’Last
│ │ │ │ bytes long. In such cases you need to read chunks of the file separately.
│ │ │ │ The mmap system call is such that its performance does not depend on
│ │ │ │ the size of the file your are mapping. Of course, this could be a problem if
│ │ │ │ GNATCOLL.Mmap falls back on calling read, since in that case it
│ │ │ │ needs to allocate as much memory as your file. Therefore in some cases you
│ │ │ │ will also want to only read chunks of the file at once:
│ │ │ │ declare
│ │ │ │ ├── html2text {}
│ │ │ │ │ @@ -34,33 +34,33 @@
│ │ │ │ │ actual contents is temporarily mapped in memory by the system. To modify the
│ │ │ │ │ file, you just modify the contents of the memory, and do not worry about
│ │ │ │ │ writing the file back to the disk.
│ │ │ │ │ When your application does not need to read the whole contents of the file, the
│ │ │ │ │ speed up can be several orders of magnitude faster thanread(). Even when you
│ │ │ │ │ need to read the whole contents, usingmmap()is still two or three times faster,
│ │ │ │ │ which is especially interesting on big files.
│ │ │ │ │ -GNATColl'sGNATCOLL.Mmappackage provides a high-level abstraction on top of
│ │ │ │ │ +GNATCollâsGNATCOLL.Mmappackage provides a high-level abstraction on top of
│ │ │ │ │ themmapsystem call. As for most other packages in GNATColl, it also nicely
│ │ │ │ │ handles the case where your system does not actually supportmmap, and will in
│ │ │ │ │ that case fallback on usingreadandwritetransparently. In such a case, your
│ │ │ │ │ application will perform a little slower, but you do not have to modify your
│ │ │ │ │ code to adapt it to the new system.
│ │ │ │ │ Due to the low-level C API that is needed underneath, the various subprograms
│ │ │ │ │ in this package do not directly manipulate Ada strings with valid bounds.
│ │ │ │ │ Instead, a new typeStr_Accesswas defined. It does not contain the bounds of the
│ │ │ │ │ -string, and therefore you cannot use the usual'Firstand'Lastattributes on that
│ │ │ │ │ -string. But there are other subprograms that provide those values.
│ │ │ │ │ +string, and therefore you cannot use the usualâFirstandâLastattributes on
│ │ │ │ │ +that string. But there are other subprograms that provide those values.
│ │ │ │ │ Here is how to read a whole file at once. This is what your code will use in
│ │ │ │ │ -most cases, unless you expect to read files bigger thanInteger'Lastbytes long.
│ │ │ │ │ -In such cases you need to read chunks of the file separately. Themmapsystem
│ │ │ │ │ -call is such that its performance does not depend on the size of the file your
│ │ │ │ │ -are mapping. Of course, this could be a problem ifGNATCOLL.Mmapfalls back on
│ │ │ │ │ -callingread, since in that case it needs to allocate as much memory as your
│ │ │ │ │ -file. Therefore in some cases you will also want to only read chunks of the
│ │ │ │ │ -file at once:
│ │ │ │ │ +most cases, unless you expect to read files bigger thanIntegerâLastbytes
│ │ │ │ │ +long. In such cases you need to read chunks of the file separately.
│ │ │ │ │ +Themmapsystem call is such that its performance does not depend on the size of
│ │ │ │ │ +the file your are mapping. Of course, this could be a problem
│ │ │ │ │ +ifGNATCOLL.Mmapfalls back on callingread, since in that case it needs to
│ │ │ │ │ +allocate as much memory as your file. Therefore in some cases you will also
│ │ │ │ │ +want to only read chunks of the file at once:
│ │ │ │ │ declare
│ │ │ │ │ File : Mapped_File;
│ │ │ │ │ Reg : Mapped_Region;
│ │ │ │ │ Str : Long.Str_Access;
│ │ │ │ │ begin
│ │ │ │ │ File := Open_Read ("/tmp/file_on_disk");
│ │ │ │ │ Reg := Read (File); *-- map the whole file*
│ │ │ ├── ./usr/share/doc/libgnatcoll-doc/html/refcount.html
│ │ │ │ @@ -117,15 +117,15 @@
│ │ │ │
│ │ │ │ type My_Type is new Weak_Refcounted with...;
│ │ │ │
│ │ │ │ package Pointers is new Weakref_Pointers (My_Type);
│ │ │ │
│ │ │ │
│ │ │ │ The above code can be used instead of the code in the first example, and
│ │ │ │ -provides the same capability (smart pointers, reference counted types,...).
│ │ │ │ +provides the same capability (smart pointers, reference counted types,…).
│ │ │ │ However, the type My_Type is slightly bigger, but can be used to
│ │ │ │ create weak references:
│ │ │ │ WR : Weak_Ref;
│ │ │ │
│ │ │ │ declare
│ │ │ │ R : Ref;
│ │ │ │ Tmp : My_Type := ...;
│ │ │ │ ├── html2text {}
│ │ │ │ │ @@ -78,15 +78,15 @@
│ │ │ │ │ with GNATCOLL.Refcount.Weakref;
│ │ │ │ │ use GNATCOLL.Refcount.Weakref;
│ │ │ │ │
│ │ │ │ │ type My_Type is new Weak_Refcounted with...;
│ │ │ │ │
│ │ │ │ │ package Pointers is new Weakref_Pointers (My_Type);
│ │ │ │ │ The above code can be used instead of the code in the first example, and
│ │ │ │ │ -provides the same capability (smart pointers, reference counted types,...).
│ │ │ │ │ +provides the same capability (smart pointers, reference counted types,â¦).
│ │ │ │ │ However, the typeMy_Typeis slightly bigger, but can be used to create weak
│ │ │ │ │ references:
│ │ │ │ │ WR : Weak_Ref;
│ │ │ │ │
│ │ │ │ │ declare
│ │ │ │ │ R : Ref;
│ │ │ │ │ Tmp : My_Type := ...;
│ │ │ ├── ./usr/share/doc/libgnatcoll-doc/html/scripting.html
│ │ │ │ @@ -42,20 +42,20 @@
│ │ │ │
│ │ │ │
│ │ │ │ 3. Scripts: Embedding script languages¶
│ │ │ │ In a lot of contexts, you want to give the possibility to users to extend
│ │ │ │ your application. This can be done in several ways: define an Ada API from
│ │ │ │ which they can build dynamically loadable modules, provide the whole source
│ │ │ │ code to your application and let users recompile it, interface with a simpler
│ │ │ │ -scripting languages,...
│ │ │ │ +scripting languages,…
│ │ │ │ Dynamically loadable modules can be loaded on demand, as their name indicate.
│ │ │ │ However, they generally require a relatively complex environment to build,
│ │ │ │ and are somewhat less portable. But when your users are familiar with Ada,
│ │ │ │ they provide a programming environment in which they are comfortable.
│ │ │ │ -As usual, changing the module requires recompilation, re-installation,...
│ │ │ │ +As usual, changing the module requires recompilation, re-installation,…
│ │ │ │ Providing the source code to your application is generally even more
│ │ │ │ complex for users. This requires an even more complex setup, your application
│ │ │ │ is generally too big for users to dive into, and modifications done by one
│ │ │ │ users are hard to provide to other users, or will be lost when you
│ │ │ │ distribute a new version of your application.
│ │ │ │ The third solution is to embed one or more scripting languages in your
│ │ │ │ application, and export some functions to it. This often requires your users
│ │ │ │ @@ -64,103 +64,103 @@
│ │ │ │ console. The resulting scripts can easily be redistributed to other users or
│ │ │ │ even distributed with future versions of your application.
│ │ │ │ The module in GNATColl helps you implement the third solution. It was
│ │ │ │ used extensively in the GPS programming environment for its python interface.
│ │ │ │
Each of the scripting language is optional
│ │ │ │ This module can be compiled with any of these languages as an optional
│ │ │ │ dependency (except for the shell language, which is always built-in, but is
│ │ │ │ -extremely minimal, and doesn't have to be loaded at run time anyway).
│ │ │ │ +extremely minimal, and doesn’t have to be loaded at run time anyway).
│ │ │ │ If the necessary libraries are found on the system, GNATColl will
│ │ │ │ be build with support for the corresponding language, but your application
│ │ │ │ can chose at run time whether or not to activate the support for a specific
│ │ │ │ language.
│ │ │ │
Use a scripting language to provide an automatic testing framework for
│ │ │ │ your application.
│ │ │ │ The GPS environment uses python command for its automatic test suite,
│ │ │ │ including graphical tests such as pressing on a button, selecting a
│ │ │ │ -menu,...
│ │ │ │ +menu,…
│ │ │ │
│ │ │ │ 3.1. Supported languages¶
│ │ │ │ The module provides built-in support for several scripting languages, and
│ │ │ │ -other languages can "easily" be added. Your application does not change
│ │ │ │ +other languages can “easily” be added. Your application does not change
│ │ │ │ when new languages are added, since the interface to export subprograms
│ │ │ │ and classes to the scripting languages is language-neutral, and will
│ │ │ │ automatically export to all known scripting languages.
│ │ │ │ The Core component provides support for the following language:
│ │ │ │
│ │ │ │ -- Shell
This is a very simple-minded scripting language, which doesn't provide
│ │ │ │ +
- Shell
This is a very simple-minded scripting language, which doesn’t provide
│ │ │ │ flow-control instructions (The Shell language).
│ │ │ │
│ │ │ │
│ │ │ │ Optional components add support for other languages, e.g. Python. Please
│ │ │ │ -refer to the corresponding component's documentation.
│ │ │ │ +refer to the corresponding component’s documentation.
│ │ │ │
│ │ │ │ 3.1.1. The Shell language¶
│ │ │ │ The shell language was initially developed in the context of the GPS
│ │ │ │ programming environment, as a way to embed scripting commands in XML
│ │ │ │ configuration files.
│ │ │ │ In this language, you can execute any of the commands exported by the
│ │ │ │ application, passing any number of arguments they need. Arguments to function
│ │ │ │ calls can, but need not, be quoted. Quoting is only mandatory when they
│ │ │ │ -contain spaces, newline characters, or double-quotes ('"'). To quote an
│ │ │ │ +contain spaces, newline characters, or double-quotes (‘”’). To quote an
│ │ │ │ argument, surround it by double-quotes, and precede each double-quote it
│ │ │ │ contains by a backslash character. Another way of quoting is similar to
│ │ │ │ what python provides, which is to triple-quote the argument, i.e. surround it
│ │ │ │ -by '"""' on each side. In such a case, any special character (in particular
│ │ │ │ +by ‘”””’ on each side. In such a case, any special character (in particular
│ │ │ │ other double-quotes or backslashes) lose their special meaning and are just
│ │ │ │ taken as part of the argument. This is in particular useful when you do not
│ │ │ │ know in advance the contents of the argument you are quoting:
│ │ │ │ Shell> function_name arg1 "arg 2" """arg 3"""
│ │ │ │
│ │ │ │
│ │ │ │ Commands are executed as if on a stack machine: the result of a command is
│ │ │ │ pushed on the stack, and later commands can reference it using %
│ │ │ │ following by a number. By default, the number of previous results that are
│ │ │ │ kept is set to 9, and this can only be changed by modifying the source code
│ │ │ │ for GNATColl. The return values are also modified by commands executed
│ │ │ │ internally by your application, and that might have no visible output from
│ │ │ │ -the user's point of view. As a result, you should never assume you know
│ │ │ │ -what %1,... contain unless you just executed a command in the
│ │ │ │ +the user’s point of view. As a result, you should never assume you know
│ │ │ │ +what %1,… contain unless you just executed a command in the
│ │ │ │ same script:
│ │ │ │ Shell> function_name arg1
│ │ │ │ Shell> function2_name %1
│ │ │ │
│ │ │ │
│ │ │ │ In particular, the %1 syntax is used when emulating object-oriented
│ │ │ │ programming in the shell. A method of a class is just a particular function
│ │ │ │ -that contains a '.' in its name, and whose first implicit argument is the
│ │ │ │ +that contains a ‘.’ in its name, and whose first implicit argument is the
│ │ │ │ instance on which it applies. This instance is generally the result of
│ │ │ │ calling a constructor in an earlier call. Assuming, for instance, that we
│ │ │ │ -have exported a class "Base" to the shell from our Ada core, we could use
│ │ │ │ +have exported a class “Base” to the shell from our Ada core, we could use
│ │ │ │ the following code:
│ │ │ │ Shell> Base arg1 arg2
│ │ │ │ Shell> Base.method %1 arg1 arg2
│ │ │ │
│ │ │ │
│ │ │ │ to create an instance and call one of its methods.
│ │ │ │ Of course, the shell is not the best language for object-oriented programming,
│ │ │ │ and better languages should be used instead.
│ │ │ │ When an instance has associated properties (which you can export from Ada
│ │ │ │ using Set_Property), you access the properties by prefixing its name
│ │ │ │ -with "@":
│ │ │ │ +with “@”:
│ │ │ │ Shell> Base arg1 arg2 # Build new instance
│ │ │ │ Shell> @id %1 # Access its "id" field
│ │ │ │ Shell> @id %1 5 # Set its "id" field
│ │ │ │
│ │ │ │
│ │ │ │ Some commands are automatically added to the shell when this scripting
│ │ │ │ language is added to the application. These are
│ │ │ │
│ │ │ │ - Function load (file)
Loads the content of file from the disk, and execute each of its lines as
│ │ │ │ a Shell command. This can for instance be used to load scripts when your
│ │ │ │ application is loaded
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │ -- Function echo (arg...)
This function takes any number of argument, and prints them in the console
│ │ │ │ +
- Function echo (arg…)
This function takes any number of argument, and prints them in the console
│ │ │ │ associated with the language. By default, when in an interactive console, the
│ │ │ │ output of commands is automatically printed to the console. But when you
│ │ │ │ execute a script through load above, you need to explicitly call
│ │ │ │ echo to make some output visible.
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │ @@ -181,15 +181,15 @@
│ │ │ │ above Ada procedure. It will be assumed to be Console in the rest
│ │ │ │ of this document.
│ │ │ │ This class provides an interface to consoles. A console is an input/output
│ │ │ │ area in your application (whether it is a text area in a graphical
│ │ │ │ application, or simply standard text I/O in text mode). In particular,
│ │ │ │ the python standard output streams sys.stdin, sys.stdout
│ │ │ │ and sys.stderr are redirected to an instance of that class. If you
│ │ │ │ -want to see python's error messages or usual output in your application,
│ │ │ │ +want to see python’s error messages or usual output in your application,
│ │ │ │ you must register that class, and define a default console for your
│ │ │ │ scripting language through calls to
│ │ │ │ GNATCOLL.Scripts.Set_Default_Console.
│ │ │ │ You can later add new methods to this class, which would be specific to your
│ │ │ │ application. Or you can derive this class into a new class to achieve a
│ │ │ │ similar goal.
│ │ │ │
│ │ │ │ @@ -242,23 +242,23 @@
│ │ │ │ Shell, to python, or to another language integrated in GNATColl.
│ │ │ │ The code remains exactly the same, and new scripting languages can be added
│ │ │ │ in later releases of GNATColl without requiring a change in your
│ │ │ │ application. This flexibility is central to the design of GNATColl.
│ │ │ │ In exchange for that flexibility, however, there are language-specific
│ │ │ │ features that cannot be performed through the GNATColl API. At
│ │ │ │ present, this includes for instance exporting functions that return hash
│ │ │ │ -tables. But GNATColl doesn't try to export the greatest set of
│ │ │ │ +tables. But GNATColl doesn’t try to export the greatest set of
│ │ │ │ features common to all languages. On the contrary, it tries to fully
│ │ │ │ support all the languages, and provide reasonable fallback for languages
│ │ │ │ that do not support that feature. For instance, named parameters (which
│ │ │ │ are a part of the python language) are fully supported, although the
│ │ │ │ -shell language doesn't support them. But that's an implementation detail
│ │ │ │ +shell language doesn’t support them. But that’s an implementation detail
│ │ │ │ transparent to your own application.
│ │ │ │ Likewise, your application might decide to always load the python
│ │ │ │ -scripting language. If GNATColl wasn't compiled with python support,
│ │ │ │ +scripting language. If GNATColl wasn’t compiled with python support,
│ │ │ │ the corresponding Ada function still exists (and thus your code still
│ │ │ │ compiles), although of course it does nothing. But since the rest of the
│ │ │ │ code is independent of python, this is totally transparent for your
│ │ │ │ application.
│ │ │ │
GNATColl comes with some examples, which you can use
│ │ │ │ as a reference when building your own application.
│ │ │ │ See the <prefix>/share/examples/gnatcoll
directory.
│ │ │ │ @@ -269,15 +269,15 @@
│ │ │ │ to load
│ │ │ │
You can create an interactive console for the various
│ │ │ │ languages, so that users can perform experiments interactively. This
│ │ │ │ is optional, and you could decide to keep the scripting language has a
│ │ │ │ hidden implementation detail (or just for automatic testing purposes
│ │ │ │ for instance)
│ │ │ │ You can export some classes and methods.
│ │ │ │ -This is optional, but it doesn't really make sense to just embed a
│ │ │ │ +This is optional, but it doesn’t really make sense to just embed a
│ │ │ │ scripting language and export nothing to it. In such a case, you might
│ │ │ │ as well spawn a separate executable.
│ │ │ │ You can load start up scripts or plug-ins that users have
│ │ │ │ written to extend your application.
│ │ │ │
│ │ │ │
│ │ │ │ 3.2.1. Initializing the scripting module¶
│ │ │ │ @@ -489,42 +489,42 @@
│ │ │ │ to make it possible to register each exported function only once (it then
│ │ │ │ takes care of exporting it to each scripting language).
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │ - Class Scripting_Language
Instances of this type represent a specific language. It provides various
│ │ │ │ operations to export subprograms, execute commands, create the other types
│ │ │ │ -described below,... There should exists a single instance of this class per
│ │ │ │ +described below,… There should exists a single instance of this class per
│ │ │ │ supported language.
│ │ │ │ This class interacts with the script interpreter (for instance python), and
│ │ │ │ all code executed in python goes through this type, which then executes your
│ │ │ │ Ada callbacks to perform the actual operation.
│ │ │ │ It is also associated with a default console, as described above, so that
│ │ │ │ all input and output of the scripts can be made visible to the user.
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │ - Class Callback_Data
This type is an opaque tagged type that provides a language-independent
│ │ │ │ interface to the scripting language. It gives for instance access to the
│ │ │ │ various parameters passed to your subprogram (Nth_Arg functions),
│ │ │ │ allows you to set the return value (Set_Return_Value procedure),
│ │ │ │ -or raise exceptions (Set_Error_Msg procedure),...
│ │ │ │ +or raise exceptions (Set_Error_Msg procedure),…
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │ - Record Class_Type
This type is not tagged, and cannot be extended. It basically represents a
│ │ │ │ class in any of the scripting languages, and is used to create new instances
│ │ │ │ of that class from Ada.
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │ - Class Class_Instance
A class instance represents a specific instance of a class. In general,
│ │ │ │ such an instance is strongly bound to an instance of an Ada type. For
│ │ │ │ instance, if you have a Foo type in your application that you wish
│ │ │ │ -to export, you would create a Class_Type called "Foo", and then the
│ │ │ │ +to export, you would create a Class_Type called “Foo”, and then the
│ │ │ │ user can create as many instances as he wants of that class, each of which
│ │ │ │ is associated with different values of Foo in Ada.
│ │ │ │ Another more specific example is the predefined Console class. As
│ │ │ │ we have seen before, this is a Virtual_Console in Ada. You could
│ │ │ │ for instance have two graphical windows in your application, each of which
│ │ │ │ is a Virtual_Console. In the scripting language, this is exported
│ │ │ │ as a class named Console. The user can create two
│ │ │ │ @@ -645,19 +645,19 @@
│ │ │ │ the scripting language to display a proper error message to the user. You
│ │ │ │ have nothing special to do here.
│ │ │ │
│ │ │ │
│ │ │ │ 3.2.3.2.2. Support for named parameters¶
│ │ │ │ Some languages (especially python) support named parameters, ie parameters
│ │ │ │ can be specified in any order on the command line, as long as they are
│ │ │ │ -properly identified (very similar to Ada's own capabilities). In the example
│ │ │ │ +properly identified (very similar to Ada’s own capabilities). In the example
│ │ │ │ above, the call to Name_Parameters is really optional, but adds this
│ │ │ │ support for your own functions as well. You just have to specify the name
│ │ │ │ of the parameters, and GNATColl will then ensure that when you
│ │ │ │ -call Nth_Arg the parameter number 1 is really "arg1".
│ │ │ │ +call Nth_Arg the parameter number 1 is really “arg1”.
│ │ │ │ For scripting languages that do not support named parameters, this has no
│ │ │ │ effect.
│ │ │ │ Your code can then perform as complex a code as needed, and finally
│ │ │ │ return a value (or not) to the scripting language, through a call to
│ │ │ │ Set_Return_Value.
│ │ │ │ After the above code has been executed, your users can go to the python
│ │ │ │ console and type for instance:
│ │ │ │ @@ -693,25 +693,25 @@
│ │ │ │ this class.
│ │ │ │ You can then register the class methods in the same way that you registered
│ │ │ │ functions. An additional parameter Class exists for
│ │ │ │ Register_Command. A method is really just a standard function that
│ │ │ │ has an implicit first parameter which is a Class_Instance. This
│ │ │ │ extra parameter should not be taken into account in Min_Args and
│ │ │ │ Max_Args. You can also declare the method as a static method, ie
│ │ │ │ -one that doesn't take this extra implicit parameter, and basically just
│ │ │ │ +one that doesn’t take this extra implicit parameter, and basically just
│ │ │ │ uses the class as a namespace.
│ │ │ │ Some special method names are available. In particular,
│ │ │ │ Constructor_Method should be used for the constructor of a class.
│ │ │ │ It is a method that receives, as its first argument, a class instance that
│ │ │ │ has just been created. It should associate that instance with the Ada
│ │ │ │ object it represents.
│ │ │ │ Here is a simple example that exports a class. Each instance of this class
│ │ │ │ is associated with a string, passed in parameter to the constructor. The
│ │ │ │ class has a single method print, which prints its string parameter
│ │ │ │ -prefixed by the instance's string. To start with, here is a python example
│ │ │ │ +prefixed by the instance’s string. To start with, here is a python example
│ │ │ │ on what we want to achieve:
│ │ │ │ c1 = MyClass ("prefix1")
│ │ │ │ c1.print ("foo")
│ │ │ │ => "prefix1 foo"
│ │ │ │ c2 = MyClass () # Using a default prefix
│ │ │ │ c2.print ("foo")
│ │ │ │ => "default foo"
│ │ │ │ @@ -737,37 +737,37 @@
│ │ │ │ (Repo, Constructor_Method, 0, 1, Handler'Access, MyClass);
│ │ │ │ Register_Command
│ │ │ │ (Repo, "print", 1, 1, Handler'Access, MyClass);
│ │ │ │
│ │ │ │
│ │ │ │ This example also demonstrates a few concepts: the constructor is declared
│ │ │ │ as a method that takes one optional argument. The default value is in
│ │ │ │ -fact passed in the call to Nth_Arg and is set to "default".
│ │ │ │ +fact passed in the call to Nth_Arg and is set to “default”.
│ │ │ │ In the handler, we know there is always a first argument which is the
│ │ │ │ instance on which the method applies. The implementation for the
│ │ │ │ constructor stores the prefix in the instance itself, so that several
│ │ │ │ -instances can have different prefixes (we can't use global variables,
│ │ │ │ -of course, since we don't know in advance how many instances will exist).
│ │ │ │ +instances can have different prefixes (we can’t use global variables,
│ │ │ │ +of course, since we don’t know in advance how many instances will exist).
│ │ │ │ The implementation for print inserts code in the default console
│ │ │ │ for the script (we could of course use Put_Line or any other way
│ │ │ │ to output data), and computes the string to output by concatenating the
│ │ │ │ -instance's prefix and the parameter to print.
│ │ │ │ +instance’s prefix and the parameter to print.
│ │ │ │ Note that Set_Data and Get_Data take the class in parameter,
│ │ │ │ in addition to the class instance. This is needed for proper handling of
│ │ │ │ multiple inheritance: say we have a class C that extends two classes
│ │ │ │ A and B. The Ada code that deals with A associates an
│ │ │ │ integer with the class instance, whereas the code that deals with B
│ │ │ │ associates a string. Now, if you have an instance of C but call a
│ │ │ │ -method inherited from A, and if Get_Data didn't specify the
│ │ │ │ +method inherited from A, and if Get_Data didn’t specify the
│ │ │ │ class, there would be a risk that a string would be returned instead of the
│ │ │ │ expected integer. In fact, the proper solution here is that both A
│ │ │ │ and B store their preferred data at the same time in the instances,
│ │ │ │ but only fetch the one they actually need. Therefore instances of C
│ │ │ │ are associated with two datas.
│ │ │ │ -Here is a more advanced example that shows how to export an Ada object. Let's
│ │ │ │ +
Here is a more advanced example that shows how to export an Ada object. Let’s
│ │ │ │ assume we have the following Ada type that we want to make available to
│ │ │ │ scripts:
│ │ │ │ type MyType is record
│ │ │ │ Field : Integer;
│ │ │ │ end record;
│ │ │ │
│ │ │ │
│ │ │ │ @@ -794,18 +794,18 @@
│ │ │ │ (Get_Data (Inst, Get_Name (MyClass))));
│ │ │ │ begin
│ │ │ │ return Data.Val;
│ │ │ │ end Get_Data;
│ │ │ │
│ │ │ │
│ │ │ │ Several aspects worth noting in this example. Each data is associated with
│ │ │ │ -a name, not a class as in the previous example. That's in fact the same
│ │ │ │ +a name, not a class as in the previous example. That’s in fact the same
│ │ │ │ thing, and mostly for historical reasons. We have to create our own
│ │ │ │ instance of Instance_Property_Record to store the data, but the
│ │ │ │ -implementation presents no special difficulty. In fact, we don't absolutely
│ │ │ │ +implementation presents no special difficulty. In fact, we don’t absolutely
│ │ │ │ need to create Set_Data and Get_Data and could do everything
│ │ │ │ inline in the method implementation, but it is cleaner this way and easier
│ │ │ │ to reuse.
│ │ │ │ GNATColl is fully responsible for managing the lifetime of the
│ │ │ │ data associated with the class instances and you can override the procedure
│ │ │ │ Destroy if you need special memory management.
│ │ │ │
│ │ │ │ @@ -830,15 +830,15 @@
│ │ │ │ was done the same for other languages for compatibility reasons).
│ │ │ │ There are two ways to work around that limitation:
│ │ │ │
│ │ │ │ Static get methods
│ │ │ │ With each of your classes, you can export a static method generally called
│ │ │ │ get that takes in parameter a way to identify an existing instance,
│ │ │ │ and either return it or create a new one. It is also recommended to disable
│ │ │ │ -the constructor, ie force it to raise an error. Let's examine the python
│ │ │ │ +the constructor, ie force it to raise an error. Let’s examine the python
│ │ │ │ code as it would be used:
│ │ │ │ ed = Editor ("file.adb") # constructor
│ │ │ │ => Error, cannot construct instances
│ │ │ │ ed = Editor.get ("file.adb")
│ │ │ │ => Create a new instance
│ │ │ │ ed2 = Editor.get ("file.adb")
│ │ │ │ => Return existing instance
│ │ │ │ @@ -891,15 +891,15 @@
│ │ │ │
│ │ │ │
│ │ │ │ It is important to realize that in the call above, we are not calling
│ │ │ │ the constructor of a class, but a function. At the Ada level, the function
│ │ │ │ has basically the same implementation as the one we gave for get
│ │ │ │ above. But the python code looks nicer because we do not have these
│ │ │ │ additional .get() calls. The name of the class MyClassImpl
│ │ │ │ -doesn't appear anywhere in the python code, so this is mostly transparent.
│ │ │ │ +doesn’t appear anywhere in the python code, so this is mostly transparent.
│ │ │ │ However, if you have more than one scripting language, in particular for
│ │ │ │ the shell, the code looks less nice in this case:
│ │ │ │ MyClass "file.adb"
│ │ │ │ => <MyClassImpl_Instance_0x12345>
│ │ │ │ MyClassImpl.do_something %1
│ │ │ │
│ │ │ │
│ │ │ │ @@ -952,15 +952,15 @@
│ │ │ │ GNATColl provides a convenient hook to debug your script. By default,
│ │ │ │ a script (python for instance) will call your Ada callback, which might
│ │ │ │ raise errors. Most of the time, the error should indeed be reported to the
│ │ │ │ user, and you can thus raise a standard exception, or call
│ │ │ │ Set_Error_Msg.
│ │ │ │ But if you wish to know which script was executing the command, it is
│ │ │ │ generally not doable. You can however activate a trace
│ │ │ │ -(Traces: Logging information) called "PYTHON.TB" (for "traceback"), which will
│ │ │ │ +(Traces: Logging information) called “PYTHON.TB” (for “traceback”), which will
│ │ │ │ output the name of the command that is being executed, as well as the
│ │ │ │ full traceback within the python scripts. This will help you locate which
│ │ │ │ script is raising an exception.
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │ ├── html2text {}
│ │ │ │ │ @@ -13,20 +13,20 @@
│ │ │ │ │ * GNATColl_0.0_documentation »
│ │ │ │ │ * 3. Scripts: Embedding script languages
│ │ │ │ │ ****** 3. Scripts: Embedding script languages¶ ******
│ │ │ │ │ In a lot of contexts, you want to give the possibility to users to extend your
│ │ │ │ │ application. This can be done in several ways: define an Ada API from which
│ │ │ │ │ they can build dynamically loadable modules, provide the whole source code to
│ │ │ │ │ your application and let users recompile it, interface with a simpler scripting
│ │ │ │ │ -languages,...
│ │ │ │ │ +languages,â¦
│ │ │ │ │ Dynamically loadable modules can be loaded on demand, as their name indicate.
│ │ │ │ │ However, they generally require a relatively complex environment to build, and
│ │ │ │ │ are somewhat less portable. But when your users are familiar with Ada, they
│ │ │ │ │ provide a programming environment in which they are comfortable. As usual,
│ │ │ │ │ -changing the module requires recompilation, re-installation,...
│ │ │ │ │ +changing the module requires recompilation, re-installation,â¦
│ │ │ │ │ Providing the source code to your application is generally even more complex
│ │ │ │ │ for users. This requires an even more complex setup, your application is
│ │ │ │ │ generally too big for users to dive into, and modifications done by one users
│ │ │ │ │ are hard to provide to other users, or will be lost when you distribute a new
│ │ │ │ │ version of your application.
│ │ │ │ │ The third solution is to embed one or more scripting languages in your
│ │ │ │ │ application, and export some functions to it. This often requires your users to
│ │ │ │ │ @@ -35,83 +35,84 @@
│ │ │ │ │ The resulting scripts can easily be redistributed to other users or even
│ │ │ │ │ distributed with future versions of your application.
│ │ │ │ │ The module in GNATColl helps you implement the third solution. It was used
│ │ │ │ │ extensively in the GPS programming environment for its python interface.
│ │ │ │ │ [TIP:] Each of the scripting language is optional
│ │ │ │ │ This module can be compiled with any of these languages as an optional
│ │ │ │ │ dependency (except for the shell language, which is always built-in, but is
│ │ │ │ │ -extremely minimal, and doesn't have to be loaded at run time anyway). If the
│ │ │ │ │ +extremely minimal, and doesnât have to be loaded at run time anyway). If the
│ │ │ │ │ necessary libraries are found on the system, GNATColl will be build with
│ │ │ │ │ support for the corresponding language, but your application can chose at run
│ │ │ │ │ time whether or not to activate the support for a specific language.
│ │ │ │ │ [TIP:] Use a scripting language to provide an automatic testing framework for
│ │ │ │ │ your application.
│ │ │ │ │ The GPS environment uses python command for its automatic test suite, including
│ │ │ │ │ -graphical tests such as pressing on a button, selecting a menu,...
│ │ │ │ │ +graphical tests such as pressing on a button, selecting a menu,â¦
│ │ │ │ │ ***** 3.1. Supported languages¶ *****
│ │ │ │ │ The module provides built-in support for several scripting languages, and other
│ │ │ │ │ -languages can "easily" be added. Your application does not change when new
│ │ │ │ │ +languages can âeasilyâ be added. Your application does not change when new
│ │ │ │ │ languages are added, since the interface to export subprograms and classes to
│ │ │ │ │ the scripting languages is language-neutral, and will automatically export to
│ │ │ │ │ all known scripting languages.
│ │ │ │ │ The Core component provides support for the following language:
│ │ │ │ │ Shell
│ │ │ │ │ - This is a very simple-minded scripting language, which doesn't provide
│ │ │ │ │ + This is a very simple-minded scripting language, which doesnât provide
│ │ │ │ │ flow-control instructions (The_Shell_language).
│ │ │ │ │ Optional components add support for other languages, e.g. Python. Please refer
│ │ │ │ │ -to the corresponding component's documentation.
│ │ │ │ │ +to the corresponding componentâs documentation.
│ │ │ │ │ **** 3.1.1. The Shell language¶ ****
│ │ │ │ │ The shell language was initially developed in the context of the GPS
│ │ │ │ │ programming environment, as a way to embed scripting commands in XML
│ │ │ │ │ configuration files.
│ │ │ │ │ In this language, you can execute any of the commands exported by the
│ │ │ │ │ application, passing any number of arguments they need. Arguments to function
│ │ │ │ │ calls can, but need not, be quoted. Quoting is only mandatory when they contain
│ │ │ │ │ -spaces, newline characters, or double-quotes ('"'). To quote an argument,
│ │ │ │ │ +spaces, newline characters, or double-quotes (âââ). To quote an argument,
│ │ │ │ │ surround it by double-quotes, and precede each double-quote it contains by a
│ │ │ │ │ backslash character. Another way of quoting is similar to what python provides,
│ │ │ │ │ -which is to triple-quote the argument, i.e. surround it by '"""' on each side.
│ │ │ │ │ -In such a case, any special character (in particular other double-quotes or
│ │ │ │ │ -backslashes) lose their special meaning and are just taken as part of the
│ │ │ │ │ -argument. This is in particular useful when you do not know in advance the
│ │ │ │ │ +which is to triple-quote the argument, i.e. surround it by âââââ on
│ │ │ │ │ +each side. In such a case, any special character (in particular other double-
│ │ │ │ │ +quotes or backslashes) lose their special meaning and are just taken as part of
│ │ │ │ │ +the argument. This is in particular useful when you do not know in advance the
│ │ │ │ │ contents of the argument you are quoting:
│ │ │ │ │ Shell> function_name arg1 "arg 2" """arg 3"""
│ │ │ │ │ Commands are executed as if on a stack machine: the result of a command is
│ │ │ │ │ pushed on the stack, and later commands can reference it using%following by a
│ │ │ │ │ number. By default, the number of previous results that are kept is set to 9,
│ │ │ │ │ and this can only be changed by modifying the source code for GNATColl. The
│ │ │ │ │ return values are also modified by commands executed internally by your
│ │ │ │ │ -application, and that might have no visible output from the user's point of
│ │ │ │ │ -view. As a result, you should never assume you know what%1,... contain unless
│ │ │ │ │ +application, and that might have no visible output from the userâs point of
│ │ │ │ │ +view. As a result, you should never assume you know what%1,⦠contain unless
│ │ │ │ │ you just executed a command in the same script:
│ │ │ │ │ Shell> function_name arg1
│ │ │ │ │ Shell> function2_name %1
│ │ │ │ │ In particular, the%1syntax is used when emulating object-oriented programming
│ │ │ │ │ in the shell. A method of a class is just a particular function that contains a
│ │ │ │ │ -'.' in its name, and whose first implicit argument is the instance on which it
│ │ │ │ │ -applies. This instance is generally the result of calling a constructor in an
│ │ │ │ │ -earlier call. Assuming, for instance, that we have exported a class "Base" to
│ │ │ │ │ -the shell from our Ada core, we could use the following code:
│ │ │ │ │ +â.â in its name, and whose first implicit argument is the instance on which
│ │ │ │ │ +it applies. This instance is generally the result of calling a constructor in
│ │ │ │ │ +an earlier call. Assuming, for instance, that we have exported a class
│ │ │ │ │ +âBaseâ to the shell from our Ada core, we could use the following code:
│ │ │ │ │ Shell> Base arg1 arg2
│ │ │ │ │ Shell> Base.method %1 arg1 arg2
│ │ │ │ │ to create an instance and call one of its methods. Of course, the shell is not
│ │ │ │ │ the best language for object-oriented programming, and better languages should
│ │ │ │ │ be used instead.
│ │ │ │ │ When an instance has associated properties (which you can export from Ada
│ │ │ │ │ -usingSet_Property), you access the properties by prefixing its name with "@":
│ │ │ │ │ +usingSet_Property), you access the properties by prefixing its name with
│ │ │ │ │ +â@â:
│ │ │ │ │ Shell> Base arg1 arg2 # Build new instance
│ │ │ │ │ Shell> @id %1 # Access its "id" field
│ │ │ │ │ Shell> @id %1 5 # Set its "id" field
│ │ │ │ │ Some commands are automatically added to the shell when this scripting language
│ │ │ │ │ is added to the application. These are
│ │ │ │ │ Function load (file)
│ │ │ │ │ Loads the content offilefrom the disk, and execute each of its lines as a
│ │ │ │ │ Shell command. This can for instance be used to load scripts when your
│ │ │ │ │ application is loaded
│ │ │ │ │ - Function echo (arg...)
│ │ │ │ │ + Function echo (argâ¦)
│ │ │ │ │ This function takes any number of argument, and prints them in the
│ │ │ │ │ console associated with the language. By default, when in an interactive
│ │ │ │ │ console, the output of commands is automatically printed to the console.
│ │ │ │ │ But when you execute a script throughloadabove, you need to explicitly
│ │ │ │ │ callechoto make some output visible.
│ │ │ │ │ Function clear_cache
│ │ │ │ │ This frees the memory used to store the output of previous commands.
│ │ │ │ │ @@ -126,15 +127,15 @@
│ │ │ │ │ Class Console
│ │ │ │ │ Consoleis a name that you can chose yourself when you call the above Ada
│ │ │ │ │ procedure. It will be assumed to beConsolein the rest of this document.
│ │ │ │ │ This class provides an interface to consoles. A console is an input/
│ │ │ │ │ output area in your application (whether it is a text area in a graphical
│ │ │ │ │ application, or simply standard text I/O in text mode). In particular,
│ │ │ │ │ the python standard output streamssys.stdin,sys.stdoutandsys.stderrare
│ │ │ │ │ - redirected to an instance of that class. If you want to see python's
│ │ │ │ │ + redirected to an instance of that class. If you want to see pythonâs
│ │ │ │ │ error messages or usual output in your application, you must register
│ │ │ │ │ that class, and define a default console for your scripting language
│ │ │ │ │ through calls toGNATCOLL.Scripts.Set_Default_Console.
│ │ │ │ │ You can later add new methods to this class, which would be specific to
│ │ │ │ │ your application. Or you can derive this class into a new class to
│ │ │ │ │ achieve a similar goal.
│ │ │ │ │ Console.write(text)
│ │ │ │ │ @@ -168,38 +169,39 @@
│ │ │ │ │ transparent for your application whether you are talking to the Shell, to
│ │ │ │ │ python, or to another language integrated in GNATColl. The code remains exactly
│ │ │ │ │ the same, and new scripting languages can be added in later releases of
│ │ │ │ │ GNATColl without requiring a change in your application. This flexibility is
│ │ │ │ │ central to the design of GNATColl.
│ │ │ │ │ In exchange for that flexibility, however, there are language-specific features
│ │ │ │ │ that cannot be performed through the GNATColl API. At present, this includes
│ │ │ │ │ -for instance exporting functions that return hash tables. But GNATColl doesn't
│ │ │ │ │ -try to export the greatest set of features common to all languages. On the
│ │ │ │ │ -contrary, it tries to fully support all the languages, and provide reasonable
│ │ │ │ │ -fallback for languages that do not support that feature. For instance, named
│ │ │ │ │ -parameters (which are a part of the python language) are fully supported,
│ │ │ │ │ -although the shell language doesn't support them. But that's an implementation
│ │ │ │ │ -detail transparent to your own application.
│ │ │ │ │ +for instance exporting functions that return hash tables. But GNATColl
│ │ │ │ │ +doesnât try to export the greatest set of features common to all languages.
│ │ │ │ │ +On the contrary, it tries to fully support all the languages, and provide
│ │ │ │ │ +reasonable fallback for languages that do not support that feature. For
│ │ │ │ │ +instance, named parameters (which are a part of the python language) are fully
│ │ │ │ │ +supported, although the shell language doesnât support them. But thatâs an
│ │ │ │ │ +implementation detail transparent to your own application.
│ │ │ │ │ Likewise, your application might decide to always load the python scripting
│ │ │ │ │ -language. If GNATColl wasn't compiled with python support, the corresponding
│ │ │ │ │ +language. If GNATColl wasnât compiled with python support, the corresponding
│ │ │ │ │ Ada function still exists (and thus your code still compiles), although of
│ │ │ │ │ course it does nothing. But since the rest of the code is independent of
│ │ │ │ │ python, this is totally transparent for your application.
│ │ │ │ │ [TIP:] GNATColl comes with some examples, which you can use as a reference when
│ │ │ │ │ building your own application. See the /share/examples/gnatcoll
│ │ │ │ │ directory.
│ │ │ │ │ Interfacing your application with the scripting module is a multistep process:
│ │ │ │ │ * You must initialize GNATColl and decide which features to load
│ │ │ │ │ * You can create an interactive console for the various languages, so that
│ │ │ │ │ users can perform experiments interactively. This is optional, and you
│ │ │ │ │ could decide to keep the scripting language has a hidden implementation
│ │ │ │ │ detail (or just for automatic testing purposes for instance)
│ │ │ │ │ - * You can export some classes and methods. This is optional, but it doesn't
│ │ │ │ │ - really make sense to just embed a scripting language and export nothing
│ │ │ │ │ - to it. In such a case, you might as well spawn a separate executable.
│ │ │ │ │ + * You can export some classes and methods. This is optional, but it
│ │ │ │ │ + doesnât really make sense to just embed a scripting language and export
│ │ │ │ │ + nothing to it. In such a case, you might as well spawn a separate
│ │ │ │ │ + executable.
│ │ │ │ │ * You can load start up scripts or plug-ins that users have written to
│ │ │ │ │ extend your application.
│ │ │ │ │ **** 3.2.1. Initializing the scripting module¶ ****
│ │ │ │ │ GNATColl must be initialized properly in order to provide added value to your
│ │ │ │ │ application. This cannot be done automatically simply by depending on the
│ │ │ │ │ library, since this initialization requires multiple-step that must be done at
│ │ │ │ │ specific moments in the initialization of your whole application.
│ │ │ │ │ @@ -358,37 +360,37 @@
│ │ │ │ │ instance in your whole application, and whose main role is to give access
│ │ │ │ │ to each of the scripting languages (Lookup_Scripting_Languagefunction),
│ │ │ │ │ and to make it possible to register each exported function only once (it
│ │ │ │ │ then takes care of exporting it to each scripting language).
│ │ │ │ │ Class Scripting_Language
│ │ │ │ │ Instances of this type represent a specific language. It provides various
│ │ │ │ │ operations to export subprograms, execute commands, create the other
│ │ │ │ │ - types described below,... There should exists a single instance of this
│ │ │ │ │ + types described below,⦠There should exists a single instance of this
│ │ │ │ │ class per supported language.
│ │ │ │ │ This class interacts with the script interpreter (for instance python),
│ │ │ │ │ and all code executed in python goes through this type, which then
│ │ │ │ │ executes your Ada callbacks to perform the actual operation.
│ │ │ │ │ It is also associated with a default console, as described above, so that
│ │ │ │ │ all input and output of the scripts can be made visible to the user.
│ │ │ │ │ Class Callback_Data
│ │ │ │ │ This type is an opaque tagged type that provides a language-independent
│ │ │ │ │ interface to the scripting language. It gives for instance access to the
│ │ │ │ │ various parameters passed to your subprogram (Nth_Argfunctions), allows
│ │ │ │ │ you to set the return value (Set_Return_Valueprocedure), or raise
│ │ │ │ │ - exceptions (Set_Error_Msgprocedure),...
│ │ │ │ │ + exceptions (Set_Error_Msgprocedure),â¦
│ │ │ │ │ Record Class_Type
│ │ │ │ │ This type is not tagged, and cannot be extended. It basically represents
│ │ │ │ │ a class in any of the scripting languages, and is used to create new
│ │ │ │ │ instances of that class from Ada.
│ │ │ │ │ Class Class_Instance
│ │ │ │ │ A class instance represents a specific instance of a class. In general,
│ │ │ │ │ such an instance is strongly bound to an instance of an Ada type. For
│ │ │ │ │ instance, if you have aFootype in your application that you wish to
│ │ │ │ │ - export, you would create aClass_Typecalled "Foo", and then the user can
│ │ │ │ │ - create as many instances as he wants of that class, each of which is
│ │ │ │ │ + export, you would create aClass_Typecalled âFooâ, and then the user
│ │ │ │ │ + can create as many instances as he wants of that class, each of which is
│ │ │ │ │ associated with different values ofFooin Ada.
│ │ │ │ │ Another more specific example is the predefinedConsoleclass. As we have
│ │ │ │ │ seen before, this is aVirtual_Consolein Ada. You could for instance have
│ │ │ │ │ two graphical windows in your application, each of which is
│ │ │ │ │ aVirtual_Console. In the scripting language, this is exported as a class
│ │ │ │ │ namedConsole. The user can create two instances of those, each of which
│ │ │ │ │ is associated with one of your graphical windows. This way,
│ │ │ │ │ @@ -485,20 +487,20 @@
│ │ │ │ │ through one of the numerousNth_Argfunctions. In the example above, we assume
│ │ │ │ │ they are integer. But if one of them was passed as a string, an exception would
│ │ │ │ │ be raised and sent back to the scripting language to display a proper error
│ │ │ │ │ message to the user. You have nothing special to do here.
│ │ │ │ │ ** 3.2.3.2.2. Support for named parameters¶ **
│ │ │ │ │ Some languages (especially python) support named parameters, ie parameters can
│ │ │ │ │ be specified in any order on the command line, as long as they are properly
│ │ │ │ │ -identified (very similar to Ada's own capabilities). In the example above, the
│ │ │ │ │ -call toName_Parametersis really optional, but adds this support for your own
│ │ │ │ │ -functions as well. You just have to specify the name of the parameters, and
│ │ │ │ │ +identified (very similar to Adaâs own capabilities). In the example above,
│ │ │ │ │ +the call toName_Parametersis really optional, but adds this support for your
│ │ │ │ │ +own functions as well. You just have to specify the name of the parameters, and
│ │ │ │ │ GNATColl will then ensure that when you callNth_Argthe parameter number 1 is
│ │ │ │ │ -really "arg1". For scripting languages that do not support named parameters,
│ │ │ │ │ -this has no effect.
│ │ │ │ │ +really âarg1â. For scripting languages that do not support named
│ │ │ │ │ +parameters, this has no effect.
│ │ │ │ │ Your code can then perform as complex a code as needed, and finally return a
│ │ │ │ │ value (or not) to the scripting language, through a call toSet_Return_Value.
│ │ │ │ │ After the above code has been executed, your users can go to the python console
│ │ │ │ │ and type for instance:
│ │ │ │ │ from MyModule import * # MyModule is the name we declared above
│ │ │ │ │ print sum (1,2)
│ │ │ │ │ => 3
│ │ │ │ │ @@ -523,24 +525,24 @@
│ │ │ │ │ required setup has been done internally so that you can now add methods to this
│ │ │ │ │ class.
│ │ │ │ │ You can then register the class methods in the same way that you registered
│ │ │ │ │ functions. An additional parameterClassexists forRegister_Command. A method is
│ │ │ │ │ really just a standard function that has an implicit first parameter which is
│ │ │ │ │ aClass_Instance. This extra parameter should not be taken into account
│ │ │ │ │ inMin_ArgsandMax_Args. You can also declare the method as a static method, ie
│ │ │ │ │ -one that doesn't take this extra implicit parameter, and basically just uses
│ │ │ │ │ +one that doesnât take this extra implicit parameter, and basically just uses
│ │ │ │ │ the class as a namespace.
│ │ │ │ │ Some special method names are available. In particular,Constructor_Methodshould
│ │ │ │ │ be used for the constructor of a class. It is a method that receives, as its
│ │ │ │ │ first argument, a class instance that has just been created. It should
│ │ │ │ │ associate that instance with the Ada object it represents.
│ │ │ │ │ Here is a simple example that exports a class. Each instance of this class is
│ │ │ │ │ associated with a string, passed in parameter to the constructor. The class has
│ │ │ │ │ a single methodprint, which prints its string parameter prefixed by the
│ │ │ │ │ -instance's string. To start with, here is a python example on what we want to
│ │ │ │ │ +instanceâs string. To start with, here is a python example on what we want to
│ │ │ │ │ achieve:
│ │ │ │ │ c1 = MyClass ("prefix1")
│ │ │ │ │ c1.print ("foo")
│ │ │ │ │ => "prefix1 foo"
│ │ │ │ │ c2 = MyClass () # Using a default prefix
│ │ │ │ │ c2.print ("foo")
│ │ │ │ │ => "default foo"
│ │ │ │ │ @@ -562,34 +564,34 @@
│ │ │ │ │
│ │ │ │ │ Register_Command
│ │ │ │ │ (Repo, Constructor_Method, 0, 1, Handler'Access, MyClass);
│ │ │ │ │ Register_Command
│ │ │ │ │ (Repo, "print", 1, 1, Handler'Access, MyClass);
│ │ │ │ │ This example also demonstrates a few concepts: the constructor is declared as a
│ │ │ │ │ method that takes one optional argument. The default value is in fact passed in
│ │ │ │ │ -the call toNth_Argand is set to "default". In the handler, we know there is
│ │ │ │ │ +the call toNth_Argand is set to âdefaultâ. In the handler, we know there is
│ │ │ │ │ always a first argument which is the instance on which the method applies. The
│ │ │ │ │ implementation for the constructor stores the prefix in the instance itself, so
│ │ │ │ │ -that several instances can have different prefixes (we can't use global
│ │ │ │ │ -variables, of course, since we don't know in advance how many instances will
│ │ │ │ │ +that several instances can have different prefixes (we canât use global
│ │ │ │ │ +variables, of course, since we donât know in advance how many instances will
│ │ │ │ │ exist). The implementation forprintinserts code in the default console for the
│ │ │ │ │ script (we could of course usePut_Lineor any other way to output data), and
│ │ │ │ │ -computes the string to output by concatenating the instance's prefix and the
│ │ │ │ │ +computes the string to output by concatenating the instanceâs prefix and the
│ │ │ │ │ parameter toprint.
│ │ │ │ │ Note thatSet_DataandGet_Datatake the class in parameter, in addition to the
│ │ │ │ │ class instance. This is needed for proper handling of multiple inheritance: say
│ │ │ │ │ we have a classCthat extends two classesAandB. The Ada code that deals
│ │ │ │ │ withAassociates an integer with the class instance, whereas the code that deals
│ │ │ │ │ withBassociates a string. Now, if you have an instance ofCbut call a method
│ │ │ │ │ -inherited fromA, and ifGet_Datadidn't specify the class, there would be a risk
│ │ │ │ │ -that a string would be returned instead of the expected integer. In fact, the
│ │ │ │ │ -proper solution here is that bothAandBstore their preferred data at the same
│ │ │ │ │ -time in the instances, but only fetch the one they actually need. Therefore
│ │ │ │ │ -instances ofCare associated with two datas.
│ │ │ │ │ -Here is a more advanced example that shows how to export an Ada object. Let's
│ │ │ │ │ +inherited fromA, and ifGet_Datadidnât specify the class, there would be a
│ │ │ │ │ +risk that a string would be returned instead of the expected integer. In fact,
│ │ │ │ │ +the proper solution here is that bothAandBstore their preferred data at the
│ │ │ │ │ +same time in the instances, but only fetch the one they actually need.
│ │ │ │ │ +Therefore instances ofCare associated with two datas.
│ │ │ │ │ +Here is a more advanced example that shows how to export an Ada object. Letâs
│ │ │ │ │ assume we have the following Ada type that we want to make available to
│ │ │ │ │ scripts:
│ │ │ │ │ type MyType is record
│ │ │ │ │ Field : Integer;
│ │ │ │ │ end record;
│ │ │ │ │ As you can see, this is not a tagged type, but could certainly be. There is of
│ │ │ │ │ course no procedureSet_Datain GNATCOLL.Scripts that enables us to storeMyTypein
│ │ │ │ │ @@ -611,18 +613,18 @@
│ │ │ │ │ function Get_Data (Inst : Class_Instance) return MyType is
│ │ │ │ │ Data : MyProps := MyProps (Instance_Property'
│ │ │ │ │ (Get_Data (Inst, Get_Name (MyClass))));
│ │ │ │ │ begin
│ │ │ │ │ return Data.Val;
│ │ │ │ │ end Get_Data;
│ │ │ │ │ Several aspects worth noting in this example. Each data is associated with a
│ │ │ │ │ -name, not a class as in the previous example. That's in fact the same thing,
│ │ │ │ │ +name, not a class as in the previous example. Thatâs in fact the same thing,
│ │ │ │ │ and mostly for historical reasons. We have to create our own instance
│ │ │ │ │ ofInstance_Property_Recordto store the data, but the implementation presents no
│ │ │ │ │ -special difficulty. In fact, we don't absolutely need to
│ │ │ │ │ +special difficulty. In fact, we donât absolutely need to
│ │ │ │ │ createSet_DataandGet_Dataand could do everything inline in the method
│ │ │ │ │ implementation, but it is cleaner this way and easier to reuse.
│ │ │ │ │ GNATColl is fully responsible for managing the lifetime of the data associated
│ │ │ │ │ with the class instances and you can override the procedureDestroyif you need
│ │ │ │ │ special memory management.
│ │ │ │ │ *** 3.2.3.4. Reusing class instances¶ ***
│ │ │ │ │ We mentioned above that it is more convenient for users of your exported
│ │ │ │ │ @@ -641,16 +643,16 @@
│ │ │ │ │ already received the created instance (this is forced by python, and was done
│ │ │ │ │ the same for other languages for compatibility reasons). There are two ways to
│ │ │ │ │ work around that limitation:
│ │ │ │ │ * Staticgetmethods
│ │ │ │ │ With each of your classes, you can export a static method generally
│ │ │ │ │ calledgetthat takes in parameter a way to identify an existing instance,
│ │ │ │ │ and either return it or create a new one. It is also recommended to
│ │ │ │ │ - disable the constructor, ie force it to raise an error. Let's examine the
│ │ │ │ │ - python code as it would be used:
│ │ │ │ │ + disable the constructor, ie force it to raise an error. Letâs examine
│ │ │ │ │ + the python code as it would be used:
│ │ │ │ │ ed = Editor ("file.adb") # constructor
│ │ │ │ │ => Error, cannot construct instances
│ │ │ │ │ ed = Editor.get ("file.adb")
│ │ │ │ │ => Create a new instance
│ │ │ │ │ ed2 = Editor.get ("file.adb")
│ │ │ │ │ => Return existing instance
│ │ │ │ │ ed == ed2
│ │ │ │ │ @@ -693,15 +695,15 @@
│ │ │ │ │ => ed is of type MyClassImpl
│ │ │ │ │ ed = MyClass ("file.adb") # return same instance
│ │ │ │ │ ed.do_something()
│ │ │ │ │ It is important to realize that in the call above, we are not calling the
│ │ │ │ │ constructor of a class, but a function. At the Ada level, the function
│ │ │ │ │ has basically the same implementation as the one we gave forgetabove. But
│ │ │ │ │ the python code looks nicer because we do not have these additional.get
│ │ │ │ │ - ()calls. The name of the classMyClassImpldoesn't appear anywhere in the
│ │ │ │ │ + ()calls. The name of the classMyClassImpldoesnât appear anywhere in the
│ │ │ │ │ python code, so this is mostly transparent.
│ │ │ │ │ However, if you have more than one scripting language, in particular for
│ │ │ │ │ the shell, the code looks less nice in this case:
│ │ │ │ │ MyClass "file.adb"
│ │ │ │ │ =>
│ │ │ │ │ MyClassImpl.do_something %1
│ │ │ │ │ and the new name of the class is visible in the method call.
│ │ │ │ │ @@ -739,16 +741,16 @@
│ │ │ │ │ **** 3.2.6. Debugging scripts¶ ****
│ │ │ │ │ GNATColl provides a convenient hook to debug your script. By default, a script
│ │ │ │ │ (python for instance) will call your Ada callback, which might raise errors.
│ │ │ │ │ Most of the time, the error should indeed be reported to the user, and you can
│ │ │ │ │ thus raise a standard exception, or callSet_Error_Msg.
│ │ │ │ │ But if you wish to know which script was executing the command, it is generally
│ │ │ │ │ not doable. You can however activate a trace (Traces:_Logging_information)
│ │ │ │ │ -called"PYTHON.TB"(for "traceback"), which will output the name of the command
│ │ │ │ │ -that is being executed, as well as the full traceback within the python
│ │ │ │ │ +calledâPYTHON.TBâ(for âtracebackâ), which will output the name of the
│ │ │ │ │ +command that is being executed, as well as the full traceback within the python
│ │ │ │ │ scripts. This will help you locate which script is raising an exception.
│ │ │ │ │ [Logo]
│ │ │ │ │ **** Table_of_Contents ****
│ │ │ │ │ * 3._Scripts:_Embedding_script_languages
│ │ │ │ │ o 3.1._Supported_languages
│ │ │ │ │ # 3.1.1._The_Shell_language
│ │ │ │ │ # 3.1.2._Classes_exported_to_all_languages
│ │ │ ├── ./usr/share/doc/libgnatcoll-doc/html/storage_pools.html
│ │ │ │ @@ -51,16 +51,16 @@
│ │ │ │ This can of course be done in most languages. However, that generally
│ │ │ │ means you have to remember not to use the standard memory allocations
│ │ │ │ like malloc or new, and instead call one of your
│ │ │ │ subprograms. If you ever decide to change the allocation strategy, or
│ │ │ │ want to experiment with several strategies, that means updating your
│ │ │ │ code in several places.
│ │ │ │ In Ada, when you declare the type of your data, you also specify through
│ │ │ │ -a 'Storage_Pool attribute how the memory for instances of that
│ │ │ │ -type should be allocated. And that's it. You then use the usual
│ │ │ │ +a ‘Storage_Pool attribute how the memory for instances of that
│ │ │ │ +type should be allocated. And that’s it. You then use the usual
│ │ │ │ new keyword to allocate memory.
│ │ │ │ GNATColl provides a number of examples for such storage pools,
│ │ │ │ with various goals. There is also one advanced such pool in the GNAT
│ │ │ │ run-time itself, called GNAT.Debug_Pools, which allows you to
│ │ │ │ control memory leaks and whether all accesses do reference valid memory
│ │ │ │ location (and not memory that has already been deallocated).
│ │ │ │ In GNATColl, you will find the following storage pools:
│ │ │ │ ├── html2text {}
│ │ │ │ │ @@ -20,16 +20,17 @@
│ │ │ │ │ results in a single system call, which speeds up your application.
│ │ │ │ │ This can of course be done in most languages. However, that generally means you
│ │ │ │ │ have to remember not to use the standard memory allocations likemallocornew,
│ │ │ │ │ and instead call one of your subprograms. If you ever decide to change the
│ │ │ │ │ allocation strategy, or want to experiment with several strategies, that means
│ │ │ │ │ updating your code in several places.
│ │ │ │ │ In Ada, when you declare the type of your data, you also specify through
│ │ │ │ │ -a'Storage_Poolattribute how the memory for instances of that type should be
│ │ │ │ │ -allocated. And that's it. You then use the usualnewkeyword to allocate memory.
│ │ │ │ │ +aâStorage_Poolattribute how the memory for instances of that type should be
│ │ │ │ │ +allocated. And thatâs it. You then use the usualnewkeyword to allocate
│ │ │ │ │ +memory.
│ │ │ │ │ GNATColl provides a number of examples for such storage pools, with various
│ │ │ │ │ goals. There is also one advanced such pool in the GNAT run-time itself,
│ │ │ │ │ calledGNAT.Debug_Pools, which allows you to control memory leaks and whether
│ │ │ │ │ all accesses do reference valid memory location (and not memory that has
│ │ │ │ │ already been deallocated).
│ │ │ │ │ In GNATColl, you will find the following storage pools:
│ │ │ │ │ `GNATCOLL.Storage_Pools.Alignment`
│ │ │ ├── ./usr/share/doc/libgnatcoll-doc/html/strings.html
│ │ │ │ @@ -41,19 +41,19 @@
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │ 5. Strings: high-performance strings¶
│ │ │ │ The generic package GNATCOLL.Strings_Impl
(and its default
│ │ │ │ instantiation in GNATCOLL.Strings
) provides a high-performance
│ │ │ │ strings implementation.
│ │ │ │ -It comes in addition to Ada's own String and Unbounded_String types,
│ │ │ │ +
It comes in addition to Ada’s own String and Unbounded_String types,
│ │ │ │ although it attempts to find a middle ground in between (flexibility
│ │ │ │ vs performance).
│ │ │ │ GNATCOLL.Strings therefore provides strings (named XString, as in
│ │ │ │ -extended-strings) that can grow as needed (up to Natural'Last, like standard
│ │ │ │ +extended-strings) that can grow as needed (up to Natural’Last, like standard
│ │ │ │ strings), yet are faster than unbounded strings. They also come with an
│ │ │ │ extended API, which includes all primitive operations from unbounded strings,
│ │ │ │ in addition to some subprograms inspired from GNATCOLL.Utils and the python and
│ │ │ │ C++ programming languages.
│ │ │ │
│ │ │ │ 5.1. Small string optimization¶
│ │ │ │ GNATCOLL.Strings uses a number of tricks to improve on the efficiency. The
│ │ │ │ @@ -87,17 +87,17 @@
│ │ │ │
│ │ │ │ So in the same amount of memory (24 bytes), we can either store a small string
│ │ │ │ of 23 characters or less with no memory allocations, or a big string that
│ │ │ │ requires allocation. In a typical application, most strings are smaller than 23
│ │ │ │ bytes, so we are saving very significant time here.
│ │ │ │ This representation has to work on both 32 bits systems and 64 bits systems, so
│ │ │ │ we have careful representation clauses to take this into account. It also
│ │ │ │ -needs to work on both big-endian and little-endian systems. Thanks to Ada's
│ │ │ │ +needs to work on both big-endian and little-endian systems. Thanks to Ada’s
│ │ │ │ representation clauses, this one in fact relatively easy to achieve (well,
│ │ │ │ -okay, after trying a few different approaches to emulate what's done in C++,
│ │ │ │ +okay, after trying a few different approaches to emulate what’s done in C++,
│ │ │ │ and that did not work elegantly). In fact, emulating via bit-shift operations
│ │ │ │ ended up with code that was less efficient than letting the compiler do it
│ │ │ │ automatically because of our representation clauses.
│ │ │ │
│ │ │ │
│ │ │ │ 5.2. Character types¶
│ │ │ │ Applications should be able to handle the whole set of Unicode characters. In
│ │ │ │ @@ -145,40 +145,40 @@
│ │ │ │
This is often a reasonable number, and given that applications mostly use small
│ │ │ │ strings, we are already saving a lot of allocations. However, in some cases we
│ │ │ │ know that the typical length of strings in a particular context is different.
│ │ │ │ For instance, GNATCOLL.Traces builds messages to output in the log file. Such
│ │ │ │ messages will typically be at most 100 characters, although they can of course
│ │ │ │ be much larger sometimes.
│ │ │ │ We have added one more formal parameter to GNATCOLL.Strings_Impl to control the
│ │ │ │ -maximum size of small strings. If for instance we decide that a "small" string
│ │ │ │ +maximum size of small strings. If for instance we decide that a “small” string
│ │ │ │ is anywhere from 1 to 100 characters long (i.e. we do not want to allocate
│ │ │ │ memory for those strings), it can be done via this parameter.
│ │ │ │ Of course, in such cases the size of the string itself becomes much larger.
│ │ │ │ In this example it would be 101 bytes long, rather than the 24 bytes. Although
│ │ │ │ we are saving on memory allocations, we are also spending more time copying
│ │ │ │ -data when the string is passed around, so you'll need to measure the
│ │ │ │ +data when the string is passed around, so you’ll need to measure the
│ │ │ │ performance here.
│ │ │ │ The maximum size for the small string is 127 bytes however, because this size
│ │ │ │ and the 1-bit flag need to fit in 1 bytes in the representation clauses we
│ │ │ │ showed above. We tried to make this more configurable, but this makes things
│ │ │ │ significantly more complex between little-endian and big-endian systems, and
│ │ │ │ -having large "small" strings would not make much sense in terms of performance
│ │ │ │ +having large “small” strings would not make much sense in terms of performance
│ │ │ │ anyway.
│ │ │ │ Typical C++ implementations do not make this small size configurable.
│ │ │ │
│ │ │ │
│ │ │ │ 5.4. Task safety¶
│ │ │ │ Just like unbounded strings, the strings in this package are not thread safe.
│ │ │ │ This means that you cannot access the same string (read or write) from two
│ │ │ │ different threads without somehow protecting the access via a protected type,
│ │ │ │ -locks,...
│ │ │ │ +locks,…
│ │ │ │ In practice, sharing strings would rarely be done, so if the package itself
│ │ │ │ was doing its own locking we would end up with very bad performance in all
│ │ │ │ cases, for a few cases where it might prove useful.
│ │ │ │ -As we'll discuss below, it is possible to use two different strings that
│ │ │ │ +
As we’ll discuss below, it is possible to use two different strings that
│ │ │ │ actually share the same internal buffer, from two different threads. Since this
│ │ │ │ is an implementation detail, this package takes care of guaranteeing the
│ │ │ │ integrity of the shared data in such a case.
│ │ │ │
│ │ │ │
│ │ │ │ 5.5. Copy on write¶
│ │ │ │ There is one more formal parameter, to configure whether this package should
│ │ │ │ @@ -217,38 +217,38 @@
│ │ │ │
This package has a slightly different strategy. Remember that we only start
│ │ │ │ allocating memory past the size of small strings, so we will for instance first
│ │ │ │ allocate 24 bytes. When more memory is needed, we multiply this size by 1.5,
│ │ │ │ which some researchers have found to be a good comprise between waste of memory
│ │ │ │ and number of allocations. For very large strings, we always allocate multiples
│ │ │ │ of the memory page size (4096 bytes), since this is what the system will make
│ │ │ │ available anyway. So we will basically allocate the following: 24, 36, 54, 82,
│ │ │ │ -122,...
│ │ │ │ +122,…
│ │ │ │ An additional constraint is that we only ever allocate even number of bytes.
│ │ │ │ This is called the capacity of the string. In the layout of the big string,
│ │ │ │ as shown above, we store half that capacity, which saves one bit that we
│ │ │ │ use for the flag.
│ │ │ │
│ │ │ │
│ │ │ │ 5.7. Substrings¶
│ │ │ │ One other optimization performed by this package (which is not done for
│ │ │ │ unbounded strings or various C++ implementations) is to optimize substrings
│ │ │ │ when also using copy-on-write.
│ │ │ │ We simply store the index of the first character of the string within the
│ │ │ │ shared buffer, instead of always starting at the first.
│ │ │ │ -From the user's point of view, this is an implementation detail. Strings
│ │ │ │ +
From the user’s point of view, this is an implementation detail. Strings
│ │ │ │ are always indexed from 1, and internally we convert to an actual position
│ │ │ │ in the buffer. This means that if we need to reallocate the buffer, for
│ │ │ │ instance when the string is modified, we transparently change the index
│ │ │ │ of the first character, but the indexes the user was using are still valid.
│ │ │ │ This results in very significant savings, as shown below in the timings
│ │ │ │ for Trim for instance. Also, we can do an operation like splitting a
│ │ │ │ string very efficiently.
│ │ │ │ -For instance, the following code doesn't allocate any memory, beside
│ │ │ │ +
For instance, the following code doesn’t allocate any memory, beside
│ │ │ │ setting the initial value of the string. It parses a file containing
│ │ │ │ -some "key=value" lines, with optional spaces, and possibly empty lines:
│ │ │ │ +some “key=value” lines, with optional spaces, and possibly empty lines:
│ │ │ │ declare
│ │ │ │ S, Key, Value : XString;
│ │ │ │ L : XString_Array (1 .. 2);
│ │ │ │ Last : Natural;
│ │ │ │ begin
│ │ │ │ S.Set (".......");
│ │ │ │ ├── html2text {}
│ │ │ │ │ @@ -11,18 +11,18 @@
│ │ │ │ │ * next |
│ │ │ │ │ * previous |
│ │ │ │ │ * GNATColl_0.0_documentation »
│ │ │ │ │ * 5. Strings: high-performance strings
│ │ │ │ │ ****** 5. Strings: high-performance strings¶ ******
│ │ │ │ │ The generic package GNATCOLL.Strings_Impl (and its default instantiation in
│ │ │ │ │ GNATCOLL.Strings) provides a high-performance strings implementation.
│ │ │ │ │ -It comes in addition to Ada's ownStringandUnbounded_Stringtypes, although it
│ │ │ │ │ +It comes in addition to Adaâs ownStringandUnbounded_Stringtypes, although it
│ │ │ │ │ attempts to find a middle ground in between (flexibility vs performance).
│ │ │ │ │ GNATCOLL.Strings therefore provides strings (namedXString, as in extended-
│ │ │ │ │ -strings) that can grow as needed (up toNatural'Last, like standard strings),
│ │ │ │ │ +strings) that can grow as needed (up toNaturalâLast, like standard strings),
│ │ │ │ │ yet are faster than unbounded strings. They also come with an extended API,
│ │ │ │ │ which includes all primitive operations from unbounded strings, in addition to
│ │ │ │ │ some subprograms inspired from GNATCOLL.Utils and the python and C++
│ │ │ │ │ programming languages.
│ │ │ │ │ ***** 5.1. Small string optimization¶ *****
│ │ │ │ │ GNATCOLL.Strings uses a number of tricks to improve on the efficiency. The most
│ │ │ │ │ important one is to limit the number of memory allocations. For this, we use a
│ │ │ │ │ @@ -53,17 +53,17 @@
│ │ │ │ │ This is because of alignment issues.
│ │ │ │ │ So in the same amount of memory (24 bytes), we can either store a small string
│ │ │ │ │ of 23 characters or less with no memory allocations, or a big string that
│ │ │ │ │ requires allocation. In a typical application, most strings are smaller than 23
│ │ │ │ │ bytes, so we are saving very significant time here.
│ │ │ │ │ This representation has to work on both 32 bits systems and 64 bits systems, so
│ │ │ │ │ we have careful representation clauses to take this into account. It also needs
│ │ │ │ │ -to work on both big-endian and little-endian systems. Thanks to Ada's
│ │ │ │ │ +to work on both big-endian and little-endian systems. Thanks to Adaâs
│ │ │ │ │ representation clauses, this one in fact relatively easy to achieve (well,
│ │ │ │ │ -okay, after trying a few different approaches to emulate what's done in C++,
│ │ │ │ │ +okay, after trying a few different approaches to emulate whatâs done in C++,
│ │ │ │ │ and that did not work elegantly). In fact, emulating via bit-shift operations
│ │ │ │ │ ended up with code that was less efficient than letting the compiler do it
│ │ │ │ │ automatically because of our representation clauses.
│ │ │ │ │ ***** 5.2. Character types¶ *****
│ │ │ │ │ Applications should be able to handle the whole set of Unicode characters. In
│ │ │ │ │ Ada, these are represented as the Wide_Character type, rather than Character,
│ │ │ │ │ and stored on 2 bytes rather than 1. Of course, for a lot of applications it
│ │ │ │ │ @@ -102,38 +102,38 @@
│ │ │ │ │ This is often a reasonable number, and given that applications mostly use small
│ │ │ │ │ strings, we are already saving a lot of allocations. However, in some cases we
│ │ │ │ │ know that the typical length of strings in a particular context is different.
│ │ │ │ │ For instance, GNATCOLL.Traces builds messages to output in the log file. Such
│ │ │ │ │ messages will typically be at most 100 characters, although they can of course
│ │ │ │ │ be much larger sometimes.
│ │ │ │ │ We have added one more formal parameter to GNATCOLL.Strings_Impl to control the
│ │ │ │ │ -maximum size of small strings. If for instance we decide that a "small" string
│ │ │ │ │ -is anywhere from 1 to 100 characters long (i.e. we do not want to allocate
│ │ │ │ │ -memory for those strings), it can be done via this parameter.
│ │ │ │ │ +maximum size of small strings. If for instance we decide that a âsmallâ
│ │ │ │ │ +string is anywhere from 1 to 100 characters long (i.e. we do not want to
│ │ │ │ │ +allocate memory for those strings), it can be done via this parameter.
│ │ │ │ │ Of course, in such cases the size of the string itself becomes much larger. In
│ │ │ │ │ this example it would be 101 bytes long, rather than the 24 bytes. Although we
│ │ │ │ │ are saving on memory allocations, we are also spending more time copying data
│ │ │ │ │ -when the string is passed around, so you'll need to measure the performance
│ │ │ │ │ +when the string is passed around, so youâll need to measure the performance
│ │ │ │ │ here.
│ │ │ │ │ The maximum size for the small string is 127 bytes however, because this size
│ │ │ │ │ and the 1-bit flag need to fit in 1 bytes in the representation clauses we
│ │ │ │ │ showed above. We tried to make this more configurable, but this makes things
│ │ │ │ │ significantly more complex between little-endian and big-endian systems, and
│ │ │ │ │ -having large "small" strings would not make much sense in terms of performance
│ │ │ │ │ -anyway.
│ │ │ │ │ +having large âsmallâ strings would not make much sense in terms of
│ │ │ │ │ +performance anyway.
│ │ │ │ │ Typical C++ implementations do not make this small size configurable.
│ │ │ │ │ ***** 5.4. Task safety¶ *****
│ │ │ │ │ Just like unbounded strings, the strings in this package are not thread safe.
│ │ │ │ │ This means that you cannot access the same string (read or write) from two
│ │ │ │ │ different threads without somehow protecting the access via a protected type,
│ │ │ │ │ -locks,...
│ │ │ │ │ +locks,â¦
│ │ │ │ │ In practice, sharing strings would rarely be done, so if the package itself was
│ │ │ │ │ doing its own locking we would end up with very bad performance in all cases,
│ │ │ │ │ for a few cases where it might prove useful.
│ │ │ │ │ -As we'll discuss below, it is possible to use two different strings that
│ │ │ │ │ +As weâll discuss below, it is possible to use two different strings that
│ │ │ │ │ actually share the same internal buffer, from two different threads. Since this
│ │ │ │ │ is an implementation detail, this package takes care of guaranteeing the
│ │ │ │ │ integrity of the shared data in such a case.
│ │ │ │ │ ***** 5.5. Copy on write¶ *****
│ │ │ │ │ There is one more formal parameter, to configure whether this package should
│ │ │ │ │ use copy-on-write or not. When copy on write is enabled, you can have multiple
│ │ │ │ │ strings that internally share the same buffer of characters. This means that
│ │ │ │ │ @@ -167,36 +167,36 @@
│ │ │ │ │ This package has a slightly different strategy. Remember that we only start
│ │ │ │ │ allocating memory past the size of small strings, so we will for instance first
│ │ │ │ │ allocate 24 bytes. When more memory is needed, we multiply this size by 1.5,
│ │ │ │ │ which some researchers have found to be a good comprise between waste of memory
│ │ │ │ │ and number of allocations. For very large strings, we always allocate multiples
│ │ │ │ │ of the memory page size (4096 bytes), since this is what the system will make
│ │ │ │ │ available anyway. So we will basically allocate the following: 24, 36, 54, 82,
│ │ │ │ │ -122,...
│ │ │ │ │ +122,â¦
│ │ │ │ │ An additional constraint is that we only ever allocate even number of bytes.
│ │ │ │ │ This is called the capacity of the string. In the layout of the big string, as
│ │ │ │ │ shown above, we store half that capacity, which saves one bit that we use for
│ │ │ │ │ the flag.
│ │ │ │ │ ***** 5.7. Substrings¶ *****
│ │ │ │ │ One other optimization performed by this package (which is not done for
│ │ │ │ │ unbounded strings or various C++ implementations) is to optimize substrings
│ │ │ │ │ when also using copy-on-write.
│ │ │ │ │ We simply store the index of the first character of the string within the
│ │ │ │ │ shared buffer, instead of always starting at the first.
│ │ │ │ │ -From the user's point of view, this is an implementation detail. Strings are
│ │ │ │ │ +From the userâs point of view, this is an implementation detail. Strings are
│ │ │ │ │ always indexed from 1, and internally we convert to an actual position in the
│ │ │ │ │ buffer. This means that if we need to reallocate the buffer, for instance when
│ │ │ │ │ the string is modified, we transparently change the index of the first
│ │ │ │ │ character, but the indexes the user was using are still valid.
│ │ │ │ │ This results in very significant savings, as shown below in the timings for
│ │ │ │ │ Trim for instance. Also, we can do an operation like splitting a string very
│ │ │ │ │ efficiently.
│ │ │ │ │ -For instance, the following code doesn't allocate any memory, beside setting
│ │ │ │ │ -the initial value of the string. It parses a file containing some "key=value"
│ │ │ │ │ -lines, with optional spaces, and possibly empty lines:
│ │ │ │ │ +For instance, the following code doesnât allocate any memory, beside setting
│ │ │ │ │ +the initial value of the string. It parses a file containing some
│ │ │ │ │ +âkey=valueâ lines, with optional spaces, and possibly empty lines:
│ │ │ │ │ declare
│ │ │ │ │ S, Key, Value : XString;
│ │ │ │ │ L : XString_Array (1 .. 2);
│ │ │ │ │ Last : Natural;
│ │ │ │ │ begin
│ │ │ │ │ S.Set (".......");
│ │ │ ├── ./usr/share/doc/libgnatcoll-doc/html/templates.html
│ │ │ │ @@ -40,45 +40,45 @@
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │ 10. Templates: generating text¶
│ │ │ │ This module provides convenient subprograms for replacing specific
│ │ │ │ substrings with other values. It is typically used to replace substrings
│ │ │ │ -like "%{version}" in a longer string with the actual version, at run time.
│ │ │ │ +like “%{version}” in a longer string with the actual version, at run time.
│ │ │ │ This module is not the same as the templates parser provided in the context
│ │ │ │ of AWS, the Ada web server, where external files are parsed and processed
│ │ │ │ to generate other files. The latter provides advanced features like filters,
│ │ │ │ -loops,...
│ │ │ │ +loops,…
│ │ │ │ The substrings to be replaced always start with a specific delimiter, which
│ │ │ │ is set to % by default, but can be overridden in your code. The name
│ │ │ │ of the substring to be replaced is then the identifier following that
│ │ │ │ delimiter, with the following rules:
│ │ │ │
│ │ │ │ If the character following the delimiter is the delimiter itself,
│ │ │ │ then the final string will contain a single instance of that delimiter, and
│ │ │ │ no further substitution is done for that delimiter. An example of this is
│ │ │ │ -"%%".
│ │ │ │ +“%%”.
│ │ │ │ If the character immediately after the delimiter is a curly brace
│ │ │ │ ({), then the name of the identifier is the text until the next
│ │ │ │ closing curly brace. It can then contain any character expect a closing
│ │ │ │ -curly brace. An example of this is "%{long name}"
│ │ │ │ +curly brace. An example of this is “%{long name}”
│ │ │ │ If the first character after the delimiter is a digit, then the
│ │ │ │ name of the identifier is the number after the delimiter. An example of
│ │ │ │ -this is "%12". As a special case, if the first non-digit
│ │ │ │ +this is “%12”. As a special case, if the first non-digit
│ │ │ │ character is the symbol -, it is added as part of the name of the
│ │ │ │ -identifier, as in "%1-". One use for this feature is to indicate
│ │ │ │ +identifier, as in “%1-“. One use for this feature is to indicate
│ │ │ │ you want to replace it with all the positional parameters %1%2%3%4. For
│ │ │ │ instance, if you are writing the command line to spawn an external tool,
│ │ │ │ to which the user can pass any number of parameter, you could specify that
│ │ │ │ -command line as "tool -o %1 %2-" to indicate that all parameters
│ │ │ │ +command line as “tool -o %1 %2-“ to indicate that all parameters
│ │ │ │ should be concatenated on the command line.
│ │ │ │ If the first character after the delimiter is a letter, the identifier
│ │ │ │ follows the same rules as for Ada identifiers, and can contain any letter,
│ │ │ │ -digit, or underscore character. An example of this is "%ab_12". For
│ │ │ │ +digit, or underscore character. An example of this is “%ab_12”. For
│ │ │ │ readability, it is recommended to use the curly brace notation when the
│ │ │ │ name is complex, but that is not mandatory.
│ │ │ │ Otherwise the name of the identifier is the single character
│ │ │ │ following the delimiter
│ │ │ │
│ │ │ │ For each substring matching the rules above, the Substitute subprogram
│ │ │ │ will look for possible replacement text in the following order:
│ │ │ │ ├── html2text {}
│ │ │ │ │ @@ -10,47 +10,47 @@
│ │ │ │ │ * index
│ │ │ │ │ * next |
│ │ │ │ │ * previous |
│ │ │ │ │ * GNATColl_0.0_documentation »
│ │ │ │ │ * 10. Templates: generating text
│ │ │ │ │ ****** 10. Templates: generating text¶ ******
│ │ │ │ │ This module provides convenient subprograms for replacing specific substrings
│ │ │ │ │ -with other values. It is typically used to replace substrings like "%{version}"
│ │ │ │ │ -in a longer string with the actual version, at run time.
│ │ │ │ │ +with other values. It is typically used to replace substrings like â%
│ │ │ │ │ +{version}â in a longer string with the actual version, at run time.
│ │ │ │ │ This module is not the same as the templates parser provided in the context of
│ │ │ │ │ AWS, the Ada web server, where external files are parsed and processed to
│ │ │ │ │ generate other files. The latter provides advanced features like filters,
│ │ │ │ │ -loops,...
│ │ │ │ │ +loops,â¦
│ │ │ │ │ The substrings to be replaced always start with a specific delimiter, which is
│ │ │ │ │ set to%by default, but can be overridden in your code. The name of the
│ │ │ │ │ substring to be replaced is then the identifier following that delimiter, with
│ │ │ │ │ the following rules:
│ │ │ │ │ * If the character following the delimiter is the delimiter itself, then
│ │ │ │ │ the final string will contain a single instance of that delimiter, and no
│ │ │ │ │ further substitution is done for that delimiter. An example of this
│ │ │ │ │ - is"%%".
│ │ │ │ │ + isâ%%â.
│ │ │ │ │ * If the character immediately after the delimiter is a curly brace ({),
│ │ │ │ │ then the name of the identifier is the text until the next closing curly
│ │ │ │ │ brace. It can then contain any character expect a closing curly brace. An
│ │ │ │ │ - example of this is"%{long name}"
│ │ │ │ │ + example of this isâ%{long name}â
│ │ │ │ │ * If the first character after the delimiter is a digit, then the name of
│ │ │ │ │ the identifier is the number after the delimiter. An example of this
│ │ │ │ │ - is"%12". As a special case, if the first non-digit character is the
│ │ │ │ │ - symbol-, it is added as part of the name of the identifier, as in"%1-".
│ │ │ │ │ - One use for this feature is to indicate you want to replace it with all
│ │ │ │ │ - the positional parameters %1%2%3%4. For instance, if you are writing the
│ │ │ │ │ - command line to spawn an external tool, to which the user can pass any
│ │ │ │ │ - number of parameter, you could specify that command line as"tool -o %1
│ │ │ │ │ - %2-"to indicate that all parameters should be concatenated on the command
│ │ │ │ │ - line.
│ │ │ │ │ + isâ%12â. As a special case, if the first non-digit character is the
│ │ │ │ │ + symbol-, it is added as part of the name of the identifier, as inâ%1-
│ │ │ │ │ + â. One use for this feature is to indicate you want to replace it with
│ │ │ │ │ + all the positional parameters %1%2%3%4. For instance, if you are writing
│ │ │ │ │ + the command line to spawn an external tool, to which the user can pass
│ │ │ │ │ + any number of parameter, you could specify that command line asâtool -
│ │ │ │ │ + o %1 %2-âto indicate that all parameters should be concatenated on the
│ │ │ │ │ + command line.
│ │ │ │ │ * If the first character after the delimiter is a letter, the identifier
│ │ │ │ │ follows the same rules as for Ada identifiers, and can contain any
│ │ │ │ │ - letter, digit, or underscore character. An example of this is"%ab_12".
│ │ │ │ │ - For readability, it is recommended to use the curly brace notation when
│ │ │ │ │ - the name is complex, but that is not mandatory.
│ │ │ │ │ + letter, digit, or underscore character. An example of this
│ │ │ │ │ + isâ%ab_12â. For readability, it is recommended to use the curly brace
│ │ │ │ │ + notation when the name is complex, but that is not mandatory.
│ │ │ │ │ * Otherwise the name of the identifier is the single character following
│ │ │ │ │ the delimiter
│ │ │ │ │ For each substring matching the rules above, theSubstitutesubprogram will look
│ │ │ │ │ for possible replacement text in the following order:
│ │ │ │ │ * If theSubstringsparameter contains an entry for that name, the
│ │ │ │ │ corresponding value is used.
│ │ │ │ │ * Otherwise, if acallbackwas specified, it is called with the name of the
│ │ │ ├── ./usr/share/doc/libgnatcoll-doc/html/traces.html
│ │ │ │ @@ -41,40 +41,40 @@
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │ 4. Traces: Logging information¶
│ │ │ │ Most applications need to log various kinds of information: error messages,
│ │ │ │ information messages or debug messages among others. These logs can be
│ │ │ │ displayed and stored in a number of places: standard output, a file, the
│ │ │ │ -system logger, an application-specific database table,...
│ │ │ │ +system logger, an application-specific database table,…
│ │ │ │ The package GNATCOLL.Traces
addresses the various needs, except for the
│ │ │ │ application-specific database, which of course is specific to your business
│ │ │ │ and needs various custom fields in any case, which cannot be easily provided
│ │ │ │ through a general interface.
│ │ │ │ This module is organized around two tagged types (used through access types,
│ │ │ │ in fact, so the latter are mentioned below as a shortcut):
│ │ │ │
│ │ │ │ - Trace_Handle
This type defines a handle (similar to a file descriptor in other contexts)
│ │ │ │ which is latter used to output messages. An application will generally
│ │ │ │ define several handles, which can be enabled or disabled separately, therefore
│ │ │ │ limiting the amount of logging.
│ │ │ │
│ │ │ │ - Trace_Stream
Streams are the ultimate types responsible for the output of the messages.
│ │ │ │ One or more handles are associated with each stream. The latter can be a file,
│ │ │ │ -the standard output, a graphical window, a socket,... New types of streams
│ │ │ │ +the standard output, a graphical window, a socket,… New types of streams
│ │ │ │ can easily be defined in your application.
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │ 4.1. Configuring traces¶
│ │ │ │ As mentioned above, an application will generally create several
│ │ │ │ Trace_Handle (typically one per module in the application). When
│ │ │ │ new features are added to the application, the developers will generally
│ │ │ │ need to add lots of traces to help investigate problems once the application
│ │ │ │ -is installed at a customer's site. The problem here is that each module
│ │ │ │ +is installed at a customer’s site. The problem here is that each module
│ │ │ │ might output a lot of information, thus confusing the logs; this also does
│ │ │ │ not help debugging.
│ │ │ │ The GNATCOLL.Traces package allows the user to configure which handles
│ │ │ │ should actually generate logs, and which should just be silent and not
│ │ │ │ generate anything. Depending on the part of the application that needs to
│ │ │ │ be investigated, one can therefore enable a set of handles or another, to
│ │ │ │ be able to concentrate on that part of the application.
│ │ │ │ @@ -93,70 +93,70 @@
│ │ │ │ Parse_Config_File.
│ │ │ │
│ │ │ │ If no file name was specified in that call, the environment variable
│ │ │ │ ADA_DEBUG_FILE might point to a configuration file.
│ │ │ │
│ │ │ │ If the above two attempts did not find a suitable configuration file,
│ │ │ │ the current directory is searched for a file called .gnatdebug.
│ │ │ │ -Finally, the user's home directory will also be searched for that file.
│ │ │ │ +Finally, the user’s home directory will also be searched for that file.
│ │ │ │
│ │ │ │ In all cases, the format of the configuration file is the same. Its goal is
│ │ │ │ to associate the name of a trace_handle with the name of a
│ │ │ │ trace_stream on which it should be displayed.
│ │ │ │ Streams are identified by a name. You can provide additional streams by
│ │ │ │ creating a new tagged object (Defining custom stream types). Here are
│ │ │ │ the various possibilities to reference a stream:
│ │ │ │
│ │ │ │ -- "name"
where name is a string made of letters, digits and slash ('/') characters.
│ │ │ │ +
- “name”
where name is a string made of letters, digits and slash (‘/’) characters.
│ │ │ │ This is the name of a file to which the traces should be redirected. The
│ │ │ │ previous contents of the file is discarded. If the name of the file is a
│ │ │ │ relative path, it is relative to the location of the configuration file, not
│ │ │ │ necessarily to the current directory when the file is parsed.
│ │ │ │ In the file name, $$ is automatically replaced by the process number.
│ │ │ │ $D is automatically replaced by the current date. $T is automatically
│ │ │ │ replaced by the current date and time. Other patterns of the form $name,
│ │ │ │ ${name}, or $(name) are substituted with the value of the named environment
│ │ │ │ -variable, if it exists. If ">>" is used instead of ">" to redirect to that
│ │ │ │ +variable, if it exists. If “>>” is used instead of “>” to redirect to that
│ │ │ │ stream, the file is appended to, instead of truncated.
│ │ │ │
│ │ │ │ -- "&1"
This syntax is similar to the one used on Unix shells, and indicates that
│ │ │ │ +
- “&1”
This syntax is similar to the one used on Unix shells, and indicates that
│ │ │ │ the output should be displayed on the standard output for the application.
│ │ │ │ If the application is graphical, and in particular on Windows platforms, it
│ │ │ │ is possible that there is no standard output!
│ │ │ │
│ │ │ │ -- "&2"
Similar to the previous one, but the output is sent to standard error.
│ │ │ │ +- “&2”
Similar to the previous one, but the output is sent to standard error.
│ │ │ │
│ │ │ │ -- "&syslog"
-
│ │ │ │ +
- “&syslog”
-
│ │ │ │
│ │ │ │
│ │ │ │ Comments in a configuration file must be on a line of their own, and start
│ │ │ │ -with --. Empty lines are ignored. The rest of the lines represent
│ │ │ │ +with –. Empty lines are ignored. The rest of the lines represent
│ │ │ │ configurations, as in:
│ │ │ │
│ │ │ │ -If a line contains the single character "+", it activates all
│ │ │ │ +
If a line contains the single character “+”, it activates all
│ │ │ │ trace_handle by default. This means the rest of the configuration
│ │ │ │ file should disable those handles that are not needed. The default is that
│ │ │ │ all handles are disabled by default, and the configuration file should
│ │ │ │ activate the ones it needs. The Ada source code can change the default
│ │ │ │ status of each handles, as well
│ │ │ │ -If the line starts with the character ">", followed by a
│ │ │ │ +
If the line starts with the character “>”, followed by a
│ │ │ │ stream name (as defined above), this becomes the default stream. All handles
│ │ │ │ will be displayed on that stream, unless otherwise specified. If the stream
│ │ │ │ does not exist, it defaults to standard output.
│ │ │ │ Otherwise, the first token on the line is the name of a handle.
│ │ │ │ If that is the only element on the line, the handle is activated, and will
│ │ │ │ be displayed on the default stream.
│ │ │ │ -Otherwise, the next element on the line should be a "=" sign,
│ │ │ │ -followed by either "yes" or "no", depending on whether the
│ │ │ │ +
Otherwise, the next element on the line should be a “=” sign,
│ │ │ │ +followed by either “yes” or “no”, depending on whether the
│ │ │ │ handle should resp. be enabled or disabled.
│ │ │ │ -Finally, the rest of the line can optionally contain the ">"
│ │ │ │ +
Finally, the rest of the line can optionally contain the “>”
│ │ │ │ character followed by the name of the stream to which the handle should
│ │ │ │ be directed.
│ │ │ │ There is are two special cases for the names on this line: they can
│ │ │ │ -start with either "*." or ".*" to indicate the settings apply to a
│ │ │ │ +start with either “*.” or “.*” to indicate the settings apply to a
│ │ │ │ whole set of handles. See the example below.
│ │ │ │
│ │ │ │
│ │ │ │ Here is a short example of a configuration file. It activates all handles
│ │ │ │ by default, and defines four handles: two of them are directed to the
│ │ │ │ default stream (standard error), the third one to a file on the disk,
│ │ │ │ and the last one to the system logger syslog (if your system supports it,
│ │ │ │ @@ -297,15 +297,15 @@
│ │ │ │
│ │ │ │
│ │ │ │ 4.3. Log decorators¶
│ │ │ │ Speaking of color, a number of decorators are defined by
│ │ │ │ GNATCOLL.Traces. Their goal is not to be used for outputting information,
│ │ │ │ but to configure what extra information should be output with all log
│ │ │ │ messages. They are activated through the same configuration file as the
│ │ │ │ -traces, with the same syntax (i.e either "=yes" or "=no").
│ │ │ │ +traces, with the same syntax (i.e either “=yes” or “=no”).
│ │ │ │ Here is an exhaustive list:
│ │ │ │
│ │ │ │ - DEBUG.ABSOLUTE_TIME
If this decorator is activated in the configuration file, the absolute time
│ │ │ │ when Trace is called is automatically added to the output, when the
│ │ │ │ streams supports it (in particular, this has no effect for syslog, which
│ │ │ │ already does this on its own).
│ │ │ │
│ │ │ │ @@ -318,21 +318,21 @@
│ │ │ │ - DEBUG.STACK_TRACE
If this decorator is activated, then the stack trace is also displayed. It can
│ │ │ │ be converted to a symbolic stack trace through the use of the external
│ │ │ │ application addr2line, but that would be too costly to do this
│ │ │ │ automatically for each message.
│ │ │ │
│ │ │ │ - DEBUG.LOCATION
If this decorator is activated, the location of the call to Trace is
│ │ │ │ automatically displayed. This is a file:line:column information. This
│ │ │ │ -works even when the executable wasn't compiled with debug information
│ │ │ │ +works even when the executable wasn’t compiled with debug information
│ │ │ │
│ │ │ │ - DEBUG.ENCLOSING_ENTITY
Activate this decorator to automatically display the name of the subprogram
│ │ │ │ that contains the call to Trace.
│ │ │ │
│ │ │ │ - DEBUG.COLORS
If this decorator is activated, the messages will use colors for the various
│ │ │ │ -fields, if the stream supports it (syslog doesn't).
│ │ │ │ +fields, if the stream supports it (syslog doesn’t).
│ │ │ │
│ │ │ │ - DEBUG.COUNT
This decorator displays two additional numbers on each line: the first is
│ │ │ │ the number of times this handle was used so far in the application, the second
│ │ │ │ is the total number of traces emitted so far. These numbers can for instance
│ │ │ │ be used to set conditional breakpoints on a specific trace (break on
│ │ │ │ gnat.traces.log or gnat.traces.trace and check the value of
│ │ │ │ Handle.Count. It can also be used to refer to a specific line in some
│ │ │ │ @@ -358,15 +358,15 @@
│ │ │ │ (elapsed: 2ms)(loc: gnatcoll-traces.adb:224)
│ │ │ │ (entity:GNATCOLL.Traces.Log)
│ │ │ │ (callstack: 40FD9902 082FCFDD 082FE8DF )
│ │ │ │
│ │ │ │
│ │ │ │ Depending on your application, there are lots of other possible decorators
│ │ │ │ that could be useful (for instance the current thread, or the name of the
│ │ │ │ -executable when you have several of them,...). Since GNATCOLL.Traces
│ │ │ │ +executable when you have several of them,…). Since GNATCOLL.Traces
│ │ │ │ cannot provide all possible decorators, it provides support, through tagged
│ │ │ │ types, so that you can create your own decorators.
│ │ │ │ This needs you to override the Trace_Handle_Record tagged type. Since
│ │ │ │ this type is created through calls to GNATCOLL.Traces.Create. This is done
│ │ │ │ by providing an additional Factory parameter to Create; this is
│ │ │ │ a function that allocates and returns the new handle.
│ │ │ │ Then you can override either (or both) of the primitive operations
│ │ │ │ @@ -408,22 +408,22 @@
│ │ │ │ application which is charge of monitoring your application.
│ │ │ │ You do not need the code below if you simply want to have a new stream in
│ │ │ │ your application (for instance using one for logging Info messages, one for
│ │ │ │ Error messages, and so on). In this case, the function Create is all
│ │ │ │ you need.
│ │ │ │ GNATCOLL.Traces provides the type Trace_Stream_Record, which can
│ │ │ │ be overridden to redirect the traces to your own streams.
│ │ │ │ -Let's assume for now that you have defined a new type of stream (called
│ │ │ │ -"mystream"). To keep the example simple, we will assume this stream
│ │ │ │ +
Let’s assume for now that you have defined a new type of stream (called
│ │ │ │ +“mystream”). To keep the example simple, we will assume this stream
│ │ │ │ also redirects to a file. For flexibility, however, you want to let the user
│ │ │ │ configure the file name from the traces configuration file. Here is an
│ │ │ │ example of a configuration file that sets the default stream to a file
│ │ │ │ called foo
, and redirects a specific handle to another file called
│ │ │ │ bar
. Note how the same syntax that was used for standard output and
│ │ │ │ -standard error is also reused (ie the stream name starts with the "&"
│ │ │ │ +standard error is also reused (ie the stream name starts with the “&”
│ │ │ │ symbol, to avoid confusion with standard file names):
│ │ │ │ >&mystream:foo
│ │ │ │ MODULE=yes >&mystream:bar
│ │ │ │
│ │ │ │
│ │ │ │ You need of course to do a bit of coding in Ada to create the stream. This
│ │ │ │ is done by creating a new child of Trace_Stream_Record, and override
│ │ │ │ @@ -441,23 +441,23 @@
│ │ │ │ begin
│ │ │ │ Str.Get_String (S, L);
│ │ │ │ Put (Stream.File.all, String (S (1 .. L)));
│ │ │ │ end Put;
│ │ │ │
│ │ │ │
│ │ │ │ The above code did not open the file itself, as you might have noticed,
│ │ │ │ -nor did it register the name "mystream" so that it can be used in
│ │ │ │ +nor did it register the name “mystream” so that it can be used in
│ │ │ │ the configuration file. All this is done by creating a factory, ie a
│ │ │ │ function in charge of creating the new stream.
│ │ │ │ A factory is also a tagged object (so that you can store custom information
│ │ │ │ in it), with a single primitive operation, New_Stream, in charge of
│ │ │ │ creating and initializing a new stream.
│ │ │ │ This operation receives
│ │ │ │ in parameter the argument specified by the user in the configuration file
│ │ │ │ -(after the ":" character, if any), and must return a newly
│ │ │ │ +(after the “:” character, if any), and must return a newly
│ │ │ │ allocated stream. This function is also never called twice with the
│ │ │ │ same argument, since GNATCOLL.Traces automatically reuses an existing
│ │ │ │ stream when one with the same name and arguments already exists:
│ │ │ │ type My_Stream_Factory is new Stream_Factory with null record;
│ │ │ │
│ │ │ │ overriding function New_Stream
│ │ │ │ (Self : My_Stream_Factory; Args : String) return Trace_Stream
│ │ │ │ @@ -475,31 +475,31 @@
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │ 4.5. Logging to syslog¶
│ │ │ │ Among the predefined streams, GNATColl gives access to the system
│ │ │ │ logger syslog. This is a standard utility on all Unix systems, but is
│ │ │ │ not available on other systems. When you compile GNATColl, you should
│ │ │ │ -specify the switch --enable-syslog to configure to activate the
│ │ │ │ -support. If either this switch wasn't specified, or configure could not find
│ │ │ │ +specify the switch –enable-syslog to configure to activate the
│ │ │ │ +support. If either this switch wasn’t specified, or configure could not find
│ │ │ │ the relevant header files anyway, then support for syslog will not
│ │ │ │ be available. In this case, the package GNATCOLL.Traces.Syslog is still
│ │ │ │ available, but contains a single function that does nothing. If your
│ │ │ │ -configuration files redirect some trace handles to "syslog", they will
│ │ │ │ +configuration files redirect some trace handles to “syslog”, they will
│ │ │ │ instead be redirect to the default stream or to standard output.
│ │ │ │ Activating support for syslog requires the following call in your application:
│ │ │ │ GNATCOLL.Traces.Syslog.Register_Syslog_Stream;
│ │ │ │
│ │ │ │
│ │ │ │ This procedure is always available, whether your system supports or not
│ │ │ │ -syslog, and will simply do nothing if it doesn't support syslog. This means
│ │ │ │ +syslog, and will simply do nothing if it doesn’t support syslog. This means
│ │ │ │ that you do not need to have conditional code in your application to handle
│ │ │ │ that, and you can let GNATColl take care of this.
│ │ │ │ After the above call, trace handles can be redirected to a stream named
│ │ │ │ -"syslog".
│ │ │ │ +“syslog”.
│ │ │ │ The package GNATCOLL.Traces.Syslog also contains a low-level interface
│ │ │ │ to syslog, which, although fully functional, you should probably not use,
│ │ │ │ since that would make your code system-dependent.
│ │ │ │ Syslog itself dispatches its output based on two criteria: the
│ │ │ │ facility, which indicates what application emitted the message,
│ │ │ │ and where it should be filed, and the level which indicates the
│ │ │ │ urgency level of the message. Both of these criteria can be specified in
│ │ │ │ ├── html2text {}
│ │ │ │ │ @@ -12,36 +12,36 @@
│ │ │ │ │ * previous |
│ │ │ │ │ * GNATColl_0.0_documentation »
│ │ │ │ │ * 4. Traces: Logging information
│ │ │ │ │ ****** 4. Traces: Logging information¶ ******
│ │ │ │ │ Most applications need to log various kinds of information: error messages,
│ │ │ │ │ information messages or debug messages among others. These logs can be
│ │ │ │ │ displayed and stored in a number of places: standard output, a file, the system
│ │ │ │ │ -logger, an application-specific database table,...
│ │ │ │ │ +logger, an application-specific database table,â¦
│ │ │ │ │ The package GNATCOLL.Traces addresses the various needs, except for the
│ │ │ │ │ application-specific database, which of course is specific to your business and
│ │ │ │ │ needs various custom fields in any case, which cannot be easily provided
│ │ │ │ │ through a general interface.
│ │ │ │ │ This module is organized around two tagged types (used through access types, in
│ │ │ │ │ fact, so the latter are mentioned below as a shortcut):
│ │ │ │ │ Trace_Handle
│ │ │ │ │ This type defines a handle (similar to a file descriptor in other
│ │ │ │ │ contexts) which is latter used to output messages. An application will
│ │ │ │ │ generally define several handles, which can be enabled or disabled
│ │ │ │ │ separately, therefore limiting the amount of logging.
│ │ │ │ │ Trace_Stream
│ │ │ │ │ Streams are the ultimate types responsible for the output of the
│ │ │ │ │ messages. One or more handles are associated with each stream. The latter
│ │ │ │ │ - can be a file, the standard output, a graphical window, a socket,... New
│ │ │ │ │ + can be a file, the standard output, a graphical window, a socket,⦠New
│ │ │ │ │ types of streams can easily be defined in your application.
│ │ │ │ │ ***** 4.1. Configuring traces¶ *****
│ │ │ │ │ As mentioned above, an application will generally create severalTrace_Handle
│ │ │ │ │ (typically one per module in the application). When new features are added to
│ │ │ │ │ the application, the developers will generally need to add lots of traces to
│ │ │ │ │ -help investigate problems once the application is installed at a customer's
│ │ │ │ │ +help investigate problems once the application is installed at a customerâs
│ │ │ │ │ site. The problem here is that each module might output a lot of information,
│ │ │ │ │ thus confusing the logs; this also does not help debugging.
│ │ │ │ │ TheGNATCOLL.Tracespackage allows the user to configure which handles should
│ │ │ │ │ actually generate logs, and which should just be silent and not generate
│ │ │ │ │ anything. Depending on the part of the application that needs to be
│ │ │ │ │ investigated, one can therefore enable a set of handles or another, to be able
│ │ │ │ │ to concentrate on that part of the application.
│ │ │ │ │ @@ -54,68 +54,68 @@
│ │ │ │ │ The configuration file is found in one of three places, in the following order:
│ │ │ │ │ * The file name is specified in the source code in the call
│ │ │ │ │ toParse_Config_File.
│ │ │ │ │ * If no file name was specified in that call, the environment
│ │ │ │ │ variableADA_DEBUG_FILEmight point to a configuration file.
│ │ │ │ │ * If the above two attempts did not find a suitable configuration file, the
│ │ │ │ │ current directory is searched for a file called.gnatdebug. Finally, the
│ │ │ │ │ - user's home directory will also be searched for that file.
│ │ │ │ │ + userâs home directory will also be searched for that file.
│ │ │ │ │ In all cases, the format of the configuration file is the same. Its goal is to
│ │ │ │ │ associate the name of atrace_handlewith the name of atrace_streamon which it
│ │ │ │ │ should be displayed.
│ │ │ │ │ Streams are identified by a name. You can provide additional streams by
│ │ │ │ │ creating a new tagged object (Defining_custom_stream_types). Here are the
│ │ │ │ │ various possibilities to reference a stream:
│ │ │ │ │ - "name"
│ │ │ │ │ - where name is a string made of letters, digits and slash ('/')
│ │ │ │ │ + ânameâ
│ │ │ │ │ + where name is a string made of letters, digits and slash (â/â)
│ │ │ │ │ characters. This is the name of a file to which the traces should be
│ │ │ │ │ redirected. The previous contents of the file is discarded. If the name
│ │ │ │ │ of the file is a relative path, it is relative to the location of the
│ │ │ │ │ configuration file, not necessarily to the current directory when the
│ │ │ │ │ file is parsed. In the file name,$$is automatically replaced by the
│ │ │ │ │ process number.$Dis automatically replaced by the current date.$Tis
│ │ │ │ │ automatically replaced by the current date and time. Other patterns of
│ │ │ │ │ the form$name,${name}, or$(name)are substituted with the value of the
│ │ │ │ │ - named environment variable, if it exists. If ">>" is used instead of ">"
│ │ │ │ │ - to redirect to that stream, the file is appended to, instead of
│ │ │ │ │ + named environment variable, if it exists. If â>>â is used instead of
│ │ │ │ │ + â>â to redirect to that stream, the file is appended to, instead of
│ │ │ │ │ truncated.
│ │ │ │ │ - "&1"
│ │ │ │ │ + â&1â
│ │ │ │ │ This syntax is similar to the one used on Unix shells, and indicates that
│ │ │ │ │ the output should be displayed on the standard output for the
│ │ │ │ │ application. If the application is graphical, and in particular on
│ │ │ │ │ Windows platforms, it is possible that there is no standard output!
│ │ │ │ │ - "&2"
│ │ │ │ │ + â&2â
│ │ │ │ │ Similar to the previous one, but the output is sent to standard error.
│ │ │ │ │ - "&syslog"
│ │ │ │ │ + â&syslogâ
│ │ │ │ │ Logging_to_syslog.
│ │ │ │ │ Comments in a configuration file must be on a line of their own, and start
│ │ │ │ │ -with--. Empty lines are ignored. The rest of the lines represent
│ │ │ │ │ +withâ. Empty lines are ignored. The rest of the lines represent
│ │ │ │ │ configurations, as in:
│ │ │ │ │ - * If a line contains the single character"+", it activates
│ │ │ │ │ + * If a line contains the single characterâ+â, it activates
│ │ │ │ │ alltrace_handleby default. This means the rest of the configuration file
│ │ │ │ │ should disable those handles that are not needed. The default is that all
│ │ │ │ │ handles are disabled by default, and the configuration file should
│ │ │ │ │ activate the ones it needs. The Ada source code can change the default
│ │ │ │ │ status of each handles, as well
│ │ │ │ │ - * If the line starts with the character">", followed by a stream name (as
│ │ │ │ │ - defined above), this becomes the default stream. All handles will be
│ │ │ │ │ + * If the line starts with the characterâ>â, followed by a stream name
│ │ │ │ │ + (as defined above), this becomes the default stream. All handles will be
│ │ │ │ │ displayed on that stream, unless otherwise specified. If the stream does
│ │ │ │ │ not exist, it defaults to standard output.
│ │ │ │ │ * Otherwise, the first token on the line is the name of a handle. If that
│ │ │ │ │ is the only element on the line, the handle is activated, and will be
│ │ │ │ │ displayed on the default stream.
│ │ │ │ │ - Otherwise, the next element on the line should be a"="sign, followed by
│ │ │ │ │ - either"yes"or"no", depending on whether the handle should resp. be
│ │ │ │ │ - enabled or disabled.
│ │ │ │ │ - Finally, the rest of the line can optionally contain the">"character
│ │ │ │ │ + Otherwise, the next element on the line should be aâ=âsign, followed
│ │ │ │ │ + by eitherâyesâorânoâ, depending on whether the handle should
│ │ │ │ │ + resp. be enabled or disabled.
│ │ │ │ │ + Finally, the rest of the line can optionally contain theâ>âcharacter
│ │ │ │ │ followed by the name of the stream to which the handle should be
│ │ │ │ │ directed.
│ │ │ │ │ There is are two special cases for the names on this line: they can start
│ │ │ │ │ - with either"*."or".*"to indicate the settings apply to a whole set of
│ │ │ │ │ - handles. See the example below.
│ │ │ │ │ + with eitherâ*.âorâ.*âto indicate the settings apply to a whole
│ │ │ │ │ + set of handles. See the example below.
│ │ │ │ │ Here is a short example of a configuration file. It activates all handles by
│ │ │ │ │ default, and defines four handles: two of them are directed to the default
│ │ │ │ │ stream (standard error), the third one to a file on the disk, and the last one
│ │ │ │ │ to the system logger syslog (if your system supports it, otherwise to the
│ │ │ │ │ default stream, ie standard error):
│ │ │ │ │ +
│ │ │ │ │ >&2
│ │ │ │ │ @@ -226,15 +226,15 @@
│ │ │ │ │ Trace (Me, A & B & C & D & E);
│ │ │ │ │ end if;
│ │ │ │ │ ***** 4.3. Log decorators¶ *****
│ │ │ │ │ Speaking of color, a number of decorators are defined byGNATCOLL.Traces. Their
│ │ │ │ │ goal is not to be used for outputting information, but to configure what extra
│ │ │ │ │ information should be output with all log messages. They are activated through
│ │ │ │ │ the same configuration file as the traces, with the same syntax (i.e
│ │ │ │ │ -either"=yes"or"=no").
│ │ │ │ │ +eitherâ=yesâorâ=noâ).
│ │ │ │ │ Here is an exhaustive list:
│ │ │ │ │ DEBUG.ABSOLUTE_TIME
│ │ │ │ │ If this decorator is activated in the configuration file, the absolute
│ │ │ │ │ time when Trace is called is automatically added to the output, when the
│ │ │ │ │ streams supports it (in particular, this has no effect for syslog, which
│ │ │ │ │ already does this on its own).
│ │ │ │ │ DEBUG.MICRO_TIME
│ │ │ │ │ @@ -247,21 +247,21 @@
│ │ │ │ │ If this decorator is activated, then the stack trace is also displayed.
│ │ │ │ │ It can be converted to a symbolic stack trace through the use of the
│ │ │ │ │ external applicationaddr2line, but that would be too costly to do this
│ │ │ │ │ automatically for each message.
│ │ │ │ │ DEBUG.LOCATION
│ │ │ │ │ If this decorator is activated, the location of the call to Trace is
│ │ │ │ │ automatically displayed. This is a file:line:column information. This
│ │ │ │ │ - works even when the executable wasn't compiled with debug information
│ │ │ │ │ + works even when the executable wasnât compiled with debug information
│ │ │ │ │ DEBUG.ENCLOSING_ENTITY
│ │ │ │ │ Activate this decorator to automatically display the name of the
│ │ │ │ │ subprogram that contains the call toTrace.
│ │ │ │ │ DEBUG.COLORS
│ │ │ │ │ If this decorator is activated, the messages will use colors for the
│ │ │ │ │ - various fields, if the stream supports it (syslog doesn't).
│ │ │ │ │ + various fields, if the stream supports it (syslog doesnât).
│ │ │ │ │ DEBUG.COUNT
│ │ │ │ │ This decorator displays two additional numbers on each line: the first is
│ │ │ │ │ the number of times this handle was used so far in the application, the
│ │ │ │ │ second is the total number of traces emitted so far. These numbers can
│ │ │ │ │ for instance be used to set conditional breakpoints on a specific trace
│ │ │ │ │ (break ongnat.traces.logorgnat.traces.traceand check the value
│ │ │ │ │ ofHandle.Count. It can also be used to refer to a specific line in some
│ │ │ │ │ @@ -283,15 +283,15 @@
│ │ │ │ │ output on a single line:
│ │ │ │ │ [MODULE] 6/247 User Message (2007-07-03 13:12:53.46)
│ │ │ │ │ (elapsed: 2ms)(loc: gnatcoll-traces.adb:224)
│ │ │ │ │ (entity:GNATCOLL.Traces.Log)
│ │ │ │ │ (callstack: 40FD9902 082FCFDD 082FE8DF )
│ │ │ │ │ Depending on your application, there are lots of other possible decorators that
│ │ │ │ │ could be useful (for instance the current thread, or the name of the executable
│ │ │ │ │ -when you have several of them,...). SinceGNATCOLL.Tracescannot provide all
│ │ │ │ │ +when you have several of them,â¦). SinceGNATCOLL.Tracescannot provide all
│ │ │ │ │ possible decorators, it provides support, through tagged types, so that you can
│ │ │ │ │ create your own decorators.
│ │ │ │ │ This needs you to override theTrace_Handle_Recordtagged type. Since this type
│ │ │ │ │ is created through calls toGNATCOLL.Traces.Create. This is done by providing an
│ │ │ │ │ additionalFactoryparameter toCreate; this is a function that allocates and
│ │ │ │ │ returns the new handle.
│ │ │ │ │ Then you can override either (or both) of the primitive
│ │ │ │ │ @@ -326,23 +326,23 @@
│ │ │ │ │ even a CORBA ORB) to communicate with another application which is charge of
│ │ │ │ │ monitoring your application.
│ │ │ │ │ You do not need the code below if you simply want to have a new stream in your
│ │ │ │ │ application (for instance using one for logging Info messages, one for Error
│ │ │ │ │ messages, and so on). In this case, the functionCreateis all you need.
│ │ │ │ │ GNATCOLL.Tracesprovides the typeTrace_Stream_Record, which can be overridden to
│ │ │ │ │ redirect the traces to your own streams.
│ │ │ │ │ -Let's assume for now that you have defined a new type of stream
│ │ │ │ │ -(called"mystream"). To keep the example simple, we will assume this stream also
│ │ │ │ │ -redirects to a file. For flexibility, however, you want to let the user
│ │ │ │ │ +Letâs assume for now that you have defined a new type of stream
│ │ │ │ │ +(calledâmystreamâ). To keep the example simple, we will assume this stream
│ │ │ │ │ +also redirects to a file. For flexibility, however, you want to let the user
│ │ │ │ │ configure the file name from the traces configuration file. Here is an example
│ │ │ │ │ of a configuration file that sets the default stream to a file called foo, and
│ │ │ │ │ redirects a specific handle to another file called bar. Note how the same
│ │ │ │ │ syntax that was used for standard output and standard error is also reused (ie
│ │ │ │ │ -the stream name starts with the"&"symbol, to avoid confusion with standard file
│ │ │ │ │ -names):
│ │ │ │ │ +the stream name starts with theâ&âsymbol, to avoid confusion with standard
│ │ │ │ │ +file names):
│ │ │ │ │ >&mystream:foo
│ │ │ │ │ MODULE=yes >&mystream:bar
│ │ │ │ │ You need of course to do a bit of coding in Ada to create the stream. This is
│ │ │ │ │ done by creating a new child ofTrace_Stream_Record, and override the primitive
│ │ │ │ │ operationPut.
│ │ │ │ │ The whole output message is given as a single parameter toPut:
│ │ │ │ │ type My_Stream is new Trace_Stream_Record with record
│ │ │ │ │ @@ -355,21 +355,21 @@
│ │ │ │ │ S : Msg_Strings.Unconstrained_String_Access;
│ │ │ │ │ L : Natural;
│ │ │ │ │ begin
│ │ │ │ │ Str.Get_String (S, L);
│ │ │ │ │ Put (Stream.File.all, String (S (1 .. L)));
│ │ │ │ │ end Put;
│ │ │ │ │ The above code did not open the file itself, as you might have noticed, nor did
│ │ │ │ │ -it register the name"mystream"so that it can be used in the configuration file.
│ │ │ │ │ -All this is done by creating a factory, ie a function in charge of creating the
│ │ │ │ │ -new stream.
│ │ │ │ │ +it register the nameâmystreamâso that it can be used in the configuration
│ │ │ │ │ +file. All this is done by creating a factory, ie a function in charge of
│ │ │ │ │ +creating the new stream.
│ │ │ │ │ A factory is also a tagged object (so that you can store custom information in
│ │ │ │ │ it), with a single primitive operation,New_Stream, in charge of creating and
│ │ │ │ │ initializing a new stream. This operation receives in parameter the argument
│ │ │ │ │ -specified by the user in the configuration file (after the":"character, if
│ │ │ │ │ +specified by the user in the configuration file (after theâ:âcharacter, if
│ │ │ │ │ any), and must return a newly allocated stream. This function is also never
│ │ │ │ │ called twice with the same argument, sinceGNATCOLL.Tracesautomatically reuses
│ │ │ │ │ an existing stream when one with the same name and arguments already exists:
│ │ │ │ │ type My_Stream_Factory is new Stream_Factory with null record;
│ │ │ │ │
│ │ │ │ │ overriding function New_Stream
│ │ │ │ │ (Self : My_Stream_Factory; Args : String) return Trace_Stream
│ │ │ │ │ @@ -382,30 +382,30 @@
│ │ │ │ │ end Factory;
│ │ │ │ │
│ │ │ │ │ Fact : access My_Stream_Factory := new My_Stream_Factory;
│ │ │ │ │ Register_Stream_Factory ("mystream", Fact);
│ │ │ │ │ ***** 4.5. Logging to syslog¶ *****
│ │ │ │ │ Among the predefined streams, GNATColl gives access to the system loggersyslog.
│ │ │ │ │ This is a standard utility on all Unix systems, but is not available on other
│ │ │ │ │ -systems. When you compile GNATColl, you should specify the switch--enable-
│ │ │ │ │ -syslogto configure to activate the support. If either this switch wasn't
│ │ │ │ │ +systems. When you compile GNATColl, you should specify the switchâenable-
│ │ │ │ │ +syslogto configure to activate the support. If either this switch wasnât
│ │ │ │ │ specified, or configure could not find the relevant header files anyway, then
│ │ │ │ │ support forsyslogwill not be available. In this case, the
│ │ │ │ │ packageGNATCOLL.Traces.Syslogis still available, but contains a single function
│ │ │ │ │ that does nothing. If your configuration files redirect some trace handles
│ │ │ │ │ -to"syslog", they will instead be redirect to the default stream or to standard
│ │ │ │ │ -output.
│ │ │ │ │ +toâsyslogâ, they will instead be redirect to the default stream or to
│ │ │ │ │ +standard output.
│ │ │ │ │ Activating support for syslog requires the following call in your application:
│ │ │ │ │ GNATCOLL.Traces.Syslog.Register_Syslog_Stream;
│ │ │ │ │ This procedure is always available, whether your system supports or not syslog,
│ │ │ │ │ -and will simply do nothing if it doesn't support syslog. This means that you do
│ │ │ │ │ -not need to have conditional code in your application to handle that, and you
│ │ │ │ │ -can let GNATColl take care of this.
│ │ │ │ │ +and will simply do nothing if it doesnât support syslog. This means that you
│ │ │ │ │ +do not need to have conditional code in your application to handle that, and
│ │ │ │ │ +you can let GNATColl take care of this.
│ │ │ │ │ After the above call, trace handles can be redirected to a stream
│ │ │ │ │ -named"syslog".
│ │ │ │ │ +namedâsyslogâ.
│ │ │ │ │ The packageGNATCOLL.Traces.Syslogalso contains a low-level interface to syslog,
│ │ │ │ │ which, although fully functional, you should probably not use, since that would
│ │ │ │ │ make your code system-dependent.
│ │ │ │ │ Syslog itself dispatches its output based on two criteria: thefacility, which
│ │ │ │ │ indicates what application emitted the message, and where it should be filed,
│ │ │ │ │ and thelevelwhich indicates the urgency level of the message. Both of these
│ │ │ │ │ criteria can be specified in theGNATCOLL.Tracesconfiguration file, as follows:
│ │ │ ├── ./usr/share/doc/libgnatcoll-doc/html/tribooleans.html
│ │ │ │ @@ -43,21 +43,21 @@
│ │ │ │
│ │ │ │ 15. Tribooleans: Three state logic¶
│ │ │ │ Through the package GNATCOLL.Tribooleans, GNATColl provides
│ │ │ │ a type that extends the classical Boolean type with an
│ │ │ │ Indeterminate value.
│ │ │ │ There are various cases where such a type is useful. One example we have
│ │ │ │ is when a user is doing a search (on a database or any set of data), and
│ │ │ │ -can specify some optional boolean criteria ("must the contact be french?").
│ │ │ │ -He can choose to only see french people ("True"), to see no french people
│ │ │ │ -at all ("False"), or to get all contacts ("Indeterminate"). With a classical
│ │ │ │ +can specify some optional boolean criteria (“must the contact be french?”).
│ │ │ │ +He can choose to only see french people (“True”), to see no french people
│ │ │ │ +at all (“False”), or to get all contacts (“Indeterminate”). With a classical
│ │ │ │ boolean, there is no way to cover all these cases.
│ │ │ │ Of course, there are more advanced use cases for such a type. To support
│ │ │ │ these cases, the Tribooleans package overrides the usual logical
│ │ │ │ -operations "and", "or", "xor", "not" and
│ │ │ │ +operations “and”, “or”, “xor”, “not” and
│ │ │ │ provides an Equal function.
│ │ │ │ See the specs of the package to see the truth tables associated with those
│ │ │ │ operators.
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │ ├── html2text {}
│ │ │ │ │ @@ -13,21 +13,21 @@
│ │ │ │ │ * GNATColl_0.0_documentation »
│ │ │ │ │ * 15. Tribooleans: Three state logic
│ │ │ │ │ ****** 15. Tribooleans: Three state logic¶ ******
│ │ │ │ │ Through the packageGNATCOLL.Tribooleans, GNATColl provides a type that extends
│ │ │ │ │ the classicalBooleantype with anIndeterminatevalue.
│ │ │ │ │ There are various cases where such a type is useful. One example we have is
│ │ │ │ │ when a user is doing a search (on a database or any set of data), and can
│ │ │ │ │ -specify some optional boolean criteria ("must the contact be french?"). He can
│ │ │ │ │ -choose to only see french people ("True"), to see no french people at all
│ │ │ │ │ -("False"), or to get all contacts ("Indeterminate"). With a classical boolean,
│ │ │ │ │ -there is no way to cover all these cases.
│ │ │ │ │ +specify some optional boolean criteria (âmust the contact be french?â). He
│ │ │ │ │ +can choose to only see french people (âTrueâ), to see no french people at
│ │ │ │ │ +all (âFalseâ), or to get all contacts (âIndeterminateâ). With a
│ │ │ │ │ +classical boolean, there is no way to cover all these cases.
│ │ │ │ │ Of course, there are more advanced use cases for such a type. To support these
│ │ │ │ │ cases, theTribooleanspackage overrides the usual logical
│ │ │ │ │ -operations"and","or","xor","not"and provides anEqualfunction.
│ │ │ │ │ +operationsâandâ,âorâ,âxorâ,ânotâand provides anEqualfunction.
│ │ │ │ │ See the specs of the package to see the truth tables associated with those
│ │ │ │ │ operators.
│ │ │ │ │ [Logo]
│ │ │ │ │ *** Previous topic ***
│ │ │ │ │ 14._VFS:_Manipulating_Files
│ │ │ │ │ *** Next topic ***
│ │ │ │ │ 16._Geometry:_primitive_geometric_operations
│ │ │ ├── ./usr/share/doc/libgnatcoll-doc/html/vfs.html
│ │ │ │ @@ -67,35 +67,35 @@
│ │ │ │ course, might be an expansive computation). To make this easier,
│ │ │ │ GNATColl provides a type that encapsulates the notion of a file,
│ │ │ │ and removes the need for the application to indicate whether it needs a
│ │ │ │ full name, a base name, or any other part of the file name.
│ │ │ │
│ │ │ │ 14.1. Filesystems abstraction¶
│ │ │ │ There exists lots of different filesystems on all machines. These include
│ │ │ │ -such things as FAT, VFAT, NTFS, ext2, VMS,.... However, all these can
│ │ │ │ +such things as FAT, VFAT, NTFS, ext2, VMS,…. However, all these can
│ │ │ │ be grouped into three families of filesystems:
│ │ │ │
│ │ │ │ windows-based filesystems
│ │ │ │ On such filesystems, the full name of a file is split into three parts: the
│ │ │ │ -name of the drive (c:, d:,...), the directories which are separated by
│ │ │ │ +name of the drive (c:, d:,…), the directories which are separated by
│ │ │ │ a backslash, and the base name. Such filesystems are sometimes inaccurately
│ │ │ │ said to be case insensitive: by that, one means that the same file can be
│ │ │ │ accessed through various casing. However, a user is generally expecting a
│ │ │ │ specific casing when a file name is displayed, and the application should
│ │ │ │ strive to preserve that casing (as opposed to, for instance, systematically
│ │ │ │ convert the file name to lower cases).
│ │ │ │ A special case of a windows-based filesystems is that emulated by the
│ │ │ │ cygwin development environment. In this case, the filesystem is seen as if
│ │ │ │ it was unix-based (see below), with one special quirk to indicate the drive
│ │ │ │ -letter (the file name starts with "/cygwin/c/").
│ │ │ │ +letter (the file name starts with “/cygwin/c/”).
│ │ │ │
│ │ │ │ unix-based filesystems
│ │ │ │ On such filesystems, directories are separated by forward slashed. File
│ │ │ │ -names are case sensitive, that is a directory can contain both "foo" and
│ │ │ │ -"Foo", which is not possible on windows-based filesystems.
│ │ │ │ +names are case sensitive, that is a directory can contain both “foo” and
│ │ │ │ +“Foo”, which is not possible on windows-based filesystems.
│ │ │ │
│ │ │ │ vms filesystem
│ │ │ │ This filesystem represents path differently than the other two, using
│ │ │ │ brackets to indicate parent directories
│ │ │ │
│ │ │ │
│ │ │ │ A given machine can actually have several file systems in parallel, when
│ │ │ │ @@ -109,15 +109,15 @@
│ │ │ │ a set of tagged types in the GNATCOLL.Filesystem package and its
│ │ │ │ children. Such a type has primitive operations to manipulate the names of
│ │ │ │ files (retrieving the base name from a full name for instance), to check
│ │ │ │ various attributes of the file (is this a directory, a symbolic link, is the
│ │ │ │ file readable or writable), or to
│ │ │ │ manipulate the file itself (copying, deleting, reading and writing).
│ │ │ │ It provides similar operations for directories (creating or deleting paths,
│ │ │ │ -reading the list of files in a directory,...).
│ │ │ │ +reading the list of files in a directory,…).
│ │ │ │ It also provides information on the system itself (the list of available drives
│ │ │ │ on a windows machine for instance).
│ │ │ │ The root type Filesystem_Record is abstract, and is specialized in
│ │ │ │ various child types. A convenient factory is provided to return the filesystem
│ │ │ │ appropriate for the local machine (Get_Local_Filesystem), but you
│ │ │ │ might chose to create your own factory in your application if you have
│ │ │ │ specialized needs (Remote filesystems).
│ │ │ │ @@ -148,24 +148,24 @@
│ │ │ │
│ │ │ │ 14.2. Remote filesystems¶
│ │ │ │ Once the abstract for filesystems exists, it is tempting to use it to
│ │ │ │ access files on remote machines. There are of course lots of differences
│ │ │ │ with filesystems on the local machine: their names are manipulated
│ │ │ │ similarly (although you need to somehow indicate on which host they are
│ │ │ │ to be found), but any operation of the file itself needs to be done on the
│ │ │ │ -remote host itself, as it can't be done through calls to the system's
│ │ │ │ +remote host itself, as it can’t be done through calls to the system’s
│ │ │ │ standard C library.
│ │ │ │ Note that when we speak of disks on a remote machine, we indicate disks
│ │ │ │ that are not accessible locally, for instance through NFS mounts or samba.
│ │ │ │ In such cases, the files are accessed transparently as if they were local,
│ │ │ │ and all this is taken care of by the system itself, no special layer is
│ │ │ │ needed at the application level.
│ │ │ │ GNATColl provides an extensive framework for manipulating such
│ │ │ │ remote files. It knows what commands need to be run on the remote host to
│ │ │ │ -perform the operations ("cp" or "copy", "stat" or "dir /a-d",...) and
│ │ │ │ +perform the operations (“cp” or “copy”, “stat” or “dir /a-d”,…) and
│ │ │ │ will happily perform these operations when you try to manipulate such
│ │ │ │ files.
│ │ │ │ There are however two operations that your own application needs to take
│ │ │ │ care of to take full advantage of remote files.
│ │ │ │
│ │ │ │ 14.2.1. Filesystem factory¶
│ │ │ │ GNATColl cannot know in advance what filesystem is running on the
│ │ │ │ @@ -219,15 +219,15 @@
│ │ │ │ different machines.
│ │ │ │ GNATColl does not try to second guess your intention here. It
│ │ │ │ performs all its remote operations through a tagged type defined in
│ │ │ │ GNATCOLL.Filesystem.Transport. This type is abstract, and must be
│ │ │ │ overridden in your application. For instance, GPS has a full support for
│ │ │ │ choosing which protocol to use on which host, what kind of filesystem is
│ │ │ │ running on that host, to recognize password queries from the transport
│ │ │ │ -protocol,.... All these can be encapsulated in the transport
│ │ │ │ +protocol,…. All these can be encapsulated in the transport
│ │ │ │ protocol.
│ │ │ │ Once you have created one or more children of
│ │ │ │ Filesystem_Transport_Record, you associate them with your
│ │ │ │ instance of the filesystem through a call to the Setup primitive
│ │ │ │ operation of the filesystem. See the factory example above.
│ │ │ │
│ │ │ │
│ │ │ │ ├── html2text {}
│ │ │ │ │ @@ -36,33 +36,33 @@
│ │ │ │ │ the API, and certainly fills the code with lots of conversion from full name to
│ │ │ │ │ base name, and sometimes reverse (which, of course, might be an expansive
│ │ │ │ │ computation). To make this easier, GNATColl provides a type that encapsulates
│ │ │ │ │ the notion of a file, and removes the need for the application to indicate
│ │ │ │ │ whether it needs a full name, a base name, or any other part of the file name.
│ │ │ │ │ ***** 14.1. Filesystems abstraction¶ *****
│ │ │ │ │ There exists lots of different filesystems on all machines. These include such
│ │ │ │ │ -things as FAT, VFAT, NTFS, ext2, VMS,.... However, all these can be grouped
│ │ │ │ │ +things as FAT, VFAT, NTFS, ext2, VMS,â¦. However, all these can be grouped
│ │ │ │ │ into three families of filesystems:
│ │ │ │ │ * windows-based filesystems
│ │ │ │ │ On such filesystems, the full name of a file is split into three parts:
│ │ │ │ │ - the name of the drive (c:, d:,...), the directories which are separated
│ │ │ │ │ + the name of the drive (c:, d:,â¦), the directories which are separated
│ │ │ │ │ by a backslash, and the base name. Such filesystems are sometimes
│ │ │ │ │ inaccurately said to be case insensitive: by that, one means that the
│ │ │ │ │ same file can be accessed through various casing. However, a user is
│ │ │ │ │ generally expecting a specific casing when a file name is displayed, and
│ │ │ │ │ the application should strive to preserve that casing (as opposed to, for
│ │ │ │ │ instance, systematically convert the file name to lower cases).
│ │ │ │ │ A special case of a windows-based filesystems is that emulated by the
│ │ │ │ │ cygwin development environment. In this case, the filesystem is seen as
│ │ │ │ │ if it was unix-based (see below), with one special quirk to indicate the
│ │ │ │ │ - drive letter (the file name starts with "/cygwin/c/").
│ │ │ │ │ + drive letter (the file name starts with â/cygwin/c/â).
│ │ │ │ │ * unix-based filesystems
│ │ │ │ │ On such filesystems, directories are separated by forward slashed. File
│ │ │ │ │ - names are case sensitive, that is a directory can contain both "foo" and
│ │ │ │ │ - "Foo", which is not possible on windows-based filesystems.
│ │ │ │ │ + names are case sensitive, that is a directory can contain both âfooâ
│ │ │ │ │ + and âFooâ, which is not possible on windows-based filesystems.
│ │ │ │ │ * vms filesystem
│ │ │ │ │ This filesystem represents path differently than the other two, using
│ │ │ │ │ brackets to indicate parent directories
│ │ │ │ │ A given machine can actually have several file systems in parallel, when a
│ │ │ │ │ remote disk is mounted through NFS or samba for instance. There is generally no
│ │ │ │ │ easy way to guess that information automatically, and it generally does not
│ │ │ │ │ matter since the system will convert from the native file system to that of the
│ │ │ │ │ @@ -72,15 +72,15 @@
│ │ │ │ │ GNATColl abstracts the differences between these filesystems through a set of
│ │ │ │ │ tagged types in theGNATCOLL.Filesystempackage and its children. Such a type has
│ │ │ │ │ primitive operations to manipulate the names of files (retrieving the base name
│ │ │ │ │ from a full name for instance), to check various attributes of the file (is
│ │ │ │ │ this a directory, a symbolic link, is the file readable or writable), or to
│ │ │ │ │ manipulate the file itself (copying, deleting, reading and writing). It
│ │ │ │ │ provides similar operations for directories (creating or deleting paths,
│ │ │ │ │ -reading the list of files in a directory,...).
│ │ │ │ │ +reading the list of files in a directory,â¦).
│ │ │ │ │ It also provides information on the system itself (the list of available drives
│ │ │ │ │ on a windows machine for instance).
│ │ │ │ │ The root typeFilesystem_Recordis abstract, and is specialized in various child
│ │ │ │ │ types. A convenient factory is provided to return the filesystem appropriate
│ │ │ │ │ for the local machine (Get_Local_Filesystem), but you might chose to create
│ │ │ │ │ your own factory in your application if you have specialized needs (Remote
│ │ │ │ │ filesystems).
│ │ │ │ │ @@ -106,24 +106,24 @@
│ │ │ │ │ subprogramsLocale_To_DisplayandSet_Locale_To_Display_Encoder
│ │ │ │ │ ***** 14.2. Remote filesystems¶ *****
│ │ │ │ │ Once the abstract for filesystems exists, it is tempting to use it to access
│ │ │ │ │ files on remote machines. There are of course lots of differences with
│ │ │ │ │ filesystems on the local machine: their names are manipulated similarly
│ │ │ │ │ (although you need to somehow indicate on which host they are to be found), but
│ │ │ │ │ any operation of the file itself needs to be done on the remote host itself, as
│ │ │ │ │ -it can't be done through calls to the system's standard C library.
│ │ │ │ │ +it canât be done through calls to the systemâs standard C library.
│ │ │ │ │ Note that when we speak of disks on a remote machine, we indicate disks that
│ │ │ │ │ are not accessible locally, for instance through NFS mounts or samba. In such
│ │ │ │ │ cases, the files are accessed transparently as if they were local, and all this
│ │ │ │ │ is taken care of by the system itself, no special layer is needed at the
│ │ │ │ │ application level.
│ │ │ │ │ GNATColl provides an extensive framework for manipulating such remote files. It
│ │ │ │ │ knows what commands need to be run on the remote host to perform the operations
│ │ │ │ │ -("cp" or "copy", "stat" or "dir /a-d",...) and will happily perform these
│ │ │ │ │ -operations when you try to manipulate such files.
│ │ │ │ │ +(âcpâ or âcopyâ, âstatâ or âdir /a-dâ,â¦) and will happily
│ │ │ │ │ +perform these operations when you try to manipulate such files.
│ │ │ │ │ There are however two operations that your own application needs to take care
│ │ │ │ │ of to take full advantage of remote files.
│ │ │ │ │ **** 14.2.1. Filesystem factory¶ ****
│ │ │ │ │ GNATColl cannot know in advance what filesystem is running on the remote host,
│ │ │ │ │ so it does not try to guess it. As a result, your application should have a
│ │ │ │ │ factory that creates the proper instance of aFilesystem_Recorddepending on the
│ │ │ │ │ host. Something like:
│ │ │ │ │ @@ -168,15 +168,15 @@
│ │ │ │ │ (and will likely be asked to the user). Furthermore, you might not want to use
│ │ │ │ │ the same protocol to connect to different machines.
│ │ │ │ │ GNATColl does not try to second guess your intention here. It performs all its
│ │ │ │ │ remote operations through a tagged type defined
│ │ │ │ │ inGNATCOLL.Filesystem.Transport. This type is abstract, and must be overridden
│ │ │ │ │ in your application. For instance, GPS has a full support for choosing which
│ │ │ │ │ protocol to use on which host, what kind of filesystem is running on that host,
│ │ │ │ │ -to recognize password queries from the transport protocol,.... All these can be
│ │ │ │ │ +to recognize password queries from the transport protocol,â¦. All these can be
│ │ │ │ │ encapsulated in the transport protocol.
│ │ │ │ │ Once you have created one or more children ofFilesystem_Transport_Record, you
│ │ │ │ │ associate them with your instance of the filesystem through a call to
│ │ │ │ │ theSetupprimitive operation of the filesystem. See the factory example above.
│ │ │ │ │ ***** 14.3. Virtual files¶ *****
│ │ │ │ │ As we have seen, the filesystem type abstracts all the operations for
│ │ │ │ │ manipulating files and their names. There is however another aspect when
│ │ │ ├── ./usr/share/doc/libgnatcoll-doc/text/boyer_moore.txt
│ │ │ │ @@ -12,15 +12,15 @@
│ │ │ │ efficient depending on the pattern.
│ │ │ │
│ │ │ │ It deals with string searching, and does not handle regular
│ │ │ │ expressions for instance.
│ │ │ │
│ │ │ │ This algorithm needs to preprocess its key (the searched string), but
│ │ │ │ does not need to perform any specific analysis of the string to be
│ │ │ │ -searched. Its execution time can be sub-linear: it doesn't need to
│ │ │ │ +searched. Its execution time can be sub-linear: it doesn’t need to
│ │ │ │ actually check every character of the string to be searched, and will
│ │ │ │ skip over some of them. The worst case for this algorithm has been
│ │ │ │ proved to need approximately 3 * N comparisons, hence the algorithm
│ │ │ │ has a complexity of O(n).
│ │ │ │
│ │ │ │ The longer the key, the faster the algorithm in general, since that
│ │ │ │ provides more context as to how many characters can be skipped when a
│ │ │ │ @@ -29,18 +29,18 @@
│ │ │ │ We will not go into the details of the algorithm, although a general
│ │ │ │ description follows: when the pattern is being preprocessed, Boyer-
│ │ │ │ Moore computes how many characters can be skipped if an incorrect
│ │ │ │ match is found at that point, depending on which character was read.
│ │ │ │ In addition, this algorithm tries to match the key starting from its
│ │ │ │ end, which in general provides a greater number of characters to skip.
│ │ │ │
│ │ │ │ -For instance, if you are looking for "ABC" in the string "ABDEFG" at
│ │ │ │ -the first position, the algorithm will compare "C" and "D". Since "D"
│ │ │ │ -does not appear in the key "ABC", it knows that it can immediately
│ │ │ │ -skip 3 characters and start the search after "D".
│ │ │ │ +For instance, if you are looking for “ABC” in the string “ABDEFG” at
│ │ │ │ +the first position, the algorithm will compare “C” and “D”. Since “D”
│ │ │ │ +does not appear in the key “ABC”, it knows that it can immediately
│ │ │ │ +skip 3 characters and start the search after “D”.
│ │ │ │
│ │ │ │ Using this package is extremely easy, and it has only a limited API:
│ │ │ │
│ │ │ │ declare
│ │ │ │ Str : constant String := "ABDEABCFGABC";
│ │ │ │ Key : Pattern;
│ │ │ │ Index : Integer;
│ │ │ │ ├── encoding
│ │ │ │ │ @@ -1 +1 @@
│ │ │ │ │ -us-ascii
│ │ │ │ │ +utf-8
│ │ │ ├── ./usr/share/doc/libgnatcoll-doc/text/building.txt
│ │ │ │ @@ -45,15 +45,15 @@
│ │ │ │
│ │ │ │ *SOURCE_DIR*
│ │ │ │ For out-of-tree build
│ │ │ │
│ │ │ │ *ENABLE_SHARED*
│ │ │ │ Controls whether shared and static-pic library variants should be
│ │ │ │ built: yes (default) or no. If you only intend to use static
│ │ │ │ - libraries, specify 'no'.
│ │ │ │ + libraries, specify ‘no’.
│ │ │ │
│ │ │ │ Module-specific:
│ │ │ │
│ │ │ │ *GNATCOLL_MMAP*
│ │ │ │ Whether MMAP is supported: yes (default) or no; this has no effect
│ │ │ │ on Windows where embedded MMAP implementation is always provided.
│ │ │ │
│ │ │ │ @@ -87,13 +87,13 @@
│ │ │ │ build it first. This command will install all library variants that
│ │ │ │ were built.
│ │ │ │
│ │ │ │ Your application can now use the GNATColl code through a project file,
│ │ │ │ by adding a "with" clause to "gnatcoll.gpr".
│ │ │ │
│ │ │ │ If you wish to install in a different location than was specified at
│ │ │ │ -configure time, you can override the "prefix" variable from the
│ │ │ │ +configure time, you can override the “prefix” variable from the
│ │ │ │ command line, for instance:
│ │ │ │
│ │ │ │ make prefix=/alternate/directory install
│ │ │ │
│ │ │ │ This does not require any recompilation.
│ │ │ │ ├── encoding
│ │ │ │ │ @@ -1 +1 @@
│ │ │ │ │ -us-ascii
│ │ │ │ │ +utf-8
│ │ │ ├── ./usr/share/doc/libgnatcoll-doc/text/config.txt.gz
│ │ │ │ ├── config.txt
│ │ │ │ │ @@ -11,30 +11,30 @@
│ │ │ │ │ could chose to use an XML file (but these are in general hard to edit
│ │ │ │ │ manually), a binary file, or any other format. One format that is
│ │ │ │ │ found very often is the one used by a lot of Windows applications (the
│ │ │ │ │ ".ini" file format).
│ │ │ │ │
│ │ │ │ │ *GNATCOLL.Config* is independent from the actual format you are using,
│ │ │ │ │ and you can add your own parsers compatible with the *GNATCOLL.Config*
│ │ │ │ │ -API. Out of the box, support is provided for ".ini" files, so let's
│ │ │ │ │ +API. Out of the box, support is provided for ".ini" files, so let’s
│ │ │ │ │ detail this very simply format:
│ │ │ │ │
│ │ │ │ │ # A single-line comment
│ │ │ │ │ [Section1]
│ │ │ │ │ key1 = value
│ │ │ │ │ key2=value2
│ │ │ │ │
│ │ │ │ │ [Section2]
│ │ │ │ │ key1 = value3
│ │ │ │ │
│ │ │ │ │ -Comments are (by default) started with *'#'* signs, but you can
│ │ │ │ │ +Comments are (by default) started with *‘#’* signs, but you can
│ │ │ │ │ configure that and use any prefix you want. The *(key, value)* pairs
│ │ │ │ │ are then organized into optional sections (if you do not start a
│ │ │ │ │ section before the first key, that key will be considered as part of
│ │ │ │ │ -the *""* section). A section then extends until the start of the next
│ │ │ │ │ +the *“”* section). A section then extends until the start of the next
│ │ │ │ │ section.
│ │ │ │ │
│ │ │ │ │ The values associated with the various keys can be strings, integers
│ │ │ │ │ or booleans. Spaces on the left and right of the values and keys are
│ │ │ │ │ trimmed, and therefore irrelevant.
│ │ │ │ │
│ │ │ │ │ Support is providing for interpreting the values as file or directory
│ │ │ │ │ @@ -84,20 +84,20 @@
│ │ │ │ │ Put_Line (Config.Get ("section.key")); -- Ada05 dotted notation
│ │ │ │ │
│ │ │ │ │ Again, the values are by default read as strings, but you can
│ │ │ │ │ interpret them as integers, booleans or files.
│ │ │ │ │
│ │ │ │ │ A third layer is provided in *GNATCOLL.Config*. This solves the issue
│ │ │ │ │ of possible typos in code: in the above example, we could have made a
│ │ │ │ │ -typo when writting *"section.key"*. That would only be detected at run
│ │ │ │ │ +typo when writting *“section.key”*. That would only be detected at run
│ │ │ │ │ time. Another issue is that we might decide to rename the key in the
│ │ │ │ │ configuration file. We would then have to go through all the
│ │ │ │ │ application code to find all the places where this key is references
│ │ │ │ │ -(and that can't be based on cross-references generated by the
│ │ │ │ │ -compiler, since that's inside a string).
│ │ │ │ │ +(and that can’t be based on cross-references generated by the
│ │ │ │ │ +compiler, since that’s inside a string).
│ │ │ │ │
│ │ │ │ │ To solve this issue, it is possible to declare a set of constants that
│ │ │ │ │ represent the keys, and then use these to access the values, solving
│ │ │ │ │ the two problems above:
│ │ │ │ │
│ │ │ │ │ Section_Key1 : constant Config_Key := Create ("Key1", "Section");
│ │ │ │ │ Section_Key2 : constant Config_Key := Create ("Key2", "Section");
│ │ │ │ │ ├── encoding
│ │ │ │ │ │ @@ -1 +1 @@
│ │ │ │ │ │ -us-ascii
│ │ │ │ │ │ +utf-8
│ │ │ ├── ./usr/share/doc/libgnatcoll-doc/text/email.txt.gz
│ │ │ │ ├── email.txt
│ │ │ │ │ @@ -151,8 +151,8 @@
│ │ │ │ │ 11.4. Creating messages
│ │ │ │ │ =======================
│ │ │ │ │
│ │ │ │ │ The subprograms in *GNATCOLL.Email* can also be used to create a
│ │ │ │ │ message from scratch. Alternatively, if you have already parsed a
│ │ │ │ │ message, you can alter it, or easily generate a reply to it (using the
│ │ │ │ │ *Reply_To* subprogram. The latter will preset some headers, so that
│ │ │ │ │ -message threading is preserved in the user's mailers.
│ │ │ │ │ +message threading is preserved in the user’s mailers.
│ │ │ │ │ ├── encoding
│ │ │ │ │ │ @@ -1 +1 @@
│ │ │ │ │ │ -us-ascii
│ │ │ │ │ │ +utf-8
│ │ │ ├── ./usr/share/doc/libgnatcoll-doc/text/filling.txt
│ │ │ │ @@ -1,12 +1,12 @@
│ │ │ │ 9. **Paragraph filling**: formatting text
│ │ │ │ *****************************************
│ │ │ │
│ │ │ │ The package *GNATCOLL.Paragraph_Filling* provides several algorithms
│ │ │ │ -for filling paragraphs---formatting them to take up the minimal number
│ │ │ │ +for filling paragraphs—formatting them to take up the minimal number
│ │ │ │ of lines and to look better. *Knuth_Fill* is based on an algorithm
│ │ │ │ invented by Donald Knuth, and used in TeX. *Pretty_Fill* uses a
│ │ │ │ different algorithm, which was judged by some to produce more
│ │ │ │ aesthetically pleasing output.
│ │ │ │
│ │ │ │ More detailed documentation may be found in the comments in the
│ │ │ │ package spec.
│ │ │ │ ├── encoding
│ │ │ │ │ @@ -1 +1 @@
│ │ │ │ │ -us-ascii
│ │ │ │ │ +utf-8
│ │ │ ├── ./usr/share/doc/libgnatcoll-doc/text/geometry.txt
│ │ │ │ @@ -1,14 +1,14 @@
│ │ │ │ 16. **Geometry**: primitive geometric operations
│ │ │ │ ************************************************
│ │ │ │
│ │ │ │ GNATColl provides the package *GNATCOLL.Geometry*. This package
│ │ │ │ includes a number of primitive operations on geometric figures like
│ │ │ │ points, segments, lines, circles, rectangles and polygons. In
│ │ │ │ -particular, you can compute their intersections, the distances,...
│ │ │ │ +particular, you can compute their intersections, the distances,…
│ │ │ │
│ │ │ │ This package is generic, so that you can specify the type of
│ │ │ │ coordinates you wish to handle:
│ │ │ │
│ │ │ │ declare
│ │ │ │ package Float_Geometry is new GNATCOLL.Geometry (Float);
│ │ │ │ use Float_Geometry;
│ │ │ │ ├── encoding
│ │ │ │ │ @@ -1 +1 @@
│ │ │ │ │ -us-ascii
│ │ │ │ │ +utf-8
│ │ │ ├── ./usr/share/doc/libgnatcoll-doc/text/json.txt
│ │ │ │ @@ -1,13 +1,13 @@
│ │ │ │ 21. **JSON**: handling JSON data
│ │ │ │ ********************************
│ │ │ │
│ │ │ │ JSON is a format often used on the web to communicate between a server
│ │ │ │ and a browser, or between servers. It plays a similar role to XML, but
│ │ │ │ -it has a much lighter syntax. On the other hand, it doesn't provide
│ │ │ │ +it has a much lighter syntax. On the other hand, it doesn’t provide
│ │ │ │ advanced features like validation, which XML provides.
│ │ │ │
│ │ │ │ The "GNATCOLL.JSON" package provides an Ada API to decode JSON data
│ │ │ │ from strings and to encode that data back to strings. It also allows
│ │ │ │ one to create and modify JSON data.
│ │ │ │
│ │ │ │
│ │ │ │ @@ -79,17 +79,17 @@
│ │ │ │ My_Obj.Set_Field ("name", "theName");
│ │ │ │
│ │ │ │ -- Now serialize it. The call below will display:
│ │ │ │ -- {"field1": 1, "name": "thename"}
│ │ │ │ Put_Line (My_Obj.Write);
│ │ │ │ end JSON_Test;
│ │ │ │
│ │ │ │ -The above uses the Ada 2005 "dot notation" to call primitive
│ │ │ │ +The above uses the Ada 2005 “dot notation” to call primitive
│ │ │ │ operations (".Set_Field", ".Write"), but naturally the more
│ │ │ │ -traditional "prefix notation" is also available:
│ │ │ │ +traditional “prefix notation” is also available:
│ │ │ │
│ │ │ │ Set_Field (My_Obj, "field1", Create (1));
│ │ │ │
│ │ │ │ It is also possible to create JSON arrays. These are not tagged types,
│ │ │ │ so the prefix notation has to be used. Here is a further example that
│ │ │ │ sets another field in the object we had before ("My_Obj"):
│ │ │ │ ├── encoding
│ │ │ │ │ @@ -1 +1 @@
│ │ │ │ │ -us-ascii
│ │ │ │ │ +utf-8
│ │ │ ├── ./usr/share/doc/libgnatcoll-doc/text/mmap.txt.gz
│ │ │ │ ├── mmap.txt
│ │ │ │ │ @@ -31,32 +31,32 @@
│ │ │ │ │
│ │ │ │ │ When your application does not need to read the whole contents of the
│ │ │ │ │ file, the speed up can be several orders of magnitude faster than
│ │ │ │ │ *read()*. Even when you need to read the whole contents, using
│ │ │ │ │ *mmap()* is still two or three times faster, which is especially
│ │ │ │ │ interesting on big files.
│ │ │ │ │
│ │ │ │ │ -GNATColl's *GNATCOLL.Mmap* package provides a high-level abstraction
│ │ │ │ │ +GNATColl’s *GNATCOLL.Mmap* package provides a high-level abstraction
│ │ │ │ │ on top of the *mmap* system call. As for most other packages in
│ │ │ │ │ GNATColl, it also nicely handles the case where your system does not
│ │ │ │ │ actually support *mmap*, and will in that case fallback on using
│ │ │ │ │ *read* and *write* transparently. In such a case, your application
│ │ │ │ │ will perform a little slower, but you do not have to modify your code
│ │ │ │ │ to adapt it to the new system.
│ │ │ │ │
│ │ │ │ │ Due to the low-level C API that is needed underneath, the various
│ │ │ │ │ subprograms in this package do not directly manipulate Ada strings
│ │ │ │ │ with valid bounds. Instead, a new type *Str_Access* was defined. It
│ │ │ │ │ does not contain the bounds of the string, and therefore you cannot
│ │ │ │ │ -use the usual *'First* and *'Last* attributes on that string. But
│ │ │ │ │ +use the usual *‘First* and *‘Last* attributes on that string. But
│ │ │ │ │ there are other subprograms that provide those values.
│ │ │ │ │
│ │ │ │ │ Here is how to read a whole file at once. This is what your code will
│ │ │ │ │ use in most cases, unless you expect to read files bigger than
│ │ │ │ │ -*Integer'Last* bytes long. In such cases you need to read chunks of
│ │ │ │ │ +*Integer’Last* bytes long. In such cases you need to read chunks of
│ │ │ │ │ the file separately. The *mmap* system call is such that its
│ │ │ │ │ performance does not depend on the size of the file your are mapping.
│ │ │ │ │ Of course, this could be a problem if *GNATCOLL.Mmap* falls back on
│ │ │ │ │ calling *read*, since in that case it needs to allocate as much memory
│ │ │ │ │ as your file. Therefore in some cases you will also want to only read
│ │ │ │ │ chunks of the file at once:
│ │ │ │ │ ├── encoding
│ │ │ │ │ │ @@ -1 +1 @@
│ │ │ │ │ │ -us-ascii
│ │ │ │ │ │ +utf-8
│ │ │ ├── ./usr/share/doc/libgnatcoll-doc/text/refcount.txt.gz
│ │ │ │ ├── refcount.txt
│ │ │ │ │ @@ -88,15 +88,15 @@
│ │ │ │ │
│ │ │ │ │ type My_Type is new Weak_Refcounted with...;
│ │ │ │ │
│ │ │ │ │ package Pointers is new Weakref_Pointers (My_Type);
│ │ │ │ │
│ │ │ │ │ The above code can be used instead of the code in the first example,
│ │ │ │ │ and provides the same capability (smart pointers, reference counted
│ │ │ │ │ -types,...). However, the type *My_Type* is slightly bigger, but can be
│ │ │ │ │ +types,…). However, the type *My_Type* is slightly bigger, but can be
│ │ │ │ │ used to create weak references:
│ │ │ │ │
│ │ │ │ │ WR : Weak_Ref;
│ │ │ │ │
│ │ │ │ │ declare
│ │ │ │ │ R : Ref;
│ │ │ │ │ Tmp : My_Type := ...;
│ │ │ │ │ ├── encoding
│ │ │ │ │ │ @@ -1 +1 @@
│ │ │ │ │ │ -us-ascii
│ │ │ │ │ │ +utf-8
│ │ │ ├── ./usr/share/doc/libgnatcoll-doc/text/scripting.txt.gz
│ │ │ │ ├── scripting.txt
│ │ │ │ │ @@ -1,22 +1,22 @@
│ │ │ │ │ 3. **Scripts**: Embedding script languages
│ │ │ │ │ ******************************************
│ │ │ │ │
│ │ │ │ │ In a lot of contexts, you want to give the possibility to users to
│ │ │ │ │ extend your application. This can be done in several ways: define an
│ │ │ │ │ Ada API from which they can build dynamically loadable modules,
│ │ │ │ │ provide the whole source code to your application and let users
│ │ │ │ │ -recompile it, interface with a simpler scripting languages,...
│ │ │ │ │ +recompile it, interface with a simpler scripting languages,…
│ │ │ │ │
│ │ │ │ │ Dynamically loadable modules can be loaded on demand, as their name
│ │ │ │ │ indicate. However, they generally require a relatively complex
│ │ │ │ │ environment to build, and are somewhat less portable. But when your
│ │ │ │ │ users are familiar with Ada, they provide a programming environment in
│ │ │ │ │ which they are comfortable. As usual, changing the module requires
│ │ │ │ │ -recompilation, re-installation,...
│ │ │ │ │ +recompilation, re-installation,…
│ │ │ │ │
│ │ │ │ │ Providing the source code to your application is generally even more
│ │ │ │ │ complex for users. This requires an even more complex setup, your
│ │ │ │ │ application is generally too big for users to dive into, and
│ │ │ │ │ modifications done by one users are hard to provide to other users, or
│ │ │ │ │ will be lost when you distribute a new version of your application.
│ │ │ │ │
│ │ │ │ │ @@ -32,115 +32,115 @@
│ │ │ │ │ used extensively in the GPS programming environment for its python
│ │ │ │ │ interface.
│ │ │ │ │
│ │ │ │ │ [image: TIP:][image] Each of the scripting language is optional
│ │ │ │ │
│ │ │ │ │ This module can be compiled with any of these languages as an optional
│ │ │ │ │ dependency (except for the shell language, which is always built-in,
│ │ │ │ │ -but is extremely minimal, and doesn't have to be loaded at run time
│ │ │ │ │ +but is extremely minimal, and doesn’t have to be loaded at run time
│ │ │ │ │ anyway). If the necessary libraries are found on the system, GNATColl
│ │ │ │ │ will be build with support for the corresponding language, but your
│ │ │ │ │ application can chose at run time whether or not to activate the
│ │ │ │ │ support for a specific language.
│ │ │ │ │
│ │ │ │ │ [image: TIP:][image] Use a scripting language to provide an automatic
│ │ │ │ │ testing framework for your application.
│ │ │ │ │
│ │ │ │ │ The GPS environment uses python command for its *automatic test
│ │ │ │ │ suite*, including graphical tests such as pressing on a button,
│ │ │ │ │ -selecting a menu,...
│ │ │ │ │ +selecting a menu,…
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │ 3.1. Supported languages
│ │ │ │ │ ========================
│ │ │ │ │
│ │ │ │ │ The module provides built-in support for several scripting languages,
│ │ │ │ │ -and other languages can "easily" be added. Your application does not
│ │ │ │ │ +and other languages can “easily” be added. Your application does not
│ │ │ │ │ change when new languages are added, since the interface to export
│ │ │ │ │ subprograms and classes to the scripting languages is language-
│ │ │ │ │ neutral, and will automatically export to all known scripting
│ │ │ │ │ languages.
│ │ │ │ │
│ │ │ │ │ The Core component provides support for the following language:
│ │ │ │ │
│ │ │ │ │ *Shell*
│ │ │ │ │ - This is a very simple-minded scripting language, which doesn't
│ │ │ │ │ + This is a very simple-minded scripting language, which doesn’t
│ │ │ │ │ provide flow-control instructions (The Shell language).
│ │ │ │ │
│ │ │ │ │ Optional components add support for other languages, e.g. Python.
│ │ │ │ │ -Please refer to the corresponding component's documentation.
│ │ │ │ │ +Please refer to the corresponding component’s documentation.
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │ 3.1.1. The Shell language
│ │ │ │ │ -------------------------
│ │ │ │ │
│ │ │ │ │ The shell language was initially developed in the context of the GPS
│ │ │ │ │ programming environment, as a way to embed scripting commands in XML
│ │ │ │ │ configuration files.
│ │ │ │ │
│ │ │ │ │ In this language, you can execute any of the commands exported by the
│ │ │ │ │ application, passing any number of arguments they need. Arguments to
│ │ │ │ │ function calls can, but need not, be quoted. Quoting is only mandatory
│ │ │ │ │ -when they contain spaces, newline characters, or double-quotes ('"').
│ │ │ │ │ +when they contain spaces, newline characters, or double-quotes (‘”’).
│ │ │ │ │ To quote an argument, surround it by double-quotes, and precede each
│ │ │ │ │ double-quote it contains by a backslash character. Another way of
│ │ │ │ │ quoting is similar to what python provides, which is to triple-quote
│ │ │ │ │ -the argument, i.e. surround it by '"""' on each side. In such a case,
│ │ │ │ │ +the argument, i.e. surround it by ‘”””’ on each side. In such a case,
│ │ │ │ │ any special character (in particular other double-quotes or
│ │ │ │ │ backslashes) lose their special meaning and are just taken as part of
│ │ │ │ │ the argument. This is in particular useful when you do not know in
│ │ │ │ │ advance the contents of the argument you are quoting:
│ │ │ │ │
│ │ │ │ │ Shell> function_name arg1 "arg 2" """arg 3"""
│ │ │ │ │
│ │ │ │ │ Commands are executed as if on a stack machine: the result of a
│ │ │ │ │ command is pushed on the stack, and later commands can reference it
│ │ │ │ │ using *%* following by a number. By default, the number of previous
│ │ │ │ │ results that are kept is set to 9, and this can only be changed by
│ │ │ │ │ modifying the source code for GNATColl. The return values are also
│ │ │ │ │ modified by commands executed internally by your application, and that
│ │ │ │ │ -might have no visible output from the user's point of view. As a
│ │ │ │ │ -result, you should never assume you know what *%1*,... contain unless
│ │ │ │ │ +might have no visible output from the user’s point of view. As a
│ │ │ │ │ +result, you should never assume you know what *%1*,… contain unless
│ │ │ │ │ you just executed a command in the same script:
│ │ │ │ │
│ │ │ │ │ Shell> function_name arg1
│ │ │ │ │ Shell> function2_name %1
│ │ │ │ │
│ │ │ │ │ In particular, the *%1* syntax is used when emulating object-oriented
│ │ │ │ │ programming in the shell. A method of a class is just a particular
│ │ │ │ │ -function that contains a '.' in its name, and whose first implicit
│ │ │ │ │ +function that contains a ‘.’ in its name, and whose first implicit
│ │ │ │ │ argument is the instance on which it applies. This instance is
│ │ │ │ │ generally the result of calling a constructor in an earlier call.
│ │ │ │ │ -Assuming, for instance, that we have exported a class "Base" to the
│ │ │ │ │ +Assuming, for instance, that we have exported a class “Base” to the
│ │ │ │ │ shell from our Ada core, we could use the following code:
│ │ │ │ │
│ │ │ │ │ Shell> Base arg1 arg2
│ │ │ │ │ Shell> Base.method %1 arg1 arg2
│ │ │ │ │
│ │ │ │ │ to create an instance and call one of its methods. Of course, the
│ │ │ │ │ shell is not the best language for object-oriented programming, and
│ │ │ │ │ better languages should be used instead.
│ │ │ │ │
│ │ │ │ │ When an instance has associated properties (which you can export from
│ │ │ │ │ Ada using *Set_Property*), you access the properties by prefixing its
│ │ │ │ │ -name with "@":
│ │ │ │ │ +name with “@”:
│ │ │ │ │
│ │ │ │ │ Shell> Base arg1 arg2 # Build new instance
│ │ │ │ │ Shell> @id %1 # Access its "id" field
│ │ │ │ │ Shell> @id %1 5 # Set its "id" field
│ │ │ │ │
│ │ │ │ │ Some commands are automatically added to the shell when this scripting
│ │ │ │ │ language is added to the application. These are
│ │ │ │ │
│ │ │ │ │ *Function load (file)*
│ │ │ │ │ Loads the content of *file* from the disk, and execute each of its
│ │ │ │ │ lines as a Shell command. This can for instance be used to load
│ │ │ │ │ scripts when your application is loaded
│ │ │ │ │
│ │ │ │ │ -*Function echo (arg...)*
│ │ │ │ │ +*Function echo (arg…)*
│ │ │ │ │ This function takes any number of argument, and prints them in the
│ │ │ │ │ console associated with the language. By default, when in an
│ │ │ │ │ interactive console, the output of commands is automatically
│ │ │ │ │ printed to the console. But when you execute a script through
│ │ │ │ │ *load* above, you need to explicitly call *echo* to make some
│ │ │ │ │ output visible.
│ │ │ │ │
│ │ │ │ │ @@ -165,15 +165,15 @@
│ │ │ │ │ of this document.
│ │ │ │ │
│ │ │ │ │ This class provides an interface to consoles. A console is an
│ │ │ │ │ input/output area in your application (whether it is a text area in
│ │ │ │ │ a graphical application, or simply standard text I/O in text mode).
│ │ │ │ │ In particular, the python standard output streams *sys.stdin*,
│ │ │ │ │ *sys.stdout* and *sys.stderr* are redirected to an instance of that
│ │ │ │ │ - class. If you want to see python's error messages or usual output
│ │ │ │ │ + class. If you want to see python’s error messages or usual output
│ │ │ │ │ in your application, you must register that class, and define a
│ │ │ │ │ default console for your scripting language through calls to
│ │ │ │ │ *GNATCOLL.Scripts.Set_Default_Console*.
│ │ │ │ │
│ │ │ │ │ You can later add new methods to this class, which would be
│ │ │ │ │ specific to your application. Or you can derive this class into a
│ │ │ │ │ new class to achieve a similar goal.
│ │ │ │ │ @@ -224,24 +224,24 @@
│ │ │ │ │ code remains exactly the same, and new scripting languages can be
│ │ │ │ │ added in later releases of GNATColl without requiring a change in your
│ │ │ │ │ application. This flexibility is central to the design of GNATColl.
│ │ │ │ │
│ │ │ │ │ In exchange for that flexibility, however, there are language-specific
│ │ │ │ │ features that cannot be performed through the GNATColl API. At
│ │ │ │ │ present, this includes for instance exporting functions that return
│ │ │ │ │ -hash tables. But GNATColl doesn't try to export the greatest set of
│ │ │ │ │ +hash tables. But GNATColl doesn’t try to export the greatest set of
│ │ │ │ │ features common to all languages. On the contrary, it tries to fully
│ │ │ │ │ support all the languages, and provide reasonable fallback for
│ │ │ │ │ languages that do not support that feature. For instance, named
│ │ │ │ │ parameters (which are a part of the python language) are fully
│ │ │ │ │ -supported, although the shell language doesn't support them. But
│ │ │ │ │ -that's an implementation detail transparent to your own application.
│ │ │ │ │ +supported, although the shell language doesn’t support them. But
│ │ │ │ │ +that’s an implementation detail transparent to your own application.
│ │ │ │ │
│ │ │ │ │ Likewise, your application might decide to always load the python
│ │ │ │ │ -scripting language. If GNATColl wasn't compiled with python support,
│ │ │ │ │ +scripting language. If GNATColl wasn’t compiled with python support,
│ │ │ │ │ the corresponding Ada function still exists (and thus your code still
│ │ │ │ │ compiles), although of course it does nothing. But since the rest of
│ │ │ │ │ the code is independent of python, this is totally transparent for
│ │ │ │ │ your application.
│ │ │ │ │
│ │ │ │ │ [image: TIP:][image] GNATColl comes with some examples, which you can
│ │ │ │ │ use as a reference when building your own application. See the
│ │ │ │ │ @@ -255,15 +255,15 @@
│ │ │ │ │ * You *can* create an **interactive console** for the various
│ │ │ │ │ languages, so that users can perform experiments interactively. This
│ │ │ │ │ is optional, and you could decide to keep the scripting language has
│ │ │ │ │ a hidden implementation detail (or just for automatic testing
│ │ │ │ │ purposes for instance)
│ │ │ │ │
│ │ │ │ │ * You *can* **export** some classes and methods. This is optional, but
│ │ │ │ │ - it doesn't really make sense to just embed a scripting language and
│ │ │ │ │ + it doesn’t really make sense to just embed a scripting language and
│ │ │ │ │ export nothing to it. In such a case, you might as well spawn a
│ │ │ │ │ separate executable.
│ │ │ │ │
│ │ │ │ │ * You *can* load **start up scripts** or plug-ins that users have
│ │ │ │ │ written to extend your application.
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │ @@ -502,15 +502,15 @@
│ │ │ │ │ (*Lookup_Scripting_Language* function), and to make it possible to
│ │ │ │ │ register each exported function only once (it then takes care of
│ │ │ │ │ exporting it to each scripting language).
│ │ │ │ │
│ │ │ │ │ *Class Scripting_Language*
│ │ │ │ │ Instances of this type represent a specific language. It provides
│ │ │ │ │ various operations to export subprograms, execute commands, create
│ │ │ │ │ - the other types described below,... There should exists a single
│ │ │ │ │ + the other types described below,… There should exists a single
│ │ │ │ │ instance of this class per supported language.
│ │ │ │ │
│ │ │ │ │ This class interacts with the script interpreter (for instance
│ │ │ │ │ python), and all code executed in python goes through this type,
│ │ │ │ │ which then executes your Ada callbacks to perform the actual
│ │ │ │ │ operation.
│ │ │ │ │
│ │ │ │ │ @@ -520,27 +520,27 @@
│ │ │ │ │
│ │ │ │ │ *Class Callback_Data*
│ │ │ │ │ This type is an opaque tagged type that provides a language-
│ │ │ │ │ independent interface to the scripting language. It gives for
│ │ │ │ │ instance access to the various parameters passed to your subprogram
│ │ │ │ │ (*Nth_Arg* functions), allows you to set the return value
│ │ │ │ │ (*Set_Return_Value* procedure), or raise exceptions
│ │ │ │ │ - (*Set_Error_Msg* procedure),...
│ │ │ │ │ + (*Set_Error_Msg* procedure),…
│ │ │ │ │
│ │ │ │ │ *Record Class_Type*
│ │ │ │ │ This type is not tagged, and cannot be extended. It basically
│ │ │ │ │ represents a class in any of the scripting languages, and is used
│ │ │ │ │ to create new instances of that class from Ada.
│ │ │ │ │
│ │ │ │ │ *Class Class_Instance*
│ │ │ │ │ A class instance represents a specific instance of a class. In
│ │ │ │ │ general, such an instance is strongly bound to an instance of an
│ │ │ │ │ Ada type. For instance, if you have a *Foo* type in your
│ │ │ │ │ application that you wish to export, you would create a
│ │ │ │ │ - *Class_Type* called "Foo", and then the user can create as many
│ │ │ │ │ + *Class_Type* called “Foo”, and then the user can create as many
│ │ │ │ │ instances as he wants of that class, each of which is associated
│ │ │ │ │ with different values of *Foo* in Ada.
│ │ │ │ │
│ │ │ │ │ Another more specific example is the predefined *Console* class. As
│ │ │ │ │ we have seen before, this is a *Virtual_Console* in Ada. You could
│ │ │ │ │ for instance have two graphical windows in your application, each
│ │ │ │ │ of which is a *Virtual_Console*. In the scripting language, this is
│ │ │ │ │ @@ -673,20 +673,20 @@
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │ 3.2.3.2.2. Support for named parameters
│ │ │ │ │ """""""""""""""""""""""""""""""""""""""
│ │ │ │ │
│ │ │ │ │ Some languages (especially python) support named parameters, ie
│ │ │ │ │ parameters can be specified in any order on the command line, as long
│ │ │ │ │ -as they are properly identified (very similar to Ada's own
│ │ │ │ │ +as they are properly identified (very similar to Ada’s own
│ │ │ │ │ capabilities). In the example above, the call to *Name_Parameters* is
│ │ │ │ │ really optional, but adds this support for your own functions as well.
│ │ │ │ │ You just have to specify the name of the parameters, and GNATColl will
│ │ │ │ │ then ensure that when you call *Nth_Arg* the parameter number 1 is
│ │ │ │ │ -really "arg1". For scripting languages that do not support named
│ │ │ │ │ +really “arg1”. For scripting languages that do not support named
│ │ │ │ │ parameters, this has no effect.
│ │ │ │ │
│ │ │ │ │ Your code can then perform as complex a code as needed, and finally
│ │ │ │ │ return a value (or not) to the scripting language, through a call to
│ │ │ │ │ *Set_Return_Value*.
│ │ │ │ │
│ │ │ │ │ After the above code has been executed, your users can go to the
│ │ │ │ │ @@ -725,27 +725,27 @@
│ │ │ │ │
│ │ │ │ │ You can then register the class methods in the same way that you
│ │ │ │ │ registered functions. An additional parameter *Class* exists for
│ │ │ │ │ *Register_Command*. A method is really just a standard function that
│ │ │ │ │ has an implicit first parameter which is a *Class_Instance*. This
│ │ │ │ │ extra parameter should not be taken into account in *Min_Args* and
│ │ │ │ │ *Max_Args*. You can also declare the method as a static method, ie one
│ │ │ │ │ -that doesn't take this extra implicit parameter, and basically just
│ │ │ │ │ +that doesn’t take this extra implicit parameter, and basically just
│ │ │ │ │ uses the class as a namespace.
│ │ │ │ │
│ │ │ │ │ Some special method names are available. In particular,
│ │ │ │ │ *Constructor_Method* should be used for the constructor of a class. It
│ │ │ │ │ is a method that receives, as its first argument, a class instance
│ │ │ │ │ that has just been created. It should associate that instance with the
│ │ │ │ │ Ada object it represents.
│ │ │ │ │
│ │ │ │ │ Here is a simple example that exports a class. Each instance of this
│ │ │ │ │ class is associated with a string, passed in parameter to the
│ │ │ │ │ constructor. The class has a single method *print*, which prints its
│ │ │ │ │ -string parameter prefixed by the instance's string. To start with,
│ │ │ │ │ +string parameter prefixed by the instance’s string. To start with,
│ │ │ │ │ here is a python example on what we want to achieve:
│ │ │ │ │
│ │ │ │ │ c1 = MyClass ("prefix1")
│ │ │ │ │ c1.print ("foo")
│ │ │ │ │ => "prefix1 foo"
│ │ │ │ │ c2 = MyClass () # Using a default prefix
│ │ │ │ │ c2.print ("foo")
│ │ │ │ │ @@ -772,39 +772,39 @@
│ │ │ │ │ (Repo, Constructor_Method, 0, 1, Handler'Access, MyClass);
│ │ │ │ │ Register_Command
│ │ │ │ │ (Repo, "print", 1, 1, Handler'Access, MyClass);
│ │ │ │ │
│ │ │ │ │ This example also demonstrates a few concepts: the constructor is
│ │ │ │ │ declared as a method that takes one optional argument. The default
│ │ │ │ │ value is in fact passed in the call to *Nth_Arg* and is set to
│ │ │ │ │ -"default". In the handler, we know there is always a first argument
│ │ │ │ │ +“default”. In the handler, we know there is always a first argument
│ │ │ │ │ which is the instance on which the method applies. The implementation
│ │ │ │ │ for the constructor stores the prefix in the instance itself, so that
│ │ │ │ │ -several instances can have different prefixes (we can't use global
│ │ │ │ │ -variables, of course, since we don't know in advance how many
│ │ │ │ │ +several instances can have different prefixes (we can’t use global
│ │ │ │ │ +variables, of course, since we don’t know in advance how many
│ │ │ │ │ instances will exist). The implementation for *print* inserts code in
│ │ │ │ │ the default console for the script (we could of course use *Put_Line*
│ │ │ │ │ or any other way to output data), and computes the string to output by
│ │ │ │ │ -concatenating the instance's prefix and the parameter to *print*.
│ │ │ │ │ +concatenating the instance’s prefix and the parameter to *print*.
│ │ │ │ │
│ │ │ │ │ Note that *Set_Data* and *Get_Data* take the class in parameter, in
│ │ │ │ │ addition to the class instance. This is needed for proper handling of
│ │ │ │ │ multiple inheritance: say we have a class *C* that extends two classes
│ │ │ │ │ *A* and *B*. The Ada code that deals with *A* associates an integer
│ │ │ │ │ with the class instance, whereas the code that deals with *B*
│ │ │ │ │ associates a string. Now, if you have an instance of *C* but call a
│ │ │ │ │ -method inherited from *A*, and if *Get_Data* didn't specify the class,
│ │ │ │ │ +method inherited from *A*, and if *Get_Data* didn’t specify the class,
│ │ │ │ │ there would be a risk that a string would be returned instead of the
│ │ │ │ │ expected integer. In fact, the proper solution here is that both *A*
│ │ │ │ │ and *B* store their preferred data at the same time in the instances,
│ │ │ │ │ but only fetch the one they actually need. Therefore instances of *C*
│ │ │ │ │ are associated with two datas.
│ │ │ │ │
│ │ │ │ │ Here is a more advanced example that shows how to export an Ada
│ │ │ │ │ -object. Let's assume we have the following Ada type that we want to
│ │ │ │ │ +object. Let’s assume we have the following Ada type that we want to
│ │ │ │ │ make available to scripts:
│ │ │ │ │
│ │ │ │ │ type MyType is record
│ │ │ │ │ Field : Integer;
│ │ │ │ │ end record;
│ │ │ │ │
│ │ │ │ │ As you can see, this is not a tagged type, but could certainly be.
│ │ │ │ │ @@ -830,18 +830,18 @@
│ │ │ │ │ Data : MyProps := MyProps (Instance_Property'
│ │ │ │ │ (Get_Data (Inst, Get_Name (MyClass))));
│ │ │ │ │ begin
│ │ │ │ │ return Data.Val;
│ │ │ │ │ end Get_Data;
│ │ │ │ │
│ │ │ │ │ Several aspects worth noting in this example. Each data is associated
│ │ │ │ │ -with a name, not a class as in the previous example. That's in fact
│ │ │ │ │ +with a name, not a class as in the previous example. That’s in fact
│ │ │ │ │ the same thing, and mostly for historical reasons. We have to create
│ │ │ │ │ our own instance of *Instance_Property_Record* to store the data, but
│ │ │ │ │ -the implementation presents no special difficulty. In fact, we don't
│ │ │ │ │ +the implementation presents no special difficulty. In fact, we don’t
│ │ │ │ │ absolutely need to create *Set_Data* and *Get_Data* and could do
│ │ │ │ │ everything inline in the method implementation, but it is cleaner this
│ │ │ │ │ way and easier to reuse.
│ │ │ │ │
│ │ │ │ │ GNATColl is fully responsible for managing the lifetime of the data
│ │ │ │ │ associated with the class instances and you can override the procedure
│ │ │ │ │ *Destroy* if you need special memory management.
│ │ │ │ │ @@ -874,15 +874,15 @@
│ │ │ │ │
│ │ │ │ │ * Static *get* methods
│ │ │ │ │
│ │ │ │ │ With each of your classes, you can export a static method generally
│ │ │ │ │ called *get* that takes in parameter a way to identify an existing
│ │ │ │ │ instance, and either return it or create a new one. It is also
│ │ │ │ │ recommended to disable the constructor, ie force it to raise an
│ │ │ │ │ - error. Let's examine the python code as it would be used:
│ │ │ │ │ + error. Let’s examine the python code as it would be used:
│ │ │ │ │
│ │ │ │ │ ed = Editor ("file.adb") # constructor
│ │ │ │ │ => Error, cannot construct instances
│ │ │ │ │ ed = Editor.get ("file.adb")
│ │ │ │ │ => Create a new instance
│ │ │ │ │ ed2 = Editor.get ("file.adb")
│ │ │ │ │ => Return existing instance
│ │ │ │ │ @@ -935,15 +935,15 @@
│ │ │ │ │ ed.do_something()
│ │ │ │ │
│ │ │ │ │ It is important to realize that in the call above, we are not
│ │ │ │ │ calling the constructor of a class, but a function. At the Ada
│ │ │ │ │ level, the function has basically the same implementation as the one
│ │ │ │ │ we gave for *get* above. But the python code looks nicer because we
│ │ │ │ │ do not have these additional *.get()* calls. The name of the class
│ │ │ │ │ - *MyClassImpl* doesn't appear anywhere in the python code, so this is
│ │ │ │ │ + *MyClassImpl* doesn’t appear anywhere in the python code, so this is
│ │ │ │ │ mostly transparent.
│ │ │ │ │
│ │ │ │ │ However, if you have more than one scripting language, in particular
│ │ │ │ │ for the shell, the code looks less nice in this case:
│ │ │ │ │
│ │ │ │ │ MyClass "file.adb"
│ │ │ │ │ =>
│ │ │ │ │ @@ -1008,11 +1008,11 @@
│ │ │ │ │ a script (python for instance) will call your Ada callback, which
│ │ │ │ │ might raise errors. Most of the time, the error should indeed be
│ │ │ │ │ reported to the user, and you can thus raise a standard exception, or
│ │ │ │ │ call *Set_Error_Msg*.
│ │ │ │ │
│ │ │ │ │ But if you wish to know which script was executing the command, it is
│ │ │ │ │ generally not doable. You can however activate a trace (Traces:
│ │ │ │ │ -Logging information) called *"PYTHON.TB"* (for "traceback"), which
│ │ │ │ │ +Logging information) called *“PYTHON.TB”* (for “traceback”), which
│ │ │ │ │ will output the name of the command that is being executed, as well as
│ │ │ │ │ the full traceback within the python scripts. This will help you
│ │ │ │ │ locate which script is raising an exception.
│ │ │ │ │ ├── encoding
│ │ │ │ │ │ @@ -1 +1 @@
│ │ │ │ │ │ -us-ascii
│ │ │ │ │ │ +utf-8
│ │ │ ├── ./usr/share/doc/libgnatcoll-doc/text/storage_pools.txt
│ │ │ │ @@ -12,16 +12,16 @@
│ │ │ │ means you have to remember not to use the standard memory allocations
│ │ │ │ like *malloc* or *new*, and instead call one of your subprograms. If
│ │ │ │ you ever decide to change the allocation strategy, or want to
│ │ │ │ experiment with several strategies, that means updating your code in
│ │ │ │ several places.
│ │ │ │
│ │ │ │ In Ada, when you declare the type of your data, you also specify
│ │ │ │ -through a *'Storage_Pool* attribute how the memory for instances of
│ │ │ │ -that type should be allocated. And that's it. You then use the usual
│ │ │ │ +through a *‘Storage_Pool* attribute how the memory for instances of
│ │ │ │ +that type should be allocated. And that’s it. You then use the usual
│ │ │ │ *new* keyword to allocate memory.
│ │ │ │
│ │ │ │ GNATColl provides a number of examples for such storage pools, with
│ │ │ │ various goals. There is also one advanced such pool in the GNAT run-
│ │ │ │ time itself, called *GNAT.Debug_Pools*, which allows you to control
│ │ │ │ memory leaks and whether all accesses do reference valid memory
│ │ │ │ location (and not memory that has already been deallocated).
│ │ │ │ ├── encoding
│ │ │ │ │ @@ -1 +1 @@
│ │ │ │ │ -us-ascii
│ │ │ │ │ +utf-8
│ │ │ ├── ./usr/share/doc/libgnatcoll-doc/text/strings.txt.gz
│ │ │ │ ├── strings.txt
│ │ │ │ │ @@ -1,20 +1,20 @@
│ │ │ │ │ 5. **Strings**: high-performance strings
│ │ │ │ │ ****************************************
│ │ │ │ │
│ │ │ │ │ The generic package "GNATCOLL.Strings_Impl" (and its default
│ │ │ │ │ instantiation in "GNATCOLL.Strings") provides a high-performance
│ │ │ │ │ strings implementation.
│ │ │ │ │
│ │ │ │ │ -It comes in addition to Ada's own *String* and *Unbounded_String*
│ │ │ │ │ +It comes in addition to Ada’s own *String* and *Unbounded_String*
│ │ │ │ │ types, although it attempts to find a middle ground in between
│ │ │ │ │ (flexibility vs performance).
│ │ │ │ │
│ │ │ │ │ GNATCOLL.Strings therefore provides strings (named *XString*, as in
│ │ │ │ │ -extended-strings) that can grow as needed (up to *Natural'Last*, like
│ │ │ │ │ +extended-strings) that can grow as needed (up to *Natural’Last*, like
│ │ │ │ │ standard strings), yet are faster than unbounded strings. They also
│ │ │ │ │ come with an extended API, which includes all primitive operations
│ │ │ │ │ from unbounded strings, in addition to some subprograms inspired from
│ │ │ │ │ GNATCOLL.Utils and the python and C++ programming languages.
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │ 5.1. Small string optimization
│ │ │ │ │ @@ -56,17 +56,17 @@
│ │ │ │ │ big string that requires allocation. In a typical application, most
│ │ │ │ │ strings are smaller than 23 bytes, so we are saving very significant
│ │ │ │ │ time here.
│ │ │ │ │
│ │ │ │ │ This representation has to work on both 32 bits systems and 64 bits
│ │ │ │ │ systems, so we have careful representation clauses to take this into
│ │ │ │ │ account. It also needs to work on both big-endian and little-endian
│ │ │ │ │ -systems. Thanks to Ada's representation clauses, this one in fact
│ │ │ │ │ +systems. Thanks to Ada’s representation clauses, this one in fact
│ │ │ │ │ relatively easy to achieve (well, okay, after trying a few different
│ │ │ │ │ -approaches to emulate what's done in C++, and that did not work
│ │ │ │ │ +approaches to emulate what’s done in C++, and that did not work
│ │ │ │ │ elegantly). In fact, emulating via bit-shift operations ended up with
│ │ │ │ │ code that was less efficient than letting the compiler do it
│ │ │ │ │ automatically because of our representation clauses.
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │ 5.2. Character types
│ │ │ │ │ ====================
│ │ │ │ │ @@ -125,47 +125,47 @@
│ │ │ │ │ particular context is different. For instance, GNATCOLL.Traces builds
│ │ │ │ │ messages to output in the log file. Such messages will typically be at
│ │ │ │ │ most 100 characters, although they can of course be much larger
│ │ │ │ │ sometimes.
│ │ │ │ │
│ │ │ │ │ We have added one more formal parameter to GNATCOLL.Strings_Impl to
│ │ │ │ │ control the maximum size of small strings. If for instance we decide
│ │ │ │ │ -that a "small" string is anywhere from 1 to 100 characters long (i.e.
│ │ │ │ │ +that a “small” string is anywhere from 1 to 100 characters long (i.e.
│ │ │ │ │ we do not want to allocate memory for those strings), it can be done
│ │ │ │ │ via this parameter.
│ │ │ │ │
│ │ │ │ │ Of course, in such cases the size of the string itself becomes much
│ │ │ │ │ larger. In this example it would be 101 bytes long, rather than the 24
│ │ │ │ │ bytes. Although we are saving on memory allocations, we are also
│ │ │ │ │ spending more time copying data when the string is passed around, so
│ │ │ │ │ -you'll need to measure the performance here.
│ │ │ │ │ +you’ll need to measure the performance here.
│ │ │ │ │
│ │ │ │ │ The maximum size for the small string is 127 bytes however, because
│ │ │ │ │ this size and the 1-bit flag need to fit in 1 bytes in the
│ │ │ │ │ representation clauses we showed above. We tried to make this more
│ │ │ │ │ configurable, but this makes things significantly more complex between
│ │ │ │ │ -little-endian and big-endian systems, and having large "small" strings
│ │ │ │ │ +little-endian and big-endian systems, and having large “small” strings
│ │ │ │ │ would not make much sense in terms of performance anyway.
│ │ │ │ │
│ │ │ │ │ Typical C++ implementations do not make this small size configurable.
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │ 5.4. Task safety
│ │ │ │ │ ================
│ │ │ │ │
│ │ │ │ │ Just like unbounded strings, the strings in this package are not
│ │ │ │ │ thread safe. This means that you cannot access the same string (read
│ │ │ │ │ or write) from two different threads without somehow protecting the
│ │ │ │ │ -access via a protected type, locks,...
│ │ │ │ │ +access via a protected type, locks,…
│ │ │ │ │
│ │ │ │ │ In practice, sharing strings would rarely be done, so if the package
│ │ │ │ │ itself was doing its own locking we would end up with very bad
│ │ │ │ │ performance in all cases, for a few cases where it might prove useful.
│ │ │ │ │
│ │ │ │ │ -As we'll discuss below, it is possible to use two different strings
│ │ │ │ │ +As we’ll discuss below, it is possible to use two different strings
│ │ │ │ │ that actually share the same internal buffer, from two different
│ │ │ │ │ threads. Since this is an implementation detail, this package takes
│ │ │ │ │ care of guaranteeing the integrity of the shared data in such a case.
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │ 5.5. Copy on write
│ │ │ │ │ ==================
│ │ │ │ │ @@ -219,15 +219,15 @@
│ │ │ │ │ start allocating memory past the size of small strings, so we will for
│ │ │ │ │ instance first allocate 24 bytes. When more memory is needed, we
│ │ │ │ │ multiply this size by 1.5, which some researchers have found to be a
│ │ │ │ │ good comprise between waste of memory and number of allocations. For
│ │ │ │ │ very large strings, we always allocate multiples of the memory page
│ │ │ │ │ size (4096 bytes), since this is what the system will make available
│ │ │ │ │ anyway. So we will basically allocate the following: 24, 36, 54, 82,
│ │ │ │ │ -122,...
│ │ │ │ │ +122,…
│ │ │ │ │
│ │ │ │ │ An additional constraint is that we only ever allocate even number of
│ │ │ │ │ bytes. This is called the capacity of the string. In the layout of the
│ │ │ │ │ big string, as shown above, we store half that capacity, which saves
│ │ │ │ │ one bit that we use for the flag.
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │ @@ -237,28 +237,28 @@
│ │ │ │ │ One other optimization performed by this package (which is not done
│ │ │ │ │ for unbounded strings or various C++ implementations) is to optimize
│ │ │ │ │ substrings when also using copy-on-write.
│ │ │ │ │
│ │ │ │ │ We simply store the index of the first character of the string within
│ │ │ │ │ the shared buffer, instead of always starting at the first.
│ │ │ │ │
│ │ │ │ │ -From the user's point of view, this is an implementation detail.
│ │ │ │ │ +From the user’s point of view, this is an implementation detail.
│ │ │ │ │ Strings are always indexed from 1, and internally we convert to an
│ │ │ │ │ actual position in the buffer. This means that if we need to
│ │ │ │ │ reallocate the buffer, for instance when the string is modified, we
│ │ │ │ │ transparently change the index of the first character, but the indexes
│ │ │ │ │ the user was using are still valid.
│ │ │ │ │
│ │ │ │ │ This results in very significant savings, as shown below in the
│ │ │ │ │ timings for Trim for instance. Also, we can do an operation like
│ │ │ │ │ splitting a string very efficiently.
│ │ │ │ │
│ │ │ │ │ -For instance, the following code doesn't allocate any memory, beside
│ │ │ │ │ +For instance, the following code doesn’t allocate any memory, beside
│ │ │ │ │ setting the initial value of the string. It parses a file containing
│ │ │ │ │ -some "key=value" lines, with optional spaces, and possibly empty
│ │ │ │ │ +some “key=value” lines, with optional spaces, and possibly empty
│ │ │ │ │ lines:
│ │ │ │ │
│ │ │ │ │ declare
│ │ │ │ │ S, Key, Value : XString;
│ │ │ │ │ L : XString_Array (1 .. 2);
│ │ │ │ │ Last : Natural;
│ │ │ │ │ begin
│ │ │ │ │ ├── encoding
│ │ │ │ │ │ @@ -1 +1 @@
│ │ │ │ │ │ -us-ascii
│ │ │ │ │ │ +utf-8
│ │ │ ├── ./usr/share/doc/libgnatcoll-doc/text/templates.txt
│ │ │ │ @@ -1,51 +1,51 @@
│ │ │ │ 10. **Templates**: generating text
│ │ │ │ **********************************
│ │ │ │
│ │ │ │ This module provides convenient subprograms for replacing specific
│ │ │ │ substrings with other values. It is typically used to replace
│ │ │ │ -substrings like "%{version}" in a longer string with the actual
│ │ │ │ +substrings like “%{version}” in a longer string with the actual
│ │ │ │ version, at run time.
│ │ │ │
│ │ │ │ This module is not the same as the templates parser provided in the
│ │ │ │ context of AWS, the Ada web server, where external files are parsed
│ │ │ │ and processed to generate other files. The latter provides advanced
│ │ │ │ -features like filters, loops,...
│ │ │ │ +features like filters, loops,…
│ │ │ │
│ │ │ │ The substrings to be replaced always start with a specific delimiter,
│ │ │ │ which is set to *%* by default, but can be overridden in your code.
│ │ │ │ The name of the substring to be replaced is then the identifier
│ │ │ │ following that delimiter, with the following rules:
│ │ │ │
│ │ │ │ * If the character following the delimiter is the delimiter itself,
│ │ │ │ then the final string will contain a single instance of that
│ │ │ │ delimiter, and no further substitution is done for that delimiter.
│ │ │ │ - An example of this is *"%%"*.
│ │ │ │ + An example of this is *“%%”*.
│ │ │ │
│ │ │ │ * If the character immediately after the delimiter is a curly brace
│ │ │ │ (*{*), then the name of the identifier is the text until the next
│ │ │ │ closing curly brace. It can then contain any character expect a
│ │ │ │ - closing curly brace. An example of this is *"%{long name}"*
│ │ │ │ + closing curly brace. An example of this is *“%{long name}”*
│ │ │ │
│ │ │ │ * If the first character after the delimiter is a digit, then the name
│ │ │ │ of the identifier is the number after the delimiter. An example of
│ │ │ │ - this is *"%12"*. As a special case, if the first non-digit character
│ │ │ │ + this is *“%12”*. As a special case, if the first non-digit character
│ │ │ │ is the symbol *-*, it is added as part of the name of the
│ │ │ │ - identifier, as in *"%1-"*. One use for this feature is to indicate
│ │ │ │ + identifier, as in *“%1-“*. One use for this feature is to indicate
│ │ │ │ you want to replace it with all the positional parameters %1%2%3%4.
│ │ │ │ For instance, if you are writing the command line to spawn an
│ │ │ │ external tool, to which the user can pass any number of parameter,
│ │ │ │ - you could specify that command line as *"tool -o %1 %2-"* to
│ │ │ │ + you could specify that command line as *“tool -o %1 %2-“* to
│ │ │ │ indicate that all parameters should be concatenated on the command
│ │ │ │ line.
│ │ │ │
│ │ │ │ * If the first character after the delimiter is a letter, the
│ │ │ │ identifier follows the same rules as for Ada identifiers, and can
│ │ │ │ contain any letter, digit, or underscore character. An example of
│ │ │ │ - this is *"%ab_12"*. For readability, it is recommended to use the
│ │ │ │ + this is *“%ab_12”*. For readability, it is recommended to use the
│ │ │ │ curly brace notation when the name is complex, but that is not
│ │ │ │ mandatory.
│ │ │ │
│ │ │ │ * Otherwise the name of the identifier is the single character
│ │ │ │ following the delimiter
│ │ │ │
│ │ │ │ For each substring matching the rules above, the *Substitute*
│ │ │ │ ├── encoding
│ │ │ │ │ @@ -1 +1 @@
│ │ │ │ │ -us-ascii
│ │ │ │ │ +utf-8
│ │ │ ├── ./usr/share/doc/libgnatcoll-doc/text/traces.txt.gz
│ │ │ │ ├── traces.txt
│ │ │ │ │ @@ -1,15 +1,15 @@
│ │ │ │ │ 4. **Traces**: Logging information
│ │ │ │ │ **********************************
│ │ │ │ │
│ │ │ │ │ Most applications need to log various kinds of information: error
│ │ │ │ │ messages, information messages or debug messages among others. These
│ │ │ │ │ logs can be displayed and stored in a number of places: standard
│ │ │ │ │ output, a file, the system logger, an application-specific database
│ │ │ │ │ -table,...
│ │ │ │ │ +table,…
│ │ │ │ │
│ │ │ │ │ The package "GNATCOLL.Traces" addresses the various needs, except for
│ │ │ │ │ the application-specific database, which of course is specific to your
│ │ │ │ │ business and needs various custom fields in any case, which cannot be
│ │ │ │ │ easily provided through a general interface.
│ │ │ │ │
│ │ │ │ │ This module is organized around two tagged types (used through access
│ │ │ │ │ @@ -21,26 +21,26 @@
│ │ │ │ │ will generally define several handles, which can be enabled or
│ │ │ │ │ disabled separately, therefore limiting the amount of logging.
│ │ │ │ │
│ │ │ │ │ *Trace_Stream*
│ │ │ │ │ Streams are the ultimate types responsible for the output of the
│ │ │ │ │ messages. One or more handles are associated with each stream. The
│ │ │ │ │ latter can be a file, the standard output, a graphical window, a
│ │ │ │ │ - socket,... New types of streams can easily be defined in your
│ │ │ │ │ + socket,… New types of streams can easily be defined in your
│ │ │ │ │ application.
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │ 4.1. Configuring traces
│ │ │ │ │ =======================
│ │ │ │ │
│ │ │ │ │ As mentioned above, an application will generally create several
│ │ │ │ │ *Trace_Handle* (typically one per module in the application). When new
│ │ │ │ │ features are added to the application, the developers will generally
│ │ │ │ │ need to add lots of traces to help investigate problems once the
│ │ │ │ │ -application is installed at a customer's site. The problem here is
│ │ │ │ │ +application is installed at a customer’s site. The problem here is
│ │ │ │ │ that each module might output a lot of information, thus confusing the
│ │ │ │ │ logs; this also does not help debugging.
│ │ │ │ │
│ │ │ │ │ The *GNATCOLL.Traces* package allows the user to configure which
│ │ │ │ │ handles should actually generate logs, and which should just be silent
│ │ │ │ │ and not generate anything. Depending on the part of the application
│ │ │ │ │ that needs to be investigated, one can therefore enable a set of
│ │ │ │ │ @@ -63,85 +63,85 @@
│ │ │ │ │ *Parse_Config_File*.
│ │ │ │ │
│ │ │ │ │ * If no file name was specified in that call, the environment variable
│ │ │ │ │ *ADA_DEBUG_FILE* might point to a configuration file.
│ │ │ │ │
│ │ │ │ │ * If the above two attempts did not find a suitable configuration
│ │ │ │ │ file, the current directory is searched for a file called
│ │ │ │ │ - *.gnatdebug*. Finally, the user's home directory will also be
│ │ │ │ │ + *.gnatdebug*. Finally, the user’s home directory will also be
│ │ │ │ │ searched for that file.
│ │ │ │ │
│ │ │ │ │ In all cases, the format of the configuration file is the same. Its
│ │ │ │ │ goal is to associate the name of a *trace_handle* with the name of a
│ │ │ │ │ *trace_stream* on which it should be displayed.
│ │ │ │ │
│ │ │ │ │ Streams are identified by a name. You can provide additional streams
│ │ │ │ │ by creating a new tagged object (Defining custom stream types). Here
│ │ │ │ │ are the various possibilities to reference a stream:
│ │ │ │ │
│ │ │ │ │ -*"name"*
│ │ │ │ │ - where name is a string made of letters, digits and slash ('/')
│ │ │ │ │ +*“name”*
│ │ │ │ │ + where name is a string made of letters, digits and slash (‘/’)
│ │ │ │ │ characters. This is the name of a file to which the traces should
│ │ │ │ │ be redirected. The previous contents of the file is discarded. If
│ │ │ │ │ the name of the file is a relative path, it is relative to the
│ │ │ │ │ location of the configuration file, not necessarily to the current
│ │ │ │ │ directory when the file is parsed. In the file name, *$$* is
│ │ │ │ │ automatically replaced by the process number. *$D* is automatically
│ │ │ │ │ replaced by the current date. *$T* is automatically replaced by the
│ │ │ │ │ current date and time. Other patterns of the form *$name*,
│ │ │ │ │ *${name}*, or *$(name)* are substituted with the value of the named
│ │ │ │ │ - environment variable, if it exists. If ">>" is used instead of ">"
│ │ │ │ │ + environment variable, if it exists. If “>>” is used instead of “>”
│ │ │ │ │ to redirect to that stream, the file is appended to, instead of
│ │ │ │ │ truncated.
│ │ │ │ │
│ │ │ │ │ -*"&1"*
│ │ │ │ │ +*“&1”*
│ │ │ │ │ This syntax is similar to the one used on Unix shells, and
│ │ │ │ │ indicates that the output should be displayed on the standard
│ │ │ │ │ output for the application. If the application is graphical, and in
│ │ │ │ │ particular on Windows platforms, it is possible that there is no
│ │ │ │ │ standard output!
│ │ │ │ │
│ │ │ │ │ -*"&2"*
│ │ │ │ │ +*“&2”*
│ │ │ │ │ Similar to the previous one, but the output is sent to standard
│ │ │ │ │ error.
│ │ │ │ │
│ │ │ │ │ -*"&syslog"*
│ │ │ │ │ +*“&syslog”*
│ │ │ │ │ Logging to syslog.
│ │ │ │ │
│ │ │ │ │ Comments in a configuration file must be on a line of their own, and
│ │ │ │ │ -start with *--*. Empty lines are ignored. The rest of the lines
│ │ │ │ │ +start with *–*. Empty lines are ignored. The rest of the lines
│ │ │ │ │ represent configurations, as in:
│ │ │ │ │
│ │ │ │ │ -* If a line contains the single character *"+"*, it activates all
│ │ │ │ │ +* If a line contains the single character *“+”*, it activates all
│ │ │ │ │ *trace_handle* by default. This means the rest of the configuration
│ │ │ │ │ file should disable those handles that are not needed. The default
│ │ │ │ │ is that all handles are disabled by default, and the configuration
│ │ │ │ │ file should activate the ones it needs. The Ada source code can
│ │ │ │ │ change the default status of each handles, as well
│ │ │ │ │
│ │ │ │ │ -* If the line starts with the character *">"*, followed by a stream
│ │ │ │ │ +* If the line starts with the character *“>”*, followed by a stream
│ │ │ │ │ name (as defined above), this becomes the default stream. All
│ │ │ │ │ handles will be displayed on that stream, unless otherwise
│ │ │ │ │ specified. If the stream does not exist, it defaults to standard
│ │ │ │ │ output.
│ │ │ │ │
│ │ │ │ │ * Otherwise, the first token on the line is the name of a handle. If
│ │ │ │ │ that is the only element on the line, the handle is activated, and
│ │ │ │ │ will be displayed on the default stream.
│ │ │ │ │
│ │ │ │ │ - Otherwise, the next element on the line should be a *"="* sign,
│ │ │ │ │ - followed by either *"yes"* or *"no"*, depending on whether the
│ │ │ │ │ + Otherwise, the next element on the line should be a *“=”* sign,
│ │ │ │ │ + followed by either *“yes”* or *“no”*, depending on whether the
│ │ │ │ │ handle should resp. be enabled or disabled.
│ │ │ │ │
│ │ │ │ │ - Finally, the rest of the line can optionally contain the *">"*
│ │ │ │ │ + Finally, the rest of the line can optionally contain the *“>”*
│ │ │ │ │ character followed by the name of the stream to which the handle
│ │ │ │ │ should be directed.
│ │ │ │ │
│ │ │ │ │ There is are two special cases for the names on this line: they can
│ │ │ │ │ - start with either *"*."* or *".*"* to indicate the settings apply to
│ │ │ │ │ + start with either *“*.”* or *“.*”* to indicate the settings apply to
│ │ │ │ │ a whole set of handles. See the example below.
│ │ │ │ │
│ │ │ │ │ Here is a short example of a configuration file. It activates all
│ │ │ │ │ handles by default, and defines four handles: two of them are directed
│ │ │ │ │ to the default stream (standard error), the third one to a file on the
│ │ │ │ │ disk, and the last one to the system logger syslog (if your system
│ │ │ │ │ supports it, otherwise to the default stream, ie standard error):
│ │ │ │ │ @@ -297,15 +297,15 @@
│ │ │ │ │ ===================
│ │ │ │ │
│ │ │ │ │ Speaking of color, a number of decorators are defined by
│ │ │ │ │ *GNATCOLL.Traces*. Their goal is not to be used for outputting
│ │ │ │ │ information, but to configure what extra information should be output
│ │ │ │ │ with all log messages. They are activated through the same
│ │ │ │ │ configuration file as the traces, with the same syntax (i.e either
│ │ │ │ │ -*"=yes"* or *"=no"*).
│ │ │ │ │ +*“=yes”* or *“=no”*).
│ │ │ │ │
│ │ │ │ │ Here is an exhaustive list:
│ │ │ │ │
│ │ │ │ │ *DEBUG.ABSOLUTE_TIME*
│ │ │ │ │ If this decorator is activated in the configuration file, the
│ │ │ │ │ absolute time when Trace is called is automatically added to the
│ │ │ │ │ output, when the streams supports it (in particular, this has no
│ │ │ │ │ @@ -324,24 +324,24 @@
│ │ │ │ │ displayed. It can be converted to a symbolic stack trace through
│ │ │ │ │ the use of the external application *addr2line*, but that would be
│ │ │ │ │ too costly to do this automatically for each message.
│ │ │ │ │
│ │ │ │ │ *DEBUG.LOCATION*
│ │ │ │ │ If this decorator is activated, the location of the call to Trace
│ │ │ │ │ is automatically displayed. This is a file:line:column information.
│ │ │ │ │ - This works even when the executable wasn't compiled with debug
│ │ │ │ │ + This works even when the executable wasn’t compiled with debug
│ │ │ │ │ information
│ │ │ │ │
│ │ │ │ │ *DEBUG.ENCLOSING_ENTITY*
│ │ │ │ │ Activate this decorator to automatically display the name of the
│ │ │ │ │ subprogram that contains the call to *Trace*.
│ │ │ │ │
│ │ │ │ │ *DEBUG.COLORS*
│ │ │ │ │ If this decorator is activated, the messages will use colors for
│ │ │ │ │ - the various fields, if the stream supports it (syslog doesn't).
│ │ │ │ │ + the various fields, if the stream supports it (syslog doesn’t).
│ │ │ │ │
│ │ │ │ │ *DEBUG.COUNT*
│ │ │ │ │ This decorator displays two additional numbers on each line: the
│ │ │ │ │ first is the number of times this handle was used so far in the
│ │ │ │ │ application, the second is the total number of traces emitted so
│ │ │ │ │ far. These numbers can for instance be used to set conditional
│ │ │ │ │ breakpoints on a specific trace (break on *gnat.traces.log* or
│ │ │ │ │ @@ -371,15 +371,15 @@
│ │ │ │ │ [MODULE] 6/247 User Message (2007-07-03 13:12:53.46)
│ │ │ │ │ (elapsed: 2ms)(loc: gnatcoll-traces.adb:224)
│ │ │ │ │ (entity:GNATCOLL.Traces.Log)
│ │ │ │ │ (callstack: 40FD9902 082FCFDD 082FE8DF )
│ │ │ │ │
│ │ │ │ │ Depending on your application, there are lots of other possible
│ │ │ │ │ decorators that could be useful (for instance the current thread, or
│ │ │ │ │ -the name of the executable when you have several of them,...). Since
│ │ │ │ │ +the name of the executable when you have several of them,…). Since
│ │ │ │ │ *GNATCOLL.Traces* cannot provide all possible decorators, it provides
│ │ │ │ │ support, through tagged types, so that you can create your own
│ │ │ │ │ decorators.
│ │ │ │ │
│ │ │ │ │ This needs you to override the *Trace_Handle_Record* tagged type.
│ │ │ │ │ Since this type is created through calls to *GNATCOLL.Traces.Create*.
│ │ │ │ │ This is done by providing an additional *Factory* parameter to
│ │ │ │ │ @@ -430,23 +430,23 @@
│ │ │ │ │ in your application (for instance using one for logging Info messages,
│ │ │ │ │ one for Error messages, and so on). In this case, the function
│ │ │ │ │ *Create* is all you need.
│ │ │ │ │
│ │ │ │ │ *GNATCOLL.Traces* provides the type *Trace_Stream_Record*, which can
│ │ │ │ │ be overridden to redirect the traces to your own streams.
│ │ │ │ │
│ │ │ │ │ -Let's assume for now that you have defined a new type of stream
│ │ │ │ │ -(called *"mystream"*). To keep the example simple, we will assume this
│ │ │ │ │ +Let’s assume for now that you have defined a new type of stream
│ │ │ │ │ +(called *“mystream”*). To keep the example simple, we will assume this
│ │ │ │ │ stream also redirects to a file. For flexibility, however, you want to
│ │ │ │ │ let the user configure the file name from the traces configuration
│ │ │ │ │ file. Here is an example of a configuration file that sets the default
│ │ │ │ │ stream to a file called "foo", and redirects a specific handle to
│ │ │ │ │ another file called "bar". Note how the same syntax that was used for
│ │ │ │ │ standard output and standard error is also reused (ie the stream name
│ │ │ │ │ -starts with the *"&"* symbol, to avoid confusion with standard file
│ │ │ │ │ +starts with the *“&”* symbol, to avoid confusion with standard file
│ │ │ │ │ names):
│ │ │ │ │
│ │ │ │ │ >&mystream:foo
│ │ │ │ │ MODULE=yes >&mystream:bar
│ │ │ │ │
│ │ │ │ │ You need of course to do a bit of coding in Ada to create the stream.
│ │ │ │ │ This is done by creating a new child of *Trace_Stream_Record*, and
│ │ │ │ │ @@ -465,23 +465,23 @@
│ │ │ │ │ L : Natural;
│ │ │ │ │ begin
│ │ │ │ │ Str.Get_String (S, L);
│ │ │ │ │ Put (Stream.File.all, String (S (1 .. L)));
│ │ │ │ │ end Put;
│ │ │ │ │
│ │ │ │ │ The above code did not open the file itself, as you might have
│ │ │ │ │ -noticed, nor did it register the name *"mystream"* so that it can be
│ │ │ │ │ +noticed, nor did it register the name *“mystream”* so that it can be
│ │ │ │ │ used in the configuration file. All this is done by creating a
│ │ │ │ │ factory, ie a function in charge of creating the new stream.
│ │ │ │ │
│ │ │ │ │ A factory is also a tagged object (so that you can store custom
│ │ │ │ │ information in it), with a single primitive operation, *New_Stream*,
│ │ │ │ │ in charge of creating and initializing a new stream. This operation
│ │ │ │ │ receives in parameter the argument specified by the user in the
│ │ │ │ │ -configuration file (after the *":"* character, if any), and must
│ │ │ │ │ +configuration file (after the *“:”* character, if any), and must
│ │ │ │ │ return a newly allocated stream. This function is also never called
│ │ │ │ │ twice with the same argument, since *GNATCOLL.Traces* automatically
│ │ │ │ │ reuses an existing stream when one with the same name and arguments
│ │ │ │ │ already exists:
│ │ │ │ │
│ │ │ │ │ type My_Stream_Factory is new Stream_Factory with null record;
│ │ │ │ │
│ │ │ │ │ @@ -501,36 +501,36 @@
│ │ │ │ │
│ │ │ │ │ 4.5. Logging to syslog
│ │ │ │ │ ======================
│ │ │ │ │
│ │ │ │ │ Among the predefined streams, GNATColl gives access to the system
│ │ │ │ │ logger *syslog*. This is a standard utility on all Unix systems, but
│ │ │ │ │ is not available on other systems. When you compile GNATColl, you
│ │ │ │ │ -should specify the switch *--enable-syslog* to configure to activate
│ │ │ │ │ -the support. If either this switch wasn't specified, or configure
│ │ │ │ │ +should specify the switch *–enable-syslog* to configure to activate
│ │ │ │ │ +the support. If either this switch wasn’t specified, or configure
│ │ │ │ │ could not find the relevant header files anyway, then support for
│ │ │ │ │ *syslog* will not be available. In this case, the package
│ │ │ │ │ *GNATCOLL.Traces.Syslog* is still available, but contains a single
│ │ │ │ │ function that does nothing. If your configuration files redirect some
│ │ │ │ │ -trace handles to *"syslog"*, they will instead be redirect to the
│ │ │ │ │ +trace handles to *“syslog”*, they will instead be redirect to the
│ │ │ │ │ default stream or to standard output.
│ │ │ │ │
│ │ │ │ │ Activating support for syslog requires the following call in your
│ │ │ │ │ application:
│ │ │ │ │
│ │ │ │ │ GNATCOLL.Traces.Syslog.Register_Syslog_Stream;
│ │ │ │ │
│ │ │ │ │ This procedure is always available, whether your system supports or
│ │ │ │ │ -not syslog, and will simply do nothing if it doesn't support syslog.
│ │ │ │ │ +not syslog, and will simply do nothing if it doesn’t support syslog.
│ │ │ │ │ This means that you do not need to have conditional code in your
│ │ │ │ │ application to handle that, and you can let GNATColl take care of
│ │ │ │ │ this.
│ │ │ │ │
│ │ │ │ │ After the above call, trace handles can be redirected to a stream
│ │ │ │ │ -named *"syslog"*.
│ │ │ │ │ +named *“syslog”*.
│ │ │ │ │
│ │ │ │ │ The package *GNATCOLL.Traces.Syslog* also contains a low-level
│ │ │ │ │ interface to syslog, which, although fully functional, you should
│ │ │ │ │ probably not use, since that would make your code system-dependent.
│ │ │ │ │
│ │ │ │ │ Syslog itself dispatches its output based on two criteria: the
│ │ │ │ │ *facility*, which indicates what application emitted the message, and
│ │ │ │ │ ├── encoding
│ │ │ │ │ │ @@ -1 +1 @@
│ │ │ │ │ │ -us-ascii
│ │ │ │ │ │ +utf-8
│ │ │ ├── ./usr/share/doc/libgnatcoll-doc/text/tribooleans.txt
│ │ │ │ @@ -3,20 +3,20 @@
│ │ │ │
│ │ │ │ Through the package *GNATCOLL.Tribooleans*, GNATColl provides a type
│ │ │ │ that extends the classical *Boolean* type with an *Indeterminate*
│ │ │ │ value.
│ │ │ │
│ │ │ │ There are various cases where such a type is useful. One example we
│ │ │ │ have is when a user is doing a search (on a database or any set of
│ │ │ │ -data), and can specify some optional boolean criteria ("must the
│ │ │ │ -contact be french?"). He can choose to only see french people
│ │ │ │ -("True"), to see no french people at all ("False"), or to get all
│ │ │ │ -contacts ("Indeterminate"). With a classical boolean, there is no way
│ │ │ │ +data), and can specify some optional boolean criteria (“must the
│ │ │ │ +contact be french?”). He can choose to only see french people
│ │ │ │ +(“True”), to see no french people at all (“False”), or to get all
│ │ │ │ +contacts (“Indeterminate”). With a classical boolean, there is no way
│ │ │ │ to cover all these cases.
│ │ │ │
│ │ │ │ Of course, there are more advanced use cases for such a type. To
│ │ │ │ support these cases, the *Tribooleans* package overrides the usual
│ │ │ │ -logical operations *"and"*, *"or"*, *"xor"*, *"not"* and provides an
│ │ │ │ +logical operations *“and”*, *“or”*, *“xor”*, *“not”* and provides an
│ │ │ │ *Equal* function.
│ │ │ │
│ │ │ │ See the specs of the package to see the truth tables associated with
│ │ │ │ those operators.
│ │ │ │ ├── encoding
│ │ │ │ │ @@ -1 +1 @@
│ │ │ │ │ -us-ascii
│ │ │ │ │ +utf-8
│ │ │ ├── ./usr/share/doc/libgnatcoll-doc/text/vfs.txt.gz
│ │ │ │ ├── vfs.txt
│ │ │ │ │ @@ -34,39 +34,39 @@
│ │ │ │ │ any other part of the file name.
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │ 14.1. Filesystems abstraction
│ │ │ │ │ =============================
│ │ │ │ │
│ │ │ │ │ There exists lots of different filesystems on all machines. These
│ │ │ │ │ -include such things as FAT, VFAT, NTFS, ext2, VMS,.... However, all
│ │ │ │ │ +include such things as FAT, VFAT, NTFS, ext2, VMS,…. However, all
│ │ │ │ │ these can be grouped into three families of filesystems:
│ │ │ │ │
│ │ │ │ │ * windows-based filesystems
│ │ │ │ │
│ │ │ │ │ On such filesystems, the full name of a file is split into three
│ │ │ │ │ - parts: the name of the drive (c:, d:,...), the directories which are
│ │ │ │ │ + parts: the name of the drive (c:, d:,…), the directories which are
│ │ │ │ │ separated by a backslash, and the base name. Such filesystems are
│ │ │ │ │ sometimes inaccurately said to be case insensitive: by that, one
│ │ │ │ │ means that the same file can be accessed through various casing.
│ │ │ │ │ However, a user is generally expecting a specific casing when a file
│ │ │ │ │ name is displayed, and the application should strive to preserve
│ │ │ │ │ that casing (as opposed to, for instance, systematically convert the
│ │ │ │ │ file name to lower cases).
│ │ │ │ │
│ │ │ │ │ A special case of a windows-based filesystems is that emulated by
│ │ │ │ │ the cygwin development environment. In this case, the filesystem is
│ │ │ │ │ seen as if it was unix-based (see below), with one special quirk to
│ │ │ │ │ - indicate the drive letter (the file name starts with "/cygwin/c/").
│ │ │ │ │ + indicate the drive letter (the file name starts with “/cygwin/c/”).
│ │ │ │ │
│ │ │ │ │ * unix-based filesystems
│ │ │ │ │
│ │ │ │ │ On such filesystems, directories are separated by forward slashed.
│ │ │ │ │ File names are case sensitive, that is a directory can contain both
│ │ │ │ │ - "foo" and "Foo", which is not possible on windows-based filesystems.
│ │ │ │ │ + “foo” and “Foo”, which is not possible on windows-based filesystems.
│ │ │ │ │
│ │ │ │ │ * vms filesystem
│ │ │ │ │
│ │ │ │ │ This filesystem represents path differently than the other two,
│ │ │ │ │ using brackets to indicate parent directories
│ │ │ │ │
│ │ │ │ │ A given machine can actually have several file systems in parallel,
│ │ │ │ │ @@ -81,15 +81,15 @@
│ │ │ │ │ set of tagged types in the *GNATCOLL.Filesystem* package and its
│ │ │ │ │ children. Such a type has primitive operations to manipulate the names
│ │ │ │ │ of files (retrieving the base name from a full name for instance), to
│ │ │ │ │ check various attributes of the file (is this a directory, a symbolic
│ │ │ │ │ link, is the file readable or writable), or to manipulate the file
│ │ │ │ │ itself (copying, deleting, reading and writing). It provides similar
│ │ │ │ │ operations for directories (creating or deleting paths, reading the
│ │ │ │ │ -list of files in a directory,...).
│ │ │ │ │ +list of files in a directory,…).
│ │ │ │ │
│ │ │ │ │ It also provides information on the system itself (the list of
│ │ │ │ │ available drives on a windows machine for instance).
│ │ │ │ │
│ │ │ │ │ The root type *Filesystem_Record* is abstract, and is specialized in
│ │ │ │ │ various child types. A convenient factory is provided to return the
│ │ │ │ │ filesystem appropriate for the local machine (*Get_Local_Filesystem*),
│ │ │ │ │ @@ -131,26 +131,26 @@
│ │ │ │ │ ========================
│ │ │ │ │
│ │ │ │ │ Once the abstract for filesystems exists, it is tempting to use it to
│ │ │ │ │ access files on remote machines. There are of course lots of
│ │ │ │ │ differences with filesystems on the local machine: their names are
│ │ │ │ │ manipulated similarly (although you need to somehow indicate on which
│ │ │ │ │ host they are to be found), but any operation of the file itself needs
│ │ │ │ │ -to be done on the remote host itself, as it can't be done through
│ │ │ │ │ -calls to the system's standard C library.
│ │ │ │ │ +to be done on the remote host itself, as it can’t be done through
│ │ │ │ │ +calls to the system’s standard C library.
│ │ │ │ │
│ │ │ │ │ Note that when we speak of disks on a remote machine, we indicate
│ │ │ │ │ disks that are not accessible locally, for instance through NFS mounts
│ │ │ │ │ or samba. In such cases, the files are accessed transparently as if
│ │ │ │ │ they were local, and all this is taken care of by the system itself,
│ │ │ │ │ no special layer is needed at the application level.
│ │ │ │ │
│ │ │ │ │ GNATColl provides an extensive framework for manipulating such remote
│ │ │ │ │ files. It knows what commands need to be run on the remote host to
│ │ │ │ │ -perform the operations ("cp" or "copy", "stat" or "dir /a-d",...) and
│ │ │ │ │ +perform the operations (“cp” or “copy”, “stat” or “dir /a-d”,…) and
│ │ │ │ │ will happily perform these operations when you try to manipulate such
│ │ │ │ │ files.
│ │ │ │ │
│ │ │ │ │ There are however two operations that your own application needs to
│ │ │ │ │ take care of to take full advantage of remote files.
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │ @@ -210,15 +210,15 @@
│ │ │ │ │
│ │ │ │ │ GNATColl does not try to second guess your intention here. It performs
│ │ │ │ │ all its remote operations through a tagged type defined in
│ │ │ │ │ *GNATCOLL.Filesystem.Transport*. This type is abstract, and must be
│ │ │ │ │ overridden in your application. For instance, GPS has a full support
│ │ │ │ │ for choosing which protocol to use on which host, what kind of
│ │ │ │ │ filesystem is running on that host, to recognize password queries from
│ │ │ │ │ -the transport protocol,.... All these can be encapsulated in the
│ │ │ │ │ +the transport protocol,…. All these can be encapsulated in the
│ │ │ │ │ transport protocol.
│ │ │ │ │
│ │ │ │ │ Once you have created one or more children of
│ │ │ │ │ *Filesystem_Transport_Record*, you associate them with your instance
│ │ │ │ │ of the filesystem through a call to the *Setup* primitive operation of
│ │ │ │ │ the filesystem. See the factory example above.
│ │ │ │ │ ├── encoding
│ │ │ │ │ │ @@ -1 +1 @@
│ │ │ │ │ │ -us-ascii
│ │ │ │ │ │ +utf-8
├── libgnatcoll19_21.0.0-4_arm64.deb
│ ├── control.tar.xz
│ │ ├── control.tar
│ │ │ ├── ./md5sums
│ │ │ │ ├── ./md5sums
│ │ │ │ │┄ Files differ
│ ├── data.tar.xz
│ │ ├── data.tar
│ │ │ ├── ./usr/lib/aarch64-linux-gnu/libgnatcoll.so.19
│ │ │ │┄ File has been modified after NT_GNU_BUILD_ID has been applied.
│ │ │ │ ├── readelf --wide --notes {}
│ │ │ │ │ @@ -1,4 +1,4 @@
│ │ │ │ │
│ │ │ │ │ Displaying notes found in: .note.gnu.build-id
│ │ │ │ │ Owner Data size Description
│ │ │ │ │ - GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring) Build ID: 741ce70cae34ead8cba4b6704c2dfe9056571d39
│ │ │ │ │ + GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring) Build ID: 317aec252cb5a2c24a2d3a59b7970742b7060f18
│ │ │ │ ├── readelf --wide --decompress --hex-dump=.gnu_debuglink {}
│ │ │ │ │┄ error from `readelf --wide --decompress --hex-dump=.gnu_debuglink {}`:
│ │ │ │ │┄ readelf: Error: no .dynamic section in the dynamic segment
│ │ │ │ │ @@ -1,7 +1,7 @@
│ │ │ │ │
│ │ │ │ │ Hex dump of section '.gnu_debuglink':
│ │ │ │ │ - 0x00000000 31636537 30636165 33346561 64386362 1ce70cae34ead8cb
│ │ │ │ │ - 0x00000010 61346236 37303463 32646665 39303536 a4b6704c2dfe9056
│ │ │ │ │ - 0x00000020 35373164 33392e64 65627567 00000000 571d39.debug....
│ │ │ │ │ - 0x00000030 725ffe8c r_..
│ │ │ │ │ + 0x00000000 37616563 32353263 62356132 63323461 7aec252cb5a2c24a
│ │ │ │ │ + 0x00000010 32643361 35396237 39373037 34326237 2d3a59b7970742b7
│ │ │ │ │ + 0x00000020 30363066 31382e64 65627567 00000000 060f18.debug....
│ │ │ │ │ + 0x00000030 101f5972 ..Yr
├── libgnatcoll19-dbgsym_21.0.0-4_arm64.deb
│ ├── file list
│ │ @@ -1,3 +1,3 @@
│ │ -rw-r--r-- 0 0 0 4 2020-12-22 09:58:09.000000 debian-binary
│ │ -rw-r--r-- 0 0 0 536 2020-12-22 09:58:09.000000 control.tar.xz
│ │ --rw-r--r-- 0 0 0 3182336 2020-12-22 09:58:09.000000 data.tar.xz
│ │ +-rw-r--r-- 0 0 0 3182360 2020-12-22 09:58:09.000000 data.tar.xz
│ ├── control.tar.xz
│ │ ├── control.tar
│ │ │ ├── ./control
│ │ │ │ @@ -6,8 +6,8 @@
│ │ │ │ Maintainer: Nicolas Boulenguez
│ │ │ │ Installed-Size: 4208
│ │ │ │ Depends: libgnatcoll19 (= 21.0.0-4)
│ │ │ │ Section: debug
│ │ │ │ Priority: optional
│ │ │ │ Multi-Arch: same
│ │ │ │ Description: debug symbols for libgnatcoll19
│ │ │ │ -Build-Ids: 741ce70cae34ead8cba4b6704c2dfe9056571d39
│ │ │ │ +Build-Ids: 317aec252cb5a2c24a2d3a59b7970742b7060f18
│ │ │ ├── ./md5sums
│ │ │ │ ├── ./md5sums
│ │ │ │ │┄ Files differ
│ │ │ │ ├── line order
│ │ │ │ │ @@ -1 +1 @@
│ │ │ │ │ -usr/lib/debug/.build-id/74/1ce70cae34ead8cba4b6704c2dfe9056571d39.debug
│ │ │ │ │ +usr/lib/debug/.build-id/31/7aec252cb5a2c24a2d3a59b7970742b7060f18.debug
│ ├── data.tar.xz
│ │ ├── data.tar
│ │ │ ├── file list
│ │ │ │ @@ -1,10 +1,10 @@
│ │ │ │ drwxr-xr-x 0 root (0) root (0) 0 2020-12-22 09:58:09.000000 ./
│ │ │ │ drwxr-xr-x 0 root (0) root (0) 0 2020-12-22 09:58:09.000000 ./usr/
│ │ │ │ drwxr-xr-x 0 root (0) root (0) 0 2020-12-22 09:58:09.000000 ./usr/lib/
│ │ │ │ drwxr-xr-x 0 root (0) root (0) 0 2020-12-22 09:58:09.000000 ./usr/lib/debug/
│ │ │ │ drwxr-xr-x 0 root (0) root (0) 0 2020-12-22 09:58:09.000000 ./usr/lib/debug/.build-id/
│ │ │ │ -drwxr-xr-x 0 root (0) root (0) 0 2020-12-22 09:58:09.000000 ./usr/lib/debug/.build-id/74/
│ │ │ │ --rw-r--r-- 0 root (0) root (0) 4297784 2020-12-22 09:58:09.000000 ./usr/lib/debug/.build-id/74/1ce70cae34ead8cba4b6704c2dfe9056571d39.debug
│ │ │ │ +drwxr-xr-x 0 root (0) root (0) 0 2020-12-22 09:58:09.000000 ./usr/lib/debug/.build-id/31/
│ │ │ │ +-rw-r--r-- 0 root (0) root (0) 4298144 2020-12-22 09:58:09.000000 ./usr/lib/debug/.build-id/31/7aec252cb5a2c24a2d3a59b7970742b7060f18.debug
│ │ │ │ drwxr-xr-x 0 root (0) root (0) 0 2020-12-22 09:58:09.000000 ./usr/share/
│ │ │ │ drwxr-xr-x 0 root (0) root (0) 0 2020-12-22 09:58:09.000000 ./usr/share/doc/
│ │ │ │ lrwxrwxrwx 0 root (0) root (0) 0 2020-12-22 09:58:09.000000 ./usr/share/doc/libgnatcoll19-dbgsym -> libgnatcoll19
│ │ │ │ --- ./usr/lib/debug/.build-id/74/1ce70cae34ead8cba4b6704c2dfe9056571d39.debug
│ │ │ ├── +++ ./usr/lib/debug/.build-id/31/7aec252cb5a2c24a2d3a59b7970742b7060f18.debug
│ │ │ │┄ File has been modified after NT_GNU_BUILD_ID has been applied.
│ │ │ │┄ Files 2% similar despite different names
│ │ │ │ ├── readelf --wide --file-header {}
│ │ │ │ │ @@ -6,15 +6,15 @@
│ │ │ │ │ OS/ABI: UNIX - System V
│ │ │ │ │ ABI Version: 0
│ │ │ │ │ Type: DYN (Shared object file)
│ │ │ │ │ Machine: AArch64
│ │ │ │ │ Version: 0x1
│ │ │ │ │ Entry point address: 0x19b720
│ │ │ │ │ Start of program headers: 64 (bytes into file)
│ │ │ │ │ - Start of section headers: 4295544 (bytes into file)
│ │ │ │ │ + Start of section headers: 4295904 (bytes into file)
│ │ │ │ │ Flags: 0x0
│ │ │ │ │ Size of this header: 64 (bytes)
│ │ │ │ │ Size of program headers: 56 (bytes)
│ │ │ │ │ Number of program headers: 7
│ │ │ │ │ Size of section headers: 64 (bytes)
│ │ │ │ │ Number of section headers: 35
│ │ │ │ │ Section header string table index: 34
│ │ │ │ ├── readelf --wide --sections {}
│ │ │ │ │ @@ -1,8 +1,8 @@
│ │ │ │ │ -There are 35 section headers, starting at offset 0x418b78:
│ │ │ │ │ +There are 35 section headers, starting at offset 0x418ce0:
│ │ │ │ │
│ │ │ │ │ Section Headers:
│ │ │ │ │ [Nr] Name Type Address Off Size ES Flg Lk Inf Al
│ │ │ │ │ [ 0] NULL 0000000000000000 000000 000000 00 0 0 0
│ │ │ │ │ [ 1] .note.gnu.build-id NOTE 00000000000001c8 0001c8 000024 00 A 0 0 4
│ │ │ │ │ [ 2] .gnu.hash NOBITS 00000000000001f0 0001ec 019dc0 00 A 3 0 8
│ │ │ │ │ [ 3] .dynsym NOBITS 0000000000019fb0 0001ec 056928 18 A 4 3 8
│ │ │ │ │ @@ -24,21 +24,21 @@
│ │ │ │ │ [19] .data.rel.ro NOBITS 000000000057f138 00f120 01a430 00 WA 0 0 8
│ │ │ │ │ [20] .dynamic NOBITS 0000000000599568 00f120 0002a0 10 WA 4 0 8
│ │ │ │ │ [21] .got NOBITS 0000000000599808 00f120 00c7f8 08 WA 0 0 8
│ │ │ │ │ [22] .data NOBITS 00000000005a6000 00f120 0020a0 00 WA 0 0 8
│ │ │ │ │ [23] .bss NOBITS 00000000005a80a0 00f120 002ee0 00 WA 0 0 16
│ │ │ │ │ [24] .comment PROGBITS 0000000000000000 0001ec 000027 01 MS 0 0 1
│ │ │ │ │ [25] .debug_aranges PROGBITS 0000000000000000 000218 000355 00 C 0 0 8
│ │ │ │ │ - [26] .debug_info PROGBITS 0000000000000000 000570 167d61 00 C 0 0 8
│ │ │ │ │ - [27] .debug_abbrev PROGBITS 0000000000000000 1682d8 0057b0 00 C 0 0 8
│ │ │ │ │ - [28] .debug_line PROGBITS 0000000000000000 16da88 07787b 00 C 0 0 8
│ │ │ │ │ - [29] .debug_str PROGBITS 0000000000000000 1e5308 023f65 01 MSC 0 0 8
│ │ │ │ │ - [30] .debug_loc PROGBITS 0000000000000000 209270 0b94ef 00 C 0 0 8
│ │ │ │ │ - [31] .debug_ranges PROGBITS 0000000000000000 2c2760 01cdaa 00 C 0 0 8
│ │ │ │ │ - [32] .symtab SYMTAB 0000000000000000 2df510 064b60 18 33 2416 8
│ │ │ │ │ - [33] .strtab STRTAB 0000000000000000 344070 0d49a5 00 0 0 1
│ │ │ │ │ - [34] .shstrtab STRTAB 0000000000000000 418a15 00015c 00 0 0 1
│ │ │ │ │ + [26] .debug_info PROGBITS 0000000000000000 000570 167d7a 00 C 0 0 8
│ │ │ │ │ + [27] .debug_abbrev PROGBITS 0000000000000000 1682f0 0057b0 00 C 0 0 8
│ │ │ │ │ + [28] .debug_line PROGBITS 0000000000000000 16daa0 07787b 00 C 0 0 8
│ │ │ │ │ + [29] .debug_str PROGBITS 0000000000000000 1e5320 0240b2 01 MSC 0 0 8
│ │ │ │ │ + [30] .debug_loc PROGBITS 0000000000000000 2093d8 0b94ef 00 C 0 0 8
│ │ │ │ │ + [31] .debug_ranges PROGBITS 0000000000000000 2c28c8 01cdaa 00 C 0 0 8
│ │ │ │ │ + [32] .symtab SYMTAB 0000000000000000 2df678 064b60 18 33 2416 8
│ │ │ │ │ + [33] .strtab STRTAB 0000000000000000 3441d8 0d49a5 00 0 0 1
│ │ │ │ │ + [34] .shstrtab STRTAB 0000000000000000 418b7d 00015c 00 0 0 1
│ │ │ │ │ Key to Flags:
│ │ │ │ │ W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
│ │ │ │ │ L (link order), O (extra OS processing required), G (group), T (TLS),
│ │ │ │ │ C (compressed), x (unknown), o (OS specific), E (exclude),
│ │ │ │ │ D (mbind), p (processor specific)
│ │ │ │ ├── readelf --wide --notes {}
│ │ │ │ │ @@ -1,4 +1,4 @@
│ │ │ │ │
│ │ │ │ │ Displaying notes found in: .note.gnu.build-id
│ │ │ │ │ Owner Data size Description
│ │ │ │ │ - GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring) Build ID: 741ce70cae34ead8cba4b6704c2dfe9056571d39
│ │ │ │ │ + GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring) Build ID: 317aec252cb5a2c24a2d3a59b7970742b7060f18
│ │ │ │ ├── readelf --wide --debug-dump=info {}
│ │ │ │ │ @@ -98,15 +98,15 @@
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ DW_AT_stmt_list : (sec_offset) 0x32a
│ │ │ │ │ DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1>: Abbrev Number: 112 (DW_TAG_base_type)
│ │ │ │ │ DW_AT_byte_size : (data1) 1
│ │ │ │ │ DW_AT_encoding : (data1) 8 (unsigned char)
│ │ │ │ │ - DW_AT_name : (strp) (offset: 0x38f7f): character
│ │ │ │ │ + DW_AT_name : (strp) (offset: 0x38ec6): character
│ │ │ │ │ <1>: Abbrev Number: 0
│ │ │ │ │ Compilation Unit @ offset 0xd8:
│ │ │ │ │ Length: 0x1a (32-bit)
│ │ │ │ │ Version: 4
│ │ │ │ │ Abbrev Offset: 0x5c
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ @@ -273,28 +273,28 @@
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0><228>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ <229> DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ <22d> DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1><231>: Abbrev Number: 112 (DW_TAG_base_type)
│ │ │ │ │ <232> DW_AT_byte_size : (data1) 8
│ │ │ │ │ <233> DW_AT_encoding : (data1) 7 (unsigned)
│ │ │ │ │ - <234> DW_AT_name : (strp) (offset: 0x5ad0): system__address
│ │ │ │ │ + <234> DW_AT_name : (strp) (offset: 0x5a17): system__address
│ │ │ │ │ <1><238>: Abbrev Number: 0
│ │ │ │ │ Compilation Unit @ offset 0x239:
│ │ │ │ │ Length: 0x18 (32-bit)
│ │ │ │ │ Version: 4
│ │ │ │ │ Abbrev Offset: 0x5c
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0><244>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ <245> DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ <249> DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1><24d>: Abbrev Number: 6 (DW_TAG_base_type)
│ │ │ │ │ <24e> DW_AT_byte_size : (data1) 8
│ │ │ │ │ <24f> DW_AT_encoding : (data1) 5 (signed)
│ │ │ │ │ - <250> DW_AT_name : (strp) (offset: 0x5d06): system__storage_elements__Tstorage_offsetB
│ │ │ │ │ + <250> DW_AT_name : (strp) (offset: 0x5c4d): system__storage_elements__Tstorage_offsetB
│ │ │ │ │ <254> DW_AT_artificial : (flag_present) 1
│ │ │ │ │ <1><254>: Abbrev Number: 0
│ │ │ │ │ Compilation Unit @ offset 0x255:
│ │ │ │ │ Length: 0x15 (32-bit)
│ │ │ │ │ Version: 4
│ │ │ │ │ Abbrev Offset: 0
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ @@ -338,15 +338,15 @@
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0><2ab>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ <2ac> DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ <2b0> DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1><2b4>: Abbrev Number: 6 (DW_TAG_base_type)
│ │ │ │ │ <2b5> DW_AT_byte_size : (data1) 8
│ │ │ │ │ <2b6> DW_AT_encoding : (data1) 5 (signed)
│ │ │ │ │ - <2b7> DW_AT_name : (strp) (offset: 0x3c34c): long_long_integer
│ │ │ │ │ + <2b7> DW_AT_name : (strp) (offset: 0x3c266): long_long_integer
│ │ │ │ │ <2bb> DW_AT_artificial : (flag_present) 1
│ │ │ │ │ <1><2bb>: Abbrev Number: 0
│ │ │ │ │ Compilation Unit @ offset 0x2bc:
│ │ │ │ │ Length: 0x2f (32-bit)
│ │ │ │ │ Version: 4
│ │ │ │ │ Abbrev Offset: 0x5c
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ @@ -354,15 +354,15 @@
│ │ │ │ │ <2c8> DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ <2cc> DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1><2d0>: Abbrev Number: 112 (DW_TAG_base_type)
│ │ │ │ │ <2d1> DW_AT_byte_size : (data1) 8
│ │ │ │ │ <2d2> DW_AT_encoding : (data1) 7 (unsigned)
│ │ │ │ │ <2d3> DW_AT_name : (strp) (offset: 0x25d8): system__storage_elements__integer_address
│ │ │ │ │ <1><2d7>: Abbrev Number: 126 (DW_TAG_subprogram)
│ │ │ │ │ - <2d8> DW_AT_name : (strp) (offset: 0x4b97): system__storage_elements__to_integer
│ │ │ │ │ + <2d8> DW_AT_name : (strp) (offset: 0x4ade): system__storage_elements__to_integer
│ │ │ │ │ <2dc> DW_AT_decl_file : (data1) 24
│ │ │ │ │ <2dd> DW_AT_decl_line : (data1) 68
│ │ │ │ │ <2de> DW_AT_decl_column : (data1) 4
│ │ │ │ │ <2df> DW_AT_type : (ref_udata) <0x2d0>, system__storage_elements__integer_address
│ │ │ │ │ <2e0> DW_AT_inline : (data1) 3 (declared as inline and inlined)
│ │ │ │ │ <2><2e1>: Abbrev Number: 14 (DW_TAG_formal_parameter)
│ │ │ │ │ <2e2> DW_AT_name : (strp) (offset: 0xf25e9): value
│ │ │ │ │ @@ -379,24 +379,24 @@
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0><2fa>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ <2fb> DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ <2ff> DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1><303>: Abbrev Number: 70 (DW_TAG_subprogram)
│ │ │ │ │ <304> DW_AT_external : (flag_present) 1
│ │ │ │ │ <304> DW_AT_declaration : (flag_present) 1
│ │ │ │ │ - <304> DW_AT_linkage_name: (strp) (offset: 0x59e1): ada__tags__check_tsd
│ │ │ │ │ - <308> DW_AT_name : (strp) (offset: 0x59e1): ada__tags__check_tsd
│ │ │ │ │ + <304> DW_AT_linkage_name: (strp) (offset: 0x5928): ada__tags__check_tsd
│ │ │ │ │ + <308> DW_AT_name : (strp) (offset: 0x5928): ada__tags__check_tsd
│ │ │ │ │ <30c> DW_AT_decl_file : (data1) 14
│ │ │ │ │ <30d> DW_AT_decl_line : (data2) 465
│ │ │ │ │ <30f> DW_AT_decl_column : (data1) 14
│ │ │ │ │ <1><310>: Abbrev Number: 70 (DW_TAG_subprogram)
│ │ │ │ │ <311> DW_AT_external : (flag_present) 1
│ │ │ │ │ <311> DW_AT_declaration : (flag_present) 1
│ │ │ │ │ - <311> DW_AT_linkage_name: (strp) (offset: 0x6fb5): ada__tags__register_tag
│ │ │ │ │ - <315> DW_AT_name : (strp) (offset: 0x6fb5): ada__tags__register_tag
│ │ │ │ │ + <311> DW_AT_linkage_name: (strp) (offset: 0x6efc): ada__tags__register_tag
│ │ │ │ │ + <315> DW_AT_name : (strp) (offset: 0x6efc): ada__tags__register_tag
│ │ │ │ │ <319> DW_AT_decl_file : (data1) 14
│ │ │ │ │ <31a> DW_AT_decl_line : (data2) 552
│ │ │ │ │ <31c> DW_AT_decl_column : (data1) 14
│ │ │ │ │ <1><31d>: Abbrev Number: 0
│ │ │ │ │ Compilation Unit @ offset 0x31e:
│ │ │ │ │ Length: 0x1a (32-bit)
│ │ │ │ │ Version: 4
│ │ │ │ │ @@ -404,29 +404,29 @@
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0><329>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ <32a> DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ <32e> DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1><332>: Abbrev Number: 53 (DW_TAG_subprogram)
│ │ │ │ │ <333> DW_AT_external : (flag_present) 1
│ │ │ │ │ <333> DW_AT_declaration : (flag_present) 1
│ │ │ │ │ - <333> DW_AT_linkage_name: (strp) (offset: 0x5542): __gnat_rcheck_PE_Access_Before_Elaboration
│ │ │ │ │ - <337> DW_AT_name : (strp) (offset: 0x5542): __gnat_rcheck_PE_Access_Before_Elaboration
│ │ │ │ │ + <333> DW_AT_linkage_name: (strp) (offset: 0x5489): __gnat_rcheck_PE_Access_Before_Elaboration
│ │ │ │ │ + <337> DW_AT_name : (strp) (offset: 0x5489): __gnat_rcheck_PE_Access_Before_Elaboration
│ │ │ │ │ <1><33b>: Abbrev Number: 0
│ │ │ │ │ Compilation Unit @ offset 0x33c:
│ │ │ │ │ Length: 0x1d (32-bit)
│ │ │ │ │ Version: 4
│ │ │ │ │ Abbrev Offset: 0x5c
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0><347>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ <348> DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ <34c> DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1><350>: Abbrev Number: 55 (DW_TAG_subprogram)
│ │ │ │ │ <351> DW_AT_external : (flag_present) 1
│ │ │ │ │ <351> DW_AT_declaration : (flag_present) 1
│ │ │ │ │ - <351> DW_AT_linkage_name: (strp) (offset: 0x556d): __gnat_raise_exception
│ │ │ │ │ + <351> DW_AT_linkage_name: (strp) (offset: 0x54b4): __gnat_raise_exception
│ │ │ │ │ <355> DW_AT_name : (strp) (offset: 0x3da7): ada__exceptions__raise_exception_always
│ │ │ │ │ <359> DW_AT_decl_file : (data1) 26
│ │ │ │ │ <35a> DW_AT_decl_line : (data1) 182
│ │ │ │ │ <35b> DW_AT_decl_column : (data1) 14
│ │ │ │ │ <1><35c>: Abbrev Number: 0
│ │ │ │ │ Compilation Unit @ offset 0x35d:
│ │ │ │ │ Length: 0x18 (32-bit)
│ │ │ │ │ @@ -473,30 +473,30 @@
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0><3ba>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ <3bb> DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ <3bf> DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1><3c3>: Abbrev Number: 53 (DW_TAG_subprogram)
│ │ │ │ │ <3c4> DW_AT_external : (flag_present) 1
│ │ │ │ │ <3c4> DW_AT_declaration : (flag_present) 1
│ │ │ │ │ - <3c4> DW_AT_linkage_name: (strp) (offset: 0x5f35): __gnat_rcheck_CE_Overflow_Check
│ │ │ │ │ - <3c8> DW_AT_name : (strp) (offset: 0x5f35): __gnat_rcheck_CE_Overflow_Check
│ │ │ │ │ + <3c4> DW_AT_linkage_name: (strp) (offset: 0x5e7c): __gnat_rcheck_CE_Overflow_Check
│ │ │ │ │ + <3c8> DW_AT_name : (strp) (offset: 0x5e7c): __gnat_rcheck_CE_Overflow_Check
│ │ │ │ │ <1><3cc>: Abbrev Number: 0
│ │ │ │ │ Compilation Unit @ offset 0x3cd:
│ │ │ │ │ Length: 0x1a (32-bit)
│ │ │ │ │ Version: 4
│ │ │ │ │ Abbrev Offset: 0x5c
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0><3d8>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ <3d9> DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ <3dd> DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1><3e1>: Abbrev Number: 53 (DW_TAG_subprogram)
│ │ │ │ │ <3e2> DW_AT_external : (flag_present) 1
│ │ │ │ │ <3e2> DW_AT_declaration : (flag_present) 1
│ │ │ │ │ - <3e2> DW_AT_linkage_name: (strp) (offset: 0x55b2): __gnat_rcheck_CE_Range_Check
│ │ │ │ │ - <3e6> DW_AT_name : (strp) (offset: 0x55b2): __gnat_rcheck_CE_Range_Check
│ │ │ │ │ + <3e2> DW_AT_linkage_name: (strp) (offset: 0x54f9): __gnat_rcheck_CE_Range_Check
│ │ │ │ │ + <3e6> DW_AT_name : (strp) (offset: 0x54f9): __gnat_rcheck_CE_Range_Check
│ │ │ │ │ <1><3ea>: Abbrev Number: 0
│ │ │ │ │ Compilation Unit @ offset 0x3eb:
│ │ │ │ │ Length: 0x1a (32-bit)
│ │ │ │ │ Version: 4
│ │ │ │ │ Abbrev Offset: 0x5c
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0><3f6>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ @@ -515,16 +515,16 @@
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0><414>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ <415> DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ <419> DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1><41d>: Abbrev Number: 53 (DW_TAG_subprogram)
│ │ │ │ │ <41e> DW_AT_external : (flag_present) 1
│ │ │ │ │ <41e> DW_AT_declaration : (flag_present) 1
│ │ │ │ │ - <41e> DW_AT_linkage_name: (strp) (offset: 0x5d69): __gnat_malloc
│ │ │ │ │ - <422> DW_AT_name : (strp) (offset: 0x5d69): __gnat_malloc
│ │ │ │ │ + <41e> DW_AT_linkage_name: (strp) (offset: 0x5cb0): __gnat_malloc
│ │ │ │ │ + <422> DW_AT_name : (strp) (offset: 0x5cb0): __gnat_malloc
│ │ │ │ │ <1><426>: Abbrev Number: 0
│ │ │ │ │ Compilation Unit @ offset 0x427:
│ │ │ │ │ Length: 0x1a (32-bit)
│ │ │ │ │ Version: 4
│ │ │ │ │ Abbrev Offset: 0x5c
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0><432>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ @@ -547,32 +547,32 @@
│ │ │ │ │ <1><459>: Abbrev Number: 112 (DW_TAG_base_type)
│ │ │ │ │ <45a> DW_AT_byte_size : (data1) 1
│ │ │ │ │ <45b> DW_AT_encoding : (data1) 7 (unsigned)
│ │ │ │ │ <45c> DW_AT_name : (strp) (offset: 0x7742): ada__streams__stream_element
│ │ │ │ │ <1><460>: Abbrev Number: 6 (DW_TAG_base_type)
│ │ │ │ │ <461> DW_AT_byte_size : (data1) 8
│ │ │ │ │ <462> DW_AT_encoding : (data1) 5 (signed)
│ │ │ │ │ - <463> DW_AT_name : (strp) (offset: 0x551c): ada__streams__Tstream_element_offsetB
│ │ │ │ │ + <463> DW_AT_name : (strp) (offset: 0x5463): ada__streams__Tstream_element_offsetB
│ │ │ │ │ <467> DW_AT_artificial : (flag_present) 1
│ │ │ │ │ <1><467>: Abbrev Number: 0
│ │ │ │ │ Compilation Unit @ offset 0x468:
│ │ │ │ │ Length: 0x41 (32-bit)
│ │ │ │ │ Version: 4
│ │ │ │ │ Abbrev Offset: 0x5c
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0><473>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ <474> DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ <478> DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1><47c>: Abbrev Number: 26 (DW_TAG_subrange_type)
│ │ │ │ │ <47d> DW_AT_lower_bound : (sdata) -9223372036854775808
│ │ │ │ │ <487> DW_AT_upper_bound : (sdata) 9223372036854775807
│ │ │ │ │ - <491> DW_AT_name : (strp) (offset: 0x5941): ada__streams__stream_element_offset
│ │ │ │ │ + <491> DW_AT_name : (strp) (offset: 0x5888): ada__streams__stream_element_offset
│ │ │ │ │ <495> DW_AT_type : (ref_addr) <0x460>, ada__streams__Tstream_element_offsetB
│ │ │ │ │ <1><499>: Abbrev Number: 92 (DW_TAG_array_type)
│ │ │ │ │ - <49a> DW_AT_name : (strp) (offset: 0x606d): ada__streams__stream_element_array___XUA
│ │ │ │ │ + <49a> DW_AT_name : (strp) (offset: 0x5fb4): ada__streams__stream_element_array___XUA
│ │ │ │ │ <49e> DW_AT_type : (ref_addr) <0x459>, ada__streams__stream_element
│ │ │ │ │ <4a2> DW_AT_sibling : (ref_udata) <0x4a9>
│ │ │ │ │ <2><4a3>: Abbrev Number: 4 (DW_TAG_subrange_type)
│ │ │ │ │ <4a4> DW_AT_type : (ref_addr) <0x460>, ada__streams__Tstream_element_offsetB
│ │ │ │ │ <2><4a8>: Abbrev Number: 0
│ │ │ │ │ <1><4a9>: Abbrev Number: 5 (DW_TAG_pointer_type)
│ │ │ │ │ <4aa> DW_AT_byte_size : (data1) 8
│ │ │ │ │ @@ -583,29 +583,29 @@
│ │ │ │ │ Version: 4
│ │ │ │ │ Abbrev Offset: 0x5c
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0><4b8>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ <4b9> DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ <4bd> DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1><4c1>: Abbrev Number: 76 (DW_TAG_structure_type)
│ │ │ │ │ - <4c2> DW_AT_name : (strp) (offset: 0x61a1): ada__streams__stream_element_array___XUP
│ │ │ │ │ + <4c2> DW_AT_name : (strp) (offset: 0x60e8): ada__streams__stream_element_array___XUP
│ │ │ │ │ <4c6> DW_AT_byte_size : (data1) 16
│ │ │ │ │ <4c7> DW_AT_decl_file : (data1) 19
│ │ │ │ │ <4c8> DW_AT_decl_line : (data1) 54
│ │ │ │ │ <4c9> DW_AT_decl_column : (data1) 9
│ │ │ │ │ <4ca> DW_AT_sibling : (ref_udata) <0x507>
│ │ │ │ │ <2><4cb>: Abbrev Number: 31 (DW_TAG_member)
│ │ │ │ │ <4cc> DW_AT_name : (strp) (offset: 0x1b26): P_ARRAY
│ │ │ │ │ <4d0> DW_AT_decl_file : (data1) 19
│ │ │ │ │ <4d1> DW_AT_decl_line : (data1) 42
│ │ │ │ │ <4d2> DW_AT_decl_column : (data1) 9
│ │ │ │ │ <4d3> DW_AT_type : (ref_addr) <0x4a9>, ada__streams__stream_element_array___XUA, ada__streams__stream_element
│ │ │ │ │ <4d7> DW_AT_data_member_location: (data1) 0
│ │ │ │ │ <2><4d8>: Abbrev Number: 2 (DW_TAG_structure_type)
│ │ │ │ │ - <4d9> DW_AT_name : (strp) (offset: 0x6096): ada__streams__stream_element_array___XUB
│ │ │ │ │ + <4d9> DW_AT_name : (strp) (offset: 0x5fdd): ada__streams__stream_element_array___XUB
│ │ │ │ │ <4dd> DW_AT_byte_size : (data1) 16
│ │ │ │ │ <4de> DW_AT_decl_file : (data1) 12
│ │ │ │ │ <4df> DW_AT_decl_line : (data1) 0
│ │ │ │ │ <4e0> DW_AT_artificial : (flag_present) 1
│ │ │ │ │ <4e0> DW_AT_sibling : (ref_udata) <0x4fc>
│ │ │ │ │ <3><4e1>: Abbrev Number: 1 (DW_TAG_member)
│ │ │ │ │ <4e2> DW_AT_name : (string) LB0
│ │ │ │ │ @@ -641,15 +641,15 @@
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0><516>: Abbrev Number: 2 (DW_TAG_partial_unit)
│ │ │ │ │ <517> DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ <51b> DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1><51f>: Abbrev Number: 6 (DW_TAG_subprogram)
│ │ │ │ │ <520> DW_AT_external : (flag_present) 1
│ │ │ │ │ <520> DW_AT_declaration : (flag_present) 1
│ │ │ │ │ - <520> DW_AT_linkage_name: (strp) (offset: 0x6b36): _Unwind_Resume
│ │ │ │ │ + <520> DW_AT_linkage_name: (strp) (offset: 0x6a7d): _Unwind_Resume
│ │ │ │ │ <524> DW_AT_name : (strp) (offset: 0x373e): __builtin_unwind_resume
│ │ │ │ │ <528> DW_AT_decl_file : (data1) 12
│ │ │ │ │ <529> DW_AT_decl_line : (data1) 0
│ │ │ │ │ <1><52a>: Abbrev Number: 0
│ │ │ │ │ Compilation Unit @ offset 0x52b:
│ │ │ │ │ Length: 0x29 (32-bit)
│ │ │ │ │ Version: 4
│ │ │ │ │ @@ -726,16 +726,16 @@
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0><5bc>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ <5bd> DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ <5c1> DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1><5c5>: Abbrev Number: 55 (DW_TAG_subprogram)
│ │ │ │ │ <5c6> DW_AT_external : (flag_present) 1
│ │ │ │ │ <5c6> DW_AT_declaration : (flag_present) 1
│ │ │ │ │ - <5c6> DW_AT_linkage_name: (strp) (offset: 0x65b1): system__secondary_stack__ss_mark
│ │ │ │ │ - <5ca> DW_AT_name : (strp) (offset: 0x65b1): system__secondary_stack__ss_mark
│ │ │ │ │ + <5c6> DW_AT_linkage_name: (strp) (offset: 0x64f8): system__secondary_stack__ss_mark
│ │ │ │ │ + <5ca> DW_AT_name : (strp) (offset: 0x64f8): system__secondary_stack__ss_mark
│ │ │ │ │ <5ce> DW_AT_decl_file : (data1) 25
│ │ │ │ │ <5cf> DW_AT_decl_line : (data1) 92
│ │ │ │ │ <5d0> DW_AT_decl_column : (data1) 13
│ │ │ │ │ <1><5d1>: Abbrev Number: 0
│ │ │ │ │ Compilation Unit @ offset 0x5d2:
│ │ │ │ │ Length: 0x1d (32-bit)
│ │ │ │ │ Version: 4
│ │ │ │ │ @@ -765,16 +765,16 @@
│ │ │ │ │ <608> DW_AT_external : (flag_present) 1
│ │ │ │ │ <608> DW_AT_declaration : (flag_present) 1
│ │ │ │ │ <608> DW_AT_linkage_name: (strp) (offset: 0x7476): __gnat_begin_handler_v1
│ │ │ │ │ <60c> DW_AT_name : (strp) (offset: 0x7476): __gnat_begin_handler_v1
│ │ │ │ │ <1><610>: Abbrev Number: 53 (DW_TAG_subprogram)
│ │ │ │ │ <611> DW_AT_external : (flag_present) 1
│ │ │ │ │ <611> DW_AT_declaration : (flag_present) 1
│ │ │ │ │ - <611> DW_AT_linkage_name: (strp) (offset: 0x6f2f): __gnat_end_handler_v1
│ │ │ │ │ - <615> DW_AT_name : (strp) (offset: 0x6f2f): __gnat_end_handler_v1
│ │ │ │ │ + <611> DW_AT_linkage_name: (strp) (offset: 0x6e76): __gnat_end_handler_v1
│ │ │ │ │ + <615> DW_AT_name : (strp) (offset: 0x6e76): __gnat_end_handler_v1
│ │ │ │ │ <1><619>: Abbrev Number: 0
│ │ │ │ │ Compilation Unit @ offset 0x61a:
│ │ │ │ │ Length: 0x26 (32-bit)
│ │ │ │ │ Version: 4
│ │ │ │ │ Abbrev Offset: 0x5c
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0><625>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ @@ -787,30 +787,30 @@
│ │ │ │ │ <633> DW_AT_name : (strp) (offset: 0x367e): ada__exceptions__triggered_by_abort
│ │ │ │ │ <637> DW_AT_decl_file : (data1) 26
│ │ │ │ │ <638> DW_AT_decl_line : (data1) 239
│ │ │ │ │ <639> DW_AT_decl_column : (data1) 13
│ │ │ │ │ <1><63a>: Abbrev Number: 53 (DW_TAG_subprogram)
│ │ │ │ │ <63b> DW_AT_external : (flag_present) 1
│ │ │ │ │ <63b> DW_AT_declaration : (flag_present) 1
│ │ │ │ │ - <63b> DW_AT_linkage_name: (strp) (offset: 0x5253): __gnat_rcheck_PE_Finalize_Raised_Exception
│ │ │ │ │ - <63f> DW_AT_name : (strp) (offset: 0x5253): __gnat_rcheck_PE_Finalize_Raised_Exception
│ │ │ │ │ + <63b> DW_AT_linkage_name: (strp) (offset: 0x519a): __gnat_rcheck_PE_Finalize_Raised_Exception
│ │ │ │ │ + <63f> DW_AT_name : (strp) (offset: 0x519a): __gnat_rcheck_PE_Finalize_Raised_Exception
│ │ │ │ │ <1><643>: Abbrev Number: 0
│ │ │ │ │ Compilation Unit @ offset 0x644:
│ │ │ │ │ Length: 0x1d (32-bit)
│ │ │ │ │ Version: 4
│ │ │ │ │ Abbrev Offset: 0x5c
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0><64f>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ <650> DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ <654> DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1><658>: Abbrev Number: 55 (DW_TAG_subprogram)
│ │ │ │ │ <659> DW_AT_external : (flag_present) 1
│ │ │ │ │ <659> DW_AT_declaration : (flag_present) 1
│ │ │ │ │ - <659> DW_AT_linkage_name: (strp) (offset: 0x5f95): system__secondary_stack__ss_allocate
│ │ │ │ │ - <65d> DW_AT_name : (strp) (offset: 0x5f95): system__secondary_stack__ss_allocate
│ │ │ │ │ + <659> DW_AT_linkage_name: (strp) (offset: 0x5edc): system__secondary_stack__ss_allocate
│ │ │ │ │ + <65d> DW_AT_name : (strp) (offset: 0x5edc): system__secondary_stack__ss_allocate
│ │ │ │ │ <661> DW_AT_decl_file : (data1) 25
│ │ │ │ │ <662> DW_AT_decl_line : (data1) 72
│ │ │ │ │ <663> DW_AT_decl_column : (data1) 14
│ │ │ │ │ <1><664>: Abbrev Number: 0
│ │ │ │ │ Compilation Unit @ offset 0x665:
│ │ │ │ │ Length: 0x1a (32-bit)
│ │ │ │ │ Version: 4
│ │ │ │ │ @@ -895,15 +895,15 @@
│ │ │ │ │ Version: 4
│ │ │ │ │ Abbrev Offset: 0x5c
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0><737>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ <738> DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ <73c> DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1><740>: Abbrev Number: 52 (DW_TAG_structure_type)
│ │ │ │ │ - <741> DW_AT_name : (strp) (offset: 0x5d77): system__atomic_counters__atomic_counter
│ │ │ │ │ + <741> DW_AT_name : (strp) (offset: 0x5cbe): system__atomic_counters__atomic_counter
│ │ │ │ │ <745> DW_AT_byte_size : (data1) 4
│ │ │ │ │ <746> DW_AT_decl_file : (data1) 18
│ │ │ │ │ <747> DW_AT_decl_line : (data1) 102
│ │ │ │ │ <748> DW_AT_decl_column : (data1) 9
│ │ │ │ │ <2><749>: Abbrev Number: 31 (DW_TAG_member)
│ │ │ │ │ <74a> DW_AT_name : (strp) (offset: 0xf25e9): value
│ │ │ │ │ <74e> DW_AT_decl_file : (data1) 18
│ │ │ │ │ @@ -919,15 +919,15 @@
│ │ │ │ │ Abbrev Offset: 0
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0><763>: Abbrev Number: 2 (DW_TAG_partial_unit)
│ │ │ │ │ <764> DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ <768> DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1><76c>: Abbrev Number: 7 (DW_TAG_subprogram)
│ │ │ │ │ <76d> DW_AT_external : (flag_present) 1
│ │ │ │ │ - <76d> DW_AT_name : (strp) (offset: 0x4f86): system__standard_library__abort_undefer_direct
│ │ │ │ │ + <76d> DW_AT_name : (strp) (offset: 0x4ecd): system__standard_library__abort_undefer_direct
│ │ │ │ │ <771> DW_AT_decl_file : (data1) 5
│ │ │ │ │ <772> DW_AT_decl_line : (data1) 72
│ │ │ │ │ <773> DW_AT_decl_column : (data1) 4
│ │ │ │ │ <774> DW_AT_inline : (data1) 3 (declared as inline and inlined)
│ │ │ │ │ <1><775>: Abbrev Number: 0
│ │ │ │ │ Compilation Unit @ offset 0x776:
│ │ │ │ │ Length: 0x3d (32-bit)
│ │ │ │ │ @@ -941,15 +941,15 @@
│ │ │ │ │ <78b> DW_AT_name : (strp) (offset: 0x289a): ada__containers__helpers__tamper_counts
│ │ │ │ │ <78f> DW_AT_byte_size : (data1) 8
│ │ │ │ │ <790> DW_AT_decl_file : (data1) 11
│ │ │ │ │ <791> DW_AT_decl_line : (data1) 43
│ │ │ │ │ <792> DW_AT_decl_column : (data1) 9
│ │ │ │ │ <793> DW_AT_sibling : (ref_udata) <0x7af>
│ │ │ │ │ <2><794>: Abbrev Number: 31 (DW_TAG_member)
│ │ │ │ │ - <795> DW_AT_name : (strp) (offset: 0x3f9eb): busy
│ │ │ │ │ + <795> DW_AT_name : (strp) (offset: 0x3f959): busy
│ │ │ │ │ <799> DW_AT_decl_file : (data1) 11
│ │ │ │ │ <79a> DW_AT_decl_line : (data1) 44
│ │ │ │ │ <79b> DW_AT_decl_column : (data1) 7
│ │ │ │ │ <79c> DW_AT_type : (ref_addr) <0x38d>, system__atomic_counters__atomic_unsigned
│ │ │ │ │ <7a0> DW_AT_data_member_location: (data1) 0
│ │ │ │ │ <2><7a1>: Abbrev Number: 31 (DW_TAG_member)
│ │ │ │ │ <7a2> DW_AT_name : (strp) (offset: 0x3aa92): lock
│ │ │ │ │ @@ -958,30 +958,30 @@
│ │ │ │ │ <7a8> DW_AT_decl_column : (data1) 7
│ │ │ │ │ <7a9> DW_AT_type : (ref_addr) <0x38d>, system__atomic_counters__atomic_unsigned
│ │ │ │ │ <7ad> DW_AT_data_member_location: (data1) 4
│ │ │ │ │ <2><7ae>: Abbrev Number: 0
│ │ │ │ │ <1><7af>: Abbrev Number: 6 (DW_TAG_base_type)
│ │ │ │ │ <7b0> DW_AT_byte_size : (data1) 4
│ │ │ │ │ <7b1> DW_AT_encoding : (data1) 5 (signed)
│ │ │ │ │ - <7b2> DW_AT_name : (strp) (offset: 0x4964): ada__containers__Tcount_typeB
│ │ │ │ │ + <7b2> DW_AT_name : (strp) (offset: 0x48ab): ada__containers__Tcount_typeB
│ │ │ │ │ <7b6> DW_AT_artificial : (flag_present) 1
│ │ │ │ │ <1><7b6>: Abbrev Number: 0
│ │ │ │ │ Compilation Unit @ offset 0x7b7:
│ │ │ │ │ Length: 0x1e (32-bit)
│ │ │ │ │ Version: 4
│ │ │ │ │ Abbrev Offset: 0x5c
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0><7c2>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ <7c3> DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ <7c7> DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1><7cb>: Abbrev Number: 70 (DW_TAG_subprogram)
│ │ │ │ │ <7cc> DW_AT_external : (flag_present) 1
│ │ │ │ │ <7cc> DW_AT_declaration : (flag_present) 1
│ │ │ │ │ - <7cc> DW_AT_linkage_name: (strp) (offset: 0x5700): system__storage_pools__subpools__allocate_any_controlled
│ │ │ │ │ - <7d0> DW_AT_name : (strp) (offset: 0x5700): system__storage_pools__subpools__allocate_any_controlled
│ │ │ │ │ + <7cc> DW_AT_linkage_name: (strp) (offset: 0x5647): system__storage_pools__subpools__allocate_any_controlled
│ │ │ │ │ + <7d0> DW_AT_name : (strp) (offset: 0x5647): system__storage_pools__subpools__allocate_any_controlled
│ │ │ │ │ <7d4> DW_AT_decl_file : (data1) 32
│ │ │ │ │ <7d5> DW_AT_decl_line : (data2) 263
│ │ │ │ │ <7d7> DW_AT_decl_column : (data1) 14
│ │ │ │ │ <1><7d8>: Abbrev Number: 0
│ │ │ │ │ Compilation Unit @ offset 0x7d9:
│ │ │ │ │ Length: 0x1e (32-bit)
│ │ │ │ │ Version: 4
│ │ │ │ │ @@ -989,16 +989,16 @@
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0><7e4>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ <7e5> DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ <7e9> DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1><7ed>: Abbrev Number: 70 (DW_TAG_subprogram)
│ │ │ │ │ <7ee> DW_AT_external : (flag_present) 1
│ │ │ │ │ <7ee> DW_AT_declaration : (flag_present) 1
│ │ │ │ │ - <7ee> DW_AT_linkage_name: (strp) (offset: 0x4a4e): system__storage_pools__subpools__deallocate_any_controlled
│ │ │ │ │ - <7f2> DW_AT_name : (strp) (offset: 0x4a4e): system__storage_pools__subpools__deallocate_any_controlled
│ │ │ │ │ + <7ee> DW_AT_linkage_name: (strp) (offset: 0x4995): system__storage_pools__subpools__deallocate_any_controlled
│ │ │ │ │ + <7f2> DW_AT_name : (strp) (offset: 0x4995): system__storage_pools__subpools__deallocate_any_controlled
│ │ │ │ │ <7f6> DW_AT_decl_file : (data1) 32
│ │ │ │ │ <7f7> DW_AT_decl_line : (data2) 305
│ │ │ │ │ <7f9> DW_AT_decl_column : (data1) 14
│ │ │ │ │ <1><7fa>: Abbrev Number: 0
│ │ │ │ │ Compilation Unit @ offset 0x7fb:
│ │ │ │ │ Length: 0x18 (32-bit)
│ │ │ │ │ Version: 4
│ │ │ │ │ @@ -1006,15 +1006,15 @@
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0><806>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ <807> DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ <80b> DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1><80f>: Abbrev Number: 112 (DW_TAG_base_type)
│ │ │ │ │ <810> DW_AT_byte_size : (data1) 4
│ │ │ │ │ <811> DW_AT_encoding : (data1) 7 (unsigned)
│ │ │ │ │ - <812> DW_AT_name : (strp) (offset: 0x5ddd): system__unsigned_types__unsigned
│ │ │ │ │ + <812> DW_AT_name : (strp) (offset: 0x5d24): system__unsigned_types__unsigned
│ │ │ │ │ <1><816>: Abbrev Number: 0
│ │ │ │ │ Compilation Unit @ offset 0x817:
│ │ │ │ │ Length: 0x1b (32-bit)
│ │ │ │ │ Version: 4
│ │ │ │ │ Abbrev Offset: 0x5c
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0><822>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ @@ -1047,15 +1047,15 @@
│ │ │ │ │ Version: 4
│ │ │ │ │ Abbrev Offset: 0x5c
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0><85e>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ <85f> DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ <863> DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1><867>: Abbrev Number: 101 (DW_TAG_subprogram)
│ │ │ │ │ - <868> DW_AT_name : (strp) (offset: 0x5a2e): system__atomic_counters__increment__2
│ │ │ │ │ + <868> DW_AT_name : (strp) (offset: 0x5975): system__atomic_counters__increment__2
│ │ │ │ │ <86c> DW_AT_decl_file : (data1) 3
│ │ │ │ │ <86d> DW_AT_decl_line : (data1) 78
│ │ │ │ │ <86e> DW_AT_decl_column : (data1) 4
│ │ │ │ │ <86f> DW_AT_inline : (data1) 3 (declared as inline and inlined)
│ │ │ │ │ <2><870>: Abbrev Number: 14 (DW_TAG_formal_parameter)
│ │ │ │ │ <871> DW_AT_name : (strp) (offset: 0x5bbfc): item
│ │ │ │ │ <875> DW_AT_decl_file : (data1) 18
│ │ │ │ │ @@ -1091,29 +1091,29 @@
│ │ │ │ │ Version: 4
│ │ │ │ │ Abbrev Offset: 0x5c
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0><8b4>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ <8b5> DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ <8b9> DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1><8bd>: Abbrev Number: 76 (DW_TAG_structure_type)
│ │ │ │ │ - <8be> DW_AT_name : (strp) (offset: 0x452b): system__finalization_masters__fm_node
│ │ │ │ │ + <8be> DW_AT_name : (strp) (offset: 0x4472): system__finalization_masters__fm_node
│ │ │ │ │ <8c2> DW_AT_byte_size : (data1) 16
│ │ │ │ │ <8c3> DW_AT_decl_file : (data1) 21
│ │ │ │ │ <8c4> DW_AT_decl_line : (data1) 151
│ │ │ │ │ <8c5> DW_AT_decl_column : (data1) 9
│ │ │ │ │ <8c6> DW_AT_sibling : (ref_udata) <0x8dc>
│ │ │ │ │ <2><8c7>: Abbrev Number: 13 (DW_TAG_member)
│ │ │ │ │ - <8c8> DW_AT_name : (strp) (offset: 0xc286): prev
│ │ │ │ │ + <8c8> DW_AT_name : (strp) (offset: 0xc1cd): prev
│ │ │ │ │ <8cc> DW_AT_decl_file : (data1) 21
│ │ │ │ │ <8cd> DW_AT_decl_line : (data1) 152
│ │ │ │ │ <8ce> DW_AT_decl_column : (data1) 7
│ │ │ │ │ <8cf> DW_AT_type : (ref_udata) <0x8dc>, system__finalization_masters__fm_node_ptr, system__finalization_masters__fm_node
│ │ │ │ │ <8d0> DW_AT_data_member_location: (data1) 0
│ │ │ │ │ <2><8d1>: Abbrev Number: 13 (DW_TAG_member)
│ │ │ │ │ - <8d2> DW_AT_name : (strp) (offset: 0x6a138): next
│ │ │ │ │ + <8d2> DW_AT_name : (strp) (offset: 0x6a1f1): next
│ │ │ │ │ <8d6> DW_AT_decl_file : (data1) 21
│ │ │ │ │ <8d7> DW_AT_decl_line : (data1) 153
│ │ │ │ │ <8d8> DW_AT_decl_column : (data1) 7
│ │ │ │ │ <8d9> DW_AT_type : (ref_udata) <0x8dc>, system__finalization_masters__fm_node_ptr, system__finalization_masters__fm_node
│ │ │ │ │ <8da> DW_AT_data_member_location: (data1) 8
│ │ │ │ │ <2><8db>: Abbrev Number: 0
│ │ │ │ │ <1><8dc>: Abbrev Number: 80 (DW_TAG_typedef)
│ │ │ │ │ @@ -1122,24 +1122,24 @@
│ │ │ │ │ <8e2> DW_AT_decl_line : (data1) 52
│ │ │ │ │ <8e3> DW_AT_decl_column : (data1) 9
│ │ │ │ │ <8e4> DW_AT_type : (ref_udata) <0x8e5>, system__finalization_masters__fm_node
│ │ │ │ │ <1><8e5>: Abbrev Number: 5 (DW_TAG_pointer_type)
│ │ │ │ │ <8e6> DW_AT_byte_size : (data1) 8
│ │ │ │ │ <8e7> DW_AT_type : (ref_udata) <0x8bd>, system__finalization_masters__fm_node
│ │ │ │ │ <1><8e8>: Abbrev Number: 73 (DW_TAG_typedef)
│ │ │ │ │ - <8e9> DW_AT_name : (strp) (offset: 0x5893): system__finalization_masters__finalize_address_ptr
│ │ │ │ │ + <8e9> DW_AT_name : (strp) (offset: 0x57da): system__finalization_masters__finalize_address_ptr
│ │ │ │ │ <8ed> DW_AT_decl_file : (data1) 21
│ │ │ │ │ <8ee> DW_AT_decl_line : (data1) 47
│ │ │ │ │ <8ef> DW_AT_decl_column : (data1) 9
│ │ │ │ │ <8f0> DW_AT_type : (ref_addr) <0x82b>
│ │ │ │ │ <1><8f4>: Abbrev Number: 55 (DW_TAG_subprogram)
│ │ │ │ │ <8f5> DW_AT_external : (flag_present) 1
│ │ │ │ │ <8f5> DW_AT_declaration : (flag_present) 1
│ │ │ │ │ - <8f5> DW_AT_linkage_name: (strp) (offset: 0x4afe): system__finalization_masters__base_pool
│ │ │ │ │ - <8f9> DW_AT_name : (strp) (offset: 0x4afe): system__finalization_masters__base_pool
│ │ │ │ │ + <8f5> DW_AT_linkage_name: (strp) (offset: 0x4a45): system__finalization_masters__base_pool
│ │ │ │ │ + <8f9> DW_AT_name : (strp) (offset: 0x4a45): system__finalization_masters__base_pool
│ │ │ │ │ <8fd> DW_AT_decl_file : (data1) 21
│ │ │ │ │ <8fe> DW_AT_decl_line : (data1) 193
│ │ │ │ │ <8ff> DW_AT_decl_column : (data1) 13
│ │ │ │ │ <1><900>: Abbrev Number: 55 (DW_TAG_subprogram)
│ │ │ │ │ <901> DW_AT_external : (flag_present) 1
│ │ │ │ │ <901> DW_AT_declaration : (flag_present) 1
│ │ │ │ │ <901> DW_AT_linkage_name: (strp) (offset: 0x763c): system__storage_pools__allocate_any
│ │ │ │ │ @@ -1231,21 +1231,21 @@
│ │ │ │ │ Version: 4
│ │ │ │ │ Abbrev Offset: 0x5c
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0><9b7>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ <9b8> DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ <9bc> DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1><9c0>: Abbrev Number: 80 (DW_TAG_typedef)
│ │ │ │ │ - <9c1> DW_AT_name : (strp) (offset: 0x6cae): system__stream_attributes__s_as
│ │ │ │ │ + <9c1> DW_AT_name : (strp) (offset: 0x6bf5): system__stream_attributes__s_as
│ │ │ │ │ <9c5> DW_AT_decl_file : (data1) 4
│ │ │ │ │ <9c6> DW_AT_decl_line : (data1) 57
│ │ │ │ │ <9c7> DW_AT_decl_column : (data1) 12
│ │ │ │ │ <9c8> DW_AT_type : (ref_udata) <0x9c9>, system__stream_attributes__s_as, ada__streams__stream_element
│ │ │ │ │ <1><9c9>: Abbrev Number: 115 (DW_TAG_array_type)
│ │ │ │ │ - <9ca> DW_AT_name : (strp) (offset: 0x6cae): system__stream_attributes__s_as
│ │ │ │ │ + <9ca> DW_AT_name : (strp) (offset: 0x6bf5): system__stream_attributes__s_as
│ │ │ │ │ <9ce> DW_AT_GNAT_descriptive_type: (ref_addr) <0x4c1>
│ │ │ │ │ <9d2> DW_AT_type : (ref_addr) <0x459>, ada__streams__stream_element
│ │ │ │ │ <2><9d6>: Abbrev Number: 51 (DW_TAG_subrange_type)
│ │ │ │ │ <9d7> DW_AT_type : (ref_addr) <0x460>, ada__streams__Tstream_element_offsetB
│ │ │ │ │ <9db> DW_AT_upper_bound : (sdata) 8
│ │ │ │ │ <2><9dc>: Abbrev Number: 0
│ │ │ │ │ <1><9dd>: Abbrev Number: 0
│ │ │ │ │ @@ -1256,16 +1256,16 @@
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0><9e9>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ <9ea> DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ <9ee> DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1><9f2>: Abbrev Number: 70 (DW_TAG_subprogram)
│ │ │ │ │ <9f3> DW_AT_external : (flag_present) 1
│ │ │ │ │ <9f3> DW_AT_declaration : (flag_present) 1
│ │ │ │ │ - <9f3> DW_AT_linkage_name: (strp) (offset: 0x5082): ada__strings__unbounded__finalize__2
│ │ │ │ │ - <9f7> DW_AT_name : (strp) (offset: 0x5082): ada__strings__unbounded__finalize__2
│ │ │ │ │ + <9f3> DW_AT_linkage_name: (strp) (offset: 0x4fc9): ada__strings__unbounded__finalize__2
│ │ │ │ │ + <9f7> DW_AT_name : (strp) (offset: 0x4fc9): ada__strings__unbounded__finalize__2
│ │ │ │ │ <9fb> DW_AT_decl_file : (data1) 17
│ │ │ │ │ <9fc> DW_AT_decl_line : (data2) 749
│ │ │ │ │ <9fe> DW_AT_decl_column : (data1) 25
│ │ │ │ │ <1><9ff>: Abbrev Number: 0
│ │ │ │ │ Compilation Unit @ offset 0xa00:
│ │ │ │ │ Length: 0x1e (32-bit)
│ │ │ │ │ Version: 4
│ │ │ │ │ @@ -1273,16 +1273,16 @@
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1>: Abbrev Number: 70 (DW_TAG_subprogram)
│ │ │ │ │ DW_AT_external : (flag_present) 1
│ │ │ │ │ DW_AT_declaration : (flag_present) 1
│ │ │ │ │ - DW_AT_linkage_name: (strp) (offset: 0x617e): ada__strings__unbounded__reference
│ │ │ │ │ - DW_AT_name : (strp) (offset: 0x617e): ada__strings__unbounded__reference
│ │ │ │ │ + DW_AT_linkage_name: (strp) (offset: 0x60c5): ada__strings__unbounded__reference
│ │ │ │ │ + DW_AT_name : (strp) (offset: 0x60c5): ada__strings__unbounded__reference
│ │ │ │ │ DW_AT_decl_file : (data1) 17
│ │ │ │ │ DW_AT_decl_line : (data2) 710
│ │ │ │ │ DW_AT_decl_column : (data1) 14
│ │ │ │ │ <1>: Abbrev Number: 0
│ │ │ │ │ Compilation Unit @ offset 0xa22:
│ │ │ │ │ Length: 0x1d (32-bit)
│ │ │ │ │ Version: 4
│ │ │ │ │ @@ -1290,16 +1290,16 @@
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1>: Abbrev Number: 55 (DW_TAG_subprogram)
│ │ │ │ │ DW_AT_external : (flag_present) 1
│ │ │ │ │ DW_AT_declaration : (flag_present) 1
│ │ │ │ │ - DW_AT_linkage_name: (strp) (offset: 0x5108): ada__strings__unbounded__to_string
│ │ │ │ │ - DW_AT_name : (strp) (offset: 0x5108): ada__strings__unbounded__to_string
│ │ │ │ │ + DW_AT_linkage_name: (strp) (offset: 0x504f): ada__strings__unbounded__to_string
│ │ │ │ │ + DW_AT_name : (strp) (offset: 0x504f): ada__strings__unbounded__to_string
│ │ │ │ │ DW_AT_decl_file : (data1) 17
│ │ │ │ │ DW_AT_decl_line : (data1) 116
│ │ │ │ │ DW_AT_decl_column : (data1) 13
│ │ │ │ │ <1>: Abbrev Number: 0
│ │ │ │ │ Compilation Unit @ offset 0xa43:
│ │ │ │ │ Length: 0x5d (32-bit)
│ │ │ │ │ Version: 4
│ │ │ │ │ @@ -1332,15 +1332,15 @@
│ │ │ │ │ DW_AT_name : (string) LB0
│ │ │ │ │ DW_AT_decl_file : (data1) 12
│ │ │ │ │ DW_AT_decl_line : (data1) 0
│ │ │ │ │ DW_AT_type : (ref_udata) <0xa7e>, positive___XDLU_1__2147483647, integer
│ │ │ │ │ DW_AT_data_member_location: (data1) 0
│ │ │ │ │ <3>: Abbrev Number: 69 (DW_TAG_subrange_type)
│ │ │ │ │ DW_AT_upper_bound : (sdata) 2147483647
│ │ │ │ │ - DW_AT_name : (strp) (offset: 0x5c7f): positive___XDLU_1__2147483647
│ │ │ │ │ + DW_AT_name : (strp) (offset: 0x5bc6): positive___XDLU_1__2147483647
│ │ │ │ │ DW_AT_type : (ref_addr) <0xb4>, integer
│ │ │ │ │ DW_AT_artificial : (flag_present) 1
│ │ │ │ │ <3>: Abbrev Number: 86 (DW_TAG_member)
│ │ │ │ │ DW_AT_name : (string) UB0
│ │ │ │ │ DW_AT_decl_file : (data1) 12
│ │ │ │ │ DW_AT_decl_line : (data1) 0
│ │ │ │ │ DW_AT_type : (ref_udata) <0xa7e>, positive___XDLU_1__2147483647, integer
│ │ │ │ │ @@ -1362,15 +1362,15 @@
│ │ │ │ │ Version: 4
│ │ │ │ │ Abbrev Offset: 0x5c
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1>: Abbrev Number: 73 (DW_TAG_typedef)
│ │ │ │ │ - DW_AT_name : (strp) (offset: 0x5e08): system__strings__string_access
│ │ │ │ │ + DW_AT_name : (strp) (offset: 0x5d4f): system__strings__string_access
│ │ │ │ │ DW_AT_decl_file : (data1) 13
│ │ │ │ │ DW_AT_decl_line : (data1) 45
│ │ │ │ │ DW_AT_decl_column : (data1) 9
│ │ │ │ │ DW_AT_type : (ref_addr) <0xa57>, string___XUP
│ │ │ │ │ <1>: Abbrev Number: 0
│ │ │ │ │ Compilation Unit @ offset 0xac5:
│ │ │ │ │ Length: 0x9e (32-bit)
│ │ │ │ │ @@ -1386,21 +1386,21 @@
│ │ │ │ │ DW_AT_decl_line : (data2) 268
│ │ │ │ │ DW_AT_decl_column : (data1) 9
│ │ │ │ │ DW_AT_type : (ref1) <0xae3>, ada__tags__dispatch_table, ada__tags__dispatch_table, ada__tags__prim_ptr
│ │ │ │ │ <1>: Abbrev Number: 36 (DW_TAG_pointer_type)
│ │ │ │ │ DW_AT_byte_size : (data1) 8
│ │ │ │ │ DW_AT_type : (ref1) <0xae6>, ada__tags__dispatch_table, ada__tags__dispatch_table, ada__tags__prim_ptr
│ │ │ │ │ <1>: Abbrev Number: 46 (DW_TAG_typedef)
│ │ │ │ │ - DW_AT_name : (strp) (offset: 0x66ba): ada__tags__dispatch_table
│ │ │ │ │ + DW_AT_name : (strp) (offset: 0x6601): ada__tags__dispatch_table
│ │ │ │ │ DW_AT_decl_file : (data1) 14
│ │ │ │ │ DW_AT_decl_line : (data2) 263
│ │ │ │ │ DW_AT_decl_column : (data1) 12
│ │ │ │ │ DW_AT_type : (ref1) <0xaf0>, ada__tags__dispatch_table, ada__tags__prim_ptr
│ │ │ │ │ <1>: Abbrev Number: 23 (DW_TAG_array_type)
│ │ │ │ │ - DW_AT_name : (strp) (offset: 0x66ba): ada__tags__dispatch_table
│ │ │ │ │ + DW_AT_name : (strp) (offset: 0x6601): ada__tags__dispatch_table
│ │ │ │ │ DW_AT_GNAT_descriptive_type: (ref1) <0xb02>
│ │ │ │ │ DW_AT_type : (ref_addr) <0x28f>, ada__tags__prim_ptr
│ │ │ │ │ DW_AT_sibling : (ref1) <0xb02>
│ │ │ │ │ <2>: Abbrev Number: 51 (DW_TAG_subrange_type)
│ │ │ │ │ DW_AT_type : (ref_addr) <0xb4>, integer
│ │ │ │ │ DW_AT_upper_bound : (sdata) 1
│ │ │ │ │ <2>: Abbrev Number: 0
│ │ │ │ │ @@ -1474,21 +1474,21 @@
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1>: Abbrev Number: 3 (DW_TAG_imported_unit)
│ │ │ │ │ DW_AT_import : (ref_addr) <0xad0> [Abbrev Number: 10 (DW_TAG_partial_unit)]
│ │ │ │ │ <1>: Abbrev Number: 52 (DW_TAG_structure_type)
│ │ │ │ │ - DW_AT_name : (strp) (offset: 0x50ea): ada__finalization__controlled
│ │ │ │ │ + DW_AT_name : (strp) (offset: 0x5031): ada__finalization__controlled
│ │ │ │ │ DW_AT_byte_size : (data1) 8
│ │ │ │ │ DW_AT_decl_file : (data1) 16
│ │ │ │ │ DW_AT_decl_line : (data1) 59
│ │ │ │ │ DW_AT_decl_column : (data1) 9
│ │ │ │ │ <2>: Abbrev Number: 39 (DW_TAG_member)
│ │ │ │ │ - DW_AT_name : (strp) (offset: 0x6cfcb): _parent
│ │ │ │ │ + DW_AT_name : (strp) (offset: 0x6d084): _parent
│ │ │ │ │ DW_AT_decl_file : (data1) 14
│ │ │ │ │ DW_AT_decl_line : (data2) 268
│ │ │ │ │ DW_AT_decl_column : (data1) 9
│ │ │ │ │ DW_AT_type : (ref_addr) <0xb52>, system__finalization_root__root_controlled
│ │ │ │ │ DW_AT_data_member_location: (data1) 0
│ │ │ │ │ <2>: Abbrev Number: 0
│ │ │ │ │ <1>: Abbrev Number: 0
│ │ │ │ │ @@ -1539,37 +1539,37 @@
│ │ │ │ │ <1>: Abbrev Number: 3 (DW_TAG_imported_unit)
│ │ │ │ │ DW_AT_import : (ref_addr) <0x6eb2> [Abbrev Number: 127 (DW_TAG_partial_unit)]
│ │ │ │ │ <1>: Abbrev Number: 3 (DW_TAG_imported_unit)
│ │ │ │ │ DW_AT_import : (ref_addr) <0x6ec9> [Abbrev Number: 127 (DW_TAG_partial_unit)]
│ │ │ │ │ <1>: Abbrev Number: 3 (DW_TAG_imported_unit)
│ │ │ │ │ DW_AT_import : (ref_addr) <0x7199> [Abbrev Number: 127 (DW_TAG_partial_unit)]
│ │ │ │ │ <1>: Abbrev Number: 30 (DW_TAG_structure_type)
│ │ │ │ │ - DW_AT_name : (strp) (offset: 0x527e): ada__streams__root_stream_type
│ │ │ │ │ + DW_AT_name : (strp) (offset: 0x51c5): ada__streams__root_stream_type
│ │ │ │ │ DW_AT_byte_size : (data1) 8
│ │ │ │ │ DW_AT_decl_file : (data1) 19
│ │ │ │ │ DW_AT_decl_line : (data1) 70
│ │ │ │ │ DW_AT_decl_column : (data1) 9
│ │ │ │ │ DW_AT_sibling : (ref1) <0xc2e>
│ │ │ │ │ <2>: Abbrev Number: 31 (DW_TAG_member)
│ │ │ │ │ DW_AT_name : (strp) (offset: 0x345e): _tag
│ │ │ │ │ DW_AT_decl_file : (data1) 19
│ │ │ │ │ DW_AT_decl_line : (data1) 70
│ │ │ │ │ DW_AT_decl_column : (data1) 53
│ │ │ │ │ DW_AT_type : (ref_addr) <0xad9>, ada__tags__tag, ada__tags__dispatch_table, ada__tags__dispatch_table, ada__tags__prim_ptr
│ │ │ │ │ DW_AT_data_member_location: (data1) 0
│ │ │ │ │ <2>: Abbrev Number: 0
│ │ │ │ │ <1>: Abbrev Number: 30 (DW_TAG_structure_type)
│ │ │ │ │ - DW_AT_name : (strp) (offset: 0x5381): ada__finalization__limited_controlled
│ │ │ │ │ + DW_AT_name : (strp) (offset: 0x52c8): ada__finalization__limited_controlled
│ │ │ │ │ DW_AT_byte_size : (data1) 8
│ │ │ │ │ DW_AT_decl_file : (data1) 16
│ │ │ │ │ DW_AT_decl_line : (data1) 65
│ │ │ │ │ DW_AT_decl_column : (data1) 9
│ │ │ │ │ DW_AT_sibling : (ref1) <0xc46>
│ │ │ │ │ <2>: Abbrev Number: 31 (DW_TAG_member)
│ │ │ │ │ - DW_AT_name : (strp) (offset: 0x6cfcb): _parent
│ │ │ │ │ + DW_AT_name : (strp) (offset: 0x6d084): _parent
│ │ │ │ │ DW_AT_decl_file : (data1) 16
│ │ │ │ │ DW_AT_decl_line : (data1) 65
│ │ │ │ │ DW_AT_decl_column : (data1) 9
│ │ │ │ │ DW_AT_type : (ref_addr) <0xb52>, system__finalization_root__root_controlled
│ │ │ │ │ DW_AT_data_member_location: (data1) 0
│ │ │ │ │ <2>: Abbrev Number: 0
│ │ │ │ │ <1>: Abbrev Number: 60 (DW_TAG_typedef)
│ │ │ │ │ @@ -1586,30 +1586,30 @@
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1>: Abbrev Number: 53 (DW_TAG_subprogram)
│ │ │ │ │ DW_AT_external : (flag_present) 1
│ │ │ │ │ DW_AT_declaration : (flag_present) 1
│ │ │ │ │ - DW_AT_linkage_name: (strp) (offset: 0x6b54): __gnat_set_exception_parameter
│ │ │ │ │ - DW_AT_name : (strp) (offset: 0x6b54): __gnat_set_exception_parameter
│ │ │ │ │ + DW_AT_linkage_name: (strp) (offset: 0x6a9b): __gnat_set_exception_parameter
│ │ │ │ │ + DW_AT_name : (strp) (offset: 0x6a9b): __gnat_set_exception_parameter
│ │ │ │ │ <1>: Abbrev Number: 0
│ │ │ │ │ Compilation Unit @ offset 0xc72:
│ │ │ │ │ Length: 0x1d (32-bit)
│ │ │ │ │ Version: 4
│ │ │ │ │ Abbrev Offset: 0x5c
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1>: Abbrev Number: 55 (DW_TAG_subprogram)
│ │ │ │ │ DW_AT_external : (flag_present) 1
│ │ │ │ │ DW_AT_declaration : (flag_present) 1
│ │ │ │ │ - DW_AT_linkage_name: (strp) (offset: 0x5bca): ada__strings__unbounded__to_unbounded_string
│ │ │ │ │ - DW_AT_name : (strp) (offset: 0x5bca): ada__strings__unbounded__to_unbounded_string
│ │ │ │ │ + DW_AT_linkage_name: (strp) (offset: 0x5b11): ada__strings__unbounded__to_unbounded_string
│ │ │ │ │ + DW_AT_name : (strp) (offset: 0x5b11): ada__strings__unbounded__to_unbounded_string
│ │ │ │ │ DW_AT_decl_file : (data1) 17
│ │ │ │ │ DW_AT_decl_line : (data1) 103
│ │ │ │ │ DW_AT_decl_column : (data1) 13
│ │ │ │ │ <1>: Abbrev Number: 0
│ │ │ │ │ Compilation Unit @ offset 0xc93:
│ │ │ │ │ Length: 0x1a (32-bit)
│ │ │ │ │ Version: 4
│ │ │ │ │ @@ -1617,16 +1617,16 @@
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ DW_AT_stmt_list : (sec_offset) 0x476
│ │ │ │ │ DW_AT_comp_dir : (strp) (offset: 0x98): ./obj/gnatcoll/relocatable
│ │ │ │ │ <1>: Abbrev Number: 53 (DW_TAG_subprogram)
│ │ │ │ │ DW_AT_external : (flag_present) 1
│ │ │ │ │ DW_AT_declaration : (flag_present) 1
│ │ │ │ │ - DW_AT_linkage_name: (strp) (offset: 0x546a): ada__strings__unbounded___assign__2
│ │ │ │ │ - DW_AT_name : (strp) (offset: 0x546a): ada__strings__unbounded___assign__2
│ │ │ │ │ + DW_AT_linkage_name: (strp) (offset: 0x53b1): ada__strings__unbounded___assign__2
│ │ │ │ │ + DW_AT_name : (strp) (offset: 0x53b1): ada__strings__unbounded___assign__2
│ │ │ │ │ <1>: Abbrev Number: 0
│ │ │ │ │ Compilation Unit @ offset 0xcb1:
│ │ │ │ │ Length: 0x1d (32-bit)
│ │ │ │ │ Version: 4
│ │ │ │ │ Abbrev Offset: 0x5c
│ │ │ │ │ Pointer Size: 8
│ │ │ │ │ <0>: Abbrev Number: 10 (DW_TAG_partial_unit)
│ │ │ │ │ @@ -1709,37 +1709,37 @@
│ │ │ │ │ <2>: Abbrev Number: 37 (DW_TAG_subrange_type)
│ │ │ │ │ DW_AT_lower_bound : (sdata) 0
│ │ │ │ │ DW_AT_upper_bound : (sdata) 2147483647
│ │ │ │ │ DW_AT_name : (strp) (offset: 0x15cc): natural___XDLU_0__2147483647
│ │ │ │ │ DW_AT_type : (ref_addr) <0xb4>, integer
│ │ │ │ │ DW_AT_artificial : (flag_present) 1
│ │ │ │ │ <2>: Abbrev Number: 39 (DW_TAG_member)
│ │ │ │ │ - DW_AT_name : (strp) (offset: 0x5d97): counter
│ │ │ │ │ + DW_AT_name : (strp) (offset: 0x5cde): counter
│ │ │ │ │ DW_AT_decl_file : (data1) 17
│ │ │ │ │ DW_AT_decl_line : (data2) 699
│ │ │ │ │ DW_AT_decl_column : (data1) 7
│ │ │ │ │ DW_AT_type : (ref_addr) <0x740>, system__atomic_counters__atomic_counter
│ │ │ │ │ DW_AT_data_member_location: (data1) 4
│ │ │ │ │ <2>: Abbrev Number: 17 (DW_TAG_member)
│ │ │ │ │ DW_AT_name : (strp) (offset: 0x7530): last
│ │ │ │ │ DW_AT_decl_file : (data1) 17
│ │ │ │ │ DW_AT_decl_line : (data2) 702
│ │ │ │ │ DW_AT_decl_column : (data1) 7
│ │ │ │ │ DW_AT_type : (ref1) <0xd4b>, natural___XDLU_0__2147483647, integer
│ │ │ │ │ DW_AT_data_member_location: (data1) 8
│ │ │ │ │ <2>: Abbrev Number: 23 (DW_TAG_array_type)
│ │ │ │ │ - DW_AT_name : (strp) (offset: 0x6758): ada__strings__unbounded__shared_string__T80s
│ │ │ │ │ + DW_AT_name : (strp) (offset: 0x669f): ada__strings__unbounded__shared_string__T80s
│ │ │ │ │ DW_AT_GNAT_descriptive_type: (ref1) <0xd84>
│ │ │ │ │ DW_AT_type : (ref_addr) <0xd0>, character
│ │ │ │ │ DW_AT_sibling : (ref1) <0xd84>
│ │ │ │ │ <3>: Abbrev Number: 4 (DW_TAG_subrange_type)
│ │ │ │ │ DW_AT_type : (ref_addr) <0xb4>, integer
│ │ │ │ │ <3>: Abbrev Number: 0
│ │ │ │ │ <2>: Abbrev Number: 47 (DW_TAG_structure_type)
│ │ │ │ │ - DW_AT_name : (strp) (offset: 0x52e9): ada__strings__unbounded__shared_string__T80s___XA
│ │ │ │ │ + DW_AT_name : (strp) (offset: 0x5230): ada__strings__unbounded__shared_string__T80s___XA
│ │ │ │ │ DW_AT_byte_size : (data1) 4
│ │ │ │ │ DW_AT_decl_file : (data1) 17
│ │ │ │ │ DW_AT_decl_line : (data2) 703
│ │ │ │ │ DW_AT_decl_column : (data1) 27
│ │ │ │ │ DW_AT_artificial : (flag_present) 1
│ │ │ │ │ DW_AT_sibling : (ref1) <0xda4>
│ │ │ │ │ <3>: Abbrev Number: 17 (DW_TAG_member)
│ │ │ │ │ @@ -1774,15 +1774,15 @@
│ │ │ │ │ DW_AT_name : (strp) (offset: 0x286e): max_length
│ │ │ │ │ DW_AT_decl_file : (data1) 17
│ │ │ │ │ DW_AT_decl_line : (data2) 703
│ │ │ │ │