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