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