1 /****************************************************************************** 2 * 3 * Module Name: asmain - Main module for the acpi source processor utility 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2013, 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 printf ("\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 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)) != EOF) 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 499 { 500 AsProcessOneFile (ConversionTable, NULL, TargetPath, 0, SourcePath, FILE_TYPE_SOURCE); 501 } 502 } 503 504 /* Always display final summary and stats */ 505 506 AsDisplayStats (); 507 508 return (0); 509 }