MUSASHI C source: xtshare.c
0001: /*============================================================================*/
0002: /* 変更履歴 */
0003: /*----------------------------------------------------------------------------*/
0004: /* 1.0 : 新しいAPIに対応 2003/06/20 */
0005: /*============================================================================*/
0006:
0007: #include <musashi.h>
0008: #include <stdlib.h>
0009:
0010: #include <xtshareHelp.h>
0011: struct mssComHelp comHelp={
0012: "xtshare", /* コマンド名 */
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: /*----------------------------------------------------------------------------*/
0026: /*文字列としての項目をvalに変換する関数 */
0027: /*----------------------------------------------------------------------------*/
0028: void setValFromFldStr(MssValue *val, char **str, struct mssFields *fld)
0029: {
0030: int i;
0031: for(i=0; i<fld->cnt; i++){
0032: *(val+i)=mssVstr2d( *(str+MssFlds2num(fld,i)) );
0033: }
0034: }
0035:
0036: int main(int argc, char *argv[]){
0037: /*============================================================================*/
0038: /* オプション宣言&定義 */
0039: /*============================================================================*/
0040: /*----------------------------------------------------------------------------*/
0041: /* キー項目 */
0042: /*----------------------------------------------------------------------------*/
0043: MssOptKEY optKEY={
0044: OKEY, /* オプションタイプ */
0045: "k", /* キーワード(複数文字は不可) */
0046: 0, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0047: MssFieldMaxCnt, /* 指定可能な最大項目数 */
0048: "i", /* 対象とする入力データのキーワード(GUIで利用) */
0049: 2, /* デフォルト(このオプションが指定されなかったときの動作を指定) */
0050: /* 1:全ての行を異るキー値として扱う */
0051: /* 2:全ての行を同じキー値として扱う) */
0052: KEYT, /* このオプションのタイトル(Helpで表示) */
0053: KEYC /* このオプションのコメント(Helpで表示) */
0054: };
0055:
0056: /*----------------------------------------------------------------------------*/
0057: /* 対象項目 */
0058: /*----------------------------------------------------------------------------*/
0059: MssOptFLD optFLD={
0060: OFLD, /* オプションタイプ */
0061: "f", /* キーワード(複数文字は不可) */
0062: 1, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0063: MssFieldMaxCnt, /* 指定可能な最大項目数 */
0064: "i", /* 対象とする入力データのキーワード(GUIで利用) */
0065: 1, /* 正規表現を許可するかどうか(0:不可,1:可) */
0066: 1, /* 新項目名を指定できるかどうか(0:不可,1:可) */
0067: NULL, /* 項目オプション(%以下)で指定可能な文字 */
0068: /* ex) 指定不可の場合はNULL, "nr": "-f 項目名%rn"の指定可能 */
0069: FLDT, /* このオプションのタイトル(Helpで表示) */
0070: FLDC, /* このオプションのコメント(Helpで表示) */
0071: FLDF /* フラグについての説明(Helpで表示)複数の場合はカンマで区切る */
0072: };
0073:
0074: /*----------------------------------------------------------------------------*/
0075: /* シーケンシャル処理 */
0076: /*----------------------------------------------------------------------------*/
0077: MssOptFLG optSEQ={
0078: OFLG, /* オプションタイプ */
0079: "q", /* キーワード(複数文字は不可) */
0080: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0081: SEQT, /* このオプションのタイトル(Helpで表示) */
0082: SEQC /* このオプションのコメント(Helpで表示) */
0083: };
0084:
0085: /*----------------------------------------------------------------------------*/
0086: /* 入力ファイル */
0087: /*----------------------------------------------------------------------------*/
0088: MssOptINF optINF={
0089: OINF, /* オプションタイプ */
0090: "i", /* キーワード(複数文字は不可) */
0091: 0, /* 0:オプション, 1:必須 */
0092: 1, /* 指定可能の最大ファイル数 */
0093: 0, /*1:file not foundのエラーで終了しない 0:する */
0094: INFT, /* このオプションのタイトル(Helpで表示) */
0095: INFC /* このオプションのコメント(Helpで表示) */
0096: };
0097:
0098: /*----------------------------------------------------------------------------*/
0099: /* 出力ファイル */
0100: /*----------------------------------------------------------------------------*/
0101: MssOptOTF optOTF={
0102: OOTF, /* オプションタイプ */
0103: "o", /* キーワード(複数文字は不可) */
0104: 0, /* 0:オプション, 1:必須 */
0105: OTFT, /* このオプションのタイトル(Helpで表示) */
0106: OTFC /* このオプションのコメント(Helpで表示) */
0107: };
0108:
0109: /*----------------------------------------------------------------------------*/
0110: /* 圧縮出力 */
0111: /*----------------------------------------------------------------------------*/
0112: MssOptFLG optZIP={
0113: OFLG, /* オプションタイプ */
0114: "z", /* キーワード(複数文字は不可) */
0115: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0116: ZIPT, /* このオプションのタイトル(Helpで表示) */
0117: ZIPC /* このオプションのコメント(Helpで表示) */
0118: };
0119:
0120: /*----------------------------------------------------------------------------*/
0121: /* plain text */
0122: /*----------------------------------------------------------------------------*/
0123: MssOptFLG optTXT={
0124: OFLG, /* オプションタイプ */
0125: "t", /* キーワード(複数文字は不可) */
0126: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0127: TXTT, /* このオプションのタイトル(Helpで表示) */
0128: TXTC /* このオプションのコメント(Helpで表示) */
0129: };
0130:
0131: /*----------------------------------------------------------------------------*/
0132: /* ワークファイル用ディレクトリ名 */
0133: /*----------------------------------------------------------------------------*/
0134: MssOptSTR optTMP={
0135: OSTR, /* オプションタイプ */
0136: "T", /* キーワード(複数文字は不可) */
0137: 0, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0138: MssTempDir, /* デフォルト */
0139: 1, /* 文字列の最小長 */
0140: MssFileNameMaxLen, /* 文字列の最大長 */
0141: TMPT, /* このオプションのタイトル(Helpで表示) */
0142: TMPC /* このオプションのコメント(Helpで表示) */
0143: };
0144:
0145: /*----------------------------------------------------------------------------*/
0146: /* オプションをまとめる */
0147: /*----------------------------------------------------------------------------*/
0148: void *opt[]={&optKEY,&optFLD,&optSEQ,&optINF,&optOTF,&optZIP,&optTXT,&optTMP,NULL};
0149:
0150: /*============================================================================*/
0151: /* 変数宣言&定義 */
0152: /*============================================================================*/
0153: struct mssHeader *hdi; /*入力ファイル用<head>タグ格納構造体*/
0154: struct mssHeader *hdo; /*出力ファイル用<head>タグ格納構造体*/
0155: struct mssFPR *fpr; /*入力ファイル構造体 */
0156: struct mssFPW *fpw; /*出力ファイル構造体 */
0157: struct mssFldRecKey *frk=NULL;/*キー単位バッファ構造体 */
0158: struct mssFields *sf; /*ソート項目構造体 */
0159: int sorted; /*ソート済チェック用 */
0160:
0161: MssValue *val,*rsl;
0162: int i;
0163:
0164: /*----------------------------------------------------------------------------*/
0165: /* 前処理 */
0166: /*----------------------------------------------------------------------------*/
0167: mssInit(argc,argv,&comHelp); /* シグナル処理などの初期化 */
0168: mssHelpDoc(opt,&comHelp,argc,argv);/* ヘルプ */
0169: mssSetOption(opt,argc,argv); /* コマンドオプションの設定 */
0170: fpr=mssOpenFPR(optINF.str,4); /* 入力ファイルオープン */
0171: hdi=mssReadHeader(fpr); /* ヘッダの読み込み */
0172: mssSetOptKey(&optKEY, hdi); /* -k 項目をヘッダー項目に関連づける */
0173: mssSetOptFld(&optFLD, hdi); /* -f 項目をヘッダー項目に関連づける */
0174:
0175: /*ソート項目の作成*/
0176: sf=mssInitFields();
0177: mssAddFieldsByFields(sf,optKEY.flds); /* -k 項目をソート項目としてセット */
0178: mssSetFieldsSortPriority(sf); /* ソート優先順位番号を登録順にふる */
0179: sorted=mssChkSorted(sf,hdi); /* ソート済かチェック */
0180:
0181: /*mssShowFields(sf);*/
0182: /*mssShowOption(opt);*/
0183: /*mssShowHeader(hdi);*/
0184:
0185: /*----------------------------------------------------------------------------*/
0186: /*出力ヘッダーの作成と出力 */
0187: /*----------------------------------------------------------------------------*/
0188: /*出力ヘッダーの初期化(タイトル等のコピー)*/
0189: hdo=mssInitCpyHeader(hdi);
0190:
0191: /*入力ヘッダの全項目を追加*/
0192: mssAddFieldsByFields(hdo->flds,hdi->flds);
0193:
0194: /*新項目名を追加する*/
0195: mssAddFieldsByStrList(hdo->flds,optFLD.newNam,optFLD.cnt);
0196:
0197: /*ソートする必要があるならばsfのソート情報を反映*/
0198: if(!optSEQ.set && !sorted){
0199: mssSetFieldsSort(hdo->flds,sf);
0200: }
0201:
0202: /*標準出力オープン+ヘッダーの出力*/
0203: fpw=mssOpenFPW(optOTF.str,optZIP.set,0);
0204: mssWriteHeader(hdo, fpw);
0205:
0206: /*----------------------------------------------------------------------------*/
0207: /*メインルーチン */
0208: /*----------------------------------------------------------------------------*/
0209: /*集計用領域の確保&初期化*/
0210: val=mssMalloc(sizeof(MssValue)*optFLD.flds->cnt,"xtshare");
0211: rsl=mssMalloc(sizeof(MssValue)*optFLD.flds->cnt,"xtshare");
0212: for(i=0; i<optFLD.flds->cnt; i++){
0213: mssVinit(val+i,DBL);
0214: mssVinit(rsl+i,DBL);
0215: }
0216:
0217: /*ソートが必用ならばソートしてソート済みファイルとしてオープン*/
0218: if(!optSEQ.set && !sorted)
0219: fpr=mssReopenFPRsort(fpr,4,sf,hdi->flds->cnt,optTMP.str);
0220:
0221: /*FRK構造体の初期化*/
0222: frk=mssInitFRK(hdi->flds->cnt, &optKEY,optTMP.str);
0223:
0224: while(1){
0225: /*データ読み込み*/
0226: if(EOF==mssReadFRK(fpr,frk)) break;
0227:
0228: /*合計の計算*/
0229: while( EOF != mssReadFldRecFRK(frk) ){
0230: setValFromFldStr(val, frk->pnt, optFLD.flds);
0231: for(i=0; i<optFLD.flds->cnt; i++) *(rsl+i)=mssVadd(*(rsl+i),*(val+i));
0232: }
0233:
0234: /*シェアを計算して出力*/
0235: mssSeekTopFRK(frk);
0236: while( EOF != mssReadFldRecFRK(frk) ){
0237: mssGV.inCnt++;
0238: setValFromFldStr(val, frk->pnt, optFLD.flds);
0239: mssWriteFld(frk->pnt,frk->fldCnt,"",fpw);
0240: for(i=0; i<optFLD.flds->cnt; i++){
0241: mssWriteDlm(fpw);
0242: mssVwriteDbl(mssVdiv(*(val+i),*(rsl+i)), fpw);
0243: }
0244: mssWriteRet(fpw);
0245: mssGV.outCnt++;
0246: }
0247:
0248: for(i=0; i<optFLD.flds->cnt; i++) mssVclear(rsl+i);
0249: }
0250:
0251: mssFreeFRK(frk);
0252: mssFree(val);
0253: mssFree(rsl);
0254:
0255: /*----------------------------------------------------------------------------*/
0256: /*フッター出力&終了処理 */
0257: /*----------------------------------------------------------------------------*/
0258: /*printf("allocCnt=%d\n",getAllocCnt());*/
0259: mssWriteFooter(fpw); /* フッターの出力 */
0260: mssCloseFPR(fpr); /* 入力ファイルのクローズ */
0261: mssCloseFPW(fpw); /* 出力ファイルのクローズ */
0262: mssFreeFields(sf); /* ソート項目構造体の領域開放 */
0263: mssFreeHeader(hdi); /* 入力ヘッダ領域開放 */
0264: mssFreeHeader(hdo); /* 出力ヘッダ領域開放 */
0265: mssFreeOption(opt); /* オプション領域開放 */
0266: mssShowEndMsg(); /* 完了メッセージ */
0267: return(0); /* to avoid warning message */
0268: }