/// <summary>
 /// Initializes a new instance of the <see cref="ServiceArguments"/> class, explicitly specifying the arguments.
 /// Typically used in tests.
 /// </summary>
 /// <param name="serviceStartupMode">Optional. The service startup mode to use.</param>
 /// <param name="consoleOutputMode">Optional. The console output mode to use.</param>
 /// <param name="basePortOverride">Optional. The base port override to use, or null to not override the base port.</param>
 public ServiceArguments(ServiceStartupMode serviceStartupMode = ServiceStartupMode.Unspecified,
                         ConsoleOutputMode consoleOutputMode   = ConsoleOutputMode.Unspecified,
                         int?basePortOverride     = null, string instanceName = null,
                         int?shutdownWhenPidExits = null, int?slotNumber      = null, int?shutdownWaitTimeSec = null, int?serviceDrainTimeSec = null)
 {
     ServiceStartupMode   = serviceStartupMode;
     ConsoleOutputMode    = consoleOutputMode;
     BasePortOverride     = basePortOverride;
     InstanceName         = instanceName;
     ShutdownWhenPidExits = shutdownWhenPidExits;
     SlotNumber           = slotNumber;
     OnStopWaitTimeSec    = shutdownWaitTimeSec;
     ApplyDefaults();
 }
示例#2
0
        private static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            ConsoleOutputMode consoleOutputMode = new ConsoleOutputMode();
            ConsoleInputMode  consoleInputMode  = new ConsoleInputMode();

            DisplayObject("ConsoleOutputMode", consoleOutputMode);

            consoleOutputMode.IsEnableVirtualTerminalProcessing = false;
            consoleOutputMode.IsDisabledNewLineAutoReturn       = true;

            string line = new string('=', 120);

            Console.WriteLine(line);
            Console.Write(line);

            DisplayObject("ConsoleOutputMode", consoleOutputMode);

            Pause.QuickDisplay();
        }
示例#3
0
 public UsageException()
 {
     m_outputMode = ConsoleOutputMode.Console;
 }
示例#4
0
 public UsageException(string message, Exception innerException)
     : base(message, innerException)
 {
     m_outputMode = ConsoleOutputMode.Console;
 }
示例#5
0
 protected UsageException(SerializationInfo info, StreamingContext context)
     : base(info, context)
 {
     if (info == null)
     {
         throw new ArgumentException(StringMgr.GetString("InternalCompilerError"));
     }
     m_outputMode = ConsoleOutputMode.Console;
 }
示例#6
0
 public UsageException(ConsoleOutputMode outputMode, string format, params object[] args)
     : base(StringMgr.GetString(format, args))
 {
     m_outputMode = outputMode;
 }
示例#7
0
 public UsageException(ConsoleOutputMode outputMode)
     : base(string.Empty)
 {
     m_outputMode = outputMode;
 }
