/* $DOC$
   $NAME$
      ft_FUse()
   $CATEGORY$
      File I/O
   $ONELINER$
      Open or close a text file for use by the ft_F*() functions
   $SYNTAX$
      ft_FUse( [ <cFile> ] [, <nMode> ] ) -> nHandle | 0
   $ARGUMENTS$
      ^b<cFile>^n is the text file you want to open.  If not specified,
      the file currently open, if any, will be closed.

      ^b<nMode>^n is the open mode for the file.  Please refer to the
      discussion of file open modes in fileio.ch for a list of allowable
      open modes.  If not specified, the file will be opened with a mode
      of FO_READ + FO_SHARED.
   $RETURNS$
      If ^b<cFile>^n is passed and the file is opened successfully, an
      integer containing the text file's workarea.  If the file cannot be
      opened, F_ERROR (-1) will be returned.  In this case, check the
      return value of ^bft_FError()^n for the cause of the error.

      If ft_FUse() is called without any arguments, it will close the
      text file in the current "text area" and return 0.

      If a read error occurs ^ft_FError()^n will contain the error code.
   $DESCRIPTION$
      The ft_F*() file functions are for reading text files, that is,
      files where each line (record) is delimited by a CRLF/LF.

      Each file is opened in its own "workarea", similar to the concept
      use by dbf files.  As provided, a maximum of 10 files (in 10
      workareas) can be opened (assuming there are sufficient file
      handles available).  That number may be increased by modifying
      the #define TEXT_WORKAREAS in the C source code and recompiling.
   $EXAMPLES$
      #include "fileio.ch"

      // open a text file for reading
      ft_FUse( "test.txt" )

      // open a text file for reading and writing
      ft_FUse( "test.txt", FO_READWRITE + FO_SHARED )

      // close file
      ft_FUse()
   $SEEALSO$
      ft_FUse(), ft_FSelect()
   $END$
 */

/* $DOC$
   $NAME$
      ft_FSelect()
   $CATEGORY$
      File I/O
   $ONELINER$
      Select a text file workarea
   $SYNTAX$
      ft_FSelect( [ <nNewArea> ] ) -> nPreviousArea
   $ARGUMENTS$
      ^b<nNewArea>^n is the text file workarea to select.
   $RETURNS$
      The current selected text file area.
   $DESCRIPTION$
      This function selects a text file "workarea" from 1 to 10.  A
      file may or may not be open in the selected area.

      Passing 0 for ^b<nNewArea>^n selects the next available workarea,
      similar to Clipper's SELECT 0 command.  If no more workareas are
      available the current workarea is not changed.

      Each file is opened in its own "workarea", similar to the concept
      used by dbf files.  As provided, a maximum of 10 files (in 10
      workareas) can be opened (assuming there are sufficient file
      handles available).  That number may be increased by modifying
      the #define TEXT_WORKAREAS in the C source code and recompiling.

      All the ft_F*() file functions operate on the file in the currently
      selected text file workarea.

      Text file workareas are separate from and independent of Clipper's
      database workareas.
   $EXAMPLES$
      ft_FSelect( 1 )

      nFile1 := ft_FUse( "temp.c" )

      ? ft_FLastRe()                 // no. of lines in temp.c

      ft_FSelect( 2 )

      nFile2 := ft_FUse( "temp.h" )

      ? ft_FLastRe()                 // no. of lines in temp.h
   $SEEALSO$
      ft_FUse()
   $END$
 */

/* $DOC$
   $NAME$
      ft_FGoTop()
   $CATEGORY$
      File I/O
   $ONELINER$
      Go to the first record in a text file
   $SYNTAX$
      ft_FGoTop() -> NIL
   $ARGUMENTS$
      None
   $RETURNS$
      NIL
   $DESCRIPTION$
      This function moves the record pointer to the first record
      in the currently selected text file workarea.

      A text file "record" is a line of text terminated by a CRLF/LF.
   $EXAMPLES$
      ft_FUse( "test.txt" )      // open text file

      DO WHILE ! ft_FEof()
         ? ft_FReadLn()        // read thru file
         ft_FSkip()
      ENDDO

      ft_FGoTop()              // go back to top

      ? ft_FRecNo()            // 1
   $SEEALSO$
      ft_FSelect(), ft_FUse(), ft_FRecNo(), ft_FGoBot()
   $END$
 */

