nysol 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+ #/* ////////// LICENSE INFO ////////////////////
4
+ #
5
+ # * Copyright (C) 2013 by NYSOL CORPORATION
6
+ # *
7
+ # * Unless you have received this program directly from NYSOL pursuant
8
+ # * to the terms of a commercial license agreement with NYSOL, then
9
+ # * this program is licensed to you under the terms of the GNU Affero General
10
+ # * Public License (AGPL) as published by the Free Software Foundation,
11
+ # * either version 3 of the License, or (at your option) any later version.
12
+ # *
13
+ # * This program is distributed in the hope that it will be useful, but
14
+ # * WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF
15
+ # * NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
16
+ # *
17
+ # * Please refer to the AGPL (http://www.gnu.org/licenses/agpl-3.0.txt)
18
+ # * for more details.
19
+ #
20
+ # ////////// LICENSE INFO ////////////////////*/
21
+
22
+ require "rubygems"
23
+ require "nysol/mcmd"
24
+ require "nysol/mparallelmanager"
25
+
26
+
27
+ $version="1.0"
28
+ $revision="###VERSION###"
29
+
30
+ def help
31
+
32
+ STDERR.puts <<EOF
33
+ ----------------------------
34
+ msend.rb version #{$version}
35
+ ----------------------------
36
+ 概要) データ送信プログラム i=path o=ip:path
37
+ データを転送するプログラム
38
+ 特徴) i=指定したファイルをo=に指定したpathにコピーする
39
+ 用法) msend.rb i= [o=|O=] [uid=]
40
+ i= : ファイル名
41
+ o= : 出力ファイル名。全ての結果はここで指定したファイルに出力される。
42
+ O= : 出力ディレクトリ名。このディレクトリの直下に、各入力ファイルと同じファイル名で出力される。
43
+ uid= : ユーザ名
44
+ EOF
45
+ exit
46
+ end
47
+
48
+ def ver()
49
+ $revision ="0" if $revision =~ /VERSION/
50
+ STDERR.puts "version #{$version} revision #{$revision}"
51
+ exit
52
+ end
53
+
54
+ help() if ARGV[0]=="--help" or ARGV.size <= 0
55
+ ver() if ARGV[0]=="--version"
56
+
57
+ args=MCMD::Margs.new(ARGV,"i=,o=,O=,uid=,retry=","i=")
58
+
59
+ ifiles = args.str("i=")
60
+ ofile = args.str("o=")
61
+ opath = args.str("O=")
62
+ uid = args.str("uid=")
63
+ pclist = args.str("pclist=","/etc/pclist")
64
+
65
+ pcM = MCMD::MpcManager.new(pclist)
66
+
67
+ if !ofile and !opath then
68
+ STDERR.puts "It is necessary either o= or O= "
69
+ exit
70
+ end
71
+
72
+ i_sep = ifiles.split(":")
73
+ i_fn = i_sep[-1]
74
+ i_ip = i_sep[0] if i_sep.size > 1
75
+
76
+ dicF = true if opath
77
+ oname = dicF ? opath : ofile
78
+ o_sep = oname.split(":")
79
+ o_fn = o_sep[-1]
80
+ o_ip = o_sep[0] if o_sep.size > 1
81
+
82
+ if i_sep.size ==1 and o_sep.size ==1 then
83
+ system("cp #{i_fn} #{o_fn}")
84
+ elsif o_sep.size == 1 then
85
+ MCMD::NetTools.recv(i_ip,uid,i_fn,o_fn,pcM.getPWDbyIP(i_ip))
86
+ elsif i_sep.size == 1 then
87
+ MCMD::NetTools.send(o_ip,uid,i_fn,o_fn,pcM.getPWDbyIP(o_ip))
88
+ else
89
+ STDERR.puts "Not compatible"
90
+ exit
91
+ end
92
+
93
+ # 終了メッセージ
94
+ MCMD::endLog(args.cmdline)
95
+
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+ require "rubygems"
3
+ require "nysol/mcmd"
4
+
5
+ $version="1.0"
6
+ $revision="###VERSION###"
7
+
8
+ def help
9
+ STDERR.puts <<EOF
10
+ ----------------------------
11
+ mtempclean.rb version #{$version}
12
+ ----------------------------
13
+ 概要) mtempで作成される一時ファイルおよびディレクトリを削除する
14
+ 用法) mtempclean.rb [-save]
15
+ -save : 削除する前に、圧縮補完する
16
+ EOF
17
+ exit
18
+ end
19
+
20
+ def ver()
21
+ $revision ="0" if $revision =~ /VERSION/
22
+ STDERR.puts "version #{$version} revision #{$revision}"
23
+ exit
24
+ end
25
+
26
+ help() if ARGV[0]=="--help"
27
+ ver() if ARGV[0]=="--version"
28
+
29
+ args=MCMD::Margs.new(ARGV,"-save")
30
+ save=args.bool("-save")
31
+ wf=MCMD::Mtemp.new
32
+ wf.forceDel(save)
33
+
@@ -0,0 +1,14 @@
1
+ require "rubygems"
2
+ require "mkmf"
3
+
4
+ unless have_library("kgmod3")
5
+ puts("need libkgmod.")
6
+ puts("refer https://github.com/nysol/mcmd")
7
+ exit 1
8
+ end
9
+
10
+ $LOCAL_LIBS += "-lkgmod3"
11
+ create_makefile("nysol/mcsvin")
12
+
13
+
14
+
@@ -0,0 +1,857 @@
1
+ /* ////////// LICENSE INFO ////////////////////
2
+
3
+ * Copyright (C) 2013 by NYSOL CORPORATION
4
+ *
5
+ * Unless you have received this program directly from NYSOL pursuant
6
+ * to the terms of a commercial license agreement with NYSOL, then
7
+ * this program is licensed to you under the terms of the GNU Affero General
8
+ * Public License (AGPL) as published by the Free Software Foundation,
9
+ * either version 3 of the License, or (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful, but
12
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF
13
+ * NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
14
+ *
15
+ * Please refer to the AGPL (http://www.gnu.org/licenses/agpl-3.0.txt)
16
+ * for more details.
17
+
18
+ ////////// LICENSE INFO ////////////////////*/
19
+ // =============================================================================
20
+ // mcsvin.cpp CSV入力クラス
21
+ // =============================================================================
22
+ #include <iostream>
23
+ #include <unistd.h>
24
+ #include <sys/types.h>
25
+ #include <ruby.h>
26
+ #include <kgmodincludesort.h>
27
+ #include <kgCSV.h>
28
+ #include <kgArgFld.h>
29
+ #include <kgMethod.h>
30
+
31
+ extern "C" {
32
+ void Init_mcsvin(void);
33
+ }
34
+
35
+ using namespace std;
36
+ using namespace kglib;
37
+ using namespace kgmod;
38
+
39
+ // -----------------------------------------------------------------------------
40
+ // encodingを考慮した文字列生成
41
+ // -----------------------------------------------------------------------------
42
+ //static VALUE str2rbstr(const char *ptr)
43
+ static VALUE str2rbstr(string ptr)
44
+ {
45
+ // rb_external_str_new_cstrが定義されているばそちらを使う
46
+ #if defined(rb_external_str_new_cstr)
47
+ return rb_external_str_new_cstr(ptr.c_str());
48
+ #else
49
+ return rb_str_new2(ptr.c_str());
50
+ #endif
51
+
52
+ }
53
+ // =============================================================================
54
+ // CSV入力クラス
55
+ // =============================================================================
56
+ class mcsvin : public kgModIncludeSort
57
+ {
58
+ //kgCSV* iFile_; // 次のいずれかの変数へのポインタ
59
+ //kgCSVkey iFileKey_; // 入力ファイル(k=指定がある時)
60
+ //kgCSVfld iFileFld_; // 入力ファイル(k=指定がない時)
61
+ kgCSVkey iFile_; // 入力ファイル統一
62
+
63
+
64
+ kgArgFld kField_; // k=
65
+ size_t fldSize_;
66
+
67
+ // each用
68
+ void runHashKey(void);
69
+ void runArrayKey(void);
70
+ void runHash(void);
71
+ void runArray(void);
72
+
73
+ // ges用
74
+ VALUE getsHashKey(void);
75
+ VALUE getsArrayKey(void);
76
+ VALUE getsHash(void);
77
+ VALUE getsArray(void);
78
+
79
+
80
+ public:
81
+ //kgCSV* iFile_; // 次のいずれかの変数へのポインタ
82
+ string fsName_; // ファイル名(i=)
83
+
84
+ VALUE names_; // 項目名(f=) or 項目数(size=)
85
+ bool hasKey_; // k=が指定されているかどうか。
86
+ bool hasSkey_; // s=が指定されているかどうか。
87
+ bool byArray_; // valをArrayに格納するフラグ
88
+ bool kbFlag_; //key-breakを判定するフラグ
89
+ bool qflg_;
90
+
91
+ mcsvin(void){ // コンストラクタ
92
+ _name = "mcsvin";
93
+ _version = "2.0";
94
+ byArray_ = false;
95
+ hasKey_ = false;
96
+ kbFlag_ = true;
97
+ };
98
+
99
+ virtual ~mcsvin(void){ close(); }
100
+
101
+ // -----------------------------------------------------------------------------
102
+ // 処理行数取得
103
+ // -----------------------------------------------------------------------------
104
+ // -----------------------------------------------------------------------------
105
+ // ファイルオープン&ヘッダ読み込みSUBルーチン
106
+ // -----------------------------------------------------------------------------
107
+ void openByKey() try{
108
+ iFile_.open(fsName_.c_str(), _env,_args.toBool("-nfn"));
109
+ iFile_.read_header();
110
+ vector<kgstr_t> vs = _args.toStringVector("k=",false);
111
+ vector<kgstr_t> vss = _args.toStringVector("s=",false);
112
+
113
+ if(!qflg_){
114
+ vector<kgstr_t> vsk = vs;
115
+ vsk.insert(vsk.end(),vss.begin(),vss.end());
116
+ sortingRun(&iFile_,vsk);
117
+ }
118
+ kField_.set(vs, &iFile_, _fldByNum);
119
+ iFile_.setKey(kField_.getNum());
120
+
121
+ }catch(...){
122
+ throw;
123
+ }
124
+ void openByfld() try{
125
+ iFile_.open(fsName_.c_str(), _env,_args.toBool("-nfn"));
126
+ iFile_.read_header();
127
+ // iFile_=&iFileFld_;
128
+ }catch(...){
129
+ throw;
130
+ }
131
+
132
+ // -----------------------------------------------------------------------------
133
+ // ファイルオープン&ヘッダ読み込み
134
+ // -----------------------------------------------------------------------------
135
+ void open() try {
136
+ rb_gc_start(); //gcのタイミングは要再考
137
+ //k=有り無しで処理を変える
138
+ try {
139
+ if(hasKey_||hasSkey_){ openByKey();}
140
+ else { openByfld();}
141
+ }catch(...){//一度だけリトライ
142
+ try{
143
+ rb_gc_start();
144
+ if(hasKey_||hasSkey_){
145
+ iFile_.clear();
146
+ openByKey();
147
+ }
148
+ else{
149
+ iFile_.clear();
150
+ openByfld();
151
+ }
152
+ }catch(...){
153
+ throw;
154
+ }
155
+ }
156
+ fldSize_=iFile_.fldSize();
157
+
158
+ }catch(...){
159
+ throw;
160
+ }
161
+
162
+ // -----------------------------------------------------------------------------
163
+ // ファイルクローズ
164
+ // -----------------------------------------------------------------------------
165
+ void close(void) try {
166
+ iFile_.close();
167
+ }catch(...){
168
+ throw;
169
+ }
170
+
171
+ // -----------------------------------------------------------------------------
172
+ //アクセッサ
173
+ // -----------------------------------------------------------------------------
174
+ bool nfn() const{ return iFile_.noFldName();}
175
+ size_t fldsize() const{ return fldSize_;}
176
+ string fldName(size_t i){ return iFile_.fldName(i);}
177
+
178
+ size_t iRecNo() const{
179
+ return iFile_.recNo();
180
+ }
181
+
182
+
183
+ // -----------------------------------------------------------------------------
184
+ // 実行関数
185
+ // -----------------------------------------------------------------------------
186
+ int run();
187
+ VALUE gets();
188
+
189
+ };
190
+
191
+ // -----------------------------------------------------------------------------
192
+ // Array格納、Key指定なし
193
+ // -----------------------------------------------------------------------------
194
+ void mcsvin::runArray(void) try {
195
+
196
+ // -nfnで0バイトデータ場合はreturn
197
+ if( nfn() && fldsize()==0 ){ return; }
198
+
199
+ // 一行ずつ読み込みyield実行
200
+ VALUE fldArray=0;
201
+ while( EOF != iFile_.read() ) {
202
+
203
+ if((iFile_.status() & kgCSV::End )) break;
204
+
205
+ fldArray=rb_ary_new2(fldSize_);
206
+ for(int i=0; i<static_cast<int>(fldSize_); i++){
207
+ VALUE str;
208
+ if(*iFile_.getVal(i)=='\0'){ str=Qnil; } // nullはQnil
209
+ else { str=str2rbstr(iFile_.getVal(i)); }
210
+ rb_ary_store( fldArray,i,str );
211
+ }
212
+
213
+ // yield実行(blockの実行)
214
+ rb_yield_values(1,fldArray);
215
+ }
216
+ close();
217
+
218
+ }catch(...){
219
+ throw;
220
+ }
221
+
222
+ // -----------------------------------------------------------------------------
223
+ // Hash格納、Key指定なし
224
+ // -----------------------------------------------------------------------------
225
+ void mcsvin::runHash(void) try {
226
+
227
+ // -nfnで0バイトデータ場合はreturn
228
+ if( nfn() && fldsize()==0 ){ return; }
229
+
230
+ // 一行ずつ読み込みyield実行
231
+ while( EOF != iFile_.read() ) {
232
+ if((iFile_.status() & kgCSV::End )) break;
233
+ VALUE fldHash=rb_hash_new();
234
+ for(int i=0; i<static_cast<int>(fldSize_); i++){
235
+ VALUE str;
236
+ if(*iFile_.getVal(i)=='\0') { str=Qnil;}// nullはQnil
237
+ else { str=str2rbstr(iFile_.getVal(i));}
238
+ rb_hash_aset( fldHash,str2rbstr( iFile_.fldName(i).c_str()), str );
239
+ }
240
+
241
+ // yield実行(blockの実行)
242
+ rb_yield_values(1,fldHash);
243
+ }
244
+ close();
245
+
246
+ }catch(...){
247
+ throw;
248
+ }
249
+
250
+ // -----------------------------------------------------------------------------
251
+ // Array格納、Key指定あり
252
+ // -----------------------------------------------------------------------------
253
+ void mcsvin::runArrayKey(void) try {
254
+
255
+ // -nfnで0バイトデータ場合はreturn
256
+ if( nfn() && fldsize()==0 ){ return; }
257
+
258
+ // キーブレイクフラグ(last)
259
+ VALUE keybreakBot_rb;
260
+
261
+ // キーブレイクフラグ(first)
262
+ VALUE keybreakTop_rb;
263
+
264
+ // 一行ずつ読み込みyield実行
265
+ while( EOF != iFile_.read() ) {
266
+
267
+ if( iFile_.begin() ){
268
+ kbFlag_=true;
269
+ continue;
270
+ }
271
+
272
+ if( kbFlag_ ){ keybreakTop_rb=Qtrue; }
273
+ else { keybreakTop_rb=Qfalse;}
274
+
275
+ if( iFile_.keybreak() ){
276
+ keybreakBot_rb=Qtrue;
277
+ kbFlag_=true;
278
+ }else{
279
+ keybreakBot_rb=Qfalse;
280
+ kbFlag_=false;
281
+ }
282
+
283
+ // 項目値配列
284
+ VALUE fldArray=rb_ary_new2(fldSize_);
285
+ for(int i=0; i<static_cast<int>(fldSize_); i++){
286
+ VALUE str;
287
+ if(*iFile_.getOldVal(i)=='\0'){ str=Qnil; }// nullはQnil
288
+ else { str=str2rbstr(iFile_.getOldVal(i));}
289
+ rb_ary_store( fldArray,i,str );
290
+ }
291
+
292
+ // yield実行(blockの実行)
293
+ rb_yield_values(3,fldArray,keybreakTop_rb,keybreakBot_rb);
294
+ }
295
+ close();
296
+
297
+ }catch(...){
298
+ throw;
299
+ }
300
+
301
+ // -----------------------------------------------------------------------------
302
+ // Hash格納、Key指定あり
303
+ // -----------------------------------------------------------------------------
304
+ void mcsvin::runHashKey() try {
305
+
306
+ // -nfnで0バイトデータ場合はreturn
307
+ if( nfn() && fldsize()==0 ){ return; }
308
+
309
+ // キーブレイクフラグ(last)
310
+ VALUE keybreakBot_rb;
311
+
312
+ // キーブレイクフラグ(first)
313
+ VALUE keybreakTop_rb;
314
+
315
+ // 一行ずつ読み込みyield実行
316
+ while( EOF != iFile_.read() ) {
317
+
318
+ if(iFile_.begin()){
319
+ kbFlag_=true;
320
+ continue;
321
+ }
322
+
323
+ if( kbFlag_ ) { keybreakTop_rb=Qtrue; }
324
+ else { keybreakTop_rb=Qfalse;}
325
+
326
+ if( iFile_.keybreak() ){
327
+ keybreakBot_rb=Qtrue;
328
+ kbFlag_=true;
329
+ }else{
330
+ keybreakBot_rb=Qfalse;
331
+ kbFlag_=false;
332
+ }
333
+
334
+ VALUE fldHash=rb_hash_new();
335
+ for(int i=0; i<static_cast<int>(fldSize_); i++){
336
+ VALUE str;
337
+ if(*iFile_.getOldVal(i)=='\0'){ str=Qnil; }// nullはQnil
338
+ else { str=str2rbstr(iFile_.getOldVal(i));}
339
+ rb_hash_aset( fldHash,str2rbstr( iFile_.fldName(i).c_str()), str );
340
+
341
+ }
342
+
343
+ // yield実行(blockの実行)
344
+ rb_yield_values(3,fldHash,keybreakTop_rb,keybreakBot_rb);
345
+ }
346
+ close();
347
+
348
+ }catch(...){
349
+ throw;
350
+ }
351
+
352
+ // ======================================================================
353
+ // EACH
354
+ // ======================================================================
355
+ int mcsvin::run() try
356
+ {
357
+ // -nfnの場合は自動的にArray
358
+ if(byArray_ || nfn()){
359
+ if(hasKey_) runArrayKey();
360
+ else runArray();
361
+ }else{
362
+ if(hasKey_) runHashKey();
363
+ else runHash();
364
+ }
365
+ // ここでソートスレッドの終了確認
366
+ th_cancel();
367
+ return 0;
368
+
369
+ }catch(...){
370
+ throw;
371
+ }
372
+
373
+ // -----------------------------------------------------------------------------
374
+ // Array格納、GETS
375
+ // -----------------------------------------------------------------------------
376
+ VALUE mcsvin::getsArray() try
377
+ {
378
+ // -nfnで0バイトデータ場合はreturn
379
+ if( nfn() && fldsize()==0 ){ return Qnil; }
380
+
381
+ // 項目値配列
382
+ VALUE datas=rb_ary_new2(fldSize_);
383
+
384
+ // 一行ずつ読み込み
385
+ if ( iFile_.read() == EOF ){ return Qnil; }
386
+
387
+ for(int i=0; i<static_cast<int>(fldSize_); i++){
388
+ VALUE str;
389
+ if(*iFile_.getVal(i)=='\0'){ str=Qnil; }// nullはQnil
390
+ else { str=str2rbstr(iFile_.getVal(i));}
391
+ rb_ary_store( datas,i,str );
392
+ }
393
+
394
+ return datas;
395
+
396
+ }catch(...){
397
+ throw;
398
+ }
399
+
400
+ // -----------------------------------------------------------------------------
401
+ // HASH格納、GETS
402
+ // -----------------------------------------------------------------------------
403
+ VALUE mcsvin::getsHash() try
404
+ {
405
+ // -nfnで0バイトデータ場合はreturn
406
+ if( nfn() && fldsize()==0 ){ return Qnil; }
407
+
408
+ // 一行ずつ読み込み
409
+ if ( iFile_.read() == EOF){ return Qnil; }
410
+
411
+ VALUE fldHash=rb_hash_new();
412
+ for(int i=0; i<static_cast<int>(fldSize_); i++){
413
+ VALUE str;
414
+ if(*iFile_.getVal(i)=='\0'){ str=Qnil; }// nullはQnil
415
+ else { str=str2rbstr(iFile_.getVal(i));}
416
+ rb_hash_aset(fldHash,str2rbstr(iFile_.fldName(i).c_str()), str );
417
+ }
418
+
419
+ return fldHash;
420
+
421
+ }catch(...){
422
+ throw;
423
+ }
424
+
425
+ // -----------------------------------------------------------------------------
426
+ // Array格納、KEYあり、GETS
427
+ // -----------------------------------------------------------------------------
428
+ VALUE mcsvin::getsArrayKey() try
429
+ {
430
+ // -nfnで0バイトデータ場合はreturn
431
+ if( nfn() && fldsize()==0 ){ return rb_ary_new3(3,Qnil,Qnil,Qnil); }
432
+
433
+ // キーブレイクフラグ(last,first)
434
+ VALUE keybreakBot_rb;
435
+ VALUE keybreakTop_rb;
436
+
437
+ // 一行読み込み
438
+ if ( EOF != iFile_.read() ){
439
+ return rb_ary_new3(3,Qnil,Qnil,Qnil);
440
+ }
441
+
442
+ // 先頭行の場合は再読み込み
443
+ if( iFile_.begin() ){
444
+ kbFlag_=true;
445
+ if ( EOF != iFile_.read() ){
446
+ return rb_ary_new3(3,Qnil,Qnil,Qnil);
447
+ }
448
+ }
449
+
450
+ if( kbFlag_ ){ keybreakTop_rb=Qtrue; }
451
+ else { keybreakTop_rb=Qfalse;}
452
+
453
+ if( iFile_.keybreak() ){
454
+ keybreakBot_rb=Qtrue;
455
+ kbFlag_=true;
456
+ }else{
457
+ keybreakBot_rb=Qfalse;
458
+ kbFlag_=false;
459
+ }
460
+
461
+ // 項目値配列
462
+ VALUE fldArray=rb_ary_new2(fldSize_);
463
+ for(int i=0; i<static_cast<int>(fldSize_); i++){
464
+ VALUE str;
465
+ if(*iFile_.getOldVal(i)=='\0') { str=Qnil; } // nullはQnil
466
+ else { str=str2rbstr(iFile_.getOldVal(i)); }
467
+ rb_ary_store( fldArray,i,str );
468
+ }
469
+
470
+ // return値配列
471
+ VALUE datas=rb_ary_new2(3);
472
+ rb_ary_store( datas,0,fldArray );
473
+ rb_ary_store( datas,1,keybreakTop_rb );
474
+ rb_ary_store( datas,2,keybreakBot_rb );
475
+
476
+ return datas;
477
+
478
+ }catch(...){
479
+ throw;
480
+ }
481
+
482
+ // -----------------------------------------------------------------------------
483
+ // HASH格納、KEYあり、GETS
484
+ // -----------------------------------------------------------------------------
485
+ VALUE mcsvin::getsHashKey() try
486
+ {
487
+ // -nfnで0バイトデータ場合はreturn
488
+ if( nfn() && fldsize()==0 ){ return rb_ary_new3(3,Qnil,Qnil,Qnil); }
489
+
490
+ // キーブレイクフラグ(last,first)
491
+ VALUE keybreakBot_rb;
492
+ VALUE keybreakTop_rb;
493
+
494
+ // 一行読み込み
495
+ if ( EOF != iFile_.read() ){
496
+ return rb_ary_new3(3,Qnil,Qnil,Qnil);
497
+ }
498
+
499
+ // 先頭行の場合は再読み込み
500
+ if( iFile_.begin() ){
501
+ kbFlag_=true;
502
+ if ( EOF != iFile_.read() ){
503
+ return rb_ary_new3(3,Qnil,Qnil,Qnil);
504
+ }
505
+ }
506
+
507
+ if( kbFlag_ ) { keybreakTop_rb=Qtrue; }
508
+ else { keybreakTop_rb=Qfalse;}
509
+
510
+ if( iFile_.keybreak() ){
511
+ keybreakBot_rb=Qtrue;
512
+ kbFlag_=true;
513
+ }else{
514
+ keybreakBot_rb=Qfalse;
515
+ kbFlag_=false;
516
+ }
517
+
518
+ VALUE fldHash=rb_hash_new();
519
+
520
+ for(int i=0; i<static_cast<int>(fldSize_); i++){
521
+
522
+ VALUE str;
523
+ if(*iFile_.getOldVal(i)=='\0'){ str=Qnil; } // nullはQnil
524
+ else { str=str2rbstr(iFile_.getOldVal(i));}
525
+ rb_hash_aset( fldHash , str2rbstr( fldName(i)) , str );
526
+ }
527
+
528
+ // 項目値の格納
529
+ VALUE datas=rb_ary_new2(3);
530
+ rb_ary_store( datas,0,fldHash );
531
+ rb_ary_store( datas,1,keybreakTop_rb );
532
+ rb_ary_store( datas,2,keybreakBot_rb );
533
+
534
+ return datas;
535
+
536
+ }catch(...){
537
+ throw;
538
+ }
539
+
540
+ // ======================================================================
541
+ // GETS
542
+ // ======================================================================
543
+ VALUE mcsvin::gets() try
544
+ {
545
+ // -nfnの場合は自動的にArray
546
+ if(byArray_ || nfn()){
547
+ if(hasKey_) return getsArrayKey();
548
+ else return getsArray();
549
+ }else{
550
+ if(hasKey_) return getsHashKey();
551
+ else return getsHash();
552
+ }
553
+
554
+ }catch(...){
555
+ throw;
556
+ }
557
+
558
+ // =============================================================================
559
+ // rMmcsvin クラス(mcsvinクラスのrubyラッパ)
560
+ // 機能: 1) kgEnvとコマンドライン引数のメモリを確保する
561
+ // 2) 正常終了,エラー終了の統一的メソッドを提供する
562
+ // =============================================================================
563
+ class rMcsvin
564
+ {
565
+ private:
566
+
567
+ void freeMod() try
568
+ {
569
+ if(mod!=0){ delete mod; }
570
+ mod=0;
571
+
572
+ }catch(...){
573
+ rb_raise(rb_eRuntimeError,"Error at freeMod()");
574
+ }
575
+
576
+ public:
577
+ kgEnv env;
578
+ string argstr; // rubyの引数をコピーして格納するための変数
579
+ kgAutoPtr2<char*> argv;
580
+ mcsvin* mod; // 一度実行(RUN)されると0となる.
581
+ VALUE object_; // rMcsvinオブジェクト(rb_yieldで必要)
582
+
583
+ ~rMcsvin(){ if(mod!=0) { delete mod;} }
584
+
585
+ // ガベージコレクションで終了メソッド
586
+ void gcEnd() try {
587
+ if(mod!=0){
588
+ mod->close();
589
+ freeMod();
590
+ }
591
+ }catch(...){
592
+ rb_raise(rb_eRuntimeError,"Error at gcEnd()");
593
+ }
594
+
595
+ // エラー終了メソッド
596
+ void errorEnd(kgError& err) try
597
+ {
598
+ mod->errorEnd(err);
599
+
600
+ }catch(...){
601
+ rb_raise(rb_eRuntimeError,"Error at errorEnd()");
602
+ }
603
+
604
+ // 正常終了メソッド
605
+ void successEnd() try
606
+ {
607
+ mod->successEnd();
608
+ }catch(...){
609
+ rb_raise(rb_eRuntimeError,"Error at successEnd()");
610
+ }
611
+ };
612
+
613
+ // =============================================================================
614
+ // 公開メソッド
615
+ // =============================================================================
616
+ // -----------------------------------------------------------------------------
617
+ // NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW
618
+ //
619
+ // def initialize(args,arrayHashFlag)
620
+ // 引数の設定(rubyで指定されたargvをkgmodにchar*として渡す)
621
+ // -----------------------------------------------------------------------------
622
+ VALUE csvin_init(int argc, VALUE *argv, VALUE self) try
623
+ {
624
+ rMcsvin* rmod;
625
+ Data_Get_Struct(self,rMcsvin,rmod);
626
+
627
+ try {
628
+
629
+ // 引数をopetionsにセット
630
+ VALUE options;
631
+ rb_scan_args(argc, argv,"01",&options);
632
+
633
+ // rubyの引数文字列を一旦rmod->argstrに退避させてからtoken分割する。
634
+ // 退避させないと、ruby変数としての文字列を変更してしまうことになる。
635
+ if(TYPE(options)==T_NIL){
636
+ rmod->argstr="";
637
+ }else if(TYPE(options)==T_STRING){
638
+ rmod->argstr=RSTRING_PTR(options);
639
+ }else{
640
+ rb_raise(rb_eRuntimeError,"1st argument must be String");
641
+ }
642
+ vector<char *> opts = splitToken(const_cast<char*>(rmod->argstr.c_str()), ' ',true);
643
+
644
+ // 引数文字列へのポインタの領域はここでauto変数に確保する
645
+ char** vv;
646
+ try{
647
+ rmod->argv.set(new char*[opts.size()+1]);
648
+ vv = rmod->argv.get();
649
+ }catch(...){
650
+ rb_raise(rb_eRuntimeError,"memory allocation error");
651
+ }
652
+
653
+ // vv配列0番目はコマンド名
654
+ vv[0]=const_cast<char*>(rmod->mod->name());
655
+
656
+ size_t vvSize;
657
+ for(vvSize=0; vvSize<opts.size(); vvSize++){
658
+ vv[vvSize+1] = opts.at(vvSize);
659
+ }
660
+ vvSize+=1;
661
+
662
+ // modの初期化&引数の存在チェック
663
+ rmod->mod->init(vvSize, const_cast<const char**>(vv), &rmod->env);
664
+ rmod->mod->args()->paramcheck("i=,k=,s=,-nfn,-array,-q",false);
665
+
666
+ // 各種引数の設定 i=、-array、k=
667
+ // k=が指定されていればkgCSVkeyを利用、指定されていなければkgCSVfldを利用する。
668
+ rmod->mod->fsName_ = rmod->mod->args()->toString("i=",false);
669
+ rmod->mod->byArray_ = rmod->mod->args()->toBool("-array");
670
+ rmod->mod->qflg_ = rmod->mod->args()->toBool("-q");
671
+ if(rmod->mod->args()->get(string("k=")).size()==0){
672
+ rmod->mod->hasKey_=false;
673
+ }else{
674
+ rmod->mod->hasKey_=true;
675
+ }
676
+ if(rmod->mod->args()->get(string("s=")).size()==0){
677
+ rmod->mod->hasSkey_=false;
678
+ }else{
679
+ rmod->mod->hasSkey_=true;
680
+ }
681
+
682
+
683
+ // このタイミングでファイルオープン
684
+ // でないと、newした直後にnamesメソッドが使えない。
685
+ rmod->mod->open();
686
+
687
+ // ブロック引数があればyield実行
688
+ if(rb_block_given_p()){
689
+ rb_yield(rmod->object_);
690
+ rmod->successEnd();
691
+ }
692
+
693
+ }catch(kgError& err){ // kgmod関係エラーのchatch
694
+ rmod->errorEnd(err);
695
+ throw;
696
+ }
697
+ return self;
698
+
699
+ }catch(...){
700
+ rb_raise(rb_eRuntimeError,"Error at csvin_init()");
701
+ }
702
+
703
+ // -----------------------------------------------------------------------------
704
+ // EACH
705
+ // -----------------------------------------------------------------------------
706
+ VALUE csvin_each(VALUE self) try
707
+ {
708
+ rMcsvin* rmod;
709
+ Data_Get_Struct(self,rMcsvin,rmod);
710
+
711
+ if(rmod->mod == 0){
712
+ rb_raise(rb_eRuntimeError,"`Mcsvin.each' cannot be executed just once");
713
+ }
714
+
715
+ try {
716
+
717
+ rmod->mod->run();
718
+
719
+ }catch(kgError& err){
720
+ rmod->errorEnd(err); throw;
721
+ }
722
+
723
+ return Qtrue;
724
+
725
+ }catch(...){
726
+ rb_raise(rb_eRuntimeError,"Error at csvin_each()");
727
+ }
728
+
729
+ // -----------------------------------------------------------------------------
730
+ // GETS
731
+ // -----------------------------------------------------------------------------
732
+ VALUE csvin_gets(VALUE self) try
733
+ {
734
+ rMcsvin* rmod;
735
+ Data_Get_Struct(self,rMcsvin,rmod);
736
+
737
+ try {
738
+
739
+ return rmod->mod->gets();
740
+
741
+ }catch(kgError& err){
742
+ rmod->errorEnd(err); throw;
743
+ }
744
+ return Qnil;
745
+
746
+ }catch(...){
747
+ rb_raise(rb_eRuntimeError,"Error at csvin_gets()");
748
+ }
749
+
750
+ // -----------------------------------------------------------------------------
751
+ // NAMES NAMES NAMES NAMES NAMES NAMES NAMES NAMES NAMES NAMES NAMES NAMES
752
+ // -----------------------------------------------------------------------------
753
+ /*
754
+ * call-seq:
755
+ * names -> String Array
756
+ *
757
+ * 項目名の配列を返す。
758
+ *
759
+ * === 引数
760
+ * なし
761
+ *
762
+ */
763
+ VALUE csvin_names(VALUE self) try
764
+ {
765
+ rMcsvin* rmod;
766
+ Data_Get_Struct(self,rMcsvin,rmod);
767
+
768
+ try {
769
+
770
+ // 項目名のセット
771
+ if( rmod->mod->nfn() ){
772
+ return Qnil;
773
+ }else{
774
+ VALUE names = rb_ary_new2(rmod->mod->fldsize());
775
+ for(size_t i=0; i<rmod->mod->fldsize(); i++){
776
+ rb_ary_store( names, i, str2rbstr( rmod->mod->fldName(i) ) );
777
+ }
778
+ return names;
779
+ }
780
+
781
+ return Qnil;
782
+
783
+ }catch(kgError& err){
784
+ rmod->errorEnd(err); throw;
785
+ }
786
+
787
+ }catch(...){
788
+ rb_raise(rb_eRuntimeError,"at csvin_names()");
789
+ }
790
+
791
+ // -----------------------------------------------------------------------------
792
+ // CLOSE
793
+ // closeしてないけどいいの?
794
+ // -----------------------------------------------------------------------------
795
+ VALUE csvin_close(VALUE self) try
796
+ {
797
+ rMcsvin* rmod;
798
+ Data_Get_Struct(self,rMcsvin,rmod);
799
+
800
+ try {
801
+ rmod->successEnd();
802
+
803
+ }catch(kgError& err){ // kgmod関係エラーのchatch
804
+ rmod->errorEnd(err); throw;
805
+ }
806
+
807
+ return Qtrue;
808
+
809
+ }catch(...){
810
+ rb_raise(rb_eRuntimeError,"Error at csvin_close()");
811
+ }
812
+
813
+ // -----------------------------------------------------------------------------
814
+ // メモリ解放
815
+ // kgRubyModの領域開放(GC時にrubyにより実行される)(xxx_alloc()にて登録される)
816
+ // -----------------------------------------------------------------------------
817
+ void csvin_free(rMcsvin* rmod) try
818
+ {
819
+ if(rmod!=0) delete rmod;
820
+
821
+ }catch(...){
822
+ rb_raise(rb_eRuntimeError,"Error at csvin_free()");
823
+ }
824
+
825
+ // -----------------------------------------------------------------------------
826
+ // インスタンス化される時のメモリ確保
827
+ // -----------------------------------------------------------------------------
828
+ VALUE mcsvin_alloc(VALUE klass) try
829
+ {
830
+ rMcsvin* rmod=new rMcsvin;
831
+ rmod->mod = new mcsvin;
832
+ VALUE object=Data_Wrap_Struct(klass,0,csvin_free,rmod);
833
+ rmod->object_ = object;
834
+ return object;
835
+
836
+ }catch(...){
837
+ rb_raise(rb_eRuntimeError,"Error at csvin_alloc()");
838
+ }
839
+
840
+ // -----------------------------------------------------------------------------
841
+ // ruby Mcsvin クラス init
842
+ // -----------------------------------------------------------------------------
843
+ void Init_mcsvin(void)
844
+ {
845
+ // モジュール定義:MCMD::xxxxの部分
846
+ VALUE mcmd=rb_define_module("MCMD");
847
+
848
+ VALUE mcsvin;
849
+ mcsvin=rb_define_class_under(mcmd,"Mcsvin",rb_cObject);
850
+ rb_define_alloc_func(mcsvin, mcsvin_alloc);
851
+ rb_define_method(mcsvin,"initialize", (VALUE (*)(...))csvin_init ,-1);
852
+ rb_define_method(mcsvin,"each" , (VALUE (*)(...))csvin_each ,0);
853
+ rb_define_method(mcsvin,"gets" , (VALUE (*)(...))csvin_gets ,0);
854
+ rb_define_method(mcsvin,"names" , (VALUE (*)(...))csvin_names,0);
855
+ rb_define_method(mcsvin,"close" , (VALUE (*)(...))csvin_close,0);
856
+ }
857
+