xref: /netbsd-src/sys/external/bsd/acpica/dist/tools/acpisrc/asfile.c (revision 046a29855e04359424fd074e8313af6b6be8cfb6)
1 /******************************************************************************
2  *
3  * Module Name: asfile - Main module for the acpi source processor utility
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2023, 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 MERCHANTABILITY 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 
46 /* Local prototypes */
47 
48 void
49 AsDoWildcard (
50     ACPI_CONVERSION_TABLE   *ConversionTable,
51     char                    *SourcePath,
52     char                    *TargetPath,
53     int                     MaxPathLength,
54     int                     FileType,
55     char                    *WildcardSpec);
56 
57 BOOLEAN
58 AsDetectLoneLineFeeds (
59     char                    *Filename,
60     char                    *Buffer);
61 
62 static BOOLEAN
63 AsCheckForNonPrintableChars (
64     char                    *FileBuffer,
65     UINT32                  FileSize);
66 
67 static ACPI_INLINE int
AsMaxInt(int a,int b)68 AsMaxInt (int a, int b)
69 {
70     return (a > b ? a : b);
71 }
72 
73 
74 /******************************************************************************
75  *
76  * FUNCTION:    AsDoWildcard
77  *
78  * DESCRIPTION: Process files via wildcards
79  *
80  ******************************************************************************/
81 
82 void
AsDoWildcard(ACPI_CONVERSION_TABLE * ConversionTable,char * SourcePath,char * TargetPath,int MaxPathLength,int FileType,char * WildcardSpec)83 AsDoWildcard (
84     ACPI_CONVERSION_TABLE   *ConversionTable,
85     char                    *SourcePath,
86     char                    *TargetPath,
87     int                     MaxPathLength,
88     int                     FileType,
89     char                    *WildcardSpec)
90 {
91     void                    *DirInfo;
92     char                    *Filename;
93     char                    *SourceDirPath;
94     char                    *TargetDirPath;
95     char                    RequestedFileType;
96 
97 
98     if (FileType == FILE_TYPE_DIRECTORY)
99     {
100         RequestedFileType = REQUEST_DIR_ONLY;
101     }
102     else
103     {
104         RequestedFileType = REQUEST_FILE_ONLY;
105     }
106 
107     VERBOSE_PRINT (("Checking for %s source files in directory \"%s\"\n",
108             WildcardSpec, SourcePath));
109 
110     /* Open the directory for wildcard search */
111 
112     DirInfo = AcpiOsOpenDirectory (SourcePath, WildcardSpec, RequestedFileType);
113     if (DirInfo)
114     {
115         /*
116          * Get all of the files that match both the
117          * wildcard and the requested file type
118          */
119         while ((Filename = AcpiOsGetNextFilename (DirInfo)))
120         {
121             /* Looking for directory files, must check file type */
122 
123             switch (RequestedFileType)
124             {
125             case REQUEST_DIR_ONLY:
126 
127                 /* If we actually have a dir, process the subtree */
128 
129                 if (!AsCheckForDirectory (SourcePath, TargetPath, Filename,
130                     &SourceDirPath, &TargetDirPath))
131                 {
132                     VERBOSE_PRINT (("Subdirectory: %s\n", Filename));
133 
134                     AsProcessTree (ConversionTable, SourceDirPath, TargetDirPath);
135                     free (SourceDirPath);
136                     free (TargetDirPath);
137                 }
138                 break;
139 
140             case REQUEST_FILE_ONLY:
141 
142                 /* Otherwise, this is a file, not a directory */
143 
144                 VERBOSE_PRINT (("File: %s\n", Filename));
145 
146                 AsProcessOneFile (ConversionTable, SourcePath, TargetPath,
147                     MaxPathLength, Filename, FileType);
148                 break;
149 
150             default:
151 
152                 break;
153             }
154         }
155 
156         /* Cleanup */
157 
158         AcpiOsCloseDirectory (DirInfo);
159     }
160 }
161 
162 
163 /******************************************************************************
164  *
165  * FUNCTION:    AsProcessTree
166  *
167  * DESCRIPTION: Process the directory tree. Files with the extension ".C" and
168  *              ".H" are processed as the tree is traversed.
169  *
170  ******************************************************************************/
171 
172 ACPI_NATIVE_INT
AsProcessTree(ACPI_CONVERSION_TABLE * ConversionTable,char * SourcePath,char * TargetPath)173 AsProcessTree (
174     ACPI_CONVERSION_TABLE   *ConversionTable,
175     char                    *SourcePath,
176     char                    *TargetPath)
177 {
178     int                     MaxPathLength;
179 
180 
181     MaxPathLength = AsMaxInt (strlen (SourcePath), strlen (TargetPath));
182 
183     if (!(ConversionTable->Flags & FLG_NO_FILE_OUTPUT))
184     {
185         if (ConversionTable->Flags & FLG_LOWERCASE_DIRNAMES)
186         {
187             AcpiUtStrlwr (TargetPath);
188         }
189 
190         VERBOSE_PRINT (("Creating Directory \"%s\"\n", TargetPath));
191         if (mkdir (TargetPath))
192         {
193             if (errno != EEXIST)
194             {
195                 printf ("Could not create target directory\n");
196                 return (-1);
197             }
198         }
199     }
200 
201     /* Do the C source files */
202 
203     AsDoWildcard (ConversionTable, SourcePath, TargetPath, MaxPathLength,
204         FILE_TYPE_SOURCE, "*.c");
205 
206     /* Do the C header files */
207 
208     AsDoWildcard (ConversionTable, SourcePath, TargetPath, MaxPathLength,
209         FILE_TYPE_HEADER, "*.h");
210 
211     /* Do the Lex file(s) */
212 
213     AsDoWildcard (ConversionTable, SourcePath, TargetPath, MaxPathLength,
214         FILE_TYPE_SOURCE, "*.l");
215 
216     /* Do the yacc file(s) */
217 
218     AsDoWildcard (ConversionTable, SourcePath, TargetPath, MaxPathLength,
219         FILE_TYPE_SOURCE, "*.y");
220 
221     /* Do any ASL files */
222 
223     AsDoWildcard (ConversionTable, SourcePath, TargetPath, MaxPathLength,
224         FILE_TYPE_HEADER, "*.asl");
225 
226     /* Do any subdirectories */
227 
228     AsDoWildcard (ConversionTable, SourcePath, TargetPath, MaxPathLength,
229         FILE_TYPE_DIRECTORY, "*");
230 
231     return (0);
232 }
233 
234 
235 /******************************************************************************
236  *
237  * FUNCTION:    AsDetectLoneLineFeeds
238  *
239  * DESCRIPTION: Find LF without CR.
240  *
241  ******************************************************************************/
242 
243 BOOLEAN
AsDetectLoneLineFeeds(char * Filename,char * Buffer)244 AsDetectLoneLineFeeds (
245     char                    *Filename,
246     char                    *Buffer)
247 {
248     UINT32                  i = 1;
249     UINT32                  LfCount = 0;
250     UINT32                  LineCount = 0;
251 
252 
253     if (!Buffer[0])
254     {
255         return (FALSE);
256     }
257 
258     while (Buffer[i])
259     {
260         if (Buffer[i] == 0x0A)
261         {
262             if (Buffer[i-1] != 0x0D)
263             {
264                 LfCount++;
265             }
266 
267             LineCount++;
268         }
269         i++;
270     }
271 
272     if (LfCount)
273     {
274         if (LineCount == LfCount)
275         {
276             if (!Gbl_IgnoreLoneLineFeeds)
277             {
278                 printf ("%s: ****File has UNIX format**** (LF only, not CR/LF) %u lines\n",
279                     Filename, LfCount);
280             }
281         }
282         else
283         {
284             printf ("%s: %u lone linefeeds in file\n", Filename, LfCount);
285         }
286 
287         return (TRUE);
288     }
289 
290     return (FALSE);
291 }
292 
293 
294 /******************************************************************************
295  *
296  * FUNCTION:    AsConvertFile
297  *
298  * DESCRIPTION: Perform the requested transforms on the file buffer (as
299  *              determined by the ConversionTable and the FileType).
300  *
301  ******************************************************************************/
302 
303 void
AsConvertFile(ACPI_CONVERSION_TABLE * ConversionTable,char * FileBuffer,char * Filename,ACPI_NATIVE_INT FileType)304 AsConvertFile (
305     ACPI_CONVERSION_TABLE   *ConversionTable,
306     char                    *FileBuffer,
307     char                    *Filename,
308     ACPI_NATIVE_INT         FileType)
309 {
310     UINT32                  i;
311     UINT32                  Functions;
312     ACPI_STRING_TABLE       *StringTable;
313     ACPI_IDENTIFIER_TABLE   *ConditionalTable;
314     ACPI_IDENTIFIER_TABLE   *LineTable;
315     ACPI_TYPED_IDENTIFIER_TABLE *StructTable;
316     ACPI_IDENTIFIER_TABLE   *SpecialMacroTable;
317     char                    *SpdxHeader=NULL;
318 
319 
320     switch (FileType)
321     {
322     case FILE_TYPE_SOURCE:
323 
324         Functions           = ConversionTable->SourceFunctions;
325         StringTable         = ConversionTable->SourceStringTable;
326         LineTable           = ConversionTable->SourceLineTable;
327         ConditionalTable    = ConversionTable->SourceConditionalTable;
328         StructTable         = ConversionTable->SourceStructTable;
329         SpecialMacroTable   = ConversionTable->SourceSpecialMacroTable;
330         SpdxHeader          = ConversionTable->SourceSpdxHeader;
331         break;
332 
333     case FILE_TYPE_HEADER:
334 
335         Functions           = ConversionTable->HeaderFunctions;
336         StringTable         = ConversionTable->HeaderStringTable;
337         LineTable           = ConversionTable->HeaderLineTable;
338         ConditionalTable    = ConversionTable->HeaderConditionalTable;
339         StructTable         = ConversionTable->HeaderStructTable;
340         SpecialMacroTable   = ConversionTable->HeaderSpecialMacroTable;
341         SpdxHeader          = ConversionTable->HeaderSpdxHeader;
342         break;
343 
344     case FILE_TYPE_PATCH:
345 
346         Functions           = ConversionTable->PatchFunctions;
347         StringTable         = ConversionTable->PatchStringTable;
348         LineTable           = ConversionTable->PatchLineTable;
349         ConditionalTable    = ConversionTable->PatchConditionalTable;
350         StructTable         = ConversionTable->PatchStructTable;
351         SpecialMacroTable   = ConversionTable->PatchSpecialMacroTable;
352         break;
353 
354     default:
355 
356         printf ("Unknown file type, cannot process\n");
357         return;
358     }
359 
360 
361     Gbl_StructDefs = strstr (FileBuffer, "/* acpisrc:StructDefs");
362     Gbl_Files++;
363     VERBOSE_PRINT (("Processing %u bytes\n",
364         (unsigned int) strlen (FileBuffer)));
365 
366     if (Gbl_Cleanup)
367     {
368         AsRemoveExtraLines (FileBuffer, Filename);
369         AsRemoveSpacesAfterPeriod (FileBuffer, Filename);
370     }
371 
372     if (ConversionTable->LowerCaseTable)
373     {
374         for (i = 0; ConversionTable->LowerCaseTable[i].Identifier; i++)
375         {
376             AsLowerCaseString (ConversionTable->LowerCaseTable[i].Identifier,
377                 FileBuffer);
378         }
379     }
380 
381     /* Process all the string replacements */
382 
383     if (StringTable)
384     {
385         for (i = 0; StringTable[i].Target; i++)
386         {
387             AsReplaceString (StringTable[i].Target, StringTable[i].Replacement,
388                 StringTable[i].Type, FileBuffer);
389         }
390     }
391 
392     if (LineTable)
393     {
394         for (i = 0; LineTable[i].Identifier; i++)
395         {
396             AsRemoveLine (FileBuffer, LineTable[i].Identifier);
397         }
398     }
399 
400     if (ConditionalTable)
401     {
402         for (i = 0; ConditionalTable[i].Identifier; i++)
403         {
404             AsRemoveConditionalCompile (FileBuffer, ConditionalTable[i].Identifier);
405         }
406     }
407 
408 #ifdef _OBSOLETE_FUNCTIONS
409     if (MacroTable)
410     {
411         for (i = 0; MacroTable[i].Identifier; i++)
412         {
413             AsRemoveMacro (FileBuffer, MacroTable[i].Identifier);
414         }
415     }
416 #endif
417 
418     if (StructTable)
419     {
420         for (i = 0; StructTable[i].Identifier; i++)
421         {
422             AsInsertPrefix (FileBuffer, StructTable[i].Identifier,
423                 StructTable[i].Type);
424         }
425     }
426 
427     if (SpecialMacroTable)
428     {
429         for (i = 0; SpecialMacroTable[i].Identifier; i++)
430         {
431             AsCleanupSpecialMacro (FileBuffer, SpecialMacroTable[i].Identifier);
432         }
433     }
434 
435     /* Process the function table */
436 
437     for (i = 0; i < 32; i++)
438     {
439         /* Decode the function bitmap */
440 
441         switch (((UINT32) 1 << i) & Functions)
442         {
443         case 0:
444 
445             /* This function not configured */
446             break;
447 
448         case CVT_COUNT_TABS:
449 
450             AsCountTabs (FileBuffer, Filename);
451             break;
452 
453         case CVT_COUNT_NON_ANSI_COMMENTS:
454 
455             AsCountNonAnsiComments (FileBuffer, Filename);
456             break;
457 
458         case CVT_CHECK_BRACES:
459 
460             AsCheckForBraces (FileBuffer, Filename);
461             break;
462 
463         case CVT_TRIM_LINES:
464 
465             AsTrimLines (FileBuffer, Filename);
466             break;
467 
468         case CVT_COUNT_LINES:
469 
470             AsCountSourceLines (FileBuffer, Filename);
471             break;
472 
473         case CVT_BRACES_ON_SAME_LINE:
474 
475             AsBracesOnSameLine (FileBuffer);
476             break;
477 
478         case CVT_MIXED_CASE_TO_UNDERSCORES:
479 
480             AsMixedCaseToUnderscores (FileBuffer, Filename);
481             break;
482 
483         case CVT_LOWER_CASE_IDENTIFIERS:
484 
485             AsLowerCaseIdentifiers (FileBuffer);
486             break;
487 
488         case CVT_REMOVE_DEBUG_MACROS:
489 
490             AsRemoveDebugMacros (FileBuffer);
491             break;
492 
493         case CVT_TRIM_WHITESPACE:
494 
495             AsTrimWhitespace (FileBuffer);
496             break;
497 
498         case CVT_REMOVE_EMPTY_BLOCKS:
499 
500             AsRemoveEmptyBlocks (FileBuffer, Filename);
501             break;
502 
503         case CVT_REDUCE_TYPEDEFS:
504 
505             AsReduceTypedefs (FileBuffer, "typedef union");
506             AsReduceTypedefs (FileBuffer, "typedef struct");
507             break;
508 
509         case CVT_SPACES_TO_TABS4:
510 
511             AsTabify4 (FileBuffer);
512             break;
513 
514         case CVT_SPACES_TO_TABS8:
515 
516             AsTabify8 (FileBuffer);
517             break;
518 
519         case CVT_COUNT_SHORTMULTILINE_COMMENTS:
520 
521 #ifdef ACPI_FUTURE_IMPLEMENTATION
522             AsTrimComments (FileBuffer, Filename);
523 #endif
524             break;
525 
526         default:
527 
528             printf ("Unknown conversion subfunction opcode\n");
529             break;
530         }
531     }
532 
533     if (ConversionTable->NewHeader)
534     {
535         AsReplaceHeader (FileBuffer, ConversionTable->NewHeader);
536     }
537     if (SpdxHeader)
538     {
539         AsDoSpdxHeader (FileBuffer, SpdxHeader);
540     }
541 }
542 
543 /*******************************************************************************
544  *
545  * FUNCTION:    AsCheckForNonPrintableChars
546  *
547  * PARAMETERS:  FileBuffer              - Buffer with contents of entire file
548  *              FileSize                - Size of the file and buffer
549  *
550  * RETURN:      TRUE if there are no non-printable characters
551  *
552  * DESCRIPTION: Scan a file for any non-printable ASCII bytes.
553  *
554  ******************************************************************************/
555 
556 static BOOLEAN
AsCheckForNonPrintableChars(char * FileBuffer,UINT32 FileSize)557 AsCheckForNonPrintableChars (
558     char                    *FileBuffer,
559     UINT32                  FileSize)
560 {
561     BOOLEAN                 Found = TRUE;
562     UINT8                   Byte;
563     UINT32                  i;
564 
565 
566     /* Scan entire file for any non-printable characters */
567 
568     for (i = 0; i < FileSize; i++)
569     {
570         Byte = FileBuffer[i];
571         if (!isprint (Byte) && !isspace (Byte))
572         {
573             printf ( "Non-printable character (0x%2.2X) "
574                 "at file offset: %8u (0x%X)\n", Byte, i, i);
575             Found = FALSE;
576         }
577     }
578 
579     return (Found);
580 }
581 
582 
583 /******************************************************************************
584  *
585  * FUNCTION:    AsProcessOneFile
586  *
587  * DESCRIPTION: Process one source file. The file is opened, read entirely
588  *              into a buffer, converted, then written to a new file.
589  *
590  ******************************************************************************/
591 
592 ACPI_NATIVE_INT
AsProcessOneFile(ACPI_CONVERSION_TABLE * ConversionTable,char * SourcePath,char * TargetPath,int MaxPathLength,char * Filename,ACPI_NATIVE_INT FileType)593 AsProcessOneFile (
594     ACPI_CONVERSION_TABLE   *ConversionTable,
595     char                    *SourcePath,
596     char                    *TargetPath,
597     int                     MaxPathLength,
598     char                    *Filename,
599     ACPI_NATIVE_INT         FileType)
600 {
601     char                    *Pathname;
602     char                    *OutPathname;
603     int                     Status = 0;
604 
605 
606     /* Allocate a file pathname buffer for both source and target */
607 
608     Pathname = calloc (MaxPathLength + strlen (Filename) + 2, 1);
609     if (!Pathname)
610     {
611         printf ("Could not allocate buffer for file pathnames\n");
612         return (-1);
613     }
614 
615     Gbl_FileType = FileType;
616 
617     /* Generate the source pathname and read the file */
618 
619     if (SourcePath)
620     {
621         strcpy (Pathname, SourcePath);
622         strcat (Pathname, "/");
623     }
624 
625     strcat (Pathname, Filename);
626     if (AsGetFile (Pathname, &Gbl_FileBuffer, &Gbl_FileSize))
627     {
628         Status = -1;
629         goto Exit1;
630     }
631 
632     /* Exit now if simply checking the file for printable ascii chars */
633 
634     if (Gbl_CheckAscii)
635     {
636         Status = 0;
637         goto Exit2;
638     }
639 
640     Gbl_HeaderSize = 0;
641     if (strstr (Filename, ".asl"))
642     {
643         Gbl_HeaderSize = LINES_IN_ASL_HEADER; /* Lines in default ASL header */
644     }
645     else if (strstr (Gbl_FileBuffer, LEGAL_HEADER_SIGNATURE))
646     {
647         Gbl_HeaderSize = LINES_IN_LEGAL_HEADER; /* Normal C file and H header */
648     }
649     else if (strstr (Gbl_FileBuffer, LINUX_HEADER_SIGNATURE))
650     {
651         Gbl_HeaderSize = LINES_IN_LINUX_HEADER; /* Linuxized C file and H header */
652     }
653 
654     /* Process the file in the buffer */
655 
656     Gbl_MadeChanges = FALSE;
657     if (!Gbl_IgnoreLoneLineFeeds && Gbl_HasLoneLineFeeds)
658     {
659         /*
660          * All lone LFs will be converted to CR/LF
661          * (when file is written, Windows version only)
662          */
663         printf ("Converting lone linefeeds\n");
664         Gbl_MadeChanges = TRUE;
665     }
666 
667     AsConvertFile (ConversionTable, Gbl_FileBuffer, Pathname, FileType);
668 
669     if (!(ConversionTable->Flags & FLG_NO_FILE_OUTPUT))
670     {
671         if (!(Gbl_Overwrite && !Gbl_MadeChanges))
672         {
673             /* Generate the target pathname and write the file */
674 
675             OutPathname = calloc (MaxPathLength +
676                 strlen (Filename) + 2 + strlen (TargetPath), 1);
677             if (!OutPathname)
678             {
679                 printf ("Could not allocate buffer for file pathnames\n");
680                 Status = -1;
681                 goto Exit2;
682             }
683 
684             strcpy (OutPathname, TargetPath);
685             if (SourcePath)
686             {
687                 strcat (OutPathname, "/");
688                 strcat (OutPathname, Filename);
689             }
690 
691             AsPutFile (OutPathname, Gbl_FileBuffer, ConversionTable->Flags);
692             free (OutPathname);
693         }
694     }
695 
696 Exit2:
697     free (Gbl_FileBuffer);
698 
699 Exit1:
700     free (Pathname);
701     return (Status);
702 }
703 
704 
705 /******************************************************************************
706  *
707  * FUNCTION:    AsCheckForDirectory
708  *
709  * DESCRIPTION: Check if the current file is a valid directory. If not,
710  *              construct the full pathname for the source and target paths.
711  *              Checks for the dot and dot-dot files (they are ignored)
712  *
713  ******************************************************************************/
714 
715 ACPI_NATIVE_INT
AsCheckForDirectory(char * SourceDirPath,char * TargetDirPath,char * Filename,char ** SourcePath,char ** TargetPath)716 AsCheckForDirectory (
717     char                    *SourceDirPath,
718     char                    *TargetDirPath,
719     char                    *Filename,
720     char                    **SourcePath,
721     char                    **TargetPath)
722 {
723     char                    *SrcPath;
724     char                    *TgtPath;
725 
726 
727     if (!(strcmp (Filename, ".")) ||
728         !(strcmp (Filename, "..")))
729     {
730         return (-1);
731     }
732 
733     SrcPath = calloc (strlen (SourceDirPath) + strlen (Filename) + 2, 1);
734     if (!SrcPath)
735     {
736         printf ("Could not allocate buffer for directory source pathname\n");
737         return (-1);
738     }
739 
740     TgtPath = calloc (strlen (TargetDirPath) + strlen (Filename) + 2, 1);
741     if (!TgtPath)
742     {
743         printf ("Could not allocate buffer for directory target pathname\n");
744         free (SrcPath);
745         return (-1);
746     }
747 
748     strcpy (SrcPath, SourceDirPath);
749     strcat (SrcPath, "/");
750     strcat (SrcPath, Filename);
751 
752     strcpy (TgtPath, TargetDirPath);
753     strcat (TgtPath, "/");
754     strcat (TgtPath, Filename);
755 
756     *SourcePath = SrcPath;
757     *TargetPath = TgtPath;
758     return (0);
759 }
760 
761 
762 /******************************************************************************
763  *
764  * FUNCTION:    AsGetFile
765  *
766  * DESCRIPTION: Open a file and read it entirely into a an allocated buffer
767  *
768  ******************************************************************************/
769 
770 int
AsGetFile(char * Filename,char ** FileBuffer,UINT32 * FileSize)771 AsGetFile (
772     char                    *Filename,
773     char                    **FileBuffer,
774     UINT32                  *FileSize)
775 {
776     FILE                    *File;
777     UINT32                  Size;
778     char                    *Buffer;
779     size_t                  Actual;
780 
781 
782     /* Binary mode leaves CR/LF pairs */
783 
784     File = fopen (Filename, "rb");
785     if (!File)
786     {
787         printf ("Could not open file %s\n", Filename);
788         return (-1);
789     }
790 
791     /* Need file size to allocate a buffer */
792 
793     Size = CmGetFileSize (File);
794     if (Size == ACPI_UINT32_MAX)
795     {
796         printf ("Could not get file size for %s\n", Filename);
797         goto ErrorExit;
798     }
799 
800     /*
801      * Create a buffer for the entire file
802      * Add plenty extra buffer to accommodate string replacements
803      */
804     Gbl_TotalSize += Size;
805 
806     Buffer = calloc (Size * 2, 1);
807     if (!Buffer)
808     {
809         printf ("Could not allocate buffer of size %u\n", Size * 2);
810         goto ErrorExit;
811     }
812 
813     /* Read the entire file */
814 
815     Actual = fread (Buffer, 1, Size, File);
816     if (Actual != Size)
817     {
818         printf ("Could not read the input file %s (%u bytes)\n",
819             Filename, Size);
820         goto ErrorFree;
821     }
822 
823     Buffer [Size] = 0;         /* Null terminate the buffer */
824     fclose (File);
825 
826     /* This option checks the entire file for non-printable chars */
827 
828     if (Gbl_CheckAscii)
829     {
830         if (AsCheckForNonPrintableChars (Buffer, Size))
831         {
832             printf ("File contains only printable ASCII characters\n");
833         }
834 
835         free (Buffer);
836         return (0);
837     }
838 
839     /* Check for unix contamination */
840 
841     Gbl_HasLoneLineFeeds = AsDetectLoneLineFeeds (Filename, Buffer);
842 
843     /*
844      * Convert all CR/LF pairs to LF only. We do this locally so that
845      * this code is portable across operating systems.
846      */
847     AsConvertToLineFeeds (Buffer);
848 
849     *FileBuffer = Buffer;
850     *FileSize = Size;
851     return (0);
852 
853 ErrorFree:
854     free (Buffer);
855 
856 ErrorExit:
857     fclose (File);
858     return (-1);
859 }
860 
861 
862 /******************************************************************************
863  *
864  * FUNCTION:    AsPutFile
865  *
866  * DESCRIPTION: Create a new output file and write the entire contents of the
867  *              buffer to the new file. Buffer must be a zero terminated string
868  *
869  ******************************************************************************/
870 
871 int
AsPutFile(char * Pathname,char * FileBuffer,UINT32 SystemFlags)872 AsPutFile (
873     char                    *Pathname,
874     char                    *FileBuffer,
875     UINT32                  SystemFlags)
876 {
877     FILE                    *File;
878     UINT32                  FileSize;
879     size_t                  Actual;
880     int                     Status = 0;
881 
882 
883     /* Create the target file */
884 
885     if (!(SystemFlags & FLG_NO_CARRIAGE_RETURNS))
886     {
887         /* Put back the CR before each LF */
888 
889         AsInsertCarriageReturns (FileBuffer);
890     }
891 
892     File = fopen (Pathname, "w+b");
893     if (!File)
894     {
895         perror ("Could not create destination file");
896         printf ("Could not create destination file \"%s\"\n", Pathname);
897         return (-1);
898     }
899 
900     /* Write the buffer to the file */
901 
902     FileSize = strlen (FileBuffer);
903     Actual = fwrite (FileBuffer, 1, FileSize, File);
904     if (Actual != FileSize)
905     {
906         printf ("Error writing output file \"%s\"\n", Pathname);
907         Status = -1;
908     }
909 
910     fclose (File);
911     return (Status);
912 }
913