]> git.pond.sub.org Git - empserver/blob - src/lib/gen/vsprintf.c
Import of Empire 4.2.12
[empserver] / src / lib / gen / vsprintf.c
1 #if !defined(_WIN32)
2 #ifndef __STDC__
3
4 /* Portable vsprintf  by Robert A. Larson <blarson@skat.usc.edu> */
5
6 /* Copyright 1989 Robert A. Larson.
7  * Distribution in any form is allowed as long as the author
8  * retains credit, changes are noted by their author and the
9  * copyright message remains intact.  This program comes as-is
10  * with no warentee of fitness for any purpouse.
11  *
12  * Thanks to Doug Gwen, Chris Torek, and others who helped clarify
13  * the ansi printf specs.
14  *
15  * Please send any bug fixes and improvments to blarson@skat.usc.edu .
16  * The use of goto is NOT a bug.
17  */
18
19 /* Feb  7, 1989         blarson         First usenet release */
20
21 /* This code implements the vsprintf function, without relying on
22  * the existance of _doprint or other system specific code.
23  *
24  * Define NOVOID if void * is not a supported type.
25  *
26  * Two compile options are available for efficency:
27  *      INTSPRINTF      should be defined if sprintf is int and returns
28  *                      the number of chacters formated.
29  *      LONGINT         should be defined if sizeof(long) == sizeof(int)
30  *
31  *      They only make the code smaller and faster, they need not be
32  *      defined.
33  *
34  * UNSIGNEDSPECIAL should be defined if unsigned is treated differently
35  * than int in argument passing.  If this is definded, and LONGINT is not,
36  * the compiler must support the type unsingned long.
37  *
38  * Most quirks and bugs of the available sprintf fuction are duplicated,
39  * however * in the width and precision fields will work correctly
40  * even if sprintf does not support this, as will the n format.
41  *
42  * Bad format strings, or those with very long width and precision
43  * fields (including expanded * fields) will cause undesired results.
44  */
45 #include "misc.h"
46 #include "gen.h"
47
48 #ifdef OSK              /* os9/68k can take advantage of both */
49 #define LONGINT
50 #define INTSPRINTF
51 #endif
52
53 #define NOVOID
54
55 /* This must be a typedef not a #define! */
56 #ifdef NOVOID
57 typedef s_char *pointer;
58 #else
59 typedef void *pointer;
60 #endif
61
62 #ifdef  INTSPRINTF
63 #define Sprintf(string,format,arg)      (sprintf((string),(format),(arg)))
64 #else
65 #define Sprintf(string,format,arg)      (\
66         sprintf((string),(format),(arg)),\
67         strlen(string)\
68 )
69 #endif
70
71 #include <stdarg.h>
72
73 typedef int *intp;
74
75 int vsprintf(dest, format, args)
76 s_char *dest;
77 register s_char *format;
78 va_list args;
79 {
80     register s_char *dp = dest;
81     register s_char c;
82     register s_char *tp;
83     s_char tempfmt[64];
84 #ifndef LONGINT
85     int longflag;
86 #endif
87
88     tempfmt[0] = '%';
89     while(c = *format++) {
90         if(c=='%') {
91             tp = &tempfmt[1];
92 #ifndef LONGINT
93             longflag = 0;
94 #endif
95 continue_format:
96             switch(c = *format++) {
97                 case 's':
98                     *tp++ = c;
99                     *tp = '\0';
100                     dp += Sprintf(dp, tempfmt, va_arg(args, s_char *));
101                     break;
102                 case 'u':
103                 case 'x':
104                 case 'o':
105                 case 'X':
106 #ifdef UNSIGNEDSPECIAL
107                     *tp++ = c;
108                     *tp = '\0';
109 #ifndef LONGINT
110                     if(longflag)
111                         dp += Sprintf(dp, tempfmt, va_arg(args, unsigned long));
112                     else
113 #endif
114                         dp += Sprintf(dp, tempfmt, va_arg(args, unsigned));
115                     break;
116 #endif
117                 case 'd':
118                 case 'c':
119                 case 'i':
120                     *tp++ = c;
121                     *tp = '\0';
122 #ifndef LONGINT
123                     if(longflag)
124                         dp += Sprintf(dp, tempfmt, va_arg(args, long));
125                     else
126 #endif
127                         dp += Sprintf(dp, tempfmt, va_arg(args, int));
128                     break;
129                 case 'f':
130                 case 'e':
131                 case 'E':
132                 case 'g':
133                 case 'G':
134                     *tp++ = c;
135                     *tp = '\0';
136                     dp += Sprintf(dp, tempfmt, va_arg(args, double));
137                     break;
138                 case 'p':
139                     *tp++ = c;
140                     *tp = '\0';
141                     dp += Sprintf(dp, tempfmt, va_arg(args, pointer));
142                     break;
143                 case '-':
144                 case '+':
145                 case '0':
146                 case '1':
147                 case '2':
148                 case '3':
149                 case '4':
150                 case '5':
151                 case '6':
152                 case '7':
153                 case '8':
154                 case '9':
155                 case '.':
156                 case ' ':
157                 case '#':
158                 case 'h':
159                     *tp++ = c;
160                     goto continue_format;
161                 case 'l':
162 #ifndef LONGINT
163                     longflag = 1;
164                     *tp++ = c;
165 #endif
166                     goto continue_format;
167                 case '*':
168                     tp += Sprintf(tp, "%d", va_arg(args, int));
169                     goto continue_format;
170                 case 'n':
171                     *va_arg(args, intp) = dp - dest;
172                     break;
173                 case '%':
174                 default:
175                     *dp++ = c;
176                     break;
177             }
178         } else *dp++ = c;
179     }
180     *dp = '\0';
181     return dp - dest;
182 }
183
184 #endif /* __STDC__ */
185 #endif