MUSASHI C source: xtuniq.c
0001: /*============================================================================*/
0002: /* 変更履歴 */
0003: /*----------------------------------------------------------------------------*/
0004: /* 1.0 : 新しいAPIに対応(2003/06) */
0005: /*============================================================================*/
0006:
0007: #include <musashi.h>
0008: #include <mssUniq.h>
0009: #include <stdlib.h>
0010:
0011: #include <xtuniqHelp.h>
0012: struct mssComHelp comHelp={
0013: "xtuniq", /* コマンド名 */
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: MssOptKEY optKEY={
0031: OKEY, /* オプションタイプ */
0032: "k", /* キーワード(複数文字は不可) */
0033: 0, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0034: MssFieldMaxCnt, /* 指定可能な最大項目数 */
0035: "i", /* 対象とする入力データのキーワード(GUIで利用) */
0036: 2, /* デフォルト(このオプションが指定されなかったときの動作を指定) */
0037: /* 1:全ての行を異るキー値として扱う */
0038: /* 2:全ての行を同じキー値として扱う) */
0039: KEYT, /* このオプションのタイトル(Helpで表示) */
0040: KEYC /* このオプションのコメント(Helpで表示) */
0041: };
0042:
0043: /*----------------------------------------------------------------------------*/
0044: /* シーケンシャル処理 */
0045: /*----------------------------------------------------------------------------*/
0046: MssOptFLG optSEQ={
0047: OFLG, /* オプションタイプ */
0048: "q", /* キーワード(複数文字は不可) */
0049: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0050: SEQT, /* このオプションのタイトル(Helpで表示) */
0051: SEQC /* このオプションのコメント(Helpで表示) */
0052: };
0053:
0054: /*----------------------------------------------------------------------------*/
0055: /* 入力ファイル */
0056: /*----------------------------------------------------------------------------*/
0057: MssOptINF optINF={
0058: OINF, /* オプションタイプ */
0059: "i", /* キーワード(複数文字は不可) */
0060: 0, /* 0:オプション, 1:必須 */
0061: 1, /* 指定可能の最大ファイル数 */
0062: 0, /*1:file not foundのエラーで終了しない 0:する */
0063: INFT, /* このオプションのタイトル(Helpで表示) */
0064: INFC /* このオプションのコメント(Helpで表示) */
0065: };
0066:
0067: /*----------------------------------------------------------------------------*/
0068: /* 出力ファイル */
0069: /*----------------------------------------------------------------------------*/
0070: MssOptOTF optOTF={
0071: OOTF, /* オプションタイプ */
0072: "o", /* キーワード(複数文字は不可) */
0073: 0, /* 0:オプション, 1:必須 */
0074: OTFT, /* このオプションのタイトル(Helpで表示) */
0075: OTFC /* このオプションのコメント(Helpで表示) */
0076: };
0077:
0078: /*----------------------------------------------------------------------------*/
0079: /* 圧縮出力 */
0080: /*----------------------------------------------------------------------------*/
0081: MssOptFLG optZIP={
0082: OFLG, /* オプションタイプ */
0083: "z", /* キーワード(複数文字は不可) */
0084: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0085: ZIPT, /* このオプションのタイトル(Helpで表示) */
0086: ZIPC /* このオプションのコメント(Helpで表示) */
0087: };
0088:
0089: /*----------------------------------------------------------------------------*/
0090: /* plain text */
0091: /*----------------------------------------------------------------------------*/
0092: MssOptFLG optTXT={
0093: OFLG, /* オプションタイプ */
0094: "t", /* キーワード(複数文字は不可) */
0095: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0096: TXTT, /* このオプションのタイトル(Helpで表示) */
0097: TXTC /* このオプションのコメント(Helpで表示) */
0098: };
0099:
0100: /*----------------------------------------------------------------------------*/
0101: /* ワークファイル用ディレクトリ名 */
0102: /*----------------------------------------------------------------------------*/
0103: MssOptSTR optTMP={
0104: OSTR, /* オプションタイプ */
0105: "T", /* キーワード(複数文字は不可) */
0106: 0, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0107: MssTempDir, /* デフォルト */
0108: 1, /* 文字列の最小長 */
0109: MssFileNameMaxLen, /* 文字列の最大長 */
0110: TMPT, /* このオプションのタイトル(Helpで表示) */
0111: TMPC /* このオプションのコメント(Helpで表示) */
0112: };
0113:
0114: /*----------------------------------------------------------------------------*/
0115: /* オプションをまとめる */
0116: /*----------------------------------------------------------------------------*/
0117: void *opt[]={&optKEY,&optSEQ,
0118: &optINF,&optOTF,&optZIP,&optTXT,&optTMP,NULL};
0119:
0120: /*============================================================================*/
0121: /* 変数宣言&定義 */
0122: /*============================================================================*/
0123: struct mssHeader *hdi; /*入力ファイル用<head>タグ格納構造体*/
0124: struct mssHeader *hdo; /*出力ファイル用<head>タグ格納構造体*/
0125: struct mssFPR *fpr; /*入力ファイル構造体 */
0126: struct mssFPW *fpw; /*出力ファイル構造体 */
0127: struct mssFields *sf ; /*キー項目構造体 */
0128: struct mssFldRecDbl *frd; /*項目-二行バッファ構造体 */
0129: struct mssUnqDat *ud; /*集計計算用の構造体 */
0130:
0131: int sorted;
0132:
0133: /*----------------------------------------------------------------------------*/
0134: /* 前処理 */
0135: /*----------------------------------------------------------------------------*/
0136: mssInit(argc,argv,&comHelp); /* シグナル処理などの初期化 */
0137: mssHelpDoc(opt,&comHelp,argc,argv);/* ヘルプ */
0138: mssSetOption(opt,argc,argv); /* コマンドオプションの設定 */
0139: fpr=mssOpenFPR(optINF.str,4);/* 入力ファイルオープン */
0140: hdi=mssReadHeader(fpr); /* ヘッダの読み込み */
0141: mssSetOptKey(&optKEY,hdi); /* 項目パラメータの設定 */
0142:
0143: /*ソート項目の作成*/
0144: sf=mssInitFields();
0145: mssAddFieldsByFields(sf,optKEY.flds);
0146:
0147: sorted=mssChkSorted(sf,hdi); /* ソート済かチェック */
0148:
0149: /*----------------------------------------------------------------------------*/
0150: /*出力ヘッダーの作成と出力 */
0151: /*----------------------------------------------------------------------------*/
0152: /*出力ヘッダーの初期化(タイトル等のコピー)*/
0153: hdo=mssInitCpyHeader(hdi);
0154:
0155: if(!optSEQ.set && !sorted){
0156: mssAddFieldsByFields(hdo->flds,hdi->flds); /*入力ヘッダの全項目を追加*/
0157: mssSetFieldsSort(hdo->flds,sf); /*sfによるソート情報の設定*/
0158: }else{
0159: mssAddFieldsByFields(hdo->flds,hdi->flds); /*入力ヘッダの全項目を追加*/
0160: }
0161:
0162: /*標準出力オープン+ヘッダーの出力*/
0163: fpw=mssOpenFPW(optOTF.str,optZIP.set,0);
0164: mssWriteHeader(hdo, fpw);
0165:
0166: /*----------------------------------------------------------------------------*/
0167: /*メインルーチン */
0168: /*----------------------------------------------------------------------------*/
0169:
0170: ud=mssInitUnqDat(hdi->flds->cnt,&optKEY,optTMP.str,&mssGV.inCnt);
0171:
0172: /*シーケンシャル集計フラグがOffかつソート済みでなければ*/
0173: if( !optSEQ.set && !sorted){
0174: ud->procType=1;
0175: mssPreUnq(ud, fpr);
0176: while( EOF != mssReadWriteUnq(ud, fpw) ) mssGV.outCnt++;
0177:
0178: /*キーブレーク処理*/
0179: }else{
0180: ud->procType=0;
0181: frd=mssInitFRD(hdi->flds->cnt);
0182: while( EOF!=mssReadFRD(fpr,frd) ){
0183:
0184: /*キーブレイク時の処理*/
0185: if(mssKeyBreak(frd, &optKEY)){
0186: /*一行書き出し*/
0187: mssWriteFld(frd->pnt[frd->old],frd->fldCnt,"\n",fpw);
0188: mssGV.outCnt++;
0189: if(frd->eof) break;
0190: }
0191: mssGV.inCnt++;
0192: }
0193: mssFreeFRD(frd);
0194: }
0195: mssFreeUnqDat(ud);
0196:
0197: /*----------------------------------------------------------------------------*/
0198: /*フッター出力&終了処理 */
0199: /*----------------------------------------------------------------------------*/
0200: mssWriteFooter(fpw); /*フッターの出力*/
0201: mssCloseFPR(fpr); /*入力ファイルのクローズ*/
0202: mssCloseFPW(fpw); /*出力ファイルのクローズ*/
0203: mssFreeFields(sf); /*ソート項目構造体の領域開放*/
0204: mssFreeHeader(hdi); /*入力ヘッダ領域開放*/
0205: mssFreeHeader(hdo); /*出力ヘッダ領域開放*/
0206: mssFreeOption(opt); /*オプション領域開放*/
0207: mssShowEndMsg(); /*完了メッセージ*/
0208: mssEnd(mssExitSuccess); /*終了*/
0209: return(0); /* to avoid warning message*/
0210: }