/* Utils.em - a small collection of useful editing macros */
/*-------------------------------------------------------------------------
I N S E R T H E A D E R
Inserts a comment header block at the top of the current function.
This actually works on any type of symbol, not just functions.
To use this, define an environment variable "MYNAME" and set it
to your email name. eg. set MYNAME=raygr
-------------------------------------------------------------------------*/
macro setEnvironment()
{
//版本判断,3.5065以下程序不支持
ProVer = GetProgramInfo();
if(ProVer.versionMinor < 50 || Prover.versionBuild < 60)
{
Msg("您的Source Insight版本太低,如需使用此工具,请安装3.50.0060及以上版。");
stop
}
initGlobal();
hProj = GetCurrentProj();
dir_proj = GetProjDir(hProj);
//寻找代码目录
depend_file = cat(dir_proj, "\\Build\\depend");
msg(depend_file);
//depend文件不存在,说明代码和source insight工程不在一个文件夹,则询问
if(0 == ifExist(depend_file))
{
dir_proj = searchDir();
}
Msg(dir_proj);
if(-1 == dir_proj)
{
dir_proj = Ask("请输入当前工程的代码目录,如'D:\\Code\\P_2011.05.04_XQ_2.66");
}
if(strmid(dir_proj, strlen(dir_proj) - 1, strlen(dir_proj)) == "\\")
{
dir_proj = strmid(dir_proj, 0, strlen(dir_proj) - 1);
}
//向depend文件写入命令
depend_file = cat(dir_proj, "\\Build\\depend");
cmd_count = writeMakeFile(depend_file);
//向depend_ti文件写入命令
depend_file = cat(dir_proj, "\\Build\\depend_ti");
writeMakeFile(depend_file);
//modFile();
Msg("请在您的编译路劲例键入编译命令,并加上check参数,如:make OEM_VENDOR=honeyWell check");
//向工程添加环境变量
con_file = cat(dir_proj, "\\defined.all");
setCondition(hProj, con_file);
con_file = cat(dir_proj, "\\defined");
setCondition(hProj, con_file);
//从depend文件中清除linux命令
depend_file = cat(dir_proj, "\\Build\\depend");
restoreMakeFile(depend_file);
depend_file = cat(dir_proj, "\\Build\\depend_ti");
restoreMakeFile(depend_file);
con_file = cat(dir_proj, "\\defined");
if(0 != ifExist(con_file))
{
SyncProjEx(hProj, 0, 1, 0);
Msg("环境变量已经设定。");
}
else
{
Msg("未检测到临时文件defined和defined.all是否编译路径有误?");
}
}
macro clearEnviroment()
{
ProVer = GetProgramInfo();
if(PorVer.versionMinor < 50 || Prover.versionBuild < 60)
{
Msg("您的Source Insight版本太低,如需使用此工具,请安装3.50.0060及以上版。");
stop
}
hProj = GetCurrentProj();
dir_proj = GetProjDir(hProj);
//寻找代码目录
depend_file = cat(dir_proj, "\\Build\\depend");
//depend文件不存在,说明代码和Source Insight工程不在一个文件夹,则询问
if(0 == ifExist(depend_file))
{
dir_proj = searchDir();
}
if(-1 == dir_proj)
{
dir_proj = Ask("请输入当前工程的代码目录,如'D:\\Code\\P_2011.05.04_XQ_2.66");
}
if(strmid(dir_proj, strlen(dir_proj) - 1, strlen(dir_proj)) == "\\")
{
dir_proj = strmid(dir_proj, 0, strlen(dir_proj) - 1);
}
//根据宏名列表文件,清除已经存在的环境变量
con_file = cat(dir_proj, "\\defined.all");
clearCondition(hProj, con_file);
con_file = cat(dir_proj, "\\defined");
clearCondition(hProj, con_file);
SyncProjEx(hProj, 0, 1, 0);
//清理中间文件,避免对下次产生干扰,但保留clsList用于清理环境变量
com_str = cat("cmd /C \"del ", cat(dir_proj, "\\defined.all\""));
RunCmdLine(com_str, dir_proj, 1);
com_str = cat("cmd /C \"del ", cat(dir_proj, "\\defined\""));
RunCmdLine(com_str, dir_proj, 1);
Msg("已经完成清理已有的!");
}
macro nameOf(str)
{
pos = 0;
while(pos<strlen(str))
{
if(strmid(str, pos, pos+1) == "=")
break;
pos = pos + 1;
}
if(strlen(str) <= 2)
{
return strmid(str, 0, pos);
}
else if(strmid(str, 0, 2) == "-D" || strmid(str, 0, 2) == "-U")
{
return strmid(str, 2, pos);
}
else
{
return strmid(str, 0, pos);
}
}
macro valueOf(str)
{
pos = 0;
while(pos < strlen(str))
{
if(strmid(str, pos, pos+1) == "=")
break;
pos = pos + 1;
}
if(strlen(str) <= 2)
{
return 0;
}
else if(strmid(str, 0, 2) == "-D" && strlen(str) == pos)
{
return 1;
}
else if(strmid(str, 0, 2) == "-D" && strlen(str) != pos)
{
return strmid(str, pos+1, strlen(str));
}
else
{
return 0;
}
}
//判断文件是否存在,0代表不存在,1代表存在
macro ifExist(file)
{
hbuf = openBuf(file);
if(0 == hbuf)
{
return 0;
}
else
{
closeBuf(hbuf);
return 1;
}
}
macro lineOfFile(file, str)
{
if(0 == ifExist(file))
{
return 0;
}
else
{
hbuf = openBuf(file);
ln_cnt = GetBufLineCount(hbuf);
ln = 0;
while(ln < ln_cnt)
{
if(str == GetBufLine(hbuf, ln))
return ln;
ln = ln + 1;
}
CloseBuf(hbuf);
return 0;
}
}
macro initGlobal()
{
PutEnv("cmd_count", "5");//需要插入的命令行数
PutEnv("cmd_str0", "check:");
PutEnv("cmd_str1", "\t-\@echo Collecting condition variable .......';find ../../ -name *.cpp -exec grep -E '^\\s*#if|^\\s*#elif' {} \\; < ../../tmp ;");
PutEnv("cmd_str2", "\t-\@cat ../../tmp| grep -E '^\\s*#[^\\/]+' - o | sed -r 's/\\/\\||&&/\\n/g' | sed -r 's/#[a-z]+|defined|\\(|\\)|\s+|!|[0-9]*\\s*(>|<|=|<=|>=|==)\\s*[0-9]*|\\s*|\"//g' > ../../tmp1;");
PutEnv("cmd_str3", "\t-\@cat ../../tmp1| sed -r '/^(0|1)?$$/d' | sort -u | sed -r 's/(.*)/-U\\1/g' > ../../defined.all");
PutEnv("cmd_str4", "\t-\@echo $(CFLAGS)|sed -r 's/(-[a-zA-Z])/\\n\\1/g' | grep -E '(-D|-U).*' -o | sed -r 's/=.*|\\s+//g' > ../../defined;rm ../../tmp*;");
}
macro restoreMakeFile(depend_file)
{
str = GetEnv("cmd_str0");
ln = lineOfFile(depend_file, str);
count = GetEnv("cmd_count");
if(0 == ifExist(depend_file) || ln == 0)
{
return 0;
}
else
{
hbuf = OpenBuf(depend_file);
ln = GetBufLineCount(hbuf);
i = ln;
while(i < ln - count)
{
DelBufLine(hbuf, i - 1);
i = i - 1;
}
SaveBuf(hbuf);
CloseBuf(hbuf);
return count;
}
}
//向depend文件写入linux命令(用于提取宏以及处理),返回插入命令的行数
macro writeMakeFile(depend_file)
{
str = Getenv("cmd_str0");
ln = lineOfFile(depend_file, str);
cmdLnCnt = GetEnv("cmd_count");
if(0 == ln)
{
if(0 == depend_file)
{
return 0;
}
else if(0 == ifExist(depend_file))
{
return 0;
}
else
{
hbuf = OpenBuf(depend_file);
ln = GetBufLineCount(hbuf);
i = cmdLnCnt - 1;
while(i >= 0)
{
InsBufLine(hbuf, ln, GetEnv(cat("cmd_str", i)));
i = i - 1;
}
SaveBuf(hbuf);
CloseBuf(hbuf);
return count;
}
}
else
{
return cmdLnCnt;
}
}
//根据file的内容,向hProj添加环境变量
macro setCondition(hProj, con_file)
{
ln = 0;
if(ifExist(con_file))
{
hbuf = OpenBuf(con_file);
ln_cnt = GetBufLineCount(hbuf)
while(ln < ln_cnt)
{
str = GetBufLine(hbuf, ln);
if(str != " ")
{
DeleteConditionVariable(hProj, nameOf(str));
AddConditionVariable(hProj, nameOf(str), valueOf(str));
}
ln = ln + 1;
}
CloseBuf(hbuf);
}
return ln;
}
//清除工程内,file文件制定的环境变量,返回删除掉的变量数
macro clearCondition(hProj, file)
{
if(0 == ifExist(file))
{
return 0;
}
else
{
hbuf = OpenBuf(file);
ln_cnt = GetBufLineCount(hbuf);
ln = 0;
while(ln < ln_cnt)
{
str = GetBufLine(hbuf, ln);
DeleteConditionVariable(hProj, nameOf(str));
ln = ln + 1;
}
CloseBuf(hbuf);
//SyncProjEx(hproj, 0, 1, 0);
return ln;
}
}
macro searchDir()
{
hbuf = GetCurrentBuf();
dir_str = GetbufName(hbuf);
Msg(dir_str);
pos = strlen(dir_str) - 1;
Msg(pos);
while(pos > 0)
{
while(pos > 0)
{
if(strmid(dir_str, pos, pos + 1) == "\\")
{
break;
}
pos = pos - 1;
}
if(ifExist(cat(strmid(dir_str, 0, pos), "\\Build\\depend")))
{
break;
}
pos = pos - 1;
}
if(pos > 0)
{
return strmid(dir_str, 0, pos);
}
else
{
return -1;
}
}
macro modFile()
{
hbuf = GetCurrentBuf();
ln_cnt = GetBufLineCount(hbuf);
if(GetBufLine(hbuf, ln_cnt - 1) == " ")
{
DelBufLine(hbuf, ln_cnt - 1);
}
else
{
AppendBufLine(hbuf, " ");
}
SaveBuf(hbuf);
}
macro diff()
{
filename = GetBufName(GetCurrentBuf())
path = strmid(filename, 0, getFileName(filename));
cmdline = cat(cat("cmd /C \"TortoiseProc.exe /command:diff /path:\"", filename), "\"\"");
//cmdline = cat(cat("TortoiseProc.exe /command:diff /path:\"", filename), "\"");
RunCmdLine(cmdline, path, 0);
}
macro log()
{
filename = GetBufName(GetCurrentBuf())
path = strmid(filename, 0, getFileName(filename));
cmdline = cat(cat("cmd /C \"TortoiseProc.exe /command:log /path:\"", filename), "\"\"");
//cmdline = cat(cat("TortoiseProc.exe /command:log /path:\"", filename), "\"");
RunCmdLine(cmdline, path, 0);
}
macro explorer()
{
filename = GetBufName(GetCurrentBuf())
path = strmid(filename, 0, getFileName(filename));
cmdline = cat(cat("explorer /select,\"", filename), "\"");
RunCmdLine(cmdline, path, 0);
}
macro getFileName(str)
{
//倒序查找"\"
pos = strlen(str) - 1;
while(pos >= 0)
{
if(strmid(str, pos, pos + 1) == "\\")
{
return pos;
}
pos = pos - 1;
}
}
macro InsertHeader()
{
// Get the owner's name from the environment variable: MYNAME.
// If the variable doesn't exist, then the owner field is skipped.
szMyName = getenv(MYNAME)
// Get a handle to the current file buffer and the name
// and location of the current symbol where the cursor is.
hbuf = GetCurrentBuf()
szFunc = GetCurSymbol()
ln = GetSymbolLine(szFunc)
// begin assembling the title string
sz = "/* "
/* convert symbol name to T E X T L I K E T H I S */
cch = strlen(szFunc)
ich = 0
while (ich < cch)
{
ch = szFunc[ich]
if (ich > 0)
if (isupper(ch))
sz = cat(sz, " ")
else
sz = cat(sz, " ")
sz = Cat(sz, toupper(ch))
ich = ich + 1
}
sz = Cat(sz, " */")
InsBufLine(hbuf, ln, sz)
InsBufLine(hbuf, ln+1, "/*-------------------------------------------------------------------------")
/* if owner variable exists, insert Owner: name */
if (strlen(szMyName) > 0)
{
InsBufLine(hbuf, ln+2, " Owner: @szMyName@")
InsBufLine(hbuf, ln+3, " ")
ln = ln + 4
}
else
ln = ln + 2
InsBufLine(hbuf, ln, " ") // provide an indent already
InsBufLine(hbuf, ln+1, "-------------------------------------------------------------------------*/")
// put the insertion point inside the header comment
SetBufIns(hbuf, ln, 4)
}
/* InsertFileHeader:
Inserts a comment header block at the top of the current function.
This actually works on any type of symbol, not just functions.
To use this, define an environment variable "MYNAME" and set it
to your email name. eg. set MYNAME=raygr
*/
macro InsertFileHeader()
{
szMyName = getenv(MYNAME)
hbuf = GetCurrentBuf()
InsBufLine(hbuf, 0, "/*-------------------------------------------------------------------------")
/* if owner variable exists, insert Owner: name */
InsBufLine(hbuf, 1, " ")
if (strlen(szMyName) > 0)
{
sz = " Owner: @szMyName@"
InsBufLine(hbuf, 2, " ")
InsBufLine(hbuf, 3, sz)
ln = 4
}
else
ln = 2
InsBufLine(hbuf, ln, "-------------------------------------------------------------------------*/")
}
// Inserts "Returns True .. or False..." at the current line
macro ReturnTrueOrFalse()
{
hbuf = GetCurrentBuf()
ln = GetBufLineCur(hbuf)
InsBufLine(hbuf, ln, " Returns True if successful or False if errors.")
}
/* Inserts ifdef REVIEW around the selection */
macro IfdefReview()
{
IfdefSz("REVIEW");
}
/* Inserts ifdef BOGUS around the selection */
macro IfdefBogus()
{
IfdefSz("BOGUS");
}
/* Inserts ifdef NEVER around the selection */
macro IfdefNever()
{
IfdefSz("NEVER");
}
// Ask user for ifdef condition and wrap it around current
// selection.
macro InsertIfdef()
{
sz = Ask("Enter ifdef condition:")
if (sz != "")
IfdefSz(sz);
}
macro InsertCPlusPlus()
{
IfdefSz("__cplusplus");
}
// Wrap ifdef <sz> .. endif around the current selection
macro IfdefSz(sz)
{
hwnd = GetCurrentWnd()
lnFirst = GetWndSelLnFirst(hwnd)
lnLast = GetWndSelLnLast(hwnd)
hbuf = GetCurrentBuf()
InsBufLine(hbuf, lnFirst, "#ifdef @sz@")
InsBufLine(hbuf, lnLast+2, "#endif /* @sz@ */")
}
// Delete the current line and appends it to the clipboard buffer
macro KillLine()
{
hbufCur = GetCurrentBuf();
lnCur = GetBufLnCur(hbufCur)
hbufClip = GetBufHandle("Clipboard")
AppendBufLine(hbufClip, GetBufLine(hbufCur, lnCur))
DelBufLine(hbufCur, lnCur)
}
// Paste lines killed with KillLine (clipboard is emptied)
macro PasteKillLine()
{
Paste
EmptyBuf(GetBufHandle("Clipboard"))
}
// delete all lines in the buffer
macro EmptyBuf(hbuf)
{
lnMax = GetBufLineCount(hbuf)
while (lnMax > 0)
{
DelBufLine(hbuf, 0)
lnMax = lnMax - 1
}
}
// Ask the user for a symbol name, then jump to its declaration
macro JumpAnywhere()
{
symbol = Ask("What declaration would you like to see?")
JumpToSymbolDef(symbol)
}
// list all siblings of a user specified symbol
// A sibling is any other symbol declared in the same file.
macro OutputSiblingSymbols()
{
symbol = Ask("What symbol would you like to list siblings for?")
hbuf = ListAllSiblings(symbol)
SetCurrentBuf(hbuf)
}
// Given a symbol name, open the file its declared in and
// create a new output buffer listing all of the symbols declared
// in that file. Returns the new buffer handle.
macro ListAllSiblings(symbol)
{
loc = GetSymbolLocation(symbol)
if (loc == "")
{
msg ("@symbol@ not found.")
stop
}
hbufOutput = NewBuf("Results")
hbuf = OpenBuf(loc.file)
if (hbuf == 0)
{
msg ("Can't open file.")
stop
}
isymMax = GetBufSymCount(hbuf)
isym = 0;
while (isym < isymMax)
{
AppendBufLine(hbufOutput, GetBufSymName(hbuf, isym))
isym = isym + 1
}
CloseBuf(hbuf)
return hbufOutput
}