コード例 #1
0
ファイル: dump.c プロジェクト: eakmeister/cc65
void DumpObjSegments (FILE* F, unsigned long Offset)
/* Dump the segments in the object file */
{
    ObjHeader  H;
    Collection StrPool = AUTO_COLLECTION_INITIALIZER;
    unsigned   Count;
    unsigned   I;

    /* Seek to the header position and read the header */
    FileSetPos (F, Offset);
    ReadObjHeader (F, &H);

    /* Seek to the start of the string pool and read it */
    FileSetPos (F, Offset + H.StrPoolOffs);
    ReadStrPool (F, &StrPool);

    /* Seek to the start of the segments */
    FileSetPos (F, Offset + H.SegOffs);

    /* Output a header */
    printf ("  Segments:\n");

    /* Read the number of segments and print it */
    Count = ReadVar (F);
    printf ("    Count:%27u\n", Count);

    /* Read and print all segments */
    for (I = 0; I < Count; ++I) {

	/* Read the data for one segments */
        unsigned long DataSize  = Read32 (F);
        unsigned long NextSeg   = ftell (F) + DataSize;
       	const char*   Name      = GetString (&StrPool, ReadVar (F));
	unsigned      Len       = strlen (Name);
        unsigned      Flags     = ReadVar (F);
	unsigned long Size      = ReadVar (F);
       	unsigned long Align     = ReadVar (F);
       	unsigned char AddrSize  = Read8 (F);
        unsigned long FragCount = ReadVar (F);

	/* Print the header */
	printf ("    Index:%27u\n", I);

	/* Print the data */
	printf ("      Name:%*s\"%s\"\n", (int)(24-Len), "", Name);
        printf ("      Flags:%25u\n", Flags);
       	printf ("      Size:%26lu\n", Size);
	printf ("      Alignment:%21lu\n", Align);
	printf ("      Address size:%14s0x%02X  (%s)\n", "", AddrSize,
                AddrSizeToStr (AddrSize));
       	printf ("      Fragment count:%16lu\n", FragCount);

        /* Seek to the end of the segment data (start of next) */
        FileSetPos (F, NextSeg);
    }

    /* Destroy the string pool */
    DestroyStrPool (&StrPool);
}
コード例 #2
0
ファイル: dump.c プロジェクト: eakmeister/cc65
void DumpObjSegSize (FILE* F, unsigned long Offset)
/* Dump the sizes of the segment in the object file */
{
    ObjHeader   H;
    Collection  StrPool = AUTO_COLLECTION_INITIALIZER;
    unsigned    Count;

    /* Seek to the header position and read the header */
    FileSetPos (F, Offset);
    ReadObjHeader (F, &H);

    /* Seek to the start of the string pool and read it */
    FileSetPos (F, Offset + H.StrPoolOffs);
    ReadStrPool (F, &StrPool);

    /* Seek to the start of the segments */
    FileSetPos (F, Offset + H.SegOffs);

    /* Output a header */
    printf ("  Segment sizes:\n");

    /* Read the number of segments */
    Count = ReadVar (F);

    /* Read and print the sizes of all segments */
    while (Count--) {

        unsigned long Size;

       	/* Read the data for one segment */
        unsigned long DataSize = Read32 (F);
        unsigned long NextSeg  = ftell (F) + DataSize;
	const char*   Name     = GetString (&StrPool, ReadVar (F));
	unsigned      Len      = strlen (Name);

        /* Skip segment flags, read size */
        (void) ReadVar (F);     
        Size = ReadVar (F);

        /* Skip alignment, type and fragment count */
        (void) ReadVar (F);
        (void) Read8 (F);
        (void) ReadVar (F);

	/* Print the size for this segment */
	printf ("    %s:%*s%6lu\n", Name, (int)(24-Len), "", Size);

        /* Seek to the end of the segment data (start of next) */
        FileSetPos (F, NextSeg);
    }

    /* Destroy the string pool */
    DestroyStrPool (&StrPool);
}
コード例 #3
0
ファイル: dump.c プロジェクト: eakmeister/cc65
void DumpObjImports (FILE* F, unsigned long Offset)
/* Dump the imports in the object file */
{
    ObjHeader  H;
    Collection StrPool = AUTO_COLLECTION_INITIALIZER;
    unsigned   Count;
    unsigned   I;

    /* Seek to the header position and read the header */
    FileSetPos (F, Offset);
    ReadObjHeader (F, &H);

    /* Seek to the start of the string pool and read it */
    FileSetPos (F, Offset + H.StrPoolOffs);
    ReadStrPool (F, &StrPool);

    /* Seek to the start of the imports */
    FileSetPos (F, Offset + H.ImportOffs);

    /* Output a header */
    printf ("  Imports:\n");

    /* Read the number of imports and print it */
    Count = ReadVar (F);
    printf ("    Count:%27u\n", Count);

    /* Read and print all imports */
    for (I = 0; I < Count; ++I) {

       	/* Read the data for one import */
       	unsigned char AddrSize = Read8 (F);
       	const char*   Name     = GetString (&StrPool, ReadVar (F));
	unsigned      Len      = strlen (Name);

        /* Skip both line info lists */
        SkipLineInfoList (F);
        SkipLineInfoList (F);

	/* Print the header */
	printf ("    Index:%27u\n", I);

	/* Print the data */
	printf ("      Address size:%14s0x%02X  (%s)\n", "", AddrSize,
                AddrSizeToStr (AddrSize));
	printf ("      Name:%*s\"%s\"\n", (int)(24-Len), "", Name);
    }

    /* Destroy the string pool */
    DestroyStrPool (&StrPool);
}
コード例 #4
0
ファイル: dump.c プロジェクト: eakmeister/cc65
void DumpObjFiles (FILE* F, unsigned long Offset)
/* Dump the source files */
{
    ObjHeader  H;
    Collection StrPool = AUTO_COLLECTION_INITIALIZER;
    unsigned   Count;
    unsigned   I;

    /* Seek to the header position and read the header */
    FileSetPos (F, Offset);
    ReadObjHeader (F, &H);

    /* Seek to the start of the string pool and read it */
    FileSetPos (F, Offset + H.StrPoolOffs);
    ReadStrPool (F, &StrPool);

    /* Seek to the start of the source files */
    FileSetPos (F, Offset + H.FileOffs);

    /* Output a header */
    printf ("  Files:\n");

    /* Read the number of files and print it */
    Count = ReadVar (F);
    printf ("    Count:%27u\n", Count);

    /* Read and print all files */
    for (I = 0; I < Count; ++I) {

	/* Read the data for one file */
       	const char*   Name  = GetString (&StrPool, ReadVar (F));
	unsigned long MTime = Read32 (F);
	unsigned long Size  = ReadVar (F);
	unsigned      Len   = strlen (Name);

	/* Print the header */
	printf ("    Index:%27u\n", I);

	/* Print the data */
	printf ("      Name:%*s\"%s\"\n", (int)(24-Len), "", Name);
       	printf ("      Size:%26lu\n", Size);
	printf ("      Modification time:%13lu  (%s)\n", MTime, TimeToStr (MTime));
    }

    /* Destroy the string pool */
    DestroyStrPool (&StrPool);
}
コード例 #5
0
ファイル: dump.c プロジェクト: eakmeister/cc65
void DumpObjHeader (FILE* F, unsigned long Offset)
/* Dump the header of the given object file */
{
    ObjHeader H;

    /* Seek to the header position */
    FileSetPos (F, Offset);

    /* Read the header */
    ReadObjHeader (F, &H);

    /* Now dump the information */

    /* Output a header */
    printf ("  Header:\n");

    /* Magic */
    printf ("    Magic:%17s0x%08lX\n", "", H.Magic);

    /* Version */
    printf ("    Version:%25u\n", H.Version);

    /* Flags */
    printf ("    Flags:%21s0x%04X  (", "", H.Flags);
    if (H.Flags & OBJ_FLAGS_DBGINFO) {
    	printf ("OBJ_FLAGS_DBGINFO");
    }
    printf (")\n");

    /* Options */
    DumpObjHeaderSection ("Options", H.OptionOffs, H.OptionSize);

    /* Files */
    DumpObjHeaderSection ("Files", H.FileOffs, H.FileSize);

    /* Segments */
    DumpObjHeaderSection ("Segments", H.SegOffs, H.SegSize);

    /* Imports */
    DumpObjHeaderSection ("Imports", H.ImportOffs, H.ImportSize);

    /* Exports */
    DumpObjHeaderSection ("Exports", H.ExportOffs, H.ExportSize);

    /* Debug symbols */
    DumpObjHeaderSection ("Debug symbols", H.DbgSymOffs, H.DbgSymSize);

    /* Line infos */
    DumpObjHeaderSection ("Line infos", H.LineInfoOffs, H.LineInfoSize);

    /* String pool */
    DumpObjHeaderSection ("String pool", H.StrPoolOffs, H.StrPoolSize);

    /* Assertions */
    DumpObjHeaderSection ("Assertions", H.AssertOffs, H.AssertSize);

    /* Scopes */
    DumpObjHeaderSection ("Scopes", H.ScopeOffs, H.ScopeSize);
}
コード例 #6
0
ファイル: objfile.c プロジェクト: gilligan/snesdev
void ObjReadScopes (FILE* F, unsigned long Pos, ObjData* O)
/* Read the scope table from a file at the given offset */
{
    unsigned I;

    /* Seek to the correct position */
    FileSetPos (F, Pos);

    /* Read the data */
    O->ScopeCount = ReadVar (F);
    O->Scopes     = xmalloc (O->ScopeCount * sizeof (O->Scopes[0]));
    for (I = 0; I < O->ScopeCount; ++I) {
        O->Scopes[I] = 0;       /* ReadScope (F, O); ### not implemented */
    }
}
コード例 #7
0
ファイル: objfile.c プロジェクト: gilligan/snesdev
void ObjReadAssertions (FILE* F, unsigned long Pos, ObjData* O)
/* Read the assertions from a file at the given offset */
{
    unsigned I;

    /* Seek to the correct position */
    FileSetPos (F, Pos);

    /* Read the data */
    O->AssertionCount = ReadVar (F);
    O->Assertions     = xmalloc (O->AssertionCount * sizeof (O->Assertions[0]));
    for (I = 0; I < O->AssertionCount; ++I) {
        O->Assertions[I] = ReadAssertion (F, O);
    }
}
コード例 #8
0
ファイル: objfile.c プロジェクト: gilligan/snesdev
void ObjReadStrPool (FILE* F, unsigned long Pos, ObjData* O)
/* Read the string pool from a file at the given position */
{
    unsigned I;

    /* Seek to the correct position */
    FileSetPos (F, Pos);

    /* Read the data */
    O->StringCount = ReadVar (F);
    O->Strings     = xmalloc (O->StringCount * sizeof (O->Strings[0]));
    for (I = 0; I < O->StringCount; ++I) {
        O->Strings[I] = ReadStr (F);
    }
}
コード例 #9
0
ファイル: objfile.c プロジェクト: gilligan/snesdev
void ObjReadLineInfos (FILE* F, unsigned long Pos, ObjData* O)
/* Read the line infos from a file at the given position */
{
    unsigned I;

    /* Seek to the correct position */
    FileSetPos (F, Pos);

    /* Read the data */
    O->LineInfoCount = ReadVar (F);
    O->LineInfos     = xmalloc (O->LineInfoCount * sizeof (O->LineInfos[0]));
    for (I = 0; I < O->LineInfoCount; ++I) {
        O->LineInfos[I] = ReadLineInfo (F, O);
    }
}
コード例 #10
0
ファイル: objfile.c プロジェクト: gilligan/snesdev
void ObjReadDbgSyms (FILE* F, unsigned long Pos, ObjData* O)
/* Read the debug symbols from a file at the given position */
{
    unsigned I;

    /* Seek to the correct position */
    FileSetPos (F, Pos);

    /* Read the data */
    O->DbgSymCount = ReadVar (F);
    O->DbgSyms	   = xmalloc (O->DbgSymCount * sizeof (O->DbgSyms[0]));
    for (I = 0; I < O->DbgSymCount; ++I) {
        O->DbgSyms [I] = ReadDbgSym (F, O);
    }
}
コード例 #11
0
ファイル: dump.c プロジェクト: eakmeister/cc65
void DumpObjScopes (FILE* F, unsigned long Offset)
/* Dump the scopes from an object file */
{
    ObjHeader   H;
    Collection  StrPool = AUTO_COLLECTION_INITIALIZER;
    unsigned    Count;
    unsigned    I;

    /* Seek to the header position and read the header */
    FileSetPos (F, Offset);
    ReadObjHeader (F, &H);

    /* Seek to the start of the string pool and read it */
    FileSetPos (F, Offset + H.StrPoolOffs);
    ReadStrPool (F, &StrPool);

    /* Seek to the start of scopes */
    FileSetPos (F, Offset + H.ScopeOffs);

    /* Output a header */
    printf ("  Scopes:\n");

    /* Check if the object file was compiled with debug info */
    if ((H.Flags & OBJ_FLAGS_DBGINFO) == 0) {
	/* Print that there no scopes and bail out */
	printf ("    Count:%27u\n", 0);
	return;
    }

    /* Read the number of scopes and print it */
    Count = ReadVar (F);
    printf ("    Count:%27u\n", Count);

    /* Read and print all scopes */
    for (I = 0; I < Count; ++I) {

        const char*     Name;
        unsigned        Len;

        /* Read the data */
        unsigned        ParentId = ReadVar (F);
        unsigned        LexicalLevel = ReadVar (F);
        unsigned        Flags = ReadVar (F);
        const char*     ScopeType = GetScopeType (ReadVar (F));

	/* Print the header */
	printf ("    Index:%27u\n", I);

       	/* Print the data */
        printf ("      Parent id:%21u\n",       ParentId);
        printf ("      Lexical level:%17u\n",   LexicalLevel);
       	printf ("      Flags:%21s0x%02X\n",     "", Flags);
        printf ("      Type:%26s\n",            ScopeType);

        /* Resolve and print the name */
       	Name = GetString (&StrPool, ReadVar (F));
	Len  = strlen (Name);
	printf ("      Name:%*s\"%s\"\n", (int)(24-Len), "", Name);

        /* Size */
       	if (SCOPE_HAS_SIZE (Flags)) {
            unsigned long Size = ReadVar (F);
	    printf ("      Size:%20s0x%04lX  (%lu)\n", "", Size, Size);
	}

        /* Label */
        if (SCOPE_HAS_LABEL (Flags)) {
            unsigned LabelId = ReadVar (F);
            printf ("      Label id:%22u\n", LabelId);
        }

        /* Skip the spans */
        SkipSpanList (F);
    }

    /* Destroy the string pool */
    DestroyStrPool (&StrPool);
}
コード例 #12
0
ファイル: dump.c プロジェクト: eakmeister/cc65
void DumpObjLineInfo (FILE* F, unsigned long Offset)
/* Dump the line info from an object file */
{
    ObjHeader   H;
    Collection  StrPool = AUTO_COLLECTION_INITIALIZER;
    unsigned    Count;
    unsigned    I;

    /* Seek to the header position and read the header */
    FileSetPos (F, Offset);
    ReadObjHeader (F, &H);

    /* Seek to the start of the string pool and read it */
    FileSetPos (F, Offset + H.StrPoolOffs);
    ReadStrPool (F, &StrPool);

    /* Seek to the start of line infos */
    FileSetPos (F, Offset + H.LineInfoOffs);

    /* Output a header */
    printf ("  Line info:\n");

    /* Check if the object file was compiled with debug info */
    if ((H.Flags & OBJ_FLAGS_DBGINFO) == 0) {
	/* Print that there no line infos and bail out */
	printf ("    Count:%27u\n", 0);
	return;
    }

    /* Read the number of line infos and print it */
    Count = ReadVar (F);
    printf ("    Count:%27u\n", Count);

    /* Read and print all line infos */
    for (I = 0; I < Count; ++I) {

	FilePos   Pos;
        unsigned  Type;

       	/* File position of line info */
	ReadFilePos (F, &Pos);

        /* Type of line info */
        Type = ReadVar (F);

        /* Skip the spans */
        SkipSpanList (F);

	/* Print the header */
	printf ("    Index:%27u\n", I);

	/* Print the data */
        printf ("      Type:%26u\n", LI_GET_TYPE (Type));
        printf ("      Count:%25u\n", LI_GET_COUNT (Type));
       	printf ("      Line:%26u\n", Pos.Line);
       	printf ("      Col:%27u\n", Pos.Col);
       	printf ("      Name:%26u\n", Pos.Name);
    }

    /* Destroy the string pool */
    DestroyStrPool (&StrPool);
}
コード例 #13
0
ファイル: dump.c プロジェクト: eakmeister/cc65
void DumpObjDbgSyms (FILE* F, unsigned long Offset)
/* Dump the debug symbols from an object file */
{
    ObjHeader   H;
    Collection  StrPool = AUTO_COLLECTION_INITIALIZER;
    unsigned    Count;
    unsigned    I;

    /* Seek to the header position and read the header */
    FileSetPos (F, Offset);
    ReadObjHeader (F, &H);

    /* Seek to the start of the string pool and read it */
    FileSetPos (F, Offset + H.StrPoolOffs);
    ReadStrPool (F, &StrPool);

    /* Seek to the start of the debug syms */
    FileSetPos (F, Offset + H.DbgSymOffs);

    /* Output a header */
    printf ("  Debug symbols:\n");

    /* Check if the object file was compiled with debug info */
    if ((H.Flags & OBJ_FLAGS_DBGINFO) == 0) {
	/* Print that there no debug symbols and bail out */
	printf ("    Count:%27u\n", 0);
	return;
    }

    /* Read the number of exports and print it */
    Count = ReadVar (F);
    printf ("    Count:%27u\n", Count);

    /* Read and print all debug symbols */
    for (I = 0; I < Count; ++I) {

    	unsigned long 	Value = 0;
        unsigned long   Size = 0;
        unsigned        ImportId = 0;
        unsigned        ExportId = 0;

       	/* Read the data for one symbol */
       	unsigned Type          = ReadVar (F);
        unsigned char AddrSize = Read8 (F);
        unsigned long Owner    = ReadVar (F);
       	const char*   Name     = GetString (&StrPool, ReadVar (F));
	unsigned      Len      = strlen (Name);
	if (SYM_IS_CONST (Type)) {
	    Value = Read32 (F);
	} else {
	    SkipExpr (F);
	}
        if (SYM_HAS_SIZE (Type)) {
            Size = ReadVar (F);
        }
        if (SYM_IS_IMPORT (Type)) {
            ImportId = ReadVar (F);
        }
        if (SYM_IS_EXPORT (Type)) {
            ExportId = ReadVar (F);
        }

        /* Skip both line info lists */
        SkipLineInfoList (F);
        SkipLineInfoList (F);

	/* Print the header */
	printf ("    Index:%27u\n", I);

	/* Print the data */
       	printf ("      Type:%22s0x%02X  (%s)\n", "", Type, GetExportFlags (Type, 0));
	printf ("      Address size:%14s0x%02X  (%s)\n", "", AddrSize,
                AddrSizeToStr (AddrSize));
       	printf ("      Owner:%25lu\n", Owner);
	printf ("      Name:%*s\"%s\"\n", (int)(24-Len), "", Name);
	if (SYM_IS_CONST (Type)) {
	    printf ("      Value:%15s0x%08lX  (%lu)\n", "", Value, Value);
	}
       	if (SYM_HAS_SIZE (Type)) {
	    printf ("      Size:%20s0x%04lX  (%lu)\n", "", Size, Size);
	}
       	if (SYM_IS_IMPORT (Type)) {
	    printf ("      Import:%24u\n", ImportId);
	}
       	if (SYM_IS_EXPORT (Type)) {
	    printf ("      Export:%24u\n", ExportId);
	}
    }

    /* Destroy the string pool */
    DestroyStrPool (&StrPool);
}
コード例 #14
0
ファイル: dump.c プロジェクト: eakmeister/cc65
void DumpObjExports (FILE* F, unsigned long Offset)
/* Dump the exports in the object file */
{
    ObjHeader 	H;
    Collection  StrPool = AUTO_COLLECTION_INITIALIZER;
    unsigned   	Count;
    unsigned   	I;

    /* Seek to the header position and read the header */
    FileSetPos (F, Offset);
    ReadObjHeader (F, &H);

    /* Seek to the start of the string pool and read it */
    FileSetPos (F, Offset + H.StrPoolOffs);
    ReadStrPool (F, &StrPool);

    /* Seek to the start of the exports */
    FileSetPos (F, Offset + H.ExportOffs);

    /* Output a header */
    printf ("  Exports:\n");

    /* Read the number of exports and print it */
    Count = ReadVar (F);
    printf ("    Count:%27u\n", Count);

    /* Read and print all exports */
    for (I = 0; I < Count; ++I) {

	unsigned long 	Value = 0;
        unsigned long   Size = 0;
       	unsigned char  	ConDes[CD_TYPE_COUNT];
       	const char*    	Name;
	unsigned	Len;


       	/* Read the data for one export */
       	unsigned Type          = ReadVar (F);
        unsigned char AddrSize = Read8 (F);
	ReadData (F, ConDes, SYM_GET_CONDES_COUNT (Type));
       	Name  = GetString (&StrPool, ReadVar (F));
	Len   = strlen (Name);
       	if (SYM_IS_CONST (Type)) {
	    Value = Read32 (F);
	} else {
       	    SkipExpr (F);
	}
        if (SYM_HAS_SIZE (Type)) {
            Size = ReadVar (F);
        }

        /* Skip both line infos lists */
        SkipLineInfoList (F);
        SkipLineInfoList (F);

	/* Print the header */
	printf ("    Index:%27u\n", I);

	/* Print the data */
       	printf ("      Type:%22s0x%02X  (%s)\n", "", Type, GetExportFlags (Type, ConDes));
	printf ("      Address size:%14s0x%02X  (%s)\n", "", AddrSize,
                AddrSizeToStr (AddrSize));
	printf ("      Name:%*s\"%s\"\n", (int)(24-Len), "", Name);
	if (SYM_IS_CONST (Type)) {
    	    printf ("      Value:%15s0x%08lX  (%lu)\n", "", Value, Value);
    	}
       	if (SYM_HAS_SIZE (Type)) {
	    printf ("      Size:%16s0x%04lX  (%lu)\n", "", Size, Size);
	}
    }

    /* Destroy the string pool */
    DestroyStrPool (&StrPool);
}
コード例 #15
0
ファイル: dump.c プロジェクト: eakmeister/cc65
void DumpObjOptions (FILE* F, unsigned long Offset)
/* Dump the file options */
{
    ObjHeader  H;
    Collection StrPool = AUTO_COLLECTION_INITIALIZER;
    unsigned   Count;
    unsigned   I;

    /* Seek to the header position and read the header */
    FileSetPos (F, Offset);
    ReadObjHeader (F, &H);

    /* Seek to the start of the string pool and read it */
    FileSetPos (F, Offset + H.StrPoolOffs);
    ReadStrPool (F, &StrPool);

    /* Seek to the start of the options */
    FileSetPos (F, Offset + H.OptionOffs);

    /* Output a header */
    printf ("  Options:\n");

    /* Read the number of options and print it */
    Count = ReadVar (F);
    printf ("    Count:%27u\n", Count);

    /* Read and print all options */
    for (I = 0; I < Count; ++I) {

    	const char*   ArgStr;
    	unsigned      ArgLen;

    	/* Read the type of the option and the value */
    	unsigned char Type = Read8 (F);
        unsigned long Val  = ReadVar (F);

       	/* Get the type of the argument */
    	unsigned char ArgType = Type & OPT_ARGMASK;

    	/* Determine which option follows */
    	const char* TypeDesc;
    	switch (Type) {
       	    case OPT_COMMENT:  	TypeDesc = "OPT_COMMENT";	break;
    	    case OPT_AUTHOR:  	TypeDesc = "OPT_AUTHOR";	break;
    	    case OPT_TRANSLATOR:TypeDesc = "OPT_TRANSLATOR";	break;
    	    case OPT_COMPILER:	TypeDesc = "OPT_COMPILER";	break;
    	    case OPT_OS:      	TypeDesc = "OPT_OS";		break;
    	    case OPT_DATETIME:	TypeDesc = "OPT_DATETIME";	break;
    	    default:	      	TypeDesc = "OPT_UNKNOWN";	break;
    	}

    	/* Print the header */
    	printf ("    Index:%27u\n", I);

    	/* Print the data */
    	printf ("      Type:%22s0x%02X  (%s)\n", "", Type, TypeDesc);
    	switch (ArgType) {

    	    case OPT_ARGSTR:
    	     	ArgStr = GetString (&StrPool, Val);
    	    	ArgLen = strlen (ArgStr);
    	     	printf ("      Data:%*s\"%s\"\n", (int)(24-ArgLen), "", ArgStr);
    	     	break;

    	    case OPT_ARGNUM:
    	     	printf ("      Data:%26lu", Val);
    	    	if (Type == OPT_DATETIME) {
    		    /* Print the time as a string */
    		    printf ("  (%s)", TimeToStr (Val));
    		}
		printf ("\n");
	     	break;

	    default:
	     	/* Unknown argument type. This means that we cannot determine
	     	 * the option length, so we cannot proceed.
	     	 */
	     	Error ("Unknown option type: 0x%02X", Type);
	     	break;
	}
    }

    /* Destroy the string pool */
    DestroyStrPool (&StrPool);
}
コード例 #16
0
ファイル: pcx.c プロジェクト: Aliandrana/cc65
Bitmap* ReadPCXFile (const Collection* A)
/* Read a bitmap from a PCX file */
{
    PCXHeader* P;
    Bitmap* B;
    unsigned char* L;
    Pixel* Px;
    unsigned MaxIdx = 0;
    unsigned X, Y;


    /* Get the file name */
    const char* Name = NeedAttrVal (A, "name", "read pcx file");

    /* Open the file */
    FILE* F = fopen (Name, "rb");
    if (F == 0) {
        Error ("Cannot open PCX file `%s': %s", Name, strerror (errno));
    }

    /* Read the PCX header */
    P = ReadPCXHeader (F, Name);

    /* Dump the header if requested */
    if (Verbosity > 0) {
        DumpPCXHeader (P, Name);
    }

    /* Create the bitmap */
    B = NewBitmap (P->Width, P->Height);

    /* Copy the name */
    SB_CopyStr (&B->Name, Name);

    /* Allocate memory for the scan line */
    L = xmalloc (P->Width);

    /* Read the pixel data */
    Px = B->Data;
    if (P->Planes == 1) {

        /* This is either monochrome or indexed */
        if (P->BPP == 1) {
            /* Monochrome */
            for (Y = 0, Px = B->Data; Y < P->Height; ++Y) {

                unsigned I;
                unsigned char Mask;

                /* Read the plane */
                ReadPlane (F, P, L);

                /* Create pixels */
                for (X = 0, I = 0, Mask = 0x01; X < P->Width; ++Px) {
                    Px->Index = (L[I] & Mask) != 0;
                    if (Mask == 0x80) {
                        Mask = 0x01;
                        ++I;
                    } else {
                        Mask <<= 1;
                    }
                }

            }
        } else {
            /* One plane with 8bpp is indexed */
            for (Y = 0, Px = B->Data; Y < P->Height; ++Y) {

                /* Read the plane */
                ReadPlane (F, P, L);

                /* Create pixels */
                for (X = 0; X < P->Width; ++X, ++Px) {
                    if (L[X] > MaxIdx) {
                        MaxIdx = L[X];
                    }
                    Px->Index = L[X];
                }
            }
        }

        /* One plane means we have a palette which is either part of the header
        ** or follows.
        */
        if (P->PalInfo == 0) {

            /* Create the monochrome palette */
            B->Pal = NewMonochromePalette ();

        } else {

            unsigned      Count;
            unsigned      I;
            unsigned char Palette[256][3];
            unsigned long EndPos;

            /* Determine the current file position */
            unsigned long CurPos = FileGetPos (F);

            /* Seek to the end of the file */
            (void) fseek (F, 0, SEEK_END);

            /* Get this position */
            EndPos = FileGetPos (F);

            /* There's a palette if the old location is 769 bytes from the end */
            if (EndPos - CurPos == sizeof (Palette) + 1) {

                /* Seek back */
                FileSetPos (F, CurPos);

                /* Check for palette marker */
                if (Read8 (F) != 0x0C) {
                    Error ("Invalid palette marker in PCX file `%s'", Name);
                }

            } else if (EndPos == CurPos) {

                /* The palette is in the header */
                FileSetPos (F, 16);

                /* Check the maximum index for safety */
                if (MaxIdx > 15) {
                    Error ("PCX file `%s' contains more than 16 indexed colors "
                           "but no extra palette", Name);
                }

            } else {
                Error ("Error in PCX file `%s': %lu bytes at end of pixel data",
                       Name, EndPos - CurPos);
            }

            /* Read the palette. We will just read what we need. */
            Count = MaxIdx + 1;
            ReadData (F, Palette, Count * sizeof (Palette[0]));

            /* Create the palette from the data */
            B->Pal = NewPalette (Count);
            for (I = 0; I < Count; ++I) {
                B->Pal->Entries[I].R = Palette[I][0];
                B->Pal->Entries[I].G = Palette[I][1];
                B->Pal->Entries[I].B = Palette[I][2];
                B->Pal->Entries[I].A = 0;
            }

        }

    } else {

        /* 3 or 4 planes are RGB or RGBA (don't know if this exists) */
        for (Y = 0, Px = B->Data; Y < P->Height; ++Y) {

            /* Read the R plane and move the data */
            ReadPlane (F, P, L);
            for (X = 0; X < P->Width; ++X, ++Px) {
                Px->C.R = L[X];
            }

            /* Read the G plane and move the data */
            ReadPlane (F, P, L);
            for (X = 0; X < P->Width; ++X, ++Px) {
                Px->C.G = L[X];
            }

            /* Read the B plane and move the data */
            ReadPlane (F, P, L);
            for (X = 0; X < P->Width; ++X, ++Px) {
                Px->C.B = L[X];
            }

            /* Either read the A plane or clear it */
            if (P->Planes == 4) {
                ReadPlane (F, P, L);
                for (X = 0; X < P->Width; ++X, ++Px) {
                    Px->C.A = L[X];
                }
            } else {
                for (X = 0; X < P->Width; ++X, ++Px) {
                    Px->C.A = 0;
                }
            }
        }
    }

    /* Close the file */
    fclose (F);

    /* Free memory for the scan line */
    xfree (L);

    /* Free the PCX header */
    FreePCXHeader (P);

    /* Return the bitmap */
    return B;
}