Esempio n. 1
0
static void GetInputChar (void)
/* Read the next character from the input stream and make CurC and NextC
 * valid. If end of line is reached, both are set to NUL, no more lines
 * are read by this function.
 */
{
    /* Drop all pushed fragments that don't have data left */
    while (SB_GetIndex (Line) >= SB_GetLen (Line)) {
        /* Cannot read more from this line, check next line on stack if any */
        if (CollCount (&InputStack) == 0) {
            /* This is THE line */
            break;
        }
        FreeStrBuf (Line);
        Line = CollPop (&InputStack);
    }

    /* Now get the next characters from the line */
    if (SB_GetIndex (Line) >= SB_GetLen (Line)) {
        CurC = NextC = '\0';
    } else {
        CurC = SB_AtUnchecked (Line, SB_GetIndex (Line));
        if (SB_GetIndex (Line) + 1 < SB_GetLen (Line)) {
            /* NextC comes from this fragment */
            NextC = SB_AtUnchecked (Line, SB_GetIndex (Line) + 1);
        } else {
            /* NextC comes from next fragment */
            if (CollCount (&InputStack) > 0) {
                NextC = ' ';
            } else {
                NextC = '\0';
            }
        }
    }
}
Esempio n. 2
0
static unsigned GetRegInfo1 (CodeSeg* S,
                             CodeEntry* E,
                             int Index,
                             Collection* Visited,
                             unsigned Used,
                             unsigned Unused,
                             unsigned Wanted)
