removed gcc warning: 'c' may be used uninitialized in this function
[fw/sdcc] / src / asm.c
index d4860c284ab40a8ac4253866a9c12d31b1366db2..bc61329fb38070db8dfba885a864441c6384dbe8 100644 (file)
--- a/src/asm.c
+++ b/src/asm.c
@@ -6,21 +6,15 @@
     Note that the functions below only handle digit format modifiers.
     eg %02X is ok, but %lu and %.4u will fail.
 */
+#include <errno.h>
+
 #include "common.h"
 #include "asm.h"
-
-#ifdef _WIN32
-   // for O_BINARY in _pipe()
-#  include <fcntl.h>
-#  include <io.h>
-#else
-   // for pipe and close
-#  include <unistd.h>
-#endif
+#include "dbuf_string.h"
 
 /* A 'token' is like !blah or %24f and is under the programmers
    control. */
-#define MAX_TOKEN_LEN          64
+#define MAX_TOKEN_LEN           64
 
 static hTab *_h;
 
@@ -36,34 +30,17 @@ FileBaseName (char *fileFullName)
   while (*fileFullName)
     {
       if ((*fileFullName == '/') || (*fileFullName == '\\') || (*fileFullName == ':'))
-       {
-         p = fileFullName;
-         p++;
-       }
+        {
+          p = fileFullName;
+          p++;
+        }
       fileFullName++;
     }
   return p;
 }
 
