//***************************************************************************** // 軽量版 putc,puts,printf,sprintf,vsprintf 関数 // (C)YdlProg //***************************************************************************** #include #include #include #include "../lib3052/typedef.h" //============================================================================= // プロトタイプ宣言 //============================================================================= //------------------------------------------------------------------------- // sprintf.c //------------------------------------------------------------------------- extern unsigned char *_smr_adr[] ; // 標準入出力関数の入出力先の割り当て //***************************************************************************** // Yellow Scope へ1文字出力 // // _putc_ys // 2004/12/23 : 初期バージョン完成 // // [IN] char code = 出力コード // // [OUT] なし //***************************************************************************** static void _putc_ys(char c) { Uint8 *tdr = _smr_adr[1] + 3 ; Uint8 *ssr = _smr_adr[1] + 4 ; while((*ssr & 0x80) == 0) ; // 送信完了待ち *tdr = c ; // 送信 *ssr &= ~0x80 ; // フラグクリア } //***************************************************************************** // 標準出力に1文字出力 // // _putc // 2004/12/23 : 初期バージョン完成 // // [IN] char code = 出力コード // // [OUT] なし //***************************************************************************** void _putc(char code) { Uint8 *scr = _smr_adr[1] + 2 ; *scr &= ~0x40 ; _putc_ys(0x48) ; _putc_ys(0x01) ; _putc_ys(code) ; _putc_ys(-(0x48 + 0x01 + code)) ; *scr |= 0x40 ; } //***************************************************************************** // 標準出力に文字列出力 // // _puts // 2004/12/23 : 初期バージョン完成 // // [IN] char *str = 出力文字列 // // [OUT] なし //***************************************************************************** void _puts(const char *str) { while(*str) { _putc(*str) ; *str ++ ; } } //***************************************************************************** // 軽量版 printf // // _printf // 2004/12/22 : 初期バージョン完成 // // [IN] char *format = 書式文字列 // // [OUT] なし //***************************************************************************** void _printf(const char *format,...) { char buff[256] ; char *str = buff ; va_list argptr ; va_start(argptr,format) ; _vsprintf(buff,format,argptr) ; va_end(argptr) ; _puts(str) ; } //***************************************************************************** // 軽量版 sprintf // // _sprintf // 2004/12/22 : 初期バージョン完成 // // [IN] char *buff = 展開バッファのポインタ // char *format = 書式文字列 // // [OUT] なし //***************************************************************************** void _sprintf(char *buff,const char *format,...) { va_list argptr ; va_start(argptr,format) ; _vsprintf(buff,format,argptr) ; va_end(argptr) ; } //***************************************************************************** // printf,sprintf 展開処理 // // _vsprintf // 2004/12/23 : 初期バージョン完成 // // [IN] char *buff = 展開バッファのポインタ // char *format = 書式文字列 // va_list argptr = 引数リストのポインタ // // [OUT] なし // // 備考:%c %s %d %u %x %X と %-05d 等の、左寄せ、桁数指定、 // 0 で埋めるは使用可能。%f %e 等の小数点を含むものは使用できない。 //***************************************************************************** void _vsprintf(char *buff,const char *format,va_list argptr) { Uint8 lflag ; int ecx,len ; while(*format) { switch(*format) { case '%' : format ++ ; lflag = 0 ; if(*format == '-') { // 左詰め lflag |= (1 << 0) ; format ++ ; } if(*format == '0') { // 0 で埋める lflag |= (1 << 1) ; format ++ ; } len = 0 ; // 桁数指定 if((*format >= '1') && (*format <= '9')) { while((*format >= '0') && (*format <= '9')) { len = len * 10 + *format - '0' ; format ++ ; } } switch(*format) { case 'c' : if(len) { memset(buff,' ',len) ; if(lflag & (1 << 0)) { *buff = va_arg(argptr,char) ; } else { buff[len - 1] = va_arg(argptr,char) ; } buff += len ; } else { *buff = va_arg(argptr,char) ; buff ++ ; if(*buff) buff ++ ; // パッチ 2005/01/14 } format ++ ; break ; case 's' : { char *str = va_arg(argptr,char *) ; int slen = strlen(str) ; if(len) { if(slen > len) len = slen ; memset(buff,' ',len) ; if(lflag & (1 << 0)) { memcpy(buff,str,slen) ; } else { memcpy(&buff[len - slen],str,slen) ; } buff += len ; } else { memcpy(buff,str,slen) ; buff += slen ; } format ++ ; break ; } case 'd' : case 'u' : case 'x' : case 'X' : { char str[6] ; int slen = 0 ; BOOL act = FALSE ; switch(*format) { case 'd' : { int num = va_arg(argptr,int) ; if(num < 0) { *buff = '-' ; buff ++ ; if(len) len -- ; num = ~num + 1 ; } for(ecx = 10000 ; ecx != 0 ; ecx /= 10) { str[slen] = num / ecx + '0' ; num %= ecx ; if((str[slen] != '0') || (act)) { act = TRUE ; slen ++ ; } } break ; } case 'u' : { Uint16 num = va_arg(argptr,Uint16) ; for(ecx = 10000 ; ecx != 0 ; ecx /= 10) { str[slen] = num / ecx + '0' ; num %= ecx ; if((str[slen] != '0') || (act)) { act = TRUE ; slen ++ ; } } break ; } case 'x' : case 'X' : { Uint16 num = (Uint16)va_arg(argptr,int) ; for(ecx = 0 ; ecx < 16 / 4 ; ecx ++) { str[slen] = (num >> (12 - (ecx << 2))) & 0x0f ; if(str[slen] <= 9) str[slen] += '0' ; else if(*format == 'x') str[slen] += 'a' - 10 ; else str[slen] += 'A' - 10 ; if(str[0] == '0') continue ; slen ++ ; } break ; } } if(!slen) slen ++ ; if(len) { if(slen > len) len = slen ; if(lflag & (1 << 1)) memset(buff,'0',len) ; else memset(buff,' ',len) ; if(lflag & (1 << 0)) { memcpy(buff,str,slen) ; } else { memcpy(&buff[len - slen],str,slen) ; } buff += len ; } else { memcpy(buff,str,slen) ; buff += slen ; } format ++ ; break ; } } break ; default : *buff = *format ++ ; buff ++ ; break ; } } *buff = 0 ; }