mirror of
https://github.com/uffejakobsen/acme.git
synced 2025-01-12 05:31:19 +00:00
85f0c32ff4
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@246 4df02467-bbd4-4a76-a152-e7ce94205b78
140 lines
3.6 KiB
C
140 lines
3.6 KiB
C
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
|
|
// Copyright (C) 1998-2020 Marco Baye
|
|
// Have a look at "acme.c" for further info
|
|
//
|
|
// Dynamic buffer stuff
|
|
#include "dynabuf.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "acme.h"
|
|
#include "global.h"
|
|
#include "input.h"
|
|
|
|
|
|
// Constants and macros
|
|
|
|
// macro to grow dynabuf (CAUTION - fails if a < 1)
|
|
#define MAKE_LARGER_THAN(a) (2 * (a))
|
|
// if someone requests a dynabuf smaller than this, use this size instead
|
|
#define DYNABUF_MINIMUM_INITIALSIZE 128 // should be >0 (see above)
|
|
// initial size for global dynabuf
|
|
// (as it holds macros, loop bodies, etc., make it large to begin with)
|
|
#define GLOBALDYNABUF_INITIALSIZE 1024 // should be >0 (see above)
|
|
|
|
|
|
// Variables
|
|
struct dynabuf *GlobalDynaBuf; // global dynamic buffer
|
|
|
|
|
|
// Functions
|
|
|
|
// get new buffer of given size
|
|
static void resize(struct dynabuf *db, size_t new_size)
|
|
{
|
|
char *new_buf;
|
|
|
|
new_buf = realloc(db->buffer, new_size);
|
|
if (new_buf == NULL)
|
|
Throw_serious_error(exception_no_memory_left);
|
|
db->reserved = new_size;
|
|
db->buffer = new_buf;
|
|
}
|
|
|
|
|
|
// Exported functions
|
|
|
|
// Create and init a dynamic buffer and return pointer
|
|
struct dynabuf *DynaBuf_create(int initial_size)
|
|
{
|
|
struct dynabuf *db;
|
|
|
|
if (initial_size < DYNABUF_MINIMUM_INITIALSIZE)
|
|
initial_size = DYNABUF_MINIMUM_INITIALSIZE;
|
|
if ((db = malloc(sizeof(*db)))) {
|
|
db->size = 0;
|
|
db->reserved = initial_size;
|
|
db->buffer = malloc(initial_size);
|
|
if (db->buffer)
|
|
return db; // if both pointers are != NULL, no error
|
|
}
|
|
// otherwise, complain
|
|
fputs("Error: No memory for dynamic buffer.\n", stderr);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
// Enlarge buffer
|
|
void DynaBuf_enlarge(struct dynabuf *db)
|
|
{
|
|
resize(db, MAKE_LARGER_THAN(db->reserved));
|
|
}
|
|
|
|
// Claim enough memory to hold a copy of the current buffer contents,
|
|
// make that copy and return it.
|
|
// The copy must be released by calling free().
|
|
char *DynaBuf_get_copy(struct dynabuf *db)
|
|
{
|
|
char *copy;
|
|
|
|
copy = safe_malloc(db->size);
|
|
memcpy(copy, db->buffer, db->size);
|
|
return copy;
|
|
}
|
|
|
|
// add char to buffer
|
|
void DynaBuf_append(struct dynabuf *db, char byte)
|
|
{
|
|
DYNABUF_APPEND(db, byte);
|
|
}
|
|
|
|
// Append string to buffer (without terminator)
|
|
void DynaBuf_add_string(struct dynabuf *db, const char *string)
|
|
{
|
|
char byte;
|
|
|
|
while ((byte = *string++))
|
|
DYNABUF_APPEND(db, byte);
|
|
}
|
|
/*
|
|
// make sure DynaBuf is large enough to take "size" more bytes
|
|
// return pointer to end of current contents
|
|
static char *ensure_free_space(struct dynabuf *db, int size)
|
|
{
|
|
while ((db->reserved - db->size) < size)
|
|
resize(db, MAKE_LARGER_THAN(db->reserved));
|
|
return db->buffer + db->size;
|
|
}*/
|
|
|
|
// Convert buffer contents to lower case (target and source may be identical)
|
|
void DynaBuf_to_lower(struct dynabuf *target, struct dynabuf *source)
|
|
{
|
|
char *read,
|
|
*write,
|
|
byte;
|
|
|
|
// make sure target can take it
|
|
if (source->size > target->reserved)
|
|
resize(target, source->size);
|
|
// convert to lower case
|
|
read = source->buffer; // CAUTION - ptr may change when buf grows!
|
|
write = target->buffer; // CAUTION - ptr may change when buf grows!
|
|
while ((byte = *read++)) {
|
|
// we want to keep underscore, so this check restricts:
|
|
if (byte <= 'Z')
|
|
byte |= 32;
|
|
*write++ = byte;
|
|
}
|
|
// Okay, so this method of converting to lowercase is lousy.
|
|
// But actually it doesn't matter, because only pre-defined
|
|
// keywords are converted, and all of those are plain
|
|
// old-fashioned 7-bit ASCII anyway. So I guess it'll do.
|
|
// FIXME - use BYTE_ macro from global.h
|
|
*write = '\0'; // terminate
|
|
}
|
|
|
|
// Initialisation - allocate global dynamic buffer
|
|
void DynaBuf_init(void)
|
|
{
|
|
GlobalDynaBuf = DynaBuf_create(GLOBALDYNABUF_INITIALSIZE);
|
|
}
|