// Preprocess those parameters, which must be processed before the rest of // command line. Return 'false' to stop further processing. void CommandData::PreprocessArg(const wchar *Arg) { if (IsSwitch(Arg[0]) && !NoMoreSwitches) { Arg++; if (Arg[0]=='-' && Arg[1]==0) // Switch "--". NoMoreSwitches=true; if (wcsicomp(Arg,L"cfg-")==0) ConfigDisabled=true; if (wcsnicomp(Arg,L"ilog",4)==0) { // Ensure that correct log file name is already set // if we need to report an error when processing the command line. ProcessSwitch(Arg); InitLogOptions(LogName,ErrlogCharset); } if (wcsnicomp(Arg,L"sc",2)==0) { // Process -sc before reading any file lists. ProcessSwitch(Arg); if (*LogName!=0) InitLogOptions(LogName,ErrlogCharset); } } else if (*Command==0) wcsncpy(Command,Arg,ASIZE(Command)); // Need for rar.ini. }
CommandLine::StringType CommandLine::GetCommandLineString() const { StringType string(argv_[0]); string = QuoteForCommandLineToArgvW(string); // Append switches and arguments. bool parse_switches = true; for(size_t i=1; i<argv_.size(); ++i) { CommandLine::StringType arg = argv_[i]; CommandLine::StringType switch_string; CommandLine::StringType switch_value; parse_switches &= arg != kSwitchTerminator; string.append(StringType(FILE_PATH_LITERAL(" "))); if (parse_switches && IsSwitch(arg, &switch_string, &switch_value)) { string.append(switch_string); if(!switch_value.empty()) { switch_value = QuoteForCommandLineToArgvW(switch_value); string.append(kSwitchValueSeparator + switch_value); } } else { arg = QuoteForCommandLineToArgvW(arg); string.append(arg); } } return string; }
CommandLine::StringType CommandLine::GetArgumentsString() const { StringType params; // Append switches and arguments. bool parse_switches = true; for (size_t i = 1; i < argv_.size(); ++i) { StringType arg = argv_[i]; StringType switch_string; StringType switch_value; parse_switches &= arg != kSwitchTerminator; if (i > 1) params.append(StringType(FILE_PATH_LITERAL(" "))); if (parse_switches && IsSwitch(arg, &switch_string, &switch_value)) { params.append(switch_string); if (!switch_value.empty()) { #if defined(OS_WIN) switch_value = QuoteForCommandLineToArgvW(switch_value); #endif params.append(kSwitchValueSeparator + switch_value); } } else { #if defined(OS_WIN) arg = QuoteForCommandLineToArgvW(arg); #endif params.append(arg); } } return params; }
bool CommandData::IsConfigEnabled(int argc,char *argv[]) { bool ConfigEnabled=true; for (int I=1;I<argc;I++) if (IsSwitch(*argv[I])) { if (stricomp(&argv[I][1],"-")==0) break; if (stricomp(&argv[I][1],"cfg-")==0) ConfigEnabled=false; #ifndef GUI if (strnicomp(&argv[I][1],"ilog",4)==0) { // Ensure that correct log file name is already set // if we need to report an error when processing the command line. ProcessSwitch(&argv[I][1]); InitLogOptions(LogName); } #endif if (strnicomp(&argv[I][1],"sc",2)==0) { // Process -sc before reading any file lists. ProcessSwitch(&argv[I][1]); } } return(ConfigEnabled); }
// Preprocess those parameters, which must be processed before the rest of // command line. Return 'false' to stop further processing. bool CommandData::PreprocessSwitch(const char *Switch) { if (IsSwitch(Switch[0])) { Switch++; if (stricomp(Switch,"-")==0) // Switch "--". return false; if (stricomp(Switch,"cfg-")==0) ConfigDisabled=true; #ifndef GUI if (strnicomp(Switch,"ilog",4)==0) { // Ensure that correct log file name is already set // if we need to report an error when processing the command line. ProcessSwitch(Switch); InitLogOptions(LogName); } #endif if (strnicomp(Switch,"sc",2)==0) { // Process -sc before reading any file lists. ProcessSwitch(Switch); } } return true; }
int CCommandLineParameters::SwitchCount() { int count = 0; for (int i = 1;i < paramcount; i++) { if (IsSwitch(parms[i])) count++; } return count; }
int CCommandLineParameters::FirstNonSwitchIndex() { for (int i = 1;i < paramcount; i++) { if (!IsSwitch(parms[i])) { return i; } } return 0; }
void CommandData::ProcessSwitchesString(char *Str) { while (*Str) { while (!IsSwitch(*Str) && *Str!=0) Str++; if (*Str==0) break; char *Next=Str; while (!(Next[0]==' ' && IsSwitch(Next[1])) && *Next!=0) Next++; char NextChar=*Next; *Next=0; ProcessSwitch(Str+1); *Next=NextChar; Str=Next; } }
void CommandData::ProcessSwitchesString(const wchar *Str) { wchar *Par; while ((Str=AllocCmdParam(Str,&Par))!=NULL) { if (IsSwitch(*Par)) ProcessSwitch(Par+1); free(Par); } }
VOID CommandLine::ParseFromString(const CString & strCommandLine) { CString strCommandLineCopy = strCommandLine; strCommandLineCopy.Trim(); if (strCommandLineCopy.IsEmpty()) return; INT nNumArgs = 0; WCHAR ** pszArgs = NULL; pszArgs = ::CommandLineToArgvW(strCommandLineCopy.GetBuffer(), &nNumArgs); // Populate program_ with the trimmed version of the first arg. m_strProgram = pszArgs[0]; m_strProgram.Trim(); BOOL bParseSwitches = TRUE; for (INT i = 1; i < nNumArgs; ++i) { CString strArg = pszArgs[i]; strArg.Trim(); if (!bParseSwitches) { m_vNonSwitchArgs.push_back(strArg); continue; } if (strArg == kPrefix) { bParseSwitches = FALSE; continue; } CString strSwitchName; CString strSwitchValue; if (IsSwitch(strArg, strSwitchName, strSwitchValue)) { m_mapSwitchValues[strSwitchName] = strSwitchValue; } else { m_vNonSwitchArgs.push_back(strArg); } } if (pszArgs) { LocalFree(pszArgs); } m_bCmdLineChange = TRUE; }
void CommandLine::ParseFromString(const std::wstring& command_line) { TrimWhitespace(command_line, TRIM_ALL, &command_line_string_); if(command_line_string_.empty()) { return; } int num_args = 0; wchar_t** args = NULL; args = CommandLineToArgvW(command_line_string_.c_str(), &num_args); // 去掉第一个参数两端空白并填充到_program TrimWhitespace(args[0], TRIM_ALL, &program_); bool parse_switches = true; for(int i=1; i<num_args; ++i) { std::wstring arg; TrimWhitespace(args[i], TRIM_ALL, &arg); if(!parse_switches) { args_.push_back(arg); continue; } if(arg == kSwitchTerminator) { parse_switches = false; continue; } std::string switch_string; std::wstring switch_value; if(IsSwitch(arg, &switch_string, &switch_value)) { switches_[switch_string] = switch_value; } else { args_.push_back(arg); } } if(args) { LocalFree(args); } }
bool CommandData::IsConfigEnabled(int argc,char *argv[]) { bool ConfigEnabled=true; for (int I=1;I<argc;I++) if (IsSwitch(*argv[I])) { if (stricomp(&argv[I][1],"cfg-")==0) ConfigEnabled=false; if (strnicomp(&argv[I][1],"ilog",4)==0) { ProcessSwitch(&argv[I][1]); InitLogOptions(LogName); } } return(ConfigEnabled); }
int CCommandLineParameters::Switch(const char *sz, const BOOL bCase /* = FALSE */ ) { if (!sz || !sz[0]) { return 0; } char sz2[255]; strncpy(sz2,sz,sizeof(sz2)-1); sz2[sizeof(sz2)-1] = 0; char *p = sz2; if (strchr(szSwitchChars,*p) != NULL) p++; // check for abbrevation int ful_amt = 0; int abr_amt = 0; char *abbr = strchr(p,'*'); if (abbr) { *abbr = 0; abr_amt = strlen(p); strcpy(abbr,abbr+1); } ful_amt = strlen(p); for (int i = 1;i < paramcount; i++) { if (!IsSwitch(parms[i])) continue; char *pColon = strchr(&parms[i][1],':'); int arg_amt = 0; if (pColon) { arg_amt = pColon - &parms[i][1]; } else { arg_amt = strlen(&parms[i][1]); } if (bCase) { if (arg_amt == ful_amt && strncmp(p,&parms[i][1],ful_amt) == 0) return i; if (arg_amt == abr_amt && strncmp(p,&parms[i][1],abr_amt) == 0) return i; } else { if (arg_amt == ful_amt && _strnicmp(p,&parms[i][1],ful_amt) == 0) return i; if (arg_amt == abr_amt && _strnicmp(p,&parms[i][1],abr_amt) == 0) return i; } } return 0; }
// RJM: added Replace() to remove quotation marks from command line arguments...this should be handled by DOS // but it won't hurt to make sure CString CCommandLineParameters::GetNonSwitchStr( const BOOL bBreakAtSwitch, /* = TRUE */ const BOOL bFirstOnly /* = FALSE */) { CString sLine = ""; int i = 1; while (i < paramcount) { if (IsSwitch(parms[i])) { if (bBreakAtSwitch) break; } else { sLine += parms[i]; if (bFirstOnly) break; sLine += " "; } i++; } sLine.TrimRight(); sLine.Replace("\"", ""); return sLine; }
void CommandData::ParseArg(char *Arg,wchar *ArgW) { if (IsSwitch(*Arg) && !NoMoreSwitches) if (Arg[1]=='-') NoMoreSwitches=true; else ProcessSwitch(&Arg[1]); else if (*Command==0) { strncpy(Command,Arg,sizeof(Command)); if (ArgW!=NULL) strncpyw(CommandW,ArgW,sizeof(CommandW)/sizeof(CommandW[0])); if (toupper(*Command)=='S') { const char *SFXName=Command[1] ? Command+1:DefSFXName; if (PointToName(SFXName)!=SFXName || FileExist(SFXName)) strcpy(SFXModule,SFXName); else GetConfigName(SFXName,SFXModule,true); } #ifndef GUI *Command=toupper(*Command); if (*Command!='I' && *Command!='S') strupper(Command); #endif } else if (*ArcName==0) { strncpy(ArcName,Arg,sizeof(ArcName)); if (ArgW!=NULL) strncpyw(ArcNameW,ArgW,sizeof(ArcNameW)/sizeof(ArcNameW[0])); } else { int Length=strlen(Arg); char EndChar=Arg[Length-1]; char CmdChar=toupper(*Command); bool Add=strchr("AFUM",CmdChar)!=NULL; bool Extract=CmdChar=='X' || CmdChar=='E'; if ((IsDriveDiv(EndChar) || IsPathDiv(EndChar)) && !Add) strcpy(ExtrPath,Arg); else if ((Add || CmdChar=='T') && *Arg!='@') FileArgs->AddString(Arg); else { struct FindData FileData; bool Found=FindFile::FastFind(Arg,NULL,&FileData); if (!Found && *Arg=='@' && !IsWildcard(Arg)) { ReadTextFile(Arg+1,FileArgs,false,true,true,true,true); FileLists=true; } else if (Found && FileData.IsDir && Extract && *ExtrPath==0) { strcpy(ExtrPath,Arg); AddEndSlash(ExtrPath); } else FileArgs->AddString(Arg); } } }
int main(int argc, char *argv[]) { int i; DWORD dwBase = 0xFFFFFFFFL; /* First address to dump */ DWORD dwLength = 0xFFFFFFFFL; /* Number of bytes to dump */ BYTE table[16]; /* 16 bytes table */ DWORD ul; WORD u; char *pszName = NULL; /* File name */ FILE *f; #ifndef __unix__ /* Force stdin and stdout to untranslated */ _setmode( _fileno( stdin ), _O_BINARY ); #endif for (i=1; i<argc; i++) { if (IsSwitch(argv[i])) { if ( streq(argv[i]+1, "?") || streq(argv[i]+1, "h") || streq(argv[i]+1, "-help")) { usage(); } if (streq(argv[i]+1, "p")) { paginate = GetScreenRows() - 1; /* Pause once per screen */ continue; } if (streq(argv[i]+1, "V")) { /* -V: Display the version */ printf("%s\n", PROGRAM_VERSION " " PROGRAM_DATE " " OS_NAME); exit(0); } printf("Unrecognized switch %s. Ignored.\n", argv[i]); continue; } if (!pszName) { pszName = argv[i]; continue; } if (dwBase == 0xFFFFFFFFL) { if (sscanf(argv[i], "%lX", &ul)) dwBase = ul; continue; } if (dwLength == 0xFFFFFFFFL) { if (sscanf(argv[i], "%lX", &ul)) dwLength = ul; continue; } printf("Unexpected argument: %s\nIgnored.\n", argv[i]); break; /* Ignore other arguments */ } if (pszName) { f = fopen(pszName, "rb"); if (!f) { printf("Cannot open file %s.\n", pszName); exit(1); } } else { if (!is_redirected(stdin)) usage(); f = stdin; paginate = FALSE; /* Avoid waiting forever */ } printf("\n\ Offset 00 04 08 0C 0 4 8 C \n\ -------- ----------- ----------- ----------- ----------- -------- --------\n\ "); if (dwBase == 0xFFFFFFFFL) dwBase = 0; fseek(f, dwBase & 0xFFFFFFF0L, SEEK_SET); for (ul = dwBase & 0xFFFFFFF0L; between(dwBase & 0xFFFFFFF0L, ul, dwBase+dwLength); ul += 16) { size_t nRead; nRead = fread(table, 1, 16, f); if (!nRead) break; printf("%08lX ", ul); /* Display the hex dump */ for (u=0; u<nRead; u++) { if (!(u&3)) printf(" "); if (between(dwBase, ul+u, dwBase+dwLength)) printf("%02X ", (WORD)table[u]); else printf(" "); } for ( ; u<16; u++) { if (!(u&3)) printf(" "); printf(" "); } /* Display the character dump */ for (u=0; u<nRead; u++) { if (!(u&7)) printf(" "); #ifdef __unix__ if ( (table[u] & 0x7F) < 0x20) table[u] = ' '; #else switch (table[u]) { case '\x07': table[u] = ' '; break; case '\x08': table[u] = ' '; break; /* Backspace */ case '\x09': table[u] = ' '; break; /* Tab */ case '\x0A': table[u] = ' '; break; /* Line feed */ case '\x0D': table[u] = ' '; break; /* Carrier return */ case '\x1A': table[u] = ' '; break; default: break; } #endif if (between(dwBase, ul+u, dwBase+dwLength) && (table[u]>' ')) printf("%c", table[u]); else printf(" "); } for ( ; u<16; u++) { if (!(u&7)) printf(" "); printf(" "); } printflf(); } printflf(); return 0; }
void CommandData::ParseArg(char *Arg,wchar *ArgW) { if (IsSwitch(*Arg) && !NoMoreSwitches) if (Arg[1]=='-') NoMoreSwitches=true; else ProcessSwitch(Arg+1,(ArgW!=NULL && *ArgW!=0 ? ArgW+1:NULL)); else if (*Command==0) { strncpyz(Command,Arg,ASIZE(Command)); if (ArgW!=NULL) wcsncpy(CommandW,ArgW,ASIZE(CommandW)); #ifndef GUI *Command=etoupper(*Command); // 'I' and 'S' commands can contain case sensitive strings after // the first character, so we must not modify their case. // 'S' can contain SFX name, which case is important in Unix. if (*Command!='I' && *Command!='S') strupper(Command); #endif } else if (*ArcName==0 && *ArcNameW==0) { strncpyz(ArcName,Arg,ASIZE(ArcName)); if (ArgW!=NULL) wcsncpyz(ArcNameW,ArgW,ASIZE(ArcNameW)); } else { bool EndSeparator; // If last character is the path separator. if (ArgW!=NULL) { size_t Length=wcslen(ArgW); wchar EndChar=Length==0 ? 0:ArgW[Length-1]; EndSeparator=IsDriveDiv(EndChar) || IsPathDiv(EndChar); } else { size_t Length=strlen(Arg); char EndChar=Length==0 ? 0:Arg[Length-1]; EndSeparator=IsDriveDiv(EndChar) || IsPathDiv(EndChar); } char CmdChar=etoupper(*Command); bool Add=strchr("AFUM",CmdChar)!=NULL; bool Extract=CmdChar=='X' || CmdChar=='E'; if (EndSeparator && !Add) { strncpyz(ExtrPath,Arg,ASIZE(ExtrPath)); if (ArgW!=NULL) wcsncpyz(ExtrPathW,ArgW,ASIZE(ExtrPathW)); } else if ((Add || CmdChar=='T') && *Arg!='@') FileArgs->AddString(Arg,ArgW); else { FindData FileData; bool Found=FindFile::FastFind(Arg,ArgW,&FileData); if (!Found && *Arg=='@' && !IsWildcard(Arg,ArgW)) { FileLists=true; RAR_CHARSET Charset=FilelistCharset; #if defined(_WIN_ALL) && !defined(GUI) // for compatibility reasons we use OEM encoding // in Win32 console version by default if (Charset==RCH_DEFAULT) Charset=RCH_OEM; #endif wchar *WideArgName=(ArgW!=NULL && *ArgW!=0 ? ArgW+1:NULL); ReadTextFile(Arg+1,WideArgName,FileArgs.get(),false,true,Charset,true,true,true); } else if (Found && FileData.IsDir && Extract && *ExtrPath==0 && *ExtrPathW==0) { strncpyz(ExtrPath,Arg,ASIZE(ExtrPath)-1); AddEndSlash(ExtrPath); if (ArgW!=NULL) { wcsncpyz(ExtrPathW,ArgW,ASIZE(ExtrPathW)-1); AddEndSlash(ExtrPathW); } } else FileArgs->AddString(Arg,ArgW); } } }
int main(int argc, char *argv[]) { char *pszMyFile = NULL; char szPath[_MAX_PATH]; char szDrive[_MAX_DRIVE]; char szDir[_MAX_DIR]; char *pszDir = szDir; char szFname[_MAX_FNAME]; char szExt[_MAX_EXT]; char szBasename[_MAX_PATH]; /* Initial szFname + szExt */ int err; int iOffset; int iMax; int i; char *pszExactCaseNameFound = NULL; char *pszOtherCaseNameFound = NULL; for (i=1 ; i<argc ; i++) { if (IsSwitch(argv[i])) { /* It's a switch */ if ( streq(argv[i]+1, "?") || streq(argv[i]+1, "h") || streq(argv[i]+1, "-help") ) { /* -?: Help */ usage(); /* Display help */ return 0; } #ifndef _MSDOS if (streq(argv[i]+1, "a")) { /* -a: Append the extension */ iAppend = TRUE; continue; } if (streq(argv[i]+1, "A")) { /* -A: Replace the extension */ iAppend = FALSE; continue; } #endif #ifdef _DEBUG if (streq(argv[i]+1, "d")) { /* -d: Debug information */ DEBUG_ON(); continue; } #endif if (streq(argv[i]+1, "q")) { /* -q: Be quiet */ iQuiet = TRUE; continue; } #ifdef _DEBUG if (streq(argv[i]+1, "t")) { closedir(opendir(argv[i+1])); exit(0); } #ifdef _MSDOS if (streq(argv[i]+1, "T")) { opendir(""); for (i=0; i<_sys_nerr; i++) printf("errno=%d: %s\n", i, strerror(i)); exit(0); } #endif #endif if (streq(argv[i]+1, "v")) { /* -v: Verbose information */ iVerbose = TRUE; continue; } if (streq(argv[i]+1, "V")) { /* -V: Display the version */ printf("%s\n", VERSION); exit(0); } if (streq(argv[i]+1, "X")) { /* -X: Do not execute */ iExec = FALSE; continue; } /* Unsupported switch! */ fprintf(stderr, "Unsupported switch, ignored: %s", argv[i]); continue; } if (!pszMyFile) { pszMyFile = argv[i]; continue; } /* Unsupported argument */ fprintf(stderr, "Unsupported argument, ignored: %s", argv[i]); } if (!pszMyFile) { usage(); exit(0); } /* Check if the specified file exists. */ /* Note: The file name case matching is file system specific, _not_ OS specific. Use the access() result as a proof of existence and readability, whether the case matches or not, and independantly of the host OS. */ if (access(pszMyFile, R_OK)) { fprintf(stderr, "Error: File %s: %s!\n", pszMyFile, strerror(errno)); exit(1); } _splitpath(pszMyFile, szDrive, szDir, szFname, szExt); DEBUG_PRINTF(("\"%s\" \"%s\" \"%s\" \"%s\"\n", szDrive, szDir, szFname, szExt)); _makepath(szBasename, NULL, NULL, szFname, szExt); DEBUG_PRINTF(("szBasename = \"%s\";\n", szBasename)); if (iAppend && szExt[0]) { strcat(szFname, szExt); /* The period is already in szExt */ } if (!szDir[0]) pszDir = "."; /* Now scan all existing backups, to find the largest backup number used. */ _makepath(szPath, szDrive, pszDir, NULL, NULL); iOffset = (int)strlen(szFname) + 1; DEBUG_PRINTF(("iOffset = %d; // Backup suffix offset\n", iOffset)); iMax = 0; { DIR *pDir; struct dirent *pDE; char szPattern[_MAX_PATH]; pDir = opendir(szPath); if (!pDir) { fprintf(stderr, "Error: Directory %s: %s\n", szPath, strerror(errno)); exit(1); } _makepath(szPattern, NULL, NULL, szFname, "*"); while ((pDE = readdir(pDir))) { if (pDE->d_type != DT_REG) continue; /* We want only files */ /* Check the case of the base file */ if (!_stricmp(szBasename, pDE->d_name)) { if (!strcmp(szBasename, pDE->d_name)) { /* This can happen only once */ pszExactCaseNameFound = strdup(pDE->d_name); DEBUG_PRINTF(("// Found base name with exact case: \"%s\"\n", pszExactCaseNameFound)); } else if (!pszOtherCaseNameFound) { /* Else can happen many times */ pszOtherCaseNameFound = strdup(pDE->d_name); DEBUG_PRINTF(("// Found base name with != case: \"%s\"\n", pszOtherCaseNameFound)); } } /* Check files that match the wildcard pattern */ if (fnmatch(szPattern, pDE->d_name, FNM_CASEFOLD) == FNM_MATCH) { int i = 0; DEBUG_PRINTF(("// Found backup name: \"%s\"\n", pDE->d_name)); sscanf(pDE->d_name + iOffset, "%03d", &i); if (i > iMax) iMax = i; DEBUG_PRINTF(("iMax = %d;\n", iMax)); } } closedir(pDir); } /* Correct the file name case if needed */ /* Note: Unix file systems are case dependant, Microsoft file systems are not. But Linux accessing a Microsoft file system across the network will _also_ be case _independant_. "cat HeLlO.tXt" _will_ successfully read file hello.txt. So if the file passed the access() test above, then we _must_ correct the case now, for all operating systems _even_ for Unix. */ strcpy(szPath, pszMyFile); if (pszOtherCaseNameFound && !pszExactCaseNameFound) { DEBUG_PRINTF(("// Correcting case: \"%s\"\n", pszOtherCaseNameFound)); _splitpath(pszOtherCaseNameFound, NULL, NULL, szFname, szExt); _makepath(szPath, szDrive, szDir, szFname, szExt); if (iAppend && szExt[0]) { strcat(szFname, szExt); /* The period is already in szExt */ } } if (iVerbose && !iQuiet) printf("Backing up %s\n", szPath); /* Generate the backup file name */ sprintf(szExt, ".%03d", iMax+1); _makepath(szPath, szDrive, szDir, szFname, szExt); if (!iQuiet) printf("%s%s\n", iVerbose ? " as " : "", szPath); /* Backup the file */ err = 0; if (iExec) err = fcopy(szPath, pszMyFile); switch (err) { case 0: break; /* Success */ case 1: fprintf(stderr, "Not enough memory.\n"); break; case 2: fprintf(stderr, "Error reading from %s.\n", argv[2]); break; case 3: fprintf(stderr, "Error writing to %s.\n", argv[3]); break; default: { #if defined(_WIN32) LPVOID lpMsgBuf; if (FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ (LPTSTR) &lpMsgBuf, 0, NULL )) { fprintf(stderr, "Error. %s\n", lpMsgBuf); LocalFree( lpMsgBuf ); /* Free the buffer */ } else { fprintf(stderr, "Unexpected return value: %d\n", err); break; } #else fprintf(stderr, "Unexpected return value: %d\n", err); break; #endif break; } } return err; }
/*------------------------------------------------------ int CCmdLine::SplitLine(int argc, char **argv) parse the command line into switches and arguments returns number of switches found ------------------------------------------------------*/ int CCmdLine::SplitLine(int argc, char **argv) { clear(); StringType curParam; // current argv[x] // skip the exe name (start with i = 1) for (int i = 1; i < argc; i++) { // if it's a switch, start a new CCmdLine if (IsSwitch(argv[i])) { curParam = argv[i]; StringType arg; // look at next input string to see if it's a switch or an argument if (i + 1 < argc) { if (!IsSwitch(argv[i + 1])) { // it's an argument, not a switch arg = argv[i + 1]; // skip to next i++; } else { arg = ""; } } // add it CCmdParam cmd; cmd.m_strings.push_back(arg); // add the CCmdParam to 'this' pair<CCmdLine::iterator, bool> res = insert(CCmdLine::value_type(curParam, cmd)); } else { // it's not a new switch, so it must be more stuff for the last switch // ...let's add it CCmdLine::iterator theIterator; // get an iterator for the current param theIterator = find(curParam); if (theIterator!=end()) { (*theIterator).second.m_strings.push_back(argv[i]); } else { // ?? } } } return size(); }
/* * recursively generate the recipes for a node in the graph */ void _dxf_ExComputeRecipes(Program *p, int funcInd) { gfunc *n = FETCH_LIST(p->funcs, funcInd); int i, j, size, ntags, macro_tags=0, extra_tags, async_tags=0; gvar *gv; uint32 tcrc; gvar *out; uint32 *inTags, staticTags[STATIC_TAGS]; int varInd, *varIndp; int varInd2; ProgramVariable *pv, *inpv, *pv_key; MacroRef *mr; AsyncVars *avars; _excache fcache; _excache pvcache; Program *subP=NULL; int tag_changed = FALSE; uint32 crc = 0xFFFFFFFF; char *async_name=NULL, *name; int passthru = FALSE; char mod_cache_str[ MAX_PATH_STR_LEN ], *mod; /* Get module path string */ mod = _dxf_ExGFuncPathToCacheString( n ); if ( strlen(mod) > sizeof(mod_cache_str)-1 ) _dxf_ExDie("Module path is too long"); strcpy( mod_cache_str, mod ); check_async: if(n->flags & (MODULE_ASYNC | MODULE_ASYNCLOCAL)) { if(p->loopctl.first && (n->flags & MODULE_ASYNCLOCAL)) { if(strcmp(n->name, "GetLocal") == 0) DXReadyToRunNoExecute(mod_cache_str); } varInd = *FETCH_LIST(n->inputs, n->nin - 2); pv = FETCH_LIST(p->vars, varInd); if(!pv->gv) _dxf_ExDie("Cannot compute a cache tag from a NULL gvar"); if(n->flags & MODULE_ASYNCNAMED) { varInd2 = *FETCH_LIST(n->inputs, n->rerun_index); pv_key = FETCH_LIST(p->vars, varInd2); if(pv_key->gv && pv_key->gv->obj) { if(pv->gv->obj) DXDelete(pv->gv->obj); pv->gv->obj = DXReference(pv_key->gv->obj); } } if(!pv->gv->obj) _dxf_ExDie("Cannot compute a cache tag from a NULL gvar"); /* Put an extra reference on this input, we don't want this gvar to be deleted until the current graph finishes executing. This is incase the results were thrown out of cache and because of a switch need to run again. If this is in a loop it will get an extra ref each time through the loop which isn't needed but will get cleaned up ok in the end. */ ExReference(pv->gv); pv->refs++; async_name = DXGetString((String)pv->gv->obj); varInd = *FETCH_LIST(n->inputs, n->nin - 1); pv = FETCH_LIST(p->vars, varInd); gv = (gvar *)_dxf_ExGlobalVariableSearch(async_name); if(gv) { if(gv != pv->gv) { _dxf_ExUndefineGvar(pv->gv); _dxf_ExDefineGvar(pv->gv, gv->obj); } ExDelete(gv); } else { Object value; value = (Object) _dxfExNewInteger (0); _dxf_ExDefineGvar(pv->gv, (Object)_dxfExNewInteger(0)); _dxf_ExUpdateGlobalDict (async_name, value, 0); } /* Put an extra reference on this input, we don't want this gvar to be deleted until the current graph finishes executing. This is incase the results were thrown out of cache and because of a switch need to run again. If this is in a loop it will get an extra ref each time through the loop which isn't needed but will get cleaned up ok in the end. */ ExReference(pv->gv); pv->refs++; } if(n->ftype == F_MACRO) { subP = n->func.subP; macro_tags = SIZE_LIST(subP->macros); async_tags = SIZE_LIST(subP->async_vars); extra_tags = macro_tags + async_tags; } else if(n->flags & MODULE_LOOP) { /* to cause the cache tag of loop modules to change even though */ /* their inputs don't change, use the counter for the loop */ extra_tags = 1; } else extra_tags = 0; ntags = n->nin+extra_tags; if(ntags > STATIC_TAGS) inTags = (uint32 *)DXAllocate(ntags*sizeof(uint32)); else inTags = staticTags; /* add the crc of all of the module inputs to the total crc */ for (i = 0; i < SIZE_LIST(n->inputs); i++) { varIndp = FETCH_LIST(n->inputs, i); if(varIndp == NULL) _dxf_ExDie("Executive Inconsistency: _dxf_ExComputeRecipes"); varInd = *varIndp; inTags[i] = computeRecipe(p, varInd); ExDebug ("1", "Cache value for input %s.%d = 0x%08x ", n->name, i, inTags[i]); } if(n->ftype == F_MACRO) { for (j = 0; j < macro_tags; j++, i++) { crc = 0xFFFFFFFF; mr = FETCH_LIST(subP->macros, j); inTags[i] = _dxf_ExCRCInt(crc, mr->index); } for (j = 0; j < async_tags; j++, i++) { avars = FETCH_LIST(subP->async_vars, j); pv = FETCH_LIST(p->vars, avars->nameindx); if(!pv->gv || !pv->gv->obj) _dxf_ExDie("Cannot compute a cache tag from a NULL async name"); name = DXGetString((String)pv->gv->obj); pv = FETCH_LIST(p->vars, avars->valueindx); gv = (gvar *)_dxf_ExGlobalVariableSearch(name); if(gv) { if(gv != pv->gv) { _dxf_ExUndefineGvar(pv->gv); _dxf_ExDefineGvar(pv->gv, gv->obj); } ExDelete(gv); } else { Object value; value = (Object) _dxfExNewInteger (0); _dxf_ExDefineGvar(pv->gv, (Object)_dxfExNewInteger(0)); _dxf_ExUpdateGlobalDict (name, value, 0); } inTags[i] = computeRecipe(p, avars->valueindx); } } else if(n->flags & MODULE_LOOP) { /* to cause the cache tag of loop modules to change even though */ /* their inputs don't change, use the counter for the loop */ crc = 0xFFFFFFFF; inTags[i] = _dxf_ExCRCInt(crc, p->loopctl.counter); } if((n->flags & MODULE_PASSTHRU) && (n->nin == n->nout+1)) passthru = TRUE; if(n->flags & (MODULE_CONTAINS_STATE | MODULE_CHANGES_STATE)) { Object new_tag_obj, old_tag_obj; uint32 oldtag, newtag; newtag = _dxf_ExGenCacheTag (n->name,0,ntags,inTags); new_tag_obj = (Object)DXMakeInteger(newtag); old_tag_obj = DXGetCacheEntry(mod_cache_str, ntags, 0); if(!old_tag_obj) { DXSetCacheEntry(new_tag_obj, CACHE_PERMANENT, mod_cache_str, ntags, 0); } else { /* we don't want an extra reference on this */ DXDelete(old_tag_obj); if(!DXExtractInteger(old_tag_obj, (int *)&oldtag)) oldtag = 0; /* this means we just caused a DXReadyToRun so we know */ /* this macro will run this time, save the new cache tag */ if(oldtag == 0) { DXSetCacheEntry(new_tag_obj,CACHE_PERMANENT,mod_cache_str,ntags,0); DXDelete(old_tag_obj); } else if(oldtag != newtag) { /* An input has changed since last time, we need to */ /* cause execution of this macro and we need to recompute */ /* the cache tag. */ DXReadyToRunNoExecute(async_name); DXDelete(new_tag_obj); new_tag_obj = (Object)DXMakeInteger(0); DXSetCacheEntry(new_tag_obj,CACHE_PERMANENT,mod_cache_str,ntags,0); DXDelete(old_tag_obj); goto check_async; } else DXDelete(new_tag_obj); } } /* generate the recipes for all of the outputs from this module */ /* Update the pathtag table if module cache attribute is "cache last" */ n->tag_changed = FALSE; for (i = 0; i < SIZE_LIST(n->outputs); i++) { varIndp = FETCH_LIST(n->outputs, i); if(varIndp == NULL) _dxf_ExDie("Executive Inconsistency: _dxf_ExComputeRecipes"); varInd = *varIndp; pv = FETCH_LIST(p->vars, varInd); pv->is_output = TRUE; out = pv->gv; if (out->reccrc == 0 || (n->required != -1 && (!IsSwitch(n) || !IsFastSwitch(n)))) { /* This code is currently just intended for macrostart */ if(passthru) { varInd2 = *FETCH_LIST(n->inputs, i+1); if (varInd2 != -1) { inpv = FETCH_LIST(p->vars, varInd2); tcrc = inpv->gv->reccrc; } else tcrc = _dxf_ExGenCacheTag (n->name,i,n->nin+extra_tags,inTags); } else tcrc = _dxf_ExGenCacheTag (n->name,i,n->nin+extra_tags,inTags); if(out->reccrc != 0 && tcrc != out->reccrc) _dxf_ExUndefineGvar(out); pv->reccrc = out->reccrc = tcrc; /* make process group name part of cache tag */ if(n->procgroupid) { size = strlen (n->procgroupid); out->reccrc = EXTAG(_dxf_ExCRCByteV(out->reccrc & 0x7fffffff, (unsigned char *) n->procgroupid, 1, size)); } ExDebug ("1", "Cache value for %s.%d = 0x%08x ", n->name, i, out->reccrc); } pvcache = pv->excache; fcache = n->excache; if((n->flags & (MODULE_ASYNC | MODULE_ASYNCLOCAL)) && (pvcache == CACHE_ALL)) pvcache = pv->excache = CACHE_LAST; /* I don't think we allow the user to turn off cacheing for */ /* macros that have state in them. */ if(n->flags & MODULE_CHANGES_STATE) pvcache = pv->excache = CACHE_LAST_PERM; if(n->flags & MODULE_CONTAINS_STATE) pvcache = pv->excache = CACHE_LAST; /* object lvl cache attribute overrides function lvl cache attribute */ if (pvcache == CACHE_LAST || pvcache == CACHE_LAST_PERM) tag_changed = _dxf_ExManageCacheTable(&n->mod_path, out->reccrc, i); else if(fcache == CACHE_LAST && !pv->cacheattr) tag_changed = _dxf_ExManageCacheTable(&n->mod_path, out->reccrc, i); n->tag_changed = tag_changed; } if(n->nout == 0 && !(n->flags & MODULE_SIDE_EFFECT)) { tcrc = _dxf_ExGenCacheTag (n->name, 0, n->nin+extra_tags, inTags); n->tag_changed = _dxf_ExManageCacheTable(&n->mod_path, tcrc, 0); } if(ntags > STATIC_TAGS) DXFree(inTags); }
void CommandData::ParseArg(wchar *Arg) { if (IsSwitch(*Arg) && !NoMoreSwitches) if (Arg[1]=='-' && Arg[2]==0) NoMoreSwitches=true; else ProcessSwitch(Arg+1); else if (*Command==0) { wcsncpyz(Command,Arg,ASIZE(Command)); *Command=toupperw(*Command); // 'I' and 'S' commands can contain case sensitive strings after // the first character, so we must not modify their case. // 'S' can contain SFX name, which case is important in Unix. if (*Command!='I' && *Command!='S') wcsupper(Command); } else if (*ArcName==0) wcsncpyz(ArcName,Arg,ASIZE(ArcName)); else { // Check if last character is the path separator. size_t Length=wcslen(Arg); wchar EndChar=Length==0 ? 0:Arg[Length-1]; bool EndSeparator=IsDriveDiv(EndChar) || IsPathDiv(EndChar); wchar CmdChar=toupperw(*Command); bool Add=wcschr(L"AFUM",CmdChar)!=NULL; bool Extract=CmdChar=='X' || CmdChar=='E'; if (EndSeparator && !Add) wcsncpyz(ExtrPath,Arg,ASIZE(ExtrPath)); else if ((Add || CmdChar=='T') && (*Arg!='@' || ListMode==RCLM_REJECT_LISTS)) FileArgs.AddString(Arg); else { FindData FileData; bool Found=FindFile::FastFind(Arg,&FileData); if ((!Found || ListMode==RCLM_ACCEPT_LISTS) && ListMode!=RCLM_REJECT_LISTS && *Arg=='@' && !IsWildcard(Arg)) { FileLists=true; ReadTextFile(Arg+1,&FileArgs,false,true,FilelistCharset,true,true,true); } else if (Found && FileData.IsDir && Extract && *ExtrPath==0) { wcsncpyz(ExtrPath,Arg,ASIZE(ExtrPath)); AddEndSlash(ExtrPath,ASIZE(ExtrPath)); } else FileArgs.AddString(Arg); } } }
void CommandData::ParseArg(char *Arg,wchar *ArgW) { if (IsSwitch(*Arg) && !NoMoreSwitches) if (Arg[1]=='-') NoMoreSwitches=true; else ProcessSwitch(&Arg[1],(ArgW!=NULL && *ArgW!=0 ? &ArgW[1]:NULL)); else if (*Command==0) { strncpyz(Command,Arg,ASIZE(Command)); if (ArgW!=NULL) strncpyw(CommandW,ArgW,sizeof(CommandW)/sizeof(CommandW[0])); if (etoupper(*Command)=='S') { const char *SFXName=Command[1] ? Command+1:DefSFXName; if (PointToName(SFXName)!=SFXName || FileExist(SFXName)) strcpy(SFXModule,SFXName); else GetConfigName(SFXName,SFXModule,true); } #ifndef GUI *Command=etoupper(*Command); if (*Command!='I' && *Command!='S') strupper(Command); #endif } else if (*ArcName==0) { strncpyz(ArcName,Arg,ASIZE(ArcName)); if (ArgW!=NULL) strncpyzw(ArcNameW,ArgW,ASIZE(ArcNameW)); } else { size_t Length=strlen(Arg); char EndChar=Length==0 ? 0:Arg[Length-1]; char CmdChar=etoupper(*Command); bool Add=strchr("AFUM",CmdChar)!=NULL; bool Extract=CmdChar=='X' || CmdChar=='E'; if ((IsDriveDiv(EndChar) || IsPathDiv(EndChar)) && !Add) { strncpyz(ExtrPath,Arg,ASIZE(ExtrPath)); if (ArgW!=NULL) strncpyzw(ExtrPathW,ArgW,ASIZE(ExtrPathW)); } else if ((Add || CmdChar=='T') && *Arg!='@') FileArgs->AddString(Arg); else { struct FindData FileData; bool Found=FindFile::FastFind(Arg,NULL,&FileData); if (!Found && *Arg=='@' && !IsWildcard(Arg)) { FileLists=true; RAR_CHARSET Charset=FilelistCharset; #if defined(_WIN_32) && !defined(GUI) // for compatibility reasons we use OEM encoding // in Win32 console version by default if (Charset==RCH_DEFAULT) Charset=RCH_OEM; #endif ReadTextFile(Arg+1,FileArgs,false,true,Charset,true,true,true); } else if (Found && FileData.IsDir && Extract && *ExtrPath==0) { strcpy(ExtrPath,Arg); AddEndSlash(ExtrPath); } else FileArgs->AddString(Arg); } } }