コマンドライン引数の取得
Posted feedbacks - Other
既出よりもう少し丁寧なの
1 2 3 | foreach my $arg (@ARGV){
print "$arg\n";
}
|
Mac OS X (PowerPC 32bit) アセンブリで。Mac OS X (PowerPC) のアセンブリでは、関数の引数はレジスタ r3-r10 に入ります。あとはmain関数の引数を操作するだけです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | ;; Mac OS X (PowerPC 32bit)
;; % as -o cmdline.o cmdline.s && gcc cmdline.o -o cmdline
.machine ppc
.globl _main
_main:
;; r3 = int argc
;; r4 = char *argv[]
;; それぞれ r6, r7 にコピーしておく
mr r6, r3
mr r7, r4
_print_arg:
;; まず、文字列の長さをカウントする
lwz r4, 0(r7) ; カウント用文字列
li r5, 0 ; 長さの初期化
_count_strlen:
lbz r0, 0(r4) ; 1文字レジスタに移す
cmpli cr7, r0, 0
beq cr7, _print_arg_write
addi r4, r4, 1
addi r5, r5, 1
b _count_strlen
_print_arg_write:
;; 引数文字列の表示
;; 引数の残数をスタックに退避
;; sys_write() を呼ぶたびに実行
subi r1, r1, 4
stw r6, 0(r1)
;; sys_write()
;; r5 は _count_strlen で既に代入済み
li r3, 1 ; 標準出力
lwz r4, 0(r7) ; 出力する文字列
li r0, 4 ; sys_write
sc ; 呼び出し
;; スタックから引数の残数を復帰
lwz r6, 0(r1)
addi r1, r1, 4
;; 引数の残数をスタックに退避
subi r1, r1, 4
stw r6, 0(r1)
;; スペースを出力
li r3, 1 ; 標準出力
li r4, hi16(space)
addi r4, r4, lo16(space)
li r5, 1 ; 出力する文字列の長さ
li r0, 4 ; sys_write
sc ; 呼び出し
;; スタックから引数の残数を復帰
lwz r6, 0(r1)
addi r1, r1, 4
;; 繰り返しの終了条件判断
subi r6, r6, 1 ; カウント減
cmpi cr7, r6, 0
beq cr7, _end
addi r7, r7, 4 ; 引数文字列のポインタを一つ進める
b _print_arg ; 次の引数へ
_end:
;; 改行を出力
li r3, 1 ; 標準出力
li r4, hi16(lf)
addi r4, r4, lo16(lf)
li r5, 1
li r0, 4 ; sys_write
sc ; 呼び出し
;; sys_exit()
li r3, 0
li r0, 1
sc
.data
.align 2
space:
.asciz " "
lf:
.asciz "\n"
|
argc - コマンドラインパラメータ数を返す関数 argv - コマンドラインパラメータを返す関数 ※argv(str, 0) => (空っぽ) C:/>ge2exe para.g C:/>para.exe a b c d 1 = a 2 = b 3 = c 4 = d C:/>
see: gentee.com :: View topic - Pass Parameters on Command Line
1 2 3 4 5 6 7 8 9 10 | func main<main>
{
uint i
str stemp
fornum i = 1, argc() + 1
{
print( "\(i) = \(argv( stemp, i ))\n")
}
}
|
Factor では "-" 以外で始まる引数はファイル名とみなされてしまいます。"-引数名=値" という形式で渡す必要があります。引数名がそのままグローバル変数名になるので get で取得します。
factor-nt.exe -script arg.factor -arg1=a -arg2=b -arg3=c -arg4=d
1 2 3 4 5 | USING: command-line prettyprint namespaces ;
"arg1" get .
"arg2" get .
"arg3" get .
"arg4" get .
|
Limboでは、initの引数として文字列リストを得ます。 習慣的に、名前はargvまたはargs。 先頭がコマンド名、続いてa, b, c, d... リストは、hd(先頭の値を取得)、tl(先頭を除いたリストを取得)を使って操作します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | implement Argv;
include "sys.m";
sys: Sys;
include "draw.m";
Argv: module
{
init: fn(nil: ref Draw->Context, argv: list of string);
};
init(nil: ref Draw->Context, argv: list of string)
{
sys = load Sys Sys->PATH;
for(p := tl argv; p != nil; p = tl p)
sys->print("%s\n", hd p);
}
|
LLVMアセンブリでは、main関数のパラメータでコマンドライン引数を受け取れます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | declare i32 @puts(i8 *)
; コマンド名を除き、すべての引数を表示する
define i32 @main(i32 %argc, i8** %argv) {
%i = alloca i32
store i32 1, i32* %i
br label %loop
loop:
%i_val = load i32* %i
%cont = icmp slt i32 %i_val, %argc
br i1 %cont, label %body, label %return
body:
%argv_addr = ptrtoint i8** %argv to i32
%count = mul i32 4, %i_val
%arg_addr = add i32 %argv_addr, %count
%args = inttoptr i32 %arg_addr to i8**
%arg = load i8** %args
call i32 @puts(i8* %arg)
%next_i = add i32 %i_val, 1
store i32 %next_i, i32* %i
br label %loop
return:
ret i32 0
}
|





dankogai
#4868()
Rating12/18=0.67
以下にけだし同感なので。
inferno :: どう書く?orgは多言語クックブックになれるか > 一般投稿が可になった時に、ちょっと感じてたんですがやっぱり最近ある傾向が顕著で。というのは数学パズル系とか、(数学的な、事務処理などではない)アルゴリズム勝負!なお題ばっかりなんですよね。
というわけで、たまには簡単でその場で答えが出て、なによりある言語使いにとって「外国語」ではこういうんだというのがわかる問題として考えてみました。
% program a b c dで a, b, c, d を得るにはどうしたらよいかという、それこそネイティブには刺身タンポポより簡単だけど、「外国人」にはとっさに浮かばないという問題です。
Dan the Practical Programmer
[ reply ]