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