]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkCompatibilityPkg/Sample/Tools/Source/ProcessDsc/ProcessDsc.c
Sync all bug fixes between EDK1.04 and EDK1.06 into EdkCompatibilityPkg.
[mirror_edk2.git] / EdkCompatibilityPkg / Sample / Tools / Source / ProcessDsc / ProcessDsc.c
index 20faf6f69f9443505efbfd25d642969cabdb9f12..5f64bf5685fc8a45a3500281c29b114811fcaae1 100644 (file)
@@ -1,6 +1,6 @@
 /*++\r
 \r
-Copyright (c) 2004 - 2007, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials                          \r
 are licensed and made available under the terms and conditions of the BSD License         \r
 which accompanies this distribution.  The full text of the license may be found at        \r
@@ -27,25 +27,18 @@ Abstract:
 #include <direct.h>   // for _mkdir()\r
 #include <errno.h>\r
 #include <stdlib.h>   // for getenv()\r
+#include <shlwapi.h>  // for PathCanonicalize()\r
 #include "DSCFile.h"\r
+#include "MultiThread.h"\r
 #include "FWVolume.h"\r
 #include "Exceptions.h"\r
 #include "Common.h"\r
 \r
 #include "EfiUtilityMsgs.h"\r
 #include "TianoBind.h"\r
-//\r
-// Disable warning for while(1) code\r
-//\r
-#pragma warning(disable : 4127)\r
-//\r
-// Disable warning for unreferenced function parameters\r
-//\r
-#pragma warning(disable : 4100)\r
-\r
-extern int  errno;\r
 \r
-#define PROGRAM_NAME  "ProcessDsc"\r
+#define UTILITY_NAME    "ProcessDsc"\r
+#define UTILITY_VERSION "v1.0"\r
 \r
 //\r
 // Common symbol name definitions. For example, the user can reference\r
@@ -220,25 +213,39 @@ typedef struct _SYMBOL {
 } SYMBOL;\r
 \r
 //\r
-// Define new SYMBOL list to record all module name used in the platform.dsc file.\r
+// Module globals for multi-thread build\r
 //\r
-SYMBOL *gModuleList = NULL;\r
+static BUILD_ITEM  **mCurrentBuildList;          // build list currently handling\r
+static BUILD_ITEM  *mCurrentBuildItem;           // build item currently handling\r
+\r
+//\r
+// Define masks for the build targets\r
+//\r
+#define BUILD_TARGET_COMPONENTS 0x01\r
+#define BUILD_TARGET_LIBRARIES  0x02\r
+#define BUILD_TARGET_FVS        0x04\r
+#define BUILD_TARGET_ALL        0xff\r
+\r
 \r
 //\r
 // This structure is used to save globals\r
 //\r
 struct {\r
-  INT8    *DscFilename;\r
-  SYMBOL  *Symbol;\r
-  INT8    MakefileName[MAX_PATH]; // output makefile name\r
-  INT8    XRefFileName[MAX_PATH];\r
-  INT8    GuidDatabaseFileName[MAX_PATH];\r
-  INT8    ModuleMakefileName[MAX_PATH];\r
-  FILE    *MakefileFptr;\r
-  FILE    *ModuleMakefileFptr;\r
-  SYMBOL  *ModuleList;\r
-  SYMBOL  *OutdirList;\r
-  UINT32  Verbose;\r
+  INT8                *DscFilename;\r
+  SYMBOL              *Symbol;\r
+  INT8                MakefileName[MAX_PATH]; // output makefile name\r
+  INT8                XRefFileName[MAX_PATH];\r
+  INT8                GuidDatabaseFileName[MAX_PATH];\r
+  INT8                ModuleMakefileName[MAX_PATH];\r
+  FILE                *MakefileFptr;\r
+  FILE                *ModuleMakefileFptr;\r
+  SYMBOL              *ModuleList;\r
+  SYMBOL              *OutdirList;\r
+  UINT32              Verbose;\r
+  UINT32              ThreadNumber;\r
+  UINT32              BuildTarget;\r
+  BUILD_ITEM          *LibraryList;\r
+  COMPONENTS_ITEM     *ComponentsList;\r
 } gGlobals;\r
 \r
 //\r
@@ -584,16 +591,18 @@ Returns:
 \r
 --*/\r
 {\r
-  int       i;\r
-  DSC_FILE  DSCFile;\r
-  SECTION   *Sect;\r
-  INT8      Line[MAX_LINE_LEN];\r
-  INT8      ExpLine[MAX_LINE_LEN];\r
-  INT8      *EMsg;\r
-  FILE      *FpModule;\r
-  SYMBOL    *TempSymbol;\r
-\r
-  SetUtilityName (PROGRAM_NAME);\r
+  int                   i;\r
+  DSC_FILE              DSCFile;\r
+  SECTION               *Sect;\r
+  INT8                  Line[MAX_LINE_LEN];\r
+  INT8                  ExpLine[MAX_LINE_LEN];\r
+  INT8                  *BuildDir;\r
+  INT8                  *EMsg;\r
+  FILE                  *FpModule;\r
+  SYMBOL                *TempSymbol;\r
+  COMPONENTS_ITEM       *TempComponents;\r
+\r
+  SetUtilityName (UTILITY_NAME);\r
 \r
   InitExceptions ();\r
 \r
@@ -710,6 +719,7 @@ Returns:
   //\r
   Sect = DSCFileFindSection (&DSCFile, LIBRARIES_SECTION_NAME);\r
   if (Sect != NULL) {\r
+    mCurrentBuildList = &gGlobals.LibraryList;\r
     ProcessSectionComponents (&DSCFile, DSC_SECTION_TYPE_LIBRARIES, 0);\r
   }\r
 \r
@@ -721,6 +731,7 @@ Returns:
   //\r
   Sect = DSCFileFindSection (&DSCFile, LIBRARIES_PLATFORM_SECTION_NAME);\r
   if (Sect != NULL) {\r
+    mCurrentBuildList = &gGlobals.LibraryList;\r
     ProcessSectionComponents (&DSCFile, DSC_SECTION_TYPE_PLATFORM_LIBRARIES, 0);\r
   }\r
 \r
@@ -735,6 +746,8 @@ Returns:
   Sect = DSCFileFindSection (&DSCFile, COMPONENTS_SECTION_NAME);\r
   if (Sect != NULL) {\r
     fprintf (gGlobals.MakefileFptr, "components_0 : \n");\r
+    TempComponents    = AddComponentsItem (&gGlobals.ComponentsList);\r
+    mCurrentBuildList = &TempComponents->BuildList;\r
     ProcessSectionComponents (&DSCFile, DSC_SECTION_TYPE_COMPONENTS, 0);\r
     fprintf (gGlobals.MakefileFptr, "\n");\r
   }\r
@@ -754,6 +767,8 @@ Returns:
     Sect = DSCFileFindSection (&DSCFile, Line);\r
     if (Sect != NULL) {\r
       fprintf (gGlobals.MakefileFptr, "components_%d : \n", i);\r
+      TempComponents    = AddComponentsItem (&gGlobals.ComponentsList);\r
+      mCurrentBuildList = &TempComponents->BuildList;\r
       ProcessSectionComponents (&DSCFile, DSC_SECTION_TYPE_COMPONENTS, i);\r
       fprintf (gGlobals.MakefileFptr, "\n");\r
     } else {\r
@@ -807,12 +822,52 @@ ProcessingError:
     fclose (gGlobals.ModuleMakefileFptr);\r
     gGlobals.ModuleMakefileFptr = NULL;\r
   }\r
-    \r
+  \r
+  //\r
+  // Start multi-thread build if ThreadNumber is specified and no error status\r
+  //\r
+  if ((gGlobals.ThreadNumber != 0) && (GetUtilityStatus () < STATUS_ERROR)) {\r
+    BuildDir = GetSymbolValue (BUILD_DIR);\r
+    if (gGlobals.BuildTarget & BUILD_TARGET_LIBRARIES) {\r
+      if (StartMultiThreadBuild (&gGlobals.LibraryList, gGlobals.ThreadNumber, BuildDir) != 0) {\r
+        Error (NULL, 0, 0, NULL, "Multi-thread build libraries failure");\r
+        goto Cleanup;\r
+      }\r
+    }\r
+    i = 0;\r
+    TempComponents = gGlobals.ComponentsList;\r
+    while (TempComponents != NULL) {\r
+      if (gGlobals.BuildTarget & BUILD_TARGET_COMPONENTS) {\r
+        if (StartMultiThreadBuild (&TempComponents->BuildList, gGlobals.ThreadNumber, BuildDir) != 0) {\r
+          Error (NULL, 0, 0, NULL, "Multi-thread build components %d failure", i);\r
+          goto Cleanup;\r
+        }\r
+      }\r
+      if (gGlobals.BuildTarget & BUILD_TARGET_FVS) {\r
+        sprintf (ExpLine, "nmake -nologo -f %s fvs_%d", gGlobals.MakefileName, i);\r
+        _flushall ();\r
+        if (system (ExpLine)) {\r
+          Error (NULL, 0, 0, NULL, "Build FVs for components %d failure", i);\r
+          goto Cleanup;\r
+        }\r
+      }\r
+      i++;\r
+      TempComponents = TempComponents->Next;\r
+    }\r
+  }\r
+\r
+Cleanup:    \r
   //\r
   // Clean up\r
   //\r
+  FreeBuildList (gGlobals.LibraryList);\r
+  gGlobals.LibraryList = NULL;\r
+  FreeComponentsList (gGlobals.ComponentsList);\r
+  gGlobals.ComponentsList = NULL;\r
   FreeSymbols (gGlobals.ModuleList);\r
+  gGlobals.ModuleList = NULL;\r
   FreeSymbols (gGlobals.OutdirList);\r
+  gGlobals.OutdirList = NULL;\r
   FreeSymbols (gGlobals.Symbol);\r
   gGlobals.Symbol = NULL;\r
   CFVDestructor ();\r
@@ -1311,6 +1366,16 @@ Returns:
     CreatePackageFile (DSCFile);\r
   }\r
 \r
