jcs
/amend
/amendments
/41
util: Lots of changes from other projects
Make all filesystem functions work on Str255s for filenames, not
        char *s
        Make vwarn() (and new progress() function) use new hard-coded DITLs
        to avoid needing to have these in every project's resource fork
        Use panic() instead of err(1, ...)
    jcs made amendment 41 over 3 years ago
--- util.c	Thu Dec 30 16:39:45 2021
+++ util.c	Mon Jan 10 22:12:47 2022
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021 joshua stein <jcs@jcs.org>
+ * Copyright (c) 2020-2022 joshua stein <jcs@jcs.org>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -22,18 +22,38 @@
 #include "util.h"
 
 /* ALRT resources */
-#define ERROR_ALERT_ID 129
 #define ASK_ALERT_ID 130
 
-#define ERROR_STRING_SIZE 1024
+#define ERROR_STRING_SIZE	1024
+static char err_str[ERROR_STRING_SIZE];
 
+/* basic DITL with an ok button (1), text area (2), and icon (3) */
+#define ALERT_DITL_ICON		3
+static char alert_ditl[] = {
+	0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+	0x00, 0xE6, 0x00, 0x5A, 0x01, 0x20, 0x04, 0x02,
+	0x4F, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,
+	0x00, 0x32, 0x00, 0x40, 0x01, 0x21, 0x08, 0x02,
+	0x5E, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,
+	0x00, 0x0A, 0x00, 0x2A, 0x00, 0x2A, 0xA0, 0x02,
+	0x00, 0x02
+};
+static Handle alert_ditl_h = NULL;
+
+static char progress_ditl[] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
+	0x00, 0x1E, 0x00, 0x32, 0x01, 0x3B, 0x08, 0x02,
+	0x5E, 0x30
+};
+static Handle progress_ditl_h = NULL;
+static DialogPtr progress_dialog = NULL;
+
 enum {
 	STOP_ALERT,
 	CAUTION_ALERT,
 	NOTE_ALERT
 };
 
-Handle err_str;
 static TEHandle track_control_te = NULL;
 
 void vwarn(short alert_func, const char *format, va_list ap);
@@ -48,10 +68,10 @@ xmalloc(size_t size)
 	void *ptr;
 
 	if (size == 0)
-		err(2, "xmalloc: zero size");
+		panic("xmalloc: zero size");
 	ptr = malloc(size);
 	if (ptr == NULL)
-		err(2, "xmalloc: allocating %zu bytes", size);
+		panic("xmalloc: allocating %zu bytes", size);
 	return ptr;
 }
 
@@ -70,7 +90,7 @@ xcalloc(size_t nmemb, size_t size)
 
 	ptr = calloc(nmemb, size);
 	if (ptr == NULL)
-		err(2, "xcalloc: allocating %zu * %zu bytes", nmemb, size);
+		panic("xcalloc: allocating %zu * %zu bytes", nmemb, size);
 	return ptr;
 }
 
@@ -81,25 +101,30 @@ xrealloc(void *src, size_t size)
 	
 	ret = realloc(src, size);
 	if (ret == NULL)
-		err(2, "Couldn't realloc %lu bytes of memory", size);
+		panic("Couldn't realloc %lu bytes of memory", size);
 	return ret;
 }
 
 #define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
 
 void *
+xmallocarray(size_t nmemb, size_t size)
+{
+	if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
+	  nmemb > 0 && SIZE_MAX / nmemb < size)
+		panic("xmallocarray");
+	return xmalloc(size * nmemb);
+}
+
+void *
 xreallocarray(void *optr, size_t nmemb, size_t size)
 {
 	void *new_ptr;
 	
 	if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
-	  nmemb > 0 && SIZE_MAX / nmemb < size) {
-		err(2, "reallocarray");
-	}
-	if ((new_ptr = realloc(optr, size * nmemb)) == NULL)
-		err(2, "realloc");
-	
-	return new_ptr;
+	  nmemb > 0 && SIZE_MAX / nmemb < size)
+		panic("xreallocarray");
+	return xrealloc(optr, size * nmemb);
 }
 
 char *
@@ -111,8 +136,7 @@ xstrdup(const char *str)
 	len = strlen(str);
 	
 	cp = xmalloc(len + 1);
-	strncpy(cp, str, len);
-	cp[len] = '\0';
+	strlcpy(cp, str, len + 1);
 	
 	return cp;
 }
@@ -139,48 +163,103 @@ getline(char *str, size_t len, char **ret)
 	return 0;
 }
 
-/*
- * BSD err(3) and warn(3) functions, must call err_init() before using
- */
- 
-void
-err_init(void)
+const char *
+ordinal(unsigned short n)
 {
-	if (!(err_str = NewHandle(ERROR_STRING_SIZE))) {
-		SysBeep(20);
-		ExitToShell();
+	switch (n % 100) {
+	case 11:
+	case 12:
+	case 13:
+		return "th";
+	default:
+		switch (n % 10) {
+		case 1:
+			return "st";
+		case 2:
+			return "nd";
+		case 3:
+			return "rd";
+		default:
+			return "th";
+		}
 	}
 }
 
+static char ostype_s[5];
+
+char *
+OSTypeToString(OSType type)
+{
+	ostype_s[0] = (unsigned char)((type >> 24) & 0xff);
+	ostype_s[1] = (unsigned char)((type >> 16) & 0xff);
+	ostype_s[2] = (unsigned char)((type >> 8) & 0xff);
+	ostype_s[3] = (unsigned char)(type & 0xff);
+	ostype_s[4] = 0;
+	
+	return ostype_s;
+}
+
+/*
+ * BSD err(3) and warn(3) functions
+ */
+
 void
 vwarn(short alert_func, const char *format, va_list ap)
 {
-	size_t len;
-	short quit = 0;
-	WindowPtr win;
+	Rect bounds, irect;
+	short quit = 0, height, width, hit;
+	WindowPtr win, dialog;
+	OSType itype;
+	Handle ihandle;
 	
 	GetPort(&win);
 
-	HLock(err_str);
-	len = vsprintf(*err_str, format, ap);
-	if (len >= ERROR_STRING_SIZE) {
-		sprintf(*err_str, "raise_error string overflow!");
-		quit = 1;
-	}
+	vsnprintf(err_str, ERROR_STRING_SIZE, format, ap);
 
-	ParamText(CtoPstr(*err_str), "\p", "\p", "\p");
+	width = 300;
+	height = 100;
+	bounds.left = (screenBits.bounds.right - width) / 2;
+	bounds.right = bounds.left + width;
+	bounds.top = GetMBarHeight() +
+	  ((screenBits.bounds.bottom - height) / 2.5);
+	bounds.bottom = bounds.top + height;
+	
+	ParamText(CtoPstr(err_str), "\p", "\p", "\p");
+
+	alert_ditl_h = xNewHandle(sizeof(alert_ditl));
+	HLock(alert_ditl_h);
+	memcpy(*alert_ditl_h, alert_ditl, sizeof(alert_ditl));
+	HUnlock(alert_ditl_h);
+
+	dialog = NewDialog(nil, &bounds, "\p", false, dBoxProc,
+	  (WindowPtr)-1L, false, 0, alert_ditl_h);
+	  
+#if 0
+	/* XXX: why doesn't changing this work? */
+	GetDItem(dialog, ALERT_DITL_ICON, &itype, &ihandle, &irect);
 	switch (alert_func) {
 	case CAUTION_ALERT:
-		CautionAlert(ERROR_ALERT_ID, nil);
+		ihandle = GetIcon(cautionIcon);
 		break;
 	case NOTE_ALERT:
-		NoteAlert(ERROR_ALERT_ID, nil);
+		ihandle = GetIcon(noteIcon);
 		break;
 	default:
-		StopAlert(ERROR_ALERT_ID, nil);
+		ihandle = GetIcon(stopIcon);
 	}
-	HUnlock(err_str);
-	
+	ihandle = GetIcon(cautionIcon);
+	SetDItem(dialog, ALERT_DITL_ICON, itype, ihandle, &irect);
+#endif
+
+	ShowWindow(dialog);
+	for (;;) {
+		ModalDialog(0, &hit);
+		if (hit == ok)
+			break;
+	}
+	DisposDialog(dialog);
+	DisposHandle(alert_ditl_h);
+
 	SetPort(win);
 	
 	if (quit)
@@ -188,35 +267,47 @@ vwarn(short alert_func, const char *format, va_list ap
 }
 
 void
-warn(const char *format, ...)
+panic(const char *format, ...)
 {
 	va_list ap;
 
 	va_start(ap, format);
-	vwarn(CAUTION_ALERT, format, ap);
+	vwarn(STOP_ALERT, format, ap);
 	va_end(ap);
+	
+	ExitToShell();
 }
 
 void
-warnx(const char *format, ...)
+err(short ret, const char *format, ...)
 {
 	va_list ap;
 
 	va_start(ap, format);
+	vwarn(STOP_ALERT, format, ap);
+	va_end(ap);
+	
+	ExitToShell();
+}
+
+void
+warn(const char *format, ...)
+{
+	va_list ap;
+
+	va_start(ap, format);
 	vwarn(CAUTION_ALERT, format, ap);
 	va_end(ap);
 }
 
 void
-err(short retcode, const char *format, ...)
+warnx(const char *format, ...)
 {
 	va_list ap;
 
 	va_start(ap, format);
-	vwarn(STOP_ALERT, format, ap);
+	vwarn(CAUTION_ALERT, format, ap);
 	va_end(ap);
-	
-	ExitToShell();
 }
 
 void
@@ -239,34 +330,94 @@ ask(const char *format, ...)
 
 	GetPort(&win);
 
-	HLock(err_str);
 	va_start(ap, format);
-	len = vsprintf(*err_str, format, ap);
+	len = vsnprintf(err_str, ERROR_STRING_SIZE, format, ap);
 	va_end(ap);
-	if (len >= ERROR_STRING_SIZE)
-		err(1, "ask string overflow!");
 
-	ParamText(CtoPstr(*err_str), "\p", "\p", "\p");
+	ParamText(CtoPstr(err_str), "\p", "\p", "\p");
 	ret = StopAlert(ASK_ALERT_ID, nil);
-	HUnlock(err_str);
 	
 	SetPort(win);
 	return ret;
 }
 
+void
+progress(char *format, ...)
+{
+	static Str255 progress_s;
+	Handle thandle;
+	va_list argptr;
+	Rect bounds = { 100, 90, 160, 420 }; /* tlbr */
+	Rect trect;
+	static WindowPtr progress_win;
+	short ttype;
 
+	if (format == NULL) {
+		if (progress_dialog != NULL) {
+			DisposDialog(progress_dialog);
+			DisposHandle(progress_ditl_h);
+			progress_dialog = NULL;
+		}
+		SetPort(progress_win);
+		return;
+	}
+		
+	va_start(argptr, format);
+	vsnprintf((char *)progress_s, 256, format, argptr);
+	va_end(argptr);
+	CtoPstr(progress_s);
+	
+	if (progress_dialog == NULL) {
+		GetPort(&progress_win);
+	
+		progress_ditl_h = xNewHandle(sizeof(progress_ditl));
+		HLock(progress_ditl_h);
+		memcpy(*progress_ditl_h, progress_ditl, sizeof(progress_ditl));
+		HUnlock(progress_ditl_h);
+	
+		progress_dialog = NewDialog(nil, &bounds, "\p", false, dBoxProc,
+		  (WindowPtr)-1L, false, 0, progress_ditl_h);
+	}
+	
+	GetDItem(progress_dialog, 1, &ttype, &thandle, &trect);
+	SetIText(thandle, progress_s);
+	
+	ShowWindow(progress_dialog);
+	DrawDialog(progress_dialog);
+}
+
 /*
+ * General Mac-specific non-GUI functions
+ */
+static unsigned long _xorshift_state = 0;
+unsigned long
+xorshift32(void)
+{
+	unsigned long x = _xorshift_state;
+	if (x == 0)
+		x = Ticks;
+	x ^= x << 13;
+	x ^= x >> 17;
+	x ^= x << 5;
+	return _xorshift_state = x;
+}
+
+
+/*
  * Error checking wrappers for Mac toolkit functions
  */
  
 Handle
-xNewHandle(unsigned long size)
+xNewHandle(size_t size)
 {
 	Handle h;
 	
+	if (size == 0)
+		panic("Zero xNewHandle size");
+
 	h = NewHandle(size);
 	if (h == NULL)
-		err(1, "Failed to NewHandle(%lu)", size);
+		panic("Failed to NewHandle(%lu)", size);
 	
 	return h;
 }
@@ -278,7 +429,7 @@ xGetResource(ResType type, short id)
 	
 	h = GetResource(type, id);
 	if (h == NULL)
-		err(1, "Failed to find resource %d", id);
+		panic("Failed to find resource %d", id);
 	
 	return h;
 }
@@ -290,7 +441,7 @@ xGetString(short id)
 	
 	h = GetString(id);
 	if (h == NULL)
-		err(1, "Failed to find STR resource %d", id);
+		panic("Failed to find STR resource %d", id);
 	
 	return h;
 }
@@ -325,84 +476,27 @@ xGetStringAsLong(short id)
 	return r;
 }
 
+void
+xSetHandleSize(Handle h, Size s)
+{
+	SetHandleSize(h, s);
+	if (MemError())
+		panic("Failed to SetHandleSize to %ld", s);
+}
+
 /*
  * Filesystem utilities
  */
  
-/*
- * With SFGetFile, when the user has a folder selected and clicks Open,
- * File Manager will change to the folder and expect the user to select a
- * file in it.  This triggers sfHookOpenFolder, but when the user double-
- * clicks on a folder to browse into it, the same result code is returned.
- *
- * To be able to return the folder itself, we need to know whether the user
- * double-clicked a folder, or clicked Open.  When we get our hook callback,
- * we check where the mouse is in relation to the Open button rect.  If
- * the user clicked Open, we return the folder itself, otherwise we assume
- * the user double-clicked a folder and we should browse into it.
- *
- * Finally, we return the full path of the file/folder as a char *, rather
- * than just a ref id.
- */
-char *
-askfileordirpath(void)
-{
-	Point pt = { 75, 75 };
-	SFReply reply;
-	HParamBlockRec hpbr;
-	Str63 fName = { 0 };
-	char *ret = NULL;
-	
-	SFGetFile(pt, "\p", NULL, -1, 0, open_dialog_hook, &reply);
-	if (!reply.good)
-		return NULL;
-		
-	if (reply.fName[0] == 0) {
-		/* selected a folder, look it up */
-		hpbr.fileParam.ioCompletion = 0;
-		hpbr.fileParam.ioNamePtr = (StringPtr)&fName;
-		hpbr.fileParam.ioVRefNum = reply.vRefNum;
-		hpbr.fileParam.ioDirID = reply.fType;
-		hpbr.fileParam.ioFDirIndex = -1;
-		PBGetCatInfo(&hpbr, false);
-		memcpy(reply.fName, fName, sizeof(fName));
-	}
-	
-	getpath(reply.vRefNum, reply.fName, &ret, true);
-	
-	return ret;
-}
-
-pascal short
-open_dialog_hook(short theItem, DialogPtr theDialog)
-{
-	short item_type;
-	Handle item;
-	Rect item_rect;
-	Point mouse;
-	
-	if (theItem == sfHookOpenFolder) {
-		GetDItem(theDialog, getOpen, &item_type, &item, &item_rect);
-		GetMouse(&mouse);
-		
-		if (PtInRect(mouse, &item_rect)) {
-			/* clicked open */
-			return getOpen;
-		}
-	}
-	
-	return theItem;
-}
-
 short
-getpath(short vRefNum, Str255 fileName, char **ret, bool include_file)
+getpath(short vRefNum, Str255 fileName, Str255 *ret, bool include_file)
 {
 	WDPBRec wdir;
 	HVolumeParam wvol;
 	DirInfo wcinfo;
 	Str255 name;
-	size_t retlen = 0;
-	char *tmp;
+	size_t retlen = 0, len;
+	char tmpret[256], tmp[256];
 	
 	wdir.ioVRefNum = wdir.ioWDVRefNum = vRefNum;
 	wdir.ioWDIndex = 0;
@@ -440,17 +534,14 @@ getpath(short vRefNum, Str255 fileName, char **ret, bo
 		if (PBGetCatInfo((CInfoPBPtr)&wcinfo, 0) != noErr)
 			break;
 		
+		len = name[0];
+		PtoCstr(name);
 		if (retlen == 0) {
-			retlen = name[0];
-			*ret = xmalloc(retlen + 1);
-			sprintf(*ret, "%s", PtoCstr(name));
+			retlen = len;
+			strlcpy(tmpret, (char *)name, sizeof(tmpret));
 		} else {
-			tmp = xstrdup(*ret);
-			free(*ret);
-			*ret = xmalloc(retlen + 1 + name[0] + 1);
-			retlen += 1 + name[0];
-			sprintf(*ret, "%s:%s", PtoCstr(name), tmp);
-			free(tmp);
+			strlcpy(tmp, tmpret, sizeof(tmp));
+			snprintf(tmpret, sizeof(tmpret), "%s:%s", name, tmp);
 		}
 	}
 	
@@ -459,31 +550,44 @@ getpath(short vRefNum, Str255 fileName, char **ret, bo
 		memcpy(name, fileName, sizeof(name));
 		PtoCstr(name);
 		if (retlen == 0)
-			*ret = xstrdup((char *)name);
+			strlcpy(tmpret, (char *)name, sizeof(tmpret));
 		else {
-			*ret = xrealloc(*ret, retlen + 1 + fileName[0] + 1);
-			sprintf(*ret + retlen, ":%s", (char *)name);
+			strlcat(tmpret, ":", sizeof(tmpret));
+			strlcat(tmpret, (char *)name, sizeof(tmpret));
 		}
 	} else if (retlen == 0) {
-		*ret = NULL;
+		(*ret)[0] = 0;
+		return 0;
 	}
 	
+	CtoPstr(tmpret);
+	memcpy(*ret, tmpret, sizeof(tmpret));
+	
 	return 0;
 }
 
 short
-stat(const char *path, struct stat *sb)
+stat(char *path, struct stat *sb)
 {
-	CInfoPBRec catblock = { 0 };
+	char *ppath;
 	short ret;
-	char *tpath;
 	
-	tpath = xstrdup(path);
-	CtoPstr(tpath);
+	ppath = xstrdup(path);
+	CtoPstr(ppath);
+	ret = FStat((unsigned char *)ppath, sb);
+	free(ppath);
+	
+	return ret;
+}
 
-	catblock.hFileInfo.ioNamePtr = (StringPtr)tpath;
+short
+FStat(Str255 path, struct stat *sb)
+{
+	CInfoPBRec catblock = { 0 };
+	short ret;
+
+	catblock.hFileInfo.ioNamePtr = path;
 	ret = PBGetCatInfo(&catblock, 0);
-	free(tpath);
 	if (ret != noErr)
 		return -1;
 	
@@ -498,12 +602,12 @@ stat(const char *path, struct stat *sb)
 }
 
 bool
-is_dir(char *path)
+FIsDir(Str255 path)
 {
 	struct stat st;
 	short ret;
 	
-	if ((ret = stat(path, &st)) != 0)
+	if ((ret = FStat(path, &st)) != 0)
 		return ret;
 
 	/* bit 4 is set in ioFlAttrib if the item is a directory */
@@ -514,10 +618,10 @@ is_dir(char *path)
 }
 
 OSErr
-copy_file(Str255 source, Str255 dest, bool overwrite,
-  bool keep_source_open)
+copy_file(Str255 source, Str255 dest, bool overwrite)
 {
 	FInfo fi;
+	IOParam pb;
 	short error, source_ref, dest_ref;
 	
 	/* copy data fork */
@@ -536,21 +640,23 @@ copy_file(Str255 source, Str255 dest, bool overwrite,
 	if (error)
 		return error;
 	
-	error = FSOpen(source, 0, &source_ref);
+	memset(&pb, 0, sizeof(pb));
+	pb.ioNamePtr = source;
+	pb.ioPermssn = fsRdPerm;
+	error = PBOpen(&pb, false);
 	if (error)
 		return error;
-		
+	source_ref = pb.ioRefNum;
+	
 	error = FSOpen(dest, 0, &dest_ref);
 	if (error) {
-		if (!keep_source_open)
-			FSClose(source_ref);
+		FSClose(source_ref);
 		return error;
 	}
 
 	error = copy_file_contents(source_ref, dest_ref);
 	
-	if (!keep_source_open)
-		FSClose(source_ref);
+	FSClose(source_ref);
 	FSClose(dest_ref);
 	
 	if (error)
@@ -561,26 +667,31 @@ copy_file(Str255 source, Str255 dest, bool overwrite,
 	 * an open resource file.
 	 */
 	source_ref = OpenRFPerm(source, 0, fsRdWrShPerm);
+	
+	if (source_ref == -1 && ResError() == eofErr) {
+		/* no resource fork */
+		FSClose(source_ref);
+		FSClose(dest_ref);
+		return 0;
+	}
+	
 	if (source_ref == -1)
 		return ResError();
 
 	CreateResFile(dest);
 	if (ResError()) {
-		if (!keep_source_open)
-			FSClose(source_ref);
+		FSClose(source_ref);
 		return ResError();
 	}
 	error = OpenRF(dest, 0, &dest_ref);
 	if (error) {
-		if (!keep_source_open)
-			FSClose(source_ref);
+		FSClose(source_ref);
 		return error;
 	}
 	
 	error = copy_file_contents(source_ref, dest_ref);
 	
-	if (!keep_source_open)
-		FSClose(source_ref);
+	FSClose(source_ref);
 	FSClose(dest_ref);
 	
 	return error;
@@ -589,7 +700,7 @@ copy_file(Str255 source, Str255 dest, bool overwrite,
 OSErr
 copy_file_contents(short source_ref, short dest_ref)
 {
-	char buf[512];
+	char buf[1024];
 	short error;
 	long source_size, count;
 	
@@ -651,6 +762,7 @@ FSReadLine(short frefnum, char *buf, size_t buflen)
 	return total_read;
 }
 
+
 /*
  * General Mac-specific GUI functions
  */
@@ -751,7 +863,7 @@ TrackMouseDownInControl(ControlHandle control, short p
 	short page, val, adj, lheight;
 	
 	if (track_control_te == NULL)
-		err(1, "TrackMouseDownInControl without SetTrackControlTE");
+		panic("TrackMouseDownInControl without SetTrackControlTE");
 	
 	lheight = TEGetHeight(0, 0, track_control_te);
 
--- util.h	Thu Dec 30 16:24:50 2021
+++ util.h	Mon Jan 10 16:40:54 2022
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021 joshua stein <jcs@jcs.org>
+ * Copyright (c) 2020-2022 joshua stein <jcs@jcs.org>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -25,12 +25,19 @@
 #define SIZE_MAX ULONG_MAX
 #endif
 
+#define nitems(what) (sizeof((what)) / sizeof((what)[0]))
+
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#define BOUND(a, min, max) ((a) > (max) ? (max) : ((a) < (min) ? (min) : (a)))
+
 #define SCROLLBAR_WIDTH 16
 
+/* GetMBarHeight() is not very useful */
+#define MENUBAR_HEIGHT 20
+
 #define MAX_TEXTEDIT_SIZE 32767L
 
-#define nitems(what) (sizeof((what)) / sizeof((what)[0]))
-
 #ifndef bool
 typedef Boolean bool;
 #endif
@@ -57,43 +64,43 @@ void *xmalloc(size_t);
 void *xmalloczero(size_t);
 void *xcalloc(size_t, size_t);
 void *xrealloc(void *src, size_t size);
+void *xmallocarray(size_t nmemb, size_t size);
 void *xreallocarray(void *, size_t, size_t);
 char *xstrdup(const char *);
 
 short getline(char *str, size_t len, char **ret);
-/* from strnatcmp.c */
-int strnatcmp(char const *a, char const *b);
-int strnatcasecmp(char const *a, char const *b);
+size_t strlcpy(char *dst, const char *src, size_t dsize);
+size_t strlcat(char *dst, const char *src, size_t dsize);
+const char *ordinal(unsigned short n);
+char *OSTypeToString(OSType type);
 
-void err_init(void);
+unsigned long xorshift32(void);
+
+void panic(const char *format, ...);
+void err(short ret, const char *format, ...);
 void warnx(const char *format, ...);
 void warn(const char *format, ...);
-void err(short retcode, const char *format, ...);
 void note(const char *format, ...);
 short ask(const char *format, ...);
 #define ASK_YES 1
 #define ASK_NO  2
+void progress(char *format, ...);
 
-Handle xNewHandle(unsigned long size);
+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);
 
-char *askfileordirpath(void);
-short getpath(short vRefNum, Str255 fileName, char **ret,
+short getpath(short vRefNum, Str255 fileName, Str255 *ret,
   bool include_file);
-pascal short open_dialog_hook(short theItem, DialogPtr theDialog);
-pascal Boolean open_dialog_filter(DialogPtr theDialog,
-  EventRecord *theEvent, short *itemHit);
-bool is_dir(char *path);
-short stat(const char *path, struct stat *sb);
-OSErr copy_file(Str255 source, Str255 dest, bool overwrite,
-  bool keep_source_open);
+bool FIsDir(Str255 path);
+short stat(char *path, struct stat *sb);
+short FStat(Str255 path, struct stat *sb);
+OSErr copy_file(Str255 source, Str255 dest, bool overwrite);
 OSErr copy_file_contents(short source_ref, short dest_ref);
 OSErr FSReadLine(short frefnum, char *buf, size_t buflen);
-
-Handle SetResSize(Handle res, size_t size);
 
 short FontHeight(short font_id, short size);
 void DrawGrowIconOnly(WindowPtr win);