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-2025 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"
59 # include "GIndexing.h"
64 typedef unsigned int FIO_File
;
66 # define MaxBufferLength (1024*16)
67 # define MaxErrorString (1024*8)
68 # define CreatePermissions 0666
69 typedef struct FIO_NameInfo_r FIO_NameInfo
;
71 typedef struct FIO_buf_r FIO_buf
;
73 typedef FIO_buf
*FIO_Buffer
;
75 typedef struct FIO_fds_r FIO_fds
;
77 typedef FIO_fds
*FIO_FileDescriptor
;
79 typedef struct FIO__T7_a FIO__T7
;
81 typedef char *FIO_PtrToChar
;
83 typedef enum {FIO_successful
, FIO_outofmemory
, FIO_toomanyfilesopen
, FIO_failed
, FIO_connectionfailure
, FIO_endofline
, FIO_endoffile
} FIO_FileStatus
;
85 typedef enum {FIO_unused
, FIO_openedforread
, FIO_openedforwrite
, FIO_openedforrandom
} FIO_FileUsage
;
87 struct FIO_NameInfo_r
{
95 unsigned int position
;
103 struct FIO__T7_a
{ char array
[MaxBufferLength
+1]; };
107 FIO_FileStatus state
;
114 static Indexing_Index FileInfo
;
115 static FIO_File Error
;
118 IsNoError - returns a TRUE if no error has occured on file, f.
121 extern "C" bool FIO_IsNoError (FIO_File f
);
124 IsActive - returns TRUE if the file, f, is still active.
127 extern "C" bool FIO_IsActive (FIO_File f
);
128 extern "C" bool FIO_Exists (const char *fname_
, unsigned int _fname_high
);
129 extern "C" FIO_File
FIO_OpenToRead (const char *fname_
, unsigned int _fname_high
);
130 extern "C" FIO_File
FIO_OpenToWrite (const char *fname_
, unsigned int _fname_high
);
131 extern "C" FIO_File
FIO_OpenForRandom (const char *fname_
, unsigned int _fname_high
, bool towrite
, bool newfile
);
134 Close - close a file which has been previously opened using:
135 OpenToRead, OpenToWrite, OpenForRandom.
136 It is correct to close a file which has an error status.
139 extern "C" void FIO_Close (FIO_File f
);
142 exists - returns TRUE if a file named, fname exists for reading.
145 extern "C" bool FIO_exists (void * fname
, unsigned int flength
);
148 openToRead - attempts to open a file, fname, for reading and
149 it returns this file.
150 The success of this operation can be checked by
154 extern "C" FIO_File
FIO_openToRead (void * fname
, unsigned int flength
);
157 openToWrite - attempts to open a file, fname, for write and
158 it returns this file.
159 The success of this operation can be checked by
163 extern "C" FIO_File
FIO_openToWrite (void * fname
, unsigned int flength
);
166 openForRandom - attempts to open a file, fname, for random access
167 read or write and it returns this file.
168 The success of this operation can be checked by
170 towrite, determines whether the file should be
171 opened for writing or reading.
174 extern "C" FIO_File
FIO_openForRandom (void * fname
, unsigned int flength
, bool towrite
, bool newfile
);
177 FlushBuffer - flush contents of file, f.
180 extern "C" void FIO_FlushBuffer (FIO_File f
);
183 ReadNBytes - reads nBytes of a file into memory area, dest, returning
184 the number of bytes actually read.
185 This function will consume from the buffer and then
186 perform direct libc reads. It is ideal for large reads.
189 extern "C" unsigned int FIO_ReadNBytes (FIO_File f
, unsigned int nBytes
, void * dest
);
192 ReadAny - reads HIGH (a) + 1 bytes into, a. All input
193 is fully buffered, unlike ReadNBytes and thus is more
194 suited to small reads.
197 extern "C" void FIO_ReadAny (FIO_File f
, unsigned char *a
, unsigned int _a_high
);
200 WriteNBytes - writes nBytes from memory area src to a file
201 returning the number of bytes actually written.
202 This function will flush the buffer and then
203 write the nBytes using a direct write from libc.
204 It is ideal for large writes.
207 extern "C" unsigned int FIO_WriteNBytes (FIO_File f
, unsigned int nBytes
, void * src
);
210 WriteAny - writes HIGH (a) + 1 bytes onto, file, f. All output
211 is fully buffered, unlike WriteNBytes and thus is more
212 suited to small writes.
215 extern "C" void FIO_WriteAny (FIO_File f
, unsigned char *a
, unsigned int _a_high
);
218 WriteChar - writes a single character to file, f.
221 extern "C" void FIO_WriteChar (FIO_File f
, char ch
);
224 EOF - tests to see whether a file, f, has reached end of file.
227 extern "C" bool FIO_EOF (FIO_File f
);
230 EOLN - tests to see whether a file, f, is upon a newline.
231 It does NOT consume the newline.
234 extern "C" bool FIO_EOLN (FIO_File f
);
237 WasEOLN - tests to see whether a file, f, has just seen a newline.
240 extern "C" bool FIO_WasEOLN (FIO_File f
);
243 ReadChar - returns a character read from file f.
244 Sensible to check with IsNoError or EOF after calling
248 extern "C" char FIO_ReadChar (FIO_File f
);
251 UnReadChar - replaces a character, ch, back into file f.
252 This character must have been read by ReadChar
253 and it does not allow successive calls. It may
254 only be called if the previous read was successful
255 or end of file was seen.
256 If the state was previously endoffile then it
257 is altered to successful.
258 Otherwise it is left alone.
261 extern "C" void FIO_UnReadChar (FIO_File f
, char ch
);
264 WriteLine - writes out a linefeed to file, f.
267 extern "C" void FIO_WriteLine (FIO_File f
);
270 WriteString - writes a string to file, f.
273 extern "C" void FIO_WriteString (FIO_File f
, const char *a_
, unsigned int _a_high
);
276 ReadString - reads a string from file, f, into string, a.
277 It terminates the string if HIGH is reached or
278 if a newline is seen or an error occurs.
281 extern "C" void FIO_ReadString (FIO_File f
, char *a
, unsigned int _a_high
);
284 WriteCardinal - writes a CARDINAL to file, f.
285 It writes the binary image of the cardinal
289 extern "C" void FIO_WriteCardinal (FIO_File f
, unsigned int c
);
292 ReadCardinal - reads a CARDINAL from file, f.
293 It reads a binary image of a CARDINAL
297 extern "C" unsigned int FIO_ReadCardinal (FIO_File f
);
300 GetUnixFileDescriptor - returns the UNIX file descriptor of a file.
303 extern "C" int FIO_GetUnixFileDescriptor (FIO_File f
);
306 SetPositionFromBeginning - sets the position from the beginning of the file.
309 extern "C" void FIO_SetPositionFromBeginning (FIO_File f
, long int pos
);
312 SetPositionFromEnd - sets the position from the end of the file.
315 extern "C" void FIO_SetPositionFromEnd (FIO_File f
, long int pos
);
318 FindPosition - returns the current absolute position in file, f.
321 extern "C" long int FIO_FindPosition (FIO_File f
);
324 GetFileName - assigns, a, with the filename associated with, f.
327 extern "C" void FIO_GetFileName (FIO_File f
, char *a
, unsigned int _a_high
);
330 getFileName - returns the address of the filename associated with, f.
333 extern "C" void * FIO_getFileName (FIO_File f
);
336 getFileNameLength - returns the number of characters associated with filename, f.
339 extern "C" unsigned int FIO_getFileNameLength (FIO_File f
);
342 FlushOutErr - flushes, StdOut, and, StdErr.
343 It is also called when the application calls M2RTS.Terminate.
344 (which is automatically placed in program modules by the GM2
348 extern "C" void FIO_FlushOutErr (void);
351 Max - returns the maximum of two values.
354 static unsigned int Max (unsigned int a
, unsigned int b
);
357 Min - returns the minimum of two values.
360 static unsigned int Min (unsigned int a
, unsigned int b
);
363 GetNextFreeDescriptor - returns the index to the FileInfo array indicating
367 static FIO_File
GetNextFreeDescriptor (void);
370 SetState - sets the field, state, of file, f, to, s.
373 static void SetState (FIO_File f
, FIO_FileStatus s
);
376 InitializeFile - initialize a file descriptor
379 static FIO_File
InitializeFile (FIO_File f
, void * fname
, unsigned int flength
, FIO_FileStatus fstate
, FIO_FileUsage use
, bool towrite
, unsigned int buflength
);
382 ConnectToUnix - connects a FIO file to a UNIX file descriptor.
385 static void ConnectToUnix (FIO_File f
, bool towrite
, bool newfile
);
388 ReadFromBuffer - attempts to read, nBytes, from file, f.
389 It firstly consumes the buffer and then performs
390 direct unbuffered reads. This should only be used
391 when wishing to read large files.
393 The actual number of bytes read is returned.
394 -1 is returned if EOF is reached.
397 static int ReadFromBuffer (FIO_File f
, void * a
, unsigned int nBytes
);
400 BufferedRead - will read, nBytes, through the buffer.
401 Similar to ReadFromBuffer, but this function will always
402 read into the buffer before copying into memory.
404 Useful when performing small reads.
407 static int BufferedRead (FIO_File f
, unsigned int nBytes
, void * dest
);
410 HandleEscape - translates
411 and \t into their respective ascii codes.
414 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
);
420 static void Cast (unsigned char *a
, unsigned int _a_high
, const unsigned char *b_
, unsigned int _b_high
);
423 StringFormat1 - converts string, src, into, dest, together with encapsulated
424 entity, w. It only formats the first %s or %d with n.
427 static void StringFormat1 (char *dest
, unsigned int _dest_high
, const char *src_
, unsigned int _src_high
, const unsigned char *w_
, unsigned int _w_high
);
430 FormatError - provides a orthoganal counterpart to the procedure below.
433 static void FormatError (const char *a_
, unsigned int _a_high
);
436 FormatError1 - generic error procedure taking standard format string
437 and single parameter.
440 static void FormatError1 (const char *a_
, unsigned int _a_high
, const unsigned char *w_
, unsigned int _w_high
);
443 FormatError2 - generic error procedure taking standard format string
447 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
);
450 CheckAccess - checks to see whether a file f has been
451 opened for read/write.
454 static void CheckAccess (FIO_File f
, FIO_FileUsage use
, bool towrite
);
460 static void SetEndOfLine (FIO_File f
, char ch
);
463 BufferedWrite - will write, nBytes, through the buffer.
464 Similar to WriteNBytes, but this function will always
465 write into the buffer before copying into memory.
467 Useful when performing small writes.
470 static int BufferedWrite (FIO_File f
, unsigned int nBytes
, void * src
);
473 PreInitialize - preinitialize the file descriptor.
476 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
);
479 Init - initialize the modules, global variables.
482 static void Init (void);
486 Max - returns the maximum of two values.
489 static unsigned int Max (unsigned int a
, unsigned int b
)
499 /* static analysis guarentees a RETURN statement will be used before here. */
500 __builtin_unreachable ();
505 Min - returns the minimum of two values.
508 static unsigned int Min (unsigned int a
, unsigned int b
)
518 /* static analysis guarentees a RETURN statement will be used before here. */
519 __builtin_unreachable ();
524 GetNextFreeDescriptor - returns the index to the FileInfo array indicating
528 static FIO_File
GetNextFreeDescriptor (void)
532 FIO_FileDescriptor fd
;
535 h
= Indexing_HighIndice (FileInfo
);
540 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
549 Indexing_PutIndice (FileInfo
, f
, NULL
); /* create new slot */
550 return f
; /* create new slot */
553 ReturnException ("../../gcc/m2/gm2-libs/FIO.def", 25, 1);
554 __builtin_unreachable ();
559 SetState - sets the field, state, of file, f, to, s.
562 static void SetState (FIO_File f
, FIO_FileStatus s
)
564 FIO_FileDescriptor fd
;
566 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
572 InitializeFile - initialize a file descriptor
575 static FIO_File
InitializeFile (FIO_File f
, void * fname
, unsigned int flength
, FIO_FileStatus fstate
, FIO_FileUsage use
, bool towrite
, unsigned int buflength
)
578 FIO_FileDescriptor fd
;
580 Storage_ALLOCATE ((void **) &fd
, sizeof (FIO_fds
));
583 SetState (Error
, FIO_outofmemory
);
588 Indexing_PutIndice (FileInfo
, f
, reinterpret_cast <void *> (fd
));
589 fd
->name
.size
= flength
+1; /* need to guarantee the nul for C */
590 fd
->usage
= use
; /* need to guarantee the nul for C */
591 fd
->output
= towrite
;
592 Storage_ALLOCATE (&fd
->name
.address
, fd
->name
.size
);
593 if (fd
->name
.address
== NULL
)
595 fd
->state
= FIO_outofmemory
;
598 fd
->name
.address
= libc_strncpy (fd
->name
.address
, fname
, flength
);
599 /* and assign nul to the last byte */
600 p
= static_cast<FIO_PtrToChar
> (fd
->name
.address
);
604 /* now for the buffer */
605 Storage_ALLOCATE ((void **) &fd
->buffer
, sizeof (FIO_buf
));
606 if (fd
->buffer
== NULL
)
608 SetState (Error
, FIO_outofmemory
);
613 fd
->buffer
->valid
= false;
614 fd
->buffer
->bufstart
= 0;
615 fd
->buffer
->size
= buflength
;
616 fd
->buffer
->position
= 0;
617 fd
->buffer
->filled
= 0;
618 if (fd
->buffer
->size
== 0)
620 fd
->buffer
->address
= NULL
;
624 Storage_ALLOCATE (&fd
->buffer
->address
, fd
->buffer
->size
);
625 if (fd
->buffer
->address
== NULL
)
627 fd
->state
= FIO_outofmemory
;
633 fd
->buffer
->left
= fd
->buffer
->size
;
637 fd
->buffer
->left
= 0;
639 fd
->buffer
->contents
= static_cast<FIO__T7
*> (fd
->buffer
->address
); /* provides easy access for reading characters */
640 fd
->state
= fstate
; /* provides easy access for reading characters */
644 /* static analysis guarentees a RETURN statement will be used before here. */
645 __builtin_unreachable ();
650 ConnectToUnix - connects a FIO file to a UNIX file descriptor.
653 static void ConnectToUnix (FIO_File f
, bool towrite
, bool newfile
)
655 FIO_FileDescriptor fd
;
659 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
666 fd
->unixfd
= libc_creat (fd
->name
.address
, CreatePermissions
);
670 fd
->unixfd
= libc_open (fd
->name
.address
, (int ) (wrapc_WriteOnly ()), 0);
675 fd
->unixfd
= libc_open (fd
->name
.address
, (int ) (wrapc_ReadOnly ()), 0);
679 fd
->state
= FIO_connectionfailure
;
687 ReadFromBuffer - attempts to read, nBytes, from file, f.
688 It firstly consumes the buffer and then performs
689 direct unbuffered reads. This should only be used
690 when wishing to read large files.
692 The actual number of bytes read is returned.
693 -1 is returned if EOF is reached.
696 static int ReadFromBuffer (FIO_File f
, void * a
, unsigned int nBytes
)
698 typedef unsigned char *ReadFromBuffer__T1
;
704 ReadFromBuffer__T1 p
;
705 FIO_FileDescriptor fd
;
709 total
= 0; /* how many bytes have we read */
710 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
)); /* how many bytes have we read */
711 /* extract from the buffer first */
712 if ((fd
->buffer
!= NULL
) && fd
->buffer
->valid
)
714 if (fd
->buffer
->left
> 0)
716 /* avoid gcc warning by using compound statement even if not strictly necessary. */
719 /* too expensive to call memcpy for 1 character */
720 p
= static_cast<ReadFromBuffer__T1
> (a
);
721 (*p
) = static_cast<unsigned char> ((*fd
->buffer
->contents
).array
[fd
->buffer
->position
]);
722 fd
->buffer
->left
-= 1; /* remove consumed bytes */
723 fd
->buffer
->position
+= 1; /* move onwards n bytes */
724 nBytes
= 0; /* reduce the amount for future direct */
730 n
= Min (fd
->buffer
->left
, nBytes
);
731 t
= fd
->buffer
->address
;
732 t
= reinterpret_cast<void *> (reinterpret_cast<char *> (t
)+fd
->buffer
->position
);
733 p
= static_cast<ReadFromBuffer__T1
> (libc_memcpy (a
, t
, static_cast<size_t> (n
)));
734 fd
->buffer
->left
-= n
; /* remove consumed bytes */
735 fd
->buffer
->position
+= n
; /* move onwards n bytes */
736 /* move onwards ready for direct reads */
737 a
= reinterpret_cast<void *> (reinterpret_cast<char *> (a
)+n
);
738 nBytes
-= n
; /* reduce the amount for future direct */
741 return total
; /* much cleaner to return now, */
743 /* difficult to record an error if */
745 /* the read below returns -1 */
749 /* still more to read */
750 result
= static_cast<int> (libc_read (fd
->unixfd
, a
, static_cast<size_t> ((int ) (nBytes
))));
753 /* avoid dangling else. */
755 fd
->abspos
+= result
;
756 /* now disable the buffer as we read directly into, a. */
757 if (fd
->buffer
!= NULL
)
759 fd
->buffer
->valid
= false;
767 fd
->state
= FIO_endoffile
;
771 fd
->state
= FIO_failed
;
773 /* indicate buffer is empty */
774 if (fd
->buffer
!= NULL
)
776 fd
->buffer
->valid
= false;
777 fd
->buffer
->left
= 0;
778 fd
->buffer
->position
= 0;
779 if (fd
->buffer
->address
!= NULL
)
781 (*fd
->buffer
->contents
).array
[fd
->buffer
->position
] = ASCII_nul
;
793 /* static analysis guarentees a RETURN statement will be used before here. */
794 __builtin_unreachable ();
799 BufferedRead - will read, nBytes, through the buffer.
800 Similar to ReadFromBuffer, but this function will always
801 read into the buffer before copying into memory.
803 Useful when performing small reads.
806 static int BufferedRead (FIO_File f
, unsigned int nBytes
, void * dest
)
808 typedef unsigned char *BufferedRead__T3
;
814 FIO_FileDescriptor fd
;
818 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
819 total
= 0; /* how many bytes have we read */
820 if (fd
!= NULL
) /* how many bytes have we read */
822 /* extract from the buffer first */
823 if (fd
->buffer
!= NULL
)
827 if ((fd
->buffer
->left
> 0) && fd
->buffer
->valid
)
831 /* too expensive to call memcpy for 1 character */
832 p
= static_cast<BufferedRead__T3
> (dest
);
833 (*p
) = static_cast<unsigned char> ((*fd
->buffer
->contents
).array
[fd
->buffer
->position
]);
834 fd
->buffer
->left
-= 1; /* remove consumed byte */
835 fd
->buffer
->position
+= 1; /* move onwards n byte */
836 total
+= 1; /* move onwards n byte */
841 n
= Min (fd
->buffer
->left
, nBytes
);
842 src
= fd
->buffer
->address
;
843 src
= reinterpret_cast<void *> (reinterpret_cast<char *> (src
)+fd
->buffer
->position
);
844 p
= static_cast<BufferedRead__T3
> (libc_memcpy (dest
, src
, static_cast<size_t> (n
)));
845 fd
->buffer
->left
-= n
; /* remove consumed bytes */
846 fd
->buffer
->position
+= n
; /* move onwards n bytes */
847 /* move onwards ready for direct reads */
848 dest
= reinterpret_cast<void *> (reinterpret_cast<char *> (dest
)+n
);
849 nBytes
-= n
; /* reduce the amount for future direct */
857 n
= static_cast<int> (libc_read (fd
->unixfd
, fd
->buffer
->address
, static_cast<size_t> (fd
->buffer
->size
)));
860 /* avoid dangling else. */
861 fd
->buffer
->valid
= true;
862 fd
->buffer
->position
= 0;
863 fd
->buffer
->left
= n
;
864 fd
->buffer
->filled
= n
;
865 fd
->buffer
->bufstart
= fd
->abspos
;
870 fd
->state
= FIO_endoffile
;
876 fd
->buffer
->valid
= false;
877 fd
->buffer
->position
= 0;
878 fd
->buffer
->left
= 0;
879 fd
->buffer
->filled
= 0;
880 fd
->state
= FIO_failed
;
890 /* static analysis guarentees a RETURN statement will be used before here. */
891 __builtin_unreachable ();
896 HandleEscape - translates
897 and \t into their respective ascii codes.
900 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
)
902 char src
[_src_high
+1];
904 /* make a local copy of each unbounded array. */
905 memcpy (src
, src_
, _src_high
+1);
907 if (((((*i
)+1) < HighSrc
) && (src
[(*i
)] == '\\')) && ((*j
) < HighDest
))
909 /* avoid gcc warning by using compound statement even if not strictly necessary. */
910 if (src
[(*i
)+1] == 'n')
912 /* requires a newline */
913 const_cast<char *>(dest
)[(*j
)] = ASCII_nl
;
917 else if (src
[(*i
)+1] == 't')
919 /* avoid dangling else. */
920 /* requires a tab (yuck) tempted to fake this but I better not.. */
921 const_cast<char *>(dest
)[(*j
)] = ASCII_tab
;
927 /* avoid dangling else. */
928 /* copy escaped character */
930 const_cast<char *>(dest
)[(*j
)] = src
[(*i
)];
942 static void Cast (unsigned char *a
, unsigned int _a_high
, const unsigned char *b_
, unsigned int _b_high
)
945 unsigned char b
[_b_high
+1];
947 /* make a local copy of each unbounded array. */
948 memcpy (b
, b_
, _b_high
+1);
950 if (_a_high
== _b_high
)
952 for (i
=0; i
<=_a_high
; i
++)
954 const_cast<unsigned char *>(a
)[i
] = b
[i
];
959 FormatError ((const char *) "cast failed", 11);
965 StringFormat1 - converts string, src, into, dest, together with encapsulated
966 entity, w. It only formats the first %s or %d with n.
969 static void StringFormat1 (char *dest
, unsigned int _dest_high
, const char *src_
, unsigned int _src_high
, const unsigned char *w_
, unsigned int _w_high
)
971 typedef struct StringFormat1__T8_a StringFormat1__T8
;
973 typedef char *StringFormat1__T4
;
975 struct StringFormat1__T8_a
{ char array
[MaxErrorString
+1]; };
976 unsigned int HighSrc
;
977 unsigned int HighDest
;
981 StringFormat1__T8 str
;
983 char src
[_src_high
+1];
984 unsigned char w
[_w_high
+1];
986 /* make a local copy of each unbounded array. */
987 memcpy (src
, src_
, _src_high
+1);
988 memcpy (w
, w_
, _w_high
+1);
990 HighSrc
= StrLib_StrLen ((const char *) src
, _src_high
);
991 HighDest
= _dest_high
;
996 while ((((i
< HighSrc
) && (src
[i
] != ASCII_nul
)) && (j
< HighDest
)) && (src
[i
] != '%'))
1000 HandleEscape ((char *) dest
, _dest_high
, (const char *) src
, _src_high
, &i
, &j
, HighSrc
, HighDest
);
1004 const_cast<char *>(dest
)[j
] = src
[i
];
1009 if ((((i
+1) < HighSrc
) && (src
[i
] == '%')) && (j
< HighDest
))
1011 /* avoid gcc warning by using compound statement even if not strictly necessary. */
1012 if (src
[i
+1] == 's')
1014 Cast ((unsigned char *) &p
, (sizeof (p
)-1), (const unsigned char *) w
, _w_high
);
1015 while ((j
< HighDest
) && ((*p
) != ASCII_nul
))
1017 const_cast<char *>(dest
)[j
] = (*p
);
1023 const_cast<char *>(dest
)[j
] = ASCII_nul
;
1025 j
= StrLib_StrLen ((const char *) dest
, _dest_high
);
1028 else if (src
[i
+1] == 'd')
1030 /* avoid dangling else. */
1031 const_cast<char *>(dest
)[j
] = ASCII_nul
;
1032 Cast ((unsigned char *) &c
, (sizeof (c
)-1), (const unsigned char *) w
, _w_high
);
1033 NumberIO_CardToStr (c
, 0, (char *) &str
.array
[0], MaxErrorString
);
1034 StrLib_StrConCat ((const char *) dest
, _dest_high
, (const char *) &str
.array
[0], MaxErrorString
, (char *) dest
, _dest_high
);
1035 j
= StrLib_StrLen ((const char *) dest
, _dest_high
);
1040 /* avoid dangling else. */
1041 const_cast<char *>(dest
)[j
] = src
[i
];
1046 /* and finish off copying src into dest */
1047 while (((i
< HighSrc
) && (src
[i
] != ASCII_nul
)) && (j
< HighDest
))
1051 HandleEscape ((char *) dest
, _dest_high
, (const char *) src
, _src_high
, &i
, &j
, HighSrc
, HighDest
);
1055 const_cast<char *>(dest
)[j
] = src
[i
];
1062 const_cast<char *>(dest
)[j
] = ASCII_nul
;
1068 FormatError - provides a orthoganal counterpart to the procedure below.
1071 static void FormatError (const char *a_
, unsigned int _a_high
)
1075 /* make a local copy of each unbounded array. */
1076 memcpy (a
, a_
, _a_high
+1);
1078 FIO_WriteString (FIO_StdErr
, (const char *) a
, _a_high
);
1083 FormatError1 - generic error procedure taking standard format string
1084 and single parameter.
1087 static void FormatError1 (const char *a_
, unsigned int _a_high
, const unsigned char *w_
, unsigned int _w_high
)
1089 typedef struct FormatError1__T9_a FormatError1__T9
;
1091 struct FormatError1__T9_a
{ char array
[MaxErrorString
+1]; };
1094 unsigned char w
[_w_high
+1];
1096 /* make a local copy of each unbounded array. */
1097 memcpy (a
, a_
, _a_high
+1);
1098 memcpy (w
, w_
, _w_high
+1);
1100 StringFormat1 ((char *) &s
.array
[0], MaxErrorString
, (const char *) a
, _a_high
, (const unsigned char *) w
, _w_high
);
1101 FormatError ((const char *) &s
.array
[0], MaxErrorString
);
1106 FormatError2 - generic error procedure taking standard format string
1110 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
)
1112 typedef struct FormatError2__T10_a FormatError2__T10
;
1114 struct FormatError2__T10_a
{ char array
[MaxErrorString
+1]; };
1115 FormatError2__T10 s
;
1117 unsigned char w1
[_w1_high
+1];
1118 unsigned char w2
[_w2_high
+1];
1120 /* make a local copy of each unbounded array. */
1121 memcpy (a
, a_
, _a_high
+1);
1122 memcpy (w1
, w1_
, _w1_high
+1);
1123 memcpy (w2
, w2_
, _w2_high
+1);
1125 StringFormat1 ((char *) &s
.array
[0], MaxErrorString
, (const char *) a
, _a_high
, (const unsigned char *) w1
, _w1_high
);
1126 FormatError1 ((const char *) &s
.array
[0], MaxErrorString
, (const unsigned char *) w2
, _w2_high
);
1131 CheckAccess - checks to see whether a file f has been
1132 opened for read/write.
1135 static void CheckAccess (FIO_File f
, FIO_FileUsage use
, bool towrite
)
1137 FIO_FileDescriptor fd
;
1141 /* avoid dangling else. */
1142 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1145 if (f
!= FIO_StdErr
)
1147 FormatError ((const char *) "this file has probably been closed and not reopened successfully or alternatively never opened\\n", 96);
1150 __builtin_unreachable ();
1154 if ((use
== FIO_openedforwrite
) && (fd
->usage
== FIO_openedforread
))
1156 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));
1158 __builtin_unreachable ();
1160 else if ((use
== FIO_openedforread
) && (fd
->usage
== FIO_openedforwrite
))
1162 /* avoid dangling else. */
1163 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));
1165 __builtin_unreachable ();
1167 else if (fd
->state
== FIO_connectionfailure
)
1169 /* avoid dangling else. */
1170 FormatError1 ((const char *) "this file (%s) was not successfully opened\\n", 44, (const unsigned char *) &fd
->name
.address
, (sizeof (fd
->name
.address
)-1));
1172 __builtin_unreachable ();
1174 else if (towrite
!= fd
->output
)
1176 /* avoid dangling else. */
1179 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));
1181 __builtin_unreachable ();
1185 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));
1187 __builtin_unreachable ();
1194 FormatError ((const char *) "this file has not been opened successfully\\n", 44);
1196 __builtin_unreachable ();
1205 static void SetEndOfLine (FIO_File f
, char ch
)
1207 FIO_FileDescriptor fd
;
1209 CheckAccess (f
, FIO_openedforread
, false);
1212 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1215 fd
->state
= FIO_endofline
;
1219 fd
->state
= FIO_successful
;
1226 BufferedWrite - will write, nBytes, through the buffer.
1227 Similar to WriteNBytes, but this function will always
1228 write into the buffer before copying into memory.
1230 Useful when performing small writes.
1233 static int BufferedWrite (FIO_File f
, unsigned int nBytes
, void * src
)
1235 typedef unsigned char *BufferedWrite__T5
;
1240 BufferedWrite__T5 p
;
1241 FIO_FileDescriptor fd
;
1245 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1248 total
= 0; /* how many bytes have we read */
1249 if (fd
->buffer
!= NULL
) /* how many bytes have we read */
1251 /* place into the buffer first */
1254 if (fd
->buffer
->left
> 0)
1258 /* too expensive to call memcpy for 1 character */
1259 p
= static_cast<BufferedWrite__T5
> (src
);
1260 (*fd
->buffer
->contents
).array
[fd
->buffer
->position
] = static_cast<char> ((*p
));
1261 fd
->buffer
->left
-= 1; /* reduce space */
1262 fd
->buffer
->position
+= 1; /* move onwards n byte */
1263 total
+= 1; /* move onwards n byte */
1268 n
= Min (fd
->buffer
->left
, nBytes
);
1269 dest
= fd
->buffer
->address
;
1270 dest
= reinterpret_cast<void *> (reinterpret_cast<char *> (dest
)+fd
->buffer
->position
);
1271 p
= static_cast<BufferedWrite__T5
> (libc_memcpy (dest
, src
, static_cast<size_t> ((unsigned int ) (n
))));
1272 fd
->buffer
->left
-= n
; /* remove consumed bytes */
1273 fd
->buffer
->position
+= n
; /* move onwards n bytes */
1274 /* move ready for further writes */
1275 src
= reinterpret_cast<void *> (reinterpret_cast<char *> (src
)+n
);
1276 nBytes
-= n
; /* reduce the amount for future writes */
1277 total
+= n
; /* reduce the amount for future writes */
1282 FIO_FlushBuffer (f
);
1283 if ((fd
->state
!= FIO_successful
) && (fd
->state
!= FIO_endofline
))
1294 /* static analysis guarentees a RETURN statement will be used before here. */
1295 __builtin_unreachable ();
1300 PreInitialize - preinitialize the file descriptor.
1303 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
)
1305 FIO_FileDescriptor fd
;
1306 FIO_FileDescriptor fe
;
1307 char fname
[_fname_high
+1];
1309 /* make a local copy of each unbounded array. */
1310 memcpy (fname
, fname_
, _fname_high
+1);
1312 if ((InitializeFile (f
, const_cast<void*> (static_cast<const void*>(fname
)), StrLib_StrLen ((const char *) fname
, _fname_high
), state
, use
, towrite
, bufsize
)) == f
)
1314 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1317 fe
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, FIO_StdErr
));
1321 __builtin_unreachable ();
1325 fd
->unixfd
= fe
->unixfd
; /* the error channel */
1336 __builtin_unreachable ();
1342 Init - initialize the modules, global variables.
1345 static void Init (void)
1347 FileInfo
= Indexing_InitIndex (0);
1349 PreInitialize (Error
, (const char *) "error", 5, FIO_toomanyfilesopen
, FIO_unused
, false, -1, 0);
1351 PreInitialize (FIO_StdIn
, (const char *) "<stdin>", 7, FIO_successful
, FIO_openedforread
, false, 0, MaxBufferLength
);
1353 PreInitialize (FIO_StdOut
, (const char *) "<stdout>", 8, FIO_successful
, FIO_openedforwrite
, true, 1, MaxBufferLength
);
1355 PreInitialize (FIO_StdErr
, (const char *) "<stderr>", 8, FIO_successful
, FIO_openedforwrite
, true, 2, MaxBufferLength
);
1356 if (! (M2RTS_InstallTerminationProcedure ((PROC
) {(PROC_t
) FIO_FlushOutErr
})))
1359 __builtin_unreachable ();
1365 IsNoError - returns a TRUE if no error has occured on file, f.
1368 extern "C" bool FIO_IsNoError (FIO_File f
)
1370 FIO_FileDescriptor fd
;
1378 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1379 return (fd
!= NULL
) && (((fd
->state
== FIO_successful
) || (fd
->state
== FIO_endoffile
)) || (fd
->state
== FIO_endofline
));
1381 /* static analysis guarentees a RETURN statement will be used before here. */
1382 __builtin_unreachable ();
1387 IsActive - returns TRUE if the file, f, is still active.
1390 extern "C" bool FIO_IsActive (FIO_File f
)
1398 return (Indexing_GetIndice (FileInfo
, f
)) != NULL
;
1400 /* static analysis guarentees a RETURN statement will be used before here. */
1401 __builtin_unreachable ();
1404 extern "C" bool FIO_Exists (const char *fname_
, unsigned int _fname_high
)
1406 char fname
[_fname_high
+1];
1408 /* make a local copy of each unbounded array. */
1409 memcpy (fname
, fname_
, _fname_high
+1);
1412 The following functions are wrappers for the above.
1414 return FIO_exists (const_cast<void*> (static_cast<const void*>(fname
)), StrLib_StrLen ((const char *) fname
, _fname_high
));
1415 /* static analysis guarentees a RETURN statement will be used before here. */
1416 __builtin_unreachable ();
1419 extern "C" FIO_File
FIO_OpenToRead (const char *fname_
, unsigned int _fname_high
)
1421 char fname
[_fname_high
+1];
1423 /* make a local copy of each unbounded array. */
1424 memcpy (fname
, fname_
, _fname_high
+1);
1426 return FIO_openToRead (const_cast<void*> (static_cast<const void*>(fname
)), StrLib_StrLen ((const char *) fname
, _fname_high
));
1427 /* static analysis guarentees a RETURN statement will be used before here. */
1428 __builtin_unreachable ();
1431 extern "C" FIO_File
FIO_OpenToWrite (const char *fname_
, unsigned int _fname_high
)
1433 char fname
[_fname_high
+1];
1435 /* make a local copy of each unbounded array. */
1436 memcpy (fname
, fname_
, _fname_high
+1);
1438 return FIO_openToWrite (const_cast<void*> (static_cast<const void*>(fname
)), StrLib_StrLen ((const char *) fname
, _fname_high
));
1439 /* static analysis guarentees a RETURN statement will be used before here. */
1440 __builtin_unreachable ();
1443 extern "C" FIO_File
FIO_OpenForRandom (const char *fname_
, unsigned int _fname_high
, bool towrite
, bool newfile
)
1445 char fname
[_fname_high
+1];
1447 /* make a local copy of each unbounded array. */
1448 memcpy (fname
, fname_
, _fname_high
+1);
1450 return FIO_openForRandom (const_cast<void*> (static_cast<const void*>(fname
)), StrLib_StrLen ((const char *) fname
, _fname_high
), towrite
, newfile
);
1451 /* static analysis guarentees a RETURN statement will be used before here. */
1452 __builtin_unreachable ();
1457 Close - close a file which has been previously opened using:
1458 OpenToRead, OpenToWrite, OpenForRandom.
1459 It is correct to close a file which has an error status.
1462 extern "C" void FIO_Close (FIO_File f
)
1464 FIO_FileDescriptor fd
;
1468 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1470 we allow users to close files which have an error status
1474 FIO_FlushBuffer (f
);
1475 if (fd
->unixfd
>= 0)
1477 if ((libc_close (fd
->unixfd
)) != 0)
1479 FormatError1 ((const char *) "failed to close file (%s)\\n", 27, (const unsigned char *) &fd
->name
.address
, (sizeof (fd
->name
.address
)-1));
1480 fd
->state
= FIO_failed
; /* --fixme-- too late to notify user (unless we return a BOOLEAN) */
1483 if (fd
->name
.address
!= NULL
)
1485 Storage_DEALLOCATE (&fd
->name
.address
, fd
->name
.size
);
1487 if (fd
->buffer
!= NULL
)
1489 if (fd
->buffer
->address
!= NULL
)
1491 Storage_DEALLOCATE (&fd
->buffer
->address
, fd
->buffer
->size
);
1493 Storage_DEALLOCATE ((void **) &fd
->buffer
, sizeof (FIO_buf
));
1496 Storage_DEALLOCATE ((void **) &fd
, sizeof (FIO_fds
));
1497 Indexing_PutIndice (FileInfo
, f
, NULL
);
1504 exists - returns TRUE if a file named, fname exists for reading.
1507 extern "C" bool FIO_exists (void * fname
, unsigned int flength
)
1511 f
= FIO_openToRead (fname
, flength
);
1512 if (FIO_IsNoError (f
))
1522 /* static analysis guarentees a RETURN statement will be used before here. */
1523 __builtin_unreachable ();
1528 openToRead - attempts to open a file, fname, for reading and
1529 it returns this file.
1530 The success of this operation can be checked by
1534 extern "C" FIO_File
FIO_openToRead (void * fname
, unsigned int flength
)
1538 f
= GetNextFreeDescriptor ();
1541 SetState (f
, FIO_toomanyfilesopen
);
1545 f
= InitializeFile (f
, fname
, flength
, FIO_successful
, FIO_openedforread
, false, MaxBufferLength
);
1546 ConnectToUnix (f
, false, false);
1549 /* static analysis guarentees a RETURN statement will be used before here. */
1550 __builtin_unreachable ();
1555 openToWrite - attempts to open a file, fname, for write and
1556 it returns this file.
1557 The success of this operation can be checked by
1561 extern "C" FIO_File
FIO_openToWrite (void * fname
, unsigned int flength
)
1565 f
= GetNextFreeDescriptor ();
1568 SetState (f
, FIO_toomanyfilesopen
);
1572 f
= InitializeFile (f
, fname
, flength
, FIO_successful
, FIO_openedforwrite
, true, MaxBufferLength
);
1573 ConnectToUnix (f
, true, true);
1576 /* static analysis guarentees a RETURN statement will be used before here. */
1577 __builtin_unreachable ();
1582 openForRandom - attempts to open a file, fname, for random access
1583 read or write and it returns this file.
1584 The success of this operation can be checked by
1586 towrite, determines whether the file should be
1587 opened for writing or reading.
1590 extern "C" FIO_File
FIO_openForRandom (void * fname
, unsigned int flength
, bool towrite
, bool newfile
)
1594 f
= GetNextFreeDescriptor ();
1597 SetState (f
, FIO_toomanyfilesopen
);
1601 f
= InitializeFile (f
, fname
, flength
, FIO_successful
, FIO_openedforrandom
, towrite
, MaxBufferLength
);
1602 ConnectToUnix (f
, towrite
, newfile
);
1605 /* static analysis guarentees a RETURN statement will be used before here. */
1606 __builtin_unreachable ();
1611 FlushBuffer - flush contents of file, f.
1614 extern "C" void FIO_FlushBuffer (FIO_File f
)
1616 FIO_FileDescriptor fd
;
1620 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1623 if (fd
->output
&& (fd
->buffer
!= NULL
))
1625 if ((fd
->buffer
->position
== 0) || ((libc_write (fd
->unixfd
, fd
->buffer
->address
, static_cast<size_t> (fd
->buffer
->position
))) == ((int ) (fd
->buffer
->position
))))
1627 fd
->abspos
+= fd
->buffer
->position
;
1628 fd
->buffer
->bufstart
= fd
->abspos
;
1629 fd
->buffer
->position
= 0;
1630 fd
->buffer
->filled
= 0;
1631 fd
->buffer
->left
= fd
->buffer
->size
;
1635 fd
->state
= FIO_failed
;
1644 ReadNBytes - reads nBytes of a file into memory area, dest, returning
1645 the number of bytes actually read.
1646 This function will consume from the buffer and then
1647 perform direct libc reads. It is ideal for large reads.
1650 extern "C" unsigned int FIO_ReadNBytes (FIO_File f
, unsigned int nBytes
, void * dest
)
1652 typedef char *ReadNBytes__T2
;
1659 CheckAccess (f
, FIO_openedforread
, false);
1660 n
= ReadFromBuffer (f
, dest
, nBytes
);
1667 p
= static_cast<ReadNBytes__T2
> (dest
);
1669 SetEndOfLine (f
, (*p
));
1677 /* static analysis guarentees a RETURN statement will be used before here. */
1678 __builtin_unreachable ();
1683 ReadAny - reads HIGH (a) + 1 bytes into, a. All input
1684 is fully buffered, unlike ReadNBytes and thus is more
1685 suited to small reads.
1688 extern "C" void FIO_ReadAny (FIO_File f
, unsigned char *a
, unsigned int _a_high
)
1690 CheckAccess (f
, FIO_openedforread
, false);
1691 if ((BufferedRead (f
, _a_high
+1, a
)) == ((int ) (_a_high
+1)))
1693 SetEndOfLine (f
, static_cast<char> (a
[_a_high
]));
1699 WriteNBytes - writes nBytes from memory area src to a file
1700 returning the number of bytes actually written.
1701 This function will flush the buffer and then
1702 write the nBytes using a direct write from libc.
1703 It is ideal for large writes.
1706 extern "C" unsigned int FIO_WriteNBytes (FIO_File f
, unsigned int nBytes
, void * src
)
1709 FIO_FileDescriptor fd
;
1711 CheckAccess (f
, FIO_openedforwrite
, true);
1712 FIO_FlushBuffer (f
);
1715 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1718 total
= static_cast<int> (libc_write (fd
->unixfd
, src
, static_cast<size_t> ((int ) (nBytes
))));
1721 fd
->state
= FIO_failed
;
1726 fd
->abspos
+= (unsigned int ) (total
);
1727 if (fd
->buffer
!= NULL
)
1729 fd
->buffer
->bufstart
= fd
->abspos
;
1731 return (unsigned int ) (total
);
1736 /* static analysis guarentees a RETURN statement will be used before here. */
1737 __builtin_unreachable ();
1742 WriteAny - writes HIGH (a) + 1 bytes onto, file, f. All output
1743 is fully buffered, unlike WriteNBytes and thus is more
1744 suited to small writes.
1747 extern "C" void FIO_WriteAny (FIO_File f
, unsigned char *a
, unsigned int _a_high
)
1749 CheckAccess (f
, FIO_openedforwrite
, true);
1750 if ((BufferedWrite (f
, _a_high
+1, a
)) == ((int ) (_a_high
+1)))
1756 WriteChar - writes a single character to file, f.
1759 extern "C" void FIO_WriteChar (FIO_File f
, char ch
)
1761 CheckAccess (f
, FIO_openedforwrite
, true);
1762 if ((BufferedWrite (f
, sizeof (ch
), &ch
)) == ((int ) (sizeof (ch
))))
1768 EOF - tests to see whether a file, f, has reached end of file.
1771 extern "C" bool FIO_EOF (FIO_File f
)
1773 FIO_FileDescriptor fd
;
1775 CheckAccess (f
, FIO_openedforread
, false);
1778 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1781 return fd
->state
== FIO_endoffile
;
1785 /* static analysis guarentees a RETURN statement will be used before here. */
1786 __builtin_unreachable ();
1791 EOLN - tests to see whether a file, f, is upon a newline.
1792 It does NOT consume the newline.
1795 extern "C" bool FIO_EOLN (FIO_File f
)
1798 FIO_FileDescriptor fd
;
1800 CheckAccess (f
, FIO_openedforread
, false);
1802 we will read a character and then push it back onto the input stream,
1803 having noted the file status, we also reset the status.
1807 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1810 if ((fd
->state
== FIO_successful
) || (fd
->state
== FIO_endofline
))
1812 ch
= FIO_ReadChar (f
);
1813 if ((fd
->state
== FIO_successful
) || (fd
->state
== FIO_endofline
))
1815 FIO_UnReadChar (f
, ch
);
1817 return ch
== ASCII_nl
;
1822 /* static analysis guarentees a RETURN statement will be used before here. */
1823 __builtin_unreachable ();
1828 WasEOLN - tests to see whether a file, f, has just seen a newline.
1831 extern "C" bool FIO_WasEOLN (FIO_File f
)
1833 FIO_FileDescriptor fd
;
1835 CheckAccess (f
, FIO_openedforread
, false);
1842 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1843 return (fd
!= NULL
) && (fd
->state
== FIO_endofline
);
1845 /* static analysis guarentees a RETURN statement will be used before here. */
1846 __builtin_unreachable ();
1851 ReadChar - returns a character read from file f.
1852 Sensible to check with IsNoError or EOF after calling
1856 extern "C" char FIO_ReadChar (FIO_File f
)
1860 CheckAccess (f
, FIO_openedforread
, false);
1861 if ((BufferedRead (f
, sizeof (ch
), &ch
)) == ((int ) (sizeof (ch
))))
1863 SetEndOfLine (f
, ch
);
1870 /* static analysis guarentees a RETURN statement will be used before here. */
1871 __builtin_unreachable ();
1876 UnReadChar - replaces a character, ch, back into file f.
1877 This character must have been read by ReadChar
1878 and it does not allow successive calls. It may
1879 only be called if the previous read was successful
1880 or end of file was seen.
1881 If the state was previously endoffile then it
1882 is altered to successful.
1883 Otherwise it is left alone.
1886 extern "C" void FIO_UnReadChar (FIO_File f
, char ch
)
1888 FIO_FileDescriptor fd
;
1893 CheckAccess (f
, FIO_openedforread
, false);
1896 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
1897 if (((fd
->state
== FIO_successful
) || (fd
->state
== FIO_endoffile
)) || (fd
->state
== FIO_endofline
))
1899 /* avoid dangling else. */
1900 if ((fd
->buffer
!= NULL
) && fd
->buffer
->valid
)
1902 /* we assume that a ReadChar has occurred, we will check just in case. */
1903 if (fd
->state
== FIO_endoffile
)
1905 fd
->buffer
->position
= MaxBufferLength
;
1906 fd
->buffer
->left
= 0;
1907 fd
->buffer
->filled
= 0;
1908 fd
->state
= FIO_successful
;
1910 if (fd
->buffer
->position
> 0)
1912 fd
->buffer
->position
-= 1;
1913 fd
->buffer
->left
+= 1;
1914 (*fd
->buffer
->contents
).array
[fd
->buffer
->position
] = ch
;
1918 /* if possible make room and store ch */
1919 if (fd
->buffer
->filled
== fd
->buffer
->size
)
1921 FormatError1 ((const char *) "performing too many UnReadChar calls on file (%d)\\n", 51, (const unsigned char *) &f
, (sizeof (f
)-1));
1925 n
= fd
->buffer
->filled
-fd
->buffer
->position
;
1926 b
= &(*fd
->buffer
->contents
).array
[fd
->buffer
->position
];
1927 a
= &(*fd
->buffer
->contents
).array
[fd
->buffer
->position
+1];
1928 a
= libc_memcpy (a
, b
, static_cast<size_t> (n
));
1929 fd
->buffer
->filled
+= 1;
1930 (*fd
->buffer
->contents
).array
[fd
->buffer
->position
] = ch
;
1937 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));
1944 WriteLine - writes out a linefeed to file, f.
1947 extern "C" void FIO_WriteLine (FIO_File f
)
1949 FIO_WriteChar (f
, ASCII_nl
);
1954 WriteString - writes a string to file, f.
1957 extern "C" void FIO_WriteString (FIO_File f
, const char *a_
, unsigned int _a_high
)
1962 /* make a local copy of each unbounded array. */
1963 memcpy (a
, a_
, _a_high
+1);
1965 l
= StrLib_StrLen ((const char *) a
, _a_high
);
1966 if ((FIO_WriteNBytes (f
, l
, const_cast<void*> (static_cast<const void*>(a
)))) != l
)
1972 ReadString - reads a string from file, f, into string, a.
1973 It terminates the string if HIGH is reached or
1974 if a newline is seen or an error occurs.
1977 extern "C" void FIO_ReadString (FIO_File f
, char *a
, unsigned int _a_high
)
1983 CheckAccess (f
, FIO_openedforread
, false);
1987 ch
= FIO_ReadChar (f
);
1990 /* avoid gcc warning by using compound statement even if not strictly necessary. */
1991 if (((ch
== ASCII_nl
) || (! (FIO_IsNoError (f
)))) || (FIO_EOF (f
)))
1993 const_cast<char *>(a
)[i
] = ASCII_nul
;
1998 const_cast<char *>(a
)[i
] = ch
;
2002 } while (! ((((ch
== ASCII_nl
) || (i
> high
)) || (! (FIO_IsNoError (f
)))) || (FIO_EOF (f
))));
2007 WriteCardinal - writes a CARDINAL to file, f.
2008 It writes the binary image of the cardinal
2012 extern "C" void FIO_WriteCardinal (FIO_File f
, unsigned int c
)
2014 FIO_WriteAny (f
, (unsigned char *) &c
, (sizeof (c
)-1));
2019 ReadCardinal - reads a CARDINAL from file, f.
2020 It reads a binary image of a CARDINAL
2024 extern "C" unsigned int FIO_ReadCardinal (FIO_File f
)
2028 FIO_ReadAny (f
, (unsigned char *) &c
, (sizeof (c
)-1));
2030 /* static analysis guarentees a RETURN statement will be used before here. */
2031 __builtin_unreachable ();
2036 GetUnixFileDescriptor - returns the UNIX file descriptor of a file.
2039 extern "C" int FIO_GetUnixFileDescriptor (FIO_File f
)
2041 FIO_FileDescriptor fd
;
2045 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
2051 FormatError1 ((const char *) "file %d has not been opened or is out of range\\n", 48, (const unsigned char *) &f
, (sizeof (f
)-1));
2053 /* static analysis guarentees a RETURN statement will be used before here. */
2054 __builtin_unreachable ();
2059 SetPositionFromBeginning - sets the position from the beginning of the file.
2062 extern "C" void FIO_SetPositionFromBeginning (FIO_File f
, long int pos
)
2065 FIO_FileDescriptor fd
;
2069 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
2072 /* always force the lseek, until we are confident that abspos is always correct,
2073 basically it needs some hard testing before we should remove the OR TRUE. */
2074 if ((fd
->abspos
!= pos
) || true)
2076 FIO_FlushBuffer (f
);
2077 if (fd
->buffer
!= NULL
)
2081 fd
->buffer
->left
= fd
->buffer
->size
;
2085 fd
->buffer
->left
= 0;
2087 fd
->buffer
->position
= 0;
2088 fd
->buffer
->filled
= 0;
2090 offset
= static_cast<long int> (libc_lseek (fd
->unixfd
, (off_t
) (pos
), wrapc_SeekSet ()));
2091 if ((offset
>= 0) && (pos
== offset
))
2097 fd
->state
= FIO_failed
;
2100 if (fd
->buffer
!= NULL
)
2102 fd
->buffer
->valid
= false;
2103 fd
->buffer
->bufstart
= fd
->abspos
;
2112 SetPositionFromEnd - sets the position from the end of the file.
2115 extern "C" void FIO_SetPositionFromEnd (FIO_File f
, long int pos
)
2118 FIO_FileDescriptor fd
;
2122 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
2125 FIO_FlushBuffer (f
);
2126 if (fd
->buffer
!= NULL
)
2130 fd
->buffer
->left
= fd
->buffer
->size
;
2134 fd
->buffer
->left
= 0;
2136 fd
->buffer
->position
= 0;
2137 fd
->buffer
->filled
= 0;
2139 offset
= static_cast<long int> (libc_lseek (fd
->unixfd
, (off_t
) (pos
), wrapc_SeekEnd ()));
2142 fd
->abspos
= offset
;
2146 fd
->state
= FIO_failed
;
2150 if (fd
->buffer
!= NULL
)
2152 fd
->buffer
->valid
= false;
2153 fd
->buffer
->bufstart
= offset
;
2161 FindPosition - returns the current absolute position in file, f.
2164 extern "C" long int FIO_FindPosition (FIO_File f
)
2166 FIO_FileDescriptor fd
;
2170 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
2173 if ((fd
->buffer
== NULL
) || ! fd
->buffer
->valid
)
2179 return fd
->buffer
->bufstart
+((long int ) (fd
->buffer
->position
));
2184 /* static analysis guarentees a RETURN statement will be used before here. */
2185 __builtin_unreachable ();
2190 GetFileName - assigns, a, with the filename associated with, f.
2193 extern "C" void FIO_GetFileName (FIO_File f
, char *a
, unsigned int _a_high
)
2195 typedef char *GetFileName__T6
;
2199 FIO_FileDescriptor fd
;
2203 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
2206 FormatError ((const char *) "this file has probably been closed and not reopened successfully or alternatively never opened\\n", 96);
2208 __builtin_unreachable ();
2212 if (fd
->name
.address
== NULL
)
2214 StrLib_StrCopy ((const char *) "", 0, (char *) a
, _a_high
);
2218 p
= static_cast<GetFileName__T6
> (fd
->name
.address
);
2220 while (((*p
) != ASCII_nul
) && (i
<= _a_high
))
2222 const_cast<char *>(a
)[i
] = (*p
);
2233 getFileName - returns the address of the filename associated with, f.
2236 extern "C" void * FIO_getFileName (FIO_File f
)
2238 FIO_FileDescriptor fd
;
2242 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
2245 FormatError ((const char *) "this file has probably been closed and not reopened successfully or alternatively never opened\\n", 96);
2247 __builtin_unreachable ();
2251 return fd
->name
.address
;
2255 /* static analysis guarentees a RETURN statement will be used before here. */
2256 __builtin_unreachable ();
2261 getFileNameLength - returns the number of characters associated with filename, f.
2264 extern "C" unsigned int FIO_getFileNameLength (FIO_File f
)
2266 FIO_FileDescriptor fd
;
2270 fd
= static_cast<FIO_FileDescriptor
> (Indexing_GetIndice (FileInfo
, f
));
2273 FormatError ((const char *) "this file has probably been closed and not reopened successfully or alternatively never opened\\n", 96);
2275 __builtin_unreachable ();
2279 return fd
->name
.size
;
2283 /* static analysis guarentees a RETURN statement will be used before here. */
2284 __builtin_unreachable ();
2289 FlushOutErr - flushes, StdOut, and, StdErr.
2290 It is also called when the application calls M2RTS.Terminate.
2291 (which is automatically placed in program modules by the GM2
2295 extern "C" void FIO_FlushOutErr (void)
2297 if (FIO_IsNoError (FIO_StdOut
))
2299 FIO_FlushBuffer (FIO_StdOut
);
2301 if (FIO_IsNoError (FIO_StdErr
))
2303 FIO_FlushBuffer (FIO_StdErr
);
2307 extern "C" void _M2_FIO_init (__attribute__((unused
)) int argc
, __attribute__((unused
)) char *argv
[], __attribute__((unused
)) char *envp
[])
2312 extern "C" void _M2_FIO_fini (__attribute__((unused
)) int argc
, __attribute__((unused
)) char *argv
[], __attribute__((unused
)) char *envp
[])