AdaCore / gprbuild

GPRbuild is an advanced build system designed to help automate the construction of multi-language systems.
Other
65 stars 21 forks source link

gprbuild is sometimes failing on '@' symbol with Ada 202x code #109

Closed CameronHowie closed 2 years ago

CameronHowie commented 2 years ago

gprbuild frequently reports "illegal character" failure upon recompiling a modified Ada source file.

MY TOOLCHAIN: GNAT FSF 11.2 on Windows x64 using Mingw32 (MSYS2) package management.

SCENARIO: I made a small Ada project to try out Ada 202x and the -gnat2020 and -gnatX Ada compiler switches. In particular, I wanted to use the '@' symbol e.g., for incrementing a variable as supported by the Ada 202x language release:

x : Integer := 10; ... x := @ + 1;

While gprbuild and GNAT managed to compile the code just fine initially, after I edited the source code e.g., to:

x := @ - 1;

and then recompiled it using gprbuild, I got an error message from the 'GPR scanner' causing gprbuild to fail with the error message:

gprbuild -p -PTestAda2022.gpr -m -Xbuild=debug --config=default.cgpr

(null):51:21: illegal character

I believe the issue is somehow tied to .ALI files or temporary compilation state for a given file (see my final comments later below on how deleting temporary files sometimes solves the problem). Anyway, first some comments on how I've hacked in a somewhat workable solution:

I wanted to know where in GPR this error was coming from and tracked it down in your gprbuild source code to the package:

gpr\src\gpr-err-scanner.adb

at about line 363, in this statement:

Error_Msg ("illegal character", Scan_Ptr);

Notice the source file name is reported to stderr (I assume) as "(null)" which may not be what you intend -- I would think it should name the source code file, though the line and column numbers are correct (here 51 and 21). However, that's of minor importance to me right now. I had to hack gprbuild to support the '@' symbol. For example, below this existing scanner code to handle a "Comma":

    --  Comma

     when ',' =>
        Accumulate_Checksum (',');
        Scan_Ptr := Scan_Ptr + 1;
        Token := Tok_Comma;
        return;

I added a similar block for '@' (fortunately your code had "Tok_At" defined upstream so I could use that directly here):

     --  At symbol; modified by Cameron to support Ada 202x

     when '@' =>
        Accumulate_Checksum ('@');
        Scan_Ptr := Scan_Ptr + 1;
        Token := Tok_At;
        return;

and then I had to remove '@' from the set of "invalid graphic characters" further down the same file by changing this line of code:

     when '#' | '$' | '?' | '@' | '`' | '\' | '^' | '~' =>

to this:

     when '#' | '$' | '?' | '`' | '\' | '^' | '~' =>

I recompiled and reinstalled gprbuild. However, that failed (produced gprbuild errors) if the '@' appears in a string literal, or at least it was causing some sort of problems. For example I got an error like:

(null):522:70: strings are delimited by double quote character

for a source code line like:

Put_Line (context & " @ char:" & i'Image);

so I replaced the above "when '@'" code to be much simpler, copying your code for ASCII.HT symbol:

     --  At symbol; modified by Cameron for Ada 2020x
     --  We just skip the character and don't set "Token := Tok_At;"
     --  Thus we mimic the logic above for "when ASCII.HT":

     when '@' =>
        Scan_Ptr := Scan_Ptr + 1;

I am now able to use gprbuild with Ada 202x code using the '@' symbol, including recompiling edited source files. However, I still occasionally get "illegal character" gprbuild failures after quick editing of a file and then trying to recompile soon afterwards. Perhaps there's some state in the .ALI files or timestamp tracking issue relating to these '@' symbols. In those cases, I fix the problem by deleting all the object and .ALI files for the source file in question, at which point gprbuild works. Obviously, my hack is insufficient to handle the underlying root issue 100% reliably.

anisimkov commented 2 years ago

It is known issue, but it should be fixed in gprbuild 22.0 which is currently in fresh GNAT FSF 11.2. I just build it by instructions from https://github.com/alire-project/GNAT-FSF-builds and checked. Could you check the output of gprbuild --version in reproducing configuration ?

I built it in Linux but I do not think that Windows has any difference in @ processing. Most probable it is older gprbuild version. The fix is in commit 8b47335eb6c3cdc4a23a545a4341d89d3118d38a

CameronHowie commented 2 years ago

Aaah, yes, I was using the 2021-sustained branch. I like to have a more stable branch for my builds, but I'll upgrade to one of the 2022 branches in light of this patch. Thanks