#
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.OutputStreamWriter;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import com.ibatis.common.exception.NestedRuntimeException;
Document getDoc(Reader reader) {
try {
// Configuration
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(false);
dbf.setValidating(true);
dbf.setIgnoringComments(true);
dbf.setIgnoringElementContentWhitespace(true);
dbf.setCoalescing(false);
dbf.setExpandEntityReferences(false);
OutputStreamWriter errorWriter = new OutputStreamWriter(System.err);
DocumentBuilder db = dbf.newDocumentBuilder();
db.setErrorHandler(new SimpleErrorHandler(new PrintWriter(errorWriter, true)));
//db.setEntityResolver(new DaoClasspathEntityResolver());
// Parse input file
Document doc = db.parse(new ReaderInputStream(reader));
return doc;
} catch (Exception e) {
throw new NestedRuntimeException("XML Parser Error. Cause: " + e);
}
}
/**********************************************************/
private static class SimpleErrorHandler implements ErrorHandler {
/**
* Error handler output goes here
*/
private PrintWriter out;
SimpleErrorHandler(PrintWriter out) {
this.out = out;
}
/**
* Returns a string describing parse exception details
*/
private String getParseExceptionInfo(SAXParseException spe) {
String systemId = spe.getSystemId();
if (systemId == null) {
systemId = "null";
}
String info = "URI=" + systemId +
" Line=" + spe.getLineNumber() +
": " + spe.getMessage();
return info;
}
// The following methods are standard SAX ErrorHandler methods.
// See SAX documentation for more info.
public void warning(SAXParseException spe) throws SAXException {
out.println("Warning: " + getParseExceptionInfo(spe));
}
public void error(SAXParseException spe) throws SAXException {
String message = "Error: " + getParseExceptionInfo(spe);
throw new SAXException(message);
}
public void fatalError(SAXParseException spe) throws SAXException {
String message = "Fatal Error: " + getParseExceptionInfo(spe);
throw new SAXException(message);
}
}
在sources.list中加入:
deb http://archive.ubuntu.org.cn/ubuntu-cn ubuntu.org.cn main
#apt-get update
#apt-get install ttf-arphic-newsung
這樣就可以安裝上新宋體.
kanru 是我國臺灣地區著名的 Debian 黑客
引用:
作者: kanru
有在注意 freetype 最新發展的人應該已經知道
freetype2 已經內建粗體模擬支援(cvs 版本),在 xft2 中相對應的程式碼也已經有了
所以只要更新這兩個套件便可以有基本的粗體支援 眨眨眼
想要嘗鮮的人可以加入以下到 sources.list
代碼:
deb http://people.debian.org.tw/~koster/debian/sid ./ deb-src http://people.debian.org.tw/~koster/debian/sid ./
|
其中 freetype2 的部份是今天更新的 cvs 版本,有熱呼呼的的粗體支援
xft2 是拿 debian 中的版本直接重新編譯,讓 configure 偵測到已經開啟模擬粗體
更新 libfreetype6 與 libxft2 後重新啟動 X 便能體驗到久違的粗體 眨眨眼
NOTE: 此修正是以直接修改底層的方式,與其他之前的 patch 不同
混用這些不同 patch 的套件將有不能預期的後果
相關網址:
freetype maillist 討論串
http://lists.gnu.org/archive/html/f...5/msg00019.html
(Firefly) freetype已經接受粗體補丁?
http://firefly.idv.tw/test/Forum.ph...=view&History=0
|
加了 apt 源后
apt-get update
apt-get install libfreetype6 libxft2
然后重啟 X , 就可以看到效果了
引用:
作者: kanru
補充一下
如果您有修改過 /etc/fonts/fonts.conf
請檢查有沒有這幾行
PHP代碼:
<!--
Synthetic emboldening for fonts that do not have bold face available
--> <match target="font"> <!-- check to see if the font is just regular --> <test name="weight" compare="less_eq"> <int>100</int> </test> <!-- check to see if the pattern requests bold --> <test target="pattern" name="weight" compare="more_eq"> <int>200</int> </test> <!-- set the embolden flag --> <edit name="embolden" mode="assign"> <bool>true</bool> </edit> </match>
|
這些是用?碓O定啟用模擬粗體的,是 Debian 預設安裝,沒改過 fonts.conf 的人應該不用再改
作者:robbin 網址:http://www.fankai.com/
在IBM的developerWorks上有幾篇非常優秀的關于Java XML API的評測文章,它們是:
http://www-900.ibm.com/developerWorks/cn/xml/x-injava/index.shtml
http://www-900.ibm.com/developerWorks/cn/xml/x-injava2/index.shtml
http://www-900.ibm.com/developerWorks/cn/xml/x-databdopt/part2/index.shtml
http://www-900.ibm.com/developerWorks/cn/xml/x-databdopt/part1/index.shtml
對這幾篇文章我想說的就是“吐血推薦”
Java的XML API這幾篇文章該講的都講到了,我只想補充幾點:
一、Crimson和Xerces恩仇錄
Crimson來自于Sun捐贈給Apache的ProjectX項目,Xerces來自IBM捐贈給Apache的XML4J項目,結果Xerces勝出,成了Apache XML小組全力開發的XML API,而Crimon已經早就不做了,如今Xerces名滿天下,到處都是在用Xerces DOM和SAX解析器,只有Sun不服氣,非要在JDK1.4里面使用過時的Crimson,讓人感覺像是在賭氣一樣,真是讓人可憐又可氣!不過IBM發行JDK用的XML 解析器自然是Xerces。
由于JDK的Class Loader的優先級關系,當你采用JAXP編寫XML程序的時候,即使把Xerces包
引入CLASSPATH,JDK還是會頑固的使用Crimson,這一點通過打開JVM的verbose參數可以觀察到。不過JDK也允許你采用其它的解
析器,因此我們可以通過在JRE\lib\目錄下建一個jaxp.properties的文件,來替換解析器,jaxp.properties內容如下:
javax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl javax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl 這樣就可以使用Xerces,當然你必須還是要把Xerces包放到CLASSPATH下。
二、JAXP的姍姍來遲
Sun在XML領域總是后知后覺,等到Sun重視XML的時候,XML的API早就滿天 飛了,尤其是IBM具有非常大的領先優勢。不過Sun是規范的制訂者,于是參考W3C的標準制訂了JAXP規范。JAXP不像Xerces和Crimon那樣,它只是一個spec,本身是不做任何事情的,它的作用就是提出一個統一的接口,讓其它的XML API都來遵循JAXP編程,那么用JAXP寫出來的程序,底層的API可以任意切換。
具
體來說JAXP包括了幾個工廠類,這就是JDK1.4里面的javax.xml.parsers 包,用來尋找符合DOM標準的XML
API實現類的位置;此外JAXP還包括一整套interface,這就是JDK1.4里面的org.w3c.dom那幾個包。工廠類負責加載DOM的實
現類。那么加載的規則是什么呢?
我是通過閱讀JAXP的源代碼知道的,工廠類首先會根據java命令行傳入的參數進行尋找,然后在根據
JRE\lib\jaxp.properties中定義的實現類尋找,最后什么都找不到的話,就用Crimson。注意Crimons是由
Bootstrap Class Loader來load的,如果你不通過上面兩個方法來改變工廠的尋找順序,那么鐵定用Crimson了 
三、 DOM解析器和DOM API
當你嚴格采用JAXP編程的時候,是遵循W3C的DOm標準的,那么在JAXP底層你實際上可以任意切換不同的DOM實現,例如Xerces,或者Crimon,再或者其它,切換方法就是配置jaxp.properties。因此JAXP就是一些標準接口而已。
而Xerces和Crimon也不單單是一個DOM實現那么簡單,他們本身實際上也包含SAX解析器和DOM解析器。所以一個JAXP程序下面有如下層次:
JAXP應用程序 -> JAXP接口 -> Xerces DOM實現 -> Xerces DOM/SAX 解析器
只要你用JAXP編程,那么你就可以切換到Crimson上來
JAXP應用程序 -> JAXP接口 -> Crimson DOM實現 -> Crimson DOM/SAX 解析器
另外你也可以這樣來做:
JAXP應用程序 -> JAXP接口 -> Crimson DOM實現 -> Xerces DOM/SAX 解析器
不過如果你的程序不安裝JAXP來寫,那么就沒有辦法切換不同的DOM實現了。
四、不是標準的dom4j和jdom
W3C
的DOM標準API難用的讓人想撞墻,于是有一幫人開發Java專用的XML
API目的是為了便于使用,這就是jdom的由來,開發到一半的時候,另一部分人又分了出來,他們有自己的想法,于是他們就去開發dom4j,形成了今天
這樣兩個API,至于他們之間的性能,功能之比較看看上面我推薦的文章就知道了,jdom全面慘敗。
jdom 相當于上面的 JAXP接口 + Xerces DOM實現部分,它本身沒有解析器,它可以使用Xerces或者Crimson的解析器,就是這樣:
jdom應用程序 -> jdom API -> Xerces/Crimson解析器
dom4j 和jdom類似,不過他自己綁定了一個叫做Alfred2的解析器,功能不是很全,但是速度很快,當沒有其它的解析器的時候,dom4j將使用Alfred2解析器,如下:
dom4j應用程序 -> dom4j API -> Xerces/Crimson解析器
或者
dom4j應用程序 -> dom4j API -> Alfred2解析器
你在SF上下載的dom4j.jar是不含 Alfred2解析器的,而dom4j-full.jar包含了 Alfred2解析器,在這種情況下,實際上你什么也不需要,光是一個dom4j-full.jar就全部都包括了。
因此可以看出采用dom4j/jdom編寫的應用程序,已經不具備可移植性了。
五、小插曲
Sun是JAXP標準的制訂者,甚至很執著的在JDK1.4里面綁定Crimson DOM實現和解析器,然后可笑的是,Sun自己的JAXM RI竟然不是用JAXP寫出來的,而是dom4j,制訂標準讓大家遵守,自己卻監守自盜,這未免太說不過去了吧!
BTW: Hibernate也用的是dom4j來讀取XML配置文件,如今已經越來越多的程序紛紛采用dom4j,如果你不是那么在乎可移植性,我強烈建議你采用dom4j。
因為sourcenav不支持中文的locale,所以會報錯誤.
只要輸入:$export LANG=en_US
$export LC_ALL=en_US
$snavigator
這樣就能正確的起動.
詳細的命令如下:
mount -t smbfs -o username=tridge,password=foobar //fjall/test /data/test
不符合ANSI/ISO的源代碼
/*
* pedant.c - use -ansi, -pedantic or
-pedantic-errors
*/
#include <stdio.h>
void
main(void)
{
long long int i = 0l;
printf("This is a non-conforming
c program\n");
}
使用gcc pedant.c -o
pedant這個命令時,編譯器會警告main函數的返回類型無效:
$gcc pedant.c -o pedant
pedant.c:In
function 'main':
pedant.c:7 warning:return type of 'main' is not
'int'
現在給gcc加上-ansi選項:
$gcc -ansi pedant.c -o pedant
$gcc pedant.c -o
pedant
pedant.c: In function 'main'
pedant.c:7 warning: return type of
'main' is not
'int'
gcc再次給出了同樣的警告信息,并忽略了無效的數據類型.
-ansi,-pedantic以及-pedantic-errors編譯選項并不能保證被編譯的程序的ANSI/ISO兼容性,它們僅被用來幫助程序員離這個目標更近.
$gcc
-Wall pedant.c -o pedant
pedant.c:7: warning: return type of 'main' is not
'int'
pedant.c: In function 'main':
pedant.c:8 warning: unused variable
'i'
-Wall系列選項的另一個極端是-w選項,它能關閉所有的警告信息。-W{warning}選項的作用是打開warning所指出的用戶感興趣的特殊警
告信息,比如隱身函數說明(-Wimplicit-function-declaration)或者隱身聲明返回類型的函數(-Wreturn-
type).前者的作用在于它提示出定義了一個函數卻沒有事先聲明或者忘記了包含適當的頭文件.后者的作用在于指出聲明的函數可能沒有指定它的返回類型,
此時默認的返回類型為int.
提示:如果只想檢查語法而實際上不做如何編譯工作,那么可以調用帶有-fsyntax-only參數的GCC.
選項
說明
-Wcomment
如果出現了注解嵌套(在第一個/*之后又出現了第二個/*)則發出警告
-Wformat
如果傳遞給printf及及其相關函數
的參數和對應的格式字符串中指定的類型不平配則發出警告
-Wmain
如果main的返回類型不
是int或者調用main時使用的參數數目不正確則不出警告
-Wparentheses
如果在出現了賦值(例如,(n=10))的地方使用了括號,而那里根據前后關系推斷應該是比較(例如,(n==100))而非賦值的時候,或者如果括號能夠解決運算優先級問題的時候,發出警告
-Wswitch
如果swtich語句少了它的一個或多
個枚舉值的case分支(只有索引值是enum類型時才適用)則發出警告
-Wunused
如果聲明的變量沒有使用,或者函數聲明
為static類型但卻從未使用,則發出警告
-Wuninitialized
如果使用的自動變量沒有初始化則發出警告
-Wundef
如果在#if宏中使用了未定義的變量作判斷則發出警告
-Winline
如果函數不能被內聯則發出警告
-Wmissing-declarations 如果定義了全局函數但卻沒有在任何頭文件中聲明它,則發出警告
-Wlong-long
如果使用了long long類型則發出警告
-Werror
將所有的警告轉變為錯誤
常見的編程錯誤:
/*
* blunder.c - Mistakes caught by
-W(warning)
*/
#include <stdio.h>
#include
<stdlib.h>
int main(int argc, char *argv[])
{
int i,
j;
printf("%c\n", "not a character"); /* -Wformat */
if(i =
10) /*
-Wparenthesses */
printf("oops\n");
if(j !=
10)
/* -Wuninitialized */
printf("another oops\n");
/* /*
*/ /*
-Wcomment */
no_decl(); /*
-Wmissing-declaration */
return (EXIT_SUCCESS);
}
void
no_decl(void)
{
printf("no_decl\n");
}
$gcc blunder.c -o
blunder
blunder.c:27: warning: type mismatch with previous implicit
declaration
blunder.c:21: warning: previous implicit declaration of
'no_decl'
blunder.c:27: warning: 'no_decl' was previously implicitly declared
to return
'int'
gcc只發出了和隱式聲明no_decl函數有關的警告.它忽略了其他潛在的錯誤,這些錯誤包括:
.傳遞給printf的參數類型(一個字符串)和格式化字符串定義的類型(一個字符)不匹配.這會產生一個-Wformat警告.
.變量i和j使用前都沒有初始化.它們中的任何一個都產生-Wuninitialized警告.
.在根據前后關系推斷應該對變量i的值做比較的地方,卻對變量i進行賦值.這應該會產生一個-Wparentheses警告.
.在注釋嵌套開始的地方應該會產生一個-Wcomment警告.
例如,如果已經在/home/fred/include 下保存了自定義的頭文件,那么為了讓gcc能夠找到它們,可按下面的例子使用-I選項:
$gcc
myapp.c -I /home/fred/include -o
myapp
-L選項對庫文件起的作用和-I選項告訴gcc把DIRNAME添加到庫文件搜索路徑里,要保證DIRNAME比標準位置先被搜索.
假設讀者需要測試一個新的編程庫libnew.so,當前它保存在/home/fred/lib下(.so是共享庫文件的標準擴展名).為了鏈接庫文件,gcc命令行應與下面類似:
$gcc
myapp.c -L/home/fred/lib -lnew -o
myapp
-L/home/fred/lib結構讓gcc先在/home/fred/lib下查找庫文件,然后再到默認的庫文件搜索路徑下進行查找.-l選項使得鏈
接程序使用指定的函數庫中的目標代碼,也就是本例中的libnew.so.把函數庫命名為lib{名字}是UNIX的約定,與許多其他編譯器一樣,gcc
也遵循此約定.如果忘了使用-l選項,則與庫的鏈接將失敗,并且gcc產生錯誤,說明程序中引用了未定義的函數名.
默認情況下,gcc使用共享庫進行鏈接,所以在需要鏈接靜態庫時必須使用-static選項來保證只使用靜態庫.
$gcc
cursesapp.c -lncurses -static -o
cursesapp
在鏈接靜態庫時,可執行程序的大小比鏈接共享庫要達很多.使用共享庫時,程序所使用的代碼是在運行時動態鏈接,而不是在編譯時靜態鏈接,因此,如果所需要的共享庫沒有在用戶系統中安裝,運行就會失敗.
選項 說明
-o FILE 指定輸出文件名,在編譯為目標代碼時,這一選項不
是必須的.如果FILE沒有指定,默認文件名時a.out
-c
只編譯不鏈接
-DFOO=BAR 在命令行定義預處理宏FOO,其值為BAR
-IDIRNAME 將DIRNAME加入到包含文件的搜索目錄列表中
-LDIRNAME 將DIRNAME加入到庫文件的搜索目錄列表中
-static
鏈接靜態庫,即執行靜態鏈接默認情況下gcc只鏈接共享庫
-IFOO 鏈接名為libFOO的函數庫
-g
在可執行程序中包含標準調試信息
-ggdb 在可執行程序中包含只有GNU
debugger(gdb)才能識別大量調試信息
-O
優化編譯過的代碼
-ON
指定代碼優化的級別為N,0<=N<=
3,如果未指定N,則默認級別為1
-ansi 支持ANSI/ISO
C的標準語法,取消GNU的語法擴展中與該標準有沖突部分(但這一選項并不能保證生成ANSI兼容的代碼)
-pedantic 允許發出ANSI/ISO
C標準所列出的所有警告
-pedantic-errors 允許發出ANSI/ISO
C標準所列出的所有錯誤
-traditional 支持Kernighan & Ritchie C 語法
(如用舊式語法定義函數).
-w
關閉所有警告,建議不要使用此項
-Wall
允許發出gcc能提供的所有有用的警告.也可以用-W{warning}來標
記指定的警告
-werror 把所有警告轉換為錯誤,以在警告發生時中止編譯過程
-MM
輸出一個make兼容的相關列表
-v
顯示在編譯過程的每一步中用到的命令
實例代碼:
/*
* hello.c - Canonical "Hello, World!" program
*/
#include
<stdio.h>
int main(void)
{
printf("Hello,Linux programming
world!\n");
return 0;
}
在命令行上鍵入以下命令編譯和運行這段程序:
$gcc hello.c -o
hello
$./hello
Hello, Linux programming
world!
第一行命令告訴gcc對源代碼hello.c進行編譯和鏈接,并使用-o參數指定創建名為hello的可見程序.第二行命令執行hello這個程序,第三行是程序的執行結果.
其實,gcc首先運行預處理程序cpp來展開hello.c中的宏并在其中插入#include文件所包含的內容:然后把預處理后的源代碼編譯成為目標代碼;最后,鏈接程序ld創建一個名為hello的二進制文件.
現在我們來通過手工操作重新創建這些步驟,以逐步執行編譯過程.第一布是運行預處理器.使用-E選項告訴gcc在預處理后停止編譯過程:
$gcc
-E hello.c -o
hello.cpp
此時查看hello.cpp會發現stdio.h的內容確實都插到文件里去了,而其他應當被預處理的標記也做了類似處理.
下一步是將hello.cpp編譯為目標代碼.可使用gcc的-c選項來完成:
$gcc
-x cpp-output -c hello.cpp -o
hello.o
-x選項告訴gcc從指定的步驟開始編譯,在本例中也就是編譯器處理后的源代碼(cpp-output).
gcc是怎么知道如何處理某種特殊類型的文件呢?它是依靠文件的擴展名來決定如何正確處理該文件的.
——————————————————————————————
擴展名
類型
.c
C語言源代碼
.C,.cc
C++語言源代碼
.i
預處理后的C源代碼
.ii
預處理后的C++源代碼
.S,.s
匯編語言源代碼
.o
編譯后的目標代碼
.a,.so
編譯后的庫代碼
———————————————————————————————
最后,鏈接目標文件,生成二進制代碼.
$gcc
hello.c -o hello
|