[Main]
Name=fopen
Type=Function
Subtype=tigcc.a
Header Files=stdio.h
Definition=FILE *fopen (const char *filename, const char *mode);

[Description]
Opens a stream.

[Explanation]
fopen opens the file named by <I>filename</I> (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 <I>mode</I> string used in calls to fopen is one of
the following values:
<BR><BR>
<TABLE BORDER CELLPADDING="5">
<TR><TD><B>Mode</B></TD><TD><B>Description</B></TD></TR>
<TR><TD>r</TD>
<TD>Open for reading only.</TD></TR>
<TR><TD>w</TD>
<TD>Create for writing. If a file by that name already exists, it will be overwritten.</TD></TR>
<TR><TD>a</TD>
<TD>Append; open for writing at end of file, or create for writing if the file does not exist.</TD></TR>
<TR><TD>r+</TD>
<TD>Open an existing file for update (reading and writing).</TD></TR>
<TR><TD>w+</TD>
<TD>Create a new file for update (reading and writing). If a file by that name already exists, it will be overwritten.</TD></TR>
<TR><TD>a+</TD>
<TD>Open for append; open for update at the end of the file, or create if the file does not exist.</TD>
</TR></TABLE>
<BR>
On successful completion, fopen returns a pointer to the newly opened
stream. In the event of error, it returns <A HREF="$$LINK(alloc.h/NULL)">NULL</A>. 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.
<BR>
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
<B>_fmode</B>, which is not implemented here).
<BR><BR>
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:
<PRE>FILE *f = fopen ("example", "w");
fputs ("First line\n", f);
fputs ("Second line\n", f);
fputs ("Third line\n", f);
fclose (f);
</PRE>
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.
<BR><BR>
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
(<A HREF="$$LINK(estack.h/)">STR_TAG</A> or 0x2D byte). Here is an example of creating a file which
represents a string variable:
<PRE>FILE *f = fopen ("example", "wb");
fputc (0, f);
fputs ("This is a string", f);
fputc (0, f);
fputc (STR_TAG, f);
fclose (f);
</PRE>
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 <A HREF="$$LINK(fseek)">fseek</A> or <A HREF="$$LINK(rewind)">rewind</A>, and that input
cannot be directly followed by output without an intervening <A HREF="$$LINK(fseek)">fseek</A>,
<A HREF="$$LINK(rewind)">rewind</A>, or an input that encounters end-of-file. I don't see any reason
to implement such limitation here.
<BR><BR>
The filename pointed to by <I>filename</I> 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 <A HREF="$$LINK(alloc.h/NULL)">NULL</A>.
If no folder name is given, the current folder is assumed.
<BR><BR>
<B>Note:</B> All functions which accept a parameter which is a pointer to a <A HREF="$$LINK(FILE)">FILE</A>
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.

[References]
Out=alloc.h/HeapAlloc, alloc.h/HeapAllocPtr, alloc.h/HeapFreePtr, alloc.h/HeapSize, alloc.h/HLock, graph.h/SaveScrState, graph.h/RestoreScrState, string.h/strpbrk, vat.h/DerefSym, vat.h/SymAdd, vat.h/SymDel, vat.h/SymFind
In=freopen
