五月 2, 2013
» Auth-source in Emacs

前幾天將 Emacs 一口氣更新到 24.3 以後,發現有一堆東西都不太一樣了,一執行就回報一堆錯誤。畢竟現在已經有很多工作都在上面進行,工具有問題的話很麻煩,只好花點時間調整。

首先要找出有問題的套件,暫時移出路徑待修,結果一整理下來發現有一大堆根本不曉得為什麼存在的東西會報錯,把 mercurial log 叫出來一看才知道上次整修的時間已經是 2009 了。存在這麼多年卻完全沒印象的東西叫做垃圾,乾脆整個目錄都翻出來整理。(不過我要強調這只是倒垃圾,還不到 dot emacs bankruptcy 的程度XD)

後來在更新 g-client 設定時,發現在新版裡已經改用 auth-source 來取得認證所需的資訊。玩了一下發現這東西還真是不錯,可以把一些認證用的密碼資訊統一管理,並透過 api 來取得。大概瞭解運作方式後,馬上動手整合到跟認證有關的套件中。

auth-source 目前支援兩種用來取得認證資訊的 backend,分別是傳統的 .netrc 和 freedesktop 提出的 Secret Service API.netrc 雖然比較簡單,但對於有 un*x-like 環境使用經驗的人會比較熟悉,再加上 auth-source 支援 GPG 加密過的 .netrc,因此目標就是把敏感資訊都移到 .netrc 裡面管理。另一方面也是因為我沒有 Gnome 或 KDE 環境,沒辦法實驗 Secret Service API。

首先要告訴 auth-source 資料庫的位置,如果沒有特殊需求的話,預設會先找 ~/.authinfo,格式等同於 ~/.netrc。雖然這個檔案一般會將權限設為 600,但裡面存放的是明碼,總覺得不太保險。有使用 GPG 的話,可以將這個檔案加密使用,auth-source 可以處理加密後的檔案,預設檔名會是 ~/.authinfo.gpg。如果想改變存放位置,可以透過 auth-sources 指定路徑:

基本的 .netrc 內容格式如下:

machine <host> login <user> password <pass>

可以看到能儲存的資訊有 host、user、password 三種,而 auth-source 引入新的 key:port,可以用來儲存額外資訊,也可以當作搜尋時的 key 來使用。 使用方式並不難,只要透過 auth-source-search 這支函式,並在 spec 參數指定好用來搜尋的 key 就可以得到結果。例如我想取得某個站的認證密碼:

傳回來的資訊是一個 plist,可以透過 plist-get 取得需要的資訊。其中 secret 欄位的值有可能是一個用來取得真正密碼的函式,因此需要特別處理。除此之外,由於上面的例子中指定找不到就建立一組新資訊,在認證資訊不存在時,可以選擇是否儲存目前設定,一般會需要搭配 auth-source-creation-defaultsauth-source-creation-prompts 以提示使用者輸入不足的資訊:

同時,在第一次建立時也可以從 plist 取得儲存用的程序,直接執行就可以了。

執行這個函式會詢問儲存位置,也可以趁這個時候修改儲存內容。

完成這些工作,取得密碼後就可以丟給真正執行認證的函式處理了。


Filed under: emacs, Note

十月 11, 2012
» 2012 Sep‧東京 Day 6

2012.9.19

總算(寫)到了最後一天啦!整理遊記跟照片真的是很累的事,雖然每天回到飯店都會做一些記錄,但也只有前兩天比較完整,最後幾天的內容幾乎派不上用場。每天下班後只能空出一點時間整理,日子一拖下去很多當時的情境會忘光光;再加上我都在迷路,根本不曉得跑到哪裡,自由行程那兩天的路線有一大半不在計畫內,事後看著照片要查也很難找XD

雖然沒有打算刻意整理,但因為房間內的東西幾乎沒動到,把東西整理完大概就是房間的原狀了。昨晚睡前就先把所有行李都塞好,反正今天應該不會再買東西了… 吧。

吃完最後一天的早餐,就準備 checkout,然後在附近耗掉早上的時間。其實以東京來說,反正交通那麼方便,就算只有半天也可以去其他地方玩一下再回來。不過來了上野那麼多天,一直都沒好好看一下這個城市,所以最後一天就不打算到處亂跑啦。出門的時候正下著毛毛雨,想了一下決定先去買好回機場的車票,再去一趟上野公園,反正還有很多地方沒看到。


買完票以後從不忍池口出去,沿著上坡的路一直走就可以走到不忍池和弁天堂。後來才知道這裡供奉的弁才天是音樂女神和財神,如果早知道的話,應該會想辦法在行程裡排個了法寺吧XD 通過參道時雨勢突然變大,只好跑到屋簷下躲雨,順便休息一下。

在弁天堂的後面亂跑,發現一個劍豪的紀念碑。後來查了一下櫛淵虚冲軒 (くしぶちきょちゅうけん),原來是神道一心流兵法的創始人,本名叫櫛淵彌兵衛宣根,虚冲軒則是他的號。除了劍豪的碑以外,不忍池周圍還有很多奇怪的碑或塚。例如鳥塚,是為了感謝養活人類的雞而立的慰靈塚 (日語中的「鳥」是雞的意思)。附近還有菜刀塚、琴弦塚、和扇塚、魚塚等等,甚至還有為了感謝鱉而立的碑。



由於記憶卡已經滿了,再加上下雨實在有點麻煩,這一天幾乎沒拍到什麼照片。

不曉得是不是因為下雨的關係,來這裡的人很少,只看到幾位像是觀光客的人 (而且還講中文XD)。離開弁天堂以後繼續往上走,如果可以的話是想走到東照宮,途中經過看起來像動物園的地方,但走了半天看不到盡頭,加上雨一直變大,結果中途就折返了XD 回車站的途中參觀了一下花園稲荷神社,原來這裡也跟彰義隊有點關係。稲荷神掌管的是農產品,大概是因為跟民生相關,供奉稲荷神的神社非常多。

