MUSASHI C source: xtchgnum.c


0001:  
0002: /*============================================================================*/ 
0003: /* 変更履歴                                                                   */ 
0004: /*----------------------------------------------------------------------------*/ 
0005: /* 1.0 : 新しいAPIに対応 2003/06/20                                           */ 
0006: /*============================================================================*/ 
0007: #include <musashi.h
0008: #include <stdio.h> 
0009: #include <stdlib.h> 
0010: #include <string.h> 
0011: #include <float.h> 
0012:  
0013: #include <xtchgnumHelp.h> 
0014: struct mssComHelp comHelp={ 
0015:   "xtchgnum",     /* コマンド名       */ 
0016:   "1.0",          /* バージョン       */ 
0017:   HELPT,          /* コマンドタイトル */ 
0018:   HELPS,          /* 要約             */ 
0019:   HELPE,          /* 利用例           */ 
0020:   HELPR,          /* 参照コマンド     */ 
0021:   HELPA,          /* 作者情報         */ 
0022:   HELPB,          /* バグレポート情報 */ 
0023:   HELPH           /* ホームページ     */ 
0024: }; 
0025:  
0026: extern struct mssGlobalVariables mssGV; 
0027:  
0028: static MssOptDLS *LST; 
0029: static MssOptSLS *VAL; 
0030: static MssOptFLG *REQ; 
0031: static MssOptFLG *FRP; 
0032: static MssOptSTR *OTH; 
0033: static char  **DEF; 
0034:  
0035: /*----------------------------------------------------------------------------*/ 
0036: /* -vが指定されなかったとき、デフォルトの置換文字リストを作成する             */ 
0037: /*----------------------------------------------------------------------------*/ 
0038: char **getDefRep(MssOptDLS *optVAL){ 
0039:   int i; 
0040:   char *dblStr; 
0041:   char **defRep; 
0042:   char rngStr[MssFieldMaxLen]; 
0043:  
0044:   defRep=mssMalloc(sizeof(char *)*optVAL->cnt,"getDefRep"); 
0045:   for(i=0;i<optVAL->cnt-1; i++){ 
0046:     rngStr[0]='\0'; 
0047:    
0048:     /*fromの文字列*/ 
0049:     if( *(optVAL->val+i) != -DBL_MAX ){ 
0050:       dblStr=mssFtoA(*(optVAL->val+i)); 
0051:       strcat(rngStr,dblStr); 
0052:       mssFree(dblStr); 
0053:     } 
0054:      
0055:     /*範囲文字*/ 
0056:     strcat(rngStr,"_"); 
0057:  
0058:     /*toの文字列*/ 
0059:     if( *(optVAL->val+i+1) != DBL_MAX ){ 
0060:       dblStr=mssFtoA(*(optVAL->val+i+1)); 
0061:       strcat(rngStr,dblStr); 
0062:       mssFree(dblStr); 
0063:     } 
0064:      
0065:     /*領域確保してrange->tbl構造体にセット*/ 
0066:     *(defRep+i)=mssMalloc(sizeof(char)*(strlen(rngStr)+1),"getDefRep"); 
0067:     strcpy(*(defRep+i),rngStr); 
0068:   }  
0069:  
0070:   return(defRep); 
0071: } 
0072:  
0073: /*----------------------------------------------------------------------------*/ 
0074: /*範囲にマッチする文字列を返す                                                */ 
0075: /* 2分探索法にかえる予定                                                      */ 
0076: /*----------------------------------------------------------------------------*/ 
0077: char *getRepStr(char *str){ 
0078:   double num; 
0079:   int match; 
0080:   int i; 
0081:  
0082:   if(MssIsNull(str)) return(MssNullStr); 
0083:  
0084:   match=-1; 
0085:   num=atof(str); 
0086:   for(i=0; i<LST->cnt; i++){ 
0087:     if(REQ->set){ 
0088:       if(num>*(LST->val+i)){ 
0089:         match=i; 
0090:         continue; 
0091:       }else{ 
0092:         break; 
0093:       } 
0094:     }else{ 
0095:       if(num>=*(LST->val+i)){ 
0096:         match=i; 
0097:         continue; 
0098:       }else{ 
0099:         break; 
0100:       } 
0101:     } 
0102:   } 
0103:  
0104:   /*最後の条件にマッチしたということは、範囲外ということ*/ 
0105:   if(match>=LST->cnt-1){ 
0106:       match=-1; 
0107:   } 
0108:  
0109:   if(match==-1){ 
0110:          if(OTH->set) return(OTH->str);   /*unmatch & OTH指定 */ 
0111:     else if(FRP->set) return(str);        /*unmatch & FRP指定 */ 
0112:     else              return(MssNullStr); /*else              */ 
0113:   }else{ 
0114:     if(VAL->set){ 
0115:       return(*(VAL->strList+match)); 
0116:     }else{ 
0117:       return(*(DEF+match)); 
0118:     } 
0119:   } 
0120: } 
0121:  
0122: int main(int argc, char *argv[]){ 
0123: /*============================================================================*/ 
0124: /* オプション宣言&定義                                                       */ 
0125: /*============================================================================*/ 
0126: /*----------------------------------------------------------------------------*/ 
0127: /* 対象項目                                                                   */ 
0128: /*----------------------------------------------------------------------------*/ 
0129:   MssOptFLD optFLD={ 
0130:     OFLD,   /* オプションタイプ                                             */ 
0131:     "f",    /* キーワード(複数文字は不可)                                   */ 
0132:     1,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0133:     MssFieldMaxCnt, /* 指定可能な最大項目数                                 */ 
0134:     "i",    /* 対象とする入力データのキーワード(GUIで利用)                  */ 
0135:     1,      /* 正規表現を許可するかどうか(0:不可,1:可)                      */ 
0136:     1,      /* 新項目名を指定できるかどうか(0:不可,1:可)                    */ 
0137:     NULL,   /* 項目オプション(%以下)で指定可能な文字                        */ 
0138:             /* ex) 指定不可の場合はNULL, "nr": "-f 項目名%rn"の指定可能     */ 
0139:     FLDT,   /* このオプションのタイトル(Helpで表示)                         */ 
0140:     FLDC,   /* このオプションのコメント(Helpで表示)                         */ 
0141:     FLDF    /* フラグについての説明(Helpで表示)複数の場合はカンマで区切る   */ 
0142:   }; 
0143:  
0144: /*----------------------------------------------------------------------------*/ 
0145: /* 数値範囲リスト                                                             */ 
0146: /*----------------------------------------------------------------------------*/ 
0147:   MssOptDLS optLST={ 
0148:     ODLS,   /* オプションタイプ                                             */ 
0149:     "R",    /* キーワード(複数文字は不可)                                   */ 
0150:     1,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0151:     NULL,   /* デフォルト(文字列として指定する)                             */ 
0152:     50,     /* カンマで区切る要素の最大数                                   */ 
0153:    -DBL_MAX,/* 値の最小値                                                   */ 
0154:     DBL_MAX,/* 値の最大値                                                   */ 
0155:     LSTT,   /* このオプションのタイトル(Helpで表示)                         */ 
0156:     LSTC    /* このオプションのコメント(Helpで表示)                         */ 
0157:   }; 
0158:  
0159: /*----------------------------------------------------------------------------*/ 
0160: /* 置換文字列リスト                                                           */ 
0161: /*----------------------------------------------------------------------------*/ 
0162:   MssOptSLS optVAL={ 
0163:     OSLS,   /* オプションタイプ                                             */ 
0164:     "v",    /* キーワード(複数文字は不可)                                   */ 
0165:     0,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0166:     NULL,   /* デフォルト(文字列)                                           */ 
0167:     49,     /* カンマで区切られる要素数の最大値                             */ 
0168:     1,      /* 各要素の文字列長の最小値                                     */ 
0169:     MssFieldMaxLen,/* 各要素の文字列長の最大値                              */ 
0170:     0,      /* 1:要素にコロンを指定できる,0:不可  ex) aaaa:xxxxx            */ 
0171:     VALT,   /* このオプションのタイトル(Helpで表示)                         */ 
0172:     VALC    /* このオプションのコメント(Helpで表示)                         */ 
0173:   }; 
0174:  
0175: /*----------------------------------------------------------------------------*/ 
0176: /* 数値範囲外の置換文字列                                                     */ 
0177: /*----------------------------------------------------------------------------*/ 
0178:   MssOptSTR optOTH={ 
0179:     OSTR,   /* オプションタイプ                                             */ 
0180:     "O",    /* キーワード(複数文字は不可)                                   */ 
0181:     0,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0182:     NULL,   /* デフォルト                                                   */ 
0183:     1,      /* 文字列の最小長                                               */ 
0184:     MssFieldMaxLen,/* 文字列の最大長                                        */ 
0185:     OTHT,   /* このオプションのタイトル(Helpで表示)                         */ 
0186:     OTHC    /* このオプションのコメント(Helpで表示)                         */ 
0187:   }; 
0188:    
0189: /*----------------------------------------------------------------------------*/ 
0190: /* 数値範囲外の時置換しない                                                   */ 
0191: /*----------------------------------------------------------------------------*/ 
0192:   MssOptFLG optFRP={ 
0193:     OFLG,   /* オプションタイプ                                             */ 
0194:     "F",    /* キーワード(複数文字は不可)                                   */ 
0195:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0196:     FRPT,   /* このオプションのタイトル(Helpで表示)                         */ 
0197:     FRPC    /* このオプションのコメント(Helpで表示)                         */ 
0198:   }; 
0199:  
0200: /*----------------------------------------------------------------------------*/ 
0201: /* 新しい項目として出力する                                                   */ 
0202: /*----------------------------------------------------------------------------*/ 
0203:   MssOptFLG optNEW={ 
0204:     OFLG,   /* オプションタイプ                                             */ 
0205:     "A",    /* キーワード(複数文字は不可)                                   */ 
0206:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0207:     NEWT,   /* このオプションのタイトル(Helpで表示)                         */ 
0208:     NEWC    /* このオプションのコメント(Helpで表示)                         */ 
0209:   }; 
0210:  
0211: /*----------------------------------------------------------------------------*/ 
0212: /* 数値範囲の条件を〜より大きく〜以下とする                                   */ 
0213: /*----------------------------------------------------------------------------*/ 
0214:   MssOptFLG optREQ={ 
0215:     OFLG,   /* オプションタイプ                                             */ 
0216:     "r",    /* キーワード(複数文字は不可)                                   */ 
0217:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0218:     REQT,   /* このオプションのタイトル(Helpで表示)                         */ 
0219:     REQC    /* このオプションのコメント(Helpで表示)                         */ 
0220:   }; 
0221:  
0222: /*----------------------------------------------------------------------------*/ 
0223: /* 入力ファイル                                                               */ 
0224: /*----------------------------------------------------------------------------*/ 
0225:   MssOptINF optINF={ 
0226:     OINF,   /* オプションタイプ                                             */ 
0227:     "i",    /* キーワード(複数文字は不可)                                   */ 
0228:     0,      /* 0:オプション, 1:必須                                         */ 
0229:     1,      /* 指定可能の最大ファイル数                                     */ 
0230:     0,      /*1:file not foundのエラーで終了しない 0:する                   */ 
0231:     INFT,   /* このオプションのタイトル(Helpで表示)                         */ 
0232:     INFC    /* このオプションのコメント(Helpで表示)                         */ 
0233:   }; 
0234:  
0235: /*----------------------------------------------------------------------------*/ 
0236: /* 出力ファイル                                                               */ 
0237: /*----------------------------------------------------------------------------*/ 
0238:   MssOptOTF optOTF={ 
0239:     OOTF,   /* オプションタイプ                                             */ 
0240:     "o",    /* キーワード(複数文字は不可)                                   */ 
0241:     0,      /* 0:オプション, 1:必須                                         */ 
0242:     OTFT,   /* このオプションのタイトル(Helpで表示)                         */ 
0243:     OTFC    /* このオプションのコメント(Helpで表示)                         */ 
0244:   }; 
0245:  
0246: /*----------------------------------------------------------------------------*/ 
0247: /* 圧縮出力                                                                   */ 
0248: /*----------------------------------------------------------------------------*/ 
0249:   MssOptFLG optZIP={ 
0250:     OFLG,   /* オプションタイプ                                             */ 
0251:     "z",    /* キーワード(複数文字は不可)                                   */ 
0252:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0253:     ZIPT,   /* このオプションのタイトル(Helpで表示)                         */ 
0254:     ZIPC    /* このオプションのコメント(Helpで表示)                         */ 
0255:   }; 
0256:  
0257: /*----------------------------------------------------------------------------*/ 
0258: /* plain text                                                                 */ 
0259: /*----------------------------------------------------------------------------*/ 
0260:   MssOptFLG optTXT={ 
0261:     OFLG,   /* オプションタイプ                                             */ 
0262:     "t",    /* キーワード(複数文字は不可)                                   */ 
0263:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0264:     TXTT,   /* このオプションのタイトル(Helpで表示)                         */ 
0265:     TXTC    /* このオプションのコメント(Helpで表示)                         */ 
0266:   }; 
0267:  
0268: /*----------------------------------------------------------------------------*/ 
0269: /* オプションをまとめる                                                       */ 
0270: /*----------------------------------------------------------------------------*/ 
0271:   void *opt[]={&optFLD,&optLST,&optVAL,&optOTH,&optFRP,&optNEW,&optREQ, 
0272:                &optINF,&optOTF,&optZIP,&optTXT,NULL}; 
0273:  
0274: /*============================================================================*/ 
0275: /* 変数宣言&定義                                                             */ 
0276: /*============================================================================*/ 
0277:   struct mssHeader *hdi; /*入力ファイル用<head>タグ格納構造体*/ 
0278:   struct mssHeader *hdo; /*出力ファイル用<head>タグ格納構造体*/ 
0279:   struct mssFPR    *fpr; /*入力ファイル構造体                */ 
0280:   struct mssFPW    *fpw; /*出力ファイル構造体                */ 
0281:   struct mssFldRec *fr;  /*項目-行バッファ構造体             */ 
0282:  
0283:   int i; 
0284:  
0285: /*----------------------------------------------------------------------------*/ 
0286: /* 前処理                                                                     */ 
0287: /*----------------------------------------------------------------------------*/ 
0288:   mssInit(argc,argv,&comHelp);       /* シグナル処理などの初期化              */ 
0289:   mssHelpDoc(opt,&comHelp,argc,argv);/* ヘルプ                                */ 
0290:   mssSetOption(opt,argc,argv);       /* コマンドオプションの設定              */ 
0291:   fpr=mssOpenFPR(optINF.str,4);      /* 入力ファイルオープン                  */ 
0292:   hdi=mssReadHeader(fpr);            /* ヘッダの読み込み                      */ 
0293:   mssSetOptFld(&optFLD, hdi);        /* -f 項目をヘッダー項目に関連づける     */ 
0294:  
0295: /*mssShowOption(opt);*/ 
0296: /*mssShowHeader(hdi);*/ 
0297:      
0298:   if(optFRP.set && optOTH.set){ 
0299:     mssShowErrMsg("-O and -F are exclusive"); 
0300:     mssEnd(mssErrorNoDefault); 
0301:   } 
0302:  
0303:   if(optVAL.set && (optVAL.cnt != optLST.cnt-1)){ 
0304:     mssShowErrMsg("the number of elements on -v must be %d",optLST.cnt-1); 
0305:     mssEnd(mssErrorNoDefault); 
0306:   } 
0307:  
0308:   /* -v(置換文字列)の指定がなければ、数値範囲を置換文字列とする) */ 
0309:   if(!optVAL.set){ 
0310:     DEF=getDefRep(&optLST); 
0311:   } 
0312:  
0313:   LST=&optLST; 
0314:   VAL=&optVAL; 
0315:   REQ=&optREQ; 
0316:   FRP=&optFRP; 
0317:   OTH=&optOTH; 
0318:  
0319: /*----------------------------------------------------------------------------*/ 
0320: /*出力ヘッダーの作成と出力                                                    */ 
0321: /*----------------------------------------------------------------------------*/ 
0322:   /*出力ヘッダーの初期化(タイトル等のコピー)*/ 
0323:   hdo=mssInitCpyHeader(hdi);  
0324:    
0325:   /*入力ヘッダの全項目を追加*/ 
0326:    
0327:   /*新項目名を追加する*/ 
0328:   if(optNEW.set){ 
0329:     mssAddFieldsByFields(hdo->flds,hdi->flds);             
0330:     mssAddFieldsByStrList(hdo->flds,optFLD.newNam,optFLD.cnt); 
0331:  
0332:   /*-fで指定された項目は-fから、その他は入力ヘッダから項目を追加する*/ 
0333:   }else{ 
0334:     mssAddHeadOrOptFields(hdo->flds,hdi,&optFLD); 
0335:   } 
0336:  
0337:   /*標準出力オープン+ヘッダーの出力*/ 
0338:   fpw=mssOpenFPW(optOTF.str,optZIP.set,0); 
0339:   mssWriteHeader(hdo, fpw); 
0340:  
0341: /*----------------------------------------------------------------------------*/ 
0342: /*メインルーチン                                                              */ 
0343: /*----------------------------------------------------------------------------*/ 
0344:  
0345:   fr=mssInitFldRec(hdi->flds->cnt); 
0346:   while( EOF != mssReadFldRec(fpr,fr) ){ 
0347:     mssGV.inCnt++; 
0348:  
0349:     /*新項目追加の場合*/ 
0350:     if(optNEW.set){ 
0351:       mssWriteFld(fr->pnt,fr->fldCnt,"",fpw); 
0352:       for(i=0; i<optFLD.flds->cnt; i++){ 
0353:         mssWriteDlm(fpw); 
0354:         mssWriteStr(getRepStr(*(fr->pnt+MssFlds2num(optFLD.flds,i))),fpw); 
0355:       } 
0356:       mssWriteRet(fpw); 
0357:  
0358:     /*新項目置換の場合*/ 
0359:     }else{ 
0360:       for(i=0; i<hdi->flds->cnt-1; i++){ 
0361:         if( *(optFLD.fldNo2optNo+i)==-1){ 
0362:           mssWriteStr(*(fr->pnt+MssFlds2num(hdi->flds,i)),fpw); 
0363:         }else{ 
0364:           mssWriteStr(getRepStr(*(fr->pnt+MssFlds2num(hdi->flds,i))),fpw); 
0365:         } 
0366:         mssWriteDlm(fpw); 
0367:       } 
0368:       if( *(optFLD.fldNo2optNo+i)==-1){ 
0369:         mssWriteStr(*(fr->pnt+MssFlds2num(hdi->flds,i)),fpw); 
0370:       }else{ 
0371:         mssWriteStr(getRepStr(*(fr->pnt+MssFlds2num(hdi->flds,i))),fpw); 
0372:       } 
0373:       mssWriteRet(fpw); 
0374:     } 
0375:     mssGV.outCnt++; 
0376:   } 
0377:  
0378:   /*領域開放*/ 
0379:   mssFreeFldRec(fr); 
0380:   if(!optVAL.set){ 
0381:     for(i=0;i<optLST.cnt-1; i++) mssFree(*(DEF+i)); 
0382:     mssFree(DEF); 
0383:   } 
0384:  
0385: /*----------------------------------------------------------------------------*/ 
0386: /*フッター出力&終了処理                                                       */ 
0387: /*----------------------------------------------------------------------------*/ 
0388: /*printf("allocCnt=%d\n",getAllocCnt());*/ 
0389:   mssWriteFooter(fpw);     /* フッターの出力             */ 
0390:   mssCloseFPR(fpr);        /* 入力ファイルのクローズ     */ 
0391:   mssCloseFPW(fpw);        /* 出力ファイルのクローズ     */ 
0392:   mssFreeHeader(hdi);      /* 入力ヘッダ領域開放         */ 
0393:   mssFreeHeader(hdo);      /* 出力ヘッダ領域開放         */ 
0394:   mssFreeOption(opt);      /* オプション領域開放         */ 
0395:   mssShowEndMsg();         /* 完了メッセージ             */ 
0396:   mssEnd(mssExitSuccess);  /* 終了                       */ 
0397:   return(0);               /* to avoid warning message   */ 
0398: }