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