⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file.c

📁 THOMSON-DAVIS用C语言开发的编缉器,简单,易懂.
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * This file contains the file i/o stuff.  These functions get stuff from
 * from the outside world into a form for TDE.  The form TDE uses is a
 * double linked list.  Each node in the list points to the prev and
 * the next nodes, if they exist.  Also in each node is a pointer to a
 * line of text, a line length variable, and a dirty node indicator.  In
 * earlier versions of TDE, a '\n' was used to terminate a line of text.
 * In this version, we must keep an accurate count of characters in
 * each line of text, as no character is used to terminate the line.
 *
 * Each file must contain at least one node.  That node is called the
 * EOF node.  The EOF node terminates the double linked list for each
 * file.  The EOF node has a NULL pointer in the line field, a NULL
 * pointer in the next field, and an EOF in the len field.  Here's
 * a crude picture of the double linked list structure:
 *
 *              Regular node                             EOF node
 *     ---------                                 ---------
 *     | prev  | ---> pointer to prev node       | prev  | ---> unknown
 *     | line  | ---> "Hello world"              | line  | ---> NULL
 *     | len   | ---> 11                         | len   | ---> EOF
 *     | dirty | ---> TRUE | FALSE               | dirty | ---> FALSE
 *     | next  | ---> pointer to next node       | next  | ---> NULL
 *     ---------                                 ---------
 *
 * Implicitly, I am assuming that EOF is defined as (-1) in stdio.h.
 *
 * The load_file function is probably more complicated than expected, but
 * I was trying to read chunks of text that match the disk cluster size
 * and/or some multiple of the cache in the disk controller.
 *
 *
 * New editor name:  TDE, the Thomson-Davis Editor.
 * Author:           Frank Davis
 * Date:             June 5, 1991, version 1.0
 * Date:             July 29, 1991, version 1.1
 * Date:             October 5, 1991, version 1.2
 * Date:             January 20, 1992, version 1.3
 * Date:             February 17, 1992, version 1.4
 * Date:             April 1, 1992, version 1.5
 * Date:             June 5, 1992, version 2.0
 * Date:             October 31, 1992, version 2.1
 * Date:             April 1, 1993, version 2.2
 * Date:             June 5, 1993, version 3.0
 *
 * This code is released into the public domain, Frank Davis.
 * You may distribute it freely.
 */


#include "tdestr.h"             /* tde types */
#include "common.h"
#include "define.h"
#include "tdefunc.h"


#include <dos.h>                /* for renaming files */
#include <bios.h>               /* for direct BIOS keyboard input */
#include <io.h>                 /* for file attribute code */
#include <fcntl.h>              /* open flags */
#if defined( __MSC__ )
   #include <errno.h>
   #include <sys\types.h>       /* S_IWRITE etc */
#endif
#include <sys\stat.h>           /* S_IWRITE etc */


/*
 * Name:    hw_fattrib
 * Purpose: To determine the current file attributes.
 * Date:    December 26, 1991
 * Passed:  name: name of file to be checked
 * Returns: use the function in the tdeasm file to get the DOS file
 *          attributes.  get_fattr() returns 0 or OK if no error.
 */
int  hw_fattrib( char *name )
{
register int rc;
int  fattr;

   rc = get_fattr( name, &fattr );
   return( rc == OK ? rc : ERROR );
}


/*
 * Name:    change_mode
 * Purpose: To prompt for file access mode.
 * Date:    January 11, 1992
 * Passed:  name:  name of file
 *          line:  line to display message
 * Returns: OK if file could be changed
 *          ERROR otherwise
 * Notes:   function is used to change file attributes for save_as function.
 */
int  change_mode( char *name, int line )
{
int  result;
int  fattr;
register int rc;
char line_buff[(MAX_COLS+1)*2]; /* buffer for char and attribute  */

   rc = OK;
   result = get_fattr( name, &fattr );
   if (result != OK)
      rc = ERROR;
   else if (result == OK && fattr & READ_ONLY) {
      /*
       * file is read only
       */
      save_screen_line( 0, line, line_buff );
      /*
       * file is write protected. overwrite anyway (y/n)?
       */
      set_prompt( main6, line );
      if (get_yn( ) != A_YES)
         rc = ERROR;
      if (rc == OK && set_fattr( name, ARCHIVE ) != OK)
         rc = ERROR;
      restore_screen_line( 0, line, line_buff );
   }
   return( rc );
}