回到車站後還有一點時間,想了一下就跑去逛ヨドバシカメラ了。在台灣看不到這麼帥氣的綜合電器商場大樓,趁著一早沒什麼人,直接殺到頂樓慢慢逛下來。本來想說帶個日本配列的鍵盤回去,但挑來挑去沒什麼滿意的 (而且又貴…)。最大的收獲大概就是玩了一下 3DS 和 iPad,見識了裸視 3D 和傳說中流暢的 iPad 操作。除了電器用品,這裡玩具也不少,結果又轉了一顆海洋堂的轉蛋XD 回台灣後打開一看,拿到一個不認識的角色「楪いのり」(連名字都不曉得怎麼輸入XD),但做的相當不錯。


逛完以後又是煩惱午餐的時候了。由於這一趟來完全沒吃到拉麵,很快地就決定去武藏吃つけ麵了。第一次吃這種麵,觀察了一下其他人的動作才開始吃,連吃完可以加熱湯也是問旁邊上班族才知道XD 不過這沾麵用的濃湯真的非常鹹,要不是狂灌冰水實在受不了。下次有機會改吃一蘭好了XD

吃完以後就回飯店拿行李,準備搭車回機場了。當初研究了好久,刻意選上野的原因就是因為回機場太方便了。從京成上野駅搭京成特急回機場,雖然不是最快的,但絕對不會搭錯車XD 而且票價應該是最便宜的吧。六天的旅行就這樣結束啦。在出發前做了很多天鍵盤旅行,但實際走一趟又是完全不同的體驗和感受。這趟除了預定的活動外,也體驗一下日本的現代化、日本的便利,以及和台灣相似又充滿驚奇的異國生活,同時也是自學日語的成果驗收XD

回到台灣以後又是另一個挑戰的開始,要整理上千張照片,遊記,還有戰利品們…


Filed under: Note

九月 23, 2012
» 2012 Sep‧東京 Day 1 – 2


經過一個半小時的路程,總算抵達終點的京成上野駅。上野其實離會場有點距離,當初會選擇住上野只是單純聽過著名的上野動物園,完全不曉得上野在哪。選個名字比較有聽過的地方,在車站附近的話交通也方便,就這樣定下來了。結果根本沒去動物園,只在大到不行的上野公園晃一晃而已。


到了京成上野站後,先到遊客中心搜括一堆地圖和景點情報,順便熟悉一下車站附近的路。結果往著名的アメ横移動時已經是下午四點啦。這個時間人非常多,為了感受一下氣氛,我決定不走大馬路,直接穿過アメ横的小路到旅館。這裡因為是著名的消費景點,店家多,人也非常非常多,但我拖著行李在外面玩了三個小時已經有點累了,完全沒有心情逛街,只想趕快找到旅館休息。邊迷路邊在人群中穿梭,最後幸運從一個蠻近的路口穿出來,剛好可以看到接下來幾天要住的地方。


從車站到旅館,走過這一段路才慢慢意識到,原來要靠左邊走阿,難怪一直撞人XD 但其他人也很體諒地閃開,大概看我拖著行李一副快走不動的樣子吧。但有可能心裡想著:又是個死觀光客吧XD 過去的台灣不管在語言或生活習慣上都受到日本的影響,但到了日本雖然可以感受到親切感,還是有不少文化和生活習慣上的差異可以很直接感受到。在這樣一個熟悉又陌生的地方,看著周圍熙熙攘攘的行人,想起在阿部寬在電影中說的「扁臉族」,不由得輕笑起來,調整心情開始享受接下來幾天的異國生活。


雖然才剛到日本,但這一天的晚上已經預定有日本主辦單位方面為我們 (應該說是外國參加者) 辦的 Welcome Party,地點在品川附近。由於時間還早,研究了一下在車站拿到的地圖後,決定再次穿過アメ横,到御徒町駅搭車。


上野的馬路上幾乎都是公車和汽車,幾乎看不到機車。除此之外就是自行車和行人了,路口大概都看得到專門給自行車或行人使用的號誌。有趣的是自行車跟行人共用紅磚道,也有專用的停車場。在日本騎自行車的人不少,甚至還遇到有人邊玩手機邊騎,看到行人也可以如常閃避,實在太厲害了。台灣雖然沒有專用號誌,但有些地方鋪了自行車專用道,只是常常看到上面停滿汽車,自行車一樣跟行人爭道,相當可惜。

到了車站,真是慶幸有先買好 suica,只要在閘門嗶嗶一下就可以進去了,不必到車站還在算車資買票,也不會忘了取票 (回程就遇到了,還好有人提醒XD)。到這裡我才知道為什麼很多人推薦住在山手線附近,因為搭車實在太方便了。雖然東京有可怕的地鐵網,但山手線的鐵軌在天上,不要離太遠的話抬起頭就會看到,找到後沿著走就會到車站;地鐵的入口常常隱藏在建築物間,路不熟的話實在沒那麼容易找。


因為是個小車站所以很容易就找到月台,沒兩分鐘車就來了。這裡可以搭到山手線和京浜東北線的車,Welcome Party 的會場得先到浜松町駅,不管搭哪一條線都到得了,所以隨便看到有車就上也不用怕,也不用管什麼內圈外圈,只要方向對就沒問題。為了確保不會跑錯方向,至少要先記住幾個大站的方向,例如東京、上野、品川和渋谷等地方的相對位置。雖然 JR 上的網頁已經提供了足夠的資訊,但出門在外沒網路,也沒印出來的情況下,如何掌握最少情報就不會迷路也是很重要的。

後來發現這些車站的樣子,在 Youtube 上很容易找到影片,真的很擔心的話也可以先研究看看。我因為匆忙出門,根本沒想到要先研究一下路線,事後也證明沒那麼難,只要在看得到鐵軌的範圍亂跑,要迷路還真不容易。但這些話對於還沒體驗過的人來說應該還是聽不進去吧 (我當初也是這樣XD),總之還是只能說,去了就知道搭車沒那麼難。

雖然順利解決了搭車問題,沒想到接下來又遇到大問題。到了車站後,根據之前的情報會有穿黃衣的工作人員在車站帶路,沒想到提早半小時到還是看不到人。我因為沒帶餐廳地圖只好憑著記憶在車站到處問人,連超商員工都被我抓來問了,還是沒半個人知道餐廳位置 (其實不能怪他們,因為我忘了店名,只記得是雞肉料理的店,能找到也太神了)。最後已經想放棄,正打算隨便吃個拉麵回去時,竟然在車站內撿到跟我一樣被丟下的 hychen 和 kanru XD 三個人在外面繞了很久還是找不到,最後只好在路邊找了家居酒屋先解決晚餐。回來一查才發現一度走到很近的地方了,再往前走個一分鐘應該就到了,沒想到一直鬼打牆,在反方向繞半天 (誰叫那邊剛好有另一家雞肉料理的店,名字不同所以走到一半就折回來了XD)。


