Exemple #1
0
        public bool ProcessArguments(string[] args)
        {
            try
            {
                DisableTracker();
                CommandLine = args;
                for (int i = 0; i < args.Length; i++)
                {
                    var opt  = getOption(args[i]);
                    var full = getFullOption(args[i]);

                    onlyOptions.Add(full);

                    #region switch process each argument type
                    switch (opt)
                    {
                    case "/c":
                        HasDashC = true;
                        break;

                    case "/o":
                        return(NotSupported("/o"));

                    case "/D":
                        if (opt == full)
                        {
                            // define value is next argument...
                            i++;
                            onlyOptions.Add(args[i]);
                        }
                        break;

                    case "/I":
                        if (opt == full)
                        {
                            // include path is next argument..
                            // microsoft really dont know how to do command line!
                            i++;
                            if (i > args.Length)
                            {
                                return(NotSupported("-I has no path!"));
                            }
                            full = "/I" + args[i];

                            onlyOptions.Add(args[i]);

                            goto default;
                        }
                        break;

                    case "/Z7":
                        GeneratePdb = false;
                        PdbFile     = null;
                        break;

                    case "/Yu":
                        PrecompiledHeaders = true;
                        return(NotSupported("pre-compiler headers {0}", opt));

                    case "/FI":
                        return(NotSupported(opt));

                    case "/Zi":
                        GeneratePdb = true;
                        break;

                    case "/Fd":
                        PdbFile = Path.Combine(WorkingDirectory, full.Substring(3));
                        // openssl gives us a posix path here..
                        PdbFile = PdbFile.Replace('/', '\\');
                        if (!PdbFile.ToLower().EndsWith(".pdb") && !PdbFile.EndsWith("\\"))
                        {
                            PdbFile = PdbFile + ".pdb";
                        }
                        break;

                    case "/Fo":
                        ObjectTarget = Path.Combine(WorkingDirectory, full.Substring(3));
                        if (ArgumentUtils.TargetIsFolder(ObjectTarget))
                        {
                            ObjectTargetIsFolder = true;
                        }
                        else
                        {
                            ObjectTarget = ArgumentUtils.TargetObject(ObjectTarget);
                        }
                        break;

                    case "/Tp":
                    case "/Tc":
                        var srcfile = ArgumentUtils.MakeWindowsPath(full.Substring(3));
                        if (!Path.IsPathRooted(srcfile))
                        {
                            srcfile = Path.Combine(WorkingDirectory, srcfile);
                        }

                        if (FileUtils.Exists(srcfile))
                        {
                            srcs.Add(srcfile);

                            // remove last added option
                            onlyOptions.RemoveAt(onlyOptions.Count - 1);
                            srcsOptions.Add(full);
                        }
                        else
                        {
                            return(NotSupported("cant find file for {0}", full));
                        }
                        break;

                    case "/E":
                        return(NotSupported(opt));

                    case "/EP":
                        return(NotSupported(opt));

                    case "/MP":
                        var numOfCompilersStr = full.Substring(3);
                        if (string.IsNullOrEmpty(numOfCompilersStr))
                        {
                            ParallelCompilers = Environment.ProcessorCount;
                        }
                        else
                        {
                            int parallel;
                            if (int.TryParse(numOfCompilersStr, out parallel))
                            {
                                ParallelCompilers = parallel;
                            }
                            else
                            {
                                ParallelCompilers = Environment.ProcessorCount;
                            }
                        }
                        break;

                    default:
                        #region positional or other flag options

                        if (full == "/link")
                        {
                            Linking = true;
                            return(NotSupported("/link"));
                        }

                        if (opt.StartsWith("@"))
                        {
                            // remove last added option
                            onlyOptions.RemoveAt(onlyOptions.Count - 1);

                            #region response file
                            ResponseFile = ArgumentUtils.MakeWindowsPath(full.Substring(1));

                            if (ResponseFile.EndsWith(InternalResponseFileSuffix))
                            {
                                Logging.Emit("cclash misshelper internal response file");
                                return(false);
                            }

                            if (!Path.IsPathRooted(ResponseFile))
                            {
                                ResponseFile = Path.Combine(WorkingDirectory, ResponseFile);
                            }
                            string rsptxt = File.ReadAllText(ResponseFile);
                            if (rsptxt.Length < 2047)
                            // windows max command line, this is why they invented response files
                            {
                                Logging.Emit("response data [{0}]", rsptxt);
                                if (args.Length == 1)
                                {
                                    // this only works if it is the one and only arg!
                                    args = ArgumentUtils.FixupArgs(CommandLineToArgs(rsptxt).Skip(1)).ToArray();
                                    i    = -1;
                                    // replace the command line with the response file content
                                    // and restart parsing. This does go wrong if the response text is huge
                                    continue;
                                }
                            }
                            else
                            {
                                Logging.Emit("response file too large");
                            }

                            return(NotSupported("response file error"));

                            #endregion
                        }

                        if (!full.StartsWith("/"))
                        {
                            // NOTE, if we ever cache -link calls this will also match input objects and libs
                            var file = ArgumentUtils.MakeWindowsPath(full);
                            if (!Path.IsPathRooted(file))
                            {
                                file = Path.Combine(WorkingDirectory, file);
                            }

                            if (FileUtils.Exists(file))
                            {
                                srcs.Add(file);

                                // remove last added option
                                onlyOptions.RemoveAt(onlyOptions.Count - 1);
                                srcsOptions.Add(full);
                                continue;
                            }
                        }
                        if (full.StartsWith("/I"))
                        {
                            var d = ArgumentUtils.MakeWindowsPath(full.Substring(2));
                            if (d == ".")
                            {
                                d = WorkingDirectory;
                            }
                            if (d == "..")
                            {
                                d = Path.GetDirectoryName(WorkingDirectory);
                            }

                            if (!Path.IsPathRooted(d))
                            {
                                d = Path.Combine(WorkingDirectory, d);
                            }

                            if (Directory.Exists(d))
                            {
                                cliincs.Add(d);
                                continue;
                            }
                        }
                        #endregion

                        break;
                    }
                    #endregion
                }

                if (SingleSource)
                {
                    var defaultObj = ArgumentUtils.TargetObject(Path.GetFileNameWithoutExtension(SingleSourceFile));
                    if (ObjectTarget == null)
                    {
                        if (Path.IsPathRooted(defaultObj))
                        {
                            ObjectTarget = defaultObj;
                        }
                        else
                        {
                            ObjectTarget = Path.Combine(WorkingDirectory, defaultObj);
                        }
                    }

                    if (ObjectTargetIsFolder)
                    {
                        ObjectTarget = Path.Combine(ObjectTarget, defaultObj);
                    }

                    if (GeneratePdb)
                    {
                        if (Settings.ConvertObjPdbToZ7)
                        {
                            Logging.Emit("converting pdb request to Z7 embedded debug {0}:{1}", WorkingDirectory, Path.GetFileName(ObjectTarget));
                            // append /Z7 to the arg list and don't generate a pdb
                            var newargs = new List <string>();
                            foreach (var a in args)
                            {
                                if (!(a.StartsWith("/Zi") || a.StartsWith("/Fd")))
                                {
                                    newargs.Add(a);
                                }
                            }
                            newargs.Add("/Z7");
                            AttemptPdb       = false;
                            PdbFile          = null;
                            GeneratePdb      = false;
                            PdbExistsAlready = false;
                            args             = newargs.ToArray();
                        }
                    }

                    if (GeneratePdb)
                    {
                        return(NotSupported("PDB file requested"));
                    }
                }
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e);
                return(NotSupported("option parser exception '{0}'", e));
            }
            CompileArgs = args.ToArray();
            return(IsSupported);
        }
Exemple #2
0
 string getFullOption(string arg)
 {
     arg = arg.Trim('"', '\'');
     return(ArgumentUtils.CanonicalArgument(arg));
 }