/// <summary> /// Parses the given command line and returns the arguments form is. /// The command line is expected to be without the command name. /// </summary> public static SimpleList <Pair <string, string> > GetArgumentsFromCommandLine(string commandLineWithoutCommand) { commandLineWithoutCommand = commandLineWithoutCommand.Trim(); var result = SList.Create <Pair <string, string> >(3); var builder = new StringBuilder(commandLineWithoutCommand.Length); var argName = string.Empty; var argValue = string.Empty; const int lookForArgState = 0; const int readArgNameState = 1; const int readArgValueState = 2; int currentState = lookForArgState; // If it don't start with the argument prefix, it means that the parameter has no name, just value if (!commandLineWithoutCommand.StartsWith(ArgumentPrefix.ToString())) { currentState = readArgValueState; } var onQuote = false; var ignoreNextSpecial = false; for (int i = 0; i < commandLineWithoutCommand.Length; i++) { var letter = commandLineWithoutCommand[i]; // Specials var isEmpty = letter == ' ' && !ignoreNextSpecial; var isQuote = letter == '"' && !ignoreNextSpecial; var isBackSlash = letter == '\\' && !ignoreNextSpecial; var isArgPrefix = letter == ArgumentPrefix && !ignoreNextSpecial; ignoreNextSpecial = false; if (isQuote) { onQuote = !onQuote; continue; } else if (isBackSlash) { ignoreNextSpecial = true; continue; } if (onQuote) { ignoreNextSpecial = true; } switch (currentState) { case lookForArgState: if (isArgPrefix) { currentState = readArgNameState; } break; case readArgNameState: // if there's a space after the start of a arg, ignore the space if (isEmpty && builder.Length == 0) { continue; } if (isEmpty) { argName = builder.ToString(); TextUtil.ClearBuilder(builder); currentState = readArgValueState; argValue = string.Empty; } else { builder.Append(letter); } break; case readArgValueState: if (isArgPrefix) { argValue = builder.ToString(); TextUtil.ClearBuilder(builder); var pair = CreateArgPair(argName, argValue); SList.Add(result, pair); argName = string.Empty; argValue = string.Empty; currentState = readArgNameState; } else { builder.Append(letter); } break; } } // Process what might have been left on the command line switch (currentState) { case lookForArgState: argName = string.Empty; argValue = string.Empty; break; case readArgNameState: argName = builder.ToString(); break; case readArgValueState: argValue = builder.ToString(); break; } // We can arguments with empty names but values or with empty values but names if (!(string.IsNullOrEmpty(argName) && string.IsNullOrEmpty(argValue))) { var finalPair = CreateArgPair(argName, argValue); SList.Add(result, finalPair); } return(result); }
/// <summary> /// Returns the directory at the given path. Returns null if did not found a dir. /// </summary> public static HashDir FindDirByPath(string path) { if (PathUtil.GetPathType(path) != PathType.Folder) { return(null); } var data = DataHolder.DeviceData.CurrentDevice.FileSystem; HashDir currentDir; // If a path starts with the separator, it means it starts on the root folder if (path.StartsWith(PathUtil.PathSeparator)) { currentDir = data.RootDir; // remove the path separator because we are already on the root folder path = path.Remove(0, 1); } else { currentDir = data.CurrentDir; } var builder = new StringBuilder(path.Length); for (int i = 0; i < path.Length; i++) { var current = path[i]; if (current == PathUtil.PathSeparator[0]) { currentDir = ProcessPathPart(currentDir, builder.ToString()); TextUtil.ClearBuilder(builder); // if currentDir is null, it's a invalid path if (currentDir == null) { return(null); } } else { builder.Append(current); } } // If there's still something to process // this can happen if the path did NOT ended in a path separator if (builder.Length > 0) { currentDir = ProcessPathPart(currentDir, builder.ToString()); TextUtil.ClearBuilder(builder); } if (currentDir != null) { if (!IsDirAvaibale(currentDir)) { return(null); } } return(currentDir); }