MUSASHI C source: xt2xml.c


0001: /*============================================================================*/ 
0002: /* 変更履歴                                                                   */ 
0003: /*----------------------------------------------------------------------------*/ 
0004: /* 1.0 : 新しいAPIに対応 2003/06/20                                           */ 
0005: /* 1.1 : まったく動作しなかったエラー修正(APIにて) 
0006: /*============================================================================*/ 
0007:  
0008: #include <musashi.h
0009: #include <stdlib.h> 
0010: #include <string.h> 
0011:  
0012: #include <xt2xmlHelp.h> 
0013: struct mssComHelp comHelp={ 
0014:   "xt2xml",       /* コマンド名       */                                     
0015:   "1.1",          /* バージョン       */ 
0016:   HELPT,          /* コマンドタイトル */ 
0017:   HELPS,          /* 要約             */ 
0018:   HELPE,          /* 利用例           */ 
0019:   HELPR,          /* 参照コマンド     */ 
0020:   HELPA,          /* 作者情報         */ 
0021:   HELPB,          /* バグレポート情報 */                                       
0022:   HELPH           /* ホームページ     */ 
0023: }; 
0024:  
0025: extern struct mssGlobalVariables mssGV; 
0026: static int spcCnt=0; 
0027:  
0028: void writeXmlKeyTag(struct mssFldRecDbl *frd, MssOptKEY *optKEY, struct mssFPW *fpw){ 
0029:  
0030:   int i,fn,flg; 
0031:   int wflg[256]; /*ネストの限界*/ 
0032:   struct mssXmlTag *xmlTag; 
0033:  
0034:   /*書き出すキーの番号を決定する*/ 
0035:   if(frd->firstRead || frd->eof){ 
0036:     for(i=0; i<optKEY->flds->cnt; i++) wflg[i]=1; 
0037:   }else{ 
0038:     for(i=0; i<optKEY->flds->cnt; i++){ 
0039:       fn=MssFlds2num(optKEY->flds,i); 
0040:       if( 0 != strcmp(*(frd->pnt[frd->new]+fn),*(frd->pnt[frd->old]+fn)) ){ 
0041:         wflg[i]=1; 
0042:       }else{ 
0043:         wflg[i]=0; 
0044:       } 
0045:     } 
0046:     flg=0; 
0047:     for(i=0; i<optKEY->flds->cnt; i++){ 
0048:       if(wflg[i]) flg=1; 
0049:       if(flg)wflg[i]=1; 
0050:     } 
0051:   } 
0052:  
0053:   /*終了タグの書き出し*/ 
0054:   if(!frd->firstRead){ 
0055:     for(i=optKEY->flds->cnt-1; i>=0; i--){ 
0056:       if(wflg[i]){ 
0057:         spcCnt--; 
0058:         xmlTag=mssInitXmlTag(MssFlds2name(optKEY->flds,i),NULL); 
0059:         mssWriteXmlIndent(spcCnt,fpw); 
0060:         mssWriteXmlEndTag(xmlTag,NULL,fpw); 
0061:         mssFreeXmlTag(xmlTag); 
0062:         mssWriteRet(fpw); 
0063:         mssGV.outCnt++; 
0064:       } 
0065:     } 
0066:   } 
0067:  
0068:   /*開始タグの書き出し*/ 
0069:   if(!frd->eof){ 
0070:     for(i=0; i<optKEY->flds->cnt; i++){ 
0071:       if(wflg[i]){ 
0072:         fn=MssFlds2num(optKEY->flds,i); 
0073:         xmlTag=mssInitXmlTag(MssFlds2name(optKEY->flds,i),NULL); 
0074:         mssAddXmlTagAttributeStr(xmlTag, "id", *(frd->pnt[frd->new]+fn), NULL); 
0075:         mssWriteXmlIndent(spcCnt,fpw); 
0076:         mssWriteXmlStartTag(xmlTag,NULL,fpw); 
0077:         mssFreeXmlTag(xmlTag); 
0078:         mssWriteRet(fpw); 
0079:         mssGV.outCnt++; 
0080:         spcCnt++; 
0081:       } 
0082:     } 
0083:   } 
0084: } 
0085:  
0086: void writeXmlFld( 
0087:   struct mssFldRecDbl *frd, 
0088:   MssOptKEY *optKEY, 
0089:   struct mssHeader *hd, 
0090:   struct mssXmlTag *lineTag, 
0091:   struct mssFPW *fpw){ 
0092:  
0093:   int i,j; 
0094:   int wflg[256]; /*ネストの限界*/ 
0095:  
0096:   /* -k で指定した項目を除いた全項目番号を調べる */ 
0097:   for(i=0; i<frd->fldCnt; i++){ 
0098:     wflg[i]=1; 
0099:     for(j=0; j<optKEY->flds->cnt; j++){ 
0100:       if(i==MssFlds2num(optKEY->flds,j)){ 
0101:         wflg[i]=0; 
0102:         break; 
0103:       } 
0104:     } 
0105:   } 
0106:  
0107:   /* 行タグが指定されていれば出力する */ 
0108:   if(lineTag!=NULL){ 
0109:     mssWriteXmlIndent(spcCnt,fpw); 
0110:     mssWriteXmlStartTag(lineTag,NULL,fpw); 
0111:     mssWriteRet(fpw); 
0112:     mssGV.outCnt++; 
0113:     spcCnt++; 
0114:   } 
0115:  
0116:   /* 項目タグ&値を出力する */ 
0117:   for(i=0; i<hd->flds->cnt; i++){ 
0118:     if(wflg[i]){ 
0119:       if(**(frd->pnt[frd->new]+i)!=MssNullChr){ 
0120:         mssWriteXmlTagStr(spcCnt, MssFlds2name(hd->flds, i), 
0121:                         *(frd->pnt[frd->new]+i), 1, NULL, fpw); 
0122:         mssGV.outCnt++; 
0123:       } 
0124:     } 
0125:   } 
0126:  
0127:   /* 行タグが指定されていればそのENDタグを出力する */ 
0128:   if(lineTag!=NULL){ 
0129:     spcCnt--; 
0130:     mssWriteXmlIndent(spcCnt,fpw); 
0131:     mssWriteXmlEndTag(lineTag,NULL,fpw); 
0132:     mssWriteRet(fpw); 
0133:     mssGV.outCnt++; 
0134:   } 
0135: } 
0136:  
0137: int main(int argc, char *argv[]){ 
0138: /*============================================================================*/ 
0139: /* オプション宣言&定義                                                       */ 
0140: /*============================================================================*/ 
0141: /*----------------------------------------------------------------------------*/ 
0142: /* キー項目                                                                   */ 
0143: /*----------------------------------------------------------------------------*/ 
0144:   MssOptKEY optKEY={ 
0145:     OKEY,   /* オプションタイプ                                             */ 
0146:     "k",    /* キーワード(複数文字は不可)                                   */ 
0147:     0,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0148:     MssFieldMaxCnt, /* 指定可能な最大項目数                                 */ 
0149:     "i",    /* 対象とする入力データのキーワード(GUIで利用)                  */ 
0150:     2,      /* デフォルト(このオプションが指定されなかったときの動作を指定) */ 
0151:             /* 1:全ての行を異るキー値として扱う                             */ 
0152:             /* 2:全ての行を同じキー値として扱う)                            */ 
0153:     KEYT,   /* このオプションのタイトル(Helpで表示)                         */ 
0154:     KEYC    /* このオプションのコメント(Helpで表示)                         */ 
0155:   }; 
0156:  
0157: /*----------------------------------------------------------------------------*/ 
0158: /* 行タグ名                                                                   */ 
0159: /*----------------------------------------------------------------------------*/ 
0160:   MssOptSTR optLTG={ 
0161:     OSTR,   /* オプションタイプ                                             */ 
0162:     "L",    /* キーワード(複数文字は不可)                                   */ 
0163:     0,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0164:     NULL,   /* デフォルト                                                   */ 
0165:     1,      /* 文字列の最小長                                               */ 
0166:     50,     /* 文字列の最大長                                               */ 
0167:     LTGT,   /* このオプションのタイトル(Helpで表示)                         */ 
0168:     LTGC    /* このオプションのコメント(Helpで表示)                         */ 
0169:   }; 
0170:  
0171: /*----------------------------------------------------------------------------*/ 
0172: /* ルートタグ名                                                               */ 
0173: /*----------------------------------------------------------------------------*/ 
0174:   MssOptSTR optRTG={ 
0175:     OSTR,   /* オプションタイプ                                             */ 
0176:     "R",    /* キーワード(複数文字は不可)                                   */ 
0177:     0,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0178:     "root", /* デフォルト                                                   */ 
0179:     1,      /* 文字列の最小長                                               */ 
0180:     50,     /* 文字列の最大長                                               */ 
0181:     RTGT,   /* このオプションのタイトル(Helpで表示)                         */ 
0182:     RTGC    /* このオプションのコメント(Helpで表示)                         */ 
0183:   }; 
0184:       
0185: /*----------------------------------------------------------------------------*/ 
0186: /* シーケンシャル処理                                                         */ 
0187: /*----------------------------------------------------------------------------*/ 
0188:   MssOptFLG optSEQ={ 
0189:     OFLG,   /* オプションタイプ                                             */ 
0190:     "q",    /* キーワード(複数文字は不可)                                   */ 
0191:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0192:     SEQT,   /* このオプションのタイトル(Helpで表示)                         */ 
0193:     SEQC    /* このオプションのコメント(Helpで表示)                         */ 
0194:   }; 
0195:  
0196: /*----------------------------------------------------------------------------*/ 
0197: /* 入力ファイル                                                               */ 
0198: /*----------------------------------------------------------------------------*/ 
0199:   MssOptINF optINF={ 
0200:     OINF,   /* オプションタイプ                                             */ 
0201:     "i",    /* キーワード(複数文字は不可)                                   */ 
0202:     0,      /* 0:オプション, 1:必須                                         */ 
0203:     1,      /* 指定可能の最大ファイル数                                     */ 
0204:     0,      /*1:file not foundのエラーで終了しない 0:する                   */ 
0205:     INFT,   /* このオプションのタイトル(Helpで表示)                         */ 
0206:     INFC    /* このオプションのコメント(Helpで表示)                         */ 
0207:   }; 
0208:  
0209: /*----------------------------------------------------------------------------*/ 
0210: /* 出力ファイル                                                               */ 
0211: /*----------------------------------------------------------------------------*/ 
0212:   MssOptOTF optOTF={ 
0213:     OOTF,   /* オプションタイプ                                             */ 
0214:     "o",    /* キーワード(複数文字は不可)                                   */ 
0215:     0,      /* 0:オプション, 1:必須                                         */ 
0216:     OTFT,   /* このオプションのタイトル(Helpで表示)                         */ 
0217:     OTFC    /* このオプションのコメント(Helpで表示)                         */ 
0218:   }; 
0219:  
0220: /*----------------------------------------------------------------------------*/ 
0221: /* 圧縮出力                                                                   */ 
0222: /*----------------------------------------------------------------------------*/ 
0223:   MssOptFLG optZIP={ 
0224:     OFLG,   /* オプションタイプ                                             */ 
0225:     "z",    /* キーワード(複数文字は不可)                                   */ 
0226:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0227:     ZIPT,   /* このオプションのタイトル(Helpで表示)                         */ 
0228:     ZIPC    /* このオプションのコメント(Helpで表示)                         */ 
0229:   }; 
0230:  
0231: /*----------------------------------------------------------------------------*/ 
0232: /* ワークファイル用ディレクトリ名                                             */ 
0233: /*----------------------------------------------------------------------------*/ 
0234:   MssOptSTR optTMP={ 
0235:     OSTR,   /* オプションタイプ                                             */ 
0236:     "T",    /* キーワード(複数文字は不可)                                   */ 
0237:     0,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0238:     MssTempDir, /* デフォルト                                               */ 
0239:     1,      /* 文字列の最小長                                               */ 
0240:     MssFileNameMaxLen,  /* 文字列の最大長                                   */ 
0241:     TMPT,   /* このオプションのタイトル(Helpで表示)                         */ 
0242:     TMPC    /* このオプションのコメント(Helpで表示)                         */ 
0243:   }; 
0244:      
0245: /*----------------------------------------------------------------------------*/ 
0246: /* オプションをまとめる                                                       */ 
0247: /*----------------------------------------------------------------------------*/ 
0248:   void *opt[]={&optKEY,&optLTG,&optRTG,&optSEQ, 
0249:                &optINF,&optOTF,&optZIP,&optTMP,NULL}; 
0250:      
0251: /*============================================================================*/ 
0252: /* 変数宣言&定義                                                             */ 
0253: /*============================================================================*/ 
0254:   struct mssHeader *hdi; /*入力ファイル用<head>タグ格納構造体*/ 
0255:   struct mssFPR    *fpr; /*入力ファイル構造体*/ 
0256:   struct mssFPW    *fpw; /*出力ファイル構造体*/ 
0257:   struct mssFields *sf;  /*ソート項目構造体  */ 
0258:  
0259:   struct mssFldRecDbl *frd; /*項目-二行バッファ構造体*/ 
0260:  
0261:   int sorted; 
0262:   struct mssXmlTag *rootTag; 
0263:   struct mssXmlTag *lineTag; 
0264:  
0265:   int lineNo; 
0266:   char *tmp; 
0267:  
0268: /*------------------------------------------------------------------------------ 
0269: パラメータ処理 
0270: ------------------------------------------------------------------------------*/ 
0271:   mssInit(argc,argv,&comHelp);       /* シグナル処理などの初期化              */ 
0272:   mssHelpDoc(opt,&comHelp,argc,argv);/* ヘルプ                                */ 
0273:   mssSetOption(opt,argc,argv);       /* コマンドオプションの設定              */ 
0274:   fpr=mssOpenFPR(optINF.str,4);      /* 入力ファイルオープン                  */ 
0275:   hdi=mssReadHeader(fpr);            /* ヘッダの読み込み                      */ 
0276:   mssSetOptKey(&optKEY, hdi);        /* -k 項目をヘッダー項目に関連づける     */ 
0277:  
0278:   /*ソート項目の作成*/ 
0279:   sf=mssInitFields(); 
0280:   mssAddFieldsByFields(sf,optKEY.flds); /* -k 項目をソート項目としてセット    */ 
0281:   mssSetFieldsSortPriority(sf);         /* ソート優先順位番号を登録順にふる   */ 
0282:   sorted=mssChkSorted(sf,hdi);          /* ソート済かチェック                 */ 
0283:    
0284: /*mssShowFields(sf);*/ 
0285: /*mssShowOption(opt);*/ 
0286: /*mssShowHeader(hdi);*/ 
0287:      
0288: /*----------------------------------------------------------------------------*/ 
0289: /*前処理                                                                      */ 
0290: /*----------------------------------------------------------------------------*/ 
0291:   lineTag=mssInitXmlTag(optLTG.str,NULL); /*行タグの設定*/ 
0292:  
0293:   /*グローバルタグの設定*/ 
0294:   rootTag=mssInitXmlTagByOpt(optRTG.str,NULL); 
0295:  
0296: /*----------------------------------------------------------------------------*/ 
0297: /*出力ヘッダーの作成と出力                                                    */ 
0298: /*----------------------------------------------------------------------------*/ 
0299:   /*標準出力オープン+ヘッダーの出力*/ 
0300:   fpw=mssOpenFPW(optOTF.str,optZIP.set,0); 
0301:  
0302: /*----------------------------------------------------------------------------*/ 
0303: /*メインルーチン                                                              */ 
0304: /*----------------------------------------------------------------------------*/ 
0305:   /*ソートが必用ならばソートしてソート済みファイルとしてオープン*/ 
0306:   if( !optSEQ.set && !sorted) 
0307:     fpr=mssReopenFPRsort(fpr,4,sf,hdi->flds->cnt,optTMP.str); 
0308:  
0309:   /*xmlヘッダーの書き出し*/ 
0310:   mssWriteXmlDeclaration(MssXmlDefVer,MssXmlDefEnc,fpw); 
0311:   mssGV.outCnt++; 
0312:  
0313:   /*グローバルタグの書き出し*/ 
0314:   mssWriteXmlStartTag(rootTag,NULL,fpw); 
0315:   mssWriteRet(fpw); 
0316:   mssGV.outCnt++; 
0317:   spcCnt++; 
0318:  
0319:   /*タイトルの出力*/ 
0320:   mssWriteXmlTagStr(spcCnt,"title",hdi->title,1,NULL,fpw); 
0321:   tmp=hdi->title; 
0322:   while(*tmp!='\0') if(*tmp++=='\n') mssGV.outCnt++; 
0323:   mssGV.outCnt++; 
0324:  
0325:   /*コメントの出力*/ 
0326:   mssWriteXmlTagStr(spcCnt,"comment",hdi->comment,1,NULL,fpw); 
0327:   tmp=hdi->comment; 
0328:   while(*tmp!='\0') if(*tmp++=='\n') mssGV.outCnt++; 
0329:   mssGV.outCnt++; 
0330:  
0331:   frd=mssInitFRD(hdi->flds->cnt); 
0332:   lineNo=1; 
0333:   while(EOF!=mssReadFRD(fpr,frd)){ 
0334:     mssGV.inCnt++; 
0335:  
0336:     /*キーブレイク時の処理*/ 
0337:     if(mssKeyBreak(frd, &optKEY)){ 
0338:       writeXmlKeyTag(frd,&optKEY,fpw); 
0339:       if(frd->eof) break; 
0340:       lineNo=1; 
0341:     } 
0342:  
0343:     /*最初の一行目はkeyBreakに引っかからないため*/ 
0344:     if(frd->firstRead) writeXmlKeyTag(frd,&optKEY,fpw); 
0345:  
0346:     /*通常行の処理(集計値の計算)*/ 
0347:     mssAddXmlTagAttributeInt(lineTag,"no", lineNo,NULL); 
0348:     writeXmlFld(frd,&optKEY,hdi,lineTag,fpw); 
0349:     lineNo++; 
0350:   } 
0351:   mssFreeFRD(frd); 
0352:  
0353:   /*グローバルタグの書き出し*/ 
0354:   spcCnt--; 
0355:   mssWriteXmlIndent(spcCnt,fpw); 
0356:   mssWriteXmlEndTag(rootTag,NULL,fpw); 
0357:   mssWriteRet(fpw); 
0358:   mssGV.outCnt++; 
0359:  
0360:   mssFreeXmlTag(rootTag); 
0361:   mssFreeXmlTag(lineTag); 
0362:  
0363: /*----------------------------------------------------------------------------*/ 
0364: /*フッター出力&終了処理                                                       */ 
0365: /*----------------------------------------------------------------------------*/ 
0366:   mssCloseFPW(fpw);       /*出力ファイルのクローズ      */ 
0367:   mssCloseFPR(fpr);       /*入力ファイルのクローズ      */ 
0368:   mssFreeFields(sf);      /*ソート項目構造体の領域開放  */ 
0369:   mssFreeHeader(hdi);     /*入力ヘッダ領域開放          */ 
0370:   mssFreeOption(opt);     /*オプション領域開放          */ 
0371:   mssShowEndMsg();        /* 完了メッセージ             */ 
0372:   mssEnd(mssExitSuccess); /* 終了                       */ 
0373:   return(0);              /* to avoid warning message   */ 
0374: }