Bring in acpica 20110211, still not ok anyway
[dragonfly.git] / sys / contrib / dev / acpica-unix / tools / acpisrc / asfile.c
1
2 /******************************************************************************
3  *
4  * Module Name: asfile - Main module for the acpi source processor utility
5  *
6  *****************************************************************************/
7
8 /******************************************************************************
9  *
10  * 1. Copyright Notice
11  *
12  * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
13  * All rights reserved.
14  *
15  * 2. License
16  *
17  * 2.1. This is your license from Intel Corp. under its intellectual property
18  * rights.  You may have additional license terms from the party that provided
19  * you this software, covering your right to use that party's intellectual
20  * property rights.
21  *
22  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23  * copy of the source code appearing in this file ("Covered Code") an
24  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25  * base code distributed originally by Intel ("Original Intel Code") to copy,
26  * make derivatives, distribute, use and display any portion of the Covered
27  * Code in any form, with the right to sublicense such rights; and
28  *
29  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30  * license (with the right to sublicense), under only those claims of Intel
31  * patents that are infringed by the Original Intel Code, to make, use, sell,
32  * offer to sell, and import the Covered Code and derivative works thereof
33  * solely to the minimum extent necessary to exercise the above copyright
34  * license, and in no event shall the patent license extend to any additions
35  * to or modifications of the Original Intel Code.  No other license or right
36  * is granted directly or by implication, estoppel or otherwise;
37  *
38  * The above copyright and patent license is granted only if the following
39  * conditions are met:
40  *
41  * 3. Conditions
42  *
43  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44  * Redistribution of source code of any substantial portion of the Covered
45  * Code or modification with rights to further distribute source must include
46  * the above Copyright Notice, the above License, this list of Conditions,
47  * and the following Disclaimer and Export Compliance provision.  In addition,
48  * Licensee must cause all Covered Code to which Licensee contributes to
49  * contain a file documenting the changes Licensee made to create that Covered
50  * Code and the date of any change.  Licensee must include in that file the
51  * documentation of any changes made by any predecessor Licensee.  Licensee
52  * must include a prominent statement that the modification is derived,
53  * directly or indirectly, from Original Intel Code.
54  *
55  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56  * Redistribution of source code of any substantial portion of the Covered
57  * Code or modification without rights to further distribute source must
58  * include the following Disclaimer and Export Compliance provision in the
59  * documentation and/or other materials provided with distribution.  In
60  * addition, Licensee may not authorize further sublicense of source of any
61  * portion of the Covered Code, and must include terms to the effect that the
62  * license from Licensee to its licensee is limited to the intellectual
63  * property embodied in the software Licensee provides to its licensee, and
64  * not to intellectual property embodied in modifications its licensee may
65  * make.
66  *
67  * 3.3. Redistribution of Executable. Redistribution in executable form of any
68  * substantial portion of the Covered Code or modification must reproduce the
69  * above Copyright Notice, and the following Disclaimer and Export Compliance
70  * provision in the documentation and/or other materials provided with the
71  * distribution.
72  *
73  * 3.4. Intel retains all right, title, and interest in and to the Original
74  * Intel Code.
75  *
76  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77  * Intel shall be used in advertising or otherwise to promote the sale, use or
78  * other dealings in products derived from or relating to the Covered Code
79  * without prior written authorization from Intel.
80  *
81  * 4. Disclaimer and Export Compliance
82  *
83  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89  * PARTICULAR PURPOSE.
90  *
91  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98  * LIMITED REMEDY.
99  *
100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
101  * software or system incorporating such software without first obtaining any
102  * required license or other approval from the U. S. Department of Commerce or
103  * any other agency or department of the United States Government.  In the
104  * event Licensee exports any such software from the United States or
105  * re-exports any such software from a foreign destination, Licensee shall
106  * ensure that the distribution and export/re-export of the software is in
107  * compliance with all laws, regulations, orders, or other restrictions of the
108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109  * any of its subsidiaries will export/re-export any technical data, process,
110  * software, or service, directly or indirectly, to any country for which the
111  * United States government or any agency thereof requires an export license,
112  * other governmental approval, or letter of assurance, without first obtaining
113  * such license, approval or letter.
114  *
115  *****************************************************************************/
116
117 #include "acpisrc.h"
118
119 /* Local prototypes */
120
121 void
122 AsDoWildcard (
123     ACPI_CONVERSION_TABLE   *ConversionTable,
124     char                    *SourcePath,
125     char                    *TargetPath,
126     int                     MaxPathLength,
127     int                     FileType,
128     char                    *WildcardSpec);
129
130 BOOLEAN
131 AsDetectLoneLineFeeds (
132     char                    *Filename,
133     char                    *Buffer);
134
135 static ACPI_INLINE int
136 AsMaxInt (int a, int b)
137 {
138     return (a > b ? a : b);
139 }
140
141
142 /******************************************************************************
143  *
144  * FUNCTION:    AsDoWildcard
145  *
146  * DESCRIPTION: Process files via wildcards
147  *
148  ******************************************************************************/
149
150 void
151 AsDoWildcard (
152     ACPI_CONVERSION_TABLE   *ConversionTable,
153     char                    *SourcePath,
154     char                    *TargetPath,
155     int                     MaxPathLength,
156     int                     FileType,
157     char                    *WildcardSpec)
158 {
159     void                    *DirInfo;
160     char                    *Filename;
161     char                    *SourceDirPath;
162     char                    *TargetDirPath;
163     char                    RequestedFileType;
164
165
166     if (FileType == FILE_TYPE_DIRECTORY)
167     {
168         RequestedFileType = REQUEST_DIR_ONLY;
169     }
170     else
171     {
172         RequestedFileType = REQUEST_FILE_ONLY;
173     }
174
175     VERBOSE_PRINT (("Checking for %s source files in directory \"%s\"\n",
176             WildcardSpec, SourcePath));
177
178     /* Open the directory for wildcard search */
179
180     DirInfo = AcpiOsOpenDirectory (SourcePath, WildcardSpec, RequestedFileType);
181     if (DirInfo)
182     {
183         /*
184          * Get all of the files that match both the
185          * wildcard and the requested file type
186          */
187         while ((Filename = AcpiOsGetNextFilename (DirInfo)))
188         {
189             /* Looking for directory files, must check file type */
190
191             switch (RequestedFileType)
192             {
193             case REQUEST_DIR_ONLY:
194
195                 /* If we actually have a dir, process the subtree */
196
197                 if (!AsCheckForDirectory (SourcePath, TargetPath, Filename,
198                         &SourceDirPath, &TargetDirPath))
199                 {
200                     VERBOSE_PRINT (("Subdirectory: %s\n", Filename));
201
202                     AsProcessTree (ConversionTable, SourceDirPath, TargetDirPath);
203                     free (SourceDirPath);
204                     free (TargetDirPath);
205                 }
206                 break;
207
208             case REQUEST_FILE_ONLY:
209
210                 /* Otherwise, this is a file, not a directory */
211
212                 VERBOSE_PRINT (("File: %s\n", Filename));
213
214                 AsProcessOneFile (ConversionTable, SourcePath, TargetPath,
215                         MaxPathLength, Filename, FileType);
216                 break;
217
218             default:
219                 break;
220             }
221         }
222
223         /* Cleanup */
224
225         AcpiOsCloseDirectory (DirInfo);
226     }
227 }
228
229
230 /******************************************************************************
231  *
232  * FUNCTION:    AsProcessTree
233  *
234  * DESCRIPTION: Process the directory tree.  Files with the extension ".C" and
235  *              ".H" are processed as the tree is traversed.
236  *
237  ******************************************************************************/
238
239 ACPI_NATIVE_INT
240 AsProcessTree (
241     ACPI_CONVERSION_TABLE   *ConversionTable,
242     char                    *SourcePath,
243     char                    *TargetPath)
244 {
245     int                     MaxPathLength;
246
247
248     MaxPathLength = AsMaxInt (strlen (SourcePath), strlen (TargetPath));
249
250     if (!(ConversionTable->Flags & FLG_NO_FILE_OUTPUT))
251     {
252         if (ConversionTable->Flags & FLG_LOWERCASE_DIRNAMES)
253         {
254             strlwr (TargetPath);
255         }
256
257         VERBOSE_PRINT (("Creating Directory \"%s\"\n", TargetPath));
258         if (mkdir (TargetPath))
259         {
260             if (errno != EEXIST)
261             {
262                 printf ("Could not create target directory\n");
263                 return -1;
264             }
265         }
266     }
267
268     /* Do the C source files */
269
270     AsDoWildcard (ConversionTable, SourcePath, TargetPath, MaxPathLength,
271             FILE_TYPE_SOURCE, "*.c");
272
273     /* Do the C header files */
274
275     AsDoWildcard (ConversionTable, SourcePath, TargetPath, MaxPathLength,
276             FILE_TYPE_HEADER, "*.h");
277
278     /* Do the Lex file(s) */
279
280     AsDoWildcard (ConversionTable, SourcePath, TargetPath, MaxPathLength,
281             FILE_TYPE_SOURCE, "*.l");
282
283     /* Do the yacc file(s) */
284
285     AsDoWildcard (ConversionTable, SourcePath, TargetPath, MaxPathLength,
286             FILE_TYPE_SOURCE, "*.y");
287
288     /* Do any ASL files */
289
290     AsDoWildcard (ConversionTable, SourcePath, TargetPath, MaxPathLength,
291             FILE_TYPE_HEADER, "*.asl");
292
293     /* Do any subdirectories */
294
295     AsDoWildcard (ConversionTable, SourcePath, TargetPath, MaxPathLength,
296             FILE_TYPE_DIRECTORY, "*");
297
298     return 0;
299 }
300
301
302 /******************************************************************************
303  *
304  * FUNCTION:    AsDetectLoneLineFeeds
305  *
306  * DESCRIPTION: Find LF without CR.
307  *
308  ******************************************************************************/
309
310 BOOLEAN
311 AsDetectLoneLineFeeds (
312     char                    *Filename,
313     char                    *Buffer)
314 {
315     UINT32                  i = 1;
316     UINT32                  LfCount = 0;
317     UINT32                  LineCount = 0;
318
319
320     if (!Buffer[0])
321     {
322         return FALSE;
323     }
324
325     while (Buffer[i])
326     {
327         if (Buffer[i] == 0x0A)
328         {
329             if (Buffer[i-1] != 0x0D)
330             {
331                 LfCount++;
332             }
333             LineCount++;
334         }
335         i++;
336     }
337
338     if (LfCount)
339     {
340         if (LineCount == LfCount)
341         {
342             if (!Gbl_IgnoreLoneLineFeeds)
343             {
344                 printf ("%s: ****File has UNIX format**** (LF only, not CR/LF) %u lines\n",
345                     Filename, LfCount);
346             }
347         }
348         else
349         {
350             printf ("%s: %u lone linefeeds in file\n", Filename, LfCount);
351         }
352         return TRUE;
353     }
354
355     return (FALSE);
356 }
357
358
359 /******************************************************************************
360  *
361  * FUNCTION:    AsConvertFile
362  *
363  * DESCRIPTION: Perform the requested transforms on the file buffer (as
364  *              determined by the ConversionTable and the FileType).
365  *
366  ******************************************************************************/
367
368 void
369 AsConvertFile (
370     ACPI_CONVERSION_TABLE   *ConversionTable,
371     char                    *FileBuffer,
372     char                    *Filename,
373     ACPI_NATIVE_INT         FileType)
374 {
375     UINT32                  i;
376     UINT32                  Functions;
377     ACPI_STRING_TABLE       *StringTable;
378     ACPI_IDENTIFIER_TABLE   *ConditionalTable;
379     ACPI_IDENTIFIER_TABLE   *LineTable;
380     ACPI_IDENTIFIER_TABLE   *MacroTable;
381     ACPI_TYPED_IDENTIFIER_TABLE *StructTable;
382
383
384     switch (FileType)
385     {
386     case FILE_TYPE_SOURCE:
387         Functions           = ConversionTable->SourceFunctions;
388         StringTable         = ConversionTable->SourceStringTable;
389         LineTable           = ConversionTable->SourceLineTable;
390         ConditionalTable    = ConversionTable->SourceConditionalTable;
391         MacroTable          = ConversionTable->SourceMacroTable;
392         StructTable         = ConversionTable->SourceStructTable;
393        break;
394
395     case FILE_TYPE_HEADER:
396         Functions           = ConversionTable->HeaderFunctions;
397         StringTable         = ConversionTable->HeaderStringTable;
398         LineTable           = ConversionTable->HeaderLineTable;
399         ConditionalTable    = ConversionTable->HeaderConditionalTable;
400         MacroTable          = ConversionTable->HeaderMacroTable;
401         StructTable         = ConversionTable->HeaderStructTable;
402         break;
403
404     default:
405         printf ("Unknown file type, cannot process\n");
406         return;
407     }
408
409
410     Gbl_StructDefs = strstr (FileBuffer, "/* acpisrc:StructDefs");
411     Gbl_Files++;
412     VERBOSE_PRINT (("Processing %u bytes\n",
413         (unsigned int) strlen (FileBuffer)));
414
415     if (ConversionTable->LowerCaseTable)
416     {
417         for (i = 0; ConversionTable->LowerCaseTable[i].Identifier; i++)
418         {
419             AsLowerCaseString (ConversionTable->LowerCaseTable[i].Identifier,
420                                 FileBuffer);
421         }
422     }
423
424     /* Process all the string replacements */
425
426     if (StringTable)
427     {
428         for (i = 0; StringTable[i].Target; i++)
429         {
430             AsReplaceString (StringTable[i].Target, StringTable[i].Replacement,
431                     StringTable[i].Type, FileBuffer);
432         }
433     }
434
435     if (LineTable)
436     {
437         for (i = 0; LineTable[i].Identifier; i++)
438         {
439             AsRemoveLine (FileBuffer, LineTable[i].Identifier);
440         }
441     }
442
443     if (ConditionalTable)
444     {
445         for (i = 0; ConditionalTable[i].Identifier; i++)
446         {
447             AsRemoveConditionalCompile (FileBuffer, ConditionalTable[i].Identifier);
448         }
449     }
450
451     if (MacroTable)
452     {
453         for (i = 0; MacroTable[i].Identifier; i++)
454         {
455             AsRemoveMacro (FileBuffer, MacroTable[i].Identifier);
456         }
457     }
458
459     if (StructTable)
460     {
461         for (i = 0; StructTable[i].Identifier; i++)
462         {
463             AsInsertPrefix (FileBuffer, StructTable[i].Identifier, StructTable[i].Type);
464         }
465     }
466
467     /* Process the function table */
468
469     for (i = 0; i < 32; i++)
470     {
471         /* Decode the function bitmap */
472
473         switch ((1 << i) & Functions)
474         {
475         case 0:
476             /* This function not configured */
477             break;
478
479
480         case CVT_COUNT_TABS:
481
482             AsCountTabs (FileBuffer, Filename);
483             break;
484
485
486         case CVT_COUNT_NON_ANSI_COMMENTS:
487
488             AsCountNonAnsiComments (FileBuffer, Filename);
489             break;
490
491
492         case CVT_CHECK_BRACES:
493
494             AsCheckForBraces (FileBuffer, Filename);
495             break;
496
497
498         case CVT_TRIM_LINES:
499
500             AsTrimLines (FileBuffer, Filename);
501             break;
502
503
504         case CVT_COUNT_LINES:
505
506             AsCountSourceLines (FileBuffer, Filename);
507             break;
508
509
510         case CVT_BRACES_ON_SAME_LINE:
511
512             AsBracesOnSameLine (FileBuffer);
513             break;
514
515
516         case CVT_MIXED_CASE_TO_UNDERSCORES:
517
518             AsMixedCaseToUnderscores (FileBuffer);
519             break;
520
521
522         case CVT_LOWER_CASE_IDENTIFIERS:
523
524             AsLowerCaseIdentifiers (FileBuffer);
525             break;
526
527
528         case CVT_REMOVE_DEBUG_MACROS:
529
530             AsRemoveDebugMacros (FileBuffer);
531             break;
532
533
534         case CVT_TRIM_WHITESPACE:
535
536             AsTrimWhitespace (FileBuffer);
537             break;
538
539
540         case CVT_REMOVE_EMPTY_BLOCKS:
541
542             AsRemoveEmptyBlocks (FileBuffer, Filename);
543             break;
544
545
546         case CVT_REDUCE_TYPEDEFS:
547
548             AsReduceTypedefs (FileBuffer, "typedef union");
549             AsReduceTypedefs (FileBuffer, "typedef struct");
550             break;
551
552
553         case CVT_SPACES_TO_TABS4:
554
555             AsTabify4 (FileBuffer);
556             break;
557
558
559         case CVT_SPACES_TO_TABS8:
560
561             AsTabify8 (FileBuffer);
562             break;
563
564         case CVT_COUNT_SHORTMULTILINE_COMMENTS:
565
566 #ifdef ACPI_FUTURE_IMPLEMENTATION
567             AsTrimComments (FileBuffer, Filename);
568 #endif
569             break;
570
571         default:
572
573             printf ("Unknown conversion subfunction opcode\n");
574             break;
575         }
576     }
577
578     if (ConversionTable->NewHeader)
579     {
580         AsReplaceHeader (FileBuffer, ConversionTable->NewHeader);
581     }
582 }
583
584
585 /******************************************************************************
586  *
587  * FUNCTION:    AsProcessOneFile
588  *
589  * DESCRIPTION: Process one source file.  The file is opened, read entirely
590  *              into a buffer, converted, then written to a new file.
591  *
592  ******************************************************************************/
593
594 ACPI_NATIVE_INT
595 AsProcessOneFile (
596     ACPI_CONVERSION_TABLE   *ConversionTable,
597     char                    *SourcePath,
598     char                    *TargetPath,
599     int                     MaxPathLength,
600     char                    *Filename,
601     ACPI_NATIVE_INT         FileType)
602 {
603     char                    *Pathname;
604     char                    *OutPathname = NULL;
605
606
607     /* Allocate a file pathname buffer for both source and target */
608
609     Pathname = calloc (MaxPathLength + strlen (Filename) + 2, 1);
610     if (!Pathname)
611     {
612         printf ("Could not allocate buffer for file pathnames\n");
613         return -1;
614     }
615
616     Gbl_FileType = FileType;
617
618     /* Generate the source pathname and read the file */
619
620     if (SourcePath)
621     {
622         strcpy (Pathname, SourcePath);
623         strcat (Pathname, "/");
624     }
625
626     strcat (Pathname, Filename);
627
628     if (AsGetFile (Pathname, &Gbl_FileBuffer, &Gbl_FileSize))
629     {
630         return -1;
631     }
632
633     Gbl_HeaderSize = 0;
634     if (strstr (Filename, ".asl"))
635     {
636         Gbl_HeaderSize = LINES_IN_ASL_HEADER; /* Lines in default ASL header */
637     }
638     else if (strstr (Gbl_FileBuffer, LEGAL_HEADER_SIGNATURE))
639     {
640         Gbl_HeaderSize = LINES_IN_LEGAL_HEADER; /* Normal C file and H header */
641     }
642     else if (strstr (Gbl_FileBuffer, LINUX_HEADER_SIGNATURE))
643     {
644         Gbl_HeaderSize = LINES_IN_LINUX_HEADER; /* Linuxized C file and H header */
645     }
646
647     /* Process the file in the buffer */
648
649     Gbl_MadeChanges = FALSE;
650     if (!Gbl_IgnoreLoneLineFeeds && Gbl_HasLoneLineFeeds)
651     {
652         /*
653          * All lone LFs will be converted to CR/LF
654          * (when file is written, Windows version only)
655          */
656         printf ("Converting lone linefeeds\n");
657         Gbl_MadeChanges = TRUE;
658     }
659
660     AsConvertFile (ConversionTable, Gbl_FileBuffer, Pathname, FileType);
661
662     if (!(ConversionTable->Flags & FLG_NO_FILE_OUTPUT))
663     {
664         if (!(Gbl_Overwrite && !Gbl_MadeChanges))
665         {
666             /* Generate the target pathname and write the file */
667
668             OutPathname = calloc (MaxPathLength + strlen (Filename) + 2 + strlen (TargetPath), 1);
669             if (!OutPathname)
670             {
671                 printf ("Could not allocate buffer for file pathnames\n");
672                 return -1;
673             }
674
675             strcpy (OutPathname, TargetPath);
676             if (SourcePath)
677             {
678                 strcat (OutPathname, "/");
679                 strcat (OutPathname, Filename);
680             }
681
682             AsPutFile (OutPathname, Gbl_FileBuffer, ConversionTable->Flags);
683         }
684     }
685
686     free (Gbl_FileBuffer);
687     free (Pathname);
688     if (OutPathname)
689     {
690         free (OutPathname);
691     }
692
693     return 0;
694 }
695
696
697 /******************************************************************************
698  *
699  * FUNCTION:    AsCheckForDirectory
700  *
701  * DESCRIPTION: Check if the current file is a valid directory.  If not,
702  *              construct the full pathname for the source and target paths.
703  *              Checks for the dot and dot-dot files (they are ignored)
704  *
705  ******************************************************************************/
706
707 ACPI_NATIVE_INT
708 AsCheckForDirectory (
709     char                    *SourceDirPath,
710     char                    *TargetDirPath,
711     char                    *Filename,
712     char                    **SourcePath,
713     char                    **TargetPath)
714 {
715     char                    *SrcPath;
716     char                    *TgtPath;
717
718
719     if (!(strcmp (Filename, ".")) ||
720         !(strcmp (Filename, "..")))
721     {
722         return -1;
723     }
724
725     SrcPath = calloc (strlen (SourceDirPath) + strlen (Filename) + 2, 1);
726     if (!SrcPath)
727     {
728         printf ("Could not allocate buffer for directory source pathname\n");
729         return -1;
730     }
731
732     TgtPath = calloc (strlen (TargetDirPath) + strlen (Filename) + 2, 1);
733     if (!TgtPath)
734     {
735         printf ("Could not allocate buffer for directory target pathname\n");
736         free (SrcPath);
737         return -1;
738     }
739
740     strcpy (SrcPath, SourceDirPath);
741     strcat (SrcPath, "/");
742     strcat (SrcPath, Filename);
743
744     strcpy (TgtPath, TargetDirPath);
745     strcat (TgtPath, "/");
746     strcat (TgtPath, Filename);
747
748     *SourcePath = SrcPath;
749     *TargetPath = TgtPath;
750     return 0;
751 }
752
753
754 /******************************************************************************
755  *
756  * FUNCTION:    AsGetFile
757  *
758  * DESCRIPTION: Open a file and read it entirely into a an allocated buffer
759  *
760  ******************************************************************************/
761
762 int
763 AsGetFile (
764     char                    *Filename,
765     char                    **FileBuffer,
766     UINT32                  *FileSize)
767 {
768
769     int                     FileHandle;
770     UINT32                  Size;
771     char                    *Buffer;
772
773
774     /* Binary mode leaves CR/LF pairs */
775
776     FileHandle = open (Filename, O_BINARY | O_RDONLY);
777     if (!FileHandle)
778     {
779         printf ("Could not open %s\n", Filename);
780         return -1;
781     }
782
783     if (fstat (FileHandle, &Gbl_StatBuf))
784     {
785         printf ("Could not get file status for %s\n", Filename);
786         goto ErrorExit;
787     }
788
789     /*
790      * Create a buffer for the entire file
791      * Add plenty extra buffer to accomodate string replacements
792      */
793     Size = Gbl_StatBuf.st_size;
794     Gbl_TotalSize += Size;
795
796     Buffer = calloc (Size * 2, 1);
797     if (!Buffer)
798     {
799         printf ("Could not allocate buffer of size %u\n", Size * 2);
800         goto ErrorExit;
801     }
802
803     /* Read the entire file */
804
805     Size = read (FileHandle, Buffer, Size);
806     if (Size == -1)
807     {
808         printf ("Could not read the input file %s\n", Filename);
809         goto ErrorExit;
810     }
811
812     Buffer [Size] = 0;         /* Null terminate the buffer */
813     close (FileHandle);
814
815     /* Check for unix contamination */
816
817     Gbl_HasLoneLineFeeds = AsDetectLoneLineFeeds (Filename, Buffer);
818
819     /*
820      * Convert all CR/LF pairs to LF only.  We do this locally so that
821      * this code is portable across operating systems.
822      */
823     AsConvertToLineFeeds (Buffer);
824
825     *FileBuffer = Buffer;
826     *FileSize = Size;
827
828     return 0;
829
830
831 ErrorExit:
832
833     close (FileHandle);
834     return -1;
835 }
836
837
838 /******************************************************************************
839  *
840  * FUNCTION:    AsPutFile
841  *
842  * DESCRIPTION: Create a new output file and write the entire contents of the
843  *              buffer to the new file.  Buffer must be a zero terminated string
844  *
845  ******************************************************************************/
846
847 int
848 AsPutFile (
849     char                    *Pathname,
850     char                    *FileBuffer,
851     UINT32                  SystemFlags)
852 {
853     UINT32                  FileSize;
854     int                     DestHandle;
855     int                     OpenFlags;
856
857
858     /* Create the target file */
859
860     OpenFlags = O_TRUNC | O_CREAT | O_WRONLY | O_BINARY;
861
862     if (!(SystemFlags & FLG_NO_CARRIAGE_RETURNS))
863     {
864         /* Put back the CR before each LF */
865
866         AsInsertCarriageReturns (FileBuffer);
867     }
868
869     DestHandle = open (Pathname, OpenFlags, S_IREAD | S_IWRITE);
870     if (DestHandle == -1)
871     {
872         perror ("Could not create destination file");
873         printf ("Could not create destination file \"%s\"\n", Pathname);
874         return -1;
875     }
876
877     /* Write the buffer to the file */
878
879     FileSize = strlen (FileBuffer);
880     write (DestHandle, FileBuffer, FileSize);
881
882     close (DestHandle);
883
884     return 0;
885 }
886
887