250 lines
5.4 KiB
C++
250 lines
5.4 KiB
C++
/*
|
|
ConsoleHepler.h
|
|
Console처리용 helper object
|
|
|
|
Created 2005/06, by JiYoung
|
|
*/
|
|
|
|
|
|
//=============================================
|
|
// Console helper
|
|
//=============================================
|
|
|
|
#include <io.h>
|
|
#include <fcntl.h>
|
|
#include <sys/stat.h>
|
|
#include <assert.h>
|
|
#include <string>
|
|
|
|
#include "ConsoleHelper.h"
|
|
|
|
bool ConsoleHelper::CollectCommandOutput(char *outputBuffer, const char **commandList)
|
|
{
|
|
assert(outputBuffer!=NULL && commandList!=NULL);
|
|
|
|
std::string _key;
|
|
std::vector<std::string> arg;
|
|
const char **c=commandList;
|
|
char lineBuf[1024];
|
|
char lineBuf2[1024];
|
|
|
|
outputBuffer[0]=0;
|
|
while (*c!=NULL) {
|
|
_key=*(c++);
|
|
processConsoleCommand(_key, (int)arg.size(), arg, lineBuf);
|
|
if (lineBuf[0]!=0) {
|
|
sprintf(lineBuf2, "%s %s\n", _key.c_str(), lineBuf); // Key와 result를 join
|
|
strcat(outputBuffer, lineBuf2);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool ConsoleHelper::loadFromFile(const char *filename) // File을 load해서 setupByConfigurationText()을 부른다
|
|
{
|
|
int f=::_open(filename, _O_RDONLY | _O_TEXT, _S_IREAD | _S_IWRITE);
|
|
if (f==-1) return false;
|
|
|
|
long filesize=_lseek(f, 0, SEEK_END);
|
|
_lseek(f, 0, SEEK_SET);
|
|
|
|
char *text=new char[filesize*2];
|
|
int n=::_read(f, text, filesize*2);
|
|
text[n]=0;
|
|
|
|
bool b=setupByConfigurationText(text);
|
|
|
|
delete [] text;
|
|
|
|
::_close(f);
|
|
|
|
return b;
|
|
}
|
|
|
|
|
|
bool ConsoleHelper::saveToFile(const char *filename) // buildConfigurationText()를 부른 다음 결과를 file save한다
|
|
{
|
|
int f=::_open(filename, _O_WRONLY | _O_CREAT | _O_TRUNC | _O_TEXT, _S_IREAD | _S_IWRITE);
|
|
if (f==-1) return false;
|
|
|
|
const int BUFFERSIZE=16384;
|
|
|
|
char *buffer=new char [BUFFERSIZE];
|
|
buildConfigurationText(buffer);
|
|
if (strlen(buffer) > BUFFERSIZE-1) {
|
|
// BUFFER OVERFLOW : INCREASE BUFFER SIZE (..........)
|
|
assert(0);
|
|
}
|
|
|
|
::_write(f, buffer, (unsigned int)strlen(buffer));
|
|
::_close(f);
|
|
|
|
delete [] buffer;
|
|
|
|
return true;
|
|
}
|
|
|
|
namespace {
|
|
size_t getLine(const char *str) { // str부터 scan해서 한 라인이 끝나는 char수를 센다. \r\n포함
|
|
size_t l=0;
|
|
while ( (*str!=0)&&(*str!='\r')&&(*str!='\n') ) { str++; l++; }
|
|
while ((*str=='\r')||(*str=='\n') ) { str++; l++; }
|
|
return l;
|
|
}
|
|
|
|
size_t stripLine(const char *str, int *startPos) // str부터 scan해서, strip된 line의 start pos와 length를 돌려준다
|
|
{
|
|
// 앞에서 strip
|
|
(*startPos)=0;
|
|
while ((*str==' ')||(*str=='\t')||(*str=='\r')||(*str=='\n')) {
|
|
str++;
|
|
(*startPos)++;
|
|
}
|
|
// 뒤에서 strip
|
|
size_t len=strlen(str);
|
|
const char *pEnd=str+len-1;
|
|
while ( ((*pEnd==' ')||(*pEnd=='\t')||(*pEnd=='\r')||(*pEnd=='\n')) && (len>0) ) {
|
|
pEnd--;
|
|
len--;
|
|
}
|
|
return len;
|
|
}
|
|
}
|
|
|
|
|
|
bool ConsoleHelper::setupByConfigurationText(const char *configText)
|
|
{
|
|
// strtok를 사용하기 위해 버퍼 카피
|
|
size_t len=strlen(configText);
|
|
if (len==0) return false;
|
|
|
|
char *buffer=new char[len+1];
|
|
memcpy(buffer, configText, len);
|
|
buffer[len]=0;
|
|
|
|
const int LINESIZE=512;
|
|
char line[512];
|
|
char *linep=buffer;
|
|
char *cmdp;
|
|
char *argp;
|
|
|
|
char dummyOutputBuffer[1024];
|
|
|
|
// Get a line
|
|
int strippedPos;
|
|
size_t lineLength;
|
|
int n, m;
|
|
|
|
std::string _key;
|
|
std::string _param;
|
|
std::vector<std::string> arg;
|
|
|
|
while (*linep!=0) {
|
|
// Get a line
|
|
lineLength=getLine(linep);
|
|
assert(lineLength < LINESIZE);
|
|
strncpy(line, linep, lineLength);
|
|
line[lineLength]=0;
|
|
linep+=lineLength; // Go to next line
|
|
|
|
// Strip line
|
|
lineLength=stripLine(line, &strippedPos);
|
|
cmdp=line+strippedPos;
|
|
if (lineLength==0) continue;
|
|
cmdp[lineLength]=0;
|
|
|
|
// Remove comment
|
|
n=(int)strcspn(cmdp, "!#"); // ! 이나 #으로 시작하면 커멘트 라인
|
|
cmdp[n]=0; // 커멘트 이후 삭제
|
|
lineLength=n;
|
|
|
|
// Parse command
|
|
n=(int)strcspn(cmdp, " \t\r\n");
|
|
if (n==0) continue;
|
|
cmdp[n]=0; // Save key
|
|
_key=cmdp;
|
|
n++;
|
|
|
|
arg.clear();
|
|
while (n < (int)lineLength) {
|
|
// Skip whitespaces
|
|
m = (int)strspn(cmdp+n, " \t\r\n");
|
|
argp=cmdp+n+m;
|
|
n+=m;
|
|
// Find end-of-arg
|
|
m = (int)strcspn(argp, " \t\r\n");
|
|
n+=m;
|
|
if (m!=0) {
|
|
// Add argument
|
|
argp[m]=0;
|
|
_param=argp;
|
|
arg.push_back(_param);
|
|
n++;
|
|
}
|
|
}
|
|
// Call processor
|
|
processConsoleCommand(_key, (int)arg.size(), arg, dummyOutputBuffer);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/*
|
|
bool ConsoleHelper::buildConfigurationText(char *outputBuffer)
|
|
// Status를 읽어서 config file을 build한다.
|
|
// outputBuffer: config file을 홀드할 '충분히 큰' 버퍼
|
|
{
|
|
// EXAMPLE!!!
|
|
const char *commandList[] = { // Config file에 write할 커맨드 목록을 여기 적는다
|
|
"wttexture"
|
|
, "wtwidth"
|
|
, "wtlength"
|
|
|
|
, "wt00color0"
|
|
, "wt00color1"
|
|
, "wt00u"
|
|
, "wt00v"
|
|
|
|
, "wt01color0"
|
|
, "wt01color1"
|
|
, "wt01u"
|
|
, "wt01v"
|
|
|
|
, "wt10color0"
|
|
, "wt10color1"
|
|
, "wt10u"
|
|
, "wt10v"
|
|
|
|
, "wt11color0"
|
|
, "wt11color1"
|
|
, "wt11u"
|
|
, "wt11v"
|
|
, NULL // EOL
|
|
};
|
|
|
|
return CollectCommandOutput(outputBuffer, commandList); // 여기서 그 결과를 gather해서 outputBuffer를 만든다
|
|
}
|
|
*/
|
|
|
|
|
|
//#define KEY(str) if (
|
|
#define PRINTKEY_INT(buf, intv) { sprintf(buf, "%d", intv); }
|
|
#define PRINTKEY_FLOAT(buf, floatv) { sprintf(buf, "%f", floatv); }
|
|
#define PRINT_COLOR(buf, intv) { sprintf(buf, "0x%08x", intv);}
|
|
#define PRINT_HEX(buf, intv) { sprintf(buf, "0x%x", intv); }
|
|
|
|
|
|
|
|
/*
|
|
void ConsoleHelper::processConsoleCommand(std::string &key, int argc, std::vector<std::string> &argv, char *outputBuffer)
|
|
// Game console에서 들어온 파라미터를 redirect한다
|
|
// outputBuffer : 처리 결과를 sprintf()할 텍스트 버퍼. 여기 들어가는 결과가 콘솔 화면에 출력된다
|
|
{
|
|
|
|
}
|
|
*/
|
|
|