#
編譯器行為測試
測試 說明
AC_C_BIGENDIAN 如果按高字節在前存儲字,定義WORDS_BIGENDIAN
AC_C_CONST 如果編譯器不完全支持const聲明,定義const為空
AC_C_INLINE
如果編譯器不支持關鍵字inline,__inline__或__inline,定義inline為空
AC_C_CHAR_UNSIGNED 如果char是無符號數,定義CHAR_UNSIGNED
AC_C_LONG_DOUBLE 如果主機編譯器支持長雙精度類型,定義
HAVE_LONG_DOUBLE
AC_C_CHECK_SIZEOF
把輸出變量SIZEOF_UCtype定義為C或C++預定義type類型的大小值(type[, cross-size])
系統服務測試
測試
說明
AC_SYS_INTERPRETER
根據腳本是否以#!/bin/sh為提示符來設置shell變量ac_cv_sys_interpreter為yes或no.
AC_PATH_X 找到X
Window頭文件和庫文件
所在的路徑,并設置shell變量x_includes和x_libraries為適當路徑值,如果沒有找到路徑,則設置no_x
AC_SYS_LONG_FILE_NAMES
如果系統支持長于14個字符的文件名,定義 HAVE_LONG_FILE_NAMES
AC_SYS_RESTARTABLE_SYSCALLS
如果系統調用會重啟信號中斷,定義 HAVE_RESTARTABLE_SYSCALLS
UNIX變體測試宏
測試 說明
AC_AIX
如果宿主系統是AIX,定義_ALL_SOURCE
AC_DYNIX_SEQ
已廢棄--用AC_FUNC_GETMNTENT代替
AC_IRIX_SUN 已廢棄--用AC_FUNC_GETMNTENT代替
AC_ISC_POSIX
定義_POSIX_SOURCE以允許使用POSIX特性
AC_MINIX
在MINIX系統上定義_MINIX和_POSIX_SOURCE以允許使用POSIX特性
AC_SCO_INTL 已廢棄--被AC_FUNC_STRFTIME代替
AC_XENIX_DIR
已廢棄--被AC_HEADER_DIRENT代替
AC_TRY_CPP(includes
[,action_if_true[,action_if_false]])
這個宏把includes文件名傳給預處理程序,如果預處理程序處理成功則執行shell命令action_if_true,反之執行action_if_false.
AC_EGREP_HEADER(pattern,header,action_if_found
\
[,action_if_not_found])
這個宏可以用來在頭文件header中查找egrep的表達式pattern,如果找到pattern,則執行shell命令action_if_found,反之執行action_if_not_found.
AC_EGREP_CPP(pattern,program,[action_if_found
\
[,action_if_not_found]])
用預處理程序對C源代碼program進行處理以查找egrep的表達式pattern,如果找到pattern,則執行shell命令action_if_found,反之執行action_if_not_found.
AC_TRY_COMPILE(includes,function_body,[action_if_found
\
[,action_if_not_found]])
這個宏查找C或C++編譯器的某個語法特性.編譯器將編譯包含includes中的頭文件并使用function_body中定義的函數的測試程序,如果
編譯成功,則執行shell命令action_if_found,反之執行action_if_not_found.這個宏不執行鏈接,可以用
AC_TRY_LINK來測試鏈接情況.
AC_TRY_LINK(includes,function_body,[,action_if_found
\
[,action_if_not_found]])
這個宏在AC_TRY_COMPILE之后增加鏈接測試.編譯器將編譯并鏈接其中包含includes中的頭文件并使用function_body中定義
的函數的測試程序,如果鏈接成功,則執行shell命令action_if_found,反之執行action_if_not_found.
AC_TRY_RUN(program,[action_if_true[,action_if_false
\
[,action_if_cross_compiling]]])
這個宏測試宿主系統的運行時行為.編譯,鏈接和執行C程序program,如果program,如果program返回0,則執行shell命令
action_if_true,否則執行action_if_false.如果程序要編譯為在另一類型的系統上運行,則用
action_if_cross_compiling代替action_if_found.
AC_CHECK_PROG
測試在當前路徑下是否在指定程序program.
AC_CHECK_FUNC
測試指定函數是否在C的鏈接函數庫中存在.
AC_CHECK_HEADER
測試指定頭文件是否存在
AC_CHECK_TYPE
如果指定的類型沒有被定義,設置一個默認值.
test -z "$LDFLAGS" && LDFLAGS="-I/usr/include"
AC_SUBST(LBFLAGS)
dnl Tests for UNIX
variants
dnl
AC_CANONICAL_HOST
AC_CANONICAL_HOST報告從GNU觀點看到的宿主機類型.它輸出cpu-company-system形式的系統
名稱.例如,筆者的一個系統上,AC_CANONICAL_HOST報告其類型為i686-unknown-linux.
dnl
Tests for
programs
dnl
AC_PROG_CC
AC_PROG_LEX
AC_PROG_AWK
AC_PROG_YACC
AC_CHECK_PROG(SHELL,bash,/bin/bash,/bin/sh)
這一代碼段按順序判斷并設置了編譯器,詞法分析器lexer,awk,yacc以及本地shell.
dnl
Tests for libraries
dnl
AC_CHECK_LIB(socket,
socket)
AC_CHECK_LIB(resolv,res_init,[echo"res_init() not in
libresolv"],
[echo "res_init() found int libresolv"])
"Test for
libraries"的這一代碼段展示了怎么為autoconf的宏編寫自定義的命令.
dnl Tests for header
files
dnl
AC_CHECK_HEADER(killer.h)
AC_CHECK_HEADERS([resolv.h
temio.h curses.h sys/time.h fcntl.h \
sys/fcntl.
memory.h])
AC_DECL_SYS_SIGLIST
AC_HEADER_STDC
以"\"結尾的一行說明了多參數續行的正確方式.前面已經介紹過,使用字符"\"告訴m4和shell需要續行,并且用m4的引用符號把整個參數括起來.
dnl
Tests for
typedefs
dnl
AC_TYPE_GETGROUPS
AC_TYPE_SIZE_T
AC_TYPE_PID_T
dnl
Tests for structures
AC_HEADER_TIME
AC_STRUCT_TIMEZONE
dnl Tests
of compiler
behavior
dnl
AC_C_BIGENDIAN
AC_C_INLINE
AC_CHECK_SIZEOF(int,
32)
AC_C_BIGENDIAN宏將產生一個警告,因為調用AC_TRY_RUN時沒有設置默認值以允許交叉編譯,可以忽略這個警告.
dnl
Tests for library
functions
dnl
AC_FUNC_GETLOADAVG
AC_FUNC_MMAP
AC_FUNC_UTIME_NULL
AC_FUNC_VFORK
dnl
Tests of system
services
dnl
AC_SYS_INTERPRETER
AC_PATH_X
AC_SYS_RESTARTABLE_SYSCALL
AC_SYS_RESTARTABLE_SYSCALLS宏將產生一個警告,因為調用AC_TRY_RUN時沒有默認值允許交叉編譯,可以忽略這個警告.
dnl
Tests in this section exercise a few of `autoconf' ''s generic
macros
dnl
dnl First, let's see if we have a usable void pointer
type
dnl
AC_MSG_CHECKING(for a usable void pointer
type)
現在情況開始變得有趣起來.基本上,普通宏允許你通過編寫自己的宏對autoconf進行擴展.例如,AC_MSG_CHECKING在屏幕上打印字符串"checking",隨后是一個空格以及傳入的參數
AC_TRY_COMPILE(
[ ],
[ char *ptr;
void *xmalloc();
ptr = (char *)
xmalloc(1);
],
[AC_DEFINE(HAVE_VOID_POINTER)
AC_MSG_RESULT(usable void pointer]
)
留意AC_TRY_COMPILE宏.autoconf能夠把C代碼嵌入到一個C程序框架中,并把這個程序寫入已生成的configure腳本中,以便在
運行configure時編譯這個程序;然后,configure捕獲編譯器的輸出并查找錯誤.AC_DEFINE
(HAVE_VOID_POINTER)產生了一個名為HAVE_VOID_POINTER的預處理器符號(必須將它放置在./acconfig.h中,
因為它并不在其他地方存在).如果編譯成功,configure把"#define HAVE_VOID_POINTER
1"寫入到config.h中并且在屏幕上打印"usable void pointer";如果編譯失敗則在config.h中寫入"/*
#undef HAVE_VOID_POINTER */,并顯示"no usable void
pointer".在你自己的源代碼文件中,只需按如下的方式測試這個預處理符號:
#ifdef HAVE_VOID_POINTER
/* do
something */
#else
/* do something else */
#endif
dnl Now,
let's exercises the preprocessor
dnl
AC_TRY_CPP(math.h, echo 'found
math.h', echo 'no math.h - deep doo
doo!)
如果configure找到了頭文件math.h,它會在屏幕上顯示"found math.h";否則它通知用戶出現了一個問題.
dnl
Next, we test the linker
dnl
AC_TRY_LINK([#ifndef
HAVE_UNISTD_H
#include <signal.h>
#endif],
[char *ret =
*(sys_siglist + 1);],
[AC_DEFINE(HAVE_SYS_SIGLIST), AC_MSG_RESULT(got
sys_siglist)],
[AC_MSG_RESULT(no
sys_siglist)])
這一段代碼測試連接器.同樣,因為HAVE_SYS_SIGLIST不是一個標準預處理器符合,你必須在./acconfig.h中聲明它.
dnl
Finally, set a default value for a ridiculous
type
dnl
AC_CHECK_TYPE(short_short_t, unsigned
short)
最后的測試只檢查一種(希望的)不存在C數據類型.如果確實沒有,則將short_short_t定義為unsigned
short.讀者可以到config.h中查找與short_short_t相關的#define指令來確認這個測試的結果.
dnl Autoconfigure script for bogusapp
dnl Kurt Wall
<kwall@kurtwerks.com>
dnl
dnl Process this file with 'autoconf'
to produce a 'configure'
script
第一個代碼段是標準的autoconfig.in文件頭,指出了這個configure.in腳本隸屬于什么軟件包,聯系信息(通常是軟件包的維護者)以及重新生成配置腳本的說明.
AC_INIT(bogusapp.c)
AC_CONFIG_HEADER(config.h)
接下來的兩行調用了前面介紹過的AC_INIT函數,并且在源文件樹的根目錄下創建了一個名為config.in的頭文件,其中只包含從實際的頭文件中提
取的預處理符號.主要在源代碼中包含這個頭文件并使用其中的相關符合,實際的程序就能在每個可能的系統上平滑無縫地編譯.autoconf根據名為
config.h.in中包含了程序需要的所有#define指令.
怎么創建config.h.in?幸運的是,autoconf自帶了一個名為autoheader的shell腳本,這個腳本使用起來很方便.該腳本能生
成config.h.in.autoheader通過讀入configure.in,作為autoconf軟件一部分的acconfig.h文件和位于源
代碼樹根路徑下用于保存預處理符號的acconfig.h文件,生成config.h.in文件.在你開始抱怨又要創建另一個文件之前,告訴你一個好消
息,./acconfig.h只需包含在別處沒有定義的預處理符號.更好地是,這些符號值都能為空.這個文件中只需包含可以被autoconf和
autoheader讀取和使用的合法定義的C風格預處理符號.要創建config.h.in,在創建了你的config.in,在創建了你的
config.in文件之后在源代碼目錄下執行autoheader.下面的代碼段是用于bogusapp的acconfig.h文件.
/*
Define this 1 if you compiler allows a (void *) function return */
#define
HAVE_VOID_POINTER 0
/* Define this 1 if your C compiler has a
short_short_t type */
#define short_short_t 0
/* Define this 1 if your
signal handling library support sys_siglist */
#define HAVE_SYS_SIGLIST 0
Class.forName(props.getProperty("driver"));
String url =
props.getProperty("url");
Connection con = DriverManager.getConnection(url,
props);
// showWarnings(con.getWarnings());
initLanguage(con);
return
con;
上面的Connection類的方法getWarnings檢索調用這個Connection對象的第一個警告.如果有多個可以用getNextWarning方法得到.
public
void showWarnings(SQLWarning w) {
while (w != null)
{
System.out.println(w.getMessage());
w =
w.getNextWarning();
}
}
private void initLanguage(Connection con)
throws SQLException {
Statement stmt =
con.createStatement();
stmt.executeUpdate("set LANGUAGE
'us_english'");
stmt.close();
}
上面函數顯示了一個比較簡單的調用語句的方法.
這里是使用的屬性文件注冊.屬性文件如下:
--------------------------------------------------------------------
#屬性文件connection.properties.tmpl
#
#
The URL of the server to which you want to
connect
#
driver=net.sourceforge.jtds.jdbc.Driver
url=jdbc:jtds:sqlserver://localhost/dbname
USER=XXXX
PASSWORD=YYYY
SERVERNAME=localhost
PORTNUMBER=1433
DATABASENAME=dbname
XAEMULATION=true
#
#
TDS Version
#
#
# Use this for MS SQL Server
6.5+
#
#TDS=4.2
#
# Use this for Sybase
10+
#
#TDS=5.0
#
# Use this for MS SQL Server
7.0+
#
#TDS=7.0
#
# Use this for MS SQL Server 2000
(default)
#
TDS=8.0
--------------------------------------------------------------------
讀入屬性文件如下:
String
CONNECTION_PROPERTIES = "conf/connection.properties";
File propFile = new
File(fileName);
if (!propFile.exists()) {
fail("Connection properties
not found (" + propFile + ").");
}
try {
Properties props = new
Properties();
props.load(new FileInputStream(propFile));
return
props;
}
catch (IOException e) {
throw new
RuntimeException(e.getMessage());
}
這里是fail函數是使用了junit的fail方法,表示測試失敗.
private void disconnect() throws Exception {
if (con != null)
{
con.close();
con = null;
}
}
protected void connect()
throws Exception {
disconnect();
con =
getConnection();
}
上面是一般寫法.
public Connection getConnection()
throws Exception
{
Class.forName(props.getProperty("driver"));
String url =
props.getProperty("url");
Connection con =
DriverManager.getConnection(url,
props);
// showWarnings(con.getWarnings());
initLanguage(con);
return
con;
}
diff命令比較兩個不同的文件或不同目錄下的兩個同名文件.在使用diff時,可以用選項來定制輸出格式.patch程序將讀取diff的輸出和所比較
文件中的一個來重新生成另一個.diff手冊的作者寫道:"如果你認為diff是通過從一個文件中減去另一個來生成這兩個文件的差別文件,那就可以認為
patch是使用這個差別文件和其中的一個源文件來生成另一個源文件".
diff命令的一般語法為:
diff
[option] srcfile
dstfile
diff在運行時試圖找到在srcfile和dstfile里都一樣的很多連續行,在碰到srcfile和dstfile里不一樣的行時運行被打打斷,這些有差別的行稱為塊(hunk).
diff的命令行選項合參數
選項
描述
-a 將所有的文件看作文本,既使文件看起來像是二進制的也不例外,并且進行逐行比較
-b
忽略塊中空白數目的改變
-B 忽略插入或刪除空行造成的改變
-c
產生"上下文"(context)格式的輸出
-C[num] 產生"上下文"(context)格式的輸出,顯示塊前后num行的內容,如果不指定num的值,則顯示塊前后3行的內容
-H
修改diff處理大文件的方式
-i 忽略大小寫,同樣對待大寫和小寫字母
-I
regexp 忽略插入或刪除與正則表達式regexp匹配的行
-l 將輸出結果通過pr命令處理加上頁碼
-p
顯示出現塊的C函數
-q 只報告文件是否不同;不輸出差別
-r 比較目錄時,進行遞歸比較
-s
報告兩個文件相同(默認的行為是不報告相同的文件)
-t 輸出時tab擴展為空白
-u
產生"統一"(unified)格式的輸出
-U[num] 產生"統一"(unified)格式的輸出,顯示塊前后num行的內容,如果不指定num的值,則顯示塊前后3行的內容
-v
打印diff的版本號
-w 逐行比較時忽略空白
-W cols 如果產生并排格式的輸出(參見-y)
,讓輸出的每一列有cols個字符寬
-x pattern 當比較目錄時,忽略匹配模式pattern的任何文件和子目錄
-y
產生并排格式的輸出
hello.c #include <stdio.h> int main(void) { char msg[ ] =
"Hello Linux programmer!"; puts(msg); printf("Here you are, using
diff.\n");
return 0; }
howdy.c #include
<stdio.h> #include <stdlib.h> int main(void) { char
msg[ ] = "Hello, linux programmer, from
howdy.c"; puts(msg); printf("howdy.c says, 'Here you are using
diff.'\n"); exit(EXIT_SUCCESS); } 使用diff的基本語法產生的輸出(在下面"理解正規輸出格式"部分所介紹的為正規格式)是: $diff
hello.c howdy.c la2 > #include <stdlib.h> 5c6 < char
msg[ ] = "Hello, Linux programmer!"; --- > char msg[ ] = "Hello,
Linux programmer, from howdy.c!"; 8c9 < printf("Here you are, using
diff.\n"); --- > printf("howdy.c says, 'Here you are, using
diff.'\n"); 10c11 < return 0; --- >
exit(EXIT_SUCCESS); diff能夠產生幾種輸出格式,包括正規(normal,也是diff默認的市場格式),上下文(context),統一(unified)以及并排(side-by-side)4種.
|