/* valueFromLit - creates a value from a literal */
/*-----------------------------------------------------------------*/
value *
-valueFromLit (float lit)
+valueFromLit (double lit)
{
char buffer[50];
else
sval = atol (s);
-
- if (SPEC_LONG (val->type) || sval > 32768)
- {
+ // check if we have to promote to long
+ if (SPEC_LONG (val->type) ||
+ (SPEC_USIGN(val->type) && sval>0xffff) ||
+ (!SPEC_USIGN(val->type) && ((long)sval>32767 || (long)sval<-32768))) {
if (SPEC_USIGN (val->type))
SPEC_CVAL (val->type).v_ulong = sval;
else
SPEC_CVAL (val->type).v_long = sval;
SPEC_LONG (val->type) = 1;
+ return val;
}
+
+ if (SPEC_USIGN (val->type))
+ SPEC_CVAL (val->type).v_uint = sval;
else
+ SPEC_CVAL (val->type).v_int = sval;
+
+
+ // check if we can make it a char
+ if ((SPEC_USIGN(val->type) && sval < 256) ||
+ (!SPEC_USIGN(val->type) && ((long)sval<127 && (long)sval>-128))) {
+ SPEC_NOUN (val->etype) = V_CHAR;
+ }
+ return val;
+}
+
+/*! /fn char hexEscape(char **src)
+
+ /param src Pointer to 'x' from start of hex character value
+*/
+
+char hexEscape(char **src)
+
+{
+char *s ;
+unsigned long value ;
+
+(*src)++ ; /* Skip over the 'x' */
+s = *src ; /* Save for error detection */
+
+value = strtol (*src, src, 16);
+
+if (s == *src)
+ {
+ // no valid hex found
+ werror(E_INVALID_HEX);
+ }
+
+else
+ {
+ if (value > 255)
{
- if (SPEC_USIGN (val->type))
- SPEC_CVAL (val->type).v_uint = sval;
- else
- SPEC_CVAL (val->type).v_int = sval;
+ werror(W_ESC_SEQ_OOR_FOR_CHAR);
}
+ }
- // check the size and make it a short if required
- if (sval < 256)
- SPEC_SHORT (val->etype) = 1;
+return (char) value;
+}
+/*------------------------------------------------------------------*/
+/* octalEscape - process an octal constant of max three digits */
+/* return the octal value, throw a warning for illegal octal */
+/* adjust src to point at the last proccesed char */
+/*------------------------------------------------------------------*/
- return val;
+char octalEscape (char **str) {
+ int digits;
+ unsigned value=0;
+ for (digits=0; digits<3; digits++) {
+ if (**str>='0' && **str<='7') {
+ value = value*8 + (**str-'0');
+ (*str)++;
+ } else {
+ break;
+ }
+ }
+ if (digits) {
+ if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
+ werror (W_ESC_SEQ_OOR_FOR_CHAR);
+ }
+ }
+ return value;
}
-/*------------------------------------------------------------------*/
-/* copyStr - copies src to dest ignoring leading & trailing \"s */
-/*------------------------------------------------------------------*/
-void
+/*!
+ /fn int copyStr (char *dest, char *src)
+
+ Copies a source string to a dest buffer interpreting escape sequences
+ and special characters
+
+ /param dest Buffer to receive the resultant string
+ /param src Buffer containing the source string with escape sequecnes
+ /return Number of characters in output string
+
+*/
+
+int
copyStr (char *dest, char *src)
+
{
- unsigned int x;
+ char *OriginalDest = dest ;
+
while (*src)
{
if (*src == '\"')
case 'a':
*dest++ = '\a';
break;
+
case '0':
- /* embedded octal or hex constant */
- if (*(src + 1) == 'x' ||
- *(src + 1) == 'X')
- {
- x = strtol (src, &src, 16);
- *dest++ = x;
- }
- else
- {
- /* must be octal */
- x = strtol (src, &src, 8);
- *dest++ = x;
- }
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ *dest++ = octalEscape(&src);
+ src-- ;
break;
+ case 'x':
+ *dest++ = hexEscape(&src) ;
+ src-- ;
+ break ;
+
case '\\':
*dest++ = '\\';
break;
*dest++ = *src++;
}
- *dest = '\0';
+ *dest++ = '\0';
+
+ return dest - OriginalDest ;
}
/*------------------------------------------------------------------*/
/* get a declarator */
val->type = newLink ();
DCL_TYPE (val->type) = ARRAY;
- DCL_ELEM (val->type) = strlen (s) - 1;
val->type->next = val->etype = newLink ();
val->etype->class = SPECIFIER;
SPEC_NOUN (val->etype) = V_CHAR;
SPEC_SCLS (val->etype) = S_LITERAL;
SPEC_CVAL (val->etype).v_char = Safe_calloc (1, strlen (s) + 1);
- copyStr (SPEC_CVAL (val->etype).v_char, s);
+ DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
+
return val;
}
charVal (char *s)
{
value *val;
+// unsigned uValue ;
val = newValue ();
case '\"':
SPEC_CVAL (val->type).v_int = '\"';
break;
- case '0':
- sscanf (s, "%o", &SPEC_CVAL (val->type).v_int);
+
+ case '0' :
+ case '1' :
+ case '2' :
+ case '3' :
+ case '4' :
+ case '5' :
+ case '6' :
+ case '7' :
+ SPEC_CVAL (val->type).v_int = octalEscape(&s);
break;
+
case 'x':
- s++; /* go behond the 'x' */
- sscanf (s, "%x", &SPEC_CVAL (val->type).v_int);
+ SPEC_CVAL (val->type).v_int = hexEscape(&s) ;
break;
+
default:
SPEC_CVAL (val->type).v_int = *s;
break;
if (SPEC_LONG (val->etype))
{
if (SPEC_USIGN (val->etype))
- SPEC_CVAL (val->etype).v_ulong = -SPEC_CVAL (val->etype).v_ulong;
+ SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
else
SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
}
else
{
if (SPEC_USIGN (val->etype))
- SPEC_CVAL (val->etype).v_uint = -SPEC_CVAL (val->etype).v_uint;
+ SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
else
SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
}
val->etype = getSpec (val->type);
return val;
}
+
+/*-----------------------------------------------------------------*/
+/* valForCastAggr - will return value for a cast of an aggregate */
+/* with no constant */
+/*-----------------------------------------------------------------*/
+value *
+valForCastArr (ast * aexpr, sym_link * type)
+{
+ value *val;
+
+ if (!IS_AST_SYM_VALUE (aexpr))
+ return NULL;
+
+ val = newValue ();
+
+ sprintf (val->name, "(%s)",
+ AST_SYMBOL (aexpr)->rname);
+
+ val->type = type;
+ val->etype = getSpec (val->type);
+ return val;
+}