makedeps.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,285 行 · 第 1/3 页

C
1,285
字号
    // Try to find it among the paths.
    //
    Fptr = FindFile (FileNameCopy, sizeof (FileNameCopy));
    if (Fptr == NULL) {
      //
      // If this is not the top-level file, and the command-line argument
      // said to ignore missing files, then return ok
      //
      if (NestDepth != START_NEST_DEPTH) {
        if (mGlobals.IgnoreNotFound) {
          if (!mGlobals.QuietMode) {
            DebugMsg (NULL, 0, 0, FileNameCopy, "could not find file");
          }

          return STATUS_SUCCESS;
        } else {
          Error (NULL, 0, 0, FileNameCopy, "could not find file");
          return STATUS_ERROR;
        }
      } else {
        //
        // Top-level (first) file. Emit an error.
        //
        Error (NULL, 0, 0, FileNameCopy, "could not find file");
        return STATUS_ERROR;
      }
    }
  }
  //
  // Print the dependency, with string substitution
  //
  PrintDependency (TargetFileName, FileNameCopy);

  //
  // Now read in lines and find all #include lines. Allow them to indent, and
  // to put spaces between the # and include.
  //
  LineNum = 0;
  while ((fgets (Line, sizeof (Line), Fptr) != NULL) && (Status == STATUS_SUCCESS)) {
    LineNum++;
    Cptr = Line;
    //
    // Skip preceeding spaces on the line
    //
    while (*Cptr && (isspace (*Cptr))) {
      Cptr++;
    }
    //
    // Check for # character
    //
    if (*Cptr == '#') {
      Cptr++;
      //
      // Check for "include"
      //
      while (*Cptr && (isspace (*Cptr))) {
        Cptr++;
      }

      if (strncmp (Cptr, "include", 7) == 0) {
        //
        // Skip over "include" and move on to filename as "file" or <file>
        //
        Cptr += 7;
        while (*Cptr && (isspace (*Cptr))) {
          Cptr++;
        }

        if (*Cptr == '<') {
          EndChar = '>';
        } else if (*Cptr == '"') {
          EndChar = '"';
        } else {
          //
          // Handle special #include MACRO_NAME(file)
          // Set EndChar to null so we fall through on processing below.
          //
          EndChar = 0;
          //
          // Look for all the special include macros and convert accordingly.
          //
          for (Index = 0; mMacroConversion[Index].IncludeMacroName != NULL; Index++) {
            //
            // Save the start of the string in case some macros are substrings
            // of others.
            //
            SaveCptr = Cptr;
            if (strncmp (
                  Cptr,
                  mMacroConversion[Index].IncludeMacroName,
                  strlen (mMacroConversion[Index].IncludeMacroName)
                  ) == 0) {
              //
              // Skip over the macro name
              //
              Cptr += strlen (mMacroConversion[Index].IncludeMacroName);
              //
              // Skip over open parenthesis, blank spaces, then find closing
              // parenthesis or blank space
              //
              while (*Cptr && (isspace (*Cptr))) {
                Cptr++;
              }

              if (*Cptr == '(') {
                Cptr++;
                while (*Cptr && (isspace (*Cptr))) {
                  Cptr++;
                }

                EndPtr = Cptr;
                while (*EndPtr && !isspace (*EndPtr) && (*EndPtr != ')')) {
                  EndPtr++;
                }

                *EndPtr = 0;
                //
                // Create the path
                //
                strcpy (MacroIncludeFileName, mMacroConversion[Index].PathName);
                strcat (MacroIncludeFileName, Cptr);
                strcat (MacroIncludeFileName, "\\");
                strcat (MacroIncludeFileName, Cptr);
                strcat (MacroIncludeFileName, ".h");
                //
                // Process immediately, then break out of the outside FOR loop.
                //
                Status = ProcessFile (TargetFileName, MacroIncludeFileName, NestDepth + 1, ProcessedFiles);
                break;
              }
            }
            //
            // Restore the start
            //
            Cptr = SaveCptr;
          }
          //
          // Don't recognize the include line? Ignore it. We assume that the
          // file compiles anyway.
          //
          if (mMacroConversion[Index].IncludeMacroName == NULL) {
            //
            // Warning (FileNameCopy, LineNum, 0, "could not parse line", NULL);
            // Status = STATUS_WARNING;
            //
          }
        }
        //
        // Process "normal" includes. If the endchar is 0, then the
        // file has already been processed. Otherwise look for the
        // endchar > or ", and process the include file.
        //
        if (EndChar != 0) {
          Cptr++;
          EndPtr = Cptr;
          while (*EndPtr && (*EndPtr != EndChar)) {
            EndPtr++;
          }

          if (*EndPtr == EndChar) {
            //
            // If we're processing it, do it
            //
            if ((EndChar != '>') || (!mGlobals.NoSystem)) {
              //
              // Null terminate the filename and try to process it.
              //
              *EndPtr = 0;
              Status  = ProcessFile (TargetFileName, Cptr, NestDepth + 1, ProcessedFiles);
            }
          } else {
            Warning (FileNameCopy, LineNum, 0, "malformed include", "missing closing %c", EndChar);
            Status = STATUS_WARNING;
            goto Finish;
          }
        }
      }
    }
  }

Finish:
  //
  // Close open files and return status
  //
  if (Fptr != NULL) {
    fclose (Fptr);
  }

  return Status;
}

static
void
PrintDependency (
  INT8    *TargetFileName,
  INT8    *DependentFile
  )
