MUSASHI C source: mssOutput.c


グローバル関数
mssCloseFPW mssOpenFPW mssWriteChr mssWriteDate mssWriteDbe mssWriteDbl mssWriteDlm mssWriteFld mssWriteInt mssWriteLong mssWriteNull mssWriteRet mssWriteStr mssWriteTime


ローカル関数
fwOpenErr mkDir zwOpenErr


0001: /** 
0002:  * # CHAPTER # 
0003:  * ============================================================================ 
0004:  * MUSASHIで用いられるデータの出力関連の関数 
0005:  * ============================================================================ 
0006:  */ 
0007:  
0008: #include <mssConfig.h
0009: #include <mssOutput.h
0010: #include <mssBase.h
0011:  
0012: #include <stdio.h> 
0013: #include <stdlib.h> 
0014: #include <string.h> 
0015: #include <zlib.h> 
0016: #include <sys/types.h> 
0017: #include <sys/stat.h> 
0018: #include <errno.h> 
0019:  
0020: /** 
0021:  * # FUNCTION # 
0022:  * 圧縮ファイルの書き込みオープンエラーの表示&終了。 
0023:  */ 
0024: static void zwOpenErr(char *fName) 
0025: { 
0026:   mssShowErrMsg("gz file write open error :\"%s\"",fName); 
0027:   mssEnd(mssErrorNoDefault); 
0028: } 
0029:  
0030: /** 
0031:  * # FUNCTION # 
0032:  * 通常ファイルの書き込みオープンエラーの表示&終了。 
0033:  */ 
0034: static void fwOpenErr(char *fName) 
0035: { 
0036:   mssShowErrMsg("file write open error :\"%s\"",fName); 
0037:   mssEnd(mssErrorNoDefault); 
0038: } 
0039:  
0040: /** 
0041:  * # FUNCTION # 
0042:  * ファイル名から必要なディレクトリを作成する。 
0043:  * ex.) 
0044:  * fileName="abc/def/ghi/dat.xt" 
0045:  *  -> カレントディレクトリにおいて、abc/dec/ghiのディレクトリを作成。 
0046:  *     最後の/以下は通常ファイルとみなす。 
0047:  */ 
0048: static void mkDir(char *fileName) 
0049: { 
0050:   char fn[MssFileNameMaxLen]; 
0051:   char *slaPos; 
0052:   char *dirTbl[100]; 
0053:   int cnt=0; 
0054:   int i; 
0055:   int rt=0; /*ルートが指定されているかフラグ'/tmp'*/ 
0056:   int err; 
0057:   char dirStr[MssFileNameMaxLen]; 
0058:  
0059:   if(*fileName=='/'){ 
0060:     fileName++; 
0061:     rt=1; 
0062:   } 
0063:  
0064:   strcpy(fn,fileName); 
0065:  
0066:   slaPos = strtok(fn,"/"); 
0067:   while(slaPos != NULL) { 
0068:     dirTbl[cnt]=slaPos;     
0069:     slaPos = strtok(NULL,"/"); 
0070:     cnt++; 
0071:     if(cnt>=100) { 
0072:       mssShowErrMsg("too deep"); 
0073:       mssEnd(mssErrorNoDefault); 
0074:     } 
0075:   } 
0076:   if(cnt<=1) return; 
0077:  
0078:   if(rt){ 
0079:     dirStr[0]='/'; dirStr[1]='\0'; 
0080:   }else{ 
0081:     dirStr[0]='\0'; 
0082:   } 
0083:  
0084:   for(i=0; i<cnt-1; i++){ 
0085:     strcat(dirStr,dirTbl[i]); 
0086:     strcat(dirStr,"/"); 
0087:     err=mkdir(dirStr,S_IRWXU|S_IRWXG|S_IRWXO); 
0088:     if(err==-1 && errno==EEXIST) continue; 
0089:     if(err==0) continue; 
0090:     mssShowErrMsg("can not make directory(%d) : \"%s\"",errno,dirStr); 
0091:     mssEnd(mssErrorNoDefault); 
0092:   } 
0093: } 
0094:  
0095: /** 
0096:  * # FUNCTION # 
0097:  * 書き込みファイルをオープンする。 
0098:  * ファイル名(fileName)がNULLの場合は標準出力、1の場合は標準エラー出力として 
0099:  * オープンする。 
0100:  * 第二引数が1の場合は、圧縮ファイルとしてオープンし、書き込み結果は全て 
0101:  * gzip圧縮される。 
0102:  * 第三引数が1の場合は、ファイル名に含まれるディレクトリを強制的に作成する。 
0103:  */ 
0104: struct mssFPW *mssOpenFPW( char *fileName, int z, int d) 
0105: { 
0106:   struct mssFPW *fp; 
0107:   int len; 
0108:  
0109:   if(d) mkDir(fileName); 
0110:  
0111:   fp=mssMalloc(sizeof(struct mssFPW),"openFPW"); 
0112:   if(fileName==NULL || fileName==(char *)1){ 
0113:     fp->fName=fileName; 
0114:   }else{ 
0115:     fp->fName=mssMalloc(sizeof(char)*(strlen(fileName)+1),"openFPW"); 
0116:     strcpy(fp->fName,fileName); 
0117:   } 
0118:  
0119:   if(z){ 
0120:     if(fileName == NULL){ 
0121:       fp->zfd=gzdopen(1,"wb"); /*stdout*/ 
0122:     }else if(fileName==(char *)1){ 
0123:       fp->zfd=gzdopen(2,"wb"); /*stderr*/ 
0124:     }else{ 
0125:       fp->zfd=gzopen(fileName,"wb"); 
0126:     } 
0127:     if(fp->zfd == NULL) zwOpenErr(fileName); 
0128:     fp->zflg=1; 
0129:   }else{ 
0130:     if(fileName == NULL){ 
0131:       fp->fp=stdout; /*stdout*/ 
0132:       fp->zflg=0; 
0133:     }else if(fileName==(char *)1){ 
0134:       fp->fp=stderr; /*stderr*/ 
0135:       fp->zflg=0; 
0136:     }else{ 
0137:       len=strlen(fileName); 
0138:       if(0==strcmp(fileName+len-3,".gz") ){ 
0139:         fp->zfd=gzopen(fileName,"wb"); 
0140:         if(fp->zfd == NULL) zwOpenErr(fileName); 
0141:         fp->zflg=1; 
0142:       }else{ 
0143:         fp->fp=fopen(fileName,"w"); 
0144:         if(fp->fp == NULL) fwOpenErr(fileName); 
0145:         fp->zflg=0; 
0146:       } 
0147:     } 
0148:   } 
0149:   return(fp); 
0150: } 
0151:  
0152: /** 
0153:  * # FUNCTION # 
0154:  * 書き込みファイルをクローズする。 
0155:  */ 
0156: void mssCloseFPW(struct mssFPW *fp){ 
0157:  
0158:   if(fp==NULL) return; 
0159:  
0160:   if(fp->fName!=NULL && fp->fName!=(char *)1){ 
0161:     if(fp->zflg){ 
0162:       gzclose(fp->zfd); 
0163:     }else{ 
0164:       fclose(fp->fp); 
0165:     } 
0166:   } 
0167:   if(fp->fName!=NULL && fp->fName!=(char *)1 ) mssFree(fp->fName); 
0168:   mssFree(fp); 
0169: } 
0170:  
0171: /** 
0172:  * # FUNCTION # 
0173:  * xmlTableの項目デリミター文字(MssFieldDelim)の出力。 
0174:  */ 
0175: void mssWriteDlm(struct mssFPW *fp){ 
0176:   if(fp->zflg){ 
0177:     gzputc(fp->zfd,MssFieldDelim); 
0178:   }else{ 
0179:     putc(MssFieldDelim,fp->fp); 
0180:   } 
0181: } 
0182:  
0183: /** 
0184:  * # FUNCTION # 
0185:  * 改行文字の出力。 
0186:  */ 
0187: void mssWriteRet(struct mssFPW *fp){ 
0188:   if(fp->zflg){ 
0189:     gzputc(fp->zfd,'\n'); 
0190:   }else{ 
0191:     putc('\n',fp->fp); 
0192:   } 
0193: } 
0194:  
0195: /** 
0196:  * # FUNCTION # 
0197:  * 文字列の出力。 
0198:  */ 
0199: void mssWriteStr(char *str,struct mssFPW *fp){ 
0200:   if(fp->zflg){ 
0201:     gzputs(fp->zfd, str); 
0202:   }else{ 
0203:     fputs(str, fp->fp); 
0204:   } 
0205: } 
0206:  
0207: /** 
0208:  * # FUNCTION # 
0209:  * 文字の出力。 
0210:  */ 
0211: void mssWriteChr(char chr,struct mssFPW *fp){ 
0212:   if(fp->zflg){ 
0213:     gzputc(fp->zfd, chr); 
0214:   }else{ 
0215:     putc(chr, fp->fp); 
0216:   } 
0217: } 
0218:  
0219: /** 
0220:  * # FUNCTION # 
0221:  * 整数(int)の出力。 
0222:  */ 
0223: void mssWriteInt(int num,struct mssFPW *fp){ 
0224:   if(fp->zflg){ 
0225:     gzprintf(fp->zfd,"%d",num); 
0226:   }else{ 
0227:     fprintf(fp->fp,"%d",num); 
0228:   } 
0229: } 
0230:  
0231: /** 
0232:  * # FUNCTION # 
0233:  * Long整数(long)の出力。 
0234:  */ 
0235: void mssWriteLong(long num,struct mssFPW *fp){ 
0236:   if(fp->zflg){ 
0237:     gzprintf(fp->zfd,"%ld",num); 
0238:   }else{ 
0239:     fprintf(fp->fp,"%ld",num); 
0240:   } 
0241: } 
0242:  
0243: /** 
0244:  * # FUNCTION # 
0245:  * Double型実数(double)を全て10進浮動小数点表記("整数部.小数部")の書式で出力。 
0246:  */ 
0247: void mssWriteDbl(double num, struct mssFPW *fp){ 
0248:   char *buf; 
0249:  
0250:   buf=mssFtoA(num); 
0251:   mssWriteStr(buf,fp); 
0252:   mssFree(buf); 
0253: } 
0254:  
0255: /** 
0256:  * # FUNCTION # 
0257:  * Double型実数(double)を数の大きさに応じて10進浮動小数点表記もしくは 
0258:  * 10進指数表記(ex.3.14152e+10)の書式で出力。 
0259:  */ 
0260: void mssWriteDbe(double num, struct mssFPW *fp){ 
0261:   char buf[100]; 
0262:  
0263:   sprintf(buf,"%g",num); 
0264:   mssWriteStr(buf,fp); 
0265: } 
0266:  
0267: /** 
0268:  * # FUNCTION # 
0269:  * NULL値(MssNullChr)の出力。 
0270:  */ 
0271: void mssWriteNull(struct mssFPW *fp){ 
0272:   mssWriteChr(MssNullChr,fp); 
0273: } 
0274:  
0275: /** 
0276:  * # FUNCTION # 
0277:  * 現在時刻の出力。 
0278:  * sepFlgを1に指定すると、"HH:MM:SS"の書式で出力。 
0279:  * それ以外は"HHMMSS"の書式で出力。 
0280:  */ 
0281: void mssWriteTime(struct mssFPW *fp,int sepFlg){ 
0282:   time_t  long_time; 
0283:   struct tm     *nt; 
0284:   char msg[100]; 
0285:  
0286:   time(&long_time); 
0287:   nt = localtime(&long_time); 
0288:  
0289:   if(sepFlg){ 
0290:     sprintf(msg, "%02d:%02d:%02d", 
0291:           nt->tm_hour, 
0292:           nt->tm_min, 
0293:           nt->tm_sec); 
0294:   }else{ 
0295:     sprintf(msg, "%02d%02d%02d", 
0296:           nt->tm_hour, 
0297:           nt->tm_min, 
0298:           nt->tm_sec); 
0299:   } 
0300:   mssWriteStr(msg,fp); 
0301: } 
0302:  
0303: /** 
0304:  * # FUNCTION # 
0305:  * 現在日付の出力。 
0306:  * sepFlgを1に指定すると、"YYYY/MM/DD"の書式で出力。 
0307:  * それ以外は"YYYYMMDD"の書式で出力。 
0308:  */ 
0309: void mssWriteDate(struct mssFPW *fp,int sepFlg){ 
0310:   time_t  long_time; 
0311:   struct tm     *nt; 
0312:   char msg[100]; 
0313:  
0314:   time(&long_time); 
0315:   nt = localtime(&long_time); 
0316:  
0317:   /*日付*/ 
0318:   if(sepFlg){ 
0319:     sprintf(msg, "%04d/%02d/%02d", 
0320:           nt->tm_year + 1900, 
0321:           nt->tm_mon + 1, 
0322:           nt->tm_mday); 
0323:   }else{ 
0324:     sprintf(msg, "%04d%02d%02d", 
0325:           nt->tm_year + 1900, 
0326:           nt->tm_mon + 1, 
0327:           nt->tm_mday); 
0328:   } 
0329:   mssWriteStr(msg,fp); 
0330: } 
0331:  
0332: /** 
0333:  * # FUNCTION # 
0334:  * 文字列配列のcnt個の文字列を出力し、末尾文字列としてendStrを出力する。 
0335:  * 出力される文字列と文字列の間にはMssFieldDelimが出力される。 
0336:  * この関数は、通常、データ一行を出力するために利用する。 
0337:  *  
0338:  */ 
0339: void mssWriteFld(char **str, int cnt, char *endStr, struct mssFPW *fp){ 
0340:   int i; 
0341:   for(i=0; i<cnt-1; i++){ 
0342:     mssWriteStr(*(str+i),fp); 
0343:     mssWriteDlm(fp); 
0344:   } 
0345:   mssWriteStr(*(str+i),fp); 
0346:   mssWriteStr(endStr,fp); 
0347: }