in AjaxMin/MainClass.cs [321:649]
private void OnUnknownParameter(object sender, UnknownParameterEventArgs ea)
{
bool flag;
if (ea.SwitchPart != null)
{
// see if the switch is okay
switch (ea.SwitchPart)
{
case "CONFIG":
if (ea.ParameterPart == null)
{
throw new NotSupportedException(AjaxMin.InvalidSwitchArg.FormatInvariant(ea.SwitchPart, ea.ParameterPart));
}
m_configuration = ea.ParameterPart;
break;
case "ECHO":
case "I": // <-- old style
// ignore any arguments
m_echoInput = true;
// -pretty and -echo are not compatible
if (m_switchParser.AnalyzeMode)
{
throw new NotSupportedException(AjaxMin.PrettyAndEchoArgs);
}
break;
case "HELP":
case "?":
// just show usage
throw new NotSupportedException(string.Empty);
case "MAP":
if (!string.IsNullOrEmpty(m_xmlInputFile))
{
throw new NotSupportedException(AjaxMin.MapAndXmlArgs);
}
// next argument is the output path
// cannot have two map arguments
if (m_symbolMap != null && !string.IsNullOrEmpty(m_symbolMap.Path))
{
throw new NotSupportedException(AjaxMin.MultipleMapArg);
}
if (ea.Index >= ea.Arguments.Count - 1)
{
throw new NotSupportedException(AjaxMin.MapArgNeedsPath);
}
if (m_symbolMap == null)
{
m_symbolMap = new SymbolMap();
}
m_symbolMap.Path = ea.Arguments[++ea.Index];
// save the map implementation name, if any
if (!ea.ParameterPart.IsNullOrWhiteSpace())
{
m_symbolMap.Name = ea.ParameterPart;
}
break;
case "MAPROOT":
if (ea.Index >= ea.Arguments.Count - 1)
{
throw new NotSupportedException(AjaxMin.MapArgNeedsPath);
}
if (m_symbolMap == null)
{
m_symbolMap = new SymbolMap();
}
m_symbolMap.SourceRoot = ea.Arguments[++ea.Index];
break;
case "MAPSAFE":
if (m_symbolMap == null)
{
m_symbolMap = new SymbolMap();
}
if (ea.ParameterPart == null)
{
// default if specified is true
m_symbolMap.SafeHeader = true;
}
else
{
// there is. parse the boolean flag part
bool safeFlag;
if (SwitchParser.BooleanSwitch(ea.ParameterPart.ToUpperInvariant(), true, out safeFlag))
{
m_symbolMap.SafeHeader = safeFlag;
}
else
{
// invalid argument switch
throw new NotSupportedException(AjaxMin.InvalidArgument.FormatInvariant(ea.Arguments[ea.Index]));
}
}
break;
case "MODERN":
// some special settings for modern apps
// kill a couple optimizations
m_switchParser.JSSettings.KillSwitch |= (long)(
TreeModifications.CombineAdjacentExpressionStatements | TreeModifications.BooleanLiteralsToNotOperators);
// and skip the size-comparison output
m_skipSizeComparisons = true;
break;
case "NOSIZE":
// putting -nosize on the command line means we want to suppress the size-comparison
// analysis that we normally output
m_skipSizeComparisons = true;
break;
case "OUT":
case "O": // <-- old style
// cannot have two out arguments. If we've already seen an out statement,
// either we will have an output file or the no-output flag will be set
if (!string.IsNullOrEmpty(m_outputFile) || m_noOutput)
{
throw new NotSupportedException(AjaxMin.MultipleOutputArg);
}
else
{
// first instance of the -out switch.
// First check to see if there's a flag on the output switch
if (!string.IsNullOrEmpty(ea.ParameterPart))
{
// there is. See if it's a boolean false. If it is, then we want no output
// and we don't follow this switch with an output path.
bool outputSwitch;
if (SwitchParser.BooleanSwitch(ea.ParameterPart.ToUpperInvariant(), true, out outputSwitch))
{
// the no-output flag is the opposite of the boolean flag
m_noOutput = !outputSwitch;
}
else
{
// invalid argument switch
throw new NotSupportedException(AjaxMin.InvalidArgument.FormatInvariant(ea.Arguments[ea.Index]));
}
}
// if we still want output, then the next argument is the output path
if (!m_noOutput)
{
if (ea.Index >= ea.Arguments.Count - 1)
{
throw new NotSupportedException(AjaxMin.OutputArgNeedsPath);
}
m_outputFile = ea.Arguments[++ea.Index];
}
}
break;
case "RENAME":
if (ea.ParameterPart == 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 (ea.Index >= ea.Arguments.Count - 1)
{
// must be followed by an encoding
throw new NotSupportedException(AjaxMin.RenameArgMissingParameterOrFilePath.FormatInvariant(ea.SwitchPart));
}
// the renaming file is specified as the NEXT argument
string renameFilePath = ea.Arguments[++ea.Index];
// and it needs to exist
EnsureInputFileExists(renameFilePath);
// process the renaming file
ProcessRenamingFile(renameFilePath);
}
break;
case "RES":
case "R": // <-- old style
// -res:id path
// must have resource file on next parameter
if (ea.Index >= ea.Arguments.Count - 1)
{
throw new NotSupportedException(AjaxMin.ResourceArgNeedsPath);
}
// the resource file name is the NEXT argument
var resourceFile = ea.Arguments[++ea.Index];
EnsureInputFileExists(resourceFile);
// create the resource strings object from the file name
// will throw an error if not a supported file type
var resourceStrings = ProcessResourceFile(resourceFile);
// set the object name from the parameter part
if (!string.IsNullOrEmpty(ea.ParameterPart))
{
// must be a series of JS identifiers separated by dots: IDENT(.IDENT)*
// if any part doesn't match a JAvaScript identifier, throw an error
var parts = ea.ParameterPart.Split('.');
foreach (var part in parts)
{
if (!JSScanner.IsValidIdentifier(part))
{
throw new NotSupportedException(AjaxMin.ResourceArgInvalidName.FormatInvariant(part));
}
}
// if we got here, then everything is valid; save the name portion
resourceStrings.Name = ea.ParameterPart;
}
else
{
// no name specified -- use Strings as the default
// (not recommended)
resourceStrings.Name = c_defaultResourceObjectName;
}
// add it to the settings objects
m_switchParser.JSSettings.AddResourceStrings(resourceStrings);
m_switchParser.CssSettings.AddResourceStrings(resourceStrings);
break;
case "SILENT":
case "S": // <-- old style
// ignore any argument part
s_silentMode = true;
m_skipSizeComparisons = true;
break;
case "TIME":
case "TIMER":
case "TIMES":
// putting the timer switch on the command line without any arguments
// is the same as putting -timer:true and perfectly valid.
if (ea.ParameterPart == null)
{
m_outputTimer = true;
}
else if (SwitchParser.BooleanSwitch(ea.ParameterPart.ToUpperInvariant(), true, out flag))
{
m_outputTimer = flag;
}
else
{
throw new NotSupportedException(AjaxMin.InvalidSwitchArg.FormatInvariant(ea.SwitchPart, ea.ParameterPart));
}
break;
case "VERBOSE":
// ignore any argument part
s_silentMode = false;
break;
case "VERSION":
// the user just wants the version number
string version = Assembly.GetExecutingAssembly().GetName().Version.ToString();
// the special prefix tells the Usage method to not create an error
// out of the text and just output it as-is
s_silentMode = true;
throw new NotSupportedException(c_rawMessagePrefix + version);
case "XML":
case "X": // <-- old style
if (m_symbolMap != null)
{
throw new NotSupportedException(AjaxMin.MapAndXmlArgs);
}
if (!string.IsNullOrEmpty(m_xmlInputFile))
{
throw new NotSupportedException(AjaxMin.MultipleXmlArgs);
}
// cannot have input files from the command line
if (m_manifest != null)
{
throw new NotSupportedException(AjaxMin.XmlArgHasInputFiles);
}
if (ea.Index >= ea.Arguments.Count - 1)
{
throw new NotSupportedException(AjaxMin.XmlArgNeedsPath);
}
// the xml file name is the NEXT argument
m_xmlInputFile = ea.Arguments[++ea.Index];
// and it must exist
EnsureInputFileExists(m_xmlInputFile);
break;
case "CL":
case "CS":
case "V":
case "3":
// just ignore -- for backwards-compatibility
break;
default:
// truly an unknown parameter -- throw a usage error
throw new NotSupportedException(AjaxMin.InvalidArgument.FormatInvariant(ea.Arguments[ea.Index]));
}
}
else
{
// no switch -- then this must be an input file!
// cannot coexist with XML file
if (!string.IsNullOrEmpty(m_xmlInputFile))
{
throw new NotSupportedException(AjaxMin.XmlArgHasInputFiles);
}
ImplicitManifestOutputGroup.Inputs.Add(new InputFile { Path = ea.Arguments[ea.Index] });
}
}