1 /****************************************************************************** 2 * 3 * Module Name: asmain - Main module for the acpi source processor utility 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2018, 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_CheckAscii = FALSE; 84 BOOLEAN Gbl_VerboseMode = FALSE; 85 BOOLEAN Gbl_QuietMode = FALSE; 86 BOOLEAN Gbl_BatchMode = FALSE; 87 BOOLEAN Gbl_DebugStatementsMode = FALSE; 88 BOOLEAN Gbl_MadeChanges = FALSE; 89 BOOLEAN Gbl_Overwrite = FALSE; 90 BOOLEAN Gbl_WidenDeclarations = FALSE; 91 BOOLEAN Gbl_IgnoreLoneLineFeeds = FALSE; 92 BOOLEAN Gbl_HasLoneLineFeeds = FALSE; 93 BOOLEAN Gbl_Cleanup = FALSE; 94 BOOLEAN Gbl_IgnoreTranslationEscapes = FALSE; 95 96 #define AS_UTILITY_NAME "ACPI Source Code Conversion Utility" 97 #define AS_SUPPORTED_OPTIONS "acdhilqsuv^y" 98 99 100 /****************************************************************************** 101 * 102 * FUNCTION: AsExaminePaths 103 * 104 * DESCRIPTION: Source and Target pathname verification and handling 105 * 106 ******************************************************************************/ 107 108 int 109 AsExaminePaths ( 110 ACPI_CONVERSION_TABLE *ConversionTable, 111 char *Source, 112 char *Target, 113 UINT32 *SourceFileType) 114 { 115 int Status; 116 int Response; 117 118 119 Status = stat (Source, &Gbl_StatBuf); 120 if (Status) 121 { 122 printf ("Source path \"%s\" does not exist\n", Source); 123 return (-1); 124 } 125 126 /* Return the filetype -- file or a directory */ 127 128 *SourceFileType = 0; 129 if (Gbl_StatBuf.st_mode & S_IFDIR) 130 { 131 *SourceFileType = S_IFDIR; 132 } 133 134 /* 135 * If we are in no-output mode or in batch mode, we are done 136 */ 137 if ((ConversionTable->Flags & FLG_NO_FILE_OUTPUT) || 138 (Gbl_BatchMode)) 139 { 140 return (0); 141 } 142 143 if (!AcpiUtStricmp (Source, Target)) 144 { 145 printf ("Target path is the same as the source path, overwrite?\n"); 146 Response = getchar (); 147 148 /* Check response */ 149 150 if (Response != 'y') 151 { 152 return (-1); 153 } 154 155 Gbl_Overwrite = TRUE; 156 } 157 else 158 { 159 Status = stat (Target, &Gbl_StatBuf); 160 if (!Status) 161 { 162 printf ("Target path already exists, overwrite?\n"); 163 Response = getchar (); 164 165 /* Check response */ 166 167 if (Response != 'y') 168 { 169 return (-1); 170 } 171 } 172 } 173 174 return (0); 175 } 176 177 178 /****************************************************************************** 179 * 180 * FUNCTION: AsDisplayStats 181 * 182 * DESCRIPTION: Display global statistics gathered during translation 183 * 184 ******************************************************************************/ 185 186 void 187 AsDisplayStats ( 188 void) 189 { 190 191 if (Gbl_QuietMode) 192 { 193 return; 194 } 195 196 printf ("\nAcpiSrc statistics:\n\n"); 197 printf ("%8u Files processed\n", Gbl_Files); 198 199 if (!Gbl_Files) 200 { 201 return; 202 } 203 204 printf ("%8u Total bytes (%.1fK/file)\n", 205 Gbl_TotalSize, ((double) Gbl_TotalSize/Gbl_Files)/1024); 206 printf ("%8u Tabs found\n", Gbl_Tabs); 207 printf ("%8u Missing if/else/while braces\n", Gbl_MissingBraces); 208 printf ("%8u Non-ANSI // comments found\n", Gbl_NonAnsiComments); 209 printf ("%8u Total Lines\n", Gbl_TotalLines); 210 printf ("%8u Lines of code\n", Gbl_SourceLines); 211 printf ("%8u Lines of non-comment whitespace\n", Gbl_WhiteLines); 212 printf ("%8u Lines of comments\n", Gbl_CommentLines); 213 printf ("%8u Long lines found\n", Gbl_LongLines); 214 215 if (Gbl_WhiteLines > 0) 216 { 217 printf ("%8.1f Ratio of code to whitespace\n", 218 ((float) Gbl_SourceLines / (float) Gbl_WhiteLines)); 219 } 220 221 if ((Gbl_CommentLines + Gbl_NonAnsiComments) > 0) 222 { 223 printf ("%8.1f Ratio of code to comments\n", 224 ((float) Gbl_SourceLines / 225 (float) (Gbl_CommentLines + Gbl_NonAnsiComments))); 226 } 227 228 if (!Gbl_TotalLines) 229 { 230 return; 231 } 232 233 printf (" %u%% code, %u%% comments, %u%% whitespace, %u%% headers\n", 234 (Gbl_SourceLines * 100) / Gbl_TotalLines, 235 (Gbl_CommentLines * 100) / Gbl_TotalLines, 236 (Gbl_WhiteLines * 100) / Gbl_TotalLines, 237 (Gbl_HeaderLines * 100) / Gbl_TotalLines); 238 return; 239 } 240 241 242 /****************************************************************************** 243 * 244 * FUNCTION: AsDisplayUsage 245 * 246 * DESCRIPTION: Usage message 247 * 248 ******************************************************************************/ 249 250 void 251 AsDisplayUsage ( 252 void) 253 { 254 255 ACPI_USAGE_HEADER ("acpisrc [-c|l|u] [-dsvy] <SourceDir> <DestinationDir>"); 256 257 ACPI_OPTION ("-a <file>", "Check entire file for non-printable characters"); 258 ACPI_OPTION ("-c", "Generate cleaned version of the source"); 259 ACPI_OPTION ("-h", "Insert dual-license header into all modules"); 260 ACPI_OPTION ("-i", "Cleanup macro indentation"); 261 ACPI_OPTION ("-l", "Generate Linux version of the source"); 262 ACPI_OPTION ("-u", "Generate Custom source translation"); 263 264 ACPI_USAGE_TEXT ("\n"); 265 ACPI_OPTION ("-d", "Leave debug statements in code"); 266 ACPI_OPTION ("-s", "Generate source statistics only"); 267 ACPI_OPTION ("-v", "Display version information"); 268 ACPI_OPTION ("-vb", "Verbose mode"); 269 ACPI_OPTION ("-vd", "Display build date and time"); 270 ACPI_OPTION ("-y", "Suppress file overwrite prompts"); 271 } 272 273 274 /****************************************************************************** 275 * 276 * FUNCTION: main 277 * 278 * DESCRIPTION: C main function 279 * 280 ******************************************************************************/ 281 282 int ACPI_SYSTEM_XFACE 283 main ( 284 int argc, 285 char *argv[]) 286 { 287 int j; 288 ACPI_CONVERSION_TABLE *ConversionTable = NULL; 289 char *SourcePath; 290 char *TargetPath; 291 UINT32 FileType; 292 293 294 ACPI_DEBUG_INITIALIZE (); /* For debug version only */ 295 AcpiOsInitialize (); 296 printf (ACPI_COMMON_SIGNON (AS_UTILITY_NAME)); 297 298 if (argc < 2) 299 { 300 AsDisplayUsage (); 301 return (0); 302 } 303 304 /* Command line options */ 305 306 while ((j = AcpiGetopt (argc, argv, AS_SUPPORTED_OPTIONS)) != ACPI_OPT_END) switch(j) 307 { 308 case 'l': 309 310 /* Linux code generation */ 311 312 printf ("Creating Linux source code\n"); 313 ConversionTable = &LinuxConversionTable; 314 Gbl_WidenDeclarations = TRUE; 315 Gbl_IgnoreLoneLineFeeds = TRUE; 316 break; 317 318 case 'c': 319 320 /* Cleanup code */ 321 322 printf ("Code cleanup\n"); 323 ConversionTable = &CleanupConversionTable; 324 Gbl_Cleanup = TRUE; 325 break; 326 327 case 'h': 328 329 /* Inject Dual-license header */ 330 331 printf ("Inserting Dual-license header to all modules\n"); 332 ConversionTable = &LicenseConversionTable; 333 break; 334 335 case 'i': 336 337 /* Cleanup wrong indent result */ 338 339 printf ("Cleaning up macro indentation\n"); 340 ConversionTable = &IndentConversionTable; 341 Gbl_IgnoreLoneLineFeeds = TRUE; 342 Gbl_IgnoreTranslationEscapes = TRUE; 343 break; 344 345 case 's': 346 347 /* Statistics only */ 348 349 break; 350 351 case 'u': 352 353 /* custom conversion */ 354 355 printf ("Custom source translation\n"); 356 ConversionTable = &CustomConversionTable; 357 break; 358 359 case 'v': 360 361 switch (AcpiGbl_Optarg[0]) 362 { 363 case '^': /* -v: (Version): signon already emitted, just exit */ 364 365 exit (0); 366 367 case 'b': 368 369 /* Verbose mode */ 370 371 Gbl_VerboseMode = TRUE; 372 break; 373 374 case 'd': 375 376 printf (ACPI_COMMON_BUILD_TIME); 377 return (0); 378 379 default: 380 381 printf ("Unknown option: -v%s\n", AcpiGbl_Optarg); 382 return (-1); 383 } 384 385 break; 386 387 case 'y': 388 389 /* Batch mode */ 390 391 Gbl_BatchMode = TRUE; 392 break; 393 394 case 'd': 395 396 /* Leave debug statements in */ 397 398 Gbl_DebugStatementsMode = TRUE; 399 break; 400 401 case 'q': 402 403 /* Quiet mode */ 404 405 Gbl_QuietMode = TRUE; 406 break; 407 408 case 'a': 409 410 Gbl_CheckAscii = TRUE; 411 break; 412 413 default: 414 415 AsDisplayUsage (); 416 return (-1); 417 } 418 419 420 SourcePath = argv[AcpiGbl_Optind]; 421 if (!SourcePath) 422 { 423 printf ("Missing source path\n"); 424 AsDisplayUsage (); 425 return (-1); 426 } 427 428 /* This option checks the entire file for printable ascii chars */ 429 430 if (Gbl_CheckAscii) 431 { 432 AsProcessOneFile (NULL, NULL, NULL, 0, SourcePath, FILE_TYPE_SOURCE); 433 return (0); 434 } 435 436 TargetPath = argv[AcpiGbl_Optind+1]; 437 438 if (!ConversionTable) 439 { 440 /* Just generate statistics. Ignore target path */ 441 442 TargetPath = SourcePath; 443 444 printf ("Source code statistics only\n"); 445 ConversionTable = &StatsConversionTable; 446 } 447 else if (!TargetPath) 448 { 449 TargetPath = SourcePath; 450 } 451 452 if (Gbl_DebugStatementsMode) 453 { 454 ConversionTable->SourceFunctions &= ~CVT_REMOVE_DEBUG_MACROS; 455 } 456 457 /* Check source and target paths and files */ 458 459 if (AsExaminePaths (ConversionTable, SourcePath, TargetPath, &FileType)) 460 { 461 return (-1); 462 } 463 464 /* Source/target can be either directories or a files */ 465 466 if (FileType == S_IFDIR) 467 { 468 /* Process the directory tree */ 469 470 AsProcessTree (ConversionTable, SourcePath, TargetPath); 471 } 472 else 473 { 474 if (Gbl_CheckAscii) 475 { 476 AsProcessOneFile (NULL, NULL, NULL, 0, 477 SourcePath, FILE_TYPE_SOURCE); 478 return (0); 479 } 480 481 /* Process a single file */ 482 483 /* Differentiate between source and header files */ 484 485 if (strstr (SourcePath, ".h")) 486 { 487 AsProcessOneFile (ConversionTable, NULL, TargetPath, 0, 488 SourcePath, FILE_TYPE_HEADER); 489 } 490 else if (strstr (SourcePath, ".c")) 491 { 492 AsProcessOneFile (ConversionTable, NULL, TargetPath, 0, 493 SourcePath, FILE_TYPE_SOURCE); 494 } 495 else if (strstr (SourcePath, ".patch")) 496 { 497 AsProcessOneFile (ConversionTable, NULL, TargetPath, 0, 498 SourcePath, FILE_TYPE_PATCH); 499 } 500 else 501 { 502 printf ("Unknown file type - %s\n", SourcePath); 503 } 504 } 505 506 /* Always display final summary and stats */ 507 508 AsDisplayStats (); 509 return (0); 510 } 511