-static const char *
-_findMapping (const char *szKey)
-{
-  return shash_find (_h, szKey);
-}
-
-// Append a string onto another, and update the pointer to the end of
-// the new string.
-static char *
-_appendAt (char *at, char *onto, const char *sz, size_t *max)
-{
-  wassert (at && onto && sz);
-  strncpyz (at, sz, *max);
-  *max -= strlen (at);
-  return at + strlen (at);
-}
-
-void 
-tvsprintf (char *buffer, size_t len, const char *format, va_list ap)
+void
+dbuf_tvprintf (struct dbuf_s *dbuf, const char *format, va_list ap)
 {
   // Under Linux PPC va_list is a structure instead of a primitive type,
   // and doesnt like being passed around.  This version turns everything
@@ -76,172 +53,157 @@ tvsprintf (char *buffer, size_t len, const char *format, va_list ap)
 
   // This is acheived by expanding the tokens and zero arg formats into
   // one big format string, which is passed to the native printf.
-  static int   count;
-  char                 noTokens[INITIAL_INLINEASM];
-  char                 newFormat[INITIAL_INLINEASM];
-  char                 *pInto = noTokens;
-  size_t       pIntoLen = sizeof(noTokens);
-  char                 *p;
-  char                 token[MAX_TOKEN_LEN];
-  const char   *sz = format;
-
-  // NULL terminate it to let strlen work.
-  *pInto = '\0';
+  static int count;
+  struct dbuf_s tmpDBuf;
+  const char *noTokens;
+  char *p;
+  char token[MAX_TOKEN_LEN];
+  const char *sz = format;
+
+  dbuf_init(&tmpDBuf, INITIAL_INLINEASM);
 
   /* First pass: expand all of the macros */
-  while (pIntoLen && *sz)
+  while (*sz)
     {
       if (*sz == '!')
-       {
-         /* Start of a token.  Search until the first
-            [non alpha, *] and call it a token. */
-         const char *t;
-         p = token;
-         sz++;
-         while (isalpha (*sz) || *sz == '*')
-           {
-             *p++ = *sz++;
-           }
-         *p = '\0';
-         /* Now find the token in the token list */
-         if ((t = _findMapping (token)))
-           {
-             pInto = _appendAt (pInto, noTokens, t, &pIntoLen);
-           }
-         else
-           {
-             fprintf (stderr, "Cant find token \"%s\"\n", token);
-             wassert (0);
-           }
-       }
+        {
+          /* Start of a token.  Search until the first
+             [non alpha, *] and call it a token. */
+          const char *t;
+          p = token;
+          sz++;
+          while (isalpha ((unsigned char)*sz) || *sz == '*')
+            {
+              *p++ = *sz++;
+            }
+          *p = '\0';
+          /* Now find the token in the token list */
+          if ((t = shash_find (_h, token)))
+            {
+              dbuf_append_str(&tmpDBuf, t);
+            }
+          else
+            {
+              fprintf (stderr, "Cant find token \"%s\"\n", token);
+              wassert (0);
+            }
+        }
       else
         {
-          *pInto++ = *sz++;
-         pIntoLen--;
+          dbuf_append_char(&tmpDBuf, *sz++);
         }
     }
 
-  if (!pIntoLen)
-  {
-      fprintf(stderr,
-               "Internal error: tvsprintf overflowed on pass one.\n");
-      // Might as well go on...
-  }
-    
-  *pInto = '\0';
-
   /* Second pass: Expand any macros that we own */
+  noTokens = dbuf_c_str(&tmpDBuf);
   sz = noTokens;
-  pInto = newFormat;
-  pIntoLen = sizeof(newFormat);
 
-  while (pIntoLen && *sz)
+  /* recycle tmpDBuf */
+  dbuf_init(&tmpDBuf, INITIAL_INLINEASM);
+
+  while (*sz)
     {
       if (*sz == '%')
-       {
-         // See if its one that we handle.
-         sz++;
-         switch (*sz)
-           {
-           case 'C':
-             // Code segment name.
-             pInto = _appendAt (pInto, newFormat, CODE_NAME, &pIntoLen);
+        {
+          // See if its one that we handle.
+          sz++;
+          switch (*sz)
+            {
+            case 'C':
+              // Code segment name.
+              dbuf_append_str(&tmpDBuf, CODE_NAME);
               sz++;
-             break;
-           case 'F':
-             // Source file name.
-             pInto = _appendAt (pInto, newFormat, fullSrcFileName, &pIntoLen);
+              break;
+
+            case 'F':
+              // Source file name.
+              dbuf_append_str(&tmpDBuf, fullSrcFileName);
               sz++;
-             break;
+              break;
+
             case 'N':
               // Current function name.
-              pInto = _appendAt (pInto, newFormat, currFunc->rname, &pIntoLen);
+              dbuf_append_str(&tmpDBuf, currFunc->rname);
               sz++;
               break;
-           case 'I':
-             {
-               // Unique ID.
-               char id[20];
-               SNPRINTF (id, sizeof(id), "%u", ++count);
-               pInto = _appendAt (pInto, newFormat, id, &pIntoLen);
-                sz++;
-               break;
-             }
-           default:
-             // Not one of ours.  Copy until the end.
-             *pInto++ = '%';
-             pIntoLen--;
-             while (pIntoLen && !isalpha (*sz))
-               {
-                 *pInto++ = *sz++;
-                 pIntoLen--;
-               }
-               if (pIntoLen)
-               {
-                   *pInto++ = *sz++;
-                   pIntoLen--;
-               }
-           }
-       }
+
+            case 'I':
+              // Unique ID.
+              dbuf_printf(&tmpDBuf, "%u", ++count);
+              sz++;
+              break;
+
+            default:
+              // Not one of ours.  Copy until the end.
+              dbuf_append_char(&tmpDBuf, '%');
+              while (!isalpha ((unsigned char)*sz))
+                dbuf_append_char(&tmpDBuf, *sz++);
+
+              dbuf_append_char(&tmpDBuf, *sz++);
+            }
+        }
       else
-       {
-         *pInto++ = *sz++;
-         pIntoLen--;
-       }
+        {
+          dbuf_append_char(&tmpDBuf, *sz++);
+        }
     }
 
-  if (!pIntoLen)
-  {
-      fprintf(stderr,
-               "Internal error: tvsprintf overflowed on pass two.\n");
-      // Might as well go on...
-  }    
-    
-  *pInto = '\0';
-
-  // Now do the actual printing
-#if defined(HAVE_VSNPRINTF)
-    {
-       int wrlen;
-       wrlen = vsnprintf (buffer, len, newFormat, ap);
-       
-       if (wrlen < 0 || wrlen >= len)
-       {
-           fprintf(stderr, "Internal error: tvsprintf truncated.\n");
-       }
-    }
-    
-#else    
-    vsprintf (buffer, newFormat, ap);
-    if (strlen(buffer) >= len)
-    {
-       fprintf(stderr, "Internal error: tvsprintf overflowed.\n");
-    }
-#endif    
+  dbuf_free(noTokens);
+
+  sz = dbuf_c_str(&tmpDBuf);
+
+  dbuf_vprintf(dbuf, sz, ap);
+
+  dbuf_destroy(&tmpDBuf);
 }
 
-void 
-tfprintf (FILE * fp, const char *szFormat,...)
+void
+dbuf_tprintf (struct dbuf_s *dbuf, const char *szFormat,...)
 {
   va_list ap;
-  char buffer[INITIAL_INLINEASM];
-
   va_start (ap, szFormat);
-  tvsprintf (buffer, INITIAL_INLINEASM, szFormat, ap);
+  dbuf_tvprintf (dbuf, szFormat, ap);
   va_end(ap);
-  fputs (buffer, fp);
 }
 
