Doom 的呐喊

Crying in the Day of Doom

RPN Calculator for iPhone

从拿到 iPhone 的第一天起,我就在不断地寻找好用的 RPN 计算器。我的要求是

  1. 类似 Emacs Calc 的进栈出栈方式
  2. 无限大的堆栈
  3. 要牛逼

iPhone RPN Icon

我一直使用的都是一个 HP i41CX 模拟器。它基本符合第一条,但是不符合第二条:它的堆栈只有四层,而且最顶层还就是你正在输入的这个。不过它非常非常得符合第三条,看看这个计算器的像板砖一样的手册就知道了。这个计算器也有一些不便,它实在是太复杂了。比如他默认的键盘配置上没有切换弧度和角度的键。键绑定是可以设的,但是我一直没有搞明白怎么设…  同样因为这个原因,我一直不知道怎么算双曲三角函数。其他的 RPN 计算器要不就是操作方式诡异,要不就是功能太少。所以昨天我终于决定自己写一个计算器。

奋斗了两天以后把四则运算都搞定了… -_-  在 iPhone 上开发程序还是很方便的,和在 Mac 上差不多,熟练了以后写界面用不了太多的时间,而且 Interface Builder 做 prototyping 也非常得爽。我的时间主要都浪费在用 UITableView 显示一个堆栈上。UITableView 就是一个和菜单差不多的可选择的列表,几乎每一个 iPhone 程序里都能看到。但是这个东西必须要有一个符合某种特定协议的数据源…  我曾经一度都想自己用 label 和 UIScrollView 实现一个这种列表了…  不过最后搞定以后发现这个东西还是挺爽的,并且附赠动画效果~~

在 iPhone 上开发程序需要花 $99 买一个许可证。… … …… 噢,不对,说错了,是苹果声称你需要买一个,实际上你不需要。免费开发程序的代价就是开发出来的程序只能在 jailbreak 过的 iPhone 上运行。当然这其实没什么,因为各种迹象表明,没有 jailbreak 过的 iPhone 的使用价值其实就和一个板砖差不多。默认情况下,如果你没买这个许可证,Xcode 是不会让你把程序往 iPhone 上传的,只能在模拟器里运行。要想在 iPhone 里运行,

  1. 当然要先 jailbreak
  2. 照着 Compiling 一节
  3. Replacing codesign with ldid,这一节貌似没什么用,我从来没有成功的运行过 ldid,不过我还是做了。
  4. 给 iPhone 装 AppSync 补丁。很多 Cydia 源里都有,比如 hackulo.us 源。
  5. 编译时使用自己生成的那个许可证。

关于调试,在开始使用 Linux 之后,我就再也没有使用过任何调试器,只使用 printf(及各种语言里的等效的函数)。Objective-c 里是有 printf 的,但是比较方便的做法是使用 NSLog()。运行的时候在 Xcode 里选择 Run -> Console,可以看到输出。顺便提一下,Objective-c 的标准库还是很牛逼的,嗯,NSString, NSNumber, NSArray, …

Code Hilighting in ConTeXt

今天需要排一个带 Scheme 代码的文档,里面还有点数学公式,所以决定用 ConTeXt。正好前几天 Steamedfish 同学跟我说过 ConTeXt 可以读取 Vim 的语法加亮,决定看一看。

Google 了一下之后发现 ConTeXt 是使用一个叫做 t-vim 的 module 来干这件事的,我使用的 ConTeXt 发行是 ConTeXt Minimal,于是进入 ConTeXt 的安装目录,更新

./first-setup.sh --extras=t-vim

然后随便排了一个代码。ConTeXt 报错

VIM - Vi IMproved 7.2 (2008 Aug 9, compiled Mar  8 2010 22:56:09)
Garbage after option argument: "-u NONE -e -C -n -c "set tabstop=8" -c
"syntax on" -c "set syntax=scheme" -c "let contextstartline=1" -c "let
contextstopline=0" -c "source 2context.vim" -c "wqa"
"009-vimsyntax.tmp" "

