MUSASHI C source: xtjoin.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 <xtjoinHelp.h> 
0012: struct mssComHelp comHelp={ 
0013:   "xtjoin",       /* コマンド名       */ 
0014:   "1.1",          /* バージョン       */ 
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 fcT;       /*トラの項目数*/ 
0028: static int fcM;       /*マスの項目数*/ 
0029: static int statT;     /*readFRK(Tra)のステータス*/ 
0030: static int statM;     /*readFRK(Mst)のステータス*/ 
0031: static struct mssFPW *op; 
0032: static MssOptKEY *OPTTKY; 
0033: static MssOptKEY *OPTMKY; 
0034: static MssOptFLD *OPTFLD; 
0035:  
0036: /** 
0037:  * # FUNCTION # 
0038:  * 現在読み込まれているTraとMstのキーの値を比較する 
0039:  */ 
0040: int keyCmp( 
0041:   struct mssFldRecDbl *frdT, 
0042:   struct mssFldRec    *frM){ 
0043:   int cmp; 
0044:   int i; 
0045:   int fnT; 
0046:   int fnM; 
0047:  
0048:   if(frdT->eof)  return(1);  /*T>M*/ 
0049:   if(statM==EOF) return(-1); /*T<M*/ 
0050:  
0051:   for(i=0; i<OPTTKY->flds->cnt; i++){ 
0052:     fnT=MssFlds2num(OPTTKY->flds,i); 
0053:     fnM=MssFlds2num(OPTMKY->flds,i); 
0054:     cmp = strcmp(*(frdT->pnt[frdT->new]+fnT),*(frM ->pnt+fnM)); 
0055:     if(cmp>0) return(1); /*T>M*/ 
0056:     if(cmp<0) return(-1);/*T<M*/ 
0057:   } 
0058:   return(0); 
0059: } 
0060:  
0061: /** 
0062:  * # FUNCTION # 
0063:  * マスター項目としてstr配列のcnt個の要素を書き出す。 
0064:  * 行末の改行を出力する。 
0065:  */ 
0066: void writeMstFld(int cnt, char **str){ 
0067:   int i; 
0068:   for(i=0; i<cnt-1; i++){ 
0069:     mssWriteStr(*(str+MssFlds2num(OPTFLD->flds,i)),op); 
0070:     mssWriteDlm(op); 
0071:   }  
0072:   mssWriteStr(*(str+MssFlds2num(OPTFLD->flds,i)),op); 
0073:   mssWriteRet(op); 
0074: }  
0075:  
0076: /** 
0077:  * # FUNCTION # 
0078:  * マスター項目として、cnt個のNULL値として書き出す。 
0079:  * 行末の改行を出力する。 
0080:  */ 
0081: void writeMstNul(int cnt){ 
0082:   int i; 
0083:   for(i=0; i<cnt-1; i++){ 
0084:     mssWriteNull(op); mssWriteDlm(op); 
0085:   }  
0086:   mssWriteNull(op); mssWriteRet(op); 
0087: }  
0088:  
0089: /** 
0090:  * # FUNCTION # 
0091:  * トランザクション項目としてstr配列のcnt個の要素を書き出す。 
0092:  * 行末はスペースを出力する。 
0093:  */ 
0094: void writeTraFld(int cnt, char **str){ 
0095:   int i; 
0096:   for(i=0; i<cnt; i++){ 
0097:     mssWriteStr(*(str+i),op); 
0098:     mssWriteDlm(op); 
0099:   }  
0100: }  
0101:  
0102: /** 
0103:  * # FUNCTION # 
0104:  * トランザクションキー項目の値が、にマスターキー項目に存在しないとき、 
0105:  * トランザクションのキー項目は、マスターの項目(str)を参照しながら出力し、 
0106:  * その他のトランザクション項目はNULL値を出力する。 
0107:  */ 
0108: void writeTraByMst(char **str){ 
0109:   int kv; 
0110:   int i; 
0111:   for(i=0; i<fcT; i++){ 
0112:     kv=*(OPTTKY->fldNo2optNo+i); 
0113:     if(kv!=-1){ 
0114:       mssWriteStr(*(str+MssFlds2num(OPTMKY->flds,kv)),op); 
0115:       mssWriteDlm(op); 
0116:     }else{ 
0117:       mssWriteNull(op); mssWriteDlm(op); 
0118:     } 
0119:   } 
0120: } 
0121:  
0122: void writeTM(struct mssFldRecDbl *frdT,struct mssFldRec *frM){ 
0123:  
0124:   /*マスターがEOFの時*/ 
0125:   if(frM==NULL){ 
0126:     writeTraFld(frdT->fldCnt,frdT->pnt[frdT->new]); 
0127:     writeMstNul(OPTFLD->flds->cnt); 
0128:     mssGV.outCnt++; 
0129:  
0130:   /*トラがEOFの時*/ 
0131:   }else if(frdT==NULL){ 
0132:     writeTraByMst(frM->pnt); 
0133:     writeMstFld(OPTFLD->flds->cnt,frM->pnt); 
0134:     mssGV.outCnt++; 
0135:  
0136:   /*トラ、マスターの両方ある場合*/ 
0137:   }else{ 
0138:     writeTraFld(frdT->fldCnt,frdT->pnt[frdT->new]); 
0139:     writeMstFld(OPTFLD->flds->cnt,frM->pnt); 
0140:     mssGV.outCnt++; 
0141:   } 
0142: } 
0143:  
0144: void writeNulMstHash(struct mssHashFld *hash){ 
0145:   struct mssHashNodeFld *node; 
0146:   int i,j; 
0147:  
0148:   for(i=0; i<hash->hashVal; i++){ /*全hash値を見る*/ 
0149:     node=*(hash->node+i); 
0150:     while(node != NULL){          /*hash値がiのノードを全て見る*/ 
0151:       if(!node->endFlg){          /*そのノードが1回も検索されていなければ*/ 
0152:         for(j=0; j<node->recCnt; j++){ 
0153:           writeTraByMst(*(node->rec+j)); 
0154:           writeMstFld(OPTFLD->flds->cnt,*(node->rec+j)); 
0155:           mssGV.outCnt++; 
0156:         } 
0157:       } 
0158:       node=node->next; 
0159:     } 
0160:   } 
0161: } 
0162:  
0163: void writeTMhash(struct mssFldRec *frT,struct mssHashNodeFld *hn){ 
0164:  
0165:   /*マスターがNULLの時*/ 
0166:   if(hn==NULL){ 
0167:     writeTraFld(frT->fldCnt,frT->pnt); 
0168:     writeMstNul(OPTFLD->flds->cnt); 
0169:     mssGV.outCnt++; 
0170:  
0171:   /*トラ、マスターの両方ある場合*/ 
0172:   }else{ 
0173:     writeTraFld(frT->fldCnt,frT->pnt); 
0174:     writeMstFld(OPTFLD->flds->cnt,*hn->rec); 
0175:     mssGV.outCnt++; 
0176:   } 
0177: } 
0178:  
0179: /*============================================================================*/ 
0180: /* version 1.00 2000/07/07 初期作成 hamuro                                    */ 
0181: /*============================================================================*/ 
0182: int main(int argc, char *argv[]){ 
0183: /*============================================================================*/ 
0184: /* オプション宣言&定義                                                       */ 
0185: /*============================================================================*/ 
0186: /*----------------------------------------------------------------------------*/ 
0187: /* 入力キー項目                                                               */ 
0188: /*----------------------------------------------------------------------------*/ 
0189:   MssOptKEY optTKY={ 
0190:     OKEY,   /* オプションタイプ                                             */ 
0191:     "k",    /* キーワード(複数文字は不可)                                   */ 
0192:     1,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0193:     MssFieldMaxCnt, /* 指定可能な最大項目数                                 */ 
0194:     "i",    /* 対象とする入力データのキーワード(GUIで利用)                  */ 
0195:     0,      /* デフォルト(このオプションが指定されなかったときの動作を指定) */ 
0196:             /* 1:全ての行を異るキー値として扱う                             */ 
0197:             /* 2:全ての行を同じキー値として扱う)                            */ 
0198:             /* 0:その他(上記の意味解釈がない)                               */ 
0199:     TKYT,   /* このオプションのタイトル(Helpで表示)                         */ 
0200:     TKYC    /* このオプションのコメント(Helpで表示)                         */ 
0201:   }; 
0202:  
0203: /*----------------------------------------------------------------------------*/ 
0204: /* 参照キー項目                                                               */ 
0205: /*----------------------------------------------------------------------------*/ 
0206:   MssOptKEY optMKY={ 
0207:     OKEY,   /* オプションタイプ                                             */ 
0208:     "K",    /* キーワード(複数文字は不可)                                   */ 
0209:     0,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0210:     MssFieldMaxCnt, /* 指定可能な最大項目数                                 */ 
0211:     "m",    /* 対象とする入力データのキーワード(GUIで利用)                  */ 
0212:     0,      /* デフォルト(このオプションが指定されなかったときの動作を指定) */ 
0213:             /* 1:全ての行を異るキー値として扱う                             */ 
0214:             /* 2:全ての行を同じキー値として扱う)                            */ 
0215:             /* 0:その他(上記の意味解釈がない)                               */ 
0216:     MKYT,   /* このオプションのタイトル(Helpで表示)                         */ 
0217:     MKYC    /* このオプションのコメント(Helpで表示)                         */ 
0218:   }; 
0219:  
0220: /*----------------------------------------------------------------------------*/ 
0221: /* 参照ファイル                                                               */ 
0222: /*----------------------------------------------------------------------------*/ 
0223:   MssOptINF optMST={ 
0224:     OINF,   /* オプションタイプ                                             */ 
0225:     "m",    /* キーワード(複数文字は不可)                                   */ 
0226:     1,      /* 0:オプション, 1:必須                                         */ 
0227:     1,      /* 指定可能の最大ファイル数                                     */ 
0228:     0,      /*1:file not foundのエラーで終了しない 0:する                   */ 
0229:     MSTT,   /* このオプションのタイトル(Helpで表示)                         */ 
0230:     MSTC    /* このオプションのコメント(Helpで表示)                         */ 
0231:   }; 
0232:  
0233: /*----------------------------------------------------------------------------*/ 
0234: /* 結合項目                                                                   */ 
0235: /*----------------------------------------------------------------------------*/ 
0236:   MssOptFLD optFLD={ 
0237:     OFLD,   /* オプションタイプ                                             */ 
0238:     "f",    /* キーワード(複数文字は不可)                                   */ 
0239:     1,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0240:     MssFieldMaxCnt, /* 指定可能な最大項目数                                 */ 
0241:     "m",    /* 対象とする入力データのキーワード(GUIで利用)                  */ 
0242:     1,      /* 正規表現を許可するかどうか(0:不可,1:可)                      */ 
0243:     1,      /* 新項目名を指定できるかどうか(0:不可,1:可)                    */ 
0244:     NULL,   /* 項目オプション(%以下)で指定可能な文字                        */ 
0245:             /* ex) 指定不可の場合はNULL, "nr": "-f 項目名%rn"の指定可能     */ 
0246:     FLDT,   /* このオプションのタイトル(Helpで表示)                         */ 
0247:     FLDC,   /* このオプションのコメント(Helpで表示)                         */ 
0248:     FLDF    /* フラグについての説明(Helpで表示)複数の場合はカンマで区切る   */ 
0249:   }; 
0250:  
0251: /*----------------------------------------------------------------------------*/ 
0252: /* マスターouterJoin                                                          */ 
0253: /*----------------------------------------------------------------------------*/ 
0254:   MssOptFLG optMNL={ 
0255:     OFLG,   /* オプションタイプ                                             */ 
0256:     "N",    /* キーワード(複数文字は不可)                                   */ 
0257:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0258:     MNLT,   /* このオプションのタイトル(Helpで表示)                         */ 
0259:     MNLC    /* このオプションのコメント(Helpで表示)                         */ 
0260:   }; 
0261:  
0262: /*----------------------------------------------------------------------------*/ 
0263: /* 入力outerJoin                                                              */ 
0264: /*----------------------------------------------------------------------------*/ 
0265:   MssOptFLG optTNL={ 
0266:     OFLG,   /* オプションタイプ                                             */ 
0267:     "n",    /* キーワード(複数文字は不可)                                   */ 
0268:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0269:     TNLT,   /* このオプションのタイトル(Helpで表示)                         */ 
0270:     TNLC    /* このオプションのコメント(Helpで表示)                         */ 
0271:   }; 
0272:  
0273: /*----------------------------------------------------------------------------*/ 
0274: /* 強制ハッシュJoin                                                           */ 
0275: /*----------------------------------------------------------------------------*/ 
0276:   MssOptINT optHAS={ 
0277:     OINT,   /* オプションタイプ                                             */ 
0278:     "H",    /* キーワード(複数文字は不可)                                   */ 
0279:     0,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0280:     1001,   /* デフォルト(数値として指定)                                   */ 
0281:     11,     /* 最小値                                                       */ 
0282:     100001, /* 最大値                                                       */ 
0283:     HAST,   /* このオプションのタイトル(Helpで表示)                         */ 
0284:     HASC    /* このオプションのコメント(Helpで表示)                         */ 
0285:   };         
0286:  
0287: /*----------------------------------------------------------------------------*/ 
0288: /* 入力ファイル                                                               */ 
0289: /*----------------------------------------------------------------------------*/ 
0290:   MssOptINF optINF={ 
0291:     OINF,   /* オプションタイプ                                             */ 
0292:     "i",    /* キーワード(複数文字は不可)                                   */ 
0293:     0,      /* 0:オプション, 1:必須                                         */ 
0294:     1,      /* 指定可能の最大ファイル数                                     */ 
0295:     0,      /*1:file not foundのエラーで終了しない 0:する                   */ 
0296:     INFT,   /* このオプションのタイトル(Helpで表示)                         */ 
0297:     INFC    /* このオプションのコメント(Helpで表示)                         */ 
0298:   }; 
0299:  
0300: /*----------------------------------------------------------------------------*/ 
0301: /* 出力ファイル                                                               */ 
0302: /*----------------------------------------------------------------------------*/ 
0303:   MssOptOTF optOTF={ 
0304:     OOTF,   /* オプションタイプ                                             */ 
0305:     "o",    /* キーワード(複数文字は不可)                                   */ 
0306:     0,      /* 0:オプション, 1:必須                                         */ 
0307:     OTFT,   /* このオプションのタイトル(Helpで表示)                         */ 
0308:     OTFC    /* このオプションのコメント(Helpで表示)                         */ 
0309:   }; 
0310:      
0311: /*----------------------------------------------------------------------------*/ 
0312: /* 圧縮出力                                                                   */ 
0313: /*----------------------------------------------------------------------------*/ 
0314:   MssOptFLG optZIP={ 
0315:     OFLG,   /* オプションタイプ                                             */ 
0316:     "z",    /* キーワード(複数文字は不可)                                   */ 
0317:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0318:     ZIPT,   /* このオプションのタイトル(Helpで表示)                         */ 
0319:     ZIPC    /* このオプションのコメント(Helpで表示)                         */ 
0320:   }; 
0321:      
0322: /*----------------------------------------------------------------------------*/ 
0323: /* plain text                                                                 */ 
0324: /*----------------------------------------------------------------------------*/ 
0325:   MssOptFLG optTXT={ 
0326:     OFLG,   /* オプションタイプ                                             */ 
0327:     "t",    /* キーワード(複数文字は不可)                                   */ 
0328:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0329:     TXTT,   /* このオプションのタイトル(Helpで表示)                         */ 
0330:     TXTC    /* このオプションのコメント(Helpで表示)                         */ 
0331:   }; 
0332:  
0333: /*----------------------------------------------------------------------------*/ 
0334: /* ワークファイル用ディレクトリ名                                             */ 
0335: /*----------------------------------------------------------------------------*/ 
0336:   MssOptSTR optTMP={ 
0337:     OSTR,   /* オプションタイプ                                             */ 
0338:     "T",    /* キーワード(複数文字は不可)                                   */ 
0339:     0,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0340:     MssTempDir, /* デフォルト                                               */ 
0341:     1,      /* 文字列の最小長                                               */ 
0342:     MssFileNameMaxLen,  /* 文字列の最大長                                   */ 
0343:     TMPT,   /* このオプションのタイトル(Helpで表示)                         */ 
0344:     TMPC    /* このオプションのコメント(Helpで表示)                         */ 
0345:   }; 
0346:  
0347: /*----------------------------------------------------------------------------*/ 
0348: /* オプションをまとめる                                                       */ 
0349: /*----------------------------------------------------------------------------*/ 
0350:   void *opt[]={&optTKY,&optMKY,&optMST,&optFLD,&optMNL,&optTNL,&optHAS, 
0351:                &optINF,&optOTF,&optZIP,&optTXT,&optTMP,NULL}; 
0352:    
0353: /*============================================================================*/ 
0354: /* 変数宣言&定義                                                             */ 
0355: /*============================================================================*/ 
0356:   struct mssHeader    *hdT; /*入力ファイル用<head>タグ格納構造体*/ 
0357:   struct mssHeader    *hdM; /*参照ファイル用<head>タグ格納構造体*/ 
0358:   struct mssHeader    *hdo; /*出力ファイル用<head>タグ格納構造体*/ 
0359:   struct mssFPR       *fprT;/*入力ファイル構造体                */ 
0360:   struct mssFPR       *fprM;/*参照ファイル構造体                */ 
0361:   struct mssFPW       *fpw; /*出力ファイル構造体                */ 
0362:   struct mssFields    *sfT; /*ソート項目構造体                  */ 
0363:   struct mssFields    *sfM; /*ソート項目構造体                  */ 
0364:   int sortedT;              /*ソート済チェック用                */ 
0365:   int sortedM;              /*ソート済チェック用                */ 
0366:  
0367:   /*hash joinにて*/ 
0368:   struct mssFldRec    *frT =NULL; 
0369:   struct mssFldRecMax *frmM=NULL; 
0370:  
0371:   /*key break joinにて*/ 
0372:   struct mssFldRecDbl *frdT=NULL; 
0373:   struct mssFldRec    *frM =NULL; 
0374:  
0375:   struct mssFileInfo  *fi=NULL; /*マスターのファイル情報*/ 
0376:  
0377:   struct mssHashFld     *hash; 
0378:   struct mssHashNodeFld *hn; 
0379:  
0380:  
0381:   /*マスターを一行でも書いたときon -tnullと単なるキーブレークを見分ける*/ 
0382:   int mstw; 
0383:  
0384:   int mstIsSmall; 
0385:   int procType; 
0386:   int kc; 
0387:   int i; 
0388:  
0389: /*----------------------------------------------------------------------------*/ 
0390: /* 前処理                                                                     */ 
0391: /*----------------------------------------------------------------------------*/ 
0392:   mssInit(argc,argv,&comHelp);       /* シグナル処理などの初期化              */ 
0393:   mssHelpDoc(opt,&comHelp,argc,argv);/* ヘルプ                                */ 
0394:   mssSetOption(opt,argc,argv);       /* コマンドオプションの設定              */ 
0395:    
0396:   /*-Kが指定されていなければ-kをコピーする*/ 
0397:   if(!optMKY.set){ 
0398:     mssCpyOptKey(&optMKY,&optTKY); 
0399:   } 
0400:    
0401:   fprT=mssOpenFPR(optINF.str,4);    /*ファイルオープン*/ 
0402:   fprM=mssOpenFPR(optMST.str,128);  /*マスターファイルオープン*/ 
0403:   hdT=mssReadHeader(fprT);          /*項目名情報の読み込み*/ 
0404:   hdM=mssReadHeader(fprM);          /*項目名情報の読み込み*/ 
0405:    
0406:   mssSetOptKey(&optTKY, hdT);       /* オプション項目をヘッダー項目に関連づけ*/ 
0407:   mssSetOptKey(&optMKY, hdM);       /* オプション項目をヘッダー項目に関連づけ*/ 
0408:   mssSetOptFld(&optFLD, hdM);       /* オプション項目をヘッダー項目に関連づけ*/ 
0409:    
0410:   /*traソート項目の作成*/ 
0411:   sfT=mssInitFields(); 
0412:   mssAddFieldsByFields(sfT,optTKY.flds);/* -k 項目をソート項目としてセット    */ 
0413:   mssSetFieldsSortPriority(sfT);        /* ソート優先順位番号を登録順にふる   */ 
0414:   sortedT=mssChkSorted(sfT,hdT);        /* ソート済かチェック                 */ 
0415:    
0416:   /*mstソート項目の作成*/ 
0417:   sfM=mssInitFields(); 
0418:   mssAddFieldsByFields(sfM,optMKY.flds);/* -k 項目をソート項目としてセット    */ 
0419:   mssSetFieldsSortPriority(sfM);        /* ソート優先順位番号を登録順にふる   */ 
0420:   sortedM=mssChkSorted(sfM,hdM);        /* ソート済かチェック                 */ 
0421:    
0422:   /*強制hashでなければ一万行を上限にマスターの情報を取得*/ 
0423:   if(!optHAS.set){ 
0424:     fi=mssGetFileInfo(optMST.str,10000); 
0425:    
0426:   /*強制hashならば全行マスターの情報を取得*/ 
0427:   }else{ 
0428:     fi=mssGetFileInfo(optMST.str,0); 
0429:   } 
0430:  
0431: /*----------------------------------------------------------------------------*/ 
0432: /*前処理                                                                      */ 
0433: /*----------------------------------------------------------------------------*/ 
0434: /* Traは大きいという前提で考える*/ 
0435: /* TraSrt MstSrt MstSmall */ 
0436: /* 無     無     小 hash                (1)*/ 
0437: /* 無     無     大 Tsrt+Msrt + keyBreak(2)*/ 
0438: /* 無     済     小 hash                (1)*/ 
0439: /* 無     済     大 Tsrt      + keyBreak(3)*/ 
0440: /* 済     無     小 Msrt      + keyBreak(4)*/ 
0441: /* 済     無     大 Msrt      + keyBreak(4)*/ 
0442: /* 済     済     小             keyBreak(5)*/ 
0443: /* 済     済     大             keyBreak(5)*/ 
0444:  
0445:   /*マスタが小さいかどうかのチェック*/ 
0446:   if(!fi->readEnd){  /*最後まで読み切っていない*/ 
0447:     mstIsSmall=0; 
0448:   }else{             /*その他は、smallであると判断*/ 
0449:     mstIsSmall=1; 
0450:   } 
0451:   mssFree(fi); 
0452:  
0453:   /*処理タイプの決定*/ 
0454:   if(sortedT==1){ 
0455:     if(sortedM==1){ 
0456:       if(mstIsSmall) procType=5; 
0457:       else           procType=5; 
0458:     }else{ 
0459:       if(mstIsSmall) procType=4; 
0460:       else           procType=4; 
0461:     } 
0462:   }else{ 
0463:     if(sortedM==1){ 
0464:       if(mstIsSmall) procType=1; 
0465:       else           procType=3; 
0466:     }else{ 
0467:       if(mstIsSmall) procType=1; 
0468:       else           procType=2; 
0469:     } 
0470:   } 
0471:  
0472:   /*強制hashの時は、強制的にtype1*/ 
0473:   if(optHAS.set) procType=1; 
0474:  
0475: /*----------------------------------------------------------------------------*/ 
0476: /*出力ヘッダーの作成と出力                                                    */ 
0477: /*----------------------------------------------------------------------------*/ 
0478:   /*出力ヘッダーの初期化(タイトル等のコピー)*/ 
0479:   hdo=mssInitCpyHeader(hdT); 
0480:  
0481:   /*入力ヘッダの全項目を追加*/ 
0482:   mssAddFieldsByFields(hdo->flds,hdT->flds); 
0483:  
0484:   /*新項目名を追加する*/ 
0485:   mssAddFieldsByStrList(hdo->flds,optFLD.newNam,optFLD.cnt); 
0486:  
0487:   if(procType==2 || procType==3){ 
0488:     mssSetFieldsSort(hdo->flds,sfT); 
0489:   } 
0490:  
0491:   /*標準出力オープン+ヘッダーの出力*/ 
0492:   fpw=mssOpenFPW(optOTF.str,optZIP.set,0); 
0493:   mssWriteHeader(hdo, fpw); 
0494:  
0495: /*----------------------------------------------------------------------------*/ 
0496: /*メインルーチン                                                              */ 
0497: /*----------------------------------------------------------------------------*/ 
0498:   /*グローバル変数セット*/ 
0499:   fcT=hdT->flds->cnt; 
0500:   fcM=hdM->flds->cnt; 
0501:   OPTTKY=&optTKY; 
0502:   OPTMKY=&optMKY; 
0503:   OPTFLD=&optFLD; 
0504:   op=fpw; 
0505:  
0506:   /*hash join*/ 
0507:   if(procType==1){ 
0508:  
0509:     /*ハッシュテーブルの作成*/ 
0510:     frmM =mssInitFRM(fcM); 
0511:     mssReadFRM(fprM,frmM); 
0512:  
0513:     /*全行読み込んでるはずなのでeofフラグがたっているはず*/ 
0514:     if(!frmM->eof) { 
0515:       mssShowErrMsg("internal error in xtjoin by hash"); 
0516:       mssEnd(mssErrorNoDefault); 
0517:     } 
0518:     hash=mssInitHashFld(optHAS.val,optMKY.flds); 
0519:     for(i=0; i<frmM->recCnt; i++){ 
0520:       mssHashInsertFld(hash, frmM->pnt+i*frmM->fldCnt); 
0521:     } 
0522: /*mssShowHashFld(hash, frmM->fldCnt);*/ 
0523:  
0524:     frT =mssInitFldRec(fcT); 
0525:     while(1){ 
0526:       statT=mssReadFldRec(fprT,frT); 
0527:  
0528:       /*Tra Endの時*/ 
0529:       if(statT==EOF){ 
0530:         if(optMNL.set) writeNulMstHash(hash); 
0531:         break; 
0532:       } 
0533:  
0534:       mssGV.inCnt++; 
0535:  
0536:       /*Traのキー項目値がMstにあるかどうか*/ 
0537:       hn=mssHashMemberFld(hash, frT->pnt, optTKY.flds); 
0538:       if(hn==NULL && !optTNL.set) continue; 
0539:  
0540:       /*書き出し*/ 
0541:       writeTMhash(frT,hn); 
0542:     } 
0543:  
0544:     mssFreeFRM(frmM); 
0545:     mssFreeFldRec(frT); 
0546:     mssFreeHashFld(hash); 
0547:  
0548:   }else{ 
0549:  
0550:     frdT=mssInitFRD(fcT); 
0551:     frM =mssInitFldRec(fcM); 
0552:     if(sortedT!=1){ 
0553:       fprT=mssReopenFPRsort(fprT,4,sfT,hdT->flds->cnt,optTMP.str); 
0554:     } 
0555:     if(sortedM!=1){ 
0556:       fprM=mssReopenFPRsort(fprM,4,sfM,hdM->flds->cnt,optTMP.str); 
0557:     } 
0558:  
0559:     /*トラ読み込み*/ 
0560:     statT=mssReadFRD(fprT,frdT); 
0561:  
0562:     /*マスタ読み込み*/ 
0563:     statM=mssReadFldRec(fprM,frM); mstw=0; 
0564:     while(1){ 
0565:  
0566:       /*Tra,Mst両方Endの時*/ 
0567:       if(frdT->eof==1 && statM==EOF) break; 
0568:  
0569:       /*TraだけEndの時*/ 
0570:       if(frdT->eof==1){ 
0571:         if(!optMNL.set) break; 
0572:       } 
0573:  
0574:       /*MstだけEndの時*/ 
0575:       if(statM==EOF){ 
0576:         if(!optTNL.set) break; 
0577:       } 
0578:  
0579:       kc=keyCmp(frdT,frM); 
0580:       if(kc == 1){       /*T>M*/ 
0581:         if(optMNL.set && mstw==0) writeTM(NULL,frM); 
0582:         statM=mssReadFldRec(fprM,frM); mstw=0; 
0583:       }else if(kc ==-1){ /*T<M*/ 
0584:         if(optTNL.set) writeTM(frdT,NULL); 
0585:         statT=mssReadFRD(fprT,frdT); 
0586:         mssGV.inCnt++; 
0587:       }else{             /*T==M*/ 
0588:         writeTM(frdT,frM); 
0589:         mstw=1; 
0590:         statT=mssReadFRD(fprT,frdT); 
0591:         mssGV.inCnt++; 
0592:       } 
0593:     } 
0594:     mssFreeFRD(frdT); 
0595:     mssFreeFldRec(frM); 
0596:   } 
0597:  
0598: /*----------------------------------------------------------------------------*/ 
0599: /*フッター出力&終了処理                                                       */ 
0600: /*----------------------------------------------------------------------------*/ 
0601:   mssWriteFooter(fpw);    /*フッターの出力              */ 
0602:   mssCloseFPR(fprT);      /*入力ファイルのクローズ      */ 
0603:   mssCloseFPR(fprM);      /*入力ファイルのクローズ      */ 
0604:   mssCloseFPW(fpw);       /*出力ファイルのクローズ      */ 
0605:   mssFreeFields(sfT);     /*ソート項目構造体の領域開放  */ 
0606:   mssFreeFields(sfM);     /*ソート項目構造体の領域開放  */ 
0607:   mssFreeHeader(hdT);     /*入力ヘッダ領域開放          */ 
0608:   mssFreeHeader(hdM);     /*入力ヘッダ領域開放          */ 
0609:   mssFreeHeader(hdo);     /*出力ヘッダ領域開放          */ 
0610:   mssFreeOption(opt);     /*オプション領域開放          */ 
0611:   mssShowEndMsg();        /* 完了メッセージ             */ 
0612:   mssEnd(mssExitSuccess); /* 終了                       */ 
0613:   return(0);              /* to avoid warning message   */ 
0614: }