/*
 * Name:    write_file
 * Purpose: To write text to a file
 *           way.
 * Date:    June 5, 1991
 * Passed:  name:  name of disk file or device
 *          open_mode:  fopen flags to be used in open
 *          file:  pointer to file structure to write
 *          start: first node to write
 *          end:   last node to write
 *          block: write a file or a marked block
 * Returns: OK, or ERROR if anything went wrong
 */
int  write_file( char *name, int open_mode, file_infos *file, long start,
                 long end, int block )
{
FILE *fp;       /* file to be written */
char *p;
char *z = "\x1a";
register int rc;
int  bc;
int  ec;
int  len;
int  write_z;
int  write_eol;
long number;
line_list_ptr ll;
char *open_string;
char *eol;
size_t eol_count;

   write_z = mode.control_z;
   switch (open_mode) {
      case APPEND :
         open_string = "ab";
         break;
      case OVERWRITE :
      default :
         open_string = "wb";
         break;
   }
   switch (file->crlf) {
      case BINARY   :
         eol_count = 0;
         eol = "";
         write_z = FALSE;
         break;
      case CRLF   :
         eol_count = 2;
         eol = "\r\n";
         break;
      case LF     :
         eol_count = 1;
         eol = "\n";
         break;
      default     :
         assert( FALSE );
   }
   rc = OK;
   if ((fp = fopen( name, open_string )) == NULL || ceh.flag == ERROR)
      rc = ERROR;
   else {
      ec = bc = len = 0;
      ll = file->line_list;
      if (block == LINE || block == BOX || block == STREAM) {
         if (g_status.marked_file == NULL)
            rc = ERROR;
         else
            file = g_status.marked_file;
         if (rc != ERROR) {
            ll = file->line_list;
            for (number=1; number<start && ll->next != NULL; number++)
               ll = ll->next;
         }
         if (rc != ERROR && (block == BOX || block == STREAM)) {
            bc  = file->block_bc;
            ec  = file->block_ec;
            len = ec + 1 - bc;
         }
         if (rc != ERROR  &&  block == STREAM) {
            if (start == end )
               block = BOX;
         }
      } else {
         for (number=1; number<start && ll->next != NULL; number++)
            ll = ll->next;
      }
      p = g_status.line_buff;
      if (rc == OK) {
         if (block == BOX) {

            assert( len >= 0 );
            assert( len < MAX_LINE_LENGTH );

            for (;start <= end  &&  ll->len != EOF && rc == OK; start++) {
               g_status.copied = FALSE;
               load_box_buff( p, ll, bc, ec, ' ' );
               if (fwrite( p, sizeof( char ), len, fp ) < (unsigned)len ||
                          ceh.flag == ERROR)
                  rc = ERROR;
               if (rc != ERROR  && fwrite( eol, sizeof( char ), eol_count, fp )
                                    < eol_count || ceh.flag == ERROR)
                  rc = ERROR;
               ll = ll->next;
               if (ll == NULL)
                  rc = ERROR;
            }
         } else {
            for (number=start; number <= end && rc == OK && ll->len != EOF;
                      number++) {
               g_status.copied = FALSE;
               copy_line( ll );
               len = g_status.line_buff_len;
               if (block == STREAM) {
                  if (number == start) {
                     bc = bc > len ? len : bc;
                     len = len - bc;

                     assert( len >= 0 );

                     memmove( p, p + bc, len );
                  } else if (number == end) {
                     ++ec;
                     len =  ec > len ? len : ec;
                  }
               }

               assert( len >= 0 );
               assert( len < MAX_LINE_LENGTH );

               if (fwrite( p, sizeof( char ), len, fp ) < (unsigned)len ||
                       ceh.flag == ERROR)
                  rc = ERROR;

               /*
                * if a Control-Z is already at EOF, don't write another one.
                */
               write_eol = TRUE;
               if (number == end) {
                  if (file->crlf == CRLF ||  file->crlf == LF) {
                     if (len > 0  &&  *(p + len - 1) == '\x1a') {
                        write_eol = FALSE;
                        write_z = FALSE;
                     }
                  }
               }

               if (write_eol == TRUE  &&  rc != ERROR  &&
                     fwrite( eol, sizeof( char ), eol_count, fp ) < eol_count
                     || ceh.flag == ERROR)
                  rc = ERROR;
               ll = ll->next;
               if (ll == NULL)
                  rc = ERROR;
            }
         }
         if (rc != ERROR  &&  write_z) {
            if (fwrite( z, sizeof( char ), 1, fp ) < 1 || ceh.flag == ERROR)
               rc = ERROR;
         }
         g_status.copied = FALSE;
         if (ceh.flag != ERROR) {
            if (fclose( fp ) != 0)
               rc = ERROR;
         }
      }
   }
   return( rc );
}


