commit 2146dc795d02ea5cc0c4ae891b3052611bb725cf Author: Kelvin Sherlock Date: Thu Jul 19 21:06:32 2018 -0400 first diff --git a/GNUmakefile b/GNUmakefile new file mode 100644 index 0000000..86a3ae1 --- /dev/null +++ b/GNUmakefile @@ -0,0 +1,18 @@ + +OBJ = o/rlint.a o/menu.a o/control.a + + +rlint : $(OBJ) + $(RM) o/menu.root o/control.root + iix link o/rlint o/menu o/control keep=$@ + + +o/rlint.a : rlint.c rlint.h +o/menu.a : menu.c rlint.h +o/control.a : control.c rlint.h + +o : + mkdir $@ + +o/%.a : %.c | o + iix compile $< keep=o/$* \ No newline at end of file diff --git a/control.c b/control.c new file mode 100644 index 0000000..960068d --- /dev/null +++ b/control.c @@ -0,0 +1,188 @@ +#include +#include +#include + +#include "rlint.h" + +void check_rControlList(Handle h) { + unsigned i; + Ref *list = *(Ref **)h; + + for(i = 0; ; ++i) { + Ref ref = list[i]; + if (!ref) break; + check(rControl, ref, check_rControl); + } +} + +void check_rControlTemplate(Handle h) { + + ControlTemplate *ptr = *(ControlTemplate **)h; + Ref ref; + unsigned moreFlags = ptr->moreFlags; + + if (ptr->procRef == simpleButtonControl) { + ref = (SimpleButtonTemplate *)ptr->titleRef; + if ((moreFlags & 0x03) == titleIsResource) + check(rPString, ref, check_rPString); + + ref = (SimpleButtonTemplate *)ptr->colorTableRef; + if ((moreFlags & 0x0c) == colorTableIsResource) + check(rCtlColorTbl, ref, check_rCtlColorTbl); + + return; + } + + if (ptr->procRef == checkControl) { + + ref = (CheckBoxTemplate *)ptr->titleRef; + if ((moreFlags & 0x03) == titleIsResource) + check(rPString, ref, check_rPString); + + ref = (CheckBoxTemplate *)ptr->colorTableRef; + if ((moreFlags & 0x0c) == colorTableIsResource) + check(rCtlColorTbl, ref, check_rCtlColorTbl); + + return; + } + + if (ptr->procRef == radioControl) { + + ref = (RadioButtonTemplate *)ptr->titleRef; + if ((moreFlags & 0x03) == titleIsResource) + check(rPString, ref, check_rPString); + + ref = (RadioButtonTemplate *)ptr->colorTableRef; + if ((moreFlags & 0x0c) == colorTableIsResource) + check(rCtlColorTbl, ref, check_rCtlColorTbl); + + return; + } + + if (ptr->procRef == scrollBarControl) { + + ref = (ScrollBarTemplate *)ptr->colorTableRef; + if ((moreFlags & 0x0c) == colorTableIsResource) + check(rCtlColorTbl, ref, check_rCtlColorTbl); + + return; + } + + + if (ptr->procRef == iconButtonControl) { + + ref = (IconButtonTemplate *)ptr->titleRef; + if ((moreFlags & 0x03) == titleIsResource) + check(rPString, ref, check_rPString); + + ref = (IconButtonTemplate *)ptr->colorTableRef; + if ((moreFlags & 0x0c) == colorTableIsResource) + check(rCtlColorTbl, ref, check_rCtlColorTbl); + + ref = (IconButtonTemplate *)ptr->iconRef; + if ((moreFlags & 0x30) == 0x20) + check(rIcon, ref, check_rIcon); + + return; + } + + if (ptr->procRef == scrollBarControl) { + + ref = (LineEditTemplate *)ptr->defaultRef; + if ((moreFlags & 0x03) == titleIsResource) + check(rPString, ref, check_rPString); + + return; + } + + if (ptr->procRef == listControl) { + + ref = (ListTemplate *)ptr->listRef; + if ((moreFlags & 0x03) == titleIsResource) + check(rListRef, ref, check_rListRef); + + ref = (ListTemplate *)ptr->colorTableRef; + if ((moreFlags & 0x0c) == colorTableIsResource) + check(rCtlColorTbl, ref, check_rCtlColorTbl); + + return; + } + + if (ptr->procRef == pictureControl) { + + ref = (PictureTemplate *)ptr->pictureRef; + if ((moreFlags & 0x03) == titleIsResource) + check(rPicture, ref, check_rPicture); + + return; + } + + if (ptr->procRef == popUpControl) { + + ref = (PopupTemplate *)ptr->menuRef; + if ((moreFlags & 0x07) == titleIsResource) + check(rMenu, ref, check_rMenu); + + ref = (PopupTemplate *)ptr->colorTableRef; + if ((moreFlags & 0x18) == 0x10) + check(rCtlColorTbl, ref, check_rCtlColorTbl); + + return; + } + + + if (ptr->procRef == growControl) { + + ref = (SizeBoxTemplate *)ptr->colorTableRef; + if ((moreFlags & 0x0c) == colorTableIsResource) + check(rCtlColorTbl, ref, check_rCtlColorTbl); + + return; + } + + + if (ptr->procRef == statTextControl) { + + ref = (StaticTextTemplate *)ptr->textRef; + if ((moreFlags & 0x03) == titleIsResource) + check(rTextForLETextBox2, ref, check_rTextForLETextBox2); + + return; + } + + + if (ptr->procRef == editTextControl) { + + ref = (TextEditTemplate *)ptr->styleRef; + if ((moreFlags & 0x03) == titleIsResource) + check(rStyleBlock, ref, check_rStyleBlock); + + ref = (TextEditTemplate *)ptr->colorRef; + if ((moreFlags & 0x0c) == colorTableIsResource) + check(rCtlColorTbl, ref, check_rCtlColorTbl); + + return; + } + +} + + +void check_rWindParam1(Handle h) { + WindParam1 *ptr = *(WindParam1 **)h; + Ref ref; + unsigned desc = ptr->p1InDesc; + + ref = ptr->p1Title; + if (desc & 0x0200) check(rPString, ref, check_rPString); + + ref = ptr->p1ColorTable; + if (desc & 0x0800) check(rWindColor, ref, check_rWindColor); + + ref = ptr->p1ControlList; + switch(desc & 0xff) { + case singleResource: check(rControlTemplate, ref, check_rControlTemplate); break; + case resourceToResource: check(rControlList, ref, check_rControlList); break; + default: /* warn about invalid value ? */ + } + +} diff --git a/menu.c b/menu.c new file mode 100644 index 0000000..8bdaf2f --- /dev/null +++ b/menu.c @@ -0,0 +1,80 @@ +#include +#include + +#include "rlint.h" + + + + +void check_rMenuItem(Handle h) { + + MenuItemTemplate *mi; + Ref ref; + + mi = *(MenuItemTemplate **)h; + ref = mi->itemTitleRef; + + if (mi->itemFlag & 0x0400) { + if (mi->itemFlag & 0x200) { + if (ref) check(rItemStruct, ref, check_rItemStruct); + } + } + else if (mi->itemFlag & mRefResource) { + if (ref) check(rPString, ref, check_rPString); + } +} + +void check_rMenu(Handle h) { + + MenuTemplate *m; + unsigned i; + Ref ref; + + m = *(MenuTemplate **)h; + if (m->menuFlag & mRefResource) { + ref = m->menuTitleRef; + if (ref) check(rPString, ref, check_rPString); + } + if (m->menuFlag & 0x2000) { + for (i = 0; ; ++i) { + ref = m->itemRefArray[i]; + if (!ref) break; + check(rMenuItem, ref, check_rMenuItem); + } + } +} + + +void check_rMenuBar(Handle h) { + + MenuBarTemplate *mb; + unsigned i; + + mb = *(MenuBarTemplate **)h; + if (mb->menuFlag & mRefResource) { + for (i = 0; ; ++i) { + Ref ref = mb->menuRefArray[i]; + if (!ref) break; + check(rMenu, ref, check_rMenu); + } + } +} + + +void check_rItemStruct(Handle h) { + + itemStruct *ptr; + Ref ref; + + ptr = *(itemStruct **)h; + if (ptr->itemFlag2 & mRefResource) { + ref = ptr->itemTitleRef; + if (ref) check(rPString, ref, check_rPString); + ref = ptr->itemIconRef; + if (ref) check(rIcon, ref, check_rIcon); + + } +} + + + diff --git a/rlint.c b/rlint.c new file mode 100644 index 0000000..34d0547 --- /dev/null +++ b/rlint.c @@ -0,0 +1,259 @@ +#include +//#include +#include +//#include +#include + +#include +#include + + +#include "rlint.h" + + +struct { + ResType type; + ResID id; +} history[10]; +unsigned level; +unsigned error_count; + + + +char *ResName(ResType type) { + static char buffer[6] = { '$', 'x', 'x', 'x', 'x', 0 }; + static char hex[] = "0123456789abcdef"; + + switch(type) { + case rIcon: return "rIcon"; + case rPicture: return "rPicture"; + case rControlList: return "rControlList"; + case rControlTemplate: return "rControlTemplate"; + case rC1InputString: return "rC1InputString"; + case rPString: return "rPString"; + case rStringList: return "rStringList"; + case rMenuBar: return "rMenuBar"; + case rMenu: return "rMenu"; + case rMenuItem: return "rMenuItem"; + case rTextForLETextBox2: return "rTextForLETextBox2"; + case rCtlDefProc: return "rCtlDefProc"; + case rCtlColorTbl: return "rCtlColorTbl"; + case rWindParam1: return "rWindParam1"; + case rWindParam2: return "rWindParam2"; + case rWindColor: return "rWindColor"; + case rTextBlock: return "rTextBlock"; + case rStyleBlock: return "rStyleBlock"; + case rToolStartup: return "rToolStartup"; + case rResName: return "rResName"; + case rAlertString: return "rAlertString"; + case rText: return "rText"; + case rCodeResource: return "rCodeResource"; + case rCDEVCode: return "rCDEVCode"; + case rCDEVFlags: return "rCDEVFlags"; + case rTwoRects: return "rTwoRects"; + case rFileType: return "rFileType"; + case rListRef: return "rListRef"; + case rCString: return "rCString"; + case rXCMD: return "rXCMD"; + case rXFCN: return "rXFCN"; + case rErrorString: return "rErrorString"; + case rKTransTable: return "rKTransTable"; + case rWString: return "rWString"; + case rC1OutputString: return "rC1OutputString"; + case rSoundSample: return "rSoundSample"; + case rTERuler: return "rTERuler"; + case rFSequence: return "rFSequence"; + case rCursor: return "rCursor"; + case rItemStruct: return "rItemStruct"; + case rVersion: return "rVersion"; + case rComment: return "rComment"; + case rBundle: return "rBundle"; + case rFinderPath: return "rFinderPath"; + case rPaletteWindow: return "rPaletteWindow"; + case rTaggedStrings: return "rTaggedStrings"; + case rPatternList: return "rPatternList"; + case rRectList: return "rRectList"; + case rPrintRecord: return "rPrintRecord"; + case rFont: return "rFont"; + } + buffer[1] = hex[(type >> 12) & 0x0f]; + buffer[2] = hex[(type >> 8) & 0x0f]; + buffer[3] = hex[(type >> 4) & 0x0f]; + buffer[4] = hex[(type >> 0) & 0x0f]; + return buffer; +} + +void error(const char *msg) { + unsigned i; + for (i = 0; i < level; ++i) { + fprintf(stderr, "%s:%08lx -> ", ResName(history[i].id), history[i].type); + } + fputs(msg, stderr); + fputs("\n", stderr); + ++error_count; +} + + + + + +void check_rStringList(Handle h){ + + typedef struct StringList { + unsigned count; + Ref strings[1]; + } StringList; + + StringList *ptr = *(StringList **)h; + unsigned i; + for (i = 0; i < ptr->count; ++i) { + Ref ref = ptr->strings[i]; + if (ref) check(rPString, ref, check_rPString); + } + +} + + +void check(ResType type, ResID id, void (*callback)(Handle)) { + + Handle h; + + + history[level].type = type; + history[level].id = id; + ++level; + + if (id == 0) { + error("Invalid resource ID"); + return; + } + + h = LoadResource(type, id); + if (_toolErr) { + error("Unable to load Resource"); + return; + } + + if (callback) { + HLock(h); + callback(h); + HUnlock(h); + } + ReleaseResource(type, id, -1); + --level; +} + + + +unsigned flag_v = 0; + +void usage(int rv) { + fputs("rlint [-v] file [...]\n", stderr); + exit(rv); +} + +GSString255Ptr c2gs(const char *cp) { + GSString255Ptr gs; + int l = strlen(cp); + gs = malloc(l + 3); + if (gs) { + gs->length = l; + strcpy(gs->text, cp); + } + return gs; +} + + + +void one_file(const char *name) { + GSString255Ptr gname; + unsigned rfd; + unsigned depth; + unsigned ti; + unsigned long ri; + + gname = c2gs(name); + + rfd = OpenResourceFile(0x8000 | readEnable, NULL, (Pointer)gname); + if (_toolErr) { + ++error_count; + fprintf(stderr, "%s: OpenResourceFile: $%04x\n", name); + free(gname); + return; + } + + depth = SetResourceFileDepth(1); + + /* now iterate through all resource types... */ + for (ti = 1; ; ++ti) { + void (*callback)(Handle) = 0; + ResType type = GetIndType(ti); + if (_toolErr == resIndexRange) break; + if (_toolErr) { + fprintf(stderr, "%s: GetIndType: $%04x\n", name, _toolErr); + continue; + } + + switch(type) { + case rMenu: callback = check_rMenu; break; + case rMenuItem: callback = check_rMenuItem; break; + case rMenuBar: callback = check_rMenuBar; break; + case rItemStruct: callback = check_rItemStruct; break; + case rControlList: callback = check_rControlList; break; + case rControlTemplate: callback = check_rControlTemplate; break; + case rWindParam1: callback = check_rWindParam1; break; + case rStringList: callback = check_rStringList; break; + default: callback = 0; + } + + for (ri = 1; ; ++ri) { + ResID id = GetIndResource(type, ri); + if (_toolErr == resIndexRange) break; + if (_toolErr) { + fprintf(stderr, "%s: GetIndResource: $%04x\n", name, _toolErr); + continue; + } + check(type, id, callback); + } + } + + + + SetResourceFileDepth(depth); + CloseResourceFile(rfd); + free(gname); +} + +int main(int argc, char **argv) { + + int c; + unsigned i; +/* + for((c = getopt(argc, argv, "hv")) != -1) { + + switch(c) { + case 'v': flag_v = 1; + case 'h': + usage(0); + case '?' + case ':' + usage(1); + } + } + argv += optind; + argc -= optind; +*/ + argv++; + argc--; + if (argc == 0) usage(0); + + + ResourceStartUp(MMStartUp()); + for (i = 0; i < argc; ++i) { + one_file(argv[i]); + } + ResourceShutDown(); + + if (error_count) return 1; + return 0; +} \ No newline at end of file