nysol 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+