コード例 #1
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);
    }
}
コード例 #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
ファイル: searchpath.c プロジェクト: FelipeBudinich/cc65
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;
}
コード例 #4
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);
}
コード例 #5
0
ファイル: main.c プロジェクト: AntiheroSoftware/cc65
static void FileNameOption (const char* Opt, const char* Arg, StrBuf* Name)
/* Handle an option that remembers a file name for later */
{
    /* Cannot have the option twice */
    if (SB_NotEmpty (Name)) {
        AbEnd ("Cannot use option `%s' twice", Opt);
    }
    /* Remember the file name for later */
    SB_CopyStr (Name, Arg);
    SB_Terminate (Name);
}
コード例 #6
0
ファイル: preproc.c プロジェクト: PanchoManera/cc65
static void ReadMacroArgs (MacroExp* E)
/* Identify the arguments to a macro call */
{
    unsigned    Parens;         /* Number of open parenthesis */
    StrBuf      Arg = STATIC_STRBUF_INITIALIZER;

    /* Read the actual macro arguments */
    Parens = 0;
    while (1) {
        if (CurC == '(') {

            /* Nested parenthesis */
            SB_AppendChar (&Arg, CurC);
            NextChar ();
            ++Parens;

        } else if (IsQuote (CurC)) {

            /* Quoted string - just copy */
            CopyQuotedString (&Arg);

        } else if (CurC == ',' || CurC == ')') {

            if (Parens) {
                /* Comma or right paren inside nested parenthesis */
                if (CurC == ')') {
                    --Parens;
                }
                SB_AppendChar (&Arg, CurC);
                NextChar ();
            } else if (CurC == ',' && ME_ArgIsVariadic (E)) {
                /* It's a comma, but we're inside a variadic macro argument, so
                 * just copy it and proceed.
                 */
                SB_AppendChar (&Arg, CurC);
                NextChar ();
            } else {
                /* End of actual argument. Remove whitespace from the end. */
                while (IsSpace (SB_LookAtLast (&Arg))) {
                    SB_Drop (&Arg, 1);
                }

                /* If this is not the single empty argument for a macro with
                 * an empty argument list, remember it.
                 */
                if (CurC != ')' || SB_NotEmpty (&Arg) || E->M->ArgCount > 0) {
                    ME_AppendActual (E, &Arg);
                }

                /* Check for end of macro param list */
                if (CurC == ')') {
                    NextChar ();
                    break;
                }

                /* Start the next param */
                NextChar ();
                SB_Clear (&Arg);
            }
        } else if (SkipWhitespace (1)) {
            /* Squeeze runs of blanks within an arg */
            if (SB_NotEmpty (&Arg)) {
                SB_AppendChar (&Arg, ' ');
            }
        } else if (CurC == '/' && NextC == '*') {
            if (SB_NotEmpty (&Arg)) {
                SB_AppendChar (&Arg, ' ');
            }
            OldStyleComment ();
        } else if (IS_Get (&Standard) >= STD_C99 && CurC == '/' && NextC == '/') {
            if (SB_NotEmpty (&Arg)) {
                SB_AppendChar (&Arg, ' ');
            }
            NewStyleComment ();
        } else if (CurC == '\0') {
            /* End of input inside macro argument list */
            PPError ("Unterminated argument list invoking macro `%s'", E->M->Name);

            ClearLine ();
            break;
        } else {
            /* Just copy the character */
            SB_AppendChar (&Arg, CurC);
            NextChar ();
        }
    }

    /* Deallocate string buf resources */
    SB_Done (&Arg);
}
コード例 #7
0
ファイル: preproc.c プロジェクト: PanchoManera/cc65
void Preprocess (void)
/* Preprocess a line */
{
    int         Skip;
    ident       Directive;

    /* Create the output buffer if we don't already have one */
    if (MLine == 0) {
        MLine = NewStrBuf ();
    }

    /* Skip white space at the beginning of the line */
    SkipWhitespace (0);

    /* Check for stuff to skip */
    Skip = 0;
    while (CurC == '\0' || CurC == '#' || Skip) {

        /* Check for preprocessor lines lines */
        if (CurC == '#') {
            NextChar ();
            SkipWhitespace (0);
            if (CurC == '\0') {
                /* Ignore the empty preprocessor directive */
                continue;
            }
            if (!IsSym (Directive)) {
                PPError ("Preprocessor directive expected");
                ClearLine ();
            } else {
                switch (FindPPToken (Directive)) {

                    case PP_DEFINE:
                        if (!Skip) {
                            DefineMacro ();
                        }
                        break;

                    case PP_ELIF:
                        if (IfIndex >= 0) {
                            if ((IfStack[IfIndex] & IFCOND_ELSE) == 0) {

                                /* Handle as #else/#if combination */
                                if ((IfStack[IfIndex] & IFCOND_SKIP) == 0) {
                                    Skip = !Skip;
                                }
                                IfStack[IfIndex] |= IFCOND_ELSE;
                                Skip = DoIf (Skip);

                                /* #elif doesn't need a terminator */
                                IfStack[IfIndex] &= ~IFCOND_NEEDTERM;
                            } else {
                                PPError ("Duplicate #else/#elif");
                            }
                        } else {
                            PPError ("Unexpected #elif");
                        }
                        break;

                    case PP_ELSE:
                        if (IfIndex >= 0) {
                            if ((IfStack[IfIndex] & IFCOND_ELSE) == 0) {
                                if ((IfStack[IfIndex] & IFCOND_SKIP) == 0) {
                                    Skip = !Skip;
                                }
                                IfStack[IfIndex] |= IFCOND_ELSE;
                            } else {
                                PPError ("Duplicate #else");
                            }
                        } else {
                            PPError ("Unexpected `#else'");
                        }
                        break;

                    case PP_ENDIF:
                        if (IfIndex >= 0) {
                            /* Remove any clauses on top of stack that do not
                             * need a terminating #endif.
                             */
                            while (IfIndex >= 0 && (IfStack[IfIndex] & IFCOND_NEEDTERM) == 0) {
                                --IfIndex;
                            }

                            /* Stack may not be empty here or something is wrong */
                            CHECK (IfIndex >= 0);

                            /* Remove the clause that needs a terminator */
                            Skip = (IfStack[IfIndex--] & IFCOND_SKIP) != 0;
                        } else {
                            PPError ("Unexpected `#endif'");
                        }
                        break;

                    case PP_ERROR:
                        if (!Skip) {
                            DoError ();
                        }
                        break;

                    case PP_IF:
                        Skip = DoIf (Skip);
                        break;

                    case PP_IFDEF:
                        Skip = DoIfDef (Skip, 1);
                        break;

                    case PP_IFNDEF:
                        Skip = DoIfDef (Skip, 0);
                        break;

                    case PP_INCLUDE:
                        if (!Skip) {
                            DoInclude ();
                        }
                        break;

                    case PP_LINE:
                        /* Should do something in C99 at least, but we ignore it */
                        if (!Skip) {
                            ClearLine ();
                        }
                        break;

                    case PP_PRAGMA:
                        if (!Skip) {
                            DoPragma ();
                            goto Done;
                        }
                        break;

                    case PP_UNDEF:
                        if (!Skip) {
                            DoUndef ();
                        }
                        break;

                    case PP_WARNING:
                        /* #warning is a non standard extension */
                        if (IS_Get (&Standard) > STD_C99) {
                            if (!Skip) {
                                DoWarning ();
                            }
                        } else {
                            if (!Skip) {
                                PPError ("Preprocessor directive expected");
                            }
                            ClearLine ();
                        }
                        break;

                    default:
                        if (!Skip) {
                            PPError ("Preprocessor directive expected");
                        }
                        ClearLine ();
                }
            }

        }
        if (NextLine () == 0) {
            if (IfIndex >= 0) {
                PPError ("`#endif' expected");
            }
            return;
        }
        SkipWhitespace (0);
    }

    PreprocessLine ();

Done:
    if (Verbosity > 1 && SB_NotEmpty (Line)) {
        printf ("%s(%u): %.*s\n", GetCurrentFile (), GetCurrentLine (),
                (int) SB_GetLen (Line), SB_GetConstBuf (Line));
    }
}
コード例 #8
0
ファイル: scanner.c プロジェクト: pfusik/cc65
static void IFNextChar (CharSource* S)
/* Read the next character from the input file */
{
    /* Check for end of line, read the next line if needed */
    while (SB_GetIndex (&S->V.File.Line) >= SB_GetLen (&S->V.File.Line)) {

        unsigned Len;

        /* End of current line reached, read next line */
        SB_Clear (&S->V.File.Line);
        while (1) {

            int N = fgetc (S->V.File.F);
            if (N == EOF) {
                /* End of file. Accept files without a newline at the end */
                if (SB_NotEmpty (&S->V.File.Line)) {
                    break;
                }

                /* No more data - add an empty line to the listing. This
                ** is a small hack needed to keep the PC output in sync.
                */
                NewListingLine (&EmptyStrBuf, S->V.File.Pos.Name, FCount);
                C = EOF;
                return;

            /* Check for end of line */
            } else if (N == '\n') {

                /* End of line */
                break;

            /* Collect other stuff */
            } else {

                /* Append data to line */
                SB_AppendChar (&S->V.File.Line, N);

            }
        }


        /* If we come here, we have a new input line. To avoid problems
        ** with strange line terminators, remove all whitespace from the
        ** end of the line, then add a single newline.
        */
        Len = SB_GetLen (&S->V.File.Line);
        while (Len > 0 && IsSpace (SB_AtUnchecked (&S->V.File.Line, Len-1))) {
            --Len;
        }
        SB_Drop (&S->V.File.Line, SB_GetLen (&S->V.File.Line) - Len);
        SB_AppendChar (&S->V.File.Line, '\n');

        /* Terminate the string buffer */
        SB_Terminate (&S->V.File.Line);

        /* One more line */
        S->V.File.Pos.Line++;

        /* Remember the new line for the listing */
        NewListingLine (&S->V.File.Line, S->V.File.Pos.Name, FCount);

    }

    /* Set the column pointer */
    S->V.File.Pos.Col = SB_GetIndex (&S->V.File.Line);

    /* Return the next character from the buffer */
    C = SB_Get (&S->V.File.Line);
}
コード例 #9
0
ファイル: input.c プロジェクト: eakmeister/cc65
int NextLine (void)
/* Get a line from the current input. Returns 0 on end of file. */
{
    AFile*     	Input;

    /* Clear the current line */
    ClearLine ();

    /* If there is no file open, bail out, otherwise get the current input file */
    if (CollCount (&AFiles) == 0) {
     	return 0;
    }
    Input = CollLast (&AFiles);

    /* Read characters until we have one complete line */
    while (1) {

        /* Read the next character */
        int C = fgetc (Input->F);

        /* Check for EOF */
        if (C == EOF) {

            /* Accept files without a newline at the end */
            if (SB_NotEmpty (Line)) {
                ++Input->Line;
                break;
            }

      	    /* Leave the current file */
      	    CloseIncludeFile ();

            /* If there is no file open, bail out, otherwise get the
             * previous input file and start over.
             */
            if (CollCount (&AFiles) == 0) {
                return 0;
            }
            Input = CollLast (&AFiles);
            continue;
        }

        /* Check for end of line */
        if (C == '\n') {

            /* We got a new line */
            ++Input->Line;

            /* If the \n is preceeded by a \r, remove the \r, so we can read
             * DOS/Windows files under *nix.
             */
            if (SB_LookAtLast (Line) == '\r') {
                SB_Drop (Line, 1);
            }

            /* If we don't have a line continuation character at the end,
             * we're done with this line. Otherwise replace the character
             * by a newline and continue reading.
             */
            if (SB_LookAtLast (Line) == '\\') {
                Line->Buf[Line->Len-1] = '\n';
            } else {
                break;
            }

        } else if (C != '\0') {         /* Ignore embedded NULs */

            /* Just some character, add it to the line */
            SB_AppendChar (Line, C);

        }
    }

    /* Add a termination character to the string buffer */
    SB_Terminate (Line);

    /* Initialize the current and next characters. */
    InitLine (Line);

    /* Create line information for this line */
    UpdateLineInfo (Input->Input, Input->Line, Line);

    /* Done */
    return 1;
}