´ÙÀ½Àº SQL ºÐ¼®±â¸¦ ÀÛ¼ºÇغ¸ÀÚ. CParseSql Ŭ·¡½º´Â ´ÙÀ½°ú °°ÀÌ ¼±¾ðµÈ´Ù.
class CParseSql : public CParse
{
public:
CParseSql();
~CParseSql() {};
TCHAR *GetInfo(int iIndex);
private:
void ParseLine(CApiEdit &ae,int nLine);
BOOL IsKeyword(CApiEdit &ae,int s, int e);
BOOL IsType(CApiEdit &ae,int s, int e);
};
¾Õ¼ ÀÛ¼ºÇÑ µÎ °³ÀÇ ºÐ¼®±â¿Í °ÅÀÇ ºñ½ÁÇÏ´Ù. C ¾ð¾î¿¡ ´ëÇÑ SQL ¹®¹ýÀÇ Æ¯Â¡À» °£´ÜÇÏ°Ô ¿ä¾àÇغ¸¸é ´ÙÀ½°ú °°´Ù.
¨ç ÇÑ ÁÙ ÁÖ¼®ÀÌ --·Î µÇ¾î ÀÖ´Ù.
¨è ÇÁ¸®ÇÁ·Î¼¼½º ½ºÅ¸ÀÏ ´ë½Å ŸÀÔ ½ºÅ¸ÀÏÀÌ ÇÊ¿äÇÏ´Ù.
¨é ¹®ÀÚ¿ Ç¥ÇöÀº °ãµû¿ÈÇ¥ ´ë½Å Ȭµû¿ÈÇ¥°¡ »ç¿ëµÈ´Ù.
¨ê È®Àå¿À» Ç¥ÇöÇÏ´Â ¹æ¹ýÀÌ ´Ù¸£´Ù. µû¿ÈÇ¥ ÀÚü´Â µÎ °³ÀÇ ¿¬¼ÓÀûÀÎ µû¿ÈÇ¥·Î Ç¥ÇöÇÑ´Ù.
¨ë ¿£ÅÍ ±âÈ£¿¡ ÀÇÇØ ¹®ÀÚ¿ÀÌ Á¾·áµÇÁö ¾Ê´Â´Ù.
ÀÌ·± Â÷ÀÌÁ¡¿¡ ÀÇÇØ ParseLine ÇÔ¼ö°¡ ´Þ¶óÁö°Ô µÈ´Ù. Ŭ·¡½ºÀÇ ±¸Çö ÄÚµå´Â ´ÙÀ½°ú °°´Ù. ÄÚµå ¸®½ºÆ® ÀÌ»óÀÇ ¼³¸íÀº ÇÊ¿äÄ¡ ¾ÊÀ» °ÍÀ¸·Î »ý°¢µÈ´Ù.
enum {
SQL_CON_NORMAL,
SQL_CON_BLOCKCOMMENT,
SQL_CON_LINECOMMENT,
SQL_CON_STRING
};
enum {
SQL_STYLE_NORMAL,
SQL_STYLE_COMMENT,
SQL_STYLE_STRING,
SQL_STYLE_NUMBER,
SQL_STYLE_KEYWORD,
SQL_STYLE_TYPE
};
CParseSql::CParseSql()
{
lstrcpy(arStyle[0].name,"º¸Åë");
arStyle[0].fore=(DWORD)-1;
lstrcpy(arStyle[1].name,"ÁÖ¼®");
arStyle[1].fore=RGB(0,0,0);
arStyle[1].back=RGB(192,192,192);
lstrcpy(arStyle[2].name,"¹®ÀÚ¿");
arStyle[2].fore=RGB(0,128,0);
lstrcpy(arStyle[3].name,"¼ýÀÚ");
arStyle[3].fore=RGB(255,0,0);
lstrcpy(arStyle[4].name,"Å°¿öµå");
arStyle[4].fore=RGB(0,0,255);
lstrcpy(arStyle[5].name,"ŸÀÔ");
arStyle[5].fore=RGB(0,255,0);
}
TCHAR *CParseSql::GetInfo(int iIndex)
{
switch (iIndex) {
case 0:
return (TCHAR *)3;
case 1:
return TEXT(" \t\r\n\"\¡¯.,<>:;/()[]{}~!@#$%^&*-+?$");
case 2:
return TEXT("--");
case 3:
return TEXT("/*");
case 4:
return TEXT("*/");
case 5:
return TEXT("");
case 6:
return TEXT("");
}
return 0;
}
void CParseSql::ParseLine(CApiEdit &ae,int nLine)
{
DWORD Context;
int s,e,i;
int nUnit=0;
int idpos,idend;
if (pInfo[nLine].pUnit[0].pos != -1)
return;
if (nLine == 0) {
Context=SQL_CON_NORMAL;
} else {
Context=pInfo[nLine-1].Context;
}
s=ae.pLine[nLine].Start;
e=ae.pLine[nLine].End;
idpos=s;
switch(Context) {
case SQL_CON_NORMAL:
MakeParseInfo(nLine,nUnit,s,SQL_STYLE_NORMAL);
break;
case SQL_CON_STRING:
MakeParseInfo(nLine,nUnit,s,SQL_STYLE_STRING);
break;
case SQL_CON_BLOCKCOMMENT:
MakeParseInfo(nLine,nUnit,s,SQL_STYLE_COMMENT);
break;
case SQL_CON_LINECOMMENT:
if (ae.pLine[nLine].nLine != 0) {
MakeParseInfo(nLine,nUnit,s,SQL_STYLE_COMMENT);
goto EndParse;
} else {
MakeParseInfo(nLine,nUnit,s,SQL_STYLE_NORMAL);
Context=SQL_CON_NORMAL;
break;
}
}
for (i=s;i<e;i++) {
switch(Context) {
case SQL_CON_NORMAL:
if (ae.buf[i]==¡®/¡¯ && ae.buf[i+1]==¡®*¡¯) {
MakeParseInfo(nLine,nUnit,i,SQL_STYLE_COMMENT);
i++;
Context=SQL_CON_BLOCKCOMMENT;
continue;
}
if (ae.buf[i]==¡®-¡¯ && ae.buf[i+1]==¡®-¡¯) {
MakeParseInfo(nLine,nUnit,i,SQL_STYLE_COMMENT);
Context=SQL_CON_LINECOMMENT;
goto EndParse;
}
if (ae.buf[i]==¡®\¡¯¡¯) {
MakeParseInfo(nLine,nUnit,i,SQL_STYLE_STRING);
Context=SQL_CON_STRING;
continue;
}
if (strchr(GetInfo(1),ae.buf[i]) || i==e-1) {
if (i==e-1 && !strchr(GetInfo(1),ae.buf[i])) {
idend=i;
} else {
idend=i-1;
}
if (idend-idpos+1 >= 1) {
if (IsKeyword(ae,idpos,idend)) {
MakeParseInfo(nLine,nUnit,idpos,SQL_STYLE_KEYWORD);
MakeParseInfo(nLine,nUnit,idend+1,SQL_STYLE_NORMAL);
} else
if (IsNumber(ae,idpos,idend)) {
MakeParseInfo(nLine,nUnit,idpos,SQL_STYLE_NUMBER);
MakeParseInfo(nLine,nUnit,idend+1,SQL_STYLE_NORMAL);
} else
if (IsType(ae,idpos,idend)) {
MakeParseInfo(nLine,nUnit,idpos,SQL_STYLE_TYPE);
MakeParseInfo(nLine,nUnit,idend+1,SQL_STYLE_NORMAL);
}
}
idpos=i+1;
}
continue;
case SQL_CON_BLOCKCOMMENT:
if (ae.buf[i]==¡®*¡¯ && ae.buf[i+1]==¡®/¡¯) {
i++;
MakeParseInfo(nLine,nUnit,i+1,SQL_STYLE_NORMAL);
Context=SQL_CON_NORMAL;
idpos=i+1;
}
continue;
case SQL_CON_STRING:
if (ae.buf[i]==¡®\¡¯¡¯) {
if (ae.buf[i+1]==¡®\¡¯¡¯) {
i++;
continue;
} else {
MakeParseInfo(nLine,nUnit,i+1,SQL_STYLE_NORMAL);
Context=SQL_CON_NORMAL;
idpos=i+1;
}
}
continue;
}
}
EndParse:
pInfo[nLine].Context=Context;
}
BOOL CParseSql::IsKeyword(CApiEdit &ae,int s, int e)
{
static TCHAR *keyword="abs acos all alter and any ascii "
"asin atan atn2 avg backup begin between break case "
"cast ceiling charindex checkpoint checksum checksum_agg "
"close coalesce collate collationproterty col_length "
"col_name columnproperty commit constraint convert contains containstable "
"continue cos cot count count_big create current_timestamp "
"current_user cursor cursor_status database databaseproperty "
"databasepropertyex datalength dateadd datediff datename "
"datepart day db_id db_name dbcc deallocate declare "
"default degrees delete deny difference drop dump else "
"end execute exists exp fetch file_id file_name "
"filegroup_id filegroup_name filegroupproperty fileproperty "
"floor formatmessage freetext freetexttable from function "
"getansinull getdate getutcdate go goto grant group "
"grouping having if in index insert isdate isnull "
"isnumeric key kill left len like load log log10 lower "
"ltrim max min month nchar newid not null nullif numeric "
"open or order parsename patindex permissions pi power primary "
"print procedure quotename radians raiserror rand readtext "
"reconfigure replace replicate restore return reverse revoke "
"right rollback round rtrim rule save schema select set "
"setuser shutdown sign sin some soundex space square sqrt "
"statistics stdev stdevp str stuff substring sum table "
"tan textptr textvalid transaction trigger trigger_nestlevel "
"truncate unicode union update updatetext upper use user "
"var varp view waitfor where while work writetext year " ;
return IsStringExist(keyword,ae.buf+s,e-s+1,FALSE);
}
BOOL CParseSql::IsType(CApiEdit &ae,int s, int e)
{
static TCHAR *type="bigint binary bit char datetime "
"decimal float image int nchar ntext numeric "
"nvarchar money real smalldatetime smallint smallmoney "
"sql_variant text timestamp tinyint uniqueidentifier "
"varbinary varchar ";
return IsStringExist(type,ae.buf+s,e-s+1,FALSE);
}