1 /****************************************************************************** 2 * 3 * Module Name: asmain - Main module for the acpi source processor utility 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include "acpisrc.h" 45 46 /* Local prototypes */ 47 48 int 49 AsExaminePaths ( 50 ACPI_CONVERSION_TABLE *ConversionTable, 51 char *Source, 52 char *Target, 53 UINT32 *SourceFileType); 54 55 void 56 AsDisplayStats ( 57 void); 58 59 void 60 AsDisplayUsage ( 61 void); 62 63 /* Globals */ 64 65 UINT32 Gbl_Tabs = 0; 66 UINT32 Gbl_MissingBraces = 0; 67 UINT32 Gbl_NonAnsiComments = 0; 68 UINT32 Gbl_Files = 0; 69 UINT32 Gbl_WhiteLines = 0; 70 UINT32 Gbl_CommentLines = 0; 71 UINT32 Gbl_SourceLines = 0; 72 UINT32 Gbl_LongLines = 0; 73 UINT32 Gbl_TotalLines = 0; 74 UINT32 Gbl_TotalSize = 0; 75 UINT32 Gbl_HeaderLines = 0; 76 UINT32 Gbl_HeaderSize = 0; 77 void *Gbl_StructDefs = NULL; 78 79 struct stat Gbl_StatBuf; 80 char *Gbl_FileBuffer; 81 UINT32 Gbl_FileSize; 82 UINT32 Gbl_FileType; 83 BOOLEAN Gbl_VerboseMode = FALSE; 84 BOOLEAN Gbl_QuietMode = FALSE; 85 BOOLEAN Gbl_BatchMode = FALSE; 86 BOOLEAN Gbl_DebugStatementsMode = FALSE; 87 BOOLEAN Gbl_MadeChanges = FALSE; 88 BOOLEAN Gbl_Overwrite = FALSE; 89 BOOLEAN Gbl_WidenDeclarations = FALSE; 90 BOOLEAN Gbl_IgnoreLoneLineFeeds = FALSE; 91 BOOLEAN Gbl_HasLoneLineFeeds = FALSE; 92 BOOLEAN Gbl_Cleanup = FALSE; 93 BOOLEAN Gbl_IgnoreTranslationEscapes = FALSE; 94 95 #define AS_UTILITY_NAME "ACPI Source Code Conversion Utility" 96 #define AS_SUPPORTED_OPTIONS "cdhilqsuv^y" 97 98 99 /****************************************************************************** 100 * 101 * FUNCTION: AsExaminePaths 102 * 103 * DESCRIPTION: Source and Target pathname verification and handling 104 * 105 ******************************************************************************/ 106 107 int 108 AsExaminePaths ( 109 ACPI_CONVERSION_TABLE *ConversionTable, 110 char *Source, 111 char *Target, 112 UINT32 *SourceFileType) 113 { 114 int Status; 115 int Response; 116 117 118 Status = stat (Source, &Gbl_StatBuf); 119 if (Status) 120 { 121 printf ("Source path \"%s\" does not exist\n", Source); 122 return (-1); 123 } 124 125 /* Return the filetype -- file or a directory */ 126 127 *SourceFileType = 0; 128 if (Gbl_StatBuf.st_mode & S_IFDIR) 129 { 130 *SourceFileType = S_IFDIR; 131 } 132 133 /* 134 * If we are in no-output mode or in batch mode, we are done 135 */ 136 if ((ConversionTable->Flags & FLG_NO_FILE_OUTPUT) || 137 (Gbl_BatchMode)) 138 { 139 return (0); 140 } 141 142 if (!AcpiUtStricmp (Source, Target)) 143 { 144 printf ("Target path is the same as the source path, overwrite?\n"); 145 Response = getchar (); 146 147 /* Check response */ 148 149 if (Response != 'y') 150 { 151 return (-1); 152 } 153 154 Gbl_Overwrite = TRUE; 155 } 156 else 157 { 158 Status = stat (Target, &Gbl_StatBuf); 159 if (!Status) 160 { 161 printf ("Target path already exists, overwrite?\n"); 162 Response = getchar (); 163 164 /* Check response */ 165 166 if (Response != 'y') 167 { 168 return (-1); 169 } 170 } 171 } 172 173 return (0); 174 } 175 176 177 /****************************************************************************** 178 * 179 * FUNCTION: AsDisplayStats 180 * 181 * DESCRIPTION: Display global statistics gathered during translation 182 * 183 ******************************************************************************/ 184 185 void 186 AsDisplayStats ( 187 void) 188 { 189 190 if (Gbl_QuietMode) 191 { 192 return; 193 } 194 195 printf ("\nAcpiSrc statistics:\n\n"); 196 printf ("%8u Files processed\n", Gbl_Files); 197 198 if (!Gbl_Files) 199 { 200 return; 201 } 202 203 printf ("%8u Total bytes (%.1fK/file)\n", 204 Gbl_TotalSize, ((double) Gbl_TotalSize/Gbl_Files)/1024); 205 printf ("%8u Tabs found\n", Gbl_Tabs); 206 printf ("%8u Missing if/else/while braces\n", Gbl_MissingBraces); 207 printf ("%8u Non-ANSI // comments found\n", Gbl_NonAnsiComments); 208 printf ("%8u Total Lines\n", Gbl_TotalLines); 209 printf ("%8u Lines of code\n", Gbl_SourceLines); 210 printf ("%8u Lines of non-comment whitespace\n", Gbl_WhiteLines); 211 printf ("%8u Lines of comments\n", Gbl_CommentLines); 212 printf ("%8u Long lines found\n", Gbl_LongLines); 213 214 if (Gbl_WhiteLines > 0) 215 { 216 printf ("%8.1f Ratio of code to whitespace\n", 217 ((float) Gbl_SourceLines / (float) Gbl_WhiteLines)); 218 } 219 220 if ((Gbl_CommentLines + Gbl_NonAnsiComments) > 0) 221 { 222 printf ("%8.1f Ratio of code to comments\n", 223 ((float) Gbl_SourceLines / 224 (float) (Gbl_CommentLines + Gbl_NonAnsiComments))); 225 } 226 227 if (!Gbl_TotalLines) 228 { 229 return; 230 } 231 232 printf (" %u%% code, %u%% comments, %u%% whitespace, %u%% headers\n", 233 (Gbl_SourceLines * 100) / Gbl_TotalLines, 234 (Gbl_CommentLines * 100) / Gbl_TotalLines, 235 (Gbl_WhiteLines * 100) / Gbl_TotalLines, 236 (Gbl_HeaderLines * 100) / Gbl_TotalLines); 237 return; 238 } 239 240 241 /****************************************************************************** 242 * 243 * FUNCTION: AsDisplayUsage 244 * 245 * DESCRIPTION: Usage message 246 * 247 ******************************************************************************/ 248 249 void 250 AsDisplayUsage ( 251 void) 252 { 253 254 ACPI_USAGE_HEADER ("acpisrc [-c|l|u] [-dsvy] <SourceDir> <DestinationDir>"); 255 256 ACPI_OPTION ("-c", "Generate cleaned version of the source"); 257 ACPI_OPTION ("-h", "Insert dual-license header into all modules"); 258 ACPI_OPTION ("-i", "Cleanup macro indentation"); 259 ACPI_OPTION ("-l", "Generate Linux version of the source"); 260 ACPI_OPTION ("-u", "Generate Custom source translation"); 261 262 ACPI_USAGE_TEXT ("\n"); 263 ACPI_OPTION ("-d", "Leave debug statements in code"); 264 ACPI_OPTION ("-s", "Generate source statistics only"); 265 ACPI_OPTION ("-v", "Display version information"); 266 ACPI_OPTION ("-vb", "Verbose mode"); 267 ACPI_OPTION ("-y", "Suppress file overwrite prompts"); 268 } 269 270 271 /****************************************************************************** 272 * 273 * FUNCTION: main 274 * 275 * DESCRIPTION: C main function 276 * 277 ******************************************************************************/ 278 279 int ACPI_SYSTEM_XFACE 280 main ( 281 int argc, 282 char *argv[]) 283 { 284 int j; 285 ACPI_CONVERSION_TABLE *ConversionTable = NULL; 286 char *SourcePath; 287 char *TargetPath; 288 UINT32 FileType; 289 290 291 ACPI_DEBUG_INITIALIZE (); /* For debug version only */ 292 AcpiOsInitialize (); 293 printf (ACPI_COMMON_SIGNON (AS_UTILITY_NAME)); 294 295 if (argc < 2) 296 { 297 AsDisplayUsage (); 298 return (0); 299 } 300 301 /* Command line options */ 302 303 while ((j = AcpiGetopt (argc, argv, AS_SUPPORTED_OPTIONS)) != ACPI_OPT_END) switch(j) 304 { 305 case 'l': 306 307 /* Linux code generation */ 308 309 printf ("Creating Linux source code\n"); 310 ConversionTable = &LinuxConversionTable; 311 Gbl_WidenDeclarations = TRUE; 312 Gbl_IgnoreLoneLineFeeds = TRUE; 313 break; 314 315 case 'c': 316 317 /* Cleanup code */ 318 319 printf ("Code cleanup\n"); 320 ConversionTable = &CleanupConversionTable; 321 Gbl_Cleanup = TRUE; 322 break; 323 324 case 'h': 325 326 /* Inject Dual-license header */ 327 328 printf ("Inserting Dual-license header to all modules\n"); 329 ConversionTable = &LicenseConversionTable; 330 break; 331 332 case 'i': 333 334 /* Cleanup wrong indent result */ 335 336 printf ("Cleaning up macro indentation\n"); 337 ConversionTable = &IndentConversionTable; 338 Gbl_IgnoreLoneLineFeeds = TRUE; 339 Gbl_IgnoreTranslationEscapes = TRUE; 340 break; 341 342 case 's': 343 344 /* Statistics only */ 345 346 break; 347 348 case 'u': 349 350 /* custom conversion */ 351 352 printf ("Custom source translation\n"); 353 ConversionTable = &CustomConversionTable; 354 break; 355 356 case 'v': 357 358 switch (AcpiGbl_Optarg[0]) 359 { 360 case '^': /* -v: (Version): signon already emitted, just exit */ 361 362 exit (0); 363 364 case 'b': 365 366 /* Verbose mode */ 367 368 Gbl_VerboseMode = TRUE; 369 break; 370 371 default: 372 373 printf ("Unknown option: -v%s\n", AcpiGbl_Optarg); 374 return (-1); 375 } 376 377 break; 378 379 case 'y': 380 381 /* Batch mode */ 382 383 Gbl_BatchMode = TRUE; 384 break; 385 386 case 'd': 387 388 /* Leave debug statements in */ 389 390 Gbl_DebugStatementsMode = TRUE; 391 break; 392 393 case 'q': 394 395 /* Quiet mode */ 396 397 Gbl_QuietMode = TRUE; 398 break; 399 400 default: 401 402 AsDisplayUsage (); 403 return (-1); 404 } 405 406 407 SourcePath = argv[AcpiGbl_Optind]; 408 if (!SourcePath) 409 { 410 printf ("Missing source path\n"); 411 AsDisplayUsage (); 412 return (-1); 413 } 414 415 TargetPath = argv[AcpiGbl_Optind+1]; 416 417 if (!ConversionTable) 418 { 419 /* Just generate statistics. Ignore target path */ 420 421 TargetPath = SourcePath; 422 423 printf ("Source code statistics only\n"); 424 ConversionTable = &StatsConversionTable; 425 } 426 else if (!TargetPath) 427 { 428 TargetPath = SourcePath; 429 } 430 431 if (Gbl_DebugStatementsMode) 432 { 433 ConversionTable->SourceFunctions &= ~CVT_REMOVE_DEBUG_MACROS; 434 } 435 436 /* Check source and target paths and files */ 437 438 if (AsExaminePaths (ConversionTable, SourcePath, TargetPath, &FileType)) 439 { 440 return (-1); 441 } 442 443 /* Source/target can be either directories or a files */ 444 445 if (FileType == S_IFDIR) 446 { 447 /* Process the directory tree */ 448 449 AsProcessTree (ConversionTable, SourcePath, TargetPath); 450 } 451 else 452 { 453 /* Process a single file */ 454 455 /* Differentiate between source and header files */ 456 457 if (strstr (SourcePath, ".h")) 458 { 459 AsProcessOneFile (ConversionTable, NULL, TargetPath, 0, 460 SourcePath, FILE_TYPE_HEADER); 461 } 462 else if (strstr (SourcePath, ".c")) 463 { 464 AsProcessOneFile (ConversionTable, NULL, TargetPath, 0, 465 SourcePath, FILE_TYPE_SOURCE); 466 } 467 else if (strstr (SourcePath, ".patch")) 468 { 469 AsProcessOneFile (ConversionTable, NULL, TargetPath, 0, 470 SourcePath, FILE_TYPE_PATCH); 471 } 472 else 473 { 474 printf ("Unknown file type - %s\n", SourcePath); 475 } 476 } 477 478 /* Always display final summary and stats */ 479 480 AsDisplayStats (); 481 return (0); 482 } 483