MUSASHI C source: xtpattern.c
0001: /*============================================================================*/
0002: /* 変更履歴 */
0003: /*----------------------------------------------------------------------------*/
0004: /* 1.0 : 新しいAPIに対応 2003/06/20 */
0005: /*============================================================================*/
0006:
0007: #include <musashi.h>
0008: #include <stdlib.h>
0009: #include <string.h>
0010:
0011: #include <xtpatternHelp.h>
0012: struct mssComHelp comHelp={
0013: "xtpattern", /* コマンド名 */
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: /*----------------------------------------------------------------------------*/
0031: /* キー項目 */
0032: /*----------------------------------------------------------------------------*/
0033: MssOptKEY optKEY={
0034: OKEY, /* オプションタイプ */
0035: "k", /* キーワード(複数文字は不可) */
0036: 0, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0037: MssFieldMaxCnt, /* 指定可能な最大項目数 */
0038: "i", /* 対象とする入力データのキーワード(GUIで利用) */
0039: 2, /* デフォルト(このオプションが指定されなかったときの動作を指定) */
0040: /* 1:全ての行を異るキー値として扱う */
0041: /* 2:全ての行を同じキー値として扱う) */
0042: KEYT, /* このオプションのタイトル(Helpで表示) */
0043: KEYC /* このオプションのコメント(Helpで表示) */
0044: };
0045:
0046: /*----------------------------------------------------------------------------*/
0047: /* ソート項目 */
0048: /*----------------------------------------------------------------------------*/
0049: MssOptFLD optSRT={
0050: OFLD, /* オプションタイプ */
0051: "s", /* キーワード(複数文字は不可) */
0052: 0, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0053: MssFieldMaxCnt, /* 指定可能な最大項目数 */
0054: "i", /* 対象とする入力データのキーワード(GUIで利用) */
0055: 0, /* 正規表現を許可するかどうか(0:不可,1:可) */
0056: 0, /* 新項目名を指定できるかどうか(0:不可,1:可) */
0057: "n,r", /* 項目オプション(%以下)で指定可能な文字 */
0058: /* ex) 指定不可の場合はNULL, "nr": "-f 項目名%rn"の指定可能 */
0059: SRTT, /* このオプションのタイトル(Helpで表示) */
0060: SRTC, /* このオプションのコメント(Helpで表示) */
0061: SRTF /* フラグについての説明(Helpで表示)複数の場合はカンマで区切る */
0062: };
0063:
0064: /*----------------------------------------------------------------------------*/
0065: /* 集計項目 */
0066: /*----------------------------------------------------------------------------*/
0067: MssOptFLD optFLD={
0068: OFLD, /* オプションタイプ */
0069: "f", /* キーワード(複数文字は不可) */
0070: 1, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0071: MssFieldMaxCnt, /* 指定可能な最大項目数 */
0072: "i", /* 対象とする入力データのキーワード(GUIで利用) */
0073: 1, /* 正規表現を許可するかどうか(0:不可,1:可) */
0074: 1, /* 新項目名を指定できるかどうか(0:不可,1:可) */
0075: NULL, /* 項目オプション(%以下)で指定可能な文字 */
0076: /* ex) 指定不可の場合はNULL, "nr": "-f 項目名%rn"の指定可能 */
0077: FLDT, /* このオプションのタイトル(Helpで表示) */
0078: FLDC, /* このオプションのコメント(Helpで表示) */
0079: FLDF /* フラグについての説明(Helpで表示)複数の場合はカンマで区切る */
0080: };
0081:
0082: /*----------------------------------------------------------------------------*/
0083: /* デリミタ */
0084: /*----------------------------------------------------------------------------*/
0085: MssOptSTR optDLM={
0086: OSTR, /* オプションタイプ */
0087: "d", /* キーワード(複数文字は不可) */
0088: 0, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0089: "", /* デフォルト */
0090: 1, /* 文字列の最小長 */
0091: 5, /* 文字列の最大長 */
0092: DLMT, /* このオプションのタイトル(Helpで表示) */
0093: DLMC /* このオプションのコメント(Helpで表示) */
0094: };
0095:
0096: /*----------------------------------------------------------------------------*/
0097: /* シーケンシャル処理 */
0098: /*----------------------------------------------------------------------------*/
0099: MssOptFLG optSEQ={
0100: OFLG, /* オプションタイプ */
0101: "q", /* キーワード(複数文字は不可) */
0102: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0103: SEQT, /* このオプションのタイトル(Helpで表示) */
0104: SEQC /* このオプションのコメント(Helpで表示) */
0105: };
0106:
0107: /*----------------------------------------------------------------------------*/
0108: /* 入力ファイル */
0109: /*----------------------------------------------------------------------------*/
0110: MssOptINF optINF={
0111: OINF, /* オプションタイプ */
0112: "i", /* キーワード(複数文字は不可) */
0113: 0, /* 0:オプション, 1:必須 */
0114: 1, /* 指定可能の最大ファイル数 */
0115: 0, /*1:file not foundのエラーで終了しない 0:する */
0116: INFT, /* このオプションのタイトル(Helpで表示) */
0117: INFC /* このオプションのコメント(Helpで表示) */
0118: };
0119:
0120: /*----------------------------------------------------------------------------*/
0121: /* 出力ファイル */
0122: /*----------------------------------------------------------------------------*/
0123: MssOptOTF optOTF={
0124: OOTF, /* オプションタイプ */
0125: "o", /* キーワード(複数文字は不可) */
0126: 0, /* 0:オプション, 1:必須 */
0127: OTFT, /* このオプションのタイトル(Helpで表示) */
0128: OTFC /* このオプションのコメント(Helpで表示) */
0129: };
0130:
0131: /*----------------------------------------------------------------------------*/
0132: /* 圧縮出力 */
0133: /*----------------------------------------------------------------------------*/
0134: MssOptFLG optZIP={
0135: OFLG, /* オプションタイプ */
0136: "z", /* キーワード(複数文字は不可) */
0137: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0138: ZIPT, /* このオプションのタイトル(Helpで表示) */
0139: ZIPC /* このオプションのコメント(Helpで表示) */
0140: };
0141:
0142: /*----------------------------------------------------------------------------*/
0143: /* plain text */
0144: /*----------------------------------------------------------------------------*/
0145: MssOptFLG optTXT={
0146: OFLG, /* オプションタイプ */
0147: "t", /* キーワード(複数文字は不可) */
0148: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0149: TXTT, /* このオプションのタイトル(Helpで表示) */
0150: TXTC /* このオプションのコメント(Helpで表示) */
0151: };
0152:
0153: /*----------------------------------------------------------------------------*/
0154: /* ワークファイル用ディレクトリ名 */
0155: /*----------------------------------------------------------------------------*/
0156: MssOptSTR optTMP={
0157: OSTR, /* オプションタイプ */
0158: "T", /* キーワード(複数文字は不可) */
0159: 0, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0160: MssTempDir, /* デフォルト */
0161: 1, /* 文字列の最小長 */
0162: MssFileNameMaxLen, /* 文字列の最大長 */
0163: TMPT, /* このオプションのタイトル(Helpで表示) */
0164: TMPC /* このオプションのコメント(Helpで表示) */
0165: };
0166:
0167: /*----------------------------------------------------------------------------*/
0168: /* オプションをまとめる */
0169: /*----------------------------------------------------------------------------*/
0170: void *opt[]={&optKEY,&optSRT,&optFLD,&optDLM,&optSEQ,
0171: &optINF,&optOTF,&optZIP,&optTXT,&optTMP,NULL};
0172:
0173: /*============================================================================*/
0174: /* 変数宣言&定義 */
0175: /*============================================================================*/
0176: struct mssHeader *hdi; /*入力ファイル用<head>タグ格納構造体*/
0177: struct mssHeader *hdo; /*出力ファイル用<head>タグ格納構造体*/
0178: struct mssFPR *fpr; /*入力ファイル構造体 */
0179: struct mssFPW *fpw; /*出力ファイル構造体 */
0180: struct mssFldRecDbl *frd; /*項目-二行バッファ構造体 */
0181: struct mssFields *sf; /*ソート項目構造体 */
0182: int sorted; /*ソート済チェック用 */
0183:
0184: struct mssStrings **buf;
0185: int keyCnt;
0186: int nulFlg[MssFieldMaxCnt];
0187: int output[MssFieldMaxCnt];
0188: int i;
0189: char *tmp;
0190:
0191: /*----------------------------------------------------------------------------*/
0192: /* 前処理 */
0193: /*----------------------------------------------------------------------------*/
0194: mssInit(argc,argv,&comHelp); /* シグナル処理などの初期化 */
0195: mssHelpDoc(opt,&comHelp,argc,argv);/* ヘルプ */
0196: mssSetOption(opt,argc,argv); /* コマンドオプションの設定 */
0197: fpr=mssOpenFPR(optINF.str,4); /* 入力ファイルオープン */
0198: hdi=mssReadHeader(fpr); /* ヘッダの読み込み */
0199: mssSetOptKey(&optKEY, hdi); /* -k 項目をヘッダー項目に関連づける */
0200: mssSetOptFld(&optSRT, hdi); /* -s 項目をヘッダー項目に関連づける */
0201: mssSetOptFld(&optFLD, hdi); /* -f 項目をヘッダー項目に関連づける */
0202:
0203: /*ソート項目の作成*/
0204: sf=mssInitFields();
0205: mssAddFieldsByFields(sf,optKEY.flds); /* -k 項目をソート項目としてセット */
0206: mssAddFieldsByFields(sf,optSRT.flds); /* -s 項目をソート項目としてセット */
0207: mssSetFieldsSortPriority(sf); /* ソート優先順位番号を登録順にふる */
0208: sorted=mssChkSorted(sf,hdi); /* ソート済かチェック */
0209:
0210: /*mssShowFields(sf);*/
0211: /*mssShowOption(opt);*/
0212: /*mssShowHeader(hdi);*/
0213:
0214: if(NULL!=strchr(optDLM.str,MssFieldDelim)){
0215: mssShowErrMsg("-d can not have a space character");
0216: mssEnd(mssErrorNoDefault);
0217: }
0218:
0219: /*----------------------------------------------------------------------------*/
0220: /*出力ヘッダーの作成と出力 */
0221: /*----------------------------------------------------------------------------*/
0222: /*出力ヘッダーの初期化(タイトル等のコピー)*/
0223: hdo=mssInitCpyHeader(hdi);
0224:
0225: /*入力ヘッダの全項目を追加*/
0226: mssAddFieldsByFields(hdo->flds,hdi->flds);
0227:
0228: /*新項目名を追加する*/
0229: mssAddFieldsByStrList(hdo->flds,optFLD.newNam,optFLD.cnt);
0230:
0231: /*ソートする必要があるならばsfのソート情報を反映*/
0232: if(!optSEQ.set && !sorted){
0233: mssSetFieldsSort(hdo->flds,sf);
0234: }
0235:
0236: /*標準出力オープン+ヘッダーの出力*/
0237: fpw=mssOpenFPW(optOTF.str,optZIP.set,0);
0238: mssWriteHeader(hdo, fpw);
0239:
0240: /*----------------------------------------------------------------------------*/
0241: /*メインルーチン */
0242: /*----------------------------------------------------------------------------*/
0243:
0244: /*初期化*/
0245: buf=mssMalloc(sizeof(struct mssStrings *)*optFLD.flds->cnt,"xtpattern");
0246: for(i=0; i<optFLD.flds->cnt; i++){
0247: *(buf+i)=mssInitStrings();
0248: nulFlg[i]=0;
0249: output[i]=0;
0250: }
0251:
0252: /*ソートが必用ならばソートしてソート済みファイルとしてオープン*/
0253: if(!optSEQ.set && !sorted)
0254: fpr=mssReopenFPRsort(fpr,4,sf,hdi->flds->cnt,optTMP.str);
0255:
0256: frd=mssInitFRD(hdi->flds->cnt);
0257: keyCnt=0;
0258: while(EOF!=mssReadFRD(fpr,frd)){
0259: mssGV.inCnt++;
0260:
0261: /*キーブレイク時の処理*/
0262: if(mssKeyBreak(frd, &optKEY)){
0263: mssWriteFld(frd->pnt[frd->old],frd->fldCnt,"",fpw);
0264: for(i=0; i<optFLD.flds->cnt; i++){
0265: mssWriteDlm(fpw);
0266: if(nulFlg[i] || !output[i])mssWriteNull(fpw);
0267: else mssWriteStr((*(buf+i))->str,fpw);
0268: }
0269: mssWriteRet(fpw);
0270: mssGV.outCnt++;
0271: if(frd->eof) break;
0272: keyCnt=0;
0273: for(i=0; i<optFLD.flds->cnt; i++){
0274: mssFreeStrings(*(buf+i));
0275: *(buf+i)=mssInitStrings();
0276: nulFlg[i]=0;
0277: output[i]=0;
0278: }
0279: }
0280:
0281: /*通常行の処理(-fの項目値とdelimiterをcatする)*/
0282: for(i=0; i<optFLD.flds->cnt; i++){
0283: if(!nulFlg[i]){
0284: tmp=*(frd->pnt[frd->new]+MssFlds2num(optFLD.flds,i));
0285: if( !MssIsNull(tmp) ){
0286: if(output[i]){
0287: mssCatStrings(*(buf+i),optDLM.str);
0288: }
0289: mssCatStrings(*(buf+i),tmp);
0290: output[i]=1;
0291: }
0292: if((*(buf+i))->cnt>=MssFieldMaxLen) nulFlg[i]=1;
0293: }
0294: }
0295: keyCnt++;
0296: }
0297: mssFreeFRD(frd);
0298: for(i=0; i<optFLD.flds->cnt; i++) mssFreeStrings(*(buf+i));
0299: mssFree(buf);
0300:
0301: /*----------------------------------------------------------------------------*/
0302: /*フッター出力&終了処理 */
0303: /*----------------------------------------------------------------------------*/
0304: mssWriteFooter(fpw); /* フッターの出力 */
0305: mssCloseFPR(fpr); /* 入力ファイルのクローズ */
0306: mssCloseFPW(fpw); /* 出力ファイルのクローズ */
0307: mssFreeFields(sf); /* ソート項目構造体の領域開放 */
0308: mssFreeHeader(hdi); /* 入力ヘッダ領域開放 */
0309: mssFreeHeader(hdo); /* 出力ヘッダ領域開放 */
0310: mssFreeOption(opt); /* オプション領域開放 */
0311: mssShowEndMsg(); /* 完了メッセージ */
0312: mssEnd(mssExitSuccess); /* 終了 */
0313: return(0); /* to avoid warning message */
0314: }