source: trunk/src/peldr/helpers.c

Last change on this file was 22028, checked in by dmik, 13 years ago

pe: A better fix for adding .EXE than r22016.

It will only add .EXE if there is no (any) extention already specified,
regardless of whether the path is present or not. This matches the
behavior of CMD.EXE on both Windows and OS/2.

File size: 7.6 KB
RevLine 
[21942]1/** @file
2 *
3 * Helper functions for the PE loader.
4 *
5 * These are needed since we don't link to LIBC.
6 *
7 * Project Odin Software License can be found in LICENSE.TXT
8 */
9
10#include "helpers.h"
11
12#ifndef NULL
13#define NULL 0
14#endif
15
16void *memcpy(void *p1, const void *p2, int n)
17{
18 char *p = (char *)p1;
19 while (n)
20 {
21 *p++ = *(char *)(p2++);
22 n--;
23 }
24 return p1;
25}
26
27char *strcpy(char *s1, const char *s2)
28{
29 char *s = s1;
30 while (*s2)
31 *s++ = *s2++;
32 *s = '\0';
33 return s1;
34}
35
36int strlen(const char *s)
37{
38 const char *s2 = s;
39 while (*s2)
40 s2++;
41 return s2 - s;
42}
43
44char *strcat(char *s1, const char *s2)
45{
46 char *s = s1;
47 while (*s)
48 s++;
49 strcpy(s, s2);
50 return s1;
51}
52
53int str_starts_with(const char *s1, const char *s2)
54{
55 while (*s1 && *s2 && *s1 == *s2)
56 {
57 s1++;
58 s2++;
59 }
60 return !*s2;
61}
62
63const char *str_skip_char(const char *s, int c)
64{
65 while (*s && *s == c)
66 s++;
67 return s;
68}
69
70const char *str_find_char(const char *s, int c)
71{
72 while (*s && *s != c)
73 s++;
74 return s;
75}
76
[22028]77const char *str_find_last_char(const char *s, int c)
78{
79 int len = strlen (s);
80 const char *e = s + len;
81 while (e >= s && *e != c)
82 e--;
83 return e < s ? s + len : e;
84}
85
[21942]86//
87// BEGIN: taken from _ras.cpp
88//
89
90void ulong2string (unsigned long number, char *string, int n, int base)
91{
92 static const char *digits = "0123456789ABCDEF";
93
94 unsigned long tmp = number;
95 char *s = string;
96 int len = 0;
97 int l = 0;
98 int i;
99
100 if (n <= 0)
101 {
102 return;
103 }
104
105 if (tmp == 0)
106 {
107 s[l++] = digits[0];
108 }
109
110 while (tmp != 0)
111 {
112 if (l >= n)
113 {
114 break;
115 }
116 s[l++] = digits[tmp%base];
117 len++;
118 tmp /= base;
119 }
120 if (l < n)
121 {
122 s[l++] = '\0';
123 }
124
125 s = string;
126
127 for (i = 0; i < len/2; i++)
128 {
129 tmp = s[i];
130 s[i] = s[len - i - 1];
131 s[len - i - 1] = tmp;
132 }
133
134 return;
135}
136
137void long2string (long number, char *string, int n, int base)
138{
139 if (n <= 0)
140 {
141 return;
142 }
143
144 if (number < 0)
145 {
146 *string++ = '-';
147 number = -number;
148 n--;
149 }
150
151 ulong2string (number, string, n, base);
152}
153
154int string2ulong (const char *string, char **pstring2, unsigned long *pvalue, int base)
155{
156 unsigned long value = 0;
157 int sign = 1;
158
159 const char *p = string;
160
161 if (p[0] == '-')
162 {
163 sign = -1;
164 p++;
165 }
166
167 if (base == 0)
168 {
169 if (p[0] == 0 && (p[1] == 'x' || p[1] == 'X'))
170 {
171 base = 16;
172 p += 2;
173 }
174 else if (p[0] == 0)
175 {
176 base = 8;
177 p += 1;
178 }
179 else
180 {
181 base = 10;
182 }
183 }
184
185 while (*p)
186 {
187 int digit = 0;
188
189 if ('0' <= *p && *p <= '9')
190 {
191 digit = *p - '0';
192 }
193 else if ('a' <= *p && *p <= 'f')
194 {
195 digit = *p - 'a' + 0xa;
196 }
197 else if ('A' <= *p && *p <= 'F')
198 {
199 digit = *p - 'A' + 0xa;
200 }
201 else
202 {
203 break;
204 }
205
206 if (digit >= base)
207 {
208 break;
209 }
210
211 value = value*base + digit;
212
213 p++;
214 }
215
216 if (pstring2)
217 {
218 *pstring2 = (char *)p;
219 }
220
221 *pvalue = sign*value;
222
223 return 1;
224}
225
226int vsnprintf(char *buf, int n, const char *fmt, va_list args)
227{
228 int count = 0;
229 char *s = (char *)fmt;
230 char *d = buf;
231
232 if (n <= 0)
233 {
234 return 0;
235 }
236
237 n--;
238
239 while (*s && count < n)
240 {
241 char tmpstr[16];
242
243 char *str = NULL;
244
245 int width = 0;
246 int precision = 0;
247
248 if (*s == '%')
249 {
250 s++;
251
252 if ('0' <= *s && *s <= '9' || *s == '-')
253 {
254 char setprec = (*s == '0');
255 string2ulong (s, &s, (unsigned long *)&width, 10);
256 if (setprec)
257 {
258 precision = width;
259 }
260 }
261
262 if (*s == '.')
263 {
264 s++;
265 string2ulong (s, &s, (unsigned long *)&precision, 10);
266 }
267
268 if (*s == 's')
269 {
270 str = va_arg(args, char *);
271 s++;
272 precision = 0;
273 }
274 else if (*s == 'c')
275 {
276 tmpstr[0] = va_arg(args, int);
277 tmpstr[1] = 0;
278 str = &tmpstr[0];
279 s++;
280 precision = 0;
281 }
282 else if (*s == 'p' || *s == 'P')
283 {
284 int num = va_arg(args, int);
285
286 ulong2string (num, tmpstr, sizeof (tmpstr), 16);
287
288 str = &tmpstr[0];
289 s++;
290 width = 8;
291 precision = 8;
292 }
293 else
294 {
295 if (*s == 'l')
296 {
297 s++;
298 }
299
300 if (*s == 'd' || *s == 'i')
301 {
302 int num = va_arg(args, int);
303
304 long2string (num, tmpstr, sizeof (tmpstr), 10);
305
306 str = &tmpstr[0];
307 s++;
308 }
309 else if (*s == 'u')
310 {
311 int num = va_arg(args, int);
312
313 ulong2string (num, tmpstr, sizeof (tmpstr), 10);
314
315 str = &tmpstr[0];
316 s++;
317 }
318 else if (*s == 'x' || *s == 'X')
319 {
320 int num = va_arg(args, int);
321
322 ulong2string (num, tmpstr, sizeof (tmpstr), 16);
323
324 str = &tmpstr[0];
325 s++;
326 }
327 }
328 }
329
330 if (str != NULL)
331 {
332 int i;
333 char numstr[16];
334 int len = strlen (str);
335 int leftalign = 0;
336
337 if (width < 0)
338 {
339 width = -width;
340 leftalign = 1;
341 }
342
343 if (precision)
344 {
345 i = 0;
346 while (precision > len)
347 {
348 numstr[i++] = '0';
349 precision--;
350 }
351
352 memcpy (&numstr[i], str, len);
353
354 str = &numstr[0];
355 len += i;
356 }
357
358 if (len < width && !leftalign)
359 {
360 while (len < width && count < n)
361 {
362 *d++ = ' ';
363 width--;
364 count++;
365 }
366
367 if (count >= n)
368 {
369 break;
370 }
371 }
372
373 i = 0;
374 while (i < len && count < n)
375 {
376 *d++ = str[i++];
377 count++;
378 }
379
380 if (count >= n)
381 {
382 break;
383 }
384
385 if (len < width && leftalign)
386 {
387 while (len < width && count < n)
388 {
389 *d++ = ' ';
390 width--;
391 count++;
392 }
393
394 if (count >= n)
395 {
396 break;
397 }
398 }
399 }
400 else
401 {
402 *d++ = *s++;
403 count++;
404 }
405 }
406
407 *d = '\0';
408
409 return count + 1;
410}
411
412int snprintf(char *buf, int n, const char *fmt, ...)
413{
414 va_list args;
415
416 int rc = 0;
417
418 va_start (args, fmt);
419
420 rc = vsnprintf (buf, n, fmt, args);
421
422 va_end (args);
423
424 return rc;
425}
426
427//
428// END: taken from _ras.cpp
429//
Note: See TracBrowser for help on using the repository browser.