示例#8
0
        private void ProcessArgs(string[] args)
        {
            List<string> inputFiles = new List<string>();
            bool levelSpecified = false;
            bool renamingSpecified = false;
            for (int ndx = 0; ndx < args.Length; ++ndx)
            {
                // parameter switch
                string thisArg = args[ndx];
                if (thisArg.Length > 1
                  && (thisArg.StartsWith("-", StringComparison.Ordinal) // this is a normal hyphen (minus character)
                  || thisArg.StartsWith("–", StringComparison.Ordinal) // this character is what Word will convert a hyphen to
                  || thisArg.StartsWith("/", StringComparison.Ordinal)))
                {
                    // general switch syntax is -switch:param
                    string[] parts = thisArg.Substring(1).Split(':');
                    string switchPart = parts[0].ToUpper(CultureInfo.InvariantCulture);
                    string paramPart = (parts.Length == 1 ? null : parts[1].ToUpper(CultureInfo.InvariantCulture));

                    // switch off the switch part
                    switch (switchPart)
                    {
                        case "ANALYZE":
                        case "A": // <-- old-style
                            // ignore any arguments
                            m_analyze = true;
                            break;

                        case "ASPNET":
                            BooleanSwitch(paramPart, switchPart, false, out m_allowAspNet);
                            break;

                        case "CC":
                            BooleanSwitch(paramPart, switchPart, true, out m_ignoreConditionalCompilation);

                            // actually, the flag is the opposite of the member -- turn CC ON and we DON'T
                            // want to ignore them; turn CC OFF and we DO want to ignore them
                            m_ignoreConditionalCompilation = !m_ignoreConditionalCompilation;

                            JavaScriptOnly();
                            break;

                        case "CLOBBER":
                            // just putting the clobber switch on the command line without any arguments
                            // is the same as putting -clobber:true and perfectly valid.
                            BooleanSwitch(paramPart, switchPart, true, out m_clobber);
                            break;

                        case "COLORS":
                            // two options: hex or names
                            if (paramPart == "HEX")
                            {
                                m_colorNames = CssColor.Hex;
                            }
                            else if (paramPart == "STRICT")
                            {
                                m_colorNames = CssColor.Strict;
                            }
                            else if (paramPart == "MAJOR")
                            {
                                m_colorNames = CssColor.Major;
                            }
                            else if (paramPart == null)
                            {
                                throw new UsageException(m_outputMode, "SwitchRequiresArg", switchPart);
                            }
                            else
                            {
                                throw new UsageException(m_outputMode, "InvalidSwitchArg", paramPart, switchPart);
                            }
                            CssOnly();
                            break;

                        case "COMMENTS":
                            // four options for css: none, all, important, or hacks
                            // two options for js: none, important
                            // (default is important)
                            if (paramPart == "NONE")
                            {
                                m_cssComments = CssComment.None;
                                m_preserveImportantComments = false;
                            }
                            else if (paramPart == "ALL")
                            {
                                m_cssComments = CssComment.All;
                                CssOnly();
                            }
                            else if (paramPart == "IMPORTANT")
                            {
                                m_cssComments = CssComment.Important;
                                m_preserveImportantComments = true;
                            }
                            else if (paramPart == "HACKS")
                            {
                                m_cssComments = CssComment.Hacks;
                                CssOnly();
                            }
                            else if (paramPart == null)
                            {
                                throw new UsageException(m_outputMode, "SwitchRequiresArg", switchPart);
                            }
                            else
                            {
                                throw new UsageException(m_outputMode, "InvalidSwitchArg", paramPart, switchPart);
                            }

                            break;

                        case "CSS":
                            // if we've already declared JS, then error
                            CssOnly();
                            break;

                        case "DEBUG":
                            // see if the param part is a comma-delimited list
                            if (paramPart.IndexOf(',') >= 0)
                            {
                                // we have a comma-separated list.
                                // the first item is the flag (if any), and the rest (if any) are the "debug" lookup names
                                // use parts[1] rather than paramParts because paramParts has been forced to upper-case
                                var items = parts[1].Split(',');

                                // use the first value as the debug boolean switch
                                BooleanSwitch(items[0], switchPart, true, out m_stripDebugStatements);

                                // and the rest as names.
                                // if we haven't created the list yet, do it now
                                if (m_debugLookups == null)
                                {
                                    m_debugLookups = new List<string>();
                                }

                                // start with index 1, since index 0 was the flag
                                for (var item = 1; item < items.Length; ++item)
                                {
                                    // get the identifier that was specified
                                    var identifier = items[item];

                                    // a blank identifier is okay -- we just ignore it
                                    if (!string.IsNullOrEmpty(identifier))
                                    {
                                        // but if it's not blank, it better be a valid JavaScript identifier or member chain
                                        if (identifier.IndexOf('.') > 0)
                                        {
                                            // it's a member chain -- check that each part is a valid JS identifier
                                            var names = identifier.Split('.');
                                            foreach (var name in names)
                                            {
                                                if (!JSScanner.IsValidIdentifier(name))
                                                {
                                                    throw new UsageException(m_outputMode, "InvalidSwitchArg", name, switchPart);
                                                }
                                            }
                                        }
                                        else
                                        {
                                            // no dot -- just an identifier
                                            if (!JSScanner.IsValidIdentifier(identifier))
                                            {
                                                throw new UsageException(m_outputMode, "InvalidSwitchArg", identifier, switchPart);
                                            }
                                        }

                                        // don't add duplicates
                                        if (!m_debugLookups.Contains(identifier))
                                        {
                                            m_debugLookups.Add(identifier);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                // no commas -- just use the entire param part as the boolean value.
                                // just putting the debug switch on the command line without any arguments
                                // is the same as putting -debug:true and perfectly valid.
                                BooleanSwitch(paramPart, switchPart, true, out m_stripDebugStatements);
                            }

                            // actually the inverse - a TRUE on the -debug switch means we DON'T want to
                            // strip debug statements, and a FALSE means we DO want to strip them
                            m_stripDebugStatements = !m_stripDebugStatements;

                            // this is a JS-only switch
                            JavaScriptOnly();
                            break;

                        case "DEFINE":
                            // the parts can be a comma-separate list of identifiers
                            if (string.IsNullOrEmpty(paramPart))
                            {
                                throw new UsageException(m_outputMode, "SwitchRequiresArg", switchPart);
                            }

                            // use paramPart because it has been forced to upper-case and these identifiers are
                            // supposed to be case-insensitive
                            foreach (string upperCaseName in paramPart.Split(','))
                            {
                                // better be a valid JavaScript identifier
                                if (!JSScanner.IsValidIdentifier(upperCaseName))
                                {
                                    throw new UsageException(m_outputMode, "InvalidSwitchArg", upperCaseName, switchPart);
                                }

                                // if we haven't created the list yet, do it now
                                if (m_defines == null)
                                {
                                    m_defines = new List<string>();
                                }

                                // don't add duplicates
                                if (!m_defines.Contains(upperCaseName))
                                {
                                    m_defines.Add(upperCaseName);
                                }
                            }

                            break;

                        case "ECHO":
                        case "I": // <-- old style
                            // ignore any arguments
                            m_echoInput = true;
                            // -pretty and -echo are not compatible
                            if (m_prettyPrint)
                            {
                                throw new UsageException(m_outputMode, "PrettyAndEchoArgs");
                            }
                            break;

                        case "ENC":
                            // the encoding is the next argument
                            if (ndx >= args.Length - 1)
                            {
                                // must be followed by an encoding
                                throw new UsageException(m_outputMode, "EncodingArgMustHaveEncoding", switchPart);
                            }
                            string encoding = args[++ndx];

                            // whether this is an in or an out encoding
                            if (paramPart == "IN")
                            {
                                // save the name -- we'll create the encoding later because we may
                                // override it on a file-by-file basis in an XML file
                                m_encodingInputName = encoding;
                            }
                            else if (paramPart == "OUT")
                            {
                                // just save the name -- we'll create the encoding later because we need
                                // to know whether we are JS or CSS to pick the right encoding fallback
                                m_encodingOutputName = encoding;
                            }
                            else if (paramPart == null)
                            {
                                throw new UsageException(m_outputMode, "SwitchRequiresArg", switchPart);
                            }
                            else
                            {
                                throw new UsageException(m_outputMode, "InvalidSwitchArg", paramPart, switchPart);
                            }
                            break;

                        case "EVALS":
                            // three options: ignore, make immediate scope safe, or make all scopes safe
                            if (paramPart == "IGNORE")
                            {
                                m_evalTreatment = EvalTreatment.Ignore;
                            }
                            else if (paramPart == "IMMEDIATE")
                            {
                                m_evalTreatment = EvalTreatment.MakeImmediateSafe;
                            }
                            else if (paramPart == "SAFEALL")
                            {
                                m_evalTreatment = EvalTreatment.MakeAllSafe;
                            }
                            else if (paramPart == null)
                            {
                                throw new UsageException(m_outputMode, "SwitchRequiresArg", switchPart);
                            }
                            else
                            {
                                throw new UsageException(m_outputMode, "InvalidSwitchArg", paramPart, switchPart);
                            }

                            // this is a JS-only switch
                            JavaScriptOnly();
                            break;

                        case "EXPR":
                            // two options: minify (default) or raw
                            if (paramPart == "MINIFY")
                            {
                                m_minifyExpressions = true;
                            }
                            else if (paramPart == "RAW")
                            {
                                m_minifyExpressions = false;
                            }
                            else
                            {
                                throw new UsageException(m_outputMode, "InvalidSwitchArg", paramPart, switchPart);
                            }

                            CssOnly();
                            break;

                        case "FNAMES":
                            // three options: 
                            // LOCK    -> keep all NFE names, don't allow renaming of function names
                            // KEEP    -> keep all NFE names, but allow function names to be renamed
                            // ONLYREF -> remove unref'd NFE names, allow function named to be renamed (DEFAULT)
                            if (paramPart == "LOCK")
                            {
                                // don't remove function expression names
                                m_removeFunctionExpressionNames = false;

                                // and preserve the names (don't allow renaming)
                                m_preserveFunctionNames = true;
                            }
                            else if (paramPart == "KEEP")
                            {
                                // don't remove function expression names
                                m_removeFunctionExpressionNames = false;

                                // but it's okay to rename them
                                m_preserveFunctionNames = false;
                            }
                            else if (paramPart == "ONLYREF")
                            {
                                // remove function expression names if they aren't referenced
                                m_removeFunctionExpressionNames = true;

                                // and rename them if we so desire
                                m_preserveFunctionNames = false;
                            }
                            else if (paramPart == null)
                            {
                                throw new UsageException(m_outputMode, "SwitchRequiresArg", switchPart);
                            }
                            else
                            {
                                throw new UsageException(m_outputMode, "InvalidSwitchArg", paramPart, switchPart);
                            }

                            // this is a JS-only switch
                            JavaScriptOnly();
                            break;

                        case "GLOBAL":
                        case "G": // <-- old style
                            // the parts can be a comma-separate list of identifiers
                            if (string.IsNullOrEmpty(paramPart))
                            {
                                throw new UsageException(m_outputMode, "SwitchRequiresArg", switchPart);
                            }

                            // use parts[1] rather than paramParts because paramParts has been forced to upper-case
                            foreach (string global in parts[1].Split(','))
                            {
                                // better be a valid JavaScript identifier
                                if (!JSScanner.IsValidIdentifier(global))
                                {
                                    throw new UsageException(m_outputMode, "InvalidSwitchArg", global, switchPart);
                                }

                                // if we haven't created the list yet, do it now
                                if (m_globals == null)
                                {
                                    m_globals = new List<string>();
                                }

                                // don't add duplicates
                                if (!m_globals.Contains(global))
                                {
                                    m_globals.Add(global);
                                }
                            }

                            // this is a JS-only switch
                            JavaScriptOnly();
                            break;

                        case "HELP":
                        case "?":
                            // just show usage
                            throw new UsageException(m_outputMode);

                        case "INLINE":
                            // set safe for inline to the same boolean.
                            // if no param part, will return false (indicating the default)
                            // if invalid param part, will throw error
                            if (!BooleanSwitch(paramPart, switchPart, true, out m_safeForInline))
                            {
                                throw new UsageException(m_outputMode, "SwitchRequiresArg", switchPart);
                            }

                            // this is a JS-only switch
                            JavaScriptOnly();
                            break;

                        case "JS":
                            // if we've already declared CSS, then error
                            JavaScriptOnly();
                            break;

                        case "KILL":
                            // optional integer switch argument
                            if (paramPart == null)
                            {
                                throw new UsageException(m_outputMode, "SwitchRequiresArg", switchPart);
                            }

                            // get the numeric portion
                            if (paramPart.StartsWith("0X", StringComparison.OrdinalIgnoreCase))
                            {
                                // it's hex -- convert the number after the "0x"
                                if (!long.TryParse(paramPart.Substring(2), NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out m_killSwitch))
                                {
                                    throw new UsageException(m_outputMode, "InvalidKillSwitchArg", paramPart);
                                }
                            }
                            else if (!long.TryParse(paramPart, NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture, out m_killSwitch))
                            {
                                throw new UsageException(m_outputMode, "InvalidKillSwitchArg", paramPart);
                            }

                            break;

                        case "LITERALS":
                            // two options: keep or combine
                            if (paramPart == "KEEP")
                            {
                                m_combineDuplicateLiterals = false;
                            }
                            else if (paramPart == "COMBINE")
                            {
                                m_combineDuplicateLiterals = true;
                            }
                            else if (paramPart == "EVAL")
                            {
                                m_evalLiteralExpressions = true;
                            }
                            else if (paramPart == "NOEVAL")
                            {
                                m_evalLiteralExpressions = false;
                            }
                            else if (paramPart == null)
                            {
                                throw new UsageException(m_outputMode, "SwitchRequiresArg", switchPart);
                            }
                            else
                            {
                                throw new UsageException(m_outputMode, "InvalidSwitchArg", paramPart, switchPart);
                            }

                            // this is a JS-only switch
                            JavaScriptOnly();
                            break;

                        case "MAC":
                            // optional boolean switch
                            // no arg is valid scenario (default is true)
                            BooleanSwitch(paramPart, switchPart, true, out m_macSafariQuirks);

                            // this is a JS-only switch
                            JavaScriptOnly();
                            break;

                        case "NEW":
                            // two options: keep and collapse
                            if (paramPart == "KEEP")
                            {
                                m_collapseToLiteral = false;
                            }
                            else if (paramPart == "COLLAPSE")
                            {
                                m_collapseToLiteral = true;
                            }
                            else if (paramPart == null)
                            {
                                throw new UsageException(m_outputMode, "SwitchRequiresArg", switchPart);
                            }
                            else
                            {
                                throw new UsageException(m_outputMode, "InvalidSwitchArg", paramPart, switchPart);
                            }

                            // this is a JS-only switch
                            JavaScriptOnly();
                            break;

                        case "NFE": // <-- deprecate; use FNAMES option instead
                            if (paramPart == "KEEPALL")
                            {
                                m_removeFunctionExpressionNames = false;
                            }
                            else if (paramPart == "ONLYREF")
                            {
                                m_removeFunctionExpressionNames = true;
                            }
                            else if (paramPart == null)
                            {
                                throw new UsageException(m_outputMode, "SwitchRequiresArg", switchPart);
                            }
                            else
                            {
                                throw new UsageException(m_outputMode, "InvalidSwitchArg", paramPart, switchPart);
                            }

                            // this is a JS-only switch
                            JavaScriptOnly();
                            break;

                        case "NORENAME":
                            // the parts can be a comma-separate list of identifiers
                            if (string.IsNullOrEmpty(paramPart))
                            {
                                throw new UsageException(m_outputMode, "SwitchRequiresArg", switchPart);
                            }

                            // use parts[1] rather than paramParts because paramParts has been forced to upper-case
                            foreach (string ident in parts[1].Split(','))
                            {
                                // better be a valid JavaScript identifier
                                if (!JSScanner.IsValidIdentifier(ident))
                                {
                                    throw new UsageException(m_outputMode, "InvalidSwitchArg", ident, switchPart);
                                }

                                // if we haven't created the list yet, do it now
                                if (m_noAutoRename == null)
                                {
                                    m_noAutoRename = new List<string>();
                                }

                                // don't add duplicates
                                if (!m_noAutoRename.Contains(ident))
                                {
                                    m_noAutoRename.Add(ident);
                                }
                            }

                            // this is a JS-only switch
                            JavaScriptOnly();
                            break;

                        case "OUT":
                        case "O": // <-- old style
                            // next argument is the output path
                            // cannot have two out arguments
                            if (!string.IsNullOrEmpty(m_outputFile))
                            {
                                throw new UsageException(m_outputMode, "MultipleOutputArg");
                            }
                            else if (ndx >= args.Length - 1)
                            {
                                throw new UsageException(m_outputMode, "OutputArgNeedsPath");
                            }
                            m_outputFile = args[++ndx];
                            break;

                        case "PPONLY":
                            // just putting the pponly switch on the command line without any arguments
                            // is the same as putting -pponly:true and perfectly valid.
                            BooleanSwitch(paramPart, switchPart, true, out m_preprocessOnly);

                            // this is a JS-only switch
                            JavaScriptOnly();
                            break;

                        case "PRETTY":
                        case "P": // <-- old style
                            m_prettyPrint = true;
                            // pretty-print and echo-input not compatible
                            if (m_echoInput)
                            {
                                throw new UsageException(m_outputMode, "PrettyAndEchoArgs");
                            }

                            // if renaming hasn't been specified yet, turn it off for prety-print
                            if (!renamingSpecified)
                            {
                                m_localRenaming = LocalRenaming.KeepAll;
                            }

                            // optional integer switch argument
                            if (paramPart != null)
                            {
                                // get the numeric portion
                                try
                                {
                                    // must be an integer value
                                    int indentSize = int.Parse(paramPart, CultureInfo.InvariantCulture);
                                    if (indentSize >= 0)
                                    {
                                        m_indentSize = indentSize;
                                    }
                                    else
                                    {
                                        throw new UsageException(m_outputMode, "InvalidTabSizeArg", paramPart);
                                    }
                                }
                                catch (FormatException e)
                                {
                                    Debug.WriteLine(e.ToString());
                                    throw new UsageException(m_outputMode, "InvalidTabSizeArg", paramPart);
                                }
                            }
                            break;

                        case "RENAME":
                            if (paramPart == null)
                            {
                                // there are no other parts after -rename
                                // the next argument should be a filename from which we can pull the
                                // variable renaming information
                                if (ndx >= args.Length - 1)
                                {
                                    // must be followed by an encoding
                                    throw new UsageException(m_outputMode, "RenameArgMissingParameterOrFilePath", switchPart);
                                }

                                // the renaming file is specified as the NEXT argument
                                string renameFilePath = args[++ndx];

                                // and it needs to exist
                                EnsureInputFileExists(renameFilePath);

                                // process the renaming file
                                ProcessRenamingFile(renameFilePath);
                            }
                            else if (paramPart.IndexOf('=') > 0)
                            {
                                // there is at least one equal sign -- treat this as a set of JS identifier
                                // pairs. split on commas -- multiple pairs can be specified
                                var paramPairs = parts[1].Split(',');
                                foreach (var paramPair in paramPairs)
                                {
                                    // split on the equal sign -- each pair needs to have an equal sige
                                    var pairParts = paramPair.Split('=');
                                    if (pairParts.Length == 2)
                                    {
                                        // there is an equal sign. The first part is the source name and the
                                        // second part is the new name to which to rename those entities.
                                        string fromIdentifier = pairParts[0];
                                        string toIdentifier = pairParts[1];
                                
                                        // make sure both parts are valid JS identifiers
                                        var fromIsValid = JSScanner.IsValidIdentifier(fromIdentifier);
                                        var toIsValid = JSScanner.IsValidIdentifier(toIdentifier);
                                        if (fromIsValid && toIsValid)
                                        {
                                            // create the map if it hasn't been created yet.
                                            if (m_renameMap == null)
                                            {
                                                m_renameMap = new Dictionary<string, string>();
                                            }

                                            m_renameMap.Add(fromIdentifier, toIdentifier);
                                        }
                                        else if (fromIsValid)
                                        {
                                            // the toIdentifier is invalid!
                                            throw new UsageException(m_outputMode, "InvalidRenameToIdentifier", toIdentifier);
                                        }
                                        else if (toIsValid)
                                        {
                                            // the fromIdentifier is invalid!
                                            throw new UsageException(m_outputMode, "InvalidRenameFromIdentifier", fromIdentifier);
                                        }
                                        else
                                        {
                                            // NEITHER of the rename parts are valid identifiers! BOTH are required to
                                            // be valid JS identifiers
                                            throw new UsageException(m_outputMode, "InvalidRenameIdentifiers", fromIdentifier, toIdentifier);
                                        }
                                    }
                                    else
                                    {
                                        // either zero or more than one equal sign. Invalid.
                                        throw new UsageException(m_outputMode, "InvalidSwitchArg", paramPart, switchPart);
                                    }
                                }
                            }
                            else
                            {
                                // no equal sign; just a plain option
                                // three options: all, localization, none
                                if (paramPart == "ALL")
                                {
                                    m_localRenaming = LocalRenaming.CrunchAll;

                                    // automatic renaming strategy has been specified by this option
                                    renamingSpecified = true;
                                }
                                else if (paramPart == "LOCALIZATION")
                                {
                                    m_localRenaming = LocalRenaming.KeepLocalizationVars;

                                    // automatic renaming strategy has been specified by this option
                                    renamingSpecified = true;
                                }
                                else if (paramPart == "NONE")
                                {
                                    m_localRenaming = LocalRenaming.KeepAll;

                                    // automatic renaming strategy has been specified by this option
                                    renamingSpecified = true;
                                }
                                else if (paramPart == "NOPROPS")
                                {
                                    // manual-renaming does not change property names
                                    m_renameProperties = false;
                                }
                                else
                                {
                                    throw new UsageException(m_outputMode, "InvalidSwitchArg", paramPart, switchPart);
                                }
                            }

                            // this is a JS-only switch
                            JavaScriptOnly();
                            break;

                        case "REORDER":
                            // default is true
                            BooleanSwitch(paramPart, switchPart, true, out m_reorderScopeDeclarations);

                            // this is a JS-only switch
                            JavaScriptOnly();
                            break;

                        case "RES":
                        case "R": // <-- old style
                            // -res:id path
                            // can't specify -R more than once
                            if (!string.IsNullOrEmpty(m_resourceFile))
                            {
                                throw new UsageException(m_outputMode, "MultipleResourceArgs");
                            }
                            // must have resource file on next parameter
                            if (ndx >= args.Length - 1)
                            {
                                throw new UsageException(m_outputMode, "ResourceArgNeedsPath");
                            }

                            // the resource file name is the NEXT argument
                            m_resourceFile = args[++ndx];
                            EnsureInputFileExists(m_resourceFile);

                            // check the extension to see if the resource file is a supported file type.
                            switch (Path.GetExtension(m_resourceFile).ToUpper(CultureInfo.InvariantCulture))
                            {
                                case ".RESOURCES":
                                case ".RESX":
                                    if (!string.IsNullOrEmpty(paramPart))
                                    {
                                        // reset paramPart to not be the forced-to-upper version
                                        paramPart = parts[1];

                                        // must be valid JS identifier
                                        if (JSScanner.IsValidIdentifier(paramPart))
                                        {
                                            // save the name portion
                                            m_resourceObjectName = paramPart;
                                        }
                                        else
                                        {
                                            throw new UsageException(m_outputMode, "ResourceArgInvalidName", paramPart);
                                        }
                                    }
                                    else
                                    {
                                        // no name specified -- use Strings as the default
                                        // (not recommended)
                                        m_resourceObjectName = c_defaultResourceObjectName;
                                    }
                                    break;

                                default:
                                    // not a supported resource file type
                                    throw new UsageException(m_outputMode, "ResourceArgInvalidType");
                            }
                            break;

                        case "SILENT":
                        case "S": // <-- old style
                            // ignore any argument part
                            m_outputMode = ConsoleOutputMode.Silent;
                            break;

                        case "TERM":
                            // optional boolean argument, defaults to true
                            BooleanSwitch(paramPart, switchPart, true, out m_terminateWithSemicolon);
                            break;

                        case "UNUSED":
                            // two options: keep and remove
                            if (paramPart == "KEEP")
                            {
                                m_removeUnneededCode = false;
                            }
                            else if (paramPart == "REMOVE")
                            {
                                m_removeUnneededCode = true;
                            }
                            else if (paramPart == null)
                            {
                                throw new UsageException(m_outputMode, "SwitchRequiresArg", switchPart);
                            }
                            else
                            {
                                throw new UsageException(m_outputMode, "InvalidSwitchArg", paramPart, switchPart);
                            }

                            // this is a JS-only switch
                            JavaScriptOnly();
                            break;

                        case "WARN":
                        case "W": // <-- old style
                            if (string.IsNullOrEmpty(paramPart))
                            {
                                // just "-warn" without anything else means all errors and warnings
                                m_warningLevel = int.MaxValue;
                            }
                            else
                            {
                                try
                                {
                                    // must be an unsigned integer value
                                    m_warningLevel = int.Parse(paramPart, NumberStyles.None, CultureInfo.InvariantCulture);
                                }
                                catch (FormatException e)
                                {
                                    Debug.WriteLine(e.ToString());
                                    throw new UsageException(m_outputMode, "InvalidWarningArg", paramPart);
                                }
                            }
                            levelSpecified = true;
                            break;

                        case "XML":
                        case "X": // <-- old style
                            if (!string.IsNullOrEmpty(m_xmlInputFile))
                            {
                                throw new UsageException(m_outputMode, "MultipleXmlArgs");
                            }
                            // cannot have input files
                            if (inputFiles.Count > 0)
                            {
                                throw new UsageException(m_outputMode, "XmlArgHasInputFiles");
                            }

                            if (ndx >= args.Length - 1)
                            {
                                throw new UsageException(m_outputMode, "XmlArgNeedsPath");
                            }

                            // the xml file name is the NEXT argument
                            m_xmlInputFile = args[++ndx];

                            // and it must exist
                            EnsureInputFileExists(m_xmlInputFile);
                            break;

                        // Backward-compatibility switches different from new switches

                        case "D":
                            // equivalent to -debug:true (default behavior)
                            m_stripDebugStatements = true;
                            JavaScriptOnly();
                            break;

                        case "E":
                        case "EO":
                            // equivalent to -enc:out <encoding>
                            if(parts.Length < 2)
                            {
                                // must be followed by an encoding
                                throw new UsageException(m_outputMode, "EncodingArgMustHaveEncoding", switchPart);
                            }

                            // just save the name -- we'll create the encoding later because we need
                            // to know whether we are JS or CSS to pick the right encoding fallback
                            m_encodingOutputName = parts[1];
                            break;

                        case "EI":
                            // equivalent to -enc:in <encoding>
                            if (parts.Length < 2)
                            {
                                // must be followed by an encoding
                                throw new UsageException(m_outputMode, "EncodingArgMustHaveEncoding", switchPart);
                            }

                            // save the name
                            m_encodingInputName = parts[1];
                            break;

                        case "H":
                            // equivalent to -rename:all -unused:remove (default behavior)
                            m_localRenaming = LocalRenaming.CrunchAll;
                            m_removeUnneededCode = true;
                            JavaScriptOnly();

                            // renaming is specified by this option
                            renamingSpecified = true;
                            break;

                        case "HL":
                            // equivalent to -rename:localization -unused:remove
                            m_localRenaming = LocalRenaming.KeepLocalizationVars;
                            m_removeUnneededCode = true;
                            JavaScriptOnly();

                            // renaming is specified by this option
                            renamingSpecified = true;
                            break;

                        case "HC":
                            // equivalent to -literals:combine -rename:all -unused:remove
                            m_combineDuplicateLiterals = true;
                            goto case "H";

                        case "HLC":
                        case "HCL":
                            // equivalent to -literals:combine -rename:localization -unused:remove
                            m_combineDuplicateLiterals = true;
                            goto case "HL";

                        case "J":
                            // equivalent to -evals:ignore (default behavior)
                            m_evalTreatment = EvalTreatment.Ignore;
                            JavaScriptOnly();
                            break;

                        case "K":
                            // equivalent to -inline:true (default behavior)
                            m_safeForInline = true;
                            JavaScriptOnly();
                            break;

                        case "L":
                            // equivalent to -new:keep (default is collapse)
                            m_collapseToLiteral = false;
                            JavaScriptOnly();
                            break;

                        case "M":
                            // equivalent to -mac:true (default behavior)
                            m_macSafariQuirks = true;
                            JavaScriptOnly();
                            break;

                        case "Z":
                            // equivalent to -term:true (default is false)
                            m_terminateWithSemicolon = true;
                            break;

                        case "CL":
                        case "CS":
                        case "V":
                        case "3":
                            // ignore -- we don't use these switches anymore.
                            // but for backwards-compatibility, don't throw an error.
                            break;

                        // end backward-compatible section

                        default:
                            throw new UsageException(m_outputMode, "InvalidArgument", args[ndx]);
                    }
                }
                else // must be an input file!
                {
                    // cannot coexist with XML option
                    if (!string.IsNullOrEmpty(m_xmlInputFile))
                    {
                        throw new UsageException(m_outputMode, "XmlArgHasInputFiles");
                    }

                    // shortcut
                    string fileName = args[ndx];

                    // make sure it exists
                    EnsureInputFileExists(fileName);

                    // we don't want duplicates
                    if (!inputFiles.Contains(fileName))
                    {
                        inputFiles.Add(fileName);
                    }
                }
            }

            // if we didn't specify the type (JS or CSS), then look at the extension of
            // the input files and see if we can divine what we are
            foreach (string path in inputFiles)
            {
                string extension = Path.GetExtension(path).ToUpperInvariant();
                switch (m_inputType)
                {
                    case InputType.Unknown:
                        // we don't know yet. If the extension is JS or CSS set to the
                        // appropriate input type
                        if (extension == ".JS")
                        {
                            m_inputType = InputType.JavaScript;
                        }
                        else if (extension == ".CSS")
                        {
                            m_inputType = InputType.Css;
                        }
                        break;

                    case InputType.JavaScript:
                        // we know we are JS -- if we find a CSS file, throw an error
                        if (extension == ".CSS")
                        {
                            throw new UsageException(m_outputMode, "ConflictingInputType");
                        }
                        break;

                    case InputType.Css:
                        // we know we are CSS -- if we find a JS file, throw an error
                        if (extension == ".JS")
                        {
                            throw new UsageException(m_outputMode, "ConflictingInputType");
                        }
                        break;
                }
            }

            // if we have input files but we don't know the type by now, 
            // then throw an exception
            if (inputFiles.Count > 0 && m_inputType == InputType.Unknown)
            {
                throw new UsageException(m_outputMode, "UnknownInputType");
            }

            m_inputFiles = inputFiles.ToArray();

            // if analyze was specified but no warning level, jack up the warning level
            // so everything is shown
            if (m_analyze && !levelSpecified)
            {
                // we want to analyze, and we didn't specify a particular warning level.
                // go ahead and report all errors
                m_warningLevel = int.MaxValue;
            }
        }
 [DllImport("Kernel32.dll")] private static extern bool SetConsoleMode(IntPtr hConsoleOutput, ConsoleOutputMode mode);