xref: /haiku/src/libs/stdc++/legacy/stream.cc (revision 16d5c24e533eb14b7b8a99ee9f3ec9ba66335b1e)
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 
form(const char * format,...)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 
itoa(unsigned long i,int size,int neg,int base)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 
dec(long i,int len)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 }
dec(int i,int len)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 }
dec(unsigned long i,int len)104 char* dec(unsigned long i, int len /* = 0 */)
105 {
106     return itoa(i, len, 0, 10);
107 }
dec(unsigned int i,int len)108 char* dec(unsigned int i, int len /* = 0 */)
109 {
110     return itoa(i, len, 0, 10);
111 }
112 
hex(long i,int len)113 char* hex(long i, int len /* = 0 */)
114 {
115     return itoa((unsigned long)i, len, 0, 16);
116 }
hex(int i,int len)117 char* hex(int i, int len /* = 0 */)
118 {
119     return itoa((unsigned long)i, len, 0, 16);
120 }
hex(unsigned long i,int len)121 char* hex(unsigned long i, int len /* = 0 */)
122 {
123     return itoa(i, len, 0, 16);
124 }
hex(unsigned int i,int len)125 char* hex(unsigned int i, int len /* = 0 */)
126 {
127     return itoa(i, len, 0, 16);
128 }
129 
oct(long i,int len)130 char* oct(long i, int len /* = 0 */)
131 {
132     return itoa((unsigned long)i, len, 0, 8);
133 }
oct(int i,int len)134 char* oct(int i, int len /* = 0 */)
135 {
136     return itoa((unsigned long)i, len, 0, 8);
137 }
oct(unsigned long i,int len)138 char* oct(unsigned long i, int len /* = 0 */)
139 {
140     return itoa(i, len, 0, 8);
141 }
oct(unsigned int i,int len)142 char* oct(unsigned int i, int len /* = 0 */)
143 {
144     return itoa(i, len, 0, 8);
145 }
146 
str(const char * s,int len,int width)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 
str(const char * s,int width)161 char* str(const char* s, int width)
162 {
163   return str (s, strlen (s), width);
164 }
165 
chr(char ch,int width)166 char* chr(char ch, int width)
167 {
168   char c = ch;
169   return str (&c, 1, width);
170 }
171