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

📄 file.c

📁 一个开源著名的TDE编辑器源代码
💻 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 node type 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 *     | type | ---> DIRTY | syntax flags       | type | ---> 0 *     | next | ---> pointer to next node       | next | ---> NULL *     --------                                 -------- * * Implicitly, I am assuming that EOF is defined as (-1) in stdio.h. * * jmh 980701: I've added a top of file marker, so now each file contains *             at least two nodes and the first line in the file becomes *             line_list->next rather than just line_list, which is the *             zeroth line and remains constant. It also causes changes in *             other files, which are not documented. * * 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. * * jmh 021101: tried to simplify it. Instead of reading into two buffers and *             and swapping the residue between them, read into one buffer *             and copy the residue into the other. I also read multiple *             binary lines at once. * * * 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 * Date:             August 29, 1993, version 3.1 * Date:             November 13, 1993, version 3.2 * Date:             June 5, 1994, version 4.0 * Date:             December 5, 1998, version 5.0 (jmh) * * 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"static char file_buf[READ_LENGTH];      /* jmh 021102: file buffer */static char *cmd_title;                 /* jmh 030331: for -c */char wksp_file[PATH_MAX];       /* jmh 020802: for -w */int  wksp_loaded;               /* jmh 020911: for AutoSaveWorkspace */extern char init_wd[PATH_MAX];  /* defined in main.c */extern char *line_in;           /* defined in config.c */extern int  make_window;        /* defined in window.c */#if defined( __WIN32__ )extern HANDLE conin;            /* defined in win32/console.c */#endifextern int  auto_reload;        /* defined in utils.c */extern TDE_WIN *results_window; /* defined in findrep.c */extern file_infos *results_file;extern file_infos *search_file;extern long found_rline;static void write_history( FILE *, HISTORY * ); /* added by jmh 021029 */static void read_history( FILE *, HISTORY * );  /* ditto *//* * 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 * * jmh:     August 27, 1997 - if name is empty (ie. "") then write to stdout. *          This allows TDE to be used in a pipe. * jmh 021103: fixed writing the first/last line of a stream block with tabs *              (but if inside a tab, it will write the tab, not the spaces). */int  write_file( char *name, int open_mode, file_infos *file, long start,                 long end, int block ){FILE *fp;       /* file to be written */text_ptr 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;int  tabs;int  tab_size;   if (block == LINE || block == BOX || block == STREAM) {      if (g_status.marked_file == NULL)         return( ERROR );      file = g_status.marked_file;   }   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     :         eol_count = 0;         eol = "";         assert( FALSE );   }   rc = OK;   if (*name == '\0') {      fp = stdout;#if !defined( __UNIX__ )      setmode( fileno( stdout ), O_BINARY );#endif   }   else if ((fp = fopen( name, open_string )) == NULL || CEH_ERROR)      rc = ERROR;   if (rc == OK) {      ll = file->line_list->next;      for (number = 1; number < start && ll->len != EOF; number++)         ll = ll->next;      ec = bc = len = 0;      if (block == BOX || block == STREAM) {         bc  = file->block_bc;         ec  = file->block_ec;         len = ec + 1 - bc;         if (block == STREAM  &&  start == end  &&  ec != -1)            block = BOX;      }      tabs = file->inflate_tabs;      tab_size = file->ptab_size;      if (block == BOX) {         p = g_status.line_buff;         for (; start <= end  &&  rc == OK; start++) {            load_box_buff( p, ll, bc, ec, ' ', tabs, tab_size );            if (fwrite( p, sizeof( char ), len, fp ) < (unsigned)len ||                       CEH_ERROR)               rc = ERROR;            if ((rc != ERROR  &&                 fwrite( eol, sizeof( char ), eol_count, fp ) < eol_count)                           || CEH_ERROR)               rc = ERROR;            ll = ll->next;            if (ll == NULL)               rc = ERROR;         }      } else {         for (number = start; number <= end  &&  rc == OK; number++) {            p   = ll->line;            len = ll->len;            if (block == STREAM) {               if (number == start) {                  if (tabs)                     bc = entab_adjust_rcol( (text_ptr)p, len, bc, tab_size );                  if (bc > len)                     bc = len;                  p   += bc;                  len -= bc;               } else if (number == end && ec != -1) {                  if (tabs)                     ec = entab_adjust_rcol( (text_ptr)p, len, ec, tab_size );                  ++ec;                  if (ec < len)                     len = ec;               }            }            if (fwrite( p, sizeof( char ), len, fp ) < (unsigned)len ||                    CEH_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 != BINARY) {                  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_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_ERROR)            rc = ERROR;      }      g_status.copied = FALSE;      if (!CEH_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 *          insert:     NULL for new file, pointer to line to insert file * Returns: OK, or ERROR if anything went wrong * * jmh:     August 27, 1997 - if name is empty (ie. "") then read from stdin. *           This allows TDE to be used in a pipe. *          January 24, 1998 - added insert line pointer to allow a file to be *           inserted into another file. * jmh 990428: if input is redirected, and output is not, set read-only mode. * jmh 990501: don't set mode.trailing = FALSE when loading BINARY (it's taken *              care of separately). * jmh 020822: removed UNIX' forced text mode for files starting with "#!" */int  load_file( char *name, file_infos *fp, int *file_mode, int bin_len,                line_list_ptr insert ){FILE *stream;                           /* stream to read */int  rc;line_list_ptr ll;line_list_ptr temp_ll;char *s, *e;int  len;int  t1, t2;int  crlf;int  prompt_line;   /*    * initialize the counters and pointers    */   rc = OK;   prompt_line = g_display.end_line;   ll = (insert == NULL) ? fp->line_list : insert;   if (*name == '\0') {      stream = stdin;#if !defined( __UNIX__ )      setmode( fileno( stdin ), O_BINARY );#endif   } else if ((stream = fopen( name, "rb" )) == NULL || CEH_ERROR) {      /*       * file not found or error loading file       */      combine_strings( line_out, main7a, name, main7b );      error( INFO, prompt_line, line_out );      rc = ERROR;   }   if (rc == OK) {      if (*file_mode == BINARY) {         crlf = BINARY;         if (bin_len < 0  ||  bin_len > READ_LENGTH)            bin_len = DEFAULT_BIN_LENGTH;         assert( bin_len < MAX_LINE_LENGTH );         t2 = (READ_LENGTH / bin_len) * bin_len;         if (t2 == 0)        /* READ_LENGTH is smaller than MAX_LINE_LENGTH */            t2 = bin_len;         while (rc == OK) {            t1 = fread( file_buf, sizeof(char), t2, stream );            if (ferror( stream )  ||  CEH_ERROR) {               combine_strings( line_out, main9, name, "'" );               error( WARNING, prompt_line, line_out );               rc = ERROR;               break;            }            if (t1 == 0)               break;            s = file_buf;            do {               if (t1 < bin_len)     /* will only occur on the last line */                  bin_len = t1;               temp_ll = new_line_text( (text_ptr)s, bin_len, 0, &rc);               if (rc != ERROR) {                  insert_node( fp, ll, temp_ll );                  ll = temp_ll;               } else {                  rc = show_file_2big( name, prompt_line );                  break;               }               s += bin_len;               t1 -= bin_len;            } while (t1 != 0);         }      } else {         crlf = LF;         len = 0;         while (rc == OK) {            t1 = fread( file_buf, 1, READ_LENGTH, stream );            if (ferror( stream )  ||  CEH_ERROR) {               combine_strings( line_out, main9, name, "'" );               error( WARNING, prompt_line, line_out );               rc = ERROR;               break;            }            if (t1 == 0)               break;            s = file_buf;            do {               e = memchr( s, '\n', t1 );               if (e == NULL) {                  if (len + t1 <= READ_LENGTH) {                     memcpy( g_status.line_buff + len, s, t1 );

⌨️ 快捷键说明

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