Merge change 7456

* changes:
  init: Change owner of /dev/uinput to system
diff --git a/libacc/acc.cpp b/libacc/acc.cpp
index 36f30a1..a84bd91 100644
--- a/libacc/acc.cpp
+++ b/libacc/acc.cpp
@@ -3425,6 +3425,17 @@
         return isalnum(ch) | (ch == '_');
     }
 
+    int decodeHex(int c) {
+        if (isdigit(c)) {
+            c -= '0';
+        } else if (c <= 'F') {
+            c = c - 'A' + 10;
+        } else {
+            c =c - 'a' + 10;
+        }
+        return c;
+    }
+
     /* read a character constant, advances ch to after end of constant */
     int getq() {
         int val = ch;
@@ -3448,15 +3459,7 @@
                 } else {
                     val = 0;
                     while (isxdigit(ch)) {
-                        int d = ch;
-                        if (isdigit(d)) {
-                            d -= '0';
-                        } else if (d <= 'F') {
-                            d = d - 'A' + 10;
-                        } else {
-                            d = d - 'a' + 10;
-                        }
-                        val = (val << 4) + d;
+                        val = (val << 4) + decodeHex(ch);
                         inp();
                     }
                 }
@@ -3535,32 +3538,35 @@
     void parseFloat() {
         tok = TOK_NUM_DOUBLE;
         // mTokenString already has the integral part of the number.
+        if(mTokenString.len() == 0) {
+            mTokenString.append('0');
+        }
         acceptCh('.');
         acceptDigitsCh();
-        bool doExp = true;
         if (acceptCh('e') || acceptCh('E')) {
-            // Don't need to do any extra work
-        } else if (ch == 'f' || ch == 'F') {
-            pdef('e'); // So it can be parsed by strtof.
-            inp();
-            tok = TOK_NUM_FLOAT;
-        } else {
-            doExp = false;
+            acceptCh('-') || acceptCh('+');
+            acceptDigitsCh();
         }
-        if (doExp) {
-            bool digitsRequired = acceptCh('-');
-            bool digitsFound = acceptDigitsCh();
-            if (digitsRequired && ! digitsFound) {
-                error("malformed exponent");
-            }
+        if (ch == 'f' || ch == 'F') {
+            tok = TOK_NUM_FLOAT;
+            inp();
+        } else if (ch == 'l' || ch == 'L') {
+            inp();
+            error("Long floating point constants not supported.");
         }
         char* pText = mTokenString.getUnwrapped();
+        char* pEnd = pText + strlen(pText);
+        char* pEndPtr = 0;
+        errno = 0;
         if (tok == TOK_NUM_FLOAT) {
-            tokd = strtof(pText, 0);
+            tokd = strtof(pText, &pEndPtr);
         } else {
-            tokd = strtod(pText, 0);
+            tokd = strtod(pText, &pEndPtr);
         }
-        //fprintf(stderr, "float constant: %s (%d) %g\n", pText, tok, tokd);
+        if (errno || pEndPtr != pEnd) {
+            error("Can't parse constant: %s", pText);
+        }
+        // fprintf(stderr, "float constant: %s (%d) %g\n", pText, tok, tokd);
     }
 
     void next() {
@@ -3584,35 +3590,66 @@
         tokl = 0;
         tok = ch;
         /* encode identifiers & numbers */
-        if (isid()) {
+        if (isdigit(ch) || ch == '.') {
+            // Start of a numeric constant. Could be integer, float, or
+            // double, won't know until we look further.
+            mTokenString.clear();
+            pdef(ch);
+            inp();
+            int base = 10;
+            if (tok == '0') {
+                if (ch == 'x' || ch == 'X') {
+                    base = 16;
+                    tok = TOK_NUM;
+                    tokc = 0;
+                    inp();
+                    while ( isxdigit(ch) ) {
+                        tokc = (tokc << 4) + decodeHex(ch);
+                        inp();
+                    }
+                } else if (isoctal(ch)){
+                    base = 8;
+                    tok = TOK_NUM;
+                    tokc = 0;
+                    while ( isoctal(ch) ) {
+                        tokc = (tokc << 3) + (ch - '0');
+                        inp();
+                    }
+                }
+            } else if (isdigit(tok)){
+                acceptDigitsCh();
+            }
+            if (base == 10) {
+                if (tok == '.' || ch == '.' || ch == 'e' || ch == 'E') {
+                    parseFloat();
+                } else {
+                    // It's an integer constant
+                    char* pText = mTokenString.getUnwrapped();
+                    char* pEnd = pText + strlen(pText);
+                    char* pEndPtr = 0;
+                    errno = 0;
+                    tokc = strtol(pText, &pEndPtr, base);
+                    if (errno || pEndPtr != pEnd) {
+                        error("Can't parse constant: %s %d %d", pText, base, errno);
+                    }
+                    tok = TOK_NUM;
+                }
+            }
+        } else if (isid()) {
             mTokenString.clear();
             while (isid()) {
                 pdef(ch);
                 inp();
             }
-            if (isdigit(tok)) {
-                // Start of a numeric constant. Could be integer, float, or
-                // double, won't know until we look further.
-                if (ch == '.' || ch == 'e' || ch == 'e'
-                    || ch == 'f' || ch == 'F')  {
-                    parseFloat();
-                } else {
-                    // It's an integer constant
-                    tokc = strtol(mTokenString.getUnwrapped(), 0, 0);
-                    tok = TOK_NUM;
-                }
-            } else {
-                tok = mTokenTable.intern(mTokenString.getUnwrapped(),
-                                         mTokenString.len());
-                // Is this a macro?
-                char* pMacroDefinition = mTokenTable[tok].mpMacroDefinition;
-                if(pMacroDefinition) {
-                    // Yes, it is a macro
-                    dptr = pMacroDefinition;
-                    dch = ch;
-                    inp();
-                    next();
-                }
+            tok = mTokenTable.intern(mTokenString.getUnwrapped(), mTokenString.len());
+            // Is this a macro?
+            char* pMacroDefinition = mTokenTable[tok].mpMacroDefinition;
+            if (pMacroDefinition) {
+                // Yes, it is a macro
+                dptr = pMacroDefinition;
+                dch = ch;
+                inp();
+                next();
             }
         } else {
             inp();
diff --git a/libacc/tests/data/float.c b/libacc/tests/data/float.c
index 8625cf1..f48b3d1 100644
--- a/libacc/tests/data/float.c
+++ b/libacc/tests/data/float.c
@@ -17,6 +17,11 @@
 float f0, f1;
 double d0, d1;
 
+void testParseConsts() {
+    printf("Constants: %g %g %g %g %g %g %g %g %g\n", 0e1, 0E1, 0.f, .01f,
+          .01e0f, 1.0e-1, 1.0e1, 1.0e+1,
+          .1f);
+}
 void testVars(float arg0, float arg1, double arg2, double arg3) {
     float local0, local1;
     double local2, local3;
@@ -41,6 +46,7 @@
 }
 
 int main() {
+    testParseConsts();
     printf("int: %d float: %g double: %g\n", 1, 2.2f, 3.3);
     printf(" ftoi(1.4f)=%d\n", ftoi(1.4f));
     printf(" dtoi(2.4)=%d\n", dtoi(2.4));
diff --git a/libacc/tests/test.py b/libacc/tests/test.py
index bb9ef01..8e4795f 100644
--- a/libacc/tests/test.py
+++ b/libacc/tests/test.py
@@ -174,7 +174,18 @@
     def testRunFloat(self):
         self.compileCheck(["-R", "data/float.c"],
             "Executing compiled code:\nresult: 0\n",
-            "int: 1 float: 2.2 double: 3.3\n ftoi(1.4f)=1\n dtoi(2.4)=2\n itof(3)=3\n itod(4)=4\nglobals: 1 2 3 4\nargs: 1 2 3 4\nlocals: 1 2 3 4\ncast rval: 2 4\ncast lval: 1.1 2 3.3 4\n")
+            """Constants: 0 0 0 0.01 0.01 0.1 10 10 0.1
+int: 1 float: 2.2 double: 3.3
+ ftoi(1.4f)=1
+ dtoi(2.4)=2
+ itof(3)=3
+ itod(4)=4
+globals: 1 2 3 4
+args: 1 2 3 4
+locals: 1 2 3 4
+cast rval: 2 4
+cast lval: 1.1 2 3.3 4
+""")
         
     def testRunFlops(self):
         self.compileCheck(["-R", "data/flops.c"],