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: }