Search code examples
stringadagetenv

How to initialise an Ada Unbounded String from GetEnv & Literal


G'day, I'm finding compile errors on what ought to be a simple piece of code. the objective is to use an environment variable as part of a default value. We are using Ada95, so I wondered if it's a version thing.

The 'model' we stated with looks (something) like this:

  Default_Override_Message_Text   : Ada.Strings.Unbounded.Unbounded_String
      := Ada.Strings.Unbounded.To_Unbounded_String(
             Gnat.Os_Lib.Getenv( "DATA_FILES" ) & 
             "/override_required.txt" );

I'm getting an error on the &:

  • invalid operand types for operator & invalid operand types for operator "&"

Whereas, this is fine.

  Default_Override_Message_Text   : Ada.Strings.Unbounded.Unbounded_String
      := Ada.Strings.Unbounded.To_Unbounded_String(
             "DATA_FILES" & "/override_required.txt" );

I turned to the internet and books, is just seems that it should work and here's a difficulty with typing or something. The example given on PLEAC give me an error too.

    username : string := Gnat.Os_Lib.Getenv("USER");
    DATA_FILES  : String := Gnat.Os_Lib.Getenv( "DATA_FILES" );

Gives the error:

  • Builder results expected type "Standard.String" 181:37 expected type "Standard.String" Builder results
  • Builder results found type "System.Strings.String_Access" 181:37

I thought with that approach I can

DATA_FILES   : String := Gnat.Os_Lib.Getenv( "GPS_DATA_FILES" );

Default_Override_Message_Text : Ada.Strings.Unbounded.Unbounded_String
        := Ada.Strings.Unbounded.To_Unbounded_String(
                DATA_FILES & "/override_required.txt" ); -- ERROR

DATA_FILES_2 : String := "GPS_DATA_FILES";        -- WORKS

Default_Override_Message_Text : Ada.Strings.Unbounded.Unbounded_String
        := Ada.Strings.Unbounded.To_Unbounded_String(
                DATA_FILES_2 & "/override_required.txt" ); -- WORKS

I'm still doing something wrong with the GetEnv because it looks like everything we want will happen similar to the DATA_FILES_2 option would work (according to my compiler) if I can correctly assign the value from GetEnv().

Can someone point out my error? Or is Ada95 using different rules to the examples I'm looking at?


Solution

  • The declaration of the Gnat.Os_Lib.Getenv function is:

    function Getenv (Name : String) return String_Access;
    

    Note that it returns a String_Access, not a String (I'm not sure why).

    Adding a .all to get the String value from the String_Access result should fix your problem:

    Default_Override_Message_Text   : Ada.Strings.Unbounded.Unbounded_String
       := Ada.Strings.Unbounded.To_Unbounded_String(
             Gnat.Os_Lib.Getenv( "DATA_FILES" ).all & 
             "/override_required.txt" );
    

    (Having Gnat.Os_Lib.Getenv return a String_Access rather than a String could have been an opportunity to distinguish between a missing environment variable and one whose value is the empty string. Unfortunately, it returns an access to an empty string in both cases.)