X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCval.c;h=31b4159c0e09a9d632b410cbac3cfedcdf3312a7;hb=1578e0ccf4979a63613559cbc354fbd696b32631;hp=9b5512cee0a4e73e06558b590898ab1d2ea65f17;hpb=9be3db2ae30121352125653520083dbc47b08afe;p=fw%2Fsdcc diff --git a/src/SDCCval.c b/src/SDCCval.c index 9b5512ce..31b4159c 100644 --- a/src/SDCCval.c +++ b/src/SDCCval.c @@ -97,6 +97,107 @@ revinit (initList * val) 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 */ /*------------------------------------------------------------------*/ @@ -215,7 +316,7 @@ symbolVal (symbol * sym) /* valueFromLit - creates a value from a literal */ /*-----------------------------------------------------------------*/ value * -valueFromLit (float lit) +valueFromLit (double lit) { char buffer[50]; @@ -309,38 +410,108 @@ constVal (char *s) 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 == '\"') @@ -371,22 +542,24 @@ copyStr (char *dest, char *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; @@ -408,7 +581,9 @@ copyStr (char *dest, char *src) *dest++ = *src++; } - *dest = '\0'; + *dest++ = '\0'; + + return dest - OriginalDest ; } /*------------------------------------------------------------------*/ @@ -424,14 +599,14 @@ strVal (char *s) /* 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; } @@ -529,6 +704,7 @@ value * charVal (char *s) { value *val; +// unsigned uValue ; val = newValue (); @@ -577,13 +753,22 @@ charVal (char *s) 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; @@ -663,14 +848,14 @@ valUnaryPM (value * val) 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; } @@ -1227,7 +1412,7 @@ getNelements (sym_link * type, initList * ilist) 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; @@ -1237,12 +1422,12 @@ getNelements (sym_link * type, initList * ilist) 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;