1 /* 2 Copyright (C) 1993 Free Software Foundation 3 4 This file is part of the GNU IO Library. This library is free 5 software; you can redistribute it and/or modify it under the 6 terms of the GNU General Public License as published by the 7 Free Software Foundation; either version 2, or (at your option) 8 any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this library; see the file COPYING. If not, write to the Free 17 Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 19 As a special exception, if you link this library with files 20 compiled with a GNU compiler to produce an executable, this does not cause 21 the resulting executable to be covered by the GNU General Public License. 22 This exception does not however invalidate any other reasons why 23 the executable file might be covered by the GNU General Public License. */ 24 25 #include <stdarg.h> 26 #include <string.h> 27 #include "libioP.h" 28 #include "stream.h" 29 #include "strstream.h" 30 31 static char Buffer[_IO_BUFSIZ]; 32 #define EndBuffer (Buffer+_IO_BUFSIZ) 33 static char* next_chunk = Buffer; // Start of available part of Buffer. 34 35 char* form(const char* format, ...) 36 { 37 int space_left = EndBuffer - next_chunk; 38 // If less that 25% of the space is available start over. 39 if (space_left < (_IO_BUFSIZ>>2)) 40 next_chunk = Buffer; 41 char* buf = next_chunk; 42 43 strstreambuf stream(buf, EndBuffer-buf-1, buf); 44 va_list ap; 45 va_start(ap, format); 46 stream.vform(format, ap); 47 va_end(ap); 48 stream.sputc(0); 49 next_chunk = buf + stream.pcount(); 50 return buf; 51 } 52 53 #define u_long unsigned long 54 55 static char* itoa(unsigned long i, int size, int neg, int base) 56 { 57 // Conservative estimate: If base==2, might need 8 characters 58 // for each input byte, but normally 3 is plenty. 59 int needed = size ? size 60 : (base >= 8 ? 3 : 8) * sizeof(unsigned long) + 2; 61 int space_left = EndBuffer - next_chunk; 62 if (space_left <= needed) 63 next_chunk = Buffer; // start over. 64 65 char* buf = next_chunk; 66 67 register char* ptr = buf+needed+1; 68 next_chunk = ptr; 69 70 if (needed < (2+neg) || ptr > EndBuffer) 71 return NULL; 72 *--ptr = 0; 73 74 if (i == 0) 75 *--ptr = '0'; 76 while (i != 0 && ptr > buf) { 77 int ch = i % base; 78 i = i / base; 79 if (ch >= 10) 80 ch += 'a' - 10; 81 else 82 ch += '0'; 83 *--ptr = ch; 84 } 85 if (neg) 86 *--ptr = '-'; 87 if (size == 0) 88 return ptr; 89 while (ptr > buf) 90 *--ptr = ' '; 91 return buf; 92 } 93 94 char* dec(long i, int len /* = 0 */) 95 { 96 if (i >= 0) return itoa((unsigned long)i, len, 0, 10); 97 else return itoa((unsigned long)(-i), len, 1, 10); 98 } 99 char* dec(int i, int len /* = 0 */) 100 { 101 if (i >= 0) return itoa((unsigned long)i, len, 0, 10); 102 else return itoa((unsigned long)(-i), len, 1, 10); 103 } 104 char* dec(unsigned long i, int len /* = 0 */) 105 { 106 return itoa(i, len, 0, 10); 107 } 108 char* dec(unsigned int i, int len /* = 0 */) 109 { 110 return itoa(i, len, 0, 10); 111 } 112 113 char* hex(long i, int len /* = 0 */) 114 { 115 return itoa((unsigned long)i, len, 0, 16); 116 } 117 char* hex(int i, int len /* = 0 */) 118 { 119 return itoa((unsigned long)i, len, 0, 16); 120 } 121 char* hex(unsigned long i, int len /* = 0 */) 122 { 123 return itoa(i, len, 0, 16); 124 } 125 char* hex(unsigned int i, int len /* = 0 */) 126 { 127 return itoa(i, len, 0, 16); 128 } 129 130 char* oct(long i, int len /* = 0 */) 131 { 132 return itoa((unsigned long)i, len, 0, 8); 133 } 134 char* oct(int i, int len /* = 0 */) 135 { 136 return itoa((unsigned long)i, len, 0, 8); 137 } 138 char* oct(unsigned long i, int len /* = 0 */) 139 { 140 return itoa(i, len, 0, 8); 141 } 142 char* oct(unsigned int i, int len /* = 0 */) 143 { 144 return itoa(i, len, 0, 8); 145 } 146 147 static char *str(const char* s, int len, int width) 148 { 149 if (width < len) 150 width = len; 151 int space_left = EndBuffer - next_chunk; 152 if (space_left <= width + 1) 153 next_chunk = Buffer; // start over. 154 char* buf = next_chunk; 155 memset (buf, ' ', width - len); 156 memcpy (buf + width - len, s, len); 157 buf[width] = 0; 158 return buf; 159 } 160 161 char* str(const char* s, int width) 162 { 163 return str (s, strlen (s), width); 164 } 165 166 char* chr(char ch, int width) 167 { 168 char c = ch; 169 return str (&c, 1, width); 170 } 171