-- --
-- B o d y --
-- --
--- Copyright (C) 2002-2007, Free Software Foundation, Inc. --
+-- Copyright (C) 2002-2008, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
-- Preprocess --
----------------
- procedure Preprocess is
+ procedure Preprocess (Source_Modified : out Boolean) is
Start_Of_Processing : Source_Ptr;
Cond : Boolean;
Preprocessor_Line : Boolean := False;
+ No_Error_Found : Boolean := True;
+ Modified : Boolean := False;
procedure Output (From, To : Source_Ptr);
-- Output the characters with indices From .. To in the buffer
-- Preprocessor line
if Token = Tok_Special and then Special_Character = '#' then
- Preprocessor_Line := True;
- Scan.all;
-
- case Token is
-
- -- #if
-
- when Tok_If =>
- declare
- If_Ptr : constant Source_Ptr := Token_Ptr;
-
- begin
- Scan.all;
- Cond := Expression (not Deleting);
-
- -- Check for an eventual "then"
-
- if Token = Tok_Then then
- Scan.all;
- end if;
-
- -- It is an error to have trailing characters after
- -- the condition or "then".
-
- if Token /= Tok_End_Of_Line
- and then Token /= Tok_EOF
- then
- Error_Msg
- ("extraneous text on preprocessor line",
- Token_Ptr);
- Go_To_End_Of_Line;
- end if;
-
- declare
- -- Set the initial state of this new "#if".
- -- This must be done before incrementing the
- -- Last of the table, otherwise function
- -- Deleting does not report the correct value.
-
- New_State : constant Pp_State :=
- (If_Ptr => If_Ptr,
- Else_Ptr => 0,
- Deleting => Deleting or (not Cond),
- Match_Seen => Deleting or Cond);
-
- begin
- Pp_States.Increment_Last;
- Pp_States.Table (Pp_States.Last) := New_State;
- end;
- end;
-
- -- #elsif
+ Modified := True;
+ Preprocessor_Line := True;
+ Scan.all;
- when Tok_Elsif =>
- Cond := False;
+ case Token is
- if Pp_States.Last = 0
- or else Pp_States.Table (Pp_States.Last).Else_Ptr
- /= 0
- then
- Error_Msg ("no IF for this ELSIF", Token_Ptr);
+ -- #if
- else
- Cond :=
- not Pp_States.Table (Pp_States.Last).Match_Seen;
- end if;
+ when Tok_If =>
+ declare
+ If_Ptr : constant Source_Ptr := Token_Ptr;
+ begin
Scan.all;
- Cond := Expression (Cond);
+ Cond := Expression (not Deleting);
-- Check for an eventual "then"
Error_Msg
("extraneous text on preprocessor line",
Token_Ptr);
-
+ No_Error_Found := False;
Go_To_End_Of_Line;
end if;
- -- Depending on the value of the condition, set the
- -- new values of Deleting and Match_Seen.
- if Pp_States.Last > 0 then
- if Pp_States.Table (Pp_States.Last).Match_Seen then
- Pp_States.Table (Pp_States.Last).Deleting :=
- True;
- else
- if Cond then
- Pp_States.Table (Pp_States.Last).Match_Seen :=
- True;
- Pp_States.Table (Pp_States.Last).Deleting :=
- False;
- end if;
- end if;
- end if;
+ declare
+ -- Set the initial state of this new "#if". This
+ -- must be done before incrementing the Last of
+ -- the table, otherwise function Deleting does
+ -- not report the correct value.
- -- #else
+ New_State : constant Pp_State :=
+ (If_Ptr => If_Ptr,
+ Else_Ptr => 0,
+ Deleting => Deleting or (not Cond),
+ Match_Seen => Deleting or Cond);
- when Tok_Else =>
- if Pp_States.Last = 0 then
- Error_Msg ("no IF for this ELSE", Token_Ptr);
+ begin
+ Pp_States.Increment_Last;
+ Pp_States.Table (Pp_States.Last) := New_State;
+ end;
+ end;
- elsif
- Pp_States.Table (Pp_States.Last).Else_Ptr /= 0
- then
- Error_Msg ("duplicate ELSE line", Token_Ptr);
- end if;
+ -- #elsif
- -- Set the possibly new values of Deleting and
- -- Match_Seen.
+ when Tok_Elsif =>
+ Cond := False;
- if Pp_States.Last > 0 then
- if Pp_States.Table (Pp_States.Last).Match_Seen then
- Pp_States.Table (Pp_States.Last).Deleting :=
- True;
+ if Pp_States.Last = 0
+ or else Pp_States.Table (Pp_States.Last).Else_Ptr /= 0
+ then
+ Error_Msg ("no IF for this ELSIF", Token_Ptr);
+ No_Error_Found := False;
- else
+ else
+ Cond :=
+ not Pp_States.Table (Pp_States.Last).Match_Seen;
+ end if;
+
+ Scan.all;
+ Cond := Expression (Cond);
+
+ -- Check for an eventual "then"
+
+ if Token = Tok_Then then
+ Scan.all;
+ end if;
+
+ -- It is an error to have trailing characters after
+ -- the condition or "then".
+
+ if Token /= Tok_End_Of_Line
+ and then Token /= Tok_EOF
+ then
+ Error_Msg
+ ("extraneous text on preprocessor line",
+ Token_Ptr);
+ No_Error_Found := False;
+
+ Go_To_End_Of_Line;
+ end if;
+
+ -- Depending on the value of the condition, set the
+ -- new values of Deleting and Match_Seen.
+ if Pp_States.Last > 0 then
+ if Pp_States.Table (Pp_States.Last).Match_Seen then
+ Pp_States.Table (Pp_States.Last).Deleting := True;
+ else
+ if Cond then
Pp_States.Table (Pp_States.Last).Match_Seen :=
True;
Pp_States.Table (Pp_States.Last).Deleting :=
False;
end if;
+ end if;
+ end if;
- -- Set the Else_Ptr to check for illegal #elsif
- -- later.
+ -- #else
- Pp_States.Table (Pp_States.Last).Else_Ptr :=
- Token_Ptr;
- end if;
+ when Tok_Else =>
+ if Pp_States.Last = 0 then
+ Error_Msg ("no IF for this ELSE", Token_Ptr);
+ No_Error_Found := False;
- Scan.all;
+ elsif
+ Pp_States.Table (Pp_States.Last).Else_Ptr /= 0
+ then
+ Error_Msg ("duplicate ELSE line", Token_Ptr);
+ No_Error_Found := False;
+ end if;
- -- It is an error to have characters after "#else"
- if Token /= Tok_End_Of_Line
- and then Token /= Tok_EOF
- then
- Error_Msg
- ("extraneous text on preprocessor line",
- Token_Ptr);
- Go_To_End_Of_Line;
- end if;
+ -- Set the possibly new values of Deleting and
+ -- Match_Seen.
- -- #end if;
+ if Pp_States.Last > 0 then
+ if Pp_States.Table (Pp_States.Last).Match_Seen then
+ Pp_States.Table (Pp_States.Last).Deleting :=
+ True;
- when Tok_End =>
- if Pp_States.Last = 0 then
- Error_Msg ("no IF for this END", Token_Ptr);
+ else
+ Pp_States.Table (Pp_States.Last).Match_Seen :=
+ True;
+ Pp_States.Table (Pp_States.Last).Deleting :=
+ False;
end if;
+ -- Set the Else_Ptr to check for illegal #elsif
+ -- later.
+
+ Pp_States.Table (Pp_States.Last).Else_Ptr :=
+ Token_Ptr;
+ end if;
+
+ Scan.all;
+
+ -- It is an error to have characters after "#else"
+ if Token /= Tok_End_Of_Line
+ and then Token /= Tok_EOF
+ then
+ Error_Msg
+ ("extraneous text on preprocessor line",
+ Token_Ptr);
+ No_Error_Found := False;
+ Go_To_End_Of_Line;
+ end if;
+
+ -- #end if;
+
+ when Tok_End =>
+ if Pp_States.Last = 0 then
+ Error_Msg ("no IF for this END", Token_Ptr);
+ No_Error_Found := False;
+ end if;
+
+ Scan.all;
+
+ if Token /= Tok_If then
+ Error_Msg ("IF expected", Token_Ptr);
+ No_Error_Found := False;
+
+ else
Scan.all;
- if Token /= Tok_If then
- Error_Msg ("IF expected", Token_Ptr);
+ if Token /= Tok_Semicolon then
+ Error_Msg ("`;` Expected", Token_Ptr);
+ No_Error_Found := False;
else
Scan.all;
- if Token /= Tok_Semicolon then
- Error_Msg ("`;` Expected", Token_Ptr);
-
- else
- Scan.all;
-
- -- It is an error to have character after
- -- "#end if;".
- if Token /= Tok_End_Of_Line
- and then Token /= Tok_EOF
- then
- Error_Msg
- ("extraneous text on preprocessor line",
- Token_Ptr);
- end if;
+ -- It is an error to have character after
+ -- "#end if;".
+ if Token /= Tok_End_Of_Line
+ and then Token /= Tok_EOF
+ then
+ Error_Msg
+ ("extraneous text on preprocessor line",
+ Token_Ptr);
+ No_Error_Found := False;
end if;
end if;
+ end if;
- -- In case of one of the errors above, skip the tokens
- -- until the end of line is reached.
+ -- In case of one of the errors above, skip the tokens
+ -- until the end of line is reached.
- Go_To_End_Of_Line;
+ Go_To_End_Of_Line;
- -- Decrement the depth of the #if stack
+ -- Decrement the depth of the #if stack
- if Pp_States.Last > 0 then
- Pp_States.Decrement_Last;
- end if;
+ if Pp_States.Last > 0 then
+ Pp_States.Decrement_Last;
+ end if;
- -- Illegal preprocessor line
+ -- Illegal preprocessor line
- when others =>
- if Pp_States.Last = 0 then
- Error_Msg ("IF expected", Token_Ptr);
+ when others =>
+ No_Error_Found := False;
- elsif
- Pp_States.Table (Pp_States.Last).Else_Ptr = 0
- then
- Error_Msg ("IF, ELSIF, ELSE, or `END IF` expected",
- Token_Ptr);
+ if Pp_States.Last = 0 then
+ Error_Msg ("IF expected", Token_Ptr);
- else
- Error_Msg ("IF or `END IF` expected", Token_Ptr);
- end if;
+ elsif
+ Pp_States.Table (Pp_States.Last).Else_Ptr = 0
+ then
+ Error_Msg ("IF, ELSIF, ELSE, or `END IF` expected",
+ Token_Ptr);
+
+ else
+ Error_Msg ("IF or `END IF` expected", Token_Ptr);
+ end if;
- -- Skip to the end of this illegal line
+ -- Skip to the end of this illegal line
- Go_To_End_Of_Line;
- end case;
+ Go_To_End_Of_Line;
+ end case;
-- Not a preprocessor line
if Token = Tok_Special
and then Special_Character = '$'
then
+ Modified := True;
+
declare
Dollar_Ptr : constant Source_Ptr := Token_Ptr;
Symbol : Symbol_Id;
for Level in reverse 1 .. Pp_States.Last loop
Error_Msg ("no `END IF` for this IF", Pp_States.Table (Level).If_Ptr);
+ No_Error_Found := False;
end loop;
+
+ Source_Modified := No_Error_Found and Modified;
end Preprocess;
end Prep;