#include "parser.h" #include "cmdline.h" #include SInt16 lastStage; Boolean dashIMinusMovesPaths; Boolean usedDashIMinus; Boolean namingSysPaths; static char STSbuf[256]; int FindFileInPath(const char *filename, OSSpec *fss) { CWFileInfo fi; CWResult result; fi.fullsearch = 1; fi.dependencyType = 0; fi.suppressload = 1; fi.isdependentoffile = kCurrentCompiledFile; result = CWFindAndLoadFile(parseopts.context, filename, &fi); if (!result) { OS_FSSpec_To_OSSpec(&fi.filespec, fss); return 1; } else { return 0; } } char *GetEnvVar(const char *name, Boolean warn, const char **match) { const char *nptr; const char *last; char *ret; nptr = name; last = name; while (*nptr) { ret = getenv(nptr); if (ret) { if (match) *match = nptr; return ret; } last = nptr; nptr = &nptr[1 + strlen(nptr)]; } if (warn) CLPReportWarning(CLPStr52, last); *match = 0; return 0; } static Boolean MatchesExtension(const char *list, const char *filename) { char *fn; const char *eptr; const char *ptr; fn = OS_GetFileNamePtr((char *) filename); eptr = strrchr(fn, '.'); if (!eptr) return 0; if (!list) return 1; ptr = eptr; while (*list) { if (*list == '|' && !*ptr) return 1; if (my_tolower(*list) == my_tolower(*ptr)) { list++; ptr++; continue; } while (*list && *list != '|') list++; if (*list) list++; ptr = eptr; } return !*list && !*ptr; } int Opt_AddAccessPath(const char *opt, void *var, const char *arg, int flags) { OSPathSpec spec; int err; arg = arg ? arg : opt; if (!arg) return 0; if (!arg[0]) return 1; if (strlen(arg) >= 256) { CLPReportError(CLPStr13, arg + strlen(arg) - 32, 256); return 0; } err = OS_MakePathSpec(0, arg, &spec); if (err == ENOENT || err == ENOENT) { CLPReportWarning(CLPStr45, arg); return 1; } else if (err != 0) { CLPOSAlert(CLPStr45, err, arg); return 1; } // this 'if' gets optimised unnecessarily if (!AddAccessPath(&spec, namingSysPaths, 0, var != NULL)) return 0; else return 1; } int Opt_AddFrameworkPath(const char *opt, void *var, const char *arg, int flags) { OSPathSpec spec; int err; arg = arg ? arg : opt; if (!arg) return 0; if (!arg[0]) return 1; if (strlen(arg) >= 256) { CLPReportError(CLPStr13, arg + strlen(arg) - 32, 256); return 0; } err = OS_MakePathSpec(0, arg, &spec); if (err == ENOENT || err == ENOENT) { CLPReportWarning(CLPStr45, arg); return 1; } else if (err != 0) { CLPOSAlert(CLPStr45, err, arg); return 1; } else { Frameworks_AddPath(&spec); return 1; } } int Opt_AddFramework(const char *opt, void *var, const char *arg, int flags) { if (!Frameworks_AddFramework(arg ? arg : opt, 0, 0)) return 0; else return 1; } void ListParseMessage(void (*errprint)(const char *, va_list), const char *envvar, SInt16 id, ...) { char buf[1024]; va_list ap; if (envvar && envvar[0]) sprintf(buf, "In environment variable '%s':\n", envvar); else buf[0] = 0; CLPGetErrorString(id, buf + strlen(buf)); va_start(ap, id); errprint(buf, ap); va_end(ap); } int AddAccessPathList(const char *list, char sep1, char sep2, int source, char *text, Boolean system, SInt32 position, Boolean recursive) { char tmp[256]; Boolean recurse; OSPathSpec spec; int err; short type; char *ptr; type = (Boolean) ((system == 1) ? 1 : 0) | (!source ? 0 : 2); recurse = (list[0] == '+'); if (recurse) ++list; if (!strchr(list, sep1)) sep1 = sep2; while (*list) { ptr = tmp; while (*list && *list != sep1 && (ptr + 1) < &tmp[256]) { *(ptr++) = *(list++); } *ptr = 0; if ((ptr + 1) >= &tmp[256]) { ListParseMessage( CLPReportError_V, (source == 1) ? text : NULL, CLPStr9, tmp, tmp + strlen(tmp) - 16, 256); return 0; } err = OS_MakePathSpec(0, tmp, &spec); if (err) { ListParseMessage( CLPReportWarning_V, (source == 1) ? text : NULL, CLPStr45, tmp); } else { AddAccessPath(&spec, type, position, recurse ^ recursive); } if (*list) ++list; recurse = *list == '+'; if (recurse) ++list; } return 1; } int Opt_FindAndAddFile(const char *opt, void *var, const char *arg, int flags) { OSSpec spec; int err; Boolean isfile; arg = arg ? arg : opt; if (!arg) return 0; if (!*arg) return 1; parseopts.userSpecifiedFiles++; err = OS_MakeSpec(arg, &spec, &isfile); if (!err) err = OS_Status(&spec); if (!err && !isfile) { CLPReportError(CLPStr47, arg); parseopts.unusedFiles++; return 0; } else if (err && err != ENOENT) { CLPOSAlert(CLPStr44, err, arg); parseopts.unusedFiles++; return 0; } else if (err && parseopts.alwaysUsePaths) { err = FindFileInPath(arg, &spec) ? 0 : ENOENT; } if (err) { CLPReportError(CLPStr44, arg); parseopts.unusedFiles++; return 0; } if (var && !MatchesExtension((const char *) var, arg)) CLPReportWarning(CLPStr76, arg, var); if (!AddFileToProject(&spec, lastStage, parseopts.lastoutputname, 1, -1)) { parseopts.unusedFiles++; return 0; } else { parseopts.lastoutputname[0] = 0; return 1; } } int Opt_FindAndAddFileRef(const char *opt, void *var, const char *arg) { OSSpec spec; int err; Boolean isfile; arg = arg ? arg : opt; if (!arg) return 0; if (!*arg) return 1; parseopts.userSpecifiedFiles++; if (var && !MatchesExtension((const char *) var, arg)) CLPReportWarning(CLPStr76, arg, var); err = OS_MakeSpec(arg, &spec, &isfile); if (!err) err = OS_Status(&spec); if (!err && !isfile) { CLPReportError(CLPStr47, arg); parseopts.unusedFiles++; return 0; } else if (err && parseopts.alwaysUsePaths) { err = FindFileInPath(arg, &spec) ? 0 : ENOENT; } if (!AddFileToProject(&spec, 0, 0, err == 0, -1)) { parseopts.unusedFiles++; return 0; } else { return AddAccessPath(&spec.path, 1, -1, 0) != 0; } } int Opt_AddUnixLibraryFile(const char *opt, void *var, const char *name) { OSSpec spec; Boolean failed; const char *eptr; const char *eend; char tmpname[64]; if (strlen(name) >= 56) { CLPReportError(CLPStr13, name + strlen(name) - 32, 64); return 0; } failed = 1; if (!var) var = ".lib|.a"; eptr = (const char *) var; while (eptr && *eptr) { eend = eptr; while (*eend && *eend != '|') ++eend; sprintf(tmpname, "lib%s%*.*s", name, eend - eptr, eend - eptr, eptr); if (FindFileInPath(tmpname, &spec)) { failed = 0; break; } if (*eend) eptr = eend + 1; else eptr = eend; } if (failed) { failed = !FindFileInPath(name, &spec); if (failed) CLPReportError(CLPStr49, name, var, name); } if (!failed) { if (!AddFileToProject(&spec, 0, 0, 1, -1)) { parseopts.unusedFiles++; failed = 1; } } return !failed; } int AddFileList(const char *list, char sep1, char sep2, int source, char *text, SInt32 position) { char tmp[256]; OSSpec spec; char *ptr; if (!strchr(list, sep1)) sep1 = sep2; while (*list) { ptr = tmp; while (*list && *list != sep1 && (ptr + 1) < &tmp[256]) { *(ptr++) = *(list++); } *ptr = 0; if ((ptr + 1) >= &tmp[256]) { ListParseMessage( CLPReportError_V, (source == 1) ? text : 0, CLPStr9, tmp, tmp + strlen(tmp) - 16, 256 ); return 0; } if (!FindFileInPath(tmp, &spec)) { if (OS_IsDir(&spec)) { ListParseMessage( CLPReportError_V, (source == 1) ? text : 0, CLPStr16, tmp ); } else { ListParseMessage( CLPReportWarning_V, (source == 1) ? text : 0, CLPStr44, tmp ); } } else { AddFileToProject(&spec, 0, 0, 1, position); } if (*list) ++list; } return 1; } int IsFileInOutputDirectory(const OSSpec *file) { OSPathSpec outdir; GetOutputFileDirectory(&outdir); return OS_EqualPathSpec(&outdir, &file->path); } void GetCFileNameInOutputDirectory(const char *input, char *name, int maxlen) { char filename[64]; OSSpec spec; int err; err = OS_MakeFileSpec(input, &spec); if (err) { CLPOSAlert(CLPStr64, err, input); name[0] = 0; return; } if (!IsFileInOutputDirectory(&spec)) { CLPReportWarning(CLPStr61, OS_SpecToStringRelative(&spec, 0, STSbuf, sizeof(STSbuf))); } OS_NameSpecToString(&spec.name, filename, 256); if (strlen(filename) >= maxlen) { CLPReportWarning(CLPStr65, filename, maxlen - 1); filename[maxlen - 1] = 0; } strcpy(name, filename); } void GetPFileNameInOutputDirectory(const char *input, unsigned char *name, int len) { GetCFileNameInOutputDirectory(input, (char *) name, len); c2pstr((char *) name); } void AddStringLenToHandle(Handle *h, const char *str, int len) { SInt32 old; if (!*h) { if ((*h = NewHandle(len + 1))) { HLock(*h); memcpy(**h, str, len); (**h)[len] = 0; HUnlock(*h); } else { exit(-23); } } else { old = GetHandleSize(*h) - 1; SetHandleSize(*h, old + len + 1); if (MemError() == noErr) { HLock(*h); memcpy(**h + old, str, len); (**h)[old + len] = 0; HUnlock(*h); } else { exit(-23); } } } void AddStringToHandle(Handle *h, const char *str) { AddStringLenToHandle(h, str, strlen(str)); } int Opt_PrintVersion(const char *opt, void *var, const char *arg, int flags) { ShowVersion(0); return 1; } void GetFirstSourceFilenameBase(char *buffer, char *defaul) { int cnt; OSSpec spec; char compiler[32]; int x; char *ext; cnt = GetFileCount(); for (x = 0; x < cnt; x++) { if (GetFileInfo(x, &spec, compiler)) { if (compiler[0]) { if (!strstr(compiler, "Lib")) { OS_NameSpecToString(&spec.name, buffer, 256); ext = strrchr(buffer, '.'); if (ext) *ext = 0; memmove(buffer, buffer, strlen(buffer) + 1); return; } } } } strcpy(buffer, defaul); } int Opt_SavePrefs(const char *opt, void *var, const char *arg, int flags) { Parser_StorePanels(parseopts.context); return 1; } int ParseNumber(const char *arg, Boolean emit_error, SInt32 *ret, const char **endptr) { char *end; if (arg[0] == '0' && (arg[1] == 'x' || arg[1] == 'X')) { *ret = strtol(arg + 2, &end, 16); } else if (arg[0] == '0') { *ret = strtol(arg + 1, &end, 8); } else { *ret = strtol(arg, &end, 10); } if (endptr) *endptr = end; if (*end && emit_error) { CLPReportError(CLPStr5, "", arg); return 0; } return 1; } int Opt_MaybeMoveAccessPaths(const char *opt, void *var, const char *arg, int flags) { if (dashIMinusMovesPaths && !usedDashIMinus) MoveSystemPathsIntoUserList(); return 1; }