| 
					
				 | 
			
			
				@@ -5,6 +5,23 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <string.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <unistd.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define BUFSIZ (4096) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static char __stdout_buf[BUFSIZ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static size_t __stdout_buf_cnt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline void __buf_flush(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    write(STDOUT_FILENO, __stdout_buf, __stdout_buf_cnt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    __stdout_buf_cnt = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline void __buf_put(int c) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    __stdout_buf[__stdout_buf_cnt++] = c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (__stdout_buf_cnt == BUFSIZ || c == '\n') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        __buf_flush(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 // where n is in the range of [0, 9] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static inline char d_to_c(int32_t n) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -368,18 +385,14 @@ int sprintf(char* buf, const char* fmt, ...) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 int puts(const char* str) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    int len = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    int ret = write(STDOUT_FILENO, str, strlen(str)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (ret < 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return EOF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    len += ret; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ret = write(STDOUT_FILENO, "\n", 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (ret < 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return EOF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    len += ret; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 1 is for \n at the end 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    int len = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // TODO: FILE* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (const char* p = str; *p; ++p, ++len) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        __buf_put(*p); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    __buf_put('\n'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return len; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -395,3 +408,188 @@ char* gets(char* buf) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int vprintf_u32(uint32_t num) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (num <= 9) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        __buf_put(d_to_c(num)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    int ret = vprintf_u32(num / 10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    __buf_put(d_to_c(num % 10)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return ret + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int vprintf_d32(int32_t num) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (num < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        __buf_put('-'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return vprintf_u32(-num) + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return vprintf_u32(num); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int vprintf_u64(uint64_t num) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (num <= 9) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        __buf_put(d_to_c(num)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    int ret = vprintf_u64(num / 10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    __buf_put(d_to_c(num % 10)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return ret + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int vprintf_d64(int64_t num) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (num < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        __buf_put('-'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return vprintf_u64(-num) + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return vprintf_u64(num); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int vprintf_x32(uint32_t num, int off) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // print leading 0x 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (off & 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        --off; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        __buf_put('0'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        __buf_put('X' + off); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return vprintf_x32(num, off) + 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (num <= 15) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        __buf_put(X_to_c(num) + off); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    int ret = vprintf_x32(num >> 4, off); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    __buf_put(X_to_c(num & 0xf) + off); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return ret + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int vprintf_x64(uint64_t num, int off) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // print leading 0x 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (off & 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        --off; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        __buf_put('0'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        __buf_put('X' + off); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return vprintf_x64(num, off) + 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (num <= 15) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        __buf_put(X_to_c(num) + off); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    int ret = vprintf_x64(num >> 4, off); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    __buf_put(X_to_c(num & 0xf) + off); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return ret + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int vprintf(const char* fmt, va_list args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    int n = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (char c = 0; (c = *fmt) != 0x00; ++fmt) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (c == '%') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            switch (*(++fmt)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case 'd': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                n += vprintf_d32(va_arg(args, int)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case 'x': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                n += vprintf_x32(va_arg(args, unsigned int), 'a' - 'A' + 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case 'X': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                n += vprintf_x32(va_arg(args, unsigned int), 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // long decimal 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case 'l': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                switch (*(++fmt)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // long long aka int64 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                case 'l': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    switch (*(++fmt)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    case 'd': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        n += vprintf_d64(va_arg(args, long long)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    case 'x': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        n += vprintf_x64(va_arg(args, unsigned long long), 'a' - 'A' + 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    case 'X': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        n += vprintf_x64(va_arg(args, unsigned long long), 'a' - 'A' + 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // long int aka int32 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                case 'd': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    n += vprintf_d32(va_arg(args, int)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                case 'x': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    n += vprintf_x32(va_arg(args, unsigned int), 'a' - 'A' + 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                case 'X': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    n += vprintf_x32(va_arg(args, unsigned int), 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // c string 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case 's': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                n += printf(va_arg(args, const char*)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // int8 char 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case 'c': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ++n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                __buf_put(va_arg(args, int)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // pointer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case 'p': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#ifdef __32bit_system 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                n += vprintf_x32(va_arg(args, size_t), 'a' - 'A' + 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                n += vprintf_x64(va_arg(args, size_t), 'a' - 'A' + 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ++n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                __buf_put(*(fmt - 1)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ++n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            __buf_put(c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int printf(const char* fmt, ...) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    va_list args; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    va_start(args, fmt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    int ret = vprintf(fmt, args); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    va_end(args); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return ret; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int putchar(int c) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    __buf_put(c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 |