2009年7月4日星期六

文本编辑器Scite与极小的C编译器TCC

09-5-7的草稿

内容包括:
终端下vim
sc介绍
sc的配置文件
用户,api,缩写,补全,帮助(加入api中)
配置方式的特点与评价
正则表达式
tcc特点
搭建c编写环境的设置
其他
风格:
说清楚即可,精简实用

[正文]
有需要在Linux终端下文本编辑,可以简单地用VIM来进行。另一个可选择是功能更加简单的nano,通常都是会被默认安装的。
"vim <文件名>"开始编辑某个文件。移动光标到需要位置,按下"i"键开始输入状态,进行文本操作后,按"ESC"键返回。要删除光标处的字符字符,用"x"键。
输入":"(会用到Shift键)开始输入命令,"w"保存,"q"退出。这些命令可能会被提示要加"!"强制执行,比如用"wq!"进行保存并退出。
这些可以算VIM的操作中最简单实用的部分了,^-^。

下面是才是本篇主角:
SciTE(SCIntilla based Text Editor),即基于SCIntilla组件的文本编辑器。
SCIntilla组件最初设计为RichEdit的替代产品

今天
不想写多了,就照上面的列表补完吧。
那个其实论简单,还是用nano,先看看自带的帮助啊的。VIM的复制粘贴键是y和p,还没试。
OK,开始话题。
SCIntilla组件以被Windows下的notepad2,notepad++使用,而linux下有 Gedit,geany,codeblock等在用。详细的列表去网上找喽。
而SciTE原本是作为该组件的演示程序的,不过功能较为完备,可以独立使用。
其实可以说是蛮好用的,尤其是敲些简单的代码时。
官方网站:http://www.scintilla.org/SciTE.html
功能特色:多语言语法高亮,正则表达式,自动完成,函数提示,缩略语,可定制,可扩展,输出格式...
^-是我随手列的,写特色却可惜不是抓眼球的东西。
~官网的下载页For Windows的版本有两个
full download:完整的包,其中SciTE.EXE, SciLexer.DLL是运行必须的,此外有详细的说明文档(官网也有,很重要的东西)和程序本身和针对各语言的配置文件(如想自行设置,这些都是极优秀的范本哦)。
single file executable called Sc1:包为单独的exe文件,已内建默认配置(想修改就请自己看文档和上面那个包里的东西喽)。
这里强调了配置文件,作者说他不会去写个图形的配置界面的。这是定位的因素,所以在使用前最好是先设定为自己顺手的样子。
配置文件 properties file(按优先级从高到低)
"Local":文件名"SciTE.properties",作用于该文件所在目录的文件被编辑时
"Directory":文件名"SciTEDirectory.properties" ,类似"Local",但包括子目录,使用前需要在先开启。
"User":文件名"SciTEUser.properties"(Windows)&".SciTEUser.properties"(GTK+
),位于用户目录,作用于当前用户。
"Global":"SciTEGlobal.properties",程序所在目录
如果使用完整版,那么已经有了写了众多被注释条目的全局配置,可以复制所需条目或自行添加条目到用户配置当中。如果需要修改全局配置,建议做好原文件的备份。
我是下载单文件版作便携版,所以直接修改空白的全局配置文件。通过选项菜单里打开文件开始编辑。
我的配置目标是作c代码的编辑器。
下载简体中文的语言文件,命名为"locale.properties",置于程序所在目录。并按照下载页提示在配置文件添加:
code.page=936
character.set=134
如果用unicode则是添加"code.page=65001",个人又加了"font.base=size:12"调整字体
使用自动完成和函数提示,快捷键参考编辑菜单(很重要)。然后比如:
下载c.api(或其他有的需要的)置于程序所在目录,配置文件添加
api.*.c=$(SciteDefaultHome)/c.api
缩写文件,我命名为"c_abbrev.properties",为"*.c"文件添加
abbreviations.*.c=$(SciteDefaultHome)/c_abbrev.properties
Ctrl+B展开,我的是,按照紧凑风格:

