Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to I build a string from other strings in Ada?

Tags:

string

ada

I want to output a header line in a log file and then a line of '-' before the data. To do this I create a string of the header and then outpout the same number of '-'.

But the below code always fails with a CONSTRAINT_ERROR because the generated string is not 1024 characters. In Ada string assignments require exactly the same length not just sufficient capacity.

Option 1) is to compute the exact length but that is brittle to future changes. Option 2) is to use something other than String.

procedure F() is 
    Msg : String(1..1024);
begin
    Open_Log();
    Msg :=       FLS(" Field1", 12) &
           "|" & FLS(" Field2", 12) &
           "|" & FLS(" Field3", 16);

    Log_To_File("# " & Msg);
    Log_To_File("# " & Fill_String(Msg'Last, '-'));
end;
like image 558
mat_geek Avatar asked Feb 15 '10 00:02

mat_geek


2 Answers

A lot of folks who are used to the C way of building strings in steps have trouble wrapping their minds around Ada strings, which you are supposed to initialize and use as-is. When you grok this fact about Ada strings, the solution becomes much simpler. I can even throw out your "Fill" routine.

procedure F() is  
   Msg : constant String
      := FLS(" Field1", 12) & 
       "|" & FLS(" Field2", 12) & 
       "|" & FLS(" Field3", 16); 
   Separator : constant String := (1..Msg'length => '-'); --'
begin 
   Open_Log(); 

   Log_To_File("# " & Msg); 
   Log_To_File("# " & Separator); 
end;

(Note: The comment is a hack to get SO's colorizer back on track)

If you didn't have to have the separator the same length, you wouldn't even need to declare the variable.

If it were me, I'd do something like have Log_To_File keep track of lengths and generate its own properly-sized separator upon request. Then you could just write:

Open_Log();
Log_To_File ("# " & FLS(" Field1", 12) & 
       "|" & FLS(" Field2", 12) & 
       "|" & FLS(" Field3", 16)); 
Log_Separator_To_File;
like image 193
T.E.D. Avatar answered Oct 10 '22 20:10

T.E.D.


Just declare Msg as a String instead of a String(1 .. 1024)

procedure F() is 

    Msg: String  
    :=       FLS(" Field1", 12) &
       "|" & FLS(" Field2", 12) &
       "|" & FLS(" Field3", 16);
    --// this 'magically' declares Msg as a String(1 .. Something)
    --// with the right Something

begin
   Open_Log();

   Log_To_File("# " & Msg);
   Log_To_File("# " & Fill_String(Msg'Last, '-')); --'
end;
like image 23
user275257 Avatar answered Oct 10 '22 19:10

user275257