MUSASHI C source: xmlenc.c
0001: /*============================================================================*/
0002: /* 変更履歴 */
0003: /*----------------------------------------------------------------------------*/
0004: /* 1.0 : 新しいAPIに対応 */
0005: /*============================================================================*/
0006:
0007: #include <musashi.h>
0008: #include <stdio.h>
0009: #include <stdlib.h>
0010: #include <string.h>
0011: #include <libxml/parser.h>
0012: #include <libxml/parserInternals.h>
0013: #include <libxml/encoding.h>
0014: #include <iconv.h>
0015: #include <errno.h>
0016: #include <glob.h>
0017:
0018: #include <xmlencHelp.h>
0019: struct mssComHelp comHelp={
0020: "xmlenc", /* コマンド名 */
0021: "1.0", /* バージョン */
0022: HELPT, /* コマンドタイトル */
0023: HELPS, /* 要約 */
0024: HELPE, /* 利用例 */
0025: HELPR, /* 参照コマンド */
0026: HELPA, /* 作者情報 */
0027: HELPB, /* バグレポート情報 */
0028: HELPH /* ホームページ */
0029: };
0030:
0031: #define UNDEF 0
0032: #define MAX_NEST 32
0033: #define LOCAL_BUF 256
0034: #define EncMax MssFieldMaxLen /*iconvで使う出力用文字列長*/
0035:
0036: /*----------------------------------------------------------------------------*/
0037: /* グローバル変数 */
0038: /*----------------------------------------------------------------------------*/
0039: extern xmlParserCtxtPtr ctxt;
0040: extern struct mssGlobalVariables mssGV;
0041:
0042: struct mssFPW *fpw; /*出力ファイル構造体*/
0043: iconv_t *icid; /*iconv用 変換ハンドラ*/
0044: char *inEnc=NULL; /*エンコーディング*/
0045: char *inVer=NULL; /*バージョン*/
0046:
0047: /*----------------------------------------------------------------------------*/
0048: /* encoding名 */
0049: /*----------------------------------------------------------------------------*/
0050: MssOptSTR optENC={
0051: OSTR, /* オプションタイプ */
0052: "e", /* キーワード(複数文字は不可) */
0053: 1, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0054: NULL , /* デフォルト */
0055: 1, /* 文字列の最小長 */
0056: 50, /* 文字列の最大長 */
0057: ENCT, /* このオプションのタイトル(Helpで表示) */
0058: ENCC /* このオプションのコメント(Helpで表示) */
0059: };
0060:
0061: /*----------------------------------------------------------------------------*/
0062: /* 入力ファイル */
0063: /*----------------------------------------------------------------------------*/
0064: MssOptINF optINF={
0065: OINF, /* オプションタイプ */
0066: "i", /* キーワード(複数文字は不可) */
0067: 0, /* 0:オプション, 1:必須 */
0068: 1, /* 指定可能の最大ファイル数 */
0069: 0, /*1:file not foundのエラーで終了しない 0:する */
0070: INFT, /* このオプションのタイトル(Helpで表示) */
0071: INFC /* このオプションのコメント(Helpで表示) */
0072: };
0073:
0074: /*----------------------------------------------------------------------------*/
0075: /* 出力ファイル */
0076: /*----------------------------------------------------------------------------*/
0077: MssOptOTF optOTF={
0078: OOTF, /* オプションタイプ */
0079: "o", /* キーワード(複数文字は不可) */
0080: 0, /* 0:オプション, 1:必須 */
0081: OTFT, /* このオプションのタイトル(Helpで表示) */
0082: OTFC /* このオプションのコメント(Helpで表示) */
0083: };
0084:
0085: /*----------------------------------------------------------------------------*/
0086: /* 圧縮出力 */
0087: /*----------------------------------------------------------------------------*/
0088: MssOptFLG optZIP={
0089: OFLG, /* オプションタイプ */
0090: "z", /* キーワード(複数文字は不可) */
0091: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0092: ZIPT, /* このオプションのタイトル(Helpで表示) */
0093: ZIPC /* このオプションのコメント(Helpで表示) */
0094: };
0095:
0096: /*----------------------------------------------------------------------------*/
0097: /* オプションをまとめる */
0098: /*----------------------------------------------------------------------------*/
0099: void *opt[]={&optENC,&optINF,&optOTF,&optZIP,NULL};
0100:
0101: /*----------------------------------------------------------------------------*/
0102: /* 構造体 */
0103: /*----------------------------------------------------------------------------*/
0104: typedef struct _XmlState {
0105: int level;
0106: int crFlg;
0107: } XmlState;
0108:
0109: /*----------------------------------------------------------------------------*/
0110: /* SAX ハンドラー */
0111: /*----------------------------------------------------------------------------*/
0112: void start_doc(XmlState *state){
0113:
0114: inEnc=mssStrdup((char *)ctxt->input->encoding);
0115: inVer=mssStrdup((char *)ctxt->version);
0116: mssWriteXmlDeclaration( inVer, optENC.str, fpw );
0117:
0118: /*出力のiconvオープン*/
0119: icid=iconv_open(optENC.str,"UTF-8");
0120: if((int)icid==-1) {
0121: mssShowErrMsg("encoding type error in iconv_open");
0122: mssEnd(mssErrorNoDefault);
0123: }
0124: }
0125:
0126: void end_doc(XmlState *state){
0127:
0128: if(icid!=NULL) iconv_close(icid);
0129: }
0130:
0131:
0132: /*エレメント start */
0133: void start_element(XmlState *state, char *fullname, char **atts){
0134: struct mssXmlTag *xmlTag;
0135: int i;
0136:
0137: mssGV.inCnt++;
0138: if(state->crFlg){
0139: mssWriteRet(fpw);
0140: state->crFlg=0;
0141: }
0142:
0143: mssWriteXmlIndent(state->level,fpw);
0144: xmlTag=mssInitXmlTag(fullname,NULL);
0145: if(atts!=NULL){
0146: for(i=0;;i++){
0147: if(*(atts+2*i+0)==NULL) break;
0148: if(*(atts+2*i+1)==NULL) break;
0149: mssAddXmlTagAttributeStr(xmlTag,*(atts+2*i),*(atts+2*i+1),NULL);
0150: }
0151: }
0152: mssWriteXmlStartTag(xmlTag,icid,fpw);
0153: mssFreeXmlTag(xmlTag);
0154:
0155: mssGV.outCnt++;
0156: state->level++;
0157: }
0158:
0159: /*エレメント end */
0160: void end_element(XmlState *state, char *fullname, char **atts){
0161: struct mssXmlTag *xmlTag;
0162:
0163: state->level--;
0164:
0165: if(state->crFlg){
0166: mssWriteRet(fpw);
0167: mssWriteXmlIndent(state->level,fpw);
0168: state->crFlg=0;
0169: }
0170:
0171: xmlTag=mssInitXmlTag(fullname,NULL);
0172: mssWriteXmlEndTag(xmlTag,icid,fpw);
0173: mssFreeXmlTag(xmlTag);
0174:
0175: if(state->level==0){
0176: mssWriteRet(fpw);
0177: }
0178: }
0179:
0180: void start_characters(XmlState *state, xmlChar *chars, int len){
0181: char *tmp;
0182:
0183: switch(*chars){
0184: case '\n':
0185: state->crFlg=1; break;
0186: case '&':
0187: mssWriteStr("&",fpw); break;
0188: case '>':
0189: mssWriteStr(">",fpw); break;
0190: case '<':
0191: mssWriteStr("<",fpw); break;
0192: case '\'':
0193: mssWriteStr("'",fpw); break;
0194: case '"':
0195: mssWriteStr(""",fpw); break;
0196: default:
0197: tmp=mssNencoding(chars,len,icid);
0198: mssWriteStr(tmp,fpw);
0199: mssFree(tmp);
0200: }
0201: }
0202:
0203: /*sax error handler*/
0204: #include "saxerror.h"
0205:
0206: static xmlSAXHandler SAXFunctions = {
0207: NULL, /* internalSubset */
0208: NULL, /* isStandalone */
0209: NULL, /* hasInternalSubset */
0210: NULL, /* hasExternalSubset */
0211: NULL, /* resolveEntity */
0212: NULL, /* getEntity */
0213: NULL, /* entityDecl */
0214: NULL, /* notationDecl */
0215: NULL, /* attributeDecl */
0216: NULL, /* elementDecl */
0217: NULL, /* unparsedEntityDecl */
0218: NULL, /* setDocumentLocator */
0219: (startDocumentSAXFunc)start_doc, /* startDocument */
0220: (endDocumentSAXFunc)end_doc, /* endDocument */
0221: (startElementSAXFunc)start_element, /* startElement */
0222: (endElementSAXFunc)end_element, /* endElement */
0223: NULL, /* reference */
0224: (charactersSAXFunc) start_characters, /* characters */
0225: NULL, /* ignorableWhitespace */
0226: NULL, /* processingInstruction */
0227: NULL, /* comment */
0228: (warningSAXFunc) xmlSaxErrEnd, /* xmlParserWarning */
0229: (errorSAXFunc) xmlSaxErrEnd, /* xmlParserError */
0230: (fatalErrorSAXFunc) xmlSaxErrEnd, /* xmlParserError */
0231: NULL, /* getParameterEntity */
0232: };
0233:
0234: int main(int argc, char *argv[]){
0235:
0236: XmlState *state;
0237:
0238: /*----------------------------------------------------------------------------*/
0239: /* 前処理 */
0240: /*----------------------------------------------------------------------------*/
0241: mssInit(argc,argv,&comHelp); /* シグナル処理などの初期化 */
0242: mssHelpDoc(opt,&comHelp,argc,argv); /* ヘルプ */
0243: mssSetOption(opt,argc,argv); /* コマンドオプションの設定 */
0244:
0245: fpw=mssOpenFPW(optOTF.str,optZIP.set,0); /*標準出力オープン*/
0246:
0247: /*----------------------------------------------------------------------------*/
0248: /*メインルーチン */
0249: /*----------------------------------------------------------------------------*/
0250:
0251: state=mssCalloc(sizeof(XmlState),"xml2xt");
0252:
0253: if(optINF.set){
0254: ctxt=(xmlParserCtxtPtr)xmlCreateFileParserCtxt(optINF.str);
0255: }else{
0256: ctxt=(xmlParserCtxtPtr)xmlCreateFileParserCtxt("/dev/stdin");
0257: }
0258: if(!ctxt){
0259: mssShowErrMsg("not xml file\n");
0260: mssEnd(mssErrorNoDefault);
0261: }
0262: ctxt->sax=&SAXFunctions;
0263:
0264: ctxt->userData=state;
0265: xmlParseDocument(ctxt);
0266: ctxt->sax=NULL;
0267: xmlFreeParserCtxt(ctxt);
0268:
0269: mssFree(inEnc);
0270: mssFree(inVer);
0271: mssFree(state);
0272:
0273: /*----------------------------------------------------------------------------*/
0274: /*フッター出力&終了処理 */
0275: /*----------------------------------------------------------------------------*/
0276: mssCloseFPW(fpw); /*出力ファイルのクローズ */
0277: mssFreeOption(opt); /*オプション領域開放 */
0278: mssShowEndMsg(); /* 完了メッセージ */
0279: return(0); /* to avoid warning message */
0280: }