home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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
-