コード例 #1
0
ファイル: error.c プロジェクト: Michaelangel007/cc65
static void VPrintMsg (const FilePos* Pos, const char* Desc,
                       const char* Format, va_list ap)
/* Format and output an error/warning message. */
{
    StrBuf S = STATIC_STRBUF_INITIALIZER;

    /* Format the actual message */
    StrBuf Msg = STATIC_STRBUF_INITIALIZER;
    SB_VPrintf (&Msg, Format, ap);
    SB_Terminate (&Msg);

    /* Format the message header */
    SB_Printf (&S, "%s(%u): %s: ",
               SB_GetConstBuf (GetFileName (Pos->Name)),
               Pos->Line,
               Desc);

    /* Append the message to the message header */
    SB_Append (&S, &Msg);

    /* Delete the formatted message */
    SB_Done (&Msg);

    /* Add a new line and terminate the generated full message */
    SB_AppendChar (&S, '\n');
    SB_Terminate (&S);

    /* Output the full message */
    fputs (SB_GetConstBuf (&S), stderr);

    /* Delete the buffer for the full message */
    SB_Done (&S);
}
コード例 #2
0
ファイル: input.c プロジェクト: eakmeister/cc65
void CreateDependencies (void)
/* Create dependency files requested by the user */
{
    if (SB_NotEmpty (&DepName)) {
        CreateDepFile (SB_GetConstBuf (&DepName),
                       IT_MAIN | IT_USRINC);
    }
    if (SB_NotEmpty (&FullDepName)) {
        CreateDepFile (SB_GetConstBuf (&FullDepName),
                       IT_MAIN | IT_SYSINC | IT_USRINC);
    }
}
コード例 #3
0
ファイル: filetab.c プロジェクト: PanchoManera/cc65
void CreateDependencies (void)
/* Create dependency files requested by the user */
{
    if (SB_NotEmpty (&DepName)) {
        CreateDepFile (SB_GetConstBuf (&DepName),
                       FT_MAIN | FT_INCLUDE | FT_BINARY);
    }
    if (SB_NotEmpty (&FullDepName)) {
        CreateDepFile (SB_GetConstBuf (&FullDepName),
                       FT_MAIN | FT_INCLUDE | FT_BINARY | FT_DBGINFO);
    }
}
コード例 #4
0
ファイル: pragma.c プロジェクト: PanchoManera/cc65
static IntStack* GetWarning (StrBuf* B)
/* Get a warning name from the string buffer. Returns a pointer to the intstack
 * that holds the state of the warning, and NULL in case of errors. The
 * function will output error messages in case of problems.
 */
{
    IntStack* S = 0;
    StrBuf W = AUTO_STRBUF_INITIALIZER;

    /* The warning name is a symbol but the '-' char is allowed within */
    if (SB_GetSym (B, &W, "-")) {

        /* Map the warning name to an IntStack that contains its state */
        S = FindWarning (SB_GetConstBuf (&W));

        /* Handle errors */
        if (S == 0) {
            Error ("Pragma expects a warning name as first argument");
        }
    }

    /* Deallocate the string */
    SB_Done (&W);

    /* Done */
    return S;
}
コード例 #5
0
ファイル: filetab.c プロジェクト: PanchoManera/cc65
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));
    }
}
コード例 #6
0
ファイル: scanner.c プロジェクト: JackieXie168/cc65
static token_t FindDotKeyword (void)
/* Find the dot keyword in SVal. Return the corresponding token if found,
** return TOK_NONE if not found.
*/
{
    struct DotKeyword K;
    struct DotKeyword* R;

    /* Initialize K */
    K.Key = SB_GetConstBuf (&CurTok.SVal);
    K.Tok = 0;

    /* If we aren't in ignore case mode, we have to uppercase the keyword */
    if (!IgnoreCase) {
        UpcaseSVal ();
    }

    /* Search for the keyword */
    R = bsearch (&K, DotKeywords, sizeof (DotKeywords) / sizeof (DotKeywords [0]),
                 sizeof (DotKeywords [0]), CmpDotKeyword);
    if (R != 0) {
        return R->Tok;
    } else {
        return TOK_NONE;
    }
}
コード例 #7
0
ファイル: scanner.c プロジェクト: pfusik/cc65
static int Sweet16Reg (const StrBuf* Id)
/* Check if the given identifier is a sweet16 register. Return -1 if this is
** not the case, return the register number otherwise.
*/
{
    unsigned RegNum;
    char Check;

    if (SB_GetLen (Id) < 2) {
        return -1;
    }
    if (toupper (SB_AtUnchecked (Id, 0)) != 'R') {
        return -1;
    }
    if (!IsDigit (SB_AtUnchecked (Id, 1))) {
        return -1;
    }

    if (sscanf (SB_GetConstBuf (Id)+1, "%u%c", &RegNum, &Check) != 1 || RegNum > 15) {
        /* Invalid register */
        return -1;
    }

    /* The register number is valid */
    return (int) RegNum;
}
コード例 #8
0
ファイル: preproc.c プロジェクト: PanchoManera/cc65
static void DoInclude (void)
/* Open an include file. */
{
    char        RTerm;
    InputType   IT;
    StrBuf      Filename = STATIC_STRBUF_INITIALIZER;


    /* Preprocess the remainder of the line */
    PreprocessLine ();

    /* Skip blanks */
    SkipWhitespace (0);

    /* Get the next char and check for a valid file name terminator. Setup
     * the include directory spec (SYS/USR) by looking at the terminator.
     */
    switch (CurC) {

        case '\"':
            RTerm   = '\"';
            IT = IT_USRINC;
            break;

        case '<':
            RTerm   = '>';
            IT = IT_SYSINC;
            break;

        default:
            PPError ("`\"' or `<' expected");
            goto Done;
    }
    NextChar ();

    /* Get a copy of the filename */
    while (CurC != '\0' && CurC != RTerm) {
        SB_AppendChar (&Filename, CurC);
        NextChar ();
    }
    SB_Terminate (&Filename);

    /* Check if we got a terminator */
    if (CurC == RTerm) {
        /* Open the include file */
        OpenIncludeFile (SB_GetConstBuf (&Filename), IT);
    } else if (CurC == '\0') {
        /* No terminator found */
        PPError ("#include expects \"FILENAME\" or <FILENAME>");
    }

Done:
    /* Free the allocated filename data */
    SB_Done (&Filename);

    /* Clear the remaining line so the next input will come from the new
     * file (if open)
     */
    ClearLine ();
}
コード例 #9
0
ファイル: searchpath.c プロジェクト: FelipeBudinich/cc65
void AddSubSearchPathFromEnv (SearchPaths* P, const char* EnvVar, const char* SubDir)
/* Add a search path from an environment variable, adding a subdirectory to
** the environment variable value.
*/
{
    StrBuf Dir = AUTO_STRBUF_INITIALIZER;

    const char* EnvVal = getenv (EnvVar);
    if (EnvVal == 0) {
        /* Not found */
        return;
    }

    /* Copy the environment variable to the buffer */
    SB_CopyStr (&Dir, EnvVal);

    /* Add a path separator if necessary */
    if (SB_NotEmpty (&Dir)) {
        if (SB_LookAtLast (&Dir) != '\\' && SB_LookAtLast (&Dir) != '/') {
            SB_AppendChar (&Dir, '/');
        }
    }

    /* Add the subdirectory and terminate the string */
    SB_AppendStr (&Dir, SubDir);
    SB_Terminate (&Dir);

    /* Add the search path */
    AddSearchPath (P, SB_GetConstBuf (&Dir));

    /* Free the temp buffer */
    SB_Done (&Dir);
}
コード例 #10
0
ファイル: attr.c プロジェクト: PanchoManera/cc65
void SplitAddAttr (Collection* C, const char* Combined, const char* Name)
/* Split a combined name/value pair and add it as an attribute to C. Some
 * attributes may not need a name. If the name is missing, use Name. If
 * Name is NULL, terminate with an error.
 */
{
    /* Name and value are separated by an equal sign */
    const char* Pos = strchr (Combined, '=');
    if (Pos == 0) {
        /* Combined is actually a value */
        if (Name == 0) {
            Error ("Command line attribute `%s' doesn't contain a name", Combined);
        }
        AddAttr (C, Name, Combined);
    } else {
        /* Must split name and value */
        StrBuf N = AUTO_STRBUF_INITIALIZER;
        SB_CopyBuf (&N, Combined, Pos - Combined);
        SB_Terminate (&N);

        /* Add the attribute */
        AddAttr (C, SB_GetConstBuf (&N), Pos+1);

        /* Release memory */
        SB_Done (&N);
    }
}
コード例 #11
0
ファイル: error.c プロジェクト: Aliandrana/snesdev
void Internal (const char* Format, ...)
/* Print a message about an internal compiler error and die. */
{
    va_list ap;

    const char* FileName;
    unsigned    LineNum;
    if (CurTok.LI) {
     	FileName = GetInputName (CurTok.LI);
     	LineNum  = GetInputLine (CurTok.LI);
    } else {
     	FileName = GetCurrentFile ();
     	LineNum  = GetCurrentLine ();
    }

    fprintf (stderr, "%s(%u): Internal compiler error:\n",
     	     FileName, LineNum);

    va_start (ap, Format);
    vfprintf (stderr, Format, ap);
    va_end (ap);
    fprintf (stderr, "\n");

    if (Line) {
        fprintf (stderr, "\nInput: %.*s\n", (int) SB_GetLen (Line), SB_GetConstBuf (Line));
    }

    /* Use abort to create a core dump */
    abort ();
}
コード例 #12
0
ファイル: error.c プロジェクト: Aliandrana/snesdev
void Fatal (const char* Format, ...)
/* Print a message about a fatal error and die */
{
    va_list ap;

    const char* FileName;
    unsigned    LineNum;
    if (CurTok.LI) {
     	FileName = GetInputName (CurTok.LI);
     	LineNum  = GetInputLine (CurTok.LI);
    } else {
     	FileName = GetCurrentFile ();
     	LineNum  = GetCurrentLine ();
    }

    fprintf (stderr, "%s(%u): Fatal: ", FileName, LineNum);

    va_start (ap, Format);
    vfprintf (stderr, Format, ap);
    va_end (ap);
    fprintf (stderr, "\n");

    if (Line) {
        Print (stderr, 1, "Input: %.*s\n", (int) SB_GetLen (Line), SB_GetConstBuf (Line));
    }
    exit (EXIT_FAILURE);
}
コード例 #13
0
ファイル: input.c プロジェクト: eakmeister/cc65
static void CreateDepFile (const char* Name, InputType Types)
/* Create a dependency file with the given name and place dependencies for
 * all files with the given types there.
 */
{
    /* Open the file */
    FILE* F = fopen (Name, "w");
    if (F == 0) {
       	Fatal ("Cannot open dependency file `%s': %s", Name, strerror (errno));
    }

    /* If a dependency target was given, use it, otherwise use the output
     * file name as target, followed by a tab character.
     */
    if (SB_IsEmpty (&DepTarget)) {
        WriteEscaped (F, OutputFilename);
    } else {
        WriteEscaped (F, SB_GetConstBuf (&DepTarget));
    }
    fputs (":\t", F);

    /* Write out the dependencies for the output file */
    WriteDep (F, Types);
    fputs ("\n\n", F);

    /* Write out a phony dependency for the included files */
    WriteDep (F, Types);
    fputs (":\n\n", F);

    /* Close the file, check for errors */
    if (fclose (F) != 0) {
    	remove (Name);
    	Fatal ("Cannot write to dependeny file (disk full?)");
    }
}
コード例 #14
0
ファイル: repeat.c プロジェクト: Aliandrana/snesdev
void ParseRepeat (void)
/* Parse and handle the .REPEAT statement */
{
    char* Name;
    TokList* List;

    /* Repeat count follows */
    long RepCount = ConstExpression ();
    if (RepCount < 0) {
	Error ("Range error");
	RepCount = 0;
    }

    /* Optional there is a comma and a counter variable */
    Name = 0;
    if (Tok == TOK_COMMA) {

       	/* Skip the comma */
       	NextTok ();

       	/* Check for an identifier */
       	if (Tok != TOK_IDENT) {
       	    ErrorSkip ("Identifier expected");
       	} else {
       	    /* Remember the name and skip it */
            SB_Terminate (&SVal);
       	    Name = xstrdup (SB_GetConstBuf (&SVal));
       	    NextTok ();
       	}
    }

    /* Separator */
    ConsumeSep ();

    /* Read the token list */
    List = CollectRepeatTokens ();

    /* If we had an error, bail out */
    if (List == 0) {
	xfree (Name);
       	return;
    }

    /* Update the token list for replay */
    List->RepMax = (unsigned) RepCount;
    List->Data   = Name;
    List->Check  = RepeatTokenCheck;

    /* If the list is empty, or repeat count zero, there is nothing
     * to repeat.
     */
    if (List->Count == 0 || RepCount == 0) {
     	FreeTokList (List);
	return;
    }

    /* Read input from the repeat descriptor */
    PushTokList (List, ".REPEAT");
}
コード例 #15
0
ファイル: pragma.c プロジェクト: PanchoManera/cc65
static pragma_t FindPragma (const StrBuf* Key)
/* Find a pragma and return the token. Return PRAGMA_ILLEGAL if the keyword is
 * not a valid pragma.
 */
{
    struct Pragma* P;
    P = bsearch (SB_GetConstBuf (Key), Pragmas, PRAGMA_COUNT, sizeof (Pragmas[0]), CmpKey);
    return P? P->Tok : PRAGMA_ILLEGAL;
}
コード例 #16
0
ファイル: anonname.c プロジェクト: Aliandrana/snesdev
int IsAnonName (const StrBuf* Name)
/* Check if the given symbol name is that of an anonymous symbol */
{           
    if (SB_GetLen (Name) < sizeof (AnonTag) - 1) {
        /* Too short */
        return 0;
    }
    return (strncmp (SB_GetConstBuf (Name), AnonTag, sizeof (AnonTag) - 1) == 0);
}
コード例 #17
0
ファイル: input.c プロジェクト: eakmeister/cc65
static AFile* NewAFile (IFile* IF, FILE* F)
/* Create a new AFile, push it onto the stack, add the path of the file to
 * the path search list, and finally return a pointer to the new AFile struct.
 */
{
    StrBuf Path = AUTO_STRBUF_INITIALIZER;

    /* Allocate a AFile structure */
    AFile* AF = (AFile*) xmalloc (sizeof (AFile));

    /* Initialize the fields */
    AF->Line  = 0;
    AF->F     = F;
    AF->Input = IF;

    /* Increment the usage counter of the corresponding IFile. If this
     * is the first use, set the file data and output debug info if
     * requested.
     */
    if (IF->Usage++ == 0) {

 	/* Get file size and modification time. There a race condition here,
         * since we cannot use fileno() (non standard identifier in standard
         * header file), and therefore not fstat. When using stat with the
         * file name, there's a risk that the file was deleted and recreated
         * while it was open. Since mtime and size are only used to check
         * if a file has changed in the debugger, we will ignore this problem
         * here.
         */
     	struct stat Buf;
 	if (FileStat (IF->Name, &Buf) != 0) {
 	    /* Error */
 	    Fatal ("Cannot stat `%s': %s", IF->Name, strerror (errno));
 	}
       	IF->Size  = (unsigned long) Buf.st_size;
 	IF->MTime = (unsigned long) Buf.st_mtime;

 	/* Set the debug data */
 	g_fileinfo (IF->Name, IF->Size, IF->MTime);
    }

    /* Insert the new structure into the AFile collection */
    CollAppend (&AFiles, AF);

    /* Get the path of this file and add it as an extra search path.
     * To avoid file search overhead, we will add one path only once.
     * This is checked by the PushSearchPath function.
     */
    SB_CopyBuf (&Path, IF->Name, FindName (IF->Name) - IF->Name);
    SB_Terminate (&Path);
    AF->SearchPath = PushSearchPath (UsrIncSearchPath, SB_GetConstBuf (&Path));
    SB_Done (&Path);

    /* Return the new struct */
    return AF;
}
コード例 #18
0
ファイル: preproc.c プロジェクト: PanchoManera/cc65
static void DoError (void)
/* Print an error */
{
    SkipWhitespace (0);
    if (CurC == '\0') {
        PPError ("Invalid #error directive");
    } else {
        PPError ("#error: %s", SB_GetConstBuf (Line) + SB_GetIndex (Line));
    }

    /* Clear the rest of line */
    ClearLine ();
}
コード例 #19
0
ファイル: pragma.c プロジェクト: PanchoManera/cc65
static int HasStr (StrBuf* B, const char* E)
/* Checks if E follows in B. If so, skips it and returns true */
{
    unsigned Len = strlen (E);
    if (SB_GetLen (B) - SB_GetIndex (B) >= Len) {
        if (strncmp (SB_GetConstBuf (B) + SB_GetIndex (B), E, Len) == 0) {
            /* Found */
            SB_SkipMultiple (B, Len);
            return 1;
        }
    }
    return 0;
}
コード例 #20
0
ファイル: preproc.c プロジェクト: PanchoManera/cc65
static void DoWarning (void)
/* Print a warning */
{
    SkipWhitespace (0);
    if (CurC == '\0') {
        PPError ("Invalid #warning directive");
    } else {
        PPWarning ("#warning: %s", SB_GetConstBuf (Line) + SB_GetIndex (Line));
    }

    /* Clear the rest of line */
    ClearLine ();
}
コード例 #21
0
ファイル: dbginfo.c プロジェクト: cc65/cc65
static int ValidateType (StrBuf* Type)
/* Check if the given type is valid and if so, return a string id for it. If
** the type isn't valid, return -1. Type is overwritten when checking.
*/
{
    unsigned        I;
    const char*     A;
    char*           B;


    /* The length must not be zero and divideable by two */
    unsigned Length = SB_GetLen (Type);
    if (Length < 2 || (Length & 0x01) != 0) {
        ErrorSkip ("Type value has invalid length");
        return -1;
    }

    /* The string must consist completely of hex digit chars */
    A = SB_GetConstBuf (Type);
    for (I = 0; I < Length; ++I) {
        if (!IsXDigit (A[I])) {
            ErrorSkip ("Type value contains invalid characters");
            return -1;
        }
    }

    /* Convert the type to binary */
    B = SB_GetBuf (Type);
    while (A < SB_GetConstBuf (Type) + Length) {
        /* Since we know, there are only hex digits, there can't be any errors */
        *B++ = (HexValue (A[0]) << 4) | HexValue (A[1]);
        A += 2;
    }
    Type->Len = (Length /= 2);

    /* Allocate the type and return it */
    return GetStrBufId (Type);
}
コード例 #22
0
ファイル: error.c プロジェクト: Aliandrana/snesdev
static void IntWarning (const char* Filename, unsigned LineNo, const char* Msg, va_list ap)
/* Print warning message - internal function. */
{
    if (!IS_Get (&WarnDisable)) {
       	fprintf (stderr, "%s(%u): Warning: ", Filename, LineNo);
     	vfprintf (stderr, Msg, ap);
     	fprintf (stderr, "\n");

        if (Line) {
     	    Print (stderr, 1, "Input: %.*s\n", (int) SB_GetLen (Line), SB_GetConstBuf (Line));
        }
     	++WarningCount;
    }
}
コード例 #23
0
ファイル: pragma.c プロジェクト: PanchoManera/cc65
static void StringPragma (StrBuf* B, void (*Func) (const char*))
/* Handle a pragma that expects a string parameter */
{
    StrBuf S = AUTO_STRBUF_INITIALIZER;

    /* We expect a string here */
    if (GetString (B, &S)) {
        /* Call the given function with the string argument */
        Func (SB_GetConstBuf (&S));
    }

    /* Call the string buf destructor */
    SB_Done (&S);
}
コード例 #24
0
ファイル: scanner.c プロジェクト: AntiheroSoftware/cc65
void CfgWarning (const FilePos* Pos, const char* Format, ...)
/* Print a warning message adding file name and line number of a given file */
{
    StrBuf Buf = STATIC_STRBUF_INITIALIZER;
    va_list ap;

    va_start (ap, Format);
    SB_VPrintf (&Buf, Format, ap);
    va_end (ap);

    Warning ("%s(%u): %s",
             GetString (Pos->Name), Pos->Line, SB_GetConstBuf (&Buf));
    SB_Done (&Buf);
}
コード例 #25
0
ファイル: exprdesc.c プロジェクト: PanchoManera/cc65
const char* ED_GetLabelName (const ExprDesc* Expr, long Offs)
/* Return the assembler label name of the given expression. Beware: This
 * function may use a static buffer, so the name may get "lost" on the second
 * call to the function.
 */
{
    static StrBuf Buf = STATIC_STRBUF_INITIALIZER;

    /* Expr may have it's own offset, adjust Offs accordingly */
    Offs += Expr->IVal;

    /* Generate a label depending on the location */
    switch (ED_GetLoc (Expr)) {

        case E_LOC_ABS:
            /* Absolute: numeric address or const */
            SB_Printf (&Buf, "$%04X", (int)(Offs & 0xFFFF));
            break;

        case E_LOC_GLOBAL:
        case E_LOC_STATIC:
            /* Global or static variable */
            if (Offs) {
                SB_Printf (&Buf, "%s%+ld", SymGetAsmName (Expr->Sym), Offs);
            } else {
                SB_Printf (&Buf, "%s", SymGetAsmName (Expr->Sym));
            }
            break;

        case E_LOC_REGISTER:
            /* Register variable */
            SB_Printf (&Buf, "regbank+%u", (unsigned)((Offs + Expr->Name) & 0xFFFFU));
            break;

        case E_LOC_LITERAL:
            /* Literal in the literal pool */
            if (Offs) {
                SB_Printf (&Buf, "%s%+ld", LocalLabelName (Expr->Name), Offs);
            } else {
                SB_Printf (&Buf, "%s", LocalLabelName (Expr->Name));
            }
            break;

        default:
            Internal ("Invalid location in ED_GetLabelName: 0x%04X", ED_GetLoc (Expr));
    }

    /* Return a pointer to the static buffer */
    return SB_GetConstBuf (&Buf);
}
コード例 #26
0
ファイル: litpool.c プロジェクト: eakmeister/cc65
static void OutputLiteral (Literal* L)
/* Output one literal to the currently active data segment */
{
    /* Translate the literal into the target charset */
    TranslateLiteral (L);

    /* Define the label for the literal */
    g_defdatalabel (L->Label);

    /* Output the literal data */
    g_defbytes (SB_GetConstBuf (&L->Data), SB_GetLen (&L->Data));

    /* Mark the literal as output */
    L->Output = 1;
}
コード例 #27
0
ファイル: error.c プロジェクト: Aliandrana/snesdev
static void IntError (const char* Filename, unsigned LineNo, const char* Msg, va_list ap)
/* Print an error message - internal function*/
{
    fprintf (stderr, "%s(%u): Error: ", Filename, LineNo);
    vfprintf (stderr, Msg, ap);
    fprintf (stderr, "\n");

    if (Line) {
        Print (stderr, 1, "Input: %.*s\n", (int) SB_GetLen (Line), SB_GetConstBuf (Line));
    }
    ++ErrorCount;
    if (ErrorCount > 10) {
       	Fatal ("Too many errors");
    }
}
コード例 #28
0
ファイル: attr.c プロジェクト: PanchoManera/cc65
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;
}
コード例 #29
0
ファイル: codeopt.c プロジェクト: coyxc/cc65
static void OpenDebugFile (const CodeSeg* S)
/* Open the debug file for the given segment if the flag is on */
{
    if (DebugOptOutput) {
        StrBuf Name = AUTO_STRBUF_INITIALIZER;
        if (S->Func) {
            SB_CopyStr (&Name, S->Func->Name);
        } else {
            SB_CopyStr (&Name, "global");
        }
        SB_AppendStr (&Name, ".opt");
        SB_Terminate (&Name);
        OpenDebugOutputFile (SB_GetConstBuf (&Name));
        SB_Done (&Name);
    }
}
コード例 #30
0
ファイル: main.c プロジェクト: AntiheroSoftware/cc65
static void DefineSymbol (const char* Def)
/* Define a symbol from the command line */
{
    const char* P;
    long Val;
    StrBuf SymName = AUTO_STRBUF_INITIALIZER;


    /* The symbol must start with a character or underline */
    if (!IsIdStart (Def [0])) {
        InvDef (Def);
    }
    P = Def;

    /* Copy the symbol, checking the rest */
    while (IsIdChar (*P)) {
        SB_AppendChar (&SymName, *P++);
    }
    SB_Terminate (&SymName);

    /* Do we have a value given? */
    if (*P != '=') {
        if (*P != '\0') {
            InvDef (Def);
        }
        Val = 0;
    } else {
        /* We have a value */
        ++P;
        if (*P == '$') {
            ++P;
            if (sscanf (P, "%lx", &Val) != 1) {
                InvDef (Def);
            }
        } else {
            if (sscanf (P, "%li", &Val) != 1) {
                InvDef (Def);
            }
        }
    }

    /* Define the new symbol */
    NewSymbol (SB_GetConstBuf (&SymName), Val);

    /* Release string memory */
    SB_Done (&SymName);
}