+  //\r
+  // Add a new build item to mCurrentBuildList\r
+  //\r
+  mCurrentBuildItem = AddBuildItem (mCurrentBuildList, GetSymbolValue (BASE_NAME), Processor, FileName);\r
+  //\r
+  // ProcessDsc allows duplicate base name libraries. Make sure the duplicate \r
+  // base name libraries will be built in the same order as listed in DSC file.\r
+  //\r
+  AddDependency (*mCurrentBuildList, mCurrentBuildItem, mCurrentBuildItem->BaseName, 1);\r
+\r
   //\r
   // Add Module name to the global module list\r
   //\r
@@ -1336,6 +1401,7 @@ Returns:
   // files in this component. This macro can then be used elsewhere to\r
   // process all the files making up the component. Required for scanning\r
   // files for string localization.\r
+  // Also add source files to mCurrentBuildItem.\r
   //\r
   ProcessSourceFiles (DSCFile, &ComponentFile, MakeFptr, SOURCE_MODE_SOURCE_FILES);\r
   //\r
@@ -1370,7 +1436,8 @@ Returns:
   // Process all the libraries to define "LIBS = x.lib y.lib..."\r
   // Be generous and append ".lib" if they forgot.\r
   // Make a macro definition: LIBS = $(LIBS) xlib.lib ylib.lib...\r
