aalloc.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 304 行
C
304 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
//
// AALLOC : allocation/deallocation of allocatable arrays
//
#include "ftnstd.h"
#include "rtenv.h"
#include "errcod.h"
#include "falloc.h"
#include <stdarg.h>
#include <malloc.h>
#include <limits.h>
#if !defined( __AXP__ ) && !defined( __PPC__ )
#include <i86.h>
#if defined( __WINDOWS_386__ )
#include <win386.h>
#endif
#endif
extern void RTErr(uint,...);
#define STAT_OK 0
#define STAT_NO_MEM 1
#define STAT_ALREADY_ALLOC 2
#define STAT_NOT_ALLOCATED 3
#if defined( M_I86 )
#if defined( __MEDIUM__ )
#define __extended_ptype __far
#else
#define __extended_ptype
#endif
#else
#define __extended_ptype __far
#endif
static void turnOffFlags( void **arr, unsigned_16 flags, unsigned_16 mask ) {
//===========================================================================
if( flags & ALLOC_STRING ) {
*((unsigned_16 *)((string *)arr + 1 )) &= ~mask;
} else {
if( flags & ALLOC_EXTENDED ) {
*((unsigned_16 *)((void __far * *)arr + 1 )) &= ~mask;
} else {
*((unsigned_16 *)(arr + 1)) &= ~mask;
}
}
}
static void turnOnFlags( void **arr, unsigned_16 flags, unsigned_16 mask ) {
//==========================================================================
if( flags & ALLOC_STRING ) {
*((unsigned_16 *)((string *)arr + 1 )) |= mask;
} else {
if( flags & ALLOC_EXTENDED ) {
*((unsigned_16 *)((void __far * *)arr + 1 )) |= mask;
} else {
*((unsigned_16 *)(arr + 1 )) |= mask;
}
}
}
static bool Allocated( void **arr, unsigned_16 flags ) {
//==========================================================
// Determine allocation status of array.
if( flags & ALLOC_EXTENDED ) {
return( (*(void __extended_ptype **)arr) != NULL );
} else {
return( *arr != NULL );
}
}
void Alloc( unsigned_16 alloc_type, uint num, ... ) {
//======================================================
void PGM * PGM * item;
struct string PGM * scb;
adv_entry PGM * adv_ent;
uint dims;
unsigned_32 size;
va_list args;
intstar4 PGM * stat;
intstar4 location;
unsigned_32 elt_size;
unsigned_16 alloc_flags;
#if defined( __WINDOWS_386__ )
unsigned_16 seg;
#endif
// Assumptions
// 1. The first field in the scb is the pointer to the string
// 2. The flags for an scb are right after the scb
// 3. The flags for an array are right before the ADV
va_start( args, num );
if( alloc_type & ( ALLOC_STAT | ALLOC_NONE ) ) {
stat = va_arg( args, intstar4 PGM * );
} else {
stat = NULL;
}
if( alloc_type & ALLOC_LOC ) {
location = va_arg( args, intstar4 );
} else {
alloc_type |= ALLOC_MEM;
}
if( stat != NULL ) {
*stat = STAT_OK;
}
while( num != 0 ) {
alloc_flags = va_arg( args, unsigned_16 );
item = va_arg( args, void PGM * PGM * );
if( alloc_flags & ALLOC_STRING ) {
scb = (string *)item;
dims = 1;
elt_size = 1;
} else {
adv_ent = va_arg( args, adv_entry * );
dims = va_arg( args, uint );
elt_size = va_arg( args, unsigned_32 );
}
if( Allocated( item, alloc_flags ) && !(alloc_flags & ALLOC_LOC) ) {
if( stat != NULL ) {
*stat = STAT_ALREADY_ALLOC;
break;
}
RTErr( MO_STORAGE_ALLOCATED );
}
if( alloc_type & ALLOC_LOC ) {
#if defined( __WINDOWS_386__ )
if( alloc_flags & ALLOC_EXTENDED ) {
seg = location >> 16;
if( ( seg == 0 ) || ( seg == 0xffff ) ) {
*(void __far **)item = MK_LOCAL32( (void *)location );
} else {
*(void __far **)item = MK_FP32( (void *)location );
}
} else {
*item = (void *)location;
}
#elif !defined( __AXP__ ) && !defined( __PPC__ )
if( alloc_flags & ALLOC_EXTENDED ) {
*(void __far **)item = MK_FP( location >> 16,
location & 0x0000ffff );
} else {
*item = (void *)location;
}
#else
*item = (void *)location;
#endif
} else {
if( alloc_flags & ALLOC_STRING ) {
size = scb->len;
dims = 0;
} else {
size = 1;
while( dims != 0 ) {
size *= adv_ent->num_elts;
++adv_ent;
--dims;
}
}
#if defined( M_I86 )
#if defined( __MEDIUM__ )
if( alloc_flags & ALLOC_EXTENDED ) {
if( size * elt_size <= UINT_MAX ) {
*(void __far **)item = _fmalloc( size * elt_size );
} else {
*(void __far **)item = NULL;
}
} else {
if( size * elt_size <= UINT_MAX ) {
*item = malloc( size * elt_size );
} else {
*item = NULL;
}
}
#else
*item = (void PGM *)halloc( size, elt_size );
#endif
#else
if( alloc_flags & ALLOC_EXTENDED ) {
*(void __far **)item = malloc( size * elt_size );
} else {
*item = malloc( size * elt_size );
}
#endif
if( !Allocated( item, alloc_flags ) ) {
if( stat != NULL ) {
*stat = STAT_NO_MEM;
break;
}
RTErr( MO_DYNAMIC_OUT );
}
}
turnOffFlags( item, alloc_flags, ALLOC_MASK );
turnOnFlags( item, alloc_flags, alloc_type );
--num;
}
va_end( args );
}
void DeAlloc( intstar4 PGM *stat, uint num, ... ) {
//====================================================
void PGM * PGM *item;
va_list args;
uint istat;
unsigned_16 alloc_flags;
istat = STAT_OK;
va_start( args, num );
while( num != 0 ) {
alloc_flags = va_arg( args, unsigned_16 );
item = va_arg( args, void PGM * PGM * );
if( !Allocated( item, alloc_flags ) ) {
istat = STAT_NOT_ALLOCATED;
} else {
if( !(alloc_flags & ALLOC_LOC) ) {
#if defined( M_I86 )
#if defined( __MEDIUM__ )
if( alloc_flags & ALLOC_EXTENDED ) {
_ffree( *(void __far **)item );
} else {
free( *item );
}
#else
hfree( *item );
#endif
#else
if( alloc_flags & ALLOC_EXTENDED ) {
free( (void *)(*(void __far **)item) );
} else {
free( *item );
}
#endif
}
if( alloc_flags & ALLOC_EXTENDED ) {
#if defined( M_I86 )
#if defined( __MEDIUM__ )
(*(void __far **)item) = NULL;
#else
*item = NULL;
#endif
#else
(*(void __far **)item) = NULL;
#endif
} else {
*item = NULL;
}
turnOffFlags( item, alloc_flags, ALLOC_MASK );
}
--num;
}
va_end( args );
if( ( istat != STAT_OK ) && ( stat == NULL ) ) {
RTErr( MO_STORAGE_NOT_ALLOCATED );
}
if( stat != NULL ) {
*stat = istat;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?