MUSASHI C source: xtdelnul.c


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