* .version: Updated to 2.3.1
[fw/sdcc] / src / SDCCglue.c
index 31c1394a4b093b06da1f17fc82f6515abeff90ef..d74a0f3bea06d25dc9d449303768cd12e470b5e7 100644 (file)
 #include "newalloc.h"
 
 #if !defined(__BORLANDC__) && !defined(_MSC_VER)
-#if 0                          /* This should no longer be necessary. */
-// This is a bit messy because we define link ourself
-#define link NoLiNk
 #include <unistd.h>
-#undef link
-#else
-
-#include <unistd.h>
-#endif
-#else
-// No unistd.h in Borland C++
 #endif
 
 symbol *interrupts[256];
@@ -48,7 +38,7 @@ set *publics = NULL;          /* public variables */
 set *externs = NULL;           /* Varibles that are declared as extern */
 
 /* TODO: this should be configurable (DS803C90 uses more than 6) */
-int maxInterrupts = 6;
+unsigned maxInterrupts = 6;
 int allocInfo = 1;
 symbol *mainf;
 extern char *VersionString;
@@ -102,49 +92,51 @@ copyFile (FILE * dest, FILE * src)
 char *
 aopLiteralLong (value * val, int offset, int size)
 {
-  char *rs;
-  union
-    {
-      float f;
-      unsigned char c[4];
-    }
-  fl;
+       char *rs;
+       union {
+               float f;
+               unsigned char c[4];
+       }
+       fl;
 
-  /* if it is a float then it gets tricky */
-  /* otherwise it is fairly simple */
-  if (!IS_FLOAT (val->type))
-    {
-      unsigned long v = floatFromVal (val);
+       if (!val) {
+         // assuming we have been warned before
+         val=constVal("0");
+       }
 
-      v >>= (offset * 8);
-      switch (size)
-       {
-       case 1:
-         tsprintf (buffer, "!immedbyte", (unsigned int) v & 0xff);
-         break;
-       case 2:
-         tsprintf (buffer, "!immedword", (unsigned int) v & 0xffff);
-         break;
-       default:
-         /* Hmm.  Too big for now. */
-         assert (0);
+       /* if it is a float then it gets tricky */
+       /* otherwise it is fairly simple */
+       if (!IS_FLOAT (val->type)) {
+               unsigned long v = (unsigned long) floatFromVal (val);
+
+               v >>= (offset * 8);
+               switch (size) {
+               case 1:
+                       tsprintf (buffer, "!immedbyte", (unsigned int) v & 0xff);
+                       break;
+               case 2:
+                       tsprintf (buffer, "!immedword", (unsigned int) v & 0xffff);
+                       break;
+               default:
+                       /* Hmm.  Too big for now. */
+                       assert (0);
+               }
+               rs = Safe_calloc (1, strlen (buffer) + 1);
+               return strcpy (rs, buffer);
        }
-      rs = Safe_calloc (1, strlen (buffer) + 1);
-      return strcpy (rs, buffer);
-    }
 
-  /* PENDING: For now size must be 1 */
-  assert (size == 1);
+       /* PENDING: For now size must be 1 */
+       assert (size == 1);
 
-  /* it is type float */
-  fl.f = (float) floatFromVal (val);
+       /* it is type float */
+       fl.f = (float) floatFromVal (val);
 #ifdef _BIG_ENDIAN
-  tsprintf (buffer, "!immedbyte", fl.c[3 - offset]);
+       tsprintf (buffer, "!immedbyte", fl.c[3 - offset]);
 #else
-  tsprintf (buffer, "!immedbyte", fl.c[offset]);
+       tsprintf (buffer, "!immedbyte", fl.c[offset]);
 #endif
-  rs = Safe_calloc (1, strlen (buffer) + 1);
-  return strcpy (rs, buffer);
+       rs = Safe_calloc (1, strlen (buffer) + 1);
+       return strcpy (rs, buffer);
 }
 
 /*-----------------------------------------------------------------*/
@@ -153,7 +145,7 @@ aopLiteralLong (value * val, int offset, int size)
 char *
 aopLiteral (value * val, int offset)
 {
-  return aopLiteralLong (val, offset, 1);
+       return aopLiteralLong (val, offset, 1);
 }
 
 /*-----------------------------------------------------------------*/
@@ -162,7 +154,9 @@ aopLiteral (value * val, int offset)
 static void 
 emitRegularMap (memmap * map, bool addPublics, bool arFlag)
 {
-  symbol *sym;
+  symbol *sym, *symIval;
+  ast *ival = NULL;
+  memmap *segment;
 
   if (addPublics)
     {
@@ -192,6 +186,8 @@ emitRegularMap (memmap * map, bool addPublics, bool arFlag)
       /* if allocation required check is needed
          then check if the symbol really requires
          allocation only for local variables */
+      if (!sym->allocreq) continue;
+
       if (arFlag && !IS_AGGREGATE (sym->type) &&
          !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
          !sym->allocreq && sym->level)
@@ -203,7 +199,7 @@ emitRegularMap (memmap * map, bool addPublics, bool arFlag)
           (sym->_isparm && !IS_REGPARM (sym->etype))) &&
          addPublics &&
          !IS_STATIC (sym->etype) &&
-         (sym->used || sym->fbody))
+          (IS_FUNC(sym->type) ? (sym->used || sym->fbody) : 1))
        {
          addSetHead (&publics, sym);
        }
