MUSASHI C source: xtcount.c


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