diff options
author | Ash Wolf <ninji@wuffs.org> | 2022-10-19 21:16:13 +0100 |
---|---|---|
committer | Ash Wolf <ninji@wuffs.org> | 2022-10-19 21:16:13 +0100 |
commit | d1f153d34b023d81768f6087f67dbfff714bafc9 (patch) | |
tree | a694d470a60655d0cda15a70791fbdb90a2398cf /command_line | |
parent | 775b6861666af36d317fb577cf489e2c6377f878 (diff) | |
download | MWCC-d1f153d34b023d81768f6087f67dbfff714bafc9.tar.gz MWCC-d1f153d34b023d81768f6087f67dbfff714bafc9.zip |
let's commit all this before my VM blows up and nukes my work
Diffstat (limited to 'command_line')
37 files changed, 7833 insertions, 211 deletions
diff --git a/command_line/C++_Parser/Src/Library/WarningHelpers.c b/command_line/C++_Parser/Src/Library/WarningHelpers.c new file mode 100644 index 0000000..35a6fa8 --- /dev/null +++ b/command_line/C++_Parser/Src/Library/WarningHelpers.c @@ -0,0 +1,84 @@ +#include "parser.h" + +int SetWarningFlags(const char *opt, void *str, const char *, int flags) { + // this is very similar to ToolHelper + // might also fail to match + unsigned char *ptr; + Boolean set; + Boolean no; + UInt16 flag; + + ptr = (unsigned char *) str; + no = (Boolean) ((flags & PARAMPARSEFLAGS_8) >> 3); + set = (Boolean) (no ^ 1); + + while (*ptr) { + if (*ptr == '+') { + set = !no; + } else if (*ptr == '-') { + set = no; + } else if (*ptr == '|') { + set = (Boolean) (no ^ 1); + } else { + flag = (ptr[0] << 8) | ptr[1]; + + if (set) + pCmdLine.noWarnings = 0; + + switch (flag) { + case 'Nw': + pCmdLine.noWarnings = set; + break; + case 'Aw': + TargetSetWarningFlags(flag, set); + break; + case 'Cw': + pCmdLine.noCmdLineWarnings = !set; + break; + case 'We': + pCmdLine.warningsAreErrors = set; + TargetSetWarningFlags(flag, set); + break; + default: + if (!TargetSetWarningFlags(flag, set)) + CLPFatalError("Bad warning settings in %s (%c%c)\n", str, ptr[0], ptr[1]); + } + + ++ptr; + } + + ++ptr; + } + + Parser_StorePanels(parseopts.context); + + return 1; +} + +int DisplayWarningOptions() { + Handle h; + + h = NewHandle(0); + if (!h) + exit(-23); + + HPrintF(h, "Command-line warning options:\n"); + + if (pCmdLine.noCmdLineWarnings) + HPrintF(h, "\t- no command-line warnings\n"); + else + HPrintF(h, "\t- command-line warnings\n"); + + if (pCmdLine.warningsAreErrors) + HPrintF(h, "\t- warnings are errors\n"); + else + HPrintF(h, "\t- warnings are not errors\n"); + + if (pCmdLine.noWarnings) + HPrintF(h, "\t- no warnings at all\n"); + + TargetDisplayWarningOptions(h); + ShowTextHandle(NULL, h); + DisposeHandle(h); + return 1; +} diff --git a/command_line/CmdLine/Src/CLBrowser.c b/command_line/CmdLine/Src/CLBrowser.c index e69de29..826d395 100644 --- a/command_line/CmdLine/Src/CLBrowser.c +++ b/command_line/CmdLine/Src/CLBrowser.c @@ -0,0 +1,217 @@ +#include "cmdline.h" + +typedef struct { + UInt16 fileID; + char *filepath; +} S43; + +typedef struct { + UInt16 fileID; + char unused[12]; + UInt16 filename_length; + char filepath[1]; +} S49; + +typedef struct { + char magic_word[4]; + char version; + char big_endian; + char padding[16]; + UInt16 file_data_count; + UInt32 browse_data_offset; + UInt32 browse_data_length; + UInt32 file_data_offset; + UInt32 file_data_length; +} T53; + +static void GetBrowseTableInfoAndLock(OSHandle *browsetable, S43 **scan, SInt32 *num, SInt32 *size) { + UInt32 tsize; + + OS_GetHandleSize(browsetable, &tsize); + if (scan) + *scan = OS_LockHandle(browsetable); + if (num) + *num = tsize / sizeof(S43); + if (size) + *size = tsize; +} + +int Browser_Initialize(OSHandle *browsetableptr) { + int err = OS_NewHandle(0, browsetableptr); + if (err) { + CLReportOSError(63, err, "allocate", "browse file table"); + return 0; + } else { + return 1; + } +} + +static int Destroy(OSHandle *browsetable) { + S43 *scan; + SInt32 num; + + GetBrowseTableInfoAndLock(browsetable, &scan, &num, NULL); + while (num--) { + xfree(scan->filepath); + scan++; + } + OS_UnlockHandle(browsetable); + return 1; +} + +int Browser_Terminate(OSHandle *browsetableptr) { + if (!Destroy(browsetableptr)) { + return 0; + } else { + OS_FreeHandle(browsetableptr); + return 1; + } +} + +int Browser_SearchFile(OSHandle *browsetable, const char *fullpath, SInt16 *ID) { + S43 *scan; + SInt32 cnt; + SInt32 idx; + SInt32 size; + Boolean found = 0; + +#line 114 + OPTION_ASSERT(OS_IsFullPath(fullpath)); + OPTION_ASSERT(browsetable!=NULL); + + GetBrowseTableInfoAndLock(browsetable, &scan, &cnt, &size); + for (idx = 0; idx < cnt; idx++) { + if (OS_EqualPath(fullpath, scan->filepath)) { + found = 1; + break; + } + scan++; + } + + if (found) + *ID = scan->fileID; + else + *ID = 0; + + OS_UnlockHandle(browsetable); + return found; +} + +int Browser_SearchAndAddFile(OSHandle *browsetable, const char *fullpath, SInt16 *ID) { + S43 *scan; + SInt32 cnt; + SInt32 size; + char *pathptr; + + if (!Browser_SearchFile(browsetable, fullpath, ID)) { + pathptr = xstrdup(fullpath); + GetBrowseTableInfoAndLock(browsetable, &scan, &cnt, &size); + OS_UnlockHandle(browsetable); + if (OS_ResizeHandle(browsetable, sizeof(S43) * (cnt + 1))) { + fprintf(stderr, "\n*** Out of memory\n"); + exit(-23); + } + + scan = (S43 *) (((char *) OS_LockHandle(browsetable)) + size); + scan->filepath = pathptr; + scan->fileID = cnt + 1; + OS_UnlockHandle(browsetable); + + *ID = scan->fileID; + return -1; + } else { + return 1; + } +} + +static SInt32 CalcDiskSpaceRequirements(S43 *mem, int num) { + SInt32 space = 0; + while (num--) { + space += 0x10; + space += (strlen(mem->filepath) + 7) & ~7; + mem++; + } + return space; +} + +static int ConvertMemToDisk(S43 *mem, S49 *disk, int num) { + int slen; + int blen; + + while (num--) { + disk->fileID = mem->fileID; + memset(disk->unused, 0, sizeof(disk->unused)); + slen = strlen(mem->filepath); + blen = (slen + 7) & ~7; + disk->filename_length = slen; + memset(disk->filepath, 0, blen); + strncpy(disk->filepath, mem->filepath, slen); + disk = (S49 *) (((unsigned char *) disk) + 0x10 + blen); + mem++; + } + + return 1; +} + +int Browser_PackBrowseFile(Handle browsedata, OSHandle *browsetable, OSHandle *browsefileptr) { + OSHandle h; + char *ptr; + T53 header; + S43 *scan; + SInt32 entries; + UInt32 datasize; + UInt32 tableoffs; + UInt32 tablesize; + UInt32 totalsize; + SInt32 a_long = 1; + int err; + void *bptr; + +#line 253 + OPTION_ASSERT(browsedata!=NULL); + OPTION_ASSERT(browsetable!=NULL); + + datasize = GetHandleSize(browsedata); + tableoffs = (datasize + sizeof(header) + 7) & ~7; + + GetBrowseTableInfoAndLock(browsetable, &scan, &entries, NULL); + tablesize = CalcDiskSpaceRequirements(scan, entries); + OS_UnlockHandle(browsetable); + + totalsize = tablesize + tableoffs; + + memcpy(header.magic_word, "DubL", 4); + header.version = 1; + header.big_endian = *((char *) &a_long) == 0; + memset(header.padding, 0, sizeof(header.padding)); + + header.browse_data_offset = sizeof(header); + header.browse_data_length = datasize; + header.file_data_offset = tableoffs; + header.file_data_length = tablesize; + header.file_data_count = entries; + + err = OS_NewHandle(totalsize, &h); + *browsefileptr = h; + if (err) { + fprintf(stderr, "\n*** Out of memory\n"); + exit(-23); + } + + ptr = OS_LockHandle(&h); + memcpy(ptr, &header, sizeof(header)); + + HLock(browsedata); + memcpy(&ptr[sizeof(header)], *browsedata, datasize); + // an 'add' for this is swapped around and i cannot fucking figure out why + memset(&ptr[sizeof(header) + datasize], 0, tableoffs - sizeof(header) - datasize); + HUnlock(browsedata); + + GetBrowseTableInfoAndLock(browsetable, &scan, &entries, NULL); + ConvertMemToDisk(scan, bptr = ptr + tableoffs, entries); + memset((char *) bptr + tablesize, 0, totalsize - tableoffs - tablesize); + OS_UnlockHandle(browsetable); + OS_UnlockHandle(&h); + return 1; +} + diff --git a/command_line/CmdLine/Src/CLDependencies.c b/command_line/CmdLine/Src/CLDependencies.c index e69de29..8c4c13b 100644 --- a/command_line/CmdLine/Src/CLDependencies.c +++ b/command_line/CmdLine/Src/CLDependencies.c @@ -0,0 +1,407 @@ +#include "cmdline.h" + +extern char STSbuf[256]; + +static Path *specialAccessPath; +SInt16 *CLT_filesp; +CPrepFileInfoStack *CLT_filestack; + +// forward decl +static Boolean FindFileInPaths(Paths *paths, const char *filename, Path **thepath, OSSpec *spec); +static void SetSpecialAccessPathFromIncludeStackTOS(); + +Boolean Incls_Initialize(Incls *incls, Target *targ) { + specialAccessPath = NULL; + incls->targ = targ; + incls->maxincls = 0; + incls->numincls = 0; + incls->bufpos = 0; + incls->buflen = 0; + incls->buffer = NULL; + incls->files = NULL; + incls->allPaths = xmalloc(NULL, sizeof(Paths)); + Paths_Initialize(incls->allPaths); + return 1; +} + +void Incls_Terminate(Incls *incls) { + if (incls->buffer) + xfree(incls->buffer); + if (incls->files) + xfree(incls->files); + Paths_Terminate(incls->allPaths); + xfree(incls->allPaths); +} + +static Boolean IsSysIncl(Incls *incls, SInt32 idx) { + InclFile *i = &incls->files[idx]; + return i->syspath; +} + +static void MakeInclFileSpec(Incls *incls, SInt32 idx, OSSpec *spec) { + InclFile *f = &incls->files[idx]; + OS_MakeSpecWithPath( + f->globalpath->spec, + &incls->buffer[f->filenameoffs], + 0, + spec); +} + +static Boolean QuickFindFileInIncls(Incls *incls, Boolean fullsearch, const char *filename, OSSpec *spec, SInt32 *index, InclFile **f) { + int idx; + for (idx = 0; idx < incls->numincls; idx++) { + *f = &incls->files[idx]; + if (OS_EqualPath(&incls->buffer[(*f)->filenameoffs], filename)) { + if (fullsearch || (*f)->syspath) { + MakeInclFileSpec(incls, idx, spec); + *index = idx; + return 1; + } + } + } + return 0; +} + +static Boolean SameIncl(Incls *incls, SInt32 a, SInt32 b) { + InclFile *ia; + InclFile *ib; + if (a == b) + return 1; + ia = &incls->files[a]; + ib = &incls->files[b]; + return ia->globalpath == ib->globalpath && OS_EqualPath(&incls->buffer[ia->filenameoffs], &incls->buffer[ib->filenameoffs]); +} + +static Path *FindOrAddGlobalInclPath(Paths *paths, OSPathSpec *spec) { + Path *path = Paths_FindPathSpec(paths, spec); + if (!path) { + path = Path_New(spec); + Paths_AddPath(paths, path); + } + return path; +} + +static Boolean _FindFileInPath(Path *path, const char *filename, Path **thepath, OSSpec *spec) { + if (!OS_MakeSpecWithPath(path->spec, filename, 0, spec) && OS_IsFile(spec)) { + *thepath = path; + return 1; + } + + if (path->recursive && FindFileInPaths(path->recursive, filename, thepath, spec)) + return 1; + + return 0; +} + +static Boolean FindFileInPaths(Paths *paths, const char *filename, Path **thepath, OSSpec *spec) { + UInt16 idx; + Path *path; + + for (idx = 0; idx < Paths_Count(paths); idx++) { + path = Paths_GetPath(paths, idx); +#line 175 + OPTION_ASSERT(path); + if (_FindFileInPath(path, filename, thepath, spec)) + return 1; + } + + return 0; +} + +static void AddFileToIncls(Incls *incls, char *infilename, Boolean syspath, Path *accesspath, Path *globalpath, Path *specialpath, SInt32 *index) { + InclFile *f; + int fnlen; + char *filename; + OSSpec spec; + + if (!accesspath && !globalpath) + filename = OS_GetFileNamePtr(infilename); + else + filename = infilename; + fnlen = strlen(filename) + 1; + + if (incls->numincls >= incls->maxincls) { + incls->maxincls += 16; + incls->files = xrealloc("include list", incls->files, sizeof(InclFile) * incls->maxincls); + } + + f = &incls->files[incls->numincls]; + f->filenameoffs = incls->bufpos; + f->syspath = syspath; + f->accesspath = accesspath; + if (globalpath) { + f->globalpath = globalpath; + } else if (accesspath) { + f->globalpath = FindOrAddGlobalInclPath(incls->allPaths, accesspath->spec); + } else { + OS_MakeFileSpec(infilename, &spec); + f->globalpath = FindOrAddGlobalInclPath(incls->allPaths, &spec.path); + } + f->specialpath = Deps_GetSpecialAccessPath(); + + if (incls->bufpos + fnlen > incls->buflen) { + incls->buflen += 1024; + incls->buffer = xrealloc("include list", incls->buffer, incls->buflen); + } + strcpy(&incls->buffer[incls->bufpos], filename); + incls->bufpos += fnlen; + *index = incls->numincls++; +} + +Boolean Incls_FindFileInPaths(Incls *incls, char *filename, Boolean fullsearch, OSSpec *spec, SInt32 *inclidx) { + Boolean found; + InclFile *incl; + Boolean foundglobal; + Path *globalpath; + Path *accesspath; + Path *specialpath; + Boolean userpath; + char rel_path[256]; + + found = 0; + if (optsCompiler.includeSearch == 3 && fullsearch) + SetSpecialAccessPathFromIncludeStackTOS(); + *inclidx = -1; + + foundglobal = QuickFindFileInIncls(incls, fullsearch, filename, spec, inclidx, &incl); + if (foundglobal) { + if (incl->specialpath == specialAccessPath && incl->syspath && !fullsearch) + found = 1; + else if (!incl->accesspath) + foundglobal = 0; + } + + if (!found) { + accesspath = globalpath = NULL; + userpath = fullsearch; + if (OS_IsFullPath(filename)) { + found = !OS_MakeFileSpec(filename, spec) && !OS_Status(spec); + accesspath = globalpath = specialpath = NULL; + } else { + specialpath = Deps_GetSpecialAccessPath(); + globalpath = specialpath; + if (specialpath) { + found = _FindFileInPath(specialpath, filename, &globalpath, spec); + accesspath = NULL; + } + if (!found && foundglobal && incl->syspath && !fullsearch) { + globalpath = incl->globalpath; + accesspath = incl->accesspath; + specialpath = NULL; + MakeInclFileSpec(incls, *inclidx, spec); + found = 1; + } + if (!found && fullsearch) { + userpath = 1; + globalpath = NULL; + found = FindFileInPaths(&incls->targ->userPaths, filename, &accesspath, spec); + } + if (!found) { + userpath = 0; + globalpath = NULL; + found = FindFileInPaths(&incls->targ->sysPaths, filename, &accesspath, spec); + } + if (!found) { + specialpath = Deps_GetSpecialAccessPath(); + globalpath = specialpath; + if (!found && MakeFrameworkPath(rel_path, filename, specialpath)) { + filename = rel_path; + found = FindFileInPaths(&FrameworkPaths, filename, &globalpath, spec); + } + } + } + + if (found && *inclidx < 0) + AddFileToIncls(incls, filename, !userpath, accesspath, globalpath, specialpath, inclidx); + } + + return found; +} + +Boolean Deps_Initialize(Deps *deps, Incls *incls) { + deps->numDeps = 0; + deps->maxDeps = 0; + deps->list = NULL; + deps->incls = incls; + return 1; +} + +void Deps_Terminate(Deps *deps) { + if (deps->list) + xfree(deps->list); +} + +int Deps_ChangeSpecialAccessPath(OSSpec *srcfss, Boolean initialize) { + static OSSpec *currentsrcfss; + OSPathSpec pathspec; + OSPathSpec *pathspecptr; + + if (initialize && srcfss) + currentsrcfss = srcfss; + + switch (optsCompiler.includeSearch) { + case IncludeSearch_Type2: + specialAccessPath = NULL; + return 1; + case IncludeSearch_Type0: + if (!initialize) + return 1; + OS_GetCWD(&pathspec); + pathspecptr = &pathspec; + break; + case IncludeSearch_Type1: + if (!initialize) + return 1; + case IncludeSearch_Type3: + if (srcfss) { + pathspecptr = &srcfss->path; + } else if (currentsrcfss) { + pathspecptr = ¤tsrcfss->path; + } else { + OS_GetCWD(&pathspec); + pathspecptr = &pathspec; + } + break; + default: +#line 468 + DO_INTERNAL_ERROR("Unhandled include file search type (%d)\n", optsCompiler.includeSearch); + } + + specialAccessPath = FindOrAddGlobalInclPath(gTarg->incls.allPaths, pathspecptr); + if (optsCmdLine.verbose > 2) + CLReport(105, OS_PathSpecToString(pathspecptr, STSbuf, sizeof(STSbuf))); + return 1; +} + +Path *Deps_GetSpecialAccessPath() { + return specialAccessPath; +} + +static void SetSpecialAccessPathFromIncludeStackTOS() { + // does not match, some registers are in the wrong order + OSSpec spec; + SInt16 index; + char *fnameptr; + VFile *vf; + + if (optsCompiler.includeSearch == IncludeSearch_Type3 && CLT_filesp && CLT_filestack) { + if (*CLT_filesp >= 0) { + index = *CLT_filesp; + while (index) { + if (!(*CLT_filestack)[index]) + break; + OS_FSSpec_To_OSSpec(&(*CLT_filestack)[index--]->textfile, &spec); + fnameptr = OS_GetFileNamePtr(OS_NameSpecToString(&spec.name, STSbuf, sizeof(STSbuf))); + vf = VFiles_Find(gTarg->virtualFiles, fnameptr); + if (!vf) { + if (!specialAccessPath || !OS_EqualPathSpec(&spec.path, specialAccessPath->spec)) { + Deps_ChangeSpecialAccessPath(&spec, 0); + return; + } + return; + } + } + } + Deps_ChangeSpecialAccessPath(NULL, 0); + } +} + +static Boolean FindDepFile(Deps *deps, SInt32 incl) { + int idx; + + for (idx = 0; idx < deps->numDeps; idx++) { + if (SameIncl(&gTarg->incls, deps->list[idx], incl)) + return 1; + } + + return 0; +} + +static void AddDepFile(Deps *deps, SInt32 incl, SInt16 dependencyType) { + if (deps->numDeps >= deps->maxDeps) { + deps->maxDeps += 16; + deps->list = xrealloc("dependency list", deps->list, sizeof(SInt32) * deps->maxDeps); + } + deps->list[deps->numDeps++] = incl; +} + +void Deps_AddDependency(Deps *deps, SInt32 incl, OSSpec *spec, Boolean unk, SInt16 dependencyType, Boolean *alreadyincluded) { + Boolean included; + + if (incl < 0) { + AddFileToIncls( + &gTarg->incls, + OS_SpecToString(spec, STSbuf, sizeof(STSbuf)), + 0, + NULL, NULL, NULL, + &incl); + } + + included = FindDepFile(deps, incl); + if (!included) { + if (!(optsCompiler.depsOnlyUserFiles ? IsSysIncl(deps->incls, incl) : 0)) + AddDepFile(deps, incl, dependencyType); + } + + if (alreadyincluded) + *alreadyincluded = included; +} + +static char *EscapeName(Boolean spaces, char *escbuf, char *path) { + char *ret; + + if (!spaces) + return path; + + ret = escbuf; + while (*path) { + if (*path == ' ') + *(escbuf++) = '\\'; + *(escbuf++) = *(path++); + } + *escbuf = 0; + return ret; +} + +void Deps_ListDependencies(Incls *incls, File *file, OSHandle *h) { + Boolean spaces; + int idx; + char linebuf[512]; + char outfilename[256]; + int totdeps; + char path[256]; + char escbuf[320]; + OSSpec spec; + +#define LIST_DEP(format, name, ...) \ +do { \ +sprintf(linebuf, format, spaces ? "" : "", EscapeName(spaces, escbuf, (name)), spaces ? "" : "", __VA_ARGS__); \ +if (OS_AppendHandle(h, linebuf, strlen(linebuf))) goto memFail; \ +} while (0) + + if (!OS_NewHandle(0, h)) { + totdeps = file->deps.numDeps; + OS_SpecToStringRelative(&file->outfss, NULL, outfilename, sizeof(outfilename)); + if (outfilename[0]) { + spaces = strchr(outfilename, ' ') != NULL; + LIST_DEP("%s%s%s%s ", outfilename, ":"); + spaces = strchr(file->srcfilename, ' ') != NULL; + LIST_DEP("%s%s%s %s\n", file->srcfilename, totdeps ? "\\" : ""); + } else { + spaces = strchr(file->srcfilename, ' ') != NULL; + LIST_DEP("%s%s%s%s %s\n", file->srcfilename, ":", totdeps ? "\\" : ""); + } + + for (idx = 0; idx < file->deps.numDeps; idx++) { + totdeps--; + MakeInclFileSpec(incls, file->deps.list[idx], &spec); + OS_SpecToString(&spec, path, sizeof(path)); + spaces = strchr(path, ' ') != NULL; + LIST_DEP("\t%s%s%s %s\n", path, totdeps ? "\\" : ""); + } + } else { + memFail: + fprintf(stderr, "\n*** Out of memory\n"); + exit(-23); + } +} diff --git a/command_line/CmdLine/Src/CLFileOps.c b/command_line/CmdLine/Src/CLFileOps.c index e69de29..14c9dc6 100644 --- a/command_line/CmdLine/Src/CLFileOps.c +++ b/command_line/CmdLine/Src/CLFileOps.c @@ -0,0 +1,803 @@ +#include "cmdline.h" + +extern char STSbuf[256]; + +static int OutputTextData(File *file, SInt16 stage, OSType maccreator, OSType mactype) { + int ret = 0; + SInt32 size; + + if (file->textdata) { + size = GetHandleSize(file->textdata); + if (stage != CmdLineStageMask_Dp || optsCmdLine.toDisk & CmdLineStageMask_Dp) { + if (!(file->writeToDisk & stage)) { + ret = ShowHandle(file->textdata, size, 0); + } else { + if (optsCmdLine.verbose) + CLReport(15, OS_SpecToStringRelative(&file->outfss, NULL, STSbuf, sizeof(STSbuf))); + ret = WriteHandleToFile(&file->outfss, file->textdata, size, maccreator, mactype); + file->wroteToDisk |= stage; + } + } else { + if (optsCompiler.outMakefile[0]) { + ret = AppendHandleToFile(&clState.makefileSpec, file->textdata, size, maccreator, mactype); + } else { + ret = ShowHandle(file->textdata, size, 0); + } + } + + DisposeHandle(file->textdata); + file->textdata = NULL; + } + + return ret; +} + +static int fstrcat(char *file, const char *add, SInt32 length) { + if (strlen(file) + strlen(add) >= length) { + return 0; + } else { + strcat(file, add); + return 1; + } +} + +static void extstrcat(char *file, const char *ext) { + if (!fstrcat(file, ext, 64)) + strcpy(file + 63 - strlen(ext), ext); +} + +int GetOutputFile(File *file, SInt16 stage) { + int err; + char tempoutfilename[256]; + char *targetoutfilename; + Boolean specifiedName; + const char *ext; + const CWObjectFlags *cof; + char tmpname[256]; + char *env; + char *extptr; + char *fnptr; + char text[64]; + char *inname; + OSPathSpec tmppath; + + if (optsCmdLine.toDisk & stage) + file->writeToDisk |= stage; + + if (file->outfileowner == stage) { + targetoutfilename = file->outfilename; + specifiedName = file->outfilename[0] && !(file->tempOnDisk & stage); + if (specifiedName) { + file->writeToDisk |= stage; + file->tempOnDisk &= ~stage; + } + } else { + targetoutfilename = tempoutfilename; + specifiedName = 0; + } + + if (!(stage & (optsCmdLine.toDisk | file->writeToDisk | file->tempOnDisk))) { + if ((stage == CmdLineStageMask_Cg) && (optsCmdLine.stages & CmdLineStageMask_Ds) && (optsCmdLine.state == OptsCmdLineState_2) && optsCompiler.keepObjects) + file->writeToDisk |= stage; + else + file->tempOnDisk |= stage; + } + + if (!specifiedName && (stage & (optsCmdLine.toDisk | file->writeToDisk | file->tempOnDisk))) { + cof = Plugin_CL_GetObjectFlags(file->compiler); + if (stage == CmdLineStageMask_Pp) { + ext = optsCompiler.ppFileExt[0] ? optsCompiler.ppFileExt : cof->ppFileExt; + } else if (stage == CmdLineStageMask_Ds) { + ext = optsCompiler.disFileExt[0] ? optsCompiler.disFileExt : cof->disFileExt; + } else if (stage == CmdLineStageMask_Dp) { + ext = optsCompiler.depFileExt[0] ? optsCompiler.depFileExt : cof->depFileExt; + } else if (stage == CmdLineStageMask_Cg) { + ext = optsCompiler.objFileExt[0] ? optsCompiler.objFileExt : cof->objFileExt; + if (!(file->objectflags & 0x80000000) && !specifiedName) + ext = NULL; + } else { + ext = NULL; + } + + if (ext && ext[0]) { + if (ext[0] != '.') { + snprintf(text, sizeof(text), ".%s", ext); + } else { + strncpy(text, ext, sizeof(text) - 1); + text[sizeof(text) - 1] = 0; + } + if ((file->tempOnDisk & stage) && !(optsCmdLine.stages & CmdLineStageMask_Dp)) { + env = getenv("TEMP"); + if (!env || !env[0] || OS_MakePathSpec(NULL, env, &tmppath)) + env = getenv("TMP"); + if (!env || !env[0] || OS_MakePathSpec(NULL, env, &tmppath)) + env = getenv("TMPDIR"); + if (!env || !env[0] || OS_MakePathSpec(NULL, env, &tmppath)) + env = "/tmp"; + if (!env || !env[0] || OS_MakePathSpec(NULL, env, &tmppath)) + env = "."; + snprintf(tmpname, sizeof(tmpname), "%s%c%s", env, OS_PATHSEP, OS_GetFileNamePtr(file->srcfilename)); + inname = tmpname; + } else if (!optsCompiler.relPathInOutputDir) { + inname = OS_GetFileNamePtr(file->srcfilename); + } else { + inname = file->srcfilename; + } + + fnptr = OS_GetFileNamePtr(inname); + extptr = strrchr(fnptr, '.'); + if (!extptr || ext[0] == '.') + extptr = fnptr + strlen(fnptr); + + if (extptr - fnptr + strlen(text) >= sizeof(text)) + extptr = &fnptr[sizeof(text) - 1] - strlen(text); + + snprintf(targetoutfilename, 256, "%.*s%s", extptr - inname, inname, text); + } else { + *targetoutfilename = 0; + file->writeToDisk &= ~stage; + file->tempOnDisk &= ~stage; + } + } + + if (stage & (file->writeToDisk | file->tempOnDisk)) { + err = OS_MakeSpecWithPath(&gTarg->outputDirectory, targetoutfilename, !optsCompiler.relPathInOutputDir, &file->outfss); + if (!err) { + if (OS_EqualSpec(&file->srcfss, &file->outfss)) { + if (specifiedName) { + CLReportError(102, targetoutfilename); + file->writeToDisk &= ~stage; + file->tempOnDisk &= ~stage; + return 0; + } + file->writeToDisk &= ~stage; + file->tempOnDisk &= ~stage; + } + } else { + CLReportOSError(9, err, targetoutfilename, OS_PathSpecToString(&gTarg->outputDirectory, STSbuf, sizeof(STSbuf))); + } + return err == 0; + } + + return 1; +} + +static int SyntaxCheckFile(File *file) { + return SendCompilerRequest(file->compiler, file, 0) != 0; +} + +static int PreprocessFile(File *file) { + const CWObjectFlags *cof; + + if (!(file->dropinflags & kCanpreprocess)) { + CLReportWarning(53, Plugin_GetDropInName(file->compiler), file->srcfilename); + return 1; + } + + if (!SendCompilerRequest(file->compiler, file, 1)) + return 0; + + if (!GetOutputFile(file, CmdLineStageMask_Pp)) + return 0; + + if (file->textdata) { + cof = Plugin_CL_GetObjectFlags(file->compiler); + return OutputTextData( + file, CmdLineStageMask_Pp, + optsCompiler.ppFileCreator ? optsCompiler.ppFileCreator : cof->ppFileCreator, + optsCompiler.ppFileType ? optsCompiler.ppFileType : cof->ppFileType); + } + + CLReportError(96, "preprocessing", file->srcfilename); + return 0; +} + +static int DependencyMapFile(File *file, Boolean compileifnecessary) { + OSHandle mf; + const CWObjectFlags *cof; + + cof = Plugin_CL_GetObjectFlags(file->compiler); + if (!(optsCmdLine.stages & (CmdLineStageMask_Pp | CmdLineStageMask_Cg)) && compileifnecessary) { + if (!SendCompilerRequest(file->compiler, file, CmdLineStageMask_Dp)) + return 0; + } + + if (!GetOutputFile(file, CmdLineStageMask_Cg)) + return 0; + + Deps_ListDependencies(&gTarg->incls, file, &mf); + file->textdata = OS_CreateMacHandle(&mf); + + if (!GetOutputFile(file, CmdLineStageMask_Dp)) + return 0; + + if (OutputTextData( + file, CmdLineStageMask_Dp, + optsCompiler.depFileCreator ? optsCompiler.depFileCreator : cof->depFileCreator, + optsCompiler.depFileType ? optsCompiler.depFileType : cof->depFileType)) { + return 1; + } else { + return 0; + } +} + +static int RecordBrowseInfo(File *file) { + const CWObjectFlags *cof; + + if (!file->recordbrowseinfo) + return 1; + + if (!file->browsedata) { + CLReportError(101, Plugin_GetDropInName(file->compiler), OS_SpecToStringRelative(&file->srcfss, NULL, STSbuf, sizeof(STSbuf))); + return 0; + } + + if ((optsCmdLine.toDisk & CmdLineStageMask_Cg) && optsCompiler.browserEnabled) { + cof = Plugin_CL_GetObjectFlags(file->compiler); + if (!WriteBrowseData(file, optsCompiler.brsFileCreator ? optsCompiler.brsFileCreator : cof->brsFileCreator, optsCompiler.brsFileType ? optsCompiler.brsFileType : cof->brsFileType)) + return 0; + } + + return 1; +} + +static int RecordObjectData(File *file) { + const CWObjectFlags *cof = Plugin_CL_GetObjectFlags(file->compiler); + + if (!file->objectdata) + return 1; + + if (!WriteObjectFile(file, optsCompiler.objFileCreator ? optsCompiler.objFileCreator : cof->objFileCreator, optsCompiler.objFileType ? optsCompiler.objFileType : cof->objFileType)) + return 0; + + return 1; +} + +int StoreObjectFile(File *file) { + if (file->wroteToDisk & CmdLineStageMask_Cg) + return 1; + + if (!file->objectdata && !file->browsedata) + return 1; + + if (GetOutputFile(file, CmdLineStageMask_Cg)) { + if (!((file->writeToDisk | file->tempOnDisk) & CmdLineStageMask_Cg)) + return 1; + + if (!RecordBrowseInfo(file) || !RecordObjectData(file)) + return 0; + + file->wroteToDisk |= CmdLineStageMask_Cg; + return 1; + } + + return 0; +} + +static int CompileFile(File *file) { + int ret = 1; + + if (!(file->dropinflags & kCanprecompile) && ((optsCompiler.forcePrecompile == 1) || (file->mappingflags & kPrecompile))) { + CLReportWarning(54, Plugin_GetDropInName(file->compiler), file->srcfilename); + return 1; + } + + if (optsCompiler.browserEnabled) { + SInt16 id; + int ret; + char fullpath[256]; + memset(file->browseoptions, 1, sizeof(file->browseoptions)); + OS_SpecToString(&file->srcfss, fullpath, sizeof(fullpath)); + ret = Browser_SearchAndAddFile(&clState.browseTableHandle, fullpath, &id); + if (!ret) + return 0; + file->recordbrowseinfo = ret < 0; + file->browseFileID = id; + if (optsCmdLine.verbose > 1) + CLReport(22, file->srcfilename, file->browseFileID); + } else { + memset(file->browseoptions, 0, sizeof(file->browseoptions)); + file->recordbrowseinfo = 0; + file->recordbrowseinfo = 0; + file->browseFileID = 0; + } + + if (!SendCompilerRequest(file->compiler, file, 2)) { + ret = 0; + } else { + if ((!file->hasobjectcode || !file->objectdata) && (file->dropinflags & kGeneratescode) && (file->objectUsage & 2)) { + CLReportError(96, "compiling", file->srcfilename); + ret = 0; + } else if (optsCmdLine.state == OptsCmdLineState_2 && !StoreObjectFile(file)) { + ret = 0; + } + } + + return ret; +} + +static int DisassembleWithLinker(File *file, Plugin *linker, SInt32 linkerDropinFlags) { + char filename[256]; + int ret; + + if (file->writeToDisk & CmdLineStageMask_Ds) { + OS_SpecToString(&file->outfss, filename, sizeof(filename)); + ret = ExecuteLinker(linker, linkerDropinFlags, file, (optsCmdLine.toDisk & CmdLineStageMask_Ds) ? NULL : filename, NULL); + file->wroteToDisk |= CmdLineStageMask_Ds; + return ret; + } + + return ExecuteLinker(linker, linkerDropinFlags, file, NULL, NULL); +} + +static int DisassembleFile(File *file) { + Plugin *disasm; + + if (!file->hasobjectcode && !file->hasresources) { + CLReportError(56, file->srcfilename); + return 0; + } + + if (!GetOutputFile(file, CmdLineStageMask_Ds)) + return 0; + + if (file->dropinflags & kCandisassemble) { + if (!SendDisassemblerRequest(file->compiler, file)) + return 0; + + if (file->textdata) { + const CWObjectFlags *cof = Plugin_CL_GetObjectFlags(file->compiler); + return OutputTextData( + file, CmdLineStageMask_Ds, + optsCompiler.disFileCreator ? optsCompiler.disFileCreator : cof->disFileCreator, + optsCompiler.disFileType ? optsCompiler.disFileType : cof->disFileType); + } + CLReportError(96, "disassembling", file->srcfilename); + return 0; + + } else { + if ((gTarg->linkerDropinFlags & dropInExecutableTool) && !(gTarg->linkerDropinFlags & cantDisassemble)) + return DisassembleWithLinker(file, gTarg->linker, gTarg->linkerDropinFlags); + if ((gTarg->preLinkerDropinFlags & dropInExecutableTool) && !(gTarg->preLinkerDropinFlags & cantDisassemble)) + return DisassembleWithLinker(file, gTarg->preLinker, gTarg->preLinkerDropinFlags); + + if (gTarg->linker && !(gTarg->linkerDropinFlags & cantDisassemble)) { + if (SendDisassemblerRequest(gTarg->linker, file)) { + if (file->textdata && GetHandleSize(file->textdata) > 0) { + const CWObjectFlags *cof = Plugin_CL_GetObjectFlags(file->compiler); + return OutputTextData( + file, CmdLineStageMask_Ds, + optsCompiler.disFileCreator ? optsCompiler.disFileCreator : cof->disFileCreator, + optsCompiler.disFileType ? optsCompiler.disFileType : cof->disFileType); + } + CLReportError(96, "disassembling", file->srcfilename); + } + return 0; + } + if (gTarg->preLinker && !(gTarg->preLinkerDropinFlags & cantDisassemble)) { + if (SendDisassemblerRequest(gTarg->preLinker, file)) { + if (file->textdata && GetHandleSize(file->textdata) > 0) { + const CWObjectFlags *cof = Plugin_CL_GetObjectFlags(file->compiler); + return OutputTextData( + file, CmdLineStageMask_Ds, + optsCompiler.disFileCreator ? optsCompiler.disFileCreator : cof->disFileCreator, + optsCompiler.disFileType ? optsCompiler.disFileType : cof->disFileType); + } + CLReportError(96, "disassembling", file->srcfilename); + } + return 0; + } + + if (gTarg->linker) + CLReportError(58, Plugin_GetDropInName(gTarg->linker), Plugin_GetDropInName(file->compiler), file->srcfilename); + else + CLReportError(57, Plugin_GetDropInName(file->compiler), file->srcfilename); + + return 0; + } +} + +static int CompileEntry(File *file, Boolean *compiled) { + UInt32 beginWork; + UInt32 endWork; + struct BuildInfo *tinfo = &gTarg->info; + + *compiled = 0; + + if (optsCmdLine.dryRun) { + *compiled = 1; + return 1; + } + + if (!(file->sourceUsage & 1)) { + if (file->mappingflags & kRsrcfile) + *compiled = 1; + return 1; + } + +#line 835 + OPTION_ASSERT(file->compiler); + + *compiled = 1; + beginWork = OS_GetMilliseconds(); + Browser_Initialize(&clState.browseTableHandle); + Deps_ChangeSpecialAccessPath(&file->srcfss, 1); + + if ((optsCmdLine.stages == 0) && !SyntaxCheckFile(file)) + return 0; + if ((optsCmdLine.stages & CmdLineStageMask_Pp) && !PreprocessFile(file)) + return 0; + if ((optsCmdLine.stages & (CmdLineStageMask_Cg | CmdLineStageMask_Ds)) && !CompileFile(file)) + return 0; + if ((optsCmdLine.stages & CmdLineStageMask_Dp) && !DependencyMapFile(file, 1)) + return 0; + if ((optsCmdLine.stages & CmdLineStageMask_Ds) && !DisassembleFile(file)) + return 0; + + if (optsCmdLine.verbose && (optsCmdLine.stages & CmdLineStageMask_Cg)) { + const char *cun; + const char *dun; + const char *uun; + CLReport(25, file->compiledlines); + tinfo->linesCompiled += file->compiledlines; + cun = dun = uun = "bytes"; + CLReport(26, file->codesize, cun, file->idatasize, dun, file->udatasize, uun); + } + tinfo->codeSize += file->codesize; + tinfo->iDataSize += file->idatasize; + tinfo->uDataSize += file->udatasize; + + Browser_Terminate(&clState.browseTableHandle); + endWork = OS_GetMilliseconds(); + + if (optsCmdLine.timeWorking) { + if (optsCmdLine.verbose) + CLReport(24, (endWork - beginWork) / 1000.0, "compile", "", "", ""); + else + CLReport(24, (endWork - beginWork) / 1000.0, "compile", "'", file->srcfilename, "'"); + } + + return 1; +} + +static void DumpFileAndPathInfo() { + int i; + int n; + + CLReport(84, "Framework search paths ([d] = default, [r] = recursive)"); + n = Paths_Count(&FrameworkPaths); + if (!n) { + CLReport(85, "(none)", ""); + } else { + for (i = 0; i < n; i++) { + Path *path = Paths_GetPath(&FrameworkPaths, i); +#line 961 + OPTION_ASSERT(path != NULL); + + CLReport(85, + OS_PathSpecToString(path->spec, STSbuf, sizeof(STSbuf)), + ((path->flags & 2) && path->recursive) ? " [d] [r]" : (path->flags & 2) ? " [d]" : path->recursive ? " [r]" : "" + ); + + if (path->recursive && optsCmdLine.verbose > 2) { + UInt16 j; + for (j = 0; j < Paths_Count(path->recursive); j++) { + Path *sub = Paths_GetPath(path->recursive, j); +#line 976 + OPTION_ASSERT(sub); + CLReport(85, "\t", OS_PathSpecToString(sub->spec, STSbuf, sizeof(STSbuf))); + } + } + } + } + + n = Frameworks_GetCount(); + if (Frameworks_GetCount()) { + CLReport(84, "Included frameworks"); + for (i = 0; i < n; i++) { + char version[80]; + Paths_FWInfo *info = Frameworks_GetInfo(i); +#line 993 + OPTION_ASSERT(info); + + version[0] = 0; + strcpy(version, "\t("); + if (!info->version.s[0]) { + strcat(version, "Current)"); + } else { + strncat(version, info->version.s, sizeof(version) - 4); + strcat(version, ")"); + } + CLReport(85, info->name.s, version); + } + } + + if (clState.plugintype == CWDROPINCOMPILERTYPE) + CLReport(84, "User include search paths ([d] = default, [r] = recursive)"); + else + CLReport(84, "Library search paths ([d] = default, [r] = recursive)"); + + if (!Paths_Count(&gTarg->userPaths) && clState.plugintype == CWDROPINCOMPILERTYPE) { + CLReport(85, "(none)", ""); + } else { + for (i = 0; i < Paths_Count(&gTarg->userPaths); i++) { + Path *path = Paths_GetPath(&gTarg->userPaths, i); +#line 1024 + OPTION_ASSERT(path != NULL); + + CLReport(85, + OS_PathSpecToString(path->spec, STSbuf, sizeof(STSbuf)), + ((path->flags & 2) && path->recursive) ? " [d] [r]" : (path->flags & 2) ? " [d]" : path->recursive ? " [r]" : "" + ); + + if (path->recursive && optsCmdLine.verbose > 2) { + UInt16 j; + for (j = 0; j < Paths_Count(path->recursive); j++) { + Path *sub = Paths_GetPath(path->recursive, j); +#line 1039 + OPTION_ASSERT(sub); + CLReport(85, "\t", OS_PathSpecToString(sub->spec, STSbuf, sizeof(STSbuf))); + } + } + } + } + + if (clState.plugintype == CWDROPINCOMPILERTYPE) + CLReport(84, "System include search paths ([d] = default, [r] = recursive)"); + + if (!Paths_Count(&gTarg->sysPaths)) + CLReport(85, "(none)", ""); + + for (i = 0; i < Paths_Count(&gTarg->sysPaths); i++) { + Path *path = Paths_GetPath(&gTarg->sysPaths, i); +#line 1054 + OPTION_ASSERT(path != NULL); + + CLReport(85, + OS_PathSpecToString(path->spec, STSbuf, sizeof(STSbuf)), + ((path->flags & 2) && path->recursive) ? " [d] [r]" : (path->flags & 2) ? " [d]" : path->recursive ? " [r]" : "" + ); + + if (path->recursive && optsCmdLine.verbose > 2) { + UInt16 j; + for (j = 0; j < Paths_Count(path->recursive); j++) { + Path *sub = Paths_GetPath(path->recursive, j); +#line 1069 + OPTION_ASSERT(sub); + CLReport(85, "\t", OS_PathSpecToString(sub->spec, STSbuf, sizeof(STSbuf))); + } + } + } + + if (clState.plugintype == CWDROPINCOMPILERTYPE) + CLReport(84, "Files in project (relative to CWD)"); + else + CLReport(84, "Link order for project (relative to CWD)"); + + for (i = 0; i < Files_Count(&gTarg->files); i++) { + File *file = Files_GetFile(&gTarg->files, i); + if (!VFiles_Find(gTarg->virtualFiles, file->srcfilename)) + CLReport(85, OS_SpecToStringRelative(&file->srcfss, NULL, STSbuf, sizeof(STSbuf)), ""); + else + CLReport(85, file->srcfilename, "\t(virtual file)"); + } +} + +int CompileFilesInProject() { + struct BuildInfo *tinfo; + SInt32 index; + SInt32 startTime; + SInt32 endTime; + int ignored; + int compiled; + Boolean failed; + + failed = 0; + startTime = OS_GetMilliseconds(); + InitializeIncludeCache(); + if (optsCmdLine.verbose > 1) + DumpFileAndPathInfo(); + + if (!SendTargetInfoRequest(gTarg, gTarg->linker, gTarg->linkerDropinFlags)) + return Result_Failed; + + ignored = 0; + compiled = 0; + for (index = 0; index < Files_Count(&gTarg->files); index++) { + int ret; + File *file; + Boolean wascompiled; + + file = Files_GetFile(&gTarg->files, index); + if (!file->outfileowner) + file->outfileowner = CmdLineStageMask_Cg; + ret = CompileEntry(file, &wascompiled); + if (ret) { + if (wascompiled) + compiled++; + if (!wascompiled) + ignored++; + if (CheckForUserBreak()) + return Result_Cancelled; + } + + if (!ret) { + if (optsCompiler.noFail) { + failed = 1; + clState.countWarnings = 0; + clState.countErrors = 0; + clState.withholdWarnings = 0; + clState.withholdErrors = 0; + } else { + return CheckForUserBreak() ? Result_Cancelled : Result_Failed; + } + } + } + + if (optsCmdLine.stages & CmdLineStageMask_Dp) { + for (index = 0; index < Files_Count(&gTarg->pchs); index++) { + int ret; + File *file; + + file = Files_GetFile(&gTarg->pchs, index); + ret = DependencyMapFile(file, 0); + if (!ret) { + if (optsCompiler.noFail) { + failed = 1; + clState.countWarnings = 0; + clState.countErrors = 0; + clState.withholdWarnings = 0; + clState.withholdErrors = 0; + } else { + return CheckForUserBreak() ? Result_Cancelled : Result_Failed; + } + } + } + } + + CleanupIncludeCache(); + + tinfo = &gTarg->info; + if (optsCmdLine.verbose && compiled > 1) { + const char *cun; + const char *dun; + const char *uun; + cun = dun = uun = "bytes"; + CLReport(27, tinfo->codeSize, cun, tinfo->iDataSize, dun, tinfo->uDataSize, uun); + } + + endTime = OS_GetMilliseconds(); + + if (optsCmdLine.timeWorking) + CLReport(24, (endTime - startTime) / 1000.0, "compile", "", "", "project"); + + if (ignored > 0 && compiled == 0 && (gTarg->preLinker || gTarg->linker)) + CLReportError(29); + + if (failed) + return Result_Failed; + return CheckForUserBreak() ? Result_Cancelled : Result_Success; +} + +static int PostLinkFilesInProject() { + SInt32 index; + SInt32 startTime; + SInt32 endTime; + File *file; + FSSpec fss; + + startTime = OS_GetMilliseconds(); + for (index = 0; index < Files_Count(&gTarg->files); index++) { + file = Files_GetFile(&gTarg->files, index); + OS_OSSpec_To_FSSpec(&file->srcfss, &fss); + gTarg->targetinfo->outfile = fss; + gTarg->targetinfo->runfile = fss; + gTarg->targetinfo->symfile = fss; + + if (!SendLinkerRequest(gTarg->postLinker, gTarg->postLinkerDropinFlags, gTarg->targetinfo)) { + return CheckForUserBreak() ? Result_Cancelled : Result_Failed; + } else { + if (CheckForUserBreak()) + return Result_Cancelled; + } + } + endTime = OS_GetMilliseconds(); + + if (optsCmdLine.timeWorking) + CLReport(24, (endTime - startTime) / 1000.0, "compile", "", "", "project"); + + return CheckForUserBreak() ? Result_Cancelled : Result_Success; +} + +int LinkProject() { + SInt32 startTime; + SInt32 endTime; + + startTime = OS_GetMilliseconds(); + if (!SendTargetInfoRequest(gTarg, gTarg->linker, gTarg->linkerDropinFlags)) + return Result_Failed; + if (!SetupTemporaries()) + return Result_Failed; + + if (gTarg->preLinker && optsLinker.callPreLinker && optsCmdLine.state == OptsCmdLineState_3) { + SInt32 subStart; + SInt32 subEnd; + + subStart = OS_GetMilliseconds(); + if (gTarg->preLinkerDropinFlags & dropInExecutableTool) { + if (!ExecuteLinker(gTarg->preLinker, gTarg->preLinkerDropinFlags, NULL, NULL, NULL)) + return Result_Failed; + } else if (!optsCmdLine.dryRun) { + if (!SendLinkerRequest(gTarg->preLinker, gTarg->preLinkerDropinFlags, gTarg->targetinfo)) + return CheckForUserBreak() ? Result_Cancelled : Result_Failed; + } + subEnd = OS_GetMilliseconds(); + + if (optsCmdLine.timeWorking) + CLReport(24, (subEnd - subStart) / 1000.0, "prelink project", "", "", ""); + } + + if (gTarg->linker && optsLinker.callLinker && optsCmdLine.state == OptsCmdLineState_3) { + SInt32 subStart; + SInt32 subEnd; + + subStart = OS_GetMilliseconds(); + if (gTarg->linkerDropinFlags & dropInExecutableTool) { + if (!ExecuteLinker(gTarg->linker, gTarg->linkerDropinFlags, NULL, NULL, NULL)) + return Result_Failed; + } else if (!optsCmdLine.dryRun) { + if (!SendLinkerRequest(gTarg->linker, gTarg->linkerDropinFlags, gTarg->targetinfo)) + return CheckForUserBreak() ? Result_Cancelled : Result_Failed; + } + subEnd = OS_GetMilliseconds(); + + if (optsCmdLine.timeWorking) + CLReport(24, (subEnd - subStart) / 1000.0, "link project", "", "", ""); + } + + if (gTarg->postLinker && optsLinker.callPostLinker && optsCmdLine.state == OptsCmdLineState_3) { + SInt32 subStart; + SInt32 subEnd; + FSSpec fss; + OSSpec outfile; + + subStart = OS_GetMilliseconds(); + if (gTarg->postLinkerDropinFlags & dropInExecutableTool) { + if (!ExecuteLinker(gTarg->postLinker, gTarg->postLinkerDropinFlags, NULL, NULL, NULL)) + return Result_Failed; + } else if (!optsCmdLine.dryRun) { + if (!SendTargetInfoRequest(gTarg, gTarg->linker, gTarg->linkerDropinFlags)) + return Result_Failed; + if (gTarg->targetinfo->outputType == linkOutputFile) + fss = gTarg->targetinfo->outfile; + if (gTarg->targetinfo->outputType != linkOutputNone) { + if (!SendLinkerRequest(gTarg->postLinker, gTarg->postLinkerDropinFlags, gTarg->targetinfo)) + return CheckForUserBreak() ? Result_Cancelled : Result_Failed; + if (!SendTargetInfoRequest(gTarg, gTarg->postLinker, gTarg->postLinkerDropinFlags)) + return Result_Failed; + } + } + subEnd = OS_GetMilliseconds(); + + if (optsCmdLine.timeWorking) + CLReport(24, (subEnd - subStart) / 1000.0, "postlink project", "", "", ""); + + if (!optsLinker.keepLinkerOutput && gTarg->targetinfo->outputType == linkOutputFile) { + if (optsCmdLine.verbose > 1) { + OS_FSSpec_To_OSSpec(&fss, &outfile); + CLReport(19, OS_SpecToString(&outfile, STSbuf, sizeof(STSbuf))); + } + FSpDelete(&fss); + } + } + + if (!DeleteTemporaries()) + return Result_Failed; + + endTime = OS_GetMilliseconds(); + + if (optsCmdLine.timeWorking) + CLReport(24, (endTime - startTime) / 1000.0, "finish link stage", "", "", ""); + + return Result_Success; +} diff --git a/command_line/CmdLine/Src/CLIncludeFileCache.c b/command_line/CmdLine/Src/CLIncludeFileCache.c index e69de29..d479f36 100644 --- a/command_line/CmdLine/Src/CLIncludeFileCache.c +++ b/command_line/CmdLine/Src/CLIncludeFileCache.c @@ -0,0 +1,159 @@ +#include "cmdline.h" + +typedef struct CacheEntry { + struct CacheEntry *next; + struct CacheEntry *prev; + int locked; + int precompiled; + Handle text; + OSSpec spec; + UInt32 size; + UInt32 when; +} CacheEntry; + +enum { + CACHE_SIZE = 0x800000 +}; + +static CacheEntry *cachelist; +static CacheEntry *freelist; +static UInt32 availablecache; + +static CacheEntry *makecacheentry() { + CacheEntry *c = freelist; + if (c) { + freelist = c->next; + return c; + } else { + return xmalloc("include file cache", sizeof(CacheEntry)); + } +} + +static void insertcacheentry(CacheEntry *c) { + if (cachelist) + cachelist->prev = c; + c->next = cachelist; + c->prev = NULL; + cachelist = c; +} + +static void deletecacheentry(CacheEntry *c) { + if (c->next) + c->next->prev = c->prev; + if (c->prev) + c->prev->next = c->next; + else + cachelist = c->next; +} + +void InitializeIncludeCache() { + freelist = NULL; + cachelist = NULL; + availablecache = CACHE_SIZE; +} + +void CleanupIncludeCache() { + CacheEntry *c; + CacheEntry *c1; + + for (c = cachelist; c; c = c1) { + c1 = c->next; + if (c->text) + DisposeHandle(c->text); + xfree(c); + } + + for (c = freelist; c; c = c1) { + c1 = c->next; + xfree(c); + } + + InitializeIncludeCache(); +} + +void CacheIncludeFile(OSSpec *spec, Handle text, Boolean precompiled) { + UInt32 size; + CacheEntry *c; + CacheEntry *lru; + + size = GetHandleSize(text); + if (precompiled) { + lru = NULL; + for (c = cachelist; c; c = c->next) { + if (c->precompiled) { + lru = c; + break; + } + } + if (lru) { + DisposeHandle(lru->text); + lru->text = NULL; + deletecacheentry(lru); + lru->next = freelist; + freelist = lru; + } + } else { + if ((SInt32) size > (SInt32) CACHE_SIZE) { + return; + } else { + while (size > availablecache) { + lru = NULL; + for (c = cachelist; c; c = c->next) { + if (!c->locked && !c->precompiled && (lru == NULL || c->when < lru->when)) + lru = c; + } + + if (lru) { + DisposeHandle(lru->text); + lru->text = NULL; + availablecache += lru->size; + deletecacheentry(lru); + lru->next = freelist; + freelist = lru; + } else { + return; + } + } + } + } + + c = makecacheentry(); + c->locked = 1; + c->precompiled = precompiled; + c->spec = *spec; + c->text = text; + c->size = size; + c->when = OS_GetMilliseconds(); + insertcacheentry(c); + + if (!precompiled) + availablecache -= size; +} + +Handle CachedIncludeFile(OSSpec *spec, Boolean *precompiled) { + CacheEntry *c; + + for (c = cachelist; c; c = c->next) { + if (OS_EqualSpec(&c->spec, spec)) { + c->when = OS_GetMilliseconds(); + *precompiled = c->precompiled; + c->locked++; + return c->text; + } + } + + return NULL; +} + +void FreeIncludeFile(Handle text) { + CacheEntry *c; + + for (c = cachelist; c; c = c->next) { + if (c->text == text) { + c->locked--; + return; + } + } + + DisposeHandle(text); +} diff --git a/command_line/CmdLine/Src/CLLicenses.c b/command_line/CmdLine/Src/CLLicenses.c index e69de29..f264e6c 100644 --- a/command_line/CmdLine/Src/CLLicenses.c +++ b/command_line/CmdLine/Src/CLLicenses.c @@ -0,0 +1,23 @@ +#include "cmdline.h" + +void License_Initialize() { +} + +void License_Terminate() { +} + +SInt32 License_Checkout() { + return 0xD0AD0A; +} + +void License_Refresh() { + +} + +void License_Checkin() { + +} + +void License_AutoCheckin() { + +} diff --git a/command_line/CmdLine/Src/CLLoadAndCache.c b/command_line/CmdLine/Src/CLLoadAndCache.c index e69de29..efc3f63 100644 --- a/command_line/CmdLine/Src/CLLoadAndCache.c +++ b/command_line/CmdLine/Src/CLLoadAndCache.c @@ -0,0 +1,85 @@ +#include "cmdline.h" + +short FixTextHandle(Handle txt) { + char *tptr; + UInt32 tlen; + char *scan; + + HLock(txt); + tptr = *txt; + tlen = GetHandleSize(txt); + + scan = tptr; + while (scan < (tptr + tlen)) { + if (scan[0] == '\r') { + if (scan[1] == '\n') + scan += 2; + else + scan += 1; + } else if (scan[0] == '\n') { + scan[0] = '\r'; + scan++; + } else { + scan++; + } + } + + HUnlock(txt); + return 0; +} + +int LoadAndCacheFile(OSSpec *spec, Handle *texthandle, Boolean *precomp) { + Handle h; + int err; + OSType mactype; + int refnum; + UInt32 ltxtlen; + + if ((*texthandle = CachedIncludeFile(spec, precomp))) + return 0; + + *precomp = !OS_GetMacFileType(spec, &mactype) && mactype != CWFOURCHAR('T','E','X','T'); + *texthandle = NULL; + + err = OS_Open(spec, OSReadOnly, &refnum); + if (err) + return err; + err = OS_GetSize(refnum, <xtlen); + if (err) + return err; + + h = NewHandle(ltxtlen + 1); + if (!h) { + fprintf(stderr, "\n*** Out of memory\n"); + exit(-23); + } + + HLock(h); + err = OS_Read(refnum, *h, <xtlen); + if (err) { + DisposeHandle(h); + OS_Close(refnum); + return err; + } + + OS_Close(refnum); + (*h)[ltxtlen] = 0; + HUnlock(h); + + if (!*precomp) + FixTextHandle(h); + + CacheIncludeFile(spec, h, *precomp); + *texthandle = h; + return 0; +} + +void CopyFileText(Handle src, char **text, SInt32 *textsize) { + *textsize = GetHandleSize(src); + *text = xmalloc(NULL, *textsize); + + HLock(src); + memcpy(*text, *src, *textsize); + *textsize -= 1; + HUnlock(src); +} diff --git a/command_line/CmdLine/Src/CLMain.c b/command_line/CmdLine/Src/CLMain.c index f8247c4..6e041ad 100644 --- a/command_line/CmdLine/Src/CLMain.c +++ b/command_line/CmdLine/Src/CLMain.c @@ -1,10 +1,10 @@ -#include "mwcc_decomp.h" +#include "cmdline.h" jmp_buf exit_program; int numPlugins; CLPluginInfo *pluginInfo; int numPanels; -char **panelNames; +const char **panelNames; CWCommandLineArgs *panel_args; CWCommandLineArgs *plugin_args; Project mainProj; @@ -18,14 +18,14 @@ char cmdline_build_date[32]; char cmdline_build_time[32]; Project *gProj = &mainProj; -static SInt16 CLT_dummymain(void *context) { +static CWPLUGIN_ENTRY(CLT_dummymain)(CWPluginContext) { return 0; } -static SInt16 CLT_GetDropInFlags(const DropInFlags **flags, SInt32 *flagsSize) { +static CWPLUGIN_ENTRY(CLT_GetDropInFlags)(const DropInFlags **flags, SInt32 *flagsSize) { static const DropInFlags sFlags = { kCurrentDropInFlagsVersion, - CWFOURCHAR('c','l','d','r'), + CWDROPINDRIVERTYPE, 7, 0, 0, @@ -36,19 +36,19 @@ static SInt16 CLT_GetDropInFlags(const DropInFlags **flags, SInt32 *flagsSize) { return 0; } -static SInt16 CLT_GetDropInName(const char **dropinName) { +static CWPLUGIN_ENTRY(CLT_GetDropInName)(const char **dropinName) { static const char *sDropInName = "Command-Line Driver"; *dropinName = sDropInName; return 0; } -static SInt16 CLT_GetDisplayName(const char **displayName) { +static CWPLUGIN_ENTRY(CLT_GetDisplayName)(const char **displayName) { static const char *sDisplayName = "Command-Line Driver"; *displayName = sDisplayName; return 0; } -static SInt16 CLT_GetPanelList(const CWPanelList **panelList) { +static CWPLUGIN_ENTRY(CLT_GetPanelList)(const CWPanelList **panelList) { static const char *sPanelNames[4]; static CWPanelList sPanelList = { kCurrentCWPanelListVersion, @@ -70,7 +70,7 @@ static SInt16 CLT_GetPanelList(const CWPanelList **panelList) { return 0; } -static SInt16 CLT_GetTargetList(const CWTargetList **targetList) { +static CWPLUGIN_ENTRY(CLT_GetTargetList)(const CWTargetList **targetList) { static FourCharCode sCPU = targetCPUAny; static FourCharCode sOS = targetOSAny; static CWTargetList sTargetList = { @@ -84,7 +84,7 @@ static SInt16 CLT_GetTargetList(const CWTargetList **targetList) { return 0; } -static SInt16 CLT_GetVersionInfo(const VersionInfo **versioninfo) { +static CWPLUGIN_ENTRY(CLT_GetVersionInfo)(const VersionInfo **versioninfo) { static const VersionInfo vi = { 3, 0, 0, 0 }; @@ -92,7 +92,7 @@ static SInt16 CLT_GetVersionInfo(const VersionInfo **versioninfo) { return 0; } -static SInt16 CLT_GetFileTypeMappings(const OSFileTypeMappingList **mappinglist) { +static CWPLUGIN_ENTRY(CLT_GetFileTypeMappings)(const OSFileTypeMappingList **mappinglist) { static const OSFileTypeMapping ftmes[2] = { {CWFOURCHAR('B','r','w','s'), "DubL", 4, 0, 0}, {CWFOURCHAR('M','M','P','r'), "looc", 4, 0, 0} @@ -278,12 +278,6 @@ int Main_Terminate(int exitcode) { return exitcode; } -enum { - ResultCode_0 = 0, - ResultCode_1 = 1, - ResultCode_2 = 2 -}; - static int Main_ParseCommandLine() { Plugin *parser; CWCommandLineArgs myargs; @@ -308,7 +302,7 @@ static int Main_ParseCommandLine() { myargs.envp = 0; if (!SendParserRequest(parser, gTarg, &myargs, gTarg->cpu, gTarg->os, numPlugins, pluginInfo, numPanels, panelNames, plugin_args, panel_args, cmdline_build_date, cmdline_build_time, Plugin_GetToolVersionInfo())) { - return CheckForUserBreak() ? ResultCode_2 : ResultCode_1; + return CheckForUserBreak() ? Result_Cancelled : Result_Failed; } if (clState.pluginDebug) { @@ -340,7 +334,7 @@ static int Main_ParseCommandLine() { } } - return ResultCode_0; + return Result_Success; } static int Main_SetupParamBlock() { @@ -622,7 +616,7 @@ static int Main_SetupContext() { CLFatalError("The linker plugin was not found!"); } - gTarg->linkmodel = 0; + gTarg->linkmodel = LinkModel0; Framework_GetEnvInfo(); return 1; diff --git a/command_line/CmdLine/Src/CLPluginAPI.c b/command_line/CmdLine/Src/CLPluginAPI.c deleted file mode 100644 index e69de29..0000000 --- a/command_line/CmdLine/Src/CLPluginAPI.c +++ /dev/null diff --git a/command_line/CmdLine/Src/CLPluginRequests.cpp b/command_line/CmdLine/Src/CLPluginRequests.cpp new file mode 100644 index 0000000..9de50ba --- /dev/null +++ b/command_line/CmdLine/Src/CLPluginRequests.cpp @@ -0,0 +1,348 @@ +#include "cmdline.h" +#include "plugin_internal.h" + +extern "C" { +static CWResult CallPlugin(Plugin *plugin) { + return Plugin_Call(plugin, plugin->context); +} +} + +static void SetupPluginContext(Plugin *plugin, CWResult request) { + OSSpec spec; + shellContextType *sc; + OSPathSpec cwd; + + sc = static_cast<shellContextType *>(plugin->context->shellContext); + sc->plugin = plugin; + sc->systemAccessPathsChanged = 1; + sc->userAccessPathsChanged = 1; + plugin->context->request = request; + plugin->context->apiVersion = 12; + plugin->context->pluginStorage = NULL; + + OS_MakeFileSpec("Project.mcp", &spec); + OS_OSSpec_To_FSSpec(&spec, &plugin->context->projectFile); + if (gTarg) { + OS_MakeSpecWithPath(&gTarg->outputDirectory, NULL, 0, &spec); + OS_OSSpec_To_FSSpec(&spec, &plugin->context->outputFileDirectory); + } else { + OS_GetCWD(&cwd); + OS_MakeSpecWithPath(&cwd, NULL, 0, &spec); + OS_OSSpec_To_FSSpec(&spec, &plugin->context->outputFileDirectory); + } + + plugin->context->shellSignature = CWFOURCHAR('C','W','I','E'); + plugin->context->pluginType = Plugin_GetDropInFlags(plugin)->dropintype; + + if (gTarg) + plugin->context->numFiles = Files_Count(&gTarg->files); + else + plugin->context->numFiles = 0; + + if (gTarg) + plugin->context->numOverlayGroups = Overlays_CountGroups(&gTarg->linkage.overlays); + else + plugin->context->numOverlayGroups = 0; + + plugin->context->pluginOSError = noErr; + plugin->context->callbackOSError = noErr; + plugin->context->accessPathList = NULL; +} + +static void DestroyPluginContext(CWPluginContext context) { +} + +Boolean SendParserRequest( + Plugin *plugin, + Target *target, + CWCommandLineArgs *args, + OSType cpu, + OSType os, + int numPlugins, + CLPluginInfo *pluginInfo, + int numPanels, + const char **panelNames, + CWCommandLineArgs *plugin_args, + CWCommandLineArgs *panel_args, + const char *build_date, + const char *build_time, + const ToolVersionInfo *build_tool +) { + int result; + CWParserContext *pc; + + SetupPluginContext(plugin, 1); + + pc = static_cast<CWParserContext *>(plugin->context); + pc->build_date = build_date; + pc->build_time = build_time; + pc->build_tool = build_tool; + pc->args = args; + pc->cpu = cpu; + pc->os = os; + pc->numPlugins = numPlugins; + pc->plugins = pluginInfo; + pc->numPanels = numPanels; + pc->panelNames = panelNames; + pc->plugin_args = plugin_args; + pc->panel_args = panel_args; + + if (CallPlugin(plugin) != cwNoErr) + return 0; + if (!SendTargetInfoRequest(target, target->linker, target->linkerDropinFlags)) + return 0; + + target->linkmodel = + (target->targetinfo->linkType == exelinkageSegmented) ? LinkModel1 : + (target->targetinfo->linkType == exelinkageOverlay1) ? LinkModel2 : + LinkModel0; + + if (!Plugin_VerifyPanels(plugin)) + return 0; + + SetupPluginContext(plugin, 2); + pc->args = args; + pc->cpu = cpu; + pc->os = os; + pc->numPlugins = numPlugins; + pc->plugins = pluginInfo; + pc->numPanels = numPanels; + pc->panelNames = panelNames; + pc->plugin_args = plugin_args; + pc->panel_args = panel_args; + + result = CallPlugin(plugin); + return (result == cwNoErr); +} + +Boolean SendCompilerRequest(Plugin *plugin, File *file, SInt16 stage) { + CWResult result; + CWCompilerLinkerContext *cc; + Boolean precompiling; + SInt16 type; + OSType mactype; + const char *pn; + int v; + + if (stage & CmdLineStageMask_Cg) { + if (optsCompiler.forcePrecompile == 1) + precompiling = 1; + else if (optsCompiler.forcePrecompile == 2) + precompiling = 0; + else + precompiling = !!(file->mappingflags & kPrecompile); + } else { + precompiling = 0; + } + + if (optsCmdLine.verbose) { + pn = Plugin_GetDropInName(plugin); + v = optsCmdLine.verbose > 1; + if (stage & CmdLineStageMask_Pp) { + CLReport(CLStr34 + v, file->srcfilename, pn); + } else if (stage & CmdLineStageMask_Cg) { + if (precompiling) + CLReport(CLStr32 + v, file->srcfilename, pn); + else + CLReport(CLStr30 + v, file->srcfilename, pn); + } else if (stage & CmdLineStageMask_Dp) { + CLReport(CLStr36 + v, file->srcfilename, pn); + } else if (stage & CmdLineStageMask_Ds) { + CLReport(CLStr46 + v, file->srcfilename, pn); + } else if (!stage) { + CLReport(CLStr48 + v, file->srcfilename, pn); + } + } + + if (!Plugin_VerifyPanels(plugin)) + return 0; + + SetupPluginContext(plugin, reqCompile); + cc = static_cast<CWCompilerLinkerContext *>(plugin->context); + *cc->targetinfo = *gTarg->targetinfo; + + OS_OSSpec_To_FSSpec(&file->srcfss, &cc->sourcefile); + if (!OS_GetMacFileType(&file->srcfss, &mactype) && mactype == CWFOURCHAR('T','E','X','T')) { + if (UCBGetFileText(cc, &cc->sourcefile, &cc->sourcetext, &cc->sourcetextsize, &type) != cwNoErr) + return 0; + } else { + cc->sourcetext = NULL; + cc->sourcetextsize = 0; + } + + cc->whichfile = file->filenum; + cc->debuginfo = optsCmdLine.debugInfo; + cc->recordbrowseinfo = file->recordbrowseinfo; + cc->fileID = file->browseFileID; + memcpy(&cc->browseoptions, file->browseoptions, sizeof(cc->browseoptions)); + + if (stage & (CmdLineStageMask_Pp | CmdLineStageMask_Dp)) { + if (stage & CmdLineStageMask_Pp) + cc->preprocess = 1; + else + cc->preprocess = 2; + } else { + cc->preprocess = 0; + } + + if ((stage & CmdLineStageMask_Cg) && precompiling) { + cc->precompile = 1; + cc->autoprecompile = 1; + } else { + cc->precompile = 0; + cc->autoprecompile = 0; + } + + if (!(stage & (CmdLineStageMask_Pp | CmdLineStageMask_Cg | CmdLineStageMask_Dp))) { + cc->preprocess = 2; + cc->precompile = 2; + } + + result = CallPlugin(plugin); + + if (cc->sourcetext) { + UCBReleaseFileText(cc, cc->sourcetext); + cc->sourcetext = NULL; + cc->sourcetextsize = 0; + } + + return (result == cwNoErr); +} + +Boolean SendTargetInfoRequest(Target *targ, Plugin *linker, SInt32 dropinflags) { + CWResult result; + CWCompilerLinkerContext *cc; + OSSpec spec; + FSSpec fss; + + if (linker && !(dropinflags & dropInExecutableTool)) { + if (optsCmdLine.verbose > 1) + CLReport(CLStr50, Plugin_GetDropInName(linker)); +#line 298 + OPTION_ASSERT(Plugin_GetPluginType(linker) == CWDROPINLINKERTYPE); + + if (!Plugin_VerifyPanels(linker)) + return 0; + + SetupPluginContext(linker, reqTargetInfo); + cc = static_cast<CWCompilerLinkerContext *>(linker->context); + *cc->targetinfo = *targ->targetinfo; + result = CallPlugin(linker); + *targ->targetinfo = *cc->targetinfo; + } else { + OS_MakeFileSpec("(unknown file)", &spec); + OS_OSSpec_To_FSSpec(&spec, &fss); + targ->targetinfo->outputType = linkOutputFile; + targ->targetinfo->outfile = fss; + targ->targetinfo->symfile = fss; + targ->targetinfo->runfile = fss; + targ->targetinfo->linkType = exelinkageFlat; + targ->targetinfo->canRun = 0; + targ->targetinfo->canDebug = 0; + targ->targetinfo->targetCPU = targ->cpu; + targ->targetinfo->targetOS = targ->os; + targ->targetinfo->outfileCreator = CWFOURCHAR('C','W','I','E'); + targ->targetinfo->outfileType = CWFOURCHAR('A','P','P','L'); + targ->targetinfo->debuggerCreator = CWFOURCHAR('M','W','D','B'); + targ->targetinfo->runHelperCreator = CWFOURCHAR('?','?','?','?'); + result = cwNoErr; + } + + return (result == cwNoErr); +} + +Boolean SendLinkerRequest(Plugin *plugin, SInt32 dropinflags, CWTargetInfo *targetInfo) { + CWResult result; + CWCompilerLinkerContext *cc; + const char *nm; + int v; + + if (optsCmdLine.verbose) { + nm = Plugin_GetDropInName(plugin); + v = optsCmdLine.verbose > 1; + if (dropinflags & isPostLinker) + CLReport(CLStr44 + v, nm); + else if (dropinflags & isPreLinker) + CLReport(CLStr42 + v, nm); + else + CLReport(CLStr40 + v, nm); + } + + if (!Plugin_VerifyPanels(plugin)) + return 0; + + SetupPluginContext(plugin, reqLink); + cc = static_cast<CWCompilerLinkerContext *>(plugin->context); + *cc->targetinfo = *targetInfo; + result = CallPlugin(plugin); + *targetInfo = *cc->targetinfo; + + return (result == cwNoErr); +} + +Boolean SendDisassemblerRequest(Plugin *linker, File *file) { + CWResult result; + Plugin *plugin; + + if (linker == NULL) + plugin = file->compiler; + else + plugin = linker; + + if (optsCmdLine.verbose) + CLReport((optsCmdLine.verbose > 1) + CLStr46, file->srcfilename, Plugin_GetDropInName(linker)); + + if (!Plugin_VerifyPanels(plugin)) + return 0; + + if (!linker) { + SetupPluginContext(plugin, reqCompDisassemble); + static_cast<CWCompilerLinkerContext *>(plugin->context)->whichfile = file->filenum; + result = CallPlugin(plugin); + } else { + SetupPluginContext(plugin, reqDisassemble); + static_cast<CWCompilerLinkerContext *>(plugin->context)->whichfile = file->filenum; + result = CallPlugin(plugin); + } + + return (result == cwNoErr); +} + +Boolean SendInitOrTermRequest(Plugin *plugin, Boolean reqIsInitialize) { + CWResult result; + OSType ty; + + result = cwErrRequestFailed; + + if (plugin) { + if (clState.pluginDebug) + CLReport(reqIsInitialize ? CLStr51 : CLStr52, Plugin_GetDropInName(plugin)); + + if (reqIsInitialize) { + ty = Plugin_GetDropInFlags(plugin)->dropintype; + if (ty == CWDROPINDRIVERTYPE) { + plugin->context = new CWPluginPrivateContext(ty); + } else if (ty == CWDROPINPARSERTYPE) { + plugin->context = new CWParserContext(); + } else if (ty == CWDROPINCOMPILERTYPE || ty == CWDROPINLINKERTYPE) { + plugin->context = new CWCompilerLinkerContext(); + } else { + plugin->context = NULL; + } + + plugin->context->shellContext = new shellContextType; + } + + if (plugin->context) { + SetupPluginContext(plugin, reqIsInitialize ? reqInitialize : reqTerminate); + result = CallPlugin(plugin); + } else { + result = cwNoErr; + } + + if (!reqIsInitialize) + License_AutoCheckin(); + } + + return (result == cwNoErr); +} diff --git a/command_line/CmdLine/Src/CLPrefs.c b/command_line/CmdLine/Src/CLPrefs.c index e69de29..7aaa28a 100644 --- a/command_line/CmdLine/Src/CLPrefs.c +++ b/command_line/CmdLine/Src/CLPrefs.c @@ -0,0 +1,123 @@ +#include "cmdline.h" + +struct PrefPanel { + char *name; + Handle data; + Handle workHandle; + PrefPanel *next; +}; + +static PrefPanel *panellist; + +PrefPanel *PrefPanel_New(const char *name, void *initdata, SInt32 initdatasize) { + PrefPanel *pnl; + pnl = xmalloc(NULL, sizeof(PrefPanel)); + if (!pnl) + return pnl; + + pnl->name = xstrdup(name); + pnl->data = NewHandle(initdatasize); + if (!pnl->data) { + fprintf(stderr, "\n*** Out of memory\n"); + exit(-23); + } + + pnl->workHandle = NULL; + + HLock(pnl->data); + if (initdata) + memcpy(*pnl->data, initdata, initdatasize); + else + memset(*pnl->data, 0, initdatasize); + HUnlock(pnl->data); + + pnl->next = NULL; + return pnl; +} + +Handle PrefPanel_GetHandle(PrefPanel *panel) { + UInt32 len = GetHandleSize(panel->data); + if (!panel->workHandle || !*panel->workHandle) + panel->workHandle = NewHandle(len); + else + SetHandleSize(panel->workHandle, len); + +#line 60 + OPTION_ASSERT(MemError()==noErr); + + HLock(panel->data); + HLock(panel->workHandle); + memcpy(*panel->workHandle, *panel->data, len); + HUnlock(panel->workHandle); + HUnlock(panel->data); + return panel->workHandle; +} + +int PrefPanel_PutHandle(PrefPanel *panel, Handle data) { + UInt32 len = GetHandleSize(data); + if (data != panel->workHandle) { + if (!panel->workHandle) + panel->workHandle = NewHandle(len); + else + SetHandleSize(panel->workHandle, len); + if (MemError() != noErr) + return 0; + + HLock(panel->workHandle); + HLock(data); + memcpy(*panel->workHandle, *data, len); + HUnlock(data); + HUnlock(panel->workHandle); + } + + HLock(panel->data); + HLock(panel->workHandle); + memcpy(*panel->data, *panel->workHandle, len); + HUnlock(panel->workHandle); + HUnlock(panel->data); + return 1; +} + +void Prefs_Initialize() { + panellist = NULL; +} + +void Prefs_Terminate() { + PrefPanel *scan; + PrefPanel *next; + + for (scan = panellist; scan; scan = next) { + xfree(scan->name); + DisposeHandle(scan->data); + next = scan->next; + xfree(scan); + } +} + +Boolean Prefs_AddPanel(PrefPanel *panel) { + PrefPanel **scan; + + for (scan = &panellist; *scan; scan = &(*scan)->next) { + if (!strcmp((*scan)->name, panel->name)) { + CLReportError(90, panel->name); + return 0; + } + } + + if (clState.pluginDebug) + CLPrint("Defining/adding pref panel '%s'\n", panel->name); + + *scan = panel; + return 1; +} + +PrefPanel *Prefs_FindPanel(const char *name) { + PrefPanel *scan; + + for (scan = panellist; scan; scan = scan->next) { + if (!ustrcmp(scan->name, name)) + break; + } + + return scan; +} diff --git a/command_line/CmdLine/Src/CLTarg.c b/command_line/CmdLine/Src/CLTarg.c index e69de29..a3f4389 100644 --- a/command_line/CmdLine/Src/CLTarg.c +++ b/command_line/CmdLine/Src/CLTarg.c @@ -0,0 +1,55 @@ +#include "cmdline.h" + +Target *Target_New(const char *name, OSType cpu, OSType os, OSType lang) { + Target *targ; + + targ = xcalloc("target", sizeof(Target)); + + strncpy(targ->targetName, name, sizeof(targ->targetName)); + targ->targetinfo = xcalloc("target info", sizeof(CWTargetInfo)); + targ->cpu = cpu; + targ->os = os; + targ->lang = lang; + + OS_GetCWD(&targ->outputDirectory); + +#line 25 + OPTION_ASSERT(Segments_Initialize(&targ->linkage.segs)); +#line 28 + OPTION_ASSERT(Overlays_Initialize(&targ->linkage.overlays)); +#line 35 + OPTION_ASSERT(Files_Initialize(&targ->files) && Files_Initialize(&targ->pchs) && VFiles_Initialize(&targ->virtualFiles) && + Paths_Initialize(&targ->sysPaths) && Paths_Initialize(&targ->userPaths) && Incls_Initialize(&targ->incls, targ)); + + return targ; +} + +void Target_Free(Target *targ) { + Segments_Terminate(&targ->linkage.segs); + Overlays_Terminate(&targ->linkage.overlays); + Paths_Terminate(&targ->sysPaths); + Paths_Terminate(&targ->userPaths); + Files_Terminate(&targ->files); + Files_Terminate(&targ->pchs); + VFiles_Terminate(&targ->virtualFiles); + Incls_Terminate(&targ->incls); + xfree(targ); +} + +void Targets_Term(Target *list) { + Target *scan; + Target *next; + + for (scan = list; scan; scan = next) { + next = scan->next; + Target_Free(scan); + } +} + +void Target_Add(Target **list, Target *targ) { + Target **scan; + + for (scan = list; *scan; scan = &(*scan)->next) {} + + *scan = targ; +} diff --git a/command_line/CmdLine/Src/CLToolExec.c b/command_line/CmdLine/Src/CLToolExec.c index e69de29..80e3a7c 100644 --- a/command_line/CmdLine/Src/CLToolExec.c +++ b/command_line/CmdLine/Src/CLToolExec.c @@ -0,0 +1,243 @@ +#include "cmdline.h" + +extern char STSbuf[256]; +extern PCmdLine pCmdLine; + +void AppendArgumentList(int *argc, char ***argv, const char *str) { + *argv = xrealloc("command-line arguments", *argv, sizeof(char *) * (*argc + 2)); + (*argv)[(*argc)++] = xstrdup(str); +} + +static int CopyArgumentList(int argc, char **argv, int *Argc, char ***Argv) { + int x; + int y; + + y = Argc ? *Argc : 0; + *Argv = xrealloc("command-line arguments", *Argv, sizeof(char *) * (y + argc + 1)); + + if (argv) { + for (x = 0; x < argc; x++) { + (*Argv)[y++] = xstrdup(argv[x]); + } + } + (*Argv)[y] = NULL; + if (Argc) + *Argc = y; + + return 1; +} + +static int FreeArgumentList(char **argv) { + char **scan; + for (scan = argv; *scan; scan++) + xfree(*scan); + xfree(argv); + return 1; +} + +static int SetupLinkerCommandLine(SInt32 dropinflags, File *file, CWCommandLineArgs *args) { + CWCommandLineArgs *baseargs; + int x; + SInt32 idx; + OSSpec spec; + + for (x = 0; x < numPlugins; x++) { + if (pluginInfo[x].plugintype == CWDROPINLINKERTYPE && ((dropinflags & (isPostLinker | isPreLinker)) == (pluginInfo[x].dropinflags & (isPostLinker | isPreLinker)))) + break; + } + +#line 89 + OPTION_ASSERT(x < numPlugins); + + args->argc = 1; + args->argv = xmalloc("command-line arguments", 2 * sizeof(char *)); + Main_PassSpecialArgs(&args->argc, &args->argv); + + baseargs = &plugin_args[x]; + CopyArgumentList(baseargs->argc - 1, baseargs->argv + 1, &args->argc, &args->argv); + + x = 0; + if (baseargs->envp) { + while (baseargs->envp[x]) + x++; + } + args->envp = NULL; + CopyArgumentList(x, baseargs->envp, NULL, &args->envp); + + if (!file && !(dropinflags & isPostLinker)) { + for (idx = 0; idx < Files_Count(&gTarg->files); idx++) { + file = Files_GetFile(&gTarg->files, idx); + if (file->sourceUsage & CmdLineStageMask_Cg) { + AppendArgumentList(&args->argc, &args->argv, file->srcfilename); + } + if (file->objectUsage & CmdLineStageMask_Cg) { + if (GetOutputFile(file, CmdLineStageMask_Cg) != 0 && StoreObjectFile(file)) + AppendArgumentList(&args->argc, &args->argv, OS_SpecToString(&file->outfss, STSbuf, sizeof(STSbuf))); + else + return 0; + } + } + } else if (file) { + args->argv = xrealloc("command-line arguments", args->argv, sizeof(char *) * (args->argc + 1)); + if (file->sourceUsage & CmdLineStageMask_Cg) { + AppendArgumentList(&args->argc, &args->argv, file->srcfilename); + } + if (file->objectUsage & CmdLineStageMask_Cg) { + if (GetOutputFile(file, CmdLineStageMask_Cg) != 0 && StoreObjectFile(file)) { + AppendArgumentList(&args->argc, &args->argv, OS_SpecToString(&file->outfss, STSbuf, sizeof(STSbuf))); + } + } + if ((pCmdLine.toDisk & CmdLineStageMask_Ds) && (file->objectUsage & CmdLineStageMask_Pp) && file->outfilename[0] && GetOutputFile(file, CmdLineStageMask_Ds)) { + AppendArgumentList(&args->argc, &args->argv, "-o"); + AppendArgumentList(&args->argc, &args->argv, OS_SpecToString(&file->outfss, STSbuf, sizeof(STSbuf))); + } + } else if (dropinflags & isPostLinker) { + OS_FSSpec_To_OSSpec(&gTarg->targetinfo->outfile, &spec); + AppendArgumentList(&args->argc, &args->argv, OS_SpecToString(&spec, STSbuf, sizeof(STSbuf))); + } + + args->argv[args->argc] = NULL; + return 1; +} + +int SetupTemporaries() { + SInt32 idx; + File *file; + + for (idx = 0; idx < Files_Count(&gTarg->files); idx++) { + file = Files_GetFile(&gTarg->files, idx); + if ((file->objectUsage & CmdLineStageMask_Cg) && !(optsCmdLine.toDisk & CmdLineStageMask_Cg) && !(file->writeToDisk & CmdLineStageMask_Cg)) { + if (!optsCompiler.keepObjects) + file->tempOnDisk |= CmdLineStageMask_Cg; + else + file->writeToDisk |= CmdLineStageMask_Cg; + } + } + + return 1; +} + +int DeleteTemporaries() { + SInt32 idx; + File *file; + + for (idx = 0; idx < Files_Count(&gTarg->files); idx++) { + file = Files_GetFile(&gTarg->files, idx); + if ((file->objectUsage & CmdLineStageMask_Cg) && (file->tempOnDisk & CmdLineStageMask_Cg) && (file->wroteToDisk & CmdLineStageMask_Cg)) { + GetOutputFile(file, CmdLineStageMask_Cg); + if (optsCmdLine.verbose > 1) + CLReport(19, OS_SpecToString(&file->outfss, STSbuf, sizeof(STSbuf))); + OS_Delete(&file->outfss); + file->tempOnDisk &= ~CmdLineStageMask_Cg; + file->wroteToDisk &= ~CmdLineStageMask_Cg; + } + } + + return 1; +} + +int ExecuteLinker(Plugin *plugin, SInt32 dropinflags, File *file, char *stdoutfile, char *stderrfile) { + char cname[64]; + const char *linkername; + OSSpec linkerspec; + CWCommandLineArgs args; + int exitcode; + int execerr; + const char *linkertype; + int ret; + char *ptr; + char *ptr2; + int x; + + // TODO rename this flag to isExecutableTool +#line 269 + OPTION_ASSERT(dropinflags & dropInExecutableTool); + + args.argc = 0; + args.argv = args.envp = NULL; + + if (dropinflags & isPreLinker) + linkertype = "pre-linker"; + else if (dropinflags & isPostLinker) + linkertype = "post-linker"; + else + linkertype = "linker"; + + linkername = Plugin_GetDropInName(plugin); + if (!(dropinflags & (isPreLinker | isPostLinker)) && optsCompiler.linkerName[0]) + linkername = optsCompiler.linkerName; + + if (OS_FindProgram(linkername, &linkerspec)) { + strcpy(cname, clState.programName); + + for (ptr = cname; *ptr; ptr++) + *ptr = tolower(*ptr); + + if ((ptr = strstr(cname, "cc")) || (ptr = strstr(cname, "pas")) || (ptr = strstr(cname, "asm"))) { + if (ptr[0] != 'c') { + memmove(ptr + 2, ptr + 3, strlen(ptr) - 3); + ptr[strlen(ptr) - 1] = 0; + } + ptr[0] = 'l'; + ptr[1] = 'd'; + } else { + if ((ptr = strstr(cname, "mwc"))) { + // this ptr2 seems redundant, but it's needed to generate the same code + ptr2 = ptr + 2; + memmove(ptr2 + 3, ptr2, strlen(ptr2)); + memcpy(ptr + 2, "Link", 4); + } + } + + if (!OS_FindProgram(cname, &linkerspec)) { + ptr = cname; + if (optsCompiler.linkerName[0]) { + CLReportWarning(66, linkertype, optsCompiler.linkerName); + CLReport(65, ptr, clState.programName); + } else if (optsCmdLine.verbose) { + CLReport(65, ptr, clState.programName); + } + } else { + CLReportError(66, linkertype, linkername); + return 0; + } + } + + ret = 1; + SetupLinkerCommandLine(dropinflags, file, &args); + args.argv[0] = xstrdup(OS_SpecToString(&linkerspec, STSbuf, sizeof(STSbuf))); + args.argv[args.argc] = 0; + + if (optsCmdLine.verbose || optsCmdLine.dryRun) { + CLPrint("\nCommand line:\n"); + for (x = 0; x < args.argc && args.argv[x]; x++) { + if (strchr(args.argv[x], ' ')) + CLPrint("\"%s\" ", args.argv[x]); + else + CLPrint("%s ", args.argv[x]); + } + CLPrint("\n\n"); + } + + fflush(stdout); + fflush(stderr); + + if (optsCmdLine.verbose) + CLReport(67, linkertype, OS_SpecToString(&linkerspec, STSbuf, sizeof(STSbuf))); + + if (!optsCmdLine.dryRun) { + execerr = OS_Execute(&linkerspec, args.argv, args.envp, stdoutfile, stderrfile, &exitcode); + if (execerr) { + CLReportError(68, linkertype, args.argv[0], OS_GetErrText(execerr)); + ret = 0; + } else if (exitcode) { + CLReportError(69 /*nice*/, linkertype, args.argv[0], exitcode); + ret = 0; + } + } + + FreeArgumentList(args.argv); + FreeArgumentList(args.envp); + + return ret; +} diff --git a/command_line/CmdLine/Src/CLWriteObjectFile.c b/command_line/CmdLine/Src/CLWriteObjectFile.c index e69de29..6e92114 100644 --- a/command_line/CmdLine/Src/CLWriteObjectFile.c +++ b/command_line/CmdLine/Src/CLWriteObjectFile.c @@ -0,0 +1,44 @@ +#include "cmdline.h" + +extern char STSbuf[256]; + +int WriteObjectFile(File *file, OSType maccreator, OSType mactype) { + FSSpec srcfss; + FSSpec outfss; + +#line 22 + OPTION_ASSERT(file->objectdata && file->compiler); + + OS_OSSpec_To_FSSpec(&file->outfss, &outfss); + OS_OSSpec_To_FSSpec(&file->srcfss, &srcfss); + + if (optsCmdLine.verbose) { + CLReport(16, + (file->tempOnDisk & CmdLineStageMask_Cg) ? "temporary " : "", + OS_SpecToStringRelative(&file->outfss, NULL, STSbuf, sizeof(STSbuf))); + } + + if (!Plugin_CL_WriteObjectFile(file->compiler, &srcfss, &outfss, maccreator, mactype, file->objectdata)) + return 0; + else + return 1; +} + +int WriteBrowseData(File *file, OSType maccreator, OSType mactype) { + OSHandle browsehandle; + OSSpec outfss; + const CWObjectFlags *cof; + + cof = Plugin_CL_GetObjectFlags(file->compiler); + outfss = file->outfss; + + OS_NameSpecSetExtension(&outfss.name, optsCompiler.brsFileExt[0] ? optsCompiler.brsFileExt : cof->brsFileExt); + if (optsCmdLine.verbose) { + CLReport(17, OS_SpecToStringRelative(&outfss, NULL, STSbuf, sizeof(STSbuf))); + } + + if (!Browser_PackBrowseFile(file->browsedata, &clState.browseTableHandle, &browsehandle)) + return 0; + + return WriteBinaryHandleToFile(&outfss, maccreator, mactype, &browsehandle) != 0; +} 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(§m); + 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() { +} diff --git a/command_line/CmdLine/Src/Clients/CLStaticMain.c b/command_line/CmdLine/Src/Clients/CLStaticMain.c index cecab30..871dcef 100644 --- a/command_line/CmdLine/Src/Clients/CLStaticMain.c +++ b/command_line/CmdLine/Src/Clients/CLStaticMain.c @@ -1,6 +1,21 @@ -#include "mwcc_decomp.h" +#include "cmdline.h" -int main(int argc, const char **argv) { +extern const char *CMDLINE_BUILD_TIME; +extern const char *CMDLINE_BUILD_DATE; + +// Glue functions +extern int RegisterStaticParserPlugins(); +extern int RegisterStaticParserResources(); + +extern void GetStaticTarget(OSType *cpu, OSType *os); +extern void GetStaticPluginType(OSType *language, OSType *plugintype); +extern void GetStaticParserPluginType(OSType *style); +extern int RegisterStaticTargetResources(); +extern int RegisterStaticTargetPlugins(); + +extern int RegisterStaticParserToolInfo(); + +int main(int argc, char **argv) { OSType cpu; OSType os; OSType lang; diff --git a/command_line/CmdLine/Src/Clients/ClientGlue.c b/command_line/CmdLine/Src/Clients/ClientGlue.c index a1b40b1..6bc0508 100644 --- a/command_line/CmdLine/Src/Clients/ClientGlue.c +++ b/command_line/CmdLine/Src/Clients/ClientGlue.c @@ -1,4 +1,4 @@ -#include "mwcc_decomp.h" +#include "cmdline.h" int RegisterResource(const char *name, SInt16 rsrcid, const char **list) { Handle h; @@ -42,7 +42,7 @@ void SetPluginType(OSType lang, OSType type) { clState.plugintype = type; } -int CmdLine_Initialize(int argc, const char **argv, const char *builddate, const char *buildtime) { +int CmdLine_Initialize(int argc, char **argv, const char *builddate, const char *buildtime) { strncpy(cmdline_build_date, builddate, sizeof(cmdline_build_date)); strncpy(cmdline_build_time, buildtime, sizeof(cmdline_build_time)); return Main_Initialize(argc, argv); diff --git a/command_line/CmdLine/Src/Envir/CLErrors.c b/command_line/CmdLine/Src/Envir/CLErrors.c index 76ff06f..591e30d 100644 --- a/command_line/CmdLine/Src/Envir/CLErrors.c +++ b/command_line/CmdLine/Src/Envir/CLErrors.c @@ -1,37 +1,114 @@ -#include "mwcc_decomp.h" - -static void CLGetErrorString(SInt16 errid, char *buffer) { +#include "cmdline.h" +static char *CLGetErrorString(SInt16 errid, char *buffer) { + getindstring(buffer, 12000, errid); + strcat(buffer, "\n"); + return buffer; } static void CLMessageReporter(int flags, SInt16 errid, va_list va) { - + static char stmsg[256]; + static char stbuf[256]; + char *ptr; + + CLGetErrorString(errid, stmsg); + ptr = mvprintf(stbuf, sizeof(stbuf), stmsg, va); + + CLStyledMessageDispatch( + NULL, + NULL, + 0, + (flags == messagetypeError) ? CLStyledMessageDispatch_Type3 : (flags == messagetypeWarning) ? CLStyledMessageDispatch_Type2 : CLStyledMessageDispatch_Type5, + "%", + ptr); + + if (ptr != stbuf) + free(ptr); } void CLReportError(SInt16 errid, ...) { - + va_list va; + va_start(va, errid); + CLMessageReporter(messagetypeError, errid, va); + va_end(va); } void CLReportWarning(SInt16 errid, ...) { - + va_list va; + va_start(va, errid); + CLMessageReporter(messagetypeWarning, errid, va); + va_end(va); } void CLReport(SInt16 errid, ...) { - + va_list va; + va_start(va, errid); + CLMessageReporter(messagetypeInfo, errid, va); + va_end(va); } void CLReportOSError(SInt16 errid, int err, ...) { + char *txt; + const char *oserr; + char mybuf[256]; + char myerr[256]; + va_list va; + + va_start(va, err); + txt = mvprintf(mybuf, sizeof(mybuf), CLGetErrorString(errid, myerr), va); + va_end(va); + oserr = OS_GetErrText(err); + CLReportError(99, txt, oserr, err); + + if (txt != mybuf) + free(txt); } void CLReportCError(SInt16 errid, int err_no, ...) { + char *txt; + const char *serr; + char mybuf[256]; + char myerr[256]; + va_list va; + + va_start(va, err_no); + txt = mvprintf(mybuf, sizeof(mybuf), CLGetErrorString(errid, myerr), va); + va_end(va); + + serr = strerror(err_no); + CLReportError(100, txt, serr, err_no); + if (txt != mybuf) + free(txt); } void CLInternalError(const char *file, int line, const char *format, ...) { + char mybuf[256]; + char *txt; + va_list va; + va_start(va, format); + txt = mvprintf(mybuf, sizeof(mybuf), format, va); + va_end(va); + CLPrintErr("INTERNAL ERROR [%s:%d]:\n%s\n", file, line, txt); + + if (txt != mybuf) + free(txt); } void CLFatalError(const char *format, ...) { + char mybuf[256]; + char *txt; + va_list va; + + va_start(va, format); + txt = mvprintf(mybuf, sizeof(mybuf), format, va); + va_end(va); + CLPrintErr("FATAL ERROR:\n%s\n", txt); + + if (txt != mybuf) + free(txt); + exit(-123); } diff --git a/command_line/CmdLine/Src/Envir/CLIO.c b/command_line/CmdLine/Src/Envir/CLIO.c index e832de5..70ba9ae 100644 --- a/command_line/CmdLine/Src/Envir/CLIO.c +++ b/command_line/CmdLine/Src/Envir/CLIO.c @@ -1,79 +1,251 @@ -#include "mwcc_decomp.h" +#include "cmdline.h" +#include <errno.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <util.h> + +extern char STSbuf[256]; + +static int ioLineNum; +static Boolean printedAnything; +static char arrowBuf[256]; +static Boolean newErr; +static Boolean newSrc; +static Boolean srcIsErr; +static OSSpec errSpec; +static OSSpec srcSpec; +static Boolean validErr; +static Boolean validSrc; +static SInt32 lastPrintingPlugin; +static Boolean ioInHelp; +static Boolean ioPiping; static void catchinterrupt() { - + clState.userBreak = 1; } static void SetupConsoleInfo() { - + struct winsize ws; + struct stat st; + + signal(SIGINT, catchinterrupt); + ioPiping = 0; + + fstat(stdout->_file, &st); + if (st.st_mode & 0x1000) + ioPiping = 1; + fstat(stderr->_file, &st); + if (st.st_mode & 0x1000) + ioPiping = 1; + + if (ioPiping) { + ws.ws_row = 0; + ws.ws_col = 80; + } else if (ioctl(stdout->_file, TIOCGWINSZ, &ws) < 0) { + ioPiping = 1; + ws.ws_row = 0; + ws.ws_col = 80; + } + + optsEnvir.rows = ws.ws_row; + optsEnvir.cols = ws.ws_col; + if (optsEnvir.cols > 256) + optsEnvir.cols = 256; } static void Crash() { - + *((unsigned char *) NULL) = 0; } void SetupDebuggingTraps() { - + signal(SIGABRT, Crash); } Boolean IO_Initialize() { + ioPiping = 0; + ioInHelp = 0; + ioLineNum = 0; + SetupConsoleInfo(); + if (ioPiping) { + setvbuf(stdout, NULL, 0, 1024); + setvbuf(stderr, NULL, 0, 1024); + } else { + setvbuf(stdout, NULL, 1, 1024); + setvbuf(stderr, NULL, 1, 1024); + } + + InitWorking(); + return 1; } Boolean IO_Terminate() { - + if (ioInHelp) + IO_HelpTerminate(); + TermWorking(); + return 1; } Boolean IO_HelpInitialize() { - + ioInHelp = 1; + return 1; } Boolean IO_HelpTerminate() { + ioInHelp = 0; + return 1; +} + +static Boolean SendHandleToFile(FILE *file, Handle text, SInt32 size) { + Boolean ret; + char *ptr; + char *lineEnd; + char *end; -} + if (file != stdout && file != stderr) + setvbuf(file, NULL, 0, 1024); -static Boolean SendHandleToFile(FILE *file, OSHandle *text) { + HLock(text); + ptr = *text; + if (size && ptr[size - 1] == 0) + size--; + if (size <= 0) { + ret = 1; + } else { + end = ptr + size; + while (ptr < end) { + lineEnd = ptr; + while (lineEnd < end && *lineEnd != '\n' && *lineEnd != '\r') + lineEnd++; + + if (lineEnd - ptr) { + if (fwrite(ptr, lineEnd - ptr, 1, file) != 1) { + CLReportCError(10, errno); + ret = 0; + goto fail; + } + } + + if (CheckForUserBreak()) { + ret = 1; + goto fail; + } + + // I have a hunch that this "\n" might be a define + if (fwrite("\n", strlen("\n"), 1, file) != 1) { + CLReportCError(10, errno); + ret = 0; + goto fail; + } + + if (lineEnd < end && *(lineEnd++) == '\r' && *lineEnd == '\n') + ++lineEnd; + ptr = lineEnd; + } + ret = 1; + } + +fail: + HUnlock(text); + fflush(file); + + if (file != stdout && file != stderr) + setvbuf(file, NULL, 2, 1024); + + return ret; } -void FixHandleForIDE(OSHandle *text) { +void FixHandleForIDE(Handle text, UInt32 size) { + char *ptr; + HLock(text); + for (ptr = *text; ptr < (*text + size); ptr++) { + if (*ptr == '\r') + *ptr = '\n'; + } + HUnlock(text); } -Boolean ShowHandle(OSHandle *text, Boolean decorate) { +Boolean ShowHandle(Handle text, UInt32 size, Boolean decorate) { + static const char *border = "===============\n"; + + if (decorate) + fprintf(stdout, border); + if (!SendHandleToFile(stdout, text, size)) + return 0; + if (decorate) + fprintf(stdout, border); + fflush(stdout); + return 1; } -Boolean WriteHandleToFile(OSSpec *spec, OSHandle *text, CWDataType creator, CWDataType type) { +Boolean WriteHandleToFile(OSSpec *spec, Handle text, UInt32 size, OSType creator, OSType type) { + FILE *file; + char path[256]; + OS_SpecToString(spec, path, sizeof(path)); + file = fopen(path, "w+b"); + if (!file) { + CLReportCError(8, errno, path); + return 0; + } + + SendHandleToFile(file, text, size); + fclose(file); + + OS_SetMacFileCreatorAndType(spec, creator, type); + return 1; } Boolean WriteBinaryHandleToFile(OSSpec *spec, CWDataType maccreator, CWDataType mactype, OSHandle *text) { + int err; + OSFileHandle file; + if ((err = OS_NewFileHandle(spec, text, 1, &file)) || (err = OS_FreeFileHandle(&file)) || (err = OS_SetMacFileCreatorAndType(spec, maccreator, mactype))) { + CLReportOSError(8, err, OS_SpecToString(spec, STSbuf, sizeof(STSbuf))); + return 0; + } + + return 1; } -Boolean AppendHandleToFile(OSSpec *spec, OSHandle *text, CWDataType maccreator, CWDataType mactype) { +Boolean AppendHandleToFile(OSSpec *spec, Handle text, UInt32 size, CWDataType maccreator, CWDataType mactype) { + FILE *file; + char path[256]; -} + OS_SpecToString(spec, path, sizeof(path)); + file = fopen(path, "a+b"); + if (!file) { + CLReportCError(8, errno, path); + return 0; + } -void InitWorking() { + SendHandleToFile(file, text, size); + fclose(file); + OS_SetMacFileCreatorAndType(spec, maccreator, mactype); + return 1; } -void ShowWorking() { +void InitWorking() { +} +void ShowWorking(int x) { } void TermWorking() { - } static void ProgressFunction(const char *functionname) { - + if (optsCmdLine.verbose) + CLReport(7, functionname); } Boolean CheckForUserBreak() { - + ShowWorking(4); + return clState.userBreak; } typedef struct { @@ -81,90 +253,650 @@ typedef struct { int pos; int maxlen; SInt16 col; - Boolean origina; + Boolean original; char *newline; } UnkCLIOStruct; +// unknown names for these inlines +inline void appendText(UnkCLIOStruct *f, const char *str) { + int len = strlen(str); + + if (f->pos + len >= f->maxlen) { + f->maxlen = f->maxlen * 2 + len; + if (f->original) { + char *oldbuf; + oldbuf = f->buffer; + f->buffer = xmalloc("message buffer", f->maxlen); + memcpy(f->buffer, oldbuf, f->pos); + } else { + f->buffer = xrealloc("message buffer", f->original ? NULL : f->buffer, f->maxlen); + } + f->original = 0; + } + + memcpy(f->buffer + f->pos, str, len); + f->pos += len; + f->col += len; +} +inline void appendChar(UnkCLIOStruct *f, char c) { + if (f->pos >= f->maxlen) { + f->maxlen *= 2; + if (f->original) { + char *oldbuf = f->buffer; + f->buffer = xmalloc("message buffer", f->maxlen); + memcpy(f->buffer, oldbuf, f->pos); + } else { + f->buffer = xrealloc("message buffer", f->buffer, f->maxlen); + } + f->original = 0; + } + + f->buffer[f->pos++] = c; + f->col++; +} + static void StartLine(UnkCLIOStruct *f) { + f->col = 0; + if (!optsEnvir.underIDE && f->newline) + appendText(f, f->newline); +} +inline void newLine(UnkCLIOStruct *f) { + if (f->newline) + appendChar(f, '\n'); + else + appendChar(f, ' '); + StartLine(f); } static void WrapText(UnkCLIOStruct *f) { - + int wrapped; + char wrapbuf[256]; + char c; + + wrapped = 0; + if (optsCmdLine.noWrapOutput) + return; + if (!f->newline) + return; + if (strlen(f->newline) > optsEnvir.cols / 2) + return; + + while (wrapped < (optsEnvir.cols - 1) && f->col > strlen(f->newline)) { + c = f->buffer[f->pos - 1]; + if (c == ' ') break; + if (c == '/') break; + if (c == '-') break; + wrapbuf[wrapped] = c; + f->pos = f->pos - 1; + f->col = f->col - 1; + wrapped++; + } + + if (f->col <= strlen(f->newline)) { + while (f->col < (optsEnvir.cols - 1) && wrapped > 0) { + appendChar(f, wrapbuf[--wrapped]); + } + } + + newLine(f); + while (wrapped > 0 && f->maxlen > 0) { + appendChar(f, wrapbuf[--wrapped]); + } } static char *IO_VFormatText(char *buffer, SInt32 size, char *newline, const char *format, va_list ap) { - + UnkCLIOStruct f; + char *arg; + + f.buffer = buffer; + f.pos = 0; + f.maxlen = size; + f.col = 0; + f.original = 1; + f.newline = newline; + StartLine(&f); + + while (*format && f.maxlen > 0) { + if (*format == '%') { + arg = va_arg(ap, char *); + while (*arg && f.maxlen > 0) { + if (*arg == '\r' || *arg == '\n') { + newLine(&f); + arg++; + } else if (*arg == '\t') { + if (f.maxlen > 0) { + do { + appendChar(&f, ' '); + } while (f.col & 7); + } + arg++; + } else { + appendChar(&f, *(arg++)); + if (!optsCmdLine.noWrapOutput && f.newline && f.col >= optsEnvir.cols - 1) + WrapText(&f); + } + } + format++; + } else if (*format == '\r' || *format == '\n') { + format++; + newLine(&f); + } else { + appendChar(&f, *(format++)); + if (!optsCmdLine.noWrapOutput && f.col >= optsEnvir.cols - 1) + WrapText(&f); + } + } + + if (f.newline) { + if (f.col == strlen(f.newline)) { + f.pos -= f.col; + f.col = 0; + } + } + + appendChar(&f, 0); + + return f.buffer; } char *IO_FormatText(char *buffer, SInt32 size, char *newline, const char *format, ...) { - -} - -void CLPrintDispatch(SInt16 msgtype, const char *message, FILE *out, char *ptr, char *nptr) { - + va_list ap; + char *ret; + + va_start(ap, format); + ret = IO_VFormatText(buffer, size, newline, format, ap); + va_end(ap); + + return ret; +} + +// TODO unify me with the one in the header +enum { + Msg_Note = 1, + Msg_Warning = 2, + Msg_Error = 3, + Msg_Alert = 4, + Msg_Status = 5 +}; +void CLPrintDispatch(int unk, SInt16 msgtype, const char *message) { + FILE *out; + const char *ptr; + const char *nptr; + + if (optsCmdLine.stderr2stdout == 1 || msgtype == Msg_Note || msgtype == Msg_Status) { + out = stdout; + } else if (msgtype == Msg_Warning || msgtype == Msg_Error || msgtype == Msg_Alert) { + out = stderr; + } else { +#line 847 + OPTION_ASSERT(0); + } + + if (!printedAnything && !ioPiping) { + printedAnything = 1; + ioLineNum = 0; + } + + ptr = message; + while (*ptr) { + nptr = ptr; + while (*nptr && *nptr != '\n' && *nptr != '\r') + ++nptr; + + if (nptr - ptr) { + if (fwrite(ptr, nptr - ptr, 1, out) != 1) + clState.userBreak = 1; + } + + if (*nptr) { + ioLineNum++; + fwrite("\n", strlen("\n"), 1, out); + if (*nptr == '\r') + nptr++; + if (*nptr == '\n') + nptr++; + if (nptr[0] && !nptr[1] && (nptr[0] == '\n' || nptr[0] == '\r')) + nptr++; + } + + ptr = nptr; + } + + if (out == stdout && optsCmdLine.verbose > 1) + fflush(out); } static void GetFileInfo(MessageRef *ref) { - + if (ref) { + srcIsErr = OS_EqualSpec(&ref->sourcefile, &ref->errorfile); + if (!validSrc || !OS_EqualSpec(&ref->sourcefile, &srcSpec)) { + newSrc = 1; + srcSpec = ref->sourcefile; + validSrc = 1; + } else { + newSrc = 0; + } + if (!validErr || !OS_EqualSpec(&ref->errorfile, &errSpec)) { + newErr = 1; + errSpec = ref->errorfile; + validErr = 1; + } else { + newErr = 0; + } + } } static char *Arrows(MessageRef *ref) { - + int start; + int len; + + arrowBuf[0] = 0; + start = ref->tokenoffset; + start %= optsEnvir.cols; + if (start >= 0 && start < sizeof(arrowBuf)) { + len = ref->tokenlength; + if (len + start > sizeof(arrowBuf)) + len = sizeof(arrowBuf) - start; + if (len == 0) + len = 1; + memset(arrowBuf, ' ', start); + memset(arrowBuf + start, '^', len); + arrowBuf[start + len] = 0; + } + + return arrowBuf; } static Boolean IsLikelyAnImporter(Plugin *plugin) { + if (Plugin_CL_GetObjectFlags(plugin)->flags & 0x80000000) + return 0; + return plugin != Plugins_CL_MatchTarget(NULL, gTarg->cpu, gTarg->os, clState.plugintype, clState.language); } static char *GuessTool(Plugin *plugin) { - + if (plugin) { + DropInFlags *df = Plugin_GetDropInFlags(plugin); + switch (df->dropintype) { + case CWDROPINDRIVERTYPE: return "Driver"; + case CWDROPINPARSERTYPE: return "Usage"; + case CWDROPINCOMPILERTYPE: + if (df->edit_language == Lang_C_CPP || df->edit_language == Lang_Pascal) + return "Compiler"; + else if (df->edit_language == CWFOURCHAR('A','s','m',' ')) + return "Assembler"; + else if (IsLikelyAnImporter(plugin)) + return "Importer"; + else + return "Compiler"; + case CWDROPINLINKERTYPE: + return "Linker"; + } + } + return "Driver"; } static char *GuessDoing(Plugin *plugin) { - -} - -static void styledMessage_MPW(Plugin *plugin, MessageRef *ref, SInt16 msgType, const char *format, va_list va) { - -} - -static void styledMessage_Default(Plugin *plugin, MessageRef *ref, SInt16 msgType, const char *format, va_list va) { - -} - -static void styledMessage_Terse(Plugin *plugin, MessageRef *ref, SInt16 msgType, const char *format, va_list va) { - -} - -static void styledMessage_IDE(Plugin *plugin, MessageRef *ref, SInt16 msgType, const char *format, va_list va) { - -} - -static void styledMessage_Parseable(Plugin *plugin, MessageRef *ref, SInt16 msgType, const char *format, va_list va) { - -} - -void CLPrintType(SInt16 msgtype, ...) { - + if (plugin) { + DropInFlags *df = Plugin_GetDropInFlags(plugin); + switch (df->dropintype) { + case CWDROPINPARSERTYPE: return "parsing"; + case CWDROPINCOMPILERTYPE: return "compiling"; + case CWDROPINLINKERTYPE: return "linking"; + } + } + return "processing"; +} + +static const char *msgnames[6] = { + "", + "Note", + "Warning", + "Error", + "Alert", + "Status" +}; + +static const char *msgnames_gcc[6] = { + "", + " note", + " warning", + "", + " alert", + " status" +}; + +static void styledMessage_MPW(Plugin *plugin, MessageRef *ref, SInt32 errorNumber, SInt16 msgType, const char *format, va_list va) { + char msgBuf[256]; + char *msgPtr; + + msgPtr = IO_VFormatText(msgBuf, sizeof(msgBuf), "# ", format, va); + if (msgType != Msg_Status) + CLPrintType(msgType, "### %s %s %s:\n", clState.programName, GuessTool(plugin), msgnames[msgType]); + + if (ref) { + CLPrintType(msgType, "#\t%s\n", ref->sourceline); + CLPrintType(msgType, "#\t%s\n", Arrows(ref)); + } + + CLPrintDispatch(0, msgType, msgPtr); + + if (ref) { + CLPrintType(msgType, "#----------------------------------------------------------\n"); + CLPrintType(msgType, " File \"%s\"; Line %d\n", OS_SpecToString(&ref->errorfile, STSbuf, sizeof(STSbuf)), ref->linenumber); + GetFileInfo(ref); + if (!srcIsErr) + CLPrintType(msgType, "#\twhile %s \"%s\"\n", GuessDoing(plugin), OS_SpecToString(&ref->sourcefile, STSbuf, sizeof(STSbuf))); + CLPrintType(msgType, "#----------------------------------------------------------\n"); + } + + if (msgPtr != msgBuf) + free(msgPtr); +} + +static void styledMessage_Default(Plugin *plugin, MessageRef *ref, SInt32 errorNumber, SInt16 msgType, const char *format, va_list va) { + char lineBuf[320]; + char msgBuf[256]; + char *msgPtr; + char *ptr; + + msgPtr = IO_VFormatText(msgBuf, sizeof(msgBuf), "# ", format, va); + if (ref) { + CLPrintType(msgType, "### %s %s:\n", clState.programName, GuessTool(plugin)); + } else if (msgType != Msg_Status) { + CLPrintType(msgType, "### %s %s %s:\n", clState.programName, GuessTool(plugin), msgnames[msgType]); + } + + if (ref) { + GetFileInfo(ref); + if (newErr || (newSrc && srcIsErr)) { + if (srcIsErr) { + sprintf(lineBuf, "#%8s: %s\n", "File", OS_SpecToStringRelative(&errSpec, NULL, STSbuf, sizeof(STSbuf))); + } else { + sprintf(lineBuf, "#%8s: %s\n", "In", OS_SpecToStringRelative(&errSpec, NULL, STSbuf, sizeof(STSbuf))); + } + CLPrintDispatch(0, msgType, lineBuf); + } + if (newSrc && !srcIsErr) { + sprintf(lineBuf, "# %7s: %s\n", "From", OS_SpecToStringRelative(&srcSpec, NULL, STSbuf, sizeof(STSbuf))); + CLPrintDispatch(0, msgType, lineBuf); + } + if (newErr || newSrc) { + ptr = &lineBuf[2]; + while (*ptr && *ptr != '\n') + *(ptr++) = '-'; + *ptr = 0; + if (ptr - lineBuf >= optsEnvir.cols - 1) + lineBuf[optsEnvir.cols - 1] = 0; + strcat(lineBuf, "\n"); + CLPrintDispatch(0, msgType, lineBuf); + } + CLPrintType(msgType, "#%8d: %s\n", ref->linenumber, ref->sourceline); + CLPrintType(msgType, "#%8s: %s\n", msgnames[msgType], Arrows(ref)); + } + + CLPrintDispatch(0, msgType, msgPtr); + if (msgPtr != msgBuf) + free(msgPtr); +} + +static void styledMessage_Terse(Plugin *plugin, MessageRef *ref, SInt32 errorNumber, SInt16 msgType, const char *format, va_list va) { + char *msg; + char *ptr; + char msgBuf[256]; + char *msgPtr; + char header[256]; + char *headPtr; + char errBuf[256]; + char *errPtr; + + if (ref) { + if (msgnames_gcc[msgType][0]) { + headPtr = mprintf( + header, sizeof(header), + "%s:%d:%s: ", + OS_SpecToStringRelative(&ref->errorfile, NULL, STSbuf, sizeof(STSbuf)), + ref->linenumber, + msgnames_gcc[msgType] + ); + } else { + headPtr = mprintf( + header, sizeof(header), + "%s:%d: ", + OS_SpecToStringRelative(&ref->errorfile, NULL, STSbuf, sizeof(STSbuf)), + ref->linenumber + ); + } + } else if (msgType != Msg_Status) { + headPtr = mprintf(header, sizeof(header), "%s: ", clState.programName); + } else { + header[0] = 0; + headPtr = header; + } + + msgPtr = IO_VFormatText(msgBuf, sizeof(msgBuf), headPtr, format, va); + if ((strstr(msgPtr, "#warning") || strstr(msgPtr, "#error")) && ref->sourceline[0]) { + errPtr = IO_FormatText(errBuf, sizeof(errBuf), headPtr, "%", ref->sourceline); + } else { + errPtr = 0; + } + + if (headPtr != header) + free(headPtr); + + msg = msgPtr; + while (*msg) { + ptr = msg; + while (*ptr && *ptr != '\n') + ptr++; + + CLPrintType(msgType, "%.*s\n", ptr - msg, msg); + if (errPtr) { + CLPrintType(msgType, "%s\n", errPtr); + if (errPtr != errBuf) + free(errPtr); + errPtr = NULL; + } + + if (*ptr) + msg = ptr + 1; + else + msg = ptr; + } + + if (msgPtr != msgBuf) + free(msgPtr); +} + +static void styledMessage_IDE(Plugin *plugin, MessageRef *ref, SInt32 errorNumber, SInt16 msgType, const char *format, va_list va) { + char msgBuf[256]; + char *msgPtr; + SInt16 oldCols; + + oldCols = optsEnvir.cols; + msgPtr = IO_VFormatText(msgBuf, sizeof(msgBuf), " ", format, va); + optsEnvir.cols = oldCols; + + CLPrintType(msgType, "%8s : %s\n", msgnames[msgType], msgPtr + 11); + if (msgPtr != msgBuf) + free(msgPtr); + + if (ref) { + msgPtr = IO_FormatText(msgBuf, sizeof(msgBuf), "\t", "%", ref->sourceline); + CLPrintType(msgType, "%s line %d%s\n", OS_SpecToStringRelative(&ref->errorfile, NULL, STSbuf, sizeof(STSbuf)), ref->linenumber, msgPtr); + if (msgPtr != msgBuf) + free(msgPtr); + } +} + +static void styledMessage_Parseable(Plugin *plugin, MessageRef *ref, SInt32 errorNumber, SInt16 msgType, const char *format, va_list va) { + char msgBuf[256]; + char *msgPtr; + + CLPrintType(msgType, "%s|%s|%s\n", clState.programName, GuessTool(plugin), msgnames[msgType]); + if (ref) { + CLPrintType( + msgType, + "(%s|%d|%d|%d|%d|%d)\n", + OS_SpecToString(&ref->errorfile, STSbuf, sizeof(STSbuf)), + ref->linenumber, + ref->tokenoffset, + ref->tokenlength, + ref->selectionoffset, + ref->selectionlength + ); + CLPrintType(msgType, "=%s\n", ref->sourceline); + } + + msgPtr = IO_VFormatText(msgBuf, sizeof(msgBuf), ">", format, va); + CLPrintType(msgType, "%s\n", msgPtr); + if (msgPtr != msgBuf) + free(msgPtr); +} + +void CLPrintType(SInt16 msgtype, const char *format, ...) { + char printbuffer[256]; + char *ptr; + va_list va; + + va_start(va, format); + ptr = mvprintf(printbuffer, sizeof(printbuffer), format, va); + va_end(va); + CLPrintDispatch(0, msgtype, ptr); + if (ptr != printbuffer) + free(ptr); } void CLPrint(const char *format, ...) { + char printbuffer[256]; + char *ptr; + va_list va; + va_start(va, format); + ptr = mvprintf(printbuffer, sizeof(printbuffer), format, va); + va_end(va); + CLPrintDispatch(0, Msg_Note, ptr); + if (ptr != printbuffer) + free(ptr); } void CLPrintWarning(const char *format, ...) { + char printbuffer[256]; + char *ptr; + va_list va; + va_start(va, format); + ptr = mvprintf(printbuffer, sizeof(printbuffer), format, va); + va_end(va); + CLPrintDispatch(0, Msg_Warning, ptr); + if (ptr != printbuffer) + free(ptr); } void CLPrintErr(const char *format, ...) { + char printbuffer[256]; + char *ptr; + va_list va; + va_start(va, format); + ptr = mvprintf(printbuffer, sizeof(printbuffer), format, va); + va_end(va); + CLPrintDispatch(0, Msg_Error, ptr); + if (ptr != printbuffer) + free(ptr); } static void FixupMessageRef(MessageRef *ref) { - -} - -SInt16 CLStyledMessageDispatch(Plugin *plugin, MessageRef *ref, SInt32 errorNumber, SInt16 msgType) { - + char *bol; + char *eol; + int len; + int scan; + + if (ref->sourceline && *ref->sourceline) { + bol = ref->sourceline + ref->tokenoffset; + eol = ref->sourceline + ref->tokenoffset + ref->tokenlength - 1; + if (eol < bol) + eol = bol; + while (bol > ref->sourceline && bol[-1] != '\r') + bol--; + while (*eol && *eol != '\r' && *eol != '\n') + eol++; + + len = eol - bol; + ref->sourceline = xmalloc("text buffer", len + 1); + strncpy(ref->sourceline, bol, len); + ref->sourceline[len] = 0; + + for (scan = 0; scan < len; scan++) { + if (ref->sourceline[scan] < ' ' || ref->sourceline[scan] >= 127) + ref->sourceline[scan] = ' '; + } + } else { + ref->sourceline = 0; + } +} + +SInt16 CLStyledMessageDispatch(Plugin *plugin, MessageRef *ref, SInt32 errorNumber, SInt16 msgType, const char *format, ...) { + va_list va; + MessageRef myref; + UInt32 ptype; + + if (msgType == Msg_Warning) { + ptype = plugin ? Plugin_GetPluginType(plugin) : CWDROPINDRIVERTYPE; + if (optsCmdLine.noWarnings) + return 0; + if ((ptype == CWDROPINDRIVERTYPE || ptype == CWDROPINPARSERTYPE) && optsCmdLine.noCmdLineWarnings) + return 0; + if (optsCmdLine.warningsAreErrors) + msgType = Msg_Error; + } + + if (msgType == Msg_Error && clState.withholdErrors) + return 0; + if (msgType == Msg_Warning && clState.withholdWarnings) + return 0; + + if (ref) { + myref = *ref; + FixupMessageRef(&myref); + } + + va_start(va, format); + if (optsCmdLine.msgStyle == 2) { + styledMessage_MPW(plugin, ref ? &myref : 0, errorNumber, msgType, format, va); + } else if (optsCmdLine.msgStyle == 1) { + styledMessage_Terse(plugin, ref ? &myref : 0, errorNumber, msgType, format, va); + } else if (optsCmdLine.msgStyle == 3) { + styledMessage_IDE(plugin, ref ? &myref : 0, errorNumber, msgType, format, va); + } else if (optsCmdLine.msgStyle == 4) { + styledMessage_Parseable(plugin, ref ? &myref : 0, errorNumber, msgType, format, va); + } else { + styledMessage_Default(plugin, ref ? &myref : 0, errorNumber, msgType, format, va); + } + va_end(va); + + if (ref && myref.sourceline) + xfree(myref.sourceline); + + if (msgType == Msg_Error && optsCmdLine.maxErrors) { + if (++clState.countErrors >= optsCmdLine.maxErrors) { + clState.withholdErrors = 1; + if (!optsCompiler.noFail) { + CLReport(70); + clState.userBreak = 1; + } else { + CLReport(71); + } + } + } + + if (msgType == Msg_Warning && optsCmdLine.maxWarnings) { + if (++clState.countWarnings >= optsCmdLine.maxWarnings) { + clState.withholdWarnings = 1; + CLReport(72); + } + } + + return msgType; } diff --git a/command_line/CmdLine/Src/MacEmul/ErrMgr.c b/command_line/CmdLine/Src/MacEmul/ErrMgr.c index 5fc621d..5ea1fe6 100644 --- a/command_line/CmdLine/Src/MacEmul/ErrMgr.c +++ b/command_line/CmdLine/Src/MacEmul/ErrMgr.c @@ -1,4 +1,4 @@ -#include "mwcc_decomp.h" +#include "cmdline.h" static const char *getsyserr(SInt16 msgNbr) { switch (msgNbr) { diff --git a/command_line/CmdLine/Src/MacEmul/Files.c b/command_line/CmdLine/Src/MacEmul/Files.c index 9a9cb60..a613b4a 100644 --- a/command_line/CmdLine/Src/MacEmul/Files.c +++ b/command_line/CmdLine/Src/MacEmul/Files.c @@ -1,4 +1,4 @@ -#include "mwcc_decomp.h" +#include "cmdline.h" typedef struct MacFileInfo { UInt32 ioFlCrDat; diff --git a/command_line/CmdLine/Src/MacEmul/LowMem.c b/command_line/CmdLine/Src/MacEmul/LowMem.c index 7fab079..cd31194 100644 --- a/command_line/CmdLine/Src/MacEmul/LowMem.c +++ b/command_line/CmdLine/Src/MacEmul/LowMem.c @@ -1,4 +1,4 @@ -#include "mwcc_decomp.h" +#include "cmdline.h" static OSErr memErr; diff --git a/command_line/CmdLine/Src/MacEmul/Memory.c b/command_line/CmdLine/Src/MacEmul/Memory.c index 0aa5d24..e201343 100644 --- a/command_line/CmdLine/Src/MacEmul/Memory.c +++ b/command_line/CmdLine/Src/MacEmul/Memory.c @@ -1,4 +1,4 @@ -#include "mwcc_decomp.h" +#include "cmdline.h" static OSErr memError; diff --git a/command_line/CmdLine/Src/MacEmul/ResourceStrings.c b/command_line/CmdLine/Src/MacEmul/ResourceStrings.c index 9f8f333..4b6bc22 100644 --- a/command_line/CmdLine/Src/MacEmul/ResourceStrings.c +++ b/command_line/CmdLine/Src/MacEmul/ResourceStrings.c @@ -1,9 +1,9 @@ -#include "mwcc_decomp.h" +#include "cmdline.h" typedef struct { const char *name; SInt16 rsrcid; - Handle strings; + const char **strings; } Res; static Res rlist[16]; @@ -12,7 +12,7 @@ void Res_Initialize() { memset(rlist, 0, sizeof(rlist)); } -int Res_AddResource(const char *name, SInt16 rsrcid, Handle strings) { +int Res_AddResource(const char *name, SInt16 rsrcid, const char **strings) { int scan; for (scan = 0; scan < 16 && rlist[scan].rsrcid; scan++) { diff --git a/command_line/CmdLine/Src/MacEmul/Resources.c b/command_line/CmdLine/Src/MacEmul/Resources.c index 796ed43..ef2aab0 100644 --- a/command_line/CmdLine/Src/MacEmul/Resources.c +++ b/command_line/CmdLine/Src/MacEmul/Resources.c @@ -1,4 +1,4 @@ -#include "mwcc_decomp.h" +#include "cmdline.h" // Fork Attributes enum { @@ -284,6 +284,7 @@ memcpy(buf, ((unsigned char *) file_data) + __offs, (count)); \ } while(0) static void ReadResourceFork(SInt16 ref, SInt8 permission, void *file_data, SInt32 file_size) { + // this function has various awkwardly swapped registers MemRsrcMap *rm; Ty70 thdr; Ty70 *dhdr; @@ -316,27 +317,29 @@ static void ReadResourceFork(SInt16 ref, SInt8 permission, void *file_data, SInt cnt = sizeof(Ty70); RF_READ(&thdr, 0, cnt, mapFail); + dhdr = &thdr; ref_offs = cnt; cnt = ((thdr.map_offs < thdr.data_offs) ? thdr.map_offs : thdr.data_offs) - sizeof(Ty70); if (cnt > sizeof(MemRsrcSysData)) cnt = sizeof(MemRsrcSysData); RF_READ(&tsys, ref_offs, cnt, mapFail); + dsys = &tsys; - msize = thdr.map_len; + msize = dhdr->map_len; buffer = malloc(msize); if (!buffer) goto memFail; - ref_offs = thdr.map_offs; + ref_offs = dhdr->map_offs; RF_READ(buffer, ref_offs, msize, mapFail); if ( - (thdr.map_offs > file_size) - || ((thdr.map_offs + thdr.map_len) > file_size) - || (thdr.data_offs > file_size) - || ((thdr.data_offs + thdr.data_len) > file_size) - || ((thdr.map_offs < thdr.data_offs) ? ((thdr.map_offs + thdr.map_len) != thdr.data_offs) : ((thdr.data_offs + thdr.data_len) != thdr.map_offs)) + (dhdr->map_offs > file_size) + || ((dhdr->map_offs + dhdr->map_len) > file_size) + || (dhdr->data_offs > file_size) + || ((dhdr->data_offs + dhdr->data_len) > file_size) + || ((dhdr->map_offs < dhdr->data_offs) ? ((dhdr->map_offs + dhdr->map_len) > dhdr->data_offs) : ((dhdr->data_offs + dhdr->data_len) > dhdr->map_offs)) ) goto mapFail; @@ -344,13 +347,13 @@ static void ReadResourceFork(SInt16 ref, SInt8 permission, void *file_data, SInt if (!rm) goto memFail; - rm->sys_data = tsys; + rm->sys_data = *dsys; dmap = (Ty73 *) buffer; - if ((dmap->typelist_offs + thdr.map_offs) > file_size) + if ((dmap->typelist_offs + dhdr->map_offs) > file_size) goto freeAndMapFail; dtyp = (Ty75 *) (((unsigned char *) buffer) + dmap->typelist_offs + 2); - if ((dmap->namelist_offs + thdr.map_offs) > file_size) + if ((dmap->namelist_offs + dhdr->map_offs) > file_size) goto freeAndMapFail; dnam = (Ty80 *) (((unsigned char *) buffer) + dmap->namelist_offs); if (dmap->types_idx != 0xFFFF) { @@ -359,21 +362,21 @@ static void ReadResourceFork(SInt16 ref, SInt8 permission, void *file_data, SInt if (!mtyp) goto freeAndReturn; - if ((thdr.map_offs + dmap->typelist_offs + dtyp[cnt].ref_list_offs) > file_size) + if ((dmap->typelist_offs + dtyp[cnt].ref_list_offs + dhdr->map_offs) > file_size) goto freeAndMapFail; drle = (Ty77 *) (((unsigned char *) dtyp) + dtyp[cnt].ref_list_offs - 2); if (dtyp[cnt].rsrc_idx != 0xFFFF) { for (rcnt = 0; rcnt <= dtyp[cnt].rsrc_idx; rcnt++) { ref_offs = (drle[rcnt].data_offs[0] << 16) | (drle[rcnt].data_offs[1] << 8) | drle[rcnt].data_offs[2]; - offs = thdr.data_offs + ref_offs; + offs = ref_offs + dhdr->data_offs; if (offs > file_size) goto freeAndMapFail; esize = 4; RF_READ(&tent, offs, esize, freeAndMapFail); offs += esize; - if ((thdr.data_offs + ref_offs + tent.len) > file_size) + if ((tent.len + ref_offs + dhdr->data_offs) > file_size) goto freeAndMapFail; hand = NewHandle(tent.len); @@ -385,7 +388,7 @@ static void ReadResourceFork(SInt16 ref, SInt8 permission, void *file_data, SInt HUnlock(hand); if (drle[rcnt].name_offs != 0xFFFF) { - nameptr = (StringPtr) (dnam + drle[rcnt].name_offs); + nameptr = (StringPtr) dnam + drle[rcnt].name_offs; name = malloc(nameptr[0] + 1); memcpy(name, nameptr, nameptr[0] + 1); } else { @@ -1250,14 +1253,14 @@ void HCreateResFile(SInt16 vRefNum, SInt32 dirID, ConstStringPtr fileName) { } } -OSErr FSpOpenResFile(const FSSpec *fss, SInt8 permission) { +OSErr FSpOpenResFile(const FSSpec *spec, SInt8 permission) { SInt16 ref; SInt32 size; if (permission != fsRdPerm) - FSpCreate(fss, 'CWIE', 'TEXT', -1); + FSpCreate(spec, 'CWIE', 'TEXT', -1); - resError = FSpOpenRF(fss, (permission == fsWrPerm) ? fsRdWrPerm : permission, &ref); + resError = FSpOpenRF(spec, (permission == fsWrPerm) ? fsRdWrPerm : permission, &ref); if (!resError) { GetEOF(ref, &size); if (size == 0 && permission != fsRdPerm) diff --git a/command_line/CmdLine/Src/MacEmul/TextUtils.c b/command_line/CmdLine/Src/MacEmul/TextUtils.c index a23ac7e..7971074 100644 --- a/command_line/CmdLine/Src/MacEmul/TextUtils.c +++ b/command_line/CmdLine/Src/MacEmul/TextUtils.c @@ -1,4 +1,4 @@ -#include "mwcc_decomp.h" +#include "cmdline.h" StringPtr c2pstr(char *s) { unsigned int l; diff --git a/command_line/CmdLine/Src/OSLib/MacFileTypes.c b/command_line/CmdLine/Src/OSLib/MacFileTypes.c index 05a2ae9..5ebb4d6 100644 --- a/command_line/CmdLine/Src/OSLib/MacFileTypes.c +++ b/command_line/CmdLine/Src/OSLib/MacFileTypes.c @@ -4,7 +4,7 @@ static OSFileTypeMappings *defaultList; static OSFileTypeMappings **fmList = &defaultList; int (*__OS_ExtendedGetMacFileTypeHook)(const OSSpec *, OSType *); -void OS_AddFileTypeMappingList(OSFileTypeMappings **list, OSFileTypeMappingList *entry) { +void OS_AddFileTypeMappingList(OSFileTypeMappings **list, const OSFileTypeMappingList *entry) { OSFileTypeMappings **scan; if (!list) @@ -27,7 +27,7 @@ void OS_UseFileTypeMappings(OSFileTypeMappings *list) { void OS_MacType_To_OSType(OSType mactype, uOSTypePair *type) { OSFileTypeMappings *list; - OSFileTypeMappingList *scan; + const OSFileTypeMappingList *scan; int idx; for (list = *fmList; list; list = list->next) { @@ -51,7 +51,7 @@ int OS_SetMacFileType(const OSSpec *spec, OSType mactype) { Boolean OS_GetMacFileTypeMagic(const char *buffer, int count, OSType *mactype) { OSFileTypeMappings *list; - OSFileTypeMappingList *scan; + const OSFileTypeMappingList *scan; int idx; *mactype = 0; diff --git a/command_line/CmdLine/Src/OSLib/Posix.c b/command_line/CmdLine/Src/OSLib/Posix.c index e3f8a03..d416b9b 100644 --- a/command_line/CmdLine/Src/OSLib/Posix.c +++ b/command_line/CmdLine/Src/OSLib/Posix.c @@ -408,14 +408,14 @@ int OS_EqualPath(const char *a, const char *b) { return !strcmp(a, b); } -int OS_CanonPath(char *src, char *dst) { +int OS_CanonPath(const char *src, char *dst) { int idx; if (strlen(src) > 255) return ENAMETOOLONG; if (!dst) - dst = src; + dst = (char *) src; for (idx = 0; src[idx]; idx++) { if (src[idx] == '\\') @@ -956,6 +956,6 @@ int OS_LoadMacResourceFork(const OSSpec *spec, void **file_data, SInt32 *file_le return ENOENT; } -int OS_IsMultiByte(const char *str, int offset) { +Boolean OS_IsMultiByte(const char *str, int offset) { return 0; } diff --git a/command_line/CmdLine/Src/Plugins/CLPlugins.c b/command_line/CmdLine/Src/Plugins/CLPlugins.c index e69de29..5f31f45 100644 --- a/command_line/CmdLine/Src/Plugins/CLPlugins.c +++ b/command_line/CmdLine/Src/Plugins/CLPlugins.c @@ -0,0 +1,981 @@ +#include "cmdline.h" + +static Plugin *pluginlist; +static ToolVersionInfo toolVersionInfo; +static VersionInfo toolVersion; +static Boolean useToolVersion; + +static void GetToolVersionInfo() { + useToolVersion = 0; +} + +const ToolVersionInfo *Plugin_GetToolVersionInfo() { + return useToolVersion ? &toolVersionInfo : 0; +} + +static const char *Plugin_GetDisplayName(Plugin *pl) { + const char *name; +#line 251 + OPTION_ASSERT(pl); + + if (pl->cb->GetDisplayName && pl->cb->GetDisplayName(&name) == 0) + return name; + else + return "(no name found)"; +} + +const char *Plugin_GetDropInName(Plugin *pl) { + const char *name; +#line 263 + OPTION_ASSERT(pl); + + if (pl->cb->GetDropInName && pl->cb->GetDropInName(&name) == 0) + return name; + else + return "(no name found)"; +} + +const VersionInfo *Plugin_GetVersionInfo(Plugin *pl) { + static const VersionInfo fakeversion = {0, 0, 0, 0}; + const VersionInfo *vi; +#line 276 + OPTION_ASSERT(pl); + + if (pl->cb->GetVersionInfo && pl->cb->GetVersionInfo(&vi) == 0) + return vi; + else + return &fakeversion; +} + +char *Plugin_GetVersionInfoASCII(Plugin *pl) { + const VersionInfo *vi; + char *buffer; + char vernum[16]; + char *bptr; + + if (!pl && useToolVersion) { + vi = &toolVersion; + } else if (!pl) { + return NULL; + } else { + vi = Plugin_GetVersionInfo(pl); + } + + buffer = xmalloc("version info", 64); + if (vi->major | vi->minor | vi->patch | vi->build != 0) { + bptr = vernum; + bptr += sprintf(bptr, "%u", vi->major); + bptr += sprintf(bptr, ".%u", vi->minor); + if (vi->patch) + bptr += sprintf(bptr, ".%u", vi->patch); + if (vi->build) + bptr += sprintf(bptr, " build %u", vi->build); + sprintf(buffer, "Version %s", vernum); + return buffer; + } else { + return NULL; + } +} + +DropInFlags *Plugin_GetDropInFlags(Plugin *pl) { + static DropInFlags retdf; + const DropInFlags *df; + SInt32 dfsize; + +#line 329 + OPTION_ASSERT(pl); + + if (pl->cb->GetDropInFlags && pl->cb->GetDropInFlags(&df, &dfsize) == 0) { + memset(&retdf, 0, sizeof(retdf)); + memcpy(&retdf, df, dfsize); + return &retdf; + } else { + return NULL; + } +} + +OSType Plugin_GetPluginType(Plugin *pl) { + DropInFlags *df; + +#line 345 + OPTION_ASSERT(pl); + + df = Plugin_GetDropInFlags(pl); + if (df) + return df->dropintype; + else + return CWFOURCHAR('N','O','N','E'); +} + +const CWTargetList *Plugin_CL_GetTargetList(Plugin *pl) { + static const CWTargetList faketl = { + kCurrentCWTargetListVersion, + 0, NULL, + 0, NULL + }; + const CWTargetList *tl; + +#line 358 + OPTION_ASSERT(pl); + OPTION_ASSERT(pl->cl_cb != NULL); + + if (pl->cl_cb->GetTargetList && pl->cl_cb->GetTargetList(&tl) == 0) + return tl; + else + return &faketl; +} + +const CWPanelList *Plugin_GetPanelList(Plugin *pl) { + static CWPanelList fakepnl = { + kCurrentCWPanelListVersion, 0, NULL + }; + const CWPanelList *pnl; + +#line 381 + OPTION_ASSERT(pl); + + if (pl->cb->GetPanelList && pl->cb->GetPanelList(&pnl) == 0) + return pnl; + else + return &fakepnl; +} + +const CWExtMapList *Plugin_CL_GetExtMapList(Plugin *pl) { + static CWExtMapList fakeel = { + kCurrentCWExtMapListVersion, + 0, NULL + }; + const CWExtMapList *el; + +#line 401 + OPTION_ASSERT(pl); + OPTION_ASSERT(pl->cl_cb != NULL); + + if (pl->cl_cb->GetDefaultMappingList && pl->cl_cb->GetDefaultMappingList(&el) == 0) + return el; + else + return &fakeel; +} + +const OSFileTypeMappingList *Plugin_GetFileTypeMappingList(Plugin *pl) { + const OSFileTypeMappingList *ftml; + +#line 422 + OPTION_ASSERT(pl); + + if (pl->cb->GetFileTypeMappings && pl->cb->GetFileTypeMappings(&ftml) == 0) + return ftml; + else + return NULL; +} + +const CWObjectFlags *Plugin_CL_GetObjectFlags(Plugin *pl) { + static CWObjectFlags fake = { + 2, 0, + "", "", "", "", "", "", + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + const CWObjectFlags *cof; + +#line 434 + OPTION_ASSERT(pl); + OPTION_ASSERT(pl->cl_cb != NULL); + + if (pl->cl_cb->GetObjectFlags && pl->cl_cb->GetObjectFlags(&cof) == 0) + return cof; + else if (Plugin_GetDropInFlags(pl)->dropintype == CWDROPINCOMPILERTYPE) + return NULL; + else + return &fake; +} + +Boolean Plugin_MatchesName(Plugin *pl, const char *name) { + const char *pname = Plugin_GetDropInName(pl); + return !strcmp(pname, name); +} + +Boolean Plugin_CL_MatchesTarget(Plugin *pl, OSType cpu, OSType os, Boolean exact) { + const CWTargetList *tl; + int idx; + int ix; + + tl = Plugin_CL_GetTargetList(pl); + + for (idx = 0; idx < tl->cpuCount; idx++) { + if (cpu == targetCPUAny || cpu == tl->cpus[idx] || (tl->cpus[idx] == targetCPUAny && !exact)) { + for (ix = 0; ix < tl->osCount; ix++) { + if (os == targetOSAny || os == tl->oss[ix] || (tl->oss[ix] == targetOSAny && !exact)) + return 1; + } + } + } + + return 0; +} + +Boolean Plugins_CL_HaveMatchingTargets(Plugin *p1, Plugin *p2, Boolean exact) { + // does not match, annoyingly + const CWTargetList *t1; + const CWTargetList *t2; + int ic1; + int ic2; + int io1; + int io2; + + t1 = Plugin_CL_GetTargetList(p1); + t2 = Plugin_CL_GetTargetList(p2); + + for (ic1 = 0; ic1 < t1->cpuCount; ic1++) { + for (ic2 = 0; ic2 < t2->cpuCount; ic2++) { + if ((t2->cpus[ic2] == targetCPUAny && !exact) || (t1->cpus[ic1] == t2->cpus[ic2]) || (t1->cpus[ic1] == targetCPUAny && !exact)) { + for (io1 = 0; io1 < t1->osCount; io1++) { + for (io2 = 0; io2 < t2->osCount; io2++) { + if ((t2->oss[io2] == targetOSAny && !exact) || (t1->oss[io1] == t2->oss[io2]) || (t1->oss[io1] == targetOSAny && !exact)) { + return 1; + } + } + } + } + } + } + + return 0; +} + +static Boolean CL_MatchesExtMapping(CWExtensionMapping *map, OSType type, const char *ext, Boolean exact) { + if (exact && type && map->type && type == map->type) + return 1; + + if ( + (((!map->extension[0] && !exact) || (!ext[0] && !exact)) && map->type == type) + || + (((!map->type && !exact) || (!type && !exact)) && !ustrcmp(map->extension, ext)) + || + (!ustrcmp(map->extension, ext) && map->type == type) + ) { + return 1; + } + + return 0; +} + +Boolean Plugin_CL_MatchesFileType(Plugin *pl, OSType type, const char *extension, Boolean exact) { + const CWExtMapList *el; + int idx; + + el = Plugin_CL_GetExtMapList(pl); + + for (idx = 0; idx < el->nMappings; idx++) { + if (CL_MatchesExtMapping(&el->mappings[idx], type, extension, exact)) + return 1; + } + + return 0; +} + +Boolean Plugin_MatchesType(Plugin *pl, OSType type, OSType lang, Boolean exact) { + const DropInFlags *df; + + df = Plugin_GetDropInFlags(pl); + if (df->dropintype == type || type == CWDROPINANYTYPE) { + if (df->edit_language == lang || lang == Lang_Any || (df->edit_language == Lang_Any && !exact)) + return 1; + } + + return 0; +} + +Boolean Plugin_Pr_MatchesPlugin(Plugin *pl, CLPluginInfo *pluginfo, OSType cpu, OSType os) { + Boolean isSupported; + +#line 566 + OPTION_ASSERT(pl->pr_cb != NULL); + + if (pl->pr_cb->SupportsPlugin && pl->pr_cb->SupportsPlugin(pluginfo, cpu, os, &isSupported) == 0) + return isSupported; + else + return 0; +} + +Boolean Plugin_Pr_MatchesPanels(Plugin *pl, int numPanels, const char **panelNames) { + Boolean isSupported; + +#line 578 + OPTION_ASSERT(pl->pr_cb != NULL); + + if (pl->pr_cb->SupportsPanels && pl->pr_cb->SupportsPanels(numPanels, panelNames, &isSupported) == 0) + return isSupported; + else + return 0; +} + +Boolean Plugin_CL_WriteObjectFile(Plugin *pl, FSSpec *srcfss, FSSpec *outfss, OSType creator, OSType type, Handle data) { + OSSpec outoss; + +#line 590 + OPTION_ASSERT(pl->cl_cb != NULL); + OPTION_ASSERT(data != NULL && srcfss != NULL && outfss != NULL); + + if (pl->cl_cb->WriteObjectFile) { + return pl->cl_cb->WriteObjectFile(srcfss, outfss, creator, type, data) == 0; + } + + OS_FSSpec_To_OSSpec(outfss, &outoss); + return WriteBinaryHandleToFile(&outoss, creator, type, OS_PeekMacHandle(data)); +} + +Boolean Plugin_CL_GetCompilerMapping(Plugin *pl, OSType type, const char *ext, UInt32 *flags) { + const CWExtMapList *el; + int idx; + int pick; + + el = Plugin_CL_GetExtMapList(pl); + pick = -1; + for (idx = 0; idx < el->nMappings; idx++) { + if (CL_MatchesExtMapping(&el->mappings[idx], type, ext, 0)) { + pick = idx; + if (CL_MatchesExtMapping(&el->mappings[idx], type, ext, 1)) + break; + } + } + + if (pick < 0) { + *flags = 0; + return 0; + } else { + *flags = el->mappings[pick].flags; + return 1; + } +} + +static Boolean SupportedPlugin(Plugin *pl, const char **reason) { + static const SInt32 DropInFlagsSize[3] = {0, 0x10, 0x12}; + const DropInFlags *df; + const CWObjectFlags *cof; + SInt32 dfsize; + + *reason = ""; + if (pl->cb->GetDropInFlags == NULL) { + *reason = "GetDropInFlags callback not found"; + return 0; + } + if (pl->cb->GetDropInFlags(&df, &dfsize)) { + *reason = "GetDropInFlags callback failed"; + return 0; + } + if (df->dropintype != CWDROPINCOMPILERTYPE && df->dropintype != CWDROPINLINKERTYPE && df->dropintype != CWDROPINPARSERTYPE && df->dropintype != CWDROPINDRIVERTYPE) { + *reason = "The plugin type is not supported by this driver"; + return 0; + } + if (df->earliestCompatibleAPIVersion > 11) { + *reason = "The plugin's earliest compatible API version is too new for this driver"; + return 0; + } + if (df->earliestCompatibleAPIVersion > 1 && df->newestAPIVersion < 11 && clState.pluginDebug) { + CLPrintErr("%s's newest compatible API version is probably too old for this driver\n", Plugin_GetDropInName(pl)); + } + if (dfsize != DropInFlagsSize[df->rsrcversion]) { + *reason = "The plugin's DropInFlags has an unexpected size"; + return 0; + } + if (!(df->dropinflags & dropInExecutableTool) && !pl->cb->main) { + *reason = "The plugin has no entry point"; + return 0; + } + if ((df->dropinflags & dropInExecutableTool) && pl->cb->main) { + *reason = "The executable tool stub has an entry point"; + return 0; + } + + if (pl->cl_cb) { + if (pl->cl_cb->GetObjectFlags == NULL && df->dropintype == CWDROPINCOMPILERTYPE) { + *reason = "GetObjectFlags callback not found in compiler plugin"; + return 0; + } + + cof = Plugin_CL_GetObjectFlags(pl); + if (cof->version < 2 || cof->flags & 0x7FFFFFFF) { + *reason = "The object flags data is out-of-date or invalid"; + return 0; + } + } + + return 1; +} + +static Boolean VerifyPanels(Plugin *pl) { + const CWPanelList *pls; + Boolean failed; + int idx; + + failed = 0; + + if (pl->cb->GetPanelList && pl->cb->GetPanelList(&pls) == 0) { + for (idx = 0; idx < pls->count; idx++) { + if (Prefs_FindPanel(pls->names[idx]) == NULL) { + CLReportError(91, pls->names[idx]); + failed = 1; + } + } + } + + return !failed; +} + +Plugin *Plugin_New(const BasePluginCallbacks *cb, const CompilerLinkerPluginCallbacks *cl_cb, const ParserPluginCallbacks *pr_cb) { + Plugin *p; + + p = xmalloc(NULL, sizeof(Plugin)); + if (!p) + return NULL; + if (!cb) + return NULL; + + p->cb = xmalloc(NULL, sizeof(BasePluginCallbacks)); + if (!p->cb) + return NULL; + *p->cb = *cb; + + if (cl_cb) { + p->cl_cb = xmalloc(NULL, sizeof(CompilerLinkerPluginCallbacks)); + if (!p->cl_cb) + return NULL; + *p->cl_cb = *cl_cb; + } else { + p->cl_cb = NULL; + } + + if (pr_cb) { + p->pr_cb = xmalloc(NULL, sizeof(ParserPluginCallbacks)); + if (!p->pr_cb) + return NULL; + *p->pr_cb = *pr_cb; + } else { + p->pr_cb = NULL; + } + + p->context = NULL; + p->next = NULL; + return p; +} + +void Plugin_Free(Plugin *pl) { + if (pl) { + if (pl->cb) + xfree(pl->cb); + if (pl->cl_cb) + xfree(pl->cl_cb); + if (pl->pr_cb) + xfree(pl->pr_cb); + xfree(pl); + } +} + +Boolean Plugin_VerifyPanels(Plugin *pl) { + if (!VerifyPanels(pl)) { + CLReportError(92, Plugin_GetDropInName(pl)); + return 0; + } else { + return 1; + } +} + +void Plugins_Init() { + pluginlist = NULL; + GetToolVersionInfo(); +} + +void Plugins_Term() { + Plugin *scan; + Plugin *next; + + scan = pluginlist; + while (scan) { + next = scan->next; + SendInitOrTermRequest(scan, 0); + Plugin_Free(scan); + scan = next; + } + + if (toolVersionInfo.company) + xfree(toolVersionInfo.company); + if (toolVersionInfo.product) + xfree(toolVersionInfo.product); + if (toolVersionInfo.tool) + xfree(toolVersionInfo.tool); + if (toolVersionInfo.copyright) + xfree(toolVersionInfo.copyright); + if (toolVersionInfo.version) + xfree(toolVersionInfo.version); +} + +int Plugins_Add(Plugin *pl) { + Plugin **scan; + const char *dropinname; + const DropInFlags *df; + const CWTargetList *tl; + const CWExtMapList *el; + const CWPanelList *pnl; + const char *failreason; + CWDataType vislang; + SInt16 step; + + dropinname = Plugin_GetDropInName(pl); + pl->cached_ascii_version = Plugin_GetVersionInfoASCII(pl); + + if (!SupportedPlugin(pl, &failreason)) { + CLReportError(88, dropinname, pl->cached_ascii_version, failreason); + return 0; + } + + scan = &pluginlist; + while (*scan) { + if (Plugin_MatchesName(*scan, dropinname)) { + CLReportError(89, dropinname); + return 0; + } + scan = &(*scan)->next; + } + + *scan = pl; + + df = Plugin_GetDropInFlags(pl); + if (!(df->dropinflags & dropInExecutableTool) && !SendInitOrTermRequest(pl, 1)) { + CLReportError(3, dropinname); + return 0; + } + + if (df->dropintype == CWDROPINCOMPILERTYPE && df->dropinflags & 0x17C000) + CLReportError(4, "compiler", dropinname); + if (df->dropintype == CWDROPINLINKERTYPE && df->dropinflags & 0x5FE4000) + CLReportError(4, "linker", dropinname); + + if (clState.pluginDebug) { + vislang = df->edit_language ? df->edit_language : CWFOURCHAR('-','-','-','-'); + CLPrint("Added plugin '%s', version '%s'\n", dropinname, pl->cached_ascii_version); + CLPrint("Type: '%c%c%c%c'; Lang: '%c%c%c%c'; API range: %d-%d\n", + (df->dropintype & 0xFF000000) >> 24, + (df->dropintype & 0x00FF0000) >> 16, + (df->dropintype & 0x0000FF00) >> 8, + (df->dropintype & 0x000000FF), + (vislang & 0xFF000000) >> 24, + (vislang & 0x00FF0000) >> 16, + (vislang & 0x0000FF00) >> 8, + (vislang & 0x000000FF), + df->earliestCompatibleAPIVersion, + df->newestAPIVersion + ); + + if (pl->cl_cb) { + tl = Plugin_CL_GetTargetList(pl); + CLPrint("Target CPUs: "); + for (step = 0; step < tl->cpuCount; step++) { + CLPrint("'%c%c%c%c', ", + (tl->cpus[step] & 0xFF000000) >> 24, + (tl->cpus[step] & 0x00FF0000) >> 16, + (tl->cpus[step] & 0x0000FF00) >> 8, + (tl->cpus[step] & 0x000000FF) + ); + } + CLPrint("\nTarget OSes: "); + for (step = 0; step < tl->osCount; step++) { + CLPrint("'%c%c%c%c', ", + (tl->oss[step] & 0xFF000000) >> 24, + (tl->oss[step] & 0x00FF0000) >> 16, + (tl->oss[step] & 0x0000FF00) >> 8, + (tl->oss[step] & 0x000000FF) + ); + } + CLPrint("\n"); + + el = Plugin_CL_GetExtMapList(pl); + CLPrint("File mappings:\n"); + for (step = 0; step < el->nMappings; step++) { + if (el->mappings[step].type) { + CLPrint("\tFile type: '%c%c%c%c' Extension: '%s'\n", + (el->mappings[step].type & 0xFF000000) >> 24, + (el->mappings[step].type & 0x00FF0000) >> 16, + (el->mappings[step].type & 0x0000FF00) >> 8, + (el->mappings[step].type & 0x000000FF), + el->mappings[step].extension + ); + } else { + CLPrint("\tFile type: <none> Extension: '%s'\n", + el->mappings[step].extension + ); + } + } + } + + pnl = Plugin_GetPanelList(pl); + CLPrint("Pref panels needed:\n"); + for (step = 0; step < pnl->count; step++) { + CLPrint("\t'%s'\n", pnl->names[step]); + } + + CLPrint("Dropin flags:\n"); + if (df->dropinflags & dropInExecutableTool) CLPrint("\texecutable tool,\n"); + if (df->dropintype == CWDROPINCOMPILERTYPE) { + if (df->dropinflags & kGeneratescode) CLPrint("\tgenerates code,\n"); + if (df->dropinflags & kGeneratesrsrcs) CLPrint("\tgenerates resources, \n"); + if (df->dropinflags & kCanpreprocess) CLPrint("\tcan preprocess, \n"); + if (df->dropinflags & kCanprecompile) CLPrint("\tcan precompile, \n"); + if (df->dropinflags & kIspascal) CLPrint("\tis Pascal, \n"); + if (df->dropinflags & kCanimport) CLPrint("\tcan import, \n"); + if (df->dropinflags & kCandisassemble) CLPrint("\tcan disassemble, \n"); + if (df->dropinflags & kCompAllowDupFileNames) CLPrint("\tallow duplicate filenames, \n"); + if (df->dropinflags & kCompMultiTargAware) CLPrint("\tallow multiple targets, \n"); + if (df->dropinflags & kCompUsesTargetStorage) CLPrint("\tuses target storage, \n"); + if (df->dropinflags & kCompEmitsOwnBrSymbols) CLPrint("\temits own browser symbols, \n"); + if (df->dropinflags & kCompAlwaysReload) CLPrint("\tshould be always reloaded, \n"); + if (df->dropinflags & kCompRequiresProjectBuildStartedMsg) CLPrint("\trequires project build started msg, \n"); + if (df->dropinflags & kCompRequiresTargetBuildStartedMsg) CLPrint("\trequires target build started msg, \n"); + if (df->dropinflags & kCompRequiresSubProjectBuildStartedMsg) CLPrint("\trequires subproject build started msg, \n"); + if (df->dropinflags & kCompRequiresFileListBuildStartedMsg) CLPrint("\trequires file list build started msg, \n"); + } + + if (df->dropintype == CWDROPINLINKERTYPE) { + if (df->dropinflags & cantDisassemble) CLPrint("\tcan't disassemble, \n"); + if (df->dropinflags & isPostLinker) CLPrint("\tis a post-linker, \n"); + if (df->dropinflags & linkAllowDupFileNames) CLPrint("\tallow duplicate filenames, \n"); + if (df->dropinflags & linkMultiTargAware) CLPrint("\tallow multiple targets, \n"); + if (df->dropinflags & isPreLinker) CLPrint("\tis a pre-linker, \n"); + if (df->dropinflags & linkerUsesTargetStorage) CLPrint("\tuses target storage, \n"); + if (df->dropinflags & linkerUnmangles) CLPrint("\tsupports unmangling, \n"); + if (df->dropinflags & magicCapLinker) CLPrint("\tis Magic Cap linker, \n"); + if (df->dropinflags & linkAlwaysReload) CLPrint("\tshould be always reloaded, \n"); + if (df->dropinflags & linkRequiresProjectBuildStartedMsg) CLPrint("\trequires project build started msg, \n"); + if (df->dropinflags & linkRequiresTargetBuildStartedMsg) CLPrint("\trequires target build started msg, \n"); + if (df->dropinflags & linkRequiresSubProjectBuildStartedMsg) CLPrint("\trequires subproject build started msg, \n"); + if (df->dropinflags & linkRequiresFileListBuildStartedMsg) CLPrint("\trequires file list build started msg, \n"); + if (df->dropinflags & linkRequiresTargetLinkStartedMsg) CLPrint("\trequires target link started msg, \n"); + if (df->dropinflags & linkerWantsPreRunRequest) CLPrint("\twants pre-run request, \n"); + } + + CLPrint("\n"); + } + + return 1; +} + +Plugin *Plugins_MatchName(Plugin *list, const char *name) { + Plugin *scan; + + scan = list ? list : pluginlist; + while (scan) { + if (Plugin_MatchesName(scan, name)) + break; + scan = scan->next; + } + + return scan; +} + +Plugin *Plugins_CL_MatchTarget(Plugin *list, OSType cpu, OSType os, OSType type, OSType lang) { + Plugin *scan; + Plugin *pick; + + scan = list ? list : pluginlist; + pick = NULL; + while (scan) { + if (scan->cl_cb) { + if (Plugin_CL_MatchesTarget(scan, cpu, os, 0) && Plugin_MatchesType(scan, type, lang, 0)) { + pick = scan; + if (Plugin_CL_MatchesTarget(scan, cpu, os, 1) && Plugin_MatchesType(scan, type, lang, 1)) + break; + } + } + scan = scan->next; + } + + return pick; +} + +Plugin *Plugins_CL_MatchFileType(Plugin *list, OSType type, const char *ext, Boolean exact) { + Plugin *scan; + + scan = list ? list : pluginlist; + while (scan) { + if (Plugin_CL_MatchesFileType(scan, type, ext, exact)) + break; + scan = scan->next; + } + + return scan; +} + +Plugin *Plugins_GetPluginForFile(Plugin *list, OSType plugintype, OSType cpu, OSType os, OSType type, const char *ext, OSType lang) { + Plugin *scan; + Plugin *pick; + + scan = list ? list : pluginlist; + pick = NULL; + while (scan) { + if (Plugin_MatchesType(scan, plugintype, lang, 1) && scan->cl_cb) { + if (Plugin_CL_MatchesTarget(scan, cpu, os, 0) && Plugin_CL_MatchesFileType(scan, type, ext, 0)) { + pick = scan; + if (Plugin_CL_MatchesTarget(scan, cpu, os, 1) && Plugin_CL_MatchesFileType(scan, type, ext, 1)) + break; + } + } + scan = scan->next; + } + + return pick; +} + +Plugin *Plugins_GetLinker(Plugin *list, OSType cpu, OSType os) { + Plugin *scan; + Plugin *pick; + + scan = list ? list : pluginlist; + pick = NULL; + while (scan) { + if (Plugin_MatchesType(scan, CWDROPINLINKERTYPE, Lang_Any, 1)) { + if (!(Plugin_GetDropInFlags(scan)->dropinflags & (isPreLinker | isPostLinker))) { + if (Plugin_CL_MatchesTarget(scan, cpu, os, 0)) { + pick = scan; + if (Plugin_CL_MatchesTarget(scan, cpu, os, 1)) + break; + } + } + } + scan = scan->next; + } + + return pick; +} + +Plugin *Plugins_GetPreLinker(Plugin *list, OSType cpu, OSType os) { + Plugin *scan; + Plugin *pick; + + scan = list ? list : pluginlist; + pick = NULL; + while (scan) { + if (Plugin_MatchesType(scan, CWDROPINLINKERTYPE, Lang_Any, 1)) { + if (Plugin_GetDropInFlags(scan)->dropinflags & isPreLinker) { + if (Plugin_CL_MatchesTarget(scan, cpu, os, 0)) { + pick = scan; + if (Plugin_CL_MatchesTarget(scan, cpu, os, 1)) + break; + } + } + } + scan = scan->next; + } + + return pick; +} + +Plugin *Plugins_GetPostLinker(Plugin *list, OSType cpu, OSType os) { + Plugin *scan; + Plugin *pick; + + scan = list ? list : pluginlist; + pick = NULL; + while (scan) { + if (Plugin_MatchesType(scan, CWDROPINLINKERTYPE, Lang_Any, 1)) { + if (Plugin_GetDropInFlags(scan)->dropinflags & isPostLinker) { + if (Plugin_CL_MatchesTarget(scan, cpu, os, 0)) { + pick = scan; + if (Plugin_CL_MatchesTarget(scan, cpu, os, 1)) + break; + } + } + } + scan = scan->next; + } + + return pick; +} + +Plugin *Plugins_GetParserForPlugin(Plugin *list, OSType style, int numPlugins, CLPluginInfo *plugins, OSType cpu, OSType os, int numPanels, const char **panelNames) { + Plugin *scan; + Plugin *pick; + Boolean allpanels; + Boolean hasplugintype; + Boolean *supports; + + scan = list ? list : pluginlist; + pick = NULL; + supports = alloca(numPanels); + + while (scan) { + if (Plugin_MatchesType(scan, CWDROPINPARSERTYPE, style, 1)) { + int idx; + int pnl; + hasplugintype = 0; + for (idx = 0; idx < numPlugins; idx++) { + if (plugins[idx].plugintype != CWDROPINPARSERTYPE && plugins[idx].plugintype != CWDROPINDRIVERTYPE && !plugins[idx].storeCommandLine) { + if (Plugin_Pr_MatchesPlugin(scan, &plugins[idx], cpu, os)) + hasplugintype = 1; + } + } + + if (hasplugintype) { + pick = scan; + allpanels = 1; + for (pnl = 0; pnl < numPanels; pnl++) { + allpanels &= (supports[pnl] = Plugin_Pr_MatchesPanels(scan, 1, &panelNames[pnl])); + } + + if (allpanels) + break; + } + } + scan = scan->next; + } + + if (pick && !allpanels) { + int idx; + CLReport(5); + + for (idx = 0; idx < numPanels; idx++) { + if (!supports[idx]) + CLReport(6, panelNames[idx]); + } + } + + return pick; +} + +Plugin *Plugins_GetCompilerForLinker(Plugin *list, Plugin *linker, OSType type, const char *ext, OSType edit) { + Plugin *scan; + Plugin *pick; + + scan = list ? list : pluginlist; + pick = NULL; + + while (scan) { + if (Plugin_MatchesType(scan, CWDROPINCOMPILERTYPE, edit, 1)) { + if (Plugin_CL_MatchesFileType(scan, type, ext, 0) && Plugins_CL_HaveMatchingTargets(scan, linker, 0)) { + pick = scan; + if (Plugin_CL_MatchesFileType(scan, type, ext, 1) && Plugins_CL_HaveMatchingTargets(scan, linker, 1)) + break; + } + } + scan = scan->next; + } + + return pick; +} + +int Plugins_GetPluginList(Plugin *list, int *numPlugins, CLPluginInfo **pluginInfo) { + Plugin *scan; + int idx; + const DropInFlags *df; + const VersionInfo *vi; + + scan = list ? list : pluginlist; + idx = 0; + while (scan) { + scan = scan->next; + idx++; + } + + *numPlugins = idx; + *pluginInfo = xmalloc(NULL, sizeof(CLPluginInfo) * idx); + if (!*pluginInfo) + return 0; + + scan = list ? list : pluginlist; + idx = 0; + while (scan) { + df = Plugin_GetDropInFlags(scan); + vi = Plugin_GetVersionInfo(scan); +#line 1270 + OPTION_ASSERT(df != NULL); + OPTION_ASSERT(vi != NULL); + (*pluginInfo)[idx].plugintype = df->dropintype; + (*pluginInfo)[idx].language = df->edit_language; + (*pluginInfo)[idx].dropinflags = df->dropinflags; + (*pluginInfo)[idx].version = scan->cached_ascii_version; + (*pluginInfo)[idx].storeCommandLine = df->dropinflags & 1; + scan = scan->next; + idx++; + } + + return 1; +} + +int Plugins_GetPrefPanelUnion(Plugin *list, int *numPanels, const char ***panelNames) { + Plugin *scan; + int tempNum; + int idx; + const char **tempPanels; + + scan = list ? list : pluginlist; + + tempNum = 0; + while (scan) { + const CWPanelList *pl; + pl = Plugin_GetPanelList(scan); + tempNum += pl->count; + scan = scan->next; + } + + tempPanels = xmalloc("plugin preference union", sizeof(const char *) * tempNum); + + idx = 0; + scan = list ? list : pluginlist; + while (scan) { + const CWPanelList *pl; + int step; + + pl = Plugin_GetPanelList(scan); + for (step = 0; step < pl->count; step++) { + int cmp; + for (cmp = 0; cmp < idx; cmp++) { + if (!ustrcmp(tempPanels[cmp], pl->names[step])) + break; + } + + if (cmp >= idx) + tempPanels[idx++] = pl->names[step]; + } + + scan = scan->next; + } + + *panelNames = xmalloc(NULL, idx * sizeof(const char *)); + if (!*panelNames) + return 0; + + *panelNames = xrealloc("plugin preference union", tempPanels, idx * sizeof(const char *)); + *numPanels = idx; + return 1; +} + +int Plugin_AddFileTypeMappings(Plugin *pl, OSFileTypeMappings **mlist) { + const OSFileTypeMappingList *ftml; + + ftml = Plugin_GetFileTypeMappingList(pl); + if (!ftml) { + return 1; + } else { + AddFileTypeMappingList(NULL, ftml); + return 1; + } +} + +int Plugins_AddFileTypeMappingsForTarget(Plugin *list, OSFileTypeMappings **mlist, OSType cpu, OSType os) { + if (!list) + list = pluginlist; + + while (list) { + if (!list->cl_cb || Plugin_CL_MatchesTarget(list, cpu, os, 0)) + Plugin_AddFileTypeMappings(list, mlist); + list = list->next; + } + + return 1; +} + +SInt16 Plugin_Call(Plugin *pl, void *context) { + if (pl->cb->main) + return pl->cb->main(context); + else + return cwErrRequestFailed; +} + diff --git a/command_line/CmdLine/Src/Project/CLAccessPaths.c b/command_line/CmdLine/Src/Project/CLAccessPaths.c index e69de29..1ffcd1d 100644 --- a/command_line/CmdLine/Src/Project/CLAccessPaths.c +++ b/command_line/CmdLine/Src/Project/CLAccessPaths.c @@ -0,0 +1,525 @@ +#include "cmdline.h" + +// TODO check where this should be! +Paths FrameworkPaths; +Frameworks FrameworkInfo; + +Path *Path_Init(const OSPathSpec *dir, Path *path) { + path->spec = xmalloc(NULL, sizeof(OSPathSpec)); + *path->spec = *dir; + path->recursive = NULL; + path->dirlist = NULL; + path->flags = 0; + return path; +} + +Path *Path_New(const OSPathSpec *dir) { + Path *path; + path = xmalloc(NULL, sizeof(Path)); + return Path_Init(dir, path); +} + +void Path_Free(Path *path) { + if (path) { + if (path->spec) + xfree(path->spec); + if (path->recursive) { + Paths_Terminate(path->recursive); + xfree(path->recursive); + } + xfree(path); + } +} + +Boolean Paths_Initialize(Paths *paths) { +#line 52 + OPTION_ASSERT(paths != NULL); + + memset(paths, 0, sizeof(Paths)); + paths->pathsArray = NULL; + return 1; +} + +Boolean Paths_Terminate(Paths *paths) { + UInt16 index; + +#line 63 + OPTION_ASSERT(paths != NULL); + + if (paths->pathsArray) { + for (index = 0; index < paths->pathsCount; index++) + Path_Free(paths->pathsArray[index]); + xfree(paths->pathsArray); + } + + paths->pathsArray = NULL; + return 1; +} + +static Boolean Paths_GrowPaths(Paths *paths, UInt16 *index) { + Path **newArray; + +#line 84 + OPTION_ASSERT(paths != NULL); + + if (paths->pathsCount >= paths->arraySize) { + paths->arraySize += 20; + newArray = xrealloc("access paths", paths->pathsArray, sizeof(Path *) * paths->arraySize); + paths->pathsArray = newArray; + } + + *index = paths->pathsCount++; + return 1; +} + +Boolean Paths_AddPath(Paths *paths, Path *path) { + UInt16 ni; + + if (Paths_GrowPaths(paths, &ni)) { + paths->pathsArray[ni] = path; + return 1; + } else { + return 0; + } +} + +Boolean Paths_InsertPath(Paths *paths, UInt16 index, Path *path) { + UInt16 ni; + + if (Paths_GrowPaths(paths, &ni)) { + if (index > ni) { + index = (ni != 0) ? (ni - 1) : 0; + } + memmove(&paths->pathsArray[index + 1], &paths->pathsArray[index], sizeof(Path *) * (paths->pathsCount - index)); + paths->pathsArray[index] = path; + return 1; + } else { + return 0; + } +} + +Boolean Paths_RemovePath(Paths *paths, UInt16 index) { + if (index >= paths->pathsCount) + return 0; + + memmove(&paths->pathsArray[index], &paths->pathsArray[index + 1], sizeof(Path *) * (paths->pathsCount - index - 1)); + paths->pathsCount--; + return 1; +} + +Boolean Paths_DeletePath(Paths *paths, UInt16 index) { + if (index >= paths->pathsCount) + return 0; + + Path_Free(paths->pathsArray[index]); + return Paths_RemovePath(paths, index); +} + +Path *Paths_GetPath(Paths *paths, UInt16 pathnum) { +#line 151 + OPTION_ASSERT(paths != NULL); + + if (pathnum < paths->pathsCount) + return paths->pathsArray[pathnum]; + else + return NULL; +} + +UInt16 Paths_Count(const Paths *paths) { +#line 161 + OPTION_ASSERT(paths != NULL); + + return paths->pathsCount; +} + +Boolean Paths_FindPath(const Paths *paths, const Path *path) { + UInt16 idx; + +#line 169 + OPTION_ASSERT(paths != NULL); + + for (idx = 0; idx < paths->pathsCount; idx++) { + if (paths->pathsArray[idx] == path) + return 1; + } + + return 0; +} + +Path *Paths_FindPathSpec(const Paths *paths, const OSPathSpec *dir) { + UInt16 idx; + Path *path; + +#line 182 + OPTION_ASSERT(paths != NULL); + + for (idx = 0; idx < paths->pathsCount; idx++) { + path = paths->pathsArray[idx]; + if (OS_EqualPathSpec(path->spec, dir)) + return path; + } + + return NULL; +} + +static Boolean GatherRecurse(Paths *list, Path *path) { + int err; + OSOpenedDir rf; + OSSpec ent; + int count; + char filename[64]; + Boolean isfile; + char *nptr; + char *eptr; + UInt16 added; + Path *nw; + + count = 0; + if (CheckForUserBreak()) + return 1; + + err = OS_OpenDir(path->spec, &rf); + while (!err) { + err = OS_ReadDir(&rf, &ent, filename, &isfile); + if (!err) { + if (!isfile) { + nw = Path_New(&ent.path); + nptr = OS_GetFileNamePtr(filename); + eptr = nptr + strlen(nptr) - 1; + if (eptr[0] == OS_PATHSEP) + eptr--; + if (eptr > nptr && *nptr == '(' && *eptr == ')') + continue; + + if (!Paths_AddPath(list, nw)) + break; + added = Paths_Count(list) - 1; + if (!GatherRecurse(list, nw)) + Paths_DeletePath(list, added); + } else { + if (!(++count % 50) && CheckForUserBreak()) + return 0; + } + } + } + OS_CloseDir(&rf); + return count > 0; +} + +Boolean Paths_GatherRecurse(Path *path) { + path->recursive = xcalloc(NULL, sizeof(Paths)); + GatherRecurse(path->recursive, path); + return Paths_Count(path->recursive) != 0; +} + +int Paths_CountRecurse(Paths *paths) { + UInt16 idx; + int mine; + Path *path; + + mine = Paths_Count(paths); + for (idx = 0; idx < mine; idx++) { + path = Paths_GetPath(paths, idx); +#line 336 + OPTION_ASSERT(path); + + if (path->recursive) + mine += Paths_CountRecurse(path->recursive); + } + + return mine; +} + +static void CopyRecurseFSS(FSSpec **list, Paths *paths, UInt16 *count) { + UInt16 idx; + OSSpec spec; + Path *path; + + for (idx = 0; idx < Paths_Count(paths); idx++) { + path = Paths_GetPath(paths, idx); +#line 353 + OPTION_ASSERT(path && *count > 0); + OS_MakeSpecWithPath(path->spec, NULL, 0, &spec); +#line 355 + OPTION_ASSERT(OS_OSSpec_To_FSSpec(&spec, *list)); + (*list)++; + (*count)--; + if (path->recursive) + CopyRecurseFSS(list, path->recursive, count); + } +} + +void Paths_CopyRecurseFSS(FSSpec *list, Paths *paths, UInt16 count) { + CopyRecurseFSS(&list, paths, &count); +#line 367 + OPTION_ASSERT(count == 0); +} + +static Boolean Frameworks_Initialize(Frameworks *fws) { +#line 405 + OPTION_ASSERT(fws != NULL); + + memset(fws, 0, sizeof(Frameworks)); + fws->fwsArray = NULL; + return 1; +} + +static Boolean Frameworks_Grow(Frameworks *fws, UInt16 *index) { + Paths_FWInfo **newArray; + +#line 418 + OPTION_ASSERT(fws != NULL); + + if (fws->fwsCount >= fws->arraySize) { + fws->arraySize += 20; + newArray = xrealloc("access frameworks", fws->fwsArray, sizeof(Paths_FWInfo *) * fws->arraySize); + fws->fwsArray = newArray; + } + + *index = fws->fwsCount++; + return 1; +} + +static Boolean Frameworks_Add(Frameworks *fws, Paths_FWInfo *info) { + UInt16 ni; + + if (Frameworks_Grow(fws, &ni)) { + fws->fwsArray[ni] = info; + return 1; + } else { + return 0; + } +} + +static Paths_FWInfo *Framework_Init(OSSpec *dir, const char *name, const char *version, Paths_FWInfo *info, Path *p, Boolean hidden) { + info->fileSpec = *dir; + if (version && version[0]) + strncpy(info->version.s, version, sizeof(info->version.s)); + else + info->version.s[0] = 0; + strncpy(info->name.s, name, sizeof(info->name.s)); + info->path = p; + info->hidden = hidden; + return info; +} + +static Paths_FWInfo *Framework_New(OSSpec *dir, const char *name, const char *version, Path *p, Boolean hidden) { + Paths_FWInfo *info; + info = xmalloc(NULL, sizeof(Paths_FWInfo)); + return Framework_Init(dir, name, version, info, p, hidden); +} + +static Boolean CheckForFileInFrameworkDir(char *out, const char *framework_path, OSPathSpec *osps, const char *fname) { + int err; + OSSpec oss; + + sprintf(out, "%s/%s", framework_path, fname); + err = OS_MakeSpecWithPath(osps, out, 0, &oss); + if (err == 0 && OS_IsFile(&oss)) + return 1; + + sprintf(out, "%s/Headers/%s", framework_path, fname); + err = OS_MakeSpecWithPath(osps, out, 0, &oss); + if (err == 0 && OS_IsFile(&oss)) + return 1; + + sprintf(out, "%s/Resources/%s", framework_path, fname); + err = OS_MakeSpecWithPath(osps, out, 0, &oss); + if (err == 0 && OS_IsFile(&oss)) + return 1; + + sprintf(out, "%s/Resources/%s", framework_path, fname); + err = OS_MakeSpecWithPath(osps, out, 0, &oss); + if (err == 0 && OS_IsFile(&oss)) + return 1; + + return 0; +} + +static Boolean CheckForFileInFramework(char *out, int i, const char *fname) { + Paths_FWInfo *info; + char framework_path[256]; + + info = Frameworks_GetInfo(i); + if (strlen(info->version.s)) + sprintf(framework_path, "%s.framework/Versions/%s", info->name.s, info->version.s); + else + sprintf(framework_path, "%s.framework", info->name.s); + + if (CheckForFileInFrameworkDir(out, framework_path, info->path->spec, fname)) + return 1; + else + return 0; +} + +Boolean MakeFrameworkPath(char *out, const char *filename, Path *globalpath) { + Paths_FWInfo *info; + int err; + char *end; + char *fname; + char framework_name[256]; + char framework_path[256]; + const char *s; + char *d; + int i; + int n; + + n = Frameworks_GetCount(); + end = strchr(filename, OS_PATHSEP); + if (!end) { + for (i = 0; i < n; i++) { + info = Frameworks_GetInfo(i); + if (!info->hidden && CheckForFileInFramework(out, i, filename)) + return 1; + } + return 0; + } + + fname = end + 1; + s = filename; + d = framework_name; + while (s < end) + *(d++) = *(s++); + *d = 0; + + for (i = 0; i < n; i++) { + if (!strcmp(Frameworks_GetInfo(i)->name.s, framework_name)) { + return CheckForFileInFramework(out, i, fname) != 0; + } + } + + if (globalpath) { + OSSpec oss; + sprintf(framework_path, "../Frameworks/%s.framework", framework_name); + err = OS_MakeSpecWithPath(globalpath->spec, framework_path, 0, &oss); + if (!err && OS_IsDir(&oss)) { + if (CheckForFileInFrameworkDir(out, framework_path, globalpath->spec, fname)) + return 1; + } + } + + n = Paths_Count(&FrameworkPaths); + sprintf(framework_path, "%s.framework", framework_name); + for (i = 0; i < n; i++) { + OSSpec oss; + Path *p; + p = Paths_GetPath(&FrameworkPaths, i); + err = OS_MakeSpecWithPath(p->spec, framework_path, 0, &oss); + if (!err && OS_IsDir(&oss)) { + if (CheckForFileInFrameworkDir(out, framework_path, p->spec, fname)) { + Frameworks_AddFramework(framework_name, NULL, 1); + return 1; + } + } + } + + return 0; +} + +void Frameworks_AddPath(const OSPathSpec *oss) { + Paths_AddPath(&FrameworkPaths, Path_New(oss)); +} + +int Frameworks_AddFramework(const char *name, const char *version, Boolean hidden) { + char fullname[256]; + int i; + Path *p; + int n_paths; + OSSpec oss; + int err; + + sprintf(fullname, "%s.framework", name); + n_paths = Paths_Count(&FrameworkPaths); + for (i = 0; i < n_paths; i++) { + p = Paths_GetPath(&FrameworkPaths, i); + err = OS_MakeSpecWithPath(p->spec, fullname, 0, &oss); + if (!err && OS_IsDir(&oss)) { + if (Frameworks_Add(&FrameworkInfo, Framework_New(&oss, name, version, p, hidden))) { + if (version && strlen(version)) { + sprintf(fullname, "Versions/%s/Frameworks", version); + err = OS_MakeSpecWithPath(&oss.path, fullname, 0, &oss); + } else { + err = OS_MakeSpecWithPath(&oss.path, "Frameworks", 0, &oss); + } + if (!err && OS_IsDir(&oss)) + Frameworks_AddPath(&oss.path); + return 1; + } + } + } + + return 0; +} + +void Framework_GetEnvInfo() { + char path[256]; + char *env; + char *ptr; + OSSpec spec; + char name[64]; + char version[16]; + int err; + Boolean is_file; + +#line 672 + OPTION_ASSERT(Paths_Initialize(&FrameworkPaths) == 1); + OPTION_ASSERT(Frameworks_Initialize(&FrameworkInfo) == 1); + + env = getenv("MWFrameworkPaths"); + if (env) { + while (*env) { + ptr = path; + while (*env && *env != ':' && (ptr + 1) < &path[sizeof(path)]) + *(ptr++) = *(env++); + *ptr = 0; + while (*env && *env == ':') + env++; + + if (path[0]) { + if (strlen(path) >= sizeof(path)) { + CLReportError(64, sizeof(path), path); + } else { + err = OS_MakeSpec(path, &spec, &is_file); + if (!is_file && !err) { + Frameworks_AddPath(&spec.path); + } else { + CLReportError(23, path); + } + } + } + } + } + + env = getenv("MWFrameworkVersions"); + if (env) { + while (*env) { + ptr = name; + while (*env && *env != ':' && (ptr + 1) < &name[sizeof(name)]) + *(ptr++) = *(env++); + *ptr = 0; + while (*env && *env == ':') + env++; + + ptr = version; + while (*env && *env != ',' && (ptr + 1) < &version[sizeof(version)]) + *(ptr++) = *(env++); + *ptr = 0; + while (*env && *env == ',') + env++; + + if (name[0]) + Frameworks_AddFramework(name, version, 0); + } + } +} + +int Frameworks_GetCount() { + return FrameworkInfo.fwsCount; +} + +Paths_FWInfo *Frameworks_GetInfo(int which) { +#line 762 + OPTION_ASSERT(FrameworkInfo.fwsArray); + OPTION_ASSERT(FrameworkInfo.fwsCount > which); + return FrameworkInfo.fwsArray[which]; +} diff --git a/command_line/CmdLine/Src/Project/CLFiles.c b/command_line/CmdLine/Src/Project/CLFiles.c index e69de29..a13deaf 100644 --- a/command_line/CmdLine/Src/Project/CLFiles.c +++ b/command_line/CmdLine/Src/Project/CLFiles.c @@ -0,0 +1,165 @@ +#include "cmdline.h" + +File *File_New() { + File *file; + file = xmalloc(NULL, sizeof(File)); + if (!file) { + return NULL; + } else { + memset(file, 0, sizeof(File)); + return file; + } +} + +void File_Free(File *file) { + if (file) { + if (file->textdata) { + DisposeHandle(file->textdata); + file->textdata = NULL; + } + if (file->objectdata) { + DisposeHandle(file->objectdata); + file->objectdata = NULL; + } + if (file->browsedata) { + DisposeHandle(file->browsedata); + file->browsedata = NULL; + } + xfree(file); + } +} + +Boolean Files_Initialize(Files *this) { +#line 47 + OPTION_ASSERT(this != NULL); + return 1; +} + +Boolean Files_Terminate(Files *this) { + File *file; + File *next; + +#line 56 + OPTION_ASSERT(this != NULL); + + for (file = this->fileList; file; file = next) { + next = file->next; + File_Free(file); + } + + return 1; +} + +Boolean Files_AddFile(Files *this, File *file) { + return Files_InsertFile(this, file, this->fileCount); +} + +Boolean Files_InsertFile(Files *this, File *file, SInt32 position) { + File **scan; + +#line 80 + OPTION_ASSERT(this != NULL); + OPTION_ASSERT(file != NULL); + + if (position < 0) + position = 0; + else if (position > this->fileCount) + position = this->fileCount; + + scan = &this->fileList; + while (position > 0) { + scan = &(*scan)->next; + position--; + } + + file->filenum = this->fileCount++; + file->next = *scan; + *scan = file; + return 1; +} + +File *Files_GetFile(Files *this, SInt32 filenum) { + File *file; + +#line 104 + OPTION_ASSERT(this != NULL); + OPTION_ASSERT(filenum >= 0); + + file = this->fileList; + while (file && file->filenum != filenum) + file = file->next; + return file; +} + +File *Files_FindFile(Files *this, OSSpec *spec) { + File *file; + + file = this->fileList; + while (file && !OS_EqualSpec(&file->srcfss, spec)) + file = file->next; + return file; +} + +int Files_Count(Files *this) { +#line 127 + OPTION_ASSERT(this != NULL); + + return this->fileCount; +} + +Boolean VFiles_Initialize(VFile **list) { + *list = NULL; + return 1; +} + +void VFiles_Terminate(VFile **list) { + VFile *next; + + while (*list) { + next = (*list)->next; + DisposeHandle((*list)->data); + xfree(*list); + list = &next; + } + + *list = NULL; +} + +VFile *VFile_New(const char *name, Handle data) { + VFile *vf; + + vf = xmalloc(NULL, sizeof(VFile)); + if (!vf) + return NULL; + + strncpy(vf->displayName, name, sizeof(vf->displayName)); + vf->displayName[sizeof(vf->displayName) - 1] = 0; + + vf->data = NewHandle(0); + if (!vf->data || HandAndHand(data, vf->data)) { + xfree(vf); + return NULL; + } + + FixTextHandle(vf->data); + vf->next = NULL; + return vf; +} + +Boolean VFiles_Add(VFile **list, VFile *entry) { + VFile **scan = list; + while (*scan) + scan = &(*scan)->next; + *scan = entry; + return 1; +} + +VFile *VFiles_Find(VFile *list, const char *name) { + VFile *scan = list; + while (scan) { + if (!strcmp(scan->displayName, name)) + break; + scan = scan->next; + } + return scan; +} diff --git a/command_line/CmdLine/Src/Project/CLOverlays.c b/command_line/CmdLine/Src/Project/CLOverlays.c index e69de29..3437366 100644 --- a/command_line/CmdLine/Src/Project/CLOverlays.c +++ b/command_line/CmdLine/Src/Project/CLOverlays.c @@ -0,0 +1,296 @@ +#include "cmdline.h" + +Boolean Overlays_Initialize(Overlays *this) { + OvlGroup *grp; + Overlay *ovl; + OvlAddr addr; + SInt32 idx; + +#line 24 + OPTION_ASSERT(this); + + this->groups = NULL; + this->lastgrp = NULL; + this->grpcnt = 0; + addr.hi = 0; + addr.lo = 0; + + grp = OvlGroup_New("main_application", addr); + if (!grp) + return 0; + + ovl = Overlay_New("MAIN"); + if (!ovl) + return 0; + + OvlGroup_AddOverlay(grp, ovl, &idx); +#line 42 + OPTION_ASSERT(idx==0); + + Overlays_AddOvlGroup(this, grp, &idx); +#line 45 + OPTION_ASSERT(idx==0); + + return 1; +} + +Boolean Overlays_Terminate(Overlays *this) { + OvlGroup *grp; + OvlGroup *nxtgrp; + +#line 54 + OPTION_ASSERT(this); + + for (grp = this->groups; grp; grp = nxtgrp) { + nxtgrp = grp->next; + OvlGroup_Delete(grp); + xfree(grp); + } + + this->groups = NULL; + return 1; +} + +Boolean Overlays_AddOvlGroup(Overlays *this, OvlGroup *grp, SInt32 *grpnum) { +#line 70 + OPTION_ASSERT(this); + OPTION_ASSERT(grp); + + if (this->groups == NULL) + this->groups = grp; + else + this->lastgrp->next = grp; + this->lastgrp = grp; + + if (grpnum) + *grpnum = this->grpcnt; + this->grpcnt++; + + return 1; +} + +OvlGroup *Overlays_GetOvlGroup(Overlays *this, SInt32 grpnum) { + OvlGroup *grp; + SInt32 cnt = 0; + +#line 93 + OPTION_ASSERT(this); + + grp = this->groups; + while (grp && cnt < grpnum) { + grp = grp->next; + cnt++; + } + + if (cnt == grpnum) + return grp; + else + return NULL; +} + +SInt32 Overlays_CountGroups(Overlays *this) { + OvlGroup *scan; + int num = 0; + +#line 112 + OPTION_ASSERT(this); + + scan = this->groups; + while (scan) { + scan = scan->next; + num++; + } + + return num; +} + +Boolean Overlays_AddFileToOverlay(Overlays *this, SInt32 grpnum, SInt32 ovlnum, SInt32 filenum) { + Overlay *oly; + +#line 130 + OPTION_ASSERT(this); + + oly = Overlays_GetOverlayInGroup(this, grpnum, ovlnum); + if (oly) + return Overlay_AddFile(oly, filenum, NULL); + else + return 0; +} + +Overlay *Overlays_GetOverlayInGroup(Overlays *this, SInt32 grpnum, SInt32 ovlnum) { + OvlGroup *grp; + +#line 144 + OPTION_ASSERT(this); + + grp = Overlays_GetOvlGroup(this, grpnum); + if (grp) + return OvlGroup_GetOverlay(grp, ovlnum); + else + return NULL; +} + +SInt32 Overlays_GetFileInOverlay(Overlays *this, SInt32 grpnum, SInt32 ovlnum, SInt32 filnum) { + Overlay *oly; + +#line 160 + OPTION_ASSERT(this); + + oly = Overlays_GetOverlayInGroup(this, grpnum, ovlnum); + if (oly) + return Overlay_GetFile(oly, filnum); + else + return -1; +} + +OvlGroup *OvlGroup_New(const char *name, OvlAddr addr) { + OvlGroup *grp; + +#line 175 + OPTION_ASSERT(name); + + grp = xmalloc(NULL, sizeof(OvlGroup)); + if (grp) { + strncpy(grp->name, name, sizeof(grp->name)); + grp->name[sizeof(grp->name) - 1] = 0; + grp->addr = addr; + grp->lastoly = NULL; + grp->olys = NULL; + grp->olycnt = 0; + grp->next = NULL; + } else { +#line 188 + DO_INTERNAL_ERROR("Could not allocate %s", "overlay group"); + } + return grp; +} + +void OvlGroup_Delete(OvlGroup *grp) { + Overlay *scan; + Overlay *next; + +#line 197 + OPTION_ASSERT(grp); + + for (scan = grp->olys; scan; scan = next) { + next = scan->next; + Overlay_Delete(scan); + xfree(scan); + } + + grp->olys = NULL; +} + +Boolean OvlGroup_AddOverlay(OvlGroup *this, Overlay *oly, SInt32 *olynum) { +#line 211 + OPTION_ASSERT(this); + OPTION_ASSERT(oly); + + if (!this->lastoly) + this->olys = oly; + else + this->lastoly->next = oly; + this->lastoly = oly; + + if (olynum) + *olynum = this->olycnt; + this->olycnt++; + + return 1; +} + +Overlay *OvlGroup_GetOverlay(OvlGroup *this, SInt32 olynum) { + Overlay *oly; + SInt32 cnt = 0; + +#line 234 + OPTION_ASSERT(this); + + oly = this->olys; + while (oly && cnt < olynum) { + oly = oly->next; + cnt++; + } + + if (cnt == olynum) + return oly; + else + return NULL; +} + +SInt32 OvlGroup_CountOverlays(OvlGroup *this) { + Overlay *scan; + int num = 0; + +#line 254 + OPTION_ASSERT(this); + + scan = this->olys; + while (scan) { + scan = scan->next; + num++; + } + + return num; +} + +Overlay *Overlay_New(const char *name) { + Overlay *oly; + + oly = xmalloc(NULL, sizeof(Overlay)); + if (oly) { + strncpy(oly->name, name, sizeof(oly->name)); + oly->name[sizeof(oly->name) - 1] = 0; + oly->list = NULL; + oly->max = 0; + oly->cnt = 0; + oly->next = NULL; + } else { +#line 281 + DO_INTERNAL_ERROR("Could not allocate %s", "overlay"); + } + return oly; +} + +void Overlay_Delete(Overlay *oly) { +#line 288 + OPTION_ASSERT(oly); + + if (oly->list) + xfree(oly->list); + oly->list = NULL; +} + +Boolean Overlay_AddFile(Overlay *oly, SInt32 filenum, SInt32 *filnum) { +#line 296 + OPTION_ASSERT(oly); + + if (oly->cnt >= oly->max) { + oly->max += 16; + oly->list = xrealloc("overlay file list", oly->list, sizeof(SInt32) * oly->max); + } + oly->list[oly->cnt] = filenum; + + if (filnum) + *filnum = oly->cnt; + oly->cnt++; + + return 1; +} + +SInt32 Overlay_GetFile(Overlay *oly, SInt32 filnum) { +#line 314 + OPTION_ASSERT(oly); + + if (filnum < oly->cnt) + return oly->list[filnum]; + else + return -1; +} + +SInt32 Overlay_CountFiles(Overlay *oly) { +#line 323 + OPTION_ASSERT(oly); + + return oly->cnt; +} diff --git a/command_line/CmdLine/Src/Project/CLProj.c b/command_line/CmdLine/Src/Project/CLProj.c index e69de29..83b2ce1 100644 --- a/command_line/CmdLine/Src/Project/CLProj.c +++ b/command_line/CmdLine/Src/Project/CLProj.c @@ -0,0 +1,16 @@ +#include "cmdline.h" + +Boolean Proj_Initialize(Project *this) { + this->targets = NULL; + OS_GetCWD(&this->projectDirectory.path); + OS_MakeNameSpec("", &this->projectDirectory.name); + return 1; +} + +Boolean Proj_Terminate(Project *this) { +#line 25 + OPTION_ASSERT(this != NULL); + + Targets_Term(this->targets); + return 1; +} diff --git a/command_line/CmdLine/Src/Project/CLSegs.c b/command_line/CmdLine/Src/Project/CLSegs.c index e69de29..a0e006c 100644 --- a/command_line/CmdLine/Src/Project/CLSegs.c +++ b/command_line/CmdLine/Src/Project/CLSegs.c @@ -0,0 +1,123 @@ +#include "cmdline.h" + +Segment *Segment_New(const char *name, UInt16 attrs) { + Segment *seg = xmalloc(NULL, sizeof(Segment)); + strncpy(seg->name, name, sizeof(seg->name)); + seg->name[sizeof(seg->name) - 1] = 0; + seg->attrs = attrs; + return seg; +} + +void Segment_Free(Segment *seg) { + if (seg) + xfree(seg); +} + +Boolean Segments_Initialize(Segments *segs) { + Segment *jump; + Segment *main; + UInt16 idx; + +#line 36 + OPTION_ASSERT(segs != NULL); + + memset(segs, 0, sizeof(Segments)); + segs->segsArray = NULL; + + jump = Segment_New("Jump Table", 0x28); + Segments_AddSegment(segs, jump, &idx); +#line 44 + OPTION_ASSERT(idx==0); + + main = Segment_New("Main", 0xFFFF); + Segments_AddSegment(segs, main, &idx); +#line 49 + OPTION_ASSERT(idx==1); + + return 1; +} + +Boolean Segments_Terminate(Segments *segs) { + UInt16 index; + +#line 57 + OPTION_ASSERT(segs != NULL); + + if (segs->segsArray) { + for (index = 0; index < segs->segsCount; index++) + Segment_Free(segs->segsArray[index]); + xfree(segs->segsArray); + } + segs->segsArray = NULL; + + return 1; +} + +static Boolean Segments_GrowSegments(Segments *segs, UInt16 *index) { + Segment **newArray; + +#line 78 + OPTION_ASSERT(segs != NULL); + + if (segs->segsCount >= segs->arraySize) { + segs->arraySize += 20; + newArray = xrealloc("segments", segs->segsArray, sizeof(Segment *) * segs->arraySize); + segs->segsArray = newArray; + } + + *index = segs->segsCount++; + return 1; +} + +Boolean Segments_AddSegment(Segments *segs, Segment *seg, UInt16 *index) { + UInt16 ni; + + if (Segments_GrowSegments(segs, &ni)) { + segs->segsArray[ni] = seg; + *index = ni; + return 1; + } else { + return 0; + } +} + +Boolean Segments_InsertSegment(Segments *segs, UInt16 index, Segment *seg) { + UInt16 ni; + + if (Segments_GrowSegments(segs, &ni)) { + if (index > ni) + index = ni - 1; + memmove(&segs->segsArray[index + 1], &segs->segsArray[index], sizeof(Segment *) * (segs->segsCount - index)); + segs->segsArray[index] = seg; + return 1; + } else { + return 0; + } +} + +Boolean Segments_DeleteSegment(Segments *segs, UInt16 index) { + if (index >= segs->segsCount) + return 0; + + Segment_Free(segs->segsArray[index]); + memmove(&segs->segsArray[index], &segs->segsArray[index + 1], sizeof(Segment *) * (segs->segsCount - index)); + segs->segsCount--; + return 1; +} + +Segment *Segments_GetSegment(Segments *segs, UInt16 segnum) { +#line 137 + OPTION_ASSERT(segs != NULL); + + if (segnum < segs->segsCount) + return segs->segsArray[segnum]; + else + return NULL; +} + +UInt16 Segments_Count(const Segments *segs) { +#line 147 + OPTION_ASSERT(segs != NULL); + + return segs->segsCount; +} diff --git a/command_line/CmdLine/Src/uFileTypeMappings.c b/command_line/CmdLine/Src/uFileTypeMappings.c new file mode 100644 index 0000000..56aaea5 --- /dev/null +++ b/command_line/CmdLine/Src/uFileTypeMappings.c @@ -0,0 +1,31 @@ +#include "cmdline.h" + +// I don't actually have a name for this file, annoyingly enough + +void AddFileTypeMappingList(OSFileTypeMappings **list, const OSFileTypeMappingList *entry) { + OS_AddFileTypeMappingList(list, entry); +} + +void UseFileTypeMappings(OSFileTypeMappings *list) { + OS_UseFileTypeMappings(list); +} + +OSErr SetMacFileType(const FSSpec *spec, OSType mactype) { + OSSpec ospec; + OSErr err; + + err = OS_FSSpec_To_OSSpec(spec, &ospec); + if (err) + return err; + return OS_SetMacFileType(&ospec, mactype); +} + +OSErr GetMacFileType(const FSSpec *spec, OSType *mactype) { + OSSpec ospec; + OSErr err; + + err = OS_FSSpec_To_OSSpec(spec, &ospec); + if (err) + return err; + return OS_GetMacFileType(&ospec, mactype); +} |