第一次去居酒屋也是新奇的體驗。在電車上看到一本正經的上班族,進了居酒屋後跟發瘋一樣,一整個吵。因為點了很多花時間的燒烤料理,所以除了聊天以外都在偷聽隔壁桌的上班族抱怨工作,沒想到可以聽得懂一大部份,所以邊吃邊聽還蠻有趣的。在居酒屋待到十一點多,最後回到上野已經快十二點了。回到飯店第一件事就是打開電視,好久沒看的 BS 放送,真懷念啊~


Filed under: Japan, Note, Travel

» 2012 Sep‧東京 Day 1 – 1

我想這系列很有機會演變成充滿內心戲且冗長的遊記。

這次會決定跑一趟東京,其實自己也很意外。這幾年已經跟社群活動太接近了,有點不太習慣,但有時候就是會一衝動做出奇怪的決定。現在回想起來,整個決策並沒有太多猶豫。決定要去以後就開始安排工作進度,拿到假單以後才開始訂旅館和機票。以前這些事情都是交給公司或旅行社處理的,第一次全部自己來其實有點興奮,但也很怕一個環節出錯就出不去了XD 雖然研究了許多網路上的心得,大概把該做的事都整理出來了,不過有朋友的幫忙讓整個進度更順利,很快就處理好住宿和交通問題。

一直到這時候才到 Connpass 系統報名,家人還確認了好幾次,問我是不是真的打算去一趟。沒想到晚了半個月報名的序號竟然讓我抽中兩份獎品,這是後話了。

總之,決定到 PyConJP 看看了,再加上兩天背包迷路之旅。


認識我的人中應該有不少人知道我學過一點日文,也許會存在我很熟悉日本這種錯誤印象,事實是我對日本完全不熟,也從沒想過要去日本。對我來說,日文就像英文一樣只是個方便的工具,讓我可以看懂日文的技術 Blog 和台灣還沒出版譯本的小說。因此到日本這件事對我來說實在是個不小的挑戰,畢竟我連東京的位置也只有個模糊的概念,更別說要安排兩天的自由行程了。除了兩個非去不可的點以外,其他的時間一直到飛機起飛都還是空白的,有點大冒險的感覺。

雖說到日本已經相當簡單了,出發前還是忍不住擔心老半天,會不會因為天候因素停飛?會不會因為某些原因無法出境之類的?以前就算上日籍老師的課,也都是懂不少中文的日本人,這下真的要面對完全不懂中文的日本人了,說得出口的日文到底能不能派上用場還不曉得… 我可不想跟日本人用英語交談。雖然看到很多人完全不懂日語也是玩得很開心,但我想既然都去一趟了,總要確認一下之前學的東西是不是有用,就當作真正的期末考口試吧。

總之出發前的幾天腦中一片混亂,先前查了幾天的資料在出發前通通忘光光,地圖來不及印,到出發前一天連交通手段都還沒查清楚。最後只好自暴自棄,到目的地後再見機行事吧!但總不能回不來吧,所以只確認了回機場的方法就出門了。


因為我只有一個人,實在很怕回程當天睡過頭錯過飛機,所以絕對不能搭太早的飛機XD 研究了好幾天,很幸運地訂到早去晚回的機票,所以一大早就得出門。

一早的機場就有很多旅遊團待命,找到報到的櫃台後就早早拿到登機證,等著登機時間。這時遇到 hychen 和 kanru 也來了,不過因為我逛了一下玩具店,比較晚一點到。那個樂高店實在很致命,但應該沒有人出門前又增加行李的吧XD 三個人在候機的時間幾乎都在聊 emacs 的操作心得 (好像有點宅XD)

搭機的過程沒什麼特別的所以沒有照片。真要說的話就是空服員一下跟我說英文,一下說日文,搞得我有點混亂XD 機上看了宇宙兄弟和一點點羅馬浴場 (テルマエ・ロマエ),兩部都是極度推薦的電影。ANA 的飛機餐很普通,但全部吃完還是可以有一點飽足感。

三個多小時的飛行很快就結束,之前聽說了十分鐘通關的神話,所以我也挑戰了一下。可能因為人不多吧,其實還蠻容易達成的,重點還是在先填好入境用的資料。這時候還不到一點半,邊等其他人邊逛機場,不過這時首先要解決的是搭車問題。這次住的地方在上野,我只記得要搭什麼特急的,但資料沒準備齊全也想不起來,最後只好鼓起勇氣開口問啦。從賣票的大姐姐問到義工(?)媽媽,連穿警衛制服和推車的也都抓來問了,最後總算順利被引導到京成特急的售票口 (其實沒有很難走啦,只是想多適應一下日文環境)。


匆匆買了一千日幣的車票後又問到賣 suica 的地方 (根本沒看到什麼みどりの窓口阿XD),最後是在紅色窗口買到的。問了一下哪些地方可以儲值,賣票的大哥哥說到處都可以,只要有機器就可以儲值 (這不是廢話嗎XD)。整備完成找到月台後已經兩點了,這時對面剛好停著還沒出發的 N’EX,看到帥氣的 N’EX 的車廂有點後悔選擇京成特急XD

到日本旅遊的台灣人實在很多,從機場到月台間,聽到的都是中文比較多。而機場內其實也到處都是中文指標,就算不懂日文也沒那麼容易迷路。到月台時已經一堆講中文的人在等車了 (從口音推測是台灣人)。



車子到了以後看到傳說中的相親座了。除了車內廣告都是日文,乘客全都帶著大包小包的行李以外,跟在台灣搭車沒什麼差別。比較特殊的是博愛座附近貼著提醒手機要關機的標示。

由於是電車,途中有很多人上車,從女學生到老奶奶都有。車上很少人會交談,途中的當地人上車後不是低頭玩著手機就是睡覺補眠。後來有兩位老奶奶上車後一直在聊天,原本以為老人說的話會比較難懂,但後來才發現這種說話速度反而容易聽懂。一個半小時的車程很無聊,不是看著窗外的景色就是到處拍拍拍。