哭了… 这不是要整死我这个 Vim 白痴么… 经过无穷多小时的 google,我终于认识到“Garbage after option argument”错误表示 Vim 的参数有错… 看来要改 t-vim 的代码了。于是打开 t-vim.tex,一看又哭了… 一个 macro 都不认识,这不是要整死我这个 TeX 白痴么… 经过 3000+ ms 的搜索,我终于认识到问题出在 t-vim.tex 的第 344 行:

330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
   {\executesystemcommand
      {mtxrun --verbose --noquote bin:vim
          "-u NONE  % No need to read unnessary configurations
           -e       % run in ex mode
           -C       % Set compatibile
           -n       % No swap
%          -V10log  % For debugging only, will go away later.
           -c \shellescapedquote set tabstop=\@@vstab \shellescapedquote\space    
           -c \shellescapedquote syntax on\shellescapedquote\space 
           -c \shellescapedquote set syntax=\@@vssyntax\shellescapedquote\space
           -c \shellescapedquote let contextstartline=\@@vsstart\shellescapedquote\space
           -c \shellescapedquote let contextstopline=\@@vsstop\shellescapedquote  \space
           -c \shellescapedquote source kpse:2context.vim\shellescapedquote\space
           -c \shellescapedquote wqa\shellescapedquote\space    
            \shellescapedquote#1\shellescapedquote\space "}}

Macro \shellescapedquote 后面的 \space 会在文件名(#1)的后面加上一个空格。而 mtxrun 会把这个空格当作参数的一部分??!!!于是 vim 就会收到一个很诡异的参数而报错。所以我首先想到的解决方法就是把最后那个 \space 去掉。然后发现编译时最后的那个引号(\shellescapedquote)居然就没了,还是出错… 于是我怒了,毅然决定把 mtxrun 换成无敌的 Bash。

\def\runvimsyntax#1
   {\executesystemcommand
      {bash -c "vim -u NONE -e -C -n -c \shellescapedquote set tabstop=\@@vstab \shellescapedquote\space -c \shellescapedquote syntax on\shellescapedquote\space -c \shellescapedquote set syntax=\@@vssyntax\shellescapedquote\space -c \shellescapedquote let contextstartline=\@@vsstart\shellescapedquote\space -c \shellescapedquote let contextstopline=\@@vsstop\shellescapedquote  \space -c \shellescapedquote source /home/corsair/software/context/tex/texmf-context/tex/context/third/vim/2context.vim\shellescapedquote\space -c \shellescapedquote wqa\shellescapedquote\space \shellescapedquote#1\shellescapedquote\space "}}

宇宙终于又开始正常运行了。

IPhone Jailbreak

正在 Dev-team 忙着整 3.1 jailbreak 的时候,惊闻某大牛已经搞出了 3.1 和 3.1.2 都能用的 jailbreak,Blackra1n。遂装,成功。然后第一件事就是装了个 MobileTerminal 和 OpenSSH,呵呵。不过 jailbreak 了以后还是不能运行自己写的代码,有两个问题:

  1. Xcode 只能编译在 simulator 运行的代码,编译 iPhone 上运行的代码还需要 sign。
  2. IPhone 还是需要检查 SHA1 hash。

第一个问题很好解决,编辑文件 /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.1.sdk/SDKSettings.plist,把 CODE_SIGNING_REQUIRED 下面的 YES 改成 NO,然后在 Xcode 里设置项目的 certificate identity 为不需要签名。第二个问题比较麻烦。Cydia 的网站里提到可以在 iPhone 里运行一条命令

sysctl -w security.mac.proc_enforce=0 \
security.mac.vnode_enforce=0

就搞定了。我这里执行以后的确可以运行没有签名的程序了,但是副作用是一旦重启 SpringBoard 就连不上 wifi。不过这个倒是不麻烦,把这两个值都恢复成原来的就行了。其实最好的解决办法是 self-signing。但是我用 codesign 老是出错… 嗯。不废话了,上 pp~~

IPhone Jailbreak

New Theme, with No Change

Not exactly… There are some visible changes. I rewrote the theme of this blog using HTML 5 and CSS 3. Everything seems fine. But can someone please tell me why the following video does not work? (At least not in my Firefox 3.5.)

I tested this theme on Chrome under Windoze, and the video was normal. I don’t know what is wrong with my Firefox because it can play many other videos without problem.

Charisma 更新

我的 blog 发布程序 Charisma 更新了。

  • 可以在配置里设置多个 blog,在程序中选择使用
  • Tag 支持

我平时的需求基本都满足了,下一步可能是加上删除 post 功能。

写了一个 WP 发布程序 aka. 我把自己侮辱了

在试用 Charm 未遂的情况下,我决定写自己的 blog 发布程序。看了一下 XML-RPC 的资料,发现 Python 对 XML-RPC 的包装极好,深得我心,于是简单的把 WP 的 API 包装了一下,开始想界面怎么写。Charm 使用了风格比较古老的菜单界面,我不是很喜欢。写起来比较简单的非交互式命令行参数界面好像也不是很合适,想来想去决定写一个类似 Mutt 的界面。

我以前从来没有用过 ncurse。看了一点 Python 的 curse 模块文档以后我发现我丫就是一个 curse/terminal 白痴,但我发扬了我党“一不怕苦,二不怕死”的大无畏精神,找到了一个从文档上看很强大的库 Urwid,开始写界面,结果写的痛不欲生,生不如死,flag 和全局变量满天飞… 总算把发布功能写完了。

以下是我写之前对程序的预期:

  1. 实现 WP XML-RPC 的全部功能
  2. 类似 Mutt 的界面
  3. 从配置文件里读取全部键绑定
  4. 配置文件里实现多 blog 配置

以下是已经实现的功能:

  1. 实现列出 post 和发布新 post 功能
  2. 类似 Mutt 0.0.1 的界面(估计值)
  3. 硬编码全部键绑定
  4. 硬编码 API URI, 用户名和密码

… 最后套用 Mutt 作者的话:All blog publishing programs suck. This one just sucks the most!

Edit: 这是在 Charisma 里编辑的。

Django in HostMonster

With effort, I finally put one of my Django applications online.  The situation is that HostMonster does provide the Python intepreter, but seems we are not suppose to use Python as a web app language because the Python is version 2.3, and no framework module is pre-installed.  So I first installed the Dejango package to ~/.python, and did some searching to find this.  According to this document, I copied my Django app to /my-web-root/latrine in which “latrine” was the name of my app, and wrote /my-web-root/latrine/.htaccess as

AddHandler fastcgi-script .fcgi
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ latrine.fcgi/$1 [QSA,L]

And wrote a latrine.fcgi script:

#!/usr/bin/env python
# -*- mode: python; -*-
 
import sys, os
 
# Add a custom Python path.
sys.path.insert(0, "/my-web-root")
sys.path.insert(0, "/my-home/.python")
 
# Switch to the directory of your project. (Optional.)
# os.chdir("/my-web-root/latrine")
 
# Set the DJANGO_SETTINGS_MODULE environment variable.
os.environ['DJANGO_SETTINGS_MODULE'] = "latrine.settings"
 
from django.core.servers.fastcgi import runfastcgi
runfastcgi(method="threaded", daemonize="false")

And happily entered http://darksair.org/latrine/ in my browser, which displayed a very friendly 500 internal error.  I was glad that I myself finally made a famous 500 error.  After the excitement, I tried to locate the fault.  I manually ran the fcgi script in a remote shell, and it was all right (Ok, except tons of Python trackbacks.  But that was another thing.).  So I decided that the problem was in .htaccess, which I sadly know nothing about…  After some painful research I notied that the fastcgi module in HostMonster was actually fcgid-script instead of fastcgi-script.  After fixing that in .htaccess, and did some simple Python debug, Latrine Live was online.

YAFV

早就想写一个地球人能用的字体查看器了。现存的字体查看器都存在一个问题,就是只能查看系统已经识别的字体,或者只能查看某个字体文件,所以对于我这种看到好字体就两眼发直且配字体可以配一整天综合症患者来说,系统里要备有两套字体查看器。

But worry no more~~  新一代轻量级字体查看器 YAFV 已经诞生。功能:

  1. 列出系统中的字体名,并查看
  2. 查看指定的字体文件
  3. 查看指定的字体名

Todo: 查看一票字体文件,像在 feh 里一样切换。

EDIT: 查看一票字体文件的功能已经实现,但是有一个严重问题:如果要查看的字体已经被安装到了系统里,会按照系统中的 style 顺序查看,而不是命令行参数中的顺序。这是因为 Qt 只能以 family name 来调用字体。我得看看 Kfontview 是怎么调用字体的…

EDIT2: 最新更新:已经可以正常的查看系统中已安装的字体文件。在 Google Code 建立了项目

Plot with Python

昨天某人给我一堆数据,需要画图。数据是一堆矩阵一个一个的放在文件里,本来想用 Python 处理成 Gnuplot 那种格式就行了,不管画图,后来发现数据多了以后需要一次一次的到 Gnuplot 里 plot "filename" with vector,如果要保存下来还要 set term post, set output xxxx,太麻烦…  遂决定直接用 Python 画了。图形库当然是用传说中的 Matplotlib。为了遵循 KISS 原则,数据处理和画图写成两个程序,用管道连接。

Google 了半天,发现 Matplotlib 里画矢量场的函数叫 quiver -_-,画图流程大概就是

import matplotlib.pyplot as Plot
 
Plot.figure(figsize=(5, 5))
Q = Plot.quiver(X, Y, DX, DY, width=0.001)

然后要直接显示就 Plot.show(),要保存就用 Plot.savefig。Matplotlib 为了给使用者“命令行”的感觉,把整个画图过程做成了一个状态机,搞得我用着很灵异…  效果还是不错的,两个命令用管道一接,很装逼~ 哈哈哈~~

生成 ASCII Arts 的程序

做个广告先:我的 wiki 搬家且更新了,重新设计了 CSS。新地址在这里。

My Wiki

写了一个生成 ASCII arts 的程序,效果如下。

 __   __                           _
 \ \ / / ___  _  _   ___ _  _  __ | |__
  \ V / / _ \| || | (_-<| || |/ _|| / /
   |_|  \___/ \_,_| /__/ \_,_|\__||_\_\

这个程序支持读取 FIGlet 的字体,并且支持两种 kerneling style: 不 kernel 和 fitting。展示如下:

         _____
 _ __   |_   _|   ___
| '_ \    | |    / _ \
| | | |   | |   |  __/
|_| |_|   |_|    \___|
    
       _____
 _ __ |_   _| ___
| '_ \  | |  / _ \
| | | | | | |  __/
|_| |_| |_|  \___|
    
No kerneling Fitting

字体在 figlet 网站下载。顺便展示几个~~

 \_/  _         _      _ |  |
  |  (_) |_|   _> |_| (_ |< o

 .oooooo..o                       oooo        .o.
d8P'    `Y8                       `888        888
Y88bo.      oooo  oooo   .ooooo.   888  oooo  888
 `"Y8888o.  `888  `888  d88' `"Y8  888 .8P'   Y8P
     `"Y88b  888   888  888        888888.    `8'
oo     .d8P  888   888  888   .o8  888 `88b.  .o.
8""88888P'   `V88V"V8P' `Y8bod8P' o888o o888o Y8P

  _____            ______        _  __  __
 / ___/ ___   ___ /_  __/ ___   | |/_/ / /_
/ /__  / _ \ / _ \ / /   / -_) _>  <  / __/
\___/  \___//_//_//_/    \__/ /_/|_|  \__/

嘿嘿 :-D