📄 printf.c,v
字号:
head 1.3;access;symbols;locks root:1.3; strict;comment @ * @;1.3date 2004.06.01.02.59.13; author root; state Exp;branches;next 1.2;1.2date 2004.05.24.13.29.03; author root; state Exp;branches;next 1.1;1.1date 2004.05.24.12.34.29; author root; state Exp;branches;next ;desc@@1.3log@add fprintf()@text@/* Snixos Project version 1.0, 2003.6 (C) Copyright 2003-2004 Snallie Jockeyson <Snallie@@tom.com> All Rights Reserved. Distributed under the terms of the GNU General Public License. printf.c: implementation of c function printf() in SNIXOS project Author : snallie@@tom.com Time : 2003.6 understood printf escape sequence: %c = char %d = signed int %x = unpaded hex %s = string %0x = padded hex %o = octal %b = binary*//* $Id: printf.c,v 1.2 2004/05/24 13:29:03 root Exp $ */#ifndef lintstatic char vcid[] = "$Id: printf.c,v 1.2 2004/05/24 13:29:03 root Exp $";#endif /* lint */#include "stdarg.h"#include "stdio.h"#include "ctype.h"#include "io.h"#include "mem.h"#include "fatfs.h"#define RESERVEDLINES 1 // head line reserved as status bar, 0 means the whole screen // will be scrolled #define XUPPER 1#define XLOWER 0// Video Card I/O ports#define TEXT_INDEX 0x03D4#define TEXT_DATA 0x03D5// Video Card Index Registers#define TEXT_CURSOR_LO 0x0F#define TEXT_CURSOR_HI 0x0Estatic void printChar(char **str, int *len, char c);static void printStr(char **str, int *len, char *pstr);static void printInt(char **str, int *len, int num, int width);static void printHex(char **str, int *len, unsigned int hex, int padded, int style);static void vaPrintf(char **str, int *len, char *fmt, va_list pvar);static unsigned char getChar(int x, int y);static unsigned char getAttrib(int x, int y);static void scrollup(void);static void writeChar(char c);static void TXTWriteChar(char c);static int intLen(int i, int radix);static unsigned char *vidmem; /* VGA video buffer for 80*25 color text mode */static int vidx; /* current cursor X position on screen */static int vidy; /* current cursor Y position on screen */static unsigned char curAttrib; /* current screent text attribute */extern int videoMode;/* * console output functions */void print_char(char c){ int i = -1; printChar(NULL, &i, c);}void print_str(char *str){ int i = -1; printStr(NULL, &i, str);}void print_int(int num){ int i = -1; printInt(NULL, &i, num, 0);}void print_hex(unsigned int hex, int padded){ int i = -1; printHex(NULL, &i, hex, padded, XLOWER);}void printf(char *fmt, ...){ int i = -1; va_list pvar; va_start(pvar, fmt); vaPrintf(NULL, &i, fmt, pvar); va_end(pvar);}void sprintf(char *str, char *fmt, ...){ int i = -1; va_list pvar; va_start(pvar, fmt); vaPrintf(&str, &i, fmt, pvar); va_end(pvar);}void snprintf(char *str, int len, char *fmt, ...){ va_list pvar; va_start(pvar, fmt); vaPrintf(&str, &len, fmt, pvar); va_end(pvar);}int fprintf(FILE * fp, char *fmt, ...){ char nstr[100]; int i = -1; char *str = nstr; va_list pvar; va_start(pvar, fmt); vaPrintf(&str, &i, fmt, pvar); va_end(pvar); i = 0; while (*(str + i)) { Mfputc(*(str + i), fp); printf("%c", *(str + i)); i++; } return i;}/* * base functions for printf implementation */static void printChar(char **str, int *len, char c){ if (str) { if (*len != 0) { *(*str)++ = c; (*len)--; } } else { writeChar(c); }}static void printStr(char **str, int *len, char *pstr){ while (*pstr) { printChar(str, len, *pstr); pstr++; }}/*printInt()print the num in decimal mode*/static void printInt(char **str, int *len, int num, int width){ char nstr[12]; int i = 10, j = 0; if (num < 0) { printChar(str, len, '-'); printInt(str, len, -1 * num, width - 1); return; } nstr[11] = '\0'; while (i > 0) { nstr[i % 11] = '0' + (num % 10); num /= 10; i--; if ((j >= width - 1) && (num <= 0)) break; else j++; } printStr(str, len, nstr + i + 1);}/*printHex()printf the hex in hexadecimal mode */static void printHex(char **str, int *len, unsigned int hex, int pad, int style){ char nstr[14]; int i = 12, j; nstr[13] = '\0'; pad--; for (j = 0; j < 8; j++) { if ((hex % 16) < 10) nstr[i] = '0' + (hex % 16); else nstr[i] = ((style == XLOWER) ? 'a' : 'A') + ((hex % 16) - 10); hex /= 16; i--; if ((j >= pad) && (hex <= 0)) break; } printStr(str, len, nstr + i + 1);}/*void printOct(char **str, int *len, unsigned int num)print the integer num in octal mode */static void printOct(char **str, int *len, unsigned int num){ int octLen = intLen(num, 8), i; char *octbuf = (char *) malloc((octLen + 1) * sizeof(char)); if (octbuf == NULL) { printf("malloc failed in printOct\n"); return; } i = octLen - 1; octbuf[octLen] = '\0'; while (num) { octbuf[i % octLen] = num % 8 + '0'; num /= 8; i--; } printStr(str, len, octbuf + i + 1); free(octbuf);}/*void printBin(char **str, int *len, unsigned int num)print the integer num in binary mode */static void printBin(char **str, int *len, unsigned int num){ int len2; int binLen = intLen(num, 2), i; char *binbuf = (char *) malloc(((binLen - 1) / 8 + 1) * 8 * sizeof(char) + sizeof(char)); if (binbuf == NULL) { printf("malloc failed in printBin\n"); return; } len2 = ((binLen - 1) / 8 + 1) * 8 * sizeof(char) + sizeof(char); i = ((binLen - 1) / 8 + 1) * 8 * sizeof(char) - 1; binbuf[((binLen - 1) / 8 + 1) * 8 * sizeof(char)] = '\0'; while (i >= 0) { binbuf[i % len2] = num % 2 + '0'; num /= 2; i--; } printStr(str, len, binbuf + i + 1); free(binbuf);}static void vaPrintf(char **str, int *len, char *fmt, va_list pvar){ while (*fmt) { if (*fmt == '%') { fmt++; if (!*fmt) { if (str) { /* add end of line to array tp for sprintf(tp,char * ,...) */ printChar(str, len, '\0'); } return; } switch (*fmt) { case 's': /* %s */ printStr(str, len, va_arg(pvar, char *)); break; case 'c': /* %c */ printChar(str, len, va_arg(pvar, char)); break; case 'd': /* %d */ printInt(str, len, va_arg(pvar, int), 0); break; case 'x': case 'X': /* %x or %X */ printHex(str, len, va_arg(pvar, unsigned int), 0, (*fmt == 'x') ? XLOWER : XUPPER); break; case 'o': /* %o */ printOct(str, len, va_arg(pvar, unsigned int)); break; case 'b': /* %b , binary output for number */ printBin(str, len, va_arg(pvar, unsigned int)); break; case '0': /* %0x %0X %0d */ fmt++; switch (*fmt) { case 'x': case 'X': printHex(str, len, va_arg(pvar, unsigned int), 8, (*fmt == 'x') ? XLOWER : XUPPER); goto ret1; case 'd': printInt(str, len, va_arg(pvar, int), 10); goto ret1; } if (isdigit(*fmt)) { int width = 0; while (isdigit(*fmt)) { width = (width * 10 + (*fmt) - '0'); fmt++; } if (*fmt == 'x' || *fmt == 'X') { printHex(str, len, va_arg(pvar, unsigned int), width, *fmt == 'x' ? XLOWER : XUPPER); } else if (*fmt == 'd') { printInt(str, len, va_arg(pvar, int), width); } } ret1: break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* %12x %12X %12d %12s %12c */ if (isdigit(*fmt)) { int width; for (width = 0; isdigit(*fmt); fmt++) { width = (width * 10 + (*fmt) - '0'); } if (*fmt == 'x' || *fmt == 'X') { printHex(str, len, va_arg(pvar, unsigned int), width, *fmt == 'x' ? XLOWER : XUPPER); } else if (*fmt == 'd') { int num = va_arg(pvar, int); int length = intLen(num, 10); while (width > length) { printChar(str, len, ' '); width--; } printInt(str, len, num, length); } else if (*fmt == 's') { char *strs = va_arg(pvar, char *); int strSize = strlen(strs); while (width - strSize > 0) { printChar(str, len, ' '); strSize++; } printStr(str, len, strs); } else if (*fmt == 'c') { width -= 1; while (width > 0) { printChar(str, len, ' '); width--; } printChar(str, len, va_arg(pvar, char)); } } break; case '-': /* %-12s %-12d %-12c , left aligned */ fmt++; if (isdigit(*fmt)) { int width = 0; while (isdigit(*fmt)) { width = (width * 10 + (*fmt) - '0'); fmt++; } if (*fmt == 's') { char *strs = va_arg(pvar, char *); int strSize = strlen(strs); printStr(str, len, strs); while (width - strSize > 0) { printChar(str, len, ' '); strSize++; } } else if (*fmt == 'd') { int num = va_arg(pvar, int); int length = intLen(num, 10); printInt(str, len, num, length); while (width - length > 0) { printChar(str, len, ' '); length++; } } else if (*fmt == 'c') { printChar(str, len, va_arg(pvar, char)); width -= 1; while (width > 0) { printChar(str, len, ' '); width--; } } } break; case '%': /* %% */ printChar(str, len, '%'); fmt++; break; default: break; } } else { printChar(str, len, *fmt); } fmt++; } /* while(*fmt) */ if (str) { /* add end of line to array tp for sprintf(tp,char *fmt, ...) */ printChar(str, len, '\0'); }}/*int intLen(int i, int radix) return the count of i's digit which is beneath the most significant digit in the desired radix. */static int intLen(int i, int radix){ int len = 0; if (i < 0) { return intLen(-i, radix); } do { i /= radix; len++; } while (i); return len;}/* VGA screen manipulation */void screen_init(void){ int i, j; vidmem = (unsigned char *) 0xb8000; set_attrib(ATTRIB_WHITE | ATTRIB_BLACK_BG); for (i = 0; i < 80; i++) { for (j = 0; j < 25; j++) { screen_putchar(i, j, ' ', curAttrib); } } //line 1 reserved as status bar screen_gotoxy(0, 0 + RESERVEDLINES);}void screen_gotoxy(int x, int y){ short pos = y * 80 + x; vidx = x; vidy = y; outb(TEXT_CURSOR_LO, TEXT_INDEX); // access lo cursor data reg outb((char) pos, TEXT_DATA); outb(TEXT_CURSOR_HI, TEXT_INDEX); // access hi cursor data reg outb((unsigned char) (pos >> 8), TEXT_DATA);}void screen_putchar(int x, int y, unsigned char c, unsigned char attrib){ vidmem[((x) + (y) * 80) * 2] = c; vidmem[(((x) + (y) * 80) * 2) + 1] = attrib;}static unsigned char getChar(int x, int y){ return vidmem[((x) + (y) * 80) * 2];}static unsigned char getAttrib(int x, int y){ return vidmem[(((x) + (y) * 80) * 2) + 1];}static void scrollup(void){ unsigned int org = (unsigned int) vidmem + (RESERVEDLINES + 1) * 160; unsigned int dst = (unsigned int) vidmem + RESERVEDLINES * 160; unsigned int cnt = 2000 - 80 * (RESERVEDLINES + 1); unsigned int cnt2 = 80; /* characters to be displaed at the bottom line on screen */ unsigned int dst2 = (unsigned int) vidmem + 24 * 80 * 2; /* bottom line address in vidram */ asm("cld\n\t" "rep\n\t" "movsl\n\t"::"c"(cnt), "D"(dst), "S"(org)); asm("cld\n\t" "rep\n\t" "stosw\n\t"::"a"(0x0720), "c"(cnt2), "D"(dst2), "S"(org));}static void writeChar(char c){ switch (videoMode) { case VIDTEXT_80X25: TXTWriteChar(c); break; case VIDGRAPH_640X480: VGAWriteChar(c); break; }}static void TXTWriteChar(char c){ if (c == '\n') { // CR LF screen_gotoxy(0, ++vidy); // screen_gotoxy(ycord,xcord) } else if (c == '\t') { // horizontal Tab screen_gotoxy(vidx += 4, vidy); } else if (c == '\b') { // backspace screen_gotoxy(vidx -= 1, vidy); writeChar(' '); screen_gotoxy(vidx -= 1, vidy); return; } else { screen_putchar(vidx, vidy, (unsigned char) c, curAttrib); screen_gotoxy(++vidx, vidy); } // off right edge if (vidx > 79) { screen_gotoxy(0, ++vidy); } // off bottom if (vidy > 24) { scrollup(); screen_gotoxy(vidx, 24); }}void set_attrib(unsigned char attrib){ curAttrib = attrib;}@1.2log@add comments to some auxilary function@text@d18 1a18 1/* $Id$ */d21 2a22 2static char vcid[] = "$Id$";#endif /* lint */d29 1d46 1a46 1 int padded, int style);d52 1d59 1a59 1d114 21d191 1a191 1 int pad, int style)d271 1a271 1 if (str){ /* add end of line to array tp for sprintf(tp,char * ,...)*/d292 1a292 1 (*fmt == 'x') ? XLOWER : XUPPER);d309 2a310 2 va_arg(pvar, unsigned int), 8, (*fmt == 'x') ? XLOWER : XUPPER);d326 2a327 2 va_arg(pvar, unsigned int), width, *fmt == 'x' ? XLOWER : XUPPER);d352 2a353 2 va_arg(pvar, unsigned int), width, *fmt == 'x' ? XLOWER : XUPPER);d431 1a431 1 } /* while(*fmt) */d433 1a433 1 if (str){ /* add end of line to array tp for sprintf(tp,char *fmt, ...) */d446 1a446 1 if (i < 0){d515 15d553 1a559 7@1.1log@Initial revision@text@d12 1a12 1 understood printf escape chars:d18 6d34 6a52 8// Video Card I/O ports#define TEXT_INDEX 0x03D4#define TEXT_DATA 0x03D5// Video Card Index Registers#define TEXT_CURSOR_LO 0x0F#define TEXT_CURSOR_HI 0x0Ed113 1a113 1 * core functionsd135 4a159 1d163 4a174 1a184 1a185 1d188 4d212 4a217 1a241 1a306 1a307 2a325 46 /* switch (*fmt) { case 'x': case 'X': printHex(str, len, va_arg(pvar, unsigned int), width, *fmt == 'x' ? XLOWER : XUPPER); break; case 'd': { int num = va_arg(pvar, int); int length = intLen(num, 10); while (width > length) { printf("%c", ' '); width--; } printf("%d", num); } break; case 's': { char *strs = va_arg(pvar, char *); int strSize = strlen(strs); while (width > strSize) { printf("%c", ' '); strSize++; } printf("%s", strs); } break; case 'c': { width -= 1; while (width > 0) { printf("%c", ' '); width--; } printf("%c", va_arg(pvar, char)); } break; } */a355 2a356 1a383 1d409 1d415 5d423 1a423 1 if (i < 0)d425 1a432 1a484 1@
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -