📄 port.c
字号:
/* * Now that I own both MSC 7.0 and BC 3.1 and have linux, lets rearrange stuff * so many compilers can compile TDE. Several implementation specific * functions needed for several environments were gathered into this file. * * In version 3.2, these functions changed to support unix. * * Although many PC C compilers have findfirst and findnext functions for * finding files, let's write our own to keep a closer watch on * critical errors. * * * 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 use and distribute it freely. */#include "tdestr.h"#include "common.h"#include "tdefunc.h"#include "define.h"#if defined( __MSC__ )#include <dos.h>#endif/* * Name: my_heapavail * Purpose: available free memory from the far heap * Date: November 13, 1993 */long my_heapavail( void ){long avail_mem;#if defined( __MSC__ )unsigned paragraphs; _dos_allocmem( 0xffff, ¶graphs ); /* * A paragraph is 16 bytes. Convert paragraphs to bytes by shifting left * 4 bits. */ avail_mem = (long)paragraphs << 4;#else /* * use the Borland farcoreleft( ) function. */ avail_mem = farcoreleft( );#endif return( avail_mem );}static int find_first( DTA *dta, char *path, int f_attr );static int find_next( DTA *dta );static FTYPE *find_wild( FFIND *dta );static char found_name[NAME_MAX+2];static FTYPE found = { found_name, 0, 0, 0 };/* * Name: find_first * Purpose: find the first file matching a pattern using DOS interrupt * Date: January 6, 1992 * Passed: dta: disk transfer address * path: path to search for files * f_attr: attributes of files to search for * Notes: return codes for find_first: * 0 no error * 2 file is invalid or does not exist * 3 path is invalid or does not exist * 18 no matching directory entry was found * -1 check the critical error flag for critical errors * * jmh 031202: ignore the "." entry here (it's always found first). */static int find_first( DTA *dta, char *path, int f_attr ){void *old_dta;int rc; ASSEMBLE {/*; save the old dta*/ mov ah, 0x2f /* DOS get dta */ int 0x21 /* DOS interrupt */ mov WORD PTR old_dta, bx /* save OFFSET of old DTA */ mov WORD PTR old_dta+2, es /* save SEGMENT of old DTA *//*; set the new dta*/ push ds /* save ds */ lds dx, dta /* get SEGMENT & OFFSET of new dta */ mov ah, 0x1a /* DOS set dta */ int 0x21 /* DOS interrupt *//*; find first matching file*/ push ds /* save ds of DTA */ mov cx, WORD PTR f_attr /* file attributes to search for */ lds dx, path /* get SEGMENT & OFFSET of path */ mov ah, 0x4e /* DOS find first file */ int 0x21 /* DOS interrupt */ pop ds /* get back ds of DTA *//*; save the return code*/ jc an_error /* carry is set if an error occured *//*; if file name begins with '.' it must be the "." entry - ignore it*/ mov bx, WORD PTR dta /* offset of DTA */ cmp BYTE PTR [bx+30], '.' /* file name is at offset 30 */ jne no_error /* not dot, found first file */ mov ah, 0x4f /* DOS find next file */ int 0x21 /* DOS interrupt */ jc an_error }no_error: ASSEMBLE { xor ax, ax /* zero out ax, return OK if no error */ }an_error: ASSEMBLE { mov WORD PTR rc, ax /* save the return code *//*; get back old dta*/ lds dx, old_dta /* get SEGMENT & OFFSET of old dta */ mov ah, 0x1a /* DOS set dta */ int 0x21 /* DOS interrupt */ pop ds /* get back ds */ } if (ceh.flag == ERROR) rc = ERROR; return( rc );}/* * Name: find_next * Purpose: find the next file matching a pattern using DOS interrupt * Date: January 6, 1992 * Passed: dta: disk transfer address * Notes: find_first() MUST be called before calling this function. * return codes for find_next (see DOS tech ref manuals): * 0 no error * 2 path is invalid or does not exist * 18 no matching directory entry was found * -1 check the critical error flag for critical errors */static int find_next( DTA *dta ){void *old_dta;int rc; ASSEMBLE {/*; save the old dta*/ mov ah, 0x2f /* DOS get dta */ int 0x21 /* DOS interrupt */ mov WORD PTR old_dta, bx /* save OFFSET of old DTA */ mov WORD PTR old_dta+2, es /* save SEGMENT of old DTA *//*; set the new dta*/ push ds /* save ds */ lds dx, dta /* get SEGMENT & OFFSET of new dta */ mov ah, 0x1a /* DOS set dta */ int 0x21 /* DOS interrupt *//*; find next matching file*/ mov ah, 0x4f /* DOS find next file */ int 0x21 /* DOS interrupt *//*; save the return code*/ jc an_error /* carry is set if an error occured */ xor ax, ax /* zero out ax, return OK if no error */ }an_error: ASSEMBLE { mov WORD PTR rc, ax /* save the return code *//*; get back old dta*/ lds dx, old_dta /* get SEGMENT & OFFSET of old dta */ mov ah, 0x1a /* DOS set dta */ int 0x21 /* DOS interrupt */ pop ds /* get back ds */ } if (ceh.flag == ERROR) rc = ERROR; return( rc );}/* * Name: find_wild * Purpose: find a file matching an "extended" wildcard pattern * Author: Jason Hood * Date: December 2, 2003 * Passed: dta: file finding info * Notes: my_find{first,next} MUST have been successfully called first; * see my_findfirst notes. */static FTYPE *find_wild( FFIND *dta ){int i;char *name;char *path; i = OK; do { if (dta->dirs == ALL_DIRS && (dta->find_info.attrib & SUBDIRECTORY)) break; if (wildcard( dta->pattern, dta->find_info.name ) == TRUE) break; i = find_next( &dta->find_info ); } while (i == OK); if (i != OK) return( NULL ); /* all done */ name = dta->find_info.name; path = found.fname; while ((*path = bj_tolower( *name )) != '\0') { name++; path++; } if (dta->dirs) { found.fsize = dta->find_info.size; found.fattr = dta->find_info.attrib; found.ftime = dta->find_info.time; if (dta->find_info.attrib & SUBDIRECTORY) { *path = '/'; path[1] = '\0'; } } return( &found );}/* * Name: my_findfirst * Purpose: find the first file matching a pattern * Date: August 5, 1997 * Passed: path: path and pattern to search for files * dta: file finding info * dirs: NO_DIRS to ignore all directories * MATCH_DIRS to match directory names * ALL_DIRS to include all directories and return file sizes * Notes: Returns NULL for no matching files or bad pattern; * otherwise a pointer to a static FTYPE, with fname holding the * filename that was found. * If dirs is TRUE fsize will hold the size of the file, and the * name will have a trailing slash ('/') if it's a directory. * The name is converted to lower-case. */FTYPE *my_findfirst( char *path, FFIND *dta, int dirs ){int i;fattr_t fattr;char temp[PATH_MAX]; dta->dirs = dirs; /* * Separate the path and pattern */ i = strlen( path ) - 1; if (i == -1) { get_current_directory( dta->stem ); strcpy( dta->pattern, "*" ); } else if (path[i] == '/' || path[i] == '\\' || path[i] == ':') { strcpy( dta->stem, path ); strcpy( dta->pattern, "*" ); } else if (file_exists( path ) == SUBDIRECTORY) { join_strings( dta->stem, path, "/" ); strcpy( dta->pattern, "*" ); } else { while (--i >= 0) { if (path[i] == '/' || path[i] == ':') break; /* if it's a backslash, it could be an escape for the pattern */ if (path[i] == '\\' && strchr( "!^-\\]", path[i+1] ) == NULL) break; } if (i >= 0) { strncpy( dta->stem, path, ++i ); dta->stem[i] = '\0'; strcpy( dta->pattern, path+i ); } else { get_current_directory( dta->stem ); strcpy( dta->pattern, path ); } if (!is_valid_pattern( dta->pattern, &i )) return( NULL ); } /* * Start scanning the directory */ join_strings( temp, dta->stem, "*.*" ); fattr = NORMAL | READ_ONLY | HIDDEN | SYSTEM | ARCHIVE; if (dirs) fattr |= SUBDIRECTORY; if (find_first( &dta->find_info, temp, fattr ) == OK) return( find_wild( dta ) ); return( NULL );}/* * Name: my_findnext * Purpose: find the next file matching a pattern * Date: August 5, 1997 * Passed: dta: file finding info * Notes: my_findfirst() MUST be called before calling this function. * Returns NULL if no more matching names; * otherwise same as my_findfirst. */FTYPE *my_findnext( FFIND *dta ){ return( (find_next( &dta->find_info ) == OK) ? find_wild( dta ) : NULL );}/* * 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 successful, 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 = Volume 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 * * jmh 020924: remove a trailing (back)slash. */int get_fattr( char *fname, fattr_t *fattr ){int rc; /* return code */int attr; ASSEMBLE { push ds lds dx, fname /* get SEGMENT & OFFSET of filename */ mov bx, dx dec bx sub al, al }find_nul: ASSEMBLE { inc bx cmp [bx], al jnz find_nul dec bx /* bx is at the last character */ cmp byte ptr [bx], '/' je slash
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -