2 * stdlib support routines for self-contained images.
4 * Copyright (C) 2010, Broadcom Corporation. All Rights Reserved.
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 * $Id: bcmstdlib.c,v 1.51.20.1 2010-03-23 01:20:17 Exp $
22 * bcmstdlib.c file should be used only to construct an OSL or alone without any OSL
23 * It should not be used with any orbitarary OSL's as there could be a conflict
24 * with some of the routines defined here.
28 #if defined(NDIS) || defined(_MINOSL_) || defined(__vxworks) || defined(PCBIOS) || \
37 * Define BCMSTDLIB_WIN32_APP if this is a Win32 Application compile
39 #if defined(_WIN32) && !defined(NDIS) && !defined(EFI)
40 #define BCMSTDLIB_WIN32_APP 1
41 #endif /* _WIN32 && !NDIS */
44 * Define BCMSTDLIB_SNPRINTF_ONLY if we only want snprintf & vsnprintf implementations
46 #if (defined(_WIN32) && !defined(EFI)) || defined(__vxworks) || defined(_CFE_)
47 #define BCMSTDLIB_SNPRINTF_ONLY 1
51 #include <bcmstdlib.h>
52 #ifndef BCMSTDLIB_WIN32_APP
60 #ifdef BCMSTDLIB_WIN32_APP
62 /* for a WIN32 application, use _vsnprintf as basis of vsnprintf/snprintf to
63 * support full set of format specifications.
67 vsnprintf(char *buf
, size_t bufsize
, const char *fmt
, va_list ap
)
71 r
= _vsnprintf(buf
, bufsize
, fmt
, ap
);
73 /* Microsoft _vsnprintf() will not null terminate on overflow,
74 * so null terminate at buffer end on error
76 if (r
< 0 && bufsize
> 0)
77 buf
[bufsize
- 1] = '\0';
83 snprintf(char *buf
, size_t bufsize
, const char *fmt
, ...)
89 r
= vsnprintf(buf
, bufsize
, fmt
, ap
);
95 #else /* BCMSTDLIB_WIN32_APP */
98 static const char digits
[17] = "0123456789ABCDEF";
99 static const char ldigits
[17] = "0123456789abcdef";
102 __atox(char *buf
, char * end
, unsigned int num
, unsigned int radix
, int width
,
113 *op
++ = digits
[num
% radix
];
118 if (width
&& (width
> retval
)) {
119 width
= width
- retval
;
127 while (op
!= buffer
) {
138 BCMROMFN(vsnprintf
)(char *buf
, size_t size
, const char *fmt
, va_list ap
)
143 unsigned char *tmpptr
;
154 end
= buf
+ size
- 1;
159 size
= end
- buf
+ 1;
189 while (*iptr
&& bcm_isdigit(*iptr
)) {
190 width
+= (*iptr
- '0');
192 if (bcm_isdigit(*iptr
))
198 while (*iptr
&& bcm_isdigit(*iptr
)) {
199 width2
+= (*iptr
- '0');
201 if (bcm_isdigit(*iptr
)) width2
*= 10;
213 tmpptr
= (unsigned char *) va_arg(ap
, unsigned char *);
214 if (!tmpptr
) tmpptr
= (unsigned char *) "(null)";
215 if ((width
== 0) & (width2
== 0)) {
224 while (width
&& *tmpptr
) {
247 optr
+= __atox(optr
, end
, i
, 10, width
, digits
);
250 x
= va_arg(ap
, unsigned int);
251 optr
+= __atox(optr
, end
, x
, 10, width
, digits
);
255 x
= va_arg(ap
, unsigned int);
256 optr
+= __atox(optr
, end
, x
, 16, width
,
257 (*iptr
== 'X') ? digits
: ldigits
);
261 x
= va_arg(ap
, unsigned int);
262 optr
+= __atox(optr
, end
, x
, 16, 8,
263 (*iptr
== 'P') ? digits
: ldigits
);
283 return (int)(optr
- buf
);
286 return (int)(end
- buf
);
292 BCMROMFN(snprintf
)(char *buf
, size_t bufsize
, const char *fmt
, ...)
298 r
= vsnprintf(buf
, bufsize
, fmt
, ap
);
304 #endif /* BCMSTDLIB_WIN32_APP */
306 #ifndef BCMSTDLIB_SNPRINTF_ONLY
310 BCMROMFN(vsprintf
)(char *buf
, const char *fmt
, va_list ap
)
312 return (vsnprintf(buf
, INT_MAX
, fmt
, ap
));
317 BCMROMFN(sprintf
)(char *buf
, const char *fmt
, ...)
323 count
= vsprintf(buf
, fmt
, ap
);
331 BCMROMFN(memmove
)(void *dest
, const void *src
, size_t n
)
333 /* only use memcpy if there is no overlap. otherwise copy each byte in a safe sequence */
334 if (((const char *)src
>= (char *)dest
+ n
) || ((const char *)src
+ n
<= (char *)dest
)) {
335 return memcpy(dest
, src
, n
);
338 /* Overlapping copy forward or backward */
340 unsigned char *d
= (unsigned char *)dest
+ (n
- 1);
341 const unsigned char *s
= (const unsigned char *)src
+ (n
- 1);
346 } else if (src
> dest
) {
347 unsigned char *d
= (unsigned char *)dest
;
348 const unsigned char *s
= (const unsigned char *)src
;
360 BCMROMFN(memcmp
)(const void *s1
, const void *s2
, size_t n
)
362 const unsigned char *ss1
;
363 const unsigned char *ss2
;
365 ss1
= (const unsigned char *)s1
;
366 ss2
= (const unsigned char *)s2
;
381 /* Skip over functions that are being used from DriverLibrary to save space */
383 BCMROMFN(strcpy
)(char *dest
, const char *src
)
387 while ((*ptr
++ = *src
++) != '\0')
394 BCMROMFN(strncpy
)(char *dest
, const char *src
, size_t n
)
402 while (p
!= endp
&& (*p
++ = *src
++) != '\0')
405 /* zero fill remainder */
413 BCMROMFN(strlen
)(const char *s
)
426 BCMROMFN(strcmp
)(const char *s1
, const char *s2
)
446 BCMROMFN(strncmp
)(const char *s1
, const char *s2
, size_t n
)
448 while (*s2
&& *s1
&& n
) {
468 BCMROMFN(strchr
)(const char *str
, int c
)
470 char *x
= (char *)str
;
472 while (*x
!= (char)c
) {
480 BCMROMFN(strrchr
)(const char *str
, int c
)
485 if (*str
== (char) c
)
487 } while (*str
++ != '\0');
492 /* Skip over functions that are being used from DriverLibrary to save space */
495 BCMROMFN(strcat
)(char *d
, const char *s
)
497 strcpy(&d
[strlen(d
)], s
);
503 BCMROMFN(index
)(const char *s
, int c
)
505 /* Terminating NUL is considered part of string */
514 /* Skip over functions that are being used from DriverLibrary to save space */
517 BCMROMFN(strstr
)(const char *s
, const char *substr
)
519 int substr_len
= strlen(substr
);
522 if (strncmp(s
, substr
, substr_len
) == 0)
530 BCMROMFN(strspn
)(const char *s
, const char *accept
)
534 while (s
[count
] && index(accept
, s
[count
]))
541 BCMROMFN(strcspn
)(const char *s
, const char *reject
)
545 while (s
[count
] && !index(reject
, s
[count
]))
552 BCMROMFN(memchr
)(const void *s
, int c
, size_t n
)
555 const unsigned char *ptr
= s
;
558 if (*ptr
== (unsigned char)c
)
568 BCMROMFN(strtoul
)(const char *cp
, char **endp
, int base
)
575 while (bcm_isspace(*cp
))
580 else if (cp
[0] == '-') {
587 if ((cp
[1] == 'x') || (cp
[1] == 'X')) {
596 } else if (base
== 16 && (cp
[0] == '0') && ((cp
[1] == 'x') || (cp
[1] == 'X'))) {
602 while (bcm_isxdigit(*cp
) &&
603 (value
= bcm_isdigit(*cp
) ? *cp
- '0' : bcm_toupper(*cp
) - 'A' + 10) <
605 result
= result
* base
+ value
;
610 result
= (ulong
)(result
* -1);
619 /* memset is not in ROM offload because it is used directly by the compiler in
620 * structure assignments/character array initialization with "".
623 memset(void *dest
, int c
, size_t n
)
631 /* 8 min because we have to create w */
632 if ((n
>= 8) && (((uintptr
)dest
& 3) == 0)) {
638 ch
= (unsigned char)(c
& 0xff);
647 d
= (unsigned char *)dw
;
650 *d
++ = (unsigned char)c
;
657 /* memcpy is not in ROM offload because it is used directly by the compiler in
658 * structure assignments.
661 memcpy(void *dest
, const void *src
, size_t n
)
666 const unsigned char *s
;
668 sw
= (const uint32
*)src
;
670 if ((n
>= 4) && (((uintptr
)src
& 3) == 0) && (((uintptr
)dest
& 3) == 0)) {
676 d
= (unsigned char *)dw
;
677 s
= (const unsigned char *)sw
;
687 /* Include printf if it has already not been defined as NULL */
690 printf(const char *fmt
, ...)
694 char buffer
[PRINTF_BUFLEN
+ 1];
697 count
= vsnprintf(buffer
, sizeof(buffer
), fmt
, ap
);
700 for (i
= 0; i
< count
; i
++) {
704 if (buffer
[i
] == '\n')
710 msgtrace_put(buffer
, count
);
718 #if !defined(_WIN32) && !defined(_CFE_) && !defined(EFI)
720 fputs(const char *s
, FILE *stream
/* UNUSED */)
737 fputc(int c
, FILE *stream
/* UNUSED */)
740 return (int)(unsigned char)c
;
747 static unsigned long seed
= 1;
753 t
= 16807 * lo
- 2836 * hi
;
754 if (t
<= 0) t
+= 0x7fffffff;
759 #endif /* BCMSTDLIB_SNPRINTF_ONLY */