From d1f153d34b023d81768f6087f67dbfff714bafc9 Mon Sep 17 00:00:00 2001
From: Ash Wolf <ninji@wuffs.org>
Date: Wed, 19 Oct 2022 21:16:13 +0100
Subject: let's commit all this before my VM blows up and nukes my work

---
 .../Src/Callbacks/CLCompilerLinkerDropin_V10.cpp   |  663 +++++++++-
 .../Src/Callbacks/CLDropinCallbacks_V10.cpp        | 1353 +++++++++++++++++++-
 .../CmdLine/Src/Callbacks/CLParserCallbacks_v1.cpp |  233 +++-
 3 files changed, 2161 insertions(+), 88 deletions(-)

(limited to 'command_line/CmdLine/Src/Callbacks')

diff --git a/command_line/CmdLine/Src/Callbacks/CLCompilerLinkerDropin_V10.cpp b/command_line/CmdLine/Src/Callbacks/CLCompilerLinkerDropin_V10.cpp
index 5861e94..070bc07 100644
--- a/command_line/CmdLine/Src/Callbacks/CLCompilerLinkerDropin_V10.cpp
+++ b/command_line/CmdLine/Src/Callbacks/CLCompilerLinkerDropin_V10.cpp
@@ -1,27 +1,636 @@
-/**
- P   1F458 | _UCBCachePrecompiledHeader
- P   1F4F8 | _UCBLoadObjectData
- P   1F5BC | _UCBStoreObjectData
- P   1F860 | _UCBFreeObjectData
- P   1F90C | _UCBDisplayLines
- P   1F980 | _UCBBeginSubCompile
- P   1F9F0 | _UCBEndSubCompile
- P   1FA60 | _UCBGetPrecompiledHeaderSpec
- P   1FD38 | _UCBGetResourceFile
- P   1FDA8 | _UCBPutResourceFile
-     1FE18 | _UnitNameToSBMName__FP6OSSpecP4File
- P   1FEA0 | _UCBLookUpUnit
- P   20544 | _UCBSBMfiles
- P   20594 | _UCBStoreUnit
- P   20848 | _UCBReleaseUnit
- P   208C8 | _UCBUnitNameToFileName
- P   20978 | _UCBOSAlert
- P   20A50 | _UCBOSErrorMessage
- P   20B38 | _UCBGetModifiedFiles
- P   20BBC | _UCBGetSuggestedObjectFileSpec
- P   20C78 | _UCBGetStoredObjectFileSpec
- P   20D4C | _UCBGetFrameworkCount
- P   20DB0 | _UCBGetFrameworkInfo
- P   20E48 | ___ct__23CWCompilerLinkerContextFv
- P   20FEC | ___dt__23CWCompilerLinkerContextFv
-*/
+#include "cmdline.h"
+#include "plugin_internal.h"
+
+extern char STSbuf[256];
+
+CWResult UCBCachePrecompiledHeader(CWPluginContext context, const CWFileSpec *filespec, CWMemHandle pchhandle) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBCachePrecompiledHeader");
+
+    OSSpec spec;
+    Handle handle;
+    OS_FSSpec_To_OSSpec(filespec, &spec);
+    UCBSecretDetachHandle(context, pchhandle, &handle);
+    CacheIncludeFile(&spec, handle, 1);
+    return cwNoErr;
+}
+
+CWResult UCBLoadObjectData(CWPluginContext context, SInt32 whichfile, CWMemHandle *objectdata) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBLoadObjectData");
+
+    File *file = Files_GetFile(&gTarg->files, whichfile);
+    if (!file)
+        return cwErrUnknownFile;
+
+    if (file->objectdata) {
+        UCBSecretAttachHandle(context, file->objectdata, objectdata);
+        return cwNoErr;
+    } else {
+        return cwErrRequestFailed;
+    }
+}
+
+CWResult UCBStoreObjectData(CWPluginContext context, SInt32 whichfile, CWObjectData *object) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBStoreObjectData");
+
+    if (CheckForUserBreak())
+        return cwErrUserCanceled;
+
+    File *filedata = Files_GetFile(&gTarg->files, whichfile);
+    if (!filedata)
+        return cwErrUnknownFile;
+
+    if (!object->objectfile) {
+        Handle objecthand;
+        Handle browsehand;
+        UCBSecretDetachHandle(context, object->objectdata, &objecthand);
+        UCBSecretDetachHandle(context, object->browsedata, &browsehand);
+        filedata->objectdata = objecthand;
+        filedata->browsedata = browsehand;
+        UCBSecretAttachHandle(context, objecthand, &object->objectdata);
+        UCBSecretAttachHandle(context, browsehand, &object->browsedata);
+    } else {
+        if (filedata->outfileowner && filedata->outfileowner != CmdLineStageMask_Cg) {
+#line 240
+            DO_INTERNAL_ERROR("Cannot store object file spec for '%s'\n", filedata->srcfilename);
+        }
+        OS_FSSpec_To_OSSpec(object->objectfile, &filedata->outfss);
+        filedata->wroteToDisk |= CmdLineStageMask_Cg;
+    }
+
+    filedata->codesize = object->codesize;
+    filedata->udatasize = object->udatasize;
+    filedata->idatasize = object->idatasize;
+    filedata->compiledlines = object->compiledlines;
+    if (filedata->dropinflags & kGeneratesrsrcs)
+        filedata->hasresources = 1;
+    else
+        filedata->hasobjectcode = 1;
+    filedata->recompileDependents = object->dependencyCount && object->interfaceChanged;
+    OS_GetTime(&filedata->outmoddate);
+    if (object->reserved1)
+        filedata->filetype = object->reserved1;
+
+    if (object->reserved2) {
+        char *newname = reinterpret_cast<char *>(object->reserved2);
+        CWFileInfo fi;
+        if (OS_MakeSpec(newname, &filedata->srcfss, NULL) || OS_Status(&filedata->srcfss)) {
+            fi.fullsearch = 1;
+            fi.dependencyType = cwNoDependency;
+            fi.isdependentoffile = -1;
+            fi.suppressload = 1;
+            if (UCBFindAndLoadFile(context, newname, &fi) == cwNoErr) {
+                OS_FSSpec_To_OSSpec(&fi.filespec, &filedata->srcfss);
+            } else {
+                char *fnptr = OS_GetFileNamePtr(newname);
+                if (fnptr != newname) {
+                    fi.fullsearch = 1;
+                    fi.dependencyType = cwNoDependency;
+                    fi.isdependentoffile = -1;
+                    fi.suppressload = 1;
+                    if (UCBFindAndLoadFile(context, fnptr, &fi) == cwNoErr) {
+                        OS_FSSpec_To_OSSpec(&fi.filespec, &filedata->srcfss);
+                    }
+                }
+            }
+        }
+    }
+
+    return cwNoErr;
+}
+
+CWResult UCBFreeObjectData(CWPluginContext context, SInt32 whichfile, CWMemHandle objectdata) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBFreeObjectData");
+
+    File *file = Files_GetFile(&gTarg->files, whichfile);
+    if (!file)
+        return cwErrUnknownFile;
+
+    if (file->objectdata) {
+        DisposeHandle(file->objectdata);
+        file->objectdata = NULL;
+        return cwNoErr;
+    } else {
+        return cwErrInvalidParameter;
+    }
+}
+
+CWResult UCBDisplayLines(CWPluginContext context, SInt32 nlines) {
+    ShowWorking(12);
+
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBDisplayLines");
+
+    if (CheckForUserBreak())
+        return cwErrUserCanceled;
+    else
+        return cwNoErr;
+}
+
+CWResult UCBBeginSubCompile(CWPluginContext context, SInt32 whichfile, CWPluginContext *subContext) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBBeginSubCompile");
+
+#line 372
+    DO_INTERNAL_ERROR("UCBBeginSubCompile not implemented");
+    return cwErrRequestFailed;
+}
+
+CWResult UCBEndSubCompile(CWPluginContext subContext) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBEndSubCompile");
+
+#line 384
+    DO_INTERNAL_ERROR("UCBEndSubCompile not implemented");
+    return cwErrRequestFailed;
+}
+
+CWResult UCBGetPrecompiledHeaderSpec(CWPluginContext context, CWFileSpec *pchspec, const char *intarget) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBGetPrecompiledHeaderSpec");
+
+    CWCompilerLinkerContext *c;
+    int err;
+    OSSpec outfss;
+    File *file;
+    const CWObjectFlags *cof;
+    char target[256];
+
+    if (context->pluginType == CWDROPINCOMPILERTYPE || context->pluginType == CWDROPINLINKERTYPE)
+        c = static_cast<CWCompilerLinkerContext *>(context);
+    else
+        return cwErrInvalidCallback;
+
+    file = Files_GetFile(&gTarg->files, c->whichfile);
+#line 420
+    OPTION_ASSERT(file != NULL);
+
+    cof = Plugin_CL_GetObjectFlags(file->compiler);
+    if (!file->outfilename[0]) {
+        if (intarget) {
+            if (optsCompiler.canonicalIncludes)
+                strcpy(target, intarget);
+            else if (OS_CanonPath(intarget, target) != noErr)
+                return cwErrInvalidParameter;
+
+            err = OS_MakeSpecWithPath(&file->srcfss.path, target, 0, &outfss);
+            if (err) {
+                CLReportOSError(CLStr97, err, target);
+                return cwErrRequestFailed;
+            }
+
+            if (!file->outfileowner || file->outfileowner == CmdLineStageMask_Cg) {
+                file->outfileowner = CmdLineStageMask_Cg;
+                OS_SpecToStringRelative(&outfss, NULL, file->outfilename, sizeof(file->outfilename));
+            }
+
+            if (optsCmdLine.verbose)
+                CLReport(CLStr16, "precompiled ", OS_SpecToStringRelative(&outfss, NULL, STSbuf, sizeof(STSbuf)));
+        } else {
+            OS_MakeSpecWithPath(&gTarg->outputDirectory, file->srcfilename, optsCompiler.relPathInOutputDir == 0, &outfss);
+            OS_NameSpecSetExtension(&outfss.name, optsCompiler.pchFileExt[0] ? optsCompiler.pchFileExt : cof->pchFileExt);
+
+            if (!file->outfileowner || file->outfileowner == CmdLineStageMask_Cg) {
+                file->outfileowner = CmdLineStageMask_Cg;
+                OS_NameSpecToString(&outfss.name, file->outfilename, sizeof(file->outfilename));
+            }
+
+            CLReport(CLStr59, OS_SpecToStringRelative(&outfss, NULL, STSbuf, sizeof(STSbuf)));
+        }
+
+        OS_OSSpec_To_FSSpec(&outfss, pchspec);
+    } else {
+        err = OS_MakeSpecWithPath(&gTarg->outputDirectory, file->outfilename, 0, &outfss);
+        if (err) {
+            CLReportOSError(CLStr97, err, file->outfilename);
+            return cwErrRequestFailed;
+        }
+
+        OS_OSSpec_To_FSSpec(&outfss, pchspec);
+
+        if (intarget)
+            CLReport(CLStr60, OS_SpecToStringRelative(&outfss, NULL, STSbuf, sizeof(STSbuf)), intarget);
+    }
+
+    return cwNoErr;
+}
+
+CWResult UCBGetResourceFile(CWPluginContext context, CWFileSpec *filespec) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBGetResourceFile");
+
+#line 514
+    DO_INTERNAL_ERROR("UCBGetResourceFile not implemented");
+    return cwErrRequestFailed;
+}
+
+CWResult UCBPutResourceFile(CWPluginContext context, const char *prompt, const char *name, CWFileSpec *filespec) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBPutResourceFile");
+
+#line 529
+    DO_INTERNAL_ERROR("UCBPutResourceFile not implemented");
+    return cwErrRequestFailed;
+}
+
+static int UnitNameToSBMName(OSSpec *spec, File *srcfile) {
+    const CWObjectFlags *cof;
+    int err;
+
+    cof = Plugin_CL_GetObjectFlags(srcfile->compiler);
+    err = OS_NameSpecChangeExtension(
+            &spec->name,
+            cof->pchFileExt ? cof->pchFileExt : ".sbm",
+            cof->pchFileExt ? (cof->pchFileExt[0] == '.') : 0
+            );
+    return err;
+}
+
+CWResult UCBLookUpUnit(CWPluginContext context, const char *name, Boolean isdependency, const void **unitdata, SInt32 *unitdatalength) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBLookUpUnit");
+
+    CWFileInfo includeinfo;
+    OSSpec unitspec;
+    OSSpec sbmspec;
+    time_t unittime;
+    UInt32 unitmactime;
+    char sbmpath[256];
+    int err;
+    CWCompilerLinkerContext *c;
+    File *srcfile;
+    File *sbmfile;
+
+    if (context->pluginType == CWDROPINCOMPILERTYPE || context->pluginType == CWDROPINLINKERTYPE)
+        c = static_cast<CWCompilerLinkerContext *>(context);
+    else
+        return cwErrInvalidCallback;
+
+    srcfile = Files_GetFile(&gTarg->files, c->whichfile);
+#line 591
+    OPTION_ASSERT(srcfile != NULL);
+
+    *unitdata = NULL;
+    *unitdatalength = 0;
+
+    if (optsCompiler.sbmState == OptsCompilerSbmState_1 || optsCompiler.sbmState == OptsCompilerSbmState_3) {
+        if (clState.pluginDebug)
+            CLPrint("UCBLookUpUnit:  sbmState == sbmRebuild or sbmClean; failing\n");
+        return cwErrSBMNotFound;
+    }
+
+    includeinfo.fullsearch = 1;
+    includeinfo.dependencyType = isdependency ? cwNormalDependency : cwNoDependency;
+    includeinfo.isdependentoffile = -1;
+    includeinfo.suppressload = 1;
+    if (UCBFindAndLoadFile(context, name, &includeinfo) != cwNoErr) {
+        if (clState.pluginDebug)
+            CLPrint("UCBLookUpUnit:  could not find source '%s'; failing\n", name);
+        return cwErrFileNotFound;
+    }
+
+    OS_FSSpec_To_OSSpec(&includeinfo.filespec, &unitspec);
+    sbmspec = unitspec;
+    err = UnitNameToSBMName(&sbmspec, srcfile);
+    if (err) {
+        if (clState.pluginDebug)
+            CLPrint("UCBLookUpUnit:  could not make precompiled unit spec for '%s' (%s)\n", name, OS_GetErrText(err));
+        return cwErrRequestFailed;
+    }
+
+    if (optsCompiler.sbmPath[0]) {
+        sbmspec.path = clState.sbmPathSpec;
+        OS_SpecToString(&sbmspec, sbmpath, sizeof(sbmpath));
+        if (clState.pluginDebug)
+            CLPrint("UCBLookUpUnit:  Only looking at '%s'\n", sbmpath);
+    } else {
+        OS_NameSpecToString(&sbmspec.name, sbmpath, sizeof(sbmpath));
+        if (clState.pluginDebug)
+            CLPrint("UCBLookUpUnit:  searching paths for '%s'\n", sbmpath);
+    }
+
+    includeinfo.fullsearch = 1;
+    includeinfo.dependencyType = isdependency ? cwNormalDependency : cwNoDependency;
+    includeinfo.isdependentoffile = -1;
+    includeinfo.suppressload = 0;
+    if (UCBFindAndLoadFile(context, sbmpath, &includeinfo) != cwNoErr || !includeinfo.filedata) {
+        if (clState.pluginDebug)
+            CLPrint("UCBLookUpUnit:  could not find or load precompiled unit file '%s'; failing\n", sbmpath);
+        return cwErrFileNotFound;
+    }
+
+    OS_FSSpec_To_OSSpec(&includeinfo.filespec, &sbmspec);
+    if (includeinfo.filedatatype != cwFileTypePrecompiledHeader) {
+        CLPrint("UCBLookUpUnit:  file '%s' does not appear to be precompiled\n", OS_SpecToString(&sbmspec, STSbuf, sizeof(STSbuf)));
+        UCBReleaseFileText(context, includeinfo.filedata);
+        return cwErrRequestFailed;
+    }
+
+    OS_GetFileTime(&unitspec, NULL, &unittime);
+    OS_TimeToMac(unittime, &unitmactime);
+    if (unitmactime != *reinterpret_cast<const UInt32 *>(includeinfo.filedata)) {
+        if (clState.pluginDebug)
+            CLPrint(
+                    "UCBLookUpUnit:  file '%s' does not have internal timestamp that matches source unit's timestamp (0x%8x != 0x%8x)\n",
+                    OS_SpecToString(&sbmspec, STSbuf, sizeof(STSbuf)),
+                    unitmactime,
+                    *reinterpret_cast<const UInt32 *>(includeinfo.filedata));
+        UCBReleaseFileText(context, includeinfo.filedata);
+        return cwErrRequestFailed;
+    }
+
+    sbmfile = Files_FindFile(&gTarg->pchs, &sbmspec);
+    if (!sbmfile) {
+        sbmfile = File_New();
+        sbmfile->srcfss = unitspec;
+        OS_SpecToString(&sbmfile->srcfss, sbmfile->srcfilename, sizeof(sbmfile->srcfilename));
+        sbmfile->outfss = sbmspec;
+        OS_SpecToString(&sbmfile->outfss, sbmfile->outfilename, sizeof(sbmfile->outfilename));
+        sbmfile->compiler = srcfile->compiler;
+        sbmfile->outfileowner = CmdLineStageMask_Cg;
+        sbmfile->writeToDisk = srcfile->writeToDisk;
+        sbmfile->dropinflags = srcfile->dropinflags;
+        sbmfile->objectflags = srcfile->objectflags;
+        sbmfile->mappingflags = srcfile->mappingflags;
+        Deps_Initialize(&sbmfile->deps, &gTarg->incls);
+        if (!Files_AddFile(&gTarg->pchs, sbmfile))
+            return cwErrRequestFailed;
+    }
+
+    if (clState.pluginDebug)
+        CLPrint("UCBLookUpUnit:  success for '%s'\n", name);
+
+    if (optsCmdLine.verbose)
+        CLReport(CLStr62, "unit symbol table", OS_SpecToStringRelative(&sbmspec, NULL, STSbuf, sizeof(STSbuf)));
+
+    *unitdata = includeinfo.filedata;
+    *unitdatalength = includeinfo.filedatalength;
+    return cwNoErr;
+}
+
+CWResult UCBSBMfiles(CWPluginContext context, short libref) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBSBMfiles");
+    return cwNoErr;
+}
+
+CWResult UCBStoreUnit(CWPluginContext context, const char *inunitname, CWMemHandle unitdata, CWDependencyTag dependencytag) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBStoreUnit");
+
+    char unitname[256];
+    OSSpec sbmspec;
+    int err;
+    Handle h;
+    OSHandle unithand;
+    OSFileHandle fhand;
+    CWCompilerLinkerContext *c;
+    File *srcfile;
+
+    if (optsCompiler.canonicalIncludes) {
+        strcpy(unitname, inunitname);
+    } else if (OS_CanonPath(inunitname, unitname)) {
+        return cwErrInvalidParameter;
+    }
+
+    if (optsCompiler.sbmState == OptsCompilerSbmState_0 || optsCompiler.sbmState == OptsCompilerSbmState_1) {
+        if (context->pluginType == CWDROPINCOMPILERTYPE || context->pluginType == CWDROPINLINKERTYPE)
+            c = static_cast<CWCompilerLinkerContext *>(context);
+        else
+            return cwErrInvalidCallback;
+
+        srcfile = Files_GetFile(&gTarg->files, c->whichfile);
+#line 791
+        OPTION_ASSERT(srcfile != NULL);
+
+        if (optsCompiler.sbmPath[0]) {
+            err = OS_MakeSpecWithPath(&clState.sbmPathSpec, unitname, 1, &sbmspec);
+            if (err) {
+                if (clState.pluginDebug)
+                    CLPrint("UCBStoreUnit:  '%s' is a bad unit name (%s)\n", unitname, OS_GetErrText(err));
+                return cwErrInvalidParameter;
+            }
+        } else {
+            err = OS_MakeFileSpec(unitname, &sbmspec);
+            if (err) {
+                if (clState.pluginDebug)
+                    CLPrint("UCBStoreUnit:  '%s' is a bad filename (%s)\n", unitname, OS_GetErrText(err));
+                return cwErrInvalidParameter;
+            }
+        }
+
+        err = UnitNameToSBMName(&sbmspec, srcfile);
+        if (err) {
+            if (clState.pluginDebug)
+                CLPrint("UCBStoreUnit:  could not make precompiled unit form of '%s' (%s)\n", unitname, OS_GetErrText(err));
+            return cwErrInvalidParameter;
+        }
+
+        if (optsCmdLine.verbose)
+            CLReport(CLStr61, "unit symbol table", OS_SpecToStringRelative(&sbmspec, NULL, STSbuf, sizeof(STSbuf)));
+
+        UCBSecretDetachHandle(context, unitdata, &h);
+        OS_DestroyMacHandle(h, &unithand);
+        err = OS_NewFileHandle(&sbmspec, &unithand, 1, &fhand);
+        if (err || (err = OS_FreeFileHandle(&fhand))) {
+            CLReportOSError(CLStr18, err, "precompiled unit", OS_SpecToStringRelative(&sbmspec, NULL, STSbuf, sizeof(STSbuf)));
+            return cwErrRequestFailed;
+        }
+    }
+
+    return cwNoErr;
+}
+
+CWResult UCBReleaseUnit(CWPluginContext context, void *unitdata) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBReleaseUnit");
+
+    if (!unitdata)
+        return cwErrRequestFailed;
+    return UCBReleaseFileText(context, static_cast<const char *>(unitdata));
+}
+
+CWResult UCBUnitNameToFileName(CWPluginContext context, const char *unitname, char *filename) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBUnitNameToFileName");
+
+    strcpy(filename, unitname);
+    if (!OS_EqualPath(filename + strlen(filename) - 2, ".p"))
+        strcat(filename, ".p");
+    return cwNoErr;
+}
+
+CWResult UCBOSAlert(CWPluginContext context, const char *message, OSErr errorcode) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBOSAlert");
+    if (CheckForUserBreak())
+        return cwErrUserCanceled;
+
+    char errormessage[256];
+    GetSysErrText(errorcode, errormessage);
+    CLStyledMessageDispatch(
+            static_cast<shellContextType *>(context->shellContext)->plugin,
+            NULL,
+            errorcode,
+            CLStyledMessageDispatch_Type4,
+            "%\n(%)\n",
+            message ? message : "",
+            errormessage
+    );
+    return cwNoErr;
+}
+
+CWResult UCBOSErrorMessage(CWPluginContext context, const char *message, OSErr errorcode) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBOSErrorMessage");
+    if (!errorcode)
+        return cwNoErr;
+    if (CheckForUserBreak())
+        return cwErrUserCanceled;
+
+    char errormessage[256];
+    GetSysErrText(errorcode, errormessage);
+    CLStyledMessageDispatch(
+            static_cast<shellContextType *>(context->shellContext)->plugin,
+            NULL,
+            errorcode,
+            CLStyledMessageDispatch_Type4,
+            "%\n%\n",
+            message ? message : "",
+            errormessage
+            );
+    return cwNoErr;
+}
+
+CWResult UCBGetModifiedFiles(CWPluginContext context, SInt32 *modifiedFileCount, const SInt32 **modifiedFiles) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBGetModifiedFiles");
+
+    *modifiedFileCount = 0;
+#line 949
+    DO_INTERNAL_ERROR("CWGetModifiedFiles not implemented!\n");
+    return cwNoErr;
+}
+
+CWResult UCBGetSuggestedObjectFileSpec(CWPluginContext context, SInt32 whichfile, CWFileSpec *fileSpec) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBGetSuggestedObjectFileSpec");
+
+    File *file;
+    if (!(file = Files_GetFile(&gTarg->files, whichfile)))
+        return cwErrUnknownFile;
+
+    if (!GetOutputFile(file, CmdLineStageMask_Cg))
+        return cwErrRequestFailed;
+
+    OS_OSSpec_To_FSSpec(&file->outfss, fileSpec);
+    return cwNoErr;
+}
+
+CWResult UCBGetStoredObjectFileSpec(CWPluginContext context, SInt32 whichfile, CWFileSpec *fileSpec) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBGetStoredObjectFileSpec");
+
+    File *file;
+    if (!(file = Files_GetFile(&gTarg->files, whichfile)))
+        return cwErrUnknownFile;
+    if (file->outfileowner != CmdLineStageMask_Cg) {
+#line 993
+        DO_INTERNAL_ERROR("Lost stored object file spec for '%s'\n", file->srcfilename);
+        return cwErrRequestFailed;
+    } else {
+        OS_OSSpec_To_FSSpec(&file->outfss, fileSpec);
+        return cwNoErr;
+    }
+}
+
+CWResult UCBGetFrameworkCount(CWPluginContext context, SInt32 *frameworkCount) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBGetFrameworkCount");
+
+    *frameworkCount = Frameworks_GetCount();
+    return cwNoErr;
+}
+
+CWResult UCBGetFrameworkInfo(CWPluginContext context, SInt32 whichFramework, CWFrameworkInfo *frameworkInfo) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBGetFrameworkCount");
+
+    Paths_FWInfo *info;
+    if ((info = Frameworks_GetInfo(whichFramework))) {
+        OS_OSSpec_To_FSSpec(&info->fileSpec, &frameworkInfo->fileSpec);
+        strncpy(frameworkInfo->version, info->version.s, sizeof(frameworkInfo->version));
+        return cwNoErr;
+    }
+
+    return cwErrFileNotFound;
+}
+
+CWCompilerLinkerCallbacks sCompilerLinkerCallbacks = {
+        UCBCachePrecompiledHeader,
+        UCBLoadObjectData,
+        UCBStoreObjectData,
+        UCBFreeObjectData,
+        UCBDisplayLines,
+        UCBBeginSubCompile,
+        UCBEndSubCompile,
+        UCBGetPrecompiledHeaderSpec,
+        UCBGetResourceFile,
+        UCBPutResourceFile,
+        UCBLookUpUnit,
+        UCBSBMfiles,
+        UCBStoreUnit,
+        UCBReleaseUnit,
+        UCBUnitNameToFileName,
+        UCBOSErrorMessage,
+        UCBOSAlert,
+        UCBGetModifiedFiles,
+        UCBGetSuggestedObjectFileSpec,
+        UCBGetStoredObjectFileSpec,
+        NULL,
+        UCBGetFrameworkCount,
+        UCBGetFrameworkInfo
+};
+
+CWCompilerLinkerContext::CWCompilerLinkerContext()
+        :
+        CWPluginPrivateContext(clState.plugintype, sizeof(CWCompilerLinkerContext)) {
+    targetinfo = static_cast<CWTargetInfo *>(xmalloc("context", sizeof(CWTargetInfo)));
+    memset(targetinfo, 0, sizeof(CWTargetInfo));
+
+    if (gTarg) {
+        targetinfo->targetCPU = gTarg->cpu;
+        targetinfo->targetOS = gTarg->os;
+    } else {
+        targetinfo->targetOS = targetOSAny;
+        targetinfo->targetCPU = targetCPUAny;
+    }
+
+    whichfile = 0;
+    memset(&sourcefile, 0, sizeof(sourcefile));
+    sourcetext = NULL;
+    sourcetextsize = 0;
+
+    preprocess = 0;
+    autoprecompile = 0;
+    precompile = 0;
+    cachingPCH = 0;
+    debuginfo = 0;
+    fileID = 0;
+    memset(&browseoptions, 0, sizeof(browseoptions));
+    reserved = NULL;
+    sequenceID = 0;
+    parentPB = NULL;
+    targetStorage = NULL;
+    texthandle = NULL;
+    memset(&targetinfo_V7, 0, sizeof(targetinfo_V7));
+
+    callbacks = &sCompilerLinkerCallbacks;
+}
+
+CWCompilerLinkerContext::~CWCompilerLinkerContext() {
+    xfree(targetinfo);
+}
diff --git a/command_line/CmdLine/Src/Callbacks/CLDropinCallbacks_V10.cpp b/command_line/CmdLine/Src/Callbacks/CLDropinCallbacks_V10.cpp
index cf6f1f7..ed02965 100644
--- a/command_line/CmdLine/Src/Callbacks/CLDropinCallbacks_V10.cpp
+++ b/command_line/CmdLine/Src/Callbacks/CLDropinCallbacks_V10.cpp
@@ -1,48 +1,1305 @@
-/*
-     1B9C8 | _ANSI_To_Mac_GMT_Time__FlPUl
-     1BA88 | _Mac_To_ANSI_Time__FUlPl
- P   1BCA4 | _UCBGetFileInfo
-     1BEA8 | _FindAndLoad_VirtualFile__FP22CWPluginPrivateContextPCcP10CWFileInfoP6OSSpecPUc
-     1BF98 | _FindAndLoad_AccessPathFile__FP22CWPluginPrivateContextPCcP10CWFileInfoP6OSSpecPUc
-     1C108 | _FindAndLoad_MissingFile__FP22CWPluginPrivateContextPCcP10CWFileInfoP6OSSpecPUc
- P   1C278 | _UCBFindAndLoadFile
- P   1C50C | _UCBGetFileText
- P   1C6BC | _UCBReleaseFileText
- P   1C754 | _UCBGetSegmentInfo
- P   1C814 | _UCBGetOverlay1GroupInfo
- P   1C8F0 | _UCBGetOverlay1FileInfo
- P   1C9A0 | _UCBGetOverlay1Info
- P   1CA74 | _UCBReportMessage
- P   1CCDC | _UCBAlert
- P   1CEB4 | _UCBShowStatus
- P   1D00C | _UCBUserBreak
- P   1D078 | _UCBGetNamedPreferences
- P   1D13C | _UCBStorePluginData
- P   1D1AC | _UCBGetPluginData
- P   1D21C | _UCBSetModDate
- P   1D35C | _UCBAddProjectEntry
- P   1DB20 | _UCBCreateNewTextDocument
- P   1DE74 | _UCBAllocateMemory
- P   1DF00 | _UCBFreeMemory
- P   1DF74 | _UCBAllocMemHandle
- P   1E00C | _UCBFreeMemHandle
- P   1E08C | _UCBGetMemHandleSize
- P   1E11C | _UCBResizeMemHandle
- P   1E1C0 | _UCBLockMemHandle
- P   1E238 | _UCBUnlockMemHandle
- P   1E29C | _UCBGetTargetName
- P   1E320 | _UCBPreDialog
- P   1E370 | _UCBPostDialog
- P   1E3C0 | _UCBPreFileAction
- P   1E430 | _UCBPostFileAction
- P   1E4A0 | _UCBCacheAccessPathList
- P   1E7A8 | _UCBSecretAttachHandle
- P   1E814 | _UCBSecretDetachHandle
- P   1E8A0 | _UCBSecretPeekHandle
- P   1E92C | _UCBCheckoutLicense
- P   1E998 | _UCBCheckinLicense
- P   1E9E8 | _UCBResolveRelativePath
- P   1EA28 | _UCBMacOSErrToCWResult
- P   1EA88 | ___ct__22CWPluginPrivateContextFll
- P   1EB10 | ___dt__22CWPluginPrivateContextFv
- */
+#include "cmdline.h"
+#include "plugin_internal.h"
+
+extern char STSbuf[256];
+
+static void ANSI_To_Mac_GMT_Time(time_t sectm, UInt32 *secs) {
+    struct tm *tmrec;
+    int years;
+    int ydays;
+
+    tmrec = localtime(&sectm);
+    years = tmrec->tm_year - 4;
+
+    ydays =
+            (years * 365) +
+            ((years + 3) / 4) -
+            ((years + 4) / 100) +
+            ((years - 296) / 400);
+
+    *secs =
+            ((ydays + tmrec->tm_yday) * 86400)
+            + (tmrec->tm_hour * 3600)
+            + (tmrec->tm_min * 60)
+            + (tmrec->tm_sec);
+}
+
+static void Mac_To_ANSI_Time(UInt32 secs, time_t *sectm) {
+    static int monthdays[12] = {
+            31, 28, 31, 30,
+            31, 30, 31, 31,
+            30, 31, 30, 31
+    };
+    struct tm tmrec;
+    int month;
+
+    memset(&tmrec, 0, sizeof(tmrec));
+    tmrec.tm_sec = secs % 60; // line 1523
+    tmrec.tm_min = (secs / 60) % 60; // line 1524
+    tmrec.tm_hour = (secs / 3600) % 24; // line 1525
+    tmrec.tm_yday = (secs / 86400) % 365;
+    tmrec.tm_year = (secs / 31536000) + 4; // line 1533
+    tmrec.tm_yday -=
+            ((((secs / 31536000) + 3) / 4)
+             -
+             (((secs / 31536000) + 4) / 100)
+             +
+             ((SInt32)((secs / 31536000) - 296) / 400))
+            ;
+
+    if ((tmrec.tm_year % 4) && ((tmrec.tm_year % 100) || !(tmrec.tm_year % 400))) {
+        monthdays[1] = 28;
+    } else {
+        monthdays[1] = 29;
+    }
+
+    for (month = 0; tmrec.tm_yday >= monthdays[month]; month++) {
+        tmrec.tm_yday -= monthdays[month];
+    }
+    tmrec.tm_mon = month;
+    tmrec.tm_mday = tmrec.tm_yday + 1;
+
+    *sectm = mktime(&tmrec);
+    if (month >= 4 && month < 10)
+        *sectm += 3600;
+}
+
+CWResult UCBGetFileInfo(CWPluginContext context, SInt32 whichfile, Boolean checkFileLocation, CWProjectFileInfo *fileinfo) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBGetFileInfo");
+
+    File *file;
+    SInt16 id;
+    int ret;
+    char fullpath[256];
+    time_t tmptime;
+
+    file = Files_GetFile(&gTarg->files, whichfile);
+    if (!file)
+        return cwErrUnknownFile;
+
+    memset(fileinfo, 0, sizeof(CWProjectFileInfo));
+    OS_OSSpec_To_FSSpec(&file->srcfss, &fileinfo->filespec);
+    OS_TimeToMac(file->srcmoddate, &fileinfo->moddate);
+    Mac_To_ANSI_Time(fileinfo->moddate, &tmptime);
+    ANSI_To_Mac_GMT_Time(tmptime, &fileinfo->moddate);
+
+    fileinfo->segment = file->segnum;
+    fileinfo->hasobjectcode = file->hasobjectcode;
+    fileinfo->hasresources = file->hasresources;
+    fileinfo->isresourcefile = file->isresourcefile;
+    fileinfo->weakimport = file->weakimport;
+    fileinfo->initbefore = file->initbefore;
+    fileinfo->mergeintooutput = file->mergeintooutput;
+    fileinfo->reserved = 0;
+    fileinfo->gendebug = file->gendebug;
+    OS_TimeToMac(file->outmoddate, &fileinfo->objmoddate);
+
+    if (file->compiler) {
+        strncpy(fileinfo->dropinname, Plugin_GetDropInName(file->compiler), 31);
+        fileinfo->dropinname[31] = 0;
+    } else {
+        fileinfo->dropinname[0] = 0;
+    }
+
+    fileinfo->fileID = file->browseFileID;
+    fileinfo->recordbrowseinfo = file->recordbrowseinfo;
+    fileinfo->filetype = file->filetype;
+    fileinfo->filecreator = file->filecreator;
+
+    if (optsCompiler.browserEnabled) {
+        ret = Browser_SearchFile(&clState.browseTableHandle, OS_SpecToString(&file->srcfss, fullpath, sizeof(fullpath)), &id);
+        if (ret) {
+            fileinfo->recordbrowseinfo = 1;
+            fileinfo->fileID = id;
+        } else {
+            fileinfo->recordbrowseinfo = 0;
+            fileinfo->fileID = id;
+        }
+    } else {
+        fileinfo->recordbrowseinfo = 0;
+        fileinfo->fileID = 0;
+    }
+    fileinfo->unitdatadependencytag = 0;
+    fileinfo->hasunitdata = 0;
+    return cwNoErr;
+}
+
+static Boolean FindAndLoad_VirtualFile(CWPluginContext context, const char *filename, CWFileInfo *fileinfo, OSSpec *spec, Boolean *loaded) {
+    VFile *vf;
+    char *fnameptr;
+
+    fnameptr = OS_GetFileNamePtr(const_cast<char *>(filename));
+    vf = VFiles_Find(gTarg->virtualFiles, fnameptr);
+    if (vf) {
+        if (!fileinfo->suppressload) {
+            CopyFileText(vf->data, const_cast<char **>(&fileinfo->filedata), &fileinfo->filedatalength);
+            *loaded = 1;
+        }
+        fileinfo->filedatatype = cwFileTypeText;
+        fileinfo->fileID = 0;
+        fileinfo->alreadyincluded = 0;
+        fileinfo->recordbrowseinfo = 0;
+        fileinfo->filespec.parID = 0;
+        fileinfo->filespec.vRefNum = 0;
+        c2pstrcpy(fileinfo->filespec.name, fnameptr);
+        OS_MakeFileSpec(fnameptr, spec);
+        if (optsCompiler.printHeaderNames)
+            CLPrint("%s\n", fnameptr);
+        return 1;
+    }
+
+    return 0;
+}
+
+static Boolean FindAndLoad_AccessPathFile(CWPluginContext context, const char *filename, CWFileInfo *fileinfo, OSSpec *spec, Boolean *loaded) {
+    SInt32 incl;
+    shellContextType *sc;
+    File *depfile;
+    SInt16 id;
+    int ret;
+    char fullpath[256];
+
+    if (Incls_FindFileInPaths(&gTarg->incls, const_cast<char *>(filename), fileinfo->fullsearch || optsCompiler.noSysPath, spec, &incl)) {
+        if (context->pluginType == CWDROPINCOMPILERTYPE) {
+            depfile = Files_GetFile(
+                    &gTarg->files,
+                    (fileinfo->isdependentoffile < 0) ? static_cast<CWCompilerLinkerContext *>(context)->whichfile : fileinfo->isdependentoffile);
+            if (depfile)
+                Deps_AddDependency(&depfile->deps, incl, NULL, 0, fileinfo->dependencyType, &fileinfo->alreadyincluded);
+
+            if (optsCompiler.browserEnabled) {
+                ret = Browser_SearchAndAddFile(&clState.browseTableHandle, OS_SpecToString(spec, fullpath, sizeof(fullpath)), &id);
+                if (ret == 0) {
+                    return 2;
+                } else if (ret < 0) {
+                    fileinfo->recordbrowseinfo = 1;
+                    fileinfo->fileID = id;
+                } else {
+                    fileinfo->recordbrowseinfo = 0;
+                    fileinfo->fileID = id;
+                }
+            } else {
+                fileinfo->recordbrowseinfo = 0;
+                fileinfo->fileID = 0;
+            }
+        }
+
+        OS_OSSpec_To_FSSpec(spec, &fileinfo->filespec);
+        return 1;
+    }
+
+    return 0;
+}
+
+static Boolean FindAndLoad_MissingFile(CWPluginContext context, const char *filename, CWFileInfo *fileinfo, OSSpec *spec, Boolean *loaded) {
+    File *file;
+    CWCompilerLinkerContext *c;
+
+    if (optsCompiler.ignoreMissingFiles) {
+        if (context->pluginType == CWDROPINCOMPILERTYPE || context->pluginType == CWDROPINLINKERTYPE)
+            c = static_cast<CWCompilerLinkerContext *>(context);
+        else
+            return 0;
+
+        file = Files_GetFile(&gTarg->files, c->whichfile);
+#line 486
+        OPTION_ASSERT(file != NULL);
+
+        OS_MakeSpecWithPath(&file->srcfss.path, filename, 1, spec);
+        Deps_AddDependency(&file->deps, -1, spec, !fileinfo->fullsearch && !optsCompiler.noSysPath, fileinfo->dependencyType, &fileinfo->alreadyincluded);
+
+        fileinfo->fileID = 0;
+        fileinfo->recordbrowseinfo = 0;
+        if (!fileinfo->suppressload) {
+            fileinfo->filedata = xstrdup("");
+            fileinfo->filedatalength = 0;
+            fileinfo->filedatatype = cwFileTypeText;
+            *loaded = 1;
+        } else {
+            fileinfo->filedata = NULL;
+            fileinfo->filedatalength = 0;
+            fileinfo->filedatatype = cwFileTypeUnknown;
+        }
+
+        OS_OSSpec_To_FSSpec(spec, &fileinfo->filespec);
+        return 1;
+    }
+
+    return 0;
+}
+
+CWResult UCBFindAndLoadFile(CWPluginContext context, const char *infilename, CWFileInfo *fileinfo) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBFindAndLoadFile");
+
+    OSSpec spec;
+    Boolean loaded;
+    char filename[256];
+    char browseinfo[64];
+
+    ShowWorking(8);
+    if (CheckForUserBreak())
+        return cwErrUserCanceled;
+
+    if (optsCompiler.canonicalIncludes)
+        strcpy(filename, infilename);
+    else if (OS_CanonPath(infilename, filename))
+        return cwErrInvalidParameter;
+
+    loaded = 0;
+    if (!FindAndLoad_VirtualFile(context, filename, fileinfo, &spec, &loaded) && !FindAndLoad_AccessPathFile(context, filename, fileinfo, &spec, &loaded) && !FindAndLoad_MissingFile(context, filename, fileinfo, &spec, &loaded)) {
+        return cwErrFileNotFound;
+    }
+
+    if (optsCompiler.printHeaderNames)
+        CLPrint("%s\n", OS_SpecToStringRelative(&spec, NULL, STSbuf, sizeof(STSbuf)));
+
+    if (context->pluginType == CWDROPINCOMPILERTYPE) {
+        if (optsCmdLine.verbose > 2) {
+            sprintf(browseinfo, " (browse fileID %d)", fileinfo->fileID);
+            CLReport(
+                    CLStr21,
+                    fileinfo->alreadyincluded ? "Included" : "Including",
+                    OS_SpecToString(&spec, STSbuf, sizeof(STSbuf)),
+                    fileinfo->recordbrowseinfo ? browseinfo : "");
+        } else if (optsCmdLine.verbose > 1 && !fileinfo->alreadyincluded) {
+            CLReport(
+                    CLStr21,
+                    "Including",
+                    OS_SpecToString(&spec, STSbuf, sizeof(STSbuf)),
+                    "");
+        }
+    } else {
+        fileinfo->fileID = 0;
+        fileinfo->recordbrowseinfo = 0;
+        fileinfo->alreadyincluded = 0;
+    }
+
+    if (!loaded) {
+        if (!fileinfo->suppressload) {
+            return UCBGetFileText(context, &fileinfo->filespec, &fileinfo->filedata, &fileinfo->filedatalength, &fileinfo->filedatatype);
+        } else {
+            fileinfo->filedata = NULL;
+            fileinfo->filedatalength = 0;
+            fileinfo->filedatatype = cwFileTypeUnknown;
+            return cwNoErr;
+        }
+    } else {
+        return cwNoErr;
+    }
+}
+
+CWResult UCBGetFileText(CWPluginContext context, const CWFileSpec *filespec, const char **text, SInt32 *textLength, short *filedatatype) {
+    int err;
+    Handle texthandle = NULL;
+    Boolean precomp;
+    OSSpec spec;
+    VFile *vf;
+    char filename[64];
+
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBGetFileText");
+
+    OS_FSSpec_To_OSSpec(filespec, &spec);
+    err = LoadAndCacheFile(&spec, &texthandle, &precomp);
+    if (err) {
+        p2cstrcpy(filename, filespec->name);
+        if (filespec->vRefNum || filespec->parID || !(vf = VFiles_Find(gTarg->virtualFiles, filename))) {
+            CLReportOSError(CLStr93, err, OS_SpecToString(&spec, STSbuf, sizeof(STSbuf)));
+            return cwErrFileNotFound;
+        }
+        CopyFileText(vf->data, const_cast<char **>(text), textLength);
+        *filedatatype = cwFileTypeText;
+        int err = OS_MakeFileSpec(filename, &spec);
+    } else {
+        if (texthandle) {
+            if (!precomp) {
+                CopyFileText(texthandle, const_cast<char **>(text), textLength);
+                FreeIncludeFile(texthandle);
+            } else {
+                HLock(texthandle);
+                *text = *texthandle;
+                *textLength = GetHandleSize(texthandle);
+            }
+        }
+
+        if (texthandle) {
+            if (!precomp)
+                *filedatatype = cwFileTypeText;
+            else
+                *filedatatype = cwFileTypePrecompiledHeader;
+        } else {
+            *filedatatype = cwFileTypeUnknown;
+        }
+    }
+
+    return cwNoErr;
+}
+
+CWResult UCBReleaseFileText(CWPluginContext context, const char *text) {
+    short callbackResult = 0;
+    CWCompilerLinkerContext *cc = static_cast<CWCompilerLinkerContext *>(context);
+
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBReleaseFileText");
+
+    if (text) {
+        if (text != cc->sourcetext)
+            xfree((void *) text);
+    } else {
+        callbackResult = cwErrInvalidParameter;
+    }
+
+    return callbackResult;
+}
+
+CWResult UCBGetSegmentInfo(CWPluginContext context, SInt32 whichsegment, CWProjectSegmentInfo *segmentinfo) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBGetSegmentInfo");
+
+    if (gTarg->linkmodel != LinkModel1)
+        return cwErrInvalidCallback;
+
+    Segment *seg = Segments_GetSegment(&gTarg->linkage.segs, whichsegment);
+    if (!seg)
+        return cwErrUnknownSegment;
+
+    strcpy(segmentinfo->name, seg->name);
+    segmentinfo->attributes = seg->attrs;
+    return cwNoErr;
+}
+
+CWResult UCBGetOverlay1GroupInfo(CWPluginContext context, SInt32 whichgroup, CWOverlay1GroupInfo *groupinfo) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBGetOverlay1GroupInfo");
+
+    OvlGroup *grp = Overlays_GetOvlGroup(&gTarg->linkage.overlays, whichgroup);
+    if (gTarg->linkmodel != LinkModel2)
+        return cwErrInvalidCallback;
+
+    if (grp) {
+        strcpy(groupinfo->name, grp->name);
+        groupinfo->address.lo = grp->addr.lo;
+        groupinfo->address.hi = grp->addr.hi;
+        groupinfo->numoverlays = OvlGroup_CountOverlays(grp);
+        return cwNoErr;
+    } else {
+        return cwErrInvalidParameter;
+    }
+}
+
+CWResult UCBGetOverlay1FileInfo(CWPluginContext context, SInt32 whichgroup, SInt32 whichoverlay, SInt32 whichoverlayfile, CWOverlay1FileInfo *fileinfo) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBGetOverlay1FileInfo");
+
+    if (gTarg->linkmodel != LinkModel2)
+        return cwErrInvalidCallback;
+
+    SInt32 filenum = Overlays_GetFileInOverlay(&gTarg->linkage.overlays, whichgroup, whichoverlay, whichoverlayfile);
+    if (filenum >= 0) {
+        fileinfo->whichfile = filenum;
+        return cwNoErr;
+    } else {
+        return cwErrInvalidParameter;
+    }
+}
+
+CWResult UCBGetOverlay1Info(CWPluginContext context, SInt32 whichgroup, SInt32 whichoverlay, CWOverlay1Info *overlayinfo) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBGetOverlay1Info");
+
+    if (gTarg->linkmodel != LinkModel2)
+        return cwErrInvalidCallback;
+
+    Overlay *oly = Overlays_GetOverlayInGroup(&gTarg->linkage.overlays, whichgroup, whichoverlay);
+    if (oly) {
+        strcpy(overlayinfo->name, oly->name);
+        overlayinfo->numfiles = Overlay_CountFiles(oly);
+        return cwNoErr;
+    } else {
+        return cwErrInvalidParameter;
+    }
+}
+
+CWResult UCBReportMessage(CWPluginContext context, const CWMessageRef *msgRef, const char *line1, const char *line2, short errorlevel, SInt32 errorNumber) {
+    if (optsCmdLine.verbose > 4)
+        CLPrint("Callback: %s\n", "UCBReportMessage");
+
+    short msgType;
+    int eeol;
+    const char *eeptr;
+    char *tptr;
+    MessageRef ref;
+    CWCompilerLinkerContext *clx;
+
+    static const char *fmts[2][2][2] = {
+            "%\n", "%",
+            "%\n", "%",
+            "%\n%\n", "%%\n",
+            "%\n%", "%%"
+    };
+
+    if (line1 == NULL) {
+        line1 = "";
+        eeol = 0;
+    } else {
+        eeptr = line1 + strlen(line1) - 1;
+        eeol = *eeptr == '\r' || *eeptr == '\n';
+    }
+
+    if (CheckForUserBreak())
+        return cwErrUserCanceled;
+
+    if (errorlevel == messagetypeError)
+        msgType = CLStyledMessageDispatch_Type3;
+    else if (errorlevel == messagetypeWarning)
+        msgType = CLStyledMessageDispatch_Type2;
+    else
+        msgType = CLStyledMessageDispatch_Type1;
+
+    clx = static_cast<CWCompilerLinkerContext *>(context);
+
+    if (!msgRef) {
+        if (line2 && line2[0]) {
+            eeptr = line2 + strlen(line2) - 1;
+            int eeol2 = *eeptr == '\r' || *eeptr == '\n';
+            CLStyledMessageDispatch(
+                    static_cast<shellContextType *>(clx->shellContext)->plugin,
+                    NULL,
+                    errorNumber,
+                    msgType,
+                    fmts[1][eeol2][eeol],
+                    line1,
+                    line2
+                    );
+        } else {
+            CLStyledMessageDispatch(
+                    static_cast<shellContextType *>(clx->shellContext)->plugin,
+                    NULL,
+                    errorNumber,
+                    msgType,
+                    fmts[0][0][eeol],
+                    line1
+            );
+        }
+    } else {
+        OS_FSSpec_To_OSSpec(&clx->sourcefile, &ref.sourcefile);
+        OS_FSSpec_To_OSSpec(&msgRef->sourcefile, &ref.errorfile);
+        ref.sourceline = const_cast<char *>(line2);
+        ref.linenumber = msgRef->linenumber;
+
+        ref.tokenoffset = msgRef->tokenoffset;
+        ref.tokenlength = msgRef->tokenlength;
+        ref.selectionoffset = msgRef->selectionoffset;
+        ref.selectionlength = msgRef->selectionlength;
+
+        if (ref.tokenoffset < 0)
+            ref.tokenoffset = 0;
+        if (ref.tokenlength < 0)
+            ref.tokenlength = 0;
+        if (ref.selectionoffset < 0)
+            ref.selectionoffset = 0;
+        if (ref.selectionlength < 0)
+            ref.selectionlength = 0;
+
+        CLStyledMessageDispatch(
+                static_cast<shellContextType *>(clx->shellContext)->plugin,
+                &ref,
+                errorNumber,
+                msgType,
+                fmts[0][0][eeol],
+                line1
+        );
+    }
+
+    return cwNoErr;
+}
+
+CWResult UCBAlert(CWPluginContext context, const char *msg1, const char *msg2, const char *msg3, const char *msg4) {
+    if (optsCmdLine.verbose > 4)
+        CLPrint("Callback: %s\n", "UCBAlert");
+
+    if (CheckForUserBreak())
+        return cwErrUserCanceled;
+
+    if (msg4) {
+        CLStyledMessageDispatch(
+                static_cast<shellContextType *>(context->shellContext)->plugin,
+                NULL,
+                0,
+                CLStyledMessageDispatch_Type4,
+                "%\n%\n%\n%\n",
+                msg1 ? msg1 : "",
+                msg2 ? msg2 : "",
+                msg3 ? msg3 : "",
+                msg4
+                );
+    } else if (msg3) {
+        CLStyledMessageDispatch(
+                static_cast<shellContextType *>(context->shellContext)->plugin,
+                NULL,
+                0,
+                CLStyledMessageDispatch_Type4,
+                "%\n%\n%\n",
+                msg1 ? msg1 : "",
+                msg2 ? msg2 : "",
+                msg3
+        );
+    } else if (msg2) {
+        CLStyledMessageDispatch(
+                static_cast<shellContextType *>(context->shellContext)->plugin,
+                NULL,
+                0,
+                CLStyledMessageDispatch_Type4,
+                "%\n%\n",
+                msg1 ? msg1 : "",
+                msg2
+        );
+    } else {
+        CLStyledMessageDispatch(
+                static_cast<shellContextType *>(context->shellContext)->plugin,
+                NULL,
+                0,
+                CLStyledMessageDispatch_Type4,
+                "%\n",
+                msg1 ? msg1 : ""
+        );
+    }
+
+    return cwNoErr;
+}
+
+CWResult UCBShowStatus(CWPluginContext context, const char *line1, const char *line2) {
+    if (optsCmdLine.verbose > 4)
+        CLPrint("Callback: %s\n", "UCBShowStatus");
+
+    if (CheckForUserBreak())
+        return cwErrUserCanceled;
+
+    if (optsCmdLine.verbose > 1) {
+        if ((!line1 || !*line1) && (!line2 || !*line2))
+            return cwNoErr;
+
+        if (line2 && *line2) {
+            CLStyledMessageDispatch(
+                    static_cast<shellContextType *>(context->shellContext)->plugin,
+                    NULL,
+                    0,
+                    CLStyledMessageDispatch_Type5,
+                    "%\n%\n",
+                    line1 ? line1 : "",
+                    line2 ? line2 : ""
+            );
+        } else {
+            CLStyledMessageDispatch(
+                    static_cast<shellContextType *>(context->shellContext)->plugin,
+                    NULL,
+                    0,
+                    CLStyledMessageDispatch_Type5,
+                    "%\n",
+                    line1 ? line1 : ""
+            );
+        }
+    }
+
+    return cwNoErr;
+}
+
+CWResult UCBUserBreak(CWPluginContext context) {
+    if (optsCmdLine.verbose > 4)
+        CLPrint("Callback: %s\n", "UCBUserBreak");
+
+    ShowWorking(8);
+    if (CheckForUserBreak())
+        return cwErrUserCanceled;
+    else
+        return cwNoErr;
+}
+
+CWResult UCBGetNamedPreferences(CWPluginContext context, const char *prefsname, CWMemHandle *prefsdata) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBGetNamedPreferences");
+
+    PrefPanel *pnl = Prefs_FindPanel(prefsname);
+    if (pnl) {
+        if (optsCmdLine.verbose > 2)
+            CLReport(83, prefsname);
+        UCBSecretAttachHandle(context, PrefPanel_GetHandle(pnl), prefsdata);
+        return cwNoErr;
+    } else {
+        CLReportError(91, prefsname);
+        *prefsdata = NULL;
+        return cwErrRequestFailed;
+    }
+}
+
+CWResult UCBStorePluginData(CWPluginContext context, SInt32 whichfile, CWDataType type, CWMemHandle prefsdata) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBStorePluginData");
+
+#line 1267
+    DO_INTERNAL_ERROR("UCBStorePluginData not implemented");
+    return cwErrRequestFailed;
+}
+
+CWResult UCBGetPluginData(CWPluginContext context, SInt32 whichfile, CWDataType type, CWMemHandle *prefsdata) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBGetPluginData");
+
+#line 1286
+    DO_INTERNAL_ERROR("UCBGetPluginData not implemented");
+    return cwErrRequestFailed;
+}
+
+CWResult UCBSetModDate(CWPluginContext context, const CWFileSpec *filespec, CWFileTime *moddate, Boolean isGenerated) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBSetModDate");
+
+    OSSpec spec;
+    time_t mdtm;
+    int err;
+    SInt32 idx;
+    File *file;
+
+    OS_FSSpec_To_OSSpec(filespec, &spec);
+    if (!moddate || !*moddate)
+        OS_GetTime(&mdtm);
+    else
+        OS_MacToTime(*moddate, &mdtm);
+
+    for (idx = 0; idx < Files_Count(&gTarg->files); idx++) {
+        file = Files_GetFile(&gTarg->files, idx);
+        if (OS_EqualSpec(&file->srcfss, &spec))
+            file->srcmoddate = mdtm;
+        else if (OS_EqualSpec(&file->outfss, &spec))
+            file->outmoddate = mdtm;
+    }
+
+    err = OS_SetFileTime(&spec, NULL, &mdtm);
+    if (err == 0)
+        return cwNoErr;
+    else
+        return cwErrRequestFailed;
+}
+
+CWResult UCBAddProjectEntry(CWPluginContext context, const CWFileSpec *fileSpec, Boolean isGenerated, const CWNewProjectEntryInfo *entry, SInt32 *whichfile) {
+    // two registers are awkwardly swapped here...
+    File *file;
+    OSSpec fss;
+    UInt32 filetype;
+    Plugin *plugin;
+    char *extptr;
+    char ext[16];
+    UInt32 flags;
+    char filename[256];
+    const DropInFlags *df;
+    OvlGroup *ovg;
+    Overlay *oly;
+    SInt32 idx;
+
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBAddProjectEntry");
+
+    OS_FSSpec_To_OSSpec(fileSpec, &fss);
+    if (OS_IsDir(&fss))
+        return cwErrInvalidParameter;
+
+    OS_NameSpecToString(&fss.name, filename, sizeof(filename));
+    if (gTarg->linker && !(gTarg->linkerDropinFlags & (linkAllowDupFileNames | dropInExecutableTool))) {
+        if (Files_FindFile(&gTarg->files, &fss)) {
+            if (optsCmdLine.verbose > 1)
+                CLReportWarning(CLStr106, filename);
+            return cwNoErr;
+        }
+    }
+
+    extptr = filename + strlen(filename) - 1;
+    while (extptr > filename && *extptr != '.')
+        --extptr;
+    if (extptr <= filename)
+        extptr = ".";
+    strncpy(ext, extptr, sizeof(ext) - 1);
+    ext[sizeof(ext) - 1] = 0;
+
+    OS_SpecToStringRelative(&fss, NULL, filename, sizeof(filename));
+    if (optsCmdLine.verbose > 2)
+        CLReport(CLStr77, " to project", filename);
+
+    if (OS_GetMacFileType(&fss, &filetype))
+        filetype = CWFOURCHAR('T','E','X','T');
+
+    plugin = Plugins_GetPluginForFile(NULL, CWDROPINANYTYPE, targetCPUAny, targetOSAny, filetype, ext, Lang_Any);
+    if (plugin && gTarg->linker && !Plugin_CL_MatchesTarget(plugin, gTarg->cpu, gTarg->os, 0))
+        CLReportError(CLStr76, filename);
+
+    if (!plugin)
+        plugin = Plugins_CL_MatchTarget(NULL, gTarg->cpu, gTarg->os, clState.plugintype, clState.language);
+
+    if (plugin) {
+        if (!Plugin_CL_GetCompilerMapping(plugin, filetype, ext, &flags)) {
+            flags = 0;
+            if (!isGenerated && !optsCompiler.compileIgnored && optsCompiler.forcePrecompile != 1) {
+                CLReportWarning(
+                        CLStr73,
+                        "file", filename,
+                        (clState.plugintype == CWDROPINCOMPILERTYPE) ? "treating as source text" : "passing unknown file to linker"
+                );
+            }
+            if (isGenerated)
+                flags = kIgnored;
+        } else if (!isGenerated && (flags & kIgnored) && !optsCompiler.compileIgnored) {
+            if ((!optsCmdLine.stages || (optsCmdLine.stages & (CmdLineStageMask_Cg | CmdLineStageMask_Ds))) && (optsCompiler.forcePrecompile != 1))
+                CLReportWarning(CLStr28, filename);
+            else
+                flags &= ~kIgnored;
+        }
+
+        if (optsCompiler.compileIgnored && !isGenerated)
+            flags &= ~kIgnored;
+
+        if (clState.pluginDebug) {
+            CLPrint("Using plugin '%s' for '%s'\n", Plugin_GetDropInName(plugin), filename);
+            CLPrint(
+                    "[flags: %s, %s, %s, %s]\n",
+                    (flags & kPrecompile) ? "precompile" : "don't precompile",
+                    (flags & kLaunchable) ? "launchable" : "not launchable",
+                    (flags & kRsrcfile) ? "resource file" : "not resource file",
+                    (flags & kIgnored) ? "ignored" : "used"
+                    );
+        }
+    } else {
+        CLReportError(CLStr74, filename);
+        flags = kIgnored;
+    }
+
+    file = File_New();
+    if (!file)
+        return cwErrOutOfMemory;
+
+    Deps_Initialize(&file->deps, &gTarg->incls);
+
+    file->segnum = (entry->segment == -1) ? (Segments_Count(&gTarg->linkage.segs) - 1) : entry->segment;
+
+    strcpy(file->srcfilename, filename);
+    file->srcfss = fss;
+
+    OS_GetFileTime(&file->srcfss, NULL, &file->srcmoddate);
+    OS_GetTime(&file->outmoddate);
+
+    file->outfilename[0] = 0;
+    memset(&file->outfss, 0, sizeof(file->outfss));
+
+    file->outfileowner = 0;
+    file->tempOnDisk = 0;
+    file->wroteToDisk = 0;
+    file->writeToDisk = 0;
+
+    if (plugin && Plugin_GetPluginType(plugin) != CWDROPINCOMPILERTYPE)
+        file->compiler = NULL;
+    else
+        file->compiler = plugin;
+
+    file->filetype = filetype;
+    file->mappingflags = flags;
+
+    if (file->compiler) {
+        df = Plugin_GetDropInFlags(file->compiler);
+        file->dropinflags = df->dropinflags;
+    } else {
+        file->dropinflags = 0;
+    }
+
+    file->weakimport = entry->weakimport;
+    file->initbefore = entry->initbefore;
+    file->mergeintooutput = entry->mergeintooutput;
+    file->isresourcefile = (flags & kRsrcfile) != 0;
+
+    if (file->compiler)
+        file->objectflags = Plugin_CL_GetObjectFlags(file->compiler)->flags;
+    else
+        file->objectflags = 0;
+
+    file->sourceUsage = 0;
+    if (!(file->mappingflags & kIgnored)) {
+        if (file->compiler) {
+            file->sourceUsage |= CmdLineStageMask_Pp;
+            if (!(file->objectflags & 0x80000000))
+                file->sourceUsage |= CmdLineStageMask_Cg;
+        } else if (plugin) {
+            file->sourceUsage |= CmdLineStageMask_Cg;
+        }
+    }
+
+    if (file->isresourcefile)
+        file->sourceUsage |= CmdLineStageMask_Cg;
+
+    file->objectUsage = file->sourceUsage & CmdLineStageMask_Pp;
+    if ((file->sourceUsage & CmdLineStageMask_Pp) && !(file->mappingflags & kPrecompile) && (optsCompiler.forcePrecompile != 1) && (file->objectflags & 0x80000000))
+        file->objectUsage |= CmdLineStageMask_Cg;
+
+    *whichfile = 0;
+    if ((entry->position != -1) ? (Files_AddFile(&gTarg->files, file) == 0) : (Files_InsertFile(&gTarg->files, file, entry->position) == 0))
+        return cwErrRequestFailed;
+    *whichfile = file->filenum;
+    context->numFiles++;
+
+    if (gTarg->linkmodel == LinkModel2) {
+        ovg = Overlays_GetOvlGroup(
+                &gTarg->linkage.overlays,
+                (entry->overlayGroup == -1) ? (Overlays_CountGroups(&gTarg->linkage.overlays) - 1) : entry->overlayGroup);
+        if (ovg) {
+            oly = OvlGroup_GetOverlay(
+                    ovg,
+                    (entry->overlay == -1) ? (OvlGroup_CountOverlays(ovg) - 1) : entry->overlay);
+            if (oly) {
+                if (!Overlay_AddFile(oly, file->filenum, &idx))
+                    return cwErrRequestFailed;
+            } else {
+                return cwErrRequestFailed;
+            }
+        } else {
+            return cwErrRequestFailed;
+        }
+    }
+
+    return cwNoErr;
+}
+
+CWResult UCBCreateNewTextDocument(CWPluginContext context, const CWNewTextDocumentInfo *docinfo) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBCreateNewTextDocument");
+
+    if (context->pluginType == CWDROPINCOMPILERTYPE || context->pluginType == CWDROPINLINKERTYPE) {
+        if (!docinfo->documentname) {
+            CWCompilerLinkerContext *clcontext = static_cast<CWCompilerLinkerContext *>(context);
+            File *file = Files_GetFile(&gTarg->files, clcontext->whichfile);
+            if (!file)
+                return cwErrUnknownFile;
+
+            if (file->textdata) {
+                if (!ShowHandle(file->textdata, GetHandleSize(file->textdata), 1))
+                    return cwErrRequestFailed;
+                DisposeHandle(file->textdata);
+            }
+
+            UCBSecretDetachHandle(context, docinfo->text, &file->textdata);
+            OS_GetTime(&file->outmoddate);
+            return cwNoErr;
+        } else {
+            Handle texth;
+            UCBSecretDetachHandle(context, docinfo->text, &texth);
+            UInt32 size = GetHandleSize(texth);
+            if (strcmp(docinfo->documentname, ">stdout") || clState.stdout_base) {
+                FILE *stdfile;
+                if (!strcmp(docinfo->documentname, ">stdout")) {
+                    stdfile = clState.stdout_written ? fopen(clState.stdout_base, "at") : fopen(clState.stdout_base, "wt");
+                    clState.stdout_written = 1;
+                } else {
+                    stdfile = fopen(docinfo->documentname, "wt");
+                }
+
+                if (stdfile) {
+                    HLock(texth);
+                    fwrite(*texth, size, 1, stdfile);
+                    fclose(stdfile);
+                    HUnlock(texth);
+                    return cwNoErr;
+                }
+            }
+
+            if (!ShowHandle(texth, size, 0))
+                return cwErrRequestFailed;
+            else
+                return cwNoErr;
+        }
+    } else if (context->pluginType == CWDROPINPARSERTYPE) {
+        Str255 filename;
+        VFile *vf;
+        Handle texth;
+        FSSpec fss;
+        CWNewProjectEntryInfo entry;
+        SInt32 pos;
+
+        UCBSecretDetachHandle(context, docinfo->text, &texth);
+
+        if (docinfo->markDirty) {
+            if (!docinfo->documentname)
+                return cwErrInvalidParameter;
+
+            vf = VFile_New(docinfo->documentname, texth);
+            if (!vf)
+                return cwErrOutOfMemory;
+            if (!VFiles_Add(&gTarg->virtualFiles, vf))
+                return cwErrRequestFailed;
+
+            entry.overlay = -1;
+            entry.overlayGroup = -1;
+            entry.segment = -1;
+            entry.position = -1;
+            entry.groupPath = NULL;
+            entry.initbefore = 0;
+            entry.weakimport = 0;
+            entry.mergeintooutput = 0;
+            c2pstrcpy(filename, docinfo->documentname);
+            FSMakeFSSpec(0, 0, filename, &fss);
+            return UCBAddProjectEntry(context, &fss, 1, &entry, &pos);
+        } else {
+            if (ShowHandle(texth, GetHandleSize(texth), docinfo->documentname != NULL))
+                return cwNoErr;
+            else
+                return cwErrRequestFailed;
+        }
+    } else {
+#line 1755
+        DO_INTERNAL_ERROR("Cannot deal with unexpected document");
+        return cwErrInvalidCallback;
+    }
+}
+
+CWResult UCBAllocateMemory(CWPluginContext context, SInt32 size, Boolean isPermanent, void **ptr) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBAllocateMemory");
+
+    *ptr = xmalloc(NULL, size);
+    return (*ptr == NULL) ? cwErrRequestFailed : cwNoErr;
+}
+
+CWResult UCBFreeMemory(CWPluginContext context, void *ptr, Boolean isPermanent) {
+    if (optsCmdLine.verbose > 4)
+        CLPrint("Callback: %s\n", "UCBFreeMemory");
+
+    if (ptr) {
+        xfree(ptr);
+        return cwNoErr;
+    } else {
+        return cwErrRequestFailed;
+    }
+}
+
+CWResult UCBAllocMemHandle(CWPluginContext context, SInt32 size, Boolean useTempMemory, CWMemHandle *memhandle) {
+    if (optsCmdLine.verbose > 4)
+        CLPrint("Callback: %s\n", "UCBAllocMemHandle");
+
+    Handle handle = NewHandle(size);
+    if (!handle)
+        return cwErrOutOfMemory;
+
+    UCBSecretAttachHandle(context, handle, memhandle);
+    return cwNoErr;
+}
+
+CWResult UCBFreeMemHandle(CWPluginContext context, CWMemHandle memhandle) {
+    if (optsCmdLine.verbose > 4)
+        CLPrint("Callback: %s\n", "UCBFreeMemHandle");
+
+    Handle handle;
+    UCBSecretDetachHandle(context, memhandle, &handle);
+    DisposeHandle(handle);
+    return cwNoErr;
+}
+
+CWResult UCBGetMemHandleSize(CWPluginContext context, CWMemHandle memhandle, SInt32 *size) {
+    if (optsCmdLine.verbose > 4)
+        CLPrint("Callback: %s\n", "UCBGetMemHandleSize");
+
+    Handle handle;
+    UCBSecretDetachHandle(context, memhandle, &handle);
+    *size = GetHandleSize(handle);
+    return cwNoErr;
+}
+
+CWResult UCBResizeMemHandle(CWPluginContext context, CWMemHandle memhandle, SInt32 newSize) {
+    if (optsCmdLine.verbose > 4)
+        CLPrint("Callback: %s\n", "UCBResizeMemHandle");
+
+    Handle handle;
+    UCBSecretDetachHandle(context, memhandle, &handle);
+    SetHandleSize(handle, newSize);
+    return (MemError() == noErr) ? cwNoErr : cwErrOutOfMemory;
+}
+
+CWResult UCBLockMemHandle(CWPluginContext context, CWMemHandle handle, Boolean moveHi, void **ptr) {
+    if (optsCmdLine.verbose > 4)
+        CLPrint("Callback: %s\n", "UCBLockMemHandle");
+
+    HLock(reinterpret_cast<Handle>(handle));
+    *ptr = *reinterpret_cast<Handle>(handle);
+    return cwNoErr;
+}
+
+CWResult UCBUnlockMemHandle(CWPluginContext context, CWMemHandle handle) {
+    if (optsCmdLine.verbose > 4)
+        CLPrint("Callback: %s\n", "UCBUnlockMemHandle");
+
+    HUnlock(reinterpret_cast<Handle>(handle));
+    return cwNoErr;
+}
+
+CWResult UCBGetTargetName(CWPluginContext context, char *name, short maxLength) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBGetTargetName");
+
+    strncpy(name, "command-line target", maxLength);
+    return cwNoErr;
+}
+
+CWResult UCBPreDialog(CWPluginContext context) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBPreDialog");
+
+    return cwNoErr;
+}
+
+CWResult UCBPostDialog(CWPluginContext context) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBPostDialog");
+
+    return cwNoErr;
+}
+
+CWResult UCBPreFileAction(CWPluginContext context, const CWFileSpec *theFile) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBPreFileAction");
+
+#line 1963
+    DO_INTERNAL_ERROR("UCBPreFileAction not implemented");
+    return cwErrRequestFailed;
+}
+
+CWResult UCBPostFileAction(CWPluginContext context, const CWFileSpec *theFile) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBPostFileAction");
+
+#line 1977
+    DO_INTERNAL_ERROR("UCBPostFileAction not implemented");
+    return cwErrRequestFailed;
+}
+
+CWResult UCBCacheAccessPathList(CWPluginContext context) {
+    IDEAccessPathList *apl;
+    shellContextType *sc;
+    int x;
+
+    sc = static_cast<shellContextType *>(context->shellContext);
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBCacheAccessPathList");
+
+    apl = context->accessPathList;
+    if (!apl)
+        apl = context->accessPathList = static_cast<IDEAccessPathList *>(calloc(sizeof(IDEAccessPathList), 1));
+
+    if (sc->userAccessPathsChanged || !apl->userPaths) {
+        OSSpec spec;
+        Path *path;
+        IDEAccessPath *ap;
+
+        apl->userPathCount = Paths_Count(&gTarg->userPaths);
+        apl->userPaths = static_cast<IDEAccessPath *>(xrealloc("access paths", apl->userPaths, sizeof(IDEAccessPath) * apl->userPathCount));
+
+        for (x = 0; x < apl->userPathCount; x++) {
+            ap = &apl->userPaths[x];
+            path = Paths_GetPath(&gTarg->userPaths, x);
+#line 2010
+            OPTION_ASSERT(path);
+
+            OS_MakeSpecWithPath(path->spec, NULL, 0, &spec);
+            OS_OSSpec_To_FSSpec(&spec, &ap->pathSpec);
+            ap->recursive = path->recursive != 0;
+            if (path->recursive) {
+                ap->subdirectoryCount = Paths_CountRecurse(path->recursive);
+                if (ap->subdirectories)
+                    xfree(ap->subdirectories);
+                ap->subdirectories = static_cast<FSSpec *>(xmalloc(NULL, sizeof(FSSpec) * ap->subdirectoryCount));
+                Paths_CopyRecurseFSS(ap->subdirectories, path->recursive, ap->subdirectoryCount);
+            } else {
+                ap->subdirectoryCount = 0;
+                ap->subdirectories = NULL;
+            }
+        }
+
+        sc->userAccessPathsChanged = 0;
+    }
+
+    if (sc->systemAccessPathsChanged || !apl->systemPaths) {
+        OSSpec spec;
+        Path *path;
+        IDEAccessPath *ap;
+
+        apl->systemPathCount = Paths_Count(&gTarg->sysPaths);
+        apl->systemPaths = static_cast<IDEAccessPath *>(xrealloc("access paths", apl->systemPaths, sizeof(IDEAccessPath) * apl->systemPathCount));
+
+        for (x = 0; x < apl->systemPathCount; x++) {
+            ap = &apl->systemPaths[x];
+            path = Paths_GetPath(&gTarg->sysPaths, x);
+#line 2044
+            OPTION_ASSERT(path);
+
+            OS_MakeSpecWithPath(path->spec, NULL, 0, &spec);
+            OS_OSSpec_To_FSSpec(&spec, &ap->pathSpec);
+            ap->recursive = path->recursive != 0;
+            if (path->recursive) {
+                ap->subdirectoryCount = Paths_CountRecurse(path->recursive);
+                if (ap->subdirectories)
+                    xfree(ap->subdirectories);
+                ap->subdirectories = static_cast<FSSpec *>(xmalloc(NULL, sizeof(FSSpec) * ap->subdirectoryCount));
+                Paths_CopyRecurseFSS(ap->subdirectories, path->recursive, ap->subdirectoryCount);
+            } else {
+                ap->subdirectoryCount = 0;
+                ap->subdirectories = NULL;
+            }
+        }
+
+        sc->systemAccessPathsChanged = 0;
+    }
+
+    return cwNoErr;
+}
+
+CWResult UCBSecretAttachHandle(CWPluginContext context, Handle handle, CWMemHandle *memHandle) {
+    if (optsCmdLine.verbose > 4)
+        CLPrint("Callback: %s\n", "UCBSecretAttachHandle");
+
+    *memHandle = reinterpret_cast<CWMemHandle>(handle);
+    return cwNoErr;
+}
+
+CWResult UCBSecretDetachHandle(CWPluginContext context, CWMemHandle memHandle, Handle *handle) {
+    if (optsCmdLine.verbose > 4)
+        CLPrint("Callback: %s\n", "UCBSecretDetachHandle");
+
+    if (!memHandle || !handle) {
+        *handle = NULL;
+        return cwErrInvalidParameter;
+    } else {
+        *handle = reinterpret_cast<Handle>(memHandle);
+        return cwNoErr;
+    }
+}
+
+CWResult UCBSecretPeekHandle(CWPluginContext context, CWMemHandle memHandle, Handle *handle) {
+    if (optsCmdLine.verbose > 4)
+        CLPrint("Callback: %s\n", "UCBSecretPeekHandle");
+
+    if (!memHandle || !handle) {
+        *handle = NULL;
+        return cwErrInvalidParameter;
+    } else {
+        *handle = reinterpret_cast<Handle>(memHandle);
+        return cwNoErr;
+    }
+}
+
+CWResult UCBCheckoutLicense(CWPluginContext context, const char *a, const char *b, SInt32 c, void *d, SInt32 *cookiePtr) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBCheckoutLicense");
+
+    if (cookiePtr)
+        *cookiePtr = 0xD0A;
+
+    return cwErrInvalidCallback;
+}
+
+CWResult UCBCheckinLicense(CWPluginContext context, SInt32 cookie) {
+    if (optsCmdLine.verbose > 3)
+        CLPrint("Callback: %s\n", "UCBCheckinLicense");
+
+    return cwErrInvalidCallback;
+}
+
+CWResult UCBResolveRelativePath(CWPluginContext context, const CWRelativePath *relativePath, CWFileSpec *fileSpec, Boolean create) {
+#line 2255
+    DO_INTERNAL_ERROR("UCBResolveRelativePath not implemented");
+    return cwErrRequestFailed;
+}
+
+CWResult UCBMacOSErrToCWResult(CWPluginContext context, OSErr err) {
+    if (optsCmdLine.verbose > 4)
+        CLPrint("Callback: %s\n", "UCBMacOSErrToCWResult");
+
+    return OSErrtoCWResult(err);
+}
+
+CW_BasePluginCallbacks sBasePluginCallbacks = {
+        UCBGetFileInfo,
+        UCBFindAndLoadFile,
+        UCBGetFileText,
+        UCBReleaseFileText,
+        UCBGetSegmentInfo,
+        UCBGetOverlay1GroupInfo,
+        UCBGetOverlay1Info,
+        UCBGetOverlay1FileInfo,
+        UCBReportMessage,
+        UCBAlert,
+        UCBShowStatus,
+        UCBUserBreak,
+        UCBGetNamedPreferences,
+        UCBStorePluginData,
+        UCBGetPluginData,
+        UCBSetModDate,
+        UCBAddProjectEntry,
+        UCBCreateNewTextDocument,
+        UCBAllocateMemory,
+        UCBFreeMemory,
+        UCBAllocMemHandle,
+        UCBFreeMemHandle,
+        UCBGetMemHandleSize,
+        UCBResizeMemHandle,
+        UCBLockMemHandle,
+        UCBUnlockMemHandle,
+        reinterpret_cast<void *>(UCBSecretAttachHandle),
+        reinterpret_cast<void *>(UCBSecretDetachHandle),
+        reinterpret_cast<void *>(UCBSecretPeekHandle),
+        NULL,
+        NULL,
+        NULL,
+        NULL,
+        NULL,
+        UCBGetTargetName,
+        UCBCacheAccessPathList,
+        UCBPreDialog,
+        UCBPostDialog,
+        UCBPreFileAction,
+        UCBPostFileAction,
+        UCBCheckoutLicense,
+        UCBCheckinLicense,
+        UCBResolveRelativePath
+};
+
+static CWIDEInfo sIDEInfo = {
+        3, 3, 0, 0, 10
+};
+
+CWPluginPrivateContext::CWPluginPrivateContext(SInt32 thePluginType, SInt32 totalSize) {
+    if (totalSize <= 0)
+        totalSize = sizeof(CWPluginPrivateContext);
+    memset(this, 0, totalSize);
+
+    shellSignature = CWFOURCHAR('C','W','I','E');
+    pluginType = thePluginType;
+    shellInfo = &sIDEInfo;
+    callbacks = &sBasePluginCallbacks;
+}
+
+CWPluginPrivateContext::~CWPluginPrivateContext() {
+    int x;
+
+    if (accessPathList) {
+        if (accessPathList->userPathCount) {
+            for (x = 0; x < accessPathList->userPathCount; x++) {
+                if (accessPathList->userPaths[x].subdirectories)
+                    xfree(accessPathList->userPaths[x].subdirectories);
+            }
+        }
+        if (accessPathList->systemPathCount) {
+            for (x = 0; x < accessPathList->systemPathCount; x++) {
+                if (accessPathList->systemPaths[x].subdirectories)
+                    xfree(accessPathList->systemPaths[x].subdirectories);
+            }
+        }
+        xfree(accessPathList->userPaths);
+        xfree(accessPathList->systemPaths);
+        xfree(accessPathList);
+        accessPathList = NULL;
+    }
+}
diff --git a/command_line/CmdLine/Src/Callbacks/CLParserCallbacks_v1.cpp b/command_line/CmdLine/Src/Callbacks/CLParserCallbacks_v1.cpp
index 5dbd4d8..19b7dab 100644
--- a/command_line/CmdLine/Src/Callbacks/CLParserCallbacks_v1.cpp
+++ b/command_line/CmdLine/Src/Callbacks/CLParserCallbacks_v1.cpp
@@ -1,13 +1,220 @@
-/*
- P    9C50 | _UCBParserAddAccessPath
- P    9DE4 | _UCBParserSwapAccessPaths
- P    9E90 | _UCBParserSetNamedPreferences
- P    9F50 | _UCBParserSetFileOutputName
- P    A03C | _UCBParserSetOutputFileDirectory
- P    A110 | _UCBParserAddOverlay1Group
- P    A1EC | _UCBParserAddOverlay1
- P    A2D0 | _UCBParserAddSegment
- P    A364 | _UCBParserSetSegment
- P    A400 | ___ct__15CWParserContextFv
- P    A480 | ___dt__15CWParserContextFv
- */
\ No newline at end of file
+#include "cmdline.h"
+#include "plugin_internal.h"
+
+extern char STSbuf[256];
+
+CWResult UCBParserAddAccessPath(CWPluginContext context, const CWNewAccessPathInfo *api) {
+    OSSpec oss;
+    Paths *paths;
+    Path *path;
+    int err;
+
+    if ((err = OS_FSSpec_To_OSSpec(&api->pathSpec, &oss))) {
+        context->callbackOSError = OS_MacError(err);
+        return cwErrInvalidParameter;
+    }
+
+    if (optsCmdLine.verbose > 2)
+        CLReport(CLStr77, " search path", OS_PathSpecToString(&oss.path, STSbuf, sizeof(STSbuf)));
+
+    if ((api->type & cwAccessPathTypeFlag1) == 0)
+        paths = &gTarg->sysPaths;
+    else
+        paths = &gTarg->userPaths;
+    path = Path_New(&oss.path);
+
+    path->flags = api->type & cwAccessPathTypeFlag2;
+    if ((api->position >= 0) ? (Paths_InsertPath(paths, api->position, path) == 0) : (Paths_AddPath(paths, path) == 0))
+        return cwErrRequestFailed;
+
+    if (api->recursive) {
+        Paths_GatherRecurse(path);
+        if (CheckForUserBreak())
+            return cwErrUserCanceled;
+    }
+
+    if (!(api->type & cwAccessPathTypeFlag1))
+        static_cast<shellContextType *>(context->shellContext)->systemAccessPathsChanged = 1;
+    else
+        static_cast<shellContextType *>(context->shellContext)->userAccessPathsChanged = 1;
+
+    return cwNoErr;
+}
+
+CWResult UCBParserSwapAccessPaths(CWPluginContext context) {
+    Path *tmp;
+    UInt16 idx;
+
+    for (idx = 0; idx < Paths_Count(&gTarg->sysPaths); idx++) {
+        tmp = Paths_GetPath(&gTarg->sysPaths, idx);
+        if (!(tmp->flags & cwAccessPathTypeFlag2)) {
+            Paths_AddPath(&gTarg->userPaths, tmp);
+            Paths_RemovePath(&gTarg->sysPaths, idx);
+            idx--;
+        }
+    }
+
+    return cwNoErr;
+}
+
+int (*PrefPanelsChangedCallback)(const char *);
+
+CWResult UCBParserSetNamedPreferences(CWPluginContext context, const char *panelName, Handle paneldata) {
+    PrefPanel *panel;
+
+    panel = Prefs_FindPanel(panelName);
+    if (!panel) {
+        panel = PrefPanel_New(panelName, *paneldata, GetHandleSize(paneldata));
+        if (!panel || !Prefs_AddPanel(panel))
+            return cwErrRequestFailed;
+    } else {
+        if (!PrefPanel_PutHandle(panel, paneldata))
+            return cwErrRequestFailed;
+    }
+
+    if (PrefPanelsChangedCallback)
+        PrefPanelsChangedCallback(panelName);
+
+    return cwNoErr;
+}
+
+CWResult UCBParserSetFileOutputName(CWPluginContext context, SInt32 position, short which, const char *outfilename) {
+    if (position < 0)
+        return cwErrInvalidParameter;
+
+    File *file = Files_GetFile(&gTarg->files, position);
+    if (!file)
+        return cwErrUnknownFile;
+
+    if (file->outfileowner)
+        CLReportError(CLStr103, file->srcfilename, file->outfilename);
+
+    strcpy(file->outfilename, outfilename);
+    if (which == 1)
+        file->outfileowner = CmdLineStageMask_Cg;
+    else if (which == 2)
+        file->outfileowner = CmdLineStageMask_Pp;
+    else if (which == 3)
+        file->outfileowner = CmdLineStageMask_Ds;
+    else
+        return cwErrInvalidParameter;
+
+    return cwNoErr;
+}
+
+CWResult UCBParserSetOutputFileDirectory(CWPluginContext context, const CWFileSpec *idefss) {
+    OSSpec fss;
+    int err;
+
+    if ((err = OS_FSSpec_To_OSSpec(idefss, &fss))) {
+        context->callbackOSError = OS_MacError(err);
+        return cwErrInvalidParameter;
+    }
+
+    gTarg->outputDirectory = fss.path;
+    context->outputFileDirectory = *idefss;
+
+    return cwNoErr;
+}
+
+CWResult UCBParserAddOverlay1Group(CWPluginContext context, const char *name, const CWAddr64 *addr, SInt32 *newGroupNumber) {
+    if (gTarg->linkmodel != LinkModel2)
+        return cwErrInvalidCallback;
+
+    OvlGroup *grp;
+    OvlAddr oaddr;
+    oaddr.hi = addr->hi;
+    oaddr.lo = addr->lo;
+
+    grp = OvlGroup_New(name, oaddr);
+    if (!grp)
+        return cwErrRequestFailed;
+    if (!Overlays_AddOvlGroup(&gTarg->linkage.overlays, grp, newGroupNumber))
+        return cwErrRequestFailed;
+
+    ++context->numOverlayGroups;
+    if (optsCmdLine.verbose > 2)
+        CLReport(CLStr79, name, oaddr.hi, oaddr.lo);
+
+    return cwNoErr;
+}
+
+CWResult UCBParserAddOverlay1(CWPluginContext context, const char *name, SInt32 groupNumber, SInt32 *newOverlayNumber) {
+    if (gTarg->linkmodel != LinkModel2)
+        return cwErrInvalidCallback;
+
+    OvlGroup *grp;
+    Overlay *ovl;
+
+    grp = Overlays_GetOvlGroup(&gTarg->linkage.overlays, groupNumber);
+    if (!grp)
+        return cwErrRequestFailed;
+    ovl = Overlay_New(name);
+    if (!ovl)
+        return cwErrOutOfMemory;
+    if (!OvlGroup_AddOverlay(grp, ovl, newOverlayNumber))
+        return cwErrOutOfMemory;
+
+    if (optsCmdLine.verbose > 2)
+        CLReport(CLStr78, name, grp->name);
+
+    return cwNoErr;
+}
+
+CWResult UCBParserAddSegment(CWPluginContext context, const char *name, short attrs, SInt32 *newSegmentNumber) {
+    if (gTarg->linkmodel != LinkModel1)
+        return cwErrInvalidCallback;
+
+    Segment *seg;
+    UInt16 index;
+
+    seg = Segment_New(name, attrs);
+    if (!Segments_AddSegment(&gTarg->linkage.segs, seg, &index))
+        return cwErrRequestFailed;
+
+    *newSegmentNumber = index;
+    return cwNoErr;
+}
+
+CWResult UCBParserSetSegment(CWPluginContext context, SInt32 segmentNumber, const char *name, short attrs) {
+    if (gTarg->linkmodel != LinkModel1)
+        return cwErrInvalidCallback;
+
+    Segment *seg = Segments_GetSegment(&gTarg->linkage.segs, segmentNumber);
+    if (!seg)
+        return cwErrUnknownSegment;
+
+    strncpy(seg->name, name, sizeof(seg->name));
+    seg->name[sizeof(seg->name) - 1] = 0;
+    seg->attrs = attrs;
+
+    return cwNoErr;
+}
+
+static CWParserCallbacks parser_cb = {
+        UCBParserAddAccessPath,
+        UCBParserSwapAccessPaths,
+        UCBParserSetNamedPreferences,
+        UCBParserSetFileOutputName,
+        UCBParserSetOutputFileDirectory,
+        UCBParserAddOverlay1Group,
+        UCBParserAddOverlay1,
+        UCBParserAddSegment,
+        UCBParserSetSegment
+};
+
+CWParserContext::CWParserContext() : CWPluginPrivateContext(CWDROPINPARSERTYPE, -1) {
+    args = NULL;
+    os = 0;
+    cpu = 0;
+    numPlugins = 0;
+    plugins = NULL;
+    numPanels = 0;
+    panelNames = NULL;
+    panel_args = NULL;
+    plugin_args = NULL;
+    callbacks = &parser_cb;
+}
+
+CWParserContext::~CWParserContext() {
+}
-- 
cgit v1.2.3