MUSASHI C source: xtcal.c
0001:
0002: /*============================================================================*/
0003: /* 変更履歴 */
0004: /*----------------------------------------------------------------------------*/
0005: /* 1.0 : 新しいAPIに対応 */
0006: /*============================================================================*/
0007: #include <musashi.h>
0008: #include <string.h>
0009:
0010: #include <xtcalHelp.h>
0011: struct mssComHelp comHelp={
0012: "xtcal", /* コマンド名 */
0013: "1.0", /* バージョン */
0014: HELPT, /* コマンドタイトル */
0015: HELPS, /* 要約 */
0016: HELPE, /* 利用例 */
0017: HELPR, /* 参照コマンド */
0018: HELPA, /* 作者情報 */
0019: HELPB, /* バグレポート情報 */
0020: HELPH /* ホームページ */
0021: };
0022:
0023: extern struct mssGlobalVariables mssGV;
0024:
0025: int main(int argc, char *argv[]){
0026: /*============================================================================*/
0027: /* オプション宣言&定義 */
0028: /*============================================================================*/
0029: /*----------------------------------------------------------------------------*/
0030: /* キー項目 */
0031: /*----------------------------------------------------------------------------*/
0032: MssOptKEY optKEY={
0033: OKEY, /* オプションタイプ */
0034: "k", /* キーワード(複数文字は不可) */
0035: 0, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0036: MssFieldMaxCnt, /* 指定可能な最大項目数 */
0037: "i", /* 対象とする入力データのキーワード(GUIで利用) */
0038: 1, /* デフォルト(このオプションが指定されなかったときの動作を指定) */
0039: /* 1:全ての行を異るキー値として扱う */
0040: /* 2:全ての行を同じキー値として扱う) */
0041: KEYT, /* このオプションのタイトル(Helpで表示) */
0042: KEYC /* このオプションのコメント(Helpで表示) */
0043: };
0044:
0045: /*----------------------------------------------------------------------------*/
0046: /* ソート項目 */
0047: /*----------------------------------------------------------------------------*/
0048: MssOptFLD optSRT={
0049: OFLD, /* オプションタイプ */
0050: "s", /* キーワード(複数文字は不可) */
0051: 0, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0052: MssFieldMaxCnt, /* 指定可能な最大項目数 */
0053: "i", /* 対象とする入力データのキーワード(GUIで利用) */
0054: 0, /* 正規表現を許可するかどうか(0:不可,1:可) */
0055: 0, /* 新項目名を指定できるかどうか(0:不可,1:可) */
0056: "n,r", /* 項目オプション(%以下)で指定可能な文字 */
0057: /* ex) 指定不可の場合はNULL, "nr": "-f 項目名%rn"の指定可能 */
0058: SRTT, /* このオプションのタイトル(Helpで表示) */
0059: SRTC, /* このオプションのコメント(Helpで表示) */
0060: SRTF /* フラグについての説明(Helpで表示)複数の場合はカンマで区切る */
0061: };
0062:
0063: /*----------------------------------------------------------------------------*/
0064: /* 計算式 */
0065: /*----------------------------------------------------------------------------*/
0066: MssOptSTR optCAL={
0067: OSTR, /* オプションタイプ */
0068: "c", /* キーワード(複数文字は不可) */
0069: 1, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0070: NULL, /* デフォルト */
0071: 1, /* 文字列の最小長 */
0072: 256, /* 文字列の最大長 */
0073: CALT, /* このオプションのタイトル(Helpで表示) */
0074: CALC /* このオプションのコメント(Helpで表示) */
0075: };
0076:
0077: /*----------------------------------------------------------------------------*/
0078: /* 新項目名 */
0079: /*----------------------------------------------------------------------------*/
0080: MssOptSLS optFNM={
0081: OSLS, /* オプションタイプ */
0082: "a", /* キーワード(複数文字は不可) */
0083: 2, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0084: NULL, /* デフォルト(文字列) */
0085: 1, /* カンマで区切られる要素数の最大値 */
0086: 1, /* 各要素の文字列長の最小値 */
0087: MssFieldNameMaxLen,/* 各要素の文字列長の最大値 */
0088: 0, /* 1:要素にコロンを指定できる,0:不可 ex) aaaa:xxxxx */
0089: FNMT, /* このオプションのタイトル(Helpで表示) */
0090: FNMC /* このオプションのコメント(Helpで表示) */
0091: };
0092:
0093: /*----------------------------------------------------------------------------*/
0094: /* シーケンシャル処理 */
0095: /*----------------------------------------------------------------------------*/
0096: MssOptFLG optSEQ={
0097: OFLG, /* オプションタイプ */
0098: "q", /* キーワード(複数文字は不可) */
0099: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0100: SEQT, /* このオプションのタイトル(Helpで表示) */
0101: SEQC /* このオプションのコメント(Helpで表示) */
0102: };
0103:
0104: /*----------------------------------------------------------------------------*/
0105: /* 入力ファイル */
0106: /*----------------------------------------------------------------------------*/
0107: MssOptINF optINF={
0108: OINF, /* オプションタイプ */
0109: "i", /* キーワード(複数文字は不可) */
0110: 0, /* 0:オプション, 1:必須 */
0111: 1, /* 指定可能の最大ファイル数 */
0112: 0, /*1:file not foundのエラーで終了しない 0:する */
0113: INFT, /* このオプションのタイトル(Helpで表示) */
0114: INFC /* このオプションのコメント(Helpで表示) */
0115: };
0116:
0117: /*----------------------------------------------------------------------------*/
0118: /* 出力ファイル */
0119: /*----------------------------------------------------------------------------*/
0120: MssOptOTF optOTF={
0121: OOTF, /* オプションタイプ */
0122: "o", /* キーワード(複数文字は不可) */
0123: 0, /* 0:オプション, 1:必須 */
0124: OTFT, /* このオプションのタイトル(Helpで表示) */
0125: OTFC /* このオプションのコメント(Helpで表示) */
0126: };
0127:
0128: /*----------------------------------------------------------------------------*/
0129: /* 圧縮出力 */
0130: /*----------------------------------------------------------------------------*/
0131: MssOptFLG optZIP={
0132: OFLG, /* オプションタイプ */
0133: "z", /* キーワード(複数文字は不可) */
0134: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0135: ZIPT, /* このオプションのタイトル(Helpで表示) */
0136: ZIPC /* このオプションのコメント(Helpで表示) */
0137: };
0138:
0139: /*----------------------------------------------------------------------------*/
0140: /* plain text */
0141: /*----------------------------------------------------------------------------*/
0142: MssOptFLG optTXT={
0143: OFLG, /* オプションタイプ */
0144: "t", /* キーワード(複数文字は不可) */
0145: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0146: TXTT, /* このオプションのタイトル(Helpで表示) */
0147: TXTC /* このオプションのコメント(Helpで表示) */
0148: };
0149:
0150: /*----------------------------------------------------------------------------*/
0151: /* ワークファイル用ディレクトリ名 */
0152: /*----------------------------------------------------------------------------*/
0153: MssOptSTR optTMP={
0154: OSTR, /* オプションタイプ */
0155: "T", /* キーワード(複数文字は不可) */
0156: 0, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0157: MssTempDir, /* デフォルト */
0158: 1, /* 文字列の最小長 */
0159: MssFileNameMaxLen, /* 文字列の最大長 */
0160: TMPT, /* このオプションのタイトル(Helpで表示) */
0161: TMPC /* このオプションのコメント(Helpで表示) */
0162: };
0163:
0164: /*----------------------------------------------------------------------------*/
0165: /* オプションをまとめる */
0166: /*----------------------------------------------------------------------------*/
0167: void *opt[]={&optKEY,&optSRT,&optCAL,&optFNM,&optSEQ,
0168: &optINF,&optOTF,&optZIP,&optTXT,&optTMP,NULL};
0169:
0170: /*============================================================================*/
0171: /* 変数宣言&定義 */
0172: /*============================================================================*/
0173: struct mssHeader *hdi; /*入力ファイル用<head>タグ格納構造体*/
0174: struct mssHeader *hdo; /*出力ファイル用<head>タグ格納構造体*/
0175: struct mssFPR *fpr; /*入力ファイル構造体 */
0176: struct mssFPW *fpw; /*出力ファイル構造体 */
0177: struct mssFldRecKey *frk; /*項目-行キーバッファ構造体 */
0178: struct mssFldRec *fr; /*項目-行バッファ構造体 */
0179: struct mssFields *sf; /*ソート項目構造体 */
0180:
0181: struct mssCal *cal=NULL; /*計算式をパースする構造体 */
0182: MssValue rsl; /*計算結果 */
0183: int sorted;
0184:
0185: /*----------------------------------------------------------------------------*/
0186: /* 前処理 */
0187: /*----------------------------------------------------------------------------*/
0188: mssInit(argc,argv,&comHelp); /* シグナル処理などの初期化 */
0189: mssHelpDoc(opt,&comHelp,argc,argv);/* ヘルプ */
0190: mssSetOption(opt,argc,argv); /* コマンドオプションの設定 */
0191: fpr=mssOpenFPR(optINF.str,4); /* 入力ファイルオープン */
0192: hdi=mssReadHeader(fpr); /* ヘッダの読み込み */
0193: mssSetOptKey(&optKEY, hdi); /* -k 項目をヘッダー項目に関連づける */
0194: mssSetOptFld(&optSRT, hdi); /* -s 項目をヘッダー項目に関連づける */
0195:
0196: /*ソート項目の作成*/
0197: sf=mssInitFields();
0198: mssAddFieldsByFields(sf,optKEY.flds); /* -k 項目をソート項目としてセット */
0199: mssAddFieldsByFields(sf,optSRT.flds); /* -s 項目をソート項目としてセット */
0200: mssSetFieldsSortPriority(sf); /* ソート優先順位番号を登録順にふる */
0201: sorted=mssChkSorted(sf,hdi); /* ソート済かチェック */
0202:
0203: /*mssShowOption(opt);*/
0204: /*mssShowHeader(hdi);*/
0205:
0206: /*----------------------------------------------------------------------------*/
0207: /*計算式の評価*/
0208: /*----------------------------------------------------------------------------*/
0209: cal=mssCalCompile(optCAL.str,hdi);
0210:
0211: /*mssCalShowTree(cal,0);*/
0212:
0213: /*----------------------------------------------------------------------------*/
0214: /*出力ヘッダーの作成と出力 */
0215: /*----------------------------------------------------------------------------*/
0216: /*出力ヘッダーの初期化(タイトル等のコピー)*/
0217: hdo=mssInitCpyHeader(hdi);
0218:
0219: /*入力ヘッダの全項目を追加*/
0220: mssAddFieldsByFields(hdo->flds,hdi->flds);
0221:
0222: /*新項目名の追加*/
0223: mssAddFieldsByStrList(hdo->flds,optFNM.strList,optFNM.cnt);
0224:
0225: /*ソートする必要があるならばsfのソート情報を反映*/
0226: if(!optSEQ.set && !sorted && optKEY.set){
0227: mssSetFieldsSort(hdo->flds,sf);
0228: }
0229:
0230: /*標準出力オープン+ヘッダーの出力*/
0231: fpw=mssOpenFPW(optOTF.str,optZIP.set,0);
0232: mssWriteHeader(hdo, fpw);
0233:
0234: /*----------------------------------------------------------------------------*/
0235: /*メインルーチン*/
0236: /*----------------------------------------------------------------------------*/
0237: /*ソートが必用ならばソートしてソート済みファイルとしてオープン*/
0238: if( !optSEQ.set && !sorted && (optKEY.set || optSRT.set) )
0239: fpr=mssReopenFPRsort(fpr,4,sf,hdi->flds->cnt,optTMP.str);
0240:
0241: if(optKEY.set){
0242:
0243: /*FRK構造体の初期化*/
0244: frk=mssInitFRK(hdi->flds->cnt, &optKEY, optTMP.str);
0245:
0246: /*calculationで利用する読込関数を登録*/
0247: mssCalReadFuncIsFRK(cal,frk);
0248:
0249: while(1){
0250: /*データ読み込み*/
0251: if(EOF==mssReadFRK(fpr,frk)) break;
0252: mssGV.keyCnt=frk->keyRecCnt;
0253: mssGV.keyNo =frk->keyNo;
0254: mssGV.keyLine=0;
0255: while(1){
0256: if(EOF==mssReadFldRecFRK(frk)) break;
0257: mssGV.inCnt++;
0258: mssGV.keyLine++; /*キー内での現在処理中行番号*/
0259:
0260: /*入力データ一行書き出し*/
0261: mssWriteFld(frk->pnt, frk->fldCnt, " ", fpw);
0262: rsl = mssCalculate(cal, frk->pnt);
0263: mssVwrite(rsl,fpw);
0264: mssWriteRet(fpw);
0265: mssGV.outCnt++;
0266: }
0267: }
0268: mssFreeFRK(frk);
0269:
0270: }else{
0271:
0272: /*FldRec構造体の初期化*/
0273: fr=mssInitFldRec(hdi->flds->cnt);
0274:
0275: /*calculationで利用する読込関数を登録*/
0276: mssCalReadFuncIsFldRec(cal,fr);
0277:
0278: /*データ読み込み*/
0279: mssGV.keyCnt=1;
0280: mssGV.keyNo =0;
0281: mssGV.keyLine=0;
0282: while(1){
0283: if(EOF==mssReadFldRec(fpr,fr)) break;
0284: mssGV.inCnt++;
0285:
0286: /*計算実行*/
0287: rsl = mssCalculate(cal, fr->pnt);
0288:
0289: /*入力データ一行書き出し*/
0290: mssWriteFld(fr->pnt, fr->fldCnt, " ", fpw);
0291:
0292: /*計算結果出力*/
0293: mssVwrite(rsl,fpw);
0294: mssWriteRet(fpw);
0295: mssGV.outCnt++;
0296: }
0297: mssFreeFldRec(fr);
0298: }
0299: mssCalFree(cal);
0300:
0301: /*----------------------------------------------------------------------------*/
0302: /*フッター出力&終了処理*/
0303: /*----------------------------------------------------------------------------*/
0304: /*printf("allocCnt=%d\n",getAllocCnt()); */
0305: mssWriteFooter(fpw); /* フッターの出力 */
0306: mssCloseFPR(fpr); /* 入力ファイルのクローズ */
0307: mssCloseFPW(fpw); /* 出力ファイルのクローズ */
0308: mssFreeFields(sf); /* ソート項目構造体の領域開放 */
0309: mssFreeHeader(hdi); /* 入力ヘッダ領域開放 */
0310: mssFreeHeader(hdo); /* 出力ヘッダ領域開放 */
0311: mssFreeOption(opt); /* オプション領域開放 */
0312: mssShowEndMsg(); /* 完了メッセージ */
0313: mssEnd(mssExitSuccess); /* 終了 */
0314: return(0); /* to avoid warning message */
0315: }