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