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