搭電車其實蠻有趣的,雖然每一站都停實在很花時間,但可以看到當地人,也可以慢慢欣賞沿途景觀。比起搭觀光巴士直達旅館的規畫,我的冒險可是從下飛機後就開始了。途中看到許多坡道和正在辦活動的河堤,因為是很多動漫畫會出現的場景,看到後開始有來到日本的感覺了 (河堤跑太快來不及拍XD)。


(待續)


Filed under: Japan, Note, Travel

十月 30, 2011
» Extending Gforth with the Code Word

很久沒發文了,但一直都有記錄筆記的習慣,原本也是打算整理好發表的,但常常寫到一半就去做其他事了,所以積了不少未完成的稿XD 這次出清一篇筆記,來談談 forth 中的 code word。

一般對於 forth 系統的擴展有兩種方式,最方便的當然是定義新的 colon word,另一種則是實作比較低階的 code word。

code word 代表的是低階實作,也就是直接跟底層平台對話。以 lisp-based forth 為例,其實就是把 lisp vm 當作(虛擬)硬體平台,因此 code word 作用大概就是產生一堆 lisp form,而 x86 native forth 當然就是產生 x86 machine code 了。

簡單地說,code word 需要負責兩件事:

  • 產生 native code
  • 讓 forth 可以順利執行這些 native code

產生 native code 的工作通常會由一個 target assembler 負責。這也是為什麼一個完整的 forth system 多半會提供自己的 assembler。雖然 forth 已經是可擴展的設計,但在需要直接操作宿主平台時,可能會需要寫成 code word 比較方便。

比較麻煩的是第二點,讓 forth 可以順利執行的關鍵在於不能干擾系統運作。forth 本身雖然是 stack vm,但還是有幾個基本的暫存器,一般在 x86 上會對應到實際的暫存器。依照實作模型的不同,可能會需要佔用 2 至 5 個不等。在 code word 中必須妥善管理這幾個暫存器,不是單純 pushapopa 就可以解決的。最常見的狀況,就是維護 SP 的值 (forth 中的 SP 暫存器,非 x86 的),確保參數可以正常傳遞,不會發生 underflow;以分支指令來說可能需要修改 IP 的值,只要改錯暫存器就會發生災難。因此第一步就是找出這幾個暫存器的對應關係。

在一般的 forth 系統中,通常會提供一個叫做 see 的 disassembler,可以透過它來猜出系統的規劃。Gforth 套件提供了好幾種實作,由於接下來的實驗在不同實作中會有不同結果,為了方便解說只使用 gforth-fast。在 Gforth 中,第一個建議觀察的是什麼事都不會做的 noop

see noop
Code noop
( $804B1BF )  add     esi , # 4  \ $83 $C6 $4
( $804B1C2 )  mov     ebx , dword ptr FC [esi]  \ $8B $5E $FC
( $804B1C5 )  mov     eax , ebx  \ $89 $D8
( $804B1C7 )  jmp     804B03C  \ $E9 $70 $FE $FF $FF
end-code

從這邊可以猜到不做事的時候,系統大概會使用 eaxebxesi,然後跳到某個位址繼續執行。因此觀察其他 word 的時候就可以先去除這幾個動作,找出真正關鍵的操作。接下來建議的是 dupdrop。這兩個 word 是基本的堆疊操作,可以直接找出 SP 在哪,甚至可以看出是否有加入 TOS (Top Of Stack) 的快取設計,也就是將 TOS 放在特定的暫存器以減少一次記憶體操作。

see drop
Code drop
( $804C836 )  add     edi , # 4  \ $83 $C7 $4
( $804C839 )  add     esi , # 4  \ $83 $C6 $4
( $804C83C )  mov     ebp , dword ptr [edi]  \ $8B $2F
( $804C83E )  mov     ebx , dword ptr FC [esi]  \ $8B $5E $FC
( $804C841 )  mov     eax , ebx  \ $89 $D8
( $804C843 )  jmp     804B03C  \ $E9 $F4 $E7 $FF $FF
end-code

drop 的內容可以看到除了 noop 以外,還操作了 edi,沒有意外的話 SP 就是它了。同時也知道堆疊往低位址成長 (因為 drop 相當於做了一次 stack pop)。作為佐證可以再觀察一下 dup,應該會看到減少 edi 內容值的運算:

see dup
Code dup
( $804C85D )  sub     edi , # 4  \ $83 $EF $4
( $804C860 )  add     esi , # 4  \ $83 $C6 $4
( $804C863 )  mov     dword ptr 4 [edi] , ebp  \ $89 $6F $4
( $804C866 )  mov     ebx , dword ptr FC [esi]  \ $8B $5E $FC
( $804C869 )  mov     eax , ebx  \ $89 $D8
( $804C86B )  jmp     804B03C  \ $E9 $CC $E7 $FF $FF
end-code

看起來的確有移動 edi 內容的操作。另外還看到奇怪的動作,把 edp 的內容搬進 stack top – 1 的位置,並不是移動到 stack top,推測 可能有 TOS 的設計。

要證實這一點,可以再看一下 swap+ 這幾個會影響 TOS 的 word。

see +
Code +
( $804B918 )  add     ebp , dword ptr 4 [edi]  \ $3 $6F $4
( $804B91B )  add     esi , # 4  \ $83 $C6 $4
( $804B91E )  add     edi , # 4  \ $83 $C7 $4
( $804B921 )  mov     ebx , dword ptr FC [esi]  \ $8B $5E $FC
( $804B924 )  mov     eax , ebx  \ $89 $D8
( $804B926 )  jmp     804B03C  \ $E9 $11 $F7 $FF $FF
end-code

看來的確是把運算後的結果 (TOS) 直接放到 ebp 了,而不是放在記憶體中。拿到 SPTOS 後就可以試著增加一個 code word 看看了。首先用最簡單的 dup 操作來驗證前面的猜測,實作一個有相同操作的 _dup

code _dup
    bp di ) mov
    4 # di sub
    next
end-code

3 _dup .s

可以看到堆疊中的確出現兩個 3 了。不過看起來自己實作的 _dup 好像比原版的 dup 還要精簡一點。另外也可以寫個 _+ 看看:

code _+
    4 # di add
    di ) bp add
    next