-  // Also add libs dependency for single module build: basenamebuild :: xlibbuild ylibbuild ...\r
+  // Add libs dependency for single module build: basenamebuild :: xlibbuild ylibbuild ...\r
+  // Also add libs dependency to mCurrentBuildItem.\r
   //\r
   ProcessLibs (&ComponentFile, MakeFptr);\r
 \r
@@ -1829,8 +1896,14 @@ Returns:
   OverridePath = GetSymbolValue (SOURCE_OVERRIDE_PATH);\r
   if (OverridePath != NULL) {\r
     ReplaceSlash (OverridePath);\r
+    fprintf (MakeFptr, "!IF EXIST(%s)\n", OverridePath);\r
     fprintf (MakeFptr, "INC = $(INC) -I %s\n", OverridePath);\r
-    fprintf (MakeFptr, "INC = $(INC) -I %s\\%s \n", OverridePath, Processor);\r
+    fprintf (MakeFptr, "!IF EXIST(%s\\%s)\n", OverridePath, Processor);\r
+    fprintf (MakeFptr, "INC = $(INC) -I %s\\%s\n", OverridePath, Processor);\r
+    fprintf (MakeFptr, "!ENDIF\n");\r
+    fprintf (MakeFptr, "!ELSE\n");\r
+    fprintf (MakeFptr, "!MESSAGE Warning: include dir %s does not exist\n", OverridePath);\r
+    fprintf (MakeFptr, "!ENDIF\n");\r
   }\r
   //\r
   // Try for an [includes.$(PROCESSOR).$(PLATFORM)]\r
