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 #include "acapps.h" 46 47 /* Local prototypes */ 48 49 int 50 AsExaminePaths ( 51 ACPI_CONVERSION_TABLE *ConversionTable, 52 char *Source, 53 char *Target, 54 UINT32 *SourceFileType); 55 56 void 57 AsDisplayStats ( 58 void); 59 60 void 61 AsDisplayUsage ( 62 void); 63 64 /* Globals */ 65 66 UINT32 Gbl_Tabs = 0; 67 UINT32 Gbl_MissingBraces = 0; 68 UINT32 Gbl_NonAnsiComments = 0; 69 UINT32 Gbl_Files = 0; 70 UINT32 Gbl_WhiteLines = 0; 71 UINT32 Gbl_CommentLines = 0; 72 UINT32 Gbl_SourceLines = 0; 73 UINT32 Gbl_LongLines = 0; 74 UINT32 Gbl_TotalLines = 0; 75 UINT32 Gbl_TotalSize = 0; 76 UINT32 Gbl_HeaderLines = 0; 77 UINT32 Gbl_HeaderSize = 0; 78 void *Gbl_StructDefs = NULL; 79 80 struct stat Gbl_StatBuf; 81 char *Gbl_FileBuffer; 82 UINT32 Gbl_FileSize; 83 UINT32 Gbl_FileType; 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 "cdhilqsuv^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 ("-c", "Generate cleaned version of the source"); 258 ACPI_OPTION ("-h", "Insert dual-license header into all modules"); 259 ACPI_OPTION ("-i", "Cleanup macro indentation"); 260 ACPI_OPTION ("-l", "Generate Linux version of the source"); 261 ACPI_OPTION ("-u", "Generate Custom source translation"); 262 263 ACPI_USAGE_TEXT ("\n"); 264 ACPI_OPTION ("-d", "Leave debug statements in code"); 265 ACPI_OPTION ("-s", "Generate source statistics only"); 266 ACPI_OPTION ("-v", "Display version information"); 267 ACPI_OPTION ("-vb", "Verbose mode"); 268 ACPI_OPTION ("-y", "Suppress file overwrite prompts"); 269 } 270 271 272 /****************************************************************************** 273 * 274 * FUNCTION: main 275 * 276 * DESCRIPTION: C main function 277 * 278 ******************************************************************************/ 279 280 int ACPI_SYSTEM_XFACE 281 main ( 282 int argc, 283 char *argv[]) 284 { 285 int j; 286 ACPI_CONVERSION_TABLE *ConversionTable = NULL; 287 char *SourcePath; 288 char *TargetPath; 289 UINT32 FileType; 290 291 292 ACPI_DEBUG_INITIALIZE (); /* For debug version only */ 293 AcpiOsInitialize (); 294 printf (ACPI_COMMON_SIGNON (AS_UTILITY_NAME)); 295 296 if (argc < 2) 297 { 298 AsDisplayUsage (); 299 return (0); 300 } 301 302 /* Command line options */ 303 304 while ((j = AcpiGetopt (argc, argv, AS_SUPPORTED_OPTIONS)) != ACPI_OPT_END) switch(j) 305 { 306 case 'l': 307 308 /* Linux code generation */ 309 310 printf ("Creating Linux source code\n"); 311 ConversionTable = &LinuxConversionTable; 312 Gbl_WidenDeclarations = TRUE; 313 Gbl_IgnoreLoneLineFeeds = TRUE; 314 break; 315 316 case 'c': 317 318 /* Cleanup code */ 319 320 printf ("Code cleanup\n"); 321 ConversionTable = &CleanupConversionTable; 322 Gbl_Cleanup = TRUE; 323 break; 324 325 case 'h': 326 327 /* Inject Dual-license header */ 328 329 printf ("Inserting Dual-license header to all modules\n"); 330 ConversionTable = &LicenseConversionTable; 331 break; 332 333 case 'i': 334 335 /* Cleanup wrong indent result */ 336 337 printf ("Cleaning up macro indentation\n"); 338 ConversionTable = &IndentConversionTable; 339 Gbl_IgnoreLoneLineFeeds = TRUE; 340 Gbl_IgnoreTranslationEscapes = TRUE; 341 break; 342 343 case 's': 344 345 /* Statistics only */ 346 347 break; 348 349 case 'u': 350 351 /* custom conversion */ 352 353 printf ("Custom source translation\n"); 354 ConversionTable = &CustomConversionTable; 355 break; 356 357 case 'v': 358 359 switch (AcpiGbl_Optarg[0]) 360 { 361 case '^': /* -v: (Version): signon already emitted, just exit */ 362 363 exit (0); 364 365 case 'b': 366 367 /* Verbose mode */ 368 369 Gbl_VerboseMode = TRUE; 370 break; 371 372 default: 373 374 printf ("Unknown option: -v%s\n", AcpiGbl_Optarg); 375 return (-1); 376 } 377 378 break; 379 380 case 'y': 381 382 /* Batch mode */ 383 384 Gbl_BatchMode = TRUE; 385 break; 386 387 case 'd': 388 389 /* Leave debug statements in */ 390 391 Gbl_DebugStatementsMode = TRUE; 392 break; 393 394 case 'q': 395 396 /* Quiet mode */ 397 398 Gbl_QuietMode = TRUE; 399 break; 400 401 default: 402 403 AsDisplayUsage (); 404 return (-1); 405 } 406 407 408 SourcePath = argv[AcpiGbl_Optind]; 409 if (!SourcePath) 410 { 411 printf ("Missing source path\n"); 412 AsDisplayUsage (); 413 return (-1); 414 } 415 416 TargetPath = argv[AcpiGbl_Optind+1]; 417 418 if (!ConversionTable) 419 { 420 /* Just generate statistics. Ignore target path */ 421 422 TargetPath = SourcePath; 423 424 printf ("Source code statistics only\n"); 425 ConversionTable = &StatsConversionTable; 426 } 427 else if (!TargetPath) 428 { 429 TargetPath = SourcePath; 430 } 431 432 if (Gbl_DebugStatementsMode) 433 { 434 ConversionTable->SourceFunctions &= ~CVT_REMOVE_DEBUG_MACROS; 435 } 436 437 /* Check source and target paths and files */ 438 439 if (AsExaminePaths (ConversionTable, SourcePath, TargetPath, &FileType)) 440 { 441 return (-1); 442 } 443 444 /* Source/target can be either directories or a files */ 445 446 if (FileType == S_IFDIR) 447 { 448 /* Process the directory tree */ 449 450 AsProcessTree (ConversionTable, SourcePath, TargetPath); 451 } 452 else 453 { 454 /* Process a single file */ 455 456 /* Differentiate between source and header files */ 457 458 if (strstr (SourcePath, ".h")) 459 { 460 AsProcessOneFile (ConversionTable, NULL, TargetPath, 0, 461 SourcePath, FILE_TYPE_HEADER); 462 } 463 else if (strstr (SourcePath, ".c")) 464 { 465 AsProcessOneFile (ConversionTable, NULL, TargetPath, 0, 466 SourcePath, FILE_TYPE_SOURCE); 467 } 468 else if (strstr (SourcePath, ".patch")) 469 { 470 AsProcessOneFile (ConversionTable, NULL, TargetPath, 0, 471 SourcePath, FILE_TYPE_PATCH); 472 } 473 else 474 { 475 printf ("Unknown file type - %s\n", SourcePath); 476 } 477 } 478 479 /* Always display final summary and stats */ 480 481 AsDisplayStats (); 482 return (0); 483 } 484