+ if (octal || hex) {
+ unsigned long sval;
+ sscanf (s, scanFmt, &sval);
+ dval=sval;
+ } else {
+ sscanf (s, scanFmt, &dval);
+ }
+
+ /* Setup the flags first */
+ /* set the _long flag if 'lL' is found */
+ if (strchr (s, 'l') || strchr (s, 'L')) {
+ SPEC_NOUN (val->type) = V_INT;
+ SPEC_LONG (val->type) = 1;
+ }
+
+ /* set the unsigned flag if 'uU' is found */
+ if (strchr (s, 'u') || strchr (s, 'U')) {
+ SPEC_USIGN (val->type) = 1;
+ }
+
+ if (dval<0) { // "-28u" will still be signed and negative
+ if (dval<-128) { // check if we have to promote to int
+ SPEC_NOUN (val->type) = V_INT;
+ }
+ if (dval<-32768) { // check if we have to promote to long int
+ SPEC_LONG (val->type) = 1;
+ }
+ } else { // >=0
+ if (dval>0xff || /* check if we have to promote to int */
+ SPEC_USIGN (val->type)) { /* if it's unsigned, we can't use unsigned
+ char. After an integral promotion it will
+ be a signed int; this certainly isn't what
+ the programer wants */
+ SPEC_NOUN (val->type) = V_INT;
+ }
+ else if (dval>0x7f && !SPEC_USIGN (val->type)) { // check if we have to promote to int
+#if 0
+ if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */
+ dval<=0xff) {
+ SPEC_USIGN (val->type) = 1;
+ } else {
+ SPEC_NOUN (val->type) = V_INT;
+ }
+#else
+ /* this is quite agressive: 'unsigned char' will be promoted to 'signed int',
+ so that the signedness of a char shouldn't matter */