MUSASHI C source: xtsel.c


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