return prev;
}
+bool
+convertIListToConstList(initList *src, literalList **lList)
+{
+ initList *iLoop;
+ literalList *head, *last, *newL;
+
+ head = last = NULL;
+
+ if (!src || src->type != INIT_DEEP)
+ {
+ return FALSE;
+ }
+
+ iLoop = src->init.deep;
+
+ while (iLoop)
+ {
+ if (iLoop->type != INIT_NODE)
+ {
+ return FALSE;
+ }
+
+ if (!IS_AST_LIT_VALUE(decorateType(resolveSymbols(iLoop->init.node))))
+ {
+ return FALSE;
+ }
+ iLoop = iLoop->next;
+ }
+
+ // We've now established that the initializer list contains only literal values.
+
+ iLoop = src->init.deep;
+ while (iLoop)
+ {
+ double val = AST_LIT_VALUE(iLoop->init.node);
+
+ if (last && last->literalValue == val)
+ {
+ last->count++;
+ }
+ else
+ {
+ newL = Safe_malloc(sizeof(literalList));
+ newL->literalValue = val;
+ newL->count = 1;
+ newL->next = NULL;
+
+ if (last)
+ {
+ last->next = newL;
+ }
+ else
+ {
+ head = newL;
+ }
+ last = newL;
+ }
+ iLoop = iLoop->next;
+ }
+
+ if (!head)
+ {
+ return FALSE;
+ }
+
+ *lList = head;
+ return TRUE;
+}
+
+literalList *
+copyLiteralList(literalList *src)
+{
+ literalList *head, *prev, *newL;
+
+ head = prev = NULL;
+
+ while (src)
+ {
+ newL = Safe_malloc(sizeof(literalList));
+
+ newL->literalValue = src->literalValue;
+ newL->count = src->count;
+ newL->next = NULL;
+
+ if (prev)
+ {
+ prev->next = newL;
+ }
+ else
+ {
+ head = newL;
+ }
+ prev = newL;
+ src = src->next;
+ }
+
+ return head;
+}
+
+
+
/*------------------------------------------------------------------*/
/* copyIlist - copy initializer list */
/*------------------------------------------------------------------*/
/* 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
- {
- if (SPEC_USIGN (val->type))
- SPEC_CVAL (val->type).v_uint = sval;
- else
- SPEC_CVAL (val->type).v_int = sval;
- }
+ 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;
+}
- // check the size and make it a short if required
- if (sval < 256)
- SPEC_SHORT (val->etype) = 1;
+/*! /fn char hexEscape(char **src)
- return val;
+ /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)
+ {
+ werror(W_ESC_SEQ_OOR_FOR_CHAR);
+ }
+ }
+
+return (char) value;
+}
/*------------------------------------------------------------------*/
/* octalEscape - process an octal constant of max three digits */
/* return the octal value, throw a warning for illegal octal */
if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
werror (W_ESC_SEQ_OOR_FOR_CHAR);
}
- (*str)--;
}
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)
+
{
+ char *OriginalDest = dest ;
+
while (*src)
{
if (*src == '\"')
case '6':
case '7':
*dest++ = octalEscape(&src);
+ src-- ;
break;
- case 'x': {
- char *s=++src;
- unsigned long value=strtol (src, &src, 16);
-
- if (s==src) {
- // no valid hex found
- werror(E_INVALID_HEX);
- } else {
- if (value>255) {
- werror(W_ESC_SEQ_OOR_FOR_CHAR);
- }
- *dest++ = value;
- src--;
- }
- break;
- }
+ case 'x':
+ *dest++ = hexEscape(&src) ;
+ src-- ;
+ break ;
case '\\':
*dest++ = '\\';
*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;
ilist = ilist->init.deep;
/* if type is a character array and there is only one
- initialiser then get the length of the string */
+ (string) initialiser then get the length of the string */
if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next)
{
ast *iast = ilist->init.node;
werror (E_INIT_WRONG);
return 0;
}
- if (!IS_ARRAY (v->type) || !IS_CHAR (v->etype))
+
+ if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
+ // yep, it's a string
{
- werror (E_INIT_WRONG);
- return 0;
+ return DCL_ELEM (v->type);
}
- return DCL_ELEM (v->type);
}
i = 0;