MUSASHI C source: xtselrand.c


0001: /*============================================================================*/ 
0002: /* 変更履歴                                                                   */ 
0003: /*----------------------------------------------------------------------------*/ 
0004: /* 1.0 : 新しいAPIに対応 2003/06/20                                           */ 
0005: /*============================================================================*/ 
0006:    
0007: #include <musashi.h
0008: #include <stdlib.h> 
0009: #include <limits.h> 
0010:  
0011: #include <xtselrandHelp.h> 
0012: struct mssComHelp comHelp={ 
0013:   "xtselrand",    /* コマンド名       */ 
0014:   "1.0",          /* バージョン       */ 
0015:   HELPT,          /* コマンドタイトル */ 
0016:   HELPS,          /* 要約             */ 
0017:   HELPE,          /* 利用例           */ 
0018:   HELPR,          /* 参照コマンド     */ 
0019:   HELPA,          /* 作者情報         */ 
0020:   HELPB,          /* バグレポート情報 */ 
0021:   HELPH           /* ホームページ     */ 
0022: };  
0023:  
0024: extern struct mssGlobalVariables mssGV; 
0025:  
0026: int main(int argc, char *argv[]){ 
0027: /*============================================================================*/ 
0028: /* オプション宣言&定義                                                       */ 
0029: /*============================================================================*/ 
0030: /*----------------------------------------------------------------------------*/ 
0031: /* キー項目                                                                   */ 
0032: /*----------------------------------------------------------------------------*/ 
0033:   MssOptKEY optKEY={ 
0034:     OKEY,   /* オプションタイプ                                             */ 
0035:     "k",    /* キーワード(複数文字は不可)                                   */ 
0036:     0,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0037:     MssFieldMaxCnt, /* 指定可能な最大項目数                                 */ 
0038:     "i",    /* 対象とする入力データのキーワード(GUIで利用)                  */ 
0039:     2,      /* デフォルト(このオプションが指定されなかったときの動作を指定) */ 
0040:             /* 1:全ての行を異るキー値として扱う                             */ 
0041:             /* 2:全ての行を同じキー値として扱う)                            */ 
0042:     KEYT,   /* このオプションのタイトル(Helpで表示)                         */ 
0043:     KEYC    /* このオプションのコメント(Helpで表示)                         */ 
0044:   }; 
0045:  
0046: /*----------------------------------------------------------------------------*/ 
0047: /* 選択件数                                                                   */ 
0048: /*----------------------------------------------------------------------------*/ 
0049:   MssOptINT optCNT={ 
0050:     OINT,   /* オプションタイプ                                             */ 
0051:     "c",    /* キーワード(複数文字は不可)                                   */ 
0052:     0,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0053:     1,      /* デフォルト(数値として指定)                                   */ 
0054:     1,      /* 最小値                                                       */ 
0055:     INT_MAX,/* 最大値                                                       */ 
0056:     CNTT,   /* このオプションのタイトル(Helpで表示)                         */ 
0057:     CNTC    /* このオプションのコメント(Helpで表示)                         */ 
0058:   };         
0059:      
0060: /*----------------------------------------------------------------------------*/ 
0061: /* 選択件数(割合)                                                             */ 
0062: /*----------------------------------------------------------------------------*/ 
0063:   MssOptDBL optPCT={ 
0064:     ODBL,   /* オプションタイプ                                             */ 
0065:     "p",    /* キーワード(複数文字は不可)                                   */ 
0066:     0,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0067:     0,      /* デフォルト(数値として指定)                                   */ 
0068:     0,      /* 最小値                                                       */ 
0069:     100,    /* 最大値                                                       */ 
0070:     PCTT,   /* このオプションのタイトル(Helpで表示)                         */ 
0071:     PCTC    /* このオプションのコメント(Helpで表示)                         */ 
0072:   }; 
0073:  
0074: /*----------------------------------------------------------------------------*/ 
0075: /* 乱数の種                                                                   */ 
0076: /*----------------------------------------------------------------------------*/ 
0077:   MssOptINT optSED={ 
0078:     OINT,   /* オプションタイプ                                             */ 
0079:     "S",    /* キーワード(複数文字は不可)                                   */ 
0080:     0,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0081:     -1,     /* デフォルト(数値として指定)                                   */ 
0082:     -1,     /* 最小値                                                       */ 
0083:     INT_MAX,/* 最大値                                                       */ 
0084:     SEDT,   /* このオプションのタイトル(Helpで表示)                         */ 
0085:     SEDC    /* このオプションのコメント(Helpで表示)                         */ 
0086:   }; 
0087:  
0088: /*----------------------------------------------------------------------------*/ 
0089: /* 条件不一致出力ファイル                                                     */ 
0090: /*----------------------------------------------------------------------------*/ 
0091:   MssOptOTF optNOF={ 
0092:     OOTF,   /* オプションタイプ                                             */ 
0093:     "u",    /* キーワード(複数文字は不可)                                   */ 
0094:     0,      /* 0:オプション, 1:必須                                         */ 
0095:     NOFT,   /* このオプションのタイトル(Helpで表示)                         */ 
0096:     NOFC    /* このオプションのコメント(Helpで表示)                         */ 
0097:   }; 
0098:  
0099: /*----------------------------------------------------------------------------*/ 
0100: /* シーケンシャル処理                                                         */ 
0101: /*----------------------------------------------------------------------------*/ 
0102:   MssOptFLG optSEQ={ 
0103:     OFLG,   /* オプションタイプ                                             */ 
0104:     "q",    /* キーワード(複数文字は不可)                                   */ 
0105:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0106:     SEQT,   /* このオプションのタイトル(Helpで表示)                         */ 
0107:     SEQC    /* このオプションのコメント(Helpで表示)                         */ 
0108:   }; 
0109:  
0110: /*----------------------------------------------------------------------------*/ 
0111: /* 入力ファイル                                                               */ 
0112: /*----------------------------------------------------------------------------*/ 
0113:   MssOptINF optINF={ 
0114:     OINF,   /* オプションタイプ                                             */ 
0115:     "i",    /* キーワード(複数文字は不可)                                   */ 
0116:     0,      /* 0:オプション, 1:必須                                         */ 
0117:     1,      /* 指定可能の最大ファイル数                                     */ 
0118:     0,      /*1:file not foundのエラーで終了しない 0:する                   */ 
0119:     INFT,   /* このオプションのタイトル(Helpで表示)                         */ 
0120:     INFC    /* このオプションのコメント(Helpで表示)                         */ 
0121:   }; 
0122:  
0123: /*----------------------------------------------------------------------------*/ 
0124: /* 出力ファイル                                                               */ 
0125: /*----------------------------------------------------------------------------*/ 
0126:   MssOptOTF optOTF={ 
0127:     OOTF,   /* オプションタイプ                                             */ 
0128:     "o",    /* キーワード(複数文字は不可)                                   */ 
0129:     0,      /* 0:オプション, 1:必須                                         */ 
0130:     OTFT,   /* このオプションのタイトル(Helpで表示)                         */ 
0131:     OTFC    /* このオプションのコメント(Helpで表示)                         */ 
0132:   }; 
0133:  
0134: /*----------------------------------------------------------------------------*/ 
0135: /* 圧縮出力                                                                   */ 
0136: /*----------------------------------------------------------------------------*/ 
0137:   MssOptFLG optZIP={ 
0138:     OFLG,   /* オプションタイプ                                             */ 
0139:     "z",    /* キーワード(複数文字は不可)                                   */ 
0140:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0141:     ZIPT,   /* このオプションのタイトル(Helpで表示)                         */ 
0142:     ZIPC    /* このオプションのコメント(Helpで表示)                         */ 
0143:   }; 
0144:      
0145: /*----------------------------------------------------------------------------*/ 
0146: /* plain text                                                                 */ 
0147: /*----------------------------------------------------------------------------*/ 
0148:   MssOptFLG optTXT={ 
0149:     OFLG,   /* オプションタイプ                                             */ 
0150:     "t",    /* キーワード(複数文字は不可)                                   */ 
0151:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0152:     TXTT,   /* このオプションのタイトル(Helpで表示)                         */ 
0153:     TXTC    /* このオプションのコメント(Helpで表示)                         */ 
0154:   }; 
0155:  
0156:  
0157: /*----------------------------------------------------------------------------*/ 
0158: /* ワークファイル用ディレクトリ名                                             */ 
0159: /*----------------------------------------------------------------------------*/ 
0160:   MssOptSTR optTMP={ 
0161:     OSTR,   /* オプションタイプ                                             */ 
0162:     "T",    /* キーワード(複数文字は不可)                                   */ 
0163:     0,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0164:     MssTempDir, /* デフォルト                                               */ 
0165:     1,      /* 文字列の最小長                                               */ 
0166:     MssFileNameMaxLen,  /* 文字列の最大長                                   */ 
0167:     TMPT,   /* このオプションのタイトル(Helpで表示)                         */ 
0168:     TMPC    /* このオプションのコメント(Helpで表示)                         */ 
0169:   }; 
0170:  
0171: /*----------------------------------------------------------------------------*/ 
0172: /* オプションをまとめる                                                       */ 
0173: /*----------------------------------------------------------------------------*/ 
0174:   void *opt[]={&optKEY,&optCNT,&optPCT,&optSED,&optNOF,&optSEQ, 
0175:                &optINF,&optOTF,&optZIP,&optTXT,&optTMP,NULL}; 
0176:  
0177: /*============================================================================*/ 
0178: /* 変数宣言&定義                                                             */ 
0179: /*============================================================================*/ 
0180:   struct mssHeader    *hdi;      /* 入力ファイル用<head>タグ格納構造体       */ 
0181:   struct mssHeader    *hdo;      /* 出力ファイル用<head>タグ格納構造体       */ 
0182:   struct mssFPR       *fpr;      /* 入力ファイル構造体                       */ 
0183:   struct mssFPW       *fpw;      /* 出力ファイル構造体                       */ 
0184:   struct mssFPW       *fpw2;     /* 条件不一致出力ファイル構造体             */ 
0185:   struct mssFldRecKey *frk=NULL; /* 項目-キーバッファ構造体                  */ 
0186:   struct mssFields    *sf;       /* ソート項目構造体                         */ 
0187:   int sorted;                    /* ソート済チェック用                       */ 
0188:  
0189:   int select; 
0190:   int remaining; 
0191:   int r;                   /*元データのwhile内行数カウンタ*/ 
0192:  
0193: /*----------------------------------------------------------------------------*/ 
0194: /* 前処理                                                                     */ 
0195: /*----------------------------------------------------------------------------*/ 
0196:   mssInit(argc,argv,&comHelp);       /* シグナル処理などの初期化              */ 
0197:   mssHelpDoc(opt,&comHelp,argc,argv);/* ヘルプ                                */ 
0198:   mssSetOption(opt,argc,argv);       /* コマンドオプションの設定              */ 
0199:   fpr=mssOpenFPR(optINF.str,4);      /* 入力ファイルオープン                  */ 
0200:   hdi=mssReadHeader(fpr);            /* ヘッダの読み込み                      */ 
0201:   mssSetOptKey(&optKEY, hdi);        /* オプション項目をヘッダー項目に関連づけ*/ 
0202:      
0203:   /*ソート項目の作成*/ 
0204:   sf=mssInitFields(); 
0205:   mssAddFieldsByFields(sf,optKEY.flds); /* -k 項目をソート項目としてセット    */ 
0206:   mssSetFieldsSortPriority(sf);         /* ソート優先順位番号を登録順にふる   */ 
0207:   sorted=mssChkSorted(sf,hdi);          /* ソート済かチェック                 */ 
0208:  
0209: /*mssShowFields(sf);*/ 
0210: /*mssShowOption(opt);*/ 
0211: /*mssShowHeader(hdi);*/ 
0212:  
0213:   if(optCNT.set + optPCT.set != 1){ 
0214:     mssShowErrMsg("must specify either -c or -p"); 
0215:     mssEnd(mssErrorNoDefault); 
0216:   } 
0217:  
0218: /*----------------------------------------------------------------------------*/ 
0219: /*出力ヘッダーの作成と出力                                                    */ 
0220: /*----------------------------------------------------------------------------*/ 
0221:   /*出力ヘッダーの初期化(タイトル等のコピー)*/ 
0222:   hdo=mssInitCpyHeader(hdi); 
0223:      
0224:   /*入力ヘッダの全項目を追加*/ 
0225:   mssAddFieldsByFields(hdo->flds,hdi->flds); 
0226:  
0227:   /*ソートする必要があるならばsfのソート情報を反映*/ 
0228:   if(!optSEQ.set && !sorted){ 
0229:     mssSetFieldsSort(hdo->flds,sf); 
0230:   } 
0231:  
0232:   /*標準出力オープン+ヘッダーの出力*/ 
0233:   fpw=mssOpenFPW(optOTF.str,optZIP.set,0); 
0234:   mssWriteHeader(hdo, fpw); 
0235:  
0236:  
0237:   /*条件不一致出力オープン+ヘッダーの出力*/ 
0238:   if(optNOF.set){ 
0239:     fpw2=mssOpenFPW(optNOF.str,optZIP.set,0); 
0240:     mssWriteHeader(hdo, fpw2); 
0241:   }else{ 
0242:     fpw2=NULL; 
0243:   } 
0244:  
0245: /*----------------------------------------------------------------------------*/ 
0246: /*メインルーチン                                                              */ 
0247: /*----------------------------------------------------------------------------*/ 
0248:   /*ソートが必用ならばソートしてソート済みファイルとしてオープン*/ 
0249:   if(!optSEQ.set && !sorted) 
0250:     fpr=mssReopenFPRsort(fpr,4,sf,hdi->flds->cnt,optTMP.str); 
0251:  
0252:   mssInitRand(optSED.val); /*乱数初期化*/ 
0253:  
0254:   /*FRK構造体の初期化*/ 
0255:   frk=mssInitFRK(hdi->flds->cnt, &optKEY, optTMP.str); 
0256:  
0257:   while(1){ 
0258:     /*データ読み込み*/ 
0259:     if(EOF==mssReadFRK(fpr,frk)) break; 
0260:      
0261:     /*サンプリング*/ 
0262:     remaining=frk->keyRecCnt; 
0263:     if(optCNT.set)select=optCNT.val; 
0264:     else          select=(int)((optPCT.val/(double)100)*(double)frk->keyRecCnt); 
0265:     if(select>frk->keyRecCnt) select=frk->keyRecCnt; 
0266:     r=0; 
0267:     while( EOF != mssReadFldRecFRK(frk) ){ 
0268:       mssGV.inCnt++; 
0269:       if( (rand()%remaining) < select ){ 
0270:         mssWriteFld(frk->pnt,frk->fldCnt,"\n",fpw); 
0271:         mssGV.outCnt++; 
0272:         select--; 
0273:       }else{ 
0274:         if(optNOF.set){ 
0275:           mssWriteFld(frk->pnt,frk->fldCnt,"\n",fpw2); 
0276:         } 
0277:       } 
0278:       r++; 
0279:       remaining--; 
0280:     } 
0281:   } 
0282:   mssFreeFRK(frk); 
0283:  
0284: /*----------------------------------------------------------------------------*/ 
0285: /*フッター出力&終了処理                                                       */ 
0286: /*----------------------------------------------------------------------------*/ 
0287: /*printf("allocCnt=%d\n",getAllocCnt());*/ 
0288:   mssWriteFooter(fpw);    /*フッターの出力              */ 
0289:   mssWriteFooter(fpw2);   /*フッターの出力              */ 
0290:   mssCloseFPW(fpw);       /*出力ファイルのクローズ      */ 
0291:   mssCloseFPW(fpw2);      /*出力ファイルのクローズ      */ 
0292:   mssCloseFPR(fpr);       /*入力ファイルのクローズ      */ 
0293:   mssFreeFields(sf);      /* ソート項目構造体の領域開放 */ 
0294:   mssFreeHeader(hdi);     /* 入力ヘッダ領域開放         */ 
0295:   mssFreeHeader(hdo);     /* 出力ヘッダ領域開放         */ 
0296:   mssFreeOption(opt);     /* オプション領域開放         */ 
0297:   mssShowEndMsg();        /* 完了メッセージ             */ 
0298:   mssEnd(mssExitSuccess); /* 終了                       */ 
0299:   return(0);              /* to avoid warning message   */ 
0300: }