@@ -214,29 +210,26 @@ emitRegularMap (memmap * map, bool addPublics, bool arFlag)
        continue;
 
       /* print extra debug info if required */
-      if ((options.debug || sym->level == 0) && !options.nodebug)
-       {
-
-         cdbSymbol (sym, cdbFile, FALSE, FALSE);
-
-         if (!sym->level)      /* global */
-           if (IS_STATIC (sym->etype))
-             fprintf (map->oFile, "F%s$", moduleName);         /* scope is file */
-           else
-             fprintf (map->oFile, "G$");       /* scope is global */
+      if (options.debug) {
+       cdbSymbol (sym, cdbFile, FALSE, FALSE);
+       if (!sym->level) /* global */
+         if (IS_STATIC (sym->etype))
+           fprintf (map->oFile, "F%s$", moduleName); /* scope is file */
          else
-           /* symbol is local */
-           fprintf (map->oFile, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
-         fprintf (map->oFile, "%s$%d$%d", sym->name, sym->level, sym->block);
-       }
-
+           fprintf (map->oFile, "G$"); /* scope is global */
+       else
+         /* symbol is local */
+         fprintf (map->oFile, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
+       fprintf (map->oFile, "%s$%d$%d", sym->name, sym->level, sym->block);
+      }
+      
       /* if is has an absolute address then generate
          an equate for this no need to allocate space */
       if (SPEC_ABSA (sym->etype))
        {
-         if ((options.debug || sym->level == 0) && !options.nodebug)
+         if (options.debug) {
            fprintf (map->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
-
+         }
          fprintf (map->oFile, "%s\t=\t0x%04x\n",
                   sym->rname,
                   SPEC_ADDR (sym->etype));
@@ -244,30 +237,45 @@ emitRegularMap (memmap * map, bool addPublics, bool arFlag)
       else
        {
          /* allocate space */
-         if ((options.debug || sym->level == 0) && !options.nodebug)
+         if (options.debug) {
            fprintf (map->oFile, "==.\n");
+         }
          if (IS_STATIC (sym->etype))
            tfprintf (map->oFile, "!slabeldef\n", sym->rname);
          else
            tfprintf (map->oFile, "!labeldef\n", sym->rname);
-         tfprintf (map->oFile, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
+         tfprintf (map->oFile, "\t!ds\n", 
+                   (unsigned int) getSize (sym->type) & 0xffff);
        }
 
       /* if it has an initial value then do it only if
          it is a global variable */
       if (sym->ival && sym->level == 0)
        {
-         ast *ival = NULL;
-
-         if (IS_AGGREGATE (sym->type))
+         if (IS_AGGREGATE (sym->type)) {
            ival = initAggregates (sym, sym->ival, NULL);
-         else
+         } else {
            ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
                     decorateType (resolveSymbols (list2expr (sym->ival))));
+         }
          codeOutFile = statsg->oFile;
          allocInfo = 0;
+
+         // set ival's lineno to where the symbol was defined
+         if (ival) ival->lineno=sym->lineDef;
          eBBlockFromiCode (iCodeFromAst (ival));
          allocInfo = 1;
+
+         /* if the ival is a symbol assigned to an aggregate,
+            (bug #458099 -> #462479)
+            we don't need it anymore, so delete it from its segment */
+         if (IS_AST_SYM_VALUE(sym->ival->init.node) &&
+             IS_AGGREGATE (sym->type) ) {
+           symIval=AST_SYMBOL(sym->ival->init.node);
+           segment = SPEC_OCLS (symIval->etype);
+           deleteSetItem (&segment->syms, symIval);
+         }
+
          sym->ival = NULL;
        }
     }
@@ -279,86 +287,105 @@ emitRegularMap (memmap * map, bool addPublics, bool arFlag)
 value *
 initPointer (initList * ilist)
 {
-  value *val;
-  ast *expr = list2expr (ilist);
-
-  if (!expr)
-    goto wrong;
+       value *val;
+       ast *expr = list2expr (ilist);
+       
+       if (!expr)
+               goto wrong;
+       
+       /* try it the oldway first */
+       if ((val = constExprValue (expr, FALSE)))
+               return val;
+       
+       /* no then we have to do these cludgy checks */
+       /* pointers can be initialized with address of
+          a variable or address of an array element */
+       if (IS_AST_OP (expr) && expr->opval.op == '&') {
+               /* address of symbol */
+               if (IS_AST_SYM_VALUE (expr->left)) {
+                       val = copyValue (AST_VALUE (expr->left));
+                       val->type = newLink ();
+                       if (SPEC_SCLS (expr->left->etype) == S_CODE) {
+                               DCL_TYPE (val->type) = CPOINTER;
+                               DCL_PTR_CONST (val->type) = port->mem.code_ro;
+                       }
+                       else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
+                               DCL_TYPE (val->type) = FPOINTER;
+                       else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
+                               DCL_TYPE (val->type) = PPOINTER;
+                       else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
+                               DCL_TYPE (val->type) = IPOINTER;
+                       else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
+                               DCL_TYPE (val->type) = EEPPOINTER;
+                       else
+                               DCL_TYPE (val->type) = POINTER;
+                       val->type->next = expr->left->ftype;
+                       val->etype = getSpec (val->type);
+                       return val;
+               }
 
-  /* try it the oldway first */
-  if ((val = constExprValue (expr, FALSE)))
-    return val;
+               /* if address of indexed array */
+               if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
+                       return valForArray (expr->left);
 
-  /* no then we have to do these cludgy checks */
-  /* pointers can be initialized with address of
-     a variable or address of an array element */
-  if (IS_AST_OP (expr) && expr->opval.op == '&')
-    {
-      /* address of symbol */
-      if (IS_AST_SYM_VALUE (expr->left))
-       {
-         val = copyValue (AST_VALUE (expr->left));
-         val->type = newLink ();
-         if (SPEC_SCLS (expr->left->etype) == S_CODE)
-           {
-             DCL_TYPE (val->type) = CPOINTER;
-             DCL_PTR_CONST (val->type) = port->mem.code_ro;
-           }
-         else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
-           DCL_TYPE (val->type) = FPOINTER;
-         else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
-           DCL_TYPE (val->type) = PPOINTER;
-         else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
-           DCL_TYPE (val->type) = IPOINTER;
-         else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
-           DCL_TYPE (val->type) = EEPPOINTER;
-         else
-           DCL_TYPE (val->type) = POINTER;
-         val->type->next = expr->left->ftype;
-         val->etype = getSpec (val->type);
-         return val;
-       }
+               /* if address of structure element then
+                  case 1. a.b ; */
+               if (IS_AST_OP (expr->left) &&
+                   expr->left->opval.op == '.') {
+                       return valForStructElem (expr->left->left,
+                                                expr->left->right);
+               }
 
-      /* if address of indexed array */
-      if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
-       return valForArray (expr->left);
+               /* case 2. (&a)->b ;
+                  (&some_struct)->element */
+               if (IS_AST_OP (expr->left) &&
+                   expr->left->opval.op == PTR_OP &&
+                   IS_ADDRESS_OF_OP (expr->left->left))
+                       return valForStructElem (expr->left->left->left,
+                                                expr->left->right);
 
-      /* if address of structure element then
-         case 1. a.b ; */
-      if (IS_AST_OP (expr->left) &&
-         expr->left->opval.op == '.')
-       {
-         return valForStructElem (expr->left->left,
-                                  expr->left->right);
        }
+       /* case 3. (((char *) &a) +/- constant) */
+       if (IS_AST_OP (expr) &&
+           (expr->opval.op == '+' || expr->opval.op == '-') &&
+           IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
+           IS_AST_OP (expr->left->right) &&
+           expr->left->right->opval.op == '&' &&
+           IS_AST_LIT_VALUE (expr->right)) {
+
+               return valForCastAggr (expr->left->right->left,
+                                      expr->left->left->opval.lnk,
+                                      expr->right, expr->opval.op);
 
-      /* case 2. (&a)->b ;
-         (&some_struct)->element */
-      if (IS_AST_OP (expr->left) &&
-         expr->left->opval.op == PTR_OP &&
-         IS_ADDRESS_OF_OP (expr->left->left))
-       return valForStructElem (expr->left->left->left,
-                                expr->left->right);
-
-    }
-  /* case 3. (((char *) &a) +/- constant) */
-  if (IS_AST_OP (expr) &&
-      (expr->opval.op == '+' || expr->opval.op == '-') &&
-      IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
-      IS_AST_OP (expr->left->right) &&
-      expr->left->right->opval.op == '&' &&
-      IS_AST_LIT_VALUE (expr->right))
-    {
-
-      return valForCastAggr (expr->left->right->left,
-                            expr->left->left->opval.lnk,
-                            expr->right, expr->opval.op);
-
-    }
-
-wrong:
-  werror (E_INIT_WRONG);
-  return NULL;
+       }
+       
+       /* case 4. (char *)(array type) */
+       if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
+           IS_ARRAY(expr->right->ftype)) {
+
+               val = copyValue (AST_VALUE (expr->right));
+               val->type = newLink ();
+               if (SPEC_SCLS (expr->right->etype) == S_CODE) {
+                       DCL_TYPE (val->type) = CPOINTER;
+                       DCL_PTR_CONST (val->type) = port->mem.code_ro;
+               }
+               else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
+                       DCL_TYPE (val->type) = FPOINTER;
+               else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
+                       DCL_TYPE (val->type) = PPOINTER;
+               else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
+                       DCL_TYPE (val->type) = IPOINTER;
+               else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
+                       DCL_TYPE (val->type) = EEPPOINTER;
+               else
+                       DCL_TYPE (val->type) = POINTER;
+               val->type->next = expr->right->ftype->next;
+               val->etype = getSpec (val->type);
+               return val;
+       }
+ wrong:
+       werror (W_INIT_WRONG);
+       return NULL;
 
 }
 
@@ -379,12 +406,12 @@ printChar (FILE * ofile, char *s, int plen)
       i = 60;
       while (i && *s && pplen < plen)
        {
-         if (*s < ' ' || *s == '\"')
+         if (*s < ' ' || *s == '\"' || *s=='\\')
            {
              *p = '\0';
              if (p != buf)
                tfprintf (ofile, "\t!ascii\n", buf);
-             tfprintf (ofile, "\t!db !constbyte\n", *s);
+             tfprintf (ofile, "\t!db !constbyte\n", (unsigned char)*s);
              p = buf;
            }
          else
@@ -415,7 +442,7 @@ printChar (FILE * ofile, char *s, int plen)
 /* return the generic pointer high byte for a given pointer type.  */
 /*-----------------------------------------------------------------*/
 int 
-pointerTypeToGPByte (const int p_type)
+pointerTypeToGPByte (const int p_type, const char *iname, const char *oname)
 {
   switch (p_type)
     {
@@ -426,6 +453,9 @@ pointerTypeToGPByte (const int p_type)
       /* hack - if we get a generic pointer, we just assume
        * it's an FPOINTER (i.e. in XDATA space).
        */
+      werror (E_CANNOT_USE_GENERIC_POINTER, iname, oname);
+      exit (1);
+      // fall through
     case FPOINTER:
       return 1;
     case CPOINTER:
@@ -447,7 +477,8 @@ pointerTypeToGPByte (const int p_type)
 void 
 _printPointerType (FILE * oFile, const char *name)
 {
-  if (IS_DS390_PORT)
+  /* if (TARGET_IS_DS390) */
+  if (options.model == MODEL_FLAT24)
     {
       fprintf (oFile, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name);
     }
@@ -471,11 +502,11 @@ printPointerType (FILE * oFile, const char *name)
 /* printGPointerType - generates ival for generic pointer type     */
 /*-----------------------------------------------------------------*/
 void 
-printGPointerType (FILE * oFile, const char *name,
+printGPointerType (FILE * oFile, const char *iname, const char *oname,
                   const unsigned int type)
 {
-  _printPointerType (oFile, name);
-  fprintf (oFile, ",#0x%02x\n", pointerTypeToGPByte (type));
+  _printPointerType (oFile, iname);
+  fprintf (oFile, ",#0x%02x\n", pointerTypeToGPByte (type, iname, oname));
 }
 
 /*-----------------------------------------------------------------*/
@@ -484,43 +515,90 @@ printGPointerType (FILE * oFile, const char *name,
 void 
 printIvalType (sym_link * type, initList * ilist, FILE * oFile)
 {
-  value *val;
+       value *val;
 
-  /* if initList is deep */
-  if (ilist->type == INIT_DEEP)
-    ilist = ilist->init.deep;
+       /* if initList is deep */
+       if (ilist->type == INIT_DEEP)
+               ilist = ilist->init.deep;
 
-  val = list2val (ilist);
-  switch (getSize (type))
-    {
-    case 1:
-      if (!val)
-       tfprintf (oFile, "\t!db !constbyte\n", 0);
-      else
-       tfprintf (oFile, "\t!dbs\n",
-                 aopLiteral (val, 0));
-      break;
+       val = list2val (ilist);
+       switch (getSize (type)) {
+       case 1:
+               if (!val)
+                       tfprintf (oFile, "\t!db !constbyte\n", 0);
+               else
+                       tfprintf (oFile, "\t!dbs\n",
+                                 aopLiteral (val, 0));
+               break;
 
-    case 2:
-      if (port->use_dw_for_init)
-       tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
-      else
-       fprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
-      break;
-    case 4:
-      if (!val)
-       {
-         tfprintf (oFile, "\t!dw !constword\n", 0);
-         tfprintf (oFile, "\t!dw !constword\n", 0);
+       case 2:
+               if (port->use_dw_for_init)
+                       tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
+               else
+                       fprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
+               break;
+       case 4:
+               if (!val) {
+                       tfprintf (oFile, "\t!dw !constword\n", 0);
+                       tfprintf (oFile, "\t!dw !constword\n", 0);
+               }
+               else {
+                       fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
+                                aopLiteral (val, 0), aopLiteral (val, 1),
+                                aopLiteral (val, 2), aopLiteral (val, 3));
+               }
+               break;
        }
-      else
-       {
-         fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
-                  aopLiteral (val, 0), aopLiteral (val, 1),
-                  aopLiteral (val, 2), aopLiteral (val, 3));
+}
+
+/*-----------------------------------------------------------------*/
+/* printIvalBitFields - generate initializer for bitfields         */
+/*-----------------------------------------------------------------*/
+void printIvalBitFields(symbol **sym, initList **ilist, FILE * oFile)
+{
+       value *val ;
+       symbol *lsym = *sym;
+       initList *lilist = *ilist ;
+       unsigned long ival = 0;
+       int size =0;
+
+       
+       do {
+               unsigned long i;
+               val = list2val(lilist);
+               if (size) {
+                       if (SPEC_BLEN(lsym->etype) > 8) {
+                               size += ((SPEC_BLEN (lsym->etype) / 8) + 
+                                        (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
+                       }
+               } else {
+                       size = ((SPEC_BLEN (lsym->etype) / 8) + 
+                                (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
+               }
+               i = (unsigned long)floatFromVal(val);
+               i <<= SPEC_BSTR (lsym->etype);
+               ival |= i;
+               if (! ( lsym->next &&
+                       (IS_BITFIELD(lsym->next->type)) &&
+                       (SPEC_BSTR(lsym->next->etype)))) break;
+               lsym = lsym->next;
+               lilist = lilist->next;
+       } while (1);
+       switch (size) {
+       case 1:
+               tfprintf (oFile, "\t!db !constbyte\n",ival);
+               break;
+
+       case 2:
+               tfprintf (oFile, "\t!dw !constword\n",ival);
+               break;
+       case 4:
+               tfprintf (oFile, "\t!db  !constword,!constword\n",
+                        (ival >> 8) & 0xffff, (ival & 0xffff));
+               break;
        }
-      break;
-    }
+       *sym = lsym;
+       *ilist = lilist;
 }
 
 /*-----------------------------------------------------------------*/
@@ -530,22 +608,25 @@ void
 printIvalStruct (symbol * sym, sym_link * type,
                 initList * ilist, FILE * oFile)
 {
-  symbol *sflds;
-  initList *iloop;
-
-  sflds = SPEC_STRUCT (type)->fields;
-  if (ilist->type != INIT_DEEP)
-    {
-      werror (E_INIT_STRUCT, sym->name);
-      return;
-    }
+       symbol *sflds;
+       initList *iloop;
 
-  iloop = ilist->init.deep;
+       sflds = SPEC_STRUCT (type)->fields;
+       if (ilist->type != INIT_DEEP) {
+               werror (E_INIT_STRUCT, sym->name);
+               return;
+       }
 
-  for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
-    printIval (sflds, sflds->type, iloop, oFile);
+       iloop = ilist->init.deep;
 
-  return;
+       for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
+               if (IS_BITFIELD(sflds->type)) {
+                       printIvalBitFields(&sflds,&iloop,oFile);
+               } else {
+                       printIval (sflds, sflds->type, iloop, oFile);
+               }
+       }
+       return;
 }
 
 /*-----------------------------------------------------------------*/
@@ -567,10 +648,6 @@ printIvalChar (sym_link * type, initList * ilist, FILE * oFile, char *s)
          if (!DCL_ELEM (type))
            DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
 
-         /* if size mismatch  */
-/*      if (DCL_ELEM (type) < ((int) strlen (SPEC_CVAL (val->etype).v_char) + 1)) */
-/*    werror (E_ARRAY_BOUND); */
-
          printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
 
          if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
@@ -630,8 +707,13 @@ printIvalArray (symbol * sym, sym_link * type, initList * ilist,
 
       /* no of elements given and we    */
       /* have generated for all of them */
-      if (!--lcnt)
+      if (!--lcnt) {
+       /* if initializers left */
+       if (iloop) {
+         werror (W_EXESS_ARRAY_INITIALIZERS, sym->name, sym->lineDef);
+       }
        break;
+      }
     }
 
   /* if we have not been given a size  */
@@ -652,7 +734,7 @@ printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile)
 
   val = list2val (ilist);
   /* check the types   */
-  if ((dLvl = checkType (val->type, type->next)) <= 0)
+  if ((dLvl = compareType (val->type, type->next)) <= 0)
     {
       tfprintf (oFile, "\t!dw !constword\n", 0);
       return;
@@ -716,10 +798,17 @@ printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile)
        }
       else if (size == GPTRSIZE)
        {
-         /* PENDING: 0x02 or 0x%02x, CDATA? */
-         printGPointerType (oFile, val->name,
-                            (IS_PTR (val->type) ? DCL_TYPE (val->type) :
-                             PTR_TYPE (SPEC_OCLS (val->etype))));
+         int type;
+         if (IS_PTR (val->type)) {
+           type = DCL_TYPE (val->type);
+         } else {
+           type = PTR_TYPE (SPEC_OCLS (val->etype));
+         }
+         if (val->sym && val->sym->isstrlit) {
+           // this is a literal string
+           type=CPOINTER;
+         }
+         printGPointerType (oFile, val->name, sym->name, type);
        }
       else
        {
@@ -752,9 +841,9 @@ printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile)
        }
     }
 
-
-  if (val->sym && val->sym->isstrlit)
+  if (val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
     addSet (&statsg->syms, val->sym);
+  }
 
   return 1;
 }
@@ -788,8 +877,8 @@ printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
       return;
 
   /* check the type      */
-  if (checkType (type, val->type) != 1)
-    werror (E_INIT_WRONG);
+  if (compareType (type, val->type) == 0)
+    werror (W_INIT_WRONG);
 
   /* if val is literal */
   if (IS_LITERAL (val->etype))
@@ -821,11 +910,15 @@ printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
     }
   else if (size == FPTRSIZE)
     {
-      tfprintf (oFile, "\t!dws\n", val->name);
+      if (port->use_dw_for_init) {
+       tfprintf (oFile, "\t!dws\n", val->name);
+      } else {
+       printPointerType (oFile, val->name);
+      }
     }
   else if (size == GPTRSIZE)
     {
-      printGPointerType (oFile, val->name,
+      printGPointerType (oFile, val->name, sym->name,
                         (IS_PTR (val->type) ? DCL_TYPE (val->type) :
                          PTR_TYPE (SPEC_OCLS (val->etype))));
     }
@@ -897,40 +990,37 @@ emitStaticSeg (memmap * map, FILE * out)
        addSetHead (&publics, sym);
 
       /* print extra debug info if required */
-      if ((options.debug || sym->level == 0) && !options.nodebug)
-       {
-
-         cdbSymbol (sym, cdbFile, FALSE, FALSE);
-
-         if (!sym->level)
-           {                   /* global */
-             if (IS_STATIC (sym->etype))
-               fprintf (out, "F%s$", moduleName);      /* scope is file */
-             else
-               fprintf (out, "G$");    /* scope is global */
-           }
-         else
-           /* symbol is local */
-           fprintf (out, "L%s$",
-                    (sym->localof ? sym->localof->name : "-null-"));
-         fprintf (out, "%s$%d$%d", sym->name, sym->level, sym->block);
-       }
-
+      if (options.debug) {
+       cdbSymbol (sym, cdbFile, FALSE, FALSE);
+       if (!sym->level)
+         {                     /* global */
+           if (IS_STATIC (sym->etype))
+             fprintf (out, "F%s$", moduleName);        /* scope is file */
+           else
+             fprintf (out, "G$");      /* scope is global */
+         }
+       else
+         /* symbol is local */
+         fprintf (out, "L%s$",
+                  (sym->localof ? sym->localof->name : "-null-"));
+       fprintf (out, "%s$%d$%d", sym->name, sym->level, sym->block);
+      }
+      
       /* if it has an absolute address */
       if (SPEC_ABSA (sym->etype))
        {
-         if ((options.debug || sym->level == 0) && !options.nodebug)
+         if (options.debug)
            fprintf (out, " == 0x%04x\n", SPEC_ADDR (sym->etype));
-
+         
          fprintf (out, "%s\t=\t0x%04x\n",
                   sym->rname,
                   SPEC_ADDR (sym->etype));
        }
       else
        {
-         if ((options.debug || sym->level == 0) && !options.nodebug)
+         if (options.debug)
            fprintf (out, " == .\n");
-
+         
          /* if it has an initial value */
          if (sym->ival)
            {
@@ -963,6 +1053,7 @@ emitStaticSeg (memmap * map, FILE * out)
 void 
 emitMaps ()
 {
+  inInitMode++;
   /* no special considerations for the following
      data, idata & bit & xdata */
   emitRegularMap (data, TRUE, TRUE);
@@ -975,6 +1066,7 @@ emitMaps ()
   emitRegularMap (code, TRUE, FALSE);
 
   emitStaticSeg (statsg, code->oFile);
+  inInitMode--;
 }
 
 /*-----------------------------------------------------------------*/
@@ -994,14 +1086,14 @@ flushStatics (void)
 void 
 createInterruptVect (FILE * vFile)
 {
-  int i = 0;
+  unsigned i = 0;
   mainf = newSymbol ("main", 0);
   mainf->block = 0;
 
   /* only if the main function exists */
   if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
     {
-      if (!options.cc_only)
+      if (!options.cc_only && !noAssemble)
        werror (E_NO_MAIN);
       return;
     }
@@ -1010,7 +1102,7 @@ createInterruptVect (FILE * vFile)
   if (!mainf->fbody)
     {
       /* if ! compile only then main function should be present */
-      if (!options.cc_only)
+      if (!options.cc_only && !noAssemble)
        werror (E_NO_MAIN);
       return;
     }
@@ -1154,9 +1246,8 @@ emitOverlay (FILE * afile)
            continue;
 
          /* print extra debug info if required */
-         if ((options.debug || sym->level == 0) && !options.nodebug)
+         if (options.debug)
            {
-
              cdbSymbol (sym, cdbFile, FALSE, FALSE);
 
              if (!sym->level)
@@ -1178,7 +1269,7 @@ emitOverlay (FILE * afile)
          if (SPEC_ABSA (sym->etype))
            {
 
-             if ((options.debug || sym->level == 0) && !options.nodebug)
+             if (options.debug)
                fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
 
              fprintf (afile, "%s\t=\t0x%04x\n",
@@ -1187,9 +1278,9 @@ emitOverlay (FILE * afile)
            }
          else
            {
-             if ((options.debug || sym->level == 0) && !options.nodebug)
+             if (options.debug)
                fprintf (afile, "==.\n");
-
+             
              /* allocate space */
              tfprintf (afile, "!labeldef\n", sym->rname);
              tfprintf (afile, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
@@ -1211,7 +1302,7 @@ glue ()
 
   addSetHead (&tmpfileSet, ovrFile);
   /* print the global struct definitions */
-  if (options.debug && !options.nodebug)
+  if (options.debug)
     cdbStructBlock (0, cdbFile);
 
   vFile = tempfile ();
@@ -1234,17 +1325,17 @@ glue ()
 
   if (!options.c1mode)
     {
-      sprintf (buffer, srcFileName);
-      strcat (buffer, ".asm");
+      sprintf (scratchFileName, srcFileName);
+      strcat (scratchFileName, port->assembler.file_ext);
     }
   else
     {
-      strcpy (buffer, options.out_name);
+      strcpy (scratchFileName, options.out_name);
     }
 
-  if (!(asmFile = fopen (buffer, "w")))
+  if (!(asmFile = fopen (scratchFileName, "w")))
     {
-      werror (E_FILE_OPEN_ERR, buffer);
+      werror (E_FILE_OPEN_ERR, scratchFileName);
       exit (1);
     }
 
@@ -1440,6 +1531,15 @@ glue ()
   applyToSet (tmpfileNameSet, rmTmpFiles);
 }
 
+#if defined (__MINGW32__) || defined (__CYGWIN__) || defined (_MSC_VER)
+void
+rm_tmpfiles (void)
+{
+  applyToSet (tmpfileSet, closeTmpFiles);
+  applyToSet (tmpfileNameSet, rmTmpFiles);
+}
+#endif
+
 /** Creates a temporary file a'la tmpfile which avoids the bugs
     in cygwin wrt c:\tmp.
     Scans, in order: TMP, TEMP, TMPDIR, else uses tmpfile().
@@ -1473,11 +1573,3 @@ tempfile (void)
   return tmpfile ();
 }
 
-char *
-gc_strdup (const char *s)
-{
-  char *ret;
-  ret = Safe_calloc (1, strlen (s) + 1);
-  strcpy (ret, s);
-  return ret;
-}