/* $DOC$
   $NAME$
      ft_FError()
   $CATEGORY$
      File I/O
   $ONELINER$
      Return the error code for a text file operation
   $SYNTAX$
      ft_FError() -> nErrorNo
   $ARGUMENTS$
      None
   $RETURNS$
      The DOS error code if one occurred.  See a reference on DOS error
      codes for an explanation of what the code means.
   $DESCRIPTION$
      This function returns the DOS error code associated with a file
      operation on the currently selected text file.

      Errors could stem from any open, create, read or write operation,
      among others.
   $EXAMPLES$
      #include "fileio.ch"
      IF ft_FUse( "test.txt" ) != F_ERROR     // open text file
         err := ft_FError()
         ? "Error opening file 'test.txt', error code (" + ;
            hb_ntos( err ) + ")"
      ENDIF
   $SEEALSO$

   $END$
 */

/* $DOC$
   $NAME$
      ft_FRecNo()
   $CATEGORY$
      File I/O
   $ONELINER$
      Return the current record number of a text file
   $SYNTAX$
      ft_FRecNo() -> nRecNo
   $ARGUMENTS$
      None
   $RETURNS$
      The current record number of a text file or 0 if no file is open.
   $DESCRIPTION$
      This function returns the current record number of the file open
      in the currently selected text file workarea.

      A text file "record" is a line of text terminated by a CRLF/LF.
   $EXAMPLES$
      ft_FUse( "test.txt" )      // open text file

      DO WHILE ! ft_FEof()
         ? ft_FReadLn()        // read thru file
         ft_FSkip()
      ENDDO

      ft_FGoTop()              // go back to top

      ? ft_FRecNo()            // 1
   $SEEALSO$
      ft_FSelect(), ft_FUse(), ft_FGoTop(), ft_FGoBot()
   $END$
 */

/* $DOC$
   $NAME$
      ft_FGoBot()
   $CATEGORY$
      File I/O
   $ONELINER$
      Go to the last record in a text file
   $SYNTAX$
      ft_FGoBot() -> NIL
   $ARGUMENTS$
      None
   $RETURNS$
      NIL
   $DESCRIPTION$
      This function moves the record pointer to the last record of the
      file in the currently selected text file workarea.

      If a read error occurs ^bft_FError()^n will contain the error code.

      A text file "record" is a line of text terminated by a CRLF/LF.
   $EXAMPLES$
      // read last line
      ft_FUse( "test.txt" )

      ft_FGoBot()

      ? ft_FReadLn()
   $SEEALSO$
      ft_FSelect(), ft_FUse(), ft_FGoTop(), ft_FRecNo(), ft_FReadLn()
   $END$
 */

/* $DOC$
   $NAME$
      ft_FSkip()
   $CATEGORY$
      File I/O
   $ONELINER$
      Move the record pointer to a new position in a text file
   $SYNTAX$
      ft_FSkip( [ <nLines> ] ) -> nLinesSkipped
   $ARGUMENTS$
      <nLines> is the number of lines to skip.  Defaults to 1 if
      not specified.
   $RETURNS$
      The number of lines actually skipped.  If the file's EOF or
      BOF was encountered before ^b<nLines>^n could be skipped, the
      return value will be less than ^b<nLines>^n.
   $DESCRIPTION$
      This function moves the text file record pointer, similar to
      the CLIPPER SKIP command.

      Use the return value to determine how many records were actually
      skipped, for example to write a custom skipper function for
      TBrowse'g text files.

      If a read error occurs ^ft_FError()^n will contain the error code.

      A text file "record" is a line of text terminated by a CRLF/LF.
   $EXAMPLES$
      // display each record of a text file

      ft_FUse( "test.txt" )

      DO WHILE ! ft_FEof()
         ? ft_FReadLn()
         ft_FSkip()
      ENDDO
   $SEEALSO$
      ft_FRecNo(), ft_FGoTop()
   $END$
 */

/* $DOC$
   $NAME$
      ft_FReadLn()
   $CATEGORY$
      File I/O
   $ONELINER$
      Read a line from the currently selected text file
   $SYNTAX$
      ft_FReadLn() -> cLine
   $ARGUMENTS$
      None
   $RETURNS$
      A string containing the current record in a text file.
   $DESCRIPTION$
      This function returns a line of text read from the file in the
      currently selected text file workarea.  Text lines are delimited
      with a CRLF/LF.  The record pointer is not moved.

      Currently the maximum record size is 4096 characters.  You may
      increase the maximum record size by changing the value of ^b#define
      ^bBUFFSIZE^n in the C source and recompiling, however you should
      consider the performance implications if you do (all read and writes
      use this buffer size, including ft_FSkip()'s and ft_FGoto()'s).

      If a read error occurs ^ft_FError()^n will contain the error code.

      A text file "record" is a line of text terminated by a CRLF/LF.
   $EXAMPLES$
      // display each record of a text file

      ft_FUse( "test.txt" )

      DO WHILE ! ft_FEof()
         ? ft_FReadLn()
         ft_FSkip()
      ENDDO
   $SEEALSO$
      ft_FUse(), ft_FWriteLn(), ft_FRecNo(), ft_FGoTop()
   $END$
 */

