2010年8月8日
1 --打开日志文件
2 svnlogPath = assert(arg[3], "路径为空");
3 svnlog = assert(io.open(svnlogPath, "r"), "打开日志文件失败!");
4
5 --日志是否为空
6 if svnlog:read(0) == nil then
7 --日志为空
8 svnlog:close();
9 io.stderr:write("请填写日志!");
10 os.exit(1);
11 else
12 --检查日志内容
13 local count = 1;
14 while true do
15 local line = svnlog:read();
16
17 if line == nil then
18 break;
19 end
20
21 --查找是否匹配
22 if string.len(line) > 0 then
23 if not string.find(line, ".:%s*%S") then
24 if not string.find(line, ".\239\188\154%s*%S") then
25 svnlog:close();
26 io.stderr:write("日志没有填写完整");
27 os.exit(1);
28 end
29 end
30 end
31
32 count = count + 1;
33 end
34
35 --检查行数是否>6行
36 if count < 6 then
37 svnlog:close();
38 io.stderr:write("请填写完整日志! ");
39 os.exit(1);
40 end
41
42 end
43
44 svnlog:close();
45
2009年11月8日
我发现串口类cnComm在串口转USB的设备上有些能工作(USB430),但在EZ430上却不能工作,很奇怪!我怀疑是硬件问题,毕竟串口转USB硬件上有差别。我发现cnComm的线程一直收到一些不存在的事件,导致死循环。
今天上网看了一篇资料,说是那个DCB配置了硬件握手协议导致了一些不支持这个功能的串口转USB设备出错。我觉得有点道理,有时间试验一下。先看一下cnComm的DCB配置情况。
发现cnComm打开了发送和接收的流控制,fDtrControl=DTR_CONTROL_ENABLE,fRtrControl=RTR_CONTROL_ENABLE。有可能是这个原因。
2009年11月3日
最近发现CRT控制台程序没有TRACE和内存溢出检查,很郁闷。无聊中翻看MSDN的Memory Management and the Debug Heap篇,发现C的Debug版本用_malloc_dbg代替malloc,而_malloc_dbg者给数据堆加上一个控制头组成链表,方便记录溢出。原话如下:
When you request a memory block, the debug heap manager allocates from the base
heap a
slightly larger block of memory than requested and returns a pointer to
your portion of that block. For example, suppose your application contains the
call:
malloc( 10 )
. In a release build,
malloc would call the base heap allocation routine
requesting an allocation of 10 bytes. In a debug build, however,
malloc
would call
_malloc_dbg, which would then call
the base heap allocation routine requesting an allocation of 10 bytes plus
approximately 36 bytes of additional memory. All the resulting memory blocks in
the debug heap are connected in a single linked list,
ordered according to when
they were allocated:
那个控制头的数据结构如下:
typedef struct _CrtMemBlockHeader
{
// Pointer to the block allocated just before this one:
struct _CrtMemBlockHeader *pBlockHeaderNext;
// Pointer to the block allocated just after this one:
struct _CrtMemBlockHeader *pBlockHeaderPrev;
char *szFileName; // File name
int nLine; // Line number
size_t nDataSize; // Size of user block
int nBlockUse; // Type of block
long lRequest; // Allocation number
// Buffer just before (lower than) the user's memory:
unsigned char gap[nNoMansLandSize];
} _CrtMemBlockHeader;
这个nBlockUse有6种内存块,具体含义还没有搞清楚,分别如下
/* Memory block identification */
#define _FREE_BLOCK 0
#define _NORMAL_BLOCK 1
#define _CRT_BLOCK 2
#define _IGNORE_BLOCK 3
#define _CLIENT_BLOCK 4
#define _MAX_BLOCKS 5
检测内存溢出用_CrtDumpMemoryLeaks(),在
crtdbg.h中定义。有时间研究一下crtdbg.h文件。
参考
http://www.cnblogs.com/phinecos/archive/2009/10/29/1592604.html
2009年10月21日
从NIST网站上下了个时间软件,看起来很古老,但功能强大。我在NIST网站上一直找不到网络时间服务器,但在这个软件中发现可以下载更新服务器地址,很好很强大。
下载
2009年10月20日
《window程序设计》果然是经典,相对于MFC来说SDK简直是返璞归真啊。继续摘录一些API函数和技巧:
CheckRadioButton(hwnd,IDC_SERVER1,IDC_SERVER10, wServer);
1、
Selects (adds a check mark to) a given radio button in a group and clears
(removes a check mark from) all other radio buttons in the group.
在IDC_SERVER1-IDC_SERVER10中选中wServer的ID,有点像分组。
DialogBoxParam (hInst, TEXT ("Servers"), hwnd, ServerDlg, (LPARAM) szIPAddr);
2、可以在WM_INITDIALOG的LPARAM传参数,建立模态对话框。ServerDlg为消息处理函数,szIPAddr为参数,在WM_INITDIALOG消息响应中处理LPARAM的值。
typedef char * va_list;
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define va_end(ap) ( ap = (va_list)0 )
3、va_list可变参数的结构,有点复杂慢慢看。
一般的用法是这样(个人理解)
va_list args; //声明变量
va_start(args, fmt); //开始解析。args指向fmt后面的参数
TYPE var = va_arg(args, TYPE); //取下一个参数并返回。args指向下一个参数
va_end(args); //结束解析
http://hi.baidu.com/kang_liang/blog/item/168c9059a9a1ca2d2934f05f.html 4、wsprintf和wvsprintf的区别,从它们的参数可以看出。
wsprintf纯粹是格式化字符串,wvsprintf是以参数列表Va_list格式化字符串。
2009年10月19日
最近看Petzold的《windows程序设计》,在Internet那章中看到如何在字符串中提取IP地址,特地标记一下:
1 GetDlgItemTextA (hwnd, wServer, szLabel, sizeof (szLabel));
2 strtok (szLabel, "(");
3 strcpy (szServer, strtok (NULL, ")"));
在Msdn上查了一下,有下面一段:
On the first call to strtok , the function skips leading delimiters and
returns a pointer to the first token in strToken , terminating the token
with a null character. More tokens can be broken out of the remainder of
strToken by a series of calls to strtok . Each call to
strtok modifies strToken by inserting a null character after the
token returned by that call. To read the next token from strToken , call
strtok with a NULL value for the strToken argument. The
NULL strToken argument causes strtok to search for the next
token in the modified strToken . The strDelimit argument can take
any value from one call to the next so that the set of delimiters may vary.
Warning Each of these functions uses a static
variable for parsing the string into tokens. If multiple or simultaneous calls
are made to the same function, a high potential for data corruption and
inaccurate results exists. Therefore, do not attempt to call the same function
simultaneously for different strings and be aware of calling one of these
function from within a loop where another routine may be called that uses the
same function. However, calling this function simultaneously from multiple
threads does not have undesirable effects.
看来用了静态变量,还好有多线程的C运行库,否则在多线程在有麻烦了。