/*++

Routine Description:

  Given a target (.obj) file name, and a dependent file name, do any string
  substitutions (per the command line options) on the file names, then
  print the dependency line of form:
  
  TargetFileName : DependentFile
  
Arguments:

  TargetFileName - build target file name
  DependentFile  - file on which TargetFileName depends

Returns:

  None
  
--*/
{
  INT8  Str[MAX_PATH];

  //
  // Go through the symbols and do replacements
  //
  strcpy (Str, TargetFileName);
  ReplaceSymbols (Str, sizeof (Str));
  fprintf (mGlobals.OutFptr, "%s : ", Str);
  strcpy (Str, DependentFile);
  ReplaceSymbols (Str, sizeof (Str));
  fprintf (mGlobals.OutFptr, "%s\n", Str);
}

static
void
ReplaceSymbols (
  INT8    *Str,
  UINT32  StrSize
  )
{
  SYMBOL  *Sym;
  INT8    StrCopy[MAX_LINE_LEN];
  INT8    *From;
  INT8    *To;
  BOOLEAN Replaced;

  //
  // Go through the entire string to look for replacement strings at
  // every position.
  //
  From  = Str;
  To    = StrCopy;
  while (*From) {
    //
    // Copy the character
    //
    *To       = *From;
    Replaced  = FALSE;
    //
    // Go through each symbol and try to find a string substitution
    //
    Sym = mGlobals.SymbolTable;
    while (Sym != NULL) {
      if (_strnicmp (From, Sym->Value, strlen (Sym->Value)) == 0) {
        //
        // Replace the string, then advance the pointers past the
        // replaced strings
        //
        strcpy (To, Sym->Name);
        To += strlen (Sym->Name);
        From += strlen (Sym->Value);
        Replaced = TRUE;
        //
        // Break from the while()
        //
        break;
      } else {
        Sym = Sym->Next;
      }
    }

    if (!Replaced) {
      From++;
      To++;
    }
  }
  //
  // Null terminate, and return it
  //
  *To = 0;
  if (strlen (StrCopy) < StrSize) {
    strcpy (Str, StrCopy);
  }
}
//
// Given a filename, try to find it along the include paths.
//
static
FILE *
FindFile (
  INT8    *FileName,
  UINT32  FileNameLen
  )
{
  FILE        *Fptr;
  STRING_LIST *List;
  STRING_LIST *SubDir;
  INT8        FullFileName[MAX_PATH * 2];

  //
  // Traverse the list of paths and try to find the file
  //
  List = mGlobals.IncludePaths;
  while (List != NULL) {
    //
    // Put the path and filename together
    //
    if (strlen (List->Str) + strlen (FileName) + 1 > sizeof (FullFileName)) {
      Error (
        __FILE__,
        __LINE__,
        0,
        "application error",
        "cannot concatenate '%s' + '%s'",
        List->Str,
        FileName
        );
      return NULL;
    }
    //
    // Append the filename to this include path and try to open the file.
    //
    strcpy (FullFileName, List->Str);
    strcat (FullFileName, FileName);
    if ((Fptr = fopen (FullFileName, "r")) != NULL) {
      //
      // Return the file name
      //
      if (FileNameLen <= strlen (FullFileName)) {
        Error (__FILE__, __LINE__, 0, "application error", "internal path name of insufficient length");
        //
        // fprintf (stdout, "File length > %d: %s\n", FileNameLen, FullFileName);
        //
        return NULL;
      }

      strcpy (FileName, FullFileName);
      return Fptr;
    }
    //
    // Didn't find it there. Now try this directory with every subdirectory
    // the user specified on the command line
    //
    for (SubDir = mGlobals.SubDirs; SubDir != NULL; SubDir = SubDir->Next) {
      strcpy (FullFileName, List->Str);
      strcat (FullFileName, SubDir->Str);
      strcat (FullFileName, FileName);
      if ((Fptr = fopen (FullFileName, "r")) != NULL) {
        //
        // Return the file name
        //
        if (FileNameLen <= strlen (FullFileName)) {
          Error (__FILE__, __LINE__, 0, "application error", "internal path name of insufficient length");
          return NULL;
        }

        strcpy (FileName, FullFileName);
        return Fptr;
      }
    }

    List = List->Next;
  }
  //
  // Not found
  //
  return NULL;
}
//
// Process the command-line arguments
//
static
STATUS
ProcessArgs (
  int   Argc,
  char  *Argv[]
  )
{
  STRING_LIST *NewList;
  STRING_LIST *LastIncludePath;
  STRING_LIST *LastSourceFile;
  SYMBOL      *Symbol;
  int         Index;
  //
  // Clear our globals
  //
  memset ((char *) &mGlobals, 0, sizeof (mGlobals));
  mGlobals.NoDupes = TRUE;
  //
  // Skip program name
  //
  Argc--;
  Argv++;
  //
  // Initialize locals
  //
  LastIncludePath = NULL;
  LastSourceFile  = NULL;
  //
  // Process until no more args
  //
  while (Argc) {
    //
    // -i path    add include search path
    //
    if (_stricmp (Argv[0], "-i") == 0) {
      //
      // check for one more arg
      //
      if (Argc > 1) {
        //
        // Allocate memory for a new list element, fill it in, and
        // add it to our list of include paths. Always make sure it
        // has a "\" on the end of it.
        //
        NewList = malloc (sizeof (STRING_LIST));
        if (NewList == NULL) {
          Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);
          return STATUS_ERROR;
        }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?