@@ -1909,43 +1982,45 @@ ProcessIncludesSectionSingle (
           //\r
           if (Cptr[1] == 0) {\r
             fprintf (MakeFptr, "INC = $(INC) -I $(SOURCE_DIR)\n");\r
-            fprintf (\r
-              MakeFptr,\r
-              "INC = $(INC) -I $(SOURCE_DIR)\\%s \n",\r
-              Processor\r
-              );\r
+            fprintf (MakeFptr, "!IF EXIST($(SOURCE_DIR)\\%s)\n", Processor);\r
+            fprintf (MakeFptr, "INC = $(INC) -I $(SOURCE_DIR)\\%s\n", Processor);\r
+            fprintf (MakeFptr, "!ENDIF\n");\r
           } else {\r
             //\r
             // Handle case of ".\path\path\path" or "..\path\path\path"\r
             //\r
-            fprintf (\r
-              MakeFptr,\r
-              "INC = $(INC) -I $(SOURCE_DIR)\\%s \n",\r
-              Cptr\r
-              );\r
-            fprintf (\r
-              MakeFptr,\r
-              "INC = $(INC) -I $(SOURCE_DIR)\\%s\\%s \n",\r
-              Cptr,\r
-              Processor\r
-              );\r
+            fprintf (MakeFptr, "!IF EXIST($(SOURCE_DIR)\\%s)\n", Cptr);\r
+            fprintf (MakeFptr, "INC = $(INC) -I $(SOURCE_DIR)\\%s\n", Cptr);\r
+            fprintf (MakeFptr, "!IF EXIST($(SOURCE_DIR)\\%s\\%s)\n", Cptr, Processor);\r
+            fprintf (MakeFptr, "INC = $(INC) -I $(SOURCE_DIR)\\%s\\%s\n", Cptr, Processor);\r
+            fprintf (MakeFptr, "!ENDIF\n");\r
+            fprintf (MakeFptr, "!ELSE\n");\r
+            fprintf (MakeFptr, "!MESSAGE Warning: include dir $(SOURCE_DIR)\\%s does not exist\n", Cptr);\r
+            fprintf (MakeFptr, "!ENDIF\n");\r
           }\r
         } else if ((Cptr[1] != ':') && isalpha (*Cptr)) {\r
-          fprintf (MakeFptr, "INC = $(INC) -I $(EFI_SOURCE)\\%s \n", Cptr);\r
-          fprintf (\r
-            MakeFptr,\r
-            "INC = $(INC) -I $(EFI_SOURCE)\\%s\\%s \n",\r
-            Cptr,\r
-            Processor\r
-            );\r
+          fprintf (MakeFptr, "!IF EXIST($(EFI_SOURCE)\\%s)\n", Cptr);\r
+          fprintf (MakeFptr, "INC = $(INC) -I $(EFI_SOURCE)\\%s\n", Cptr);\r
+          fprintf (MakeFptr, "!IF EXIST($(EFI_SOURCE)\\%s\\%s)\n", Cptr, Processor);\r
+          fprintf (MakeFptr, "INC = $(INC) -I $(EFI_SOURCE)\\%s\\%s\n", Cptr, Processor);\r
+          fprintf (MakeFptr, "!ENDIF\n");\r
+          fprintf (MakeFptr, "!ELSE\n");\r
+          fprintf (MakeFptr, "!MESSAGE Warning: include dir $(EFI_SOURCE)\\%s does not exist\n", Cptr);\r
+          fprintf (MakeFptr, "!ENDIF\n");\r
         } else {\r
           //\r
           // The line is something like: $(EFI_SOURCE)\dxe\include. Add it to\r
           // the existing $(INC) definition. Add user includes before any\r
           // other existing paths.\r
           //\r
-          fprintf (MakeFptr, "INC = $(INC) -I %s \n", Cptr);\r
-          fprintf (MakeFptr, "INC = $(INC) -I %s\\%s \n", Cptr, Processor);\r
+          fprintf (MakeFptr, "!IF EXIST(%s)\n", Cptr);\r
+          fprintf (MakeFptr, "INC = $(INC) -I %s\n", Cptr);\r
+          fprintf (MakeFptr, "!IF EXIST(%s\\%s)\n", Cptr, Processor);\r
+          fprintf (MakeFptr, "INC = $(INC) -I %s\\%s\n", Cptr, Processor);\r
+          fprintf (MakeFptr, "!ENDIF\n");\r
+          fprintf (MakeFptr, "!ELSE\n");\r
+          fprintf (MakeFptr, "!MESSAGE Warning: include dir %s does not exist\n", Cptr);\r
+          fprintf (MakeFptr, "!ENDIF\n");\r
         }\r
       }\r
     }\r