/* $DOC$
   $NAME$
      ft_FDelete()
   $CATEGORY$
      File I/O
   $ONELINER$
      Deletes a line from the currently selected text file
   $SYNTAX$
      ft_FDelete( [ <nLines> ] ) -> lSuccess
   $ARGUMENTS$
      ^b<nLines>^n is the number of lines to be eliminated, beginning with
      the current record position.

      If ^b<nLines>^n is omitted, the current record is deleted only.
   $RETURNS$
      TRUE if successful, otherwise check ^bft_FError()^n for error code.
   $DESCRIPTION$
      This function deletes one or several lines of text from the file
      in the currently selected text file workarea.  Text lines are
      delimited with a CRLF/LF.  The record pointer is not moved,
      unless the deleted lines occur at the end of the file, in which
      case ^bft_FRecNo()^n will equal ^bft_FLastRe()^n and ^bft_FEof()^n
      will be set to TRUE.
   $EXAMPLES$
      // delete the next 4 lines from a file
      ft_FUse( "test.txt" )

      ft_FDelete( 4 )
   $SEEALSO$
      ft_FAppend(), ft_FRecNo(), ft_FInsert()
   $END$
 */

/* $DOC$
   $NAME$
      ft_FInsert()
   $CATEGORY$
      File I/O
   $ONELINER$
      Inserts a line in the currently selected text file
   $SYNTAX$
      ft_FInsert( [ <nLines> ] ) -> lSuccess
   $ARGUMENTS$
      ^b<nLines>^n is the number of lines that should be inserted at the
      current record position.

      If ^b<nLines>^n is omitted, one record is inserted.
   $RETURNS$
      ^blSuccess^n is TRUE if the insert succeeded, FALSE if not.  If
      false check the return value of ^bft_FError()^n for the reason.
   $DESCRIPTION$
      This function inserts a line of text in the file in the currently
      selected text file workarea.  Text lines are delimited with a
      CRLF/LF.

      The record pointer is not moved.

      A text file "record" is a line of text terminated by a CRLF/LF.
      Each line inserted with this function will be empty.
   $EXAMPLES$
      // add a couple of blank lines of text to a file
      ft_FUse( "test.txt" )

      ft_FGoto( 10 )

      ft_FInsert( 5 )
   $SEEALSO$
      ft_FAppend(), ft_FRecNo(), ft_FDelete(), ft_FLastRe()
   $END$
 */

/* $DOC$
   $NAME$
      ft_FAppend()
   $CATEGORY$
      File I/O
   $ONELINER$
      Appends a line to the currently selected text file
   $SYNTAX$
      ft_FAppend( [ <nLines> ] ) -> NIL
   $ARGUMENTS$
      <nLines> is the number of lines that should be appended to the
      end of the currently selected text file.

      If <nLines> is omitted, one record is appended.
   $RETURNS$
      lSuccess.  If FALSE, check ^bft_FError()^n for the error code.
   $DESCRIPTION$
      This function appends a line of text to the file in the currently
      selected text file workarea.  Text lines are delimited with a
      CRLF/LF.  The record pointer is moved to the last appended
      record.

      Multiple lines may be appended with one call to ft_FAppend().

      A text file "record" is a line of text terminated by a CRLF/LF.
      Each line appended with this function will be empty.

      NOTE:  Occasionally a text file may contain a non-CRLF/LF terminated
      line, at the end of the file ("stragglers").  This function assumes
      these stragglers to be the last line of the file, and begins
      appending the new lines after this line.  In other words, if the
      last line in the text file is not terminated with a CRLF/LF prior
      to calling ft_FAppend(), the function will terminate that last line
      before appending any new lines.
   $EXAMPLES$
      // add a blank line of text to a file
      ft_FUse( "test.txt" )

      ? ft_FRecNo()           // displays 5

      ft_FAppend()

      ? ft_FRecNo()           // displays 6
   $SEEALSO$
      ft_FRecNo(), ft_FDelete(), ft_FInsert(), ft_FLastRe()
   $END$
 */

