| fopen | Function (tigcc.a)

stdio.h

FILE *fopen (const char *filename, const char *mode);

Opens a stream.

fopen opens the file named by filename (this is a normal C string, which should be in lowercase) and associates a stream with it. fopen returns a pointer to be used to identify the stream in subsequent operations. The mode string used in calls to fopen is one of the following values:

Mode | Description
r | Open for reading only.
w | Create for writing. If a file by that name already exists, it will be overwritten.
a | Append; open for writing at end of file, or create for writing if the file does not exist.
r+ | Open an existing file for update (reading and writing).
w+ | Create a new file for update (reading and writing). If a file by that name already exists, it will be overwritten.
a+ | Open for append; open for update at the end of the file, or create if the file does not exist.

On successful completion, fopen returns a pointer to the newly opened stream. In the event of error, it returns NULL. Note that files on TI are in fact TIOS variables, so their maximal size is limited (as the size of the variable is limited). Maybe in the future I will try to implement files which are limited only by the amount of the free memory.
To specify that a given file is being opened or created in text mode, append a 't' to the mode string ("rt", "w+t", and so on). Similarly, to specify binary mode, append a 'b' to the mode string ("wb", "a+b", and so on). What "text" or "binary" exactly means will be explained a bit later. fopen also allows the t or b to be inserted between the letter and the '+' character in the mode string. For example, "rt+" is equivalent to "r+t". If a 't' or 'b' is not given in the mode string, 't' is assumed (this slightly differs from the ANSI convention: in ANSI C the mode in this case is governed by the global variable _fmode, which is not implemented here).
When a file is opened in "text" mode, it is assumed to be a TEXT variable. On creating, all necessary headers and tags for the TEXT variable will be created. On opening for reading, the file pointer will be set to the first character in the first text line (asuming that it IS a text variable). So, files created in "text" mode can be readed in the TI text editor, and you can read variables created in the text editor. All '\n' characters will be translated to '\r' 0x20 sequence during writting (to satisfy the format of the text in TEXT variables), and a character after '\r' will be swallowed during reading (to skip over the "command byte" at the begining of the each line). Here is an example:

    FILE *f = fopen ("example", "w");
    fputs ("First line\n", f);
    fputs ("Second line\n", f);
    fputs ("Third line\n", f);
    fclose (f);

After this, you will have a TEXT variable called "example" which can be opened in text editor. You can read the content of a TEXT variable similarly.
When a file is opened in "binary" mode, nothing is assumed about the structure of the file. It can be a variable of any type. The user is responsible to create appropriate variable structure. There will no be any translation of characters, and after opening the file pointer will point to the first byte of the variable (after two "length" bytes), regardless of what the variable is supposed to be. For example, the string variable has the following structure: one zero byte, the content of the string, another zero byte, and finally, the string tag (STR_TAG or 0x2D byte). Here is an example of creating a file which represents a string variable:

    FILE *f = fopen ("example", "wb");
    fputc (0, f);
    fputs ("This is a string", f);
    fputc (0, f);
    fputc (STR_TAG, f);
    fclose (f);

When a file is opened for update (in both text or binary mode), both input and output can be done on the resulting stream. However, ANSI proposes that output cannot be followed directly by input without an intervening fseek or rewind, and that input cannot be directly followed by output without an intervening fseek, rewind, or an input that encounters end-of-file. I don't see any reason to implement such limitation here.
The filename pointed to by filename may also contain a path (i.e. a folder name may be given in front of the file name). If name of a folder which does not exist is given, and if fopen needs to create a new file, a dialog will appear which asks the user whether a new folder will be created. If the answer is "NO", fopen fails, returning NULL. If no folder name is given, the current folder is assumed.
Note: All functions which accept a parameter which is a pointer to a FILE structure assumes that the pointer is valid, i.e. created using fopen command. As I have no any efficient method to check whether the pointer is valid or not, no checking is implemented. So, if you pass an invalid pointer to any file handling function, the results are unpredictable.

Uses: HeapAlloc, HeapAllocPtr, HeapFreePtr, HeapSize, HLock, SaveScrState, RestoreScrState, strpbrk, DerefSym, SymAdd, SymDel, SymFind
Used by: freopen