Example #1
0
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);
    }
}
Example #2
0
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;
}
Example #3
0
int NewInputFile (const char* Name)
/* Open a new input file. Returns true if the file could be successfully opened
** and false otherwise.
*/
{
    int         RetCode = 0;            /* Return code. Assume an error. */
    char*       PathName = 0;
    FILE*       F;
    struct stat Buf;
    StrBuf      NameBuf;                /* No need to initialize */
    StrBuf      Path = AUTO_STRBUF_INITIALIZER;
    unsigned    FileIdx;
    CharSource* S;


    /* If this is the main file, just try to open it. If it's an include file,
    ** search for it using the include path list.
    */
    if (FCount == 0) {
        /* Main file */
        F = fopen (Name, "r");
        if (F == 0) {
            Fatal ("Cannot open input file '%s': %s", Name, strerror (errno));
        }
    } else {
        /* We are on include level. Search for the file in the include
        ** directories.
        */
        PathName = SearchFile (IncSearchPath, Name);
        if (PathName == 0 || (F = fopen (PathName, "r")) == 0) {
            /* Not found or cannot open, print an error and bail out */
            Error ("Cannot open include file '%s': %s", Name, strerror (errno));
            goto ExitPoint;
        }

        /* Use the path name from now on */
        Name = PathName;
    }

    /* Stat the file and remember the values. There's 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.
    */
    if (FileStat (Name, &Buf) != 0) {
        Fatal ("Cannot stat input file '%s': %s", Name, strerror (errno));
    }

    /* Add the file to the input file table and remember the index */
    FileIdx = AddFile (SB_InitFromString (&NameBuf, Name),
                       (FCount == 0)? FT_MAIN : FT_INCLUDE,
                       Buf.st_size, (unsigned long) Buf.st_mtime);

    /* Create a new input source variable and initialize it */
    S                   = xmalloc (sizeof (*S));
    S->Func             = &IFFunc;
    S->V.File.F         = F;
    S->V.File.Pos.Line  = 0;
    S->V.File.Pos.Col   = 0;
    S->V.File.Pos.Name  = FileIdx;
    SB_Init (&S->V.File.Line);

    /* Push the path for this file onto the include search lists */
    SB_CopyBuf (&Path, Name, FindName (Name) - Name);
    SB_Terminate (&Path);
    S->V.File.IncSearchPath = PushSearchPath (IncSearchPath, SB_GetConstBuf (&Path));
    S->V.File.BinSearchPath = PushSearchPath (BinSearchPath, SB_GetConstBuf (&Path));
    SB_Done (&Path);

    /* Count active input files */
    ++FCount;

    /* Use this input source */
    UseCharSource (S);

    /* File successfully opened */
    RetCode = 1;

ExitPoint:
    /* Free an allocated name buffer */
    xfree (PathName);

    /* Return the success code */
    return RetCode;
}