@@ -2260,16 +2335,35 @@ ProcessSourceFilesSection (
             // SOURCE_FILES = $(SOURCE_FILES) c:\Path\ThisFile.c\r
             //\r
             fprintf (MakeFptr, "SOURCE_FILES = $(SOURCE_FILES) %s\n", TempFileName);\r
+            //\r
+            // Save the source absolute path\r
+            //\r
+            if (PathCanonicalize (FilePath, TempFileName)) {\r
+              AddSourceFile (mCurrentBuildItem, FilePath);\r
+            }\r
           } else if (IsAbsolutePath (FileName)) {\r
             //\r
             // For Absolute path, don't print $(SOURCE_FILE) directory.\r
             //\r
             fprintf (MakeFptr, "SOURCE_FILES = $(SOURCE_FILES) %s\n", FileName);\r
+            //\r
+            // Save the source absolute path\r
+            //\r
+            if (PathCanonicalize (FilePath, FileName)) {\r
+              AddSourceFile (mCurrentBuildItem, FilePath);\r
+            }\r
           } else {\r
             //\r
             // SOURCE_FILES = $(SOURCE_FILES) $(SOURCE_DIR)\ThisFile.c\r
             //\r
             fprintf (MakeFptr, "SOURCE_FILES = $(SOURCE_FILES) $(SOURCE_DIR)\\%s\n", FileName);\r
+            //\r
+            // Save the source absolute path\r
+            //\r
+            sprintf (Str, "%s\\%s", GetSymbolValue (SOURCE_DIR), FileName);\r
+            if (PathCanonicalize (FilePath, Str)) {\r
+              AddSourceFile (mCurrentBuildItem, FilePath);\r
+            }\r
           }\r
         } else if (Mode & SOURCE_MODE_BUILD_COMMANDS) {\r
           //\r
@@ -2612,6 +2706,10 @@ ProcessLibsSingle (
           Cptr[strlen (Cptr) - 4] = 0;\r
           fprintf (gGlobals.ModuleMakefileFptr, " %sbuild", Cptr);\r
         }\r
+        //\r
+        // Add libs dependency for mCurrentBuildItem \r
+        //\r
+        AddDependency (*mCurrentBuildList, mCurrentBuildItem, Cptr, 0);\r
       }\r
     }\r
   }\r
@@ -2767,8 +2865,9 @@ ProcessIncludeFilesSingle (
               if (Cptr >= TempFileName) {\r
                 *Cptr = 0;\r
               }\r
-\r
+              fprintf (MakeFptr, "!IF EXIST(%s)\n", TempFileName);\r
               fprintf (MakeFptr, "INC = -I %s $(INC)\n", TempFileName);\r
+              fprintf (MakeFptr, "!ENDIF\n");\r
             }\r
           }\r
           //\r
@@ -4173,6 +4272,63 @@ Returns:
         }\r
         break;\r
 \r
