MUSASHI C source: xtrand.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 <xtrandHelp.h> 
0012: struct mssComHelp comHelp={ 
0013:   "xtrand",       /* コマンド名       */ 
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: #define RMSTR "RAND_MAX" 
0027:  
0028: int main(int argc, char *argv[]){ 
0029: /*============================================================================*/ 
0030: /* オプション宣言&定義                                                       */ 
0031: /*============================================================================*/ 
0032: /*----------------------------------------------------------------------------*/ 
0033: /* キー項目                                                                   */ 
0034: /*----------------------------------------------------------------------------*/ 
0035:   MssOptKEY optKEY={ 
0036:     OKEY,   /* オプションタイプ                                             */ 
0037:     "k",    /* キーワード(複数文字は不可)                                   */ 
0038:     0,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0039:     MssFieldMaxCnt, /* 指定可能な最大項目数                                 */ 
0040:     "i",    /* 対象とする入力データのキーワード(GUIで利用)                  */ 
0041:     1,      /* デフォルト(このオプションが指定されなかったときの動作を指定) */ 
0042:             /* 1:全ての行を異るキー値として扱う                             */ 
0043:             /* 2:全ての行を同じキー値として扱う)                            */ 
0044:     KEYT,   /* このオプションのタイトル(Helpで表示)                         */ 
0045:     KEYC    /* このオプションのコメント(Helpで表示)                         */ 
0046:   }; 
0047:  
0048: /*----------------------------------------------------------------------------*/ 
0049: /* 乱数の種                                                                   */ 
0050: /*----------------------------------------------------------------------------*/ 
0051:   MssOptINT optSED={ 
0052:     OINT,   /* オプションタイプ                                             */ 
0053:     "S",    /* キーワード(複数文字は不可)                                   */ 
0054:     0,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0055:     -1,     /* デフォルト(数値として指定)                                   */ 
0056:     -1,     /* 最小値                                                       */ 
0057:     INT_MAX,/* 最大値                                                       */ 
0058:     SEDT,   /* このオプションのタイトル(Helpで表示)                         */ 
0059:     SEDC    /* このオプションのコメント(Helpで表示)                         */ 
0060:   };         
0061:  
0062: /*----------------------------------------------------------------------------*/ 
0063: /* 乱数の最小値                                                               */ 
0064: /*----------------------------------------------------------------------------*/ 
0065:   MssOptINT optMIN={ 
0066:     OINT,   /* オプションタイプ                                             */ 
0067:     "M",    /* キーワード(複数文字は不可)                                   */ 
0068:     0,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0069:     0,      /* デフォルト(数値として指定)                                   */ 
0070:     0,      /* 最小値                                                       */ 
0071:     INT_MAX,/* 最大値                                                       */ 
0072:     MINT,   /* このオプションのタイトル(Helpで表示)                         */ 
0073:     MINC    /* このオプションのコメント(Helpで表示)                         */ 
0074:   };         
0075:  
0076: /*----------------------------------------------------------------------------*/ 
0077: /* 乱数の種類数                                                               */ 
0078: /*----------------------------------------------------------------------------*/ 
0079:   MssOptINT optCNT={ 
0080:     OINT,   /* オプションタイプ                                             */ 
0081:     "C",    /* キーワード(複数文字は不可)                                   */ 
0082:     0,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0083:     RAND_MAX,/* デフォルト(数値として指定)                                   */ 
0084:     0,      /* 最小値                                                       */ 
0085:     RAND_MAX,/* 最大値                                                       */ 
0086:     CNTT,   /* このオプションのタイトル(Helpで表示)                         */ 
0087:     CNTC    /* このオプションのコメント(Helpで表示)                         */ 
0088:   };         
0089:  
0090: /*----------------------------------------------------------------------------*/ 
0091: /* 新項目名                                                                   */ 
0092: /*----------------------------------------------------------------------------*/ 
0093:   MssOptSLS optFNM={ 
0094:     OSLS,   /* オプションタイプ                                             */ 
0095:     "a",    /* キーワード(複数文字は不可)                                   */ 
0096:     2,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0097:     NULL,   /* デフォルト(文字列)                                           */ 
0098:     1,      /* カンマで区切られる要素数の最大値                             */ 
0099:     1,      /* 各要素の文字列長の最小値                                     */ 
0100:     MssFieldNameMaxLen,/* 各要素の文字列長の最大値                          */ 
0101:     0,      /* 1:要素にコロンを指定できる,0:不可  ex) aaaa:xxxxx            */ 
0102:     FNMT,   /* このオプションのタイトル(Helpで表示)                         */ 
0103:     FNMC    /* このオプションのコメント(Helpで表示)                         */ 
0104:   }; 
0105:  
0106: /*----------------------------------------------------------------------------*/ 
0107: /* シーケンシャル処理                                                         */ 
0108: /*----------------------------------------------------------------------------*/ 
0109:   MssOptFLG optSEQ={ 
0110:     OFLG,   /* オプションタイプ                                             */ 
0111:     "q",    /* キーワード(複数文字は不可)                                   */ 
0112:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0113:     SEQT,   /* このオプションのタイトル(Helpで表示)                         */ 
0114:     SEQC    /* このオプションのコメント(Helpで表示)                         */ 
0115:   }; 
0116:  
0117: /*----------------------------------------------------------------------------*/ 
0118: /* 入力ファイル                                                               */ 
0119: /*----------------------------------------------------------------------------*/ 
0120:   MssOptINF optINF={ 
0121:     OINF,   /* オプションタイプ                                             */ 
0122:     "i",    /* キーワード(複数文字は不可)                                   */ 
0123:     0,      /* 0:オプション, 1:必須                                         */ 
0124:     1,      /* 指定可能の最大ファイル数                                     */ 
0125:     0,      /*1:file not foundのエラーで終了しない 0:する                   */ 
0126:     INFT,   /* このオプションのタイトル(Helpで表示)                         */ 
0127:     INFC    /* このオプションのコメント(Helpで表示)                         */ 
0128:   }; 
0129:  
0130: /*----------------------------------------------------------------------------*/ 
0131: /* 出力ファイル                                                               */ 
0132: /*----------------------------------------------------------------------------*/ 
0133:   MssOptOTF optOTF={ 
0134:     OOTF,   /* オプションタイプ                                             */ 
0135:     "o",    /* キーワード(複数文字は不可)                                   */ 
0136:     0,      /* 0:オプション, 1:必須                                         */ 
0137:     OTFT,   /* このオプションのタイトル(Helpで表示)                         */ 
0138:     OTFC    /* このオプションのコメント(Helpで表示)                         */ 
0139:   }; 
0140:  
0141: /*----------------------------------------------------------------------------*/ 
0142: /* 圧縮出力                                                                   */ 
0143: /*----------------------------------------------------------------------------*/ 
0144:   MssOptFLG optZIP={ 
0145:     OFLG,   /* オプションタイプ                                             */ 
0146:     "z",    /* キーワード(複数文字は不可)                                   */ 
0147:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0148:     ZIPT,   /* このオプションのタイトル(Helpで表示)                         */ 
0149:     ZIPC    /* このオプションのコメント(Helpで表示)                         */ 
0150:   }; 
0151:  
0152: /*----------------------------------------------------------------------------*/ 
0153: /* plain text                                                                 */ 
0154: /*----------------------------------------------------------------------------*/ 
0155:   MssOptFLG optTXT={ 
0156:     OFLG,   /* オプションタイプ                                             */ 
0157:     "t",    /* キーワード(複数文字は不可)                                   */ 
0158:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0159:     TXTT,   /* このオプションのタイトル(Helpで表示)                         */ 
0160:     TXTC    /* このオプションのコメント(Helpで表示)                         */ 
0161:   }; 
0162:  
0163: /*----------------------------------------------------------------------------*/ 
0164: /* ワークファイル用ディレクトリ名                                             */ 
0165: /*----------------------------------------------------------------------------*/ 
0166:   MssOptSTR optTMP={ 
0167:     OSTR,   /* オプションタイプ                                             */ 
0168:     "T",    /* キーワード(複数文字は不可)                                   */ 
0169:     0,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0170:     MssTempDir, /* デフォルト                                               */ 
0171:     1,      /* 文字列の最小長                                               */ 
0172:     MssFileNameMaxLen,  /* 文字列の最大長                                   */ 
0173:     TMPT,   /* このオプションのタイトル(Helpで表示)                         */ 
0174:     TMPC    /* このオプションのコメント(Helpで表示)                         */ 
0175:   }; 
0176:  
0177: /*----------------------------------------------------------------------------*/ 
0178: /* オプションをまとめる                                                       */ 
0179: /*----------------------------------------------------------------------------*/ 
0180:   void *opt[]={&optKEY,&optSED,&optMIN,&optCNT,&optFNM,&optSEQ, 
0181:                &optINF,&optOTF,&optZIP,&optTXT,&optTMP,NULL}; 
0182:  
0183: /*============================================================================*/ 
0184: /* 変数宣言&定義                                                             */ 
0185: /*============================================================================*/ 
0186:   struct mssHeader    *hdi; /*入力ファイル用<head>タグ格納構造体*/ 
0187:   struct mssHeader    *hdo; /*出力ファイル用<head>タグ格納構造体*/ 
0188:   struct mssFPR       *fpr; /*入力ファイル構造体                */ 
0189:   struct mssFPW       *fpw; /*出力ファイル構造体                */ 
0190:   struct mssFldRecDbl *frd; /*項目-二行バッファ構造体           */ 
0191:   struct mssFields    *sf;  /*ソート項目構造体                  */ 
0192:  
0193:   int    rndVal; 
0194:   double unit; 
0195:   int sorted; 
0196:  
0197: /*----------------------------------------------------------------------------*/ 
0198: /* 前処理                                                                     */ 
0199: /*----------------------------------------------------------------------------*/ 
0200:   mssInit(argc,argv,&comHelp);       /* シグナル処理などの初期化              */ 
0201:   mssHelpDoc(opt,&comHelp,argc,argv);/* ヘルプ                                */ 
0202:   mssSetOption(opt,argc,argv);       /* コマンドオプションの設定              */ 
0203:   fpr=mssOpenFPR(optINF.str,4);      /* 入力ファイルオープン                  */ 
0204:   hdi=mssReadHeader(fpr);            /* ヘッダの読み込み                      */ 
0205:   mssSetOptKey(&optKEY, hdi);        /* -k 項目をヘッダー項目に関連づける     */ 
0206:      
0207:   /*ソート項目の作成*/ 
0208:   sf=mssInitFields(); 
0209:   mssAddFieldsByFields(sf,optKEY.flds); /* -k 項目をソート項目としてセット    */ 
0210:   mssSetFieldsSortPriority(sf);         /* ソート優先順位番号を登録順にふる   */ 
0211:   sorted=mssChkSorted(sf,hdi);          /* ソート済かチェック                 */ 
0212:    
0213: /*mssShowFields(sf);*/ 
0214: /*mssShowOption(opt);*/ 
0215: /*mssShowHeader(hdi);*/ 
0216:  
0217: /*----------------------------------------------------------------------------*/ 
0218: /*出力ヘッダーの作成と出力                                                    */ 
0219: /*----------------------------------------------------------------------------*/ 
0220:   /*出力ヘッダーの初期化(タイトル等のコピー)*/ 
0221:   hdo=mssInitCpyHeader(hdi); 
0222:    
0223:   /*入力ヘッダの全項目を追加*/ 
0224:   mssAddFieldsByFields(hdo->flds,hdi->flds); 
0225:    
0226:   /*新項目名を追加する*/ 
0227:   mssAddFieldsByStrList(hdo->flds,optFNM.strList,optFNM.cnt); 
0228:    
0229:   /*ソートする必要があるならばsfのソート情報を反映*/ 
0230:   if(!optSEQ.set && !sorted){ 
0231:     mssSetFieldsSort(hdo->flds,sf); 
0232:   } 
0233:    
0234:   /*標準出力オープン+ヘッダーの出力*/ 
0235:   fpw=mssOpenFPW(optOTF.str,optZIP.set,0); 
0236:   mssWriteHeader(hdo, fpw); 
0237:  
0238: /*----------------------------------------------------------------------------*/ 
0239: /*メインルーチン                                                              */ 
0240: /*----------------------------------------------------------------------------*/ 
0241:   /*ソートが必用ならばソートしてソート済みファイルとしてオープン*/ 
0242:   if( !optSEQ.set && !sorted){ 
0243:     fpr=mssReopenFPRsort(fpr,4,sf,hdi->flds->cnt,optTMP.str); 
0244:   } 
0245:  
0246:   mssInitRand(optSED.val); /*乱数初期化*/ 
0247:  
0248:   unit=(double)(RAND_MAX)/(double)(optCNT.val-1); 
0249:   frd=mssInitFRD(hdi->flds->cnt); 
0250:   rndVal=(int)((double)rand()/unit); 
0251:  
0252:   while( EOF!=mssReadFRD(fpr,frd) ){ 
0253:  
0254:     /*キーブレイク時の処理*/ 
0255:     if(mssKeyBreak(frd, &optKEY)){ 
0256:       if(frd->eof) break; 
0257:  
0258:       if(optKEY.set){ 
0259:         rndVal=(int)((double)optMIN.val+(double)rand()/unit+0.5); 
0260:       } 
0261:     } 
0262:  
0263:     mssGV.inCnt++; 
0264:  
0265:     /*通常行の処理(集計値の計算)*/ 
0266:     if(!optKEY.set){ 
0267:       rndVal=(int)((double)optMIN.val+(double)rand()/unit+0.5); 
0268:     } 
0269:     mssWriteFld(frd->pnt[frd->new],frd->fldCnt," ",fpw); 
0270:     mssWriteInt(rndVal,fpw); mssWriteRet(fpw); 
0271:     mssGV.outCnt++; 
0272:   } 
0273:   mssFreeFRD(frd); 
0274:  
0275: /*----------------------------------------------------------------------------*/ 
0276: /*フッター出力&終了処理                                                       */ 
0277: /*----------------------------------------------------------------------------*/ 
0278: /*printf("allocCnt=%d\n",getAllocCnt());*/ 
0279:   mssWriteFooter(fpw);    /* フッターの出力             */ 
0280:   mssCloseFPR(fpr);       /* 入力ファイルのクローズ     */ 
0281:   mssCloseFPW(fpw);       /* 出力ファイルのクローズ     */ 
0282:   mssFreeFields(sf);      /* ソート項目構造体の領域開放 */ 
0283:   mssFreeHeader(hdi);     /* 入力ヘッダ領域開放         */ 
0284:   mssFreeHeader(hdo);     /* 出力ヘッダ領域開放         */ 
0285:   mssFreeOption(opt);     /* オプション領域開放         */ 
0286:   mssShowEndMsg();        /* 完了メッセージ             */ 
0287:   mssEnd(mssExitSuccess); /* 終了                       */ 
0288:   return(0);              /* to avoid warning message   */ 
0289: }