VxWorks 发表于 2008-5-28 16:56

[开源] ★-----C语法高亮程序-------★

见论坛里雨中飞燕和RockCarry都做了语法高亮程序,偶一时手痒也做了一个。

用了5天时间完成,一天时间查阅ANSI C资料,做总体设计,一天时间编码,三天时间测试,除虫,写文档。
今天解决了处理预编译指令时的一个BUG,没有再发现错误,移植到windows下编译出win32版。

软件以GPL协议发布,任何人有权向发布者索取源代码。
任何人有权做出修改并重新发布自己的版本,但也必须以GPL协议发布。
你可以从这里下载移植后的windows/dos版源码,以及原始的Unix版源码。
还可以向[email]vx.fish@gmail.com[/email]发送邮件,报告bug或索取源码。

这是Unix版源码,提供最丰富完整的文档资料:
[attach]35036[/attach]
这是移植后的windows版源码:
[attach]35037[/attach]
考虑到windows下编译不方便,这里提供编译后的win32版可执行程序:
[attach]35039[/attach]                      (17:28分修改配置文件bccn.conf后重新上传)

Unix类系统用户在下载源码后可以编译安装:[code]
# make
# make install
[/code]详情请阅读附带的INSTALL文件,安装后可以使用命令man fish获取联机帮助

windows用户请使用fish -h获取帮助,也可以阅读楼下的使用示例。

《========================================================================》
                                       NEWS
2008.05.28  晚上19:30
       更新了所有版本中bccn.conf的小错误。之前在颜色设置中误删字符a,使得预处理不能着色,
全部重新修改后上传,真是一失手成千古恨。

《========================================================================》

[[it] 本帖最后由 VxWorks 于 2008-5-28 19:33 编辑 [/it]]

VxWorks 发表于 2008-5-28 17:05

windows下使用实例:
切换到fish.exe所在文件夹下在命令行下运行fish.exe[code]
fish  -i bc.c  -c bccn.conf  -o bc.txt
[/code]bc.c是下面显示的c程序,用来做测试用的,使用选项-i指定要高亮的源程序输入
bccn.conf是为bccn.net论坛写的配置文件,你可以用记事本打开修改配色方案。
-o指定输出文件,这里输出文件是bc.txt

可以使用下面的命令获取帮助:[code]
fish   -h
[/code]将输出的bc.txt直接贴上论坛就可以了。

生成的bc.txt内容是:[code]
[color=a020f0]#include[/color][color=ff00ff]<assert.h>[/color]
[color=a020f0]#include[/color][color=ff00ff]<stdlib.h>[/color]
[color=2e8b57]int[/color] [color=000000]get_tag[/color]([color=2e8b57]char[/color] *[color=000000]buf[/color], [color=2e8b57]int[/color] [color=000000]index[/color],[color=2e8b57]char[/color] [color=000000]opt[/color])
{
        [color=2e8b57]char[/color] *[color=000000]dest[/color];
        [color=2e8b57]const[/color] [color=2e8b57]char[/color] *[color=000000]SectionName[/color]=[color=000000]sections[/color][[color=000000]index[/color]];

        [color=000000]assert[/color]([color=000000]opt[/color]==[color=ff00ff]'s'[/color] || [color=000000]opt[/color]==[color=ff00ff]'e'[/color]);
        [color=2e8b57]if[/color]([color=000000]opt[/color] == [color=ff00ff]'s'[/color])
                [color=000000]dest[/color]=[color=000000]tag_list[/color][[color=000000]index[/color]].[color=000000]start[/color];
        [color=2e8b57]else[/color]
                [color=000000]dest[/color]=[color=000000]tag_list[/color][[color=000000]index[/color]].[color=000000]end[/color];

        [color=2e8b57]while[/color](*[color=000000]buf[/color] != [color=ff00ff]'!'[/color] && *[color=000000]buf[/color] != [color=ff00ff]'\0'[/color])
                ++[color=000000]buf[/color];

        [color=2e8b57]if[/color](*[color=000000]buf[/color] == [color=ff00ff]'\0'[/color])
        {
                [color=2e8b57]if[/color]([color=000000]opt[/color] == [color=ff00ff]'s'[/color])
                        [color=000000]fprintf[/color]([color=000000]stderr[/color],[color=ff00ff]"配置文件错误:%s\nstart = \n"[/color],[color=000000]SectionName[/color]);
                [color=2e8b57]else[/color]
                        [color=000000]fprintf[/color]([color=000000]stderr[/color],[color=ff00ff]"配置文件错误:%s\nend = \n"[/color],[color=000000]SectionName[/color]);
                [color=000000]exit[/color]([color=ff00ff]1[/color]);
        }

        [color=000000]strncpy[/color]([color=000000]dest[/color],++[color=000000]buf[/color],[color=ff00ff]40[/color]);

        [color=2e8b57]return[/color] [color=ff00ff]0[/color];
}
[/code]将输出的bc.txt直接贴出来即可:


