MUSASHI C source: xtbest.c


0001:  
0002: /*============================================================================*/ 
0003: /* 変更履歴                                                                   */ 
0004: /*----------------------------------------------------------------------------*/ 
0005: /* 1.0 : 新しいAPIに対応 2003/06/20                                           */ 
0006: /*============================================================================*/ 
0007:  
0008: #include <musashi.h
0009: #include <stdlib.h> 
0010: #include <limits.h> 
0011:  
0012: #include <xtbestHelp.h> 
0013: struct mssComHelp comHelp={ 
0014:   "xtbest",       /* コマンド名       */ 
0015:   "1.0",          /* バージョン       */ 
0016:   HELPT,          /* コマンドタイトル */ 
0017:   HELPS,          /* 要約             */ 
0018:   HELPE,          /* 利用例           */ 
0019:   HELPR,          /* 参照コマンド     */ 
0020:   HELPA,          /* 作者情報         */ 
0021:   HELPB,          /* バグレポート情報 */ 
0022:   HELPH           /* ホームページ     */ 
0023: }; 
0024:  
0025: extern struct mssGlobalVariables mssGV;                                      
0026:  
0027: int main(int argc, char *argv[]){ 
0028: /*============================================================================*/ 
0029: /* オプション宣言&定義                                                       */ 
0030: /*============================================================================*/ 
0031: /*----------------------------------------------------------------------------*/ 
0032: /* キー項目                                                                   */ 
0033: /*----------------------------------------------------------------------------*/ 
0034:   MssOptKEY optKEY={ 
0035:     OKEY,   /* オプションタイプ                                             */ 
0036:     "k",    /* キーワード(複数文字は不可)                                   */ 
0037:     0,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0038:     MssFieldMaxCnt, /* 指定可能な最大項目数                                 */ 
0039:     "i",    /* 対象とする入力データのキーワード(GUIで利用)                  */ 
0040:     2,      /* デフォルト(このオプションが指定されなかったときの動作を指定) */ 
0041:             /* 1:全ての行を異るキー値として扱う                             */ 
0042:             /* 2:全ての行を同じキー値として扱う)                            */ 
0043:     KEYT,   /* このオプションのタイトル(Helpで表示)                         */ 
0044:     KEYC    /* このオプションのコメント(Helpで表示)                         */ 
0045:   }; 
0046:  
0047: /*----------------------------------------------------------------------------*/ 
0048: /* ソート項目                                                                 */ 
0049: /*----------------------------------------------------------------------------*/ 
0050:   MssOptFLD optSRT={ 
0051:     OFLD,   /* オプションタイプ                                             */ 
0052:     "s",    /* キーワード(複数文字は不可)                                   */ 
0053:     0,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0054:     MssFieldMaxCnt, /* 指定可能な最大項目数                                 */ 
0055:     "i",    /* 対象とする入力データのキーワード(GUIで利用)                  */ 
0056:     0,      /* 正規表現を許可するかどうか(0:不可,1:可)                      */ 
0057:     0,      /* 新項目名を指定できるかどうか(0:不可,1:可)                    */ 
0058:     "n,r",  /* 項目オプション(%以下)で指定可能な文字                        */ 
0059:             /* ex) 指定不可の場合はNULL, "nr": "-f 項目名%rn"の指定可能     */ 
0060:     SRTT,   /* このオプションのタイトル(Helpで表示)                         */ 
0061:     SRTC,   /* このオプションのコメント(Helpで表示)                         */ 
0062:     SRTF    /* フラグについての説明(Helpで表示)複数の場合はカンマで区切る   */ 
0063:   }; 
0064:  
0065: /*----------------------------------------------------------------------------*/ 
0066: /* 選択範囲                                                                   */ 
0067: /*----------------------------------------------------------------------------*/ 
0068:   MssOptRNG optRNG={ 
0069:     ORNG,   /* オプションタイプ                                             */ 
0070:     "R",    /* キーワード(複数文字は不可)                                   */ 
0071:     1,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0072:     NULL,   /* デフォルト(文字列として指定する)                             */ 
0073:     50,     /* カンマで区切られる要素数の最大値                             */ 
0074:     0,      /* 値の最小値                                                   */ 
0075:     INT_MAX,/* 値の最大値                                                   */ 
0076:     RNGT,   /* このオプションのタイトル(Helpで表示)                         */ 
0077:     RNGC    /* このオプションのコメント(Helpで表示)                         */ 
0078:   }; 
0079:  
0080: /*----------------------------------------------------------------------------*/ 
0081: /* 範囲逆転フラグ                                                             */ 
0082: /*----------------------------------------------------------------------------*/ 
0083:   MssOptFLG optREV={ 
0084:     OFLG,   /* オプションタイプ                                             */ 
0085:     "r",    /* キーワード(複数文字は不可)                                   */ 
0086:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0087:     REVT,   /* このオプションのタイトル(Helpで表示)                         */ 
0088:     REVC    /* このオプションのコメント(Helpで表示)                         */ 
0089:   }; 
0090:  
0091: /*----------------------------------------------------------------------------*/ 
0092: /* 範囲外出力ファイル                                                         */ 
0093: /*----------------------------------------------------------------------------*/ 
0094:   MssOptOTF optNOF={ 
0095:     OOTF,   /* オプションタイプ                                             */ 
0096:     "u",    /* キーワード(複数文字は不可)                                   */ 
0097:     0,      /* 0:オプション, 1:必須                                         */ 
0098:     NOFT,   /* このオプションのタイトル(Helpで表示)                         */ 
0099:     NOFC    /* このオプションのコメント(Helpで表示)                         */ 
0100:   }; 
0101:  
0102: /*----------------------------------------------------------------------------*/ 
0103: /* シーケンシャル処理                                                         */ 
0104: /*----------------------------------------------------------------------------*/ 
0105:   MssOptFLG optSEQ={ 
0106:     OFLG,   /* オプションタイプ                                             */ 
0107:     "q",    /* キーワード(複数文字は不可)                                   */ 
0108:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0109:     SEQT,   /* このオプションのタイトル(Helpで表示)                         */ 
0110:     SEQC    /* このオプションのコメント(Helpで表示)                         */ 
0111:   }; 
0112:  
0113: /*----------------------------------------------------------------------------*/ 
0114: /* 入力ファイル                                                               */ 
0115: /*----------------------------------------------------------------------------*/ 
0116:   MssOptINF optINF={ 
0117:     OINF,   /* オプションタイプ                                             */ 
0118:     "i",    /* キーワード(複数文字は不可)                                   */ 
0119:     0,      /* 0:オプション, 1:必須                                         */ 
0120:     1,      /* 指定可能の最大ファイル数                                     */ 
0121:     0,      /*1:file not foundのエラーで終了しない 0:する                   */ 
0122:     INFT,   /* このオプションのタイトル(Helpで表示)                         */ 
0123:     INFC    /* このオプションのコメント(Helpで表示)                         */ 
0124:   }; 
0125:  
0126: /*----------------------------------------------------------------------------*/ 
0127: /* 出力ファイル                                                               */ 
0128: /*----------------------------------------------------------------------------*/ 
0129:   MssOptOTF optOTF={ 
0130:     OOTF,   /* オプションタイプ                                             */ 
0131:     "o",    /* キーワード(複数文字は不可)                                   */ 
0132:     0,      /* 0:オプション, 1:必須                                         */ 
0133:     OTFT,   /* このオプションのタイトル(Helpで表示)                         */ 
0134:     OTFC    /* このオプションのコメント(Helpで表示)                         */ 
0135:   }; 
0136:  
0137: /*----------------------------------------------------------------------------*/ 
0138: /* 圧縮出力                                                                   */ 
0139: /*----------------------------------------------------------------------------*/ 
0140:   MssOptFLG optZIP={ 
0141:     OFLG,   /* オプションタイプ                                             */ 
0142:     "z",    /* キーワード(複数文字は不可)                                   */ 
0143:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0144:     ZIPT,   /* このオプションのタイトル(Helpで表示)                         */ 
0145:     ZIPC    /* このオプションのコメント(Helpで表示)                         */ 
0146:   }; 
0147:  
0148: /*----------------------------------------------------------------------------*/ 
0149: /* plain text                                                                 */ 
0150: /*----------------------------------------------------------------------------*/ 
0151:   MssOptFLG optTXT={ 
0152:     OFLG,   /* オプションタイプ                                             */ 
0153:     "t",    /* キーワード(複数文字は不可)                                   */ 
0154:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0155:     TXTT,   /* このオプションのタイトル(Helpで表示)                         */ 
0156:     TXTC    /* このオプションのコメント(Helpで表示)                         */ 
0157:   }; 
0158:  
0159: /*----------------------------------------------------------------------------*/ 
0160: /* ワークファイル用ディレクトリ名                                             */ 
0161: /*----------------------------------------------------------------------------*/ 
0162:   MssOptSTR optTMP={ 
0163:     OSTR,   /* オプションタイプ                                             */ 
0164:     "T",    /* キーワード(複数文字は不可)                                   */ 
0165:     0,      /* 0:オプション, 1:必須                                         */ 
0166:     MssTempDir, /* デフォルト                                               */ 
0167:     1,      /* 文字列の最小長                                               */ 
0168:     MssFileNameMaxLen,  /* 文字列の最大長                                   */ 
0169:     TMPT,   /* このオプションのタイトル(Helpで表示)                         */ 
0170:     TMPC    /* このオプションのコメント(Helpで表示)                         */ 
0171:   }; 
0172:  
0173: /*----------------------------------------------------------------------------*/ 
0174: /* オプションをまとめる                                                       */ 
0175: /*----------------------------------------------------------------------------*/ 
0176:   void *opt[]={&optKEY,&optSRT,&optRNG,&optREV,&optNOF,&optSEQ, 
0177:                &optINF,&optOTF,&optZIP,&optTXT,&optTMP,NULL}; 
0178:  
0179: /*============================================================================*/ 
0180: /* 変数宣言&定義                                                             */ 
0181: /*============================================================================*/ 
0182:   struct mssHeader    *hdi;  /* 入力ファイル用<head>タグ格納構造体 */ 
0183:   struct mssHeader    *hdo;  /* 出力ファイル用<head>タグ格納構造体 */ 
0184:   struct mssFPR       *fpr;  /* 入力ファイル構造体                 */ 
0185:   struct mssFPW       *fpw;  /* 出力ファイル構造体                 */ 
0186:   struct mssFPW       *fpw2; /* 条件不一致出力ファイル構造体       */ 
0187:   struct mssFldRecDbl *frd;  /* 項目-二行バッファ構造体            */ 
0188:   struct mssFields    *sf;   /* ソート項目構造体                   */ 
0189:   int sorted;                /* ソート済チェック用                 */ 
0190:  
0191:   int count; 
0192:   int sel; 
0193:   int max; 
0194:   int i; 
0195:  
0196: /*----------------------------------------------------------------------------*/ 
0197: /* 前処理                                                                     */ 
0198: /*----------------------------------------------------------------------------*/ 
0199:   mssInit(argc,argv,&comHelp);       /* シグナル処理などの初期化              */ 
0200:   mssHelpDoc(opt,&comHelp,argc,argv);/* ヘルプ                                */ 
0201:   mssSetOption(opt,argc,argv);       /* コマンドオプションの設定              */ 
0202:   fpr=mssOpenFPR(optINF.str,4);      /* 入力ファイルオープン                  */ 
0203:   hdi=mssReadHeader(fpr);            /* ヘッダの読み込み                      */ 
0204:   mssSetOptKey(&optKEY, hdi);        /* オプション項目をヘッダー項目に関連づけ*/ 
0205:   mssSetOptFld(&optSRT, hdi);        /* オプション項目をヘッダー項目に関連づけ*/ 
0206:    
0207:   /*ソート項目の作成*/ 
0208:   sf=mssInitFields(); 
0209:   mssAddFieldsByFields(sf,optKEY.flds); /* -k 項目をソート項目としてセット    */ 
0210:   mssAddFieldsByFields(sf,optSRT.flds); /* -s 項目をソート項目としてセット    */ 
0211:   mssSetFieldsSortPriority(sf);         /* ソート優先順位番号を登録順にふる   */ 
0212:   sorted=mssChkSorted(sf,hdi);          /* ソート済かチェック                 */ 
0213:  
0214: /*mssShowFields(sf);*/ 
0215: /*mssShowOption(opt);*/                                                        
0216: /*mssShowHeader(hdi);*/ 
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 && (optKEY.set || optSRT.set) ) 
0250:     fpr=mssReopenFPRsort(fpr,4,sf,hdi->flds->cnt,optTMP.str); 
0251:  
0252:   frd=mssInitFRD(hdi->flds->cnt); 
0253:   count=0; 
0254:  
0255:   /*rangeのmax値を求める*/ 
0256:   max=-1; 
0257:   for(i=0; i<optRNG.cnt; i++){ 
0258:     if( max<*(optRNG.to+i) ) max=*(optRNG.to+i); 
0259:   } 
0260:  
0261:   while(EOF!=mssReadFRD(fpr,frd)){ 
0262:     /*キーブレイク時の処理*/ 
0263:     if(mssKeyBreak(frd, &optKEY)){ 
0264:       if(frd->eof) break; 
0265:       count=0; 
0266:     } 
0267:  
0268:     mssGV.inCnt++; 
0269:     count++; 
0270:  
0271:     /*-kの指定が無く、rangeのmaxを超えたらbreak*/ 
0272:     if(!optKEY.set){ 
0273:       if(count > max && !optNOF.set && !optREV.set) break; 
0274:     } 
0275:  
0276:     /*通常行の処理(集計値の計算)*/ 
0277:     if(optREV.set) sel = ! mssIsInRange(&optRNG,count); 
0278:     else           sel =   mssIsInRange(&optRNG,count); 
0279:  
0280:     if(sel){ 
0281:       mssWriteFld(frd->pnt[frd->new],frd->fldCnt,"\n",fpw); 
0282:       mssGV.outCnt++; 
0283:     }else{ 
0284:       if(optNOF.set){ 
0285:         mssWriteFld(frd->pnt[frd->new],frd->fldCnt,"\n",fpw2); 
0286:       } 
0287:     } 
0288:   } 
0289:   mssFreeFRD(frd); 
0290:  
0291: /*----------------------------------------------------------------------------*/ 
0292: /*フッター出力&終了処理                                                       */ 
0293: /*----------------------------------------------------------------------------*/ 
0294: /*printf("allocCnt=%d\n",getAllocCnt());*/ 
0295:   mssWriteFooter(fpw);    /*フッターの出力              */ 
0296:   mssWriteFooter(fpw2);   /*フッターの出力              */ 
0297:   mssCloseFPW(fpw2);      /*出力ファイルのクローズ      */ 
0298:   mssCloseFPR(fpr);       /*入力ファイルのクローズ      */ 
0299:   mssCloseFPW(fpw);       /*出力ファイルのクローズ      */ 
0300:   mssFreeFields(sf);      /* ソート項目構造体の領域開放 */ 
0301:   mssFreeHeader(hdi);     /* 入力ヘッダ領域開放         */ 
0302:   mssFreeHeader(hdo);     /* 出力ヘッダ領域開放         */ 
0303:   mssFreeOption(opt);     /* オプション領域開放         */ 
0304:   mssShowEndMsg();        /* 完了メッセージ             */ 
0305:   mssEnd(mssExitSuccess); /* 終了                       */ 
0306:   return(0);              /* to avoid warning message   */ 
0307: }