-void 
+void
 tsprintf (char *buffer, size_t len, const char *szFormat,...)
 {
   va_list ap;
+  struct dbuf_s dbuf;
+  size_t copyLen;
+
+  dbuf_init(&dbuf, INITIAL_INLINEASM);
+
+  va_start (ap, szFormat);
+  dbuf_tvprintf (&dbuf, szFormat, ap);
+  va_end(ap);
+
+  copyLen = min(len - 1, dbuf_get_length(&dbuf));
+  memcpy(buffer, dbuf_get_buf(&dbuf), copyLen);
+  buffer[copyLen] = '\0';
+  dbuf_destroy(&dbuf);
+}
+
+void
+tfprintf (FILE *fp, const char *szFormat,...)
+{
+  va_list ap;
+  struct dbuf_s dbuf;
+  size_t len;
+
+  dbuf_init(&dbuf, INITIAL_INLINEASM);
+
   va_start (ap, szFormat);
-  tvsprintf (buffer, len, szFormat, ap);
+  dbuf_tvprintf (&dbuf, szFormat, ap);
   va_end(ap);
+
+  len = dbuf_get_length(&dbuf);
+  fwrite(dbuf_get_buf(&dbuf), 1, len, fp);
+  dbuf_destroy(&dbuf);
 }
 
