MUSASHI C source: xtselstr.c
0001: /*============================================================================*/
0002: /* 変更履歴 */
0003: /*----------------------------------------------------------------------------*/
0004: /* 1.0 : 新しいAPIに対応 2003/06/20 */
0005: /*============================================================================*/
0006:
0007: #include <musashi.h>
0008: #include <stdlib.h>
0009:
0010: #include <xtselstrHelp.h>
0011: struct mssComHelp comHelp={
0012: "xtselstr", /* コマンド名 */
0013: "1.0", /* バージョン */
0014: HELPT, /* コマンドタイトル */
0015: HELPS, /* 要約 */
0016: HELPE, /* 利用例 */
0017: HELPR, /* 参照コマンド */
0018: HELPA, /* 作者情報 */
0019: HELPB, /* バグレポート情報 */
0020: HELPH /* ホームページ */
0021: };
0022:
0023: extern struct mssGlobalVariables mssGV;
0024:
0025: int REV; /*条件反転フラグ*/
0026: int AND; /*項目間andフラグ*/
0027:
0028: int sel(char **pnt, struct mssFields *fld, struct mssHash *hash){
0029: int sel=0;
0030: char *str;
0031: int i;
0032:
0033: for(i=0; i<fld->cnt; i++){
0034: str=*(pnt+MssFlds2num(fld,i));
0035: if( REV ){
0036: if( AND ){
0037: if( mssHashMember(hash,str) ){sel=0; continue;}
0038: else {sel=1; break ;}
0039: }else{
0040: if( mssHashMember(hash,str) ){sel=0; break ;}
0041: else {sel=1; continue;}
0042: }
0043: }else{
0044: if( AND ){
0045: if( mssHashMember(hash,str) ){sel=1; continue;}
0046: else {sel=0; break ;}
0047: }else{
0048: if( mssHashMember(hash,str) ){sel=1; break ;}
0049: else {sel=0; continue;}
0050: }
0051: }
0052: }
0053: return(sel);
0054: }
0055:
0056: int main(int argc, char *argv[]){
0057: /*============================================================================*/
0058: /* オプション宣言&定義 */
0059: /*============================================================================*/
0060: /*----------------------------------------------------------------------------*/
0061: /* キー項目 */
0062: /*----------------------------------------------------------------------------*/
0063: MssOptKEY optKEY={
0064: OKEY, /* オプションタイプ */
0065: "k", /* キーワード(複数文字は不可) */
0066: 0, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0067: MssFieldMaxCnt, /* 指定可能な最大項目数 */
0068: "i", /* 対象とする入力データのキーワード(GUIで利用) */
0069: 1, /* デフォルト(このオプションが指定されなかったときの動作を指定) */
0070: /* 1:全ての行を異るキー値として扱う */
0071: /* 2:全ての行を同じキー値として扱う) */
0072: KEYT, /* このオプションのタイトル(Helpで表示) */
0073: KEYC /* このオプションのコメント(Helpで表示) */
0074: };
0075:
0076: /*----------------------------------------------------------------------------*/
0077: /* 対象項目 */
0078: /*----------------------------------------------------------------------------*/
0079: MssOptFLD optFLD={
0080: OFLD, /* オプションタイプ */
0081: "f", /* キーワード(複数文字は不可) */
0082: 1, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0083: MssFieldMaxCnt, /* 指定可能な最大項目数 */
0084: "i", /* 対象とする入力データのキーワード(GUIで利用) */
0085: 1, /* 正規表現を許可するかどうか(0:不可,1:可) */
0086: 0, /* 新項目名を指定できるかどうか(0:不可,1:可) */
0087: NULL, /* 項目オプション(%以下)で指定可能な文字 */
0088: /* ex) 指定不可の場合はNULL, "nr": "-f 項目名%rn"の指定可能 */
0089: FLDT, /* このオプションのタイトル(Helpで表示) */
0090: FLDC, /* このオプションのコメント(Helpで表示) */
0091: FLDF /* フラグについての説明(Helpで表示)複数の場合はカンマで区切る */
0092: };
0093:
0094: /*----------------------------------------------------------------------------*/
0095: /* 検索文字列リスト */
0096: /*----------------------------------------------------------------------------*/
0097: MssOptSLS optVAL={
0098: OSLS, /* オプションタイプ */
0099: "v", /* キーワード(複数文字は不可) */
0100: 1, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0101: NULL, /* デフォルト(文字列) */
0102: 50, /* カンマで区切られる要素数の最大値 */
0103: 1, /* 各要素の文字列長の最小値 */
0104: MssFieldMaxLen,/* 各要素の文字列長の最大値 */
0105: 0, /* 1:要素にコロンを指定できる,0:不可 ex) aaaa:xxxxx */
0106: VALT, /* このオプションのタイトル(Helpで表示) */
0107: VALC /* このオプションのコメント(Helpで表示) */
0108: };
0109:
0110: /*----------------------------------------------------------------------------*/
0111: /* 項目間ANDフラグ */
0112: /*----------------------------------------------------------------------------*/
0113: MssOptFLG optAND={
0114: OFLG, /* オプションタイプ */
0115: "F", /* キーワード(複数文字は不可) */
0116: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0117: ANDT, /* このオプションのタイトル(Helpで表示) */
0118: ANDC /* このオプションのコメント(Helpで表示) */
0119: };
0120:
0121: /*----------------------------------------------------------------------------*/
0122: /* レコード間ANDフラグ */
0123: /*----------------------------------------------------------------------------*/
0124: MssOptFLG optARC={
0125: OFLG, /* オプションタイプ */
0126: "R", /* キーワード(複数文字は不可) */
0127: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0128: ARCT, /* このオプションのタイトル(Helpで表示) */
0129: ARCC /* このオプションのコメント(Helpで表示) */
0130: };
0131:
0132: /*----------------------------------------------------------------------------*/
0133: /* 選択反転フラグ */
0134: /*----------------------------------------------------------------------------*/
0135: MssOptFLG optREV={
0136: OFLG, /* オプションタイプ */
0137: "r", /* キーワード(複数文字は不可) */
0138: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0139: REVT, /* このオプションのタイトル(Helpで表示) */
0140: REVC /* このオプションのコメント(Helpで表示) */
0141: };
0142:
0143: /*----------------------------------------------------------------------------*/
0144: /* 範囲外出力ファイル */
0145: /*----------------------------------------------------------------------------*/
0146: MssOptOTF optNOF={
0147: OOTF, /* オプションタイプ */
0148: "u", /* キーワード(複数文字は不可) */
0149: 0, /* 0:オプション, 1:必須 */
0150: NOFT, /* このオプションのタイトル(Helpで表示) */
0151: NOFC /* このオプションのコメント(Helpで表示) */
0152: };
0153:
0154: /*----------------------------------------------------------------------------*/
0155: /* シーケンシャル処理 */
0156: /*----------------------------------------------------------------------------*/
0157: MssOptFLG optSEQ={
0158: OFLG, /* オプションタイプ */
0159: "q", /* キーワード(複数文字は不可) */
0160: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0161: SEQT, /* このオプションのタイトル(Helpで表示) */
0162: SEQC /* このオプションのコメント(Helpで表示) */
0163: };
0164:
0165: /*----------------------------------------------------------------------------*/
0166: /* 入力ファイル */
0167: /*----------------------------------------------------------------------------*/
0168: MssOptINF optINF={
0169: OINF, /* オプションタイプ */
0170: "i", /* キーワード(複数文字は不可) */
0171: 0, /* 0:オプション, 1:必須 */
0172: 1, /* 指定可能の最大ファイル数 */
0173: 0, /*1:file not foundのエラーで終了しない 0:する */
0174: INFT, /* このオプションのタイトル(Helpで表示) */
0175: INFC /* このオプションのコメント(Helpで表示) */
0176: };
0177:
0178: /*----------------------------------------------------------------------------*/
0179: /* 出力ファイル */
0180: /*----------------------------------------------------------------------------*/
0181: MssOptOTF optOTF={
0182: OOTF, /* オプションタイプ */
0183: "o", /* キーワード(複数文字は不可) */
0184: 0, /* 0:オプション, 1:必須 */
0185: OTFT, /* このオプションのタイトル(Helpで表示) */
0186: OTFC /* このオプションのコメント(Helpで表示) */
0187: };
0188:
0189: /*----------------------------------------------------------------------------*/
0190: /* 圧縮出力 */
0191: /*----------------------------------------------------------------------------*/
0192: MssOptFLG optZIP={
0193: OFLG, /* オプションタイプ */
0194: "z", /* キーワード(複数文字は不可) */
0195: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0196: ZIPT, /* このオプションのタイトル(Helpで表示) */
0197: ZIPC /* このオプションのコメント(Helpで表示) */
0198: };
0199:
0200: /*----------------------------------------------------------------------------*/
0201: /* plain text */
0202: /*----------------------------------------------------------------------------*/
0203: MssOptFLG optTXT={
0204: OFLG, /* オプションタイプ */
0205: "t", /* キーワード(複数文字は不可) */
0206: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0207: TXTT, /* このオプションのタイトル(Helpで表示) */
0208: TXTC /* このオプションのコメント(Helpで表示) */
0209: };
0210:
0211: /*----------------------------------------------------------------------------*/
0212: /* ワークファイル用ディレクトリ名 */
0213: /*----------------------------------------------------------------------------*/
0214: MssOptSTR optTMP={
0215: OSTR, /* オプションタイプ */
0216: "T", /* キーワード(複数文字は不可) */
0217: 0, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0218: MssTempDir, /* デフォルト */
0219: 1, /* 文字列の最小長 */
0220: MssFileNameMaxLen, /* 文字列の最大長 */
0221: TMPT, /* このオプションのタイトル(Helpで表示) */
0222: TMPC /* このオプションのコメント(Helpで表示) */
0223: };
0224:
0225: /*----------------------------------------------------------------------------*/
0226: /* オプションをまとめる */
0227: /*----------------------------------------------------------------------------*/
0228: void *opt[]={&optKEY,&optFLD,&optVAL,&optAND,&optARC,&optREV,&optNOF,
0229: &optSEQ,&optINF,&optOTF,&optZIP,&optTXT,&optTMP,NULL};
0230:
0231: /*============================================================================*/
0232: /* 変数宣言&定義 */
0233: /*============================================================================*/
0234: struct mssHeader *hdi; /*入力ファイル用<head>タグ格納構造体*/
0235: struct mssHeader *hdo; /*出力ファイル用<head>タグ格納構造体*/
0236: struct mssFPR *fpr; /*入力ファイル構造体 */
0237: struct mssFPW *fpw; /*出力ファイル構造体 */
0238: struct mssFPW *fpw2; /*条件不一致ファイル構造体 */
0239: struct mssFldRecKey *frk; /*項目-行キーバッファ構造体 */
0240: struct mssFldRec *fr=NULL; /*項目-行バッファ構造体 */
0241: struct mssFields *sf; /*ソート項目構造体 */
0242: int sorted; /*ソート済チェック用 */
0243:
0244: struct mssHash *hash;
0245: int lineSel;
0246: int finalSel=0;
0247: MssValue v;
0248: int i;
0249:
0250: /*----------------------------------------------------------------------------*/
0251: /* 前処理 */
0252: /*----------------------------------------------------------------------------*/
0253: mssInit(argc,argv,&comHelp); /* シグナル処理などの初期化 */
0254: mssHelpDoc(opt,&comHelp,argc,argv);/* ヘルプ */
0255: mssSetOption(opt,argc,argv); /* コマンドオプションの設定 */
0256: fpr=mssOpenFPR(optINF.str,4); /* 入力ファイルオープン */
0257: hdi=mssReadHeader(fpr); /* ヘッダの読み込み */
0258: mssSetOptKey(&optKEY, hdi); /* -k 項目をヘッダー項目に関連づける */
0259: mssSetOptFld(&optFLD, hdi); /* -f 項目をヘッダー項目に関連づける */
0260:
0261: /*ソート項目の作成*/
0262: sf=mssInitFields();
0263: mssAddFieldsByFields(sf,optKEY.flds); /* -k 項目をソート項目としてセット */
0264: mssSetFieldsSortPriority(sf); /* ソート優先順位番号を登録順にふる */
0265: sorted=mssChkSorted(sf,hdi); /* ソート済かチェック */
0266:
0267: /*mssShowFields(sf);*/
0268: /*mssShowOption(opt);*/
0269: /*mssShowHeader(hdi);*/
0270:
0271: REV=optREV.set; /*リバースフラグのグローバル化*/
0272: AND=optAND.set; /*項目間andフラグのグローバル化*/
0273:
0274: /*ハッシュテーブルの作成*/
0275: mssVinit(&v,STR); /*dummy*/
0276: hash=mssInitHash(101);
0277: for(i=0; i<optVAL.cnt; i++){
0278: mssHashInsert(hash,*(optVAL.strList+i),v);
0279: }
0280: /*mssShowHash(hash);*/
0281:
0282: /*----------------------------------------------------------------------------*/
0283: /*出力ヘッダーの作成と出力 */
0284: /*----------------------------------------------------------------------------*/
0285: /*出力ヘッダーの初期化(タイトル等のコピー)*/
0286: hdo=mssInitCpyHeader(hdi);
0287:
0288: /*入力ヘッダの全項目を追加*/
0289: mssAddFieldsByFields(hdo->flds,hdi->flds);
0290:
0291: /*ソートする必要があるならばsfのソート情報を反映*/
0292: if(!optSEQ.set && !sorted){
0293: mssSetFieldsSort(hdo->flds,sf);
0294: }
0295:
0296: /*標準出力オープン+ヘッダーの出力*/
0297: fpw=mssOpenFPW(optOTF.str,optZIP.set,0);
0298: mssWriteHeader(hdo, fpw);
0299:
0300: /*条件不一致出力オープン+ヘッダーの出力*/
0301: if(optNOF.set){
0302: fpw2=mssOpenFPW(optNOF.str,optZIP.set,0);
0303: mssWriteHeader(hdo, fpw2);
0304: }else{
0305: fpw2=NULL;
0306: }
0307:
0308: /*----------------------------------------------------------------------------*/
0309: /*メインルーチン */
0310: /*----------------------------------------------------------------------------*/
0311: /*キー単位撰択でない場合*/
0312: if(optKEY.diffSame==1){
0313:
0314: fr =mssInitFldRec(hdi->flds->cnt);
0315: while( EOF != mssReadFldRec(fpr,fr) ){
0316: mssGV.inCnt++;
0317:
0318: lineSel=sel(fr->pnt, optFLD.flds, hash);
0319: if(lineSel){
0320: mssWriteFld(fr->pnt, fr->fldCnt, "\n", fpw);
0321: mssGV.outCnt++;
0322: }else{
0323: if(optNOF.set){
0324: mssWriteFld(fr->pnt, fr->fldCnt, "\n", fpw2);
0325: }
0326: }
0327: }
0328: mssFreeFldRec(fr);
0329:
0330: /*キー単位撰択の場合*/
0331: }else{
0332: /*ソートが必用ならばソートしてソート済みファイルとしてオープン*/
0333: if(!optSEQ.set && !sorted && optKEY.set)
0334: fpr=mssReopenFPRsort(fpr,4,sf,hdi->flds->cnt,optTMP.str);
0335:
0336: /*FRK構造体の初期化*/
0337: frk=mssInitFRK(hdi->flds->cnt, &optKEY,optTMP.str);
0338:
0339: while(1){
0340: /*データ読み込み*/
0341: if(EOF==mssReadFRK(fpr,frk)) break;
0342: mssGV.inCnt+=frk->keyRecCnt;
0343:
0344: while( EOF != mssReadFldRecFRK(frk) ){
0345: lineSel=sel(frk->pnt, optFLD.flds, hash);
0346:
0347: if( REV ){
0348: /*and条件*/
0349: if( optARC.set ){
0350: if(lineSel){finalSel=0; continue;}
0351: else {finalSel=1; break ;}
0352:
0353: /*or条件*/
0354: }else{
0355: if(lineSel){finalSel=0; break ;}
0356: else {finalSel=1; continue;}
0357: }
0358:
0359: }else{
0360:
0361: /*and条件*/
0362: if( optARC.set ){
0363: if(lineSel){finalSel=1; continue;}
0364: else {finalSel=0; break ;}
0365:
0366: /*or条件*/
0367: }else{
0368: if(lineSel){finalSel=1; break ;}
0369: else {finalSel=0; continue;}
0370: }
0371: }
0372: }
0373:
0374: if(finalSel){
0375: mssSeekTopFRK(frk);
0376: while( EOF != mssReadFldRecFRK(frk) ){
0377: mssWriteFld(frk->pnt, frk->fldCnt, "\n", fpw);
0378: mssGV.outCnt++;
0379: }
0380: }else{
0381: if(optNOF.set){
0382: mssSeekTopFRK(frk);
0383: while( EOF != mssReadFldRecFRK(frk) ){
0384: mssWriteFld(frk->pnt, frk->fldCnt, "\n", fpw2);
0385: }
0386: }
0387: }
0388: }
0389: mssFreeFRK(frk);
0390: }
0391: mssFreeHash(hash);
0392:
0393: /*----------------------------------------------------------------------------*/
0394: /*フッター出力&終了処理 */
0395: /*----------------------------------------------------------------------------*/
0396: /*printf("allocCnt=%d\n",getAllocCnt());*/
0397: mssWriteFooter(fpw); /*フッターの出力 */
0398: mssWriteFooter(fpw2); /*フッターの出力 */
0399: mssCloseFPW(fpw); /*出力ファイルのクローズ */
0400: mssCloseFPW(fpw2); /*出力ファイルのクローズ */
0401: mssCloseFPR(fpr); /*入力ファイルのクローズ */
0402: mssFreeFields(sf); /* ソート項目構造体の領域開放 */
0403: mssFreeHeader(hdi); /* 入力ヘッダ領域開放 */
0404: mssFreeHeader(hdo); /* 出力ヘッダ領域開放 */
0405: mssFreeOption(opt); /* オプション領域開放 */
0406: mssShowEndMsg(); /* 完了メッセージ */
0407: mssEnd(mssExitSuccess); /* 終了 */
0408: return(0); /* to avoid warning message */
0409: }