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