MUSASHI C source: xtcommon.c
0001: /*============================================================================*/
0002: /* 変更履歴 */
0003: /*----------------------------------------------------------------------------*/
0004: /* 1.0 : 新しいAPIに対応 2003/06/20 */
0005: /* 1.1 : 数値でソートしたキーを持つデータの動作不具合対処(API) 2003/08/07 */
0006: /*============================================================================*/
0007:
0008: #include <musashi.h>
0009: #include <stdlib.h>
0010:
0011: #include <xtcommonHelp.h>
0012: struct mssComHelp comHelp={
0013: "xtcommon", /* コマンド名 */
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: /*--グローバル変数*/
0027: static int statT; /*readFRK(Tra)のステータス*/
0028: static int statM; /*readFRK(Mst)のステータス*/
0029: static MssOptKEY *OPTTKY;
0030: static MssOptKEY *OPTMKY;
0031:
0032: int keyCmp(
0033: struct mssFldRec *frT,
0034: struct mssFldRec *frM){
0035: int cmp;
0036: int i;
0037: int fnT;
0038: int fnM;
0039:
0040: if(statT==EOF) return(1); /*T>M*/
0041: if(statM==EOF) return(-1); /*T<M*/
0042:
0043: for(i=0; i<OPTTKY->flds->cnt; i++){
0044: fnT=MssFlds2num(OPTTKY->flds,i);
0045: fnM=MssFlds2num(OPTMKY->flds,i);
0046: cmp = strcmp(*(frT->pnt+fnT),*(frM ->pnt+fnM));
0047: if(cmp>0) return(1); /*T>M*/
0048: if(cmp<0) return(-1);/*T<M*/
0049: }
0050: return(0);
0051: }
0052:
0053: int main(int argc, char *argv[]){
0054: /*============================================================================*/
0055: /* オプション宣言&定義 */
0056: /*============================================================================*/
0057: /*----------------------------------------------------------------------------*/
0058: /* 入力キー項目 */
0059: /*----------------------------------------------------------------------------*/
0060: MssOptKEY optTKY={
0061: OKEY, /* オプションタイプ */
0062: "k", /* キーワード(複数文字は不可) */
0063: 1, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0064: MssFieldMaxCnt, /* 指定可能な最大項目数 */
0065: "i", /* 対象とする入力データのキーワード(GUIで利用) */
0066: 0, /* デフォルト(このオプションが指定されなかったときの動作を指定) */
0067: /* 1:全ての行を異るキー値として扱う */
0068: /* 2:全ての行を同じキー値として扱う) */
0069: /* 0:その他(上記の意味解釈がない) */
0070: TKYT, /* このオプションのタイトル(Helpで表示) */
0071: TKYC /* このオプションのコメント(Helpで表示) */
0072: };
0073:
0074: /*----------------------------------------------------------------------------*/
0075: /* 参照キー項目 */
0076: /*----------------------------------------------------------------------------*/
0077: MssOptKEY optMKY={
0078: OKEY, /* オプションタイプ */
0079: "K", /* キーワード(複数文字は不可) */
0080: 0, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0081: MssFieldMaxCnt, /* 指定可能な最大項目数 */
0082: "m", /* 対象とする入力データのキーワード(GUIで利用) */
0083: 0, /* デフォルト(このオプションが指定されなかったときの動作を指定) */
0084: /* 1:全ての行を異るキー値として扱う */
0085: /* 2:全ての行を同じキー値として扱う) */
0086: /* 0:その他(上記の意味解釈がない) */
0087: MKYT, /* このオプションのタイトル(Helpで表示) */
0088: MKYC /* このオプションのコメント(Helpで表示) */
0089: };
0090:
0091: /*----------------------------------------------------------------------------*/
0092: /* 参照ファイル */
0093: /*----------------------------------------------------------------------------*/
0094: MssOptINF optMST={
0095: OINF, /* オプションタイプ */
0096: "m", /* キーワード(複数文字は不可) */
0097: 1, /* 0:オプション, 1:必須 */
0098: 1, /* 指定可能の最大ファイル数 */
0099: 0, /*1:file not foundのエラーで終了しない 0:する */
0100: MSTT, /* このオプションのタイトル(Helpで表示) */
0101: MSTC /* このオプションのコメント(Helpで表示) */
0102: };
0103:
0104: /*----------------------------------------------------------------------------*/
0105: /* アンマッチ出力ファイル */
0106: /*----------------------------------------------------------------------------*/
0107: MssOptOTF optNOF={
0108: OOTF, /* オプションタイプ */
0109: "u", /* キーワード(複数文字は不可) */
0110: 0, /* 0:オプション, 1:必須 */
0111: NOFT, /* このオプションのタイトル(Helpで表示) */
0112: NOFC /* このオプションのコメント(Helpで表示) */
0113: };
0114:
0115: /*----------------------------------------------------------------------------*/
0116: /* 強制ハッシュ */
0117: /*----------------------------------------------------------------------------*/
0118: MssOptINT optHAS={
0119: OINT, /* オプションタイプ */
0120: "H", /* キーワード(複数文字は不可) */
0121: 0, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0122: 1001, /* デフォルト(数値として指定) */
0123: 11, /* 最小値 */
0124: 100001, /* 最大値 */
0125: HAST, /* このオプションのタイトル(Helpで表示) */
0126: HASC /* このオプションのコメント(Helpで表示) */
0127: };
0128:
0129: /*----------------------------------------------------------------------------*/
0130: /* 条件反転転フラグ(アンマッチを出力) */
0131: /*----------------------------------------------------------------------------*/
0132: MssOptFLG optREV={
0133: OFLG, /* オプションタイプ */
0134: "r", /* キーワード(複数文字は不可) */
0135: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0136: REVT, /* このオプションのタイトル(Helpで表示) */
0137: REVC /* このオプションのコメント(Helpで表示) */
0138: };
0139:
0140: /*----------------------------------------------------------------------------*/
0141: /* 入力ファイル */
0142: /*----------------------------------------------------------------------------*/
0143: MssOptINF optINF={
0144: OINF, /* オプションタイプ */
0145: "i", /* キーワード(複数文字は不可) */
0146: 0, /* 0:オプション, 1:必須 */
0147: 1, /* 指定可能の最大ファイル数 */
0148: 0, /*1:file not foundのエラーで終了しない 0:する */
0149: INFT, /* このオプションのタイトル(Helpで表示) */
0150: INFC /* このオプションのコメント(Helpで表示) */
0151: };
0152:
0153: /*----------------------------------------------------------------------------*/
0154: /* 出力ファイル */
0155: /*----------------------------------------------------------------------------*/
0156: MssOptOTF optOTF={
0157: OOTF, /* オプションタイプ */
0158: "o", /* キーワード(複数文字は不可) */
0159: 0, /* 0:オプション, 1:必須 */
0160: OTFT, /* このオプションのタイトル(Helpで表示) */
0161: OTFC /* このオプションのコメント(Helpで表示) */
0162: };
0163:
0164: /*----------------------------------------------------------------------------*/
0165: /* 圧縮出力 */
0166: /*----------------------------------------------------------------------------*/
0167: MssOptFLG optZIP={
0168: OFLG, /* オプションタイプ */
0169: "z", /* キーワード(複数文字は不可) */
0170: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0171: ZIPT, /* このオプションのタイトル(Helpで表示) */
0172: ZIPC /* このオプションのコメント(Helpで表示) */
0173: };
0174:
0175: /*----------------------------------------------------------------------------*/
0176: /* plain text */
0177: /*----------------------------------------------------------------------------*/
0178: MssOptFLG optTXT={
0179: OFLG, /* オプションタイプ */
0180: "t", /* キーワード(複数文字は不可) */
0181: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0182: TXTT, /* このオプションのタイトル(Helpで表示) */
0183: TXTC /* このオプションのコメント(Helpで表示) */
0184: };
0185:
0186: /*----------------------------------------------------------------------------*/
0187: /* ワークファイル用ディレクトリ名 */
0188: /*----------------------------------------------------------------------------*/
0189: MssOptSTR optTMP={
0190: OSTR, /* オプションタイプ */
0191: "T", /* キーワード(複数文字は不可) */
0192: 0, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0193: MssTempDir, /* デフォルト */
0194: 1, /* 文字列の最小長 */
0195: MssFileNameMaxLen, /* 文字列の最大長 */
0196: TMPT, /* このオプションのタイトル(Helpで表示) */
0197: TMPC /* このオプションのコメント(Helpで表示) */
0198: };
0199:
0200: /*----------------------------------------------------------------------------*/
0201: /* オプションをまとめる */
0202: /*----------------------------------------------------------------------------*/
0203: void *opt[]={&optTKY,&optMKY,&optMST,&optNOF,&optREV,&optHAS,
0204: &optINF,&optOTF,&optZIP,&optTXT,&optTMP,NULL};
0205:
0206: /*============================================================================*/
0207: /* 変数宣言&定義 */
0208: /*============================================================================*/
0209: struct mssHeader *hdT; /*入力ファイル用<head>タグ格納構造体*/
0210: struct mssHeader *hdM; /*参照ファイル用<head>タグ格納構造体*/
0211: struct mssHeader *hdo; /*出力ファイル用<head>タグ格納構造体*/
0212: struct mssFPR *fprT; /*入力ファイル構造体 */
0213: struct mssFPR *fprM; /*参照ファイル構造体 */
0214: struct mssFPW *fpw; /*出力ファイル構造体 */
0215: struct mssFPW *fpw2; /*アンマッチ出力ファイル構造体 */
0216: struct mssFields *sfT; /*ソート項目構造体 */
0217: struct mssFields *sfM; /*ソート項目構造体 */
0218: int sortedT; /*ソート済チェック用 */
0219: int sortedM; /*ソート済チェック用 */
0220:
0221: /*hash joinにて*/
0222: struct mssFldRec *frT =NULL;
0223: struct mssFldRecMax *frmM=NULL;
0224:
0225: /*key break joinにて*/
0226: struct mssFldRec *frM =NULL;
0227:
0228: struct mssFileInfo *fi=NULL; /*マスターのファイル情報*/
0229:
0230: struct mssHashFld *hash=NULL;
0231: struct mssHashNodeFld *hn;
0232:
0233: int mstIsSmall;
0234: int procType;
0235: int kc;
0236: int i;
0237:
0238: /*----------------------------------------------------------------------------*/
0239: /* 前処理 */
0240: /*----------------------------------------------------------------------------*/
0241: mssInit(argc,argv,&comHelp); /* シグナル処理などの初期化 */
0242: mssHelpDoc(opt,&comHelp,argc,argv);/* ヘルプ */
0243: mssSetOption(opt,argc,argv); /* コマンドオプションの設定 */
0244:
0245: /*-Kが指定されていなければ-kをコピーする*/
0246: if(!optMKY.set){
0247: mssCpyOptKey(&optMKY,&optTKY);
0248: }
0249:
0250: fprT=mssOpenFPR(optINF.str,4); /*ファイルオープン*/
0251: fprM=mssOpenFPR(optMST.str,128); /*マスターファイルオープン*/
0252: hdT=mssReadHeader(fprT); /*項目名情報の読み込み*/
0253: hdM=mssReadHeader(fprM); /*項目名情報の読み込み*/
0254:
0255: mssSetOptKey(&optTKY, hdT); /* オプション項目をヘッダー項目に関連づけ*/
0256: mssSetOptKey(&optMKY, hdM); /* オプション項目をヘッダー項目に関連づけ*/
0257:
0258: /*traソート項目の作成*/
0259: sfT=mssInitFields();
0260: mssAddFieldsByFields(sfT,optTKY.flds);/* -k 項目をソート項目としてセット */
0261: mssSetFieldsSortPriority(sfT); /* ソート優先順位番号を登録順にふる */
0262: sortedT=mssChkSorted(sfT,hdT); /* ソート済かチェック */
0263:
0264: /*mstソート項目の作成*/
0265: sfM=mssInitFields();
0266: mssAddFieldsByFields(sfM,optMKY.flds);/* -k 項目をソート項目としてセット */
0267: mssSetFieldsSortPriority(sfM); /* ソート優先順位番号を登録順にふる */
0268: sortedM=mssChkSorted(sfM,hdM); /* ソート済かチェック */
0269:
0270: /*強制hashでなければ一万行を上限にマスターの情報を取得*/
0271: if(!optHAS.set){
0272: fi=mssGetFileInfo(optMST.str,10000);
0273:
0274: /*強制hashならば全行マスターの情報を取得*/
0275: }else{
0276: fi=mssGetFileInfo(optMST.str,0);
0277: }
0278:
0279: /*----------------------------------------------------------------------------*/
0280: /*前処理 */
0281: /*----------------------------------------------------------------------------*/
0282: /* Traは大きいという前提で考える*/
0283: /* TraSrt MstSrt MstSmall */
0284: /* 無 無 小 hash (1)*/
0285: /* 無 無 大 Tsrt+Msrt + keyBreak(2)*/
0286: /* 無 済 小 hash (1)*/
0287: /* 無 済 大 Tsrt + keyBreak(3)*/
0288: /* 済 無 小 Msrt + keyBreak(4)*/
0289: /* 済 無 大 Msrt + keyBreak(4)*/
0290: /* 済 済 小 keyBreak(5)*/
0291: /* 済 済 大 keyBreak(5)*/
0292:
0293: /*マスタが小さいかどうかのチェック*/
0294: if(!fi->readEnd){ /*最後まで読み切っていない*/
0295: mstIsSmall=0;
0296: }else{ /*その他は、smallであると判断*/
0297: mstIsSmall=1;
0298: }
0299: mssFree(fi);
0300:
0301: /*処理タイプの決定*/
0302: if(sortedT){
0303: if(sortedM){
0304: if(mstIsSmall) procType=5;
0305: else procType=5;
0306: }else{
0307: if(mstIsSmall) procType=4;
0308: else procType=4;
0309: }
0310: }else{
0311: if(sortedM){
0312: if(mstIsSmall) procType=1;
0313: else procType=3;
0314: }else{
0315: if(mstIsSmall) procType=1;
0316: else procType=2;
0317: }
0318: }
0319:
0320: /*強制hashの時は、強制的にtype1*/
0321: if(optHAS.set) procType=1;
0322:
0323: /*----------------------------------------------------------------------------*/
0324: /*出力ヘッダーの作成と出力 */
0325: /*----------------------------------------------------------------------------*/
0326: /*出力ヘッダーの初期化(タイトル等のコピー)*/
0327: hdo=mssInitCpyHeader(hdT);
0328:
0329: /*入力ヘッダの全項目を追加*/
0330: mssAddFieldsByFields(hdo->flds,hdT->flds);
0331:
0332: if(procType==2 || procType==3){
0333: mssSetFieldsSort(hdo->flds,sfT);
0334: }
0335:
0336: /*標準出力オープン+ヘッダーの出力*/
0337: fpw=mssOpenFPW(optOTF.str,optZIP.set,0);
0338: mssWriteHeader(hdo, fpw);
0339:
0340: /*条件不一致出力オープン+ヘッダーの出力*/
0341: if(optNOF.set){
0342: fpw2=mssOpenFPW(optNOF.str,0,0);
0343: mssWriteHeader(hdo, fpw2);
0344: }else{
0345: fpw2=NULL;
0346: }
0347:
0348: /*----------------------------------------------------------------------------*/
0349: /*メインルーチン*/
0350: /*----------------------------------------------------------------------------*/
0351: /*グローバル変数セット*/
0352: OPTTKY=&optTKY;
0353: OPTMKY=&optMKY;
0354:
0355: if(procType==1){
0356:
0357: /*ハッシュテーブルの作成*/
0358: frmM =mssInitFRM(hdM->flds->cnt);
0359: mssReadFRM(fprM,frmM);
0360:
0361: /*全行読み込んでるはずなのでeofフラグがたっているはず*/
0362: if(!frmM->eof) {
0363: mssShowErrMsg("internal error in xtcommon by hash");
0364: mssEnd(mssErrorNoDefault);
0365: }
0366: hash=mssInitHashFld(optHAS.val,optMKY.flds);
0367: for(i=0; i<frmM->recCnt; i++){
0368: mssHashInsertFld(hash, frmM->pnt+i*frmM->fldCnt);
0369: }
0370: /*mssShowHashFld(hash, frmM->fldCnt);*/
0371:
0372: frT =mssInitFldRec(hdT->flds->cnt);
0373:
0374: while(1){
0375: statT=mssReadFldRec(fprT,frT);
0376:
0377: /*Tra Endの時*/
0378: if(statT==EOF){
0379: break;
0380: }
0381:
0382: mssGV.inCnt++;
0383:
0384: /*Mstセット*/
0385: hn=mssHashMemberFld(hash, frT->pnt, optTKY.flds);
0386:
0387: /*match*/
0388: if(hn!=NULL){
0389: if(optREV.set){
0390: if(optNOF.set) mssWriteFld(frT->pnt, frT->fldCnt, "\n", fpw2);
0391: }else{
0392: mssWriteFld(frT->pnt, frT->fldCnt, "\n", fpw);
0393: mssGV.outCnt++;
0394: }
0395:
0396: /*unmatch*/
0397: }else{
0398: if(optREV.set){
0399: mssWriteFld(frT->pnt, frT->fldCnt, "\n", fpw);
0400: mssGV.outCnt++;
0401: }else{
0402: if(optNOF.set) mssWriteFld(frT->pnt, frT->fldCnt, "\n", fpw2);
0403: }
0404: }
0405: }
0406:
0407: mssFreeFRM(frmM);
0408: mssFreeFldRec(frT);
0409: mssFreeHashFld(hash);
0410:
0411: }else{
0412:
0413: frT =mssInitFldRec(hdT->flds->cnt);
0414: frM =mssInitFldRec(hdM->flds->cnt);
0415: if(!sortedT){
0416: fprT=mssReopenFPRsort(fprT,4,sfT,hdT->flds->cnt,optTMP.str);
0417: }
0418: if(!sortedM){
0419: fprM=mssReopenFPRsort(fprM,4,sfM,hdM->flds->cnt,optTMP.str);
0420: }
0421:
0422: /*トラ読み込み*/
0423: statT=mssReadFldRec(fprT,frT);
0424: mssGV.inCnt++;
0425:
0426: /*マスタ読み込み*/
0427: statM=mssReadFldRec(fprM,frM);
0428:
0429: while(1){
0430:
0431: /*Tra,Mst両方Endの時*/
0432: /*if(statT==EOF || statM==EOF) break;*/
0433: if(statT==EOF) break;
0434:
0435: kc=keyCmp(frT,frM);
0436: if(kc == 1){ /*T>M*/
0437: statM=mssReadFldRec(fprM,frM);
0438: }else if(kc ==-1){ /*T<M*/
0439: if(optREV.set){
0440: mssWriteFld(frT->pnt, frT->fldCnt, "\n", fpw);
0441: mssGV.outCnt++;
0442: }else{
0443: if(optNOF.set) mssWriteFld(frT->pnt, frT->fldCnt, "\n", fpw2);
0444: }
0445: statT=mssReadFldRec(fprT,frT);
0446: mssGV.inCnt++;
0447: }else{ /*T==M*/
0448: if(optREV.set){
0449: if(optNOF.set) mssWriteFld(frT->pnt, frT->fldCnt, "\n", fpw2);
0450: }else{
0451: mssWriteFld(frT->pnt, frT->fldCnt, "\n", fpw);
0452: mssGV.outCnt++;
0453: }
0454: statT=mssReadFldRec(fprT,frT);
0455: mssGV.inCnt++;
0456: }
0457: }
0458: mssFreeFldRec(frT);
0459: mssFreeFldRec(frM);
0460: }
0461:
0462:
0463: /*----------------------------------------------------------------------------*/
0464: /*フッター出力&終了処理 */
0465: /*----------------------------------------------------------------------------*/
0466: mssWriteFooter(fpw); /*フッターの出力 */
0467: mssWriteFooter(fpw2); /*フッターの出力 */
0468: mssCloseFPW(fpw); /*出力ファイルのクローズ */
0469: mssCloseFPW(fpw2); /*条件不一致ファイルのクローズ*/
0470: mssCloseFPR(fprT); /*入力ファイルのクローズ */
0471: mssCloseFPR(fprM); /*入力ファイルのクローズ */
0472: mssFreeFields(sfT); /*ソート項目構造体の領域開放 */
0473: mssFreeFields(sfM); /*ソート項目構造体の領域開放 */
0474: mssFreeHeader(hdT); /*入力ヘッダ領域開放 */
0475: mssFreeHeader(hdM); /*入力ヘッダ領域開放 */
0476: mssFreeHeader(hdo); /*出力ヘッダ領域開放 */
0477: mssFreeOption(opt); /*オプション領域開放 */
0478: mssShowEndMsg(); /* 完了メッセージ */
0479: mssEnd(mssExitSuccess); /* 終了 */
0480: return(0); /* to avoid warning message */
0481: }