]> git.sur5r.net Git - cc65/blobdiff - src/ld65/fileio.c
Flag labels in the map file exports list
[cc65] / src / ld65 / fileio.c
index 263f3ab4845e49989ff643dc1c7a2ec9a465d0fd..4998fe3ed572ced030c8f73950abaacac51e1d48 100644 (file)
 
 #include <string.h>
 
+/* common */
+#include "xmalloc.h"
+
+/* ld65 */
 #include "error.h"
-#include "mem.h"
 #include "fileio.h"
 
 
@@ -47,7 +50,7 @@
 
 
 
-void Write8 (FILE* F, unsigned char Val)
+void Write8 (FILE* F, unsigned Val)
 /* Write an 8 bit value to the file */
 {
     if (putc (Val, F) == EOF) {
@@ -116,14 +119,31 @@ void WriteVal (FILE* F, unsigned long Val, unsigned Size)
 
 
 
+void WriteVar (FILE* F, unsigned long V)
+/* Write a variable sized value to the file in special encoding */
+{
+    /* We will write the value to the file in 7 bit chunks. If the 8th bit
+     * is clear, we're done, if it is set, another chunk follows. This will
+     * allow us to encode smaller values with less bytes, at the expense of
+     * needing 5 bytes if a 32 bit value is written to file.
+     */
+    do {
+       unsigned char C = (V & 0x7F);
+       V >>= 7;
+       if (V) {
+           C |= 0x80;
+       }
+       Write8 (F, C);
+    } while (V != 0);
+}
+
+
+
 void WriteStr (FILE* F, const char* S)
 /* Write a string to the file */
 {
     unsigned Len = strlen (S);
-    if (Len > 255) {
-               Internal ("String too long");
-    }
-    Write8 (F, (unsigned char) Len);
+    WriteVar (F, Len);
     WriteData (F, S, Len);
 }
 
@@ -209,37 +229,43 @@ long Read32Signed (FILE* F)
 
 
 
-char* ReadStr (FILE* F, char* Str)
-/* Read a string from the file. Str must hold 256 chars at max */
+unsigned long ReadVar (FILE* F)
+/* Read a variable size value from the file */
 {
-    /* Read the length byte */
-    unsigned Len = Read8 (F);
-
-    /* Read the string itself */
-    ReadData (F, Str, Len);
-
-    /* Terminate the string and return it */
-    Str [Len] = '\0';
-    return Str;
+    /* The value was written to the file in 7 bit chunks LSB first. If there
+     * are more bytes, bit 8 is set, otherwise it is clear.
+     */
+    unsigned char C;
+    unsigned long V = 0;
+    unsigned Shift = 0;
+    do {
+       /* Read one byte */
+       C = Read8 (F);
+       /* Encode it into the target value */
+       V |= ((unsigned long)(C & 0x7F)) << Shift;
+       /* Next value */
+       Shift += 7;
+    } while (C & 0x80);
+
+    /* Return the value read */
+    return V;
 }
 
 
 
-char* ReadMallocedStr (FILE* F)
-/* Read a string from the file into a malloced area */
+char* ReadStr (FILE* F)
+/* Read a string from the file (the memory will be malloc'ed) */
 {
-    /* Read the length byte */
-    unsigned Len = Read8 (F);
+    /* Read the length */
+    unsigned Len = ReadVar (F);
 
-    /* Allocate memory */
-    char* Str = Xmalloc (Len + 1);
-
-    /* Read the string itself */
-    ReadData (F, Str, Len);
+    /* Allocate memory and read the string itself */
+    char* S = xmalloc (Len + 1);
+    ReadData (F, S, Len);
 
     /* Terminate the string and return it */
-    Str [Len] = '\0';
-    return Str;
+    S [Len] = '\0';
+    return S;
 }
 
 
@@ -247,10 +273,10 @@ char* ReadMallocedStr (FILE* F)
 FilePos* ReadFilePos (FILE* F, FilePos* Pos)
 /* Read a file position from the file */
 {
-    /* The line number is encoded as 24 bit value to save some space */
-    Pos->Line =        Read24 (F);
-    Pos->Col  = Read8 (F);
-    Pos->Name = Read8 (F);
+    /* Read the data fields */
+    Pos->Line =        ReadVar (F);
+    Pos->Col  = ReadVar (F);
+    Pos->Name = ReadVar (F);
     return Pos;
 }
 
@@ -258,12 +284,16 @@ FilePos* ReadFilePos (FILE* F, FilePos* Pos)
 
 void* ReadData (FILE* F, void* Data, unsigned Size)
 /* Read data from the file */
-{
-    if (fread (Data, 1, Size, F) != Size) {
-       Error ("Read error (file corrupt?)");
+{     
+    /* Explicitly allow reading zero bytes */
+    if (Size > 0) {
+       if (fread (Data, 1, Size, F) != Size) {
+           Error ("Read error (file corrupt?)");
+       }
     }
     return Data;
 }
 
 
 
+