[Ada] Portability improvement for constants related to serial ports
Arnaud Charlet
charlet@adacore.com
Mon Aug 6 08:36:00 GMT 2012
This change improves the process that generates s-oscons.ads so that
the proper unisgned values for serial ports related constants are
generated.
Tested on x86_64-pc-linux-gnu, committed on trunk
2012-08-06 Thomas Quinot <quinot@adacore.com>
* s-oscons-tmplt.c, xoscons.adb: Per the Single UNIX Specification,
types cc_t, speed_t, and tcflag_t defined in <termios.h> all are
unsigned types. Add required special handling to have their correct
unsigned values in s-oscons.ads.
-------------- next part --------------
Index: s-oscons-tmplt.c
===================================================================
--- s-oscons-tmplt.c (revision 190158)
+++ s-oscons-tmplt.c (working copy)
@@ -169,6 +169,9 @@
#define CND(name,comment) \
printf ("\n->CND:$%d:" #name ":$%d:" comment, __LINE__, ((int) _VAL (name)));
+#define CNU(name,comment) \
+ printf ("\n->CNU:$%d:" #name ":$%u:" comment, __LINE__, ((unsigned int) _VAL (name)));
+
#define CNS(name,comment) \
printf ("\n->CNS:$%d:" #name ":" name ":" comment, __LINE__);
@@ -185,6 +188,13 @@
: : "i" (__LINE__), "i" ((int) name));
/* Decimal constant in the range of type "int" */
+#define CNU(name, comment) \
+ asm volatile("\n->CNU:%0:" #name ":%1:" comment \
+ : : "i" (__LINE__), "i" ((int) name));
+/* Decimal constant in the range of type "unsigned int" (note, assembler
+ * always wants a signed int, we convert back in xoscons).
+ */
+
#define CNS(name, comment) \
asm volatile("\n->CNS:%0:" #name ":" name ":" comment \
: : "i" (__LINE__));
@@ -250,9 +260,9 @@
/*
- -----------------------------
- -- Platform identification --
- -----------------------------
+ ---------------------------------
+ -- General platform parameters --
+ ---------------------------------
type OS_Type is (Windows, VMS, Other_OS);
*/
@@ -273,6 +283,10 @@
*/
#define Target_Name TARGET
CST(Target_Name, "")
+
+#define sizeof_unsigned_int sizeof (unsigned int)
+CND(sizeof_unsigned_int, "Size of unsigned int")
+
/*
-------------------
@@ -630,210 +644,215 @@
#endif
CND(TCIFLUSH, "Flush input")
+#ifndef IXON
+# define IXON -1
+#endif
+CNU(IXON, "Output sw flow control")
+
#ifndef CLOCAL
# define CLOCAL -1
#endif
-CND(CLOCAL, "Local")
+CNU(CLOCAL, "Local")
#ifndef CRTSCTS
# define CRTSCTS -1
#endif
-CND(CRTSCTS, "Hardware flow control")
+CNU(CRTSCTS, "Output hw flow control")
#ifndef CREAD
# define CREAD -1
#endif
-CND(CREAD, "Read")
+CNU(CREAD, "Read")
#ifndef CS5
# define CS5 -1
#endif
-CND(CS5, "5 data bits")
+CNU(CS5, "5 data bits")
#ifndef CS6
# define CS6 -1
#endif
-CND(CS6, "6 data bits")
+CNU(CS6, "6 data bits")
#ifndef CS7
# define CS7 -1
#endif
-CND(CS7, "7 data bits")
+CNU(CS7, "7 data bits")
#ifndef CS8
# define CS8 -1
#endif
-CND(CS8, "8 data bits")
+CNU(CS8, "8 data bits")
#ifndef CSTOPB
# define CSTOPB -1
#endif
-CND(CSTOPB, "2 stop bits")
+CNU(CSTOPB, "2 stop bits")
#ifndef PARENB
# define PARENB -1
#endif
-CND(PARENB, "Parity enable")
+CNU(PARENB, "Parity enable")
#ifndef PARODD
# define PARODD -1
#endif
-CND(PARODD, "Parity odd")
+CNU(PARODD, "Parity odd")
#ifndef B0
# define B0 -1
#endif
-CND(B0, "0 bps")
+CNU(B0, "0 bps")
#ifndef B50
# define B50 -1
#endif
-CND(B50, "50 bps")
+CNU(B50, "50 bps")
#ifndef B75
# define B75 -1
#endif
-CND(B75, "75 bps")
+CNU(B75, "75 bps")
#ifndef B110
# define B110 -1
#endif
-CND(B110, "110 bps")
+CNU(B110, "110 bps")
#ifndef B134
# define B134 -1
#endif
-CND(B134, "134 bps")
+CNU(B134, "134 bps")
#ifndef B150
# define B150 -1
#endif
-CND(B150, "150 bps")
+CNU(B150, "150 bps")
#ifndef B200
# define B200 -1
#endif
-CND(B200, "200 bps")
+CNU(B200, "200 bps")
#ifndef B300
# define B300 -1
#endif
-CND(B300, "300 bps")
+CNU(B300, "300 bps")
#ifndef B600
# define B600 -1
#endif
-CND(B600, "600 bps")
+CNU(B600, "600 bps")
#ifndef B1200
# define B1200 -1
#endif
-CND(B1200, "1200 bps")
+CNU(B1200, "1200 bps")
#ifndef B1800
# define B1800 -1
#endif
-CND(B1800, "1800 bps")
+CNU(B1800, "1800 bps")
#ifndef B2400
# define B2400 -1
#endif
-CND(B2400, "2400 bps")
+CNU(B2400, "2400 bps")
#ifndef B4800
# define B4800 -1
#endif
-CND(B4800, "4800 bps")
+CNU(B4800, "4800 bps")
#ifndef B9600
# define B9600 -1
#endif
-CND(B9600, "9600 bps")
+CNU(B9600, "9600 bps")
#ifndef B19200
# define B19200 -1
#endif
-CND(B19200, "19200 bps")
+CNU(B19200, "19200 bps")
#ifndef B38400
# define B38400 -1
#endif
-CND(B38400, "38400 bps")
+CNU(B38400, "38400 bps")
#ifndef B57600
# define B57600 -1
#endif
-CND(B57600, "57600 bps")
+CNU(B57600, "57600 bps")
#ifndef B115200
# define B115200 -1
#endif
-CND(B115200, "115200 bps")
+CNU(B115200, "115200 bps")
#ifndef B230400
# define B230400 -1
#endif
-CND(B230400, "230400 bps")
+CNU(B230400, "230400 bps")
#ifndef B460800
# define B460800 -1
#endif
-CND(B460800, "460800 bps")
+CNU(B460800, "460800 bps")
#ifndef B500000
# define B500000 -1
#endif
-CND(B500000, "500000 bps")
+CNU(B500000, "500000 bps")
#ifndef B576000
# define B576000 -1
#endif
-CND(B576000, "576000 bps")
+CNU(B576000, "576000 bps")
#ifndef B921600
# define B921600 -1
#endif
-CND(B921600, "921600 bps")
+CNU(B921600, "921600 bps")
#ifndef B1000000
# define B1000000 -1
#endif
-CND(B1000000, "1000000 bps")
+CNU(B1000000, "1000000 bps")
#ifndef B1152000
# define B1152000 -1
#endif
-CND(B1152000, "1152000 bps")
+CNU(B1152000, "1152000 bps")
#ifndef B1500000
# define B1500000 -1
#endif
-CND(B1500000, "1500000 bps")
+CNU(B1500000, "1500000 bps")
#ifndef B2000000
# define B2000000 -1
#endif
-CND(B2000000, "2000000 bps")
+CNU(B2000000, "2000000 bps")
#ifndef B2500000
# define B2500000 -1
#endif
-CND(B2500000, "2500000 bps")
+CNU(B2500000, "2500000 bps")
#ifndef B3000000
# define B3000000 -1
#endif
-CND(B3000000, "3000000 bps")
+CNU(B3000000, "3000000 bps")
#ifndef B3500000
# define B3500000 -1
#endif
-CND(B3500000, "3500000 bps")
+CNU(B3500000, "3500000 bps")
#ifndef B4000000
# define B4000000 -1
#endif
-CND(B4000000, "4000000 bps")
+CNU(B4000000, "4000000 bps")
/*
Index: xoscons.adb
===================================================================
--- xoscons.adb (revision 190155)
+++ xoscons.adb (working copy)
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2008-2009, Free Software Foundation, Inc. --
+-- Copyright (C) 2008-2012, 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- --
@@ -73,13 +73,18 @@
type Asm_Info_Kind is
(CND, -- Named number (decimal)
+ CNU, -- Named number (decimal, unsigned)
CNS, -- Named number (freeform text)
C, -- Constant object
TXT); -- Literal text
-- Recognized markers found in assembly file. These markers are produced by
-- the same-named macros from the C template.
+ subtype Asm_Int_Kind is Asm_Info_Kind range CND .. CNU;
+ -- Asm_Info_Kind values with int values in input
+
subtype Named_Number is Asm_Info_Kind range CND .. CNS;
+ -- Asm_Info_Kind values with named numbers in output
type Asm_Info (Kind : Asm_Info_Kind := TXT) is record
Line_Number : Integer;
@@ -98,7 +103,7 @@
-- Value for CNS / C constant
Int_Value : Int_Value_Type;
- -- Value for CND constant
+ -- Value for CND / CNU constant
Comment : String_Access;
-- Additional descriptive comment for constant, or free-form text (TXT)
@@ -116,6 +121,9 @@
Max_Constant_Type_Len : Natural := 0;
-- Lengths of longest name and longest value
+ Size_Of_Unsigned_Int : Integer := 0;
+ -- Size of unsigned int on target
+
type Language is (Lang_Ada, Lang_C);
procedure Output_Info
@@ -195,11 +203,12 @@
- Info.Constant_Name'Length));
end case;
- if Info.Kind = CND then
+ if Info.Kind in Asm_Int_Kind then
if not Info.Int_Value.Positive then
Put ("-");
end if;
Put (Trim (Info.Int_Value.Abs_Value'Img, Side => Left));
+
else
declare
Is_String : constant Boolean :=
@@ -246,7 +255,7 @@
procedure Find_Colon (Index : in out Integer);
-- Increment Index until the next colon in Line
- function Parse_Int (S : String) return Int_Value_Type;
+ function Parse_Int (S : String; K : Asm_Int_Kind) return Int_Value_Type;
-- Parse a decimal number, preceded by an optional '$' or '#' character,
-- and return its value.
@@ -275,9 +284,12 @@
-- Parse_Int --
---------------
- function Parse_Int (S : String) return Int_Value_Type is
+ function Parse_Int
+ (S : String;
+ K : Asm_Int_Kind) return Int_Value_Type
+ is
First : Integer := S'First;
- Positive : Boolean;
+ Result : Int_Value_Type;
begin
-- On some platforms, immediate integer values are prefixed with
-- a $ or # character in assembly output.
@@ -287,15 +299,26 @@
end if;
if S (First) = '-' then
- Positive := False;
+ Result.Positive := False;
First := First + 1;
else
- Positive := True;
+ Result.Positive := True;
end if;
- return (Positive => Positive,
- Abs_Value => Long_Unsigned'Value (S (First .. S'Last)));
+ Result.Abs_Value := Long_Unsigned'Value (S (First .. S'Last));
+ if not Result.Positive and then K = CNU then
+ -- Negative value, but unsigned expected: take 2's complement
+ -- reciprocical value.
+
+ Result.Abs_Value := ((not Result.Abs_Value) + 1)
+ and
+ (Shift_Left (1, Size_Of_Unsigned_Int) - 1);
+ Result.Positive := True;
+ end if;
+
+ return Result;
+
exception
when E : others =>
Put_Line (Standard_Error, "can't parse decimal value: " & S);
@@ -315,10 +338,10 @@
Find_Colon (Index2);
Info.Line_Number :=
- Integer (Parse_Int (Line (Index1 .. Index2 - 1)).Abs_Value);
+ Integer (Parse_Int (Line (Index1 .. Index2 - 1), CNU).Abs_Value);
case Info.Kind is
- when CND | CNS | C =>
+ when CND | CNU | CNS | C =>
Index1 := Index2 + 1;
Find_Colon (Index2);
@@ -340,15 +363,24 @@
Find_Colon (Index2);
end if;
- if Info.Kind = CND then
- Info.Int_Value := Parse_Int (Line (Index1 .. Index2 - 1));
- Info.Value_Len := Index2 - Index1 - 1;
+ if Info.Kind = CND or else Info.Kind = CNU then
+ Info.Int_Value :=
+ Parse_Int (Line (Index1 .. Index2 - 1), Info.Kind);
+ Info.Value_Len := Info.Int_Value.Abs_Value'Img'Length - 1;
+ if not Info.Int_Value.Positive then
+ Info.Value_Len := Info.Value_Len + 1;
+ end if;
else
Info.Text_Value := Field_Alloc;
Info.Value_Len := Info.Text_Value'Length;
end if;
+ if Info.Constant_Name.all = "sizeof_unsigned_int" then
+ Size_Of_Unsigned_Int :=
+ 8 * Integer (Info.Int_Value.Abs_Value);
+ end if;
+
when others =>
null;
end case;
More information about the Gcc-patches
mailing list