jcs
/wikipedia
/amendments
/41
util: Sync with upstream
jcs made amendment 41 about 1 year ago
--- util.c Wed Sep 7 15:51:42 2022
+++ util.c Mon Mar 27 21:32:52 2023
@@ -53,13 +53,15 @@ static Handle alert_ditl_h = NULL;
/* DITL with a Yes button (1), No button (2), text (3), and icon (4) */
static const char ask_ditl[] = {
- 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E,
- 0x00, 0xFA, 0x00, 0x64, 0x01, 0x34, 0x04, 0x02,
- 0x4F, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D,
- 0x00, 0x4E, 0x00, 0x41, 0x01, 0x36, 0x08, 0x02,
- 0x5E, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D,
- 0x00, 0x17, 0x00, 0x2D, 0x00, 0x37, 0xA0, 0x02,
- 0x00, 0x01
+ 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x00, 0xE6, 0x00, 0x5A, 0x01, 0x20, 0x04, 0x03,
+ 0x59, 0x65, 0x73, 0x21, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x46, 0x00, 0xA0, 0x00, 0x5A, 0x00, 0xDA,
+ 0x04, 0x02, 0x4E, 0x6F, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0A, 0x00, 0x32, 0x00, 0x41, 0x01, 0x22,
+ 0x08, 0x02, 0x5E, 0x30, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x2A, 0x00, 0x2A,
+ 0xA0, 0x02, 0x00, 0x01
};
static Handle ask_ditl_h = NULL;
@@ -81,28 +83,6 @@ enum {
APPICON_ALERT
};
-/*
- * Define to audit each malloc and free and verify that a pointer isn't
- * double-freed. The list of outstanding allocations can be checked by
- * looking through malloc_map.
- */
-//#define MALLOC_DEBUG
-
-#ifdef MALLOC_DEBUG
-/*
- * List of allocations, updated at xmalloc() and xfree(). If an address
- * passed to xfree() isn't in the list, it indicates a double-free.
- */
-#define MALLOC_MAP_CHUNK_SIZE 1024
-struct malloc_map_e {
- unsigned long addr;
- unsigned long size;
- char note[MALLOC_NOTE_SIZE];
-} *malloc_map = NULL;
-unsigned long malloc_map_size = 0;
-static bool malloc_map_compact = false;
-#endif
-
void vwarn(short alert_func, const char *format, va_list ap);
/*
@@ -114,18 +94,11 @@ void
util_init(void)
{
alert_ditl_h = xNewHandle(sizeof(alert_ditl));
+ if (alert_ditl_h == NULL)
+ ExitToShell();
HLock(alert_ditl_h);
memcpy(*alert_ditl_h, alert_ditl, sizeof(alert_ditl));
HUnlock(alert_ditl_h);
-
-#ifdef MALLOC_DEBUG
- malloc_map_size = MALLOC_MAP_CHUNK_SIZE;
- malloc_map = (struct malloc_map_e *)NewPtr(malloc_map_size *
- sizeof(struct malloc_map_e));
- if (malloc_map == NULL)
- panic("NewPtr(%lu) failed", MALLOC_MAP_CHUNK_SIZE);
- memset(malloc_map, 0, malloc_map_size);
-#endif
}
/*
@@ -135,63 +108,17 @@ util_init(void)
#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
void *
-xmalloc(size_t size, char *note)
+xmalloc(size_t size)
{
void *ptr;
-#ifdef MALLOC_DEBUG
- struct malloc_map_e *new_malloc_map;
- unsigned short n, j;
-#endif
if (size == 0)
panic("xmalloc: zero size");
ptr = NewPtr(size);
+#if 0
if (ptr == NULL)
- panic("xmalloc(%lu) failed", size);
-
-#ifdef MALLOC_DEBUG
- if (malloc_map_compact) {
- for (n = 0; n < malloc_map_size; n++) {
- if (malloc_map[n].addr != 0)
- continue;
-
- for (j = n + 1; j < malloc_map_size; j++) {
- if (malloc_map[j].addr == 0)
- continue;
-
- malloc_map[n] = malloc_map[j];
- memset(&malloc_map[j], 0, sizeof(struct malloc_map_e));
- break;
- }
- }
-
- malloc_map_compact = false;
- }
-
- for (n = 0; n <= malloc_map_size; n++) {
- if (n == malloc_map_size) {
- malloc_map_size += MALLOC_MAP_CHUNK_SIZE;
- warn("xmalloc(%lu): out of malloc map entries, maybe a "
- "memory leak, resizing to %ld", size, malloc_map_size);
- new_malloc_map = (struct malloc_map_e *)NewPtr(
- malloc_map_size * sizeof(struct malloc_map_e));
- if (new_malloc_map == NULL)
- panic("out of memory resizing malloc map");
- memcpy(new_malloc_map, malloc_map,
- (malloc_map_size - MALLOC_MAP_CHUNK_SIZE) *
- sizeof(struct malloc_map_e));
- DisposePtr(malloc_map);
- malloc_map = new_malloc_map;
- }
- if (malloc_map[n].addr == 0) {
- malloc_map[n].addr = (unsigned long)ptr;
- malloc_map[n].size = size;
- strlcpy(malloc_map[n].note, note, sizeof(malloc_map[n].note));
- break;
- }
- n = n;
- }
+ warn("Insufficient memory available: xmalloc(%lu) failed", size);
#endif
return ptr;
@@ -201,79 +128,48 @@ void
xfree(void *ptrptr)
{
unsigned long *addr = (unsigned long *)ptrptr;
- void *ptr = (void *)*addr;
-#ifdef MALLOC_DEBUG
- unsigned long n;
+ void *ptr;
- for (n = 0; n <= malloc_map_size; n++) {
- if (n == malloc_map_size)
- panic("xfree(0x%lx): can't find in alloc map, likely "
- "double free()", *addr);
- if (malloc_map[n].addr == *addr) {
- malloc_map[n].addr = 0;
- malloc_map[n].size = 0;
- malloc_map[n].note[0] = '\0';
- break;
- }
- }
-#endif
+ if (ptrptr == NULL)
+ panic("xfree(NULL)");
+ ptr = (void *)*addr;
+ if (ptr == NULL)
+ panic("xfree(&NULL) likely a double-free");
+
DisposePtr(ptr);
-
*addr = 0L;
}
void *
-xmalloczero(size_t size, char *note)
+xmalloczero(size_t size)
{
void *ptr;
- ptr = xmalloc(size, note);
- memset(ptr, 0, size);
+ ptr = xmalloc(size);
+ if (ptr != NULL)
+ memset(ptr, 0, size);
return ptr;
}
void *
-xcalloc(size_t nmemb, size_t size, char *note)
+xcalloc(size_t nmemb, size_t size)
{
- void *ptr;
-
if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
nmemb > 0 && SIZE_MAX / nmemb < size)
panic("xcalloc(%lu, %lu) overflow", nmemb, size);
- ptr = xmalloczero(nmemb * size, note);
- if (ptr == NULL)
- panic("xcalloc(%lu, %lu) failed", nmemb, size);
-
- return ptr;
+
+ return xmalloczero(nmemb * size);
}
void *
xrealloc(void *src, size_t size)
{
void *ptr, *tsrc;
- unsigned long n;
- char note[MALLOC_NOTE_SIZE] = "realloc from null";
-#ifdef MALLOC_DEBUG
- if (src != NULL) {
- for (n = 0; n <= malloc_map_size; n++) {
- if (n == malloc_map_size) {
- panic("xrealloc(%lu): can't find in alloc map, likely "
- "double free()", (unsigned long)src);
- return NULL;
- }
- if (malloc_map[n].addr == (unsigned long)src) {
- strlcpy(note, malloc_map[n].note, sizeof(note));
- break;
- }
- }
- }
-#endif
-
- ptr = xmalloc(size, note);
- if (src != NULL) {
+ ptr = xmalloc(size);
+ if (ptr != NULL && src != NULL) {
memcpy(ptr, src, size);
tsrc = src;
xfree(&tsrc);
@@ -288,25 +184,26 @@ xreallocarray(void *optr, size_t nmemb, size_t size)
if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
nmemb > 0 && SIZE_MAX / nmemb < size)
panic("xreallocarray(%lu, %lu) failed", nmemb, size);
+
return xrealloc(optr, size * nmemb);
}
char *
-xstrdup(const char *str, char *note)
+xstrdup(const char *str)
{
char *cp;
size_t len;
len = strlen(str);
+ cp = xmalloc(len + 1);
+ if (cp != NULL)
+ strlcpy(cp, str, len + 1);
- cp = xmalloc(len + 1, note);
- strlcpy(cp, str, len + 1);
-
return cp;
}
char *
-xstrndup(const char *str, size_t maxlen, char *note)
+xstrndup(const char *str, size_t maxlen)
{
char *copy;
const char *cp;
@@ -317,14 +214,42 @@ xstrndup(const char *str, size_t maxlen, char *note)
;
len = (size_t)(cp - str);
- copy = xmalloc(len + 1, note);
- (void)memcpy(copy, str, len);
- copy[len] = '\0';
+ copy = xmalloc(len + 1);
+ if (copy != NULL) {
+ (void)memcpy(copy, str, len);
+ copy[len] = '\0';
+ }
return copy;
}
+/* if var having used_size can't fit add, grow it by grow_amount */
+bool
+grow_to_fit(void *var, size_t *var_size, size_t used_size, size_t add,
+ size_t grow_amount)
+{
+ char **p = var;
+ char *curp = *p;
+ char *newp;
+ size_t new_size;
+
+ if (used_size + add < *var_size)
+ return true;
+ new_size = *var_size;
+ while (new_size < used_size + add)
+ new_size += grow_amount;
+
+ newp = xrealloc(curp, new_size);
+ if (newp == NULL)
+ return false;
+
+ *var_size = new_size;
+ *p = newp;
+
+ return true;
+}
+
/*
* String functions
*/
@@ -336,8 +261,11 @@ getline(char *str, size_t len, char **ret)
for (i = 0; i < len; i++) {
if (str[i] == '\r' || i == len - 1) {
- if (*ret == NULL)
- *ret = xmalloc(i + 1, "getline");
+ if (*ret == NULL) {
+ *ret = xmalloc(i + 1);
+ if (*ret == NULL)
+ return -1;
+ }
memcpy(*ret, str, i + 1);
(*ret)[i] = '\0';
return i + 1;
@@ -700,7 +628,7 @@ center_in_screen(short width, short height, bool title
}
Point
-centered_sf_dialog(void)
+centered_sfget_dialog(void)
{
Point p;
Rect r;
@@ -712,6 +640,18 @@ centered_sf_dialog(void)
return p;
}
+Point
+centered_sfput_dialog(void)
+{
+ Point p;
+ Rect r;
+
+ center_in_screen(320, 200, false, &r);
+ p.h = r.left;
+ p.v = r.top;
+
+ return p;
+}
/*
* General Mac-specific non-GUI functions
@@ -784,32 +724,38 @@ xGetStringAsChar(short id)
h = xGetString(id);
HLock(h);
l = (*h)[0];
- out = xmalloc(l + 1, "xGetStringAsChar");
- memcpy((void *)out, (void *)(*h + 1), l);
- out[l] = '\0';
+ out = xmalloc(l + 1);
+ if (out != NULL) {
+ memcpy((void *)out, (void *)(*h + 1), l);
+ out[l] = '\0';
+ }
ReleaseResource(h);
return out;
}
-long
-xGetStringAsLong(short id)
+bool
+xGetStringAsLong(short id, long *ret)
{
char *c;
- long r;
c = xGetStringAsChar(id);
- r = atol(c);
+ if (c == NULL)
+ return false;
+ *ret = atol(c);
xfree(&c);
- return r;
+ return true;
}
-void
+bool
xSetHandleSize(Handle h, Size s)
{
SetHandleSize(h, s);
- if (MemError())
- panic("Failed to SetHandleSize to %ld", s);
+ if (MemError()) {
+ warn("Failed to SetHandleSize to %ld", s);
+ return false;
+ }
+ return true;
}
/*
@@ -817,7 +763,7 @@ xSetHandleSize(Handle h, Size s)
*/
short
-getpath(short vRefNum, Str255 fileName, Str255 *ret, bool include_file)
+getpath(short vRefNum, Str255 fileName, Str255 ret, bool include_file)
{
WDPBRec wdir;
HVolumeParam wvol;
@@ -827,20 +773,24 @@ getpath(short vRefNum, Str255 fileName, Str255 *ret, b
char *tmpret = NULL, *tmp = NULL;
char *lastcolon;
+ ret[0] = 0;
+
if (strchr((char *)fileName + 1, ':') != NULL) {
/* already a full path */
- memcpy(*ret, fileName, 256);
+ memcpy(ret, fileName, 256);
if (!include_file) {
- PtoCstr(*ret);
- lastcolon = strrchr((char *)*ret, ':');
+ PtoCstr(ret);
+ lastcolon = strrchr((char *)ret, ':');
lastcolon[0] = '\0';
- CtoPstr(*ret);
+ CtoPstr(ret);
}
return 0;
}
- name = xmalloc(FILENAME_MAX, "getpath");
-
+ name = xmalloc(FILENAME_MAX);
+ if (name == NULL)
+ return 1;
+
wdir.ioVRefNum = wdir.ioWDVRefNum = vRefNum;
wdir.ioWDIndex = 0;
wdir.ioWDProcID = 0;
@@ -873,9 +823,18 @@ getpath(short vRefNum, Str255 fileName, Str255 *ret, b
wcinfo.ioDrParID = wdir.ioWDDirID;
wcinfo.ioDrDirID = wdir.ioWDDirID;
- tmp = xmalloc(FILENAME_MAX, "getpath");
- tmpret = xmalloc(FILENAME_MAX, "getpath");
-
+ tmp = xmalloc(FILENAME_MAX);
+ if (tmp == NULL) {
+ xfree(&name);
+ return 1;
+ }
+ tmpret = xmalloc(FILENAME_MAX);
+ if (tmp == NULL) {
+ xfree(&tmp);
+ xfree(&name);
+ return 1;
+ }
+
/* go backwards, prepending each folder's parent */
while (wcinfo.ioDrParID != 1) {
wcinfo.ioDrDirID = wcinfo.ioDrParID; /* .. */
@@ -905,7 +864,7 @@ getpath(short vRefNum, Str255 fileName, Str255 *ret, b
strlcat(tmpret, name, FILENAME_MAX);
}
} else if (retlen == 0) {
- (*ret)[0] = 0;
+ ret[0] = 0;
xfree(&tmp);
xfree(&tmpret);
xfree(&name);
@@ -913,7 +872,7 @@ getpath(short vRefNum, Str255 fileName, Str255 *ret, b
}
CtoPstr(tmpret);
- memcpy(*ret, tmpret, FILENAME_MAX);
+ memcpy(ret, tmpret, FILENAME_MAX);
xfree(&tmp);
xfree(&tmpret);
xfree(&name);
@@ -927,7 +886,9 @@ stat(char *path, struct stat *sb)
char *ppath;
short ret;
- ppath = xstrdup(path, "stat");
+ ppath = xstrdup(path);
+ if (ppath == NULL)
+ return -1;
CtoPstr(ppath);
ret = FStat((unsigned char *)ppath, sb);
xfree(&ppath);
@@ -960,7 +921,6 @@ bool
FIsDir(Str255 path)
{
struct stat st;
- short ret;
if (FStat(path, &st) != 0)
return false;
@@ -1070,7 +1030,9 @@ copy_file_contents(short source_ref, short dest_ref)
if (error)
return error;
- buf = xmalloc(1024, "copy_file_contents");
+ buf = xmalloc(1024);
+ if (buf == NULL)
+ return -1;
while (source_size > 0) {
count = 1024;
@@ -1233,6 +1195,10 @@ DrawGrowIconOnly(WindowPtr win)
RgnHandle tmp;
GetClip(tmp = NewRgn());
+ if (tmp == NULL) {
+ warn("NewRgn() failed");
+ return;
+ }
r = win->portRect;
r.top = r.bottom - SCROLLBAR_WIDTH;
r.left = r.right - SCROLLBAR_WIDTH + 1;
@@ -1760,9 +1726,8 @@ static int nullio(FILE *fp, int i);
int
bounded_vfprintf(FILE *fp, const char *fmt, va_list arg)
{
- register int c, i, j, nwritten = 0;
+ register int c, i, nwritten = 0;
register unsigned long n;
- long double x;
register char *s;
#define VFPRINTF_BUFLEN 512
char buf[VFPRINTF_BUFLEN], *digits, *t;
@@ -1983,7 +1948,7 @@ conv: switch (c) {
else {
if (!F.havePrecision)
i = strlen(s);
- else if (t = memchr(s, '\0', F.precision))
+ else if ((t = memchr(s, '\0', F.precision)) != NULL)
i = t - s;
else
i = F.precision;
--- util.h Wed Sep 7 14:31:37 2022
+++ util.h Mon Mar 27 21:33:13 2023
@@ -34,15 +34,6 @@
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define BOUND(a, min, max) ((a) > (max) ? (max) : ((a) < (min) ? (min) : (a)))
-#define EXPAND_TO_FIT(var, var_size, used_size, add, grow_amount) { \
- if ((used_size) + (add) >= (var_size)) { \
- while ((used_size) + (add) >= (var_size)) { \
- (var_size) += (grow_amount); \
- } \
- (var) = xrealloc((var), (var_size)); \
- } \
-}
-
#define CHARS_TO_LONG(a,b,c,d) (unsigned long)(\
((unsigned long)((unsigned char)(a)) << 24) | \
((unsigned long)((unsigned char)(b)) << 16) | \
@@ -89,16 +80,19 @@ struct stat {
void util_init(void);
-void * xmalloc(size_t, char *note);
+void * xmalloc(size_t);
void xfree(void *ptrptr);
void xfree_verify(void);
-void * xmalloczero(size_t, char *note);
-void * xcalloc(size_t, size_t, char *note);
+void * xmalloczero(size_t);
+void * xcalloc(size_t, size_t);
void * xrealloc(void *src, size_t size);
void * xreallocarray(void *, size_t, size_t);
-char * xstrdup(const char *, char *note);
-char * xstrndup(const char *str, size_t maxlen, char *note);
+char * xstrdup(const char *);
+char * xstrndup(const char *str, size_t maxlen);
+bool grow_to_fit(void *var, size_t *var_size, size_t used_size, size_t add,
+ size_t grow_amount);
+
short getline(char *str, size_t len, char **ret);
const char * ordinal(unsigned short n);
size_t rtrim(char *str, char *chars);
@@ -120,16 +114,17 @@ void about(char *program_name);
void progress(char *format, ...);
void window_rect(WindowPtr win, Rect *ret);
void center_in_screen(short width, short height, bool titlebar, Rect *b);
-Point centered_sf_dialog(void);
+Point centered_sfget_dialog(void);
+Point centered_sfput_dialog(void);
Handle xNewHandle(size_t size);
Handle xGetResource(ResType type, short id);
StringHandle xGetString(short id);
char * xGetStringAsChar(short id);
-long xGetStringAsLong(short id);
-void xSetHandleSize(Handle h, Size s);
+bool xGetStringAsLong(short id, long *ret);
+bool xSetHandleSize(Handle h, Size s);
-short getpath(short vRefNum, Str255 fileName, Str255 *ret, bool include_file);
+short getpath(short vRefNum, Str255 fileName, Str255 ret, bool include_file);
bool FIsDir(Str255 path);
short stat(char *path, struct stat *sb);
short FStat(Str255 path, struct stat *sb);