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"],