/*
 * Name:    hw_save
 * Purpose: To save text to a file
 * Date:    November 11, 1989
 * Passed:  name:  name of disk file
 *          file:  pointer to file structure
 *          start: first character in text buffer
 *          end:   last character (+1) in text buffer
 *          block: type of block defined
 * Returns: OK, or ERROR if anything went wrong
 */
int hw_save( char *name, file_infos *file, long start, long end, int block )
{
   return( write_file( name, OVERWRITE, file, start, end, block ) );
}


/*
 * Name:    hw_append
 * Purpose: To append text to a file.
 * Date:    November 11, 1989
 * Passed:  name:  name of disk file
 *          file:  pointer to file structure
 *          start: first character in text buffer
 *          end:   last character (+1) in text buffer
 *          block: type of defined block
 * Returns: OK, or ERROR if anything went wrong
 */
int hw_append( char *name, file_infos *file, long start, long end, int block )
{
   return( write_file( name, APPEND, file, start, end, block ) );
}


/*
 * Name:    load_file
 * Purpose: To load a file into the array of text pointers.
 * Date:    December 1, 1992
 * Passed:  name:       name of disk file
 *          fp:         pointer to file structure
 *          file_mode:  BINARY or TEXT
 *          bin_len:    if opened in BINARY mode, length of node line
 * Returns: OK, or ERROR if anything went wrong
 */
int  load_file( char *name, file_infos *fp, int *file_mode, int bin_len )
{
FILE *stream;                           /* stream to read */
int  rc;
char buff[MAX_COLS+2];
char line_buff[(MAX_COLS+2)*2];         /* buffer for char and attribute  */
text_ptr l;
line_list_ptr ll;
line_list_ptr temp_ll;
unsigned long line_count;
char *e;
char *residue;
int  len;
int  res;
size_t t1, t2;
int  crlf;
int  prompt_line;

   /*
    * initialize the counters and pointers
    */
   rc = OK;
   len = 1;
   line_count = 0;
   res = 0;
   residue = g_status.line_buff;
   prompt_line = g_display.nlines;
   fp->length  = 0;
   fp->undo_count = 0;
   fp->undo_top = fp->undo_bot = NULL;
   fp->line_list_end = fp->line_list = NULL;
   ll = (line_list_ptr)my_malloc( sizeof(line_list_struc), &rc );

   if (ll != NULL) {
      ll->dirty = FALSE;
      ll->len   = EOF;
      ll->line  = NULL;
      ll->next  = ll->prev = NULL;
      fp->undo_top = fp->undo_bot = ll;
   }

   ll = (line_list_ptr)my_malloc( sizeof(line_list_struc), &rc );

   if (ll != NULL) {
      ll->dirty = FALSE;
      ll->len   = EOF;
      ll->line  = NULL;
      ll->next  = ll->prev = NULL;
      fp->line_list_end = fp->line_list = ll;
   }

   if ((stream = fopen( name, "rb" )) == NULL || ceh.flag == ERROR ||
         rc == ERROR) {
      /*
       * file not found or error loading file
       */
      combine_strings( buff, main7a, name, main7b );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -