/* * Copyright (c) 2020-2022 joshua stein * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef __UTIL_H__ #define __UTIL_H__ #include #include #include #ifndef SIZE_MAX #define SIZE_MAX ULONG_MAX #endif #define nitems(what) (sizeof((what)) / sizeof((what)[0])) #define member_size(type, member) sizeof(((type *)0)->member) #define MALLOC_NOTE_SIZE 32 #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))) /* * If var of var_size (of which used_size is used) is not big enough to * hold add, expand it by grow_amount (to give headroom for subsequent * expansion). */ #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) | \ ((unsigned long)((unsigned char)(c)) << 8) | \ (unsigned long)((unsigned char)(d)) ) #define CHARS_TO_SHORT(a,b) (unsigned short)(\ ((unsigned short)((unsigned char)(a)) << 8) | \ (unsigned short)((unsigned char)(b)) ) #define SCROLLBAR_WIDTH 16 /* GetMBarHeight() is not very useful */ #define MENUBAR_HEIGHT 20 #define TICKS_PER_SEC 60L #define MAX_TEXTEDIT_SIZE 32767L #ifndef bool typedef Boolean bool; #endif typedef signed long off_t; typedef signed long ssize_t; typedef unsigned char u_char; typedef unsigned long u_int; typedef unsigned char u_int8_t; typedef unsigned short u_int16_t; typedef unsigned long u_int32_t; #define BYTE_ORDER BIG_ENDIAN /* singly-linked lists */ #define SLIST_HEAD(name, type) struct name { struct type *slh_first; } #define SLIST_HEAD_INITIALIZER(head) { NULL } #define SLIST_ENTRY(type) struct { struct type *sle_next; } #define SLIST_FIRST(head) ((head)->slh_first) #define SLIST_END(head) NULL #define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head)) #define SLIST_NEXT(elm, field) ((elm)->field.sle_next) #define SLIST_INIT(head) do { SLIST_FIRST((head)) = NULL; } while (0) #define SLIST_FOREACH(var, head, field) \ for ((var) = SLIST_FIRST(head); \ (var) != SLIST_END(head); \ (var) = SLIST_NEXT(var, field)) #define SLIST_FOREACH_SAFE(var, head, field, tvar) \ for ((var) = SLIST_FIRST(head); \ (var) && ((tvar) = SLIST_NEXT(var, field), 1); \ (var) = (tvar)) #define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ (elm)->field.sle_next = (slistelm)->field.sle_next; \ (slistelm)->field.sle_next = (elm); \ } while (0) #define SLIST_INSERT_HEAD(head, elm, field) do { \ (elm)->field.sle_next = (head)->slh_first; \ (head)->slh_first = (elm); \ } while (0) #define SLIST_APPEND(head, elm, type, field) do { \ if (SLIST_EMPTY(head)) { \ SLIST_INSERT_HEAD(head, elm, field); \ } else { \ struct type *curelm = (head)->slh_first; \ while (curelm->field.sle_next != NULL) \ curelm = curelm->field.sle_next; \ curelm->field.sle_next = (elm); \ } \ } while (0) #define SLIST_REMOVE_AFTER(elm, field) do { \ (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \ } while (0) #define SLIST_REMOVE_HEAD(head, field) do { \ (head)->slh_first = (head)->slh_first->field.sle_next; \ } while (0) #define SLIST_REMOVE(head, elm, type, field) do { \ if ((head)->slh_first == (elm)) { \ SLIST_REMOVE_HEAD((head), field); \ } else { \ struct type *curelm = (head)->slh_first; \ while (curelm->field.sle_next != (elm)) \ curelm = curelm->field.sle_next; \ curelm->field.sle_next = curelm->field.sle_next->field.sle_next; \ } \ (elm)->field.sle_next = NULL; \ } while (0) typedef struct { short push[2], rts; void *addr; } tCodeStub; struct stat { short st_mode; ssize_t st_size; time_t st_ctime; time_t st_mtime; unsigned char st_flags; }; void util_init(void); void * xmalloc(size_t, char *note); void xfree(void *ptrptr); void xfree_verify(void); void * xmalloczero(size_t, char *note); void * xcalloc(size_t, size_t, char *note); 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); short getline(char *str, size_t len, char **ret); const char * ordinal(unsigned short n); size_t rtrim(char *str, char *chars); long strpos_quoted(char *str, char c); char * OSTypeToString(OSType type); 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 note(const char *format, ...); void appicon_note(const char *format, ...); short ask(const char *format, ...); #define ASK_YES 1 #define ASK_NO 2 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); 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); 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); 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); char * gestalt_machine_type(void); char * get_version(bool long_version); short FontHeight(short font_id, short size); void DrawGrowIconOnly(WindowPtr win); short TEGetWidth(short off, TEHandle te); void UpdateScrollbarForTE(GrafPtr win, ControlHandle scroller, TEHandle te, bool reset); void SetTrackControlTE(TEHandle te); pascal void TrackMouseDownInControl(ControlHandle control, short part); pascal bool ModalDialogFilter(DialogPtr dlg, EventRecord *event, short *hit); void PasswordDialogFieldFilterSetup(short ditl_id, char *storage, size_t len); pascal bool PasswordDialogFieldFilter(DialogPtr dlg, EventRecord *event, short *hit); void PasswordDialogFieldFinish(void); pascal void NullCaretHook(void); void HideMenuBar(void); void RestoreHiddenMenuBar(void); size_t strlcat(char *dst, const char *src, size_t dsize); size_t strlcpy(char *dst, const char *src, size_t dsize); char * strndup(const char *str, size_t maxlen); char * strsep(char **stringp, const char *delim); int snprintf(char *s, size_t size, const char *fmt, ...); int vsnprintf(char *s, size_t size, const char *fmt, void *p); short strcasecmp(const char *s1, const char *s2); short strncasecmp(const char *s1, const char *s2, size_t n); #endif