home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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
- * Date: August 29, 1993, version 3.1
- * Date: November 13, 1993, version 3.2
- *
- * 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"
-
- #if !defined( __UNIX__ )
- #include <dos.h> /* for renaming files */
- #include <bios.h> /* for direct BIOS keyboard input */
- #include <io.h> /* for file attribute code */
- #if defined( __MSC__ )
- #include <errno.h>
- #include <sys\types.h> /* S_IWRITE etc */
- #endif
- #include <sys\stat.h> /* S_IWRITE etc */
- #endif
-
- #include <fcntl.h> /* open flags */
-
- /*
- * 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 :
- eol_count = 0;
- eol = "";
- 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;
- 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;
- char temp[MAX_COLS+2];
- #if defined( __UNIX__ )
- chtype display_buff[MAX_COLS+2]; /* chtype is defined in curses.h */
- #else
- char display_buff[(MAX_COLS+2)*2];
- #endif
-
- /*
- * 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( temp, main7a, name, main7b );
- save_screen_line( 0, prompt_line, display_buff );
- set_prompt( temp, prompt_line );
- getkey( );
- restore_screen_line( 0, prompt_line, display_buff );
- if (fp->line_list != NULL)
- my_free( fp->line_list );
- if (fp->undo_top != NULL)
- my_free( fp->undo_top );
- rc = ERROR;
- } else {
- if (*file_mode == BINARY) {
- mode.trailing = FALSE;
- crlf = BINARY;
- if (bin_len < 0 || bin_len > READ_LENGTH)
- bin_len = DEFAULT_BIN_LENGTH;
- for (; rc == OK;) {
- t1 = fread( g_status.line_buff, sizeof(char), bin_len, stream );
- if (ferror( stream ) || ceh.flag == ERROR) {
- combine_strings( temp, main9, name, "'" );
- error( WARNING, prompt_line, temp );
- rc = ERROR;
- } else if (t1) {
-
- assert( t1 < MAX_LINE_LENGTH );
-
- l = (text_ptr)my_malloc( t1 * sizeof(char), &rc );
- temp_ll = (line_list_ptr)my_malloc( sizeof(line_list_struc), &rc );
-
- if (rc != ERROR) {
-
- /*
- * if everything is everything, copy from io buff to
- * dynamic mem.
- */
- if (t1 > 0)
- my_memcpy( l, g_status.line_buff, t1 );
-
- ++line_count;
- temp_ll->line = l;
- temp_ll->dirty = FALSE;
- temp_ll->len = t1;
- insert_node( fp, ll, temp_ll );
- ll = temp_ll;
- } else
- rc = show_file_2big( name, prompt_line, temp_ll, l );
- } else
- break;
- }
- } else {
- crlf = LF;
- for (; rc == OK;) {
- t1 = fread( g_status.line_buff, sizeof(char), READ_LENGTH, stream );
- if (ferror( stream ) || ceh.flag == ERROR) {
- combine_strings( temp, main9, name, "'" );
- error( WARNING, prompt_line, temp );
- rc = ERROR;
- } else {
-
- /*
- * "e" walks down io buffer 1 looking for end of lines. "t1"
- * keeps count of number of characters in io buffer 1.
- */
- e = g_status.line_buff;
- while (t1 && rc == OK) {
-
- /*
- * while "t1" is not zero and "len" is less than max line length,
- * let "e" walk down the buffer until it find <LF>.
- */
- for (; t1 && len < READ_LENGTH && *e != '\n'; len++, e++, t1--);
-
- /*
- * if "t1" is not zero, we either found a <LF> or the line
- * length max'd out.
- */
- if (t1 || len >= READ_LENGTH) {
-
- if (len > 1 && *e == '\n') {
- if (len - res == 1) {
- if (*(residue + res - 1) == '\r') {
- --len;
- --res;
- crlf = CRLF;
- }
- } else {
- if (*(e - 1) == '\r') {
- --len;
- crlf = CRLF;
- }
- }
- }
- if (len > 0)
- --len;
-
- assert( len >= 0 );
- assert( len < MAX_LINE_LENGTH );
-
- /*
- * allocate space for relocatable array of line pointers and
- * allocate space for the line we just read.
- */
- l = (text_ptr)my_malloc( len * sizeof(char), &rc );
- temp_ll =
- (line_list_ptr)my_malloc( sizeof(line_list_struc), &rc );
-
- if (rc != ERROR) {
-
- /*
- * if everything is everything, copy from io buff to
- * dynamic mem. "residue" keeps up with the beginning
- * of line in io buffer.
- */
- if (res > 0) {
-
- assert( res >= 0 );
- assert( len - res >= 0 );
-
- if (res > 0)
- my_memcpy( l, residue, res );
- if (len - res > 0)
- my_memcpy( l + res, g_status.line_buff, len - res );
- res = 0;
- } else
- if (len > 0)
- my_memcpy( l, residue, len );
-
- ++line_count;
- temp_ll->line = l;
- temp_ll->dirty = FALSE;
- temp_ll->len = len;
- insert_node( fp, ll, temp_ll );
- ll = temp_ll;
-
- /*
- * reset io buffer pointers and counters.
- */
- len = 1;
- if (t1 == 0)
- residue = g_status.tabout_buff;
- else {
- t1--;
- residue = t1 == 0 ? g_status.tabout_buff : ++e;
- }
- } else
- rc = show_file_2big( name, prompt_line, temp_ll, l );
- } else if (len < READ_LENGTH ) {
- if (!feof( stream ))
- res = len - 1;
- } else {
- error( WARNING, prompt_line, main9a );
- rc = ERROR;
- }
- }
- }
-
- if (rc != OK)
- break;
-
- /*
- * we may have read all lines that end in '\n', but there may
- * be some residue after the last '\n'. ^Z is a good example.
- */
- if (feof( stream )) {
- if (len > 1) {
- --len;
- if (t1 == 0)
- --e;
-
- assert( len >= 0 );
- assert( len < MAX_LINE_LENGTH );
-
- /*
- * allocate space for relocatable array of line pointers and
- * allocate space for the line we just read.
- */
- l = (text_ptr)my_malloc( len * sizeof(char), &rc );
- temp_ll =
- (line_list_ptr)my_malloc( sizeof(line_list_struc), &rc );
-
- if (rc != ERROR) {
-
- /*
- * if everything is everything, copy from io buff to
- * dynamic mem. "residue" keeps up with the beginning
- * of line in io buffer.
- */
- if (res > 0) {
-
- assert( res >= 0 );
- assert( res < MAX_LINE_LENGTH);
- assert( len - res >= 0 );
- assert( len - res < MAX_LINE_LENGTH);
-
- if (res > 0 )
- my_memcpy( l, residue, res );
- if (len - res > 0)
- my_memcpy( l + res, g_status.line_buff, len - res );
- } else
- if (len > 0)
- my_memcpy( l, residue, len );
- ++line_count;
- temp_ll->line = l;
- temp_ll->dirty = FALSE;
- temp_ll->len = len;
- insert_node( fp, ll, temp_ll );
- } else
- rc = show_file_2big( name, prompt_line, temp_ll, l );
- }
- break;
- }
-
- t2 = fread( g_status.tabout_buff, sizeof(char), READ_LENGTH, stream );
- if (ferror( stream ) || ceh.flag == ERROR) {
- combine_strings( temp, main9, name, "'" );
- error( WARNING, prompt_line, temp );
- rc = ERROR;
- } else if (rc == OK) {
- e = g_status.tabout_buff;
- while (t2 && rc == OK) {
- for (; t2 && len < READ_LENGTH && *e != '\n'; len++, e++, t2--);
- if (t2 || len >= READ_LENGTH) {
-
- if (len > 1 && *e == '\n') {
- if (len - res == 1) {
- if (*(residue + res - 1) == '\r') {
- --len;
- --res;
- crlf = CRLF;
- }
- } else {
- if (*(e - 1) == '\r') {
- --len;
- crlf = CRLF;
- }
- }
- }
- if (len > 0)
- --len;
-
- assert( len >= 0 );
- assert( len < MAX_LINE_LENGTH );
-
- l = (text_ptr)my_malloc( len * sizeof(char), &rc );
- temp_ll =
- (line_list_ptr)my_malloc( sizeof(line_list_struc), &rc );
-
- if (rc != ERROR) {
- if (res > 0) {
-
- assert( res >= 0 );
- assert( res < MAX_LINE_LENGTH);
- assert( len - res >= 0 );
- assert( len - res < MAX_LINE_LENGTH);
-
- if (res > 0)
- my_memcpy( l, residue, res );
- if (len - res > 0)
- my_memcpy( l+res, g_status.tabout_buff, len - res );
- res = 0;
- } else
- if (len > 0)
- my_memcpy( l, residue, len );
-
- ++line_count;
- temp_ll->line = l;
- temp_ll->dirty = FALSE;
- temp_ll->len = len;
- insert_node( fp, ll, temp_ll );
- ll = temp_ll;
-
- len = 1;
- if (t2 == 0)
- residue = g_status.line_buff;
- else {
- t2--;
- residue = t2 == 0 ? g_status.line_buff : ++e;
- }
- } else
- rc = show_file_2big( name, prompt_line, temp_ll, l );
- } else if (len < READ_LENGTH) {
- if (!feof( stream ))
- res = len - 1;
- } else {
- error( WARNING, prompt_line, main9a );
- rc = ERROR;
- }
- }
- }
-
- if (rc != ERROR && feof( stream )) {
- if (len > 1) {
- --len;
- if (t2 == 0)
- --e;
-
- assert( len >= 0 );
- assert( len < MAX_LINE_LENGTH );
-
- l = (text_ptr)my_malloc( len * sizeof(char), &rc );
- temp_ll =
- (line_list_ptr)my_malloc( sizeof(line_list_struc), &rc );
-
- if (rc != ERROR) {
- if (res > 0) {
-
- assert( res >= 0 );
- assert( res < MAX_LINE_LENGTH);
- assert( len - res >= 0 );
- assert( len - res < MAX_LINE_LENGTH);
-
- if (res > 0)
- my_memcpy( l, residue, res );
- if (len - res > 0)
- my_memcpy( l+res, g_status.tabout_buff, len - res );
- } else
- if (len > 0)
- my_memcpy( l, residue, len );
-
- ++line_count;
- temp_ll->line = l;
- temp_ll->dirty = FALSE;
- temp_ll->len = len;
- insert_node( fp, ll, temp_ll );
- } else
- rc = show_file_2big( name, prompt_line, temp_ll, l );
- }
- break;
- }
- }
- *file_mode = crlf;
- }
-
- /*
- * close the file
- */
- fp->length = line_count;
- }
- if (stream != NULL)
- fclose( stream );
- return( rc );
- }
-
-
- /*
- * Name: insert_node
- * Purpose: To insert a node into a double linked list
- * Date: December 1, 1992
- * Passed: fp: pointer to file structure that owns the double linked list
- * current: pointer to current node in double linked list
- * new: pointer to new node to insert into double linked list
- * Notes: if the current list pointer is the last node in the list, insert
- * new code behind current node.
- */
- void insert_node( file_infos *fp, line_list_ptr current, line_list_ptr new )
- {
-
- /*
- * standard double linked list insert
- */
- if (current->next != NULL) {
- current->next->prev = new;
- new->next = current->next;
- current->next = new;
- new->prev = current;
- /*
- * if the current node is the NULL node, insert the new node behind current
- */
- } else {
- new->next = current;
- if (current->prev != NULL)
- current->prev->next = new;
- new->prev = current->prev;
- current->prev = new;
- if (new->prev == NULL)
- fp->line_list = new;
- }
- }
-
-
- /*
- * Name: show_file_2big
- * Purpose: tell user we ran out of room loading file
- * Date: December 1, 1992
- * Passed: name: name of disk file
- * line: line to display messages
- * ll: double linked list pointer
- * t: text line pointer
- * Returns: WARNING
- * Notes: one or both of the malloc requests overflowed the heap. free the
- * dynamic if allocated.
- */
- int show_file_2big( char *name, int prompt_line, line_list_ptr ll, text_ptr t )
- {
- char temp[MAX_COLS+2];
-
- combine_strings( temp, main10a, name, main10b );
- error( WARNING, prompt_line, temp );
- if (t != NULL)
- my_free( t );
- if (ll != NULL)
- my_free( ll );
- return( WARNING );
- }
-
-
- /*
- * Name: backup_file
- * Purpose: To make a back-up copy of current file.
- * Date: June 5, 1991
- * Passed: window: current window pointer
- */
- int backup_file( TDE_WIN *window )
- {
- char *old_line_buff;
- char *old_tabout_buff;
- int old_line_buff_len;
- int old_tabout_buff_len;
- int old_copied;
- int rc;
- file_infos *file;
-
- rc = OK;
- file = window->file_info;
- if (file->backed_up == FALSE && file->modified == TRUE) {
- old_copied = g_status.copied;
- old_line_buff_len = g_status.line_buff_len;
- old_line_buff = calloc( MAX_LINE_LENGTH, sizeof(char) );
- old_tabout_buff_len = g_status.tabout_buff_len;
- old_tabout_buff = calloc( MAX_LINE_LENGTH, sizeof(char) );
-
- if (old_line_buff != NULL && old_tabout_buff != NULL) {
- memcpy( old_line_buff, g_status.line_buff, MAX_LINE_LENGTH );
- memcpy( old_tabout_buff, g_status.tabout_buff, MAX_LINE_LENGTH );
- if ((rc = save_backup( window )) != ERROR)
- file->backed_up = TRUE;
- else
- rc = ERROR;
- memcpy( g_status.line_buff, old_line_buff, MAX_LINE_LENGTH );
- memcpy( g_status.tabout_buff, old_tabout_buff, MAX_LINE_LENGTH );
- g_status.line_buff_len = old_line_buff_len;
- g_status.tabout_buff_len = old_tabout_buff_len;
- g_status.copied = old_copied;
- } else {
- error( WARNING, window->bottom_line, main4 );
- rc = ERROR;
- }
- if (old_line_buff != NULL)
- free( old_line_buff );
- if (old_tabout_buff != NULL)
- free( old_tabout_buff );
- }
- return( rc );
- }
-
-
- /*
- * Name: edit_file
- * Purpose: To allocate space for a new file structure and set up some
- * of the relevant fields.
- * Date: June 5, 1991
- * Modified: November 13, 1993, Frank Davis per Byrial Jensen
- * Passed: name: name of the file to edit
- * file_mode: BINARY or TEXT
- * bin_length: if opened in BINARY mode, length of binary lines
- * Returns: OK if file structure could be created
- * ERROR if out of memory
- *
- * Change: file->next_letter is initialized to 0 instead 'a'
- */
- int edit_file( char *name, int file_mode, int bin_length )
- {
- int rc; /* return code */
- int existing;
- int line;
- int rcol;
- register file_infos *file; /* file structure for file belonging to new window */
- file_infos *fp;
- long found_line;
- line_list_ptr ll;
- line_list_ptr temp_ll;
-
- line = g_display.nlines;
- rc = OK;
- /*
- * allocate a file structure for the new file
- */
- file = (file_infos *)calloc( 1, sizeof(file_infos) );
- if (file == NULL) {
- error( WARNING, line, main4 );
- rc = ERROR;
- }
- existing = FALSE;
- if (rc == OK && hw_fattrib( name ) == OK) {
- existing = TRUE;
- /*
- * g_status.temp_end is set last character read in file
- */
-
- if (g_status.command != DefineGrep &&
- g_status.command != DefineRegXGrep &&
- g_status.command != RepeatGrep)
- rc = load_file( name, file, &file_mode, bin_length );
- else {
- if (g_status.sas_defined) {
- rc = load_file( name, file, &file_mode, bin_length );
- if (rc != ERROR) {
- found_line = 1L;
- rcol = 0;
- if (g_status.sas_search_type == BOYER_MOORE)
- ll = search_forward( file->line_list, &found_line,
- (size_t *)&rcol );
- else
- ll = regx_search_forward( file->line_list, &found_line,
- &rcol );
- if (ll == NULL)
- rc = ERROR;
- else {
- g_status.sas_rline = found_line;
- g_status.sas_rcol = rcol;
- g_status.sas_ll = ll;
- }
- }
- } else
- rc = ERROR;
- }
- } else {
- if (ceh.flag == ERROR)
- rc = ERROR;
- else {
- existing = FALSE;
- file->length = 0l;
- file->undo_top = file->undo_bot = NULL;
- file->line_list_end = file->line_list = NULL;
- file->undo_count = 0;
- ll = (line_list_ptr)my_malloc( sizeof(line_list_struc), &rc );
- if (ll != NULL) {
- ll->line = NULL;
- ll->next = ll->prev = NULL;
- ll->dirty = FALSE;
- ll->len = EOF;
- file->undo_top = file->undo_bot = ll;
- } else
- rc = ERROR;
-
- ll = (line_list_ptr)my_malloc( sizeof(line_list_struc), &rc );
- if (ll != NULL) {
- ll->line = NULL;
- ll->next = ll->prev = NULL;
- ll->dirty = FALSE;
- ll->len = EOF;
- file->line_list_end = file->line_list = ll;
- } else
- rc = ERROR;
- if (rc == ERROR) {
- if (file->undo_top != NULL)
- my_free( file->undo_top );
- if (file->line_list != NULL)
- my_free( file->line_list );
- } else
- if (file_mode == TEXT)
- #if defined( __UNIX__ )
- file_mode = LF;
- #else
- file_mode = CRLF;
- #endif
- }
- }
-
- if (rc != ERROR) {
- /*
- * add file into list
- */
- file->prev = NULL;
- file->next = NULL;
- if (g_status.file_list == NULL)
- g_status.file_list = file;
- else {
- fp = g_status.current_file;
- file->prev = fp;
- if (fp->next)
- fp->next->prev = file;
- file->next = fp->next;
- fp->next = file;
- }
-
- /*
- * set up all the info we need to know about a file.
- */
-
- assert( file_mode == CRLF || file_mode == LF || file_mode == BINARY );
- assert( strlen( name ) < (size_t)g_display.ncols );
-
- strcpy( file->file_name, name );
- #if defined( __UNIX__ )
- get_fattr( name, &file->file_attrib );
- #else
- get_fattr( name, (int *)&file->file_attrib );
- #endif
- file->block_type = NOTMARKED;
- file->block_br = file->block_er = 0l;
- file->block_bc = file->block_ec = 0;
- file->ref_count = 0;
- file->modified = FALSE;
- file->backed_up = FALSE;
- file->new_file = !existing;
- file->next_letter = 0;
- file->file_no = ++g_status.file_count;
- file->crlf = file_mode;
- g_status.current_file = file;
- make_backup_fname( file );
- } else if (file != NULL) {
- /*
- * free the line pointers and linked list of line pointers.
- */
- ll = file->undo_top;
- while (ll != NULL) {
- temp_ll = ll->next;
- if (ll->line != NULL)
- my_free( ll->line );
- my_free( ll );
- ll = temp_ll;
- }
-
- ll = file->line_list;
- while (ll != NULL) {
- temp_ll = ll->next;
- if (ll->line != NULL)
- my_free( ll->line );
- my_free( ll );
- ll = temp_ll;
- }
-
- #if defined( __MSC__ )
- _fheapmin( );
- #endif
-
- free( file );
- }
- return( rc );
- }
-
-
- /*
- * Name: edit_another_file
- * Purpose: Bring in another file to editor.
- * Date: June 5, 1991
- * Passed: window: pointer to current window
- * Notes: New window replaces old window. Old window becomes invisible.
- */
- int edit_another_file( TDE_WIN *window )
- {
- #if defined( __UNIX__ )
- char fname[PATH_MAX]; /* new name for file */
- #else
- char fname[MAX_COLS]; /* new name for file */
- char spdrive[_MAX_DRIVE]; /* splitpath drive buff */
- char spdir[_MAX_DIR]; /* splitpath dir buff */
- char spname[_MAX_FNAME]; /* splitpath fname buff */
- char spext[_MAX_EXT]; /* splitpath ext buff */
- #endif
- register TDE_WIN *win; /* put window pointer in a register */
- int rc;
- int file_mode;
- int bin_length;
-
- win = window;
- entab_linebuff( );
- if (un_copy_line( win->ll, win, TRUE ) == ERROR)
- return( ERROR );
- /*
- * read in name, no default
- */
- fname[0] = '\0';
- /*
- * file name to edit
- */
- if ((rc = get_name( ed15, win->bottom_line, fname,
- g_display.message_color )) == OK && *fname != '\0') {
-
- #if defined( __UNIX__ )
-
- assert( strlen( fname ) < PATH_MAX );
-
- /*
- * X_OK is defined in unistd.h and tests for execute permission
- */
- if (access( fname, X_OK ) != ERROR) {
- file_mode = BINARY;
- bin_length = g_status.file_chunk;
- } else {
- file_mode = TEXT;
- bin_length = 0;
- }
- #else
-
- file_mode = TEXT;
- bin_length = 0;
-
- assert( strlen( fname ) < (size_t)g_display.ncols );
-
- _splitpath( fname, spdrive, spdir, spname, spext );
- if (stricmp( spext, ".exe" ) == 0 || stricmp( spext, ".com" ) == 0) {
- file_mode = BINARY;
- bin_length = g_status.file_chunk;
- }
- #endif
- rc = attempt_edit_display( fname, LOCAL, file_mode, bin_length );
- if (rc == OK)
- show_avail_mem( );
- }
- return( rc );
- }
-
-
- /*
- * Name: attempt_edit_display
- * Purpose: try to load then display a file
- * Date: June 5, 1991
- * Passed: fname: file name to load
- * update_type: update current window or entire screen
- * file_mode: BINARY or TEXT
- * bin_len: if opened in BINARY mode, length of binary lines
- * Notes: When we first start the editor, we need to update the entire
- * screen. When we load in a new file, we only need to update
- * the current window.
- */
- int attempt_edit_display( char *fname, int update_type, int file_mode,
- int bin_len )
- {
- register int rc;
- TDE_WIN *win;
-
- rc = edit_file( fname, file_mode, bin_len );
- if (rc != ERROR) {
- rc = initialize_window( );
- if (rc != ERROR) {
- win = g_status.current_window;
- if (update_type == LOCAL) {
- if (g_status.command != DefineGrep &&
- g_status.command != DefineRegXGrep &&
- g_status.command != RepeatGrep)
- redraw_current_window( win );
- show_file_count( g_status.file_count );
- show_window_count( g_status.window_count );
- show_avail_mem( );
- } else if (update_type == GLOBAL)
- redraw_screen( win );
- if (win->file_info->new_file) {
- g_status.command = AddLine;
- insert_newline( win );
- win->file_info->modified = FALSE;
- }
- }
- }
- return( rc );
- }
-
-
- /*
- * Name: file_file
- * Purpose: To file the current file to disk.
- * Date: September 17, 1991
- * Passed: window: pointer to current window
- */
- int file_file( TDE_WIN *window )
- {
- if (save_file( window ) == OK)
- finish( window );
- return( OK );
- }
-
-
- /*
- * Name: save_file
- * Purpose: To save the current file to disk.
- * Date: June 5, 1991
- * Passed: window: pointer to current window
- * Notes: If anything goes wrong, then the modified flag is set.
- * If the file is saved successfully, then modified flag is
- * cleared.
- */
- int save_file( TDE_WIN *window )
- {
- register file_infos *file;
- int rc;
- line_list_ptr temp_ll;
- #if defined( __UNIX__ )
- char temp[PATH_MAX+2];
- #else
- char temp[MAX_COLS+2];
- #endif
-
- entab_linebuff( );
- if (un_copy_line( window->ll, window, TRUE ) == ERROR)
- return( ERROR );
- file = window->file_info;
- if (file->modified == FALSE)
- return( OK );
- /*
- * set up file name
- */
- #if defined( __UNIX__ )
- assert( strlen( file->file_name ) < PATH_MAX );
- #else
- assert( strlen( file->file_name ) < (size_t)g_display.ncols );
- #endif
-
- strcpy( temp, file->file_name );
-
- /*
- * see if there was a file name - if not, then make the user
- * supply one.
- */
- if (strlen( temp ) == 0)
- rc = save_as_file( window );
- else {
- /*
- * save the file
- */
- rc = write_to_disk( window, temp );
- if (rc != ERROR) {
- file->modified = FALSE;
- file->new_file = FALSE;
- }
- }
-
- /*
- * clear the dirty flags
- */
- if (rc == OK) {
- temp_ll = window->file_info->line_list;
- for (; temp_ll->len != EOF; temp_ll=temp_ll->next)
- temp_ll->dirty = FALSE;
- window->file_info->dirty = GLOBAL;
- }
-
- return( rc );
- }
-
-
- /*
- * Name: save_backup
- * Purpose: To save a backup copy of the current file to disk.
- * Date: June 5, 1991
- * Passed: window: pointer to current window
- */
- int save_backup( TDE_WIN *window )
- {
- /*
- * set up file name
- */
- return( write_to_disk( window, window->file_info->backup_fname ) );
- }
-
-
- /*
- * Name: save_as_file
- * Purpose: To save the current file to disk, but under a new name.
- * Date: June 5, 1991
- * Passed: window: pointer to current window
- */
- int save_as_file( TDE_WIN *window )
- {
- int prompt_line;
- int rc;
- register TDE_WIN *win; /* put window pointer in a register */
- line_list_ptr temp_ll;
- #if defined( __UNIX__ )
- char answer[PATH_MAX+2];
- chtype display_buff[MAX_COLS+2]; /* chtype is defined in curses.h */
- mode_t fattr;
- #else
- char answer[MAX_COLS+2];
- char display_buff[(MAX_COLS+2)*2];
- int fattr;
- #endif
-
- win = window;
- entab_linebuff( );
- if (un_copy_line( win->ll, win, TRUE ) == ERROR)
- return( ERROR );
- /*
- * read in name
- */
- prompt_line = win->bottom_line;
- save_screen_line( 0, prompt_line, display_buff );
-
- answer[0] = '\0';
- /*
- * new file name:
- */
- if ((rc = get_name( utils9, prompt_line, answer,
- g_display.message_color )) == OK && *answer != '\0') {
-
- #if defined( __UNIX__ )
- /*
- * make sure it is OK to overwrite any existing file
- */
- rc = get_fattr( answer, &fattr );
- if (rc == OK) {
-
- /*
- * file exists. make sure this is a regular file, first
- */
- if (S_ISREG( fattr )) {
- /*
- * overwrite existing file?
- */
- set_prompt( utils10, prompt_line );
- if (get_yn( ) != A_YES ||
- change_mode( answer, prompt_line ) == ERROR)
- rc = ERROR;
- } else
- rc = ERROR;
- } else
- /*
- * file name does not exist. take a chance on a valid file name.
- */
- rc = OK;
-
- if (rc != ERROR)
- rc = write_to_disk( win, answer );
- #else
- /*
- * make sure it is OK to overwrite any existing file
- */
- rc = get_fattr( answer, &fattr );
- if (rc == OK) { /* file exists */
- /*
- * overwrite existing file?
- */
- set_prompt( utils10, prompt_line );
- if (get_yn( ) != A_YES ||
- change_mode( answer, prompt_line ) == ERROR)
- rc = ERROR;
- }
- if (rc != ERROR)
- rc = write_to_disk( win, answer );
- #endif
-
- /*
- * depending on personal taste, you may want to uncomment the next
- * lines to clear the dirty flags.
- */
- /*
- * if (rc == OK) {
- * temp_ll = window->file_info->line_list;
- * for (; temp_ll->len != EOF; temp_ll=temp_ll->next)
- * temp_ll->dirty = FALSE;
- * window->file_info->dirty = GLOBAL;
- * }
- */
- }
- restore_screen_line( 0, prompt_line, display_buff );
- return( rc );
- }
-
-
- #if defined( __UNIX__ )
- /*
- **********************************************************************
- ****************************** PART 1 ******************************
- **********************************************************************
- *
- * Let's try to make unix have the look and feel of a PC.
- */
-
-
- /*
- * Name: make_backup_fname
- * Purpose: insert a .bak to back of UNIX file name
- * Date: November 13, 1993
- * Passed: file: information allowing access to the current file
- */
- void make_backup_fname( file_infos *file )
- {
- char *p;
- int i;
- int len;
- char temp[PATH_MAX+2];
-
- /*
- * if this is a new file then don't create a backup - can't backup
- * a nonexisting file.
- */
- if (file->new_file)
- file->backed_up = TRUE;
-
- /*
- * find the file name extension if it exists
- */
- else {
- assert( strlen( file->file_name ) < PATH_MAX );
-
- strcpy( temp, file->file_name );
- len = strlen( temp );
- for (i=len, p=temp + len; i>=0; i--) {
-
- /*
- * we found the '.' extension character. get out
- */
- if (*p == '.')
- break;
-
- /*
- * we're at the beginning of the string - no directory char was
- * found. set the pointer to the beginning of file name string.
- */
- else if (i == 0) {
- p = temp + len;
- break;
- } else if (*p == '/') {
- /*
- * we found the directory character.
- */
- p = temp + len;
- break;
- }
- --p;
- }
-
- assert( strlen( temp ) + 5 < PATH_MAX );
-
- strcpy( p, ".bak" );
- strcpy( file->backup_fname, temp );
- }
- }
-
-
- /*
- * Name: write_to_disk
- * Purpose: To write file from memory to disk
- * Date: November 13, 1993
- * Passed: window: pointer to current window
- * fname: file name to save on disk
- */
- int write_to_disk( TDE_WIN *window, char *fname )
- {
- register file_infos *file;
- int rc;
- int prompt_line;
- char temp[MAX_COLS+2];
- char answer[PATH_MAX+2];
- mode_t fattr;
- chtype display_buff[MAX_COLS+2]; /* chtype is defined in curses.h */
-
- file = window->file_info;
- prompt_line = window->bottom_line;
-
- /*
- * set up file name
- */
- assert( strlen( fname ) < PATH_MAX );
-
- strcpy( answer, fname );
- save_screen_line( 0, prompt_line, display_buff );
- eol_clear( 0, prompt_line, g_display.message_color );
-
- /*
- * saving
- */
- if (strlen( answer ) > 50 )
- answer[50] ='\0';
- combine_strings( temp, utils6, answer, "'" );
- s_output( temp, prompt_line, 0, g_display.message_color );
- strcpy( answer, fname );
- if ((rc = hw_save( answer, file, 1L, file->length, NOTMARKED )) == ERROR) {
- if (ceh.flag != ERROR) {
- if (get_fattr( answer, &fattr ) == OK &&
- !(fattr & (S_IWUSR | S_IWGRP | S_IWOTH)))
- /*
- * file is read only
- */
- combine_strings( temp, utils7a, answer, utils7b );
- else
- /*
- * cannot write to
- */
- combine_strings( temp, utils8, answer, "'" );
- error( WARNING, prompt_line, temp );
- }
- }
- restore_screen_line( 0, prompt_line, display_buff );
- return( rc );
- }
-
-
- /*
- * Name: search_and_seize
- * Purpose: search files for a pattern
- * Date: November 13, 1993
- * Passed: window: pointer to current window
- * Notes: New window replaces old window. Old window becomes invisible.
- */
- int search_and_seize( TDE_WIN *window )
- {
- char name[PATH_MAX]; /* new name for file */
- char temp[PATH_MAX]; /* new name for file */
- char *eos;
- char searching[MAX_COLS]; /* buffer for displaying file name */
- int file_mode;
- mode_t file_attr;
- UNIX_DTA unix_dta;
- struct stat fstat;
- int bin_length;
- int i;
- int update_type;
- char *tokens;
- register int rc = ERROR;
- register TDE_WIN *win; /* put window pointer in a register */
- int bottom_line;
- chtype display_buff[MAX_COLS+2];
-
- win = window;
- update_type = win == NULL ? GLOBAL : LOCAL;
- if (update_type == LOCAL) {
- if (!g_status.sas_defined || g_status.command == DefineGrep ||
- g_status.command == DefineRegXGrep) {
-
- /*
- * prompt for the search pattern and the seize path.
- * initialize all this stuff.
- */
- if (g_status.command == DefineGrep)
- g_status.sas_search_type = BOYER_MOORE;
- else
- g_status.sas_search_type = REG_EXPRESSION;
-
- if (g_status.sas_search_type == BOYER_MOORE) {
- *sas_bm.pattern = '\0';
- if (get_name( win16a, win->bottom_line, (char *)sas_bm.pattern,
- g_display.message_color ) == ERROR)
- return( ERROR );
- if (*sas_bm.pattern == '\0')
- return( ERROR );
- } else {
- *sas_regx.pattern = '\0';
- if (get_name( win16b, win->bottom_line, (char *)sas_regx.pattern,
- g_display.message_color ) == ERROR)
- return( ERROR );
- if (*sas_regx.pattern == '\0')
- return( ERROR );
- else
- strcpy( (char *)regx.pattern, (char *)sas_regx.pattern );
- }
- *g_status.sas_tokens = '\0';
- if (get_name( win17, win->bottom_line, g_status.sas_tokens,
- g_display.message_color ) == ERROR)
- return( ERROR );
- i = 0;
- tokens = strtok( g_status.sas_tokens, SAS_DELIMITERS );
- while (tokens != NULL) {
- g_status.sas_arg_pointers[i++] = tokens;
- tokens = strtok( NULL, SAS_DELIMITERS );
- }
- if (i == 0)
- return( ERROR );
- g_status.sas_arg_pointers[i] = NULL;
- g_status.sas_argc = i;
- g_status.sas_arg = 0;
- g_status.sas_argv = g_status.sas_arg_pointers;
- g_status.sas_found_first = FALSE;
- if (g_status.command == DefineGrep) {
- g_status.sas_defined = TRUE;
- bm.search_defined = sas_bm.search_defined = OK;
- build_boyer_array( );
- } else {
- i = build_nfa( );
- if (i == OK) {
- g_status.sas_defined = TRUE;
- regx.search_defined = sas_regx.search_defined = OK;
- } else
- g_status.sas_defined = FALSE;
- }
- }
- bottom_line = win->bottom_line;
- } else
- bottom_line = g_display.nlines;
- if (g_status.sas_defined && g_status.sas_arg < g_status.sas_argc) {
- if (win != NULL) {
- entab_linebuff( );
- un_copy_line( win->ll, win, TRUE );
- }
-
- /*
- * while we haven't found a valid file, search thru the command
- * line path.
- * we may have an invalid file name when we finish matching all
- * files according to a pattern. then, we need to go to the next
- * command line argument if it exists.
- */
- while (rc == ERROR && g_status.sas_arg < g_status.sas_argc) {
-
- /*
- * if we haven't starting searching for a file, check to see if
- * the file is a valid file name. if no file is found, then let's
- * see if we can find according to a search pattern.
- */
- if (g_status.sas_found_first == FALSE) {
-
- assert( strlen( g_status.sas_argv[g_status.sas_arg] )
- < PATH_MAX );
-
- strcpy( name, g_status.sas_argv[g_status.sas_arg] );
- rc = get_fattr( name, &file_attr );
-
- /*
- * file exists.
- */
- if (rc == OK)
- ++g_status.sas_arg;
-
- /*
- * if we get this far, we may have a path name.
- */
- else if (rc != ERROR) {
-
- rc = OK;
- if ((g_status.sas_dp = opendir( name )) == NULL)
- rc = ERROR;
- else {
-
- /*
- * eos == end of stem
- */
- strcpy( temp, name );
- i = strlen( temp );
- if (temp[i-1] != '/')
- strcat( temp, "/" );
- eos = temp + strlen( temp );
-
- while ((rc = my_findnext( g_status.sas_dp, &unix_dta )) == OK) {
- strcpy( eos, unix_dta.fname );
- if (stat( eos, &fstat ) >= 0 && S_ISREG( fstat.st_mode ))
- break;
- }
- if (rc == ERROR) {
- closedir( g_status.sas_dp );
- g_status.sas_dp = NULL;
- }
- }
-
- /*
- * if we found a file using wildcard characters,
- * set the g_status.sas_found_first flag to true so we can
- * find the next matching file. we need to save the
- * pathname stem so we know which directory we are working in.
- */
- if (rc == OK) {
- g_status.found_first = TRUE;
-
- assert( strlen( temp ) < PATH_MAX );
-
- strcpy( name, temp );
-
- /*
- * g_status.sas_path includes the '/' at end of path
- */
- *eos = '\0';
- strcpy( g_status.sas_path, temp );
- } else {
- ++g_status.sas_arg;
- if (win != NULL)
- /*
- * invalid path or file name
- */
- error( WARNING, win->bottom_line, win8 );
- }
- } else if (rc == ERROR)
- ++g_status.sas_arg;
- } else {
-
- /*
- * we already found one file with wild card characters,
- * find the next matching file.
- */
- strcpy( temp, g_status.sas_path );
- eos = temp + strlen( temp );
-
- while ((rc = my_findnext( g_status.sas_dp, &unix_dta )) == OK) {
- strcpy( eos, unix_dta.fname );
- if (stat( eos, &fstat ) >= 0 && S_ISREG( fstat.st_mode ))
- break;
- }
-
- if (rc == OK) {
-
- assert( strlen( temp ) < PATH_MAX );
-
- strcpy( name, temp );
- } else {
- g_status.sas_found_first = FALSE;
- ++g_status.sas_arg;
- if (g_status.sas_dp != NULL)
- closedir( g_status.sas_dp );
- }
- }
-
- /*
- * if everything is everything so far, set up the file
- * and window structures and bring the file into the editor.
- */
- if (rc == OK) {
-
- assert( strlen( win19 ) + strlen( name ) < g_display.ncols );
-
- strcpy( searching, win19 );
- strcpy( temp, unix_dta.fname );
- if (strlen( temp ) > 50)
- temp[50] = '\0';
- strcat( searching, temp );
- save_screen_line( 0, bottom_line, display_buff );
- set_prompt( searching, bottom_line );
- file_mode = TEXT;
- bin_length = 0;
-
- assert( strlen( name ) < PATH_MAX );
-
- if (access( name, X_OK ) != ERROR) {
- file_mode = BINARY;
- bin_length = g_status.file_chunk;
- }
-
- rc = attempt_edit_display( name, update_type, file_mode, bin_length );
- if (rc == OK)
- show_avail_mem( );
- restore_screen_line( 0, bottom_line, display_buff );
-
- if (rc == OK) {
- win = g_status.current_window;
- bin_offset_adjust( win, g_status.sas_rline );
- find_adjust( win, g_status.sas_ll, g_status.sas_rline,
- g_status.sas_rcol );
- make_ruler( win );
- show_ruler( win );
- show_ruler_pointer( win );
- show_window_header( win );
- if (win->vertical)
- show_vertical_separator( win );
- win->file_info->dirty = LOCAL;
- }
- }
-
- /*
- * either there are no more matching files or we had an
- * invalid file name, set rc to ERROR and let's look at the
- * next file name or pattern on the command line.
- */
- else
- rc = ERROR;
- }
- }
- if (rc == ERROR && g_status.sas_arg >= g_status.sas_argc && win != NULL)
- /*
- * no more files to load
- */
- error( WARNING, win->bottom_line, win9 );
- return( rc );
- }
-
-
- /*
- * Name: edit_next_file
- * Purpose: edit next file on command line.
- * Date: November 13, 1993
- * Passed: window: pointer to current window
- * Notes: New window replaces old window. Old window becomes invisible.
- */
- int edit_next_file( TDE_WIN *window )
- {
- char name[PATH_MAX+2]; /* new name for file */
- char temp[PATH_MAX+2]; /* temp for new name for file */
- char *eos; /* end of string */
- mode_t file_type;
- UNIX_DTA unix_dta;
- struct stat fstat;
- int file_mode;
- int bin_length;
- int i;
- int update_type;
- register int rc = ERROR;
- register TDE_WIN *win; /* put window pointer in a register */
-
- win = window;
- update_type = win == NULL ? GLOBAL : LOCAL;
- if (g_status.arg < g_status.argc) {
- if (win != NULL) {
- entab_linebuff( );
- if (un_copy_line( win->ll, win, TRUE ) == ERROR)
- return( ERROR );
- }
-
- /*
- * while we haven't found a valid file, search thru the command
- * line path.
- * we may have an invalid file name when we finish matching all
- * files according to a pattern. then, we need to go to the next
- * command line argument if it exists.
- */
- while (rc == ERROR && g_status.arg < g_status.argc) {
-
- /*
- * if we haven't starting searching for a file, check to see if
- * the file is a valid file name. if no file is found, then let's
- * see if we can find according to a search pattern.
- */
- if (g_status.found_first == FALSE) {
-
- assert( strlen( g_status.argv[g_status.arg] ) < PATH_MAX );
-
- strcpy( name, g_status.argv[g_status.arg] );
- rc = get_fattr( name, &file_type );
-
- /*
- * file exists
- */
- if (rc == OK)
- ++g_status.arg;
-
- /*
- * if we get this far, we may have a path name.
- */
- else {
-
- rc = OK;
-
- /*
- * try to open arg as a directory name.
- */
- if ((g_status.dp = opendir( name )) == NULL) {
-
- /*
- * failed as a directory name. now, try to open a new file
- */
- ++g_status.arg;
- } else {
-
- /*
- * eos == end of stem
- */
- strcpy( temp, name );
- i = strlen( temp );
- if (temp[i-1] != '/')
- strcat( temp, "/" );
- eos = temp + strlen( temp );
-
- while ((rc = my_findnext( g_status.dp, &unix_dta )) == OK) {
- strcpy( eos, unix_dta.fname );
- if (stat( eos, &fstat ) >= 0 && S_ISREG( fstat.st_mode ))
- break;
- }
- if (rc == ERROR) {
- closedir( g_status.dp );
- g_status.dp = NULL;
- ++g_status.arg;
- if (win != NULL)
- /*
- * invalid path or file name
- */
- error( WARNING, win->bottom_line, win8 );
- } else {
-
- /*
- * if we found a file using wildcard characters,
- * set the g_status.found_first flag to true so we can
- * find the next matching file. we need to save the
- * pathname stem so we know which directory we are working in.
- */
- g_status.found_first = TRUE;
-
- assert( strlen( temp ) < PATH_MAX );
-
- strcpy( name, temp );
-
- /*
- * g_status.path includes the '/' at end of path
- */
- *eos = '\0';
- strcpy( g_status.path, temp );
- }
- }
- }
- } else {
-
- /*
- * we already found one file with wild card characters,
- * find the next matching file.
- */
- strcpy( temp, g_status.path );
- eos = temp + strlen( temp );
-
- while ((rc = my_findnext( g_status.dp, &unix_dta )) == OK) {
- strcpy( eos, unix_dta.fname );
- if (stat( eos, &fstat ) >= 0 && S_ISREG( fstat.st_mode ))
- break;
- }
-
- if (rc == OK) {
-
- assert( strlen( temp ) < PATH_MAX );
-
- strcpy( name, temp );
- } else {
- g_status.found_first = FALSE;
- ++g_status.arg;
- if (g_status.dp != NULL)
- closedir( g_status.dp );
- }
- }
-
- /*
- * if everything is everything so far, set up the file
- * and window structures and bring the file into the editor.
- */
- if (rc == OK) {
- file_mode = g_status.file_mode;
- bin_length = g_status.file_chunk;
-
- assert( strlen( name ) < PATH_MAX );
-
- if (access( name, X_OK ) != ERROR) {
- file_mode = BINARY;
- bin_length = g_status.file_chunk;
- }
-
- rc = attempt_edit_display( name, update_type, file_mode, bin_length );
- if (rc == OK)
- show_avail_mem( );
- }
-
- /*
- * either there are no more matching files or we had an
- * invalid file name, set rc to ERROR and let's look at the
- * next file name or pattern on the command line.
- */
- else
- rc = ERROR;
- }
- }
- if (rc == ERROR && g_status.arg >= g_status.argc && win != NULL)
- /*
- * no more files to load
- */
- error( WARNING, win->bottom_line, win9 );
- return( rc );
- }
-
-
- /*
- * Name: hw_fattrib
- * Purpose: To determine the current file attributes.
- * Date: November 13, 1993
- * 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;
- mode_t fattr;
-
- rc = get_fattr( name, &fattr );
- return( rc == OK ? rc : ERROR );
- }
-
-
- /*
- * Name: change_mode
- * Purpose: To prompt for file access mode.
- * Date: November 13, 1993
- * 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 )
- {
- mode_t fattr;
- register int rc;
- chtype display_buff[MAX_COLS+2];
-
- rc = get_fattr( name, &fattr );
- if (rc == OK && !(fattr & S_IWUSR)) {
- /*
- * file cannot be written
- */
- save_screen_line( 0, line, display_buff );
- /*
- * file is write protected. overwrite anyway (y/n)?
- */
- set_prompt( main6, line );
- if (get_yn( ) != A_YES)
- rc = ERROR;
- else if (set_fattr( name, fattr & S_IWUSR & S_IWGRP & S_IWOTH ) != OK)
- rc = ERROR;
- restore_screen_line( 0, line, display_buff );
- }
- return( rc );
- }
-
-
- /*
- * Name: change_fattr
- * Purpose: To change the file attributes
- * Date: December 31, 1991
- * Passed: window: pointer to current window
- */
- int change_fattr( TDE_WIN *window )
- {
- file_infos *file;
- TDE_WIN *wp;
- int prompt_line;
- register int ok;
- mode_t fattr;
- char *s;
- int rc;
- char answer[MAX_COLS+2];
- chtype display_buff[MAX_COLS+2];
-
- prompt_line = window->bottom_line;
- save_screen_line( 0, prompt_line, display_buff );
-
- answer[0] = '\0';
- /*
- * enter new file attributes
- */
- rc = OK;
- if ((ok = get_name( utils14, prompt_line, answer,
- g_display.message_color )) == OK) {
- if (*answer != '\0') {
- fattr = window->file_info->file_attrib;
-
- /*
- * turn off rwx for user, group, and other.
- */
- fattr &= ~S_IRWXU;
- fattr &= ~S_IRWXG;
- fattr &= ~S_IRWXO;
- s = answer;
-
- while (ok = toupper( *s )) {
- switch (*s) {
- case L_UNIX_READ :
- fattr |= S_IRUSR;
- fattr |= S_IRGRP;
- fattr |= S_IROTH;
- break;
- case L_UNIX_WRITE :
- fattr |= S_IWUSR;
- fattr |= S_IWGRP;
- fattr |= S_IWOTH;
- break;
- case L_UNIX_EXECUTE :
- fattr |= S_IXUSR;
- fattr |= S_IXGRP;
- fattr |= S_IXOTH;
- break;
- default :
- break;
- }
- s++;
- }
- file = window->file_info;
- if (set_fattr( file->file_name, fattr ) == ERROR) {
- /*
- * new file attributes not set
- */
- error( WARNING, prompt_line, utils15 );
- rc = ERROR;
- } else {
- file->file_attrib = fattr;
- for (wp=g_status.window_list; wp!=NULL; wp=wp->next) {
- if (wp->file_info == file && wp->visible)
- show_window_fname( wp );
- }
- }
- }
- } else
- rc = ERROR;
- restore_screen_line( 0, prompt_line, display_buff );
- return( rc );
- }
-
-
- /*
- * Name: get_fattr
- * Purpose: To get unix file attributes
- * Date: November 13, 1993
- * Passed: fname: ASCIIZ file name. Null terminated file name
- * fattr: pointer to file attributes
- * Returns: OK if successful, ERROR if error
- * Notes: Use stat( ) to get file attributes.
- */
- int get_fattr( char *fname, mode_t *fattr )
- {
- int rc; /* return code */
- struct stat fstat;
-
- assert( fname != NULL && fattr != NULL);
-
- rc = OK;
- ceh.flag = OK;
- if (stat( fname, &fstat) != ERROR)
- *fattr = fstat.st_mode;
- else
- rc = ERROR;
- if (ceh.flag == ERROR)
- rc = ERROR;
- return( rc );
- }
-
-
- /*
- * Name: set_fattr
- * Purpose: To set unix file attributes
- * Date: November 13, 1993
- * Passed: fname: ASCIIZ file name. Null terminated file name
- * fattr: mode_t file attributes
- * Returns: 0 if successfull, non zero if not
- * Notes: Use chmod( ) function to set file attributes. To change a
- * file mode, the effective user ID of the process must equal the
- * owner of the file, or be a superuser.
- */
- int set_fattr( char *fname, mode_t fattr )
- {
- int rc; /* return code */
-
- assert( fname != NULL );
-
- ceh.flag = OK;
- rc = OK;
- if (chmod( fname, fattr ) == ERROR)
- rc = ERROR;
- if (ceh.flag == ERROR)
- rc = ERROR;
- return( rc );
- }
-
-
- /*
- * Name: get_current_directory
- * Purpose: get current directory
- * Date: November 13, 1993
- * Passed: path: pointer to buffer to store path
- * drive: drive to get current directory
- * Notes: use simple DOS interrupt
- */
- int get_current_directory( char *path, size_t path_size )
- {
- register int rc;
-
- assert( path != NULL );
-
- rc = OK;
- ceh.flag = OK;
- if (getcwd( path, path_size ) == NULL)
- rc = ERROR;
- if (ceh.flag == ERROR)
- rc = ERROR;
- return( rc );
- }
-
-
- /*
- * Name: set_current_directory
- * Purpose: set current directory
- * Date: November 13, 1993
- * Passed: new_path: directory path, which may include drive letter
- * Notes: use simple DOS interrupt
- */
- int set_current_directory( char *new_path )
- {
- register int rc;
-
- assert( new_path != NULL );
-
- rc = OK;
- ceh.flag = OK;
- if( chdir( new_path ) == ERROR)
- rc = ERROR;
- if (ceh.flag == ERROR)
- rc = ERROR;
- return( rc );
- }
-
- #else
- /*
- **********************************************************************
- ****************************** PART 2 ******************************
- **********************************************************************
- *
- * Calls to BIOS and writes to PC hardware.
- */
-
-
- /*
- * Name: make_backup_fname
- * Purpose: add .bak to file name
- * Date: January 6, 1992
- * Passed: file: information allowing access to the current file
- */
- void make_backup_fname( file_infos *file )
- {
- char *p;
- int i;
- int len;
- char temp[MAX_COLS+2];
-
- /*
- * if this is a new file then don't create a backup - can't backup
- * a nonexisting file.
- */
- if (file->new_file)
- file->backed_up = TRUE;
-
- /*
- * find the file name extension if it exists
- */
- else {
- assert( strlen( file->file_name ) < (size_t)g_display.ncols );
-
- strcpy( temp, file->file_name );
- len = strlen( temp );
- for (i=len, p=temp + len; i>=0; i--) {
-
- /*
- * we found the '.' extension character. get out
- */
- if (*p == '.')
- break;
-
- /*
- * we found the drive or directory character. no extension so
- * set the pointer to the end of file name string.
- */
- else if (*p == '\\' || *p == ':') {
- p = temp + len;
- break;
-
- /*
- * we're at the beginning of the string - no '.', drive, or directory
- * char was found. set the pointer to the end of file name string.
- */
- } else if (i == 0) {
- p = temp + len;
- break;
- }
- --p;
- }
- assert( strlen( temp ) < (size_t)g_display.ncols );
- strcpy( p, ".bak" );
- strcpy( file->backup_fname, temp );
- }
- }
-
-
- /*
- * Name: write_to_disk
- * Purpose: To write file from memory to disk
- * Date: June 5, 1991
- * Passed: window: pointer to current window
- * fname: file name to save on disk
- */
- int write_to_disk( TDE_WIN *window, char *fname )
- {
- register file_infos *file;
- int rc;
- int prompt_line;
- char temp[MAX_COLS+2];
- char answer[MAX_COLS+2];
- char display_buff[(MAX_COLS+2)*2];
- int fattr;
-
- file = window->file_info;
- prompt_line = window->bottom_line;
-
- /*
- * set up file name
- */
- assert( strlen( fname ) < (size_t)g_display.ncols );
-
- strcpy( answer, fname );
- save_screen_line( 0, prompt_line, display_buff );
- eol_clear( 0, prompt_line, g_display.message_color );
-
- /*
- * saving
- */
- combine_strings( temp, utils6, answer, "'" );
- s_output( temp, prompt_line, 0, g_display.message_color );
- if ((rc = hw_save( answer, file, 1L, file->length, NOTMARKED )) == ERROR) {
- if (ceh.flag != ERROR) {
- if (get_fattr( answer, &fattr ) == OK && fattr & READ_ONLY)
- /*
- * file is read only
- */
- combine_strings( temp, utils7a, answer, utils7b );
- else
- /*
- * cannot write to
- */
- combine_strings( temp, utils8, answer, "'" );
- error( WARNING, prompt_line, temp );
- }
- }
- restore_screen_line( 0, prompt_line, display_buff );
- return( rc );
- }
-
-
- /*
- * Name: search_and_seize
- * Purpose: search files for a pattern
- * Date: October 31, 1992
- * Passed: window: pointer to current window
- * Notes: New window replaces old window. Old window becomes invisible.
- */
- int search_and_seize( TDE_WIN *window )
- {
- char name[MAX_COLS]; /* new name for file */
- char searching[MAX_COLS]; /* buffer for displaying file name */
- char spdrive[_MAX_DRIVE]; /* splitpath drive buff */
- char spdir[_MAX_DIR]; /* splitpath dir buff */
- char spname[_MAX_FNAME]; /* splitpath fname buff */
- char spext[_MAX_EXT]; /* splitpath ext buff */
- int file_mode;
- int bin_length;
- int i;
- int update_type;
- char *tokens;
- register int rc = ERROR;
- register TDE_WIN *win; /* put window pointer in a register */
- int bottom_line;
- char display_buff[(MAX_COLS+2)*2];
-
- win = window;
- update_type = win == NULL ? GLOBAL : LOCAL;
- if (update_type == LOCAL) {
- if (!g_status.sas_defined || g_status.command == DefineGrep ||
- g_status.command == DefineRegXGrep) {
-
- /*
- * prompt for the search pattern and the seize path.
- * initialize all this stuff.
- */
- if (g_status.command == DefineGrep)
- g_status.sas_search_type = BOYER_MOORE;
- else
- g_status.sas_search_type = REG_EXPRESSION;
-
- if (g_status.sas_search_type == BOYER_MOORE) {
- *sas_bm.pattern = '\0';
- if (get_name( win16a, win->bottom_line, (char *)sas_bm.pattern,
- g_display.message_color ) == ERROR)
- return( ERROR );
- if (*sas_bm.pattern == '\0')
- return( ERROR );
- } else {
- *sas_regx.pattern = '\0';
- if (get_name( win16b, win->bottom_line, (char *)sas_regx.pattern,
- g_display.message_color ) == ERROR)
- return( ERROR );
- if (*sas_regx.pattern == '\0')
- return( ERROR );
- else
- strcpy( (char *)regx.pattern, (char *)sas_regx.pattern );
- }
- *g_status.sas_tokens = '\0';
- if (get_name( win17, win->bottom_line, g_status.sas_tokens,
- g_display.message_color ) == ERROR)
- return( ERROR );
- i = 0;
- tokens = strtok( g_status.sas_tokens, SAS_DELIMITERS );
- while (tokens != NULL) {
- g_status.sas_arg_pointers[i++] = tokens;
- tokens = strtok( NULL, SAS_DELIMITERS );
- }
- if (i == 0)
- return( ERROR );
- g_status.sas_arg_pointers[i] = NULL;
- g_status.sas_argc = i;
- g_status.sas_arg = 0;
- g_status.sas_argv = g_status.sas_arg_pointers;
- g_status.sas_found_first = FALSE;
- if (g_status.command == DefineGrep) {
- g_status.sas_defined = TRUE;
- bm.search_defined = sas_bm.search_defined = OK;
- build_boyer_array( );
- } else {
- i = build_nfa( );
- if (i == OK) {
- g_status.sas_defined = TRUE;
- regx.search_defined = sas_regx.search_defined = OK;
- } else
- g_status.sas_defined = FALSE;
- }
- }
- bottom_line = win->bottom_line;
- } else
- bottom_line = g_display.nlines;
- if (g_status.sas_defined && g_status.sas_arg < g_status.sas_argc) {
- if (win != NULL) {
- entab_linebuff( );
- un_copy_line( win->ll, win, TRUE );
- }
-
- /*
- * while we haven't found a valid file, search thru the command
- * line path.
- * we may have an invalid file name when we finish matching all
- * files according to a pattern. then, we need to go to the next
- * command line argument if it exists.
- */
- while (rc == ERROR && g_status.sas_arg < g_status.sas_argc) {
-
- /*
- * if we haven't starting searching for a file, check to see if
- * the file is a valid file name. if no file is found, then let's
- * see if we can find according to a search pattern.
- */
- if (g_status.sas_found_first == FALSE) {
-
- assert( strlen( g_status.sas_argv[g_status.sas_arg] )
- < (size_t)g_display.ncols );
-
- strcpy( name, g_status.sas_argv[g_status.sas_arg] );
- rc = get_fattr( name, &i );
-
- /*
- * a new or blank file generates a return code of 2.
- * a pattern with wild cards generates a return code of 3.
- */
- if (rc == OK || rc == 2) {
- ++g_status.sas_arg;
- rc = OK;
-
- /*
- * if we get this far, we got an invalid path name.
- * let's try to find a matching file name using pattern.
- */
- } else if (rc != ERROR) {
- rc = my_findfirst( &g_status.sas_dta, name, NORMAL | READ_ONLY |
- HIDDEN | SYSTEM | ARCHIVE );
-
- /*
- * if we found a file using wildcard characters,
- * set the g_status.sas_found_first flag to true so we can
- * find the next matching file. we need to save the
- * pathname stem so we know which directory we are working in.
- */
- if (rc == OK) {
- g_status.sas_found_first = TRUE;
- i = strlen( name ) - 1;
- while (i >= 0) {
- if (name[i] == ':' || name[i] == '\\')
- break;
- --i;
- }
- name[++i] = '\0';
-
- assert( strlen( name ) + strlen( g_status.sas_dta.name )
- < (size_t)g_display.ncols );
-
- strcpy( g_status.sas_path, name );
- strcpy( name, g_status.sas_path );
- strcat( name, g_status.sas_dta.name );
- } else {
- ++g_status.sas_arg;
- if (win != NULL)
- /*
- * invalid path or file name
- */
- error( WARNING, win->bottom_line, win8 );
- }
- } else if (rc == ERROR)
- ++g_status.sas_arg;
- } else {
-
- /*
- * we already found one file with wild card characters,
- * find the next matching file.
- */
- rc = my_findnext( &g_status.sas_dta );
- if (rc == OK) {
-
- assert( strlen( g_status.sas_path ) +
- strlen( g_status.sas_dta.name ) < (size_t)g_display.ncols );
-
- strcpy( name, g_status.sas_path );
- strcat( name, g_status.sas_dta.name );
- } else {
- g_status.sas_found_first = FALSE;
- ++g_status.sas_arg;
- }
- }
-
- /*
- * if everything is everything so far, set up the file
- * and window structures and bring the file into the editor.
- */
- if (rc == OK) {
-
- assert( strlen( win19 ) + strlen( name ) < (size_t)g_display.ncols );
-
- strcpy( searching, win19 );
- strcat( searching, name );
- save_screen_line( 0, bottom_line, display_buff );
- set_prompt( searching, bottom_line );
- file_mode = TEXT;
- bin_length = 0;
-
- assert( strlen( name ) <= (size_t)g_display.ncols );
-
- _splitpath( name, spdrive, spdir, spname, spext );
- if (stricmp( spext, ".exe" ) == 0 || stricmp( spext, ".com" ) == 0){
- file_mode = BINARY;
- bin_length = g_status.file_chunk;
- }
- rc = attempt_edit_display( name, update_type, file_mode, bin_length );
- if (rc == OK)
- show_avail_mem( );
- restore_screen_line( 0, bottom_line, display_buff );
-
- if (rc == OK) {
- win = g_status.current_window;
- bin_offset_adjust( win, g_status.sas_rline );
- find_adjust( win, g_status.sas_ll, g_status.sas_rline,
- g_status.sas_rcol );
- make_ruler( win );
- show_ruler( win );
- show_ruler_pointer( win );
- show_window_header( win );
- if (win->vertical)
- show_vertical_separator( win );
- win->file_info->dirty = LOCAL;
- }
- }
-
- /*
- * either there are no more matching files or we had an
- * invalid file name, set rc to ERROR and let's look at the
- * next file name or pattern on the command line.
- */
- else
- rc = ERROR;
- }
- }
- if (rc == ERROR && g_status.sas_arg >= g_status.sas_argc && win != NULL)
- /*
- * no more files to load
- */
- error( WARNING, win->bottom_line, win9 );
- return( rc );
- }
-
-
- /*
- * Name: edit_next_file
- * Purpose: edit next file on command line.
- * Date: January 6, 1992
- * Passed: window: pointer to current window
- * Notes: New window replaces old window. Old window becomes invisible.
- */
- int edit_next_file( TDE_WIN *window )
- {
- char name[MAX_COLS]; /* new name for file */
- char spdrive[_MAX_DRIVE]; /* splitpath drive buff */
- char spdir[_MAX_DIR]; /* splitpath dir buff */
- char spname[_MAX_FNAME]; /* splitpath fname buff */
- char spext[_MAX_EXT]; /* splitpath ext buff */
- int file_mode;
- int bin_length;
- int i;
- int update_type;
- register int rc = ERROR;
- register TDE_WIN *win; /* put window pointer in a register */
-
- win = window;
- update_type = win == NULL ? GLOBAL : LOCAL;
- if (g_status.arg < g_status.argc) {
- if (win != NULL) {
- entab_linebuff( );
- if (un_copy_line( win->ll, win, TRUE ) == ERROR)
- return( ERROR );
- }
-
- /*
- * while we haven't found a valid file, search thru the command
- * line path.
- * we may have an invalid file name when we finish matching all
- * files according to a pattern. then, we need to go to the next
- * command line argument if it exists.
- */
- while (rc == ERROR && g_status.arg < g_status.argc) {
-
- /*
- * if we haven't starting searching for a file, check to see if
- * the file is a valid file name. if no file is found, then let's
- * see if we can find according to a search pattern.
- */
- if (g_status.found_first == FALSE) {
-
- assert( strlen( g_status.argv[g_status.arg] ) <
- (size_t)g_display.ncols );
-
- strcpy( name, g_status.argv[g_status.arg] );
- rc = get_fattr( name, &i );
-
- /*
- * a new or blank file generates a return code of 2.
- * a pattern with wild cards generates a return code of 3.
- */
- if (rc == OK || rc == 2) {
- ++g_status.arg;
- rc = OK;
-
- /*
- * if we get this far, we got an invalid path name.
- * let's try to find a matching file name using pattern.
- */
- } else if (rc != ERROR) {
- rc = my_findfirst( &g_status.dta, name, NORMAL | READ_ONLY |
- HIDDEN | SYSTEM | ARCHIVE );
-
- /*
- * if we found a file using wildcard characters,
- * set the g_status.found_first flag to true so we can
- * find the next matching file. we need to save the
- * pathname stem so we know which directory we are working in.
- */
- if (rc == OK) {
- g_status.found_first = TRUE;
- i = strlen( name ) - 1;
- while (i >= 0) {
- if (name[i] == ':' || name[i] == '\\')
- break;
- --i;
- }
- name[++i] = '\0';
-
- assert( strlen( name ) < (size_t)g_display.ncols );
-
- strcpy( g_status.path, name );
- strcpy( name, g_status.path );
- strcat( name, g_status.dta.name );
- } else {
- ++g_status.arg;
- if (win != NULL)
- /*
- * invalid path or file name
- */
- error( WARNING, win->bottom_line, win8 );
- }
- } else if (rc == ERROR)
- ++g_status.arg;
- } else {
-
- /*
- * we already found one file with wild card characters,
- * find the next matching file.
- */
- rc = my_findnext( &g_status.dta );
- if (rc == OK) {
-
- assert( strlen( g_status.path ) + strlen( g_status.dta.name )
- < (size_t)g_display.ncols );
-
- strcpy( name, g_status.path );
- strcat( name, g_status.dta.name );
- } else {
- g_status.found_first = FALSE;
- ++g_status.arg;
- }
- }
-
- /*
- * if everything is everything so far, set up the file
- * and window structures and bring the file into the editor.
- */
- if (rc == OK) {
- file_mode = g_status.file_mode;
- bin_length = g_status.file_chunk;
-
- assert( strlen( name ) <= (size_t)g_display.ncols );
-
- _splitpath( name, spdrive, spdir, spname, spext );
- if (stricmp( spext, ".exe" ) == 0 || stricmp( spext, ".com" ) == 0)
- file_mode = BINARY;
- rc = attempt_edit_display( name, update_type, file_mode, bin_length );
- if (rc == OK)
- show_avail_mem( );
- }
-
- /*
- * either there are no more matching files or we had an
- * invalid file name, set rc to ERROR and let's look at the
- * next file name or pattern on the command line.
- */
- else
- rc = ERROR;
- }
- }
- if (rc == ERROR && g_status.arg >= g_status.argc && win != NULL)
- /*
- * no more files to load
- */
- error( WARNING, win->bottom_line, win9 );
- return( rc );
- }
-
-
- /*
- * 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 display_buff[(MAX_COLS+2)*2];
-
- 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, display_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, display_buff );
- }
- return( rc );
- }
-
-
- /*
- * Name: change_fattr
- * Purpose: To change the file attributes
- * Date: December 31, 1991
- * Passed: window: pointer to current window
- */
- int change_fattr( TDE_WIN *window )
- {
- file_infos *file;
- TDE_WIN *wp;
- int prompt_line;
- register int ok;
- unsigned char fattr;
- char *s;
- int rc;
- char answer[MAX_COLS+2];
- char display_buff[(MAX_COLS+2)*2];
-
- prompt_line = window->bottom_line;
- save_screen_line( 0, prompt_line, display_buff );
-
- answer[0] = '\0';
- /*
- * enter new file attributes
- */
- if ((ok = get_name( utils14, prompt_line, answer,
- g_display.message_color )) == OK) {
- if (*answer != '\0') {
- fattr = 0;
- s = answer;
-
- /*
- * yes, I know lint complains about "ok = *s++".
- */
- while (ok = toupper( *s )) {
- switch (ok) {
- case L_DOS_ARCHIVE :
- fattr |= ARCHIVE;
- break;
- case L_DOS_SYSTEM :
- fattr |= SYSTEM;
- break;
- case L_DOS_HIDDEN :
- fattr |= HIDDEN;
- break;
- case L_DOS_READ_ONLY :
- fattr |= READ_ONLY;
- break;
- default :
- break;
- }
- s++;
- }
- file = window->file_info;
- if (set_fattr( file->file_name, fattr ))
- /*
- * new file attributes not set
- */
- error( WARNING, prompt_line, utils15 );
- else {
- file->file_attrib = fattr;
- for (wp=g_status.window_list; wp!=NULL; wp=wp->next) {
- if (wp->file_info == file && wp->visible)
- show_window_fname( wp );
- }
- }
- }
- rc = OK;
- } else
- rc = ERROR;
- restore_screen_line( 0, prompt_line, display_buff );
- return( rc );
- }
-
-
- /*
- * Name: get_fattr
- * Purpose: To get dos file attributes
- * Date: December 26, 1991
- * Passed: fname: ASCIIZ file name. Null terminated file name
- * fattr: pointer to file attributes
- * Returns: 0 if successfull, non zero if not
- * Notes: Uses the DOS function to get file attributes. I really didn't
- * like the file attribute functions in the C library: fstat() and
- * stat() or access() and chmod().
- * FYI, File Attributes:
- * 0x00 = Normal. Can be read or written w/o restriction
- * 0x01 = Read-only. Cannot be opened for write; a file with
- * the same name cannot be created.
- * 0x02 = Hidden. Not found by directory search.
- * 0x04 = System. Not found by directory search.
- * 0x08 = Volumn Label.
- * 0x10 = Directory.
- * 0x20 = Archive. Set whenever the file is changed, or
- * cleared by the Backup command.
- * Return codes:
- * 0 = No error
- * 1 = AL not 0 or 1
- * 2 = file is invalid or does not exist
- * 3 = path is invalid or does not exist
- * 5 = Access denied
- */
- int get_fattr( char FAR *fname, int *fattr )
- {
- int rc; /* return code */
- int attr;
-
- ASSEMBLE {
- push ds
- mov dx, WORD PTR fname /* get OFFSET of filename string */
- mov ax, WORD PTR fname+2 /* get SEGMENT of filename string */
- mov ds, ax /* put SEGMENT in ds */
- mov ax, 0x4300 /* function: get file attributes */
- int 0x21 /* DOS interrupt */
- pop ds
-
- jc an_error /* save the error code from get attr */
- xor ax, ax /* if no carry, no error */
- jmp SHORT get_out /* lets get out */
- }
- an_error:
-
-
- ASSEMBLE {
- xor cx, cx /* if error, then zero out cx - attrs */
- }
- get_out:
-
- ASSEMBLE {
- mov WORD PTR rc, ax /* ax contains error number on error */
- mov WORD PTR attr, cx /* cx contains file attributes */
- }
- *fattr = attr;
- if (ceh.flag == ERROR)
- rc = ERROR;
- return( rc );
- }
-
-
- /*
- * Name: set_fattr
- * Purpose: To set dos file attributes
- * Date: December 26, 1991
- * Passed: fname: ASCIIZ file name. Null terminated file name
- * fattr: file attributes
- * Returns: 0 if successfull, non zero if not
- * Notes: Uses the DOS function to get file attributes.
- * Return codes:
- * 0 = No error
- * 1 = AL not 0 or 1
- * 2 = file is invalid or does not exist
- * 3 = path is invalid or does not exist
- * 5 = Access denied
- */
- int set_fattr( char FAR *fname, int fattr )
- {
- int rc; /* return code */
-
- ASSEMBLE {
- push ds
- mov dx, WORD PTR fname /* get OFFSET of filename string */
- mov ax, WORD PTR fname+2 /* get SEGMENT of filename string */
- mov ds, ax /* put SEGMENT in ds */
- mov cx, WORD PTR fattr /* cx contains file attributes */
- mov ax, 0x4301 /* function: get file attributes */
- int 0x21 /* DOS interrupt */
- pop ds
-
- jc get_out /* save the error code from get attr */
- xor ax, ax /* if no carry, no error */
- }
- get_out:
-
- ASSEMBLE {
- mov WORD PTR rc, ax /* ax contains error number on error */
- }
- if (ceh.flag == ERROR)
- rc = ERROR;
- return( rc );
- }
-
-
- /*
- * Name: get_current_directory
- * Purpose: get current directory
- * Date: February 13, 1992
- * Passed: path: pointer to buffer to store path
- * drive: drive to get current directory
- * Notes: use simple DOS interrupt
- */
- int get_current_directory( char FAR *path, int drive )
- {
- int rc;
-
- ASSEMBLE {
- push si /* save register vars if any */
- push ds /* save ds */
-
- mov dx, WORD PTR drive /* dl = drive, 0 = default, 1 = a, etc.. */
- mov si, WORD PTR path /* get OFFSET of path */
- mov ax, WORD PTR path+2 /* get SEGMENT of path */
- mov ds, ax /* put it in ds */
- mov ah, 0x47 /* function 0x47 == get current dir */
- int 0x21 /* standard DOS interrupt */
- xor ax, ax /* zero out ax, return OK if no error */
- jnc no_error /* if carry set, then an error */
- mov ax, ERROR /* return -1 if error */
- }
- no_error:
-
- ASSEMBLE {
- pop ds /* get back ds */
- pop si /* get back si */
- mov WORD PTR rc, ax /* save return code */
- }
- if (ceh.flag == ERROR)
- rc = ERROR;
- return( rc );
- }
-
-
- /*
- * Name: set_current_directory
- * Purpose: set current directory
- * Date: February 13, 1992
- * Passed: new_path: directory path, which may include drive letter
- * Notes: use simple DOS interrupt
- */
- int set_current_directory( char FAR *new_path )
- {
- int rc;
-
- ASSEMBLE {
- push ds /* save ds */
-
- mov dx, WORD PTR new_path /* get OFFSET of new_path */
- mov ax, WORD PTR new_path+2 /* get SEGMENT of new_path */
- mov ds, ax /* put it in ds */
- mov ah, 0x3b /* function 0x3b == set current dir */
- int 0x21 /* standard DOS interrupt */
- xor ax, ax /* zero out ax, return OK if no error */
- jnc no_error /* if carry set, then an error */
- mov ax, ERROR /* return -1 if error */
- }
- no_error:
-
- ASSEMBLE {
- pop ds /* get back ds */
- mov WORD PTR rc, ax /* save return code */
- }
- if (ceh.flag == ERROR)
- rc = ERROR;
- return( rc );
- }
- #endif
-