end-code

2 3 _+ .s

結果也正確無誤,留下一個 5。到這邊已經可以做很多事了。不過偶爾可能會需要 RP,所以從 >r 找到 RP 放在記憶體的某處。查找的過程不再列出,同樣複製一個相同的 _>r 來驗證看看:

code _>r
    4 # $3c sp d) sub
    3c sp d) bx mov
    bp bx ) mov

    4 # di add
    di ) bp mov
    next
end-code

為了維護 return stack, >rr> 通常要平衡使用才不會破壞系統運作,所以我將自己實作的 _>r 搭配系統的 r> 一起使用,測試過可以正常執行。

除了這幾個重要的暫存器外,還有一個 IP,可以透過觀察 branch 找到,這裡就不再贅述了。不過還有一件重要的事需要特別提出來討論。在整理這篇筆記的過程中,我發現一個嚴重的問題:以前實驗的結果,在 0.7.0 版的 gforth-fast 可以正常運作,但換成 0.7.9 版卻無法動作,後來試了一下 0.6.2 也同用無法執行。查了文件才知道原因在於 c compiler 版本。由於不同版本的編譯器執行 register allocation 結果可能不同,會產生出完全不一樣的 forth vm,這點是特別要注意的。前面列出來的結果是在 gcc 4.4.4 建立出來的 gforth-fast 0.7.9 的環境重新實驗的。如果使用到的暫存器剛好都是自由的 (不被系統使用),換系統時就不需要再調整程式了。

雖然聽起來有點糟,但對我來說也不算什麼大問題就是了。畢竟 forth 在各系統間的相容性本來就不能期待,會想使用 code word 的人大概對正在使用的系統也有一定的掌握能力了,這樣程度的相容性問題應該都有能力處理。


會翻出這篇筆記,主要是看到有人做了一個 benchmark,gforth-fast 需要的時間是其他 forth 的好幾倍,想試試把幾個關鍵處改寫成 code word,看有沒有機會加速。最後實驗的結果是… 不行!

囧rz

非但沒變快,反而更慢了XD 也許 Gforth 在切換成 code word 可執行環境時做了很多事,因此效能不如全部都使用 colon word;也許是 instruction miss 等原因造成的吧。這個一時興起的實驗提醒了我在選系統時要記得同時測試一下 code word 的使用,暫時還是先把 Gforth 的 assembler 當作 cross assembler 使用吧。


Filed under: forth, Note

十月 26, 2011
» TestPost

不好意思,之前發現 emacs 沒辦法發出文章了,這篇文章單純測試用 測完沒問題就刪掉 <!–more–> 測試程式碼 <pre class="src"> <span style="color: #00cdcd;">init</span>: <span style="color: #00cd00;">xor</span> ax, ax <span style="color: #00cd00;">mov</span> ds, ax <span style="color: #00cd00;">mov</span> es, ax </pre> <p>測試<a target="_blank" href="http://www.google.com/">超連結</a>是否正常</p> <ol> <li>item 1</li> <li>item 2 <ul> <li>qwer <ul> <li>abcde</li> </ul></li> <li>tyui</li> </ul></li> <li>item 3 <ul> <li>mjkl</li> <li>eoru</li> </ul></li> <li>item 4</li> </ol>

五月 4, 2009
» [Note] 送patch所學到的事

這個Note是一個寫patch的經驗,前陣子寫了一個讓curl即時壓縮加密FTP/HTTP/SFTP上傳時可以續傳的一個patch,patch本身倒是沒什麼特別的,反而是在送patch跟原作者的討論過程中學到了一些東西。patch歷時約一個月才commit進cvs,不過我覺得以open source的專案來說,這樣算挺快的。

似乎還是得把前因後果交代一下,
其實一開始是我有一個想法,
就是希望我上傳到遠端伺服器的檔案都能加密起來(順便壓縮更好),
但是我覺得在local這邊先壓縮過然後再上傳的話,就會佔Local的硬碟兩份空間,所以最好的方法是realtime壓縮加密之後上傳。這樣就不會佔用local的硬碟空間,而以目前的CPU也應該都可以做到即時傳輸。
此外我希望就是能夠彈性的選擇壓縮及加密方式,不論是bz2,gzip,pkzip或是pgp及AES都要能夠自行選擇及combine。
而且最好是不需另外的伺服器程式,以目前hosting都會提供的FTP帳號就能做的方法是最好。(我需要的不是像SFTP或FTP/TLS這樣傳輸時加密或壓縮而已,我想要的是在伺服器上的最終結果也是加密及壓縮過的)

跟lloyd討論之後,他是認為lftp+namepipe的方式可行。
另外我也找到了用pipe透過curl上傳的方法。
而這兩個方法也都驗證過確實可行,不過這兩個方法都同樣有個問題,就是沒辦法續傳,而這我認為是個應該要解決的問題。

比較了兩個解決方案後,我選擇了擁有我比較喜歡的BSD license,用法也比較彈性的curl下手修改,
curl的續傳問題大概長這樣:

gzip /mnt/2311/debian-500-i386-CD-1.iso -c | curl -T - -C -
ftp://myname:mypass@192.168.23.11/debian-500-i386-CD-1.iso.gz
** Resuming transfer from byte position 46792704
% Total % Received % Xferd Average Speed Time Time Time
% Current
Dload Upload Total Spent Left
Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:--
0
curl: (31) Could not seek stream

最主要是stdin不能直接SEEK_SET,這其實不是什麼大問題,不能SEEK_SET就SEQUENCIAL READ並bypass即可,看了一下原始程式便發現其實這段code早已大部完成了,只要略為更動即可,
於是略為修改了一下curl FTP/SFTP/HTTP上傳部份的code,驗證之後便將patch送出。
原以為送出patch之後就結束了,因為作者要收不收這也不是我能控制的,不過後來curl的作者回信說,功能是沒有問題,但原本的patch會影響到ABI與目前文件的相容性,問看看我是否能提供不修改ABI的作法,我原本還無法理會作者的意思,後來繼續討論才慢慢了解,作者的意思是看能否提供完整的ABI及定義回傳值供其他使用curl library部份的程式參考,因為curl不僅僅是一個客戶端程式curl,同時也包含一套廣泛的運用在其他程式甚至內建在程式語言中的library,libcurl。即使是改動小小的部份,也有可能不經意的影響到其他重要的程式。
了解了作者的目的之後,於是我又寫一個新的patch配合這個架構,測試一下續傳上傳沒問題之後就又再次的送出,這次作者將我的多個patch檔結合後又修改了一下包括說明文件的patch就直接commit到cvs上,不過問題來了,做make test的測試到HTTP PUT該項時沒過。
仔細的研究一下,還真的是第二次更動的code造成了問題。第三次的修改並驗證之後,這次就很快的patch就被接受了,目前已經commit在curl的cvs上。