[color=a020f0]#include[/color][color=ff00ff]<assert.h>[/color]
[color=a020f0]#include[/color][color=ff00ff]<stdlib.h>[/color]
[color=2e8b57]int[/color] [color=000000]get_tag[/color]([color=2e8b57]char[/color] *[color=000000]buf[/color], [color=2e8b57]int[/color] [color=000000]index[/color],[color=2e8b57]char[/color] [color=000000]opt[/color])
{
        [color=2e8b57]char[/color] *[color=000000]dest[/color];
        [color=2e8b57]const[/color] [color=2e8b57]char[/color] *[color=000000]SectionName[/color]=[color=000000]sections[/color][[color=000000]index[/color]];

        [color=000000]assert[/color]([color=000000]opt[/color]==[color=ff00ff]'s'[/color] || [color=000000]opt[/color]==[color=ff00ff]'e'[/color]);
        [color=2e8b57]if[/color]([color=000000]opt[/color] == [color=ff00ff]'s'[/color])
                [color=000000]dest[/color]=[color=000000]tag_list[/color][[color=000000]index[/color]].[color=000000]start[/color];
        [color=2e8b57]else[/color]
                [color=000000]dest[/color]=[color=000000]tag_list[/color][[color=000000]index[/color]].[color=000000]end[/color];

        [color=2e8b57]while[/color](*[color=000000]buf[/color] != [color=ff00ff]'!'[/color] && *[color=000000]buf[/color] != [color=ff00ff]'\0'[/color])
                ++[color=000000]buf[/color];

        [color=2e8b57]if[/color](*[color=000000]buf[/color] == [color=ff00ff]'\0'[/color])
        {
                [color=2e8b57]if[/color]([color=000000]opt[/color] == [color=ff00ff]'s'[/color])
                        [color=000000]fprintf[/color]([color=000000]stderr[/color],[color=ff00ff]"配置文件错误:%s\nstart = \n"[/color],[color=000000]SectionName[/color]);
                [color=2e8b57]else[/color]
                        [color=000000]fprintf[/color]([color=000000]stderr[/color],[color=ff00ff]"配置文件错误:%s\nend = \n"[/color],[color=000000]SectionName[/color]);
                [color=000000]exit[/color]([color=ff00ff]1[/color]);
        }

        [color=000000]strncpy[/color]([color=000000]dest[/color],++[color=000000]buf[/color],[color=ff00ff]40[/color]);

        [color=2e8b57]return[/color] [color=ff00ff]0[/color];
}

当然也可以向下面这样在bc.txt文件首尾加入[code][quote][/quote][/code]添加边框。
添加后的内容是:[code]
[quote]
[color=a020f0]#include[/color][color=ff00ff]<assert.h>[/color]
[color=a020f0]#include[/color][color=ff00ff]<stdlib.h>[/color]
[color=2e8b57]int[/color] [color=000000]get_tag[/color]([color=2e8b57]char[/color] *[color=000000]buf[/color], [color=2e8b57]int[/color] [color=000000]index[/color],[color=2e8b57]char[/color] [color=000000]opt[/color])
{
        [color=2e8b57]char[/color] *[color=000000]dest[/color];
        [color=2e8b57]const[/color] [color=2e8b57]char[/color] *[color=000000]SectionName[/color]=[color=000000]sections[/color][[color=000000]index[/color]];

        [color=000000]assert[/color]([color=000000]opt[/color]==[color=ff00ff]'s'[/color] || [color=000000]opt[/color]==[color=ff00ff]'e'[/color]);
        [color=2e8b57]if[/color]([color=000000]opt[/color] == [color=ff00ff]'s'[/color])
                [color=000000]dest[/color]=[color=000000]tag_list[/color][[color=000000]index[/color]].[color=000000]start[/color];
        [color=2e8b57]else[/color]
                [color=000000]dest[/color]=[color=000000]tag_list[/color][[color=000000]index[/color]].[color=000000]end[/color];

        [color=2e8b57]while[/color](*[color=000000]buf[/color] != [color=ff00ff]'!'[/color] && *[color=000000]buf[/color] != [color=ff00ff]'\0'[/color])
                ++[color=000000]buf[/color];

        [color=2e8b57]if[/color](*[color=000000]buf[/color] == [color=ff00ff]'\0'[/color])
        {
                [color=2e8b57]if[/color]([color=000000]opt[/color] == [color=ff00ff]'s'[/color])
                        [color=000000]fprintf[/color]([color=000000]stderr[/color],[color=ff00ff]"配置文件错误:%s\nstart = \n"[/color],[color=000000]SectionName[/color]);
                [color=2e8b57]else[/color]
                        [color=000000]fprintf[/color]([color=000000]stderr[/color],[color=ff00ff]"配置文件错误:%s\nend = \n"[/color],[color=000000]SectionName[/color]);
                [color=000000]exit[/color]([color=ff00ff]1[/color]);
        }

        [color=000000]strncpy[/color]([color=000000]dest[/color],++[color=000000]buf[/color],[color=ff00ff]40[/color]);

        [color=2e8b57]return[/color] [color=ff00ff]0[/color];
}
[/quote]
[/code]添加边框后的效果如下:

