+2006-12-10 Maarten Brock <sourceforge.brock AT dse.nl>
+
+ * device/include/malloc.h: removed init_dynamic_memory
+ * device/lib/malloc.c: made init_dynamic_memory static and automatically
+ call it once from malloc. Also use _sdcc_heap[] from _heap.c
+ * device/lib/_heap.c: new, added, contains _sdcc_heap[]
+ * device/lib/libsdcc.lib,
+ * device/lib/Makefile.in,
+ * support/regression/ports/mcs51-xstack-auto/spec.mk: added _heap.c
+ * doc/sdccman.lyx: documented use of new _heap.c
+ * support/regression/tests/malloc.c: removed init_dynamic_memory
+ * src/cdbFile.c(spacesToUnderscores): new function,
+ (cdbWriteEndFunction, cdbWriteCLine): use spacesToUnderscores, fixes bug
+ 1068030
+
2006-12-09 Borut Razem <borut.razem AT siol.net>
* support/cpp2/sdcc.h: prevent multiple inclusion
#else
-extern void init_dynamic_memory(void __xdata * heap, unsigned int size);
extern void __xdata * calloc (size_t nmemb, size_t size);
extern void __xdata * malloc (size_t size);
extern void __xdata * realloc (void * ptr, size_t size);
_strncpy.c _strpbrk.c _strrchr.c _strspn.c \
_strstr.c _strtok.c \
_memcmp.c _memcpy.c _memmove.c _memset.c \
- calloc.c malloc.c realloc.c free.c \
+ _heap.c calloc.c malloc.c realloc.c free.c \
printf_large.c sprintf.c vprintf.c puts.c gets.c \
printf_fast.c printf_fast_f.c printf_tiny.c printfl.c \
assert.c time.c bpx.c \
_strncpy.c _strpbrk.c _strrchr.c _strspn.c \
_strstr.c _strtok.c \
_uchar2fs.c _uint2fs.c _ulong2fs.c \
- calloc.c malloc.c realloc.c free.c \
+ _heap.c calloc.c malloc.c realloc.c free.c \
puts.c gets.c \
printf_large.c puts.c gets.c \
assert.c time.c \
_strncpy.c _strpbrk.c _strrchr.c _strspn.c \
_strstr.c _strtok.c \
_memcmp.c _memcpy.c _memmove.c _memset.c \
- calloc.c malloc.c realloc.c free.c \
+ _heap.c calloc.c malloc.c realloc.c free.c \
printf_large.c sprintf.c vprintf.c puts.c gets.c \
assert.c time.c \
fabsf.c frexpf.c ldexpf.c expf.c powf.c sincosf.c sinf.c \
--- /dev/null
+/*-------------------------------------------------------------------------
+ _heap.c - memory heap for malloc and friends
+
+ Copyright (C) 2006 - Maarten Brock, sourceforge.brock@dse.nl
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ In other words, you are welcome to use, share and improve this program.
+ You are forbidden to forbid anyone else to use, share and improve
+ what you give them. Help stamp out software-hoarding!
+-------------------------------------------------------------------------*/
+
+/*
+ This is the default heap. If you need a different size (make a copy and)
+ recompile it with -D HEAP_SIZE=<size> where <size> is whatever you need.
+ Link the resulting object explicitly with your project.
+*/
+
+#ifndef HEAP_SIZE
+#define HEAP_SIZE 1024
+#endif
+
+__xdata char _sdcc_heap[HEAP_SIZE];
+const unsigned int _sdcc_heap_size = HEAP_SIZE;
rand
_atoi
_atol
+_heap
calloc
malloc
realloc
#define HEADER_SIZE sizeof(MEMHEADER)
- MEMHEADER xdata * _sdcc_first_memheader;
+ MEMHEADER xdata * _sdcc_first_memheader = NULL;
- void init_dynamic_memory(void xdata * heap, unsigned int size)
+ extern xdata char _sdcc_heap[];
+ extern const unsigned int _sdcc_heap_size;
+
+ static void init_dynamic_memory(void)
{
+ char xdata * heap = (char xdata *)_sdcc_heap;
+ unsigned int size = _sdcc_heap_size;
- //This function MUST be called after the RESET.
- //Parameters: heap - pointer to memory allocated by the linker
- // size - size of this memory pool
- //Example:
- // #define DYNAMIC_MEMORY_SIZE 0x2000
- // .....
- // unsigned char xdata dynamic_memory_pool[DYNAMIC_MEMORY_SIZE];
- // unsigned char xdata * current_buffer;
- // .....
- // void main(void)
- // {
- // ...
- // init_dynamic_memory(dynamic_memory_pool,DYNAMIC_MEMORY_SIZE);
- // Now it is possible to use malloc.
- // ...
- // current_buffer = malloc(0x100);
- //
- //
- char xdata * array = (char xdata *)heap;
-
- if ( !array ) //Reserved memory starts at 0x0000 but that's NULL...
+ if ( !heap ) //Reserved memory starts at 0x0000 but that's NULL...
{ //So, we lost one byte!
- array++;
+ heap++;
size--;
}
- _sdcc_first_memheader = (MEMHEADER xdata * ) array;
+ _sdcc_first_memheader = (MEMHEADER xdata * ) heap;
//Reserve a mem for last header
- _sdcc_first_memheader->next = (MEMHEADER xdata * )(array + size - sizeof(MEMHEADER xdata *));
+ _sdcc_first_memheader->next = (MEMHEADER xdata * )(heap + size - sizeof(MEMHEADER xdata *));
_sdcc_first_memheader->next->next = (MEMHEADER xdata * ) NULL; //And mark it as last
_sdcc_first_memheader->len = 0; //Empty and ready.
}
register MEMHEADER xdata * new_header;
register void xdata * ret;
- if (size>(0xFFFF-HEADER_SIZE)) return (void xdata *) NULL; //To prevent overflow in next line
+ if (size>(0xFFFF-HEADER_SIZE))
+ return (void xdata *) NULL; //To prevent overflow in next line
size += HEADER_SIZE; //We need a memory for header too
+
+ if (!_sdcc_first_memheader)
+ init_dynamic_memory();
+
current_header = _sdcc_first_memheader;
CRITICAL
{
\layout Standard
-Before using dynamic memory allocation
+As of SDCC 2.6.2 you no longer need to call an initialization routine before
+ using dynamic memory allocation
\begin_inset LatexCommand \index{dynamic memory allocation (malloc)}
\end_inset
- with SDCC, you have to provide heap
+ and a default heap
\begin_inset LatexCommand \index{heap (malloc)}
\end_inset
- space for malloc to allocate memory from
-\family typewriter
-.
+ space of 1024 bytes is provided for malloc to allocate memory from.
\family default
-You can acomplish this by including the following code into your source:
+If you need a different heap size you need to recompile _heap.c with the
+ required size defined in HEAP_SIZE. It is recommended to make a copy of this
+ file into your project directory and compile it there with:
\layout Verse
\family typewriter
-#include <malloc.h>
-\begin_inset LatexCommand \index{malloc.h}
-
-\end_inset
-
- /* calloc
-\begin_inset LatexCommand \index{calloc}
-
-\end_inset
-
-, malloc
-\begin_inset LatexCommand \index{malloc}
-
-\end_inset
-
-, realloc
-\begin_inset LatexCommand \index{realloc}
-
-\end_inset
-
-, and free
-\begin_inset LatexCommand \index{free (malloc)}
-
-\end_inset
-
- */
-\newline
-
-\newline
-#define HEAPSIZE 0x1000 /* Adjust depending on available memory */
-\newline
-unsigned char xdata myheap[HEAPSIZE]; /* The actual heap for dynamic memory
- */
+sdcc -c _heap.c -D HEAD_SIZE=2048
\newline
+\family default
+And then link it with:
+\layout Verse
-\newline
-void main (void)
-\newline
-{
-\newline
-\SpecialChar ~
-\SpecialChar ~
-\SpecialChar ~
-/* Your variable declarations come here*/
-\newline
-\SpecialChar ~
-\SpecialChar ~
-\SpecialChar ~
-...
-\newline
-\SpecialChar ~
-\SpecialChar ~
-\SpecialChar ~
-init_dynamic_memory((MEMHEADER xdata *)myheap, HEAPSIZE);
-\newline
-\SpecialChar ~
-\SpecialChar ~
-\SpecialChar ~
-...
- /* Rest of your code*/
-\newline
-}
+\family typewriter
+sdcc main.rel _heap.rel
\newline
\layout Subsection
FILE *cdbFilePtr = NULL;
char *cdbModuleName = NULL;
+/******************************************************************
+ * spacesToUnderscores - replace all non alpha-numerics with
+ * underscores
+ *
+ *
+ *****************************************************************/
+
+static char *
+spacesToUnderscores (char *dest, const char *src, size_t len)
+{
+ unsigned int i;
+ char *p;
+
+ assert(dest != NULL);
+ assert(src != NULL);
+ assert(len > 0);
+
+ --len;
+ for (p = dest, i = 0; *src != '\0' && i < len; ++src, ++i) {
+ *p++ = (isspace((unsigned char)*src) || (*src == '-')) ? '_' : *src;
+ }
+ *p = '\0';
+
+ return dest;
+}
+
+
/******************************************************************
*
*
sprintf (debugSym, "C$%s$%d$%d$%d",
FileBaseName (ic->filename), pSym->lastLine,
ic->level, ic->block);
+ spacesToUnderscores (debugSym, debugSym, sizeof (debugSym));
emitDebuggerSymbol (debugSym);
}
sprintf (debugSym, "C$%s$%d$%d$%d",
FileBaseName (ic->filename), ic->lineno,
ic->level, ic->block);
+ spacesToUnderscores (debugSym, debugSym, sizeof (debugSym));
emitDebuggerSymbol (debugSym);
return 1;
_strncpy.c _strpbrk.c _strrchr.c _strspn.c \
_strstr.c _strtok.c \
_uchar2fs.c _uint2fs.c _ulong2fs.c \
- calloc.c malloc.c realloc.c free.c \
+ _heap.c calloc.c malloc.c realloc.c free.c \
serial.c ser_ir.c printfl.c \
printf_large.c sprintf.c vprintf.c puts.c gets.c \
assert.c time.c bpx.c
#include <malloc.h>
#endif
+#if defined(SDCC_pic16)
xdata char heap[100];
+#endif
void
testMalloc(void)
#if !defined(__GNUC__) && !defined(SDCC_gbz80) && !defined(SDCC_z80)
#if defined(SDCC_pic16)
_initHeap(heap, sizeof heap);
-#else
- init_dynamic_memory(heap, sizeof(heap));
#endif
- p1 = malloc(200);
+ p1 = malloc(2000);
ASSERT(p1 == NULL);
LOG(("p1 == NULL when out of memory\n"));
#ifdef PORT_HOST