MUSASHI C source: xtcalender.c


0001: /*============================================================================*/ 
0002: /* 変更履歴                                                                   */ 
0003: /*----------------------------------------------------------------------------*/ 
0004: /* 1.0 : 新しいAPIに対応 2003/06/20                                           */ 
0005: /*============================================================================*/ 
0006:    
0007: #include <musashi.h
0008: #include <sys/time.h> 
0009: #include <stdlib.h> 
0010: #include <string.h> 
0011: #include <limits.h> 
0012: #include <sys/types.h> 
0013: #include <unistd.h> 
0014:  
0015: #include <xtcalenderHelp.h> 
0016: struct mssComHelp comHelp={ 
0017:   "xtcalender",   /* コマンド名       */ 
0018:   "1.0",          /* バージョン       */ 
0019:   HELPT,          /* コマンドタイトル */                                     
0020:   HELPS,          /* 要約             */ 
0021:   HELPE,          /* 利用例           */ 
0022:   HELPR,          /* 参照コマンド     */ 
0023:   HELPA,          /* 作者情報         */  
0024:   HELPB,          /* バグレポート情報 */ 
0025:   HELPH           /* ホームページ     */ 
0026: };   
0027:  
0028: extern struct mssGlobalVariables mssGV; 
0029:  
0030: void writeYear(int y, struct mssFPW *fpw){ 
0031:   mssWriteInt(1900+y,fpw); 
0032: } 
0033:  
0034: void writeMonth(int m, struct mssFPW *fpw){ 
0035:   if(1+m<10){ 
0036:     mssWriteInt(0,fpw); 
0037:   } 
0038:   mssWriteInt(1+m ,fpw); 
0039: } 
0040:  
0041: void writeDay(int d, struct mssFPW *fpw){ 
0042:   if(d<10){ 
0043:     mssWriteInt(0,fpw); 
0044:   } 
0045:   mssWriteInt(d ,fpw); 
0046: } 
0047:  
0048: void writeAllDate(struct tm *time, struct mssFPW *fpw){ 
0049:   writeYear(time->tm_year,fpw); 
0050:   writeMonth(time->tm_mon,fpw); 
0051:   writeDay(time->tm_mday,fpw); 
0052: } 
0053:  
0054: time_t getTimeByYMD(int y, int m, int d){ 
0055:   struct tm cTime; 
0056:  
0057:   cTime.tm_year=y ; 
0058:   cTime.tm_mon =m; 
0059:   cTime.tm_mday=d; 
0060:   cTime.tm_hour=11; 
0061:   cTime.tm_min=0; 
0062:   cTime.tm_sec=1; 
0063:   cTime.tm_isdst=-1; 
0064:   return(mktime(&cTime)); 
0065: } 
0066:  
0067: void writeBeginPad(time_t t,int cYear,int cMonth,int mon,struct mssFPW *fpw){ 
0068:   struct tm *cTime; 
0069:   int days; 
0070:   int i; 
0071:  
0072:   cTime=localtime(&t); 
0073:   if(mon) days=cTime->tm_wday-1; 
0074:   else    days=cTime->tm_wday-0; 
0075:  
0076:   t-=86400*days; 
0077:   for(i=0; i<days; i++){ 
0078:     cTime=localtime(&t); 
0079:     writeYear(cYear,fpw); 
0080:     mssWriteDlm(fpw); 
0081:     writeMonth(cMonth,fpw); 
0082:     mssWriteDlm(fpw); 
0083:     writeAllDate(cTime,fpw); 
0084:     mssWriteRet(fpw); 
0085:     mssGV.outCnt++; 
0086:     t+=86400; 
0087:   } 
0088: } 
0089:  
0090: void writeEndPad(time_t t,int cYear,int cMonth,int mon,struct mssFPW *fpw){ 
0091:   struct tm *cTime; 
0092:   int days; 
0093:   int i; 
0094:  
0095:   cTime=localtime(&t); 
0096:   if(mon){ 
0097:     if(cTime->tm_wday==0)      days=1; 
0098:     else if(cTime->tm_wday==1) days=0; 
0099:     else                       days=8-cTime->tm_wday; 
0100:   }else{ 
0101:     if(cTime->tm_wday==0) days=0; 
0102:     else                  days=7-cTime->tm_wday; 
0103:   } 
0104:  
0105:   for(i=0; i<days; i++){ 
0106:     cTime=localtime(&t); 
0107:     writeYear(cYear,fpw); 
0108:     mssWriteDlm(fpw); 
0109:     writeMonth(cMonth,fpw); 
0110:     mssWriteDlm(fpw); 
0111:     writeAllDate(cTime,fpw); 
0112:     mssWriteRet(fpw); 
0113:     mssGV.outCnt++; 
0114:     t+=86400; 
0115:   } 
0116: } 
0117:  
0118: /*----------------------------------------------------------------------------*/ 
0119: /* パディングを考慮して1ヵ月のカレンダーを出力                               */ 
0120: /*----------------------------------------------------------------------------*/ 
0121: void writeOneMonth(int cYear,int cMonth,int pad, int mon, struct mssFPW *fpw){ 
0122:   time_t t; 
0123:   struct tm *cTime; 
0124:   t=getTimeByYMD(cYear,cMonth,1); 
0125:  
0126:   if(pad) writeBeginPad(t,cYear,cMonth,mon,fpw); 
0127:   while(1){ 
0128:     cTime=localtime(&t); 
0129:     if(cTime->tm_mon!=cMonth) break; 
0130:  
0131:     writeYear(cTime->tm_year,fpw); 
0132:     mssWriteDlm(fpw); 
0133:     writeMonth(cTime->tm_mon,fpw); 
0134:     mssWriteDlm(fpw); 
0135:     writeAllDate(cTime,fpw); 
0136:     mssWriteRet(fpw); 
0137:     mssGV.outCnt++; 
0138:     t+=86400; 
0139:   } 
0140:   if(pad) writeEndPad(t,cYear,cMonth,mon,fpw); 
0141: } 
0142:   
0143: int main(int argc, char *argv[]){ 
0144: /*============================================================================*/ 
0145: /* オプション宣言&定義                                                       */ 
0146: /*============================================================================*/ 
0147: /*----------------------------------------------------------------------------*/ 
0148: /* 月の範囲(200201:200212                                                     */ 
0149: /*----------------------------------------------------------------------------*/ 
0150:   MssOptRNG optRNG={ 
0151:     ORNG,   /* オプションタイプ                                             */ 
0152:     "R",    /* キーワード(複数文字は不可)                                   */ 
0153:     0,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0154:     NULL,   /* デフォルト(文字列として指定する)                             */ 
0155:     1,      /* カンマで区切られる要素数の最大値                             */ 
0156:     190001, /* 値の最小値                                                   */ 
0157:     299912, /* 値の最大値                                                   */ 
0158:     RNGT,   /* このオプションのタイトル(Helpで表示)                         */ 
0159:     RNGC    /* このオプションのコメント(Helpで表示)                         */ 
0160:   }; 
0161:  
0162: /*----------------------------------------------------------------------------*/ 
0163: /* 前後月のパディングを行う                                                   */ 
0164: /*----------------------------------------------------------------------------*/ 
0165:   MssOptFLG optPAD={ 
0166:     OFLG,   /* オプションタイプ                                             */ 
0167:     "p",    /* キーワード(複数文字は不可)                                   */ 
0168:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0169:     PADT,   /* このオプションのタイトル(Helpで表示)                         */ 
0170:     PADC    /* このオプションのコメント(Helpで表示)                         */ 
0171:   }; 
0172:  
0173: /*----------------------------------------------------------------------------*/ 
0174: /* 月曜日を週の最初の曜日にする(-pといっしょに利用)                           */ 
0175: /*----------------------------------------------------------------------------*/ 
0176:   MssOptFLG optMON={ 
0177:     OFLG,   /* オプションタイプ                                             */ 
0178:     "m",    /* キーワード(複数文字は不可)                                   */ 
0179:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0180:     MONT,   /* このオプションのタイトル(Helpで表示)                         */ 
0181:     MONC    /* このオプションのコメント(Helpで表示)                         */ 
0182:   }; 
0183:  
0184: /*----------------------------------------------------------------------------*/ 
0185: /* 出力ファイル                                                               */ 
0186: /*----------------------------------------------------------------------------*/ 
0187:   MssOptOTF optOTF={ 
0188:     OOTF,   /* オプションタイプ                                             */ 
0189:     "o",    /* キーワード(複数文字は不可)                                   */ 
0190:     0,      /* 0:オプション, 1:必須                                         */ 
0191:     OTFT,   /* このオプションのタイトル(Helpで表示)                         */ 
0192:     OTFC    /* このオプションのコメント(Helpで表示)                         */ 
0193:   }; 
0194:  
0195: /*----------------------------------------------------------------------------*/ 
0196: /* 圧縮出力                                                                   */ 
0197: /*----------------------------------------------------------------------------*/ 
0198:   MssOptFLG optZIP={ 
0199:     OFLG,   /* オプションタイプ                                             */ 
0200:     "z",    /* キーワード(複数文字は不可)                                   */ 
0201:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0202:     ZIPT,   /* このオプションのタイトル(Helpで表示)                         */ 
0203:     ZIPC    /* このオプションのコメント(Helpで表示)                         */ 
0204:   }; 
0205:  
0206: /*----------------------------------------------------------------------------*/ 
0207: /* plain text                                                                 */ 
0208: /*----------------------------------------------------------------------------*/ 
0209:   MssOptFLG optTXT={ 
0210:     OFLG,   /* オプションタイプ                                             */ 
0211:     "t",    /* キーワード(複数文字は不可)                                   */ 
0212:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0213:     TXTT,   /* このオプションのタイトル(Helpで表示)                         */ 
0214:     TXTC    /* このオプションのコメント(Helpで表示)                         */ 
0215:   }; 
0216:  
0217: /*----------------------------------------------------------------------------*/ 
0218: /* ワークファイル用ディレクトリ名                                             */ 
0219: /*----------------------------------------------------------------------------*/ 
0220:   MssOptSTR optTMP={ 
0221:     OSTR,   /* オプションタイプ                                             */ 
0222:     "T",    /* キーワード(複数文字は不可)                                   */ 
0223:     0,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0224:     MssTempDir, /* デフォルト                                               */ 
0225:     1,      /* 文字列の最小長                                               */ 
0226:     MssFileNameMaxLen,  /* 文字列の最大長                                   */ 
0227:     TMPT,   /* このオプションのタイトル(Helpで表示)                         */ 
0228:     TMPC    /* このオプションのコメント(Helpで表示)                         */ 
0229:   }; 
0230:  
0231: /*----------------------------------------------------------------------------*/ 
0232: /* オプションをまとめる                                                       */ 
0233: /*----------------------------------------------------------------------------*/ 
0234:   void *opt[]={&optRNG,&optMON,&optPAD,&optOTF,&optZIP,&optTXT,&optTMP,NULL}; 
0235:    
0236: /*============================================================================*/ 
0237: /* 変数宣言&定義                                                             */ 
0238: /*============================================================================*/ 
0239:   struct mssHeader    *hdi; /*入力ファイル用<head>タグ格納構造体*/ 
0240:   struct mssHeader    *hdo; /*出力ファイル用<head>タグ格納構造体*/ 
0241:   struct mssFPR       *fpr; /*入力ファイル構造体                */ 
0242:   struct mssFPW       *fpw; /*出力ファイル構造体                */ 
0243:    
0244:   char *dummyFldName[]={"year","month","date"}; 
0245:   int   dummyFldCnt=3; 
0246:   char  dummyFName[MssFileNameMaxLen]; 
0247:  
0248:   int fYear,cYear,tYear,fMonth,cMonth,tMonth; 
0249:   time_t t; 
0250:   struct tm *cTime; 
0251:  
0252: /*----------------------------------------------------------------------------*/ 
0253: /* 前処理                                                                     */ 
0254: /*----------------------------------------------------------------------------*/ 
0255:   mssInit(argc,argv,&comHelp);       /* シグナル処理などの初期化              */ 
0256:   mssHelpDoc(opt,&comHelp,argc,argv);/* ヘルプ                                */ 
0257:   mssSetOption(opt,argc,argv);       /* コマンドオプションの設定              */ 
0258: /*mssShowOption(opt);*/ 
0259:  
0260:   if(optMON.set && !optPAD.set){ 
0261:     mssShowErrMsg("can not specify -m without -p"); 
0262:     mssEnd(mssErrorNoDefault); 
0263:   } 
0264:  
0265:   if(optRNG.set){ 
0266:     fYear =*optRNG.from/100-1900; 
0267:     tYear =*optRNG.to  /100-1900; 
0268:     fMonth=*optRNG.from%100-1; 
0269:     tMonth=*optRNG.to  %100-1; 
0270:     if(fMonth>11 || fMonth<0 || tMonth>11 || tMonth<0){ 
0271:       mssShowErrMsg("invalid month"); 
0272:       mssEnd(mssErrorNoDefault); 
0273:     } 
0274:     /*始点と終点の大小関係をチェック*/ 
0275:     if(fYear>tYear || (fYear==tYear && fMonth>tMonth)){ 
0276:       mssShowErrMsg("start month must be less than or eaqual to end month"); 
0277:       mssEnd(mssErrorNoDefault); 
0278:     } 
0279:  
0280:     t=getTimeByYMD(fYear,fMonth,1); 
0281:  
0282:   }else{ 
0283:     t=time(NULL); 
0284:     cTime=localtime(&t); 
0285:     fYear =tYear =cTime->tm_year; 
0286:     fMonth=tMonth=cTime->tm_mon; 
0287:     t=getTimeByYMD(fYear,fMonth,1); 
0288:   } 
0289:  
0290:   /*ダミー入力データのファイル名*/ 
0291:   sprintf(dummyFName,"%s/xt##%d-calender",optTMP.str,getpid()); 
0292:  
0293:   /*ブランクのxmlTableファイルを作成し、入力ファイルとする*/ 
0294:   mssCreateBlankXtFile(dummyFldName,dummyFldCnt,dummyFName); 
0295:  
0296:   /*usedTempFileFlgをONにし、終了時に時動的にファイルは削除される。*/ 
0297:   mssGV.usedTempFileFlg=1; 
0298:  
0299:   fpr=mssOpenFPR(dummyFName,4);   /* 入力ファイルオープン         */ 
0300:   hdi=mssReadHeader(fpr);         /* ヘッダの読み込み             */ 
0301:  
0302: /*----------------------------------------------------------------------------*/ 
0303: /*出力ヘッダーの作成と出力                                                    */ 
0304: /*----------------------------------------------------------------------------*/ 
0305:   /*出力ヘッダーの初期化(タイトル等のコピー)*/ 
0306:   hdo=mssInitCpyHeader(hdi); 
0307:  
0308:   /*入力ヘッダの全項目を追加*/ 
0309:   mssAddFieldsByFields(hdo->flds,hdi->flds); 
0310:  
0311:   /*標準出力オープン+ヘッダーの出力*/ 
0312:   fpw=mssOpenFPW(optOTF.str,optZIP.set,0); 
0313:   mssWriteHeader(hdo, fpw); 
0314:  
0315: /*----------------------------------------------------------------------------*/ 
0316: /*メインルーチン*/ 
0317: /*----------------------------------------------------------------------------*/ 
0318: /*tm_wday:0->日曜*/ 
0319:  
0320:   cYear =fYear; 
0321:   cMonth=fMonth; 
0322:   while(1){ 
0323:  
0324:     writeOneMonth(cYear,cMonth,optPAD.set,optMON.set,fpw); 
0325:  
0326:     cMonth++; 
0327:     if(cMonth>11){ 
0328:       cYear++; 
0329:       cMonth=0; 
0330:     } 
0331:     if(cYear>tYear) break; 
0332:     if(cYear==tYear && cMonth>tMonth) break; 
0333:   } 
0334:   mssGV.inCnt=0; 
0335:  
0336: /*----------------------------------------------------------------------------*/ 
0337: /*フッター出力&終了処理*/ 
0338: /*----------------------------------------------------------------------------*/ 
0339:   mssWriteFooter(fpw);    /*フッターの出力              */ 
0340:   mssCloseFPR(fpr);       /*入力ファイルのクローズ      */ 
0341:   mssCloseFPW(fpw);       /*出力ファイルのクローズ      */ 
0342:   mssFreeHeader(hdi);     /* 入力ヘッダ領域開放         */ 
0343:   mssFreeHeader(hdo);     /* 出力ヘッダ領域開放         */ 
0344:   mssFreeOption(opt);     /* オプション領域開放         */ 
0345:   mssShowEndMsg();        /* 完了メッセージ             */ 
0346:   mssEnd(mssExitSuccess); /* 終了                       */ 
0347:   return(0);              /* to avoid warning message   */ 
0348: }