/* $DOC$
   $NAME$
      ft_FWriteLn()
   $CATEGORY$
      File I/O
   $ONELINER$
      Write a line to the currently selected text file
   $SYNTAX$
      ft_FWriteLn( <cData>, [ <lInsert> ] ) -> lSuccess
   $ARGUMENTS$
      <cData> is a string of data to write to the file at the current
       record position.

      <lInsert> is a logical indicating whether the contents
      of the current record are to be preserved, that is, if lInsert
      evaluates to .T., the a new record is inserted at the current
      position.  The current record then is pushed down to ft_FRecNo()+1.

      If lInsert is .F. or omitted, the current record is replaced by
      cData.
   $RETURNS$
      TRUE if successful, otherwise check ^ft_FError()^n for error code.
   $DESCRIPTION$
      This function writes a line of text to the file in the currently
      selected text file workarea.  Text lines are delimited with a
      CRLF/LF.  The record pointer is not moved.

      The contents of the current record are updated to reflect the new
      new line written, unless the Insert option is selected.

      Writing a null string has the effect of clearing the current line
      if in overstrike mode, else inserting a new line (same as
      ft_FInsert()).

      A text file "record" is a line of text terminated by a CRLF/LF.
   $EXAMPLES$
      // write a line of text to a file

      ft_FUse( "config.sys" )

      DO WHILE ! hb_LeftEqI( ft_FReadLn(), "FILES=" ) .AND. ! ft_FEof()
         ft_FSkip()
      ENDDO

      ft_FWriteLn( "FILES=30", ft_FEof() )
   $SEEALSO$
      ft_FReadLn(), ft_FRecNo(), ft_FInsert(), ft_FDelete()
   $END$
 */

/* $DOC$
   $NAME$
      ft_FLastRe()
   $CATEGORY$
      File I/O
   $ONELINER$
      Get the no. of records in the currently selected text file
   $SYNTAX$
      ft_FLastRe() -> nLastRecordNum
   $ARGUMENTS$
      None
   $RETURNS$
      An integer containing the number of records in the text file in
      the currently selected text file workarea, or zero if no file
      is currently open in the workarea.
   $DESCRIPTION$
      This function returns the number of the last record in a text file.

      A text file "record" is a line of text terminated by a CRLF/LF.
   $EXAMPLES$
      ft_FUse( "test.txt" )

      ? ft_FLastRe()
   $SEEALSO$
      ft_FUse(), ft_FRecNo()
   $END$
 */

/* $DOC$
   $NAME$
      ft_FEof()
   $CATEGORY$
      File I/O
   $ONELINER$
      Determine if end of text file has been encountered
   $SYNTAX$
      ft_FEof() -> lResult
   $ARGUMENTS$
      None
   $RETURNS$
      .T. if an attempt was made to skip past the last record of
      the currently selected text file, otherwise .F.
   $DESCRIPTION$
      This function is similar to the CLIPPER Eof() function.

      A text file "record" is a line of text terminated by a CRLF/LF.
   $EXAMPLES$
      ft_FUse( "test.txt" )

      ? ft_FEof()        // .F.

      ft_FSkip()

      ? ft_FEof()        // .T.
   $SEEALSO$
      ft_FUse(), ft_FSkip()
   $END$
 */

/* $DOC$
   $NAME$
      ft_FBof()
   $CATEGORY$
      File I/O
   $ONELINER$
      Determine if attempt to skip past beginning of text file
   $SYNTAX$
      ft_FBof() -> lResult
   $ARGUMENTS$
      None
   $RETURNS$
      .T. if an attempt was made to skip past the first record of
      the currently selected text file, otherwise .F.
   $DESCRIPTION$
      This function is similar to the Clipper Bof() function.

      A text file "record" is a line of text terminated by a CRLF/LF.
   $EXAMPLES$
      ft_FUse( "test.txt" )

      ft_FGoTop()

      ? ft_FBof()        // .F.

      ft_FSkip( -1 )

      ? ft_FBof()        // .T.
   $SEEALSO$
      ft_FSkip(), ft_FEof(), ft_FGoTop()
   $END$
 */

/* $DOC$
   $NAME$
      ft_FGoto()
   $CATEGORY$
      File I/O
   $ONELINER$
      Move record pointer to specific record in a text file
   $SYNTAX$
      ft_FGoto( nLine ) -> NIL
   $ARGUMENTS$
      <nLine> is the record number to go to.
   $RETURNS$
      NIL
   $DESCRIPTION$
      This function moves the record pointer to a specific record
      in the file in the currently selected text file workarea.  If
      the record number requested is greater than the number of records
      in the file, the record pointer will be positioned at the last
      record.

      Internally, the function operates differently depending on how
      you invoke it.  Passing a value for ^b<nLine>^n results in what
      is effectively a skip operation, which is fairly quick.  However
      if you pass 0 for ^b<nLine>^n, e.g. ft_FGoto( 0 ), the function
      internally goes to the top of the file, then skips down the
      required number of records.  Hence if your file is relatively
      large and the current record is a high number, you may see some
      delay as ft_FGoto( 0 ) skips through the file.

      A text file "record" is a line of text terminated by a CRLF/LF.
   $EXAMPLES$
      // read 5th line of text from file

      ft_FUse( "test.txt" )

      ft_FGoto( 5 )

      ? ft_FReadLn()
   $SEEALSO$
      ft_FRecNo(), ft_FGoTop(), ft_FReadLn()
   $END$
 */