這次寫patch得到一些經驗:

1. 寫patch時應配合原程式的架構及style,會比較容易被接受。
2. 寫完patch之後應照原程式的測試方式做一遍測試,而非只是測試自己的情況。
3. 大部份時候都要仔細考慮並聆聽來自原作者的意見,畢竟他是最清楚全部情況的人。
4. 不要懶的送patch,雖然可能會多費一些時間跟功夫,但送了patch通常可以學到更多。

ref: 我和curl作者討論的過程,https://sourceforge.net/tracker/?func=detail&atid;=100976&aid;=2709004&group;_id=976

二月 11, 2009
» Line wrap in Emacs

在大部份的編輯器中,對付太長的文字列通常用的是自動換行 (line wrap),就我目前所知,在 Emacs 中有以下幾種不同方式可以選擇:

Line wrap

預設行為即是一般常見的 line wrap。在這種環境下的文字內容並不會被更動,僅在顯示時將超出視窗邊界的部份顯示在下一行,同時在換行處加上一個記號 (如箭頭標示處):


在切割視窗時情況不同:


可以設定一下得到相同行為:

(setq truncate-partial-width-windows nil)


Truncation

打開 truncate line 以後,超出視窗邊界的部份不顯示,同時會在邊界處顯示一個特殊符號作為識別 (與 line wrap 時用的符號不同)。一般適合在寫程式的時候使用

M-x toggle-truncate-lines


也可以寫到 .emacs

(setq default-truncate-lines t)

為了方便可以設個快速鍵:

(global-set-key [f11] 'toggle-truncate-lines)

Filling text

fill 是破壞性操作,會根據 fill-column 的值強制在特定位置插入換行字元。手動操作時只需要按下 M-q 即可,或是乾脆啟用 auto fill:

M-x auto-fill-mode


fill-column

換行寬度可以自行修改,因為設定 fill-column 要求一個數值當作參數,:

C-u 60 M-x set-fill-column

C-u 60 C-x f

fill-prefix

fill-prefix 的內容會自動加到被修改的文字列前面,預設為 nil (代表換行後前面不加任何字)。假設 fill-prefix"… ",則換行後會在該列最前面加上 "… "

設定這個參數可以用 set-fill-prefixC-x .,要注意的是這個動作會將游標所在位置前的同列文字設為 fill-prefix,若在斷行處操作,則整列文字都會被採用。因此我建議透過 eval 方式設定:

M-: (setq fill-prefix "... ")

或乾脆寫進 .emacs


fill prefix 對於整理程式碼註解很有幫助,但對於一般文字也許會造成困擾。要取消 fill-prefix 只需要找個空行再設定一次即可 (minibuf 會顯示 "fill-prefix cancelled")

Long line mode

相較於 fill mode,long line mode 則是溫和的非破壞性操作,只是在顯示上調整成 fill mode 的效果 (soft newline),並不會真的插入換行 (hard newline):

M-x longlines-mode


但顯示與實際內容畢竟有差別,可以將真正的換行處以特殊符號表示以資識別:

M-x longlines-show-hard-newlines


在處理長文字列的顯示上,Emacs 提供了豐富的設定以應付各種需求。就我個人來說,對於一般的文章我習慣用 line wrap 型式顯式;而在編輯程式碼的時候,這種方式反而會破壞縮排的視覺效果,這時改用 truncation 就很適合了。至於 long line mode,我到現在還沒用過。當然,一般編輯程式碼的時候很少會出現超長的程式碼 (也許寫 gtk 程式時例外XD),閱讀上非常不便。非不得已的時候,我會想辦法在 80 columns 內先斷行 (以前留下來的習慣@@),非超出視窗不可的部份,就交給強大的編輯器來處理吧!

Reference


Posted in emacs, Note

二月 5, 2009
» 透過 Outline mode 編輯 Muse 文稿內容

前陣子在使用 muse 撰寫筆記的時候,總覺得要找標題不太方便,似乎也沒辦法透過 speedbar 顯示大綱,玩了半天就想到了 outline mode 這個好東西,剛好語法是一樣的,只要簡單配置一下就可以帶來很大的方便。測試了一下後加了一些設定:

(add-hook 'muse-mode-hook
	'(lambda ()
	   (outline-minor-mode t)))

(define-key muse-mode-map (kbd "<f5>")  'outline-up-heading)
(define-key muse-mode-map (kbd "<f6>")  'outline-backward-same-level)
(define-key muse-mode-map (kbd "<f7>")  'outline-forward-same-level)
(define-key muse-mode-map (kbd "<f8>")  'outline-next-heading)
(define-key muse-mode-map (kbd "<f12>") 'outline-toggle-children)
(define-key muse-mode-map (kbd "C-<f12>") 'outline-mark-subtree)

(define-key muse-mode-map (kbd "C-<f5>") 'outline-promote)
(define-key muse-mode-map (kbd "C-<f6>") 'outline-move-subtree-up)
(define-key muse-mode-map (kbd "C-<f7>") 'outline-move-subtree-down)
(define-key muse-mode-map (kbd "C-<f8>") 'outline-demote)

在進入 muse mode 的同時也啟用 outline minor mode,並設定一些快速鍵以便快速在各個標題之間定位。事後在調整內容次序時,還可以整個 subtree 一起調整,不必再笨笨地用 copy & paste 修改了。


Posted in emacs, Note

十月 19, 2008
» Blogging with Emacs

玩了幾個晚上,總算可以順利從 emacs 裡將文章送到 Blog 了。 自從開始用 emacs 後就一直改用 muse 在寫筆記和報告,設定好以後可以透過 LaTeX 轉換成 PDF 檔,相當方便。用習慣後也曾興起透過 muse 寫 Blog 的念頭,找了很多資料,也知道有很多人實作成功,但說真的要拿來用還是有點問題,主要還是 elisp 不熟,而且大部份的實作竟然都是直接在 emacs 裡寫 html 後送出去 (還有人推薦用 nxml);就算直接在後台寫也有方便的 wysiwyg editor,但 emacs 還有 muse 這個好東西,何必那麼苦命呢。

» Blogging with Emacs

玩了幾個晚上,總算可以順利從 emacs 裡將文章送到 Blog 了。

自從開始用 emacs 後就一直改用 muse 在寫筆記和報告,設定好以後可以透過 LaTeX 轉換成 PDF 檔,相當方便。用習慣後也曾興起透過 muse 寫 Blog 的念頭,找了很多資料,也知道有很多人實作成功,但說真的要拿來用還是有點問題,主要還是 elisp 不熟,而且大部份的實作竟然都是直接在 emacs 裡寫 html 後送出去 (還有人推薦用 nxml);就算直接在後台寫也有方便的 wysiwyg editor,但 emacs 還有 muse 這個好東西,何必那麼苦命呢。

目前的做法還是透過 xml-rpcweblogger,後來找到有人針對 wordpress 的修改,安裝上並不難,只需稍微自訂一下就可以使用。

首先必須透過 weblogger-setup-weblog 建立設定檔,可以有多組設定,每一組設定會有一個名字作為識別。要注意的是預設並不儲存密碼,往後傳送資料時必須手動輸入。如果想偷懶可以設定一下 weblogger-save-password,建立設定資料時就會自動儲存密碼。

開始撰寫文章時先 M-x weblogger-start-entry,會自動建立簡單的樣板,填入 Subject 與內容即可。需要加上 Category 的話,可以在 header section 手動加入一行 "Keywords: ",各分類之間以逗點分隔 (必須是 server 上存在的 Category 名稱)。目前似乎還不支援 Tag。發布文件的方式很簡單,熱鍵跟存檔一樣是 C-x C-s,也可以用 C-c C-c 存成 Draft。日後需要修改時也可以把文章抓回來修改後再回存,相當方便1

Weblogger 的使用不難,比較麻煩的是跟 muse 銜接的部份,研究了一晚找出需要的資料結構,原來是建構在 message-mode 之上,所以得先產生類似 message header 的資料。這部份我直接以 html style 為基礎,建立一個新的 muse style 來處理:

(muse-derive-style "my-blog" "html"
                   :suffix ".wp.html"
                   :header
"Subject: <lisp>(muse-publishing-directive \"title\")</lisp>
From: <lisp>(muse-publishing-directive \"author\")</lisp>
Keywords: <lisp>(muse-publishing-directive \"desc\")</lisp>
--text follows this line--
"
                   :footer ""
                   :browser   'find-file
                   :regexps `((100000 "!!more!!" 0 more) )
                   :functions '((more . muse-mywp-markup-more))
                   :strings '(
(image-link      . "<a target=\"_blank\" class=\"image-link\" href=\"%s\">
<img src=\"%s.%s\"></a>")
(url             . "<a target=\"_blank\" href=\"%s\">%s</a>")
(link            . "<a target=\"_blank\" href=\"%s\">%s</a>")
(link-and-anchor . "<a target=\"_blank\" href=\"%s#%s\">%s</a>")))

當然在 project 部份也要新增一個項目

(setq muse-project-alist
	'(("blog" ("~/Note/blog" )
		(:base "my-blog" :path "~/Note/blog/convert"))))

本來的想法是找出 muse 資料的產生方式,直接丟到 webloger buffer,但是一堆括號看到頭暈,所以用了比較笨的方式:先用 muse 轉換過,再呼叫修改過的 weblogger 函式將結果轉換出必要的資料結構,最後丟上 server。

修改這些其實還算簡單,但我有個需求是要同時送到多個地方備份用,這可要我命了…因為裡面一堆全域變數,從帳號設定對應到內部資料結構的部份又太複雜 (誰說用 functional language 不會有 side-effect…XD),所以我還是用最笨的方式,每次連線前先重置相關的全域變數:

(defun muse-blog-start-entry ()
  (unless weblogger-entry-ring
    (setq weblogger-entry-ring
      (make-ring weblogger-max-entries-in-ring)))
  (ring-insert weblogger-entry-ring '(("content" "")))
  (setq weblogger-ring-index 0)
  (unless weblogger-server-username
    (setq weblogger-server-username ""))
  (unless weblogger-server-password
    (setq weblogger-server-password ""))
  (weblogger-edit-entry (weblogger-entry-buffer-to-struct)))

(defun muse-blog-send-post (&optional blogConfName)
  "send current to blog"
  (unless blogConfName
    (read-from-minibuffer "Select a blog conf: " blogConfName))
  (setq weblogger-server-username nil)
  (setq weblogger-server-password nil)
  (setq weblogger-server-url nil)
  (setq weblogger-weblog-id nil)
  (weblogger-select-configuration blogConfName)
  (weblogger-start-entry)
  (set-buffer-modified-p t)
  (weblogger-save-entry t)
  (bury-buffer))

(defvar muse-blog-conf-name-alist nil)

(defun muse-blog-publish ()
  (interactive)
  (when muse-blog-conf-name-alist
    (mapcar 'muse-blog-send-post muse-blog-conf-name-alist)))

使用前需要先設定 muse-blog-conf-name-alist,內容是一個字串的 list,就是先前在 weblogger 中建立的 profile 名稱,發布文章時就會丟到所有在清單中的 Blog 位置。

muse 文稿的部份,要注意的是利用了三個 directives:title、author 與 desc,分別對應到 message header 中的 Subject、From 與 Keywords。以本文為例,開頭的前幾行如下:

#title Blogging with Emacs
#author letoh
#desc note, emacs

產生出來的 header 如下:

Subject: Blogging with Emacs
From: letoh
Keywords: note, emacs
–text follows this line–

到這樣已經相當好用了,同一份 muse 文件除了生成 LaTeX / ConTeXt 文稿或 PDF 外,也可以發布到 Blog 上,當然產生 static page 或整理起來變成 Wiki 更不是問題。只剩一個小小的缺憾,就是還沒把 blogger 分舵加進來,因為 blogger 已經不用 xmlrpc,改用 Blogger Data API 了,這兩天再努力看看吧。有任何建議也歡迎指教。


1. 實際使用後發現抓回來的文章如果包含 <!--more--> (wordpress 設定摘要位置用的記號),只會抓回摘要的部份;此時若回存會把文章後半部份蓋掉XD 修改方法還在研究中…


Posted in emacs, Note

» Blogging with Emacs

玩了幾個晚上,總算可以順利從 emacs 裡將文章送到 Blog 了。 自從開始用 emacs 後就一直改用 muse 在寫筆記和報告,設定好以後可以透過 LaTeX 轉換成 PDF 檔,相當方便。用習慣後也曾興起透過 muse 寫 Blog 的念頭,找了很多資料,也知道有很多人實作成功,但說真的要拿來用還是有點問題,主要還是 elisp 不熟,而且大部份的實作竟然都是直接在 emacs 裡寫 html 後送出去 (還有人推薦用 nxml);就算直接在後台寫也有方便的 wysiwyg editor,但 emacs 還有 muse 這個好東西,何必那麼苦命呢。

十月 16, 2008
» Emacs 發布測試

test for blogging with emacs
透過 emacs 來寫 blog

Todo:

  • fetch entry 後,延伸閱讀以後的資料會抓不到 (也許是透過 rss/atom 抓 description 而已),此時再存檔的話,當初沒抓下來的資料就會變成光了
  • 拿掉 auto-fill-mode
  • 整合 muse (目前看到有日本人實作過),這樣等於間接把 local preview 做好
  • multi-server configuration
  • categories auto-completion (以前用 python 寫過,但現在得用 elisp 寫…囧rz)
  • 自訂 ping-slug (印象中在 api 裡有看到)

Posted in ACG, emacs, Note

八月 31, 2008
» 統計檔案大小

隨手寫了一個 script,用來統計檔案大小

#!/usr/bin/perl -p
BEGIN { my $total = 0; }
/(\d+)/; $total += $1;
END { print “Total: $total\t” . ($total / 1024) . “M\n”; }

存成 ts 後可以搭配 duls -s 使用,或者是輸出為每一行開頭有數字的任何指令,例如 seqnl

$ seq 5 | ts
$ ls / | nl | ts

當然這只是好玩而已,沒什麼實際用途

突然想到這幾年陸續接觸了幾種不同的程式語言,包括平日使用最多的 python。但日常使用其實很少出現複雜的應用,大多數情況用 perl 處理起來還是簡潔多了 (雖然這個 perl script 寫得有點像 awk script…)

最後附一下 awk 版:

BEGIN { total = 0 }
total += $1
END { print “Total:”, total,”\t”,total/1024,”M” }


» 統計檔案大小

隨手寫了一個 script,用來統計檔案大小

六月 22, 2008
» VirtualBox 1.6.2

由於 sane 不支援我的 scanner,為了試試透過 virtualbox 存取 scanner,這兩天在家把新版裝起來玩…

» VirtualBox 1.6.2

由於 sane 不支援我的 scanner,為了試試透過 virtualbox 存取 scanner,這兩天在家把新版裝起來玩…

根據網路上看到的使用心得,新的 1.6.2 版似乎在 usb 的支援上增強不少,但為了在 guest OS 裡抓到 usb device 也費了不少工夫,一度還以為只有 windows 版才有改進…搞了一個下午才順利偵測到 scanner

網路沒設,主要是處理 usb 的部份,記錄一下大概的步驟:

  1. 新增 usbusers 群組,把自己的帳號加進去
  2. 修改 /etc/rc.d/rc.S 中 mount usbfs 的命令,加上 -o devgid=<gid of usbusers>,devmode=664 (我用的 distro 是 Slackware)
  3. 修改 /etc/udev/rules.d/65-permissions.rules,加一行 SUBSYSTEM=="usb_device", GROUP="usbusers", MODE="0664"
  4. 在 virtualbox 中加入 usb device filter (vid 和 pid 可以透過 lsusb 查到)

處理完以後啟動 guest OS 就可以抓到 device 了,為了證明可以啟動 scanner,掃張圖來看看


六月 20, 2008
» libreadline.so.5: undefined symbol: PC

這兩天在 slackware 12.1 環境編譯一個有用到 readline 的程式,可是搞了老半天編譯好的程式都沒有 readline 跟 history 的功能。測試一下發現會出現 undefined symbol 的訊息,按照 maillist 上提供的指令 ldd -d -r /usr/lib/libreadline.so.5.2 出現這些訊息: undefined symbol: PC (/usr/lib/libreadline.so.5.2) undefined symbol: UP (/usr/lib/libreadline.so.5.2) undefined symbol: BC (/usr/lib/libreadline.so.5.2) undefined symbol: tgetflag (/usr/lib/libreadline.so.5.2) undefined symbol: tgetent (/usr/lib/libreadline.so.5.2) undefined [...]

» libreadline.so.5: undefined symbol: PC

這兩天在 slackware 12.1 環境編譯一個有用到 readline 的程式,可是搞了老半天編譯好的程式都沒有 readline 跟 history 的功能。測試一下發現會出現 undefined symbol 的訊息,按照 maillist 上提供的指令 ldd -d -r /usr/lib/libreadline.so.5.2 出現這些訊息:

undefined symbol: PC (/usr/lib/libreadline.so.5.2)
undefined symbol: UP (/usr/lib/libreadline.so.5.2)
undefined symbol: BC (/usr/lib/libreadline.so.5.2)
undefined symbol: tgetflag (/usr/lib/libreadline.so.5.2)
undefined symbol: tgetent (/usr/lib/libreadline.so.5.2)
undefined symbol: tputs (/usr/lib/libreadline.so.5.2)
undefined symbol: tgoto (/usr/lib/libreadline.so.5.2)
undefined symbol: tgetnum (/usr/lib/libreadline.so.5.2)
undefined symbol: tgetstr (/usr/lib/libreadline.so.5.2)

查了一下發現這些東西在 libtermcap 裡,比較簡單一點的方法就是修改 Makefile 或 build script,在 linking 時加上 libtermcap 即可


六月 15, 2008
» Device driver check page

Debian GNU/Linux device driver check page 在 kerneltrap 上看來的網站,把 lspci -n 的結果丟進去即可,相當方便

biggo.com.tw

A Django site.