AmendHub

jcs

/

amend

/

amendments

/

92

*: Bring in util from Subtext with malloc debugging, integrate it


jcs made amendment 92 about 1 month 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