1 /******************************************************************************
3 * Module Name: asfile - Main module for the acpi source processor utility
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2013, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
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.
46 /* Local prototypes */
50 ACPI_CONVERSION_TABLE *ConversionTable,
58 AsDetectLoneLineFeeds (
62 static ACPI_INLINE int
63 AsMaxInt (int a, int b)
65 return (a > b ? a : b);
69 /******************************************************************************
71 * FUNCTION: AsDoWildcard
73 * DESCRIPTION: Process files via wildcards
75 ******************************************************************************/
79 ACPI_CONVERSION_TABLE *ConversionTable,
90 char RequestedFileType;
93 if (FileType == FILE_TYPE_DIRECTORY)
95 RequestedFileType = REQUEST_DIR_ONLY;
99 RequestedFileType = REQUEST_FILE_ONLY;
102 VERBOSE_PRINT (("Checking for %s source files in directory \"%s\"\n",
103 WildcardSpec, SourcePath));
105 /* Open the directory for wildcard search */
107 DirInfo = AcpiOsOpenDirectory (SourcePath, WildcardSpec, RequestedFileType);
111 * Get all of the files that match both the
112 * wildcard and the requested file type
114 while ((Filename = AcpiOsGetNextFilename (DirInfo)))
116 /* Looking for directory files, must check file type */
118 switch (RequestedFileType)
120 case REQUEST_DIR_ONLY:
122 /* If we actually have a dir, process the subtree */
124 if (!AsCheckForDirectory (SourcePath, TargetPath, Filename,
125 &SourceDirPath, &TargetDirPath))
127 VERBOSE_PRINT (("Subdirectory: %s\n", Filename));
129 AsProcessTree (ConversionTable, SourceDirPath, TargetDirPath);
130 free (SourceDirPath);
131 free (TargetDirPath);
135 case REQUEST_FILE_ONLY:
137 /* Otherwise, this is a file, not a directory */
139 VERBOSE_PRINT (("File: %s\n", Filename));
141 AsProcessOneFile (ConversionTable, SourcePath, TargetPath,
142 MaxPathLength, Filename, FileType);
153 AcpiOsCloseDirectory (DirInfo);
158 /******************************************************************************
160 * FUNCTION: AsProcessTree
162 * DESCRIPTION: Process the directory tree. Files with the extension ".C" and
163 * ".H" are processed as the tree is traversed.
165 ******************************************************************************/
169 ACPI_CONVERSION_TABLE *ConversionTable,
176 MaxPathLength = AsMaxInt (strlen (SourcePath), strlen (TargetPath));
178 if (!(ConversionTable->Flags & FLG_NO_FILE_OUTPUT))
180 if (ConversionTable->Flags & FLG_LOWERCASE_DIRNAMES)
182 AsStrlwr (TargetPath);
185 VERBOSE_PRINT (("Creating Directory \"%s\"\n", TargetPath));
186 if (mkdir (TargetPath))
190 printf ("Could not create target directory\n");
196 /* Do the C source files */
198 AsDoWildcard (ConversionTable, SourcePath, TargetPath, MaxPathLength,
199 FILE_TYPE_SOURCE, "*.c");
201 /* Do the C header files */
203 AsDoWildcard (ConversionTable, SourcePath, TargetPath, MaxPathLength,
204 FILE_TYPE_HEADER, "*.h");
206 /* Do the Lex file(s) */
208 AsDoWildcard (ConversionTable, SourcePath, TargetPath, MaxPathLength,
209 FILE_TYPE_SOURCE, "*.l");
211 /* Do the yacc file(s) */
213 AsDoWildcard (ConversionTable, SourcePath, TargetPath, MaxPathLength,
214 FILE_TYPE_SOURCE, "*.y");
216 /* Do any ASL files */
218 AsDoWildcard (ConversionTable, SourcePath, TargetPath, MaxPathLength,
219 FILE_TYPE_HEADER, "*.asl");
221 /* Do any subdirectories */
223 AsDoWildcard (ConversionTable, SourcePath, TargetPath, MaxPathLength,
224 FILE_TYPE_DIRECTORY, "*");
230 /******************************************************************************
232 * FUNCTION: AsDetectLoneLineFeeds
234 * DESCRIPTION: Find LF without CR.
236 ******************************************************************************/
239 AsDetectLoneLineFeeds (
245 UINT32 LineCount = 0;
255 if (Buffer[i] == 0x0A)
257 if (Buffer[i-1] != 0x0D)
268 if (LineCount == LfCount)
270 if (!Gbl_IgnoreLoneLineFeeds)
272 printf ("%s: ****File has UNIX format**** (LF only, not CR/LF) %u lines\n",
278 printf ("%s: %u lone linefeeds in file\n", Filename, LfCount);
287 /******************************************************************************
289 * FUNCTION: AsConvertFile
291 * DESCRIPTION: Perform the requested transforms on the file buffer (as
292 * determined by the ConversionTable and the FileType).
294 ******************************************************************************/
298 ACPI_CONVERSION_TABLE *ConversionTable,
301 ACPI_NATIVE_INT FileType)
305 ACPI_STRING_TABLE *StringTable;
306 ACPI_IDENTIFIER_TABLE *ConditionalTable;
307 ACPI_IDENTIFIER_TABLE *LineTable;
308 ACPI_IDENTIFIER_TABLE *MacroTable;
309 ACPI_TYPED_IDENTIFIER_TABLE *StructTable;
310 ACPI_IDENTIFIER_TABLE *SpecialMacroTable;
315 case FILE_TYPE_SOURCE:
317 Functions = ConversionTable->SourceFunctions;
318 StringTable = ConversionTable->SourceStringTable;
319 LineTable = ConversionTable->SourceLineTable;
320 ConditionalTable = ConversionTable->SourceConditionalTable;
321 MacroTable = ConversionTable->SourceMacroTable;
322 StructTable = ConversionTable->SourceStructTable;
323 SpecialMacroTable = ConversionTable->SourceSpecialMacroTable;
326 case FILE_TYPE_HEADER:
328 Functions = ConversionTable->HeaderFunctions;
329 StringTable = ConversionTable->HeaderStringTable;
330 LineTable = ConversionTable->HeaderLineTable;
331 ConditionalTable = ConversionTable->HeaderConditionalTable;
332 MacroTable = ConversionTable->HeaderMacroTable;
333 StructTable = ConversionTable->HeaderStructTable;
334 SpecialMacroTable = ConversionTable->HeaderSpecialMacroTable;
339 printf ("Unknown file type, cannot process\n");
344 Gbl_StructDefs = strstr (FileBuffer, "/* acpisrc:StructDefs");
346 VERBOSE_PRINT (("Processing %u bytes\n",
347 (unsigned int) strlen (FileBuffer)));
351 AsRemoveExtraLines (FileBuffer, Filename);
352 AsRemoveSpacesAfterPeriod (FileBuffer, Filename);
355 if (ConversionTable->LowerCaseTable)
357 for (i = 0; ConversionTable->LowerCaseTable[i].Identifier; i++)
359 AsLowerCaseString (ConversionTable->LowerCaseTable[i].Identifier,
364 /* Process all the string replacements */
368 for (i = 0; StringTable[i].Target; i++)
370 AsReplaceString (StringTable[i].Target, StringTable[i].Replacement,
371 StringTable[i].Type, FileBuffer);
377 for (i = 0; LineTable[i].Identifier; i++)
379 AsRemoveLine (FileBuffer, LineTable[i].Identifier);
383 if (ConditionalTable)
385 for (i = 0; ConditionalTable[i].Identifier; i++)
387 AsRemoveConditionalCompile (FileBuffer, ConditionalTable[i].Identifier);
393 for (i = 0; MacroTable[i].Identifier; i++)
395 AsRemoveMacro (FileBuffer, MacroTable[i].Identifier);
401 for (i = 0; StructTable[i].Identifier; i++)
403 AsInsertPrefix (FileBuffer, StructTable[i].Identifier, StructTable[i].Type);
407 if (SpecialMacroTable)
409 for (i = 0; SpecialMacroTable[i].Identifier; i++)
411 AsCleanupSpecialMacro (FileBuffer, SpecialMacroTable[i].Identifier);
415 /* Process the function table */
417 for (i = 0; i < 32; i++)
419 /* Decode the function bitmap */
421 switch ((1 << i) & Functions)
425 /* This function not configured */
430 AsCountTabs (FileBuffer, Filename);
433 case CVT_COUNT_NON_ANSI_COMMENTS:
435 AsCountNonAnsiComments (FileBuffer, Filename);
438 case CVT_CHECK_BRACES:
440 AsCheckForBraces (FileBuffer, Filename);
445 AsTrimLines (FileBuffer, Filename);
448 case CVT_COUNT_LINES:
450 AsCountSourceLines (FileBuffer, Filename);
453 case CVT_BRACES_ON_SAME_LINE:
455 AsBracesOnSameLine (FileBuffer);
458 case CVT_MIXED_CASE_TO_UNDERSCORES:
460 AsMixedCaseToUnderscores (FileBuffer, Filename);
463 case CVT_LOWER_CASE_IDENTIFIERS:
465 AsLowerCaseIdentifiers (FileBuffer);
468 case CVT_REMOVE_DEBUG_MACROS:
470 AsRemoveDebugMacros (FileBuffer);
473 case CVT_TRIM_WHITESPACE:
475 AsTrimWhitespace (FileBuffer);
478 case CVT_REMOVE_EMPTY_BLOCKS:
480 AsRemoveEmptyBlocks (FileBuffer, Filename);
483 case CVT_REDUCE_TYPEDEFS:
485 AsReduceTypedefs (FileBuffer, "typedef union");
486 AsReduceTypedefs (FileBuffer, "typedef struct");
489 case CVT_SPACES_TO_TABS4:
491 AsTabify4 (FileBuffer);
494 case CVT_SPACES_TO_TABS8:
496 AsTabify8 (FileBuffer);
499 case CVT_COUNT_SHORTMULTILINE_COMMENTS:
501 #ifdef ACPI_FUTURE_IMPLEMENTATION
502 AsTrimComments (FileBuffer, Filename);
508 printf ("Unknown conversion subfunction opcode\n");
513 if (ConversionTable->NewHeader)
515 AsReplaceHeader (FileBuffer, ConversionTable->NewHeader);
520 /******************************************************************************
522 * FUNCTION: AsProcessOneFile
524 * DESCRIPTION: Process one source file. The file is opened, read entirely
525 * into a buffer, converted, then written to a new file.
527 ******************************************************************************/
531 ACPI_CONVERSION_TABLE *ConversionTable,
536 ACPI_NATIVE_INT FileType)
539 char *OutPathname = NULL;
542 /* Allocate a file pathname buffer for both source and target */
544 Pathname = calloc (MaxPathLength + strlen (Filename) + 2, 1);
547 printf ("Could not allocate buffer for file pathnames\n");
551 Gbl_FileType = FileType;
553 /* Generate the source pathname and read the file */
557 strcpy (Pathname, SourcePath);
558 strcat (Pathname, "/");
561 strcat (Pathname, Filename);
563 if (AsGetFile (Pathname, &Gbl_FileBuffer, &Gbl_FileSize))
569 if (strstr (Filename, ".asl"))
571 Gbl_HeaderSize = LINES_IN_ASL_HEADER; /* Lines in default ASL header */
573 else if (strstr (Gbl_FileBuffer, LEGAL_HEADER_SIGNATURE))
575 Gbl_HeaderSize = LINES_IN_LEGAL_HEADER; /* Normal C file and H header */
577 else if (strstr (Gbl_FileBuffer, LINUX_HEADER_SIGNATURE))
579 Gbl_HeaderSize = LINES_IN_LINUX_HEADER; /* Linuxized C file and H header */
582 /* Process the file in the buffer */
584 Gbl_MadeChanges = FALSE;
585 if (!Gbl_IgnoreLoneLineFeeds && Gbl_HasLoneLineFeeds)
588 * All lone LFs will be converted to CR/LF
589 * (when file is written, Windows version only)
591 printf ("Converting lone linefeeds\n");
592 Gbl_MadeChanges = TRUE;
595 AsConvertFile (ConversionTable, Gbl_FileBuffer, Pathname, FileType);
597 if (!(ConversionTable->Flags & FLG_NO_FILE_OUTPUT))
599 if (!(Gbl_Overwrite && !Gbl_MadeChanges))
601 /* Generate the target pathname and write the file */
603 OutPathname = calloc (MaxPathLength + strlen (Filename) + 2 + strlen (TargetPath), 1);
606 printf ("Could not allocate buffer for file pathnames\n");
610 strcpy (OutPathname, TargetPath);
613 strcat (OutPathname, "/");
614 strcat (OutPathname, Filename);
617 AsPutFile (OutPathname, Gbl_FileBuffer, ConversionTable->Flags);
621 free (Gbl_FileBuffer);
632 /******************************************************************************
634 * FUNCTION: AsCheckForDirectory
636 * DESCRIPTION: Check if the current file is a valid directory. If not,
637 * construct the full pathname for the source and target paths.
638 * Checks for the dot and dot-dot files (they are ignored)
640 ******************************************************************************/
643 AsCheckForDirectory (
654 if (!(strcmp (Filename, ".")) ||
655 !(strcmp (Filename, "..")))
660 SrcPath = calloc (strlen (SourceDirPath) + strlen (Filename) + 2, 1);
663 printf ("Could not allocate buffer for directory source pathname\n");
667 TgtPath = calloc (strlen (TargetDirPath) + strlen (Filename) + 2, 1);
670 printf ("Could not allocate buffer for directory target pathname\n");
675 strcpy (SrcPath, SourceDirPath);
676 strcat (SrcPath, "/");
677 strcat (SrcPath, Filename);
679 strcpy (TgtPath, TargetDirPath);
680 strcat (TgtPath, "/");
681 strcat (TgtPath, Filename);
683 *SourcePath = SrcPath;
684 *TargetPath = TgtPath;
689 /******************************************************************************
691 * FUNCTION: AsGetFile
693 * DESCRIPTION: Open a file and read it entirely into a an allocated buffer
695 ******************************************************************************/
711 /* Binary mode leaves CR/LF pairs */
713 File = fopen (Filename, "rb");
716 printf ("Could not open file %s\n", Filename);
720 /* Need file size to allocate a buffer */
722 Seek1 = fseek (File, 0L, SEEK_END);
724 Seek2 = fseek (File, 0L, SEEK_SET);
726 if (Seek1 || Seek2 || (Size == -1))
728 printf ("Could not get file size for %s\n", Filename);
733 * Create a buffer for the entire file
734 * Add plenty extra buffer to accommodate string replacements
736 Gbl_TotalSize += Size;
738 Buffer = calloc (Size * 2, 1);
741 printf ("Could not allocate buffer of size %u\n", Size * 2);
745 /* Read the entire file */
747 Actual = fread (Buffer, 1, Size, File);
750 printf ("Could not read the input file %s (%u bytes)\n",
755 Buffer [Size] = 0; /* Null terminate the buffer */
758 /* Check for unix contamination */
760 Gbl_HasLoneLineFeeds = AsDetectLoneLineFeeds (Filename, Buffer);
763 * Convert all CR/LF pairs to LF only. We do this locally so that
764 * this code is portable across operating systems.
766 AsConvertToLineFeeds (Buffer);
768 *FileBuffer = Buffer;
780 /******************************************************************************
782 * FUNCTION: AsPutFile
784 * DESCRIPTION: Create a new output file and write the entire contents of the
785 * buffer to the new file. Buffer must be a zero terminated string
787 ******************************************************************************/
801 /* Create the target file */
803 if (!(SystemFlags & FLG_NO_CARRIAGE_RETURNS))
805 /* Put back the CR before each LF */
807 AsInsertCarriageReturns (FileBuffer);
810 File = fopen (Pathname, "w+b");
813 perror ("Could not create destination file");
814 printf ("Could not create destination file \"%s\"\n", Pathname);
818 /* Write the buffer to the file */
820 FileSize = strlen (FileBuffer);
821 Actual = fwrite (FileBuffer, 1, FileSize, File);
822 if (Actual != FileSize)
824 printf ("Error writing output file \"%s\"\n", Pathname);