[quote]
[color=a020f0]#include[/color][color=ff00ff]<assert.h>[/color]
[color=a020f0]#include[/color][color=ff00ff]<stdlib.h>[/color]
[color=2e8b57]int[/color] [color=000000]get_tag[/color]([color=2e8b57]char[/color] *[color=000000]buf[/color], [color=2e8b57]int[/color] [color=000000]index[/color],[color=2e8b57]char[/color] [color=000000]opt[/color])
{
        [color=2e8b57]char[/color] *[color=000000]dest[/color];
        [color=2e8b57]const[/color] [color=2e8b57]char[/color] *[color=000000]SectionName[/color]=[color=000000]sections[/color][[color=000000]index[/color]];

        [color=000000]assert[/color]([color=000000]opt[/color]==[color=ff00ff]'s'[/color] || [color=000000]opt[/color]==[color=ff00ff]'e'[/color]);
        [color=2e8b57]if[/color]([color=000000]opt[/color] == [color=ff00ff]'s'[/color])
                [color=000000]dest[/color]=[color=000000]tag_list[/color][[color=000000]index[/color]].[color=000000]start[/color];
        [color=2e8b57]else[/color]
                [color=000000]dest[/color]=[color=000000]tag_list[/color][[color=000000]index[/color]].[color=000000]end[/color];

        [color=2e8b57]while[/color](*[color=000000]buf[/color] != [color=ff00ff]'!'[/color] && *[color=000000]buf[/color] != [color=ff00ff]'\0'[/color])
                ++[color=000000]buf[/color];

        [color=2e8b57]if[/color](*[color=000000]buf[/color] == [color=ff00ff]'\0'[/color])
        {
                [color=2e8b57]if[/color]([color=000000]opt[/color] == [color=ff00ff]'s'[/color])
                        [color=000000]fprintf[/color]([color=000000]stderr[/color],[color=ff00ff]"配置文件错误:%s\nstart = \n"[/color],[color=000000]SectionName[/color]);
                [color=2e8b57]else[/color]
                        [color=000000]fprintf[/color]([color=000000]stderr[/color],[color=ff00ff]"配置文件错误:%s\nend = \n"[/color],[color=000000]SectionName[/color]);
                [color=000000]exit[/color]([color=ff00ff]1[/color]);
        }

        [color=000000]strncpy[/color]([color=000000]dest[/color],++[color=000000]buf[/color],[color=ff00ff]40[/color]);

        [color=2e8b57]return[/color] [color=ff00ff]0[/color];
}
[/quote]

[[it] 本帖最后由 VxWorks 于 2008-5-28 18:13 编辑 [/it]]

Loli 发表于 2008-5-28 17:10

占个位置先。。。。。

[img]http://image5.poco.cn/mypoco/myphoto/20080527/11/44345316200805271150431618239162290_008_640.jpg[/img][color=white]

Loli 发表于 2008-5-28 17:19

非Win32图形界面啊。。。只好做插件了

