    AEP: 4
    Title: -gnatW8 impact on Alire
    Author: Alejandro R. Mosteo <amosteo@unizar.es>
    Status: Draft
    Created: 21-feb-2023

Abstract
========

Herein is documented the impact of enabling `-gnatW8` by default in Alire, and
mitigating measures and circumstances.

Details
=======

GNAT, by default, uses Latin-1 as the default character set [1][3], as specified
by the Ada 83 standard.

Later revisions opened the door to use UTF-16 and UTF-32. GNAT governs the
encodings to expect and accept through the `-gnatW` and `-gnati` switches [2].

When no switch is given, a source is considered Latin-1 unless it starts with a
UTF-8 BOM identifier, in which case the file is compiled as if `-gnatW8` were
supplied.

Trouble arises because the same source can be compiled multiple times (e.g.,
specifications or generic bodies) with different switches in effect.

For example, a crate may want to use full Unicode (in conformance with the Ada
standard), and will set `-gnatW8`. A dependency, though, uses Latin-1 encoding
and no switch. The dependency will compile properly on its own, but when used
as a dependency it may cause errors as a Latin-1 file is compiled as UTF-8. This
will happen even if no `-gnatW8` is given if the root file uses a BOM and the
dependency file uses plain Latin-1.

This means there is no universal solution, as GNAT may always cause conflicts
whenever there are files using different encodings, no matter if their
respective projects use the appropriate encoding switches, or the UTF-8 files
are properly BOM-marked.

Trying to stay Unicode-agnostic would be a possibility, but crates can get
surreptitiously into the index that compile properly on their own, but later
cause conflicts when used in combination with other crates.

The impact of adding `-gnatW8` to all new crates is mitigated in the case of
dependencies compiled as libraries that use Latin-1 encoding in non-generic
bodies and not supplying `-gnatW8` themselves. These dependencies will still be
built properly, and won't cause errors in clients of such a library.

Proposal
========

The modern course of action seems to be to mandate UTF-8 encoding for all
sources in the Alire ecosystem, and enable `-gnatW8` in the default project
files created by Alire. At least this way, after a transition period, the
problem is in the past for good. This is also in conformance with recent Ada
standards.

As mitigations, we can fix or notify all crates already in the index before the
launch of Alire 2.0. We can also check during index submission that sources are
either UTF-8-encoded or plain ASCII to avoid the introduction of new
potentially problematic crates.

Impacted crates
===============

The following crates fail to compile when `-gnatW8` is unconditionally applied
(via `gprbuild -gnatW8`). Some failures are caused by dependencies and not by
the crate itself. Some others are expected to fail, as they use Latin-1
encoding. Still others, however, are already using UTF-8 encoding, but relying
on assumptions of UTF-8 strings being literally interpreted as byte sequences
instead of Latin-1 strings, even when using the `String` type.

Not all of them are problematic, as non-generic bodies won't "contaminate" a
client, and can be used as-is by `-gnatW8`-enabled crates. Several of them are
already maintained by Alire developers.

FAIL:apdf=5.0.3
	pdf_out_demo.adb:70:54: illegal wide character
FAIL:awa=2.4.0
	asf-converters-numbers.adb:131:53: error: literal out of range of type Standard.Character
FAIL:awa_unit=2.4.0
	asf-converters-numbers.adb:131:53: error: literal out of range of type Standard.Character
FAIL:excel_writer=17.0.1
	excel_out_demo.adb:125:39: illegal wide character
	csv2html.adb:19:13: illegal wide character
FAIL:mandelbrot_ascii=1.0.0
	mandelbrot_ascii.adb:105:05: literal out of range of type Standard.Character
FAIL:pico_examples=2.0.0
	main.adb:34:70: error: literal out of range of type Standard.Character
FAIL:progress_indicators=0.0.1
	progress_indicators-bars.adb:32:46: literal out of range of type Standard.Character
FAIL:semantic_versioning=2.1.0
	semantic_versioning-demo.adb:101:47: literal out of range of type Standard.Character
FAIL:septum=0.0.7
	progress_indicators-bars.adb:32:46: literal out of range of type Standard.Character
FAIL:serverfaces=1.5.0
	asf-converters-numbers.adb:131:53: error: literal out of range of type Standard.Character
FAIL:serverfaces_unit=1.5.0
	asf-converters-numbers.adb:131:53: error: literal out of range of type Standard.Character
FAIL:simple_logging=1.2.0
	simple_logging.adb:121:25: literal out of range of type Standard.Character

References
==========

[1] http://www.ada-auth.org/standards/rm12_w_tc1/html/RM-2-1.html
[2] https://docs.adacore.com/live/wave/gnat_ugn/html/gnat_ugn/gnat_ugn/building_executable_programs_with_gnat.html#character-set-control
[3] http://www.ada-auth.org/standards/rm12_w_tc1/html/RM-3-5-2.html

comp.lang.ada
=============
Discussions related to Unicode at comp.lang.ada and elsewhere:

https://groups.google.com/g/comp.lang.ada/c/l0aflBePm_E/
https://two-wrongs.com/unicode-strings-in-ada-2012
https://groups.google.com/g/comp.lang.ada/c/QeKNbHFqPEg/


Copyright
=========

This document has been placed in the public domain.
