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