Ejemplo n.º 1
0
//---------------------------------------------------------------------------
UnicodeString TFileMasks::ComposeMaskStr(
  TStrings * MasksStr, bool Directory)
{
  UnicodeString Result;
  UnicodeString ResultNoDirMask;
  for (intptr_t I = 0; I < MasksStr->GetCount(); ++I)
  {
    UnicodeString Str = MasksStr->GetString(I).Trim();
    if (!Str.IsEmpty())
    {
      for (intptr_t P = 1; P <= Str.Length(); P++)
      {
        if (Str.IsDelimiter(AllFileMasksDelimiters, P))
        {
          Str.Insert(Str[P], P);
          P++;
        }
      }

      UnicodeString StrNoDirMask;
      if (Directory)
      {
        StrNoDirMask = Str;
        Str = MakeDirectoryMask(Str);
      }
      else
      {
        while (Str.IsDelimiter(DirectoryMaskDelimiters, Str.Length()))
        {
          Str.SetLength(Str.Length() - 1);
        }
        StrNoDirMask = Str;
      }

      AddToList(Result, Str, FileMasksDelimiterStr);
      AddToList(ResultNoDirMask, StrNoDirMask, FileMasksDelimiterStr);
    }
  }

  // For directories, the above will add slash ay the end of masks,
  // breaking size and time masks and thus circumverting their validation.
  // This performes as hoc validation to cover the scenario.
  // For files this makes no difference, but no harm either
  TFileMasks Temp(Directory ? 1 : 0);
  Temp = ResultNoDirMask;

  return Result;
}
Ejemplo n.º 2
0
void TOptions::Add(const UnicodeString & Value)
{
  if (!FNoMoreSwitches &&
      (Value.Length() == 2) &&
      (Value[1] == Value[2]) &&
      (FSwitchMarks.Pos(Value[1]) > 0))
  {
    FNoMoreSwitches = true;
  }
  else
  {
    bool Switch = false;
    intptr_t Index = 0; // shut up
    if (!FNoMoreSwitches &&
        (Value.Length() >= 2) &&
        (FSwitchMarks.Pos(Value[1]) > 0))
    {
      Index = 2;
      Switch = true;
      while (Switch && (Index <= Value.Length()))
      {
        if (Value.IsDelimiter(FSwitchValueDelimiters, Index))
        {
          break;
        }
        // this is to treat /home/martin as parameter, not as switch
        else if ((Value[Index] != L'?') && !IsLetter(Value[Index]))
        {
          Switch = false;
          break;
        }
        ++Index;
      }
    }

    if (Switch)
    {
      TOption Option;
      Option.Type = otSwitch;
      Option.Name = Value.SubString(2, Index - 2);
      Option.Value = Value.SubString(Index + 1, Value.Length());
      Option.Used = false;
      FOptions.push_back(Option);
    }
    else
    {
      TOption Option;
      Option.Type = otParam;
      Option.Value = Value;
      Option.Used = false;
      FOptions.push_back(Option);
      ++FParamCount;
    }
  }

  FOriginalOptions = FOptions;
}
Ejemplo n.º 3
0
//---------------------------------------------------------------------------
intptr_t LastDelimiter(const UnicodeString & Delimiters, const UnicodeString & Str)
{
  if (Str.Length())
  {
    for (intptr_t I = Str.Length(); I >= 1; --I)
    {
      if (Str.IsDelimiter(Delimiters, I))
      {
        return I;
      }
    }
  }
  return 0;
}
Ejemplo n.º 4
0
//---------------------------------------------------------------------------
intptr_t FirstDelimiter(const UnicodeString & Delimiters, const UnicodeString & Str)
{
  if (Str.Length())
  {
    for (intptr_t I = 1; I <= Str.Length(); ++I)
    {
      if (Str.IsDelimiter(Delimiters, I))
      {
        return I;
      }
    }
  }
  return 0;
}
Ejemplo n.º 5
0
//---------------------------------------------------------------------------
UnicodeString TFileMasks::MakeDirectoryMask(const UnicodeString & Str)
{
  assert(!Str.IsEmpty());
  UnicodeString Result = Str;
  if (Result.IsEmpty() || !Result.IsDelimiter(DirectoryMaskDelimiters, Result.Length()))
  {
    intptr_t D = Result.LastDelimiter(DirectoryMaskDelimiters);
    // if there's any [back]slash anywhere in str,
    // add the same [back]slash at the end, otherwise add slash
    wchar_t Delimiter = (D > 0) ? Result[D] : DirectoryMaskDelimiters[1];
    Result += Delimiter;
  }
  return Result;
}
Ejemplo n.º 6
0
//---------------------------------------------------------------------------
UnicodeString TCustomCommand::Complete(const UnicodeString & Command,
  bool LastPass)
{
  UnicodeString Result;
  intptr_t Index = 1;

  while (Index <= Command.Length())
  {
    intptr_t Len;
    wchar_t PatternCmd;
    GetToken(Command, Index, Len, PatternCmd);

    if (PatternCmd == TEXT_TOKEN)
    {
      Result += Command.SubString(Index, Len);
    }
    else if (PatternCmd == L'!')
    {
      if (LastPass)
      {
        Result += L'!';
      }
      else
      {
        Result += Command.SubString(Index, Len);
      }
    }
    else
    {
      wchar_t Quote = NoQuote;
      if ((Index > 1) && (Index + Len - 1 < Command.Length()) &&
          Command.IsDelimiter(Quotes, Index - 1) &&
          Command.IsDelimiter(Quotes, Index + Len) &&
          (Command[Index - 1] == Command[Index + Len]))
      {
        Quote = Command[Index - 1];
      }
      UnicodeString Pattern = Command.SubString(Index, Len);
      UnicodeString Replacement;
      bool Delimit = true;
      if (PatternReplacement(Pattern, Replacement, Delimit))
      {
        if (!LastPass)
        {
          Replacement = StringReplace(Replacement, L"!", L"!!",
            TReplaceFlags() << rfReplaceAll);
        }
        if (Delimit)
        {
          DelimitReplacement(Replacement, Quote);
        }
        Result += Replacement;
      }
      else
      {
        Result += Pattern;
      }
    }

    Index += Len;
  }

  return Result;
}
Ejemplo n.º 7
0
//---------------------------------------------------------------------------
void TFileMasks::CreateMask(
  const UnicodeString & MaskStr, intptr_t MaskStart, intptr_t /*MaskEnd*/, bool Include)
{
  bool Directory = false; // shut up
  TMask Mask;

  Mask.MaskStr = MaskStr;
  Mask.UserStr = MaskStr;
  Mask.FileNameMask.Kind = TMaskMask::Any;
  Mask.FileNameMask.Mask = nullptr;
  Mask.DirectoryMask.Kind = TMaskMask::Any;
  Mask.DirectoryMask.Mask = nullptr;
  Mask.HighSizeMask = TMask::None;
  Mask.LowSizeMask = TMask::None;
  Mask.HighModificationMask = TMask::None;
  Mask.LowModificationMask = TMask::None;

  wchar_t NextPartDelimiter = L'\0';
  intptr_t NextPartFrom = 1;
  while (NextPartFrom <= MaskStr.Length())
  {
    wchar_t PartDelimiter = NextPartDelimiter;
    intptr_t PartFrom = NextPartFrom;
    UnicodeString PartStr = CopyToChars(MaskStr, NextPartFrom, L"<>", false, &NextPartDelimiter, true);

    intptr_t PartStart = MaskStart + PartFrom - 1;
    intptr_t PartEnd = MaskStart + NextPartFrom - 1 - 2;

    TrimEx(PartStr, PartStart, PartEnd);

    if (PartDelimiter != L'\0')
    {
      bool Low = (PartDelimiter == L'>');

      TMask::TMaskBoundary Boundary;
      if ((PartStr.Length() >= 1) && (PartStr[1] == L'='))
      {
        Boundary = TMask::Close;
        PartStr.Delete(1, 1);
      }
      else
      {
        Boundary = TMask::Open;
      }

      TFormatSettings FormatSettings = TFormatSettings::Create(GetDefaultLCID());
      FormatSettings.DateSeparator = L'-';
      FormatSettings.TimeSeparator = L':';
      FormatSettings.ShortDateFormat = L"yyyy/mm/dd";
      FormatSettings.ShortTimeFormat = L"hh:nn:ss";

      TDateTime Modification;
      if (TryStrToDateTime(PartStr, Modification, FormatSettings) ||
          TryRelativeStrToDateTime(PartStr, Modification))
      {
        TMask::TMaskBoundary & ModificationMask =
          (Low ? Mask.LowModificationMask : Mask.HighModificationMask);

        if ((ModificationMask != TMask::None) || Directory)
        {
          // include delimiter into size part
          ThrowError(PartStart - 1, PartEnd);
        }

        ModificationMask = Boundary;
        (Low ? Mask.LowModification : Mask.HighModification) = Modification;
      }
      else
      {
        TMask::TMaskBoundary & SizeMask = (Low ? Mask.LowSizeMask : Mask.HighSizeMask);
        __int64 & Size = (Low ? Mask.LowSize : Mask.HighSize);

        if ((SizeMask != TMask::None) || Directory)
        {
          // include delimiter into size part
          ThrowError(PartStart - 1, PartEnd);
        }

        SizeMask = Boundary;
        Size = ParseSize(PartStr);
      }
    }
    else if (!PartStr.IsEmpty())
    {
      intptr_t D = PartStr.LastDelimiter(DirectoryMaskDelimiters);

      Directory = (D > 0) && (D == PartStr.Length());

      if (Directory)
      {
        do
        {
          PartStr.SetLength(PartStr.Length() - 1);
          Mask.UserStr.Delete(PartStart - MaskStart + D, 1);
          D--;
        }
        while (PartStr.IsDelimiter(DirectoryMaskDelimiters, PartStr.Length()));

        D = PartStr.LastDelimiter(DirectoryMaskDelimiters);

        if (FForceDirectoryMasks == 0)
        {
          Directory = false;
          Mask.MaskStr = Mask.UserStr;
        }
      }
      else if (FForceDirectoryMasks > 0)
      {
        Directory = true;
        Mask.MaskStr.Insert(DirectoryMaskDelimiters[1], PartStart - MaskStart + PartStr.Length());
      }

      if (D > 0)
      {
        // make sure sole "/" (root dir) is preserved as is
        CreateMaskMask(
          UnixExcludeTrailingBackslash(ToUnixPath(PartStr.SubString(1, D))),
          PartStart, PartStart + D - 1, false,
          Mask.DirectoryMask);
        CreateMaskMask(
          PartStr.SubString(D + 1, PartStr.Length() - D),
          PartStart + D, PartEnd, true,
          Mask.FileNameMask);
      }
      else
      {
        CreateMaskMask(PartStr, PartStart, PartEnd, true, Mask.FileNameMask);
      }
    }
  }

  FMasks[MASK_INDEX(Directory, Include)].push_back(Mask);
}