MUSASHI C source: xtcat.c


0001: /*============================================================================*/ 
0002: /* 変更履歴                                                                   */ 
0003: /*----------------------------------------------------------------------------*/ 
0004: /* 1.0 : 新しいAPIに対応 2003/06/20                                           */ 
0005: /*============================================================================*/ 
0006: #include <musashi.h
0007: #include <stdlib.h> 
0008:  
0009: #include <xtcatHelp.h> 
0010: struct mssComHelp comHelp={ 
0011:   "xtcat",        /* コマンド名       */                                     
0012:   "1.1",          /* バージョン       */ 
0013:   HELPT,          /* コマンドタイトル */ 
0014:   HELPS,          /* 要約             */ 
0015:   HELPE,          /* 利用例           */ 
0016:   HELPR,          /* 参照コマンド     */ 
0017:   HELPA,          /* 作者情報         */ 
0018:   HELPB,          /* バグレポート情報 */                                       
0019:   HELPH           /* ホームページ     */ 
0020: }; 
0021:  
0022: extern struct mssGlobalVariables mssGV; 
0023:  
0024: int diffHeaderName(struct mssHeader *hdi,struct mssHeader *hdn){ 
0025:   int i; 
0026:  
0027:   /*項目数が異なれば*/ 
0028:   if(hdi->flds->cnt != hdn->flds->cnt) return(1); 
0029:  
0030:   /*項目名が異なれば*/ 
0031:   for(i=0; i<hdi->flds->cnt; i++){ 
0032:     if( 0!=strcmp(MssFlds2name(hdi->flds,i),MssFlds2name(hdn->flds,i)) ){ 
0033:       return(1); 
0034:     } 
0035:   } 
0036:   return(0); 
0037: } 
0038:  
0039: void setFldConv(int conv[MssFieldMaxCnt],struct mssHeader *hdi,struct mssHeader *hdn){ 
0040:   int i,j; 
0041:   int ino,jno; 
0042:  
0043:   /*初期化:-1は対応する項目がないという意味*/ 
0044:   for(i=0; i<hdi->flds->cnt; i++)conv[i]=-1; 
0045:  
0046:   for(i=0; i<hdi->flds->cnt; i++){ 
0047:     ino=MssFlds2num(hdi->flds,i); 
0048:     for(j=0; j<hdn->flds->cnt; j++){ 
0049:       jno=MssFlds2num(hdn->flds,j); 
0050:       if( 0==strcmp(MssFlds2name(hdi->flds,i),MssFlds2name(hdn->flds,j)) ){ 
0051:         conv[ino]=jno; 
0052:       } 
0053:     } 
0054:   } 
0055: } 
0056:  
0057: int main(int argc, char *argv[]){ 
0058: /*============================================================================*/ 
0059: /* オプション宣言&定義                                                       */ 
0060: /*============================================================================*/ 
0061: /*----------------------------------------------------------------------------*/ 
0062: /* 項目数のみチェックするフラグ                                               */ 
0063: /*----------------------------------------------------------------------------*/ 
0064:   MssOptFLG optCNT={ 
0065:     OFLG,   /* オプションタイプ                                             */ 
0066:     "c",    /* キーワード(複数文字は不可)                                   */ 
0067:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0068:     CNTT,   /* このオプションのタイトル(Helpで表示)                         */ 
0069:     CNTC    /* このオプションのコメント(Helpで表示)                         */ 
0070:   }; 
0071:  
0072: /*----------------------------------------------------------------------------*/ 
0073: /* 同一項目名のみcatするフラグ                                                */ 
0074: /*----------------------------------------------------------------------------*/ 
0075:   MssOptFLG optNAM={ 
0076:     OFLG,   /* オプションタイプ                                             */ 
0077:     "n",    /* キーワード(複数文字は不可)                                   */ 
0078:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0079:     NAMT,   /* このオプションのタイトル(Helpで表示)                         */ 
0080:     NAMC    /* このオプションのコメント(Helpで表示)                         */ 
0081:   }; 
0082:  
0083: /*----------------------------------------------------------------------------*/ 
0084: /* 入力ファイル                                                               */ 
0085: /*----------------------------------------------------------------------------*/ 
0086:   MssOptINF optINF={ 
0087:     OINF,   /* オプションタイプ                                             */ 
0088:     "i",    /* キーワード(複数文字は不可)                                   */ 
0089:     1,      /* 0:オプション, 1:必須                                         */ 
0090:     256,    /* 指定可能の最大ファイル数                                     */ 
0091:     0,      /*1:file not foundのエラーで終了しない 0:する                   */ 
0092:     INFT,   /* このオプションのタイトル(Helpで表示)                         */ 
0093:     INFC    /* このオプションのコメント(Helpで表示)                         */ 
0094:   }; 
0095:  
0096: /*----------------------------------------------------------------------------*/ 
0097: /* 出力ファイル                                                               */ 
0098: /*----------------------------------------------------------------------------*/ 
0099:   MssOptOTF optOTF={ 
0100:     OOTF,   /* オプションタイプ                                             */ 
0101:     "o",    /* キーワード(複数文字は不可)                                   */ 
0102:     0,      /* 0:オプション, 1:必須                                         */ 
0103:     OTFT,   /* このオプションのタイトル(Helpで表示)                         */ 
0104:     OTFC    /* このオプションのコメント(Helpで表示)                         */ 
0105:   }; 
0106:  
0107: /*----------------------------------------------------------------------------*/ 
0108: /* 圧縮出力                                                                   */ 
0109: /*----------------------------------------------------------------------------*/ 
0110:   MssOptFLG optZIP={ 
0111:     OFLG,   /* オプションタイプ                                             */ 
0112:     "z",    /* キーワード(複数文字は不可)                                   */ 
0113:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0114:     ZIPT,   /* このオプションのタイトル(Helpで表示)                         */ 
0115:     ZIPC    /* このオプションのコメント(Helpで表示)                         */ 
0116:   }; 
0117:  
0118:  
0119: /*----------------------------------------------------------------------------*/ 
0120: /* オプションをまとめる                                                       */ 
0121: /*----------------------------------------------------------------------------*/ 
0122:   void *opt[]={&optCNT,&optNAM,&optINF,&optOTF,&optZIP,NULL}; 
0123:  
0124: /*============================================================================*/ 
0125: /* 変数宣言&定義                                                             */ 
0126: /*============================================================================*/ 
0127:   struct mssHeader *hdi; /*一つめの入力ファイル用<head>タグ格納構造体*/ 
0128:   struct mssHeader *hdn; /*二つめ以降の入力ファイル用<head>タグ格納構造体*/ 
0129:   struct mssHeader *hdo; /*出力ファイル用<head>タグ格納構造体*/ 
0130:   struct mssFPR    *fpi; 
0131:   struct mssFPR    *fpn; 
0132:   struct mssFPW    *fpw; 
0133:   struct mssFldRec *fri =NULL; 
0134:   struct mssFldRec *frn =NULL; 
0135:  
0136:   int i,j; 
0137:   int conv[MssFieldMaxCnt]; 
0138:  
0139: /*----------------------------------------------------------------------------*/ 
0140: /* 前処理                                                                     */ 
0141: /*----------------------------------------------------------------------------*/ 
0142:   mssInit(argc,argv,&comHelp);      /* シグナル処理などの初期化     */ 
0143:   mssHelpDoc(opt,&comHelp,argc,argv);    /* ヘルプ                       */ 
0144:   mssSetOption(opt,argc,argv);      /* コマンドオプションの設定     */ 
0145: /*prnOption(opt);*/ 
0146:  
0147:   if( (optCNT.set+optNAM.set) >1 ){ 
0148:     mssShowErrMsg("must choose one from -c,-n"); 
0149:     mssEnd(mssErrorNoDefault); 
0150:   } 
0151:  
0152:   fpi=mssOpenFPR(*(optINF.strList+0),4); /*一つめのファイルオープン*/ 
0153:   hdi=mssReadHeader(fpi);                /*項目名情報の読み込み*/ 
0154: /*prnHeader(hdi);*/ 
0155:  
0156: /*----------------------------------------------------------------------------*/ 
0157: /*出力ヘッダーの作成と出力                                                    */ 
0158: /*----------------------------------------------------------------------------*/ 
0159:   /*入力ヘッダーを出力ヘッダーにコピー*/ 
0160:   hdo=mssInitCpyHeader(hdi); 
0161:  
0162:   /*入力ヘッダの全項目を追加*/ 
0163:   mssAddFieldsByFields(hdo->flds,hdi->flds); 
0164:  
0165:   /*ソート順序は崩れるため、ソート情報をクリア*/ 
0166:   mssClearFieldsSort(hdo->flds); 
0167:  
0168:   /*標準出力オープン+ヘッダーの出力*/ 
0169:   fpw=mssOpenFPW(optOTF.str,optZIP.set,0); 
0170:   mssWriteHeader(hdo, fpw); 
0171:  
0172: /*----------------------------------------------------------------------------*/ 
0173: /*メインルーチン                                                              */ 
0174: /*----------------------------------------------------------------------------*/ 
0175:  
0176:   fri =mssInitFldRec(hdi->flds->cnt); 
0177:   while( EOF!=mssReadFldRec(fpi,fri) ){ 
0178:     mssGV.inCnt++; 
0179:     mssWriteFld(fri->pnt,fri->fldCnt,"\n",fpw); 
0180:     mssGV.outCnt++; 
0181:   } 
0182:   mssFreeFldRec(fri); 
0183:   mssCloseFPR(fpi);/*入力ファイルのクローズ*/ 
0184:  
0185:   for(i=1; i<optINF.cnt; i++){ 
0186:     fpn=mssOpenFPR(*(optINF.strList+i),4); /*ファイルオープン*/ 
0187:     hdn=mssReadHeader(fpn);                /*項目名情報の読み込み*/ 
0188:  
0189:     /*項目数チェックの場合*/ 
0190:     if(optCNT.set){ 
0191:       if(hdi->flds->cnt!=hdn->flds->cnt){ 
0192:         mssShowErrMsg("different number of fields on header : %s", 
0193:                        *(optINF.strList+i)); 
0194:         mssEnd(mssErrorNoDefault); 
0195:       } 
0196:       frn =mssInitFldRec(hdn->flds->cnt); 
0197:       while( EOF!=mssReadFldRec(fpn,frn) ){ 
0198:         mssGV.inCnt++; 
0199:         mssWriteFld(frn->pnt,frn->fldCnt,"\n",fpw); 
0200:         mssGV.outCnt++; 
0201:       } 
0202:  
0203:     /*項目名チェックの場合*/ 
0204:     }else if(optNAM.set){ 
0205:       setFldConv(conv,hdi,hdn); 
0206:       frn =mssInitFldRec(hdn->flds->cnt); 
0207:       while( EOF!=mssReadFldRec(fpn,frn) ){ 
0208:         mssGV.inCnt++; 
0209:         for(j=0; j<hdi->flds->cnt-1; j++){ 
0210:           if(conv[j]==-1) mssWriteNull(fpw); 
0211:           else            mssWriteStr(*(frn->pnt+conv[j]),fpw); 
0212:           mssWriteDlm(fpw); 
0213:         } 
0214:         if(conv[j]==-1) mssWriteNull(fpw); 
0215:         else            mssWriteStr(*(frn->pnt+conv[j]),fpw); 
0216:         mssWriteRet(fpw); 
0217:         mssGV.outCnt++; 
0218:       } 
0219:  
0220:     /*デフォルト*/ 
0221:     }else{ 
0222:       if(diffHeaderName(hdi,hdn)){ 
0223:         mssShowErrMsg("different type of header detected : %s", 
0224:                                                       *(optINF.strList+i)); 
0225:         mssEnd(mssErrorNoDefault); 
0226:       } 
0227:       frn =mssInitFldRec(hdn->flds->cnt); 
0228:       while( EOF!=mssReadFldRec(fpn,frn) ){ 
0229:         mssGV.inCnt++; 
0230:         mssWriteFld(frn->pnt,frn->fldCnt,"\n",fpw); 
0231:         mssGV.outCnt++; 
0232:       } 
0233:     } 
0234:  
0235:     mssCloseFPR(fpn);/*入力ファイルのクローズ*/ 
0236:     mssFreeFldRec(frn); 
0237:     mssFreeHeader(hdn); 
0238:   } 
0239:  
0240: /*----------------------------------------------------------------------------*/ 
0241: /*フッター出力&終了処理                                                       */ 
0242: /*----------------------------------------------------------------------------*/ 
0243: /*printf("allocCnt=%d\n",getAllocCnt());*/ 
0244:   mssWriteFooter(fpw);    /*フッターの出力           */ 
0245:   mssCloseFPW(fpw);       /*出力ファイルのクローズ   */ 
0246:   mssFreeHeader(hdi);     /*入力ヘッダ領域開放       */ 
0247:   mssFreeHeader(hdo);     /*出力ヘッダ領域開放       */ 
0248:   mssFreeOption(opt);     /*オプション領域開放       */ 
0249:   mssShowEndMsg();        /*完了メッセージ           */ 
0250:   mssEnd(mssExitSuccess); /*終了                     */ 
0251:   return(0);              /* to avoid warning message*/ 
0252: }