jcs
/amend
/amendments
/92
*: Bring in util from Subtext with malloc debugging, integrate it
jcs made amendment 92 over 2 years ago
--- bile.c Wed Aug 17 10:17:27 2022
+++ bile.c Wed Aug 3 13:59:30 2022
@@ -71,7 +71,7 @@ bile_create(const Str255 filename, short vrefnum, cons
return NULL;
SetFPos(fh, fsFromStart, 0);
- bile = xmalloczero(sizeof(struct bile));
+ bile = xmalloczero(sizeof(struct bile), "bile_create");
memcpy(bile->magic, BILE_MAGIC, sizeof(bile->magic));
bile->vrefnum = vrefnum;
bile->frefnum = fh;
@@ -80,9 +80,9 @@ bile_create(const Str255 filename, short vrefnum, cons
/* write magic */
len = BILE_MAGIC_LEN;
- tmp = xstrdup(BILE_MAGIC);
+ tmp = xstrdup(BILE_MAGIC, "bile_create magic");
_bile_error = FSWrite(bile->frefnum, &len, tmp);
- free(tmp);
+ xfree(&tmp);
if (_bile_error)
goto create_bail;
@@ -100,11 +100,11 @@ bile_create(const Str255 filename, short vrefnum, cons
/* padding */
len = BILE_HEADER_LEN - BILE_MAGIC_LEN - BILE_OBJECT_SIZE -
BILE_OBJECT_SIZE;
- tmp = xmalloczero(len);
+ tmp = xmalloczero(len, "bile_create padding");
_bile_error = FSWrite(bile->frefnum, &len, tmp);
if (_bile_error)
goto create_bail;
- free(tmp);
+ xfree(&tmp);
GetFPos(fh, &bile->file_size);
@@ -118,7 +118,7 @@ create_bail:
FSClose(bile->frefnum);
bile->frefnum = -1;
if (bile != NULL)
- free(bile);
+ xfree(&bile);
return NULL;
}
@@ -144,7 +144,7 @@ bile_open(const Str255 filename, short vrefnum)
GetFPos(fh, &file_size);
SetFPos(fh, fsFromStart, 0);
- bile = xmalloczero(sizeof(struct bile));
+ bile = xmalloczero(sizeof(struct bile), "bile_open");
memcpy(bile->magic, BILE_MAGIC, sizeof(bile->magic));
bile->vrefnum = vrefnum;
bile->frefnum = fh;
@@ -196,7 +196,7 @@ open_bail:
FSClose(bile->frefnum);
bile->frefnum = -1;
if (bile != NULL)
- free(bile);
+ xfree(&bile);
return NULL;
}
@@ -263,7 +263,7 @@ bile_close(struct bile *bile)
FSClose(bile->frefnum);
bile->frefnum = -1;
if (bile->map != NULL)
- free(bile->map);
+ xfree(&bile->map);
}
struct bile_object *
@@ -271,6 +271,7 @@ bile_find(struct bile *bile, const OSType type, const
{
struct bile_object *o, *ocopy;
unsigned long n;
+ char note[MALLOC_NOTE_SIZE];
bile_check_sanity(bile);
@@ -278,7 +279,9 @@ bile_find(struct bile *bile, const OSType type, const
if (o == NULL)
return NULL;
- ocopy = xmalloc(BILE_OBJECT_SIZE);
+ snprintf(note, sizeof(note), "bile_find %s %lu", OSTypeToString(type),
+ id);
+ ocopy = xmalloc(BILE_OBJECT_SIZE, note);
memcpy(ocopy, o, BILE_OBJECT_SIZE);
return ocopy;
@@ -346,6 +349,7 @@ bile_get_nth_of_type(struct bile *bile, const unsigned
{
struct bile_object *o, *ocopy;
size_t n, count = 0;
+ char note[MALLOC_NOTE_SIZE];
bile_check_sanity(bile);
@@ -357,7 +361,9 @@ bile_get_nth_of_type(struct bile *bile, const unsigned
continue;
if (count == index) {
- ocopy = xmalloc(BILE_OBJECT_SIZE);
+ snprintf(note, sizeof(note), "bile_get_nth %s %lu",
+ OSTypeToString(type), index);
+ ocopy = xmalloc(BILE_OBJECT_SIZE, note);
memcpy(ocopy, o, BILE_OBJECT_SIZE);
return ocopy;
}
@@ -571,6 +577,7 @@ bile_read_alloc(struct bile *bile, const OSType type,
struct bile_object *o;
size_t ret;
char **data;
+ char note[MALLOC_NOTE_SIZE];
bile_check_sanity(bile);
@@ -587,7 +594,9 @@ bile_read_alloc(struct bile *bile, const OSType type,
return 0;
}
- *data = xmalloczero(o->size);
+ snprintf(note, sizeof(note), "bile_read_alloc %s %ld",
+ OSTypeToString(type), id);
+ *data = xmalloczero(o->size, note);
ret = bile_read_object(bile, o, *data, o->size);
return ret;
@@ -635,7 +644,7 @@ bile_write(struct bile *bile, const OSType type, const
short
bile_marshall_object(struct bile *bile,
const struct bile_object_field *fields, const size_t nfields,
- void *object, void *ret_ptr, size_t *ret_size)
+ void *object, void *ret_ptr, size_t *ret_size, char *note)
{
char **ret;
char *data, *ptr;
@@ -690,7 +699,7 @@ iterate_fields:
}
if (!write) {
- data = xmalloc(size);
+ data = xmalloc(size, note);
write = true;
size = 0;
goto iterate_fields;
@@ -706,7 +715,7 @@ short
bile_unmarshall_object(struct bile *bile,
const struct bile_object_field *fields, const size_t nfields,
const void *data, const size_t data_size, void *object,
- const size_t object_size, bool deep)
+ const size_t object_size, bool deep, char *note)
{
size_t off, fsize = 0, n;
char *ptr, *dptr;
@@ -732,7 +741,7 @@ bile_unmarshall_object(struct bile *bile,
memset(ptr, 0, sizeof(dptr));
continue;
}
- dptr = xmalloc(fsize);
+ dptr = xmalloc(fsize, note);
memcpy(ptr, &dptr, sizeof(dptr));
ptr = dptr;
}
@@ -754,6 +763,7 @@ bile_unmarshall_object(struct bile *bile,
return 0;
}
+
short
bile_verify(struct bile *bile)
{
@@ -902,10 +912,10 @@ bile_read_map(struct bile *bile, struct bile_object *m
/* read entire map */
size = map_obj.size;
- map = xmalloczero(size);
+ map = xmalloczero(size, "bile_read_map");
_bile_error = FSRead(bile->frefnum, &size, map);
if (_bile_error) {
- free(map);
+ xfree(&map);
return -1;
}
@@ -940,7 +950,7 @@ bile_write_map(struct bile *bile)
new_map_size = BILE_OBJECT_SIZE * new_nobjects;
new_map_obj = bile_alloc(bile, BILE_TYPE_MAP, new_map_id,
new_map_size);
- new_map = xcalloc(BILE_OBJECT_SIZE, new_nobjects);
+ new_map = xcalloc(BILE_OBJECT_SIZE, new_nobjects, "bile_write_map");
for (n = 0, new_nobjects = 0; n < bile->nobjects; n++) {
obj = &bile->map[n];
@@ -982,7 +992,7 @@ bile_write_map(struct bile *bile)
}
/* successfully wrote new map, switch over */
- free(bile->map);
+ xfree(&bile->map);
bile->nobjects = new_nobjects;
bile->map = new_map;
bile->old_map_ptr.pos = bile->map_ptr.pos;
--- bile.h Wed Aug 17 10:16:55 2022
+++ bile.h Thu Aug 18 22:18:13 2022
@@ -137,11 +137,11 @@ short bile_verify(struct bile *bile);
short bile_marshall_object(struct bile *bile,
const struct bile_object_field *fields,
const size_t nfields, void *object,
- void *ret_ptr, size_t *ret_size);
+ void *ret_ptr, size_t *ret_size, char *note);
short bile_unmarshall_object(struct bile *bile,
const struct bile_object_field *fields,
const size_t nfields, const void *data,
const size_t data_size, void *object,
- const size_t object_size, bool deep);
+ const size_t object_size, bool deep, char *note);
#endif
--- browser.c Wed Aug 17 17:07:23 2022
+++ browser.c Thu Aug 18 22:50:26 2022
@@ -118,7 +118,7 @@ browser_init(struct repo *repo)
Cell cell = { 0 };
short colonpos, n;
- browser = xmalloczero(sizeof(struct browser));
+ browser = xmalloczero(sizeof(struct browser), "browser");
browser->state = BROWSER_STATE_IDLE;
browser->repo = repo;
@@ -208,7 +208,7 @@ browser_init(struct repo *repo)
browser_add_files(browser);
UpdateScrollbarForTE(browser->diff_scroller, browser->diff_te, true);
- focusable = xmalloczero(sizeof(struct focusable));
+ focusable = xmalloczero(sizeof(struct focusable), "focusable");
focusable->cookie = browser;
focusable->win = browser->win;
focusable->idle = browser_idle;
@@ -237,7 +237,7 @@ browser_close(struct focusable *focusable)
TEDispose(browser->diff_te);
DisposeWindow(browser->win);
- free(browser);
+ xfree(&browser);
menu_defaults();
@@ -323,7 +323,8 @@ browser_selected_file_ids(struct browser *browser, sho
return 0;
}
- *selected_files = xmalloc(browser->repo->nfiles * sizeof(short));
+ *selected_files = xcalloc(browser->repo->nfiles, sizeof(short),
+ "selected_files");
if (browser_is_all_files_selected(browser)) {
nselected_files = browser->repo->nfiles;
@@ -386,7 +387,7 @@ browser_filter_amendments(struct browser *browser)
InvalRect(&(*(browser->amendment_list))->rView);
if (selected_files)
- free(selected_files);
+ xfree(&selected_files);
}
void
@@ -649,9 +650,9 @@ browser_mouse_down(struct focusable *focusable, EventR
}
if (selected_files)
- free(selected_files);
+ xfree(&selected_files);
if (now_selected_files)
- free(now_selected_files);
+ xfree(&now_selected_files);
return;
}
--- committer.c Wed Aug 17 16:58:51 2022
+++ committer.c Thu Aug 18 22:50:45 2022
@@ -67,7 +67,7 @@ committer_init(struct browser *browser)
TextStyle style;
short fh;
- committer = xmalloczero(sizeof(struct committer));
+ committer = xmalloczero(sizeof(struct committer), "committer_init");
committer->browser = browser;
browser->committer = committer;
@@ -149,7 +149,7 @@ committer_init(struct browser *browser)
committer->last_te = committer->log_te;
- focusable = xmalloczero(sizeof(struct focusable));
+ focusable = xmalloczero(sizeof(struct focusable), "committer focusable");
focusable->cookie = committer;
focusable->win = committer->win;
focusable->modal = true;
@@ -177,13 +177,13 @@ committer_close(struct focusable *focusable)
}
if (committer->diffed_files != NULL)
- free(committer->diffed_files);
+ xfree(&committer->diffed_files);
TEDispose(committer->log_te);
TEDispose(committer->diff_te);
DisposeWindow(committer->win);
- free(committer);
+ xfree(&committer);
return true;
}
@@ -435,8 +435,8 @@ committer_generate_diff(struct committer *committer)
committer->diff_subs = 0;
committer->ndiffed_files = 0;
committer->allow_commit = false;
- committer->diffed_files = xmalloc(sizeof(struct diffed_file) *
- nselected_files);
+ committer->diffed_files = xcalloc(sizeof(struct diffed_file),
+ nselected_files, "committer diffed_files");
committer->diff_too_big = false;
HLock(committer->diff_te);
@@ -488,7 +488,7 @@ committer_generate_diff(struct committer *committer)
done_diffing:
if (selected_files != NULL)
- free(selected_files);
+ xfree(&selected_files);
SetCursor(&arrow);
if (!committer->allow_commit) {
--- diffreg.c Wed Jun 15 22:07:22 2022
+++ diffreg.c Thu Aug 18 22:51:20 2022
@@ -346,18 +346,18 @@ diffreg(char *file1, char *file2, int flags)
unsort(sfile[0], slen[0], class);
class = xreallocarray(class, slen[0] + 2, sizeof(*class));
- klist = xcalloc(slen[0] + 2, sizeof(*klist));
+ klist = xcalloc(slen[0] + 2, sizeof(*klist), "diffreg klist");
clen = 0;
clistlen = 100;
- clist = xcalloc(clistlen, sizeof(*clist));
+ clist = xcalloc(clistlen, sizeof(*clist), "diffreg clist");
i = stone(class, slen[0], member, klist, flags);
- free(member);
- free(class);
+ xfree(&member);
+ xfree(&class);
J = xreallocarray(J, len[0] + 2, sizeof(*J));
unravel(klist[i]);
- free(clist);
- free(klist);
+ xfree(&clist);
+ xfree(&klist);
ixold = xreallocarray(ixold, len[0] + 2, sizeof(*ixold));
ixnew = xreallocarray(ixnew, len[1] + 2, sizeof(*ixnew));
@@ -417,7 +417,7 @@ prepare(int i, FILE *fd, off_t filesize, int flags)
if (sz < 100)
sz = 100;
- p = xcalloc(sz + 3, sizeof(*p));
+ p = xcalloc(sz + 3, sizeof(*p), "diff prepare");
for (j = 0; (h = readhash(fd, flags));) {
if (j == sz) {
sz = sz * 3 / 2;
@@ -745,12 +745,12 @@ unsort(struct line *f, int l, int *b)
{
int *a, i;
- a = xcalloc(l + 1, sizeof(*a));
+ a = xcalloc(l + 1, sizeof(*a), "diff unsort");
for (i = 1; i <= l; i++)
a[f[i].serial] = f[i].value;
for (i = 1; i <= l; i++)
b[i] = a[i];
- free(a);
+ xfree(&a);
}
static int
@@ -843,7 +843,7 @@ preadline(int fd, size_t rlen, off_t off)
ssize_t nr;
off_t pos;
- line = xmalloc(rlen + 1);
+ line = xmalloc(rlen + 1, "diff preadline");
pos = lseek(fd, 0, SEEK_CUR);
lseek(fd, off, SEEK_SET);
if ((nr = read(fd, line, rlen)) == -1)
@@ -862,7 +862,7 @@ ignoreline(char *line)
int ret;
ret = regexec(&ignore_re, line, 0, NULL, 0);
- free(line);
+ xfree(&line);
return (ret == 0); /* if it matched, it should be ignored. */
#endif
return 0;
--- editor.c Wed Aug 17 16:59:44 2022
+++ editor.c Thu Aug 18 22:51:50 2022
@@ -57,7 +57,7 @@ editor_init(struct browser *browser, struct repo_amend
short fh, off;
struct tm *ttm = NULL;
- editor = xmalloczero(sizeof(struct editor));
+ editor = xmalloczero(sizeof(struct editor), "editor");
editor->browser = browser;
editor->amendment = amendment;
@@ -152,7 +152,7 @@ editor_init(struct browser *browser, struct repo_amend
editor->last_te = editor->author_te;
- focusable = xmalloczero(sizeof(struct focusable));
+ focusable = xmalloczero(sizeof(struct focusable), "editor focusable");
focusable->cookie = editor;
focusable->win = editor->win;
focusable->modal = true;
@@ -175,7 +175,7 @@ editor_close(struct focusable *focusable)
TEDispose(editor->log_te);
DisposeWindow(editor->win);
- free(editor);
+ xfree(&editor);
return true;
}
@@ -435,13 +435,13 @@ editor_save(struct editor *editor)
return;
}
- date = xmalloc(len + 1);
+ date = xmalloc(len + 1, "editor_save");
memcpy(date, *(*(editor->date_te))->hText, len);
date[len] = '\0';
ret = sscanf(date, "%d-%d-%d %d:%d:%d%n", &yy, &mm, &dd, &hh, &min,
&ss, &count);
- free(date);
+ xfree(&date);
if (ret != 6 || count < 11) {
warn("Date must be in YYYY-MM-DD HH:MM:SS format");
return;
@@ -487,7 +487,7 @@ editor_save(struct editor *editor)
if (size != len)
panic("Failed storing amendment in repo file: %d",
bile_error(editor->browser->repo->bile));
- free(data);
+ xfree(&data);
editor->browser->need_refresh = true;
focusable_close(focusable_find(editor->win));
--- focusable.c Tue Aug 16 14:20:54 2022
+++ focusable.c Thu Aug 18 22:52:10 2022
@@ -118,10 +118,8 @@ focusable_close(struct focusable *focusable)
nfocusables--;
if (nfocusables)
focusables = xreallocarray(focusables, sizeof(Ptr), nfocusables);
- else {
- free(focusables);
- focusables = NULL;
- }
+ else
+ xfree(&focusables);
if (nfocusables && focusables[0]->visible)
focusable_show(focusables[0]);
@@ -160,7 +158,7 @@ focusables_quit(void)
* nfocusables and focusables array will probably be
* modified as each focusable quits
*/
- tfocusables = xcalloc(sizeof(Ptr), tnfocusables);
+ tfocusables = xcalloc(sizeof(Ptr), tnfocusables, "tfocusables");
memcpy(tfocusables, focusables, sizeof(Ptr) * tnfocusables);
for (n = 0; n < tnfocusables; n++) {
@@ -170,7 +168,7 @@ focusables_quit(void)
}
}
- free(tfocusables);
+ xfree(&tfocusables);
}
return quit;
--- main.c Tue Aug 16 16:44:27 2022
+++ main.c Thu Aug 18 23:02:32 2022
@@ -56,6 +56,7 @@ main(void)
InitCursor();
MaxApplZone();
+ util_init();
settings_load();
mbar = GetNewMBar(MBAR_ID);
--- repo.c Wed Aug 17 14:23:09 2022
+++ repo.c Thu Aug 18 22:53:33 2022
@@ -109,20 +109,20 @@ repo_init(struct bile *bile, short is_new)
short error, fh;
unsigned long i;
- repo = xmalloczero(sizeof(struct repo));
+ repo = xmalloczero(sizeof(struct repo), "repo");
repo->bile = bile;
repo->next_file_id = 1;
repo->next_amendment_id = 1;
if (repo_migrate(repo, is_new) != 0) {
- free(repo);
+ xfree(&repo);
return NULL;
}
/* fill in file info */
repo->nfiles = bile_count_by_type(bile, REPO_FILE_RTYPE);
if (repo->nfiles) {
- repo->files = xmalloc(repo->nfiles * sizeof(Ptr));
+ repo->files = xcalloc(repo->nfiles, sizeof(Ptr), "repo files");
for (i = 0; i < repo->nfiles; i++) {
bob = bile_get_nth_of_type(bile, i, REPO_FILE_RTYPE);
if (bob == NULL)
@@ -130,12 +130,13 @@ repo_init(struct bile *bile, short is_new)
size = bile_read_alloc(bile, REPO_FILE_RTYPE, bob->id, &data);
if (size == 0)
panic("failed fetching file %ld", bob->id);
- repo->files[i] = xmalloczero(sizeof(struct repo_file));
+ repo->files[i] = xmalloczero(sizeof(struct repo_file),
+ "repo file");
repo->files[i] = repo_parse_file(bob->id, (unsigned char *)data,
size);
if (repo->files[i]->id >= repo->next_file_id)
repo->next_file_id = repo->files[i]->id + 1;
- free(data);
+ xfree(&data);
}
}
repo_sort_files(repo);
@@ -143,7 +144,8 @@ repo_init(struct bile *bile, short is_new)
/* fill in amendment info */
repo->namendments = bile_count_by_type(bile, REPO_AMENDMENT_RTYPE);
if (repo->namendments) {
- repo->amendments = xmalloc(repo->namendments * sizeof(Ptr));
+ repo->amendments = xcalloc(repo->namendments, sizeof(Ptr),
+ "repo amendments");
for (i = 0; i < repo->namendments; i++) {
bob = bile_get_nth_of_type(bile, i, REPO_AMENDMENT_RTYPE);
if (bob == NULL)
@@ -157,7 +159,7 @@ repo_init(struct bile *bile, short is_new)
(unsigned char *)data, size);
if (repo->amendments[i]->id >= repo->next_amendment_id)
repo->next_amendment_id = repo->amendments[i]->id + 1;
- free(data);
+ xfree(&data);
}
}
repo_sort_amendments(repo);
@@ -182,23 +184,23 @@ repo_close(struct repo *repo)
DisposHandle(amendment->log);
if (amendment->file_ids != NULL)
- free(amendment->file_ids);
+ xfree(&amendment->file_ids);
- free(amendment);
+ xfree(&amendment);
}
- free(repo->amendments);
+ xfree(&repo->amendments);
for (i = 0; i < repo->nfiles; i++) {
file = repo->files[i];
if (file == NULL)
continue;
- free(file);
+ xfree(&file);
}
- free(repo->files);
+ xfree(&repo->files);
bile_close(repo->bile);
- free(repo);
+ xfree(&repo);
}
struct repo_file *
@@ -210,7 +212,7 @@ repo_parse_file(unsigned long id, unsigned char *data,
datapos = 0;
- file = xmalloczero(sizeof(struct repo_file));
+ file = xmalloczero(sizeof(struct repo_file), "repo_parse_file");
file->id = id;
/* filename, pstr */
@@ -257,7 +259,8 @@ repo_parse_amendment(unsigned long id, unsigned char *
unsigned short len, i;
short datapos;
- amendment = xmalloczero(sizeof(struct repo_amendment));
+ amendment = xmalloczero(sizeof(struct repo_amendment),
+ "repo_parse_amendment");
amendment->id = id;
/* date */
@@ -280,7 +283,8 @@ repo_parse_amendment(unsigned long id, unsigned char *
data += 2;
if (amendment->nfiles) {
- amendment->file_ids = xmalloc(sizeof(short) * amendment->nfiles);
+ amendment->file_ids = xcalloc(amendment->nfiles, sizeof(short),
+ "amendment file_ids");
for (i = 0; i < amendment->nfiles; i++) {
amendment->file_ids[i] = (data[0] << 8) | data[1];
data += 2;
@@ -331,7 +335,7 @@ repo_diff_header(struct repo *repo, struct repo_amendm
unsigned short header_len;
short i;
- *ret = xmalloc(128 + amendment->log_len);
+ *ret = xmalloc(128 + amendment->log_len, "repo_diff_header");
ttm = localtime(&amendment->date);
header_len = sprintf(*ret,
"Author: %s\r"
@@ -392,9 +396,9 @@ repo_show_diff_text(struct repo *repo, struct repo_ame
trunc = 1;
}
- dtext = xmalloc(all_len);
+ dtext = xmalloc(all_len, "repo_show_diff_text");
memcpy(dtext, buf, header_len);
- free(buf);
+ xfree(&buf);
size = bile_read_object(repo->bile, bob, dtext + header_len,
all_len - header_len);
@@ -418,7 +422,7 @@ repo_show_diff_text(struct repo *repo, struct repo_ame
style.tsSize = 9;
TESetStyle(doFont | doSize, &style, false, te);
TEStylInsert(dtext, all_len, 0, te);
- free(dtext);
+ xfree(&dtext);
}
static long repo_add_file_filter_repo_dir;
@@ -523,7 +527,7 @@ repo_add_file(struct repo *repo)
repo->nfiles++;
repo->files = xrealloc(repo->files, repo->nfiles * sizeof(Ptr));
file = repo->files[repo->nfiles - 1] =
- xmalloczero(sizeof(struct repo_file));
+ xmalloczero(sizeof(struct repo_file), "repo_add_file");
file->id = repo->next_file_id;
repo->next_file_id++;
@@ -572,7 +576,7 @@ repo_file_update(struct repo *repo, struct repo_file *
/* filename len, filename, type, creator, ctime, mtime, flags */
len = 1 + filename[0] + 4 + 4 + 4 + 4 + 1;
- data = xmalloczero(len);
+ data = xmalloczero(len, "repo_file_update");
datapos = 0;
/* copy filename as pstr */
@@ -599,7 +603,7 @@ repo_file_update(struct repo *repo, struct repo_file *
panic("repo_file_update: failed writing file data: %d",
bile_error(repo->bile));
- free(data);
+ xfree(&data);
}
short
@@ -651,7 +655,7 @@ repo_checkout_file(struct repo *repo, struct repo_file
if (error && error != dupFNErr) {
warn("Failed to create file %s: %d", PtoCstr(filename),
error);
- free(textob);
+ xfree(&textob);
return -1;
}
@@ -664,7 +668,7 @@ repo_checkout_file(struct repo *repo, struct repo_file
panic("Failed to truncate file %s: %d", PtoCstr(filename), error);
/* TODO: add offset to bile_read to read in chunks */
- text = xmalloc(textob->size);
+ text = xmalloc(textob->size, "repo_checkout_file");
size = bile_read_object(repo->bile, textob, text, textob->size);
if (size != textob->size)
panic("Failed to read text object %ld: %d", textob->id,
@@ -674,8 +678,8 @@ repo_checkout_file(struct repo *repo, struct repo_file
if (error)
panic("Failed to write file to %s: %d", PtoCstr(filename), error);
- free(text);
- free(textob);
+ xfree(&text);
+ xfree(&textob);
FSClose(frefnum);
return 0;
@@ -761,7 +765,7 @@ repo_diff_file(struct repo *repo, struct repo_file *fi
if (error)
panic("Failed to write old file to %s: %d",
PtoCstr(fromfilename), error);
- free(text);
+ xfree(&text);
}
}
@@ -848,7 +852,7 @@ repo_file_changed(struct repo *repo, struct repo_file
if (bob == NULL)
return 1;
fsize = bob->size;
- free(bob);
+ xfree(&bob);
memcpy((char *)filename, file->filename, sizeof(file->filename));
CtoPstr(filename);
@@ -911,16 +915,16 @@ repo_export_patch(struct repo *repo, struct repo_amend
if (error)
panic("Failed to write diff header to %s: %d", PtoCstr(filename),
error);
- free(buf);
+ xfree(&buf);
- buf = xmalloc(bob->size);
+ buf = xmalloc(bob->size, "repo_export_patch");
size = bile_read_object(repo->bile, bob, buf, bob->size);
error = FSWrite(frefnum, &size, buf);
if (error)
panic("Failed to write diff to %s: %d", PtoCstr(filename), error);
- free(buf);
- free(bob);
+ xfree(&buf);
+ xfree(&bob);
FSClose(frefnum);
}
@@ -938,13 +942,15 @@ repo_amend(struct repo *repo, struct diffed_file *diff
size_t size;
short i, id, error, frefnum;
- amendment = xmalloczero(sizeof(struct repo_amendment));
+ amendment = xmalloczero(sizeof(struct repo_amendment),
+ "repo_amend amendment");
amendment->id = repo->next_amendment_id;
amendment->date = Time;
/* find files with actual data changes */
amendment->nfiles = 0;
- amendment->file_ids = xcalloc(sizeof(short), nfiles);
+ amendment->file_ids = xcalloc(sizeof(short), nfiles,
+ "repo_amend file_ids");
for (i = 0; i < nfiles; i++) {
if (diffed_files[i].flags & DIFFED_FILE_TEXT) {
amendment->file_ids[amendment->nfiles] =
@@ -988,7 +994,7 @@ repo_amend(struct repo *repo, struct diffed_file *diff
if (size != datalen)
panic("Failed storing amendment in repo file: %d",
bile_error(repo->bile));
- free(amendment_data);
+ xfree(&amendment_data);
/* store new versions of each file */
for (i = 0; i < nfiles; i++) {
@@ -1015,7 +1021,7 @@ repo_amend(struct repo *repo, struct diffed_file *diff
panic("Failed to get size of file %s: %d",
PtoCstr(tfilename), error);
- tdata = xmalloc(fsize);
+ tdata = xmalloc(fsize, "repo_amend data");
error = FSRead(frefnum, &fsize, tdata);
if (error)
panic("Failed to read %ul of file %s: %d", fsize,
@@ -1028,7 +1034,7 @@ repo_amend(struct repo *repo, struct diffed_file *diff
if (size != fsize)
panic("Failed to write new text file at %s: %d",
PtoCstr(tfilename), bile_error(repo->bile));
- free(tdata);
+ xfree(&tdata);
}
}
@@ -1077,7 +1083,7 @@ repo_marshall_amendment(struct repo_amendment *amendme
/* log (wstr) */
len += sizeof(short) + amendment->log_len;
- *retdata = xmalloc(len);
+ *retdata = xmalloc(len, "repo_marshall_amendment");
data = *retdata;
data[pos++] = (amendment->date >> 24) & 0xff;
@@ -1166,7 +1172,7 @@ repo_migrate(struct repo *repo, short is_new)
/* copy templates from our resource file to bile file */
while ((bob = bile_get_nth_of_type(repo->bile, 0, 'TMPL')) != NULL) {
bile_delete(repo->bile, 'TMPL', bob->id);
- free(bob);
+ xfree(&bob);
}
ntmpls = Count1Resources('TMPL');
--- settings.c Wed Jun 15 11:35:22 2022
+++ settings.c Thu Aug 18 22:53:46 2022
@@ -32,7 +32,7 @@ settings_load(void)
author = xGetStringAsChar(STR_AUTHOR_ID);
memcpy(settings.author, author, sizeof(settings.author));
settings.author[sizeof(settings.author)] = '\0';
- free(author);
+ xfree(&author);
if (settings.author[0] == '\0')
snprintf(settings.author, sizeof(settings.author), "unknown");
--- util.c Tue Aug 16 21:45:41 2022
+++ util.c Thu Aug 18 23:17:52 2022
@@ -18,7 +18,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-
+#include <GestaltEqu.h>
+#include <Script.h>
+#include <SetUpA4.h>
#include "util.h"
/* ALRT resources */
@@ -63,79 +65,222 @@ static const char progress_ditl[] = {
static Handle progress_ditl_h = NULL;
static DialogPtr progress_dialog = NULL;
+static TEHandle track_control_te = NULL;
+
enum {
STOP_ALERT,
CAUTION_ALERT,
NOTE_ALERT
};
-static TEHandle track_control_te = NULL;
+#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_SIZE 512
+struct malloc_map_e {
+ unsigned long addr;
+ unsigned long size;
+ char note[MALLOC_NOTE_SIZE];
+} malloc_map[MALLOC_MAP_SIZE];
+
+/*
+ * On xfree(&), the pointer will be updated to point here. xfree_verify()
+ * should be called periodically to detect any writes to it, indicating
+ * a use-after-free.
+ */
+#define MALLOC_UAF_SIZE 256
+static const char malloc_uaf_zero[MALLOC_UAF_SIZE] = { 0 };
+static char malloc_uaf[MALLOC_UAF_SIZE];
+
+static bool malloc_map_compact = false;
+
+#endif
+
void vwarn(short alert_func, const char *format, va_list ap);
/*
+ * Util helper needed to be called at program startup, to pre-allocate
+ * some things that we can't do during errors.
+ */
+
+void
+util_init(void)
+{
+ alert_ditl_h = xNewHandle(sizeof(alert_ditl));
+ HLock(alert_ditl_h);
+ memcpy(*alert_ditl_h, alert_ditl, sizeof(alert_ditl));
+ HUnlock(alert_ditl_h);
+
+#ifdef MALLOC_DEBUG
+ memset(&malloc_map, 0, sizeof(malloc_map));
+ memset(&malloc_uaf, 0, sizeof(malloc_uaf));
+#endif
+}
+
+/*
* Memory functions
*/
-
+
+#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
+
void *
-xmalloc(size_t size)
+xmalloc(size_t size, char *note)
{
void *ptr;
-
+#ifdef MALLOC_DEBUG
+ unsigned short n, j;
+#endif
+
if (size == 0)
panic("xmalloc: zero size");
- ptr = malloc(size);
+
+ ptr = NewPtr(size);
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(malloc_map[j]));
+ break;
+ }
+ }
+
+ malloc_map_compact = false;
+ }
+
+ for (n = 0; n <= MALLOC_MAP_SIZE; n++) {
+ if (n == MALLOC_MAP_SIZE)
+ panic("xmalloc(%lu): out of malloc map entries, likely a "
+ "memory leak", size);
+ 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;
+ }
+#endif
+
return ptr;
}
+void
+xfree(void *ptrptr)
+{
+ unsigned long *addr = (unsigned long *)ptrptr;
+ void *ptr = (void *)*addr;
+#ifdef MALLOC_DEBUG
+ unsigned long n;
+
+ if (*addr == (unsigned long)&malloc_uaf)
+ panic("xfree(%lu): double free()", *addr);
+
+ for (n = 0; n <= MALLOC_MAP_SIZE; n++) {
+ if (n == MALLOC_MAP_SIZE)
+ panic("xfree(%lu): 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
+
+ DisposePtr(ptr);
+
+#ifdef MALLOC_DEBUG
+ *addr = (unsigned long)&malloc_uaf;
+#else
+ *addr = 0L;
+#endif
+}
+
+#ifdef MALLOC_DEBUG
+void
+xfree_verify(void)
+{
+ if (memcmp(malloc_uaf, malloc_uaf_zero, sizeof(malloc_uaf)) != 0)
+ panic("xfree_verify: use-after-free detected");
+}
+#endif
+
void *
-xmalloczero(size_t size)
+xmalloczero(size_t size, char *note)
{
- void *ptr = xmalloc(size);
+ void *ptr;
+
+ ptr = xmalloc(size, note);
memset(ptr, 0, size);
+
return ptr;
}
void *
-xcalloc(size_t nmemb, size_t size)
+xcalloc(size_t nmemb, size_t size, char *note)
{
void *ptr;
- ptr = calloc(nmemb, size);
+ 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;
}
void *
xrealloc(void *src, size_t size)
{
- void *ret;
+ void *ptr, *tsrc;
+ unsigned long n;
+ char note[MALLOC_NOTE_SIZE] = "realloc from null";
- ret = realloc(src, size);
- if (ret == NULL)
- panic("realloc(%lu) failed", size);
- return ret;
-}
+#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
-#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
+ ptr = xmalloc(size, note);
+ if (src != NULL) {
+ memcpy(ptr, src, size);
+ tsrc = src;
+ xfree(&tsrc);
+ }
-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(%lu, %lu) failed", nmemb, size);
- return xmalloc(size * nmemb);
+ return ptr;
}
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)
panic("xreallocarray(%lu, %lu) failed", nmemb, size);
@@ -143,14 +288,14 @@ xreallocarray(void *optr, size_t nmemb, size_t size)
}
char *
-xstrdup(const char *str)
+xstrdup(const char *str, char *note)
{
char *cp;
size_t len;
len = strlen(str);
- cp = xmalloc(len + 1);
+ cp = xmalloc(len + 1, note);
strlcpy(cp, str, len + 1);
return cp;
@@ -168,7 +313,7 @@ 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);
+ *ret = xmalloc(i + 1, "getline");
memcpy(*ret, str, i + 1);
(*ret)[i] = '\0';
return i + 1;
@@ -200,6 +345,30 @@ ordinal(unsigned short n)
}
}
+size_t
+rtrim(char *str, char *chars)
+{
+ size_t len, rlen, n, j;
+
+ rlen = len = strlen(str);
+
+ for (n = len; n > 0; n--) {
+ for (j = 0; chars[j] != '\0'; j++) {
+ if (str[n - 1] == chars[j]) {
+ rlen--;
+ str[n - 1] = '\0';
+ goto next_in_str;
+ }
+ }
+
+ break;
+next_in_str:
+ continue;
+ }
+
+ return rlen;
+}
+
long
strpos_quoted(char *str, char c)
{
@@ -249,11 +418,9 @@ OSTypeToString(OSType type)
void
vwarn(short alert_func, const char *format, va_list ap)
{
- Rect bounds, irect;
- short quit = 0, height, width, hit;
+ Rect bounds;
+ short height, width, hit;
WindowPtr win, dialog;
- OSType itype;
- Handle ihandle;
GetPort(&win);
@@ -266,14 +433,9 @@ vwarn(short alert_func, const char *format, va_list ap
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);
@@ -301,12 +463,21 @@ vwarn(short alert_func, const char *format, va_list ap
break;
}
DisposDialog(dialog);
- DisposHandle(alert_ditl_h);
- SetPort(win);
-
- if (quit)
+ /*
+ * Pre-allocate for the next one while we have memory. We can't use
+ * xNewHandle because we might already be alerting about an OOM
+ * condition.
+ */
+ DisposHandle(alert_ditl_h);
+ alert_ditl_h = NewHandle(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);
+
+ SetPort(win);
}
void
@@ -366,11 +537,9 @@ note(const char *format, ...)
short
ask(const char *format, ...)
{
- Rect bounds, irect;
+ Rect bounds;
short height, width, hit;
WindowPtr win, dialog;
- OSType itype;
- Handle ihandle;
va_list ap;
GetPort(&win);
@@ -404,7 +573,7 @@ ask(const char *format, ...)
break;
}
DisposDialog(dialog);
- DisposHandle(alert_ditl_h);
+ DisposHandle(ask_ditl_h);
SetPort(win);
@@ -465,7 +634,6 @@ window_rect(WindowPtr win, Rect *ret)
/*
* General Mac-specific non-GUI functions
*/
-
static unsigned long _xorshift_state = 0;
unsigned long
xorshift32(void)
@@ -533,7 +701,7 @@ xGetStringAsChar(short id)
h = xGetString(id);
HLock(h);
l = (*h)[0];
- out = xmalloc(l + 1);
+ out = xmalloc(l + 1, "xGetStringAsChar");
memcpy((void *)out, (void *)(*h + 1), l);
out[l] = '\0';
ReleaseResource(h);
@@ -549,7 +717,7 @@ xGetStringAsLong(short id)
c = xGetStringAsChar(id);
r = atol(c);
- free(c);
+ xfree(&c);
return r;
}
@@ -566,15 +734,14 @@ xSetHandleSize(Handle h, Size s)
*/
short
-getpath(const short vRefNum, const Str255 fileName, Str255 *ret,
- bool include_file)
+getpath(short vRefNum, Str255 fileName, Str255 *ret, bool include_file)
{
WDPBRec wdir;
HVolumeParam wvol;
DirInfo wcinfo;
- Str255 name;
+ char *name = NULL;
size_t retlen = 0, len;
- char tmpret[256], tmp[256];
+ char *tmpret = NULL, *tmp = NULL;
char *lastcolon;
if (strchr((char *)fileName + 1, ':') != NULL) {
@@ -589,35 +756,43 @@ getpath(const short vRefNum, const Str255 fileName, St
return 0;
}
+ name = xmalloc(FILENAME_MAX, "getpath");
+
wdir.ioVRefNum = wdir.ioWDVRefNum = vRefNum;
wdir.ioWDIndex = 0;
wdir.ioWDProcID = 0;
- wdir.ioNamePtr = (StringPtr)&name;
+ wdir.ioNamePtr = (StringPtr)name;
if (PBGetWDInfo(&wdir, 0) != noErr) {
warn("Failed looking up directory");
+ xfree(&name);
return 1;
}
- wvol.ioNamePtr = (StringPtr)&name;
+ wvol.ioNamePtr = (StringPtr)name;
wvol.ioVRefNum = vRefNum;
wvol.ioVolIndex = 0;
if (PBHGetVInfoSync((HParmBlkPtr)&wvol) != noErr) {
warn("Failed getting volume info");
+ xfree(&name);
return 1;
}
if (wvol.ioVSigWord != 0x4244) {
warn("Unknown filesystem type 0x%x", wvol.ioVSigWord);
+ xfree(&name);
return 1;
}
wcinfo.ioVRefNum = vRefNum;
- wcinfo.ioNamePtr = (StringPtr)&name;
+ wcinfo.ioNamePtr = (StringPtr)name;
wcinfo.ioFDirIndex = -1;
wcinfo.ioDrParID = wdir.ioWDDirID;
wcinfo.ioDrDirID = wdir.ioWDDirID;
+ tmp = xmalloc(FILENAME_MAX, "getpath");
+ tmpret = xmalloc(FILENAME_MAX, "getpath");
+
/* go backwards, prepending each folder's parent */
while (wcinfo.ioDrParID != 1) {
wcinfo.ioDrDirID = wcinfo.ioDrParID; /* .. */
@@ -629,31 +804,37 @@ getpath(const short vRefNum, const Str255 fileName, St
PtoCstr(name);
if (retlen == 0) {
retlen = len;
- strlcpy(tmpret, (char *)name, sizeof(tmpret));
+ strlcpy(tmpret, (char *)name, FILENAME_MAX);
} else {
- strlcpy(tmp, tmpret, sizeof(tmp));
- snprintf(tmpret, sizeof(tmpret), "%s:%s", name, tmp);
+ strlcpy(tmp, tmpret, FILENAME_MAX);
+ snprintf(tmpret, FILENAME_MAX, "%s:%s", name, tmp);
}
}
if (include_file) {
/* append the original path */
- memcpy(name, fileName, sizeof(name));
+ memcpy(name, fileName, FILENAME_MAX);
PtoCstr(name);
if (retlen == 0)
- strlcpy(tmpret, (char *)name, sizeof(tmpret));
+ strlcpy(tmpret, name, FILENAME_MAX);
else {
- strlcat(tmpret, ":", sizeof(tmpret));
- strlcat(tmpret, (char *)name, sizeof(tmpret));
+ strlcat(tmpret, ":", FILENAME_MAX);
+ strlcat(tmpret, name, FILENAME_MAX);
}
} else if (retlen == 0) {
(*ret)[0] = 0;
+ xfree(&tmp);
+ xfree(&tmpret);
+ xfree(&name);
return 0;
}
CtoPstr(tmpret);
- memcpy(*ret, tmpret, sizeof(tmpret));
-
+ memcpy(*ret, tmpret, FILENAME_MAX);
+ xfree(&tmp);
+ xfree(&tmpret);
+ xfree(&name);
+
return 0;
}
@@ -663,10 +844,10 @@ stat(char *path, struct stat *sb)
char *ppath;
short ret;
- ppath = xstrdup(path);
+ ppath = xstrdup(path, "stat");
CtoPstr(ppath);
ret = FStat((unsigned char *)ppath, sb);
- free(ppath);
+ xfree(&ppath);
return ret;
}
@@ -698,8 +879,8 @@ FIsDir(Str255 path)
struct stat st;
short ret;
- if ((ret = FStat(path, &st)) != 0)
- return ret;
+ if (FStat(path, &st) != 0)
+ return false;
/* bit 4 is set in ioFlAttrib if the item is a directory */
if (st.st_flags & (1 << 4))
@@ -791,7 +972,7 @@ copy_file(Str255 source, Str255 dest, bool overwrite)
OSErr
copy_file_contents(short source_ref, short dest_ref)
{
- char buf[1024];
+ char *buf;
short error;
long source_size, count;
@@ -805,19 +986,24 @@ copy_file_contents(short source_ref, short dest_ref)
error = SetFPos(dest_ref, fsFromStart, 0);
if (error)
return error;
+
+ buf = xmalloc(1024, "copy_file_contents");
+
while (source_size > 0) {
- count = sizeof(buf);
+ count = 1024;
if (count > source_size)
count = source_size;
- error = FSRead(source_ref, &count, &buf);
+ error = FSRead(source_ref, &count, buf);
if (error && error != eofErr)
break;
source_size -= count;
- error = FSWrite(dest_ref, &count, &buf);
+ error = FSWrite(dest_ref, &count, buf);
if (error && error != eofErr)
break;
}
+ xfree(&buf);
+
if (error && error != eofErr)
return error;
@@ -830,7 +1016,7 @@ FSReadLine(short frefnum, char *buf, size_t buflen)
{
char tbuf;
size_t pos, fsize, rlen = 1, total_read = 0;
- short error, found = -1, i;
+ short error;
GetFPos(frefnum, &pos);
GetEOF(frefnum, &fsize);
@@ -855,6 +1041,80 @@ FSReadLine(short frefnum, char *buf, size_t buflen)
/*
+ * Gestalt functions
+ */
+char *
+gestalt_machine_type(void)
+{
+ short error;
+ long resp;
+
+ error = Gestalt(gestaltMachineType, &resp);
+ if (error)
+ return NULL;
+ switch (resp) {
+ case gestaltClassic:
+ return "Macintosh 128K";
+ case gestaltMacXL:
+ return "Macintosh XL";
+ case gestaltMac512KE:
+ return "Macintosh 512Ke";
+ case gestaltMacPlus:
+ return "Macintosh Plus";
+ case gestaltMacSE:
+ return "Macintosh SE";
+ case gestaltMacII:
+ return "Macintosh II";
+ case gestaltMacIIx:
+ return "Macintosh IIx";
+ case gestaltMacIIcx:
+ return "Macintosh IIcx";
+ case gestaltMacSE030:
+ return "Macintosh SE/30";
+ case gestaltPortable:
+ return "Macintosh Portable";
+ case gestaltMacIIci:
+ return "Macintosh IIci";
+ case gestaltMacIIfx:
+ return "Macintosh IIfx";
+ case gestaltMacClassic:
+ return "Macintosh Classic";
+ case gestaltMacIIsi:
+ return "Macintosh IIsi";
+ case gestaltMacLC:
+ return "Macintosh LC";
+ }
+
+ return NULL;
+}
+
+char *
+get_version(bool long_version)
+{
+ static char vers_s[256] = { 0 };
+ char *v;
+ VersRecHndl vers;
+ short len;
+
+ vers = (VersRecHndl)GetResource('vers', 1);
+ if (!vers)
+ return "?.?";
+
+ HLock(vers);
+ v = (char *)&(*vers)->shortVersion;
+ len = v[0];
+ if (long_version) {
+ v += len + 1;
+ len = v[0];
+ }
+ memcpy(vers_s, v, len + 1);
+ ReleaseResource(vers);
+
+ PtoCstr(vers_s);
+ return vers_s;
+}
+
+/*
* General Mac-specific GUI functions
*/
@@ -926,8 +1186,7 @@ UpdateScrollbarForTE(ControlHandle control, TEHandle t
{
size_t vlines, telines;
TERec *ter;
- short fheight, fwidth, max, val, per_page, per_line, horiz, max_chars,
- n;
+ short fheight, fwidth, max, val, per_line, horiz, max_chars, n;
HLock(te);
ter = *te;
@@ -969,8 +1228,8 @@ UpdateScrollbarForTE(ControlHandle control, TEHandle t
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++;
+ //if (telines >= vlines)
+ // telines++;
max = telines - vlines + 1;
if (max < 1)
max = 1;
@@ -989,7 +1248,13 @@ UpdateScrollbarForTE(ControlHandle control, TEHandle t
}
}
}
- SetCtlMax(control, max);
+
+ /*
+ * Avoid SetCtlMax because it will redraw and then SetCtlValue will
+ * redraw again, which can cause a jump if we're trying to keep the
+ * scrollbar position in the same place (like at the bottom).
+ */
+ (*control)->contrlMax = max;
SetCtlValue(control, val);
HUnlock(te);
@@ -1065,9 +1330,22 @@ TrackMouseDownInControl(ControlHandle control, short p
pascal bool
ModalDialogFilter(DialogPtr dlg, EventRecord *event, short *hit)
{
+ WindowPtr event_win;
+ short event_in;
char key;
switch (event->what) {
+ case mouseDown:
+ event_in = FindWindow(event->where, &event_win);
+
+ switch (event_in) {
+ case inGoAway:
+ if (TrackGoAway(dlg, event->where)) {
+ *hit = -1;
+ return true;
+ }
+ }
+ break;
case keyDown:
key = event->message & charCodeMask;
@@ -1090,7 +1368,7 @@ ModalDialogFilter(DialogPtr dlg, EventRecord *event, s
return false;
} else if (key == 13 || key == 3) {
/* OK button */
- *hit = 1;
+ *hit = OK;
return true;
}
@@ -1100,6 +1378,84 @@ ModalDialogFilter(DialogPtr dlg, EventRecord *event, s
return false;
}
+static short _password_dialog_ditl_id = -1;
+static char *_password_dialog_storage = NULL;
+static size_t _password_dialog_storage_len = 0;
+
+void
+PasswordDialogFieldFilterSetup(short ditl_id, char *storage, size_t len)
+{
+ _password_dialog_ditl_id = ditl_id;
+ _password_dialog_storage = storage;
+ _password_dialog_storage_len = len;
+
+ memset(_password_dialog_storage, 0, len);
+}
+
+pascal bool
+PasswordDialogFieldFilter(DialogPtr dlg, EventRecord *event, short *hit)
+{
+ DialogPeek dlgp;
+ short sel_start, sel_end;
+ char key;
+
+ dlgp = (DialogPeek)dlg;
+ if (dlgp->editField == _password_dialog_ditl_id - 1) {
+ sel_start = (*(dlgp->textH))->selStart;
+ sel_end = (*(dlgp->textH))->selEnd;
+
+ switch (event->what) {
+ case keyDown:
+ case autoKey:
+ key = event->message & charCodeMask;
+ if (event->modifiers & cmdKey) {
+ /* TODO: implement DlgPaste for cmd+v? */
+ event->what = nullEvent;
+ return false;
+ }
+
+ if (key == 8) {
+ /* backspace */
+ if (sel_start == sel_end && sel_start > 0)
+ memmove(_password_dialog_storage + sel_start - 1,
+ _password_dialog_storage + sel_start,
+ _password_dialog_storage_len - sel_start - 1);
+ else if (sel_start != sel_end)
+ memmove(_password_dialog_storage + sel_start,
+ _password_dialog_storage + sel_end,
+ _password_dialog_storage_len - sel_end - 1);
+ } else if (sel_start >= _password_dialog_storage_len) {
+ event->what = nullEvent;
+ return false;
+ } else if (key >= ' ' && key <= '~') {
+ if (sel_start != sel_end)
+ /* delete selection before making space for new char */
+ memmove(_password_dialog_storage + sel_start,
+ _password_dialog_storage + sel_end,
+ _password_dialog_storage_len - sel_end - 1);
+ memmove(_password_dialog_storage + sel_start + 1,
+ _password_dialog_storage + sel_start,
+ _password_dialog_storage_len - sel_start - 1);
+ _password_dialog_storage[sel_start] = key;
+ event->message = '•';
+ }
+ _password_dialog_storage[(*(dlgp->textH))->teLength + 1] = '\0';
+ sel_start = 0;
+ break;
+ }
+ }
+
+ return ModalDialogFilter(dlg, event, hit);
+}
+
+void
+PasswordDialogFieldFinish(void)
+{
+ _password_dialog_ditl_id = -1;
+ _password_dialog_storage = NULL;
+ _password_dialog_storage_len = 0;
+}
+
/* (*(some_te))->caretHook = NullCaretHook; */
pascal void
NullCaretHook(void)
@@ -1108,4 +1464,60 @@ NullCaretHook(void)
move.l (a7)+,d0
rts
}
-}
+}
+
+static bool menu_bar_hidden = false;
+static short old_mbar_height;
+static Rect mbar_rect;
+static RgnHandle mbar_save_region;
+
+void
+HideMenuBar(void)
+{
+ RgnHandle mbar_region;
+ WindowPeek win;
+
+ old_mbar_height = GetMBarHeight();
+ SetRect(&mbar_rect, screenBits.bounds.left, screenBits.bounds.top,
+ screenBits.bounds.right, screenBits.bounds.top + old_mbar_height);
+
+ mbar_save_region = NewRgn();
+ mbar_region = NewRgn();
+
+ MBarHeight = 0;
+ CopyRgn(GetGrayRgn(), mbar_save_region);
+ RectRgn(mbar_region, &mbar_rect);
+ UnionRgn(GetGrayRgn(), mbar_region, GetGrayRgn());
+
+ win = (WindowPeek)FrontWindow();
+ PaintOne(win, mbar_region);
+ PaintBehind(win, mbar_region);
+ CalcVis(win);
+ CalcVisBehind(win, mbar_region);
+ DisposeRgn(mbar_region);
+
+ menu_bar_hidden = true;
+}
+
+void
+RestoreHiddenMenuBar(void)
+{
+ WindowPeek win;
+
+ if (!menu_bar_hidden)
+ return;
+
+ CopyRgn(mbar_save_region, GetGrayRgn());
+ MBarHeight = old_mbar_height;
+
+ RectRgn(mbar_save_region, &mbar_rect);
+ win = (WindowPeek)FrontWindow();
+ CalcVis(win);
+ CalcVisBehind(win, mbar_save_region);
+ DisposeRgn(mbar_save_region);
+
+ menu_bar_hidden = false;
+
+ HiliteMenu(0);
+ DrawMenuBar();
+}
--- util.h Tue Aug 16 21:24:22 2022
+++ util.h Thu Aug 18 22:36:49 2022
@@ -17,11 +17,13 @@
#ifndef __UTIL_H__
#define __UTIL_H__
-#include <stddef.h>
#include <stdlib.h>
#include <limits.h>
#include <time.h>
+#define MALLOC_DEBUG
+#define MALLOC_NOTE_SIZE 32
+
#ifndef SIZE_MAX
#define SIZE_MAX ULONG_MAX
#endif
@@ -42,28 +44,43 @@
} \
}
+#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
+
typedef struct {
short push[2], rts;
void *addr;
} tCodeStub;
-typedef struct stat {
+struct stat {
short st_mode;
ssize_t st_size;
time_t st_ctime;
@@ -71,20 +88,24 @@ typedef struct stat {
unsigned char st_flags;
};
-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 *);
+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);
+
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);
+const char * ordinal(unsigned short n);
+size_t rtrim(char *str, char *chars);
long strpos_quoted(char *str, char c);
-char *OSTypeToString(OSType type);
+char * OSTypeToString(OSType type);
unsigned long xorshift32(void);
@@ -102,12 +123,11 @@ void window_rect(WindowPtr win, Rect *ret);
Handle xNewHandle(size_t size);
Handle xGetResource(ResType type, short id);
StringHandle xGetString(short id);
-char *xGetStringAsChar(short id);
+char * xGetStringAsChar(short id);
long xGetStringAsLong(short id);
void xSetHandleSize(Handle h, Size s);
-short getpath(const short vRefNum, const 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);
@@ -115,6 +135,9 @@ OSErr copy_file(Str255 source, Str255 dest, bool overw
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);
@@ -123,6 +146,13 @@ 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);
#endif