/* Recursively called subfunction for GetRegInfo. */
{
    /* Remember the current count of the line collection */
    unsigned Count = CollCount (Visited);

    /* Call the worker routine */
    unsigned R = GetRegInfo2 (S, E, Index, Visited, Used, Unused, Wanted);

    /* Restore the old count, unmarking all new entries */
    unsigned NewCount = CollCount (Visited);
    while (NewCount-- > Count) {
        CodeEntry* E = CollAt (Visited, NewCount);
        CE_ResetMark (E);
        CollDelete (Visited, NewCount);
    }

    /* Return the registers used */
    return R;
}
Esempio n. 3
0
File: segments.c Progetto: cc65/cc65
void SegDump (void)
/* Dump the segments and it's contents */
{
    unsigned I, J;
    unsigned long Count;
    unsigned char* Data;

    for (I = 0; I < CollCount (&SegmentList); ++I) {
        Segment* Seg = CollAtUnchecked (&SegmentList, I);
        printf ("Segment: %s (%lu)\n", GetString (Seg->Name), Seg->Size);
        for (J = 0; J < CollCount (&Seg->Sections); ++J) {
            Section* S = CollAtUnchecked (&Seg->Sections, J);
            unsigned J;
            Fragment* F = S->FragRoot;
            printf ("  Section:\n");
            while (F) {
                switch (F->Type) {

                    case FRAG_LITERAL:
                        printf ("    Literal (%u bytes):", F->Size);
                        Count = F->Size;
                        Data  = F->LitBuf;
                        J = 100;
                        while (Count--) {
                            if (J > 75) {
                                printf ("\n   ");
                                J = 3;
                            }
                            printf (" %02X", *Data++);
                            J += 3;
                        }
                        printf ("\n");
                        break;

                    case FRAG_EXPR:
                        printf ("    Expression (%u bytes):\n", F->Size);
                        printf ("    ");
                        DumpExpr (F->Expr, 0);
                        break;

                    case FRAG_SEXPR:
                        printf ("    Signed expression (%u bytes):\n", F->Size);
                        printf ("      ");
                        DumpExpr (F->Expr, 0);
                        break;

                    case FRAG_FILL:
                        printf ("    Empty space (%u bytes)\n", F->Size);
                        break;

                    default:
                        Internal ("Invalid fragment type: %02X", F->Type);
                }
                F = F->Next;
            }
        }
    }
}
Esempio n. 4
0
static void ExecCmd (Collection* Args, const CmdEntry* Tab, unsigned Count)
/* Search for the command in slot 0 of the given collection. If found, check
 * the argument count, then execute it. If there are problems, output a
 * diagnostic.
 */
{
    /* Search for the command, check number of args, then execute it */
    const char* Cmd = CollAt (Args, 0);
    const CmdEntry* E = FindCmd (Cmd, Tab, Count);
    if (E == 0) {
        PrintLine ("No such command: %s", Cmd);
        return;
    }

    /* Check the number of arguments. Zero means that the function will check
     * itself. A negative count means that the function needs at least
     * abs(count) arguments. A positive count means that the function needs
     * exactly this number of arguments.
     * Note: The number includes the command itself.
     */
    if (E->ArgCount > 0 && (int)CollCount (Args) != E->ArgCount) {
        /* Argument number mismatch */
        switch (E->ArgCount) {

            case 1:
                PrintLine ("Command doesn't accept an argument");
                return;

            case 2:
                PrintLine ("Command requires an argument");
                return;

            default:
                PrintLine ("Command requires %d arguments", E->ArgCount-1);
                return;
        }
    } else if (E->ArgCount < 0 && (int)CollCount (Args) < -E->ArgCount) {
        /* Argument number mismatch */
        switch (E->ArgCount) {

            case -2:
                PrintLine ("Command requires at least one argument");
                return;

            default:
                PrintLine ("Command requires at least %d arguments", E->ArgCount-1);
                return;
        }
    } else {
        /* Remove the command from the argument list, then execute it */
        CollDelete (Args, 0);
        E->Func (Args);
    }
}
Esempio n. 5
0
static void PrintO65Stats (const O65Data* D)
/* Print information about the O65 file if --verbose is given */
{
    Print (stdout, 1, "Size of text segment:               %5lu\n", D->Header.tlen);
    Print (stdout, 1, "Size of data segment:               %5lu\n", D->Header.dlen);
    Print (stdout, 1, "Size of bss segment:                %5lu\n", D->Header.blen);
    Print (stdout, 1, "Size of zeropage segment:           %5lu\n", D->Header.zlen);
    Print (stdout, 1, "Number of imports:                  %5u\n", CollCount (&D->Imports));
    Print (stdout, 1, "Number of exports:                  %5u\n", CollCount (&D->Exports));
    Print (stdout, 1, "Number of text segment relocations: %5u\n", CollCount (&D->TextReloc));
    Print (stdout, 1, "Number of data segment relocations: %5u\n", CollCount (&D->DataReloc));
}
Esempio n. 6
0
ExprNode* ULabRef (int Which)
/* Get an unnamed label. If Which is negative, it is a backreference (a
 * reference to an already defined label), and the function will return a
 * segment relative expression. If Which is positive, it is a forward ref,
 * and the function will return a expression node for an unnamed label that
 * must be resolved later.
 */
{
    int     Index;
    ULabel* L;

    /* Which can never be 0 */
    PRECONDITION (Which != 0);

    /* Get the index of the referenced label */
    if (Which > 0) {
        --Which;
    }
    Index = (int) ULabDefCount + Which;

    /* We cannot have negative label indices */
    if (Index < 0) {
        /* Label does not exist */
        Error ("Undefined label");
        /* We must return something valid */
        return GenCurrentPC();
    }

    /* Check if the label exists. If not, generate enough forward labels. */
    if (Index < (int) CollCount (&ULabList)) {
        /* The label exists, get it. */
        L = CollAtUnchecked (&ULabList, Index);
    } else {
        /* Generate new, undefined labels */
        while (Index >= (int) CollCount (&ULabList)) {
            L = NewULabel (0);
        }
    }

    /* Mark the label as referenced */
    ++L->Ref;

    /* If the label is already defined, return its value, otherwise return
     * just a reference.
     */
    if (L->Val) {
        return CloneExpr (L->Val);
    } else {
        return GenULabelExpr (Index);
    }
}
Esempio n. 7
0
void InsertObjGlobals (ObjData* O)
/* Insert imports and exports from the object file into the global import and
 * export lists.
 */
{
    unsigned I;

    /* Insert exports and imports */
    for (I = 0; I < CollCount (&O->Exports); ++I) {
        InsertExport (CollAt (&O->Exports, I));
    }
    for (I = 0; I < CollCount (&O->Imports); ++I) {
        InsertImport (CollAt (&O->Imports, I));
    }
}
Esempio n. 8
0
Collection* ParseAttrList (const char* List, const char** NameList, unsigned NameCount)
/* Parse a list containing name/value pairs into a sorted collection. Some
 * attributes may not need a name, so NameList contains these names. If there
 * were no errors, the function returns a alphabetically sorted collection
 * containing Attr entries.
 */
{
    const char* Name;

    /* Create a new collection */
    Collection* C = NewCollection ();

    /* Name/value pairs are separated by commas */
    const char* L = List;
    StrBuf B = AUTO_STRBUF_INITIALIZER;
    while (1) {
        if (*L == ',' || *L == ':' || *L == '\0') {

            /* Terminate the string */
            SB_Terminate (&B);

            /* Determine the default name */
            if (CollCount (C) >= NameCount) {
                Name = 0;
            } else {
                Name = NameList[CollCount (C)];
            }

            /* Split and add this attribute/value pair */
            SplitAddAttr (C, SB_GetConstBuf (&B), Name);

            /* Done, clear the buffer. */
            SB_Clear (&B);
            if (*L == '\0') {
                break;
            }
        } else {
            SB_AppendChar (&B, *L);
        }
        ++L;
    }

    /* Free memory */
    SB_Done (&B);

    /* Return the collection with the attributes */
    return C;
}
Esempio n. 9
0
static void CloseIncludeFile (void)
/* Close an include file and switch to the higher level file. Set Input to
 * NULL if this was the main file.
 */
{
    AFile* Input;

    /* Get the number of active input files */
    unsigned AFileCount = CollCount (&AFiles);

    /* Must have an input file when called */
    PRECONDITION (AFileCount > 0);

    /* Get the current active input file */
    Input = (AFile*) CollLast (&AFiles);

    /* Close the current input file (we're just reading so no error check) */
    fclose (Input->F);

    /* Delete the last active file from the active file collection */
    CollDelete (&AFiles, AFileCount-1);

    /* If we had added an extra search path for this AFile, remove it */
    if (Input->SearchPath) {
        PopSearchPath (UsrIncSearchPath);
    }

    /* Delete the active file structure */
    FreeAFile (Input);
}
Esempio n. 10
0
void CS_DelLabel (CodeSeg* S, CodeLabel* L)
/* Remove references from this label and delete it. */
{
    unsigned Count, I;

    /* First, remove the label from the hash chain */
    CS_RemoveLabelFromHash (S, L);

    /* Remove references from insns jumping to this label */
    Count = CollCount (&L->JumpFrom);
    for (I = 0; I < Count; ++I) {
       	/* Get the insn referencing this label */
       	CodeEntry* E = CollAt (&L->JumpFrom, I);
       	/* Remove the reference */
       	CE_ClearJumpTo (E);
    }
    CollDeleteAll (&L->JumpFrom);

    /* Remove the reference to the owning instruction if it has one. The
     * function may be called for a label without an owner when deleting
     * unfinished parts of the code. This is unfortunate since it allows
     * errors to slip through.
     */
    if (L->Owner) {
       	CollDeleteItem (&L->Owner->Labels, L);
    }

    /* All references removed, delete the label itself */
    FreeCodeLabel (L);
}
Esempio n. 11
0
File: segments.c Progetto: cc65/cc65
int IsBSSType (Segment* S)
/* Check if the given segment is a BSS style segment, that is, it does not
** contain non-zero data.
*/
{
    /* Loop over all sections */
    unsigned I;
    for (I = 0; I < CollCount (&S->Sections); ++I) {

        /* Get the next section */
        Section* Sec = CollAtUnchecked (&S->Sections, I);

        /* Loop over all fragments */
        Fragment* F = Sec->FragRoot;
        while (F) {
            if (F->Type == FRAG_LITERAL) {
                unsigned char* Data = F->LitBuf;
                unsigned long Count = F->Size;
                while (Count--) {
                    if (*Data++ != 0) {
                        return 0;
                    }
                }
            } else if (F->Type == FRAG_EXPR || F->Type == FRAG_SEXPR) {
                if (GetExprVal (F->Expr) != 0) {
                    return 0;
                }
            }
            F = F->Next;
        }
    }
    return 1;
}
Esempio n. 12
0
void WriteAssertions (void)
/* Write the assertion table to the object file */
{
    unsigned I;

    /* Get the number of assertions */
    unsigned Count = CollCount (&Assertions);

    /* Tell the object file module that we're about to start the assertions */
    ObjStartAssertions ();

    /* Write the string count to the list */
    ObjWriteVar (Count);

    /* Write the assertions */
    for (I = 0; I < Count; ++I) {

        /* Get the next assertion */
        Assertion* A = CollAtUnchecked (&Assertions, I);

        /* Write it to the file */
        WriteExpr (A->Expr);
        ObjWriteVar ((unsigned) A->Action);
        ObjWriteVar (A->Msg);
        WriteLineInfo (&A->LI);
    }

    /* Done writing the assertions */
    ObjEndAssertions ();
}
Esempio n. 13
0
static void SymReplaceExprRefs (SymEntry* S)
/* Replace the references to this symbol by a copy of the symbol expression */
{
    unsigned I;
    long     Val;

    /* Check if the expression is const and get its value */
    int IsConst = IsConstExpr (S->Expr, &Val);
    CHECK (IsConst);

    /* Loop over all references */
    for (I = 0; I < CollCount (&S->ExprRefs); ++I) {

        /* Get the expression node */
        ExprNode* E = CollAtUnchecked (&S->ExprRefs, I);

        /* Safety */
        CHECK (E->Op == EXPR_SYMBOL && E->V.Sym == S);

        /* We cannot touch the root node, since there are pointers to it.
        ** Replace it by a literal node.
        */
        E->Op = EXPR_LITERAL;
        E->V.IVal = Val;
    }

    /* Remove all symbol references from the symbol */
    CollDeleteAll (&S->ExprRefs);
}
Esempio n. 14
0
static void ReadIndex (void)
/* Read the index of a library file */
{
    unsigned Count, I;

    /* Seek to the start of the index */
    fseek (Lib, Header.IndexOffs, SEEK_SET);

    /* Read the object file count and calculate the cross ref size */
    Count = ReadVar (Lib);

    /* Read all entries in the index */
    while (Count--) {
        ReadIndexEntry ();
    }

    /* Read basic object file data from the actual entries */
    for (I = 0; I < CollCount (&ObjPool); ++I) {

        /* Get the object file entry */
        ObjData* O = CollAtUnchecked (&ObjPool, I);

        /* Read data */
        ObjReadData (Lib, O);
    }
}
Esempio n. 15
0
char* SearchFile (const SearchPaths* P, const char* File)
/* Search for a file in a list of directories. Return a pointer to a malloced
** area that contains the complete path, if found, return 0 otherwise.
*/
{
    char* Name = 0;
    StrBuf PathName = AUTO_STRBUF_INITIALIZER;

    /* Start the search */
    unsigned I;
    for (I = 0; I < CollCount (P); ++I) {

        /* Copy the next path element into the buffer */
        SB_CopyStr (&PathName, CollConstAt (P, I));

        /* Add a path separator and the filename */
        if (SB_NotEmpty (&PathName)) {
            SB_AppendChar (&PathName, '/');
        }
        SB_AppendStr (&PathName, File);
        SB_Terminate (&PathName);

        /* Check if this file exists */
        if (access (SB_GetBuf (&PathName), 0) == 0) {
            /* The file exists, we're done */
            Name = xstrdup (SB_GetBuf (&PathName));
            break;
        }
    }

    /* Cleanup and return the result of the search */
    SB_Done (&PathName);
    return Name;
}
Esempio n. 16
0
static Segment* NewSegFromDef (SegDef* Def)
/* Create a new segment from a segment definition. Used only internally, no
 * checks.
 */
{
    /* Create a new segment */
    Segment* S = xmalloc (sizeof (*S));

    /* Initialize it */
    S->Root      = 0;
    S->Last      = 0;
    S->FragCount = 0;
    S->Num       = CollCount (&SegmentList);
    S->Flags     = SEG_FLAG_NONE;
    S->Align     = 1;
    S->RelocMode = 1;
    S->PC        = 0;
    S->AbsPC     = 0;
    S->Def       = Def;

    /* Insert it into the segment list */
    CollAppend (&SegmentList, S);

    /* And return it... */
    return S;
}
Esempio n. 17
0
void PrintDbgModules (FILE* F)
/* Output the modules to a debug info file */
{
    unsigned I;

    /* Output modules */
    for (I = 0; I < CollCount (&ObjDataList); ++I) {

        /* Get this object file */
        const ObjData* O = CollConstAt (&ObjDataList, I);

        /* The main source file is the one at index zero */
        const FileInfo* Source = CollConstAt (&O->Files, 0);

        /* Output the module line */
        fprintf (F,
                 "mod\tid=%u,name=\"%s\",file=%u",
                 I,
                 GetObjFileName (O),
                 Source->Id);

        /* Add library if any */
        if (O->Lib != 0) {
            fprintf (F, ",lib=%u", GetLibId (O->Lib));
        }

        /* Terminate the output line */
        fputc ('\n', F);
    }

}
Esempio n. 18
0
static void WriteDep (FILE* F, FileType Types)
/* Helper function. Writes all file names that match Types to the output */
{
    unsigned I;

    /* Loop over all files */
    for (I = 0; I < CollCount (&FileTab); ++I) {

        const StrBuf* Filename;

        /* Get the next input file */
        const FileEntry* E = (const FileEntry*) CollAt (&FileTab, I);

        /* Ignore it if it is not of the correct type */
        if ((E->Type & Types) == 0) {
            continue;
        }

        /* If this is not the first file, add a space */
        if (I > 0) {
            fputc (' ', F);
        }

        /* Print the dependency */
        Filename = GetStrBuf (E->Name);
        fprintf (F, "%*s", SB_GetLen (Filename), SB_GetConstBuf (Filename));
    }
}
Esempio n. 19
0
void SymLeaveLevel (void)
/* Leave the current lexical level */
{
    /* If this is a scope that allows to emit data into segments, close the
    ** open the spans.
    */
    if (CurrentScope->Type <= SCOPE_HAS_DATA) {
        CloseSpanList (&CurrentScope->Spans);
    }

    /* If we have spans, the first one is the segment that was active, when the
    ** scope was opened. Set the size of the scope to the number of data bytes
    ** emitted into this segment. If we have an owner symbol set the size of
    ** this symbol, too.
    */
    if (CollCount (&CurrentScope->Spans) > 0) {
        const Span* S = CollAtUnchecked (&CurrentScope->Spans, 0);
        unsigned long Size = GetSpanSize (S);
        DefSizeOfScope (CurrentScope, Size);
        if (CurrentScope->Label) {
            DefSizeOfSymbol (CurrentScope->Label, Size);
        }
    }

    /* Mark the scope as closed */
    CurrentScope->Flags |= ST_CLOSED;

    /* Leave the scope */
    CurrentScope = CurrentScope->Parent;
}
Esempio n. 20
0
void UseSeg (const SegDef* D)
/* Use the segment with the given name */
{
    unsigned I;
    for (I = 0; I < CollCount (&SegmentList); ++I) {
        Segment* Seg = CollAtUnchecked (&SegmentList, I);
       	if (strcmp (Seg->Def->Name, D->Name) == 0) {
     	    /* We found this segment. Check if the type is identical */
	    if (D->AddrSize != ADDR_SIZE_DEFAULT &&
                Seg->Def->AddrSize != D->AddrSize) {
	 	Error ("Segment attribute mismatch");
	 	/* Use the new attribute to avoid errors */
	        Seg->Def->AddrSize = D->AddrSize;
       	    }
       	    ActiveSeg = Seg;
     	    return;
     	}
    }

    /* Segment is not in list, create a new one */
    if (D->AddrSize == ADDR_SIZE_DEFAULT) {
        ActiveSeg = NewSegment (D->Name, ADDR_SIZE_ABS);
    } else {
        ActiveSeg = NewSegment (D->Name, D->AddrSize);
    }
}
Esempio n. 21
0
static void PrintUnresolved (ExpCheckFunc F, void* Data)
/* Print a list of unresolved symbols. On unresolved symbols, F is
** called (see the comments on ExpCheckFunc in the data section).
*/
{
    unsigned I;

    /* Print all open imports */
    for (I = 0; I < ExpCount; ++I) {
        Export* E = ExpPool [I];
        if (E->Expr == 0 && E->ImpCount > 0 && F (E->Name, Data) == 0) {
            /* Unresolved external */
            Import* Imp = E->ImpList;
            fprintf (stderr,
                     "Unresolved external `%s' referenced in:\n",
                     GetString (E->Name));
            while (Imp) {
                unsigned J;
                for (J = 0; J < CollCount (&Imp->RefLines); ++J) {
                    const LineInfo* LI = CollConstAt (&Imp->RefLines, J);
                    fprintf (stderr,
                         "  %s(%u)\n",
                         GetSourceName (LI),
                         GetSourceLine (LI));
                }
                Imp = Imp->Next;
            }
        }
    }
}
Esempio n. 22
0
static void WriteDep (FILE* F, InputType Types)
/* Helper function. Writes all file names that match Types to the output */
{
    unsigned I;

    /* Loop over all files */
    unsigned FileCount = CollCount (&IFiles);
    for (I = 0; I < FileCount; ++I) {

    	/* Get the next input file */
    	const IFile* IF = (const IFile*) CollAt (&IFiles, I);

        /* Ignore it if it is not of the correct type */
        if ((IF->Type & Types) == 0) {
            continue;
        }

    	/* If this is not the first file, add a space */
       	if (I > 0) {
            fputc (' ', F);
        }

    	/* Print the dependency escaping spaces */
        WriteEscaped (F, IF->Name);
    }
}
Esempio n. 23
0
static void AddNotifications (const Collection* LineInfos)
/* Output additional notifications for an error or warning */
{
    unsigned I;
    unsigned Output;
    unsigned Skipped;

    /* The basic line info is always in slot zero. It has been used to
    ** output the actual error or warning. The following slots may contain
    ** more information. Check them and print additional notifications if
    ** they're present, but limit the number to a reasonable value.
    */
    for (I = 1, Output = 0, Skipped = 0; I < CollCount (LineInfos); ++I) {
        /* Get next line info */
        const LineInfo* LI = CollConstAt (LineInfos, I);
        /* Check the type and output an appropriate note */
        const char* Msg;
        switch (GetLineInfoType (LI)) {

        case LI_TYPE_ASM:
            Msg = "Expanded from here";
            break;

        case LI_TYPE_EXT:
            Msg = "Assembler code generated from this line";
            break;

        case LI_TYPE_MACRO:
            Msg = "Macro was defined here";
            break;

        case LI_TYPE_MACPARAM:
            Msg = "Macro parameter came from here";
            break;

        default:
            /* No output */
            Msg = 0;
            break;

        }

        /* Output until an upper limit of messages is reached */
        if (Msg) {
            if (Output < MAX_NOTES) {
                PrintMsg (GetSourcePos (LI), "Note", "%s", Msg);
                ++Output;
            } else {
                ++Skipped;
            }
        }
    }

    /* Add a note if we have more stuff that we won't output */
    if (Skipped > 0) {
        const LineInfo* LI = CollConstAt (LineInfos, 0);
        PrintMsg (GetSourcePos (LI), "Note",
                  "Dropping %u additional line infos", Skipped);
    }
}
Esempio n. 24
0
File: dbginfo.c Progetto: cc65/cc65
void WriteHLLDbgSyms (void)
/* Write a list of all high level language symbols to the object file. */
{
    unsigned I;

    /* Only if debug info is enabled */
    if (DbgSyms) {

        /* Write the symbol count to the list */
        ObjWriteVar (CollCount (&HLLDbgSyms));

        /* Walk through list and write all symbols to the file. */
        for (I = 0; I < CollCount (&HLLDbgSyms); ++I) {

            /* Get the next symbol */
            HLLDbgSym* S = CollAtUnchecked (&HLLDbgSyms, I);

            /* Get the type of the symbol */
            unsigned SC = HLL_GET_SC (S->Flags);

            /* Remember if the symbol has debug info attached
            ** ### This should go into DbgInfoCheck
            */
            if (S->Sym && S->Sym->DebugSymId != ~0U) {
                S->Flags |= HLL_DATA_SYM;
            }

            /* Write the symbol data */
            ObjWriteVar (S->Flags);
            ObjWriteVar (S->Name);
            if (HLL_HAS_SYM (S->Flags)) {
                ObjWriteVar (S->Sym->DebugSymId);
            }
            if (SC == HLL_SC_AUTO || SC == HLL_SC_REG) {
                ObjWriteVar (S->Offs);
            }
            ObjWriteVar (S->Type);
            ObjWriteVar (S->Scope->Id);
        }

    } else {

        /* Write a count of zero */
        ObjWriteVar (0);

    }
}
Esempio n. 25
0
static void ConvertImports (FILE* F, const O65Data* D)
/* Convert the imports */
{
    unsigned I;

    if (CollCount (&D->Imports) > 0) {
        for (I = 0; I < CollCount (&D->Imports); ++I) {

            /* Get the next import */
            const O65Import* Import = CollConstAt (&D->Imports, I);

            /* Import it by name */
            fprintf (F, ".import\t%s\n", Import->Name);
        }
        fprintf (F, "\n");
    }
}
Esempio n. 26
0
char* GetSearchPath (SearchPaths* P, unsigned Index)
/* Return the search path at the given index, if the index is valid, return an
** empty string otherwise.
*/
{
    if (Index < CollCount (P))
        return CollAtUnchecked (P, Index);
    return "";
}
Esempio n. 27
0
struct DbgSym* GetObjDbgSym (const ObjData* O, unsigned Id)
/* Get a debug symbol from an object file checking for a valid index */
{
    if (Id >= CollCount (&O->DbgSyms)) {
        Error ("Invalid debug symbol index (%u) in module `%s'",
               Id, GetObjFileName (O));
    }
    return CollAtUnchecked (&O->DbgSyms, Id);
}
Esempio n. 28
0
struct Export* GetObjExport (const ObjData* O, unsigned Id)
/* Get an export from an object file checking for a valid index */
{
    if (Id >= CollCount (&O->Exports)) {
        Error ("Invalid export index (%u) in module `%s'",
               Id, GetObjFileName (O));
    }
    return CollAtUnchecked (&O->Exports, Id);
}
Esempio n. 29
0
struct Scope* GetObjScope (const ObjData* O, unsigned Id)
/* Get a scope from an object file checking for a valid index */
{
    if (Id >= CollCount (&O->Scopes)) {
        Error ("Invalid scope index (%u) in module `%s'",
               Id, GetObjFileName (O));
    }
    return CollAtUnchecked (&O->Scopes, Id);
}
Esempio n. 30
0
const char* GetCurrentFile (void)
/* Return the name of the current input file */
{
    unsigned AFileCount = CollCount (&AFiles);
    if (AFileCount > 0) {
     	const AFile* AF = (const AFile*) CollAt (&AFiles, AFileCount-1);
     	return AF->Input->Name;
    } else {
     	/* No open file. Use the main file if we have one. */
     	unsigned IFileCount = CollCount (&IFiles);
     	if (IFileCount > 0) {
     	    const IFile* IF = (const IFile*) CollAt (&IFiles, 0);
     	    return IF->Name;
     	} else {
      	    return "(outside file scope)";
     	}
    }
}