+      //\r
+      // Enable multi-thread build and specify the thread number\r
+      //\r
+      case 'n':\r
+      case 'N':\r
+        //\r
+        // Skip to next arg\r
+        //\r
+        Argc--;\r
+        Argv++;\r
+        if (Argc == 0) {\r
+          Argv--;\r
+          Error (NULL, 0, 0, Argv[0], "missing input thread number with option");\r
+          Usage ();\r
+          return STATUS_ERROR;\r
+        } else {\r
+          gGlobals.ThreadNumber = atoi (Argv[0]);\r
+          if (gGlobals.ThreadNumber == 0) {\r
+            Argv--;\r
+            Error (NULL, 0, 0, Argv[0], "input thread number should not be %s", Argv[1]);\r
+            return STATUS_ERROR;\r
+          } else if (gGlobals.ThreadNumber > MAXIMUM_WAIT_OBJECTS) {\r
+            Argv--;\r
+            Error (NULL, 0, 0, Argv[0], "input thread number should not greater than %d", MAXIMUM_WAIT_OBJECTS);\r
+            return STATUS_ERROR;\r
+          }\r
+        }\r
+        break;\r
+\r
+      //\r
+      // Specify the multi-thread build target\r
+      //\r
+      case 't':\r
+      case 'T':\r
+        //\r
+        // Skip to next arg\r
+        //\r
+        Argc--;\r
+        Argv++;\r
+        if (Argc == 0) {\r
+          Argv--;\r
+          Error (NULL, 0, 0, Argv[0], "missing input build target with option");\r
+          Usage ();\r
+          return STATUS_ERROR;\r
+        } else if (_stricmp (Argv[0], "all") == 0) {\r
+          gGlobals.BuildTarget |= BUILD_TARGET_ALL;\r
+        } else if (_stricmp (Argv[0], "libraries") == 0) {\r
+          gGlobals.BuildTarget |= BUILD_TARGET_LIBRARIES;\r
+        } else if (_stricmp (Argv[0], "components") == 0) {\r
+          gGlobals.BuildTarget |= BUILD_TARGET_COMPONENTS;\r
+        } else {\r
+          Argv--;\r
+          Error (NULL, 0, 0, Argv[0], "input build target not supported");\r
+          Usage ();\r
+        }\r
+        break;\r
+\r
       case 'v':\r
       case 'V':\r
         gGlobals.Verbose = 1;\r
@@ -4228,7 +4384,14 @@ Returns:
   if (FreeCwd) {\r
     free (Cptr);\r
   }\r
-\r
+  \r
+  //\r
+  // Default build target is all\r
+  //\r
+  if (gGlobals.BuildTarget == 0) {\r
+    gGlobals.BuildTarget = BUILD_TARGET_ALL;\r
+  }\r
+  \r
   return 0;\r
 }\r
 \r
@@ -4426,18 +4589,29 @@ Usage (
   VOID\r
   )\r
 {\r
-  int               i;\r
-  static const INT8 *Help[] = {\r
-    "Usage:  ProcessDsc {options} [Dsc Filename]",\r
-    "    Options:",\r
-    "       -d var=value        to define symbol 'var' to 'value'",\r
-    "       -v                  for verbose mode",\r
-    "       -g filename         to preparse GUID listing file",\r
-    "       -x filename         to create a cross-reference file",\r
+  int         Index;\r
+  const char  *Str[] = {\r
+    UTILITY_NAME" "UTILITY_VERSION" - Intel Process DSC File Utility",\r
+    "  Copyright (C), 2004 - 2008 Intel Corporation",\r
+    \r
+#if ( defined(UTILITY_BUILD) && defined(UTILITY_VENDOR) )\r
+    "  Built from "UTILITY_BUILD", project of "UTILITY_VENDOR,\r
+#endif\r
+    "",\r
+    "Usage:",\r
+    "  "UTILITY_NAME" [OPTION]... DSCFILE",\r
+    "Options:",\r
+    "  -d var=value        to define symbol 'var' to 'value'",\r
+    "  -v                  for verbose mode",\r
+    "  -g filename         to preparse GUID listing file",\r
+    "  -x filename         to create a cross-reference file",\r
+    "  -n threadnumber     to build with multi-thread",\r
+    "  -t target           to build the specified target:",\r
+    "                      all, libraries or components",\r
     NULL\r
   };\r
-  for (i = 0; Help[i] != NULL; i++) {\r
-    fprintf (stdout, "%s\n", Help[i]);\r
+  for (Index = 0; Str[Index] != NULL; Index++) {\r
+    fprintf (stdout, "%s\n", Str[Index]);\r
   }\r
 }\r
 \r
@@ -4562,7 +4736,7 @@ SmartOpen (
     if (SmartFile->FileContent != NULL) {\r
       memset (SmartFile->FileContent, 0, FileSize + 1);\r
       //\r
-      // Usually FileLength < FileSize, because in text mode, carriage return-linefeed\r
+      // Usually FileLength < FileSize, because in text mode, carriage return¨Clinefeed\r
       // combinations are translated into single linefeeds on input\r
       //       \r
       SmartFile->FileLength = fread (SmartFile->FileContent, sizeof(char), FileSize, Fptr);\r