Refactor allocation API

This way we don't need to expose MemError() to platform-independent
code.
This commit is contained in:
Dietrich Epp 2022-03-25 13:33:24 -04:00
parent 617bf831d8
commit 8e2efa707e
7 changed files with 105 additions and 105 deletions

View File

@ -9,16 +9,17 @@ const struct ConvertEngine kEngines[][2] = {
{{Convert1fBuild, Convert1fRun}, {Convert1rBuild, Convert1rRun}}}; {{Convert1fBuild, Convert1fRun}, {Convert1rBuild, Convert1rRun}}};
int ConverterBuild(struct Converter *c, Handle data, Size datasz, int ConverterBuild(struct Converter *c, Handle data, Size datasz,
ConvertDirection direction, OSErr *errp) ConvertDirection direction)
{ {
int engine, r; int engine;
const struct ConvertEngine *funcs; const struct ConvertEngine *funcs;
Handle out; Handle out;
ErrorCode err;
if (datasz == 0) { if (datasz == 0) {
return kErrorBadData; return kErrorBadData;
} }
engine = (UInt8) * *data - 1; engine = (UInt8)(**data) - 1;
if (engine < 0 || (int)(sizeof(kEngines) / sizeof(*kEngines)) <= engine) { if (engine < 0 || (int)(sizeof(kEngines) / sizeof(*kEngines)) <= engine) {
/* Invalid engine. */ /* Invalid engine. */
return kErrorBadData; return kErrorBadData;
@ -28,9 +29,9 @@ int ConverterBuild(struct Converter *c, Handle data, Size datasz,
/* Invalid engine. */ /* Invalid engine. */
return kErrorBadData; return kErrorBadData;
} }
r = funcs->build(&out, data, datasz, errp); err = funcs->build(&out, data, datasz);
if (r != 0) { if (err != 0) {
return r; return err;
} }
c->data = out; c->data = out;
c->run = funcs->run; c->run = funcs->run;

View File

@ -4,19 +4,6 @@
#include "lib/defs.h" #include "lib/defs.h"
/* Error codes. */
enum
{
/* No error. */
kErrorOK,
/* Memory allocation failed. */
kErrorNoMemory,
/* Invaild table data. */
kErrorBadData
};
enum enum
{ {
/* Constants for CR and LF. Note that we should not use '\n' or '\r' /* Constants for CR and LF. Note that we should not use '\n' or '\r'
@ -62,8 +49,7 @@ struct ConverterState {
}; };
/* Implementation function for building a converter. */ /* Implementation function for building a converter. */
typedef int (*ConvertBuildf)(Handle *out, Handle data, Size datasz, typedef ErrorCode (*ConvertBuildf)(Handle *out, Handle data, Size datasz);
OSErr *errp);
/* Implementation function for running a converter. */ /* Implementation function for running a converter. */
typedef void (*ConvertRunf)(const void *cvtptr, LineBreakConversion lc, typedef void (*ConvertRunf)(const void *cvtptr, LineBreakConversion lc,
@ -78,16 +64,16 @@ struct Converter {
/* Build a converter from the given conversion table data. */ /* Build a converter from the given conversion table data. */
int ConverterBuild(struct Converter *c, Handle data, Size datasz, int ConverterBuild(struct Converter *c, Handle data, Size datasz,
ConvertDirection direction, OSErr *errp); ConvertDirection direction);
/* Engine 1: extended ASCII */ /* Engine 1: extended ASCII */
int Convert1fBuild(Handle *out, Handle data, Size datasz, OSErr *errp); ErrorCode Convert1fBuild(Handle *out, Handle data, Size datasz);
void Convert1fRun(const void *cvtptr, LineBreakConversion lc, void Convert1fRun(const void *cvtptr, LineBreakConversion lc,
struct ConverterState *stateptr, UInt8 **optr, UInt8 *oend, struct ConverterState *stateptr, UInt8 **optr, UInt8 *oend,
const UInt8 **iptr, const UInt8 *iend); const UInt8 **iptr, const UInt8 *iend);
int Convert1rBuild(Handle *out, Handle data, Size datasz, OSErr *errp); ErrorCode Convert1rBuild(Handle *out, Handle data, Size datasz);
void Convert1rRun(const void *cvtptr, LineBreakConversion lc, void Convert1rRun(const void *cvtptr, LineBreakConversion lc,
struct ConverterState *stateptr, UInt8 **optr, UInt8 *oend, struct ConverterState *stateptr, UInt8 **optr, UInt8 *oend,
const UInt8 **iptr, const UInt8 *iend); const UInt8 **iptr, const UInt8 *iend);

View File

@ -12,7 +12,7 @@ struct Convert1fState {
UInt8 lastch; UInt8 lastch;
}; };
int Convert1fBuild(Handle *out, Handle data, Size datasz, OSErr *errp) ErrorCode Convert1fBuild(Handle *out, Handle data, Size datasz)
{ {
Handle h; Handle h;
struct Convert1fData *cvt; struct Convert1fData *cvt;
@ -22,7 +22,6 @@ int Convert1fBuild(Handle *out, Handle data, Size datasz, OSErr *errp)
h = NewHandle(sizeof(struct Convert1fData)); h = NewHandle(sizeof(struct Convert1fData));
if (h == NULL) { if (h == NULL) {
*errp = MemError();
return kErrorNoMemory; return kErrorNoMemory;
} }
cvt = (void *)*h; cvt = (void *)*h;

View File

@ -28,12 +28,11 @@ struct TTree {
int count; int count;
}; };
static int CreateTree(struct TTree *tree, Handle data, Size datasz, OSErr *errp) static ErrorCode CreateTree(struct TTree *tree, Handle data, Size datasz)
{ {
struct TNode **nodes, *node; struct TNode **nodes, *node;
int i, j, dpos, enclen, encend, state, cur, nodecount, nodealloc; int i, j, dpos, enclen, encend, state, cur, nodecount, nodealloc;
unsigned ch; unsigned ch;
OSErr err;
/* Create a tree with a root node mapping all the ASCII characters except /* Create a tree with a root node mapping all the ASCII characters except
NUL, CR, and LF. NUL won't map because an output of 0 is interpreted as NUL, CR, and LF. NUL won't map because an output of 0 is interpreted as
@ -42,8 +41,7 @@ static int CreateTree(struct TTree *tree, Handle data, Size datasz, OSErr *errp)
nodes = nodes =
(struct TNode **)NewHandle(kInitialTableAlloc * sizeof(struct TNode)); (struct TNode **)NewHandle(kInitialTableAlloc * sizeof(struct TNode));
if (nodes == NULL) { if (nodes == NULL) {
err = MemError(); return kErrorNoMemory;
goto have_error;
} }
nodecount = 1; nodecount = 1;
nodealloc = kInitialTableAlloc; nodealloc = kInitialTableAlloc;
@ -81,11 +79,11 @@ static int CreateTree(struct TTree *tree, Handle data, Size datasz, OSErr *errp)
if (state == 0) { if (state == 0) {
if (nodecount >= nodealloc) { if (nodecount >= nodealloc) {
nodealloc *= 2; nodealloc *= 2;
SetHandleSize((Handle)nodes, if (!ResizeHandle(
nodealloc * sizeof(struct TNode)); (Handle)nodes,
err = MemError(); nodealloc * sizeof(struct TNode))) {
if (err != 0) { DisposeHandle((Handle)nodes);
goto have_error; return kErrorNoMemory;
} }
node = *nodes + cur; node = *nodes + cur;
} }
@ -105,7 +103,10 @@ static int CreateTree(struct TTree *tree, Handle data, Size datasz, OSErr *errp)
} }
} }
} }
SetHandleSize((Handle)nodes, nodecount * sizeof(struct TNode)); if (!ResizeHandle((Handle)nodes, nodecount * sizeof(struct TNode))) {
DisposeHandle((Handle)nodes);
return kErrorNoMemory;
}
tree->nodes = nodes; tree->nodes = nodes;
tree->count = nodecount; tree->count = nodecount;
return 0; return 0;
@ -113,11 +114,6 @@ static int CreateTree(struct TTree *tree, Handle data, Size datasz, OSErr *errp)
bad_table: bad_table:
DisposeHandle((Handle)nodes); DisposeHandle((Handle)nodes);
return kErrorBadData; return kErrorBadData;
have_error:
DisposeHandle((Handle)nodes);
*errp = err;
return kErrorNoMemory;
} }
struct NodeInfo { struct NodeInfo {
@ -139,8 +135,7 @@ struct CNode {
UInt8 span; UInt8 span;
}; };
static int CompactTree(Handle *out, struct TNode **nodes, int nodecount, static ErrorCode CompactTree(Handle *out, struct TNode **nodes, int nodecount)
OSErr *errp)
{ {
Handle ctree; Handle ctree;
struct TNode *node; struct TNode *node;
@ -153,7 +148,6 @@ static int CompactTree(Handle *out, struct TNode **nodes, int nodecount,
/* Figure out where each compacted node will go. */ /* Figure out where each compacted node will go. */
infos = (struct NodeInfo **)NewHandle(sizeof(struct NodeInfo) * nodecount); infos = (struct NodeInfo **)NewHandle(sizeof(struct NodeInfo) * nodecount);
if (infos == NULL) { if (infos == NULL) {
*errp = MemError();
return kErrorNoMemory; return kErrorNoMemory;
} }
offset = 0; offset = 0;
@ -178,7 +172,6 @@ static int CompactTree(Handle *out, struct TNode **nodes, int nodecount,
/* Create the compacted tree. */ /* Create the compacted tree. */
ctree = NewHandle(offset); ctree = NewHandle(offset);
if (ctree == NULL) { if (ctree == NULL) {
*errp = MemError();
DisposeHandle((Handle)infos); DisposeHandle((Handle)infos);
return kErrorNoMemory; return kErrorNoMemory;
} }
@ -208,18 +201,18 @@ static int CompactTree(Handle *out, struct TNode **nodes, int nodecount,
return 0; return 0;
} }
int Convert1rBuild(Handle *out, Handle data, Size datasz, OSErr *errp) ErrorCode Convert1rBuild(Handle *out, Handle data, Size datasz)
{ {
struct TTree table; struct TTree table;
int r; ErrorCode err;
r = CreateTree(&table, data, datasz, errp); err = CreateTree(&table, data, datasz);
if (r != 0) { if (err != 0) {
return r; return err;
} }
r = CompactTree(out, table.nodes, table.count, errp); err = CompactTree(out, table.nodes, table.count);
DisposeHandle((Handle)table.nodes); DisposeHandle((Handle)table.nodes);
return r; return err;
} }
struct Convert1rState { struct Convert1rState {

View File

@ -41,7 +41,7 @@ static void Failf(const char *msg, ...)
static const char *const kErrorNames[] = {"ok", "no memory", "bad data"}; static const char *const kErrorNames[] = {"ok", "no memory", "bad data"};
static const char *ErrorName(int err) static const char *ErrorName(ErrorCode err)
{ {
if (err < 0 || (int)(sizeof(kErrorNames) / sizeof(*kErrorNames)) <= err) { if (err < 0 || (int)(sizeof(kErrorNames) / sizeof(*kErrorNames)) <= err) {
Dief("bad error code: %d", err); Dief("bad error code: %d", err);
@ -151,12 +151,12 @@ static void TestConverter(const char *name, struct CharmapData data)
Handle datah; Handle datah;
struct Converter cf, cr, cc; struct Converter cf, cr, cc;
struct ConverterState st; struct ConverterState st;
int r, i, j, k, jmax, len0, len1, len2; int i, j, k, jmax, len0, len1, len2;
OSErr err;
UInt8 *ptr; UInt8 *ptr;
const UInt8 *iptr, *iend, *istart; const UInt8 *iptr, *iend, *istart;
UInt8 *optr, *oend; UInt8 *optr, *oend;
int lblen[4]; int lblen[4];
ErrorCode err;
cf.data = NULL; cf.data = NULL;
cr.data = NULL; cr.data = NULL;
@ -166,14 +166,14 @@ static void TestConverter(const char *name, struct CharmapData data)
/* Load the converter into memory and build the conversion table. */ /* Load the converter into memory and build the conversion table. */
datap = (void *)data.ptr; datap = (void *)data.ptr;
datah = &datap; datah = &datap;
r = ConverterBuild(&cf, datah, data.size, kToUTF8, &err); err = ConverterBuild(&cf, datah, data.size, kToUTF8);
if (r != 0) { if (err != 0) {
Failf("ConverterBuild: to UTF-8: %s", ErrorName(r)); Failf("ConverterBuild: to UTF-8: %s", ErrorName(err));
goto done; goto done;
} }
r = ConverterBuild(&cr, datah, data.size, kFromUTF8, &err); err = ConverterBuild(&cr, datah, data.size, kFromUTF8);
if (r != 0) { if (err != 0) {
Failf("ConverterBuild: from UTF-8: %s", ErrorName(r)); Failf("ConverterBuild: from UTF-8: %s", ErrorName(err));
goto done; goto done;
} }
@ -282,7 +282,7 @@ int main(int argc, char **argv)
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
buf = malloc(kConvertBufferSize); buf = malloc(kConvertBufferSize);
if (buf == NULL) { if (buf == NULL) {
DieErrorf(errno, "malloc"); Dief("malloc failed");
} }
gBuffer[i] = buf; gBuffer[i] = buf;
} }

View File

@ -2,18 +2,35 @@
#define defs_h #define defs_h
/* defs.h - common definitions. */ /* defs.h - common definitions. */
/*==============================================================================
Basic definitions
==============================================================================*/
#if macintosh #if macintosh
#include <MacTypes.h> #include <MacTypes.h>
#else #else
/* Definitions in <MacTypes.h> */
/* Include <stddef.h> for NULL */ /* Include <stddef.h> for NULL */
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#if __STDC_VERSION__ >= 199901l
#include <stdbool.h>
#endif
#if __bool_true_false_are_defined
typedef bool Boolean;
#else
enum
{
false,
true
};
typedef unsigned char Boolean;
#endif
typedef uint8_t UInt8; typedef uint8_t UInt8;
typedef int8_t SInt8; typedef int8_t SInt8;
typedef uint16_t UInt16; typedef uint16_t UInt16;
@ -25,19 +42,47 @@ typedef char *Ptr;
typedef Ptr *Handle; typedef Ptr *Handle;
typedef long Size; typedef long Size;
typedef SInt16 OSErr; #endif
/* Definitions in <MacMemory.h> */ /*==============================================================================
Error codes and error reporting
==============================================================================*/
Handle NewHandle(Size byteCount); /* Error codes. */
void HLock(Handle h); typedef enum
void HUnlock(Handle h); {
/* No error. */
kErrorOK,
/* Memory allocation failed. */
kErrorNoMemory,
/* Invaild table data. */
kErrorBadData
} ErrorCode;
/*==============================================================================
Memory allocation
==============================================================================*/
#if macintosh
#include <MacMemory.h>
#else
/* Allocate a relocatable block of memory. */
Handle NewHandle(Size byteSize);
/* Free a relocatable block of memory. */
void DisposeHandle(Handle h); void DisposeHandle(Handle h);
void SetHandleSize(Handle h, Size newSize);
OSErr MemError(void);
#endif #endif
/* Resize a relocatable block of memory. Return true on success. */
Boolean ResizeHandle(Handle h, Size newSize);
/* Fill memory with zeroes. */
void MemClear(void *ptr, Size size); void MemClear(void *ptr, Size size);
#endif #endif

View File

@ -22,19 +22,6 @@ void Dief(const char *msg, ...)
exit(1); exit(1);
} }
void DieErrorf(int errcode, const char *msg, ...)
{
va_list ap;
fputs("Error: ", stderr);
va_start(ap, msg);
vfprintf(stderr, msg, ap);
va_end(ap);
fputs(": ", stderr);
fputs(strerror(errcode), stderr);
fputc('\n', stderr);
exit(1);
}
Handle NewHandle(Size byteCount) Handle NewHandle(Size byteCount)
{ {
Ptr p; Ptr p;
@ -45,26 +32,17 @@ Handle NewHandle(Size byteCount)
} }
p = malloc(byteCount); p = malloc(byteCount);
if (byteCount > 0 && p == NULL) { if (byteCount > 0 && p == NULL) {
Dief("NewHandle: malloc failed"); return NULL;
} }
h = malloc(sizeof(Ptr)); h = malloc(sizeof(Ptr));
if (h == NULL) { if (h == NULL) {
Dief("NewHandle: malloc failed"); free(p);
return NULL;
} }
*h = p; *h = p;
return h; return h;
} }
void HLock(Handle h)
{
(void)h;
}
void HUnlock(Handle h)
{
(void)h;
}
void DisposeHandle(Handle h) void DisposeHandle(Handle h)
{ {
if (h != NULL) { if (h != NULL) {
@ -73,23 +51,21 @@ void DisposeHandle(Handle h)
} }
} }
void SetHandleSize(Handle h, Size newSize) Boolean ResizeHandle(Handle h, Size newSize)
{ {
Ptr p; Ptr p;
if (h == NULL) { if (h == NULL) {
Dief("SetHandleSize: h = NULL"); Dief("ResizeHandle: h = NULL");
}
if (newSize < 0) {
Dief("ResizeHandle: newSize = %ld", newSize);
} }
p = realloc(*h, newSize); p = realloc(*h, newSize);
if (newSize > 0 && p == NULL) { if (newSize > 0 && p == NULL) {
Dief("SetHandleSize: realloc failed"); return false;
} }
*h = p; *h = p;
} return true;
OSErr MemError(void)
{
/* Memory allocation failures abort the program. */
return 0;
} }
void MemClear(void *ptr, Size size) void MemClear(void *ptr, Size size)