if=if(|){\n\t\n}
else=else{\n\t|\n}
for=for(i=0;i<|;i++){\n\t\n} while=while(|){\n\t\n}\n do=do{\n\t|\n}while()\n switch=switch(|){\n\tcase :\n\t\t\n\t\tbreak;\n\tdefault:\n\t\t\n} #try=try{\n\t|\n}catch(){\n\t\n} (=(|) {={\n\t|\n} Tc=#include \nint main(int argc, char** argv){\n\t|\n\treturn 0;\n}\n

设定缩进使用
tabsize=4
indent.size=4
补全功能也包括文件中出现的文本,我又使用了:
autocompleteword.automatic=1
autocomplete.cpp.fillups=(
为折叠符号和高亮当前行颜色添加:
fold.symbols=3
caret.line.back=#FFFED8
至于是否显示工具栏和初始位置,在供参考设置里名称相当明显,而文档中有更具体的说明。再多话了,文档确实是好东西。

下面添加TCC - Tiny C Compiler
http://bellard.org/tcc/
小巧快速完整的c编译器,也可直接运行脚本并提供lib。
基于OTCC,是作者参加混乱代码大赛的作品。
尤其是编译速度相比gcc相当快,虽然缺乏代码优化。

Features
SMALL! You can compile and execute C code everywhere, for example on rescue disks (about 100KB for x86 TCC executable, including C preprocessor, C compiler, assembler and linker).
FAST! tcc generates x86 code. No byte code overhead. Compile, assemble and link several times faster than GCC.
UNLIMITED! Any C dynamic library can be used directly. TCC is heading torward full ISOC99 compliance. TCC can of course compile itself.
SAFE! tcc includes an optional memory and bound checker. Bound checked code can be mixed freely with standard code.
Compile and execute C source directly. No linking or assembly necessary. Full C preprocessor and GNU-like assembler included.
C script supported : just add '#!/usr/local/bin/tcc -run' at the first line of your C source, and execute it directly from the command line.
With libtcc, you can use TCC as a backend for dynamic code generation.

编译tcc source.c,
运行tcc -run source.c,
libtcc的示例在源码包中,
使用.dll或.so的方法(tcc完整命令)文档有说明。
比如肯恩有需要对.dll使用tiny_libmaker.exe并置所生成文件于/lib目录。
在scite添加(也可在对应语言的配置文件中,除非是编辑新的语言文件否则不建议)
command.compile.*.c=tcc/tcc $(FileNameExt)
#command.build.*.c=tcc/tcc -run $(FileNameExt)
执行会有输出,dos命令用"cmd /c "执行。
其他:
#command.help.$(file.patterns.cpp)=$(CurrentWord)!C:\Program Files\wscite\docs\cpp.chm #添加帮助,比如实用的K&R
用astyle.exe格式化代码,对应"indent"菜单项。
能搜索到别人的配置文件,可以参考。
如需添加调试工具可参考 http://scitedebug.luaforge.net/,
貌似是支持GDB的。
build原本是对应makefile
比如 http://wiki.ubuntu.org.cn/%E8%B7%9F%E6%88%91%E4%B8%80%E8%B5%B7%E5%86%99Makefile

CC=gcc
CFLAGS=-Wall
hello: s1.o s2.o
clean:
rm -f hello s1.o s2.o


scite的配置方式:
在scite中选择打开配置文件是以自身打在,而本身提供了专门的语法高亮。
作者没有提供编辑配置的图形界面,但提供了较友好的默认全局配置文件。
其中的被注释的行(即未开启的行)会以较暗较小的形式展现,默认全局配置文件里已分类列出提供的设置(自行添加或扩展不算的)。可以复制出需要条目或直观的进行修改。
不同配置文件以不同优先级或语言,共同作用。

正则表达式:
用以匹配字符串
http://www.scintilla.org/SciTERegEx.html

| 或
{n} n次
{n,m} 最少n次且最多m次
\ 转义符
[xyz] 字符集合
[^a-z] 负值字符范围
* {0,}
+ {1,}
? {0,1}
? 非贪婪
\d 数字字符
\D 非数字字符
\W [^A-Za-z0-9_]
^$ 字符串的开始结束位置

转文:
http://zh.wikipedia.org/w/index.php?title=%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F&variant=zh-hans

基本概念
一个正则表达式通常被称为一个模式 (pattern),为用来描述或者匹配一系列符合某个句法规则的字符串。例如:Handel、H?ndel 和 Haendel 这三个字符串,都可以由 "H(a|?|ae)ndel" 这个模式来描述。大部分正则表达式的形式都有如下的结构:
替换
|
竖直分隔符代表替换。例如"gray|grey"可以匹配grey或gray。
数量限定
某个字符后的数量限定符用来限定前面这个字符允许出现的个数。最常见的数量限定符包括“+”、“?”和“*”(不加数量限定则代表出现一次且仅出现一次):
+
加号代表前面的字符必须至少出现一次。(1次、或多次)。例如,"goo+gle"可以匹配google、gooogle、goooogle等;
?
问号代表前面的字符最多只可以出现一次。(0次、或1次)。例如,"colou?r"可以匹配colour或者color;
*
星号代表前面的字符可以不出现,也可以出现一次或者多次。(0次、或1次、或多次)。例如,"0*42"可以匹配42、042、0042、00042等。
匹配
圆括号可以用来定义操作符的范围和优先度。例如,"gr(a|e)y"等价于"gray|grey","(grand)?father"匹配father和grandfather。
上述这些构造子都可以自由组合,因此,"H(ae?|?)ndel"和"H(a|ae|?)ndel"是相同的。
精确的语法可能因不同的工具或程序而异。

表达式全集
正则表达式有多种不同的风格。下表是在PCRE中元字符及其在正则表达式上下文中的行为的一个完整列表:
字符 描述
\ 将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。例如,“n”匹配字符“n”。“\n”匹配一个换行符。序列“\\”匹配“\”而“\(”则匹配“(”。
^ 匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。
$ 匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“\n”或“\r”之前的位置。
* 匹配前面的子表达式零次或多次。例如,zo*能匹配“z”以及“zoo”。*等价于{0,}。
+ 匹配前面的子表达式一次或多次。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。
? 匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“do”或“does”中的“do”。?等价于{0,1}。
{n} n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。
{n,} n是一个非负整数。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。
{n,m} m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3}”将匹配“fooooood”中的前三个o。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。 ? 当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+?”将匹配单个“o”,而“o+”将匹配所有“o”。 . 匹配除“\n”之外的任何单个字符。要匹配包括“\n”在内的任何字符,请使用像“[.\n]”的模式。 (pattern) 匹配pattern并获取这一匹配。所获取的匹配可以从产生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中则使用$0…$9属性。要匹配圆括号字符,请使用“\(”或“\)”。 (?:pattern) 匹配pattern但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用“或”字符(|)来组合一个模式的各个部分是很有用。例如: 'industr(?:y|ies)'就是一个比'industry|industries'更简略的表达式。 (?=pattern) 正向预查,在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如, “Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。 (?!pattern) 负向预查,在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如 “Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始 x|y 匹配x或y。例如,“z|food”能匹配“z”或“food”。“(z|f)ood”则匹配“zood”或“food”。 [xyz] 字符集合。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。 [^xyz] 负值字符集合。匹配未包含的任意字符。例如,“[^abc]”可以匹配“plain”中的“p”。 [a-z] 字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。 [^a-z] 负值字符范围。匹配任何不在指定范围内的任意字符。例如,“[^a-z]”可以匹配任何不在“a”到“z”范围内的任意字符。 \b 匹配一个单词边界,也就是指单词和空格间的位置。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”。 \B 匹配非单词边界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。 \cx 匹配由x指明的控制字符。例如,\cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的“c”字符。 \d 匹配一个数字字符。等价于[0-9]。 \D 匹配一个非数字字符。等价于[^0-9]。 \f 匹配一个换页符。等价于\x0c和\cL。 \n 匹配一个换行符。等价于\x0a和\cJ。 \r 匹配一个回车符。等价于\x0d和\cM。 \s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[\f\n\r\t\v]。 \S 匹配任何非空白字符。等价于[^\f\n\r\t\v]。 \t 匹配一个制表符。等价于\x09和\cI。 \v 匹配一个垂直制表符。等价于\x0b和\cK。 \w 匹配包括下划线的任何单词字符。等价于“[A-Za-z0-9_]”。 \W 匹配任何非单词字符。等价于“[^A-Za-z0-9_]”。 \xn 匹配n,其中n为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,“\x41”匹配“A”。“\x041”则等价于“\x04”&“1”。正则表达式中可以使用ASCII编码。. \num 匹配num,其中num是一个正整数。对所获取的匹配的引用。例如,“(.)\1”匹配两个连续的相同字符。 \n 标识一个八进制转义值或一个向后引用。如果\n之前至少n个获取的子表达式,则n为向后引用。否则,如果n为八进制数字(0-7),则n为一个八进制转义值。 \nm 标识一个八进制转义值或一个向后引用。如果\nm之前至少有nm个获得子表达式,则nm为向后引用。如果\nm之前至少有n个获取,则n为一个后跟文字m的向后引用。如果前面的条件都不满足,若n和m均为八进制数字(0-7),则\nm将匹配八进制转义值nm。 \nml 如果n为八进制数字(0-3),且m和l均为八进制数字(0-7),则匹配八进制转义值nml。 \un 匹配n,其中n是一个用四个十六进制数字表示的Unicode字符。例如,\u00A9匹配版权符号(?)。


就差不多,结束。

附,我的"SciTEGlobal.properties"

#help=K&R


#command.build.*.c=tcc/tcc -run $(FileNameExt)

#view.indentation.guides=1

#command.help.$(file.patterns.cpp)=$(CurrentWord)!C:\Program Files\wscite\docs\cpp.chm

#font.base=size:12

#http://www.scintilla.org/SciTERegEx.html
#wikipedia

caret.line.back=#FFFED8

#command.build.*.c=tcc/tcc -run $(FileNameExt)
#size,pos

api.*.c=$(SciteDefaultHome)/c.api
#api.*.c=$(SciteDefaultHome)/c2.api

#code.page=65001
code.page=936
character.set=134
font.base=size:12
autocompleteword.automatic=1
#autocomplete.choose.single=1
#autocomplete.cpp.start.characters=*
command.compile.*.c=tcc/tcc $(FileNameExt)
autocomplete.cpp.fillups=(
fold.symbols=3

tabsize=4
indent.size=4
#娴嬭瘯
#abbreviations.*.c=$(SciteUserHome)/c_abbrev.properties
abbreviations.*.c=$(SciteDefaultHome)/c_abbrev.properties


#你会哦


用来写BAT,XML感觉也不错。BAT的":line"会整行背景加黑,很有效果。

====
090806
配置文件又添加了


command.name.0.*.c=Debug
#command.subsystem.0.*.c=1
command.0.*.c=cmd /c D:\MinGW-3.4.5\bin\gcc -g $(FileNameExt) -o $(FileName).exe && D:\MinGW-3.4.5\bin\gdb $(FileName).exe

注意gcc和gdb的路径
gdb我常用有(记得是)
break
r
q
c
n
display
watch
p
可以在不引起歧义下只输入前几个字符

====
090818
在Win32下,tcc版本0.9.24
编译libtcc.dll:
可以使用以下命令,编译通过。
http://www.mail-archive.com/tinycc-devel@nongnu.org/msg00338.html

gcc -O2 -shared -Wall -Wl,--export-all-symbols -mpreferred-stack-boundary=2 -march=i386 -falign-functions=0 -fno-strict-aliasing -DTCC_TARGET_PE -DLIBTCC -o libtcc.dll tcc.c

一般情况下编译可使用的,在源码 \win32 有 build-tcc.bat。
要编译 libtcc_test.c 文件,需先tiny_impdef.exe libtcc.dll,并编译时增加参数 -llibtcc。
路径自行注意。
我用的gcc -shared -Os -fno-strict-aliasing tcc.c -DLIBTCC -o libtcc.dll编译(这里是参照那个bat的),也可行。加"-s"不会影响调用该dll的程序的运行。
(config.h为
#define TCC_VERSION "0.9.24"
#define TCC_TARGET_PE 1
#define CONFIG_TCCDIR "."

如果按照Makefile来会使用上面引用的那个参数。
可以自动编译出libtcc.a,是用于静态链接的,tcc协议为LGPL。

没有评论: