필자의 프로젝트가 계속 증가하는 커맨드 라인 인수 목록을 지원하기 위해 수 년 동안 커져온 커다란 (악몽 읽기) 메소드가있다. 나는 인수 당 짧은 blurbs에 대한 readme 문서의 여러 페이지를 의미합니다.긴 명령 행 테스트 메소드 분리하기
각 기능을 추가 했으므로 필자는 해당 방법에 몇 줄을 추가하여 해당 인수를 처리하는 방법을 간단하게 "등록"했습니다.
그러나이 방법은보기 흉하고 버그가 발생하기 쉽고 이해하기 어렵습니다. 다음은 현재 이것을 처리하는 두 가지 메소드 중 짧은 것의 예입니다.
//All double dash arguments modify global options of the program,
//such as --all --debug --timeout etc.
void consoleParser::wordArgParse(std::vector<criterion *> *results)
{
TCHAR const *compareCurWordArg = curToken.c_str()+2;
if (!_tcsicmp(compareCurWordArg,_T("all")))
{
globalOptions::showall = TRUE;
} else if (!_tcsnicmp(compareCurWordArg,_T("custom"),6))
{
if (curToken[9] == L':')
{
globalOptions::display = curToken.substr(10,curToken.length()-11);
} else
{
globalOptions::display = curToken.substr(9,curToken.length()-10);
}
} else if (*compareCurWordArg == L'c' || *compareCurWordArg == L'C')
{
if (curToken[3] == L':')
{
globalOptions::display = curToken.substr(5,curToken.length()-6);
} else
{
globalOptions::display = curToken.substr(4,curToken.length()-5);
}
} else if (!_tcsicmp(compareCurWordArg,_T("debug")))
{
globalOptions::debug = TRUE;
} else if (!_tcsicmp(compareCurWordArg,L"expand"))
{
globalOptions::expandRegex = false;
} else if (!_tcsicmp(compareCurWordArg,L"fileLook"))
{
globalOptions::display = L"---- #f ----#nCompany: #d#nFile Description: #e#nFile Version: #g"
L"#nProduct Name: #i#nCopyright: #j#nOriginal file name: #k#nFile Size: #u#nCreated Time: #c"
L"#nModified Time: #m#nAccessed Time: #a#nMD5: #5#nSHA1: #1";
} else if (!_tcsicmp(compareCurWordArg,_T("peinfo")))
{
globalOptions::display = _T("[#p] #f");
} else if (!_tcsicmp(compareCurWordArg,L"enable-filesystem-redirector-64"))
{
globalOptions::disable64Redirector = false;
} else if (!_tcsnicmp(compareCurWordArg,_T("encoding"),8))
{
//Performance enhancement -- encoding compare only done once.
compareCurWordArg += 8;
if (!_tcsicmp(compareCurWordArg,_T("acp")))
{
globalOptions::encoding = globalOptions::ENCODING_TYPE_ACP;
} else if (!_tcsicmp(compareCurWordArg,_T("oem")))
{
globalOptions::encoding = globalOptions::ENCODING_TYPE_OEM;
} else if (!_tcsicmp(compareCurWordArg,_T("utf8")))
{
globalOptions::encoding = globalOptions::ENCODING_TYPE_UTF8;
} else if (!_tcsicmp(compareCurWordArg,_T("utf16")))
{
globalOptions::encoding = globalOptions::ENCODING_TYPE_UTF16;
} else
{
throw eMsg(L"Unrecognised encoding word argument!\r\nValid choices are --encodingACP --encodingOEM --encodingUTF8 and --encodingUTF16. Terminate.");
}
} else if (!_tcsnicmp(compareCurWordArg,L"files",5))
{
compareCurWordArg += 5;
if (*compareCurWordArg == L':') compareCurWordArg++;
std::wstring filePath(compareCurWordArg);
globalOptions::regexes.insert(globalOptions::regexes.end(), new filesRegexPlaceHolder);
results->insert(results->end(),new filesRegexPlaceHolder);
boost::algorithm::trim_if(filePath,std::bind2nd(std::equal_to<wchar_t>(),L'"'));
loadFiles(filePath);
} else if (!_tcsicmp(compareCurWordArg,_T("full")))
{
globalOptions::fullPath = TRUE;
} else if (!_tcsicmp(compareCurWordArg,_T("fs32")))
{
globalOptions::disable64Redirector = false;
} else if (!_tcsicmp(compareCurWordArg,_T("long")))
{
globalOptions::display = _T("#t #s #m #f");
globalOptions::summary = TRUE;
} else if (!_tcsnicmp(compareCurWordArg,_T("limit"),5))
{
compareCurWordArg += 5;
if (*compareCurWordArg == _T(':'))
compareCurWordArg++;
globalOptions::lineLimit = _tcstoui64(compareCurWordArg,NULL,10);
if (!globalOptions::lineLimit)
{
std::wcerr << eMsg(L"Warning: You are limiting to infinity lines. Check one of your --limit options!\r\n");
}
} else if (!_tcsicmp(compareCurWordArg,_T("short")))
{
globalOptions::display = _T("#8");
} else if (!_tcsicmp(compareCurWordArg,_T("summary")))
{
globalOptions::summary = TRUE;
} else if (!_tcsicmp(compareCurWordArg,_T("norecursion")))
{
globalOptions::noSubDirs = TRUE;
} else if (!_tcsnicmp(compareCurWordArg,_T("timeout"),7))
{
compareCurWordArg += 7;
if (*compareCurWordArg == _T(':'))
compareCurWordArg++;
globalOptions::timeout = _tcstoul(compareCurWordArg,NULL,10);
if (!globalOptions::timeout)
{
std::wcerr << eMsg(L"Warning: You are limiting to infinite time. Check one of your --timeout options!\r\n");
}
} else if (!_tcsnicmp(compareCurWordArg,_T("tx"),2))
{
compareCurWordArg += 2;
if (*compareCurWordArg == _T(':'))
compareCurWordArg++;
globalOptions::timeout = _tcstoul(compareCurWordArg,NULL,10);
if (!globalOptions::timeout)
{
std::wcerr << eMsg(L"Warning: You are limiting to infinite time. Check one of your --timeout options!\r\n");
}
} else
{
throw eMsg(L"Could not understand word argument! Ensure all of your directives are spelled correctly. Terminate.");
}
}
나는 긴 것을 게시 하겠지만 500 라인을 넘습니다.
이 특정 문제를 해결하는 더 좋은 방법이 있습니까? 아니면 그냥 긴 방법으로 남겨 두어야합니까?
EDIT : 토큰 화 라이브러리를 찾고 있지 않습니다. 이미 더러운 작업을 수행했습니다. 더 큰 더러운 메서드에서 스텁 메서드를 만드는 것이 의미가 있을지 궁금합니다.
Billy3는
부스트 라이브러리 논의? [-files "C : \ Documents and Settings \ User \ Desktop \ InFile.txt"] 토큰이 인용되지 않고 공백을 포함하는지 확인합니다. 따옴표는 토큰 자체에서 시작됩니다. –
사용해보기, 정말 사용하기 간단합니다. –
시도해보십시오. 현재 시나리오에서는 작동하지 않습니다. Project는 명령 줄에 재귀 적 파서를 구현합니다. 예 : 'progname C : \ Windows \ * AND -tf OR * .dll OR * .exe'는 파일 (폴더가 아님)이거나 .dll 또는 .exe 인 모든 파일을 인쇄합니다. 부스트 라이브러리는 쌍으로 제공되는 옵션을 중심으로 설계되었습니다. 죄송 해요. –