AmendHub

Download:

jcs

/

amend

/

amendments

/

56

util: Sync with upstream


jcs made amendment 56 over 2 years ago
--- util.c Wed Jan 19 16:02:32 2022 +++ util.c Thu Feb 3 16:35:25 2022 @@ -86,7 +86,7 @@ xmalloc(size_t size) panic("xmalloc: zero size"); ptr = malloc(size); if (ptr == NULL) - panic("xmalloc: allocating %zu bytes", size); + panic("xmalloc(%lu) failed", size); return ptr; } @@ -105,7 +105,7 @@ xcalloc(size_t nmemb, size_t size) ptr = calloc(nmemb, size); if (ptr == NULL) - panic("xcalloc: allocating %zu * %zu bytes", nmemb, size); + panic("xcalloc(%lu, %lu) failed", nmemb, size); return ptr; } @@ -116,7 +116,7 @@ xrealloc(void *src, size_t size) ret = realloc(src, size); if (ret == NULL) - panic("Couldn't realloc %lu bytes of memory", size); + panic("realloc(%lu) failed", size); return ret; } @@ -127,7 +127,7 @@ xmallocarray(size_t nmemb, size_t size) { if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && nmemb > 0 && SIZE_MAX / nmemb < size) - panic("xmallocarray"); + panic("xmallocarray(%lu, %lu) failed", nmemb, size); return xmalloc(size * nmemb); } @@ -138,7 +138,7 @@ 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"); + panic("xreallocarray(%lu, %lu) failed", nmemb, size); return xrealloc(optr, size * nmemb); } @@ -200,11 +200,39 @@ ordinal(unsigned short n) } } -static char ostype_s[5]; +long +strpos_quoted(char *str, char c) +{ + long pos; + unsigned char quot = 0; + + for (pos = 0; str[pos] != '\0'; pos++) { + if (quot) { + if (str[pos] == '\\') { + pos++; + continue; + } + if (str[pos] == quot) + quot = 0; + continue; + } else { + if (str[pos] == '"') { + quot = str[pos]; + continue; + } + if (str[pos] == c) + return pos; + } + } + + return -1; +} char * OSTypeToString(OSType type) { + static char ostype_s[5]; + ostype_s[0] = (unsigned char)((type >> 24) & 0xff); ostype_s[1] = (unsigned char)((type >> 16) & 0xff); ostype_s[2] = (unsigned char)((type >> 8) & 0xff); @@ -863,45 +891,98 @@ DrawGrowIconOnly(WindowPtr win) DisposeRgn(tmp); } +/* assumes a fixed-width style */ +short +TEGetWidth(short off, TEHandle te) +{ + TextStyle style; + short fheight, fwidth, ascent, old_font, old_size; + + TEGetStyle(off, &style, &fheight, &ascent, te); + + old_font = thePort->txFace; + old_size = thePort->txSize; + thePort->txFace = style.tsFont; + thePort->txSize = style.tsSize; + fwidth = CharWidth('m'); + thePort->txFace = old_font; + thePort->txSize = old_size; + + return fwidth; +} + +#define ceildiv(a,b) ((a / b) + (!!(a % b))) + void -UpdateScrollbarForTE(ControlHandle scroller, TEHandle te, bool reset) +UpdateScrollbarForTE(ControlHandle control, TEHandle te, bool reset) { size_t vlines, telines; TERec *ter; - short vtop, lheight; - short max, val; + short fheight, fwidth, max, val, per_page, per_line, horiz, max_chars, + n; HLock(te); ter = *te; -#define ceildiv(a,b) ((a / b) + (!!(a % b))) + horiz = (((*control)->contrlRect.bottom - (*control)->contrlRect.top) < + ((*control)->contrlRect.right - (*control)->contrlRect.left)); - lheight = TEGetHeight(0, 0, te); - vlines = (ter->viewRect.bottom - ter->viewRect.top) / lheight; - telines = ter->nLines; - /* telines is inaccurate if the last line doesn't have any chars */ - if (telines >= vlines) - telines++; - max = telines - vlines; - if (max < 1) - max = 1; - - if (reset) { - val = 1; - vtop = (*te)->viewRect.top; - TESetSelect(0, 0, te); + if (horiz) { + fwidth = TEGetWidth(0, te); + per_line = ((ter->viewRect.right - ter->viewRect.left) / + fwidth) - 1; + for (max_chars = 0, n = 1; n < ter->nLines; n++) { + if (ter->lineStarts[n] - ter->lineStarts[n - 1] > max_chars) + max_chars = ter->lineStarts[n] - ter->lineStarts[n - 1]; + } + + if (max_chars <= per_line) + /* don't enable the scrollbar */ + max = 1; + else + max = max_chars - per_line + 1; + + if (reset) { + val = 1; + TESetSelect(0, 0, te); + } else { + val = (ter->viewRect.left - ter->destRect.left); + + if (val < 0) + val = 1; + else { + val = ceildiv(val, fwidth) + 1; + if (val > max) + max = val; + } + } } else { - val = (ter->viewRect.top - ter->destRect.top); - if (val < 0) + fheight = TEGetHeight(0, 0, te); + vlines = (ter->viewRect.bottom - ter->viewRect.top) / fheight; + telines = ter->nLines; + /* telines is inaccurate if the last line doesn't have any chars */ + if (telines >= vlines) + telines++; + max = telines - vlines + 1; + if (max < 1) + max = 1; + + if (reset) { val = 1; - else { - val = ceildiv(val, lheight) + 1; - if (val > max) - max = val; + TESetSelect(0, 0, te); + } else { + val = (ter->viewRect.top - ter->destRect.top); + if (val < 0) + val = 1; + else { + val = ceildiv(val, fheight) + 1; + if (val > max) + max = val; + } } } - SetCtlMax(scroller, max); - SetCtlValue(scroller, val); + SetCtlMax(control, max); + SetCtlValue(control, val); HUnlock(te); } @@ -915,17 +996,30 @@ SetTrackControlTE(TEHandle te) pascal void TrackMouseDownInControl(ControlHandle control, short part) { - short page, val, adj, lheight; - + TERec *ter; + short page, val, adj, fheight, fwidth, horiz, per_line; + if (track_control_te == NULL) panic("TrackMouseDownInControl without SetTrackControlTE"); - - lheight = TEGetHeight(0, 0, track_control_te); - /* keep 1 line of context between pages */ - page = (((*track_control_te)->viewRect.bottom - - (*track_control_te)->viewRect.top) / lheight) - 1; - + HLock(track_control_te); + ter = *track_control_te; + + horiz = (((*control)->contrlRect.bottom - (*control)->contrlRect.top) < + ((*control)->contrlRect.right - (*control)->contrlRect.left)); + + if (horiz) { + fwidth = TEGetWidth(0, track_control_te); + per_line = ((ter->viewRect.right - ter->viewRect.left) / + fwidth) - 1; + page = ceildiv(GetCtlMax(control) + per_line, + ((per_line * 75) / 100)) + 1; + } else { + /* keep 1 line of context between pages */ + fheight = TEGetHeight(0, 0, track_control_te); + page = ((ter->viewRect.bottom - ter->viewRect.top) / fheight) - 1; + } + adj = 0; switch (part) { case inUpButton: @@ -950,6 +1044,60 @@ TrackMouseDownInControl(ControlHandle control, short p if (adj == 0) return; - TEScroll(0, -adj * lheight, track_control_te); + if (horiz) + TEScroll(-adj * fwidth, 0, track_control_te); + else + TEScroll(0, -adj * fheight, track_control_te); + SetCtlValue(control, val + adj); -} + + HUnlock(track_control_te); +} + +pascal bool +ModalDialogFilter(DialogPtr dlg, EventRecord *event, short *hit) +{ + char key; + + switch (event->what) { + case keyDown: + key = event->message & charCodeMask; + + if (event->modifiers & cmdKey) { + switch (key) { + case 'x': + ZeroScrap(); + DlgCut(dlg); + break; + case 'c': + ZeroScrap(); + DlgCopy(dlg); + break; + case 'v': + if (TEFromScrap() == noErr) + DlgPaste(dlg); + break; + } + event->what = nullEvent; + return false; + } else if (key == 13 || key == 3) { + /* OK button */ + *hit = 1; + return true; + } + + break; + } + + return false; +} + +/* (*(some_te))->caretHook = NullCaretHook; */ +pascal void +NullCaretHook(void) +{ + asm { + move.l (a7)+,d0 + rts + } +} --- util.h Mon Jan 10 16:40:54 2022 +++ util.h Thu Feb 3 16:41:00 2022 @@ -17,6 +17,7 @@ #ifndef __UTIL_H__ #define __UTIL_H__ +#include <stddef.h> #include <stdlib.h> #include <limits.h> #include <time.h> @@ -26,6 +27,7 @@ #endif #define nitems(what) (sizeof((what)) / sizeof((what)[0])) +#define member_size(type, member) sizeof(((type *)0)->member) #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) @@ -72,6 +74,7 @@ short getline(char *str, size_t len, char **ret); 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); +long strpos_quoted(char *str, char c); char *OSTypeToString(OSType type); unsigned long xorshift32(void); @@ -104,8 +107,12 @@ OSErr FSReadLine(short frefnum, char *buf, size_t bufl short FontHeight(short font_id, short size); void DrawGrowIconOnly(WindowPtr win); +short TEGetWidth(short off, TEHandle te); void UpdateScrollbarForTE(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); +pascal void NullCaretHook(void); #endif