Vietnamen’s Weblog

Time, Chances, Diligence, Intelligence: which is the most important?

Archive for Tháng Bảy 2009

Doxymacs – generate code documentation in emacs

leave a comment »

Doxymacs là sự kết hợp giữa Doxygen + {X}Emacs.

Doxygen là tool giúp trích xuất thông tin của source code thành dạng documentation giúp cho việc tra cứu tham khảo sử dụng các hàm dễ dàng. Các tool khác: JavaDoc, GTK-Doc… Yêu cầu của các tool này là comment được viết theo một qui luật định sẵn để chúng có thể trích xuất thông tin ra dễ dàng.

Emacs lại là một IDE rất mạnh và hữu ích.

Trong Ubuntu, các package này đều có sẵn

sudo aptitude

tìm kiếm doxymacs, doxygen, doxygen gui và install 3 packages này. Có thể install thêm doxygen-doc nếu muốn.

Sau đó, thêm vào file ~/.emacs

(add-hook 'c-mode-common-hook
  (lambda ()
    (require 'doxymacs)
    (doxymacs-mode t)
    (doxymacs-font-lock)))

Tuỳ vào programming language khác nhau mà cấu trúc của comment thay đổi (minh hoạ ở dưới). Tuy nhiên, để đơn giản, doxymacs cung cấp một số iteractive function

doxymacs-insert-function-comment

doxymacs-insert-file-comment  --> C-c d i

Những thức cần có khi comment một subprogram

  1. thông tin về thông số đầu vào (type, optional, in/out/inout…)
  2. thông tin về return value (type), exception gì, có cần phải free (deallocate) hay không

Comment có thể đặt ngay tại header files (.h) hoặc nơi implementation (.c/.cpp). Điều này là tuỳ ý thích mỗi người. Đối với một số ngôn ngữ, ví dụ Fortran, không có header file nên comment chỉ có ở trong implementation file.

C language

/** 
 *
 *
 * @param a
 * @param b
 *
 * @return
 */
int frobnicate_numbers (int a, int b);

Fortran

References:

  1. http://doxymacs.sourceforge.net/
  2. http://emacs-fu.blogspot.com/2009/01/commenting-your-functions.html
  3. http://www.digitalpeer.com/id/emacs
  4. http://www.lrde.epita.fr/cgi-bin/twiki/view/Projects/EmacsTricks
  5. http://www.stack.nl/~dimitri/doxygen/helpers.html
  6. Fortran patch: http://sourceforge.net/forum/message.php?msg_id=7442794
  7. http://www.stack.nl/~dimitri/doxygen/starting.html
Advertisements

Written by vietnamen

Tháng Bảy 28, 2009 at 12:49 chiều

Backup tools

leave a comment »

Backup là một tác vụ rất cần thiết với người dùng có dữ liệu lưu trữ trên máy tính, đặ biệt nếu nó là quan trọng. Hiện nay, có 2 tools trong Ubuntu: sbackup và nssbackup.

Hiện nay, sbackup không còn được phát triển, và nssbackup là một lựa chọn tốt, dù nó đang ở giai đoạn RC.

nssbackup

Not So Simple Backup nhằm cung cấp khả năng backup local, remote, …. với ưu thế GUI, background running, schedule running….

  1. Download bản mới nhất từ: https://launchpad.net/nssbackup/+download
  2. Compile:
make
sudo make install
  1. Thiết lập cấu hình
sudo nssbackup-config-gui

Bạn có thẻ lựa chọn chức năng “backup now” trong nssbackup-config-gui hoặc bạn có thể backup với nssbackupd

sudo nssbackupd

NOTE: Luôn chạy với quyền root

References:

  1. https://launchpad.net/nssbackup

Written by vietnamen

Tháng Bảy 25, 2009 at 9:06 chiều

Viết codes trong Emacs với Emacs Code Browser (ECB)

with one comment

Bài viết này nhằm tổng hợp và giới thiệu một số kinh nghiệm viết code dùng ECB-minor-mode trong Emacs.

ECB được tích hợp vào emacs nên việc cài đặt là không cần thiết. Tuy nhiên, để đảm bảo có version mới nhất, bạn nên tự cài đặt bằng cách download từ sourceforge.

Sau đó, bạn chỉ cần khai báo trong file cấu hình ~/.emacs nội dung sau

;; ECB = Emacs code browser
(add-to-list ‘load-path “~/.emacs.d/share/ecb-snap”)
(require ‘ecb)

Sau đó, mỗi lần soạn thảo code, bạn run ecb bằng lệnh: M-x ecb-minor-mode

Một số thiết lập cần chỉnh sửa với ECB:

  • path to source code

M-x customize-option <RET> ecb-source-path

Bạn thêm vào đường dẫn đến sources, điều này giúp ECB scan source files nhanh chóng. Đặc biệt ECB hỗ trợ remote coding, cho phép bạn chỉ định remote folder dùng TRAMP, ví dụ:

/ssh:username@machine:/path/to/source/

Code nagivation

Chức năng jump đến một subroutine/funciton chưa có trong ECB, bạn nên dùng etags

Tại thư mục cao nhất của source trees, chạy dòng lệnh

find . -name ‘*.[chCH]’ | xargs etags

Một số options của etags có thể sử dụng

  • –language=lang_name với lang_name có thể là auto, fortran, …
  • –include=file: chèn một tag file khác vào tag file được tạo ra

Sau đó, run/restart emacs và nhấn: M-x visit-tags-table <RET>

Bạn nhập vào đường dẫn đến tag-file

  1. Để nhảy đến một function nào, chỉ việc nhấn M-. (Meta-dot) và nhập vào tên của function/subroutine.
  2. Sau đó, để nhảy trở về vị trí cũ, bạn chỉ việc nhấn M-* (Meta-star)

Để đảm bạo, mỗi lần bạn compile thì updated etags file được tạo ra, trong makefile, bạn có thể tự tạo ra 1 target nhằm tạo tag-files với rule

etags:
        find . -name '*.[chCH]' | xargs etags

hoặc

tag:
    etags $(SRC)

với SRC là variable chứa thông tin tên mọi source files

NOTE: Hướng dẫn ở trên dùng cho file có đuôi .c hoặc .h và ở trên dùng regular expression để kết hợp 2 loại file vào 1. Nếu cho ngôn ngữ khác, bạn nên dùng extension tương ứng (ví dụ: .f95)

Function name auto complete

Bạn bind chức năng này với phím Ctrl-tab nếu đưa nội dung sau vào ~/.emacs

(add-hook 'c-mode-common-hook
        (lambda ()
                (define-key c-mode-map [(ctrl tab)] 'complete-tag)))

Harmonia

http://harmonia.cs.berkeley.edu/harmonia/projects/harmonia-mode/doc/index.html

References:

  1. http://ecb.sourceforge.net/docs/Remote-directories.html
  2. http://www.coverfire.com/archives/2004/06/24/emacs-source-code-navigation/
  3. http://www.gnu.org/software/emacs/manual/html_node/emacs/Tags.html
  4. http://www.linuxjournal.com/article/153
  5. http://en.wikipedia.org/wiki/Ctags

Written by vietnamen

Tháng Bảy 17, 2009 at 10:36 sáng

Viết clisp code trong emacs

leave a comment »

SLIME giúp cho CLisp code development trở nên dex dàng

http://common-lisp.net/project/slime/

References:

  1. http://www.a1k0n.net/blah/archives/2005/11/04/index.html

Written by vietnamen

Tháng Bảy 4, 2009 at 2:56 chiều

Run as root, keeping your $PATH environment

leave a comment »

Suppose you need root privilege to do something, but when you use su or sudo, the $PATH information is lost as you’re running as root user. To keep them, use

su -l root

Written by vietnamen

Tháng Bảy 4, 2009 at 8:22 sáng

Posted in Living better with Ubuntu, Tin học

Tagged with ,

Soạn thảo file từ xa (emacs + ssh)

leave a comment »

Emacs là một multi-purpose và extremely powerful editor + IDE. Lần này bài viết sẽ giới thiệu TRAMP (Transparent Remote file Access, Multiple Protocol)

TRAMP cho phép ta khai báo: (1) giao thức để kết nối tới remotehost (e.g. ssh), (2) giao thức để truyền tải file qua lại với remotehost (e.g. scp), (3) … từ đó bạn có thể edit 1 remote file giống như đang làm đối với 1 local file.

TRAMP bây giờ là một phần của XEmacs và GNU Emacs. Vì thế, step (I) có thể skip nếu GNU Emacs version > 22.1, XEmacs > …. Để kiểm tra version hiện có của TRAMP, trong Emacs, dùng lệnh

M-x tramp-version

Nếu cũ so với phiên bản mới nhất, ta có thể tiến hành Step (I).

(I) [Có thể skip nếu GNU Emacs version > 22.1] Phiên bản tramp đi kèm với Ubuntu (sudo aptitude) cũ, không nên dùng. Nên download version mới nhất về, sau đó bạn unzip (loại bỏ phần chỉ version trong tên thư mục cho đơn giản), move vào thư mục chia sẻ của emacs, e.g. ~/.emacs.d/share/

# mv tramp ~/.emacs.d/share
cd ~/.emacs.d/share/tramp
./configure –with-contrib
make
sudo make install

Các file cần thiết sẽ được chép vào thư mục mặc định là /usr/local/share/emacs/site-lisp/

(II) Sau đó, edit file ~/.emacs để cấu hình emacs load tramp

;; Remote file editing via ssh
(require 'tramp)
(setq tramp-default-method "ssh")

(III) Sau đó, có thể run emacs và open remoting file để edit.

C-x C-f /user@remotehost:/path/to/file

hoặc (nếu đã có cài đặt username mặc định – đọc thêm phần sau)

C-x C-f /remotehost:filename

Đi sâu vào TRAMP

Để có thể edit được remote file, đường dẫn mà TRAMP sử dụng là

/method:user@remotehost:/path/to/file

Với method là một inline method sẽ được giới thiệu, user@remotehost dùng để xác định người dùng và địa chỉ remote host để kết nối tới.

Giao thức kết nối tới remotehost (inline method)

Giao thức dùng để kết nối tới remote machine, thì được gọi là inline methods (SSH, RSH, Telnet …). Tuỳ vào remote host, mà ta chọn method phù hợp.Nếu 1 giao thức hay được dùng, ta có làm đơn giản hoá đường dẫn

/user@remotehost:/path/to/file

bằng cách khai báo nó qua biến tramp-default-method.

(setq tramp-default-method "rsh")

Trong phần giới thiệu nhanh ở trên, SSH là giao thức được dùng mặc định. Ngoài ra có nhiều option khác:

– Nếu với một user luôn dùng 1 giao thức cố định, cho dù kết nối tới remote host nào, ta dùng tramp-default-method-alist

Ví dụ: user “john” phải dùng ssh, user lily phải dùng rsync,

(add-to-list 'tramp-default-method-alist '("" "john" "ssh"))
(add-to-list 'tramp-default-method-alist '("lily" "" "rsync"))

– Khi mở file, bạn phải chỉ định username và host-name, nếu bạn là người dùng duy nhất, có thể username sẽ không thay đổi, để làm mặc định, ta dùng (cách này sẽ trở nên lỗi thời nhưng vẫn dùng được)

(setq tramp-default-user "username")

Nếu muốn chỉ định cả username lẫn hostname; ví dụ: user “john” ở host-name “binf.network.com”, ta sẽ thêm vào

(setq tramp-default-user "username"
           tramp-default-host "target-hostname")

– – Giải pháp khác là

add-to-list 'tramp-default-user-alist
        '("ssh" ".*\\.binf.network.com\\'" "john"))

NOTE: Nếu default username đã được chỉ định ở đâu đó khác, TRAMP không thể biết được và dẫn đến kết nối luôn thất bại. Giải pháp là  dùng nil

(add-to-list 'tramp-default-user-alist
       '("ssh" "\\`here\\.somewhere\\.else\\'" nil))

Sau đó, khi kết nối dùng thông tin default, ta dùng: C-x C-f /ssh::

Giao thức truyền tải file

Sau khi kết nối tới remotehost, bạn có thể đọc file và edit nó. Việc save file trở lại remote host có thể (1) dùng chung kết nối (giao thức) đang có (inline method); (2) tạo một kết nối mới chỉ dùng để truyền tải file, gọi là external method.

Dùng external method chỉ hiệu quả hơn đối với file kích thước lớn. Khuyến khích bạn nên dùng inline methods. Nếu dùng external methods, nên cấu hình sao cho lúc save file thì nó không đòi hỏi password.

+ Edit file dưới quyền user khác

Ta dùng inline method su hoặc sudo. Cả hai đều không thực sự kết nối tới một remotehost nào, mà chỉ sử dụng su program để edit file dưới quyền user khác (hoặc root với sudo).

(add-to-list 'tramp-default-method-alist
                  '("\\`localhost\\'" "\\`root\\'" "su"))

Sau đó, bạn dùng:

C-x C-f /sudo:localhost:/path/to/file

hay (nếu không có dòng lệnh trên)

C-x C-f /sudo:root@localhost:/path/to/file

Multi-hops connection (pass firewalls or proxy servers)

Việc cài đặt và cấu hình đề cập ở các phần trên chỉ giúp ích khi remoting file nằm ở trên machine mà bạn có thể kết nối trực tiếp. Tuy nhiên, thực tế là đôi khi bạn cần vượt qua một hay nhiều firewalls hay proxies trước khi có thể kết nối trực tiếp tới machine chứa file cần edit.

Ví dụ: Bạn login vào máy A (đóng vai trò proxy hay firewall) với tư cách user Auser, sau đó, từ máy A, bạn sẽ tiếp tục login vào máy B với tư cách Buser. Lúc này máy B là máy chứa file cần edit.

Để vưọt qua firewall hay proxy server, trước đây có giao thức “multi” nay đã lỗi thời với TRAMP 2.1.15.  Bạn nên dùng gateway method hay inline method được chỉ định thông qua variable tramp-default-proxies-alist

Gateway method là các phương thức dùng để vượt qua firewall hay proxy, không phải để truy cập một remote host trực tiếp.  Giao thức đo bao gồm tunnelsocks. Nó hỗ trợ việc khai báo username và password. Ở đây, ta sẽ dùng inline method, ví dụ ssh.

Ví dụ: nfat là tên bạn muốn gán cho remote host (nfat.company.com) bạn cần kết nối tới, thông tin để kết nối vào nfat là mynfat@nfat.machine.com. Tuy nhiên, account trên chỉ dùng được khi connect từ proxy host1.com. Như vậy, muốn kết nối tới nfat, bạn phải login được vào máy host1.com. Thông tin cho phép bạn truy cập vào host1.com là với username là user1. Oái oăm thay, muốn login vào host1.com bạn cần phải login từ máy gateway.com. Máy gateway.com thì có thể login từ bất kì đâu với account commonusser. Các bước như sau

(add-to-list 'tramp-default-proxies-alist
             '("nfat" nil "/ssh:mynfat@nfat.company.com:/"))
(add-to-list 'tramp-default-proxies-alist
             '("nfat\\.company\\.com" nil "/ssh:user1@host1.com:/"))

(add-to-list 'tramp-default-proxies-alist
             '("host1\\.com" nil "/ssh:commonuser@gateway.com:"))

Sau đó, chỉ việc dùng: C-x C-f /nfat:

NOTE: ‘nil’ nghĩa là “always match”.

NOTE: Please note the order of the code. add-to-list adds elements at the beginning of a list. Therefore, most relevant rules must be added last.

Proxy hosts can be cascaded. If there is another host called ‘jump.your.domain’, which is the only one in your local domain who is allowed connecting ‘bastion.your.domain’, you can add another rule:

     (add-to-list 'tramp-default-proxies-alist
                  '("\\`bastion\\.your\\.domain\\'"
                    "\\`bird\\'"
                    "/ssh:jump.your.domain:"))

Quản lí file

Mỗi khi soạn thảo remote file, TRAMP sẽ tạo 1 local copy, lưu ở /tmp folder, mỗi khi save file, bản local copy sẽ đồng thời được copy trở lại lên remote host.

Remote version control

TRAMP còn hỗ trợ remote version control. Nếu remote file đang edit là được quản lí bởi RCS hay CVS; bạn có thể commit dùng lệnh C-x v v .

Chỉnh sửa TRAMP

(custom-set-variables
 '(tramp-verbose 1)
 '(tramp-default-method "rsync")
 '(tramp-auto-save-directory "~/tmp/"))
(custom-set-faces)
(require 'tramp)
(add-to-list 'tramp-default-proxies-alist
	     (list "gluk" "root" "/ssh:alex@gluk:"))

(add-to-list 'tramp-default-proxies-alist
	     (list "plato.chalkface.com" "root" "/ssh:alex@plato.chalkface.com:"))

(add-to-list 'tramp-default-proxies-alist
	     (list "appserver" "sasa" "/ssh:root@appserver:"))

(add-to-list 'tramp-default-proxies-alist
	     (list "www.chalkface.com" "root" "/ssh:alex@www.chalkface.com:"))

(add-to-list 'tramp-default-proxies-alist
	     (list "dimon-notebook" "root" "/ssh:alex@dimon-notebook:"))

(add-to-list 'tramp-default-proxies-alist
	     (list "mir" "igleons" "/ssh:root@mir:"))

(add-to-list 'tramp-default-proxies-alist
	     (list "appserver" "sergej" "/sudo:root@appserver:"))

(add-to-list 'tramp-default-proxies-alist
	     (list "appserver" "max" "/ssh:root@appserver:"))

(add-to-list 'tramp-default-proxies-alist
	     (list "miles" "root" "/ssh:admin2@miles:"))

(add-to-list 'tramp-default-proxies-alist
	     (list "g2.chalkface.com" "root" "/ssh:alex@g2.chalkface.com:"))

(add-to-list 'tramp-default-proxies-alist
	     (list "mail2.virt.halogen.kharkov.ua" "root" "/ssh:alex@halogen.kharkov.ua:"))

(add-to-list 'tramp-default-proxies-alist
	     (list "appserver" "dixon" "/ssh:root@appserver:"))

(add-to-list 'tramp-default-proxies-alist
	     (list "appserver" "max" "/ssh:root@appserver:"))

(add-to-list 'tramp-default-proxies-alist
	     (list "appserver" "av" "/ssh:root@appserver:"))

;; (defmacro require-soft (feature &optional file)
;;   "*Try to require FEATURE, but don't signal an error if `require' fails."
;;   `(require ,feature ,file 'noerror))

;; (when (require-soft 'sudo)
;;   (defun sudo-before-save-hook ()
;;     (set (make-local-variable 'sudo:file) (buffer-file-name))
;;     (when sudo:file
;;       (unless(file-writable-p sudo:file)
;;         (set (make-local-variable 'sudo:old-owner-uid)
;;           (nth 2 (file-attributes sudo:file)))
;;         (when (numberp sudo:old-owner-uid)
;;           (unless (= (user-uid) sudo:old-owner-uid)
;;             (when (y-or-n-p
;;                     (format "File %s is owned by %s, save it with sudo? "
;;                       (file-name-nondirectory sudo:file)
;;                       (user-login-name sudo:old-owner-uid)))
;;               (sudo-chown-file (int-to-string (user-uid))
;;                 (sudo-quoting sudo:file))
;;               (add-hook 'after-save-hook
;;                 (lambda ()
;;                   (sudo-chown-file (int-to-string sudo:old-owner-uid)
;;                     (sudo-quoting sudo:file))
;;                   (if sudo-clear-password-always
;;                     (sudo-kill-password-timeout)))
;;                 nil   ;; not append
;;                 t           ;; buffer local hook
;;                 )))))))
;;   (add-hook 'before-save-hook 'sudo-before-save-hook))

===========================================================================
References:

  1. http://codesnippets.joyent.com/posts/show/366
  2. http://jeremy.zawodny.com/blog/archives/000983.html
  3. http://www.gnu.org/software/tramp/ (TRAM User Manual)
  4. http://www.emacswiki.org/emacs/TrampMode
  5. http://www.linux-mag.com/id/1527
  6. http://www.gnu.org/software/emacs/manual/html_mono/tramp.html (TRAM User Manual)

SSHFS

Một giải pháp thay vì dùng TRAMP là mount remote partition thành một local folder thông qua SSHFS.

Cách này sẽ trở nên lỗi thời

Written by vietnamen

Tháng Bảy 3, 2009 at 10:25 sáng