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