コード例 #1
0
ファイル: arccmd.cpp プロジェクト: elfmz/far2l
int ArcCommand::ReplaceVar(std::string &Command)
{
  int MaxNamesLength = 0x10000;
  std::string LocalAllFilesMask = AllFilesMask;
  bool UseSlash = false;
  bool FolderMask = false;
  bool FolderName = false;
  bool NameOnly = false;
  bool PathOnly = false;
  int QuoteName = 0;

  if (Command.size() < 3)
    return 0;

  char Chr = Command[2] & (~0x20);
  if (Command[0] != '%' || Command[1] != '%' || Chr < 'A' || Chr > 'Z')
    return 0;

  int VarLength = 3;

  while (VarLength < Command.size())
  {
    bool BreakScan = false;
    Chr = Command[VarLength];
    if (Command[2]=='F' && Chr >= '0' && Chr <= '9')
    {
      MaxNamesLength = FSF.atoi(Command.c_str() + VarLength);
      while (Chr >= '0' && Chr <= '9' && VarLength < Command.size())
        Chr = Command[++VarLength];
      continue;
    }
    if (Command[2]=='E' && Chr >= '0' && Chr <= '9')
    {
      MaxAllowedExitCode = FSF.atoi(Command.c_str() + VarLength);
      while (Chr >= '0' && Chr <= '9' && VarLength < Command.size())
        Chr=Command[++VarLength];
      continue;
    }
    switch (Command[VarLength])
    {
      case 'A': break; /* deprecated AnsiCode = true; */
      case 'Q': QuoteName = 1; break;
      case 'q': QuoteName = 2; break;
      case 'S': UseSlash = true; break;
      case 'M': FolderMask = true; break;
      case 'N': FolderName = true; break;
      case 'W': NameOnly = true; break;
      case 'P': PathOnly = true; break;
      case '*': LocalAllFilesMask = "*"; break;
      default: BreakScan = true;
    }
    if (BreakScan)
      break;
    VarLength++;
  }

  if ( (MaxNamesLength-=(int)Command.size()) <= 0)
    MaxNamesLength = 1;

  if (!FolderMask && !FolderName)
    FolderName = true;

/////////////////////////////////
  switch (Command[2])
  {
    case 'A': case 'a': /* deprecated: short name - works same as normal name */
      Command = ArcName;
      if (PathOnly)
        CutToPathOrSpace(Command);
      QuoteCmdArgIfNeed(Command);
      break;

    case 'D': case 'E':
      Command.clear();
      break;

    case 'L': case 'l':
      if (!MakeListFile(ListFileName, QuoteName, UseSlash, FolderName,
         NameOnly, PathOnly, FolderMask, LocalAllFilesMask.c_str())) {
        return -1;
      }
      Command = ListFileName;
      QuoteCmdArgIfNeed(Command);
      break;

    case 'P':
      Command = Password;
      break;

    case 'C':
      if (*CommentFileName) //второй раз сюда не лезем
        break;
      {
        Command.clear();
        int CommentFile;
        if (FSF.MkTemp(CommentFileName, "FAR") && (CommentFile =
          sdc_open(CommentFileName, O_CREAT | O_TRUNC | O_RDWR, 0660)) != -1)
        {
          char Buf[512];
          if(Info.InputBox(GetMsg(MComment), GetMsg(MInputComment), NULL, "", Buf, sizeof(Buf), NULL, 0))
          //??тут можно и заполнить строку комментарием, но надо знать, файловый
          //?? он или архивный. да и имя файла в архиве тоже надо знать...
          {
            sdc_write(CommentFile, Buf, strlen(Buf));
            sdc_close(CommentFile);
            Command = CommentFileName;
          }
          WINPORT(FlushConsoleInputBuffer)(NULL);//GetStdHandle(STD_INPUT_HANDLE));
        }
      }
      break;

    case 'r':
      Command = RealArcDir;
      if (!Command.empty())
        Command+= '/';
      break;
    case 'R':
      Command = RealArcDir;
      if (UseSlash)
      {
      }
      QuoteCmdArgIfNeed(Command);
      break;

    case 'W':
      Command = TempPath;
      break;

    case 'F': case 'f':
      if (PanelItem!=NULL)
      {
        std::string CurArcDir = ArcDir;
        if (!CurArcDir.empty() && CurArcDir[CurArcDir.size() - 1] != GOOD_SLASH)
          CurArcDir+= GOOD_SLASH;

        std::string Names, Name;

        if (NameNumber == -1)
          NameNumber = 0;

        while (NameNumber < ItemsNumber || Command[2] == 'f')
        {
          int IncreaseNumber = 0;
          DWORD FileAttr;
          if (!NextFileName.empty())
          {
            Name = PrefixFileName;
            Name+= CurArcDir;
            Name+= NextFileName;
            NextFileName.clear();
            FileAttr = 0;
          }
          else
          {
            int N;
            if (Command[2]=='f' && PrevFileNameNumber!=-1)
              N = PrevFileNameNumber;
            else
            {
              N = NameNumber;
              IncreaseNumber=1;
            }
            if (N >= ItemsNumber)
              break;

            *PrefixFileName=0;
            char *cFileName = PanelItem[N].FindData.cFileName;

            if(PanelItem[N].UserData && (PanelItem[N].Flags & PPIF_USERDATA))
            {
              struct ArcItemUserData *aud=(struct ArcItemUserData*)PanelItem[N].UserData;
              if(aud->SizeStruct == sizeof(struct ArcItemUserData))
              {
                if(aud->Prefix)
                  strncpy(PrefixFileName,aud->Prefix,sizeof(PrefixFileName));
                if(aud->LinkName)
                  cFileName=aud->LinkName;
              }
            }
            // CHECK for BUGS!!
            Name = PrefixFileName;
            if(*cFileName != GOOD_SLASH)
            {
              Name+= CurArcDir;
              Name+= cFileName;
            }
            else
              Name+= cFileName+1;
            NormalizePath(Name);
            FileAttr = PanelItem[N].FindData.dwFileAttributes;
            PrevFileNameNumber = N;
          }
          if (NameOnly)
          {
            size_t slash = Name.rfind(GOOD_SLASH);
            if (slash != std::string::npos)
              Name.erase(0, slash + 1);
          }
          if (PathOnly)
            CutToPathOrSpace(Name);
          if (Names.empty() || (Names.size() + Name.size() < MaxNamesLength && Command[2] != 'f'))
          {
            NameNumber+= IncreaseNumber;
            if (FileAttr & FILE_ATTRIBUTE_DIRECTORY)
            {
              std::string FolderMaskName = Name;
              if (!PathOnly)
              {
                FolderMaskName+= GOOD_SLASH;
                FolderMaskName+= LocalAllFilesMask;
              }
              else
                CutToPathOrSpace(FolderMaskName);
              if (FolderMask)
              {
                if (FolderName)
                  NextFileName.swap(FolderMaskName);
                else
                  Name.swap(FolderMaskName);
              }
            }

            if (QuoteName==1)
              QuoteCmdArgIfNeed(Name);
            else if (QuoteName==2)
              QuoteCmdArg(Name);

            if (!Names.empty())
              Names+= ' ';
            Names+= Name;
          }
          else
            break;
        }
        Command.swap(Names);
      }
      else
        Command.clear();
      break;
    default:
      return 0;
  }

  return VarLength;
}
コード例 #2
0
ファイル: arccmd.cpp プロジェクト: CyberShadow/FAR
int ArcCommand::ReplaceVar(char *Command,int &Length)
{
  char Chr=Command[2]&(~0x20);
  if (Command[0]!='%' || Command[1]!='%' || Chr < 'A' || Chr > 'Z')
    return FALSE;
  char SaveStr[MAX_COMMAND_LENGTH],LocalAllFilesMask[NM];
  int QuoteName=0,UseSlash=FALSE,FolderMask=FALSE,FolderName=FALSE;
  int NameOnly=FALSE,PathOnly=FALSE,AnsiCode=FALSE;
  int MaxNamesLength=127;

  int VarLength=3;

  lstrcpy(LocalAllFilesMask,AllFilesMask);

  while (1)
  {
    int BreakScan=FALSE;
    Chr=Command[VarLength];
    if (Command[2]=='F' && Chr >= '0' && Chr <= '9')
    {
      MaxNamesLength=FSF.atoi(&Command[VarLength]);
      while (Chr >= '0' && Chr <= '9')
        Chr=Command[++VarLength];
      continue;
    }
    if (Command[2]=='E' && Chr >= '0' && Chr <= '9')
    {
      MaxAllowedExitCode=FSF.atoi(&Command[VarLength]);
      while (Chr >= '0' && Chr <= '9')
        Chr=Command[++VarLength];
      continue;
    }
    switch(Command[VarLength])
    {
      case 'A':
        AnsiCode=TRUE;
        break;
      case 'Q':
        QuoteName=1;
        break;
      case 'q':
        QuoteName=2;
        break;
      case 'S':
        UseSlash=TRUE;
        break;
      case 'M':
        FolderMask=TRUE;
        break;
      case 'N':
        FolderName=TRUE;
        break;
      case 'W':
        NameOnly=TRUE;
        break;
      case 'P':
        PathOnly=TRUE;
        break;
      case '*':
        lstrcpy(LocalAllFilesMask,"*");
        break;
      default:
        BreakScan=TRUE;
        break;
    }
    if (BreakScan)
      break;
    VarLength++;
  }
  if ((MaxNamesLength-=Length)<=0)
    MaxNamesLength=1;
  if (MaxNamesLength>MAX_COMMAND_LENGTH-512)
    MaxNamesLength=MAX_COMMAND_LENGTH-512;
  if (FolderMask==FALSE && FolderName==FALSE)
    FolderName=TRUE;
  lstrcpy(SaveStr,Command+VarLength);
  switch(Command[2])
  {
    case 'A':
      lstrcpy(Command,ArcName);
      if (AnsiCode)
        OemToChar(Command,Command);
      if (PathOnly)
      {
        char *NamePtr=(char *)FSF.PointToName(Command);
        if (NamePtr!=Command)
          *(NamePtr-1)=0;
        else
          lstrcpy(Command," ");
      }
      FSF.QuoteSpaceOnly(Command);
      break;
    case 'a':
      {
        int Dot=strchr(FSF.PointToName(ArcName),'.')!=NULL;
        ConvertNameToShort(ArcName,Command);
        char *Slash=strrchr(ArcName,'\\');
        if (GetFileAttributes(ArcName)==0xFFFFFFFF && Slash!=NULL && Slash!=ArcName)
        {
          char Path[NM];
          lstrcpy(Path,ArcName);
          Path[Slash-ArcName]=0;
          ConvertNameToShort(Path,Command);
          lstrcat(Command,Slash);
        }
        if (Dot && strchr(FSF.PointToName(Command),'.')==NULL)
          lstrcat(Command,".");
        if (AnsiCode)
          OemToChar(Command,Command);
        if (PathOnly)
        {
          char *NamePtr=(char *)FSF.PointToName(Command);
          if (NamePtr!=Command)
            *(NamePtr-1)=0;
          else
            lstrcpy(Command," ");
        }
      }
      FSF.QuoteSpaceOnly(Command);
      break;
    case 'D':
      *Command=0;
      break;
    case 'E':
      *Command=0;
      break;
    case 'l':
    case 'L':
      if (!MakeListFile(ListFileName,Command[2]=='l',QuoteName,UseSlash,
                        FolderName,NameOnly,PathOnly,FolderMask,
                        LocalAllFilesMask,AnsiCode))
        return -1;
      char QListName[NM+2];
      FSF.QuoteSpaceOnly(lstrcpy(QListName,ListFileName));
      lstrcpy(Command,QListName);
      break;
    case 'P':
      lstrcpy(Command,Password);
      break;
    case 'C':
      if(*CommentFileName) //второй раз сюда не лезем
        break;
      {
        *Command=0;

        HANDLE CommentFile;
        //char CommentFileName[MAX_PATH];
        char Buf[512];
        SECURITY_ATTRIBUTES sa;

        sa.nLength=sizeof(sa);
        sa.lpSecurityDescriptor=NULL;
        sa.bInheritHandle=TRUE;

        if(FSF.MkTemp(CommentFileName, "FAR") &&
          (CommentFile=CreateFile(CommentFileName, GENERIC_WRITE,
                       FILE_SHARE_READ|FILE_SHARE_WRITE, &sa, CREATE_ALWAYS,
                       /*FILE_ATTRIBUTE_TEMPORARY|*//*FILE_FLAG_DELETE_ON_CLOSE*/0, NULL))
                       != INVALID_HANDLE_VALUE)
        {
          DWORD Count;
          if(Info.InputBox(GetMsg(MComment), GetMsg(MInputComment), NULL, "", Buf, sizeof(Buf), NULL, 0))
          //??тут можно и заполнить строку комментарием, но надо знать, файловый
          //?? он или архивный. да и имя файла в архиве тоже надо знать...
          {
            WriteFile(CommentFile, Buf, lstrlen(Buf), &Count, NULL);
            lstrcpy(Command, CommentFileName);
            CloseHandle(CommentFile);
          }
          FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));
        }
      }
      break;
    case 'R':
      lstrcpy(Command,RealArcDir);
      if (UseSlash)
      {
        for (int I=0;Command[I];I++)
          if (Command[I]=='\\')
//            Command[I]='//';
/* $ 28.11.2000 AS
*/
            Command[I]='/';
/* AS $*/
      }
      FSF.QuoteSpaceOnly(Command);
      break;
    case 'W':
      lstrcpy(Command,TempPath);
      break;
    case 'f':
    case 'F':
      if (PanelItem!=NULL)
      {
        char CurArcDir[NM];
        lstrcpy(CurArcDir,ArcDir);
        int Length=lstrlen(CurArcDir);
        if (Length>0 && CurArcDir[Length-1]!='\\')
          lstrcat(CurArcDir,"\\");

        char Names[MAX_COMMAND_LENGTH];
        *Names=0;

        if (NameNumber==-1)
          NameNumber=0;

        while (NameNumber<ItemsNumber || Command[2]=='f')
        {
          char Name[NM*2];

          int IncreaseNumber=0,FileAttr;
          if (*NextFileName)
          {
            FSF.sprintf(Name,"%s%s%s",PrefixFileName,CurArcDir,NextFileName);
            *NextFileName=0;
            FileAttr=0;
          }
          else
          {
            int N;
            if (Command[2]=='f' && PrevFileNameNumber!=-1)
              N=PrevFileNameNumber;
            else
            {
              N=NameNumber;
              IncreaseNumber=1;
            }
            if (N>=ItemsNumber)
              break;

            *PrefixFileName=0;
            char *cFileName=PanelItem[N].FindData.cFileName;

            if(PanelItem[N].UserData && (PanelItem[N].Flags & PPIF_USERDATA))
            {
              struct ArcItemUserData *aud=(struct ArcItemUserData*)PanelItem[N].UserData;
              if(aud->SizeStruct == sizeof(struct ArcItemUserData))
              {
                if(aud->Prefix)
                  lstrcpyn(PrefixFileName,aud->Prefix,sizeof(PrefixFileName));
                if(aud->LinkName)
                  cFileName=aud->LinkName;
              }
            }
            // CHECK for BUGS!!
            if(*cFileName == '\\' || *cFileName == '/')
              FSF.sprintf(Name,"%s%s",PrefixFileName,cFileName+1);
            else
              FSF.sprintf(Name,"%s%s%s",PrefixFileName,CurArcDir,cFileName);
            NormalizePath(Name,Name);
            FileAttr=PanelItem[N].FindData.dwFileAttributes;
            PrevFileNameNumber=N;
          }
          if (AnsiCode)
            OemToChar(Name,Name);
          if (NameOnly)
          {
            char NewName[NM];
            lstrcpy(NewName,FSF.PointToName(Name));
            lstrcpy(Name,NewName);
          }
          if (PathOnly)
          {
            char *NamePtr=(char *)FSF.PointToName(Name);
            if (NamePtr!=Name)
              *(NamePtr-1)=0;
            else
              lstrcpy(Name," ");
          }
          if (*Names==0 || (lstrlen(Names)+lstrlen(Name)<MaxNamesLength && Command[2]!='f'))
          {
            NameNumber+=IncreaseNumber;
            if (FileAttr & FILE_ATTRIBUTE_DIRECTORY)
            {
              char FolderMaskName[NM];
              //lstrcpy(LocalAllFilesMask,PrefixFileName);
              FSF.sprintf(FolderMaskName,"%s\\%s",Name,LocalAllFilesMask);
              if (PathOnly)
              {
                lstrcpy(FolderMaskName,Name);
                char *NamePtr=(char *)FSF.PointToName(FolderMaskName);
                if (NamePtr!=FolderMaskName)
                  *(NamePtr-1)=0;
                else
                  lstrcpy(FolderMaskName," ");
              }
              if (FolderMask)
              {
                if (FolderName)
                  lstrcpy(NextFileName,FolderMaskName);
                else
                  lstrcpy(Name,FolderMaskName);
              }
            }

            if (QuoteName==1)
              FSF.QuoteSpaceOnly(Name);
            else
              if (QuoteName==2)
                QuoteText(Name);
            if (UseSlash)
              for (int I=0;Name[I];I++)
                if (Name[I]=='\\')
//                  Name[I]='//';
/* $ 28.11.2000 AS
*/
                  Name[I]='/';
/* AS $*/


            if (*Names)
              lstrcat(Names," ");
            lstrcat(Names,Name);
          }
          else
            break;
        }
        lstrcpy(Command,Names);
      }
      else
        *Command=0;
      break;
    default:
      return FALSE;
  }
  Length=lstrlen(Command);
  lstrcat(Command,SaveStr);
  return TRUE;
}