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