MUSASHI C source: xtagg.c
0001:
0002: /*============================================================================*/
0003: /* 変更履歴 */
0004: /*----------------------------------------------------------------------------*/
0005: /* 1.0 : 新しいAPIに対応 2003/06/20 */
0006: /*============================================================================*/
0007:
0008: #include <musashi.h>
0009: #include <mssAgg.h>
0010: #include <stdlib.h>
0011:
0012: #include <xtaggHelp.h>
0013: struct mssComHelp comHelp={
0014: "xtagg", /* コマンド名 */
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 optFLD={
0051: OFLD, /* オプションタイプ */
0052: "f", /* キーワード(複数文字は不可) */
0053: 1, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0054: MssFieldMaxCnt, /* 指定可能な最大項目数 */
0055: "i", /* 対象とする入力データのキーワード(GUIで利用) */
0056: 1, /* 正規表現を許可するかどうか(0:不可,1:可) */
0057: 1, /* 新項目名を指定できるかどうか(0:不可,1:可) */
0058: NULL, /* 項目オプション(%以下)で指定可能な文字 */
0059: /* ex) 指定不可の場合はNULL, "nr": "-f 項目名%rn"の指定可能 */
0060: FLDT, /* このオプションのタイトル(Helpで表示) */
0061: FLDC, /* このオプションのコメント(Helpで表示) */
0062: FLDF /* フラグについての説明(Helpで表示)複数の場合はカンマで区切る */
0063: };
0064:
0065: /*----------------------------------------------------------------------------*/
0066: /* 集計方法 */
0067: /*----------------------------------------------------------------------------*/
0068: MssOptSEL optCAL={
0069: OSEL, /* オプションタイプ */
0070: "c", /* キーワード(複数文字は不可) */
0071: 1, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0072: NULL, /* デフォルト(文字列にて) */
0073: "sum,avg,max,min,cnt",
0074: /* 指定可能な値リスト */
0075: CALT, /* このオプションのタイトル(Helpで表示) */
0076: CALC, /* このオプションのコメント(Helpで表示) */
0077: CALS /* フラグについての説明(Helpで表示)複数の場合はカンマで区切る */
0078: };
0079:
0080: /*----------------------------------------------------------------------------*/
0081: /* シーケンシャル処理 */
0082: /*----------------------------------------------------------------------------*/
0083: MssOptFLG optSEQ={
0084: OFLG, /* オプションタイプ */
0085: "q", /* キーワード(複数文字は不可) */
0086: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0087: SEQT, /* このオプションのタイトル(Helpで表示) */
0088: SEQC /* このオプションのコメント(Helpで表示) */
0089: };
0090:
0091: /*----------------------------------------------------------------------------*/
0092: /* 入力ファイル */
0093: /*----------------------------------------------------------------------------*/
0094: MssOptINF optINF={
0095: OINF, /* オプションタイプ */
0096: "i", /* キーワード(複数文字は不可) */
0097: 0, /* 0:オプション, 1:必須 */
0098: 1, /* 指定可能の最大ファイル数 */
0099: 0, /*1:file not foundのエラーで終了しない 0:する */
0100: INFT, /* このオプションのタイトル(Helpで表示) */
0101: INFC /* このオプションのコメント(Helpで表示) */
0102: };
0103:
0104: /*----------------------------------------------------------------------------*/
0105: /* 出力ファイル */
0106: /*----------------------------------------------------------------------------*/
0107: MssOptOTF optOTF={
0108: OOTF, /* オプションタイプ */
0109: "o", /* キーワード(複数文字は不可) */
0110: 0, /* 0:オプション, 1:必須 */
0111: OTFT, /* このオプションのタイトル(Helpで表示) */
0112: OTFC /* このオプションのコメント(Helpで表示) */
0113: };
0114:
0115: /*----------------------------------------------------------------------------*/
0116: /* 圧縮出力 */
0117: /*----------------------------------------------------------------------------*/
0118: MssOptFLG optZIP={
0119: OFLG, /* オプションタイプ */
0120: "z", /* キーワード(複数文字は不可) */
0121: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0122: ZIPT, /* このオプションのタイトル(Helpで表示) */
0123: ZIPC /* このオプションのコメント(Helpで表示) */
0124: };
0125:
0126: /*----------------------------------------------------------------------------*/
0127: /* plain text */
0128: /*----------------------------------------------------------------------------*/
0129: MssOptFLG optTXT={
0130: OFLG, /* オプションタイプ */
0131: "t", /* キーワード(複数文字は不可) */
0132: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0133: TXTT, /* このオプションのタイトル(Helpで表示) */
0134: TXTC /* このオプションのコメント(Helpで表示) */
0135: };
0136:
0137: /*----------------------------------------------------------------------------*/
0138: /* ワークファイル用ディレクトリ名 */
0139: /*----------------------------------------------------------------------------*/
0140: MssOptSTR optTMP={
0141: OSTR, /* オプションタイプ */
0142: "T", /* キーワード(複数文字は不可) */
0143: 0, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0144: MssTempDir, /* デフォルト */
0145: 1, /* 文字列の最小長 */
0146: MssFileNameMaxLen, /* 文字列の最大長 */
0147: TMPT, /* このオプションのタイトル(Helpで表示) */
0148: TMPC /* このオプションのコメント(Helpで表示) */
0149: };
0150:
0151: /*----------------------------------------------------------------------------*/
0152: /* オプションをまとめる */
0153: /*----------------------------------------------------------------------------*/
0154: void *opt[]={&optKEY,&optFLD,&optCAL,&optSEQ,
0155: &optINF,&optOTF,&optZIP,&optTXT,&optTMP,NULL};
0156:
0157: /*============================================================================*/
0158: /* 変数宣言&定義 */
0159: /*============================================================================*/
0160: struct mssHeader *hdi; /*入力ファイル用<head>タグ格納構造体*/
0161: struct mssHeader *hdo; /*出力ファイル用<head>タグ格納構造体*/
0162: struct mssFPR *fpr; /*入力ファイル構造体 */
0163: struct mssFPW *fpw; /*出力ファイル構造体 */
0164: struct mssFields *sf ; /*キー項目構造体 */
0165: struct mssFldRecDbl *frd; /*項目-二行バッファ構造体 */
0166: struct mssAggDat *ad; /*集計計算用の構造体 */
0167:
0168: int sorted;
0169:
0170: /*----------------------------------------------------------------------------*/
0171: /* 前処理 */
0172: /*----------------------------------------------------------------------------*/
0173: mssInit(argc,argv,&comHelp); /* シグナル処理などの初期化 */
0174: mssHelpDoc(opt,&comHelp,argc,argv);/* ヘルプ */
0175: mssSetOption(opt,argc,argv); /* コマンドオプションの設定 */
0176: fpr=mssOpenFPR(optINF.str,4); /* 入力ファイルオープン */
0177: hdi=mssReadHeader(fpr); /* ヘッダの読み込み */
0178: mssSetOptKey(&optKEY, hdi); /* -k 項目をヘッダー項目に関連づける */
0179: mssSetOptFld(&optFLD, hdi); /* -f 項目をヘッダー項目に関連づける */
0180:
0181: /*ソート項目の作成*/
0182: sf=mssInitFields();
0183: mssAddFieldsByFields(sf,optKEY.flds); /* -k 項目をソート項目としてセット */
0184: sorted=mssChkSorted(sf,hdi); /* ソート済かチェック */
0185:
0186: /*mssShowFields(sf);*/
0187: /*mssShowHeader(hdi);*/
0188:
0189: /*----------------------------------------------------------------------------*/
0190: /*出力ヘッダーの作成と出力 */
0191: /*----------------------------------------------------------------------------*/
0192: /*出力ヘッダーの初期化(タイトル等のコピー)*/
0193: hdo=mssInitCpyHeader(hdi);
0194:
0195: /*-fで指定された項目は-fから、その他は入力ヘッダから項目を追加する*/
0196: mssAddHeadOrOptFields(hdo->flds,hdi,&optFLD);
0197:
0198: /*ソートする必要があるならばsfのソート情報を反映*/
0199: if(!optSEQ.set && !sorted){
0200: mssSetFieldsSort(hdo->flds,sf);
0201: }
0202:
0203: /*標準出力オープン+ヘッダーの出力*/
0204: fpw=mssOpenFPW(optOTF.str,optZIP.set,0);
0205: mssWriteHeader(hdo, fpw);
0206:
0207: /*----------------------------------------------------------------------------*/
0208: /*メインルーチン */
0209: /*----------------------------------------------------------------------------*/
0210: /* 集計用構造体の初期化 */
0211: ad=mssInitAggDat(hdi->flds->cnt,&optKEY,&optFLD,optCAL.str,optTMP.str,&mssGV.inCnt);
0212:
0213: /*シーケンシャル集計フラグがOffかつソート済みでなければ*/
0214: if( !optSEQ.set && !sorted){
0215: ad->procType=1;
0216: mssPreAgg(ad, fpr);
0217: while( EOF != mssReadWriteAgg(ad, fpw) ) mssGV.outCnt++;
0218:
0219: /*シーケンシャル集計フラグがOnもしくはソート済みであれば*/
0220: }else{
0221: ad->procType=0;
0222: frd=mssInitFRD(hdi->flds->cnt);
0223: while( EOF!=mssReadFRD(fpr,frd) ){
0224:
0225: /*キーブレイク時の処理*/
0226: if(mssKeyBreak(frd, &optKEY)){
0227:
0228: /*一行書き出し*/
0229: mssWriteAggFld(frd->pnt[frd->old],ad->aggVal,ad->aggType,fpw);
0230: mssGV.outCnt++;
0231: if(frd->eof) break;
0232:
0233: /*集計値の初期化*/
0234: mssClearAggVal(ad->aggVal, ad->aggType, optFLD.flds->cnt);
0235: }
0236:
0237: mssGV.inCnt++;
0238:
0239: /* -fの項目の値をvalueとしてad->valにセットする*/
0240: mssSetAggVal(ad->val, frd->pnt[frd->new]);
0241:
0242: /* ad->valの値をad->aggValに反映(足し込みなど)する*/
0243: mssCalAggVal(ad->aggVal, ad->aggType, ad->val);
0244: }
0245: mssFreeFRD(frd);
0246: }
0247: mssFreeAggDat(ad);
0248:
0249: /*----------------------------------------------------------------------------*/
0250: /*フッター出力&終了処理 */
0251: /*----------------------------------------------------------------------------*/
0252: /*printf("allocCnt=%d\n",getAllocCnt());*/
0253: mssWriteFooter(fpw); /* フッターの出力 */
0254: mssCloseFPR(fpr); /* 入力ファイルのクローズ */
0255: mssCloseFPW(fpw); /* 出力ファイルのクローズ */
0256: mssFreeFields(sf); /* ソート項目構造体の領域開放 */
0257: mssFreeHeader(hdi); /* 入力ヘッダ領域開放 */
0258: mssFreeHeader(hdo); /* 出力ヘッダ領域開放 */
0259: mssFreeOption(opt); /* オプション領域開放 */
0260: mssShowEndMsg(); /* 完了メッセージ */
0261: mssEnd(mssExitSuccess); /* 終了 */
0262: return(0); /* to avoid warning message */
0263: }