[quote][font=新宋体][size=2][color=#008000]/*****************************************************************
** HighlightCodeV3.0 software by yzfy(雨中飞燕) [url]http://yzfy.org[/url] **
*****************************************************************/
[/color][color=#FF0000]#include<assert.h>
[/color][color=#FF0000]#include<stdlib.h>
[/color][color=#0000FF]int [/color][color=#008080]get_tag[/color]([color=#0000FF]char [/color]*buf, [color=#0000FF]int [/color]index,[color=#0000FF]char [/color]opt)
[color=#800000]{
    [/color][color=#0000FF]char [/color]*dest;
    [color=#0000FF]const char [/color]*SectionName=sections[color=#800000][[/color]index[color=#800000]][/color];
    [color=#0000FF]int [/color]i=[color=#800080]0[/color];

    [color=#008080]assert[/color](opt==[color=#FF8000]'s' [/color]|| opt==[color=#FF8000]'e'[/color]);
    [color=#0000FF]if [/color](opt == [color=#FF8000]'s'[/color])
        dest=tag_list[color=#800000][[/color]index[color=#800000]][/color].start;
    [color=#0000FF]else
        [/color]dest=tag_list[color=#800000][[/color]index[color=#800000]][/color].[color=#FF8000]end[/color];

    [color=#0000FF]while [/color](buf[color=#800000][[/color]i[color=#800000]] [/color]!= [color=#FF8000]'!' [/color]&& buf[color=#800000][[/color]i[color=#800000]] [/color]!= [color=#FF8000]'\0'[/color])
        ++buf;

    [color=#0000FF]if [/color](buf[color=#800000][[/color]i[color=#800000]] [/color]== [color=#FF8000]'\0'[/color])
    [color=#800000]{
        [/color][color=#0000FF]if [/color](opt == [color=#FF8000]'s'[/color])
            [color=#008080]fprintf[/color]([color=#0000FF]stderr[/color],[color=#FF00FF]"配置文件错误:%s\nstart = \n"[/color],SectionName);
        [color=#0000FF]else
            [/color][color=#008080]fprintf[/color]([color=#0000FF]stderr[/color],[color=#FF00FF]"配置文件错误:%s\nend = \n"[/color],SectionName);
        [color=#008080]exit[/color]([color=#800080]1[/color]);
    [color=#800000]}
    [/color][color=#008080]strncpy[/color](dest,++buf,[color=#800080]40[/color]);
    [color=#0000FF]return [/color][color=#800080]0[/color];
[color=#800000]}[/color][/size][/font][/quote]

这个呢?

VxWorks 发表于 2008-5-28 17:21

sigh,3楼贴出来的着色又有问题,还是预处理。
不过还好,这次问题不在程序,是配置文件错了,修改方法:[code]
用文本编辑器打开bccn.conf找到[preprocess]段,
将start =[color=020f0]修改为start =[color=a020f0]
[/code]附带的另一个html.conf没有问题,可以生成完整的html网页。

楼上的,我的着色是模仿大多数编辑器的方案,只对关键字,常量,注释,预处理指令进行处理。

[[it] 本帖最后由 VxWorks 于 2008-5-28 17:25 编辑 [/it]]

切忌浮躁 发表于 2008-5-28 17:22

试下

[color=020f0]#include[/color] [color=ff00ff]<stdio.h>[/color]
[color=020f0]#define[/color]  [color=ff00ff]max(a,b) \
(a)>(b)?(a):(b);[/color]

[color=2e8b57]int[/color] [color=000000]test1[/color]()
{
        [color=2e8b57]int[/color] [color=000000]a[/color]=[color=ff00ff]1[/color];
        [color=2e8b57]int[/color] [color=000000]b[/color]=[color=ff00ff]0x2efd[/color];

        [color=2e8b57]double[/color] [color=000000]f1[/color]=[color=ff00ff]0.2548[/color];
        [color=2e8b57]double[/color] [color=000000]f2[/color]=[color=ff00ff]0.2e3[/color];
        [color=2e8b57]double[/color] [color=000000]f3[/color]=[color=ff00ff]5.4E5[/color];

        [color=2e8b57]char[/color] *[color=000000]string[/color]=[color=ff00ff]"hello\n"[/color];         [color=0000ff]/*hello world*/[/color]        
        [color=000000]printf[/color]([color=ff00ff]"hello wold"[/color]);        [color=0000ff]//hello   你好  
[/color]        [color=2e8b57]return[/color] [color=ff00ff]0[/color];
}


[color=2e8b57]int[/color] [color=000000]test2[/color]()
{
        
        [color=2e8b57]char[/color] *[color=000000]string[/color]=[color=ff00ff]"hello\n\";         /*hello world*/
       
        printf(\"hello wold"[/color]);        [color=0000ff]//hello world
[/color]
        [color=2e8b57]return[/color] [color=ff00ff]0[/color];
}

切忌浮躁 发表于 2008-5-28 17:27

这个是怎么的

将start =修改为start =
这个是怎么改?

VxWorks 发表于 2008-5-28 17:33

看6楼
或者重新下载,我已经更新了fish_win32.rar文件

Loli 发表于 2008-5-28 17:37

请问一下楼主,有考虑过什么标签合并的问题么?

[img]http://image5.poco.cn/mypoco/myphoto/20080527/11/44345316200805271150431618239162290_008_640.jpg[/img][color=white]

VxWorks 发表于 2008-5-28 17:39

大家可以使用下面的命令:[code]
[VxWorks @ WinXP] D:\home\fish_win32#fish -i bc.c
[/code]只指定输入,默认使用html.conf配置文件输出一个web网页,然后就可以将着色后的代码贴到自己博客或个人空间。
你也可以建立自己的配置文件,通过-c指示程序读取。

关于命令行选项的用法使用命令fish -h获取帮助。
Unix类用户man fish可以获取更详细的资料。

VxWorks 发表于 2008-5-28 17:41

[quote][bo][un]Loli[/un] 在 2008-5-28 17:37 的发言:[/bo]

请问一下楼主,有考虑过什么标签合并的问题么?

[/quote]

不懂你的意思。什么叫“标签合并”?

Loli 发表于 2008-5-28 17:44

[quote][font=新宋体][size=2][color=#008000]/*****************************************************************
** HighlightCodeV3.0 software by yzfy(雨中飞燕) [url]http://yzfy.org[/url] **
*****************************************************************/
//一个简单的小程序
//for yzfy
[/color][color=#FF0000]#include<stdio.h>
[/color][color=#0000FF]int [/color][color=#FF0000]main[/color]()
[color=#800000]{
    [/color][color=#0000FF]const long long [/color]n = [color=#800080]1[/color];
    [color=#0000FF]return [/color][color=#800080]0[/color];
[color=#800000]}
[/color][/size][/font][/quote]

以上这段代码,你看看你输出的代码的标签,是否有多余的呢?

[img]http://image5.poco.cn/mypoco/myphoto/20080527/11/44345316200805271150431618239162290_008_640.jpg[/img][color=white]

[[it] 本帖最后由 Loli 于 2008-5-28 17:46 编辑 [/it]]

zjl138 发表于 2008-5-28 17:44

为什么我弄不了,我已运行了fish.exe

[[it] 本帖最后由 zjl138 于 2008-5-28 17:56 编辑 [/it]]

VxWorks 发表于 2008-5-28 17:51

所谓的合并原来是这个意思。
这个实现起来不难,延迟输出结束标签就可以了,通过变量记忆上一次着色。

不过我觉得意义不大,毕竟代码中这种连续的情况不常见,所以不会造成太大的浪费。
如果空闲时间多,我会在正式版中加入这种功能。

VxWorks 发表于 2008-5-28 17:58

如遇到问题请仔细阅读2楼的使用示例。

[[it] 本帖最后由 VxWorks 于 2008-5-28 18:14 编辑 [/it]]

zhaoyg 发表于 2008-5-28 18:37

顶LZ。

[[it] 本帖最后由 zhaoyg 于 2008-5-28 18:43 编辑 [/it]]

思考ING 发表于 2008-5-28 18:46

顶,有能力了自己也搞个(???[tk08] )

flyue 发表于 2008-5-28 18:50

手痒是好事。说实在的,看了雨中飞燕的高亮的程序,我也手痒想做一个。可惜没时间

Knocker 发表于 2008-5-28 19:41

几年前某个夜晚,偶然看到有人在"编程爱好者"网站整这个高亮代码玩,心血来潮就写了一个半成品.当时的想法还要完成格式功能并做成IE插件.这样就不需要用户有另外繁杂多余的操作,可以直接贴入或输入代码,在点击IE中[发表贴子]按钮时,捕获button的Click事件,自动格式化与高亮textarea中的C代码.但好象第二天有什么事就没接下去写了,以后也就没什么兴趣了,现在连源码也因上次硬盘故障丢了.
[url]http://bbs.bccn.net/viewthread.php?tid=30920&highlight=%2Bknocker[/url]

Knocker 发表于 2008-5-28 19:48

另外说一句,偶记得偶的高亮大概是这样处理:
1.关键字
2.
while(*Code)
{
         switch(*Code)
        {
                Case  :
                Case  :
                Case  :
                  ....
        }      
}
哈哈,好象用了六七个Case 就处理完了[em12] [em12] [em12]

页: [1] 2

编程论坛