minibufferのフォントを大きくする
例1
minibufferにフォーカスが移ったときに一時的に大きくするようにする.
(add-hook 'minibuffer-setup-hook 'my-minibuffer-setup) (defun my-minibuffer-setup () (setq-local face-remapping-alist '((default :height 2.0))))
例2
minibuffer-promptという faceがあるが, これはプロンプトの部分だけなので微妙.
prompt以外は default faceなので, これを大きくすると全体が大きくなってしまい
目的とは少しずれてしまうかな.
(set-face-attribute 'minibuffer-prompt nil :height 2.0)
おわりに
もっとうまい方法はないものだろうか ?
Emacs Lispで「ソフトウェアエンジニアならば1時間以内に解けなければいけない5つの問題」を解いてみた
http://mattn.kaoriya.net/software/vim/20150527121332.htm
ちょうど 1時間程度. 1-4はすぐに書けて, 5に時間を要した.
(追記: 2015年6月1日 問4に誤りがあり修正しました)
問題1
'for'の代わりに loopで.
(require 'cl-lib) (defun problem1-for (lst) (cl-loop for i in lst sum i)) (defun problem1-while (lst) (let ((sum 0) (xs lst)) (while xs (setq sum (+ sum (car xs)) xs (cdr xs))) sum)) (defun problem1-recursive (lst) (if (null lst) 0 (+ (car lst) (problem1-recursive (cdr lst))))) (defun problem1-tail-recursive (lst) (cl-labels ((func (lst acc) (if (null lst) acc (func (cdr lst) (+ acc (car lst)))))) (func lst 0))) (let ((input '(1 2 3 4 5 6 7 8 9 10))) (cl-assert (= 55 (problem1-for input) (problem1-while input) (problem1-recursive input) (problem1-tail-recursive input))))
問題2
(require 'cl-lib) (defun problem2 (xs ys) (cl-loop for x in xs for y in ys collect x collect y)) (cl-assert (equal '(a 1 b 2 c 3) (problem2 '(a b c) '(1 2 3))))
他には mapcanを使うとかだろか.
(cl-mapcan (lambda (a b) (list a b)) '(1 2 3) '(a b c))
問題3
表現範囲の問題で, calcを使用. すぐ書けたものでは正しく表示できず.
(require 'cl-lib) (require 'calc-arith) (defun bignum-to-string (n) (let ((sign (if (eq (car n) 'bigpos) "" "-"))) (concat sign (mapconcat #'number-to-string (reverse (cdr n)) "")))) (defun problem3 (n) (cond ((= n 1) '(0)) ((= n 2) '(0 1)) (t (cl-loop with acc = '(1 0) repeat (- n 2) do (push (calcFunc-add (cl-first acc) (cl-second acc)) acc) finally return (reverse (mapcar (lambda (e) (if (listp e) (bignum-to-string e) e)) acc)))))) (cl-assert (string= (nth 99 (problem3 100)) "218922995834555169026"))
問題4
(1つめのコードは誤っています.)
(require 'cl-lib) (defun problem4 (lst) (let ((xs (sort lst (lambda (a b) (string< (number-to-string b) (number-to-string a)))))) (string-to-number (mapconcat #'number-to-string xs "")))) (cl-assert (= (problem4 '(50 2 1 9)) 95021))
追記: 2015/JUN/1 修正版
(require 'cl-lib) (defun compare (a b) (let ((ab-val (string-to-number (format "%s%s" a b))) (ba-val (string-to-number (format "%s%s" b a)))) (> ab-val ba-val))) (defun problem4 (lst) (let ((xs (sort lst #'compare))) (string-to-number (mapconcat #'number-to-string xs "")))) (cl-assert (= (problem4 '(420 42 423)) 42423420) (= (problem4 '(50 2 1 9)) 95021))
問題5
他はすぐに思いついたけど, これは時間がかかった.
evalは使わず. 演算子の全組み合わせを出せばすぐだなと思ったけど,
文字列連結を先にするのがうまくいかず, 苦労した.
(require 'cl-lib) (defun concat-num (a b) (string-to-number (concat (number-to-string a) (number-to-string b)))) (defun permute-ops (n) (let ((accs nil)) (cl-labels ((permute-ops- (n i acc) (if (= n i) (push (reverse acc) accs) (cl-loop for op in '(+ - concat-num) do (permute-ops- n (1+ i) (cons op acc)))))) (permute-ops- n 0 '()) accs))) (defun apply-concat (lst ops) (cl-loop with stack = (list (car lst)) for e in (cdr lst) for op in ops if (eq op 'concat-num) do (let ((a (pop stack))) (push (concat-num a e) stack)) else do (push e stack) finally return (reverse stack))) (defun calc-ops (lst- ops-) (let ((lst (apply-concat lst- ops-)) (ops (cl-loop for op in ops- unless (eq op 'concat-num) collect op))) (if (null ops) ;; all ops are concat (car lst) (cl-loop with acc = (funcall (car ops) (cl-first lst) (cl-second lst)) for op in (cdr ops) for num in (cddr lst) do (setq acc (funcall op acc num)) finally return acc)))) (defun format-ops (lst ops) (concat (number-to-string (car lst)) (cl-loop for op in ops for num in (cdr lst) if (eq op 'concat-num) concat (number-to-string num) else concat (format "%s%s" op num)))) (defun problem5 (lst) (let ((opss (permute-ops (1- (length lst))))) (cl-loop for ops in opss when (= (calc-ops lst ops) 100) collect (format-ops lst ops)))) (cl-assert (member "1+2+34-5+67-8+9" (problem5 '(1 2 3 4 5 6 7 8 9))))
NetBSD + Rasbperry Pi情報
FreeBSDの posix_spawnの実装
http://blog.kazuhooku.com/2015/05/how-to-properly-spawn-external-command.html
を見て, 再現コードを FreeBSDで実行してみたとき, 期待される挙動になったので FreeBSDでの実装を確認してみました.
コード
FreeBSD r282608のソースコードを対象にしています.
posix_spawnは lib/libc/gen/posix_spawn.cで定義される.
int posix_spawn(pid_t *pid, const char *path, const posix_spawn_file_actions_t *fa, const posix_spawnattr_t *sa, char * const argv[], char * const envp[]) { return do_posix_spawn(pid, path, fa, sa, argv, envp, 0); }
do_posix_spawn関数を呼び出すだけ.
static int do_posix_spawn(pid_t *pid, const char *path, const posix_spawn_file_actions_t *fa, const posix_spawnattr_t *sa, char * const argv[], char * const envp[], int use_env_path) { pid_t p; volatile int error = 0; p = vfork(); switch (p) { case -1: return (errno); case 0: if (sa != NULL) { error = process_spawnattr(*sa); if (error) _exit(127); } if (fa != NULL) { error = process_file_actions(*fa); if (error) _exit(127); } if (use_env_path) _execvpe(path, argv, envp != NULL ? envp : environ); else _execve(path, argv, envp != NULL ? envp : environ); error = errno; _exit(127); default: if (error != 0) _waitpid(p, NULL, WNOHANG); else if (pid != NULL) *pid = p; return (error); } }
初めに vforkを呼び出しています. vforkは forkと違いメモリ空間がコピーされない,かつ親プロセスは子プロセスが execするか exitするまで待つという性質があります.このため子プロセスが先に動作し, _execveが呼ばれます(posix_spawnpの場合は _execvpe). このとき実在しないコマンドが指定されている等で execが失敗したとき, error変数にerrnoを書き込み _exitします.
execが成功 or execが失敗+exitの後, 親プロセスが動き出します. switchの defaultの部分が実行され, はじめに errorがチェックされます. 前述の通り vforkではメモリ空間がコピーされないので, 親プロセスから子プロセスでの変更が確認できます. (vforkでなく, forkを使う場合, h2oの実装のように pipe等を使う必要があります)
で, errorが発生していれば waitpidをして, errorを返します. このような実装になっているので, 子プロセスで execが失敗した場合エラーを返すことができるということになります.
(字面だけ見ると, default節の ifが真になることはないので, コンパイラに削除される可能性がある. そうならないように volatileがつけられている. コンパイラはfork/vforkの挙動など知らない)
glibcでの実装
sysdeps/posix/spawni.cの __spawni関数です. 親プロセスが戻るところだけ示します.
/* Generate the new process. */ if ((flags & POSIX_SPAWN_USEVFORK) != 0 /* If no major work is done, allow using vfork. Note that we might perform the path searching. But this would be done by a call to execvp(), too, and such a call must be OK according to POSIX. */ || ((flags & (POSIX_SPAWN_SETSIGMASK | POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETSCHEDULER | POSIX_SPAWN_SETPGROUP | POSIX_SPAWN_RESETIDS)) == 0 && file_actions == NULL)) new_pid = __vfork (); else new_pid = __fork (); if (new_pid != 0) { if (new_pid < 0) return errno; /* The call was successful. Store the PID if necessary. */ if (pid != NULL) *pid = new_pid; return 0; }
vfork/forkが失敗した場合は errnoを返しますが, それ以外は 0を返しています.
なので子プロセスが execに失敗した場合でも 0(成功)が返っていたわけです.
vfork
vforkを使っている理由はわかりませんが, マルチスレッド下で呼ばれる可能性がある場合を考慮しているためと思われます(すぐに execすることが確定しているのでパフォーマンスを考えてのことかもしれませんが...)
マルチスレッド + forkの問題についてはこちらを参照してください
追記
Qemu ネットワーク周りリンク集
- https://fedoraproject.org/wiki/Architectures/ARM/HowToQemu
- http://blog.hvishwanath.net/2013/10/setting-up-tuntap-networking-for-qemu.html
- http://en.wikibooks.org/wiki/QEMU/Networking
- http://wiki.qemu.org/Features/HelperNetworking
- https://wwwdantyo.wordpress.com/qemu%E3%81%A7arm%E7%92%B0%E5%A2%83%E3%82%92%E6%89%8B%E3%81%AB%E3%81%84%E3%82%8C%E3%82%8B/
- http://www.ne.jp/asahi/it/life/it/embedded/qemu_arm/debian_arm_qemu.html
- https://github.com/alexpark07/KISS/blob/master/Android/AArch64_on_qemu_with_ubuntu64.md
virtio-netを使ってインタフェースを生やす
AArch64関連のリンクまとめ
毎度毎度調べるのが面倒なので.
基礎
Openembeddedを ARMv8環境向けに構築する
Qemu + buildrootによる環境構築
Qemuで openembeddedのイメージを動かす方法
ARM Fast Model(armv8)で ARM KVMを動作させる方法
qemu + binfmt + chroot で AARCH64 環境を構築する 方法
- https://syoyo.wordpress.com/2013/12/17/qemu-binfmt-chroot-%E3%81%A7-aarch64-%E7%92%B0%E5%A2%83%E3%82%92%E6%A7%8B%E7%AF%89%E3%81%99%E3%82%8B/
- http://d.hatena.ne.jp/embedded/20140427/p1
binfmtを使い, ARM向けバイナリを qemuユーザモードエミュレーションで実行する. Debian AArch64用の root file systemに対して chrootを行うことと組み合わせることで擬似的な ARM環境を構築する.