-void 
+void
 asm_addTree (const ASM_MAPPINGS * pMappings)
 {
   const ASM_MAPPING *pMap;
@@ -258,56 +220,46 @@ asm_addTree (const ASM_MAPPINGS * pMappings)
 
 /*-----------------------------------------------------------------*/
 /* printILine - return the readable i-code for this ic             */
-/*                                                                 */
-/* iCodePrint wants a file stream so we need a pipe to fool it     */
 /*-----------------------------------------------------------------*/
-static char verbalICode[1024];
-
-char *printILine (iCode *ic) {
-  int filedes[2];
-  FILE *pipeStream;
+char *
+printILine (iCode *ic)
+{
+  char *verbalICode;
+  struct dbuf_s tmpBuf;
   iCodeTable *icTab=getTableEntry(ic->op);
-  int res;
-
-#ifdef _WIN32
-  res = _pipe(filedes, 256, O_BINARY);
-#else
-  res = pipe(filedes);
-#endif
-  assert(res != -1); // forget it
-  if (res == -1)
-    return "";  // return empty line if pipe creation failed
-
-  // stuff the pipe with the readable icode
-  pipeStream=fdopen(filedes[1],"w");
-  if (ic->op != INLINEASM)
-    icTab->iCodePrint(pipeStream, ic, icTab->printName);
-  else
-    fprintf(pipeStream, "inline\n");
-  // it really needs an extra push
-  fflush(pipeStream);
-  // now swallow it
-  pipeStream=fdopen(filedes[0],"r");
-  fgets(verbalICode, sizeof(verbalICode), pipeStream);
-  // clean up the mess, we'll return here for all icodes!!
-  assert(!close (filedes[0]));
-  assert(!close (filedes[1]));
-  // kill the trailing NL
-  verbalICode[strlen(verbalICode)-1]='\0';
-  // and throw it up
+
+  dbuf_init(&tmpBuf, 1024);
+
+  if (INLINEASM == ic->op)
+    dbuf_append (&tmpBuf, "inline", (sizeof "inline") - 1);
+  else {
+    /* stuff the temporary file with the readable icode */
+    icTab->iCodePrint(&tmpBuf, ic, icTab->printName);
+  }
+
+  /* null terminate the buffer */
+  dbuf_c_str(&tmpBuf);
+  verbalICode = dbuf_detach(&tmpBuf);
+
+  /* kill the trailing NL */
+  if ('\n' == verbalICode[strlen(verbalICode) - 1])
+    verbalICode[strlen(verbalICode) - 1] = '\0';
+
+  /* and throw it up */
   return verbalICode;
 }
 
 /*-----------------------------------------------------------------*/
 /* printCLine - return the c-code for this lineno                  */
 /*-----------------------------------------------------------------*/
-static FILE *inFile=NULL;
-static char inLineString[1024];
-static int inLineNo=0;
-static char lastSrcFile[PATH_MAX];
-int rewinds=0;
-
-char *printCLine (char *srcFile, int lineno) {
+/* int rewinds=0; */
+char *
+printCLine (char *srcFile, int lineno)
+{
+  static FILE *inFile=NULL;
+  static char inLineString[1024];
+  static int inLineNo=0;
+  static char lastSrcFile[PATH_MAX];
   char *ilsP=inLineString;
 
   if (inFile) {
@@ -315,30 +267,31 @@ char *printCLine (char *srcFile, int lineno) {
       fclose (inFile);
       inFile = NULL;
       inLineNo = 0;
+      strncpyz (lastSrcFile, srcFile, PATH_MAX);
     }
   }
-  if (!inFile) {
-    inFile=fopen(srcFile, "r");
-    if (!inFile) {
-      perror ("printCLine");
-      exit (1);
-    }
-    strncpyz (lastSrcFile, srcFile, PATH_MAX);
-  }
-  if (lineno<inLineNo) {
-    fseek (inFile, 0, SEEK_SET);
-    inLineNo=0;
-    rewinds++;
+  if (!inFile && !(inFile = fopen(srcFile, "r"))) {
+    /* can't open the file:
+       don't panic, just return the error message */
+    SDCCsnprintf(inLineString, sizeof(inLineString), "ERROR: %s", strerror(errno));
   }
-  while (fgets (inLineString, 1024, inFile)) {
-    inLineNo++;
-    if (inLineNo==lineno) {
-      // remove the trailing NL
-      inLineString[strlen(inLineString)-1]='\0';
-      break;
+  else {
+    if (lineno<inLineNo) {
+      fseek (inFile, 0, SEEK_SET);
+      inLineNo=0;
+      /* rewinds++; */
+    }
+    while (fgets (inLineString, 1024, inFile)) {
+      inLineNo++;
+      if (inLineNo==lineno) {
+        // remove the trailing NL
+        inLineString[strlen(inLineString)-1]='\0';
+        break;
+      }
     }
   }
-  while (isspace ((int)*ilsP))
+
+  while (isspace ((unsigned char)*ilsP))
     ilsP++;
 
   return ilsP;
@@ -379,7 +332,7 @@ static const ASM_MAPPING _asxxxx_mapping[] =
    "; ---------------------------------"
   },
   {"functionlabeldef", "%s:"},
-  {"bankimmeds", "0    ; PENDING: bank support"},
+  {"bankimmeds", "0     ; PENDING: bank support"},
   {"los","(%s & 0xFF)"},
   {"his","(%s >> 8)"},
   {"hihis","(%s >> 16)"},
@@ -393,6 +346,7 @@ static const ASM_MAPPING _asxxxx_mapping[] =
   {"hihil","(%05d$ >> 16)"},
   {"hihihil","(%05d$ >> 24)"},
   {"equ","="},
+  {"org", ".org 0x%04X"},
   {NULL, NULL}
 };
 
@@ -432,7 +386,7 @@ static const ASM_MAPPING _gas_mapping[] =
    "; ---------------------------------"
   },
   {"functionlabeldef", "%s:"},
-  {"bankimmeds", "0    ; PENDING: bank support"},  
+  {"bankimmeds", "0     ; PENDING: bank support"},
   {NULL, NULL}
 };
 
@@ -471,7 +425,7 @@ static const ASM_MAPPING _a390_mapping[] =
    "; ---------------------------------"
   },
   {"functionlabeldef", "%s:"},
-  {"bankimmeds", "0    ; PENDING: bank support"},  
+  {"bankimmeds", "0     ; PENDING: bank support"},
   {"los","(%s & 0FFh)"},
   {"his","((%s / 256) & 0FFh)"},
   {"hihis","((%s / 65536) & 0FFh)"},
@@ -485,6 +439,7 @@ static const ASM_MAPPING _a390_mapping[] =
   {"hihil","((L%05d / 65536) & 0FFh)"},
   {"hihihil","((L%09d / 16777216) & 0FFh)"},
   {"equ"," equ"},
+  {"org", ".org 0x%04X"},
   {NULL, NULL}
 };
 
@@ -523,7 +478,7 @@ static const ASM_MAPPING _xa_asm_mapping[] =
    "; ---------------------------------"
   },
   {"functionlabeldef", "%s:"},
-  {"bankimmeds", "0    ; PENDING: bank support"},  
+  {"bankimmeds", "0     ; PENDING: bank support"},
   {"los","(%s & 0FFh)"},
   {"his","((%s / 256) & 0FFh)"},
   {"hihis","((%s / 65536) & 0FFh)"},