MUSASHI C source: xtpattern.c


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