Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/tools/widl/utils.c
4388 views
1
/*
2
* Utility routines
3
*
4
* Copyright 1998 Bertho A. Stultiens
5
* Copyright 2002 Ove Kaaven
6
*
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
11
*
12
* This library is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
16
*
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this library; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20
*/
21
22
#include "config.h"
23
24
#include <assert.h>
25
#include <stdio.h>
26
#include <stdlib.h>
27
#include <stdarg.h>
28
#include <string.h>
29
#include <ctype.h>
30
31
#include "widl.h"
32
#include "utils.h"
33
#include "parser.h"
34
35
void error_at( const struct location *where, const char *s, ... )
36
{
37
char buffer[1024];
38
39
va_list ap;
40
va_start( ap, s );
41
vsnprintf( buffer, sizeof(buffer), s, ap );
42
va_end( ap );
43
44
parser_error( where, buffer );
45
exit( 1 );
46
}
47
48
void error(const char *s, ...)
49
{
50
va_list ap;
51
va_start(ap, s);
52
fprintf(stderr, "error: ");
53
vfprintf(stderr, s, ap);
54
va_end(ap);
55
exit(2);
56
}
57
58
void warning(const char *s, ...)
59
{
60
va_list ap;
61
va_start(ap, s);
62
fprintf(stderr, "warning: ");
63
vfprintf(stderr, s, ap);
64
va_end(ap);
65
}
66
67
void warning_at( const struct location *where, const char *s, ... )
68
{
69
char buffer[1024];
70
71
va_list ap;
72
va_start( ap, s );
73
vsnprintf( buffer, sizeof(buffer), s, ap );
74
va_end( ap );
75
76
parser_warning( where, buffer );
77
}
78
79
void chat(const char *s, ...)
80
{
81
if(debuglevel & DEBUGLEVEL_CHAT)
82
{
83
va_list ap;
84
va_start(ap, s);
85
fprintf(stderr, "chat: ");
86
vfprintf(stderr, s, ap);
87
va_end(ap);
88
}
89
}
90
91
size_t widl_getline(char **linep, size_t *lenp, FILE *fp)
92
{
93
char *line = *linep;
94
size_t len = *lenp;
95
size_t n = 0;
96
97
if (!line)
98
{
99
len = 64;
100
line = xmalloc(len);
101
}
102
103
while (fgets(&line[n], len - n, fp))
104
{
105
n += strlen(&line[n]);
106
if (line[n - 1] == '\n')
107
break;
108
else if (n == len - 1)
109
{
110
len *= 2;
111
line = xrealloc(line, len);
112
}
113
}
114
115
*linep = line;
116
*lenp = len;
117
return n;
118
}
119
120
void strappend( struct strbuf *str, const char *fmt, ... )
121
{
122
va_list ap;
123
int n;
124
125
assert( (str->len == 0 && str->buf == NULL) ||
126
(str->len != 0 && str->buf != NULL) );
127
128
for (;;)
129
{
130
va_start( ap, fmt );
131
n = str->len ? vsnprintf( str->buf + str->pos, str->len - str->pos, fmt, ap ) : 128;
132
va_end( ap );
133
if (n >= 0 && n <= str->len && str->pos + n < str->len) break;
134
str->len = max( str->pos + n, str->len * 3 / 2 );
135
str->buf = xrealloc( str->buf, str->len );
136
}
137
138
str->pos += n;
139
}
140
141
/*******************************************************************
142
* buffer management
143
*
144
* Function for writing to a memory buffer.
145
*/
146
147
unsigned char *output_buffer;
148
size_t output_buffer_pos;
149
size_t output_buffer_size;
150
151
static struct resource
152
{
153
unsigned char *data;
154
size_t size;
155
} resources[16];
156
static unsigned int nb_resources;
157
158
static inline void put_resource_id( const char *str )
159
{
160
if (str[0] != '#')
161
{
162
while (*str)
163
{
164
unsigned char ch = *str++;
165
put_word( toupper(ch) );
166
}
167
put_word( 0 );
168
}
169
else
170
{
171
put_word( 0xffff );
172
put_word( atoi( str + 1 ));
173
}
174
}
175
176
void add_output_to_resources( const char *type, const char *name )
177
{
178
size_t data_size = output_buffer_pos;
179
size_t header_size = 5 * sizeof(unsigned int) + 2 * sizeof(unsigned short);
180
181
assert( nb_resources < ARRAY_SIZE( resources ));
182
183
if (type[0] != '#') header_size += (strlen( type ) + 1) * sizeof(unsigned short);
184
else header_size += 2 * sizeof(unsigned short);
185
if (name[0] != '#') header_size += (strlen( name ) + 1) * sizeof(unsigned short);
186
else header_size += 2 * sizeof(unsigned short);
187
188
header_size = (header_size + 3) & ~3;
189
align_output( 4 );
190
check_output_buffer_space( header_size );
191
resources[nb_resources].size = header_size + output_buffer_pos;
192
memmove( output_buffer + header_size, output_buffer, output_buffer_pos );
193
194
output_buffer_pos = 0;
195
put_dword( data_size ); /* ResSize */
196
put_dword( header_size ); /* HeaderSize */
197
put_resource_id( type ); /* ResType */
198
put_resource_id( name ); /* ResName */
199
align_output( 4 );
200
put_dword( 0 ); /* DataVersion */
201
put_word( 0 ); /* Memory options */
202
put_word( 0 ); /* Language */
203
put_dword( 0 ); /* Version */
204
put_dword( 0 ); /* Characteristics */
205
206
resources[nb_resources++].data = output_buffer;
207
init_output_buffer();
208
}
209
210
void flush_output_resources( const char *name )
211
{
212
unsigned int i;
213
214
/* all output must have been saved with add_output_to_resources() first */
215
assert( !output_buffer_pos );
216
217
put_dword( 0 ); /* ResSize */
218
put_dword( 32 ); /* HeaderSize */
219
put_word( 0xffff ); /* ResType */
220
put_word( 0x0000 );
221
put_word( 0xffff ); /* ResName */
222
put_word( 0x0000 );
223
put_dword( 0 ); /* DataVersion */
224
put_word( 0 ); /* Memory options */
225
put_word( 0 ); /* Language */
226
put_dword( 0 ); /* Version */
227
put_dword( 0 ); /* Characteristics */
228
229
for (i = 0; i < nb_resources; i++)
230
{
231
put_data( resources[i].data, resources[i].size );
232
free( resources[i].data );
233
}
234
flush_output_buffer( name );
235
nb_resources = 0;
236
}
237
238
/* pointer-sized word */
239
void put_pword( unsigned int val )
240
{
241
if (pointer_size == 8) put_qword( val );
242
else put_dword( val );
243
}
244
245
void put_str( int indent, const char *format, ... )
246
{
247
int n;
248
va_list args;
249
250
check_output_buffer_space( 4 * indent );
251
memset( output_buffer + output_buffer_pos, ' ', 4 * indent );
252
output_buffer_pos += 4 * indent;
253
254
for (;;)
255
{
256
size_t size = output_buffer_size - output_buffer_pos;
257
va_start( args, format );
258
n = vsnprintf( (char *)output_buffer + output_buffer_pos, size, format, args );
259
va_end( args );
260
if (n == -1) size *= 2;
261
else if ((size_t)n >= size) size = n + 1;
262
else
263
{
264
output_buffer_pos += n;
265
return;
266
}
267
check_output_buffer_space( size );
268
}
269
}
270
271