1 /* do not edit automatically generated by mc from FIO. */
2 /* FIO.mod provides a simple buffered file input/output library.
4 Copyright (C) 2001-2024 Free Software Foundation, Inc.
5 Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
7 This file is part of GNU Modula-2.
9 GNU Modula-2 is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
14 GNU Modula-2 is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
19 Under Section 7 of GPL version 3, you are granted additional
20 permissions described in the GCC Runtime Library Exception, version
21 3.1, as published by the Free Software Foundation.
23 You should have received a copy of the GNU General Public License and
24 a copy of the GCC Runtime Library Exception along with this program;
25 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
26 <http://www.gnu.org/licenses/>. */
29 # if !defined (PROC_D)
31 typedef void (*PROC_t
) (void);
32 typedef struct { PROC_t proc
; } PROC
;
47 # include "GStorage.h"
50 #if defined(__cplusplus)
60 # include "GStorage.h"
61 # include "GNumberIO.h"
63 # include "GIndexing.h"
66 typedef unsigned int FIO_File
;
73 # define UNIXREADONLY 0
74 # define UNIXWRITEONLY 1
75 # define CreatePermissions 0666
76 # define MaxBufferLength (1024*16)
77 # define MaxErrorString (1024*8)
78 typedef struct FIO_NameInfo_r FIO_NameInfo
;
80 typedef struct FIO_buf_r FIO_buf
;
82 typedef FIO_buf
*FIO_Buffer
;
84 typedef struct FIO_fds_r FIO_fds
;
86 typedef FIO_fds
*FIO_FileDescriptor
;
88 typedef struct FIO__T7_a FIO__T7
;
90 typedef char *FIO_PtrToChar
;
92 typedef enum {FIO_successful
, FIO_outofmemory
, FIO_toomanyfilesopen
, FIO_failed
, FIO_connectionfailure
, FIO_endofline
, FIO_endoffile
} FIO_FileStatus
;
94 typedef enum {FIO_unused
, FIO_openedforread
, FIO_openedforwrite
, FIO_openedforrandom
} FIO_FileUsage
;
96 struct FIO_NameInfo_r
{
104 unsigned int position
;
112 struct FIO__T7_a
{ char array
[MaxBufferLength
+1]; };
116 FIO_FileStatus state
;
123 static Indexing_Index FileInfo
;
124 static FIO_File Error
;
127 IsNoError - returns a TRUE if no error has occured on file, f.
130 extern "C" bool FIO_IsNoError (FIO_File f
);
133 IsActive - returns TRUE if the file, f, is still active.
136 extern "C" bool FIO_IsActive (FIO_File f
);
137 extern "C" bool FIO_Exists (const char *fname_
, unsigned int _fname_high
);
138 extern "C" FIO_File
FIO_OpenToRead (const char *fname_
, unsigned int _fname_high
);
139 extern "C" FIO_File
FIO_OpenToWrite (const char *fname_
, unsigned int _fname_high
);
140 extern "C" FIO_File
FIO_OpenForRandom (const char *fname_
, unsigned int _fname_high
, bool towrite
, bool newfile
);
143 Close - close a file which has been previously opened using:
144 OpenToRead, OpenToWrite, OpenForRandom.
145 It is correct to close a file which has an error status.
148 extern "C" void FIO_Close (FIO_File f
);
151 exists - returns TRUE if a file named, fname exists for reading.
154 extern "C" bool FIO_exists (void * fname
, unsigned int flength
);
157 openToRead - attempts to open a file, fname, for reading and
158 it returns this file.
159 The success of this operation can be checked by
163 extern "C" FIO_File
FIO_openToRead (void * fname
, unsigned int flength
);
166 openToWrite - attempts to open a file, fname, for write and
167 it returns this file.
168 The success of this operation can be checked by
172 extern "C" FIO_File
FIO_openToWrite (void * fname
, unsigned int flength
);
175 openForRandom - attempts to open a file, fname, for random access
176 read or write and it returns this file.
177 The success of this operation can be checked by
179 towrite, determines whether the file should be
180 opened for writing or reading.
183 extern "C" FIO_File
FIO_openForRandom (void * fname
, unsigned int flength
, bool towrite
, bool newfile
);
186 FlushBuffer - flush contents of file, f.
189 extern "C" void FIO_FlushBuffer (FIO_File f
);
192 ReadNBytes - reads nBytes of a file into memory area, dest, returning
193 the number of bytes actually read.
194 This function will consume from the buffer and then
195 perform direct libc reads. It is ideal for large reads.
198 extern "C" unsigned int FIO_ReadNBytes (FIO_File f
, unsigned int nBytes
, void * dest
);
201 ReadAny - reads HIGH(a) bytes into, a. All input
202 is fully buffered, unlike ReadNBytes and thus is more
203 suited to small reads.
206 extern "C" void FIO_ReadAny (FIO_File f
, unsigned char *a
, unsigned int _a_high
);
209 WriteNBytes - writes nBytes from memory area src to a file
210 returning the number of bytes actually written.
211 This function will flush the buffer and then
212 write the nBytes using a direct write from libc.
213 It is ideal for large writes.
216 extern "C" unsigned int FIO_WriteNBytes (FIO_File f
, unsigned int nBytes
, void * src
);
219 WriteAny - writes HIGH(a) bytes onto, file, f. All output
220 is fully buffered, unlike WriteNBytes and thus is more
221 suited to small writes.
224 extern "C" void FIO_WriteAny (FIO_File f
, unsigned char *a
, unsigned int _a_high
);
227 WriteChar - writes a single character to file, f.
230 extern "C" void FIO_WriteChar (FIO_File f
, char ch
);
233 EOF - tests to see whether a file, f, has reached end of file.
236 extern "C" bool FIO_EOF (FIO_File f
);
239 EOLN - tests to see whether a file, f, is upon a newline.
240 It does NOT consume the newline.
243 extern "C" bool FIO_EOLN (FIO_File f
);
246 WasEOLN - tests to see whether a file, f, has just seen a newline.
249 extern "C" bool FIO_WasEOLN (FIO_File f
);
252 ReadChar - returns a character read from file f.
253 Sensible to check with IsNoError or EOF after calling
257 extern "C" char FIO_ReadChar (FIO_File f
);
260 UnReadChar - replaces a character, ch, back into file f.
261 This character must have been read by ReadChar
262 and it does not allow successive calls. It may
263 only be called if the previous read was successful
264 or end of file was seen.
265 If the state was previously endoffile then it
266 is altered to successful.
267 Otherwise it is left alone.
270 extern "C" void FIO_UnReadChar (FIO_File f
, char ch
);
273 WriteLine - writes out a linefeed to file, f.
276 extern "C" void FIO_WriteLine (FIO_File f
);
279 WriteString - writes a string to file, f.
282 extern "C" void FIO_WriteString (FIO_File f
, const char *a_
, unsigned int _a_high
);
285 ReadString - reads a string from file, f, into string, a.
286 It terminates the string if HIGH is reached or
287 if a newline is seen or an error occurs.
290 extern "C" void FIO_ReadString (FIO_File f
, char *a
, unsigned int _a_high
);
293 WriteCardinal - writes a CARDINAL to file, f.
294 It writes the binary image of the cardinal
298 extern "C" void FIO_WriteCardinal (FIO_File f
, unsigned int c
);
301 ReadCardinal - reads a CARDINAL from file, f.
302 It reads a binary image of a CARDINAL
306 extern "C" unsigned int FIO_ReadCardinal (FIO_File f
);
309 GetUnixFileDescriptor - returns the UNIX file descriptor of a file.
312 extern "C" int FIO_GetUnixFileDescriptor (FIO_File f
);
315 SetPositionFromBeginning - sets the position from the beginning of the file.
318 extern "C" void FIO_SetPositionFromBeginning (FIO_File f
, long int pos
);
321 SetPositionFromEnd - sets the position from the end of the file.
324 extern "C" void FIO_SetPositionFromEnd (FIO_File f
, long int pos
);
327 FindPosition - returns the current absolute position in file, f.
330 extern "C" long int FIO_FindPosition (FIO_File f
);
333 GetFileName - assigns, a, with the filename associated with, f.
336 extern "C" void FIO_GetFileName (FIO_File f
, char *a
, unsigned int _a_high
);
339 getFileName - returns the address of the filename associated with, f.
342 extern "C" void * FIO_getFileName (FIO_File f
);
345 getFileNameLength - returns the number of characters associated with filename, f.
348 extern "C" unsigned int FIO_getFileNameLength (FIO_File f
);
351 FlushOutErr - flushes, StdOut, and, StdErr.
352 It is also called when the application calls M2RTS.Terminate.
353 (which is automatically placed in program modules by the GM2
357 extern "C" void FIO_FlushOutErr (void);
360 Max - returns the maximum of two values.
363 static unsigned int Max (unsigned int a
, unsigned int b
);
366 Min - returns the minimum of two values.
369 static unsigned int Min (unsigned int a
, unsigned int b
);
372 GetNextFreeDescriptor - returns the index to the FileInfo array indicating
376 static FIO_File
GetNextFreeDescriptor (void);
379 SetState - sets the field, state, of file, f, to, s.
382 static void SetState (FIO_File f
, FIO_FileStatus s
);
385 InitializeFile - initialize a file descriptor
388 static FIO_File
InitializeFile (FIO_File f
, void * fname
, unsigned int flength
, FIO_FileStatus fstate
, FIO_FileUsage use
, bool towrite
, unsigned int buflength
);
391 ConnectToUnix - connects a FIO file to a UNIX file descriptor.
394 static void ConnectToUnix (FIO_File f
, bool towrite
, bool newfile
);
397 ReadFromBuffer - attempts to read, nBytes, from file, f.
398 It firstly consumes the buffer and then performs
399 direct unbuffered reads. This should only be used
400 when wishing to read large files.
402 The actual number of bytes read is returned.
403 -1 is returned if EOF is reached.
406 static int ReadFromBuffer (FIO_File f
, void * a
, unsigned int nBytes
);
409 BufferedRead - will read, nBytes, through the buffer.
410 Similar to ReadFromBuffer, but this function will always
411 read into the buffer before copying into memory.
413 Useful when performing small reads.
416 static int BufferedRead (FIO_File f
, unsigned int nBytes
, void * a
);
419 HandleEscape - translates
420 and \t into their respective ascii codes.
423 static void HandleEscape (char *dest
, unsigned int _dest_high
, const char *src_
, unsigned int _src_high
, unsigned int *i
, unsigned int *j
, unsigned int HighSrc
, unsigned int HighDest
);
429 static void Cast (unsigned char *a
, unsigned int _a_high
, const unsigned char *b_
, unsigned int _b_high
);
432 StringFormat1 - converts string, src, into, dest, together with encapsulated
433 entity, w. It only formats the first %s or %d with n.
436 static void StringFormat1 (char *dest
, unsigned int _dest_high
, const char *src_
, unsigned int _src_high
, const unsigned char *w_
, unsigned int _w_high
);
439 FormatError - provides a orthoganal counterpart to the procedure below.
442 static void FormatError (const char *a_
, unsigned int _a_high
);
445 FormatError1 - generic error procedure taking standard format string
446 and single parameter.
449 static void FormatError1 (const char *a_
, unsigned int _a_high
, const unsigned char *w_
, unsigned int _w_high
);
452 FormatError2 - generic error procedure taking standard format string
456 static void FormatError2 (const char *a_
, unsigned int _a_high
, const unsigned char *w1_
, unsigned int _w1_high
, const unsigned char *w2_
, unsigned int _w2_high
);
459 CheckAccess - checks to see whether a file f has been
460 opened for read/write.
463 static void CheckAccess (FIO_File f
, FIO_FileUsage use
, bool towrite
);
469 static void SetEndOfLine (FIO_File f
, char ch
);
472 BufferedWrite - will write, nBytes, through the buffer.
473 Similar to WriteNBytes, but this function will always
474 write into the buffer before copying into memory.
476 Useful when performing small writes.
479 static int BufferedWrite (FIO_File f
, unsigned int nBytes
, void * a
);
482 PreInitialize - preinitialize the file descriptor.
485 static void PreInitialize (FIO_File f
, const char *fname_
, unsigned int _fname_high
, FIO_FileStatus state
, FIO_FileUsage use
, bool towrite
, int osfd
, unsigned int bufsize
);
488 Init - initialize the modules, global variables.
491 static void Init (void);
495 Max - returns the maximum of two values.
498 static unsigned int Max (unsigned int a
, unsigned int b
)
508 /* static analysis guarentees a RETURN statement will be used before here. */
509 __builtin_unreachable ();
514 Min - returns the minimum of two values.
517 static unsigned int Min (unsigned int a
, unsigned int b
)
527 /* static analysis guarentees a RETURN statement will be used before here. */
528 __builtin_unreachable ();
533 GetNextFreeDescriptor - returns the index to the FileInfo array indicating
537 static FIO_File
GetNextFreeDescriptor (void)
541 FIO_FileDescriptor fd
;
544 h
= Indexing_HighIndice (FileInfo
);
549 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
558 Indexing_PutIndice (FileInfo
, f
, NULL
); /* create new slot */
559 return f
; /* create new slot */
562 ReturnException ("../../gcc-read-write/gcc/m2/gm2-libs/FIO.def", 25, 1);
563 __builtin_unreachable ();
568 SetState - sets the field, state, of file, f, to, s.
571 static void SetState (FIO_File f
, FIO_FileStatus s
)
573 FIO_FileDescriptor fd
;
575 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
581 InitializeFile - initialize a file descriptor
584 static FIO_File
InitializeFile (FIO_File f
, void * fname
, unsigned int flength
, FIO_FileStatus fstate
, FIO_FileUsage use
, bool towrite
, unsigned int buflength
)
587 FIO_FileDescriptor fd
;
589 Storage_ALLOCATE ((void **) &fd
, sizeof (FIO_fds
));
592 SetState (Error
, FIO_outofmemory
);
597 Indexing_PutIndice (FileInfo
, f
, reinterpret_cast<void *> (fd
));
598 fd
->name
.size
= flength
+1; /* need to guarantee the nul for C */
599 fd
->usage
= use
; /* need to guarantee the nul for C */
600 fd
->output
= towrite
;
601 Storage_ALLOCATE (&fd
->name
.address
, fd
->name
.size
);
602 if (fd
->name
.address
== NULL
)
604 fd
->state
= FIO_outofmemory
;
607 fd
->name
.address
= libc_strncpy (fd
->name
.address
, fname
, flength
);
608 /* and assign nul to the last byte */
609 p
= static_cast<FIO_PtrToChar
> (fd
->name
.address
);
613 /* now for the buffer */
614 Storage_ALLOCATE ((void **) &fd
->buffer
, sizeof (FIO_buf
));
615 if (fd
->buffer
== NULL
)
617 SetState (Error
, FIO_outofmemory
);
622 fd
->buffer
->valid
= false;
623 fd
->buffer
->bufstart
= 0;
624 fd
->buffer
->size
= buflength
;
625 fd
->buffer
->position
= 0;
626 fd
->buffer
->filled
= 0;
627 if (fd
->buffer
->size
== 0)
629 fd
->buffer
->address
= NULL
;
633 Storage_ALLOCATE (&fd
->buffer
->address
, fd
->buffer
->size
);
634 if (fd
->buffer
->address
== NULL
)
636 fd
->state
= FIO_outofmemory
;
642 fd
->buffer
->left
= fd
->buffer
->size
;
646 fd
->buffer
->left
= 0;
648 fd
->buffer
->contents
= reinterpret_cast<FIO__T7
*> (fd
->buffer
->address
); /* provides easy access for reading characters */
649 fd
->state
= fstate
; /* provides easy access for reading characters */
653 /* static analysis guarentees a RETURN statement will be used before here. */
654 __builtin_unreachable ();
659 ConnectToUnix - connects a FIO file to a UNIX file descriptor.
662 static void ConnectToUnix (FIO_File f
, bool towrite
, bool newfile
)
664 FIO_FileDescriptor fd
;
668 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
675 fd
->unixfd
= libc_creat (fd
->name
.address
, CreatePermissions
);
679 fd
->unixfd
= libc_open (fd
->name
.address
, UNIXWRITEONLY
, 0);
684 fd
->unixfd
= libc_open (fd
->name
.address
, UNIXREADONLY
, 0);
688 fd
->state
= FIO_connectionfailure
;
696 ReadFromBuffer - attempts to read, nBytes, from file, f.
697 It firstly consumes the buffer and then performs
698 direct unbuffered reads. This should only be used
699 when wishing to read large files.
701 The actual number of bytes read is returned.
702 -1 is returned if EOF is reached.
705 static int ReadFromBuffer (FIO_File f
, void * a
, unsigned int nBytes
)
707 typedef unsigned char *ReadFromBuffer__T1
;
713 ReadFromBuffer__T1 p
;
714 FIO_FileDescriptor fd
;
718 total
= 0; /* how many bytes have we read */
719 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
)); /* how many bytes have we read */
720 /* extract from the buffer first */
721 if ((fd
->buffer
!= NULL
) && fd
->buffer
->valid
)
723 if (fd
->buffer
->left
> 0)
725 /* avoid gcc warning by using compound statement even if not strictly necessary. */
728 /* too expensive to call memcpy for 1 character */
729 p
= static_cast<ReadFromBuffer__T1
> (a
);
730 (*p
) = static_cast<unsigned char> ((*fd
->buffer
->contents
).array
[fd
->buffer
->position
]);
731 fd
->buffer
->left
-= 1; /* remove consumed bytes */
732 fd
->buffer
->position
+= 1; /* move onwards n bytes */
733 nBytes
= 0; /* reduce the amount for future direct */
739 n
= Min (fd
->buffer
->left
, nBytes
);
740 t
= fd
->buffer
->address
;
741 t
= reinterpret_cast<void *> (reinterpret_cast<char *> (t
)+fd
->buffer
->position
);
742 p
= static_cast<ReadFromBuffer__T1
> (libc_memcpy (a
, t
, static_cast<size_t> (n
)));
743 fd
->buffer
->left
-= n
; /* remove consumed bytes */
744 fd
->buffer
->position
+= n
; /* move onwards n bytes */
745 /* move onwards ready for direct reads */
746 a
= reinterpret_cast<void *> (reinterpret_cast<char *> (a
)+n
);
747 nBytes
-= n
; /* reduce the amount for future direct */
750 return total
; /* much cleaner to return now, */
752 /* difficult to record an error if */
754 /* the read below returns -1 */
758 /* still more to read */
759 result
= static_cast<int> (libc_read (fd
->unixfd
, a
, static_cast<size_t> ((int ) (nBytes
))));
762 /* avoid dangling else. */
764 fd
->abspos
+= result
;
765 /* now disable the buffer as we read directly into, a. */
766 if (fd
->buffer
!= NULL
)
768 fd
->buffer
->valid
= false;
776 fd
->state
= FIO_endoffile
;
780 fd
->state
= FIO_failed
;
782 /* indicate buffer is empty */
783 if (fd
->buffer
!= NULL
)
785 fd
->buffer
->valid
= false;
786 fd
->buffer
->left
= 0;
787 fd
->buffer
->position
= 0;
788 if (fd
->buffer
->address
!= NULL
)
790 (*fd
->buffer
->contents
).array
[fd
->buffer
->position
] = ASCII_nul
;
802 /* static analysis guarentees a RETURN statement will be used before here. */
803 __builtin_unreachable ();
808 BufferedRead - will read, nBytes, through the buffer.
809 Similar to ReadFromBuffer, but this function will always
810 read into the buffer before copying into memory.
812 Useful when performing small reads.
815 static int BufferedRead (FIO_File f
, unsigned int nBytes
, void * a
)
817 typedef unsigned char *BufferedRead__T3
;
823 FIO_FileDescriptor fd
;
827 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
828 total
= 0; /* how many bytes have we read */
829 if (fd
!= NULL
) /* how many bytes have we read */
831 /* extract from the buffer first */
832 if (fd
->buffer
!= NULL
)
836 if ((fd
->buffer
->left
> 0) && fd
->buffer
->valid
)
840 /* too expensive to call memcpy for 1 character */
841 p
= static_cast<BufferedRead__T3
> (a
);
842 (*p
) = static_cast<unsigned char> ((*fd
->buffer
->contents
).array
[fd
->buffer
->position
]);
843 fd
->buffer
->left
-= 1; /* remove consumed byte */
844 fd
->buffer
->position
+= 1; /* move onwards n byte */
845 total
+= 1; /* move onwards n byte */
850 n
= Min (fd
->buffer
->left
, nBytes
);
851 t
= fd
->buffer
->address
;
852 t
= reinterpret_cast<void *> (reinterpret_cast<char *> (t
)+fd
->buffer
->position
);
853 p
= static_cast<BufferedRead__T3
> (libc_memcpy (a
, t
, static_cast<size_t> (n
)));
854 fd
->buffer
->left
-= n
; /* remove consumed bytes */
855 fd
->buffer
->position
+= n
; /* move onwards n bytes */
856 /* move onwards ready for direct reads */
857 a
= reinterpret_cast<void *> (reinterpret_cast<char *> (a
)+n
);
858 nBytes
-= n
; /* reduce the amount for future direct */
866 n
= static_cast<int> (libc_read (fd
->unixfd
, fd
->buffer
->address
, static_cast<size_t> (fd
->buffer
->size
)));
869 /* avoid dangling else. */
870 fd
->buffer
->valid
= true;
871 fd
->buffer
->position
= 0;
872 fd
->buffer
->left
= n
;
873 fd
->buffer
->filled
= n
;
874 fd
->buffer
->bufstart
= fd
->abspos
;
879 fd
->state
= FIO_endoffile
;
885 fd
->buffer
->valid
= false;
886 fd
->buffer
->position
= 0;
887 fd
->buffer
->left
= 0;
888 fd
->buffer
->filled
= 0;
889 fd
->state
= FIO_failed
;
899 /* static analysis guarentees a RETURN statement will be used before here. */
900 __builtin_unreachable ();
905 HandleEscape - translates
906 and \t into their respective ascii codes.
909 static void HandleEscape (char *dest
, unsigned int _dest_high
, const char *src_
, unsigned int _src_high
, unsigned int *i
, unsigned int *j
, unsigned int HighSrc
, unsigned int HighDest
)
911 char src
[_src_high
+1];
913 /* make a local copy of each unbounded array. */
914 memcpy (src
, src_
, _src_high
+1);
916 if (((((*i
)+1) < HighSrc
) && (src
[(*i
)] == '\\')) && ((*j
) < HighDest
))
918 /* avoid gcc warning by using compound statement even if not strictly necessary. */
919 if (src
[(*i
)+1] == 'n')
921 /* requires a newline */
922 dest
[(*j
)] = ASCII_nl
;
926 else if (src
[(*i
)+1] == 't')
928 /* avoid dangling else. */
929 /* requires a tab (yuck) tempted to fake this but I better not.. */
930 dest
[(*j
)] = ASCII_tab
;
936 /* avoid dangling else. */
937 /* copy escaped character */
939 dest
[(*j
)] = src
[(*i
)];
951 static void Cast (unsigned char *a
, unsigned int _a_high
, const unsigned char *b_
, unsigned int _b_high
)
954 unsigned char b
[_b_high
+1];
956 /* make a local copy of each unbounded array. */
957 memcpy (b
, b_
, _b_high
+1);
959 if (_a_high
== _b_high
)
961 for (i
=0; i
<=_a_high
; i
++)
968 FormatError ((const char *) "cast failed", 11);
974 StringFormat1 - converts string, src, into, dest, together with encapsulated
975 entity, w. It only formats the first %s or %d with n.
978 static void StringFormat1 (char *dest
, unsigned int _dest_high
, const char *src_
, unsigned int _src_high
, const unsigned char *w_
, unsigned int _w_high
)
980 typedef struct StringFormat1__T8_a StringFormat1__T8
;
982 typedef char *StringFormat1__T4
;
984 struct StringFormat1__T8_a
{ char array
[MaxErrorString
+1]; };
985 unsigned int HighSrc
;
986 unsigned int HighDest
;
990 StringFormat1__T8 str
;
992 char src
[_src_high
+1];
993 unsigned char w
[_w_high
+1];
995 /* make a local copy of each unbounded array. */
996 memcpy (src
, src_
, _src_high
+1);
997 memcpy (w
, w_
, _w_high
+1);
999 HighSrc
= StrLib_StrLen ((const char *) src
, _src_high
);
1000 HighDest
= _dest_high
;
1005 while ((((i
< HighSrc
) && (src
[i
] != ASCII_nul
)) && (j
< HighDest
)) && (src
[i
] != '%'))
1009 HandleEscape ((char *) dest
, _dest_high
, (const char *) src
, _src_high
, &i
, &j
, HighSrc
, HighDest
);
1018 if ((((i
+1) < HighSrc
) && (src
[i
] == '%')) && (j
< HighDest
))
1020 /* avoid gcc warning by using compound statement even if not strictly necessary. */
1021 if (src
[i
+1] == 's')
1023 Cast ((unsigned char *) &p
, (sizeof (p
)-1), (const unsigned char *) w
, _w_high
);
1024 while ((j
< HighDest
) && ((*p
) != ASCII_nul
))
1032 dest
[j
] = ASCII_nul
;
1034 j
= StrLib_StrLen ((const char *) dest
, _dest_high
);
1037 else if (src
[i
+1] == 'd')
1039 /* avoid dangling else. */
1040 dest
[j
] = ASCII_nul
;
1041 Cast ((unsigned char *) &c
, (sizeof (c
)-1), (const unsigned char *) w
, _w_high
);
1042 NumberIO_CardToStr (c
, 0, (char *) &str
.array
[0], MaxErrorString
);
1043 StrLib_StrConCat ((const char *) dest
, _dest_high
, (const char *) &str
.array
[0], MaxErrorString
, (char *) dest
, _dest_high
);
1044 j
= StrLib_StrLen ((const char *) dest
, _dest_high
);
1049 /* avoid dangling else. */
1055 /* and finish off copying src into dest */
1056 while (((i
< HighSrc
) && (src
[i
] != ASCII_nul
)) && (j
< HighDest
))
1060 HandleEscape ((char *) dest
, _dest_high
, (const char *) src
, _src_high
, &i
, &j
, HighSrc
, HighDest
);
1071 dest
[j
] = ASCII_nul
;
1077 FormatError - provides a orthoganal counterpart to the procedure below.
1080 static void FormatError (const char *a_
, unsigned int _a_high
)
1084 /* make a local copy of each unbounded array. */
1085 memcpy (a
, a_
, _a_high
+1);
1087 FIO_WriteString (FIO_StdErr
, (const char *) a
, _a_high
);
1092 FormatError1 - generic error procedure taking standard format string
1093 and single parameter.
1096 static void FormatError1 (const char *a_
, unsigned int _a_high
, const unsigned char *w_
, unsigned int _w_high
)
1098 typedef struct FormatError1__T9_a FormatError1__T9
;
1100 struct FormatError1__T9_a
{ char array
[MaxErrorString
+1]; };
1103 unsigned char w
[_w_high
+1];
1105 /* make a local copy of each unbounded array. */
1106 memcpy (a
, a_
, _a_high
+1);
1107 memcpy (w
, w_
, _w_high
+1);
1109 StringFormat1 ((char *) &s
.array
[0], MaxErrorString
, (const char *) a
, _a_high
, (const unsigned char *) w
, _w_high
);
1110 FormatError ((const char *) &s
.array
[0], MaxErrorString
);
1115 FormatError2 - generic error procedure taking standard format string
1119 static void FormatError2 (const char *a_
, unsigned int _a_high
, const unsigned char *w1_
, unsigned int _w1_high
, const unsigned char *w2_
, unsigned int _w2_high
)
1121 typedef struct FormatError2__T10_a FormatError2__T10
;
1123 struct FormatError2__T10_a
{ char array
[MaxErrorString
+1]; };
1124 FormatError2__T10 s
;
1126 unsigned char w1
[_w1_high
+1];
1127 unsigned char w2
[_w2_high
+1];
1129 /* make a local copy of each unbounded array. */
1130 memcpy (a
, a_
, _a_high
+1);
1131 memcpy (w1
, w1_
, _w1_high
+1);
1132 memcpy (w2
, w2_
, _w2_high
+1);
1134 StringFormat1 ((char *) &s
.array
[0], MaxErrorString
, (const char *) a
, _a_high
, (const unsigned char *) w1
, _w1_high
);
1135 FormatError1 ((const char *) &s
.array
[0], MaxErrorString
, (const unsigned char *) w2
, _w2_high
);
1140 CheckAccess - checks to see whether a file f has been
1141 opened for read/write.
1144 static void CheckAccess (FIO_File f
, FIO_FileUsage use
, bool towrite
)
1146 FIO_FileDescriptor fd
;
1150 /* avoid dangling else. */
1151 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1154 if (f
!= FIO_StdErr
)
1156 FormatError ((const char *) "this file has probably been closed and not reopened successfully or alternatively never opened\\n", 96);
1159 __builtin_unreachable ();
1163 if ((use
== FIO_openedforwrite
) && (fd
->usage
== FIO_openedforread
))
1165 FormatError1 ((const char *) "this file (%s) has been opened for reading but is now being written\\n", 69, (const unsigned char *) &fd
->name
.address
, (sizeof (fd
->name
.address
)-1));
1167 __builtin_unreachable ();
1169 else if ((use
== FIO_openedforread
) && (fd
->usage
== FIO_openedforwrite
))
1171 /* avoid dangling else. */
1172 FormatError1 ((const char *) "this file (%s) has been opened for writing but is now being read\\n", 66, (const unsigned char *) &fd
->name
.address
, (sizeof (fd
->name
.address
)-1));
1174 __builtin_unreachable ();
1176 else if (fd
->state
== FIO_connectionfailure
)
1178 /* avoid dangling else. */
1179 FormatError1 ((const char *) "this file (%s) was not successfully opened\\n", 44, (const unsigned char *) &fd
->name
.address
, (sizeof (fd
->name
.address
)-1));
1181 __builtin_unreachable ();
1183 else if (towrite
!= fd
->output
)
1185 /* avoid dangling else. */
1188 FormatError1 ((const char *) "this file (%s) was opened for writing but is now being read\\n", 61, (const unsigned char *) &fd
->name
.address
, (sizeof (fd
->name
.address
)-1));
1190 __builtin_unreachable ();
1194 FormatError1 ((const char *) "this file (%s) was opened for reading but is now being written\\n", 64, (const unsigned char *) &fd
->name
.address
, (sizeof (fd
->name
.address
)-1));
1196 __builtin_unreachable ();
1203 FormatError ((const char *) "this file has not been opened successfully\\n", 44);
1205 __builtin_unreachable ();
1214 static void SetEndOfLine (FIO_File f
, char ch
)
1216 FIO_FileDescriptor fd
;
1218 CheckAccess (f
, FIO_openedforread
, false);
1221 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1224 fd
->state
= FIO_endofline
;
1228 fd
->state
= FIO_successful
;
1235 BufferedWrite - will write, nBytes, through the buffer.
1236 Similar to WriteNBytes, but this function will always
1237 write into the buffer before copying into memory.
1239 Useful when performing small writes.
1242 static int BufferedWrite (FIO_File f
, unsigned int nBytes
, void * a
)
1244 typedef unsigned char *BufferedWrite__T5
;
1249 BufferedWrite__T5 p
;
1250 FIO_FileDescriptor fd
;
1254 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1257 total
= 0; /* how many bytes have we read */
1258 if (fd
->buffer
!= NULL
) /* how many bytes have we read */
1260 /* place into the buffer first */
1263 if (fd
->buffer
->left
> 0)
1267 /* too expensive to call memcpy for 1 character */
1268 p
= static_cast<BufferedWrite__T5
> (a
);
1269 (*fd
->buffer
->contents
).array
[fd
->buffer
->position
] = static_cast<char> ((*p
));
1270 fd
->buffer
->left
-= 1; /* reduce space */
1271 fd
->buffer
->position
+= 1; /* move onwards n byte */
1272 total
+= 1; /* move onwards n byte */
1277 n
= Min (fd
->buffer
->left
, nBytes
);
1278 t
= fd
->buffer
->address
;
1279 t
= reinterpret_cast<void *> (reinterpret_cast<char *> (t
)+fd
->buffer
->position
);
1280 p
= static_cast<BufferedWrite__T5
> (libc_memcpy (a
, t
, static_cast<size_t> ((unsigned int ) (n
))));
1281 fd
->buffer
->left
-= n
; /* remove consumed bytes */
1282 fd
->buffer
->position
+= n
; /* move onwards n bytes */
1283 /* move ready for further writes */
1284 a
= reinterpret_cast<void *> (reinterpret_cast<char *> (a
)+n
);
1285 nBytes
-= n
; /* reduce the amount for future writes */
1286 total
+= n
; /* reduce the amount for future writes */
1291 FIO_FlushBuffer (f
);
1292 if ((fd
->state
!= FIO_successful
) && (fd
->state
!= FIO_endofline
))
1303 /* static analysis guarentees a RETURN statement will be used before here. */
1304 __builtin_unreachable ();
1309 PreInitialize - preinitialize the file descriptor.
1312 static void PreInitialize (FIO_File f
, const char *fname_
, unsigned int _fname_high
, FIO_FileStatus state
, FIO_FileUsage use
, bool towrite
, int osfd
, unsigned int bufsize
)
1314 FIO_FileDescriptor fd
;
1315 FIO_FileDescriptor fe
;
1316 char fname
[_fname_high
+1];
1318 /* make a local copy of each unbounded array. */
1319 memcpy (fname
, fname_
, _fname_high
+1);
1321 if ((InitializeFile (f
, &fname
, StrLib_StrLen ((const char *) fname
, _fname_high
), state
, use
, towrite
, bufsize
)) == f
)
1323 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1326 fe
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, FIO_StdErr
));
1330 __builtin_unreachable ();
1334 fd
->unixfd
= fe
->unixfd
; /* the error channel */
1345 __builtin_unreachable ();
1351 Init - initialize the modules, global variables.
1354 static void Init (void)
1356 FileInfo
= Indexing_InitIndex (0);
1358 PreInitialize (Error
, (const char *) "error", 5, FIO_toomanyfilesopen
, FIO_unused
, false, -1, 0);
1360 PreInitialize (FIO_StdIn
, (const char *) "<stdin>", 7, FIO_successful
, FIO_openedforread
, false, 0, MaxBufferLength
);
1362 PreInitialize (FIO_StdOut
, (const char *) "<stdout>", 8, FIO_successful
, FIO_openedforwrite
, true, 1, MaxBufferLength
);
1364 PreInitialize (FIO_StdErr
, (const char *) "<stderr>", 8, FIO_successful
, FIO_openedforwrite
, true, 2, MaxBufferLength
);
1365 if (! (M2RTS_InstallTerminationProcedure ((PROC
) {(PROC_t
) FIO_FlushOutErr
})))
1368 __builtin_unreachable ();
1374 IsNoError - returns a TRUE if no error has occured on file, f.
1377 extern "C" bool FIO_IsNoError (FIO_File f
)
1379 FIO_FileDescriptor fd
;
1387 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1388 return (fd
!= NULL
) && (((fd
->state
== FIO_successful
) || (fd
->state
== FIO_endoffile
)) || (fd
->state
== FIO_endofline
));
1390 /* static analysis guarentees a RETURN statement will be used before here. */
1391 __builtin_unreachable ();
1396 IsActive - returns TRUE if the file, f, is still active.
1399 extern "C" bool FIO_IsActive (FIO_File f
)
1407 return (Indexing_GetIndice (FileInfo
, f
)) != NULL
;
1409 /* static analysis guarentees a RETURN statement will be used before here. */
1410 __builtin_unreachable ();
1413 extern "C" bool FIO_Exists (const char *fname_
, unsigned int _fname_high
)
1415 char fname
[_fname_high
+1];
1417 /* make a local copy of each unbounded array. */
1418 memcpy (fname
, fname_
, _fname_high
+1);
1421 The following functions are wrappers for the above.
1423 return FIO_exists (&fname
, StrLib_StrLen ((const char *) fname
, _fname_high
));
1424 /* static analysis guarentees a RETURN statement will be used before here. */
1425 __builtin_unreachable ();
1428 extern "C" FIO_File
FIO_OpenToRead (const char *fname_
, unsigned int _fname_high
)
1430 char fname
[_fname_high
+1];
1432 /* make a local copy of each unbounded array. */
1433 memcpy (fname
, fname_
, _fname_high
+1);
1435 return FIO_openToRead (&fname
, StrLib_StrLen ((const char *) fname
, _fname_high
));
1436 /* static analysis guarentees a RETURN statement will be used before here. */
1437 __builtin_unreachable ();
1440 extern "C" FIO_File
FIO_OpenToWrite (const char *fname_
, unsigned int _fname_high
)
1442 char fname
[_fname_high
+1];
1444 /* make a local copy of each unbounded array. */
1445 memcpy (fname
, fname_
, _fname_high
+1);
1447 return FIO_openToWrite (&fname
, StrLib_StrLen ((const char *) fname
, _fname_high
));
1448 /* static analysis guarentees a RETURN statement will be used before here. */
1449 __builtin_unreachable ();
1452 extern "C" FIO_File
FIO_OpenForRandom (const char *fname_
, unsigned int _fname_high
, bool towrite
, bool newfile
)
1454 char fname
[_fname_high
+1];
1456 /* make a local copy of each unbounded array. */
1457 memcpy (fname
, fname_
, _fname_high
+1);
1459 return FIO_openForRandom (&fname
, StrLib_StrLen ((const char *) fname
, _fname_high
), towrite
, newfile
);
1460 /* static analysis guarentees a RETURN statement will be used before here. */
1461 __builtin_unreachable ();
1466 Close - close a file which has been previously opened using:
1467 OpenToRead, OpenToWrite, OpenForRandom.
1468 It is correct to close a file which has an error status.
1471 extern "C" void FIO_Close (FIO_File f
)
1473 FIO_FileDescriptor fd
;
1477 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1479 we allow users to close files which have an error status
1483 FIO_FlushBuffer (f
);
1484 if (fd
->unixfd
>= 0)
1486 if ((libc_close (fd
->unixfd
)) != 0)
1488 FormatError1 ((const char *) "failed to close file (%s)\\n", 27, (const unsigned char *) &fd
->name
.address
, (sizeof (fd
->name
.address
)-1));
1489 fd
->state
= FIO_failed
; /* --fixme-- too late to notify user (unless we return a BOOLEAN) */
1492 if (fd
->name
.address
!= NULL
)
1494 Storage_DEALLOCATE (&fd
->name
.address
, fd
->name
.size
);
1496 if (fd
->buffer
!= NULL
)
1498 if (fd
->buffer
->address
!= NULL
)
1500 Storage_DEALLOCATE (&fd
->buffer
->address
, fd
->buffer
->size
);
1502 Storage_DEALLOCATE ((void **) &fd
->buffer
, sizeof (FIO_buf
));
1505 Storage_DEALLOCATE ((void **) &fd
, sizeof (FIO_fds
));
1506 Indexing_PutIndice (FileInfo
, f
, NULL
);
1513 exists - returns TRUE if a file named, fname exists for reading.
1516 extern "C" bool FIO_exists (void * fname
, unsigned int flength
)
1520 f
= FIO_openToRead (fname
, flength
);
1521 if (FIO_IsNoError (f
))
1531 /* static analysis guarentees a RETURN statement will be used before here. */
1532 __builtin_unreachable ();
1537 openToRead - attempts to open a file, fname, for reading and
1538 it returns this file.
1539 The success of this operation can be checked by
1543 extern "C" FIO_File
FIO_openToRead (void * fname
, unsigned int flength
)
1547 f
= GetNextFreeDescriptor ();
1550 SetState (f
, FIO_toomanyfilesopen
);
1554 f
= InitializeFile (f
, fname
, flength
, FIO_successful
, FIO_openedforread
, false, MaxBufferLength
);
1555 ConnectToUnix (f
, false, false);
1558 /* static analysis guarentees a RETURN statement will be used before here. */
1559 __builtin_unreachable ();
1564 openToWrite - attempts to open a file, fname, for write and
1565 it returns this file.
1566 The success of this operation can be checked by
1570 extern "C" FIO_File
FIO_openToWrite (void * fname
, unsigned int flength
)
1574 f
= GetNextFreeDescriptor ();
1577 SetState (f
, FIO_toomanyfilesopen
);
1581 f
= InitializeFile (f
, fname
, flength
, FIO_successful
, FIO_openedforwrite
, true, MaxBufferLength
);
1582 ConnectToUnix (f
, true, true);
1585 /* static analysis guarentees a RETURN statement will be used before here. */
1586 __builtin_unreachable ();
1591 openForRandom - attempts to open a file, fname, for random access
1592 read or write and it returns this file.
1593 The success of this operation can be checked by
1595 towrite, determines whether the file should be
1596 opened for writing or reading.
1599 extern "C" FIO_File
FIO_openForRandom (void * fname
, unsigned int flength
, bool towrite
, bool newfile
)
1603 f
= GetNextFreeDescriptor ();
1606 SetState (f
, FIO_toomanyfilesopen
);
1610 f
= InitializeFile (f
, fname
, flength
, FIO_successful
, FIO_openedforrandom
, towrite
, MaxBufferLength
);
1611 ConnectToUnix (f
, towrite
, newfile
);
1614 /* static analysis guarentees a RETURN statement will be used before here. */
1615 __builtin_unreachable ();
1620 FlushBuffer - flush contents of file, f.
1623 extern "C" void FIO_FlushBuffer (FIO_File f
)
1625 FIO_FileDescriptor fd
;
1629 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1632 if (fd
->output
&& (fd
->buffer
!= NULL
))
1634 if ((fd
->buffer
->position
== 0) || ((libc_write (fd
->unixfd
, fd
->buffer
->address
, static_cast<size_t> (fd
->buffer
->position
))) == ((int ) (fd
->buffer
->position
))))
1636 fd
->abspos
+= fd
->buffer
->position
;
1637 fd
->buffer
->bufstart
= fd
->abspos
;
1638 fd
->buffer
->position
= 0;
1639 fd
->buffer
->filled
= 0;
1640 fd
->buffer
->left
= fd
->buffer
->size
;
1644 fd
->state
= FIO_failed
;
1653 ReadNBytes - reads nBytes of a file into memory area, dest, returning
1654 the number of bytes actually read.
1655 This function will consume from the buffer and then
1656 perform direct libc reads. It is ideal for large reads.
1659 extern "C" unsigned int FIO_ReadNBytes (FIO_File f
, unsigned int nBytes
, void * dest
)
1661 typedef char *ReadNBytes__T2
;
1668 CheckAccess (f
, FIO_openedforread
, false);
1669 n
= ReadFromBuffer (f
, dest
, nBytes
);
1676 p
= static_cast<ReadNBytes__T2
> (dest
);
1678 SetEndOfLine (f
, (*p
));
1686 /* static analysis guarentees a RETURN statement will be used before here. */
1687 __builtin_unreachable ();
1692 ReadAny - reads HIGH(a) bytes into, a. All input
1693 is fully buffered, unlike ReadNBytes and thus is more
1694 suited to small reads.
1697 extern "C" void FIO_ReadAny (FIO_File f
, unsigned char *a
, unsigned int _a_high
)
1699 CheckAccess (f
, FIO_openedforread
, false);
1700 if ((BufferedRead (f
, _a_high
, a
)) == ((int ) (_a_high
)))
1702 SetEndOfLine (f
, static_cast<char> (a
[_a_high
]));
1708 WriteNBytes - writes nBytes from memory area src to a file
1709 returning the number of bytes actually written.
1710 This function will flush the buffer and then
1711 write the nBytes using a direct write from libc.
1712 It is ideal for large writes.
1715 extern "C" unsigned int FIO_WriteNBytes (FIO_File f
, unsigned int nBytes
, void * src
)
1718 FIO_FileDescriptor fd
;
1720 CheckAccess (f
, FIO_openedforwrite
, true);
1721 FIO_FlushBuffer (f
);
1724 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1727 total
= static_cast<int> (libc_write (fd
->unixfd
, src
, static_cast<size_t> ((int ) (nBytes
))));
1730 fd
->state
= FIO_failed
;
1735 fd
->abspos
+= (unsigned int ) (total
);
1736 if (fd
->buffer
!= NULL
)
1738 fd
->buffer
->bufstart
= fd
->abspos
;
1740 return (unsigned int ) (total
);
1745 /* static analysis guarentees a RETURN statement will be used before here. */
1746 __builtin_unreachable ();
1751 WriteAny - writes HIGH(a) bytes onto, file, f. All output
1752 is fully buffered, unlike WriteNBytes and thus is more
1753 suited to small writes.
1756 extern "C" void FIO_WriteAny (FIO_File f
, unsigned char *a
, unsigned int _a_high
)
1758 CheckAccess (f
, FIO_openedforwrite
, true);
1759 if ((BufferedWrite (f
, _a_high
, a
)) == ((int ) (_a_high
)))
1765 WriteChar - writes a single character to file, f.
1768 extern "C" void FIO_WriteChar (FIO_File f
, char ch
)
1770 CheckAccess (f
, FIO_openedforwrite
, true);
1771 if ((BufferedWrite (f
, sizeof (ch
), &ch
)) == ((int ) (sizeof (ch
))))
1777 EOF - tests to see whether a file, f, has reached end of file.
1780 extern "C" bool FIO_EOF (FIO_File f
)
1782 FIO_FileDescriptor fd
;
1784 CheckAccess (f
, FIO_openedforread
, false);
1787 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1790 return fd
->state
== FIO_endoffile
;
1794 /* static analysis guarentees a RETURN statement will be used before here. */
1795 __builtin_unreachable ();
1800 EOLN - tests to see whether a file, f, is upon a newline.
1801 It does NOT consume the newline.
1804 extern "C" bool FIO_EOLN (FIO_File f
)
1807 FIO_FileDescriptor fd
;
1809 CheckAccess (f
, FIO_openedforread
, false);
1811 we will read a character and then push it back onto the input stream,
1812 having noted the file status, we also reset the status.
1816 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1819 if ((fd
->state
== FIO_successful
) || (fd
->state
== FIO_endofline
))
1821 ch
= FIO_ReadChar (f
);
1822 if ((fd
->state
== FIO_successful
) || (fd
->state
== FIO_endofline
))
1824 FIO_UnReadChar (f
, ch
);
1826 return ch
== ASCII_nl
;
1831 /* static analysis guarentees a RETURN statement will be used before here. */
1832 __builtin_unreachable ();
1837 WasEOLN - tests to see whether a file, f, has just seen a newline.
1840 extern "C" bool FIO_WasEOLN (FIO_File f
)
1842 FIO_FileDescriptor fd
;
1844 CheckAccess (f
, FIO_openedforread
, false);
1851 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1852 return (fd
!= NULL
) && (fd
->state
== FIO_endofline
);
1854 /* static analysis guarentees a RETURN statement will be used before here. */
1855 __builtin_unreachable ();
1860 ReadChar - returns a character read from file f.
1861 Sensible to check with IsNoError or EOF after calling
1865 extern "C" char FIO_ReadChar (FIO_File f
)
1869 CheckAccess (f
, FIO_openedforread
, false);
1870 if ((BufferedRead (f
, sizeof (ch
), &ch
)) == ((int ) (sizeof (ch
))))
1872 SetEndOfLine (f
, ch
);
1879 /* static analysis guarentees a RETURN statement will be used before here. */
1880 __builtin_unreachable ();
1885 UnReadChar - replaces a character, ch, back into file f.
1886 This character must have been read by ReadChar
1887 and it does not allow successive calls. It may
1888 only be called if the previous read was successful
1889 or end of file was seen.
1890 If the state was previously endoffile then it
1891 is altered to successful.
1892 Otherwise it is left alone.
1895 extern "C" void FIO_UnReadChar (FIO_File f
, char ch
)
1897 FIO_FileDescriptor fd
;
1902 CheckAccess (f
, FIO_openedforread
, false);
1905 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1906 if (((fd
->state
== FIO_successful
) || (fd
->state
== FIO_endoffile
)) || (fd
->state
== FIO_endofline
))
1908 /* avoid dangling else. */
1909 if ((fd
->buffer
!= NULL
) && fd
->buffer
->valid
)
1911 /* we assume that a ReadChar has occurred, we will check just in case. */
1912 if (fd
->state
== FIO_endoffile
)
1914 fd
->buffer
->position
= MaxBufferLength
;
1915 fd
->buffer
->left
= 0;
1916 fd
->buffer
->filled
= 0;
1917 fd
->state
= FIO_successful
;
1919 if (fd
->buffer
->position
> 0)
1921 fd
->buffer
->position
-= 1;
1922 fd
->buffer
->left
+= 1;
1923 (*fd
->buffer
->contents
).array
[fd
->buffer
->position
] = ch
;
1927 /* if possible make room and store ch */
1928 if (fd
->buffer
->filled
== fd
->buffer
->size
)
1930 FormatError1 ((const char *) "performing too many UnReadChar calls on file (%d)\\n", 51, (const unsigned char *) &f
, (sizeof (f
)-1));
1934 n
= fd
->buffer
->filled
-fd
->buffer
->position
;
1935 b
= &(*fd
->buffer
->contents
).array
[fd
->buffer
->position
];
1936 a
= &(*fd
->buffer
->contents
).array
[fd
->buffer
->position
+1];
1937 a
= libc_memcpy (a
, b
, static_cast<size_t> (n
));
1938 fd
->buffer
->filled
+= 1;
1939 (*fd
->buffer
->contents
).array
[fd
->buffer
->position
] = ch
;
1946 FormatError1 ((const char *) "UnReadChar can only be called if the previous read was successful or end of file, error on file (%d)\\n", 102, (const unsigned char *) &f
, (sizeof (f
)-1));
1953 WriteLine - writes out a linefeed to file, f.
1956 extern "C" void FIO_WriteLine (FIO_File f
)
1958 FIO_WriteChar (f
, ASCII_nl
);
1963 WriteString - writes a string to file, f.
1966 extern "C" void FIO_WriteString (FIO_File f
, const char *a_
, unsigned int _a_high
)
1971 /* make a local copy of each unbounded array. */
1972 memcpy (a
, a_
, _a_high
+1);
1974 l
= StrLib_StrLen ((const char *) a
, _a_high
);
1975 if ((FIO_WriteNBytes (f
, l
, &a
)) != l
)
1981 ReadString - reads a string from file, f, into string, a.
1982 It terminates the string if HIGH is reached or
1983 if a newline is seen or an error occurs.
1986 extern "C" void FIO_ReadString (FIO_File f
, char *a
, unsigned int _a_high
)
1992 CheckAccess (f
, FIO_openedforread
, false);
1996 ch
= FIO_ReadChar (f
);
1999 /* avoid gcc warning by using compound statement even if not strictly necessary. */
2000 if (((ch
== ASCII_nl
) || (! (FIO_IsNoError (f
)))) || (FIO_EOF (f
)))
2011 } while (! ((((ch
== ASCII_nl
) || (i
> high
)) || (! (FIO_IsNoError (f
)))) || (FIO_EOF (f
))));
2016 WriteCardinal - writes a CARDINAL to file, f.
2017 It writes the binary image of the cardinal
2021 extern "C" void FIO_WriteCardinal (FIO_File f
, unsigned int c
)
2023 FIO_WriteAny (f
, (unsigned char *) &c
, (sizeof (c
)-1));
2028 ReadCardinal - reads a CARDINAL from file, f.
2029 It reads a binary image of a CARDINAL
2033 extern "C" unsigned int FIO_ReadCardinal (FIO_File f
)
2037 FIO_ReadAny (f
, (unsigned char *) &c
, (sizeof (c
)-1));
2039 /* static analysis guarentees a RETURN statement will be used before here. */
2040 __builtin_unreachable ();
2045 GetUnixFileDescriptor - returns the UNIX file descriptor of a file.
2048 extern "C" int FIO_GetUnixFileDescriptor (FIO_File f
)
2050 FIO_FileDescriptor fd
;
2054 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
2060 FormatError1 ((const char *) "file %d has not been opened or is out of range\\n", 48, (const unsigned char *) &f
, (sizeof (f
)-1));
2062 /* static analysis guarentees a RETURN statement will be used before here. */
2063 __builtin_unreachable ();
2068 SetPositionFromBeginning - sets the position from the beginning of the file.
2071 extern "C" void FIO_SetPositionFromBeginning (FIO_File f
, long int pos
)
2074 FIO_FileDescriptor fd
;
2078 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
2081 /* always force the lseek, until we are confident that abspos is always correct,
2082 basically it needs some hard testing before we should remove the OR TRUE. */
2083 if ((fd
->abspos
!= pos
) || true)
2085 FIO_FlushBuffer (f
);
2086 if (fd
->buffer
!= NULL
)
2090 fd
->buffer
->left
= fd
->buffer
->size
;
2094 fd
->buffer
->left
= 0;
2096 fd
->buffer
->position
= 0;
2097 fd
->buffer
->filled
= 0;
2099 offset
= libc_lseek (fd
->unixfd
, pos
, SEEK_SET
);
2100 if ((offset
>= 0) && (pos
== offset
))
2106 fd
->state
= FIO_failed
;
2109 if (fd
->buffer
!= NULL
)
2111 fd
->buffer
->valid
= false;
2112 fd
->buffer
->bufstart
= fd
->abspos
;
2121 SetPositionFromEnd - sets the position from the end of the file.
2124 extern "C" void FIO_SetPositionFromEnd (FIO_File f
, long int pos
)
2127 FIO_FileDescriptor fd
;
2131 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
2134 FIO_FlushBuffer (f
);
2135 if (fd
->buffer
!= NULL
)
2139 fd
->buffer
->left
= fd
->buffer
->size
;
2143 fd
->buffer
->left
= 0;
2145 fd
->buffer
->position
= 0;
2146 fd
->buffer
->filled
= 0;
2148 offset
= libc_lseek (fd
->unixfd
, pos
, SEEK_END
);
2151 fd
->abspos
= offset
;
2155 fd
->state
= FIO_failed
;
2159 if (fd
->buffer
!= NULL
)
2161 fd
->buffer
->valid
= false;
2162 fd
->buffer
->bufstart
= offset
;
2170 FindPosition - returns the current absolute position in file, f.
2173 extern "C" long int FIO_FindPosition (FIO_File f
)
2175 FIO_FileDescriptor fd
;
2179 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
2182 if ((fd
->buffer
== NULL
) || ! fd
->buffer
->valid
)
2188 return fd
->buffer
->bufstart
+((long int ) (fd
->buffer
->position
));
2193 /* static analysis guarentees a RETURN statement will be used before here. */
2194 __builtin_unreachable ();
2199 GetFileName - assigns, a, with the filename associated with, f.
2202 extern "C" void FIO_GetFileName (FIO_File f
, char *a
, unsigned int _a_high
)
2204 typedef char *GetFileName__T6
;
2208 FIO_FileDescriptor fd
;
2212 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
2215 FormatError ((const char *) "this file has probably been closed and not reopened successfully or alternatively never opened\\n", 96);
2217 __builtin_unreachable ();
2221 if (fd
->name
.address
== NULL
)
2223 StrLib_StrCopy ((const char *) "", 0, (char *) a
, _a_high
);
2227 p
= static_cast<GetFileName__T6
> (fd
->name
.address
);
2229 while (((*p
) != ASCII_nul
) && (i
<= _a_high
))
2242 getFileName - returns the address of the filename associated with, f.
2245 extern "C" void * FIO_getFileName (FIO_File f
)
2247 FIO_FileDescriptor fd
;
2251 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
2254 FormatError ((const char *) "this file has probably been closed and not reopened successfully or alternatively never opened\\n", 96);
2256 __builtin_unreachable ();
2260 return fd
->name
.address
;
2264 /* static analysis guarentees a RETURN statement will be used before here. */
2265 __builtin_unreachable ();
2270 getFileNameLength - returns the number of characters associated with filename, f.
2273 extern "C" unsigned int FIO_getFileNameLength (FIO_File f
)
2275 FIO_FileDescriptor fd
;
2279 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
2282 FormatError ((const char *) "this file has probably been closed and not reopened successfully or alternatively never opened\\n", 96);
2284 __builtin_unreachable ();
2288 return fd
->name
.size
;
2292 /* static analysis guarentees a RETURN statement will be used before here. */
2293 __builtin_unreachable ();
2298 FlushOutErr - flushes, StdOut, and, StdErr.
2299 It is also called when the application calls M2RTS.Terminate.
2300 (which is automatically placed in program modules by the GM2
2304 extern "C" void FIO_FlushOutErr (void)
2306 if (FIO_IsNoError (FIO_StdOut
))
2308 FIO_FlushBuffer (FIO_StdOut
);
2310 if (FIO_IsNoError (FIO_StdErr
))
2312 FIO_FlushBuffer (FIO_StdErr
);
2316 extern "C" void _M2_FIO_init (__attribute__((unused
)) int argc
,__attribute__((unused
)) char *argv
[],__attribute__((unused
)) char *envp
[])
2321 extern "C" void _M2_FIO_fini (__attribute__((unused
)) int argc
,__attribute__((unused
)) char *argv
[],__attribute__((unused
)) char *envp
[])