| 1 | 
      /* | 
    
    
      | 2 | 
       * Copyright (c) 2020-2022 joshua stein <jcs@jcs.org> | 
    
    
      | 3 | 
       * | 
    
    
      | 4 | 
       * Permission to use, copy, modify, and distribute this software for any | 
    
    
      | 5 | 
       * purpose with or without fee is hereby granted, provided that the above | 
    
    
      | 6 | 
       * copyright notice and this permission notice appear in all copies. | 
    
    
      | 7 | 
       * | 
    
    
      | 8 | 
       * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | 
    
    
      | 9 | 
       * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | 
    
    
      | 10 | 
       * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | 
    
    
      | 11 | 
       * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | 
    
    
      | 12 | 
       * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | 
    
    
      | 13 | 
       * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | 
    
    
      | 14 | 
       * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 
    
    
      | 15 | 
       */ | 
    
    
      | 16 | 
       | 
    
    
      | 17 | 
      #ifndef __UTIL_H__ | 
    
    
      | 18 | 
      #define __UTIL_H__ | 
    
    
      | 19 | 
       | 
    
    
      | 20 | 
      #include <stdlib.h> | 
    
    
      | 21 | 
      #include "stdint.h" | 
    
    
      | 22 | 
      #include <time.h> | 
    
    
      | 23 | 
       | 
    
    
      | 24 | 
      /* uncomment to enable malloc tracking */ | 
    
    
      | 25 | 
      //#define MALLOC_DEBUG | 
    
    
      | 26 | 
       | 
    
    
      | 27 | 
      #define nitems(what) (sizeof((what)) / sizeof((what)[0])) | 
    
    
      | 28 | 
      #define member_size(type, member) sizeof(((type *)0)->member) | 
    
    
      | 29 | 
       | 
    
    
      | 30 | 
      #define MIN(a, b) ((a) < (b) ? (a) : (b)) | 
    
    
      | 31 | 
      #define MAX(a, b) ((a) > (b) ? (a) : (b)) | 
    
    
      | 32 | 
      #define BOUND(a, min, max) ((a) > (max) ? (max) : ((a) < (min) ? (min) : (a))) | 
    
    
      | 33 | 
       | 
    
    
      | 34 | 
      #define EXPAND_TO_FIT(var, var_size, used_size, add, grow_amount) { \ | 
    
    
      | 35 | 
      	if ((used_size) + (add) >= (var_size)) { \ | 
    
    
      | 36 | 
      		while ((used_size) + (add) >= (var_size)) { \ | 
    
    
      | 37 | 
      			(var_size) += (grow_amount); \ | 
    
    
      | 38 | 
      		} \ | 
    
    
      | 39 | 
      		(var) = xrealloc((var), (var_size)); \ | 
    
    
      | 40 | 
      	} \ | 
    
    
      | 41 | 
      } | 
    
    
      | 42 | 
       | 
    
    
      | 43 | 
      #define BYTES_TO_LONG(a,b,c,d) (unsigned long)(\ | 
    
    
      | 44 | 
        ((unsigned long)((unsigned char)(a)) << 24) | \ | 
    
    
      | 45 | 
        ((unsigned long)((unsigned char)(b)) << 16) | \ | 
    
    
      | 46 | 
        ((unsigned long)((unsigned char)(c)) << 8) | \ | 
    
    
      | 47 | 
        (unsigned long)((unsigned char)(d)) ) | 
    
    
      | 48 | 
      #define BYTES_TO_SHORT(a,b) (unsigned short)(\ | 
    
    
      | 49 | 
        ((unsigned short)((unsigned char)(a)) << 8) | \ | 
    
    
      | 50 | 
        (unsigned short)((unsigned char)(b)) ) | 
    
    
      | 51 | 
       | 
    
    
      | 52 | 
      #define SCROLLBAR_WIDTH 16 | 
    
    
      | 53 | 
       | 
    
    
      | 54 | 
      /* GetMBarHeight() is not very useful */ | 
    
    
      | 55 | 
      #define MENUBAR_HEIGHT 20 | 
    
    
      | 56 | 
       | 
    
    
      | 57 | 
      #define TICKS_PER_SEC 60L | 
    
    
      | 58 | 
       | 
    
    
      | 59 | 
      #define MAX_TEXTEDIT_SIZE 32767L | 
    
    
      | 60 | 
       | 
    
    
      | 61 | 
      /* singly-linked lists */ | 
    
    
      | 62 | 
      #define SLIST_HEAD(name, type)	struct name { struct type *slh_first; } | 
    
    
      | 63 | 
      #define SLIST_HEAD_INITIALIZER(head) { NULL } | 
    
    
      | 64 | 
      #define SLIST_ENTRY(type)		struct { struct type *sle_next; } | 
    
    
      | 65 | 
      #define SLIST_FIRST(head)		((head)->slh_first) | 
    
    
      | 66 | 
      #define SLIST_END(head)			NULL | 
    
    
      | 67 | 
      #define SLIST_EMPTY(head)		(SLIST_FIRST(head) == SLIST_END(head)) | 
    
    
      | 68 | 
      #define SLIST_NEXT(elm, field)	((elm)->field.sle_next) | 
    
    
      | 69 | 
      #define SLIST_INIT(head)		do { SLIST_FIRST((head)) = NULL; } while (0) | 
    
    
      | 70 | 
      #define SLIST_FOREACH(var, head, field) \ | 
    
    
      | 71 | 
      	for ((var) = SLIST_FIRST(head); \ | 
    
    
      | 72 | 
      	  (var) != SLIST_END(head); \ | 
    
    
      | 73 | 
      	  (var) = SLIST_NEXT(var, field)) | 
    
    
      | 74 | 
       | 
    
    
      | 75 | 
      #define SLIST_FOREACH_SAFE(var, head, field, tvar) \ | 
    
    
      | 76 | 
      	for ((var) = SLIST_FIRST(head); \ | 
    
    
      | 77 | 
      	  (var) && ((tvar) = SLIST_NEXT(var, field), 1); \ | 
    
    
      | 78 | 
      	  (var) = (tvar)) | 
    
    
      | 79 | 
       | 
    
    
      | 80 | 
      #define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ | 
    
    
      | 81 | 
      	(elm)->field.sle_next = (slistelm)->field.sle_next; \ | 
    
    
      | 82 | 
      	(slistelm)->field.sle_next = (elm); \ | 
    
    
      | 83 | 
      } while (0) | 
    
    
      | 84 | 
       | 
    
    
      | 85 | 
      #define SLIST_INSERT_HEAD(head, elm, field) do { \ | 
    
    
      | 86 | 
      	(elm)->field.sle_next = (head)->slh_first; \ | 
    
    
      | 87 | 
      	(head)->slh_first = (elm); \ | 
    
    
      | 88 | 
      } while (0) | 
    
    
      | 89 | 
       | 
    
    
      | 90 | 
      #define SLIST_APPEND(head, elm, type, field) do { \ | 
    
    
      | 91 | 
      	if (SLIST_EMPTY(head)) { \ | 
    
    
      | 92 | 
      		SLIST_INSERT_HEAD(head, elm, field); \ | 
    
    
      | 93 | 
      	} else { \ | 
    
    
      | 94 | 
      		struct type *curelm = (head)->slh_first; \ | 
    
    
      | 95 | 
      		while (curelm->field.sle_next != NULL) \ | 
    
    
      | 96 | 
      			curelm = curelm->field.sle_next; \ | 
    
    
      | 97 | 
      		curelm->field.sle_next = (elm); \ | 
    
    
      | 98 | 
      	} \ | 
    
    
      | 99 | 
      } while (0) | 
    
    
      | 100 | 
       | 
    
    
      | 101 | 
      #define SLIST_REMOVE_AFTER(elm, field) do { \ | 
    
    
      | 102 | 
      	(elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \ | 
    
    
      | 103 | 
      } while (0) | 
    
    
      | 104 | 
       | 
    
    
      | 105 | 
      #define SLIST_REMOVE_HEAD(head, field) do { \ | 
    
    
      | 106 | 
      	(head)->slh_first = (head)->slh_first->field.sle_next; \ | 
    
    
      | 107 | 
      } while (0) | 
    
    
      | 108 | 
       | 
    
    
      | 109 | 
      #define SLIST_REMOVE(head, elm, type, field) do { \ | 
    
    
      | 110 | 
      	if ((head)->slh_first == (elm)) { \ | 
    
    
      | 111 | 
      		SLIST_REMOVE_HEAD((head), field); \ | 
    
    
      | 112 | 
      	} else { \ | 
    
    
      | 113 | 
      		struct type *curelm = (head)->slh_first; \ | 
    
    
      | 114 | 
      		while (curelm->field.sle_next != (elm)) \ | 
    
    
      | 115 | 
      			curelm = curelm->field.sle_next; \ | 
    
    
      | 116 | 
      		curelm->field.sle_next = curelm->field.sle_next->field.sle_next; \ | 
    
    
      | 117 | 
      	} \ | 
    
    
      | 118 | 
      	(elm)->field.sle_next = NULL; \ | 
    
    
      | 119 | 
      } while (0) | 
    
    
      | 120 | 
       | 
    
    
      | 121 | 
      typedef struct { | 
    
    
      | 122 | 
      	short push[2], rts; | 
    
    
      | 123 | 
      	void *addr; | 
    
    
      | 124 | 
      } tCodeStub; | 
    
    
      | 125 | 
       | 
    
    
      | 126 | 
      struct stat { | 
    
    
      | 127 | 
      	short	st_mode; | 
    
    
      | 128 | 
      	ssize_t	st_size; | 
    
    
      | 129 | 
      	time_t	st_ctime; | 
    
    
      | 130 | 
      	time_t	st_mtime; | 
    
    
      | 131 | 
      	unsigned char st_flags; | 
    
    
      | 132 | 
      }; | 
    
    
      | 133 | 
       | 
    
    
      | 134 | 
      void util_init(void); | 
    
    
      | 135 | 
       | 
    
    
      | 136 | 
      void * xmalloc(size_t); | 
    
    
      | 137 | 
      void xfree(void *ptrptr); | 
    
    
      | 138 | 
      void xfree_verify(void); | 
    
    
      | 139 | 
      void * xmalloczero(size_t); | 
    
    
      | 140 | 
      void * xcalloc(size_t, size_t); | 
    
    
      | 141 | 
      void * xrealloc(void *src, size_t size); | 
    
    
      | 142 | 
      void * xreallocarray(void *, size_t, size_t); | 
    
    
      | 143 | 
      char * xstrdup(const char *); | 
    
    
      | 144 | 
      char * xstrndup(const char *str, size_t maxlen); | 
    
    
      | 145 | 
      #ifdef MALLOC_DEBUG | 
    
    
      | 146 | 
      void xalloc_print(size_t (*printer)(const char *, ...)); | 
    
    
      | 147 | 
      #endif | 
    
    
      | 148 | 
       | 
    
    
      | 149 | 
      short getline(char *str, size_t len, char **ret); | 
    
    
      | 150 | 
      const char * ordinal(unsigned short n); | 
    
    
      | 151 | 
      size_t rtrim(char *str, char *chars); | 
    
    
      | 152 | 
      long strpos_quoted(char *str, char c); | 
    
    
      | 153 | 
      size_t hexify(unsigned char *input, size_t len, unsigned char *output); | 
    
    
      | 154 | 
      size_t unhexify(unsigned char *input, size_t len, unsigned char *output); | 
    
    
      | 155 | 
      char * OSTypeToString(OSType type); | 
    
    
      | 156 | 
      char * strcasestr(const char *s, const char *find); | 
    
    
      | 157 | 
      short strcasecmp(const char *s1, const char *s2); | 
    
    
      | 158 | 
      short strncasecmp(const char *s1, const char *s2, size_t n); | 
    
    
      | 159 | 
       | 
    
    
      | 160 | 
      unsigned long xorshift32(void); | 
    
    
      | 161 | 
       | 
    
    
      | 162 | 
      void panic(const char *format, ...); | 
    
    
      | 163 | 
      void warn(const char *format, ...); | 
    
    
      | 164 | 
      void note(const char *format, ...); | 
    
    
      | 165 | 
      void appicon_note(const char *format, ...); | 
    
    
      | 166 | 
      short ask(const char *format, ...); | 
    
    
      | 167 | 
      #define ASK_YES 1 | 
    
    
      | 168 | 
      #define ASK_NO  2 | 
    
    
      | 169 | 
      void about(char *program_name); | 
    
    
      | 170 | 
      void progress(char *format, ...); | 
    
    
      | 171 | 
      void window_rect(WindowPtr win, Rect *ret); | 
    
    
      | 172 | 
      void center_in_screen(short width, short height, bool titlebar, Rect *b); | 
    
    
      | 173 | 
      Point centered_sfget_dialog(void); | 
    
    
      | 174 | 
      Point centered_sfput_dialog(void); | 
    
    
      | 175 | 
      void outline_button(ControlHandle button); | 
    
    
      | 176 | 
       | 
    
    
      | 177 | 
      Handle xNewHandle(size_t size); | 
    
    
      | 178 | 
      Handle xGetResource(ResType type, short id); | 
    
    
      | 179 | 
      StringHandle xGetString(short id); | 
    
    
      | 180 | 
      char * xGetStringAsChar(short id); | 
    
    
      | 181 | 
      long xGetStringAsLong(short id); | 
    
    
      | 182 | 
      void xSetHandleSize(Handle h, Size s); | 
    
    
      | 183 | 
       | 
    
    
      | 184 | 
      short getpath(short vRefNum, Str255 fileName, Str255 *ret, bool include_file); | 
    
    
      | 185 | 
      bool FIsDir(Str255 path); | 
    
    
      | 186 | 
      short stat(char *path, struct stat *sb); | 
    
    
      | 187 | 
      short FStat(Str255 path, struct stat *sb); | 
    
    
      | 188 | 
      OSErr copy_file(Str255 source, Str255 dest, bool overwrite); | 
    
    
      | 189 | 
      OSErr copy_file_contents(short source_ref, short dest_ref); | 
    
    
      | 190 | 
      OSErr FSReadLine(short frefnum, char *buf, size_t buflen); | 
    
    
      | 191 | 
      TrapType GetTrapType(unsigned long theTrap); | 
    
    
      | 192 | 
      bool TrapAvailable(unsigned long trap); | 
    
    
      | 193 | 
      void GetSystemFolder(short *vRefNumP, long *dirIDP); | 
    
    
      | 194 | 
      void GetSystemSubfolder(OSType folder, bool create, short *vRefNumP, | 
    
    
      | 195 | 
        long *dirIDP); | 
    
    
      | 196 | 
       | 
    
    
      | 197 | 
      char * gestalt_machine_type(void); | 
    
    
      | 198 | 
      char * get_version(bool long_version); | 
    
    
      | 199 | 
      bool screen_saver_running(void); | 
    
    
      | 200 | 
       | 
    
    
      | 201 | 
      short FontHeight(short font_id, short size); | 
    
    
      | 202 | 
      void DrawGrowIconOnly(WindowPtr win); | 
    
    
      | 203 | 
      short TEGetWidth(short off, TEHandle te); | 
    
    
      | 204 | 
      void UpdateScrollbarForTE(GrafPtr win, ControlHandle scroller, TEHandle te, | 
    
    
      | 205 | 
        bool reset); | 
    
    
      | 206 | 
      void SetTrackControlTE(TEHandle te); | 
    
    
      | 207 | 
      pascal void TrackMouseDownInControl(ControlHandle control, short part); | 
    
    
      | 208 | 
      pascal bool ModalDialogFilter(DialogPtr dlg, EventRecord *event, | 
    
    
      | 209 | 
        short *hit); | 
    
    
      | 210 | 
      void PasswordDialogFieldFilterSetup(short ditl_id, char *storage, | 
    
    
      | 211 | 
        size_t len); | 
    
    
      | 212 | 
      pascal bool PasswordDialogFieldFilter(DialogPtr dlg, EventRecord *event, | 
    
    
      | 213 | 
        short *hit); | 
    
    
      | 214 | 
      void PasswordDialogFieldFinish(void); | 
    
    
      | 215 | 
      pascal void NullCaretHook(void); | 
    
    
      | 216 | 
      void HideMenuBar(void); | 
    
    
      | 217 | 
      void RestoreHiddenMenuBar(void); | 
    
    
      | 218 | 
      bool CommandPeriodPressed(void); | 
    
    
      | 219 | 
       | 
    
    
      | 220 | 
      size_t strlcat(char *dst, const char *src, size_t dsize); | 
    
    
      | 221 | 
      size_t strlcpy(char *dst, const char *src, size_t dsize); | 
    
    
      | 222 | 
      char * strndup(const char *str, size_t maxlen); | 
    
    
      | 223 | 
      char * strsep(char **stringp, const char *delim); | 
    
    
      | 224 | 
      short snprintf(char *s, size_t size, const char *fmt, ...); | 
    
    
      | 225 | 
      short vsnprintf(char *s, size_t size, const char *fmt, void *p); | 
    
    
      | 226 | 
       | 
    
    
      | 227 | 
      #endif |