Call this V0.7.0
This commit is contained in:
parent
ba99b81a78
commit
3bcdb74759
2
Makefile
2
Makefile
@ -2,7 +2,7 @@
|
||||
# (C) Copyright 2014-2021 Chris Dorman, some rights reserved (GPLv2)
|
||||
# Some changes and tweaks from Menchers
|
||||
|
||||
VERSION = \"0.6.0\"
|
||||
VERSION = \"0.7.0\"
|
||||
VERSION_EXTRA = \"$(EXTRA)\"
|
||||
|
||||
PREFIX ?= /usr
|
||||
|
@ -151,6 +151,12 @@ Changelog
|
||||
|
||||
Changes between version bumps in SlideScript. Hoping to have a lightweight top-down scripting language
|
||||
by V1.0.0 release! From there it will be molding and preserving the art.
|
||||
* V0.7.0
|
||||
* Ditched old LZ77 example code, and went with a more polished LZ78 ()
|
||||
* Converted dynamic memory management layer into LZ78 engine and tar code.
|
||||
* Compress & Decompress are both fully functioning.
|
||||
* Tidies, and polishing (pushing more for that full lenguage)
|
||||
|
||||
* V0.6.0
|
||||
* Multiple dynamic memory bug fixes, SlideScript is 99% dynamic on memory use
|
||||
* Included if, and ifn functions for comp, isfile, isdir, etc return values.
|
||||
|
@ -261,6 +261,7 @@ typedef struct qlist QLIST; /* typedef the list header */
|
||||
/* a QLIST pointer and as the QLIST entry itself. */
|
||||
|
||||
UX3_EXT QLIST QM_GEN [ONE]; /* general-purpose QLIST */
|
||||
UX3_EXT QLIST QM_LZ [ONE];
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
|
330
src/inc/x3mem.h~
Normal file
330
src/inc/x3mem.h~
Normal file
@ -0,0 +1,330 @@
|
||||
/* ------------------------------------------------------------ */
|
||||
/* file information */
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
// Filename: x3mem.h
|
||||
// Purpose: Memory management
|
||||
// License: MIT/X. (c) OldCoder (Robert Kiraly) 1987-2021.
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* header file setup */
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
#ifndef _X3MEM_H /* skip this file if loaded */
|
||||
#define _X3MEM_H 1 /* flag this file */
|
||||
|
||||
#include "deps.h"
|
||||
#include "eprintf.h"
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* basic definitions */
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
#ifndef x3u_int
|
||||
#define x3u_int unsigned int
|
||||
#endif
|
||||
|
||||
#ifndef x3u_long
|
||||
#define x3u_long unsigned long
|
||||
#endif
|
||||
|
||||
#ifndef V_OBJ
|
||||
#define V_OBJ void
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* X3MEM package - overview */
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/* The X3MEM package includes the public functions listed be- */
|
||||
/* low. For more information, see the functions themselves. */
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/* QLIST support functions: (*) = macro function */
|
||||
|
||||
/* 1. chk_qm0() -- checks a "qmalloc()" storage pointer */
|
||||
/* 2. chk_qma() -- checks an entire QLIST */
|
||||
/* (*) 3. chk_qmp() -- generic version of "chk_qm0()" */
|
||||
/* 4. qcalloc() -- allocates and clears memory */
|
||||
/* 5. qmalloc() -- allocates memory */
|
||||
/* 6. qrealloc() -- re-allocates memory */
|
||||
/* 7. qfree() -- frees allocated memory */
|
||||
/* 8. qflush() -- frees an entire QLIST */
|
||||
/* 9. sys_mem() -- returns amount of free system memory */
|
||||
/* (*) 10. xqfree() -- generic version of "qfree()" */
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/* Simplified QLIST interface layer: */
|
||||
|
||||
/* 11. sqCalloc() -- similar to "calloc()" */
|
||||
/* 12. sqChkHeap() -- checks the entire "sq..." heap */
|
||||
/* 13. sqChkPtr() -- checks an "sq..." storage pointer */
|
||||
/* 14. sqFlush() -- frees all "sq..." storage */
|
||||
/* 15. sqFree() -- frees one "sq..." storage block */
|
||||
/* 16. sqMalloc() -- similar to "malloc()" */
|
||||
/* 17. sqRealloc() -- similar to "realloc()" */
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* QLIST pointers - explanation */
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/* The X3MEM functions support multiple dynamic-memory allo- */
|
||||
/* cation lists. The "qmalloc()" function, for example, */
|
||||
/* allocates memory from a specified allocation list, and the */
|
||||
/* "qfree()" function returns memory to the associated list. */
|
||||
|
||||
/* Multiple-allocation lists provide greater control over */
|
||||
/* memory allocation; e.g., the caller can free up one list in */
|
||||
/* its entirety without disturbing other lists. */
|
||||
|
||||
/* Additionally, the use of multiple allocation lists can */
|
||||
/* reduce the fragmentation problems which occur on virtual- */
|
||||
/* memory systems when free lists have grown large. */
|
||||
|
||||
/* Allocation lists are specified by QLIST pointers; to create */
|
||||
/* a new allocation list, the user simply defines a new (empty) */
|
||||
/* QLIST structure. */
|
||||
|
||||
/* If a program does not require multiple allocation lists, the */
|
||||
/* predefined general-purpose list "QM_GEN" may be used. */
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* QMALLOC structure definitions */
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/* alignment data type */
|
||||
|
||||
#ifdef QMSA /* stand-alone version */
|
||||
#ifndef DEF_ALIGN /* set default alignment type */
|
||||
#define DEF_ALIGN unsigned int
|
||||
#endif
|
||||
#endif /* endif "QMSA" */
|
||||
|
||||
#ifdef DEF_ALIGN /* is alignment type defined? */
|
||||
typedef DEF_ALIGN QM_ALIGN; /* use specified alignment type */
|
||||
#else /* use default alignment type */
|
||||
typedef long QM_ALIGN; /* "long-integer" alignment */
|
||||
#endif /* endif DEF_ALIGN */
|
||||
|
||||
/* size of an alignment unit */
|
||||
#define QMASIZE (sizeof(QM_ALIGN))
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/* "size" data type */
|
||||
|
||||
#define QM_SIZE_T unsigned int
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/* QMALLOC memory block header */
|
||||
|
||||
union qm_header
|
||||
{
|
||||
QM_ALIGN qm_d; /* align the block header */
|
||||
|
||||
struct /* begin header proper (qm_h) */
|
||||
{
|
||||
union /* begin multi-use portion */
|
||||
{ /* see explanation below */
|
||||
union qm_header *n0_free;
|
||||
struct qlist *q0_owner;
|
||||
}
|
||||
qm_x; /* end multi-use portion */
|
||||
|
||||
QM_SIZE_T q0_chk; /* consistency-check value */
|
||||
QM_SIZE_T q0_size; /* block size */
|
||||
}
|
||||
qm_h; /* end header proper (qm_h) */
|
||||
};
|
||||
|
||||
typedef union qm_header QM_HDR; /* typedef the block header */
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/* simplify the structure */
|
||||
|
||||
#define nxt_free qm_h.qm_x.n0_free
|
||||
#define qa_size qm_h.q0_size
|
||||
#define qm_chk qm_h.q0_chk
|
||||
#define qm_owner qm_h.qm_x.q0_owner
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/* QM_HDR structure */
|
||||
|
||||
/* The "QM_HDR" structure defines a block of dynamic memory. */
|
||||
/* The block is aligned on a "QM_ALIGN" boundary, and begins */
|
||||
/* with a header of type "QM_HDR". The rest of the block is */
|
||||
/* used for storage. */
|
||||
|
||||
/* "qa_size" is the total size of the memory block (including */
|
||||
/* the header itself) in "QM_ALIGN" alignment units (i.e., */
|
||||
/* units of QMASIZE bytes). */
|
||||
|
||||
/* "nxt_free" and "qm_owner" are context-dependent. See the */
|
||||
/* discussion of the QLIST structure below for additional */
|
||||
/* information. */
|
||||
|
||||
/* "qm_chk" is used internally for consistency checking. */
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/* QLIST structure */
|
||||
|
||||
struct qlist
|
||||
{
|
||||
QM_HDR *qm_free; /* QLIST free list */
|
||||
QM_HDR *qm_sysmem; /* QLIST system-memory list */
|
||||
QM_SIZE_T qm_block; /* allocation blocking factor */
|
||||
char qm_nofree; /* non-freeable flag */
|
||||
};
|
||||
|
||||
typedef struct qlist QLIST; /* typedef the list header */
|
||||
/* null structure pointer */
|
||||
#define NULL_QLS ((QLIST *) ZERO)
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/* QLIST free-list */
|
||||
|
||||
/* The "qm_free" field for a QLIST points to a list of free */
|
||||
/* memory blocks associated with the QLIST. Each free block */
|
||||
/* begins with a "QM_HDR" block header. The free blocks are */
|
||||
/* linked together by the "nxt_free" field in the "QM_HDR" */
|
||||
/* header. Blocks are allocated from this list by "qmalloc()" */
|
||||
/* and freed onto the list by "qfree()". */
|
||||
|
||||
/* When "qmalloc()" allocates a block from a free-list, it */
|
||||
/* points the "qm_owner" field in the header to the QLIST from */
|
||||
/* which the block was obtained. "qfree()" uses this field */
|
||||
/* subsequently when the block is freed. */
|
||||
|
||||
/* The memory blocks in the free list are carved out of a */
|
||||
/* lower-level system memory chain, which is discussed in the */
|
||||
/* next section. */
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/* QLIST system-memory list */
|
||||
|
||||
/* The "qm_sysmem" field for a QLIST points to a list of low- */
|
||||
/* level "system memory" blocks associated with the QLIST. */
|
||||
/* Each system memory block begins with a "QM_HDR" block head- */
|
||||
/* er. The system memory blocks are linked together by the */
|
||||
/* "nxt_free" field in the "QM_HDR" header. */
|
||||
|
||||
/* This linked list contains all of the dynamic storage */
|
||||
/* currently associated with a QLIST (on the "qm_free" free */
|
||||
/* list or not). The blocks in this list are obtained from the */
|
||||
/* operating system. */
|
||||
|
||||
/* "qmalloc()" carves the storage portion of each system memory */
|
||||
/* block up into sub-blocks, writes "QM_HDR" headers onto the */
|
||||
/* sub-blocks, and uses these secondary headers to build */
|
||||
/* higher-level (qm_free) allocation lists. */
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/* allocation blocking factor */
|
||||
|
||||
/* The "malloc"-based version of "qmalloc()" uses the standard */
|
||||
/* library routine "malloc()" to allocate dynamic memory at the */
|
||||
/* system level. */
|
||||
|
||||
/* The "stand-alone" version of "qmalloc()" uses an internal */
|
||||
/* utility routine to allocate dynamic memory at the system */
|
||||
/* level. */
|
||||
|
||||
/* The "qm_block" field in a QLIST header specifies the minimum */
|
||||
/* amount of memory (in bytes) to be requested for the QLIST */
|
||||
/* per system-level memory allocation call. */
|
||||
|
||||
/* If the "qm_block" field is not set, a reasonable default */
|
||||
/* value is used. */
|
||||
|
||||
/* If the host system has virtual memory, setting "qm_block" */
|
||||
/* as follows may improve performance: */
|
||||
/* */
|
||||
/* qm_block <- system memory page size minus total size of all */
|
||||
/* system-level storage headers. */
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* misc. global variables */
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/* "QM_GEN" is intended for use as a general-purpose QLIST. */
|
||||
|
||||
/* Note: Since "QM_GEN[]" is an array, "QM_GEN" serves both as */
|
||||
/* a QLIST pointer and as the QLIST entry itself. */
|
||||
|
||||
UX3_EXT QLIST QM_GEN [ONE]; /* general-purpose QLIST */
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/* "qm_retsys" is a flag used by the "qflush()" function. See */
|
||||
/* "qflush()" for additional information. */
|
||||
|
||||
UX3_EXT char qm_retsys; /* "qflush()" flag */
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* macro functions */
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/* "chk_qmp(xp)" checks the pointer "xp" and terminates the */
|
||||
/* caller with an error message if "xp" is not a valid */
|
||||
/* "qmalloc()" storage pointer. "xp" may be a pointer of any */
|
||||
/* type; "chk_qmp()" typecasts the pointer appropriately. */
|
||||
|
||||
/* Note: A valid storage pointer becomes invalid if the */
|
||||
/* associated storage is freed. */
|
||||
|
||||
/* "chk_qmp()" is a macro interface to the function "chk_ */
|
||||
/* qm0()". See the description of "chk_qm0()" for additional */
|
||||
/* information. */
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
#define chk_qmp(xp) chk_qm0 ((V_OBJ *) (xp))
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/* The macro function "xqfree()" is equivalent to the non-macro */
|
||||
/* function "qfree()", with the distinction that "xqfree()" */
|
||||
/* typecasts its argument appropriately. See the description */
|
||||
/* of "qfree()" for additional information. */
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
#define xqfree(p) qfree ((V_OBJ *) (p))
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* X3MEM function prototypes */
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
V_PROTO chk_qm0 (argp1 (V_OBJ *));
|
||||
V_PROTO chk_qma (argp1 (QLIST *));
|
||||
V_OBJ *qcalloc (argp3 (QLIST *,x3u_int,x3u_int));
|
||||
V_PROTO qflush (argp1 (QLIST *));
|
||||
V_PROTO qfree (argp1 (V_OBJ *));
|
||||
V_OBJ *qmalloc (argp2 (QLIST *,int));
|
||||
V_OBJ *qrealloc (argp2 (V_OBJ *,int));
|
||||
long sys_mem (argp0 ());
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
V_OBJ *sqCalloc (argp2 (x3u_int, x3u_int));
|
||||
V_PROTO sqChkHeap (argp0 ());
|
||||
V_PROTO sqChkPtr (argp2 (V_OBJ *, char *));
|
||||
V_PROTO sqFlush (argp0 ());
|
||||
V_PROTO sqFree (argp1 (V_OBJ *));
|
||||
V_OBJ *sqMalloc (argp1 (x3u_int));
|
||||
V_OBJ *sqRealloc (argp2 (V_OBJ *, x3u_int));
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* wrap it up */
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
#endif /* endif _X3MEM_H */
|
@ -24,6 +24,10 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "lz78.h"
|
||||
#include "../inc/x3mem.h"
|
||||
|
||||
UX3_EXT QLIST QM_LZ [ONE]; // Dynamic-memory QLIST
|
||||
|
||||
|
||||
/* Code used to represent an EOF */
|
||||
#define DICT_CODE_EOF 256
|
||||
@ -168,14 +172,13 @@ uint8_t bitlen(uint32_t i) {
|
||||
}
|
||||
|
||||
ht_dictionary* ht_dictionary_new(uint32_t d_size) {
|
||||
ht_dictionary* dict = malloc(sizeof(ht_dictionary));
|
||||
ht_dictionary* dict = qmalloc(QM_LZ, sizeof(ht_dictionary));
|
||||
if (dict == NULL)
|
||||
return NULL;
|
||||
|
||||
d_size = DICT_LIMIT(d_size);
|
||||
dict->root = calloc(1, sizeof(ht_entry) * d_size);
|
||||
dict->root = qcalloc(QM_LZ, 1, sizeof(ht_entry) * d_size);
|
||||
if (dict->root == NULL) {
|
||||
free(dict);
|
||||
return NULL;
|
||||
} else {
|
||||
dict->d_size = d_size;
|
||||
@ -243,22 +246,19 @@ void ht_dictionary_reset(ht_dictionary* d) {
|
||||
void ht_dictionary_destroy(ht_dictionary* d) {
|
||||
if (d != NULL)
|
||||
{
|
||||
//free(d);
|
||||
printf("I SHOULD BE FREEING MEMORY RIGHT NOW!\n");
|
||||
// This is obviously going to be fixed in due course.
|
||||
//qfree(d);
|
||||
}
|
||||
}
|
||||
|
||||
dictionary* dictionary_new(uint32_t d_size) {
|
||||
uint16_t i;
|
||||
dictionary* dict = malloc(sizeof(dictionary) + d_size);
|
||||
dictionary* dict = qmalloc(QM_LZ, sizeof(dictionary) + d_size);
|
||||
if (dict == NULL)
|
||||
return NULL;
|
||||
|
||||
d_size = DICT_LIMIT(d_size);
|
||||
dict->root = malloc(sizeof(entry) * d_size);
|
||||
dict->root = qmalloc(QM_LZ, sizeof(entry) * d_size);
|
||||
if (dict->root == NULL) {
|
||||
free(dict);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -310,8 +310,7 @@ void dictionary_reset(dictionary* d) {
|
||||
|
||||
void dictionary_destroy(dictionary* d) {
|
||||
if (d != NULL) {
|
||||
free(d->root);
|
||||
free(d);
|
||||
//qfree(d);
|
||||
}
|
||||
}
|
||||
|
||||
@ -441,7 +440,7 @@ lz78_instance* lz78_new(uint8_t cmode, uint32_t dsize) {
|
||||
lz78_d* d;
|
||||
|
||||
int max_dim = (sizeof(lz78_c) > sizeof(lz78_d)) ? sizeof(lz78_c) : sizeof(lz78_d);
|
||||
i = malloc(sizeof(lz78_instance) + max_dim);
|
||||
i = qmalloc(QM_LZ, (sizeof(lz78_instance) + max_dim));
|
||||
if (i == NULL)
|
||||
return NULL;
|
||||
i->mode = cmode;
|
||||
@ -454,13 +453,13 @@ lz78_instance* lz78_new(uint8_t cmode, uint32_t dsize) {
|
||||
c->completed = 0;
|
||||
c->main = ht_dictionary_new(c->d_size);
|
||||
if (c->main == NULL) {
|
||||
free(i);
|
||||
//qfree(i);
|
||||
return NULL;
|
||||
}
|
||||
c->secondary = ht_dictionary_new(c->d_size);
|
||||
if (c->secondary == NULL) {
|
||||
ht_dictionary_destroy(c->main);
|
||||
free(i);
|
||||
//qfree(i);
|
||||
return NULL;
|
||||
}
|
||||
c->bitbuf = DICT_CODE_START;
|
||||
@ -473,7 +472,7 @@ lz78_instance* lz78_new(uint8_t cmode, uint32_t dsize) {
|
||||
d->completed = 0;
|
||||
d->main = dictionary_new(DICT_SIZE_MIN);
|
||||
if (d->main == NULL) {
|
||||
free(i);
|
||||
//qfree(i);
|
||||
return NULL;
|
||||
}
|
||||
return i;
|
||||
@ -630,13 +629,13 @@ void lz78_destroy(lz78_instance *lz78) {
|
||||
|
||||
case LZ78_MODE_DECOMPRESS:
|
||||
d = (lz78_d*)&lz78->state;
|
||||
if (d != NULL) {
|
||||
//dictionary_destroy(d->main);
|
||||
if (d != NULL && d->main != NULL) {
|
||||
dictionary_destroy(d->main);
|
||||
ht_dictionary_destroy(d->secondary);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
free(lz78);
|
||||
qflush(QM_LZ);
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "wrapper.h"
|
||||
#include "../inc/x3mem.h"
|
||||
|
||||
/* Structure representing the type of algorithm */
|
||||
struct __algorithm {
|
||||
@ -161,7 +162,7 @@ void wrapper_perror() {
|
||||
}
|
||||
|
||||
wrapper* wrapper_new(uint8_t w_mode, uint8_t w_type, char* argv) {
|
||||
wrapper* w = malloc(sizeof(wrapper));
|
||||
wrapper* w = qmalloc(QM_LZ, sizeof(wrapper));
|
||||
if (w == NULL)
|
||||
return NULL;
|
||||
|
||||
@ -174,14 +175,14 @@ wrapper* wrapper_new(uint8_t w_mode, uint8_t w_type, char* argv) {
|
||||
break;
|
||||
|
||||
default:
|
||||
free(w);
|
||||
qfree(w);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (w->data)
|
||||
return w;
|
||||
else {
|
||||
free(w);
|
||||
qfree(w);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -198,7 +199,7 @@ void wrapper_destroy(wrapper* w) {
|
||||
default:
|
||||
return;
|
||||
}
|
||||
free(w);
|
||||
qflush(QM_LZ);
|
||||
}
|
||||
|
||||
uint8_t wrapper_compress(wrapper* w, char* input, char* output) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user