home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
High Voltage Shareware
/
high1.zip
/
high1
/
DIR8
/
TDE32.ZIP
/
PORT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-13
|
17KB
|
593 lines
/*
* 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.
*
* Incidentally, there is difference between a NULL line pointer and
* a pointer to a line that contains no characters. For example, calling
*
* line = malloc( 0 );
*
* or, more precisely in TDE:
*
* line = _fmalloc( 0 );
* line = farmalloc( 0 );
*
* will return a valid pointer to an item of 0 length in some compilers
* and a NULL pointer in other compilers. malloc( 0 ) will return a valid
* pointer to an object of zero length in MSC. malloc( 0 ) will return a
* NULL pointer in BC. The problem with returning a NULL pointer for
* malloc( 0 ) is that it's a little harder to tell if the heap is out of
* memory or if we have a valid NULL pointer. On the other hand, the good
* part about returning a NULL pointer for malloc( 0 ) is that extra space
* is not wasted for an object of 0 length. In TDE, we will test for 0
* before calling my_malloc( ) and set an ERROR code if out of memory.
*
* 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
*
* 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( __UNIX__ )
#include <bios.h> /* for REGS */
#include <dos.h> /* for intdos */
#endif
#if defined( __UNIX__ )
/*
**********************************************************************
****************************** PART 1 ******************************
**********************************************************************
*
* Let's try to make unix have the look and feel of a PC.
*/
/*
* Name: my_malloc
* Purpose: malloc from the far heap
* Date: November 13, 1993
* Passed: size: memory needed heap
* rc: pointer to return code
* Notes: set the return code only if an ERROR occured with malloc.
* returning a NULL pointer is not neccessarily an ERROR.
*/
void *my_malloc( size_t size, int *rc )
{
void *mem;
assert( size < MAX_LINE_LENGTH );
if (size == 0)
/*
* if 0 bytes are requested, return NULL
*/
mem = NULL;
else {
mem = malloc( size );
/*
* if malloc failed, return NULL and an ERROR.
*/
if (mem == NULL)
*rc = ERROR;
}
return( mem );
}
/*
* Name: my_free
* Purpose: free memory from the far heap
* Date: November 13, 1993
* Passed: mem: pointer to memory to free in far heap
*/
void my_free( void *mem )
{
assert( mem != NULL );
free( mem );
}
/*
* Name: my_heapavail
* Purpose: available free memory from the far heap
* Date: November 13, 1993
* Notes: mstats( ) is a gcc unix function that returns a structure.
* (I haven't got this working, yet.)
*/
long my_heapavail( void )
{
/*
struct mstats m;
m = mstats( );
return( (long)m.bytes_free );
*/
return( 0 );
}
/*
* Name: my_memcpy
* Purpose: copy memory
* Date: November 13, 1993
* Passed: dest: pointer to destination
* src: pointer to source
* size: number of bytes to copy
*/
void my_memcpy( void *dest, void *src, size_t size )
{
if (size > 0) {
assert( dest != NULL );
assert( src != NULL );
memcpy( dest, src, size );
}
}
/*
* Name: my_memmove
* Purpose: move memory
* Date: November 13, 1993
* Passed: dest: pointer to destination
* src: pointer to source
* size: number of bytes to copy
*/
void my_memmove( void *dest, void *src, size_t size )
{
if (size > 0) {
assert( dest != NULL );
assert( src != NULL );
memmove( dest, src, size );
}
}
/*
* Name: my_ltoa
* Purpose: ltoa is not ANSI - write our own
* Date: November 13, 1993
* Passed: lnum: number to convert to ASCII. in linux, an int is 32 bits.
* s: pointer to buffer
* radix: 0 < radix <= 16
* Notes: store the ascii string in a 20 character stack.
*/
char *my_ltoa( int lnum, char *s, int radix )
{
int sign;
char *digit = "0123456789abcdef";
char stack[20];
char *sp;
char *p;
if (radix < 0)
radix = -radix;
/*
* default an empty string.
*/
*s = '\0';
if (radix > 0 && radix <= 16) {
sign = 0;
if (lnum < 0) {
lnum = -lnum;
sign = -1;
}
/*
* put a '\0' at the beginning of our stack.
*
* standard procedure: generate the digits in reverse order.
*/
sp = stack;
*sp = '\0';
do {
*++sp = digit[lnum % radix];
lnum = lnum / radix;
} while (lnum > 0);
/*
* now, pop the ascii digits off the stack. the '\0' that we stored
* at the beginning of the stack terminates the string copy.
*/
p = s;
if (sign == -1)
*p++ = '-';
while (*p++ = *sp--);
}
return( s );
}
/*
* Name: my_findfirst
* Purpose: find the first file matching a pattern
* Date: November 13, 1993
* Passed: dta: disk transfer address
* path: path to search for files
* f_attr: attributes of files to search for
* Notes: we don't use this function in a unix environment
*/
int my_findfirst( DTA FAR *dta, char FAR *path, int f_attr )
{
return( ERROR );
}
/*
* Name: my_findnext
* Purpose: find the next file matching a pattern using POSIX readdir
* Date: November 13, 1993
* Passed: dp: directory pointer (DIR is defined in <dirent.h>
* unix_dta: a pointer for TDE's dta
* Notes: find directory elements. the readdir( ) function gets the
* next directory element. it is up to TDE to figure the
* directory element type, i.e. file, link, FIFO, subdirectory, etc...
*/
int my_findnext( DIR *dp, UNIX_DTA *unix_dta )
{
struct dirent *dir; /* dirent defined in <dirent.h> */
int rc;
/*
* make sure our directory pointers aren't null
*/
if (dp == NULL || unix_dta == NULL)
rc = ERROR;
else if ((dir = readdir( dp )) == NULL)
rc = ERROR;
else {
/*
* copy the directory element name and length to our unix_dta buffer.
* to figure the element, we will append the element name to the
* directory stem and call stat( ).
*/
strcpy( unix_dta->fname, dir->d_name );
unix_dta->name_len = strlen( unix_dta->fname );
rc = OK;
}
return( rc );
}
#else
/*
**********************************************************************
****************************** PART 2 ******************************
**********************************************************************
*
* DOS malloc and findfirst and findnext.
*/
/*
* Name: my_malloc
* Purpose: malloc from the far heap
* Date: April 1, 1993
* Passed: mem: pointer to memory to free in far heap
* rc: pointer to return code
* Notes: set the return code only if an ERROR occured with malloc.
* returning a NULL pointer is not neccessarily an ERROR.
*/
void FAR * my_malloc( size_t size, int *rc )
{
void FAR *mem;
assert( size < MAX_LINE_LENGTH );
if (size == 0)
/*
* if 0 bytes are requested, return NULL
*/
mem = NULL;
else {
#if defined( __MSC__ )
mem = _fmalloc( size );
#else
mem = farmalloc( size );
#endif
/*
* if malloc failed, return NULL and an ERROR.
*/
if (mem == NULL)
*rc = ERROR;
}
return( mem );
}
/*
* Name: my_free
* Purpose: free memory from the far heap
* Date: April 1, 1993
* Passed: mem: pointer to memory to free in far heap
*/
void my_free( void FAR *mem )
{
assert( mem != NULL );
#if defined( __MSC__ )
_ffree( mem );
#else
farfree( mem );
#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 );
}
/*
* Name: my_memcpy
* Purpose: copy memory
* Date: November 13, 1993
* Passed: dest: pointer to destination
* src: pointer to source
* size: number of bytes to copy
* Notes: far memory copy in DOS real mode
*/
void my_memcpy( void FAR *dest, void FAR *src, size_t size )
{
if (size > 0) {
assert( dest != NULL );
assert( src != NULL );
_fmemcpy( dest, src, size );
}
}
/*
* Name: my_memmove
* Purpose: move memory
* Date: November 13, 1993
* Passed: dest: pointer to destination
* src: pointer to source
* size: number of bytes to copy
* Notes: far memory move in DOS real mode - handles mem overlap
*/
void my_memmove( void FAR *dest, void FAR *src, size_t size )
{
if (size > 0) {
assert( dest != NULL );
assert( src != NULL );
_fmemmove( dest, src, size );
}
}
/*
* Name: my_ltoa
* Purpose: ltoa is not ANSI
* Date: June 5, 1991
* Passed: lnum: number to convert to ASCII
* s: pointer to buffer
* radix: 0 < radix <= 16
* Notes: If in insert mode, then this function adds the required
* number of spaces in the file.
* If not in insert mode, then tab simply moves the cursor right
* the required distance.
*/
char *my_ltoa( long lnum, char *s, int radix )
{
return( ltoa( lnum, s, radix ) );
}
/*
* Name: my_findfirst
* 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 my_findfirst:
* 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
*/
int my_findfirst( DTA FAR *dta, char FAR *path, int f_attr )
{
void FAR *old_dta;
void FAR *new_dta;
int rc;
new_dta = (void FAR *)dta;
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 ax, es
mov WORD PTR old_dta+2, ax /* save SEGMENT of old DTA */
/*
; set the new dta
*/
push ds /* save ds */
mov dx, WORD PTR new_dta /* get OFFSET of new dta */
mov ax, WORD PTR new_dta+2 /* get SEGMENT of new dta */
mov ds, ax /* put it in ds */
mov ah, 0x1a /* DOS set dta */
int 0x21 /* DOS interrupt */
pop ds /* get back ds */
/*
; find first matching file
*/
push ds /* save ds */
mov cx, WORD PTR f_attr /* file attributes to search for */
mov dx, 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, 0x4e /* DOS find first file */
int 0x21 /* DOS interrupt */
pop ds /* get back ds */
/*
; 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
*/
push ds /* save ds */
mov dx, WORD PTR old_dta /* get OFFSET of old dta */
mov ax, WORD PTR old_dta+2 /* get SEGMENT of old dta */
mov ds, ax /* put it in ds */
mov ah, 0x1a /* DOS set dta */
int 0x21 /* DOS interrupt */
pop ds /* get back ds */
}
if (ceh.flag == ERROR)
rc = ERROR;
return( rc );
}
/*
* Name: my_findnext
* Purpose: find the next file matching a pattern using DOS interrupt
* Date: January 6, 1992
* Passed: dta: disk transfer address
* Notes: my_findfirst() MUST be called before calling this function.
* return codes for my_findnext (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
*/
int my_findnext( DTA FAR *dta )
{
void FAR *old_dta;
void FAR *new_dta;
int rc;
new_dta = (void FAR *)dta;
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 ax, es
mov WORD PTR old_dta+2, ax /* save SEGMENT of old DTA */
/*
; set the new dta
*/
push ds /* save ds */
mov dx, WORD PTR new_dta /* get OFFSET of new dta */
mov ax, WORD PTR new_dta+2 /* get SEGMENT of new dta */
mov ds, ax /* put it in ds */
mov ah, 0x1a /* DOS set dta */
int 0x21 /* DOS interrupt */
pop ds /* get back ds */
/*
; find next matching file
*/
mov ah, 0x4f /* DOS find first 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
*/
push ds /* save ds */
mov dx, WORD PTR old_dta /* get OFFSET of old dta */
mov ax, WORD PTR old_dta+2 /* get SEGMENT of old dta */
mov ds, ax /* put it in ds */
mov ah, 0x1a /* DOS set dta */
int 0x21 /* DOS interrupt */
pop ds /* get back ds */
}
if (ceh.flag == ERROR)
rc = ERROR;
return( rc );
}
#endif