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/>. */
31 # if !defined (PROC_D)
33 typedef void (*PROC_t
) (void);
34 typedef struct { PROC_t proc
; } PROC
;
45 # include "GStorage.h"
47 #if defined(__cplusplus)
57 # include "GStorage.h"
58 # include "GNumberIO.h"
60 # include "GIndexing.h"
63 typedef unsigned int FIO_File
;
70 # define UNIXREADONLY 0
71 # define UNIXWRITEONLY 1
72 # define CreatePermissions 0666
73 # define MaxBufferLength (1024*16)
74 # define MaxErrorString (1024*8)
75 typedef struct FIO_NameInfo_r FIO_NameInfo
;
77 typedef struct FIO_buf_r FIO_buf
;
79 typedef FIO_buf
*FIO_Buffer
;
81 typedef struct FIO_fds_r FIO_fds
;
83 typedef FIO_fds
*FIO_FileDescriptor
;
85 typedef struct FIO__T7_a FIO__T7
;
87 typedef char *FIO_PtrToChar
;
89 typedef enum {FIO_successful
, FIO_outofmemory
, FIO_toomanyfilesopen
, FIO_failed
, FIO_connectionfailure
, FIO_endofline
, FIO_endoffile
} FIO_FileStatus
;
91 typedef enum {FIO_unused
, FIO_openedforread
, FIO_openedforwrite
, FIO_openedforrandom
} FIO_FileUsage
;
93 struct FIO_NameInfo_r
{
101 unsigned int position
;
109 struct FIO__T7_a
{ char array
[MaxBufferLength
+1]; };
113 FIO_FileStatus state
;
120 static Indexing_Index FileInfo
;
121 static FIO_File Error
;
124 IsNoError - returns a TRUE if no error has occured on file, f.
127 extern "C" bool FIO_IsNoError (FIO_File f
);
130 IsActive - returns TRUE if the file, f, is still active.
133 extern "C" bool FIO_IsActive (FIO_File f
);
134 extern "C" bool FIO_Exists (const char *fname_
, unsigned int _fname_high
);
135 extern "C" FIO_File
FIO_OpenToRead (const char *fname_
, unsigned int _fname_high
);
136 extern "C" FIO_File
FIO_OpenToWrite (const char *fname_
, unsigned int _fname_high
);
137 extern "C" FIO_File
FIO_OpenForRandom (const char *fname_
, unsigned int _fname_high
, bool towrite
, bool newfile
);
140 Close - close a file which has been previously opened using:
141 OpenToRead, OpenToWrite, OpenForRandom.
142 It is correct to close a file which has an error status.
145 extern "C" void FIO_Close (FIO_File f
);
148 exists - returns TRUE if a file named, fname exists for reading.
151 extern "C" bool FIO_exists (void * fname
, unsigned int flength
);
154 openToRead - attempts to open a file, fname, for reading and
155 it returns this file.
156 The success of this operation can be checked by
160 extern "C" FIO_File
FIO_openToRead (void * fname
, unsigned int flength
);
163 openToWrite - attempts to open a file, fname, for write and
164 it returns this file.
165 The success of this operation can be checked by
169 extern "C" FIO_File
FIO_openToWrite (void * fname
, unsigned int flength
);
172 openForRandom - attempts to open a file, fname, for random access
173 read or write and it returns this file.
174 The success of this operation can be checked by
176 towrite, determines whether the file should be
177 opened for writing or reading.
180 extern "C" FIO_File
FIO_openForRandom (void * fname
, unsigned int flength
, bool towrite
, bool newfile
);
183 FlushBuffer - flush contents of file, f.
186 extern "C" void FIO_FlushBuffer (FIO_File f
);
189 ReadNBytes - reads nBytes of a file into memory area, dest, returning
190 the number of bytes actually read.
191 This function will consume from the buffer and then
192 perform direct libc reads. It is ideal for large reads.
195 extern "C" unsigned int FIO_ReadNBytes (FIO_File f
, unsigned int nBytes
, void * dest
);
198 ReadAny - reads HIGH (a) + 1 bytes into, a. All input
199 is fully buffered, unlike ReadNBytes and thus is more
200 suited to small reads.
203 extern "C" void FIO_ReadAny (FIO_File f
, unsigned char *a
, unsigned int _a_high
);
206 WriteNBytes - writes nBytes from memory area src to a file
207 returning the number of bytes actually written.
208 This function will flush the buffer and then
209 write the nBytes using a direct write from libc.
210 It is ideal for large writes.
213 extern "C" unsigned int FIO_WriteNBytes (FIO_File f
, unsigned int nBytes
, void * src
);
216 WriteAny - writes HIGH (a) + 1 bytes onto, file, f. All output
217 is fully buffered, unlike WriteNBytes and thus is more
218 suited to small writes.
221 extern "C" void FIO_WriteAny (FIO_File f
, unsigned char *a
, unsigned int _a_high
);
224 WriteChar - writes a single character to file, f.
227 extern "C" void FIO_WriteChar (FIO_File f
, char ch
);
230 EOF - tests to see whether a file, f, has reached end of file.
233 extern "C" bool FIO_EOF (FIO_File f
);
236 EOLN - tests to see whether a file, f, is upon a newline.
237 It does NOT consume the newline.
240 extern "C" bool FIO_EOLN (FIO_File f
);
243 WasEOLN - tests to see whether a file, f, has just seen a newline.
246 extern "C" bool FIO_WasEOLN (FIO_File f
);
249 ReadChar - returns a character read from file f.
250 Sensible to check with IsNoError or EOF after calling
254 extern "C" char FIO_ReadChar (FIO_File f
);
257 UnReadChar - replaces a character, ch, back into file f.
258 This character must have been read by ReadChar
259 and it does not allow successive calls. It may
260 only be called if the previous read was successful
261 or end of file was seen.
262 If the state was previously endoffile then it
263 is altered to successful.
264 Otherwise it is left alone.
267 extern "C" void FIO_UnReadChar (FIO_File f
, char ch
);
270 WriteLine - writes out a linefeed to file, f.
273 extern "C" void FIO_WriteLine (FIO_File f
);
276 WriteString - writes a string to file, f.
279 extern "C" void FIO_WriteString (FIO_File f
, const char *a_
, unsigned int _a_high
);
282 ReadString - reads a string from file, f, into string, a.
283 It terminates the string if HIGH is reached or
284 if a newline is seen or an error occurs.
287 extern "C" void FIO_ReadString (FIO_File f
, char *a
, unsigned int _a_high
);
290 WriteCardinal - writes a CARDINAL to file, f.
291 It writes the binary image of the cardinal
295 extern "C" void FIO_WriteCardinal (FIO_File f
, unsigned int c
);
298 ReadCardinal - reads a CARDINAL from file, f.
299 It reads a binary image of a CARDINAL
303 extern "C" unsigned int FIO_ReadCardinal (FIO_File f
);
306 GetUnixFileDescriptor - returns the UNIX file descriptor of a file.
309 extern "C" int FIO_GetUnixFileDescriptor (FIO_File f
);
312 SetPositionFromBeginning - sets the position from the beginning of the file.
315 extern "C" void FIO_SetPositionFromBeginning (FIO_File f
, long int pos
);
318 SetPositionFromEnd - sets the position from the end of the file.
321 extern "C" void FIO_SetPositionFromEnd (FIO_File f
, long int pos
);
324 FindPosition - returns the current absolute position in file, f.
327 extern "C" long int FIO_FindPosition (FIO_File f
);
330 GetFileName - assigns, a, with the filename associated with, f.
333 extern "C" void FIO_GetFileName (FIO_File f
, char *a
, unsigned int _a_high
);
336 getFileName - returns the address of the filename associated with, f.
339 extern "C" void * FIO_getFileName (FIO_File f
);
342 getFileNameLength - returns the number of characters associated with filename, f.
345 extern "C" unsigned int FIO_getFileNameLength (FIO_File f
);
348 FlushOutErr - flushes, StdOut, and, StdErr.
349 It is also called when the application calls M2RTS.Terminate.
350 (which is automatically placed in program modules by the GM2
354 extern "C" void FIO_FlushOutErr (void);
357 Max - returns the maximum of two values.
360 static unsigned int Max (unsigned int a
, unsigned int b
);
363 Min - returns the minimum of two values.
366 static unsigned int Min (unsigned int a
, unsigned int b
);
369 GetNextFreeDescriptor - returns the index to the FileInfo array indicating
373 static FIO_File
GetNextFreeDescriptor (void);
376 SetState - sets the field, state, of file, f, to, s.
379 static void SetState (FIO_File f
, FIO_FileStatus s
);
382 InitializeFile - initialize a file descriptor
385 static FIO_File
InitializeFile (FIO_File f
, void * fname
, unsigned int flength
, FIO_FileStatus fstate
, FIO_FileUsage use
, bool towrite
, unsigned int buflength
);
388 ConnectToUnix - connects a FIO file to a UNIX file descriptor.
391 static void ConnectToUnix (FIO_File f
, bool towrite
, bool newfile
);
394 ReadFromBuffer - attempts to read, nBytes, from file, f.
395 It firstly consumes the buffer and then performs
396 direct unbuffered reads. This should only be used
397 when wishing to read large files.
399 The actual number of bytes read is returned.
400 -1 is returned if EOF is reached.
403 static int ReadFromBuffer (FIO_File f
, void * a
, unsigned int nBytes
);
406 BufferedRead - will read, nBytes, through the buffer.
407 Similar to ReadFromBuffer, but this function will always
408 read into the buffer before copying into memory.
410 Useful when performing small reads.
413 static int BufferedRead (FIO_File f
, unsigned int nBytes
, void * dest
);
416 HandleEscape - translates
417 and \t into their respective ascii codes.
420 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
);
426 static void Cast (unsigned char *a
, unsigned int _a_high
, const unsigned char *b_
, unsigned int _b_high
);
429 StringFormat1 - converts string, src, into, dest, together with encapsulated
430 entity, w. It only formats the first %s or %d with n.
433 static void StringFormat1 (char *dest
, unsigned int _dest_high
, const char *src_
, unsigned int _src_high
, const unsigned char *w_
, unsigned int _w_high
);
436 FormatError - provides a orthoganal counterpart to the procedure below.
439 static void FormatError (const char *a_
, unsigned int _a_high
);
442 FormatError1 - generic error procedure taking standard format string
443 and single parameter.
446 static void FormatError1 (const char *a_
, unsigned int _a_high
, const unsigned char *w_
, unsigned int _w_high
);
449 FormatError2 - generic error procedure taking standard format string
453 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
);
456 CheckAccess - checks to see whether a file f has been
457 opened for read/write.
460 static void CheckAccess (FIO_File f
, FIO_FileUsage use
, bool towrite
);
466 static void SetEndOfLine (FIO_File f
, char ch
);
469 BufferedWrite - will write, nBytes, through the buffer.
470 Similar to WriteNBytes, but this function will always
471 write into the buffer before copying into memory.
473 Useful when performing small writes.
476 static int BufferedWrite (FIO_File f
, unsigned int nBytes
, void * src
);
479 PreInitialize - preinitialize the file descriptor.
482 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
);
485 Init - initialize the modules, global variables.
488 static void Init (void);
492 Max - returns the maximum of two values.
495 static unsigned int Max (unsigned int a
, unsigned int b
)
505 /* static analysis guarentees a RETURN statement will be used before here. */
506 __builtin_unreachable ();
511 Min - returns the minimum of two values.
514 static unsigned int Min (unsigned int a
, unsigned int b
)
524 /* static analysis guarentees a RETURN statement will be used before here. */
525 __builtin_unreachable ();
530 GetNextFreeDescriptor - returns the index to the FileInfo array indicating
534 static FIO_File
GetNextFreeDescriptor (void)
538 FIO_FileDescriptor fd
;
541 h
= Indexing_HighIndice (FileInfo
);
546 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
555 Indexing_PutIndice (FileInfo
, f
, NULL
); /* create new slot */
556 return f
; /* create new slot */
559 ReturnException ("../../gcc-read-write/gcc/m2/gm2-libs/FIO.def", 25, 1);
560 __builtin_unreachable ();
565 SetState - sets the field, state, of file, f, to, s.
568 static void SetState (FIO_File f
, FIO_FileStatus s
)
570 FIO_FileDescriptor fd
;
572 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
578 InitializeFile - initialize a file descriptor
581 static FIO_File
InitializeFile (FIO_File f
, void * fname
, unsigned int flength
, FIO_FileStatus fstate
, FIO_FileUsage use
, bool towrite
, unsigned int buflength
)
584 FIO_FileDescriptor fd
;
586 Storage_ALLOCATE ((void **) &fd
, sizeof (FIO_fds
));
589 SetState (Error
, FIO_outofmemory
);
594 Indexing_PutIndice (FileInfo
, f
, reinterpret_cast<void *> (fd
));
595 fd
->name
.size
= flength
+1; /* need to guarantee the nul for C */
596 fd
->usage
= use
; /* need to guarantee the nul for C */
597 fd
->output
= towrite
;
598 Storage_ALLOCATE (&fd
->name
.address
, fd
->name
.size
);
599 if (fd
->name
.address
== NULL
)
601 fd
->state
= FIO_outofmemory
;
604 fd
->name
.address
= libc_strncpy (fd
->name
.address
, fname
, flength
);
605 /* and assign nul to the last byte */
606 p
= static_cast<FIO_PtrToChar
> (fd
->name
.address
);
610 /* now for the buffer */
611 Storage_ALLOCATE ((void **) &fd
->buffer
, sizeof (FIO_buf
));
612 if (fd
->buffer
== NULL
)
614 SetState (Error
, FIO_outofmemory
);
619 fd
->buffer
->valid
= false;
620 fd
->buffer
->bufstart
= 0;
621 fd
->buffer
->size
= buflength
;
622 fd
->buffer
->position
= 0;
623 fd
->buffer
->filled
= 0;
624 if (fd
->buffer
->size
== 0)
626 fd
->buffer
->address
= NULL
;
630 Storage_ALLOCATE (&fd
->buffer
->address
, fd
->buffer
->size
);
631 if (fd
->buffer
->address
== NULL
)
633 fd
->state
= FIO_outofmemory
;
639 fd
->buffer
->left
= fd
->buffer
->size
;
643 fd
->buffer
->left
= 0;
645 fd
->buffer
->contents
= reinterpret_cast<FIO__T7
*> (fd
->buffer
->address
); /* provides easy access for reading characters */
646 fd
->state
= fstate
; /* provides easy access for reading characters */
650 /* static analysis guarentees a RETURN statement will be used before here. */
651 __builtin_unreachable ();
656 ConnectToUnix - connects a FIO file to a UNIX file descriptor.
659 static void ConnectToUnix (FIO_File f
, bool towrite
, bool newfile
)
661 FIO_FileDescriptor fd
;
665 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
672 fd
->unixfd
= libc_creat (fd
->name
.address
, CreatePermissions
);
676 fd
->unixfd
= libc_open (fd
->name
.address
, UNIXWRITEONLY
, 0);
681 fd
->unixfd
= libc_open (fd
->name
.address
, UNIXREADONLY
, 0);
685 fd
->state
= FIO_connectionfailure
;
693 ReadFromBuffer - attempts to read, nBytes, from file, f.
694 It firstly consumes the buffer and then performs
695 direct unbuffered reads. This should only be used
696 when wishing to read large files.
698 The actual number of bytes read is returned.
699 -1 is returned if EOF is reached.
702 static int ReadFromBuffer (FIO_File f
, void * a
, unsigned int nBytes
)
704 typedef unsigned char *ReadFromBuffer__T1
;
710 ReadFromBuffer__T1 p
;
711 FIO_FileDescriptor fd
;
715 total
= 0; /* how many bytes have we read */
716 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
)); /* how many bytes have we read */
717 /* extract from the buffer first */
718 if ((fd
->buffer
!= NULL
) && fd
->buffer
->valid
)
720 if (fd
->buffer
->left
> 0)
722 /* avoid gcc warning by using compound statement even if not strictly necessary. */
725 /* too expensive to call memcpy for 1 character */
726 p
= static_cast<ReadFromBuffer__T1
> (a
);
727 (*p
) = static_cast<unsigned char> ((*fd
->buffer
->contents
).array
[fd
->buffer
->position
]);
728 fd
->buffer
->left
-= 1; /* remove consumed bytes */
729 fd
->buffer
->position
+= 1; /* move onwards n bytes */
730 nBytes
= 0; /* reduce the amount for future direct */
736 n
= Min (fd
->buffer
->left
, nBytes
);
737 t
= fd
->buffer
->address
;
738 t
= reinterpret_cast<void *> (reinterpret_cast<char *> (t
)+fd
->buffer
->position
);
739 p
= static_cast<ReadFromBuffer__T1
> (libc_memcpy (a
, t
, static_cast<size_t> (n
)));
740 fd
->buffer
->left
-= n
; /* remove consumed bytes */
741 fd
->buffer
->position
+= n
; /* move onwards n bytes */
742 /* move onwards ready for direct reads */
743 a
= reinterpret_cast<void *> (reinterpret_cast<char *> (a
)+n
);
744 nBytes
-= n
; /* reduce the amount for future direct */
747 return total
; /* much cleaner to return now, */
749 /* difficult to record an error if */
751 /* the read below returns -1 */
755 /* still more to read */
756 result
= static_cast<int> (libc_read (fd
->unixfd
, a
, static_cast<size_t> ((int ) (nBytes
))));
759 /* avoid dangling else. */
761 fd
->abspos
+= result
;
762 /* now disable the buffer as we read directly into, a. */
763 if (fd
->buffer
!= NULL
)
765 fd
->buffer
->valid
= false;
773 fd
->state
= FIO_endoffile
;
777 fd
->state
= FIO_failed
;
779 /* indicate buffer is empty */
780 if (fd
->buffer
!= NULL
)
782 fd
->buffer
->valid
= false;
783 fd
->buffer
->left
= 0;
784 fd
->buffer
->position
= 0;
785 if (fd
->buffer
->address
!= NULL
)
787 (*fd
->buffer
->contents
).array
[fd
->buffer
->position
] = ASCII_nul
;
799 /* static analysis guarentees a RETURN statement will be used before here. */
800 __builtin_unreachable ();
805 BufferedRead - will read, nBytes, through the buffer.
806 Similar to ReadFromBuffer, but this function will always
807 read into the buffer before copying into memory.
809 Useful when performing small reads.
812 static int BufferedRead (FIO_File f
, unsigned int nBytes
, void * dest
)
814 typedef unsigned char *BufferedRead__T3
;
820 FIO_FileDescriptor fd
;
824 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
825 total
= 0; /* how many bytes have we read */
826 if (fd
!= NULL
) /* how many bytes have we read */
828 /* extract from the buffer first */
829 if (fd
->buffer
!= NULL
)
833 if ((fd
->buffer
->left
> 0) && fd
->buffer
->valid
)
837 /* too expensive to call memcpy for 1 character */
838 p
= static_cast<BufferedRead__T3
> (dest
);
839 (*p
) = static_cast<unsigned char> ((*fd
->buffer
->contents
).array
[fd
->buffer
->position
]);
840 fd
->buffer
->left
-= 1; /* remove consumed byte */
841 fd
->buffer
->position
+= 1; /* move onwards n byte */
842 total
+= 1; /* move onwards n byte */
847 n
= Min (fd
->buffer
->left
, nBytes
);
848 src
= fd
->buffer
->address
;
849 src
= reinterpret_cast<void *> (reinterpret_cast<char *> (src
)+fd
->buffer
->position
);
850 p
= static_cast<BufferedRead__T3
> (libc_memcpy (dest
, src
, static_cast<size_t> (n
)));
851 fd
->buffer
->left
-= n
; /* remove consumed bytes */
852 fd
->buffer
->position
+= n
; /* move onwards n bytes */
853 /* move onwards ready for direct reads */
854 dest
= reinterpret_cast<void *> (reinterpret_cast<char *> (dest
)+n
);
855 nBytes
-= n
; /* reduce the amount for future direct */
863 n
= static_cast<int> (libc_read (fd
->unixfd
, fd
->buffer
->address
, static_cast<size_t> (fd
->buffer
->size
)));
866 /* avoid dangling else. */
867 fd
->buffer
->valid
= true;
868 fd
->buffer
->position
= 0;
869 fd
->buffer
->left
= n
;
870 fd
->buffer
->filled
= n
;
871 fd
->buffer
->bufstart
= fd
->abspos
;
876 fd
->state
= FIO_endoffile
;
882 fd
->buffer
->valid
= false;
883 fd
->buffer
->position
= 0;
884 fd
->buffer
->left
= 0;
885 fd
->buffer
->filled
= 0;
886 fd
->state
= FIO_failed
;
896 /* static analysis guarentees a RETURN statement will be used before here. */
897 __builtin_unreachable ();
902 HandleEscape - translates
903 and \t into their respective ascii codes.
906 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
)
908 char src
[_src_high
+1];
910 /* make a local copy of each unbounded array. */
911 memcpy (src
, src_
, _src_high
+1);
913 if (((((*i
)+1) < HighSrc
) && (src
[(*i
)] == '\\')) && ((*j
) < HighDest
))
915 /* avoid gcc warning by using compound statement even if not strictly necessary. */
916 if (src
[(*i
)+1] == 'n')
918 /* requires a newline */
919 dest
[(*j
)] = ASCII_nl
;
923 else if (src
[(*i
)+1] == 't')
925 /* avoid dangling else. */
926 /* requires a tab (yuck) tempted to fake this but I better not.. */
927 dest
[(*j
)] = ASCII_tab
;
933 /* avoid dangling else. */
934 /* copy escaped character */
936 dest
[(*j
)] = src
[(*i
)];
948 static void Cast (unsigned char *a
, unsigned int _a_high
, const unsigned char *b_
, unsigned int _b_high
)
951 unsigned char b
[_b_high
+1];
953 /* make a local copy of each unbounded array. */
954 memcpy (b
, b_
, _b_high
+1);
956 if (_a_high
== _b_high
)
958 for (i
=0; i
<=_a_high
; i
++)
965 FormatError ((const char *) "cast failed", 11);
971 StringFormat1 - converts string, src, into, dest, together with encapsulated
972 entity, w. It only formats the first %s or %d with n.
975 static void StringFormat1 (char *dest
, unsigned int _dest_high
, const char *src_
, unsigned int _src_high
, const unsigned char *w_
, unsigned int _w_high
)
977 typedef struct StringFormat1__T8_a StringFormat1__T8
;
979 typedef char *StringFormat1__T4
;
981 struct StringFormat1__T8_a
{ char array
[MaxErrorString
+1]; };
982 unsigned int HighSrc
;
983 unsigned int HighDest
;
987 StringFormat1__T8 str
;
989 char src
[_src_high
+1];
990 unsigned char w
[_w_high
+1];
992 /* make a local copy of each unbounded array. */
993 memcpy (src
, src_
, _src_high
+1);
994 memcpy (w
, w_
, _w_high
+1);
996 HighSrc
= StrLib_StrLen ((const char *) src
, _src_high
);
997 HighDest
= _dest_high
;
1002 while ((((i
< HighSrc
) && (src
[i
] != ASCII_nul
)) && (j
< HighDest
)) && (src
[i
] != '%'))
1006 HandleEscape ((char *) dest
, _dest_high
, (const char *) src
, _src_high
, &i
, &j
, HighSrc
, HighDest
);
1015 if ((((i
+1) < HighSrc
) && (src
[i
] == '%')) && (j
< HighDest
))
1017 /* avoid gcc warning by using compound statement even if not strictly necessary. */
1018 if (src
[i
+1] == 's')
1020 Cast ((unsigned char *) &p
, (sizeof (p
)-1), (const unsigned char *) w
, _w_high
);
1021 while ((j
< HighDest
) && ((*p
) != ASCII_nul
))
1029 dest
[j
] = ASCII_nul
;
1031 j
= StrLib_StrLen ((const char *) dest
, _dest_high
);
1034 else if (src
[i
+1] == 'd')
1036 /* avoid dangling else. */
1037 dest
[j
] = ASCII_nul
;
1038 Cast ((unsigned char *) &c
, (sizeof (c
)-1), (const unsigned char *) w
, _w_high
);
1039 NumberIO_CardToStr (c
, 0, (char *) &str
.array
[0], MaxErrorString
);
1040 StrLib_StrConCat ((const char *) dest
, _dest_high
, (const char *) &str
.array
[0], MaxErrorString
, (char *) dest
, _dest_high
);
1041 j
= StrLib_StrLen ((const char *) dest
, _dest_high
);
1046 /* avoid dangling else. */
1052 /* and finish off copying src into dest */
1053 while (((i
< HighSrc
) && (src
[i
] != ASCII_nul
)) && (j
< HighDest
))
1057 HandleEscape ((char *) dest
, _dest_high
, (const char *) src
, _src_high
, &i
, &j
, HighSrc
, HighDest
);
1068 dest
[j
] = ASCII_nul
;
1074 FormatError - provides a orthoganal counterpart to the procedure below.
1077 static void FormatError (const char *a_
, unsigned int _a_high
)
1081 /* make a local copy of each unbounded array. */
1082 memcpy (a
, a_
, _a_high
+1);
1084 FIO_WriteString (FIO_StdErr
, (const char *) a
, _a_high
);
1089 FormatError1 - generic error procedure taking standard format string
1090 and single parameter.
1093 static void FormatError1 (const char *a_
, unsigned int _a_high
, const unsigned char *w_
, unsigned int _w_high
)
1095 typedef struct FormatError1__T9_a FormatError1__T9
;
1097 struct FormatError1__T9_a
{ char array
[MaxErrorString
+1]; };
1100 unsigned char w
[_w_high
+1];
1102 /* make a local copy of each unbounded array. */
1103 memcpy (a
, a_
, _a_high
+1);
1104 memcpy (w
, w_
, _w_high
+1);
1106 StringFormat1 ((char *) &s
.array
[0], MaxErrorString
, (const char *) a
, _a_high
, (const unsigned char *) w
, _w_high
);
1107 FormatError ((const char *) &s
.array
[0], MaxErrorString
);
1112 FormatError2 - generic error procedure taking standard format string
1116 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
)
1118 typedef struct FormatError2__T10_a FormatError2__T10
;
1120 struct FormatError2__T10_a
{ char array
[MaxErrorString
+1]; };
1121 FormatError2__T10 s
;
1123 unsigned char w1
[_w1_high
+1];
1124 unsigned char w2
[_w2_high
+1];
1126 /* make a local copy of each unbounded array. */
1127 memcpy (a
, a_
, _a_high
+1);
1128 memcpy (w1
, w1_
, _w1_high
+1);
1129 memcpy (w2
, w2_
, _w2_high
+1);
1131 StringFormat1 ((char *) &s
.array
[0], MaxErrorString
, (const char *) a
, _a_high
, (const unsigned char *) w1
, _w1_high
);
1132 FormatError1 ((const char *) &s
.array
[0], MaxErrorString
, (const unsigned char *) w2
, _w2_high
);
1137 CheckAccess - checks to see whether a file f has been
1138 opened for read/write.
1141 static void CheckAccess (FIO_File f
, FIO_FileUsage use
, bool towrite
)
1143 FIO_FileDescriptor fd
;
1147 /* avoid dangling else. */
1148 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1151 if (f
!= FIO_StdErr
)
1153 FormatError ((const char *) "this file has probably been closed and not reopened successfully or alternatively never opened\\n", 96);
1156 __builtin_unreachable ();
1160 if ((use
== FIO_openedforwrite
) && (fd
->usage
== FIO_openedforread
))
1162 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));
1164 __builtin_unreachable ();
1166 else if ((use
== FIO_openedforread
) && (fd
->usage
== FIO_openedforwrite
))
1168 /* avoid dangling else. */
1169 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));
1171 __builtin_unreachable ();
1173 else if (fd
->state
== FIO_connectionfailure
)
1175 /* avoid dangling else. */
1176 FormatError1 ((const char *) "this file (%s) was not successfully opened\\n", 44, (const unsigned char *) &fd
->name
.address
, (sizeof (fd
->name
.address
)-1));
1178 __builtin_unreachable ();
1180 else if (towrite
!= fd
->output
)
1182 /* avoid dangling else. */
1185 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));
1187 __builtin_unreachable ();
1191 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));
1193 __builtin_unreachable ();
1200 FormatError ((const char *) "this file has not been opened successfully\\n", 44);
1202 __builtin_unreachable ();
1211 static void SetEndOfLine (FIO_File f
, char ch
)
1213 FIO_FileDescriptor fd
;
1215 CheckAccess (f
, FIO_openedforread
, false);
1218 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1221 fd
->state
= FIO_endofline
;
1225 fd
->state
= FIO_successful
;
1232 BufferedWrite - will write, nBytes, through the buffer.
1233 Similar to WriteNBytes, but this function will always
1234 write into the buffer before copying into memory.
1236 Useful when performing small writes.
1239 static int BufferedWrite (FIO_File f
, unsigned int nBytes
, void * src
)
1241 typedef unsigned char *BufferedWrite__T5
;
1246 BufferedWrite__T5 p
;
1247 FIO_FileDescriptor fd
;
1251 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1254 total
= 0; /* how many bytes have we read */
1255 if (fd
->buffer
!= NULL
) /* how many bytes have we read */
1257 /* place into the buffer first */
1260 if (fd
->buffer
->left
> 0)
1264 /* too expensive to call memcpy for 1 character */
1265 p
= static_cast<BufferedWrite__T5
> (src
);
1266 (*fd
->buffer
->contents
).array
[fd
->buffer
->position
] = static_cast<char> ((*p
));
1267 fd
->buffer
->left
-= 1; /* reduce space */
1268 fd
->buffer
->position
+= 1; /* move onwards n byte */
1269 total
+= 1; /* move onwards n byte */
1274 n
= Min (fd
->buffer
->left
, nBytes
);
1275 dest
= fd
->buffer
->address
;
1276 dest
= reinterpret_cast<void *> (reinterpret_cast<char *> (dest
)+fd
->buffer
->position
);
1277 p
= static_cast<BufferedWrite__T5
> (libc_memcpy (dest
, src
, static_cast<size_t> ((unsigned int ) (n
))));
1278 fd
->buffer
->left
-= n
; /* remove consumed bytes */
1279 fd
->buffer
->position
+= n
; /* move onwards n bytes */
1280 /* move ready for further writes */
1281 src
= reinterpret_cast<void *> (reinterpret_cast<char *> (src
)+n
);
1282 nBytes
-= n
; /* reduce the amount for future writes */
1283 total
+= n
; /* reduce the amount for future writes */
1288 FIO_FlushBuffer (f
);
1289 if ((fd
->state
!= FIO_successful
) && (fd
->state
!= FIO_endofline
))
1300 /* static analysis guarentees a RETURN statement will be used before here. */
1301 __builtin_unreachable ();
1306 PreInitialize - preinitialize the file descriptor.
1309 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
)
1311 FIO_FileDescriptor fd
;
1312 FIO_FileDescriptor fe
;
1313 char fname
[_fname_high
+1];
1315 /* make a local copy of each unbounded array. */
1316 memcpy (fname
, fname_
, _fname_high
+1);
1318 if ((InitializeFile (f
, &fname
, StrLib_StrLen ((const char *) fname
, _fname_high
), state
, use
, towrite
, bufsize
)) == f
)
1320 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1323 fe
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, FIO_StdErr
));
1327 __builtin_unreachable ();
1331 fd
->unixfd
= fe
->unixfd
; /* the error channel */
1342 __builtin_unreachable ();
1348 Init - initialize the modules, global variables.
1351 static void Init (void)
1353 FileInfo
= Indexing_InitIndex (0);
1355 PreInitialize (Error
, (const char *) "error", 5, FIO_toomanyfilesopen
, FIO_unused
, false, -1, 0);
1357 PreInitialize (FIO_StdIn
, (const char *) "<stdin>", 7, FIO_successful
, FIO_openedforread
, false, 0, MaxBufferLength
);
1359 PreInitialize (FIO_StdOut
, (const char *) "<stdout>", 8, FIO_successful
, FIO_openedforwrite
, true, 1, MaxBufferLength
);
1361 PreInitialize (FIO_StdErr
, (const char *) "<stderr>", 8, FIO_successful
, FIO_openedforwrite
, true, 2, MaxBufferLength
);
1362 if (! (M2RTS_InstallTerminationProcedure ((PROC
) {(PROC_t
) FIO_FlushOutErr
})))
1365 __builtin_unreachable ();
1371 IsNoError - returns a TRUE if no error has occured on file, f.
1374 extern "C" bool FIO_IsNoError (FIO_File f
)
1376 FIO_FileDescriptor fd
;
1384 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1385 return (fd
!= NULL
) && (((fd
->state
== FIO_successful
) || (fd
->state
== FIO_endoffile
)) || (fd
->state
== FIO_endofline
));
1387 /* static analysis guarentees a RETURN statement will be used before here. */
1388 __builtin_unreachable ();
1393 IsActive - returns TRUE if the file, f, is still active.
1396 extern "C" bool FIO_IsActive (FIO_File f
)
1404 return (Indexing_GetIndice (FileInfo
, f
)) != NULL
;
1406 /* static analysis guarentees a RETURN statement will be used before here. */
1407 __builtin_unreachable ();
1410 extern "C" bool FIO_Exists (const char *fname_
, unsigned int _fname_high
)
1412 char fname
[_fname_high
+1];
1414 /* make a local copy of each unbounded array. */
1415 memcpy (fname
, fname_
, _fname_high
+1);
1418 The following functions are wrappers for the above.
1420 return FIO_exists (&fname
, StrLib_StrLen ((const char *) fname
, _fname_high
));
1421 /* static analysis guarentees a RETURN statement will be used before here. */
1422 __builtin_unreachable ();
1425 extern "C" FIO_File
FIO_OpenToRead (const char *fname_
, unsigned int _fname_high
)
1427 char fname
[_fname_high
+1];
1429 /* make a local copy of each unbounded array. */
1430 memcpy (fname
, fname_
, _fname_high
+1);
1432 return FIO_openToRead (&fname
, StrLib_StrLen ((const char *) fname
, _fname_high
));
1433 /* static analysis guarentees a RETURN statement will be used before here. */
1434 __builtin_unreachable ();
1437 extern "C" FIO_File
FIO_OpenToWrite (const char *fname_
, unsigned int _fname_high
)
1439 char fname
[_fname_high
+1];
1441 /* make a local copy of each unbounded array. */
1442 memcpy (fname
, fname_
, _fname_high
+1);
1444 return FIO_openToWrite (&fname
, StrLib_StrLen ((const char *) fname
, _fname_high
));
1445 /* static analysis guarentees a RETURN statement will be used before here. */
1446 __builtin_unreachable ();
1449 extern "C" FIO_File
FIO_OpenForRandom (const char *fname_
, unsigned int _fname_high
, bool towrite
, bool newfile
)
1451 char fname
[_fname_high
+1];
1453 /* make a local copy of each unbounded array. */
1454 memcpy (fname
, fname_
, _fname_high
+1);
1456 return FIO_openForRandom (&fname
, StrLib_StrLen ((const char *) fname
, _fname_high
), towrite
, newfile
);
1457 /* static analysis guarentees a RETURN statement will be used before here. */
1458 __builtin_unreachable ();
1463 Close - close a file which has been previously opened using:
1464 OpenToRead, OpenToWrite, OpenForRandom.
1465 It is correct to close a file which has an error status.
1468 extern "C" void FIO_Close (FIO_File f
)
1470 FIO_FileDescriptor fd
;
1474 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1476 we allow users to close files which have an error status
1480 FIO_FlushBuffer (f
);
1481 if (fd
->unixfd
>= 0)
1483 if ((libc_close (fd
->unixfd
)) != 0)
1485 FormatError1 ((const char *) "failed to close file (%s)\\n", 27, (const unsigned char *) &fd
->name
.address
, (sizeof (fd
->name
.address
)-1));
1486 fd
->state
= FIO_failed
; /* --fixme-- too late to notify user (unless we return a BOOLEAN) */
1489 if (fd
->name
.address
!= NULL
)
1491 Storage_DEALLOCATE (&fd
->name
.address
, fd
->name
.size
);
1493 if (fd
->buffer
!= NULL
)
1495 if (fd
->buffer
->address
!= NULL
)
1497 Storage_DEALLOCATE (&fd
->buffer
->address
, fd
->buffer
->size
);
1499 Storage_DEALLOCATE ((void **) &fd
->buffer
, sizeof (FIO_buf
));
1502 Storage_DEALLOCATE ((void **) &fd
, sizeof (FIO_fds
));
1503 Indexing_PutIndice (FileInfo
, f
, NULL
);
1510 exists - returns TRUE if a file named, fname exists for reading.
1513 extern "C" bool FIO_exists (void * fname
, unsigned int flength
)
1517 f
= FIO_openToRead (fname
, flength
);
1518 if (FIO_IsNoError (f
))
1528 /* static analysis guarentees a RETURN statement will be used before here. */
1529 __builtin_unreachable ();
1534 openToRead - attempts to open a file, fname, for reading and
1535 it returns this file.
1536 The success of this operation can be checked by
1540 extern "C" FIO_File
FIO_openToRead (void * fname
, unsigned int flength
)
1544 f
= GetNextFreeDescriptor ();
1547 SetState (f
, FIO_toomanyfilesopen
);
1551 f
= InitializeFile (f
, fname
, flength
, FIO_successful
, FIO_openedforread
, false, MaxBufferLength
);
1552 ConnectToUnix (f
, false, false);
1555 /* static analysis guarentees a RETURN statement will be used before here. */
1556 __builtin_unreachable ();
1561 openToWrite - attempts to open a file, fname, for write and
1562 it returns this file.
1563 The success of this operation can be checked by
1567 extern "C" FIO_File
FIO_openToWrite (void * fname
, unsigned int flength
)
1571 f
= GetNextFreeDescriptor ();
1574 SetState (f
, FIO_toomanyfilesopen
);
1578 f
= InitializeFile (f
, fname
, flength
, FIO_successful
, FIO_openedforwrite
, true, MaxBufferLength
);
1579 ConnectToUnix (f
, true, true);
1582 /* static analysis guarentees a RETURN statement will be used before here. */
1583 __builtin_unreachable ();
1588 openForRandom - attempts to open a file, fname, for random access
1589 read or write and it returns this file.
1590 The success of this operation can be checked by
1592 towrite, determines whether the file should be
1593 opened for writing or reading.
1596 extern "C" FIO_File
FIO_openForRandom (void * fname
, unsigned int flength
, bool towrite
, bool newfile
)
1600 f
= GetNextFreeDescriptor ();
1603 SetState (f
, FIO_toomanyfilesopen
);
1607 f
= InitializeFile (f
, fname
, flength
, FIO_successful
, FIO_openedforrandom
, towrite
, MaxBufferLength
);
1608 ConnectToUnix (f
, towrite
, newfile
);
1611 /* static analysis guarentees a RETURN statement will be used before here. */
1612 __builtin_unreachable ();
1617 FlushBuffer - flush contents of file, f.
1620 extern "C" void FIO_FlushBuffer (FIO_File f
)
1622 FIO_FileDescriptor fd
;
1626 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1629 if (fd
->output
&& (fd
->buffer
!= NULL
))
1631 if ((fd
->buffer
->position
== 0) || ((libc_write (fd
->unixfd
, fd
->buffer
->address
, static_cast<size_t> (fd
->buffer
->position
))) == ((int ) (fd
->buffer
->position
))))
1633 fd
->abspos
+= fd
->buffer
->position
;
1634 fd
->buffer
->bufstart
= fd
->abspos
;
1635 fd
->buffer
->position
= 0;
1636 fd
->buffer
->filled
= 0;
1637 fd
->buffer
->left
= fd
->buffer
->size
;
1641 fd
->state
= FIO_failed
;
1650 ReadNBytes - reads nBytes of a file into memory area, dest, returning
1651 the number of bytes actually read.
1652 This function will consume from the buffer and then
1653 perform direct libc reads. It is ideal for large reads.
1656 extern "C" unsigned int FIO_ReadNBytes (FIO_File f
, unsigned int nBytes
, void * dest
)
1658 typedef char *ReadNBytes__T2
;
1665 CheckAccess (f
, FIO_openedforread
, false);
1666 n
= ReadFromBuffer (f
, dest
, nBytes
);
1673 p
= static_cast<ReadNBytes__T2
> (dest
);
1675 SetEndOfLine (f
, (*p
));
1683 /* static analysis guarentees a RETURN statement will be used before here. */
1684 __builtin_unreachable ();
1689 ReadAny - reads HIGH (a) + 1 bytes into, a. All input
1690 is fully buffered, unlike ReadNBytes and thus is more
1691 suited to small reads.
1694 extern "C" void FIO_ReadAny (FIO_File f
, unsigned char *a
, unsigned int _a_high
)
1696 CheckAccess (f
, FIO_openedforread
, false);
1697 if ((BufferedRead (f
, _a_high
+1, a
)) == ((int ) (_a_high
+1)))
1699 SetEndOfLine (f
, static_cast<char> (a
[_a_high
]));
1705 WriteNBytes - writes nBytes from memory area src to a file
1706 returning the number of bytes actually written.
1707 This function will flush the buffer and then
1708 write the nBytes using a direct write from libc.
1709 It is ideal for large writes.
1712 extern "C" unsigned int FIO_WriteNBytes (FIO_File f
, unsigned int nBytes
, void * src
)
1715 FIO_FileDescriptor fd
;
1717 CheckAccess (f
, FIO_openedforwrite
, true);
1718 FIO_FlushBuffer (f
);
1721 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1724 total
= static_cast<int> (libc_write (fd
->unixfd
, src
, static_cast<size_t> ((int ) (nBytes
))));
1727 fd
->state
= FIO_failed
;
1732 fd
->abspos
+= (unsigned int ) (total
);
1733 if (fd
->buffer
!= NULL
)
1735 fd
->buffer
->bufstart
= fd
->abspos
;
1737 return (unsigned int ) (total
);
1742 /* static analysis guarentees a RETURN statement will be used before here. */
1743 __builtin_unreachable ();
1748 WriteAny - writes HIGH (a) + 1 bytes onto, file, f. All output
1749 is fully buffered, unlike WriteNBytes and thus is more
1750 suited to small writes.
1753 extern "C" void FIO_WriteAny (FIO_File f
, unsigned char *a
, unsigned int _a_high
)
1755 CheckAccess (f
, FIO_openedforwrite
, true);
1756 if ((BufferedWrite (f
, _a_high
+1, a
)) == ((int ) (_a_high
+1)))
1762 WriteChar - writes a single character to file, f.
1765 extern "C" void FIO_WriteChar (FIO_File f
, char ch
)
1767 CheckAccess (f
, FIO_openedforwrite
, true);
1768 if ((BufferedWrite (f
, sizeof (ch
), &ch
)) == ((int ) (sizeof (ch
))))
1774 EOF - tests to see whether a file, f, has reached end of file.
1777 extern "C" bool FIO_EOF (FIO_File f
)
1779 FIO_FileDescriptor fd
;
1781 CheckAccess (f
, FIO_openedforread
, false);
1784 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1787 return fd
->state
== FIO_endoffile
;
1791 /* static analysis guarentees a RETURN statement will be used before here. */
1792 __builtin_unreachable ();
1797 EOLN - tests to see whether a file, f, is upon a newline.
1798 It does NOT consume the newline.
1801 extern "C" bool FIO_EOLN (FIO_File f
)
1804 FIO_FileDescriptor fd
;
1806 CheckAccess (f
, FIO_openedforread
, false);
1808 we will read a character and then push it back onto the input stream,
1809 having noted the file status, we also reset the status.
1813 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1816 if ((fd
->state
== FIO_successful
) || (fd
->state
== FIO_endofline
))
1818 ch
= FIO_ReadChar (f
);
1819 if ((fd
->state
== FIO_successful
) || (fd
->state
== FIO_endofline
))
1821 FIO_UnReadChar (f
, ch
);
1823 return ch
== ASCII_nl
;
1828 /* static analysis guarentees a RETURN statement will be used before here. */
1829 __builtin_unreachable ();
1834 WasEOLN - tests to see whether a file, f, has just seen a newline.
1837 extern "C" bool FIO_WasEOLN (FIO_File f
)
1839 FIO_FileDescriptor fd
;
1841 CheckAccess (f
, FIO_openedforread
, false);
1848 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1849 return (fd
!= NULL
) && (fd
->state
== FIO_endofline
);
1851 /* static analysis guarentees a RETURN statement will be used before here. */
1852 __builtin_unreachable ();
1857 ReadChar - returns a character read from file f.
1858 Sensible to check with IsNoError or EOF after calling
1862 extern "C" char FIO_ReadChar (FIO_File f
)
1866 CheckAccess (f
, FIO_openedforread
, false);
1867 if ((BufferedRead (f
, sizeof (ch
), &ch
)) == ((int ) (sizeof (ch
))))
1869 SetEndOfLine (f
, ch
);
1876 /* static analysis guarentees a RETURN statement will be used before here. */
1877 __builtin_unreachable ();
1882 UnReadChar - replaces a character, ch, back into file f.
1883 This character must have been read by ReadChar
1884 and it does not allow successive calls. It may
1885 only be called if the previous read was successful
1886 or end of file was seen.
1887 If the state was previously endoffile then it
1888 is altered to successful.
1889 Otherwise it is left alone.
1892 extern "C" void FIO_UnReadChar (FIO_File f
, char ch
)
1894 FIO_FileDescriptor fd
;
1899 CheckAccess (f
, FIO_openedforread
, false);
1902 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1903 if (((fd
->state
== FIO_successful
) || (fd
->state
== FIO_endoffile
)) || (fd
->state
== FIO_endofline
))
1905 /* avoid dangling else. */
1906 if ((fd
->buffer
!= NULL
) && fd
->buffer
->valid
)
1908 /* we assume that a ReadChar has occurred, we will check just in case. */
1909 if (fd
->state
== FIO_endoffile
)
1911 fd
->buffer
->position
= MaxBufferLength
;
1912 fd
->buffer
->left
= 0;
1913 fd
->buffer
->filled
= 0;
1914 fd
->state
= FIO_successful
;
1916 if (fd
->buffer
->position
> 0)
1918 fd
->buffer
->position
-= 1;
1919 fd
->buffer
->left
+= 1;
1920 (*fd
->buffer
->contents
).array
[fd
->buffer
->position
] = ch
;
1924 /* if possible make room and store ch */
1925 if (fd
->buffer
->filled
== fd
->buffer
->size
)
1927 FormatError1 ((const char *) "performing too many UnReadChar calls on file (%d)\\n", 51, (const unsigned char *) &f
, (sizeof (f
)-1));
1931 n
= fd
->buffer
->filled
-fd
->buffer
->position
;
1932 b
= &(*fd
->buffer
->contents
).array
[fd
->buffer
->position
];
1933 a
= &(*fd
->buffer
->contents
).array
[fd
->buffer
->position
+1];
1934 a
= libc_memcpy (a
, b
, static_cast<size_t> (n
));
1935 fd
->buffer
->filled
+= 1;
1936 (*fd
->buffer
->contents
).array
[fd
->buffer
->position
] = ch
;
1943 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));
1950 WriteLine - writes out a linefeed to file, f.
1953 extern "C" void FIO_WriteLine (FIO_File f
)
1955 FIO_WriteChar (f
, ASCII_nl
);
1960 WriteString - writes a string to file, f.
1963 extern "C" void FIO_WriteString (FIO_File f
, const char *a_
, unsigned int _a_high
)
1968 /* make a local copy of each unbounded array. */
1969 memcpy (a
, a_
, _a_high
+1);
1971 l
= StrLib_StrLen ((const char *) a
, _a_high
);
1972 if ((FIO_WriteNBytes (f
, l
, &a
)) != l
)
1978 ReadString - reads a string from file, f, into string, a.
1979 It terminates the string if HIGH is reached or
1980 if a newline is seen or an error occurs.
1983 extern "C" void FIO_ReadString (FIO_File f
, char *a
, unsigned int _a_high
)
1989 CheckAccess (f
, FIO_openedforread
, false);
1993 ch
= FIO_ReadChar (f
);
1996 /* avoid gcc warning by using compound statement even if not strictly necessary. */
1997 if (((ch
== ASCII_nl
) || (! (FIO_IsNoError (f
)))) || (FIO_EOF (f
)))
2008 } while (! ((((ch
== ASCII_nl
) || (i
> high
)) || (! (FIO_IsNoError (f
)))) || (FIO_EOF (f
))));
2013 WriteCardinal - writes a CARDINAL to file, f.
2014 It writes the binary image of the cardinal
2018 extern "C" void FIO_WriteCardinal (FIO_File f
, unsigned int c
)
2020 FIO_WriteAny (f
, (unsigned char *) &c
, (sizeof (c
)-1));
2025 ReadCardinal - reads a CARDINAL from file, f.
2026 It reads a binary image of a CARDINAL
2030 extern "C" unsigned int FIO_ReadCardinal (FIO_File f
)
2034 FIO_ReadAny (f
, (unsigned char *) &c
, (sizeof (c
)-1));
2036 /* static analysis guarentees a RETURN statement will be used before here. */
2037 __builtin_unreachable ();
2042 GetUnixFileDescriptor - returns the UNIX file descriptor of a file.
2045 extern "C" int FIO_GetUnixFileDescriptor (FIO_File f
)
2047 FIO_FileDescriptor fd
;
2051 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
2057 FormatError1 ((const char *) "file %d has not been opened or is out of range\\n", 48, (const unsigned char *) &f
, (sizeof (f
)-1));
2059 /* static analysis guarentees a RETURN statement will be used before here. */
2060 __builtin_unreachable ();
2065 SetPositionFromBeginning - sets the position from the beginning of the file.
2068 extern "C" void FIO_SetPositionFromBeginning (FIO_File f
, long int pos
)
2071 FIO_FileDescriptor fd
;
2075 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
2078 /* always force the lseek, until we are confident that abspos is always correct,
2079 basically it needs some hard testing before we should remove the OR TRUE. */
2080 if ((fd
->abspos
!= pos
) || true)
2082 FIO_FlushBuffer (f
);
2083 if (fd
->buffer
!= NULL
)
2087 fd
->buffer
->left
= fd
->buffer
->size
;
2091 fd
->buffer
->left
= 0;
2093 fd
->buffer
->position
= 0;
2094 fd
->buffer
->filled
= 0;
2096 offset
= libc_lseek (fd
->unixfd
, pos
, SEEK_SET
);
2097 if ((offset
>= 0) && (pos
== offset
))
2103 fd
->state
= FIO_failed
;
2106 if (fd
->buffer
!= NULL
)
2108 fd
->buffer
->valid
= false;
2109 fd
->buffer
->bufstart
= fd
->abspos
;
2118 SetPositionFromEnd - sets the position from the end of the file.
2121 extern "C" void FIO_SetPositionFromEnd (FIO_File f
, long int pos
)
2124 FIO_FileDescriptor fd
;
2128 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
2131 FIO_FlushBuffer (f
);
2132 if (fd
->buffer
!= NULL
)
2136 fd
->buffer
->left
= fd
->buffer
->size
;
2140 fd
->buffer
->left
= 0;
2142 fd
->buffer
->position
= 0;
2143 fd
->buffer
->filled
= 0;
2145 offset
= libc_lseek (fd
->unixfd
, pos
, SEEK_END
);
2148 fd
->abspos
= offset
;
2152 fd
->state
= FIO_failed
;
2156 if (fd
->buffer
!= NULL
)
2158 fd
->buffer
->valid
= false;
2159 fd
->buffer
->bufstart
= offset
;
2167 FindPosition - returns the current absolute position in file, f.
2170 extern "C" long int FIO_FindPosition (FIO_File f
)
2172 FIO_FileDescriptor fd
;
2176 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
2179 if ((fd
->buffer
== NULL
) || ! fd
->buffer
->valid
)
2185 return fd
->buffer
->bufstart
+((long int ) (fd
->buffer
->position
));
2190 /* static analysis guarentees a RETURN statement will be used before here. */
2191 __builtin_unreachable ();
2196 GetFileName - assigns, a, with the filename associated with, f.
2199 extern "C" void FIO_GetFileName (FIO_File f
, char *a
, unsigned int _a_high
)
2201 typedef char *GetFileName__T6
;
2205 FIO_FileDescriptor fd
;
2209 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
2212 FormatError ((const char *) "this file has probably been closed and not reopened successfully or alternatively never opened\\n", 96);
2214 __builtin_unreachable ();
2218 if (fd
->name
.address
== NULL
)
2220 StrLib_StrCopy ((const char *) "", 0, (char *) a
, _a_high
);
2224 p
= static_cast<GetFileName__T6
> (fd
->name
.address
);
2226 while (((*p
) != ASCII_nul
) && (i
<= _a_high
))
2239 getFileName - returns the address of the filename associated with, f.
2242 extern "C" void * FIO_getFileName (FIO_File f
)
2244 FIO_FileDescriptor fd
;
2248 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
2251 FormatError ((const char *) "this file has probably been closed and not reopened successfully or alternatively never opened\\n", 96);
2253 __builtin_unreachable ();
2257 return fd
->name
.address
;
2261 /* static analysis guarentees a RETURN statement will be used before here. */
2262 __builtin_unreachable ();
2267 getFileNameLength - returns the number of characters associated with filename, f.
2270 extern "C" unsigned int FIO_getFileNameLength (FIO_File f
)
2272 FIO_FileDescriptor fd
;
2276 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
2279 FormatError ((const char *) "this file has probably been closed and not reopened successfully or alternatively never opened\\n", 96);
2281 __builtin_unreachable ();
2285 return fd
->name
.size
;
2289 /* static analysis guarentees a RETURN statement will be used before here. */
2290 __builtin_unreachable ();
2295 FlushOutErr - flushes, StdOut, and, StdErr.
2296 It is also called when the application calls M2RTS.Terminate.
2297 (which is automatically placed in program modules by the GM2
2301 extern "C" void FIO_FlushOutErr (void)
2303 if (FIO_IsNoError (FIO_StdOut
))
2305 FIO_FlushBuffer (FIO_StdOut
);
2307 if (FIO_IsNoError (FIO_StdErr
))
2309 FIO_FlushBuffer (FIO_StdErr
);
2313 extern "C" void _M2_FIO_init (__attribute__((unused
)) int argc
,__attribute__((unused
)) char *argv
[],__attribute__((unused
)) char *envp
[])
2318 extern "C" void _M2_FIO_fini (__attribute__((unused
)) int argc
,__attribute__((unused
)) char *argv
[],__attribute__((unused
)) char *envp
[])