summaryrefslogtreecommitdiff
path: root/StdLib/LibC
diff options
context:
space:
mode:
Diffstat (limited to 'StdLib/LibC')
-rw-r--r--StdLib/LibC/CRT/Gcc.c196
-rw-r--r--StdLib/LibC/CRT/Ia32/ashrdi3.S66
-rw-r--r--StdLib/LibC/CRT/Ia32/lldiv.c97
-rw-r--r--StdLib/LibC/CRT/Ia32/lldvrm.c100
-rw-r--r--StdLib/LibC/CRT/Ia32/llmul.c79
-rw-r--r--StdLib/LibC/CRT/Ia32/llrem.c93
-rw-r--r--StdLib/LibC/CRT/Ia32/llshl.c54
-rw-r--r--StdLib/LibC/CRT/Ia32/mulll.S77
-rw-r--r--StdLib/LibC/CRT/Ia32/shldi3.S62
-rw-r--r--StdLib/LibC/CRT/Ia32/udivdi3.S83
-rw-r--r--StdLib/LibC/CRT/Ia32/ulldiv.c88
-rw-r--r--StdLib/LibC/CRT/Ia32/ulldvrm.c100
-rw-r--r--StdLib/LibC/CRT/Ia32/ullrem.c93
-rw-r--r--StdLib/LibC/CRT/Ia32/ullshr.c57
-rw-r--r--StdLib/LibC/CRT/Ia32/umoddi3.S89
-rw-r--r--StdLib/LibC/Ctype/CClass.c140
-rw-r--r--StdLib/LibC/Ctype/CConv.c48
-rw-r--r--StdLib/LibC/Ctype/Ctype.inf50
-rw-r--r--StdLib/LibC/Ctype/iCtype.c303
-rw-r--r--StdLib/LibC/LibC.inf115
-rw-r--r--StdLib/LibC/Locale/Locale.inf74
-rw-r--r--StdLib/LibC/Locale/__mb_cur_max.c39
-rw-r--r--StdLib/LibC/Locale/__wctoint.h79
-rw-r--r--StdLib/LibC/Locale/_def_messages.c24
-rw-r--r--StdLib/LibC/Locale/_def_monetary.c42
-rw-r--r--StdLib/LibC/Locale/_def_numeric.c23
-rw-r--r--StdLib/LibC/Locale/_def_time.c42
-rw-r--r--StdLib/LibC/Locale/_wcstod.h126
-rw-r--r--StdLib/LibC/Locale/_wcstol.h153
-rw-r--r--StdLib/LibC/Locale/_wcstoul.h131
-rw-r--r--StdLib/LibC/Locale/aliasname.c129
-rw-r--r--StdLib/LibC/Locale/aliasname_local.h29
-rw-r--r--StdLib/LibC/Locale/ctypeio.c186
-rw-r--r--StdLib/LibC/Locale/ctypeio.h35
-rw-r--r--StdLib/LibC/Locale/iswctype_sb.c234
-rw-r--r--StdLib/LibC/Locale/localeconv.c85
-rw-r--r--StdLib/LibC/Locale/multibyte_sb.c272
-rw-r--r--StdLib/LibC/Locale/nl_langinfo.c125
-rw-r--r--StdLib/LibC/Locale/rune.h100
-rw-r--r--StdLib/LibC/Locale/runetype.h221
-rw-r--r--StdLib/LibC/Locale/setlocale.c423
-rw-r--r--StdLib/LibC/Locale/setlocale1.c53
-rw-r--r--StdLib/LibC/Locale/setlocale32.c46
-rw-r--r--StdLib/LibC/Locale/wcscoll.c47
-rw-r--r--StdLib/LibC/Locale/wcsftime.c109
-rw-r--r--StdLib/LibC/Locale/wcstod.c51
-rw-r--r--StdLib/LibC/Locale/wcstof.c53
-rw-r--r--StdLib/LibC/Locale/wcstoimax.c59
-rw-r--r--StdLib/LibC/Locale/wcstol.c58
-rw-r--r--StdLib/LibC/Locale/wcstold.c53
-rw-r--r--StdLib/LibC/Locale/wcstoll.c58
-rw-r--r--StdLib/LibC/Locale/wcstoul.c58
-rw-r--r--StdLib/LibC/Locale/wcstoull.c58
-rw-r--r--StdLib/LibC/Locale/wcstoumax.c59
-rw-r--r--StdLib/LibC/Locale/wcsxfrm.c66
-rw-r--r--StdLib/LibC/Main/Arm/flt_rounds.c81
-rw-r--r--StdLib/LibC/Main/ByteSwap.c72
-rw-r--r--StdLib/LibC/Main/HtoNtoH.c90
-rw-r--r--StdLib/LibC/Main/Ia32/fpu_rmode.S22
-rw-r--r--StdLib/LibC/Main/Ia32/fpu_rmode.asm46
-rw-r--r--StdLib/LibC/Main/Ia32/ftol2.objbin0 -> 2320 bytes
-rw-r--r--StdLib/LibC/Main/Ia32/isinfl.c68
-rw-r--r--StdLib/LibC/Main/Ia32/isnanl.c69
-rw-r--r--StdLib/LibC/Main/Ipf/FpuRmode.s12
-rw-r--r--StdLib/LibC/Main/Ipf/flt_rounds.c25
-rw-r--r--StdLib/LibC/Main/Main.c102
-rw-r--r--StdLib/LibC/Main/X64/fpu_rmode.S20
-rw-r--r--StdLib/LibC/Main/X64/fpu_rmode.asm41
-rw-r--r--StdLib/LibC/Main/X64/isinfl.c63
-rw-r--r--StdLib/LibC/Main/X64/isnanl.c64
-rw-r--r--StdLib/LibC/Main/assert.c32
-rw-r--r--StdLib/LibC/Main/bswap16.c22
-rw-r--r--StdLib/LibC/Main/bswap32.c25
-rw-r--r--StdLib/LibC/Main/bswap64.c44
-rw-r--r--StdLib/LibC/Main/errno.c19
-rw-r--r--StdLib/LibC/Main/infinityf_ieee754.c20
-rw-r--r--StdLib/LibC/Main/isinfd_ieee754.c68
-rw-r--r--StdLib/LibC/Main/isinff_ieee754.c63
-rw-r--r--StdLib/LibC/Main/isnand_ieee754.c68
-rw-r--r--StdLib/LibC/Main/isnanf_ieee754.c63
-rw-r--r--StdLib/LibC/Main/longjmp.c20
-rw-r--r--StdLib/LibC/Main/x86flt_rounds.c23
-rw-r--r--StdLib/LibC/Math/Math.inf101
-rw-r--r--StdLib/LibC/Math/e_acos.c122
-rw-r--r--StdLib/LibC/Math/e_asin.c120
-rw-r--r--StdLib/LibC/Math/e_atan2.c128
-rw-r--r--StdLib/LibC/Math/e_cosh.c91
-rw-r--r--StdLib/LibC/Math/e_exp.c167
-rw-r--r--StdLib/LibC/Math/e_fmod.c138
-rw-r--r--StdLib/LibC/Math/e_log.c155
-rw-r--r--StdLib/LibC/Math/e_log10.c106
-rw-r--r--StdLib/LibC/Math/e_log2.c85
-rw-r--r--StdLib/LibC/Math/e_pow.c323
-rw-r--r--StdLib/LibC/Math/e_rem_pio2.c169
-rw-r--r--StdLib/LibC/Math/e_sinh.c79
-rw-r--r--StdLib/LibC/Math/e_sqrt.c464
-rw-r--r--StdLib/LibC/Math/k_cos.c89
-rw-r--r--StdLib/LibC/Math/k_rem_pio2.c305
-rw-r--r--StdLib/LibC/Math/k_sin.c72
-rw-r--r--StdLib/LibC/Math/k_tan.c156
-rw-r--r--StdLib/LibC/Math/math_private.h229
-rw-r--r--StdLib/LibC/Math/s_atan.c120
-rw-r--r--StdLib/LibC/Math/s_ceil.c74
-rw-r--r--StdLib/LibC/Math/s_copysign.c35
-rw-r--r--StdLib/LibC/Math/s_cos.c79
-rw-r--r--StdLib/LibC/Math/s_expm1.c228
-rw-r--r--StdLib/LibC/Math/s_fabs.c32
-rw-r--r--StdLib/LibC/Math/s_finite.c32
-rw-r--r--StdLib/LibC/Math/s_floor.c74
-rw-r--r--StdLib/LibC/Math/s_frexp.c52
-rw-r--r--StdLib/LibC/Math/s_infinity.c27
-rw-r--r--StdLib/LibC/Math/s_ldexp.c29
-rw-r--r--StdLib/LibC/Math/s_modf.c76
-rw-r--r--StdLib/LibC/Math/s_scalbn.c60
-rw-r--r--StdLib/LibC/Math/s_sin.c79
-rw-r--r--StdLib/LibC/Math/s_tan.c73
-rw-r--r--StdLib/LibC/Math/s_tanh.c79
-rw-r--r--StdLib/LibC/Math/w_acos.c40
-rw-r--r--StdLib/LibC/Math/w_asin.c41
-rw-r--r--StdLib/LibC/Math/w_atan2.c40
-rw-r--r--StdLib/LibC/Math/w_cosh.c39
-rw-r--r--StdLib/LibC/Math/w_exp.c46
-rw-r--r--StdLib/LibC/Math/w_fmod.c40
-rw-r--r--StdLib/LibC/Math/w_log.c40
-rw-r--r--StdLib/LibC/Math/w_log10.c43
-rw-r--r--StdLib/LibC/Math/w_log2.c43
-rw-r--r--StdLib/LibC/Math/w_pow.c62
-rw-r--r--StdLib/LibC/Math/w_sinh.c39
-rw-r--r--StdLib/LibC/Math/w_sqrt.c39
-rw-r--r--StdLib/LibC/NetUtil/NetUtil.inf59
-rw-r--r--StdLib/LibC/NetUtil/inet_addr.c225
-rw-r--r--StdLib/LibC/NetUtil/inet_lnaof.c70
-rw-r--r--StdLib/LibC/NetUtil/inet_makeaddr.c74
-rw-r--r--StdLib/LibC/NetUtil/inet_netof.c69
-rw-r--r--StdLib/LibC/NetUtil/inet_network.c120
-rw-r--r--StdLib/LibC/NetUtil/inet_ntoa.c69
-rw-r--r--StdLib/LibC/NetUtil/inet_ntop.c238
-rw-r--r--StdLib/LibC/Signal/Signal.c93
-rw-r--r--StdLib/LibC/Signal/Signal.inf39
-rw-r--r--StdLib/LibC/StdLib/Bsearch.c105
-rw-r--r--StdLib/LibC/StdLib/Environs.c208
-rw-r--r--StdLib/LibC/StdLib/Malloc.c226
-rw-r--r--StdLib/LibC/StdLib/NumericInt.c398
-rw-r--r--StdLib/LibC/StdLib/Qsort.c205
-rw-r--r--StdLib/LibC/StdLib/Rand.c67
-rw-r--r--StdLib/LibC/StdLib/StdLib.inf67
-rw-r--r--StdLib/LibC/StdLib/Xabs.c36
-rw-r--r--StdLib/LibC/StdLib/Xdiv.c76
-rw-r--r--StdLib/LibC/StdLib/strtoimax.c166
-rw-r--r--StdLib/LibC/StdLib/strtoumax.c139
-rw-r--r--StdLib/LibC/Stdio/Stdio.inf142
-rw-r--r--StdLib/LibC/Stdio/clrerr.c63
-rw-r--r--StdLib/LibC/Stdio/fclose.c83
-rw-r--r--StdLib/LibC/Stdio/fdopen.c108
-rw-r--r--StdLib/LibC/Stdio/feof.c67
-rw-r--r--StdLib/LibC/Stdio/ferror.c67
-rw-r--r--StdLib/LibC/Stdio/fflush.c115
-rw-r--r--StdLib/LibC/Stdio/fgetc.c65
-rw-r--r--StdLib/LibC/Stdio/fgetln.c71
-rw-r--r--StdLib/LibC/Stdio/fgetpos.c60
-rw-r--r--StdLib/LibC/Stdio/fgets.c119
-rw-r--r--StdLib/LibC/Stdio/fgetstr.c169
-rw-r--r--StdLib/LibC/Stdio/fgetwc.c100
-rw-r--r--StdLib/LibC/Stdio/fgetws.c92
-rw-r--r--StdLib/LibC/Stdio/fileext.h66
-rw-r--r--StdLib/LibC/Stdio/fileno.c71
-rw-r--r--StdLib/LibC/Stdio/findfp.c211
-rw-r--r--StdLib/LibC/Stdio/flags.c115
-rw-r--r--StdLib/LibC/Stdio/floatio.h55
-rw-r--r--StdLib/LibC/Stdio/flockfile.c192
-rw-r--r--StdLib/LibC/Stdio/fopen.c109
-rw-r--r--StdLib/LibC/Stdio/fparseln.c248
-rw-r--r--StdLib/LibC/Stdio/fprintf.c66
-rw-r--r--StdLib/LibC/Stdio/fpurge.c76
-rw-r--r--StdLib/LibC/Stdio/fputc.c65
-rw-r--r--StdLib/LibC/Stdio/fputs.c81
-rw-r--r--StdLib/LibC/Stdio/fputwc.c100
-rw-r--r--StdLib/LibC/Stdio/fputws.c65
-rw-r--r--StdLib/LibC/Stdio/fread.c96
-rw-r--r--StdLib/LibC/Stdio/freopen.c196
-rw-r--r--StdLib/LibC/Stdio/fscanf.c66
-rw-r--r--StdLib/LibC/Stdio/fseek.c74
-rw-r--r--StdLib/LibC/Stdio/fseeko.c290
-rw-r--r--StdLib/LibC/Stdio/fsetpos.c63
-rw-r--r--StdLib/LibC/Stdio/ftell.c103
-rw-r--r--StdLib/LibC/Stdio/ftello.c100
-rw-r--r--StdLib/LibC/Stdio/funopen.c82
-rw-r--r--StdLib/LibC/Stdio/fvwrite.c221
-rw-r--r--StdLib/LibC/Stdio/fvwrite.h50
-rw-r--r--StdLib/LibC/Stdio/fwalk.c70
-rw-r--r--StdLib/LibC/Stdio/fwide.c72
-rw-r--r--StdLib/LibC/Stdio/fwprintf.c53
-rw-r--r--StdLib/LibC/Stdio/fwrite.c89
-rw-r--r--StdLib/LibC/Stdio/fwscanf.c53
-rw-r--r--StdLib/LibC/Stdio/getc.c80
-rw-r--r--StdLib/LibC/Stdio/getchar.c72
-rw-r--r--StdLib/LibC/Stdio/gets.c80
-rw-r--r--StdLib/LibC/Stdio/gettemp.c183
-rw-r--r--StdLib/LibC/Stdio/getwc.c49
-rw-r--r--StdLib/LibC/Stdio/getwchar.c49
-rw-r--r--StdLib/LibC/Stdio/glue.h47
-rw-r--r--StdLib/LibC/Stdio/local.h113
-rw-r--r--StdLib/LibC/Stdio/makebuf.c132
-rw-r--r--StdLib/LibC/Stdio/mkdtemp.c69
-rw-r--r--StdLib/LibC/Stdio/mkstemp.c76
-rw-r--r--StdLib/LibC/Stdio/mktemp.c71
-rw-r--r--StdLib/LibC/Stdio/perror.c72
-rw-r--r--StdLib/LibC/Stdio/printf.c63
-rw-r--r--StdLib/LibC/Stdio/putc.c80
-rw-r--r--StdLib/LibC/Stdio/putchar.c75
-rw-r--r--StdLib/LibC/Stdio/puts.c85
-rw-r--r--StdLib/LibC/Stdio/putwc.c49
-rw-r--r--StdLib/LibC/Stdio/putwchar.c49
-rw-r--r--StdLib/LibC/Stdio/refill.c162
-rw-r--r--StdLib/LibC/Stdio/remove.c70
-rw-r--r--StdLib/LibC/Stdio/rewind.c63
-rw-r--r--StdLib/LibC/Stdio/rget.c70
-rw-r--r--StdLib/LibC/Stdio/scanf.c64
-rw-r--r--StdLib/LibC/Stdio/setbuf.c63
-rw-r--r--StdLib/LibC/Stdio/setbuffer.c72
-rw-r--r--StdLib/LibC/Stdio/setvbuf.c176
-rw-r--r--StdLib/LibC/Stdio/snprintf.c93
-rw-r--r--StdLib/LibC/Stdio/snprintf_ss.c69
-rw-r--r--StdLib/LibC/Stdio/sprintf.c78
-rw-r--r--StdLib/LibC/Stdio/sscanf.c89
-rw-r--r--StdLib/LibC/Stdio/stdio.c117
-rw-r--r--StdLib/LibC/Stdio/swprintf.c47
-rw-r--r--StdLib/LibC/Stdio/swscanf.c47
-rw-r--r--StdLib/LibC/Stdio/tempnam.c102
-rw-r--r--StdLib/LibC/Stdio/tmpfile.c86
-rw-r--r--StdLib/LibC/Stdio/tmpnam.c70
-rw-r--r--StdLib/LibC/Stdio/ungetc.c172
-rw-r--r--StdLib/LibC/Stdio/ungetwc.c75
-rw-r--r--StdLib/LibC/Stdio/vasprintf.c79
-rw-r--r--StdLib/LibC/Stdio/vfprintf.c2
-rw-r--r--StdLib/LibC/Stdio/vfscanf.c1129
-rw-r--r--StdLib/LibC/Stdio/vfwprintf.c2035
-rw-r--r--StdLib/LibC/Stdio/vfwscanf.c909
-rw-r--r--StdLib/LibC/Stdio/vprintf.c58
-rw-r--r--StdLib/LibC/Stdio/vscanf.c60
-rw-r--r--StdLib/LibC/Stdio/vsnprintf.c89
-rw-r--r--StdLib/LibC/Stdio/vsnprintf_ss.c494
-rw-r--r--StdLib/LibC/Stdio/vsprintf.c74
-rw-r--r--StdLib/LibC/Stdio/vsscanf.c83
-rw-r--r--StdLib/LibC/Stdio/vswprintf.c94
-rw-r--r--StdLib/LibC/Stdio/vswscanf.c100
-rw-r--r--StdLib/LibC/Stdio/vwprintf.c41
-rw-r--r--StdLib/LibC/Stdio/vwscanf.c47
-rw-r--r--StdLib/LibC/Stdio/wbuf.c99
-rw-r--r--StdLib/LibC/Stdio/wcio.h72
-rw-r--r--StdLib/LibC/Stdio/wprintf.c53
-rw-r--r--StdLib/LibC/Stdio/wscanf.c53
-rw-r--r--StdLib/LibC/Stdio/wsetup.c99
-rw-r--r--StdLib/LibC/String/Comparison.c118
-rw-r--r--StdLib/LibC/String/Concatenation.c83
-rw-r--r--StdLib/LibC/String/Copying.c141
-rw-r--r--StdLib/LibC/String/ErrorList.c144
-rw-r--r--StdLib/LibC/String/Misc.c99
-rw-r--r--StdLib/LibC/String/Searching.c262
-rw-r--r--StdLib/LibC/String/String.inf62
-rw-r--r--StdLib/LibC/Time/Theory.txt553
-rw-r--r--StdLib/LibC/Time/Time.c780
-rw-r--r--StdLib/LibC/Time/Time.inf53
-rw-r--r--StdLib/LibC/Time/TimeEfi.c48
-rw-r--r--StdLib/LibC/Time/TimeVals.h117
-rw-r--r--StdLib/LibC/Time/ZoneProc.c830
-rw-r--r--StdLib/LibC/Time/strftime.c602
-rw-r--r--StdLib/LibC/Time/tzfile.h168
-rw-r--r--StdLib/LibC/Uefi/Console.c393
-rw-r--r--StdLib/LibC/Uefi/SysCalls.c1198
-rw-r--r--StdLib/LibC/Uefi/SysEfi.h37
-rw-r--r--StdLib/LibC/Uefi/Uefi.inf49
-rw-r--r--StdLib/LibC/Uefi/Xform.c173
-rw-r--r--StdLib/LibC/Wchar/Comparison.c97
-rw-r--r--StdLib/LibC/Wchar/Concatenation.c48
-rw-r--r--StdLib/LibC/Wchar/ConsDecons.c64
-rw-r--r--StdLib/LibC/Wchar/Copying.c80
-rw-r--r--StdLib/LibC/Wchar/Searching.c268
-rw-r--r--StdLib/LibC/Wchar/String.c43
-rw-r--r--StdLib/LibC/Wchar/Wchar.inf59
-rw-r--r--StdLib/LibC/gdtoa/Ipf/strtold.c18
-rw-r--r--StdLib/LibC/gdtoa/_strtof.c46
-rw-r--r--StdLib/LibC/gdtoa/_strtold.c47
-rw-r--r--StdLib/LibC/gdtoa/atof.c22
-rw-r--r--StdLib/LibC/gdtoa/dmisc.c228
-rw-r--r--StdLib/LibC/gdtoa/dtoa.c821
-rw-r--r--StdLib/LibC/gdtoa/gdtoa.c814
-rw-r--r--StdLib/LibC/gdtoa/gdtoa.h159
-rw-r--r--StdLib/LibC/gdtoa/gdtoa.inf77
-rw-r--r--StdLib/LibC/gdtoa/gdtoaimp.h661
-rw-r--r--StdLib/LibC/gdtoa/gethex.c249
-rw-r--r--StdLib/LibC/gdtoa/gmisc.c82
-rw-r--r--StdLib/LibC/gdtoa/hd_init.c58
-rw-r--r--StdLib/LibC/gdtoa/hexnan.c134
-rw-r--r--StdLib/LibC/gdtoa/ldtoa.c113
-rw-r--r--StdLib/LibC/gdtoa/misc.c909
-rw-r--r--StdLib/LibC/gdtoa/smisc.c209
-rw-r--r--StdLib/LibC/gdtoa/strtod.c1022
-rw-r--r--StdLib/LibC/gdtoa/strtodg.c1075
-rw-r--r--StdLib/LibC/gdtoa/strtof.c85
-rw-r--r--StdLib/LibC/gdtoa/strtold_px.c4
-rw-r--r--StdLib/LibC/gdtoa/strtold_subr.c45
-rw-r--r--StdLib/LibC/gdtoa/strtopx.c108
-rw-r--r--StdLib/LibC/gdtoa/sum.c105
-rw-r--r--StdLib/LibC/gdtoa/ulp.c73
305 files changed, 41342 insertions, 0 deletions
diff --git a/StdLib/LibC/CRT/Gcc.c b/StdLib/LibC/CRT/Gcc.c
new file mode 100644
index 0000000000..01fbe79dc9
--- /dev/null
+++ b/StdLib/LibC/CRT/Gcc.c
@@ -0,0 +1,196 @@
+/** @file
+ Integer Arithmetic Run-time support functions for GCC.
+ The integer arithmetic routines are used on platforms that don't provide
+ hardware support for arithmetic operations on some modes..
+
+ Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License which accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#include <Uefi.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <sys/EfiCdefs.h>
+
+#include <Library/BaseLib.h>
+
+// Shift Datum left by Count bits.
+// ===========================================================================
+//int __ashlsi3(int Datum, int Count)
+//{
+// DebugPrint(DEBUG_INFO, "%a:\n", __func__);
+// return (int) LShiftU64 ((UINT64)Datum, (UINTN)Count);
+//}
+
+INT64 __ashldi3(INT64 Datum, int Count)
+{
+ DebugPrint(DEBUG_INFO, "%a:\n", __func__);
+ return LShiftU64 (Datum, (UINTN)Count);
+}
+
+//long long __ashlti3(long long Datum, int Count)
+//{
+// DebugPrint(DEBUG_INFO, "%a:\n", __func__);
+// return (long long) LShiftU64 ((UINT64)Datum, (UINTN)Count);
+//}
+
+// Arithmetically shift Datum right by Count bits.
+// ===========================================================================
+//int __ashrsi3(int Datum, int Count)
+//{
+// DebugPrint(DEBUG_INFO, "%a:\n", __func__);
+// return (int) ARShiftU64 ((UINT64) Datum, (UINTN)Count);
+//}
+
+INT64 __ashrdi3(INT64 Datum, int Count)
+{
+ DebugPrint(DEBUG_INFO, "%a:\n", __func__);
+ return ARShiftU64 ( Datum, (UINTN)Count);
+}
+
+//long long __ashrti3(long long Datum, int Count)
+//{
+// DebugPrint(DEBUG_INFO, "%a:\n", __func__);
+// return (long long) ARShiftU64 ((UINT64) Datum, (UINTN)Count);
+//}
+
+// Return the quotient of the signed division of Dividend and Divisor
+// ===========================================================================
+//int __divsi3(int Dividend, int Divisor)
+//{
+// DebugPrint(DEBUG_INFO, "%a:\n", __func__);
+// return (int) DivS64x64Remainder ((INT64) Dividend, (INT64) Divisor, NULL);
+//}
+
+INT64 __divdi3(INT64 Dividend, INT64 Divisor)
+{
+ INT64 Quotient;
+
+ Quotient = DivS64x64Remainder ((INT64) Dividend, (INT64) Divisor, NULL);
+ DebugPrint(DEBUG_INFO, "%a: %Ld / %Ld = %Ld\n", __func__, Dividend, Divisor, Quotient);
+
+ return Quotient;
+}
+
+//long long __divti3(long long Dividend, long long Divisor)
+//{
+// DebugPrint(DEBUG_INFO, "%a:\n", __func__);
+// return (long long) DivS64x64Remainder ((INT64) Dividend, (INT64) Divisor, NULL);
+//}
+
+// Logically shift Datum right by Count bits
+// ===========================================================================
+//int __lshrsi3(int Datum, int Count)
+//{
+// DebugPrint(DEBUG_INFO, "%a:\n", __func__);
+// return (int) RShiftU64 ((UINT64) Datum, (UINTN)Count);
+//}
+
+INT64 __lshrdi3(INT64 Datum, int Count)
+{
+ DebugPrint(DEBUG_INFO, "%a:\n", __func__);
+ return RShiftU64 ( Datum, (UINTN)Count);
+}
+
+//long long __lshrti3(int Datum, int Count)
+//{
+// DebugPrint(DEBUG_INFO, "%a:\n", __func__);
+// return (long long) RShiftU64 ((UINT64) Datum, (UINTN)Count);
+//}
+
+// Return the remainder of the signed division of Dividend and Divisor
+// ===========================================================================
+//int __modsi3(int Dividend, int Divisor)
+//{
+// INT64 Remainder;
+
+// (void) DivS64x64Remainder ((INT64) Dividend, (INT64) Divisor, &Remainder);
+// DebugPrint(DEBUG_INFO, "modsi3: %d %% %d = %d\n", Dividend, Divisor, (int)Remainder);
+
+// return (int) Remainder;
+//}
+
+INT64 __moddi3(INT64 Dividend, INT64 Divisor)
+{
+ INT64 Remainder;
+
+ (void) DivS64x64Remainder ((INT64) Dividend, (INT64) Divisor, &Remainder);
+ DebugPrint(DEBUG_INFO, "moddi3: %Ld %% %Ld = %Ld\n", (INT64)Dividend, (INT64)Divisor, Remainder);
+
+ return Remainder;
+}
+
+//long long __modti3(long long Dividend, long long Divisor)
+//{
+// INT64 Remainder;
+
+// (void) DivS64x64Remainder ((INT64) Dividend, (INT64) Divisor, &Remainder);
+// DebugPrint(DEBUG_INFO, "modti3: %Ld %% %Ld = %Ld\n", (INT64)Dividend, (INT64)Divisor, Remainder);
+
+// return (long long) Remainder;
+//}
+
+// These functions return the product of the Multiplicand and Multiplier.
+// ===========================================================================
+//long long __multi3(long long Multiplicand, long long Multiplier)
+//{
+// DebugPrint(DEBUG_INFO, "%a:\n", __func__);
+// return (long long) MultS64x64 ((INT64)Multiplicand, (INT64)Multiplier);
+//}
+
+// Return the quotient of the unsigned division of a and b.
+// ===========================================================================
+//unsigned int __udivsi3(unsigned int Dividend, unsigned int Divisor)
+//{
+// DebugPrint(DEBUG_INFO, "%a:\n", __func__);
+// return (int) DivU64x64Remainder ((UINT64) Dividend, (UINT64) Divisor, NULL);
+//}
+
+UINT64 __udivdi3(UINT64 Dividend, UINT64 Divisor)
+{
+ DebugPrint(DEBUG_INFO, "%a:\n", __func__);
+ return DivU64x64Remainder ((UINT64) Dividend, (UINT64) Divisor, NULL);
+}
+
+//unsigned long long __udivti3(unsigned long long Dividend, unsigned long long Divisor)
+//{
+// DebugPrint(DEBUG_INFO, "%a:\n", __func__);
+// return (long long) DivU64x64Remainder ((UINT64) Dividend, (UINT64) Divisor, NULL);
+//}
+
+// ===========================================================================
+//unsigned int __umodsi3(unsigned int Dividend, unsigned int Divisor)
+//{
+// UINT64 Remainder;
+
+// DebugPrint(DEBUG_INFO, "%a:\n", __func__);
+// (void) DivU64x64Remainder ((UINT64) Dividend, (UINT64) Divisor, &Remainder);
+
+// return (unsigned int) Remainder;
+//}
+
+UINT64 __umoddi3(UINT64 Dividend, UINT64 Divisor)
+{
+ UINT64 Remainder;
+
+ DebugPrint(DEBUG_INFO, "%a:\n", __func__);
+ (void) DivU64x64Remainder ((UINT64) Dividend, (UINT64) Divisor, &Remainder);
+
+ return Remainder;
+}
+
+//unsigned long long __umodti3(unsigned long long Dividend, unsigned long long Divisor)
+//{
+// UINT64 Remainder;
+
+// DebugPrint(DEBUG_INFO, "%a:\n", __func__);
+// (void) DivU64x64Remainder ((UINT64) Dividend, (UINT64) Divisor, &Remainder);
+
+// return (unsigned long long) Remainder;
+//}
diff --git a/StdLib/LibC/CRT/Ia32/ashrdi3.S b/StdLib/LibC/CRT/Ia32/ashrdi3.S
new file mode 100644
index 0000000000..1c629dc23b
--- /dev/null
+++ b/StdLib/LibC/CRT/Ia32/ashrdi3.S
@@ -0,0 +1,66 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+# Module Name:
+#
+# MathRShiftU64.S
+#
+# Abstract:
+#
+# 64-bit Math Worker Function.
+# Shifts a 64-bit unsigned value right by a certain number of bits.
+#
+#------------------------------------------------------------------------------
+
+
+ .686:
+ .code:
+
+ASM_GLOBAL ASM_PFX(__ashrdi3)
+
+#------------------------------------------------------------------------------
+#
+# void __cdecl __ashrdi3 (void)
+#
+#------------------------------------------------------------------------------
+ASM_PFX(__ashrdi3):
+ #
+ # Checking: Only handle 64bit shifting or more
+ #
+ cmpb $64, %cl
+ jae _Exit
+
+ #
+ # Handle shifting between 0 and 31 bits
+ #
+ cmpb $32, %cl
+ jae More32
+ shrd %cl, %edx, %eax
+ shr %cl, %edx
+ ret
+
+ #
+ # Handle shifting of 32-63 bits
+ #
+More32:
+ movl %edx, %eax
+ xor %edx, %edx
+ and $32, %cl
+ shr %cl, %eax
+ ret
+
+ #
+ # Invalid number (less then 32bits), return 0
+ #
+_Exit:
+ xor %eax, %eax
+ xor %edx, %edx
+ ret
diff --git a/StdLib/LibC/CRT/Ia32/lldiv.c b/StdLib/LibC/CRT/Ia32/lldiv.c
new file mode 100644
index 0000000000..cae2342243
--- /dev/null
+++ b/StdLib/LibC/CRT/Ia32/lldiv.c
@@ -0,0 +1,97 @@
+/** @file
+ 64-bit Math Worker Function.
+ The 32-bit versions of C compiler generate calls to library routines
+ to handle 64-bit math. These functions use non-standard calling conventions.
+
+ Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License which accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/BaseLib.h>
+
+
+/*
+ * Divides a 64-bit signed value with a 64-bit signed value and returns
+ * a 64-bit signed result.
+ */
+__declspec(naked) void __cdecl _alldiv (void)
+{
+ //
+ // Wrapper Implementation over EDKII DivS64x64Remainder() routine
+ // INT64
+ // EFIAPI
+ // DivS64x64Remainder (
+ // IN UINT64 Dividend,
+ // IN UINT64 Divisor,
+ // OUT UINT64 *Remainder OPTIONAL
+ // )
+ //
+ _asm {
+
+ ;Entry:
+ ; Arguments are passed on the stack:
+ ; 1st pushed: divisor (QWORD)
+ ; 2nd pushed: dividend (QWORD)
+ ;
+ ;Exit:
+ ; EDX:EAX contains the quotient (dividend/divisor)
+ ; NOTE: this routine removes the parameters from the stack.
+ ;
+ ; Original local stack when calling _alldiv
+ ; -----------------
+ ; | |
+ ; |---------------|
+ ; | |
+ ; |-- Divisor --|
+ ; | |
+ ; |---------------|
+ ; | |
+ ; |-- Dividend --|
+ ; | |
+ ; |---------------|
+ ; | ReturnAddr** |
+ ; ESP---->|---------------|
+ ;
+
+ ;
+ ; Set up the local stack for NULL Reminder pointer
+ ;
+ xor eax, eax
+ push eax
+
+ ;
+ ; Set up the local stack for Divisor parameter
+ ;
+ mov eax, [esp + 20]
+ push eax
+ mov eax, [esp + 20]
+ push eax
+
+ ;
+ ; Set up the local stack for Dividend parameter
+ ;
+ mov eax, [esp + 20]
+ push eax
+ mov eax, [esp + 20]
+ push eax
+
+ ;
+ ; Call native DivS64x64Remainder of BaseLib
+ ;
+ call DivS64x64Remainder
+
+ ;
+ ; Adjust stack
+ ;
+ add esp, 20
+
+ ret 16
+ }
+}
diff --git a/StdLib/LibC/CRT/Ia32/lldvrm.c b/StdLib/LibC/CRT/Ia32/lldvrm.c
new file mode 100644
index 0000000000..26e4ef8d53
--- /dev/null
+++ b/StdLib/LibC/CRT/Ia32/lldvrm.c
@@ -0,0 +1,100 @@
+/** @file
+ 64-bit Math Worker Function.
+ The 32-bit versions of C compiler generate calls to library routines
+ to handle 64-bit math. These functions use non-standard calling conventions.
+
+ Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License which accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/BaseLib.h>
+
+
+/*
+ * Divides a 64-bit signed value by another 64-bit signed value and returns
+ * the 64-bit signed result and the 64-bit signed remainder.
+ */
+__declspec(naked) void __cdecl _alldvrm(void)
+{
+ //
+ // Wrapper Implementation over EDKII DivS64x64Remainder() routine
+ // INT64
+ // EFIAPI
+ // DivS64x64Remainder (
+ // IN INT64 Dividend,
+ // IN INT64 Divisor,
+ // OUT INT64 *Remainder
+ // )
+ //
+ _asm {
+ ; Original local stack when calling _alldvrm
+ ; -----------------
+ ; | |
+ ; |---------------|
+ ; | |
+ ; |-- Divisor --|
+ ; | |
+ ; |---------------|
+ ; | |
+ ; |-- Dividend --|
+ ; | |
+ ; |---------------|
+ ; | ReturnAddr** |
+ ; ESP---->|---------------|
+ ;
+ ;
+ ; On Exit:
+ ; EDX:EAX contains the quotient (dividend/divisor)
+ ; EBX:ECX contains the remainder (divided % divisor)
+ ; NOTE: this routine removes the parameters from the stack.
+ ;
+
+ ;
+ ; Set up the local stack for Reminder pointer
+ ;
+ sub esp, 8
+ push esp
+
+ ;
+ ; Set up the local stack for Divisor parameter
+ ;
+ mov eax, [esp + 28]
+ push eax
+ mov eax, [esp + 28]
+ push eax
+
+ ;
+ ; Set up the local stack for Dividend parameter
+ ;
+ mov eax, [esp + 28]
+ push eax
+ mov eax, [esp + 28]
+ push eax
+
+ ;
+ ; Call native DivS64x64Remainder of BaseLib
+ ;
+ call DivS64x64Remainder
+
+ ;
+ ; EDX:EAX contains the quotient (dividend/divisor)
+ ; Put the Remainder in EBX:ECX
+ ;
+ mov ecx, [esp + 20]
+ mov ebx, [esp + 24]
+
+ ;
+ ; Adjust stack
+ ;
+ add esp, 28
+
+ ret 16
+ }
+}
diff --git a/StdLib/LibC/CRT/Ia32/llmul.c b/StdLib/LibC/CRT/Ia32/llmul.c
new file mode 100644
index 0000000000..214134cc03
--- /dev/null
+++ b/StdLib/LibC/CRT/Ia32/llmul.c
@@ -0,0 +1,79 @@
+/** @file
+ 64-bit Math Worker Function.
+ The 32-bit versions of C compiler generate calls to library routines
+ to handle 64-bit math. These functions use non-standard calling conventions.
+
+ Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License which accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/BaseLib.h>
+
+/*
+ * Multiplies a 64-bit signed or unsigned value by a 64-bit signed or unsigned value
+ * and returns a 64-bit result.
+ */
+__declspec(naked) void __cdecl _allmul (void)
+{
+ //
+ // Wrapper Implementation over EDKII MultS64x64() routine
+ // INT64
+ // EFIAPI
+ // MultS64x64 (
+ // IN INT64 Multiplicand,
+ // IN INT64 Multiplier
+ // )
+ //
+ _asm {
+ ; Original local stack when calling _allmul
+ ; -----------------
+ ; | |
+ ; |---------------|
+ ; | |
+ ; |--Multiplier --|
+ ; | |
+ ; |---------------|
+ ; | |
+ ; |--Multiplicand-|
+ ; | |
+ ; |---------------|
+ ; | ReturnAddr** |
+ ; ESP---->|---------------|
+ ;
+
+ ;
+ ; Set up the local stack for Multiplicand parameter
+ ;
+ mov eax, [esp + 16]
+ push eax
+ mov eax, [esp + 16]
+ push eax
+
+ ;
+ ; Set up the local stack for Multiplier parameter
+ ;
+ mov eax, [esp + 16]
+ push eax
+ mov eax, [esp + 16]
+ push eax
+
+ ;
+ ; Call native MulS64x64 of BaseLib
+ ;
+ call MultS64x64
+
+ ;
+ ; Adjust stack
+ ;
+ add esp, 16
+
+ ret 16
+ }
+}
diff --git a/StdLib/LibC/CRT/Ia32/llrem.c b/StdLib/LibC/CRT/Ia32/llrem.c
new file mode 100644
index 0000000000..a92c300a40
--- /dev/null
+++ b/StdLib/LibC/CRT/Ia32/llrem.c
@@ -0,0 +1,93 @@
+/** @file
+ 64-bit Math Worker Function.
+ The 32-bit versions of C compiler generate calls to library routines
+ to handle 64-bit math. These functions use non-standard calling conventions.
+
+ Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License which accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/BaseLib.h>
+
+
+/*
+ * Divides a 64-bit signed value by another 64-bit signed value and returns
+ * the 64-bit signed remainder.
+ */
+__declspec(naked) void __cdecl _allrem(void)
+{
+ //
+ // Wrapper Implementation over EDKII DivS64x64Remainder() routine
+ // UINT64
+ // EFIAPI
+ // DivS64x64Remainder (
+ // IN UINT64 Dividend,
+ // IN UINT64 Divisor,
+ // OUT UINT64 *Remainder
+ // )
+ //
+ _asm {
+ ; Original local stack when calling _allrem
+ ; -----------------
+ ; | |
+ ; |---------------|
+ ; | |
+ ; |-- Divisor --|
+ ; | |
+ ; |---------------|
+ ; | |
+ ; |-- Dividend --|
+ ; | |
+ ; |---------------|
+ ; | ReturnAddr** |
+ ; ESP---->|---------------|
+ ;
+
+ ;
+ ; Set up the local stack for Reminder pointer
+ ;
+ sub esp, 8
+ push esp
+
+ ;
+ ; Set up the local stack for Divisor parameter
+ ;
+ mov eax, [esp + 28]
+ push eax
+ mov eax, [esp + 28]
+ push eax
+
+ ;
+ ; Set up the local stack for Dividend parameter
+ ;
+ mov eax, [esp + 28]
+ push eax
+ mov eax, [esp + 28]
+ push eax
+
+ ;
+ ; Call native DivS64x64Remainder of BaseLib
+ ;
+ call DivS64x64Remainder
+
+ ;
+ ; Put the Reminder in EDX:EAX as return value
+ ;
+ mov eax, [esp + 20]
+ mov edx, [esp + 24]
+
+ ;
+ ; Adjust stack
+ ;
+ add esp, 28
+
+ ret 16
+ }
+}
diff --git a/StdLib/LibC/CRT/Ia32/llshl.c b/StdLib/LibC/CRT/Ia32/llshl.c
new file mode 100644
index 0000000000..835fd042e7
--- /dev/null
+++ b/StdLib/LibC/CRT/Ia32/llshl.c
@@ -0,0 +1,54 @@
+/** @file
+ 64-bit Math Worker Function.
+ The 32-bit versions of C compiler generate calls to library routines
+ to handle 64-bit math. These functions use non-standard calling conventions.
+
+ Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License which accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+/*
+ * Shifts a 64-bit signed value left by a particular number of bits.
+ */
+__declspec(naked) void __cdecl _allshl (void)
+{
+ _asm {
+ ;
+ ; Handle shifting of 64 or more bits (return 0)
+ ;
+ cmp cl, 64
+ jae short ReturnZero
+
+ ;
+ ; Handle shifting of between 0 and 31 bits
+ ;
+ cmp cl, 32
+ jae short More32
+ shld edx, eax, cl
+ shl eax, cl
+ ret
+
+ ;
+ ; Handle shifting of between 32 and 63 bits
+ ;
+More32:
+ mov edx, eax
+ xor eax, eax
+ and cl, 31
+ shl edx, cl
+ ret
+
+ReturnZero:
+ xor eax,eax
+ xor edx,edx
+ ret
+ }
+}
diff --git a/StdLib/LibC/CRT/Ia32/mulll.S b/StdLib/LibC/CRT/Ia32/mulll.S
new file mode 100644
index 0000000000..333fdfbb9f
--- /dev/null
+++ b/StdLib/LibC/CRT/Ia32/mulll.S
@@ -0,0 +1,77 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+# Module Name:
+#
+# MathMultS64x64.S
+#
+# Abstract:
+#
+# 64-bit Math Worker Function.
+# Multiplies a 64-bit signed or unsigned value by a 64-bit signed or unsigned value
+# and returns a 64-bit result
+#
+#------------------------------------------------------------------------------
+
+ .686:
+ .code:
+
+ASM_GLOBAL ASM_PFX(_mulll), ASM_PFX(MultS64x64)
+
+#------------------------------------------------------------------------------
+#
+# void __cdecl __mulll (void)
+#
+#------------------------------------------------------------------------------
+ASM_PFX(__mulll):
+ # Original local stack when calling __mulll
+ # -----------------
+ # | |
+ # |---------------|
+ # | |
+ # |--Multiplier --|
+ # | |
+ # |---------------|
+ # | |
+ # |--Multiplicand-|
+ # | |
+ # |---------------|
+ # | ReturnAddr** |
+ # ESP---->|---------------|
+ #
+
+ #
+ # Set up the local stack for Multiplicand parameter
+ #
+ movl 16(%esp), %eax
+ push %eax
+ movl 16(%esp), %eax
+ push %eax
+
+ #
+ # Set up the local stack for Multiplier parameter
+ #
+ movl 16(%esp), %eax
+ push %eax
+ movl 16(%esp), %eax
+ push %eax
+
+ #
+ # Call native MulS64x64 of BaseLib
+ #
+ jmp ASM_PFX(MultS64x64)
+
+ #
+ # Adjust stack
+ #
+ add $16, %esp
+
+ ret $16
diff --git a/StdLib/LibC/CRT/Ia32/shldi3.S b/StdLib/LibC/CRT/Ia32/shldi3.S
new file mode 100644
index 0000000000..b2a03d9833
--- /dev/null
+++ b/StdLib/LibC/CRT/Ia32/shldi3.S
@@ -0,0 +1,62 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+# Module Name:
+#
+# MathLShiftS64.S
+#
+# Abstract:
+#
+# 64-bit Math Worker Function.
+# Shifts a 64-bit signed value left by a certain number of bits.
+#
+#------------------------------------------------------------------------------
+
+ .686:
+ .code:
+
+ASM_GLOBAL ASM_PFX(__ashldi3)
+
+#------------------------------------------------------------------------------
+#
+# void __cdecl __ashldi3 (void)
+#
+#------------------------------------------------------------------------------
+ASM_PFX(__ashldi3):
+ #
+ # Handle shifting of 64 or more bits (return 0)
+ #
+ cmpb $64, %cl
+ jae ReturnZero
+
+ #
+ # Handle shifting of between 0 and 31 bits
+ #
+ cmpb $32, %cl
+ jae More32
+ shld %cl, %eax, %edx
+ shl %cl, %eax
+ ret
+
+ #
+ # Handle shifting of between 32 and 63 bits
+ #
+More32:
+ movl %eax, %edx
+ xor %eax, %eax
+ and $31, %cl
+ shl %cl, %edx
+ ret
+
+ReturnZero:
+ xor %eax, %eax
+ xor %edx, %edx
+ ret
diff --git a/StdLib/LibC/CRT/Ia32/udivdi3.S b/StdLib/LibC/CRT/Ia32/udivdi3.S
new file mode 100644
index 0000000000..336d75ee7c
--- /dev/null
+++ b/StdLib/LibC/CRT/Ia32/udivdi3.S
@@ -0,0 +1,83 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+# Module Name:
+#
+# MathDivU64x64.S
+#
+# Abstract:
+#
+# 64-bit Math Worker Function.
+# Divides a 64-bit unsigned value with a 64-bit unsigned value and returns
+# a 64-bit unsigned result.
+#
+#------------------------------------------------------------------------------
+
+ .686:
+ .code:
+
+ASM_GLOBAL ASM_PFX(__udivdi3), ASM_PFX(DivU64x64Remainder)
+
+#------------------------------------------------------------------------------
+#
+# void __cdecl __udivdi3 (void)
+#
+#------------------------------------------------------------------------------
+ASM_PFX(__udivdi3):
+ # Original local stack when calling __udivdi3
+ # -----------------
+ # | |
+ # |---------------|
+ # | |
+ # |-- Divisor --|
+ # | |
+ # |---------------|
+ # | |
+ # |-- Dividend --|
+ # | |
+ # |---------------|
+ # | ReturnAddr** |
+ # ESP---->|---------------|
+ #
+
+ #
+ # Set up the local stack for NULL Reminder pointer
+ #
+ xorl %eax, %eax
+ push %eax
+
+ #
+ # Set up the local stack for Divisor parameter
+ #
+ movl 20(%esp), %eax
+ push %eax
+ movl 20(%esp), %eax
+ push %eax
+
+ #
+ # Set up the local stack for Dividend parameter
+ #
+ movl 20(%esp), %eax
+ push %eax
+ movl 20(%esp), %eax
+ push %eax
+
+ #
+ # Call native DivU64x64Remainder of BaseLib
+ #
+ jmp ASM_PFX(DivU64x64Remainder)
+
+ #
+ # Adjust stack
+ #
+ addl $20, %esp
+
+ ret $16
diff --git a/StdLib/LibC/CRT/Ia32/ulldiv.c b/StdLib/LibC/CRT/Ia32/ulldiv.c
new file mode 100644
index 0000000000..e8d6efb6d8
--- /dev/null
+++ b/StdLib/LibC/CRT/Ia32/ulldiv.c
@@ -0,0 +1,88 @@
+/** @file
+ 64-bit Math Worker Function.
+ The 32-bit versions of C compiler generate calls to library routines
+ to handle 64-bit math. These functions use non-standard calling conventions.
+
+ Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License which accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/BaseLib.h>
+
+
+/*
+ * Divides a 64-bit unsigned value with a 64-bit unsigned value and returns
+ * a 64-bit unsigned result.
+ */
+__declspec(naked) void __cdecl _aulldiv (void)
+{
+ //
+ // Wrapper Implementation over EDKII DivU64x64Reminder() routine
+ // UINT64
+ // EFIAPI
+ // DivU64x64Remainder (
+ // IN UINT64 Dividend,
+ // IN UINT64 Divisor,
+ // OUT UINT64 *Remainder OPTIONAL
+ // )
+ //
+ _asm {
+
+ ; Original local stack when calling _aulldiv
+ ; -----------------
+ ; | |
+ ; |---------------|
+ ; | |
+ ; |-- Divisor --|
+ ; | |
+ ; |---------------|
+ ; | |
+ ; |-- Dividend --|
+ ; | |
+ ; |---------------|
+ ; | ReturnAddr** |
+ ; ESP---->|---------------|
+ ;
+
+ ;
+ ; Set up the local stack for NULL Reminder pointer
+ ;
+ xor eax, eax
+ push eax
+
+ ;
+ ; Set up the local stack for Divisor parameter
+ ;
+ mov eax, [esp + 20]
+ push eax
+ mov eax, [esp + 20]
+ push eax
+
+ ;
+ ; Set up the local stack for Dividend parameter
+ ;
+ mov eax, [esp + 20]
+ push eax
+ mov eax, [esp + 20]
+ push eax
+
+ ;
+ ; Call native DivU64x64Remainder of BaseLib
+ ;
+ call DivU64x64Remainder
+
+ ;
+ ; Adjust stack
+ ;
+ add esp, 20
+
+ ret 16
+ }
+}
diff --git a/StdLib/LibC/CRT/Ia32/ulldvrm.c b/StdLib/LibC/CRT/Ia32/ulldvrm.c
new file mode 100644
index 0000000000..2df587e1a4
--- /dev/null
+++ b/StdLib/LibC/CRT/Ia32/ulldvrm.c
@@ -0,0 +1,100 @@
+/** @file
+ 64-bit Math Worker Function.
+ The 32-bit versions of C compiler generate calls to library routines
+ to handle 64-bit math. These functions use non-standard calling conventions.
+
+ Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License which accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/BaseLib.h>
+
+
+/*
+ * Divides a 64-bit signed value by another 64-bit signed value and returns
+ * the 64-bit signed result and the 64-bit signed remainder.
+ */
+__declspec(naked) void __cdecl _aulldvrm(void)
+{
+ //
+ // Wrapper Implementation over EDKII DivU64x64Remainder() routine
+ // UINT64
+ // EFIAPI
+ // DivU64x64Remainder (
+ // IN UINT64 Dividend,
+ // IN UINT64 Divisor,
+ // OUT UINT64 *Remainder
+ // )
+ //
+ _asm {
+ ; Original local stack when calling _aulldvrm
+ ; -----------------
+ ; | |
+ ; |---------------|
+ ; | |
+ ; |-- Divisor --|
+ ; | |
+ ; |---------------|
+ ; | |
+ ; |-- Dividend --|
+ ; | |
+ ; |---------------|
+ ; | ReturnAddr** |
+ ; ESP---->|---------------|
+ ;
+ ;
+ ; On Exit:
+ ; EDX:EAX contains the quotient (dividend/divisor)
+ ; EBX:ECX contains the remainder (divided % divisor)
+ ; NOTE: this routine removes the parameters from the stack.
+ ;
+
+ ;
+ ; Set up the local stack for Remainder pointer
+ ;
+ sub esp, 8
+ push esp
+
+ ;
+ ; Set up the local stack for Divisor parameter
+ ;
+ mov eax, [esp + 28]
+ push eax
+ mov eax, [esp + 28]
+ push eax
+
+ ;
+ ; Set up the local stack for Dividend parameter
+ ;
+ mov eax, [esp + 28]
+ push eax
+ mov eax, [esp + 28]
+ push eax
+
+ ;
+ ; Call native DivU64x64Remainder of BaseLib
+ ;
+ call DivU64x64Remainder
+
+ ;
+ ; EDX:EAX contains the quotient (dividend/divisor)
+ ; Put the Remainder in EBX:ECX
+ ;
+ mov ecx, [esp + 20]
+ mov ebx, [esp + 24]
+
+ ;
+ ; Adjust stack
+ ;
+ add esp, 28
+
+ ret 16
+ }
+}
diff --git a/StdLib/LibC/CRT/Ia32/ullrem.c b/StdLib/LibC/CRT/Ia32/ullrem.c
new file mode 100644
index 0000000000..2e25c6c4e3
--- /dev/null
+++ b/StdLib/LibC/CRT/Ia32/ullrem.c
@@ -0,0 +1,93 @@
+/** @file
+ 64-bit Math Worker Function.
+ The 32-bit versions of C compiler generate calls to library routines
+ to handle 64-bit math. These functions use non-standard calling conventions.
+
+ Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License which accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/BaseLib.h>
+
+
+/*
+ * Divides a 64-bit unsigned value by another 64-bit unsigned value and returns
+ * the 64-bit unsigned remainder.
+ */
+__declspec(naked) void __cdecl _aullrem(void)
+{
+ //
+ // Wrapper Implementation over EDKII DivU64x64Remainder() routine
+ // UINT64
+ // EFIAPI
+ // DivU64x64Remainder (
+ // IN UINT64 Dividend,
+ // IN UINT64 Divisor,
+ // OUT UINT64 *Remainder OPTIONAL
+ // )
+ //
+ _asm {
+ ; Original local stack when calling _aullrem
+ ; -----------------
+ ; | |
+ ; |---------------|
+ ; | |
+ ; |-- Divisor --|
+ ; | |
+ ; |---------------|
+ ; | |
+ ; |-- Dividend --|
+ ; | |
+ ; |---------------|
+ ; | ReturnAddr** |
+ ; ESP---->|---------------|
+ ;
+
+ ;
+ ; Set up the local stack for Reminder pointer
+ ;
+ sub esp, 8
+ push esp
+
+ ;
+ ; Set up the local stack for Divisor parameter
+ ;
+ mov eax, [esp + 28]
+ push eax
+ mov eax, [esp + 28]
+ push eax
+
+ ;
+ ; Set up the local stack for Dividend parameter
+ ;
+ mov eax, [esp + 28]
+ push eax
+ mov eax, [esp + 28]
+ push eax
+
+ ;
+ ; Call native DivU64x64Remainder of BaseLib
+ ;
+ call DivU64x64Remainder
+
+ ;
+ ; Put the Reminder in EDX:EAX as return value
+ ;
+ mov eax, [esp + 20]
+ mov edx, [esp + 24]
+
+ ;
+ ; Adjust stack
+ ;
+ add esp, 28
+
+ ret 16
+ }
+}
diff --git a/StdLib/LibC/CRT/Ia32/ullshr.c b/StdLib/LibC/CRT/Ia32/ullshr.c
new file mode 100644
index 0000000000..f08adcb03e
--- /dev/null
+++ b/StdLib/LibC/CRT/Ia32/ullshr.c
@@ -0,0 +1,57 @@
+/** @file
+ 64-bit Math Worker Function.
+ The 32-bit versions of C compiler generate calls to library routines
+ to handle 64-bit math. These functions use non-standard calling conventions.
+
+ Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License which accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+/*
+ * Shifts a 64-bit unsigned value right by a certain number of bits.
+ */
+__declspec(naked) void __cdecl _aullshr (void)
+{
+ _asm {
+ ;
+ ; Checking: Only handle 64bit shifting or more
+ ;
+ cmp cl, 64
+ jae _Exit
+
+ ;
+ ; Handle shifting between 0 and 31 bits
+ ;
+ cmp cl, 32
+ jae More32
+ shrd eax, edx, cl
+ shr edx, cl
+ ret
+
+ ;
+ ; Handle shifting of 32-63 bits
+ ;
+More32:
+ mov eax, edx
+ xor edx, edx
+ and cl, 31
+ shr eax, cl
+ ret
+
+ ;
+ ; Invalid number (less then 32bits), return 0
+ ;
+_Exit:
+ xor eax, eax
+ xor edx, edx
+ ret
+ }
+}
diff --git a/StdLib/LibC/CRT/Ia32/umoddi3.S b/StdLib/LibC/CRT/Ia32/umoddi3.S
new file mode 100644
index 0000000000..9b72e918a4
--- /dev/null
+++ b/StdLib/LibC/CRT/Ia32/umoddi3.S
@@ -0,0 +1,89 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+# Module Name:
+#
+# MathReminderU64x64.S
+#
+# Abstract:
+#
+# 64-bit Math Worker Function.
+# Divides a 64-bit unsigned value by another 64-bit unsigned value and returns
+# the 64-bit unsigned remainder
+#
+#------------------------------------------------------------------------------
+
+ .686:
+ .code:
+
+ASM_GLOBAL ASM_PFX(__umoddi3), ASM_PFX(DivU64x64Remainder)
+
+#------------------------------------------------------------------------------
+#
+# void __cdecl __umoddi3 (void)
+#
+#------------------------------------------------------------------------------
+ASM_PFX(__umoddi3):
+ # Original local stack when calling __umoddi3
+ # -----------------
+ # | |
+ # |---------------|
+ # | |
+ # |-- Divisor --|
+ # | |
+ # |---------------|
+ # | |
+ # |-- Dividend --|
+ # | |
+ # |---------------|
+ # | ReturnAddr** |
+ # ESP---->|---------------|
+ #
+
+ #
+ # Set up the local stack for Reminder pointer
+ #
+ sub $8, %esp
+ push %esp
+
+ #
+ # Set up the local stack for Divisor parameter
+ #
+ movl 28(%esp), %eax
+ push %eax
+ movl 28(%esp), %eax
+ push %eax
+
+ #
+ # Set up the local stack for Dividend parameter
+ #
+ movl 28(%esp), %eax
+ push %eax
+ movl 28(%esp), %eax
+ push %eax
+
+ #
+ # Call native DivU64x64Remainder of BaseLib
+ #
+ jmp ASM_PFX(DivU64x64Remainder)
+
+ #
+ # Put the Reminder in EDX:EAX as return value
+ #
+ movl 20(%esp), %eax
+ movl 24(%esp), %edx
+
+ #
+ # Adjust stack
+ #
+ add $28, %esp
+
+ ret $16
diff --git a/StdLib/LibC/Ctype/CClass.c b/StdLib/LibC/Ctype/CClass.c
new file mode 100644
index 0000000000..f350063352
--- /dev/null
+++ b/StdLib/LibC/Ctype/CClass.c
@@ -0,0 +1,140 @@
+/** @file
+ Character classification and case conversion functions for <ctype.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#include <LibConfig.h>
+
+#define NO_CTYPE_MACROS // So that we don't define the classification macros
+#include <ctype.h>
+
+int
+__isCClass( int _c, unsigned int mask)
+{
+ return ((_c < 0 || _c > 127) ? 0 : (_cClass[_c] & mask));
+}
+
+/**
+
+ @return
+**/
+int isalnum(int c)
+{
+ return (__isCClass( c, (_CD | _CU | _CL | _XA)));
+}
+
+/**
+
+ @return
+**/
+int isalpha(int c)
+{
+ return (__isCClass( c, (_CU | _CL | _XA)));
+}
+
+/**
+
+ @return
+**/
+int iscntrl(int c)
+{
+ return (__isCClass( c, (_CC)));
+}
+
+/**
+
+ @return
+**/
+int isdigit(int c)
+{
+ return (__isCClass( c, (_CD)));
+}
+
+/**
+
+ @return
+**/
+int isgraph(int c)
+{
+ return (__isCClass( c, (_CG)));
+}
+
+/**
+
+ @return
+**/
+int islower(int c)
+{
+ return (__isCClass( c, (_CL)));
+}
+
+/**
+
+ @return
+**/
+int isprint(int c)
+{
+ return (__isCClass( c, (_CS | _CG)));
+}
+
+/**
+
+ @return
+**/
+int ispunct(int c)
+{
+ return (__isCClass( c, (_CP)));
+}
+
+/**
+
+ @return
+**/
+int isspace(int c)
+{
+ return (__isCClass( c, (_CW)));
+}
+
+/**
+
+ @return
+**/
+int isupper(int c)
+{
+ return (__isCClass( c, (_CU)));
+}
+
+/**
+
+ @return
+**/
+int isxdigit(int c)
+{
+ return (__isCClass( c, (_CD | _CX)));
+}
+
+#if defined(_NETBSD_SOURCE)
+int
+isblank(int c)
+{
+ return (__isCClass( c, _CB));
+}
+#endif
+
+/** The isascii function tests that a character is one of the 128 ASCII characters.
+
+ @param[in] c The character to test.
+ @return Returns nonzero (true) if c is a valid ASCII character. Otherwize,
+ zero (false) is returned.
+**/
+int isascii(int c){
+ return ((c >= 0) && (c < 128));
+}
diff --git a/StdLib/LibC/Ctype/CConv.c b/StdLib/LibC/Ctype/CConv.c
new file mode 100644
index 0000000000..6ad4f8722d
--- /dev/null
+++ b/StdLib/LibC/Ctype/CConv.c
@@ -0,0 +1,48 @@
+/** @file
+ Case conversion functions for <ctype.h>
+
+ The tolower function converts an uppercase letter to a corresponding
+ lowercase letter. If the argument is a character for which isupper
+ is true and there are one or more corresponding characters, as
+ specified by the current locale, for which islower is true, the tolower
+ function returns one of the corresponding characters (always the same one
+ for any given locale); otherwise, the argument is returned unchanged.
+
+ The toupper function converts a lowercase letter to a corresponding
+ uppercase letter. If the argument is a character for which islower is true
+ and there are one or more corresponding characters, as specified by the
+ current locale, for which isupper is true, the toupper function returns one
+ of the corresponding characters (always the same one for any given locale);
+ otherwise, the argument is returned unchanged.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#include <LibConfig.h>
+
+#define NO_CTYPE_MACROS // So that we don't define the classification macros
+#include <ctype.h>
+
+int
+tolower(
+ int _c
+ )
+{
+// return ((_c < 0 || _c > 127) ? _c : _lConvT[_c]);
+ return (isupper(_c) ? _lConvT[_c] : _c);
+}
+
+int toupper(
+ int _c
+ )
+{
+// return ((_c < 0 || _c > 127) ? _c : _uConvT[_c]);
+ return (islower(_c) ? _uConvT[_c] : _c);
+}
diff --git a/StdLib/LibC/Ctype/Ctype.inf b/StdLib/LibC/Ctype/Ctype.inf
new file mode 100644
index 0000000000..e767885326
--- /dev/null
+++ b/StdLib/LibC/Ctype/Ctype.inf
@@ -0,0 +1,50 @@
+## @file
+#
+# Character Classification library implementing the functionality described
+# by the <ctype.h> header of the C Standard Library, ISO/IEC 9899:1990 with
+# Amendment 1 (C95).
+#
+# Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THIS PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = LibCtype
+ FILE_GUID = dcc64575-fa7d-4b7b-b1ad-48427c97c74d
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = LibCtype
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[Sources]
+ iCtype.c
+ CClass.c
+ CConv.c
+
+[Packages]
+ StdLib/StdLib.dec
+ StdLibPrivateInternalFiles/DoNotUse.dec
+ MdePkg/MdePkg.dec
+
+################################################################
+#
+# The Build Options, below, are only used when building the C library.
+# DO NOT use them when building your application!
+# Nasty things could happen if you do.
+#
+[BuildOptions]
+ MSFT:*_*_*_CC_FLAGS = /GL-
diff --git a/StdLib/LibC/Ctype/iCtype.c b/StdLib/LibC/Ctype/iCtype.c
new file mode 100644
index 0000000000..69df21e7ae
--- /dev/null
+++ b/StdLib/LibC/Ctype/iCtype.c
@@ -0,0 +1,303 @@
+/** @file
+ Character classification and case conversion tables, and functions,
+ for the C Standard Library as required to implement ctype.h.
+
+ These are the default, C locale, tables.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#include <LibConfig.h>
+#include <ctype.h>
+
+/// ASCII-8 Character Classification Table
+const UINT16 _C_CharClassTable[128] = {
+ /* 00 NUL */ ( _CC ),
+ /* 01 SOH */ ( _CC ),
+ /* 02 STX */ ( _CC ),
+ /* 03 ETX */ ( _CC ),
+ /* 04 EOT */ ( _CC ),
+ /* 05 ENQ */ ( _CC ),
+ /* 06 ACK */ ( _CC ),
+ /* 07 BEL */ ( _CC ),
+ /* 08 BS */ ( _CC ),
+ /* 09 TAB */ ( _CC | _CW | _CB ),
+ /* 0A LF */ ( _CC | _CW ),
+ /* 0B VT */ ( _CC | _CW ),
+ /* 0C FF */ ( _CC | _CW ),
+ /* 0D CR */ ( _CC | _CW ),
+ /* 0E SO */ ( _CC ),
+ /* 0F SI */ ( _CC ),
+ /* 10 DLE */ ( _CC ),
+ /* 11 DC1 */ ( _CC ),
+ /* 12 DC2 */ ( _CC ),
+ /* 13 DC3 */ ( _CC ),
+ /* 14 DC4 */ ( _CC ),
+ /* 15 NAK */ ( _CC ),
+ /* 16 SYN */ ( _CC ),
+ /* 17 ETB */ ( _CC ),
+ /* 18 CAN */ ( _CC ),
+ /* 19 EM */ ( _CC ),
+ /* 1A SUB */ ( _CC ),
+ /* 1B ESC */ ( _CC ),
+ /* 1C FS */ ( _CC ),
+ /* 1D GS */ ( _CC ),
+ /* 1E RS */ ( _CC ),
+ /* 1F US */ ( _CC ),
+ /* 20 ' ' */ ( _CW | _CS | _CB ),
+ /* 21 '!' */ ( _CP | _CG ),
+ /* 22 '"' */ ( _CP | _CG ),
+ /* 23 '#' */ ( _CP | _CG ),
+ /* 24 '$' */ ( _CP | _CG ),
+ /* 25 '%' */ ( _CP | _CG ),
+ /* 26 '&' */ ( _CP | _CG ),
+ /* 27 '\''*/ ( _CP | _CG ),
+ /* 28 '(' */ ( _CP | _CG ),
+ /* 29 ')' */ ( _CP | _CG ),
+ /* 2A '*' */ ( _CP | _CG ),
+ /* 2B '+' */ ( _CP | _CG ),
+ /* 2C ',' */ ( _CP | _CG ),
+ /* 2D '-' */ ( _CP | _CG ),
+ /* 2E '.' */ ( _CP | _CG ),
+ /* 2F '/' */ ( _CP | _CG ),
+ /* 30 '0' */ ( _CD | _CG ),
+ /* 31 '1' */ ( _CD | _CG ),
+ /* 32 '2' */ ( _CD | _CG ),
+ /* 33 '3' */ ( _CD | _CG ),
+ /* 34 '4' */ ( _CD | _CG ),
+ /* 35 '5' */ ( _CD | _CG ),
+ /* 36 '6' */ ( _CD | _CG ),
+ /* 37 '7' */ ( _CD | _CG ),
+ /* 38 '8' */ ( _CD | _CG ),
+ /* 39 '9' */ ( _CD | _CG ),
+ /* 3A ':' */ ( _CP | _CG ),
+ /* 3B ';' */ ( _CP | _CG ),
+ /* 3C '<' */ ( _CP | _CG ),
+ /* 3D '=' */ ( _CP | _CG ),
+ /* 3E '>' */ ( _CP | _CG ),
+ /* 3F '?' */ ( _CP | _CG ),
+ /* 40 '@' */ ( _CP | _CG ),
+ /* 41 'A' */ ( _CU | _CX | _CG ),
+ /* 42 'B' */ ( _CU | _CX | _CG ),
+ /* 43 'C' */ ( _CU | _CX | _CG ),
+ /* 44 'D' */ ( _CU | _CX | _CG ),
+ /* 45 'E' */ ( _CU | _CX | _CG ),
+ /* 46 'F' */ ( _CU | _CX | _CG ),
+ /* 47 'G' */ ( _CU | _CG ),
+ /* 48 'H' */ ( _CU | _CG ),
+ /* 49 'I' */ ( _CU | _CG ),
+ /* 4A 'J' */ ( _CU | _CG ),
+ /* 4B 'K' */ ( _CU | _CG ),
+ /* 4C 'L' */ ( _CU | _CG ),
+ /* 4D 'M' */ ( _CU | _CG ),
+ /* 4E 'N' */ ( _CU | _CG ),
+ /* 4F 'O' */ ( _CU | _CG ),
+ /* 50 'P' */ ( _CU | _CG ),
+ /* 51 'Q' */ ( _CU | _CG ),
+ /* 52 'R' */ ( _CU | _CG ),
+ /* 53 'S' */ ( _CU | _CG ),
+ /* 54 'T' */ ( _CU | _CG ),
+ /* 55 'U' */ ( _CU | _CG ),
+ /* 56 'V' */ ( _CU | _CG ),
+ /* 57 'W' */ ( _CU | _CG ),
+ /* 58 'X' */ ( _CU | _CG ),
+ /* 59 'Y' */ ( _CU | _CG ),
+ /* 5A 'Z' */ ( _CU | _CG ),
+ /* 5B '[' */ ( _CP | _CG ),
+ /* 5C '\' */ ( _CP | _CG ),
+ /* 5D ']' */ ( _CP | _CG ),
+ /* 5E '^' */ ( _CP | _CG ),
+ /* 5F '_' */ ( _CP | _CG ),
+ /* 60 '`' */ ( _CP | _CG ),
+ /* 61 'a' */ ( _CL | _CX | _CG ),
+ /* 62 'b' */ ( _CL | _CX | _CG ),
+ /* 63 'c' */ ( _CL | _CX | _CG ),
+ /* 64 'd' */ ( _CL | _CX | _CG ),
+ /* 65 'e' */ ( _CL | _CX | _CG ),
+ /* 66 'f' */ ( _CL | _CX | _CG ),
+ /* 67 'g' */ ( _CL | _CG ),
+ /* 68 'h' */ ( _CL | _CG ),
+ /* 69 'i' */ ( _CL | _CG ),
+ /* 6A 'j' */ ( _CL | _CG ),
+ /* 6B 'k' */ ( _CL | _CG ),
+ /* 6C 'l' */ ( _CL | _CG ),
+ /* 6D 'm' */ ( _CL | _CG ),
+ /* 6E 'n' */ ( _CL | _CG ),
+ /* 6F 'o' */ ( _CL | _CG ),
+ /* 70 'p' */ ( _CL | _CG ),
+ /* 71 'q' */ ( _CL | _CG ),
+ /* 72 'r' */ ( _CL | _CG ),
+ /* 73 's' */ ( _CL | _CG ),
+ /* 74 't' */ ( _CL | _CG ),
+ /* 75 'u' */ ( _CL | _CG ),
+ /* 76 'v' */ ( _CL | _CG ),
+ /* 77 'w' */ ( _CL | _CG ),
+ /* 78 'x' */ ( _CL | _CG ),
+ /* 79 'y' */ ( _CL | _CG ),
+ /* 7A 'z' */ ( _CL | _CG ),
+ /* 7B '{' */ ( _CP | _CG ),
+ /* 7C '|' */ ( _CP | _CG ),
+ /* 7D '}' */ ( _CP | _CG ),
+ /* 7E '~' */ ( _CP | _CG ),
+ /* 7F DEL */ ( _CC )
+};
+
+/// ASCII-8 Upper case to Lower case character conversion table
+const UINT8 _C_ToLowerTable[128] = {
+ /* 00 NUL */ 0x00, /* 01 SOH */ 0x01,
+ /* 02 STX */ 0x02, /* 03 ETX */ 0x03,
+ /* 04 EOT */ 0x04, /* 05 ENQ */ 0x05,
+ /* 06 ACK */ 0x06, /* 07 BEL */ 0x07,
+ /* 08 BS */ 0x08, /* 09 TAB */ 0x09,
+ /* 0A LF */ 0x0A, /* 0B VT */ 0x0B,
+ /* 0C FF */ 0x0C, /* 0D CR */ 0x0D,
+ /* 0E SO */ 0x0E, /* 0F SI */ 0x0F,
+ /* 10 DLE */ 0x10, /* 11 DC1 */ 0x11,
+ /* 12 DC2 */ 0x12, /* 13 DC3 */ 0x13,
+ /* 14 DC4 */ 0x14, /* 15 NAK */ 0x15,
+ /* 16 SYN */ 0x16, /* 17 ETB */ 0x17,
+ /* 18 CAN */ 0x18, /* 19 EM */ 0x19,
+ /* 1A SUB */ 0x1A, /* 1B ESC */ 0x1B,
+ /* 1C FS */ 0x1C, /* 1D GS */ 0x1D,
+ /* 1E RS */ 0x1E, /* 1F US */ 0x1F,
+ /* 20 ' ' */ 0x20, /* 21 '!' */ 0x21,
+ /* 22 '"' */ 0x22, /* 23 '#' */ 0x23,
+ /* 24 '$' */ 0x24, /* 25 '%' */ 0x25,
+ /* 26 '&' */ 0x26, /* 27 '\''*/ 0x27,
+ /* 28 '(' */ 0x28, /* 29 ')' */ 0x29,
+ /* 2A '*' */ 0x2A, /* 2B '+' */ 0x2B,
+ /* 2C ',' */ 0x2C, /* 2D '-' */ 0x2D,
+ /* 2E '.' */ 0x2E, /* 2F '/' */ 0x2F,
+ /* 30 '0' */ 0x30, /* 31 '1' */ 0x31,
+ /* 32 '2' */ 0x32, /* 33 '3' */ 0x33,
+ /* 34 '4' */ 0x34, /* 35 '5' */ 0x35,
+ /* 36 '6' */ 0x36, /* 37 '7' */ 0x37,
+ /* 38 '8' */ 0x38, /* 39 '9' */ 0x39,
+ /* 3A ':' */ 0x3A, /* 3B ';' */ 0x3B,
+ /* 3C '<' */ 0x3C, /* 3D '=' */ 0x3D,
+ /* 3E '>' */ 0x3E, /* 3F '?' */ 0x3F,
+ /* 40 '@' */ 0x40, /* 41 'A' */ 0x61,
+ /* 42 'B' */ 0x62, /* 43 'C' */ 0x63,
+ /* 44 'D' */ 0x64, /* 45 'E' */ 0x65,
+ /* 46 'F' */ 0x66, /* 47 'G' */ 0x67,
+ /* 48 'H' */ 0x68, /* 49 'I' */ 0x69,
+ /* 4A 'J' */ 0x6A, /* 4B 'K' */ 0x6B,
+ /* 4C 'L' */ 0x6C, /* 4D 'M' */ 0x6D,
+ /* 4E 'N' */ 0x6E, /* 4F 'O' */ 0x6F,
+ /* 50 'P' */ 0x70, /* 51 'Q' */ 0x71,
+ /* 52 'R' */ 0x72, /* 53 'S' */ 0x73,
+ /* 54 'T' */ 0x74, /* 55 'U' */ 0x75,
+ /* 56 'V' */ 0x76, /* 57 'W' */ 0x77,
+ /* 58 'X' */ 0x78, /* 59 'Y' */ 0x79,
+ /* 5A 'Z' */ 0x7A, /* 5B '[' */ 0x5B,
+ /* 5C '\' */ 0x5C, /* 5D ']' */ 0x5D,
+ /* 5E '^' */ 0x5E, /* 5F '_' */ 0x5F,
+ /* 60 '`' */ 0x60, /* 61 'a' */ 0x61,
+ /* 62 'b' */ 0x62, /* 63 'c' */ 0x63,
+ /* 64 'd' */ 0x64, /* 65 'e' */ 0x65,
+ /* 66 'f' */ 0x66, /* 67 'g' */ 0x67,
+ /* 68 'h' */ 0x68, /* 69 'i' */ 0x69,
+ /* 6A 'j' */ 0x6A, /* 6B 'k' */ 0x6B,
+ /* 6C 'l' */ 0x6C, /* 6D 'm' */ 0x6D,
+ /* 6E 'n' */ 0x6E, /* 6F 'o' */ 0x6F,
+ /* 70 'p' */ 0x70, /* 71 'q' */ 0x71,
+ /* 72 'r' */ 0x72, /* 73 's' */ 0x73,
+ /* 74 't' */ 0x74, /* 75 'u' */ 0x75,
+ /* 76 'v' */ 0x76, /* 77 'w' */ 0x77,
+ /* 78 'x' */ 0x78, /* 79 'y' */ 0x79,
+ /* 7A 'z' */ 0x7A, /* 7B '{' */ 0x7B,
+ /* 7C '|' */ 0x7C, /* 7D '}' */ 0x7D,
+ /* 7E '~' */ 0x7E, /* 7F DEL */ 0x7F
+};
+
+/// ASCII-8 Lower case to Upper case character conversion table
+const UINT8 _C_ToUpperTable[128] = {
+ /* 00 NUL */ 0x00, /* 01 SOH */ 0x01,
+ /* 02 STX */ 0x02, /* 03 ETX */ 0x03,
+ /* 04 EOT */ 0x04, /* 05 ENQ */ 0x05,
+ /* 06 ACK */ 0x06, /* 07 BEL */ 0x07,
+ /* 08 BS */ 0x08, /* 09 TAB */ 0x09,
+ /* 0A LF */ 0x0A, /* 0B VT */ 0x0B,
+ /* 0C FF */ 0x0C, /* 0D CR */ 0x0D,
+ /* 0E SO */ 0x0E, /* 0F SI */ 0x0F,
+ /* 10 DLE */ 0x10, /* 11 DC1 */ 0x11,
+ /* 12 DC2 */ 0x12, /* 13 DC3 */ 0x13,
+ /* 14 DC4 */ 0x14, /* 15 NAK */ 0x15,
+ /* 16 SYN */ 0x16, /* 17 ETB */ 0x17,
+ /* 18 CAN */ 0x18, /* 19 EM */ 0x19,
+ /* 1A SUB */ 0x1A, /* 1B ESC */ 0x1B,
+ /* 1C FS */ 0x1C, /* 1D GS */ 0x1D,
+ /* 1E RS */ 0x1E, /* 1F US */ 0x1F,
+ /* 20 ' ' */ 0x20, /* 21 '!' */ 0x21,
+ /* 22 '"' */ 0x22, /* 23 '#' */ 0x23,
+ /* 24 '$' */ 0x24, /* 25 '%' */ 0x25,
+ /* 26 '&' */ 0x26, /* 27 '\''*/ 0x27,
+ /* 28 '(' */ 0x28, /* 29 ')' */ 0x29,
+ /* 2A '*' */ 0x2A, /* 2B '+' */ 0x2B,
+ /* 2C ',' */ 0x2C, /* 2D '-' */ 0x2D,
+ /* 2E '.' */ 0x2E, /* 2F '/' */ 0x2F,
+ /* 30 '0' */ 0x30, /* 31 '1' */ 0x31,
+ /* 32 '2' */ 0x32, /* 33 '3' */ 0x33,
+ /* 34 '4' */ 0x34, /* 35 '5' */ 0x35,
+ /* 36 '6' */ 0x36, /* 37 '7' */ 0x37,
+ /* 38 '8' */ 0x38, /* 39 '9' */ 0x39,
+ /* 3A ':' */ 0x3A, /* 3B ';' */ 0x3B,
+ /* 3C '<' */ 0x3C, /* 3D '=' */ 0x3D,
+ /* 3E '>' */ 0x3E, /* 3F '?' */ 0x3F,
+ /* 40 '@' */ 0x40, /* 41 'A' */ 0x41,
+ /* 42 'B' */ 0x42, /* 43 'C' */ 0x43,
+ /* 44 'D' */ 0x44, /* 45 'E' */ 0x45,
+ /* 46 'F' */ 0x46, /* 47 'G' */ 0x47,
+ /* 48 'H' */ 0x48, /* 49 'I' */ 0x49,
+ /* 4A 'J' */ 0x4A, /* 4B 'K' */ 0x4B,
+ /* 4C 'L' */ 0x4C, /* 4D 'M' */ 0x4D,
+ /* 4E 'N' */ 0x4E, /* 4F 'O' */ 0x4F,
+ /* 50 'P' */ 0x50, /* 51 'Q' */ 0x51,
+ /* 52 'R' */ 0x52, /* 53 'S' */ 0x53,
+ /* 54 'T' */ 0x54, /* 55 'U' */ 0x55,
+ /* 56 'V' */ 0x56, /* 57 'W' */ 0x57,
+ /* 58 'X' */ 0x58, /* 59 'Y' */ 0x59,
+ /* 5A 'Z' */ 0x5A, /* 5B '[' */ 0x5B,
+ /* 5C '\' */ 0x5C, /* 5D ']' */ 0x5D,
+ /* 5E '^' */ 0x5E, /* 5F '_' */ 0x5F,
+ /* 60 '`' */ 0x60, /* 61 'a' */ 0x41,
+ /* 62 'b' */ 0x42, /* 63 'c' */ 0x43,
+ /* 64 'd' */ 0x44, /* 65 'e' */ 0x45,
+ /* 66 'f' */ 0x46, /* 67 'g' */ 0x47,
+ /* 68 'h' */ 0x48, /* 69 'i' */ 0x49,
+ /* 6A 'j' */ 0x4A, /* 6B 'k' */ 0x4B,
+ /* 6C 'l' */ 0x4C, /* 6D 'm' */ 0x4D,
+ /* 6E 'n' */ 0x4E, /* 6F 'o' */ 0x4F,
+ /* 70 'p' */ 0x50, /* 71 'q' */ 0x51,
+ /* 72 'r' */ 0x52, /* 73 's' */ 0x53,
+ /* 74 't' */ 0x54, /* 75 'u' */ 0x55,
+ /* 76 'v' */ 0x56, /* 77 'w' */ 0x57,
+ /* 78 'x' */ 0x58, /* 79 'y' */ 0x59,
+ /* 7A 'z' */ 0x5A, /* 7B '{' */ 0x7B,
+ /* 7C '|' */ 0x7C, /* 7D '}' */ 0x7D,
+ /* 7E '~' */ 0x7E, /* 7F DEL */ 0x7F
+};
+
+/// Default character classification table is 8-bit ASCII
+const UINT16 *_cClass = _C_CharClassTable;
+
+/// Default upper to lower conversion table is 8-bit ASCII
+const UINT8 *_lConvT = _C_ToLowerTable;
+
+/// Default lower to upper conversion table is 8-bit ASCII
+const UINT8 *_uConvT = _C_ToUpperTable;
+
+void
+__set_C_locale( void )
+{
+ _cClass = _C_CharClassTable;
+ _lConvT = _C_ToLowerTable;
+ _uConvT = _C_ToUpperTable;
+}
diff --git a/StdLib/LibC/LibC.inf b/StdLib/LibC/LibC.inf
new file mode 100644
index 0000000000..4af3ffe45e
--- /dev/null
+++ b/StdLib/LibC/LibC.inf
@@ -0,0 +1,115 @@
+## @file
+# Standard C library: Miscelaneous implementations.
+#
+# Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = LibC
+ FILE_GUID = 695bec93-82ae-4c17-bdad-7f184f4e651d
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = LibC
+
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[Sources]
+ Main/errno.c
+ Main/assert.c
+ Main/isinfd_ieee754.c
+ Main/isinff_ieee754.c
+ Main/isnand_ieee754.c
+ Main/isnanf_ieee754.c
+ Main/infinityf_ieee754.c
+ Main/Main.c
+ Main/HtoNtoH.c
+ Main/ByteSwap.c
+ Main/longjmp.c
+
+[Sources.IA32]
+ Main/x86flt_rounds.c
+ Main/Ia32/fpu_rmode.asm | MSFT
+ Main/Ia32/fpu_rmode.asm | INTEL
+ Main/Ia32/fpu_rmode.S | GCC
+ Main/Ia32/isinfl.c
+ Main/Ia32/isnanl.c
+
+ # Compiler helper (C RunTime) functions
+ CRT/Ia32/llmul.c | MSFT # __allmul
+ CRT/Ia32/llshl.c | MSFT # __allshl
+ CRT/Ia32/ulldiv.c | MSFT # __aulldiv
+ CRT/Ia32/ullrem.c | MSFT # __aullrem
+ CRT/Ia32/ullshr.c | MSFT # __aullshr
+ CRT/Ia32/lldiv.c | MSFT # __alldiv
+ CRT/Ia32/llrem.c | MSFT # __allrem
+ CRT/Ia32/lldvrm.c | MSFT # __alldvrm
+ CRT/Ia32/ulldvrm.c | MSFT # __aulldvrm
+
+ CRT/Ia32/llmul.c | INTEL
+ CRT/Ia32/llshl.c | INTEL
+ CRT/Ia32/ulldiv.c | INTEL
+ CRT/Ia32/ullrem.c | INTEL
+ CRT/Ia32/ullshr.c | INTEL
+ CRT/Ia32/lldiv.c | INTEL
+ CRT/Ia32/llrem.c | INTEL
+ CRT/Ia32/lldvrm.c | INTEL
+ CRT/Ia32/ulldvrm.c | INTEL
+
+ CRT/Gcc.c | GCC
+
+[Sources.X64]
+ Main/x86flt_rounds.c
+ Main/X64/fpu_rmode.asm | MSFT
+ Main/X64/fpu_rmode.asm | INTEL
+ Main/X64/fpu_rmode.S | GCC
+ Main/X64/isinfl.c
+ Main/X64/isnanl.c
+
+[Sources.IPF]
+ Main/x86flt_rounds.c
+ Main/Ipf/FpuRmode.s
+
+[Sources.ARM]
+ Main/Arm/flt_rounds.c
+
+[Binaries.IA32]
+ LIB|Main/Ia32/ftol2.obj|*|MSFT
+
+[Packages]
+ StdLib/StdLib.dec
+ StdLibPrivateInternalFiles/DoNotUse.dec
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+
+[LibraryClasses]
+ ShellCEntryLib
+ UefiLib
+ BaseLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ TimerLib
+ LibStdLib
+ LibStdio
+ LibString
+
+################################################################
+#
+# The Build Options, below, are only used when building the C library.
+# DO NOT use them when building your application!
+# Nasty things could happen if you do.
+#
+[BuildOptions]
+ MSFT:*_*_IA32_CC_FLAGS = /GL-
diff --git a/StdLib/LibC/Locale/Locale.inf b/StdLib/LibC/Locale/Locale.inf
new file mode 100644
index 0000000000..5fee723f85
--- /dev/null
+++ b/StdLib/LibC/Locale/Locale.inf
@@ -0,0 +1,74 @@
+## @file
+# Standard C library: Locale implementation.
+#
+# Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = LibLocale
+ FILE_GUID = 9205cde5-5ae5-4a4b-bfbf-f6211967eef9
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = LibLocale
+
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[Sources]
+ __mb_cur_max.c #
+ _def_messages.c #
+ _def_monetary.c #
+ _def_numeric.c #
+ _def_time.c #
+ aliasname.c #
+ ctypeio.c #
+ localeconv.c #
+ nl_langinfo.c #
+ setlocale1.c #
+ setlocale32.c #
+ setlocale.c #
+ wcscoll.c #
+ wcsftime.c #
+ wcstoimax.c #
+ wcstol.c #
+ wcstoll.c #
+ wcstoul.c #
+ wcstoull.c #
+ wcstoumax.c #
+ wcstod.c #
+ wcstof.c #
+ wcstold.c #
+ wcsxfrm.c #
+
+ # Single-byte locale to avoid bringing in citrus
+ iswctype_sb.c #
+ multibyte_sb.c #
+
+[Packages]
+ StdLib/StdLib.dec
+ StdLibPrivateInternalFiles/DoNotUse.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ LibC
+ LibCType
+
+################################################################
+#
+# The Build Options, below, are only used when building the C library.
+# DO NOT use them when building your application!
+# Nasty things could happen if you do.
+#
+[BuildOptions]
+ GCC:*_*_*_CC_FLAGS = -fno-builtin
diff --git a/StdLib/LibC/Locale/__mb_cur_max.c b/StdLib/LibC/Locale/__mb_cur_max.c
new file mode 100644
index 0000000000..394c6c2eed
--- /dev/null
+++ b/StdLib/LibC/Locale/__mb_cur_max.c
@@ -0,0 +1,39 @@
+/* $NetBSD: __mb_cur_max.c,v 1.2 2001/01/25 01:25:06 itojun Exp $ */
+
+/*-
+ * Copyright (c)1999 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: __mb_cur_max.c,v 1.2 2001/01/25 01:25:06 itojun Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <limits.h>
+
+size_t __mb_cur_max = 1;
+size_t __mb_len_max_runtime = MB_LEN_MAX;
+
diff --git a/StdLib/LibC/Locale/__wctoint.h b/StdLib/LibC/Locale/__wctoint.h
new file mode 100644
index 0000000000..47d1e74686
--- /dev/null
+++ b/StdLib/LibC/Locale/__wctoint.h
@@ -0,0 +1,79 @@
+/* $NetBSD: __wctoint.h,v 1.1 2001/09/28 11:25:37 yamt Exp $ */
+
+/*-
+ * Copyright (c)2001 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Citrus: xpg4dl/FreeBSD/lib/libc/locale/__wctoint.h,v 1.1 2001/09/21 13:52:32 yamt Exp $
+ */
+
+
+__inline static int
+__wctoint(wchar_t wc)
+{
+ int n;
+
+ /* XXX I expect compiler to optimize this. :D */
+ switch (wc) {
+ case L'0': n = 0; break;
+ case L'1': n = 1; break;
+ case L'2': n = 2; break;
+ case L'3': n = 3; break;
+ case L'4': n = 4; break;
+ case L'5': n = 5; break;
+ case L'6': n = 6; break;
+ case L'7': n = 7; break;
+ case L'8': n = 8; break;
+ case L'9': n = 9; break;
+ case L'A': case L'a': n = 10; break;
+ case L'B': case L'b': n = 11; break;
+ case L'C': case L'c': n = 12; break;
+ case L'D': case L'd': n = 13; break;
+ case L'E': case L'e': n = 14; break;
+ case L'F': case L'f': n = 15; break;
+ case L'G': case L'g': n = 16; break;
+ case L'H': case L'h': n = 17; break;
+ case L'I': case L'i': n = 18; break;
+ case L'J': case L'j': n = 19; break;
+ case L'K': case L'k': n = 20; break;
+ case L'L': case L'l': n = 21; break;
+ case L'M': case L'm': n = 22; break;
+ case L'N': case L'n': n = 23; break;
+ case L'O': case L'o': n = 24; break;
+ case L'P': case L'p': n = 25; break;
+ case L'Q': case L'q': n = 26; break;
+ case L'R': case L'r': n = 27; break;
+ case L'S': case L's': n = 28; break;
+ case L'T': case L't': n = 29; break;
+ case L'U': case L'u': n = 30; break;
+ case L'V': case L'v': n = 31; break;
+ case L'W': case L'w': n = 32; break;
+ case L'X': case L'x': n = 33; break;
+ case L'Y': case L'y': n = 34; break;
+ case L'Z': case L'z': n = 35; break;
+ default: n = -1; break; /* error */
+ }
+
+ return n;
+}
diff --git a/StdLib/LibC/Locale/_def_messages.c b/StdLib/LibC/Locale/_def_messages.c
new file mode 100644
index 0000000000..2481febf53
--- /dev/null
+++ b/StdLib/LibC/Locale/_def_messages.c
@@ -0,0 +1,24 @@
+/* $NetBSD: _def_messages.c,v 1.6 2005/06/12 05:21:27 lukem Exp $ */
+
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: _def_messages.c,v 1.6 2005/06/12 05:21:27 lukem Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/localedef.h>
+#include <locale.h>
+
+const _MessagesLocale _DefaultMessagesLocale =
+{
+ "^[Yy]",
+ "^[Nn]",
+ "yes",
+ "no"
+} ;
+
+const _MessagesLocale *_CurrentMessagesLocale = &_DefaultMessagesLocale;
diff --git a/StdLib/LibC/Locale/_def_monetary.c b/StdLib/LibC/Locale/_def_monetary.c
new file mode 100644
index 0000000000..af11866859
--- /dev/null
+++ b/StdLib/LibC/Locale/_def_monetary.c
@@ -0,0 +1,42 @@
+/* $NetBSD: _def_monetary.c,v 1.8 2005/06/12 05:21:27 lukem Exp $ */
+
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: _def_monetary.c,v 1.8 2005/06/12 05:21:27 lukem Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/localedef.h>
+#include <limits.h>
+#include <locale.h>
+
+const _MonetaryLocale _DefaultMonetaryLocale =
+{
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ (char)CHAR_MAX,
+ (char)CHAR_MAX,
+ (char)CHAR_MAX,
+ (char)CHAR_MAX,
+ (char)CHAR_MAX,
+ (char)CHAR_MAX,
+ (char)CHAR_MAX,
+ (char)CHAR_MAX,
+ (char)CHAR_MAX,
+ (char)CHAR_MAX,
+ (char)CHAR_MAX,
+ (char)CHAR_MAX,
+ (char)CHAR_MAX,
+ (char)CHAR_MAX
+};
+
+const _MonetaryLocale *_CurrentMonetaryLocale = &_DefaultMonetaryLocale;
diff --git a/StdLib/LibC/Locale/_def_numeric.c b/StdLib/LibC/Locale/_def_numeric.c
new file mode 100644
index 0000000000..10a6cec004
--- /dev/null
+++ b/StdLib/LibC/Locale/_def_numeric.c
@@ -0,0 +1,23 @@
+/* $NetBSD: _def_numeric.c,v 1.6 2005/06/12 05:21:27 lukem Exp $ */
+
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: _def_numeric.c,v 1.6 2005/06/12 05:21:27 lukem Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/localedef.h>
+#include <locale.h>
+
+const _NumericLocale _DefaultNumericLocale =
+{
+ ".",
+ "",
+ ""
+};
+
+const _NumericLocale *_CurrentNumericLocale = &_DefaultNumericLocale;
diff --git a/StdLib/LibC/Locale/_def_time.c b/StdLib/LibC/Locale/_def_time.c
new file mode 100644
index 0000000000..102fff554d
--- /dev/null
+++ b/StdLib/LibC/Locale/_def_time.c
@@ -0,0 +1,42 @@
+/* $NetBSD: _def_time.c,v 1.8 2005/06/12 05:21:27 lukem Exp $ */
+
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: _def_time.c,v 1.8 2005/06/12 05:21:27 lukem Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/localedef.h>
+#include <locale.h>
+
+const _TimeLocale _DefaultTimeLocale =
+{
+ {
+ "Sun","Mon","Tue","Wed","Thu","Fri","Sat",
+ },
+ {
+ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
+ "Friday", "Saturday"
+ },
+ {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+ },
+ {
+ "January", "February", "March", "April", "May", "June", "July",
+ "August", "September", "October", "November", "December"
+ },
+ {
+ "AM", "PM"
+ },
+ "%a %b %e %H:%M:%S %Y",
+ "%m/%d/%y",
+ "%H:%M:%S",
+ "%I:%M:%S %p"
+};
+
+const _TimeLocale *_CurrentTimeLocale = &_DefaultTimeLocale;
diff --git a/StdLib/LibC/Locale/_wcstod.h b/StdLib/LibC/Locale/_wcstod.h
new file mode 100644
index 0000000000..1e7c47f2c0
--- /dev/null
+++ b/StdLib/LibC/Locale/_wcstod.h
@@ -0,0 +1,126 @@
+/* $NetBSD: _wcstod.h,v 1.1 2006/04/15 12:17:23 tnozaki Exp $ */
+
+/*-
+ * Copyright (c) 2002 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Original version ID:
+ * FreeBSD: /repoman/r/ncvs/src/lib/libc/locale/wcstod.c,v 1.4 2004/04/07 09:47:56 tjr Exp
+ * NetBSD: wcstod.c,v 1.8 2006/04/13 01:25:13 tnozaki Exp
+ */
+
+/*
+ * function template for wcstof, wcstod, wcstold.
+ *
+ * parameters:
+ * _FUNCNAME : function name
+ * _RETURN_TYPE : return type
+ * _STRTOD_FUNC : real conversion function
+ */
+#ifndef __WCSTOD_H_
+#define __WCSTOD_H_
+
+/*
+ * Convert a string to a double-precision number.
+ *
+ * This is the wide-character counterpart of strto{f,d,ld}(). So that
+ * we do not have to duplicate the code of strto{f,d,ld}() here,
+ * we convert the supplied wide character string to multibyte and
+ * call strto{f,d,ld}() on the result.
+ * This assumes that the multibyte encoding is compatible with ASCII
+ * for at least the digits, radix character and letters.
+ */
+_RETURN_TYPE
+_FUNCNAME(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr)
+{
+ const wchar_t *src, *start;
+ _RETURN_TYPE val;
+ char *buf, *end;
+ size_t bufsiz, len;
+
+ _DIAGASSERT(nptr != NULL);
+ /* endptr may be null */
+
+ src = nptr;
+ while (iswspace((wint_t)*src) != 0)
+ ++src;
+ if (*src == L'\0')
+ goto no_convert;
+
+ /*
+ * Convert the supplied numeric wide char. string to multibyte.
+ *
+ * We could attempt to find the end of the numeric portion of the
+ * wide char. string to avoid converting unneeded characters but
+ * choose not to bother; optimising the uncommon case where
+ * the input string contains a lot of text after the number
+ * duplicates a lot of strto{f,d,ld}()'s functionality and
+ * slows down the most common cases.
+ */
+ start = src;
+ len = wcstombs(NULL, src, 0);
+ if (len == (size_t)-1)
+ /* errno = EILSEQ */
+ goto no_convert;
+
+ _DIAGASSERT(len > 0);
+
+ bufsiz = len;
+ buf = (void *)malloc(bufsiz + 1);
+ if (buf == NULL)
+ /* errno = ENOMEM */
+ goto no_convert;
+
+ len = wcstombs(buf, src, bufsiz + 1);
+
+ _DIAGASSERT(len == bufsiz);
+ _DIAGASSERT(buf[len] == '\0');
+
+ /* Let strto{f,d,ld}() do most of the work for us. */
+ val = _STRTOD_FUNC(buf, &end);
+ if (buf == end) {
+ free(buf);
+ goto no_convert;
+ }
+
+ /*
+ * We only know where the number ended in the _multibyte_
+ * representation of the string. If the caller wants to know
+ * where it ended, count multibyte characters to find the
+ * corresponding position in the wide char string.
+ */
+ if (endptr != NULL)
+ /* XXX Assume each wide char is one byte. */
+ *endptr = __UNCONST(start + (size_t)(end - buf));
+
+ free(buf);
+
+ return val;
+
+no_convert:
+ if (endptr != NULL)
+ *endptr = __UNCONST(nptr);
+ return 0;
+}
+#endif /*__WCSTOD_H_*/
diff --git a/StdLib/LibC/Locale/_wcstol.h b/StdLib/LibC/Locale/_wcstol.h
new file mode 100644
index 0000000000..97d0dc9a95
--- /dev/null
+++ b/StdLib/LibC/Locale/_wcstol.h
@@ -0,0 +1,153 @@
+/** @file
+ Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ Original version ID:
+ @(#)strtol.c 8.1 (Berkeley) 6/4/93
+ NetBSD: wcstol.c,v 1.1 2001/09/27 16:30:36 yamt Exp
+ Citrus: xpg4dl/FreeBSD/lib/libc/locale/wcstol.c,v 1.2 2001/09/21 16:11:41 yamt Exp
+ NetBSD: _wcstol.h,v 1.3 2005/11/29 03:11:59 christos Exp
+ */
+
+/*
+ * function template for wcstol, wcstoll and wcstoimax.
+ *
+ * parameters:
+ * _FUNCNAME : function name
+ * __wINT : return type
+ * __wINT_MIN : lower limit of the return type
+ * __wINT_MAX : upper limit of the return type
+ */
+
+__wINT
+_FUNCNAME(
+ const wchar_t *nptr,
+ wchar_t **endptr,
+ int base
+ )
+{
+ const wchar_t *s;
+ __wINT acc, cutoff;
+ wint_t wc;
+ int i;
+ int neg, any, cutlim;
+
+ _DIAGASSERT(nptr != NULL);
+ /* endptr may be NULL */
+
+#ifdef __GNUC__
+ (void)&acc; (void)&cutoff;
+#endif
+
+ /* check base value */
+ if (base && (base < 2 || base > 36)) {
+ errno = EINVAL;
+ return 0;
+ }
+
+ /*
+ * Skip white space and pick up leading +/- sign if any.
+ * If base is 0, allow 0x for hex and 0 for octal, else
+ * assume decimal; if base is already 16, allow 0x.
+ */
+ s = nptr;
+ do {
+ wc = (wchar_t) *s++;
+ } while (iswspace(wc));
+ if (wc == L'-') {
+ neg = 1;
+ wc = *s++;
+ } else {
+ neg = 0;
+ if (wc == L'+')
+ wc = *s++;
+ }
+ if ((base == 0 || base == 16) &&
+ wc == L'0' && (*s == L'x' || *s == L'X')) {
+ wc = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = ((wc == L'0') ? 8 : 10);
+
+ /*
+ * See strtol for comments as to the logic used.
+ */
+ cutoff = neg ? __wINT_MIN : __wINT_MAX;
+ cutlim = (int)(cutoff % base);
+ cutoff /= base;
+ if (neg) {
+ if (cutlim > 0) {
+ cutlim -= base;
+ cutoff += 1;
+ }
+ cutlim = -cutlim;
+ }
+ for (acc = 0, any = 0;; wc = (wchar_t) *s++) {
+ i = __wctoint((wchar_t)wc);
+ if (i == -1)
+ break;
+ if (i >= base)
+ break;
+ if (any < 0)
+ continue;
+ if (neg) {
+ if (acc < cutoff || (acc == cutoff && i > cutlim)) {
+ any = -1;
+ acc = __wINT_MIN;
+ errno = ERANGE;
+ } else {
+ any = 1;
+ acc *= base;
+ acc -= i;
+ }
+ } else {
+ if (acc > cutoff || (acc == cutoff && i > cutlim)) {
+ any = -1;
+ acc = __wINT_MAX;
+ errno = ERANGE;
+ } else {
+ any = 1;
+ acc *= base;
+ acc += i;
+ }
+ }
+ }
+ if (endptr != 0)
+ *endptr = __UNCONST(any ? s - 1 : nptr);
+ return (acc);
+}
diff --git a/StdLib/LibC/Locale/_wcstoul.h b/StdLib/LibC/Locale/_wcstoul.h
new file mode 100644
index 0000000000..ebfc330fe9
--- /dev/null
+++ b/StdLib/LibC/Locale/_wcstoul.h
@@ -0,0 +1,131 @@
+/** @file
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ Original version ID:
+ @(#)strtoul.c 8.1 (Berkeley) 6/4/93
+ Citrus: xpg4dl/FreeBSD/lib/libc/locale/wcstoul.c,v 1.2 2001/09/21 16:11:41 yamt Exp
+ NetBSD: wcstoul.c,v 1.1 2001/09/27 16:30:37 yamt Exp
+ NetBSD: _wcstoul.h,v 1.3 2005/11/29 03:11:59 christos Exp
+ */
+
+/*
+ * function template for wcstoul, wcstoull and wcstoumax.
+ *
+ * parameters:
+ * _FUNCNAME : function name
+ * __wUINT : return type
+ * __wINT : signed version of __wUINT
+ * __wUINT_MAX : upper limit of the return type
+ */
+
+__wUINT
+_FUNCNAME(
+ const wchar_t *nptr,
+ wchar_t **endptr,
+ int base
+ )
+{
+ const wchar_t *s;
+ __wUINT acc, cutoff;
+ wint_t wc;
+ int i;
+ int neg, any, cutlim;
+
+ _DIAGASSERT(nptr != NULL);
+ /* endptr may be NULL */
+
+ if (base && (base < 2 || base > 36)) {
+ errno = EINVAL;
+ return 0;
+ }
+
+ /*
+ * Skip white space and pick up leading +/- sign if any.
+ * If base is 0, allow 0x for hex and 0 for octal, else
+ * assume decimal; if base is already 16, allow 0x.
+ */
+ s = nptr;
+ do {
+ wc = (wchar_t) *s++;
+ } while (iswspace(wc));
+ if (wc == L'-') {
+ neg = 1;
+ wc = *s++;
+ } else {
+ neg = 0;
+ if (wc == L'+')
+ wc = *s++;
+ }
+ if ((base == 0 || base == 16) &&
+ wc == L'0' && (*s == L'x' || *s == L'X')) {
+ wc = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = wc == L'0' ? 8 : 10;
+
+ /*
+ * See strtoul for comments as to the logic used.
+ */
+ cutoff = __wUINT_MAX / (__wUINT)base;
+ cutlim = (int)(__wUINT_MAX % (__wUINT)base);
+ for (acc = 0, any = 0;; wc = (wint_t) *s++) {
+ i = __wctoint((wchar_t)wc);
+ if (i == -1) {
+ break;
+ }
+ if (i >= base)
+ break;
+ if (any < 0)
+ continue;
+ if (acc > cutoff || (acc == cutoff && i > cutlim)) {
+ any = -1;
+ acc = __wUINT_MAX;
+ errno = ERANGE;
+ } else {
+ any = 1;
+ acc *= (__wUINT)base;
+ acc += i;
+ }
+ }
+ if (neg && any > 0)
+ acc = (__wUINT)(-((__wINT)acc));
+ if (endptr != 0)
+ *endptr = __UNCONST(any ? s - 1 : nptr);
+ return (acc);
+}
diff --git a/StdLib/LibC/Locale/aliasname.c b/StdLib/LibC/Locale/aliasname.c
new file mode 100644
index 0000000000..56303e97fe
--- /dev/null
+++ b/StdLib/LibC/Locale/aliasname.c
@@ -0,0 +1,129 @@
+/* $NetBSD: aliasname.c,v 1.2 2005/02/09 21:35:46 kleink Exp $ */
+
+/*-
+ * Copyright (c)2002 YAMAMOTO Takashi,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: aliasname.c,v 1.2 2005/02/09 21:35:46 kleink Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "aliasname_local.h"
+
+__inline int __is_ws(char);
+
+__inline int __is_ws(char ch)
+{
+
+ return (ch == ' ' || ch == '\t');
+}
+
+const char *
+__unaliasname(const char *dbname, const char *alias, void *buf, size_t bufsize)
+{
+ FILE *fp = NULL;
+ const char *result = alias;
+ size_t resultlen;
+ size_t aliaslen;
+ const char *p;
+ size_t len;
+
+ _DIAGASSERT(dbname != NULL);
+ _DIAGASSERT(alias != NULL);
+ _DIAGASSERT(buf != NULL);
+
+ fp = fopen(dbname, "r");
+ if (fp == NULL)
+ goto quit;
+
+ aliaslen = strlen(alias);
+
+ while (/*CONSTCOND*/ 1) {
+ p = fgetln(fp, &len);
+ if (p == NULL)
+ goto quit; /* eof or error */
+
+ _DIAGASSERT(len != 0);
+
+ /* ignore terminating NL */
+ if (p[len - 1] == '\n')
+ len--;
+
+ /* ignore null line and comment */
+ if (len == 0 || p[0] == '#')
+ continue;
+
+ if (aliaslen > len)
+ continue;
+
+ if (memcmp(alias, p, aliaslen))
+ continue;
+
+ p += aliaslen;
+ len -= aliaslen;
+
+ if (len == 0 || !__is_ws(*p))
+ continue;
+
+ /* entry was found here */
+ break;
+
+ /* NOTREACHED */
+ }
+
+ /* skip white spaces */
+ do {
+ p++;
+ len--;
+ } while (len != 0 && __is_ws(*p));
+
+ if (len == 0)
+ goto quit;
+
+ /* count length of result */
+ resultlen = 0;
+ while (resultlen < len && !__is_ws(*p))
+ resultlen++;
+
+ /* check if space is enough */
+ if (bufsize < resultlen + 1)
+ goto quit;
+
+ memcpy(buf, p, resultlen);
+ ((char *)buf)[resultlen] = 0;
+ result = buf;
+
+quit:
+ if (fp)
+ fclose(fp);
+
+ return result;
+}
diff --git a/StdLib/LibC/Locale/aliasname_local.h b/StdLib/LibC/Locale/aliasname_local.h
new file mode 100644
index 0000000000..9daec022b2
--- /dev/null
+++ b/StdLib/LibC/Locale/aliasname_local.h
@@ -0,0 +1,29 @@
+/* $NetBSD: aliasname_local.h,v 1.1 2002/02/13 07:45:52 yamt Exp $ */
+
+/*-
+ * Copyright (c)2002 YAMAMOTO Takashi,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+const char *__unaliasname(const char *, const char *, void *, size_t);
diff --git a/StdLib/LibC/Locale/ctypeio.c b/StdLib/LibC/Locale/ctypeio.c
new file mode 100644
index 0000000000..8679dcd884
--- /dev/null
+++ b/StdLib/LibC/Locale/ctypeio.c
@@ -0,0 +1,186 @@
+/** @file
+ Internal C-type locale functions.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1997 Christos Zoulas. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. All advertising materials mentioning features or use of this software
+ must display the following acknowledgement:
+ This product includes software developed by Christos Zoulas.
+ 4. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: ctypeio.c,v 1.7 2005/11/29 03:11:59 christos Exp
+**/
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: ctypeio.c,v 1.7 2005/11/29 03:11:59 christos Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define _CTYPE_PRIVATE
+#include <ctype.h>
+#include "ctypeio.h"
+
+int
+__loadctype(const char *name)
+{
+ FILE *fp;
+ char id[sizeof(_CTYPE_ID) - 1];
+ u_int32_t i, len;
+ unsigned short *new_ctype = NULL;
+ unsigned char *new_toupper = NULL, *new_tolower = NULL;
+
+ _DIAGASSERT(name != NULL);
+
+ if ((fp = fopen(name, "r")) == NULL)
+ return 0;
+
+ if (fread(id, sizeof(id), 1, fp) != 1)
+ goto bad;
+
+ if (memcmp(id, _CTYPE_ID, sizeof(id)) != 0)
+ goto bad;
+
+ if (fread(&i, sizeof(u_int32_t), 1, fp) != 1)
+ goto bad;
+
+ if ((i = ntohl(i)) != _CTYPE_REV)
+ goto bad;
+
+ if (fread(&len, sizeof(u_int32_t), 1, fp) != 1)
+ goto bad;
+
+ if ((len = ntohl(len)) != _CTYPE_NUM_CHARS)
+ goto bad;
+
+ if ((new_ctype = malloc(sizeof(UINT16) * (1 + len))) == NULL)
+ goto bad;
+
+ new_ctype[0] = 0;
+ if (fread(&new_ctype[1], sizeof(UINT16), len, fp) != len)
+ goto bad;
+
+ if ((new_toupper = malloc(sizeof(UINT8) * (1 + len))) == NULL)
+ goto bad;
+
+ new_toupper[0] = (UINT8)EOF;
+ if (fread(&new_toupper[1], sizeof(UINT8), len, fp) != len)
+ goto bad;
+
+ if ((new_tolower = malloc(sizeof(UINT8) * (1 + len))) == NULL)
+ goto bad;
+
+ new_tolower[0] = (UINT8)EOF;
+ if (fread(&new_tolower[1], sizeof(UINT8), len, fp) != len)
+ goto bad;
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ for (i = 1; i <= len; i++) {
+ new_ctype[i] = ntohs(new_ctype[i]);
+ }
+#endif
+
+ (void) fclose(fp);
+ if (_cClass != _C_CharClassTable)
+ free(__UNCONST(_cClass));
+ _cClass = new_ctype;
+ if (_uConvT != _C_ToUpperTable)
+ free(__UNCONST(_uConvT));
+ _uConvT = new_toupper;
+ if (_lConvT != _C_ToLowerTable)
+ free(__UNCONST(_lConvT));
+ _lConvT = new_tolower;
+
+ return 1;
+bad:
+ free(new_tolower);
+ free(new_toupper);
+ free(new_ctype);
+ (void) fclose(fp);
+ return 0;
+}
+
+int
+__savectype(
+ const char *name,
+ unsigned short *new_ctype,
+ unsigned char *new_toupper,
+ unsigned char *new_tolower
+ )
+{
+ FILE *fp;
+ u_int32_t i, len = _CTYPE_NUM_CHARS;
+
+ _DIAGASSERT(name != NULL);
+ _DIAGASSERT(new_ctype != NULL);
+ _DIAGASSERT(new_toupper != NULL);
+ _DIAGASSERT(new_tolower != NULL);
+
+ if ((fp = fopen(name, "w")) == NULL)
+ return 0;
+
+ if (fwrite(_CTYPE_ID, sizeof(_CTYPE_ID) - 1, 1, fp) != 1)
+ goto bad;
+
+ i = htonl(_CTYPE_REV);
+ if (fwrite(&i, sizeof(u_int32_t), 1, fp) != 1)
+ goto bad;
+
+ i = htonl(len);
+ if (fwrite(&i, sizeof(u_int32_t), 1, fp) != 1)
+ goto bad;
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ for (i = 1; i <= len; i++) {
+ new_ctype[i] = htons(new_ctype[i]);
+ }
+#endif
+ if (fwrite(&new_ctype[1], sizeof(UINT16), len, fp) != len)
+ goto bad;
+
+ if (fwrite(&new_toupper[1], sizeof(UINT8), len, fp) != len)
+ goto bad;
+
+ if (fwrite(&new_tolower[1], sizeof(UINT8), len, fp) != len)
+ goto bad;
+
+ (void) fclose(fp);
+ return 1;
+bad:
+ (void) fclose(fp);
+ return 0;
+}
diff --git a/StdLib/LibC/Locale/ctypeio.h b/StdLib/LibC/Locale/ctypeio.h
new file mode 100644
index 0000000000..919889fa84
--- /dev/null
+++ b/StdLib/LibC/Locale/ctypeio.h
@@ -0,0 +1,35 @@
+/* $NetBSD: ctypeio.h,v 1.1 1997/06/02 09:52:48 kleink Exp $ */
+
+/*
+ * Copyright (c) 1997 Christos Zoulas. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christos Zoulas.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+__BEGIN_DECLS
+int __loadctype (const char *);
+int __savectype (const char *, unsigned short *, unsigned char *, unsigned char *);
+__END_DECLS
diff --git a/StdLib/LibC/Locale/iswctype_sb.c b/StdLib/LibC/Locale/iswctype_sb.c
new file mode 100644
index 0000000000..454201543f
--- /dev/null
+++ b/StdLib/LibC/Locale/iswctype_sb.c
@@ -0,0 +1,234 @@
+/** @file
+ Wide character classification and conversion functions.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1989 The Regents of the University of California.
+ All rights reserved.
+ (c) UNIX System Laboratories, Inc.
+ All or some portions of this file are derived from material licensed
+ to the University of California by American Telephone and Telegraph
+ Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ the permission of UNIX System Laboratories, Inc.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ NetBSD: iswctype_sb.c,v 1.4 2004/07/21 20:27:46 tshiozak Exp
+**/
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: iswctype_sb.c,v 1.4 2004/07/21 20:27:46 tshiozak Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <ctype.h>
+#include <string.h>
+#include <wchar.h>
+#include <wctype.h>
+
+#undef iswalnum
+int
+iswalnum(wint_t c)
+{
+ return isalnum((int)c);
+}
+
+#undef iswalpha
+int
+iswalpha(wint_t c)
+{
+ return isalpha((int)c);
+}
+
+#undef iswblank
+int
+iswblank(wint_t c)
+{
+ return isblank((int)c);
+}
+
+#undef iswcntrl
+int
+iswcntrl(wint_t c)
+{
+ return iscntrl((int)c);
+}
+
+#undef iswdigit
+int
+iswdigit(wint_t c)
+{
+ return isdigit((int)c);
+}
+
+#undef iswgraph
+int
+iswgraph(wint_t c)
+{
+ return isgraph((int)c);
+}
+
+#undef iswlower
+int
+iswlower(wint_t c)
+{
+ return islower((int)c);
+}
+
+#undef iswprint
+int
+iswprint(wint_t c)
+{
+ return isprint((int)c);
+}
+
+#undef iswpunct
+int
+iswpunct(wint_t c)
+{
+ return ispunct((int)c);
+}
+
+#undef iswspace
+int
+iswspace(wint_t c)
+{
+ return isspace((int)c);
+}
+
+#undef iswupper
+int
+iswupper(wint_t c)
+{
+ return isupper((int)c);
+}
+
+#undef iswxdigit
+int
+iswxdigit(wint_t c)
+{
+ return isxdigit((int)c);
+}
+
+#undef towupper
+wint_t
+towupper(wint_t c)
+{
+ return toupper((int)c);
+}
+
+#undef towlower
+wint_t
+towlower(wint_t c)
+{
+ return tolower((int)c);
+}
+
+#undef wcwidth
+int
+/*ARGSUSED*/
+wcwidth(wchar_t c)
+{
+ return 1;
+}
+
+#undef iswctype
+int
+iswctype(wint_t c, wctype_t charclass)
+{
+ /*
+ * SUSv3: If charclass is 0, iswctype() shall return 0.
+ */
+ return (__isCClass((int)c, (unsigned int)charclass));
+}
+
+// Additional functions in <wctype.h> but not in NetBSD _sb code.
+static
+struct _typestrval {
+ char *name;
+ wctype_t value;
+} typestrval[] = {
+ { "alnum", (_CD | _CU | _CL | _XA) },
+ { "alpha", (_CU | _CL | _XA) },
+ { "blank", (_CB) },
+ { "cntrl", (_CC) },
+ { "digit", (_CD) },
+ { "graph", (_CG) },
+ { "lower", (_CL) },
+ { "print", (_CS | _CG) },
+ { "punct", (_CP) },
+ { "space", (_CW) },
+ { "upper", (_CU) },
+ { "xdigit", (_CD | _CX) }
+};
+
+#define NUM_PROPVAL (sizeof(typestrval) / sizeof(struct _typestrval))
+
+static
+struct _transtrval {
+ char *name;
+ wctrans_t function;
+} transtrval[] = {
+ { "tolower", towlower },
+ { "toupper", towupper }
+};
+
+#define NUM_TRANSVAL (sizeof(transtrval) / sizeof(struct _transtrval))
+
+wctype_t wctype(const char *property)
+{
+ int i;
+
+ for(i = 0; i < NUM_PROPVAL; ++i) {
+ if( strcmp(typestrval[i].name, property) == 0) {
+ return typestrval[i].value;
+ }
+ }
+ return 0;
+}
+
+wint_t towctrans(wint_t p1, wctrans_t tranfunc)
+{
+ return tranfunc(p1);
+}
+
+wctrans_t wctrans(const char *property)
+{
+ int i;
+
+ for(i = 0; i < NUM_TRANSVAL; ++i) {
+ if( strcmp(transtrval[i].name, property) == 0) {
+ return transtrval[i].function;
+ }
+ }
+ return NULL;
+}
diff --git a/StdLib/LibC/Locale/localeconv.c b/StdLib/LibC/Locale/localeconv.c
new file mode 100644
index 0000000000..46430f9c48
--- /dev/null
+++ b/StdLib/LibC/Locale/localeconv.c
@@ -0,0 +1,85 @@
+/* $NetBSD: localeconv.c,v 1.13 2005/11/29 03:11:59 christos Exp $ */
+
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: localeconv.c,v 1.13 2005/11/29 03:11:59 christos Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/localedef.h>
+#include <locale.h>
+
+/*
+ * The localeconv() function constructs a struct lconv from the current
+ * monetary and numeric locales.
+ *
+ * Because localeconv() may be called many times (especially by library
+ * routines like printf() & strtod()), the approprate members of the
+ * lconv structure are computed only when the monetary or numeric
+ * locale has been changed.
+ */
+int __mlocale_changed = 1;
+int __nlocale_changed = 1;
+
+/*
+ * Return the current locale conversion.
+ */
+struct lconv *
+localeconv()
+{
+ static struct lconv ret;
+
+ if (__mlocale_changed) {
+ /* LC_MONETARY */
+ ret.int_curr_symbol =
+ __UNCONST(_CurrentMonetaryLocale->int_curr_symbol);
+ ret.currency_symbol =
+ __UNCONST(_CurrentMonetaryLocale->currency_symbol);
+ ret.mon_decimal_point =
+ __UNCONST(_CurrentMonetaryLocale->mon_decimal_point);
+ ret.mon_thousands_sep =
+ __UNCONST(_CurrentMonetaryLocale->mon_thousands_sep);
+ ret.mon_grouping =
+ __UNCONST(_CurrentMonetaryLocale->mon_grouping);
+ ret.positive_sign =
+ __UNCONST(_CurrentMonetaryLocale->positive_sign);
+ ret.negative_sign =
+ __UNCONST(_CurrentMonetaryLocale->negative_sign);
+ ret.int_frac_digits = _CurrentMonetaryLocale->int_frac_digits;
+ ret.frac_digits = _CurrentMonetaryLocale->frac_digits;
+ ret.p_cs_precedes = _CurrentMonetaryLocale->p_cs_precedes;
+ ret.p_sep_by_space = _CurrentMonetaryLocale->p_sep_by_space;
+ ret.n_cs_precedes = _CurrentMonetaryLocale->n_cs_precedes;
+ ret.n_sep_by_space = _CurrentMonetaryLocale->n_sep_by_space;
+ ret.p_sign_posn = _CurrentMonetaryLocale->p_sign_posn;
+ ret.n_sign_posn = _CurrentMonetaryLocale->n_sign_posn;
+ ret.int_p_cs_precedes =
+ _CurrentMonetaryLocale->int_p_cs_precedes;
+ ret.int_n_cs_precedes =
+ _CurrentMonetaryLocale->int_n_cs_precedes;
+ ret.int_p_sep_by_space =
+ _CurrentMonetaryLocale->int_p_sep_by_space;
+ ret.int_n_sep_by_space =
+ _CurrentMonetaryLocale->int_n_sep_by_space;
+ ret.int_p_sign_posn = _CurrentMonetaryLocale->int_p_sign_posn;
+ ret.int_n_sign_posn = _CurrentMonetaryLocale->int_n_sign_posn;
+ __mlocale_changed = 0;
+ }
+
+ if (__nlocale_changed) {
+ /* LC_NUMERIC */
+ ret.decimal_point =
+ __UNCONST(_CurrentNumericLocale->decimal_point);
+ ret.thousands_sep =
+ __UNCONST(_CurrentNumericLocale->thousands_sep);
+ ret.grouping =
+ __UNCONST(_CurrentNumericLocale->grouping);
+ __nlocale_changed = 0;
+ }
+
+ return (&ret);
+}
diff --git a/StdLib/LibC/Locale/multibyte_sb.c b/StdLib/LibC/Locale/multibyte_sb.c
new file mode 100644
index 0000000000..6d57cd6c09
--- /dev/null
+++ b/StdLib/LibC/Locale/multibyte_sb.c
@@ -0,0 +1,272 @@
+/* $NetBSD: multibyte_sb.c,v 1.5 2004/07/21 20:27:46 tshiozak Exp $ */
+
+/*
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char *sccsid = "from: @(#)multibyte.c 5.1 (Berkeley) 2/18/91";
+#else
+__RCSID("$NetBSD: multibyte_sb.c,v 1.5 2004/07/21 20:27:46 tshiozak Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <wchar.h>
+
+/*
+ * Stub multibyte character functions.
+ * This cheezy implementation is fixed to the native single-byte
+ * character set.
+ */
+
+/*ARGSUSED*/
+int
+mbsinit(const mbstate_t *ps)
+{
+
+ return 1;
+}
+
+/*ARGSUSED*/
+size_t
+mbrlen(
+ const char *s,
+ size_t n,
+ mbstate_t *ps
+ )
+{
+
+ /* ps appears to be unused */
+
+ if (s == NULL || *s == '\0')
+ return 0;
+ if (n == 0)
+ return (size_t)-1;
+ return 1;
+}
+
+int
+mblen(
+ const char *s,
+ size_t n
+ )
+{
+
+ /* s may be NULL */
+
+ return (int)mbrlen(s, n, NULL);
+}
+
+/*ARGSUSED*/
+size_t
+mbrtowc(
+ wchar_t *pwc,
+ const char *s,
+ size_t n,
+ mbstate_t *ps
+ )
+{
+
+ /* pwc may be NULL */
+ /* s may be NULL */
+ /* ps appears to be unused */
+
+ if (s == NULL)
+ return 0;
+ if (n == 0)
+ return (size_t)-1;
+ if (pwc)
+ *pwc = (wchar_t) *s;
+ return (*s != '\0');
+}
+
+int
+mbtowc(
+ wchar_t *pwc,
+ const char *s,
+ size_t n
+ )
+{
+
+ /* pwc may be NULL */
+ /* s may be NULL */
+
+ return (int)mbrtowc(pwc, s, n, NULL);
+}
+
+/*ARGSUSED*/
+size_t
+wcrtomb(
+ char *s,
+ wchar_t wchar,
+ mbstate_t *ps
+ )
+{
+
+ /* s may be NULL */
+ /* ps appears to be unused */
+
+ if (s == NULL)
+ return 0;
+
+ *s = (char) wchar;
+ return 1;
+}
+
+int
+wctomb(
+ char *s,
+ wchar_t wchar
+ )
+{
+
+ /* s may be NULL */
+
+ return (int)wcrtomb(s, wchar, NULL);
+}
+
+/*ARGSUSED*/
+size_t
+mbsrtowcs(
+ wchar_t *pwcs,
+ const char **s,
+ size_t n,
+ mbstate_t *ps
+ )
+{
+ int count = 0;
+
+ /* pwcs may be NULL */
+ /* s may be NULL */
+ /* ps appears to be unused */
+
+ if (!s || !*s)
+ return 0;
+
+ if (n != 0) {
+ if (pwcs != NULL) {
+ do {
+ if ((*pwcs++ = (wchar_t) *(*s)++) == 0)
+ break;
+ count++;
+ } while (--n != 0);
+ } else {
+ do {
+ if (((wchar_t)*(*s)++) == 0)
+ break;
+ count++;
+ } while (--n != 0);
+ }
+ }
+
+ return count;
+}
+
+size_t
+mbstowcs(
+ wchar_t *pwcs,
+ const char *s,
+ size_t n
+ )
+{
+
+ /* pwcs may be NULL */
+ /* s may be NULL */
+
+ return mbsrtowcs(pwcs, &s, n, NULL);
+}
+
+/*ARGSUSED*/
+size_t
+wcsrtombs(
+ char *s,
+ const wchar_t **pwcs,
+ size_t n,
+ mbstate_t *ps
+ )
+{
+ int count = 0;
+
+ /* s may be NULL */
+ /* pwcs may be NULL */
+ /* ps appears to be unused */
+
+ if (pwcs == NULL || *pwcs == NULL)
+ return (0);
+
+ if (s == NULL) {
+ while (*(*pwcs)++ != 0)
+ count++;
+ return(count);
+ }
+
+ if (n != 0) {
+ do {
+ if ((*s++ = (char) *(*pwcs)++) == 0)
+ break;
+ count++;
+ } while (--n != 0);
+ }
+
+ return count;
+}
+
+size_t
+wcstombs(
+ char *s,
+ const wchar_t *pwcs,
+ size_t n
+ )
+{
+
+ /* s may be NULL */
+ /* pwcs may be NULL */
+
+ return wcsrtombs(s, &pwcs, n, NULL);
+}
+
+wint_t
+btowc(int c)
+{
+ if (c == EOF || c & ~0xFF)
+ return WEOF;
+ return (wint_t)c;
+}
+
+int
+wctob(wint_t c)
+{
+ if (c == WEOF || c & ~0xFF)
+ return EOF;
+ return (int)c;
+}
diff --git a/StdLib/LibC/Locale/nl_langinfo.c b/StdLib/LibC/Locale/nl_langinfo.c
new file mode 100644
index 0000000000..cd283df380
--- /dev/null
+++ b/StdLib/LibC/Locale/nl_langinfo.c
@@ -0,0 +1,125 @@
+/* $NetBSD: nl_langinfo.c,v 1.11 2005/11/29 03:11:59 christos Exp $ */
+
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: nl_langinfo.c,v 1.11 2005/11/29 03:11:59 christos Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/localedef.h>
+#include <locale.h>
+#include <nl_types.h>
+#include <langinfo.h>
+#include "rune.h"
+#include "runetype.h"
+
+char *
+nl_langinfo(nl_item item)
+{
+ const char *s;
+
+ switch (item) {
+ case D_T_FMT:
+ s = _CurrentTimeLocale->d_t_fmt;
+ break;
+ case D_FMT:
+ s = _CurrentTimeLocale->d_fmt;
+ break;
+ case T_FMT:
+ s = _CurrentTimeLocale->t_fmt;
+ break;
+ case T_FMT_AMPM:
+ s = _CurrentTimeLocale->t_fmt_ampm;
+ break;
+ case AM_STR:
+ case PM_STR:
+ s = _CurrentTimeLocale->am_pm[(size_t)(item - AM_STR)];
+ break;
+ case DAY_1:
+ case DAY_2:
+ case DAY_3:
+ case DAY_4:
+ case DAY_5:
+ case DAY_6:
+ case DAY_7:
+ s = _CurrentTimeLocale->day[(size_t)(item - DAY_1)];
+ break;
+ case ABDAY_1:
+ case ABDAY_2:
+ case ABDAY_3:
+ case ABDAY_4:
+ case ABDAY_5:
+ case ABDAY_6:
+ case ABDAY_7:
+ s = _CurrentTimeLocale->abday[(size_t)(item - ABDAY_1)];
+ break;
+ case MON_1:
+ case MON_2:
+ case MON_3:
+ case MON_4:
+ case MON_5:
+ case MON_6:
+ case MON_7:
+ case MON_8:
+ case MON_9:
+ case MON_10:
+ case MON_11:
+ case MON_12:
+ s = _CurrentTimeLocale->mon[(size_t)(item - MON_1)];
+ break;
+ case ABMON_1:
+ case ABMON_2:
+ case ABMON_3:
+ case ABMON_4:
+ case ABMON_5:
+ case ABMON_6:
+ case ABMON_7:
+ case ABMON_8:
+ case ABMON_9:
+ case ABMON_10:
+ case ABMON_11:
+ case ABMON_12:
+ s = _CurrentTimeLocale->abmon[(size_t)(item - ABMON_1)];
+ break;
+ case RADIXCHAR:
+ s = _CurrentNumericLocale->decimal_point;
+ break;
+ case THOUSEP:
+ s = _CurrentNumericLocale->thousands_sep;
+ break;
+ case YESSTR:
+ s = _CurrentMessagesLocale->yesstr;
+ break;
+ case YESEXPR:
+ s = _CurrentMessagesLocale->yesexpr;
+ break;
+ case NOSTR:
+ s = _CurrentMessagesLocale->nostr;
+ break;
+ case NOEXPR:
+ s = _CurrentMessagesLocale->noexpr;
+ break;
+ case CRNCYSTR: /* XXX */
+ s = "";
+ break;
+ case CODESET:
+#ifdef WITH_RUNE
+ s = _CurrentRuneLocale->rl_codeset;
+#else
+ s = NULL;
+#endif
+ if (!s)
+ s = "";
+ break;
+ default:
+ s = "";
+ break;
+ }
+
+ /* The return value should be really const, but the interface says OW */
+ return __UNCONST(s);
+}
diff --git a/StdLib/LibC/Locale/rune.h b/StdLib/LibC/Locale/rune.h
new file mode 100644
index 0000000000..93829e56ea
--- /dev/null
+++ b/StdLib/LibC/Locale/rune.h
@@ -0,0 +1,100 @@
+/* $NetBSD: rune.h,v 1.11 2006/02/16 19:19:49 tnozaki Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)rune.h 8.1 (Berkeley) 6/27/93
+ */
+#ifndef _RUNE_H_
+#define _RUNE_H_
+
+#include <LibConfig.h>
+
+#include <stdio.h>
+#include <wchar.h>
+#include "runetype.h"
+
+/*
+ * map _RTYPE_x to _CTYPE_x
+ *
+ * XXX: these should be defined in ctype.h and used in isxxx macros.
+ * (note: current isxxx macros use "old" NetBSD masks and
+ * _CTYPE_x are not public.)
+ */
+#define _CTYPE_A _RUNETYPE_A
+#define _CTYPE_C _RUNETYPE_C
+#define _CTYPE_D _RUNETYPE_D
+#define _CTYPE_G _RUNETYPE_G
+#define _CTYPE_L _RUNETYPE_L
+#define _CTYPE_P _RUNETYPE_P
+#define _CTYPE_S _RUNETYPE_S
+#define _CTYPE_U _RUNETYPE_U
+#define _CTYPE_X _RUNETYPE_X
+#define _CTYPE_B _RUNETYPE_B
+#define _CTYPE_R _RUNETYPE_R
+#define _CTYPE_I _RUNETYPE_I
+#define _CTYPE_T _RUNETYPE_T
+#define _CTYPE_Q _RUNETYPE_Q
+#define _CTYPE_SWM _RUNETYPE_SWM
+#define _CTYPE_SWS _RUNETYPE_SWS
+#define _CTYPE_SW0 _RUNETYPE_SW0
+#define _CTYPE_SW1 _RUNETYPE_SW1
+#define _CTYPE_SW2 _RUNETYPE_SW2
+#define _CTYPE_SW3 _RUNETYPE_SW3
+
+/*
+ * Other namespace conversion.
+ */
+
+#define rune_t __nbrune_t
+#define _RUNE_ISCACHED _NB_RUNE_ISCACHED
+#define _CACHED_RUNES _NB_CACHED_RUNES
+#define _DEFAULT_INVALID_RUNE _NB_DEFAULT_INVALID_RUNE
+#define _RuneEntry _NBRuneEntry
+#define _RuneRange _NBRuneRange
+#define _RuneLocale _NBRuneLocale
+#define _RUNE_MAGIC_1 _NB_RUNE_MAGIC_1
+#define _RUNE_MODULE_1 _NB_RUNE_MODULE_1
+#define _RUNE_CODESET _NB_RUNE_CODESET
+
+/*
+ * global variables
+ */
+extern size_t __mb_len_max_runtime;
+#define __MB_LEN_MAX_RUNTIME __mb_len_max_runtime
+
+extern _RuneLocale _DefaultRuneLocale;
+extern _RuneLocale *_CurrentRuneLocale;
+extern const char *_PathLocale;
+
+#define _LOCALE_ALIAS_NAME "locale.alias"
+
+#endif /*! _RUNE_H_ */
diff --git a/StdLib/LibC/Locale/runetype.h b/StdLib/LibC/Locale/runetype.h
new file mode 100644
index 0000000000..2cd563e103
--- /dev/null
+++ b/StdLib/LibC/Locale/runetype.h
@@ -0,0 +1,221 @@
+/* $NetBSD: runetype.h,v 1.19 2005/11/29 03:11:59 christos Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)runetype.h 8.1 (Berkeley) 6/2/93
+ */
+#ifndef _NB_RUNETYPE_H_
+#define _NB_RUNETYPE_H_
+
+#include <sys/EfiCdefs.h>
+#include <sys/types.h>
+
+/* for cross host tools on older systems */
+#ifndef UINT32_C
+/* assumes sizeof(unsigned int)>=4 */
+#define UINT32_C(c) ((uint32_t)(c##U))
+#endif
+
+typedef uint32_t __nbrune_t;
+typedef uint64_t __runepad_t;
+
+#define _NB_CACHED_RUNES (1 << 8) /* Must be a power of 2 */
+#define _NB_RUNE_ISCACHED(c) ((c)>=0 && (c)<_CACHED_RUNES)
+
+#define _NB_DEFAULT_INVALID_RUNE ((__nbrune_t)-3)
+
+/*
+ * The lower 8 bits of runetype[] contain the digit value of the rune.
+ */
+typedef uint32_t _RuneType;
+#define _RUNETYPE_A UINT32_C(0x00000100) /* Alpha */
+#define _RUNETYPE_C UINT32_C(0x00000200) /* Control */
+#define _RUNETYPE_D UINT32_C(0x00000400) /* Digit */
+#define _RUNETYPE_G UINT32_C(0x00000800) /* Graph */
+#define _RUNETYPE_L UINT32_C(0x00001000) /* Lower */
+#define _RUNETYPE_P UINT32_C(0x00002000) /* Punct */
+#define _RUNETYPE_S UINT32_C(0x00004000) /* Space */
+#define _RUNETYPE_U UINT32_C(0x00008000) /* Upper */
+#define _RUNETYPE_X UINT32_C(0x00010000) /* X digit */
+#define _RUNETYPE_B UINT32_C(0x00020000) /* Blank */
+#define _RUNETYPE_R UINT32_C(0x00040000) /* Print */
+#define _RUNETYPE_I UINT32_C(0x00080000) /* Ideogram */
+#define _RUNETYPE_T UINT32_C(0x00100000) /* Special */
+#define _RUNETYPE_Q UINT32_C(0x00200000) /* Phonogram */
+#define _RUNETYPE_SWM UINT32_C(0xc0000000)/* Mask to get screen width data */
+#define _RUNETYPE_SWS 30 /* Bits to shift to get width */
+#define _RUNETYPE_SW0 UINT32_C(0x00000000) /* 0 width character */
+#define _RUNETYPE_SW1 UINT32_C(0x40000000) /* 1 width character */
+#define _RUNETYPE_SW2 UINT32_C(0x80000000) /* 2 width character */
+#define _RUNETYPE_SW3 UINT32_C(0xc0000000) /* 3 width character */
+
+
+/*
+ * rune file format. network endian.
+ */
+typedef struct {
+ int32_t fre_min; /* First rune of the range */
+ int32_t fre_max; /* Last rune (inclusive) of the range */
+ int32_t fre_map; /* What first maps to in maps */
+ uint32_t fre_pad1; /* backward compatibility */
+ __runepad_t fre_pad2; /* backward compatibility */
+} __attribute__((__packed__)) _FileRuneEntry;
+
+
+typedef struct {
+ uint32_t frr_nranges; /* Number of ranges stored */
+ uint32_t frr_pad1; /* backward compatibility */
+ __runepad_t frr_pad2; /* backward compatibility */
+} __attribute__((__packed__)) _FileRuneRange;
+
+
+typedef struct {
+ char frl_magic[8]; /* Magic saying what version we are */
+ char frl_encoding[32];/* ASCII name of this encoding */
+
+ __runepad_t frl_pad1; /* backward compatibility */
+ __runepad_t frl_pad2; /* backward compatibility */
+ int32_t frl_invalid_rune;
+ uint32_t frl_pad3; /* backward compatibility */
+
+ _RuneType frl_runetype[_NB_CACHED_RUNES];
+ int32_t frl_maplower[_NB_CACHED_RUNES];
+ int32_t frl_mapupper[_NB_CACHED_RUNES];
+
+ /*
+ * The following are to deal with Runes larger than _CACHED_RUNES - 1.
+ * Their data is actually contiguous with this structure so as to make
+ * it easier to read/write from/to disk.
+ */
+ _FileRuneRange frl_runetype_ext;
+ _FileRuneRange frl_maplower_ext;
+ _FileRuneRange frl_mapupper_ext;
+
+ __runepad_t frl_pad4; /* backward compatibility */
+ int32_t frl_variable_len;/* how long that data is */
+ uint32_t frl_pad5; /* backward compatibility */
+
+ /* variable size data follows */
+} __attribute__((__packed__)) _FileRuneLocale;
+
+
+/*
+ * expanded rune locale declaration. local to the host. host endian.
+ */
+typedef struct {
+ __nbrune_t re_min; /* First rune of the range */
+ __nbrune_t re_max; /* Last rune (inclusive) of the range */
+ __nbrune_t re_map; /* What first maps to in maps */
+ _RuneType *re_rune_types; /* Array of types in range */
+} _NBRuneEntry;
+
+
+typedef struct {
+ uint32_t rr_nranges; /* Number of ranges stored */
+ _NBRuneEntry *rr_rune_ranges;
+} _NBRuneRange;
+
+
+/*
+ * wctrans stuffs.
+ */
+typedef struct _WCTransEntry {
+ const char *te_name;
+ __nbrune_t *te_cached;
+ _NBRuneRange *te_extmap;
+} _WCTransEntry;
+#define _WCTRANS_INDEX_LOWER 0
+#define _WCTRANS_INDEX_UPPER 1
+#define _WCTRANS_NINDEXES 2
+
+/*
+ * wctype stuffs.
+ */
+typedef struct _WCTypeEntry {
+ const char *te_name;
+ _RuneType te_mask;
+} _WCTypeEntry;
+#define _WCTYPE_INDEX_ALNUM 0
+#define _WCTYPE_INDEX_ALPHA 1
+#define _WCTYPE_INDEX_BLANK 2
+#define _WCTYPE_INDEX_CNTRL 3
+#define _WCTYPE_INDEX_DIGIT 4
+#define _WCTYPE_INDEX_GRAPH 5
+#define _WCTYPE_INDEX_LOWER 6
+#define _WCTYPE_INDEX_PRINT 7
+#define _WCTYPE_INDEX_PUNCT 8
+#define _WCTYPE_INDEX_SPACE 9
+#define _WCTYPE_INDEX_UPPER 10
+#define _WCTYPE_INDEX_XDIGIT 11
+#define _WCTYPE_NINDEXES 12
+
+/*
+ * ctype stuffs
+ */
+
+typedef struct _NBRuneLocale {
+ /*
+ * copied from _FileRuneLocale
+ */
+ char rl_magic[8]; /* Magic saying what version we are */
+ char rl_encoding[32];/* ASCII name of this encoding */
+ __nbrune_t rl_invalid_rune;
+ _RuneType rl_runetype[_NB_CACHED_RUNES];
+ __nbrune_t rl_maplower[_NB_CACHED_RUNES];
+ __nbrune_t rl_mapupper[_NB_CACHED_RUNES];
+ _NBRuneRange rl_runetype_ext;
+ _NBRuneRange rl_maplower_ext;
+ _NBRuneRange rl_mapupper_ext;
+
+ void *rl_variable;
+ size_t rl_variable_len;
+
+ /*
+ * the following portion is generated on the fly
+ */
+ const char *rl_codeset;
+ struct _citrus_ctype_rec *rl_citrus_ctype;
+ _WCTransEntry rl_wctrans[_WCTRANS_NINDEXES];
+ _WCTypeEntry rl_wctype[_WCTYPE_NINDEXES];
+} _NBRuneLocale;
+
+
+/* magic number for LC_CTYPE (rune)locale declaration */
+#define _NB_RUNE_MAGIC_1 "RuneCT10" /* Indicates version 0 of RuneLocale */
+
+/* magic string for dynamic link module - type should be like "LC_CTYPE" */
+#define _NB_RUNE_MODULE_1(type) "RuneModule10." type
+
+/* codeset tag */
+#define _NB_RUNE_CODESET "CODESET="
+
+#endif /* !_NB_RUNETYPE_H_ */
diff --git a/StdLib/LibC/Locale/setlocale.c b/StdLib/LibC/Locale/setlocale.c
new file mode 100644
index 0000000000..b6090d2ea0
--- /dev/null
+++ b/StdLib/LibC/Locale/setlocale.c
@@ -0,0 +1,423 @@
+/* $NetBSD: setlocale.c,v 1.50 2006/02/16 19:19:49 tnozaki Exp $ */
+
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+ #if 0
+ static char sccsid[] = "@(#)setlocale.c 8.1 (Berkeley) 7/4/93";
+ #else
+ __RCSID("$NetBSD: setlocale.c,v 1.50 2006/02/16 19:19:49 tnozaki Exp $");
+ #endif
+#endif /* LIBC_SCCS and not lint */
+
+#if defined(_MSC_VER)
+ // Disable warnings about assignment within conditional expressions.
+ #pragma warning ( disable : 4706 )
+#endif
+
+#define _CTYPE_PRIVATE
+
+#include "namespace.h"
+#include <sys/localedef.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <assert.h>
+#include <limits.h>
+#include <ctype.h>
+#define __SETLOCALE_SOURCE__
+#include <locale.h>
+#include <paths.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/EfiSysCall.h>
+#include "rune.h"
+#ifdef WITH_RUNE
+ #include "rune_local.h"
+#else
+ #include "ctypeio.h"
+#endif
+
+#ifdef CITRUS
+ #include <citrus/citrus_namespace.h>
+ #include <citrus/citrus_region.h>
+ #include <citrus/citrus_lookup.h>
+ #include <citrus/citrus_bcs.h>
+#else
+ #include "aliasname_local.h"
+ #define _lookup_alias(p, a, b, s, c) __unaliasname((p), (a), (b), (s))
+ #define _bcs_strcasecmp(a, b) strcasecmp((a), (b))
+#endif
+
+#define _LOCALE_SYM_FORCE "/force"
+
+#ifndef WITH_RUNE
+ const char *_PathLocale = NULL;
+#endif
+
+/*
+ * Category names for getenv()
+ */
+static const char *const categories[_LC_LAST] = {
+ "LC_ALL",
+ "LC_COLLATE",
+ "LC_CTYPE",
+ "LC_MONETARY",
+ "LC_NUMERIC",
+ "LC_TIME",
+ "LC_MESSAGES"
+};
+
+/*
+ * Current locales for each category
+ */
+static char current_categories[_LC_LAST][32] = {
+ "C",
+ "C",
+ "C",
+ "C",
+ "C",
+ "C",
+ "C"
+};
+
+/*
+ * The locales we are going to try and load
+ */
+static char new_categories[_LC_LAST][32];
+
+static char current_locale_string[_LC_LAST * 33];
+
+static char *currentlocale(void);
+static void revert_to_default(int);
+static int force_locale_enable(int);
+static int load_locale_sub(int, const char *, int);
+static char *loadlocale(int);
+static const char *__get_locale_env(int);
+
+char *
+__setlocale(int category, const char *locale)
+{
+ int i, loadlocale_success;
+ size_t len;
+ const char *env, *r;
+
+ //if (issetugid() ||
+ // (!_PathLocale && !(_PathLocale = getenv("PATH_LOCALE"))))
+ // _PathLocale = _PATH_LOCALE;
+
+ if (category < 0 || category >= _LC_LAST)
+ return (NULL);
+
+ if (!locale)
+ return (category ?
+ current_categories[category] : currentlocale());
+
+ /*
+ * Default to the current locale for everything.
+ */
+ for (i = 1; i < _LC_LAST; ++i)
+ (void)strncpyX(new_categories[i], current_categories[i],
+ sizeof(new_categories[i]));
+
+ /*
+ * Now go fill up new_categories from the locale argument
+ */
+ if (!*locale) {
+ if (category == LC_ALL) {
+ for (i = 1; i < _LC_LAST; ++i) {
+ env = __get_locale_env(i);
+ (void)strncpyX(new_categories[i], env,
+ sizeof(new_categories[i]));
+ }
+ }
+ else {
+ env = __get_locale_env(category);
+ (void)strncpyX(new_categories[category], env,
+ sizeof(new_categories[category]));
+ }
+ } else if (category) {
+ (void)strncpyX(new_categories[category], locale,
+ sizeof(new_categories[category]));
+ } else {
+ if ((r = strchr(locale, '/')) == 0) {
+ for (i = 1; i < _LC_LAST; ++i) {
+ (void)strncpyX(new_categories[i], locale,
+ sizeof(new_categories[i]));
+ }
+ } else {
+ for (i = 1;;) {
+ _DIAGASSERT(*r == '/' || *r == 0);
+ _DIAGASSERT(*locale != 0);
+ if (*locale == '/')
+ return (NULL); /* invalid format. */
+ len = r - locale;
+ if (len + 1 > sizeof(new_categories[i]))
+ return (NULL); /* too long */
+ (void)memcpy(new_categories[i], locale, len);
+ new_categories[i][len] = '\0';
+ if (*r == 0)
+ break;
+ _DIAGASSERT(*r == '/');
+ if (*(locale = ++r) == 0)
+ /* slash followed by NUL */
+ return (NULL);
+ /* skip until NUL or '/' */
+ while (*r && *r != '/')
+ r++;
+ if (++i == _LC_LAST)
+ return (NULL); /* too many slashes. */
+ }
+ if (i + 1 != _LC_LAST)
+ return (NULL); /* too few slashes. */
+ }
+ }
+
+ if (category)
+ return (loadlocale(category));
+
+ loadlocale_success = 0;
+ for (i = 1; i < _LC_LAST; ++i) {
+ if (loadlocale(i) != NULL)
+ loadlocale_success = 1;
+ }
+
+ /*
+ * If all categories failed, return NULL; we don't need to back
+ * changes off, since none happened.
+ */
+ if (!loadlocale_success)
+ return NULL;
+
+ return (currentlocale());
+}
+
+static char *
+currentlocale()
+{
+ int i;
+
+ (void)strncpyX(current_locale_string, current_categories[1],
+ sizeof(current_locale_string));
+
+ for (i = 2; i < _LC_LAST; ++i)
+ if (strcmp(current_categories[1], current_categories[i])) {
+ (void)snprintf(current_locale_string,
+ sizeof(current_locale_string), "%s/%s/%s/%s/%s/%s",
+ current_categories[1], current_categories[2],
+ current_categories[3], current_categories[4],
+ current_categories[5], current_categories[6]);
+ break;
+ }
+ return (current_locale_string);
+}
+
+static void
+revert_to_default(int category)
+{
+ switch (category) {
+ case LC_CTYPE:
+#ifdef WITH_RUNE
+ (void)_xpg4_setrunelocale("C");
+ (void)__runetable_to_netbsd_ctype("C");
+#else
+ if (_cClass != _C_CharClassTable) {
+ /* LINTED const castaway */
+ free((void *)_cClass);
+ _cClass = _C_CharClassTable;
+ }
+ if (_uConvT != _C_ToUpperTable) {
+ /* LINTED const castaway */
+ free((void *)_uConvT);
+ _uConvT = _C_ToUpperTable;
+ }
+ if (_lConvT != _C_ToLowerTable) {
+ /* LINTED const castaway */
+ free((void *)_lConvT);
+ _lConvT = _C_ToLowerTable;
+ }
+#endif
+ break;
+ case LC_MESSAGES:
+ case LC_COLLATE:
+ case LC_MONETARY:
+ case LC_NUMERIC:
+ case LC_TIME:
+ break;
+ }
+}
+
+static int
+force_locale_enable(int category)
+{
+ revert_to_default(category);
+
+ return 0;
+}
+
+static int
+load_locale_sub(
+ int category,
+ const char *locname,
+ int isspecial
+ )
+{
+ char name[PATH_MAX];
+
+ /* check for the default locales */
+ if (!strcmp(new_categories[category], "C") ||
+ !strcmp(new_categories[category], "POSIX")) {
+ revert_to_default(category);
+ return 0;
+ }
+
+ /* check whether special symbol */
+ if (isspecial && _bcs_strcasecmp(locname, _LOCALE_SYM_FORCE) == 0)
+ return force_locale_enable(category);
+
+ /* sanity check */
+ if (strchr(locname, '/') != NULL)
+ return -1;
+
+ (void)snprintf(name, sizeof(name), "%s/%s/%s",
+ _PathLocale, locname, categories[category]);
+
+ switch (category) {
+ case LC_CTYPE:
+#ifdef WITH_RUNE
+ if (_xpg4_setrunelocale(__UNCONST(locname)))
+ return -1;
+ if (__runetable_to_netbsd_ctype(locname)) {
+ /* very unfortunate, but need to go to "C" locale */
+ revert_to_default(category);
+ return -1;
+ }
+#else
+ if (!__loadctype(name))
+ return -1;
+#endif
+ break;
+
+ case LC_MESSAGES:
+ /*
+ * XXX we don't have LC_MESSAGES support yet,
+ * but catopen may use the value of LC_MESSAGES category.
+ * so return successfully if locale directory is present.
+ */
+ (void)snprintf(name, sizeof(name), "%s/%s",
+ _PathLocale, locname);
+ /* local */
+ {
+ struct stat st;
+ if (stat(name, &st) < 0)
+ return -1;
+ if (!S_ISDIR(st.st_mode))
+ return -1;
+ }
+ break;
+
+ case LC_COLLATE:
+ case LC_MONETARY:
+ case LC_NUMERIC:
+ case LC_TIME:
+ return -1;
+ }
+
+ return 0;
+}
+
+static char *
+loadlocale(int category)
+{
+ //char aliaspath[PATH_MAX], loccat[PATH_MAX], buf[PATH_MAX];
+ //const char *alias;
+
+ _DIAGASSERT(0 < category && category < _LC_LAST);
+
+ if (strcmp(new_categories[category], current_categories[category]) == 0)
+ return (current_categories[category]);
+
+ /* (1) non-aliased file */
+ if (!load_locale_sub(category, new_categories[category], 0))
+ goto success;
+
+ ///* (2) lookup locname/catname type alias */
+ //(void)snprintf(aliaspath, sizeof(aliaspath),
+ // "%s/" _LOCALE_ALIAS_NAME, _PathLocale);
+ //(void)snprintf(loccat, sizeof(loccat), "%s/%s",
+ // new_categories[category], categories[category]);
+ //alias = _lookup_alias(aliaspath, loccat, buf, sizeof(buf),
+ // _LOOKUP_CASE_SENSITIVE);
+ //if (!load_locale_sub(category, alias, 1))
+ // goto success;
+
+ ///* (3) lookup locname type alias */
+ //alias = _lookup_alias(aliaspath, new_categories[category],
+ // buf, sizeof(buf), _LOOKUP_CASE_SENSITIVE);
+ //if (!load_locale_sub(category, alias, 1))
+ // goto success;
+
+ return NULL;
+
+success:
+ (void)strncpyX(current_categories[category],
+ new_categories[category],
+ sizeof(current_categories[category]));
+ return current_categories[category];
+}
+
+static const char *
+__get_locale_env(int category)
+{
+ const char *env;
+
+ //_DIAGASSERT(category != LC_ALL);
+
+ ///* 1. check LC_ALL. */
+ //env = getenv(categories[0]);
+
+ ///* 2. check LC_* */
+ //if (!env || !*env)
+ // env = getenv(categories[category]);
+
+ ///* 3. check LANG */
+ //if (!env || !*env)
+ // env = getenv("LANG");
+
+ ///* 4. if none is set, fall to "C" */
+ //if (!env || !*env || strchr(env, '/'))
+ env = "C";
+
+ return env;
+}
diff --git a/StdLib/LibC/Locale/setlocale1.c b/StdLib/LibC/Locale/setlocale1.c
new file mode 100644
index 0000000000..b9c30bb40d
--- /dev/null
+++ b/StdLib/LibC/Locale/setlocale1.c
@@ -0,0 +1,53 @@
+/* $NetBSD: setlocale1.c,v 1.2 2003/03/11 17:23:07 tshiozak Exp $ */
+
+/*-
+ * Copyright (c)1999 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: setlocale1.c,v 1.2 2003/03/11 17:23:07 tshiozak Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+#define __SETLOCALE_SOURCE__
+#include <locale.h>
+#include "rune.h"
+
+__warn_references(setlocale,
+ "warning: reference to compatibility setlocale(); include <locale.h> for correct reference")
+
+/*
+ * Preparation for the future import of multibyte locale.
+ * This function will ensure binary compatibility for old executables.
+ */
+char *
+setlocale(int category, const char *locale)
+{
+ /* locale may be NULL */
+
+ __mb_len_max_runtime = 1;
+ return __setlocale(category, locale);
+}
diff --git a/StdLib/LibC/Locale/setlocale32.c b/StdLib/LibC/Locale/setlocale32.c
new file mode 100644
index 0000000000..68c43bba0d
--- /dev/null
+++ b/StdLib/LibC/Locale/setlocale32.c
@@ -0,0 +1,46 @@
+/* $NetBSD: setlocale32.c,v 1.2 2003/03/11 17:23:07 tshiozak Exp $ */
+
+/*-
+ * Copyright (c)1999 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: setlocale32.c,v 1.2 2003/03/11 17:23:07 tshiozak Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+#define __SETLOCALE_SOURCE__
+#include <locale.h>
+#include "rune.h"
+
+char *
+__setlocale_mb_len_max_32(int category, const char *locale)
+{
+ /* locale may be NULL */
+
+ __mb_len_max_runtime = 32;
+ return __setlocale(category, locale);
+}
diff --git a/StdLib/LibC/Locale/wcscoll.c b/StdLib/LibC/Locale/wcscoll.c
new file mode 100644
index 0000000000..5bc72fae1d
--- /dev/null
+++ b/StdLib/LibC/Locale/wcscoll.c
@@ -0,0 +1,47 @@
+/* $NetBSD: wcscoll.c,v 1.1 2003/03/02 22:18:16 tshiozak Exp $ */
+
+/*-
+ * Copyright (c)2003 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: wcscoll.c,v 1.1 2003/03/02 22:18:16 tshiozak Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+
+#include <assert.h>
+#include <wchar.h>
+
+/*
+ * Compare strings with using collating information.
+ */
+int
+wcscoll(const wchar_t *s1, const wchar_t *s2)
+{
+ /* XXX: LC_COLLATE should be implemented. */
+ return (wcscmp(s1, s2));
+}
diff --git a/StdLib/LibC/Locale/wcsftime.c b/StdLib/LibC/Locale/wcsftime.c
new file mode 100644
index 0000000000..2eb19ca5ad
--- /dev/null
+++ b/StdLib/LibC/Locale/wcsftime.c
@@ -0,0 +1,109 @@
+/* $NetBSD: wcsftime.c,v 1.2 2006/10/04 14:19:16 tnozaki Exp $ */
+/*-
+ * Copyright (c) 2002 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+__FBSDID("$FreeBSD: src/lib/libc/locale/wcsftime.c,v 1.4 2004/04/07 09:47:56 tjr Exp $");
+#else
+__RCSID("$NetBSD: wcsftime.c,v 1.2 2006/10/04 14:19:16 tnozaki Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <time.h>
+#include <wchar.h>
+#include <machine/int_limits.h>
+
+/*
+ * Convert date and time to a wide-character string.
+ *
+ * This is the wide-character counterpart of strftime(). So that we do not
+ * have to duplicate the code of strftime(), we convert the format string to
+ * multibyte, call strftime(), then convert the result back into wide
+ * characters.
+ *
+ * This technique loses in the presence of stateful multibyte encoding if any
+ * of the conversions in the format string change conversion state. When
+ * stateful encoding is implemented, we will need to reset the state between
+ * format specifications in the format string.
+ */
+size_t
+wcsftime(wchar_t *wcs, size_t maxsize,
+ const wchar_t *format, const struct tm *timeptr)
+{
+ char *dst, *dstp, *sformat;
+ size_t n, sflen;
+ int sverrno;
+
+ sformat = dst = NULL;
+
+ /*
+ * Convert the supplied format string to a multibyte representation
+ * for strftime(), which only handles single-byte characters.
+ */
+ sflen = wcstombs(NULL, format, 0);
+ if (sflen == (size_t)-1)
+ goto error;
+ if ((sformat = malloc(sflen + 1)) == NULL)
+ goto error;
+ wcstombs(sformat, format, sflen + 1);
+
+ /*
+ * Allocate memory for longest multibyte sequence that will fit
+ * into the caller's buffer and call strftime() to fill it.
+ * Then, copy and convert the result back into wide characters in
+ * the caller's buffer.
+ */
+ if (SIZE_T_MAX / MB_CUR_MAX <= maxsize) {
+ /* maxsize is preposturously large - avoid int. overflow. */
+ errno = EINVAL;
+ goto error;
+ }
+ dst = malloc(maxsize * MB_CUR_MAX);
+ if (dst == NULL)
+ goto error;
+ if (strftime(dst, maxsize, sformat, timeptr) == 0)
+ goto error;
+ dstp = dst;
+ n = mbstowcs(wcs, dstp, maxsize);
+ if (n == (size_t)-2 || n == (size_t)-1)
+ goto error;
+
+ free(sformat);
+ free(dst);
+ return n;
+
+error:
+ sverrno = errno;
+ free(sformat);
+ free(dst);
+ errno = sverrno;
+ return 0;
+}
diff --git a/StdLib/LibC/Locale/wcstod.c b/StdLib/LibC/Locale/wcstod.c
new file mode 100644
index 0000000000..0ee06bd86f
--- /dev/null
+++ b/StdLib/LibC/Locale/wcstod.c
@@ -0,0 +1,51 @@
+/* $NetBSD: wcstod.c,v 1.12 2006/04/16 17:03:32 christos Exp $ */
+
+/*-
+ * Copyright (c)2006 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: wcstod.c,v 1.12 2006/04/16 17:03:32 christos Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <assert.h>
+#include <errno.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <wctype.h>
+
+//#ifdef __weak_alias
+//__strong_alias(_wcstod,wcstod)
+//__weak_alias(wcstod,_wcstod)
+//#endif
+
+#define _FUNCNAME wcstod
+#define _RETURN_TYPE double
+#define _STRTOD_FUNC strtod
+
+#include "_wcstod.h"
diff --git a/StdLib/LibC/Locale/wcstof.c b/StdLib/LibC/Locale/wcstof.c
new file mode 100644
index 0000000000..36b06a566d
--- /dev/null
+++ b/StdLib/LibC/Locale/wcstof.c
@@ -0,0 +1,53 @@
+/* $NetBSD: wcstof.c,v 1.2 2006/04/16 17:03:32 christos Exp $ */
+
+/*-
+ * Copyright (c)2006 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: wcstof.c,v 1.2 2006/04/16 17:03:32 christos Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <wctype.h>
+
+#ifdef __weak_alias
+__strong_alias(_wcstof,wcstof)
+__weak_alias(wcstof,_wcstof)
+#endif
+
+#define _FUNCNAME wcstof
+#define _RETURN_TYPE float
+#define _STRTOD_FUNC strtof
+
+#include "_wcstod.h"
diff --git a/StdLib/LibC/Locale/wcstoimax.c b/StdLib/LibC/Locale/wcstoimax.c
new file mode 100644
index 0000000000..078b10b764
--- /dev/null
+++ b/StdLib/LibC/Locale/wcstoimax.c
@@ -0,0 +1,59 @@
+/** @file
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c)2003 Citrus Project,
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ NetBSD: wcstoimax.c,v 1.2 2004/06/21 21:20:43 itojun Exp
+**/
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: wcstoimax.c,v 1.2 2004/06/21 21:20:43 itojun Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <wctype.h>
+
+#include "__wctoint.h"
+
+#define _FUNCNAME wcstoimax
+#define __wINT intmax_t
+#define __wINT_MIN INTMAX_MIN
+#define __wINT_MAX INTMAX_MAX
+
+#include "_wcstol.h"
diff --git a/StdLib/LibC/Locale/wcstol.c b/StdLib/LibC/Locale/wcstol.c
new file mode 100644
index 0000000000..f7d92ae077
--- /dev/null
+++ b/StdLib/LibC/Locale/wcstol.c
@@ -0,0 +1,58 @@
+/** @file
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c)2003 Citrus Project,
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ NetBSD: wcstol.c,v 1.3 2004/06/21 21:20:43 itojun Exp
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: wcstol.c,v 1.3 2004/06/21 21:20:43 itojun Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <wctype.h>
+
+#include "__wctoint.h"
+
+#define _FUNCNAME wcstol
+#define __wINT long int
+#define __wINT_MIN LONG_MIN
+#define __wINT_MAX LONG_MAX
+
+#include "_wcstol.h"
diff --git a/StdLib/LibC/Locale/wcstold.c b/StdLib/LibC/Locale/wcstold.c
new file mode 100644
index 0000000000..4e557be13f
--- /dev/null
+++ b/StdLib/LibC/Locale/wcstold.c
@@ -0,0 +1,53 @@
+/* $NetBSD: wcstold.c,v 1.2 2006/04/16 17:03:32 christos Exp $ */
+
+/*-
+ * Copyright (c)2006 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: wcstold.c,v 1.2 2006/04/16 17:03:32 christos Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <wctype.h>
+
+#ifdef __weak_alias
+__strong_alias(_wcstold,wcstold)
+__weak_alias(wcstold,_wcstold)
+#endif
+
+#define _FUNCNAME wcstold
+#define _RETURN_TYPE long double
+#define _STRTOD_FUNC strtold
+
+#include "_wcstod.h"
diff --git a/StdLib/LibC/Locale/wcstoll.c b/StdLib/LibC/Locale/wcstoll.c
new file mode 100644
index 0000000000..ea0e646c19
--- /dev/null
+++ b/StdLib/LibC/Locale/wcstoll.c
@@ -0,0 +1,58 @@
+/** @file
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c)2003 Citrus Project,
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ NetBSD: wcstoll.c,v 1.2 2004/06/21 21:20:43 itojun Exp
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: wcstoll.c,v 1.2 2004/06/21 21:20:43 itojun Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <wctype.h>
+
+#include "__wctoint.h"
+
+#define _FUNCNAME wcstoll
+#define __wINT /* LONGLONG */ long long int
+#define __wINT_MIN LLONG_MIN
+#define __wINT_MAX LLONG_MAX
+
+#include "_wcstol.h"
diff --git a/StdLib/LibC/Locale/wcstoul.c b/StdLib/LibC/Locale/wcstoul.c
new file mode 100644
index 0000000000..fd7059fdb5
--- /dev/null
+++ b/StdLib/LibC/Locale/wcstoul.c
@@ -0,0 +1,58 @@
+/** @file
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c)2003 Citrus Project,
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ NetBSD: wcstoul.c,v 1.3 2004/06/21 21:20:43 itojun Exp
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: wcstoul.c,v 1.3 2004/06/21 21:20:43 itojun Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <wctype.h>
+
+#include "__wctoint.h"
+
+#define _FUNCNAME wcstoul
+#define __wINT long int
+#define __wUINT unsigned long int
+#define __wUINT_MAX ULONG_MAX
+
+#include "_wcstoul.h"
diff --git a/StdLib/LibC/Locale/wcstoull.c b/StdLib/LibC/Locale/wcstoull.c
new file mode 100644
index 0000000000..f257104b2c
--- /dev/null
+++ b/StdLib/LibC/Locale/wcstoull.c
@@ -0,0 +1,58 @@
+/** @file
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c)2003 Citrus Project,
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ NetBSD: wcstoull.c,v 1.2 2004/06/21 21:20:43 itojun Exp
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: wcstoull.c,v 1.2 2004/06/21 21:20:43 itojun Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <wctype.h>
+
+#include "__wctoint.h"
+
+#define _FUNCNAME wcstoull
+#define __wINT long long int
+#define __wUINT /* LONGLONG */ unsigned long long int
+#define __wUINT_MAX ULLONG_MAX
+
+#include "_wcstoul.h"
diff --git a/StdLib/LibC/Locale/wcstoumax.c b/StdLib/LibC/Locale/wcstoumax.c
new file mode 100644
index 0000000000..53a0de0f9e
--- /dev/null
+++ b/StdLib/LibC/Locale/wcstoumax.c
@@ -0,0 +1,59 @@
+/** @file
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c)2003 Citrus Project,
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ NetBSD: wcstoumax.c,v 1.2 2004/06/21 21:20:43 itojun Exp
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: wcstoumax.c,v 1.2 2004/06/21 21:20:43 itojun Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <wctype.h>
+
+#include "__wctoint.h"
+
+#define _FUNCNAME wcstoumax
+#define __wINT intmax_t
+#define __wUINT uintmax_t
+#define __wUINT_MAX UINTMAX_MAX
+
+#include "_wcstoul.h"
diff --git a/StdLib/LibC/Locale/wcsxfrm.c b/StdLib/LibC/Locale/wcsxfrm.c
new file mode 100644
index 0000000000..288a5f9a46
--- /dev/null
+++ b/StdLib/LibC/Locale/wcsxfrm.c
@@ -0,0 +1,66 @@
+/* $NetBSD: wcsxfrm.c,v 1.2 2006/10/15 16:14:08 christos Exp $ */
+
+/*-
+ * Copyright (c)2003 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: wcsxfrm.c,v 1.2 2006/10/15 16:14:08 christos Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+
+#include <assert.h>
+#include <wchar.h>
+
+/*
+ * Compare strings with using collating information.
+ */
+size_t
+wcsxfrm(
+ wchar_t *s1,
+ const wchar_t *s2,
+ size_t n
+ )
+{
+ size_t len;
+
+ /* XXX: LC_COLLATE should be implemented. */
+
+ len = wcslen(s2);
+ if (len<n)
+ wcscpy(s1, s2);
+ else {
+ /*
+ * SUSv3 says:
+ * If the value returned is n or more, the contents
+ * of the array pointed to by ws1 are unspecified.
+ */
+ /* thus, do nothing */
+ }
+
+ return (len);
+}
diff --git a/StdLib/LibC/Main/Arm/flt_rounds.c b/StdLib/LibC/Main/Arm/flt_rounds.c
new file mode 100644
index 0000000000..3f43650270
--- /dev/null
+++ b/StdLib/LibC/Main/Arm/flt_rounds.c
@@ -0,0 +1,81 @@
+/* $NetBSD: flt_rounds.c,v 1.3 2006/02/25 00:58:35 wiz Exp $ */
+
+/*
+ * Copyright (c) 1996 Mark Brinicombe
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Mark Brinicombe
+ * for the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: flt_rounds.c,v 1.3 2006/02/25 00:58:35 wiz Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <ieeefp.h>
+
+static const int map[] = {
+ 1, /* round to nearest */
+ 2, /* round to positive infinity */
+ 3, /* round to negative infinity */
+ 0 /* round to zero */
+};
+
+/*
+ * Return the current FP rounding mode
+ *
+ * Returns:
+ * 0 - round to zero
+ * 1 - round to nearest
+ * 2 - round to postive infinity
+ * 3 - round to negative infinity
+ *
+ * ok all we need to do is get the current FP rounding mode
+ * index our map table and return the appropriate value.
+ *
+ * HOWEVER:
+ * The ARM FPA codes the rounding mode into the actual FP instructions
+ * so there is no such thing as a global rounding mode.
+ * The default is round to nearest if rounding is not explicitly specified.
+ * FP instructions generated by GCC will not explicitly specify a rounding
+ * mode.
+ *
+ * So the best we can do it to return the rounding mode FP instructions
+ * use if rounding is not specified which is round to nearest.
+ *
+ * This could change in the future with new floating point emulators or
+ * soft float FP libraries.
+ */
+
+int __flt_rounds(void);
+
+int
+__flt_rounds()
+{
+ return(map[fpgetround()]);
+}
diff --git a/StdLib/LibC/Main/ByteSwap.c b/StdLib/LibC/Main/ByteSwap.c
new file mode 100644
index 0000000000..f405bd9385
--- /dev/null
+++ b/StdLib/LibC/Main/ByteSwap.c
@@ -0,0 +1,72 @@
+/** @file
+ Byte Swap routines for endian-nes conversions.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <Library/BaseLib.h>
+#include <LibConfig.h>
+
+#include <sys/bswap.h>
+
+// Undefine macro versions of the functions to be defined below.
+#undef bswap16
+#undef bswap32
+#undef bswap64
+
+/**
+Switches the endianness of a 16-bit integer.
+
+This function swaps the bytes in a 16-bit unsigned value to switch the value
+from little endian to big endian or vice versa. The byte swapped value is
+returned.
+
+@param Value A 16-bit unsigned value.
+
+@return The byte swapped Value.
+
+**/
+uint16_t bswap16(uint16_t Value)
+{
+ return SwapBytes16(Value);
+}
+
+/**
+Switches the endianness of a 32-bit integer.
+
+This function swaps the bytes in a 32-bit unsigned value to switch the value
+from little endian to big endian or vice versa. The byte swapped value is
+returned.
+
+@param Value A 32-bit unsigned value.
+
+@return The byte swapped Value.
+
+**/
+uint32_t bswap32(uint32_t Value)
+{
+ return SwapBytes32(Value);
+}
+
+/**
+Switches the endianness of a 64-bit integer.
+
+This function swaps the bytes in a 64-bit unsigned value to switch the value
+from little endian to big endian or vice versa. The byte swapped value is
+returned.
+
+@param Value A 64-bit unsigned value.
+
+@return The byte swapped Value.
+
+**/
+uint64_t bswap64(uint64_t Value)
+{
+ return SwapBytes64(Value);
+}
diff --git a/StdLib/LibC/Main/HtoNtoH.c b/StdLib/LibC/Main/HtoNtoH.c
new file mode 100644
index 0000000000..c501874b84
--- /dev/null
+++ b/StdLib/LibC/Main/HtoNtoH.c
@@ -0,0 +1,90 @@
+/** @File
+ Routines for translating between host and network byte-order.
+
+ Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#include <Library/BaseLib.h>
+#include <LibConfig.h>
+#include <sys/endian.h>
+
+// Undefine macro versions of the functions to be defined below.
+#undef htonl
+#undef htons
+#undef ntohl
+#undef ntohs
+
+/** 32-bit Host to Network byte order conversion.
+
+ @param[in] Datum The 32-bit value to be converted.
+ @return Datum, converted to network byte order.
+**/
+uint32_t
+htonl(
+ IN uint32_t Datum
+ )
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+ return SwapBytes32(Datum);
+#else
+ return Datum;
+#endif
+}
+
+/** 16-bit Host to Network byte order conversion.
+
+ @param[in] Datum The 16-bit value to be converted.
+ @return Datum, converted to network byte order.
+**/
+uint16_t
+htons(
+ IN uint16_t Datum
+ )
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+ return SwapBytes16(Datum);
+#else
+ return Datum;
+#endif
+}
+
+/** 32-bit Network to Host byte order conversion.
+
+ @param[in] Datum The 16-bit value to be converted.
+ @return Datum, converted to host byte order.
+**/
+uint32_t
+ntohl(
+ IN uint32_t Datum
+ )
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+ return SwapBytes32(Datum);
+#else
+ return Datum;
+#endif
+}
+
+/** 16-bit Network to Host byte order conversion.
+
+ @param[in] Datum The 16-bit value to be converted.
+ @return Datum, converted to host byte order.
+**/
+uint16_t
+ntohs(
+ IN uint16_t Datum
+ )
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+ return SwapBytes16(Datum);
+#else
+ return Datum;
+#endif
+}
diff --git a/StdLib/LibC/Main/Ia32/fpu_rmode.S b/StdLib/LibC/Main/Ia32/fpu_rmode.S
new file mode 100644
index 0000000000..3d012872fc
--- /dev/null
+++ b/StdLib/LibC/Main/Ia32/fpu_rmode.S
@@ -0,0 +1,22 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#------------------------------------------------------------------------------
+
+ASM_GLOBAL ASM_PFX(internal_FPU_rmode)
+ASM_PFX(internal_FPU_rmode):
+ subl $4,%esp
+ fnstcw (%esp)
+ movl (%esp),%eax
+ shrl $10,%eax
+ andl $3,%eax
+ addl $4,%esp
+ ret
diff --git a/StdLib/LibC/Main/Ia32/fpu_rmode.asm b/StdLib/LibC/Main/Ia32/fpu_rmode.asm
new file mode 100644
index 0000000000..11d78230c2
--- /dev/null
+++ b/StdLib/LibC/Main/Ia32/fpu_rmode.asm
@@ -0,0 +1,46 @@
+;------------------------------------------------------------------------------
+; Return the current FPU rounding mode.
+;
+; MASM implementation of the flt_rounds function by:
+; J.T. Conklin, Apr 4, 1995
+; Public domain.
+;
+; Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+; NetBSD: flt_rounds.S,v 1.6 1999/08/23 08:45:09 kleink Exp
+;------------------------------------------------------------------------------
+
+ .686
+ .model flat,C
+ .code
+
+;_map BYTE 1 ; round to nearest
+; BYTE 3 ; round to negative infinity
+; BYTE 2 ; round to positive infinity
+; BYTE 0 ; round to zero
+
+;------------------------------------------------------------------------------
+; int
+; EFIAPI
+; fpu_rmode( void );
+;
+;------------------------------------------------------------------------------
+
+internal_FPU_rmode PROC
+ sub esp, 4 ; Create a local variable for fnstcw
+ fnstcw [esp]
+ mov eax, [esp]
+ shr eax, 10
+ and eax, 3
+ add esp, 4 ; Delete the local variable
+ ret
+internal_FPU_rmode ENDP
+
+ END
diff --git a/StdLib/LibC/Main/Ia32/ftol2.obj b/StdLib/LibC/Main/Ia32/ftol2.obj
new file mode 100644
index 0000000000..b96f830bc0
--- /dev/null
+++ b/StdLib/LibC/Main/Ia32/ftol2.obj
Binary files differ
diff --git a/StdLib/LibC/Main/Ia32/isinfl.c b/StdLib/LibC/Main/Ia32/isinfl.c
new file mode 100644
index 0000000000..773758b14f
--- /dev/null
+++ b/StdLib/LibC/Main/Ia32/isinfl.c
@@ -0,0 +1,68 @@
+/* $NetBSD: isinfl.c,v 1.5.16.1 2007/05/07 19:49:07 pavel Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: Header: isinf.c,v 1.1 91/07/08 19:03:34 torek Exp
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)isinf.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: isinfl.c,v 1.5.16.1 2007/05/07 19:49:07 pavel Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <machine/ieee.h>
+#include <math.h>
+
+#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
+ // C4700: uninitialized local variable used
+ #pragma warning ( disable : 4700 )
+#endif
+
+/*
+ * 7.12.3.3 isinf - test for infinity
+ * IEEE 754 compatible 80-bit extended-precision Intel 386 version
+ */
+int
+__isinfl(long double x)
+{
+ union ieee_ext_u u;
+
+ u.extu_ld = x;
+
+ return (u.extu_ext.ext_exp == EXT_EXP_INFNAN &&
+ u.extu_ext.ext_frach == 0x80000000 && u.extu_ext.ext_fracl == 0);
+}
diff --git a/StdLib/LibC/Main/Ia32/isnanl.c b/StdLib/LibC/Main/Ia32/isnanl.c
new file mode 100644
index 0000000000..b80dc4fee2
--- /dev/null
+++ b/StdLib/LibC/Main/Ia32/isnanl.c
@@ -0,0 +1,69 @@
+/* $NetBSD: isnanl.c,v 1.5.16.1 2007/05/07 19:49:07 pavel Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: Header: isinf.c,v 1.1 91/07/08 19:03:34 torek Exp
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)isinf.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: isnanl.c,v 1.5.16.1 2007/05/07 19:49:07 pavel Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <machine/ieee.h>
+#include <math.h>
+
+#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
+ // C4700: uninitialized local variable used
+ #pragma warning ( disable : 4700 )
+#endif
+
+/*
+ * 7.12.3.4 isnan - test for a NaN
+ * IEEE 754 compatible 80-bit extended-precision Intel 386 version
+ */
+int
+__isnanl(long double x)
+{
+ union ieee_ext_u u;
+
+ u.extu_ld = x;
+
+ return (u.extu_ext.ext_exp == EXT_EXP_INFNAN &&
+ (u.extu_ext.ext_frach & 0x80000000) != 0 &&
+ (u.extu_ext.ext_frach != 0x80000000 || u.extu_ext.ext_fracl != 0));
+}
diff --git a/StdLib/LibC/Main/Ipf/FpuRmode.s b/StdLib/LibC/Main/Ipf/FpuRmode.s
new file mode 100644
index 0000000000..caf4fba207
--- /dev/null
+++ b/StdLib/LibC/Main/Ipf/FpuRmode.s
@@ -0,0 +1,12 @@
+ .globl internal_FPU_rmode
+ .proc internal_FPU_rmode
+internal_FPU_rmode::
+ // get the floating point rounding control bits
+ // bits 10 and 11 are the rc bits from main status field fpsr.sf0
+ mov r8= ar.fpsr;;
+ shr r8 = r8, 10
+ mov r9 = 3;;
+ and r8 = r8, r9;;
+ br.sptk.few b0
+
+ .endp internal_FPU_rmode
diff --git a/StdLib/LibC/Main/Ipf/flt_rounds.c b/StdLib/LibC/Main/Ipf/flt_rounds.c
new file mode 100644
index 0000000000..0a18bb7390
--- /dev/null
+++ b/StdLib/LibC/Main/Ipf/flt_rounds.c
@@ -0,0 +1,25 @@
+/*
+ * Written by J.T. Conklin, Apr 10, 1995
+ * Public domain.
+ */
+
+#include <sys/EfiCdefs.h>
+/* __FBSDID("$FreeBSD: src/lib/libc/ia64/gen/flt_rounds.c,v 1.1 2004/07/19 08:17:24 das Exp $"); */
+
+#include <float.h>
+
+static const int map[] = {
+ 1, /* round to nearest */
+ 3, /* round to zero */
+ 2, /* round to negative infinity */
+ 0 /* round to positive infinity */
+};
+
+int
+__flt_rounds(void)
+{
+ int x;
+
+ __asm("mov %0=ar.fpsr" : "=r" (x));
+ return (map[(x >> 10) & 0x03]);
+}
diff --git a/StdLib/LibC/Main/Main.c b/StdLib/LibC/Main/Main.c
new file mode 100644
index 0000000000..0336d8b36a
--- /dev/null
+++ b/StdLib/LibC/Main/Main.c
@@ -0,0 +1,102 @@
+/** @file
+ Establish the program environment and the "main" entry point.
+
+ All of the global data in the gMD structure is initialized to 0, NULL, or
+ SIG_DFL; as appropriate.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <Uefi.h>
+#include <Library/UefiLib.h>
+
+#include <Library/ShellCEntryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/TimerLib.h>
+
+#include <LibConfig.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <MainData.h>
+
+extern int main( int, wchar_t**);
+extern int __sse2_available;
+
+struct __MainData *gMD;
+
+/* Worker function to keep GCC happy. */
+void __main()
+{
+ ;
+}
+
+INTN
+EFIAPI
+ShellAppMain (
+ IN UINTN Argc,
+ IN CHAR16 **Argv
+ )
+{
+ INTN ExitVal;
+ INTN i;
+ struct __filedes *mfd;
+ FILE *fp;
+
+ ExitVal = (INTN)RETURN_SUCCESS;
+ gMD = AllocateZeroPool(sizeof(struct __MainData));
+ if( gMD == NULL ) {
+ ExitVal = (INTN)RETURN_OUT_OF_RESOURCES;
+ }
+ else {
+ /* Initialize data */
+ __sse2_available = 0;
+ _fltused = 1;
+ errno = 0;
+ EFIerrno = 0;
+
+#ifdef NT32dvm
+ gMD->ClocksPerSecond = 0; // For NT32 only
+ gMD->AppStartTime = 0; // For NT32 only
+#else
+ gMD->ClocksPerSecond = (clock_t)GetPerformanceCounterProperties( NULL, NULL);
+ gMD->AppStartTime = (clock_t)GetPerformanceCounter();
+#endif /* NT32 dvm */
+
+ // Initialize file descriptors
+ mfd = gMD->fdarray;
+ for(i = 0; i < (FOPEN_MAX); ++i) {
+ mfd[i].MyFD = (UINT16)i;
+ }
+
+ // Open stdin, stdout, stderr
+ fp = freopen("stdin:", "r", stdin);
+ if(fp != NULL) {
+ fp = freopen("stdout:", "w", stdout);
+ if(fp != NULL) {
+ fp = freopen("stderr:", "w", stderr);
+ }
+ }
+ if(fp == NULL) {
+ Print(L"ERROR Initializing Standard IO: %a.\n %r\n",
+ strerror(errno), EFIerrno);
+ }
+
+ ExitVal = (INTN)main( (int)Argc, (wchar_t **)Argv);
+
+ if (gMD->cleanup != NULL) {
+ gMD->cleanup();
+ }
+ }
+ if(gMD != NULL) {
+ FreePool( gMD );
+ }
+ return ExitVal;
+}
diff --git a/StdLib/LibC/Main/X64/fpu_rmode.S b/StdLib/LibC/Main/X64/fpu_rmode.S
new file mode 100644
index 0000000000..4999102582
--- /dev/null
+++ b/StdLib/LibC/Main/X64/fpu_rmode.S
@@ -0,0 +1,20 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#------------------------------------------------------------------------------
+
+ASM_GLOBAL ASM_PFX(internal_FPU_rmode)
+ASM_PFX(internal_FPU_rmode):
+ fnstcw -4(%rsp)
+ movl -4(%rsp),%eax
+ shrl $10,%eax
+ andl $3,%eax
+ ret
diff --git a/StdLib/LibC/Main/X64/fpu_rmode.asm b/StdLib/LibC/Main/X64/fpu_rmode.asm
new file mode 100644
index 0000000000..36b0d11ccd
--- /dev/null
+++ b/StdLib/LibC/Main/X64/fpu_rmode.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------
+; Return the current FPU rounding mode.
+;
+; MASM implementation of the flt_rounds function from NetBSD.
+;
+; Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+;------------------------------------------------------------------------------
+
+ .code
+
+;_map BYTE 1 ; round to nearest
+; BYTE 3 ; round to negative infinity
+; BYTE 2 ; round to positive infinity
+; BYTE 0 ; round to zero
+
+;------------------------------------------------------------------------------
+; int
+; EFIAPI
+; fpu_rmode( void );
+;
+; VC++ always creates space for 4 parameters on the stack, whether they are
+; used or not. We use one for temporary storage since the only variant of
+; fnstcw saves to memory, NOT a register.
+;------------------------------------------------------------------------------
+internal_FPU_rmode PROC
+ fnstcw [rsp + 8] ; save 16-bit FPU Control Word
+ mov eax, [rsp + 8] ; get the saved FPU Control Word
+ shr eax, 10
+ and rax, 3 ; index is only the LSB two bits in RAX
+ ret ; Return rounding mode in RAX
+internal_FPU_rmode ENDP
+
+ END
diff --git a/StdLib/LibC/Main/X64/isinfl.c b/StdLib/LibC/Main/X64/isinfl.c
new file mode 100644
index 0000000000..d50577ffd1
--- /dev/null
+++ b/StdLib/LibC/Main/X64/isinfl.c
@@ -0,0 +1,63 @@
+/* $NetBSD: isinfl.c,v 1.5.16.1 2007/05/07 19:49:08 pavel Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: Header: isinf.c,v 1.1 91/07/08 19:03:34 torek Exp
+ */
+
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)isinf.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: isinfl.c,v 1.5.16.1 2007/05/07 19:49:08 pavel Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <machine/ieee.h>
+#include <math.h>
+
+/*
+ * 7.12.3.3 isinf - test for infinity
+ * IEEE 754 compatible 80-bit extended-precision Intel 386 version
+ */
+int
+__isinfl(long double x)
+{
+ union ieee_ext_u u = {0.0};
+
+ u.extu_ld = x;
+
+ return (u.extu_ext.ext_exp == EXT_EXP_INFNAN &&
+ u.extu_ext.ext_frach == 0x80000000 && u.extu_ext.ext_fracl == 0);
+}
diff --git a/StdLib/LibC/Main/X64/isnanl.c b/StdLib/LibC/Main/X64/isnanl.c
new file mode 100644
index 0000000000..148d674577
--- /dev/null
+++ b/StdLib/LibC/Main/X64/isnanl.c
@@ -0,0 +1,64 @@
+/* $NetBSD: isnanl.c,v 1.5.16.1 2007/05/07 19:49:07 pavel Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: Header: isinf.c,v 1.1 91/07/08 19:03:34 torek Exp
+ */
+
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)isinf.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: isnanl.c,v 1.5.16.1 2007/05/07 19:49:07 pavel Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <machine/ieee.h>
+#include <math.h>
+
+/*
+ * 7.12.3.4 isnan - test for a NaN
+ * IEEE 754 compatible 80-bit extended-precision Intel 386 version
+ */
+int
+__isnanl(long double x)
+{
+ union ieee_ext_u u = { 0 };
+
+ u.extu_ld = x;
+
+ return (u.extu_ext.ext_exp == EXT_EXP_INFNAN &&
+ (u.extu_ext.ext_frach & 0x80000000) != 0 &&
+ (u.extu_ext.ext_frach != 0x80000000 || u.extu_ext.ext_fracl != 0));
+}
diff --git a/StdLib/LibC/Main/assert.c b/StdLib/LibC/Main/assert.c
new file mode 100644
index 0000000000..6bb53d6abd
--- /dev/null
+++ b/StdLib/LibC/Main/assert.c
@@ -0,0 +1,32 @@
+/**
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+//#include <Uefi.h>
+//#include <Library/UefiLib.h>
+
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void
+EFIAPI
+__assert(const char *func, const char *file, int line, const char *failedexpr)
+{
+ if (func == NULL)
+ printf("Assertion failed: (%s), file %s, line %d.\n",
+ failedexpr, file, line);
+ else
+ printf("Assertion failed: (%s), function %s, file %s, line %d.\n",
+ failedexpr, func, file, line);
+ abort();
+ /* NOTREACHED */
+}
diff --git a/StdLib/LibC/Main/bswap16.c b/StdLib/LibC/Main/bswap16.c
new file mode 100644
index 0000000000..c0e60f03c6
--- /dev/null
+++ b/StdLib/LibC/Main/bswap16.c
@@ -0,0 +1,22 @@
+/* $NetBSD: bswap16.c,v 1.1 2005/12/20 19:28:51 christos Exp $ */
+
+/*
+ * Written by Manuel Bouyer <bouyer@NetBSD.org>.
+ * Public domain.
+ */
+
+//#include <sys/cdefs.h>
+//#if defined(LIBC_SCCS) && !defined(lint)
+//__RCSID("$NetBSD: bswap16.c,v 1.1 2005/12/20 19:28:51 christos Exp $");
+//#endif /* LIBC_SCCS and not lint */
+
+//#include <sys/types.h>
+//#include <machine/bswap.h>
+
+#undef bswap16
+
+UINT16
+bswap16(UINT16 x)
+{
+ return ((x << 8) & 0xff00) | ((x >> 8) & 0x00ff);
+}
diff --git a/StdLib/LibC/Main/bswap32.c b/StdLib/LibC/Main/bswap32.c
new file mode 100644
index 0000000000..f573a54c6c
--- /dev/null
+++ b/StdLib/LibC/Main/bswap32.c
@@ -0,0 +1,25 @@
+/* $NetBSD: bswap32.c,v 1.1 2005/12/20 19:28:51 christos Exp $ */
+
+/*
+ * Written by Manuel Bouyer <bouyer@NetBSD.org>.
+ * Public domain.
+ */
+
+//#include <sys/cdefs.h>
+//#if defined(LIBC_SCCS) && !defined(lint)
+//__RCSID("$NetBSD: bswap32.c,v 1.1 2005/12/20 19:28:51 christos Exp $");
+//#endif /* LIBC_SCCS and not lint */
+
+//#include <sys/types.h>
+//#include <machine/bswap.h>
+
+#undef bswap32
+
+UINT32
+bswap32(UINT32 x)
+{
+ return ((x << 24) & 0xff000000 ) |
+ ((x << 8) & 0x00ff0000 ) |
+ ((x >> 8) & 0x0000ff00 ) |
+ ((x >> 24) & 0x000000ff );
+}
diff --git a/StdLib/LibC/Main/bswap64.c b/StdLib/LibC/Main/bswap64.c
new file mode 100644
index 0000000000..29e6916ea6
--- /dev/null
+++ b/StdLib/LibC/Main/bswap64.c
@@ -0,0 +1,44 @@
+/* $NetBSD: bswap64.c,v 1.1 2005/12/20 19:28:51 christos Exp $ */
+
+/*
+ * Written by Manuel Bouyer <bouyer@NetBSD.org>.
+ * Public domain.
+ */
+
+//#include <sys/cdefs.h>
+//#if defined(LIBC_SCCS) && !defined(lint)
+//__RCSID("$NetBSD: bswap64.c,v 1.1 2005/12/20 19:28:51 christos Exp $");
+//#endif /* LIBC_SCCS and not lint */
+
+//#include <sys/types.h>
+//#include <machine/bswap.h>
+
+#undef bswap64
+
+UINT64
+bswap64(UINT64 x)
+{
+#ifndef _LP64
+ /*
+ * Assume we have wide enough registers to do it without touching
+ * memory.
+ */
+ return ( (x << 56) & 0xff00000000000000UL ) |
+ ( (x << 40) & 0x00ff000000000000UL ) |
+ ( (x << 24) & 0x0000ff0000000000UL ) |
+ ( (x << 8) & 0x000000ff00000000UL ) |
+ ( (x >> 8) & 0x00000000ff000000UL ) |
+ ( (x >> 24) & 0x0000000000ff0000UL ) |
+ ( (x >> 40) & 0x000000000000ff00UL ) |
+ ( (x >> 56) & 0x00000000000000ffUL );
+#else
+ /*
+ * Split the operation in two 32bit steps.
+ */
+ u_int32_t tl, th;
+
+ th = bswap32((u_int32_t)(x & 0x00000000ffffffffULL));
+ tl = bswap32((u_int32_t)((x >> 32) & 0x00000000ffffffffULL));
+ return ((u_int64_t)th << 32) | tl;
+#endif
+}
diff --git a/StdLib/LibC/Main/errno.c b/StdLib/LibC/Main/errno.c
new file mode 100644
index 0000000000..48eb1709b6
--- /dev/null
+++ b/StdLib/LibC/Main/errno.c
@@ -0,0 +1,19 @@
+/** @file
+ Instantiate errno as declared in <errno.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+int errno = 0;
+RETURN_STATUS EFIerrno = RETURN_SUCCESS;
+
+// This is required to keep VC++ happy if you use floating-point
+int _fltused = 1;
+int __sse2_available = 0; ///< Used by ftol2_sse
diff --git a/StdLib/LibC/Main/infinityf_ieee754.c b/StdLib/LibC/Main/infinityf_ieee754.c
new file mode 100644
index 0000000000..3f191650e2
--- /dev/null
+++ b/StdLib/LibC/Main/infinityf_ieee754.c
@@ -0,0 +1,20 @@
+/* $NetBSD: infinityf_ieee754.c,v 1.2 2005/06/12 05:21:27 lukem Exp $ */
+
+/*
+ * IEEE-compatible infinityf.c -- public domain.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: infinityf_ieee754.c,v 1.2 2005/06/12 05:21:27 lukem Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <math.h>
+#include <machine/endian.h>
+
+const union __float_u __infinityf =
+#if BYTE_ORDER == BIG_ENDIAN
+ { { 0x7f, 0x80, 0, 0 } };
+#else
+ { { 0, 0, 0x80, 0x7f } };
+#endif
diff --git a/StdLib/LibC/Main/isinfd_ieee754.c b/StdLib/LibC/Main/isinfd_ieee754.c
new file mode 100644
index 0000000000..f5757b083c
--- /dev/null
+++ b/StdLib/LibC/Main/isinfd_ieee754.c
@@ -0,0 +1,68 @@
+/* $NetBSD: isinfd_ieee754.c,v 1.1 2004/03/04 23:42:39 kleink Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: Header: isinf.c,v 1.1 91/07/08 19:03:34 torek Exp
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)isinf.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: isinfd_ieee754.c,v 1.1 2004/03/04 23:42:39 kleink Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <machine/ieee.h>
+#include <math.h>
+
+/* libc.so.12 ABI compatbility */
+#ifdef __weak_alias
+__weak_alias(isinf,__isinfd)
+#endif
+
+/*
+ * 7.12.3.3 isinf - test for infinity
+ * IEEE 754 double-precision version
+ */
+int
+__isinfd(double x)
+{
+ union ieee_double_u u;
+
+ u.dblu_d = x;
+
+ return (u.dblu_dbl.dbl_exp == DBL_EXP_INFNAN &&
+ (u.dblu_dbl.dbl_frach == 0 && u.dblu_dbl.dbl_fracl == 0));
+}
diff --git a/StdLib/LibC/Main/isinff_ieee754.c b/StdLib/LibC/Main/isinff_ieee754.c
new file mode 100644
index 0000000000..ada1e728f1
--- /dev/null
+++ b/StdLib/LibC/Main/isinff_ieee754.c
@@ -0,0 +1,63 @@
+/* $NetBSD: isinff_ieee754.c,v 1.1 2004/03/04 23:42:39 kleink Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: Header: isinf.c,v 1.1 91/07/08 19:03:34 torek Exp
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)isinf.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: isinff_ieee754.c,v 1.1 2004/03/04 23:42:39 kleink Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <machine/ieee.h>
+#include <math.h>
+
+/*
+ * 7.12.3.3 isinf - test for infinity
+ * IEEE 754 single-precision version
+ */
+int
+__isinff(float x)
+{
+ union ieee_single_u u;
+
+ u.sngu_f = x;
+
+ return (u.sngu_sng.sng_exp == SNG_EXP_INFNAN &&
+ u.sngu_sng.sng_frac == 0);
+}
diff --git a/StdLib/LibC/Main/isnand_ieee754.c b/StdLib/LibC/Main/isnand_ieee754.c
new file mode 100644
index 0000000000..70c1535343
--- /dev/null
+++ b/StdLib/LibC/Main/isnand_ieee754.c
@@ -0,0 +1,68 @@
+/* $NetBSD: isnand_ieee754.c,v 1.1 2004/03/04 23:42:39 kleink Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: Header: isinf.c,v 1.1 91/07/08 19:03:34 torek Exp
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)isinf.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: isnand_ieee754.c,v 1.1 2004/03/04 23:42:39 kleink Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <machine/ieee.h>
+#include <math.h>
+
+/* libc.so.12 ABI compatbility */
+#ifdef __weak_alias
+__weak_alias(isnan,__isnand)
+#endif
+
+/*
+ * 7.12.3.4 isnan - test for a NaN
+ * IEEE 754 double-precision version
+ */
+int
+__isnand(double x)
+{
+ union ieee_double_u u;
+
+ u.dblu_d = x;
+
+ return (u.dblu_dbl.dbl_exp == DBL_EXP_INFNAN &&
+ (u.dblu_dbl.dbl_frach != 0 || u.dblu_dbl.dbl_fracl != 0));
+}
diff --git a/StdLib/LibC/Main/isnanf_ieee754.c b/StdLib/LibC/Main/isnanf_ieee754.c
new file mode 100644
index 0000000000..309404d320
--- /dev/null
+++ b/StdLib/LibC/Main/isnanf_ieee754.c
@@ -0,0 +1,63 @@
+/* $NetBSD: isnanf_ieee754.c,v 1.1 2004/03/04 23:42:39 kleink Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: Header: isinf.c,v 1.1 91/07/08 19:03:34 torek Exp
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)isinf.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: isnanf_ieee754.c,v 1.1 2004/03/04 23:42:39 kleink Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <machine/ieee.h>
+#include <math.h>
+
+/*
+ * 7.12.3.4 isnan - test for a NaN
+ * IEEE 754 single-precision version
+ */
+int
+__isnanf(float x)
+{
+ union ieee_single_u u;
+
+ u.sngu_f = x;
+
+ return (u.sngu_sng.sng_exp == SNG_EXP_INFNAN &&
+ u.sngu_sng.sng_frac != 0);
+}
diff --git a/StdLib/LibC/Main/longjmp.c b/StdLib/LibC/Main/longjmp.c
new file mode 100644
index 0000000000..2ae9a0d455
--- /dev/null
+++ b/StdLib/LibC/Main/longjmp.c
@@ -0,0 +1,20 @@
+/** @file
+ The longjmp function.
+ The C standard requires that longjmp be a function and not a macro.
+
+ Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <Library/BaseLib.h>
+#include <setjmp.h>
+
+void longjmp(jmp_buf env, int val)
+{
+ LongJump(env, (UINTN)((val == 0) ? 1 : val));
+}
diff --git a/StdLib/LibC/Main/x86flt_rounds.c b/StdLib/LibC/Main/x86flt_rounds.c
new file mode 100644
index 0000000000..d0478e2c1b
--- /dev/null
+++ b/StdLib/LibC/Main/x86flt_rounds.c
@@ -0,0 +1,23 @@
+/** @file
+ Return the current FPU rounding mode.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+extern int internal_FPU_rmode( void );
+
+static INT8 rmode[] = { 1, 3, 2, 0 };
+
+int
+EFIAPI
+__flt_rounds ( void )
+{
+ return rmode[ internal_FPU_rmode() ];
+}
diff --git a/StdLib/LibC/Math/Math.inf b/StdLib/LibC/Math/Math.inf
new file mode 100644
index 0000000000..6a48d97cac
--- /dev/null
+++ b/StdLib/LibC/Math/Math.inf
@@ -0,0 +1,101 @@
+## @file
+# Standard C library: Math Library.
+#
+# Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = LibMath
+ FILE_GUID = a9dc6f60-f861-47d1-8751-ecaae7d27291
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = LibMath
+
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[Sources]
+ # ieee 754 specific
+ e_acos.c
+ e_asin.c
+ e_atan2.c
+ e_cosh.c
+ e_exp.c
+ e_sinh.c
+ e_log.c
+ e_log2.c
+ e_log10.c
+ e_pow.c
+ e_sqrt.c
+ e_fmod.c
+ e_rem_pio2.c
+
+ # kernel functions
+ k_cos.c
+ k_sin.c
+ k_tan.c
+ k_rem_pio2.c
+
+ # Simple, unadorned, functions
+ s_atan.c
+ s_cos.c
+ s_sin.c
+ s_tan.c
+ s_expm1.c
+ s_tanh.c
+ s_frexp.c
+ s_ldexp.c
+ s_scalbn.c
+ s_copysign.c
+ s_finite.c
+ s_infinity.c
+ s_modf.c
+ s_fabs.c
+ s_ceil.c
+ s_floor.c
+
+ # wrapper functions
+ w_acos.c
+ w_asin.c
+ w_atan2.c
+ w_cosh.c
+ w_sinh.c
+ w_exp.c
+ w_log.c
+ w_log2.c
+ w_log10.c
+ w_pow.c
+ w_sqrt.c
+ w_fmod.c
+
+[Packages]
+ StdLib/StdLib.dec
+ StdLibPrivateInternalFiles/DoNotUse.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ LibC
+
+################################################################
+# The Build Options, below, are only used when building the C library.
+# DO NOT use them when building your application!
+# Nasty things could happen if you do.
+#
+# /Oi- is required for Microsoft VC++ to allow "intrinsic" functions to be
+# defined in this library.
+# /GL- is required so that LTCG generated references to functions in this library,
+# such as memcpy(), can be resolved.
+#
+[BuildOptions]
+ MSFT:*_*_*_CC_FLAGS = /Oi- /GL-
diff --git a/StdLib/LibC/Math/e_acos.c b/StdLib/LibC/Math/e_acos.c
new file mode 100644
index 0000000000..4617729af6
--- /dev/null
+++ b/StdLib/LibC/Math/e_acos.c
@@ -0,0 +1,122 @@
+/** @file
+ Compute acos(x) using ieee FP math.
+
+ Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+
+ e_acos.c 5.1 93/09/24
+ NetBSD: e_acos.c,v 1.12 2002/05/26 22:01:47 wiz Exp
+ */
+#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
+ // Keep older compilers quiet about floating-point divide-by-zero
+ #pragma warning ( disable : 4723 )
+#endif
+
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+/* __ieee754_acos(x)
+ * Method :
+ * acos(x) = pi/2 - asin(x)
+ * acos(-x) = pi/2 + asin(x)
+ * For |x|<=0.5
+ * acos(x) = pi/2 - (x + x*x^2*R(x^2)) (see asin.c)
+ * For x>0.5
+ * acos(x) = pi/2 - (pi/2 - 2asin(sqrt((1-x)/2)))
+ * = 2asin(sqrt((1-x)/2))
+ * = 2s + 2s*z*R(z) ...z=(1-x)/2, s=sqrt(z)
+ * = 2f + (2c + 2s*z*R(z))
+ * where f=hi part of s, and c = (z-f*f)/(s+f) is the correction term
+ * for f so that f+c ~ sqrt(z).
+ * For x<-0.5
+ * acos(x) = pi - 2asin(sqrt((1-|x|)/2))
+ * = pi - 0.5*(s+s*z*R(z)), where z=(1-|x|)/2,s=sqrt(z)
+ *
+ * Special cases:
+ * if x is NaN, return x itself;
+ * if |x|>1, return NaN with invalid signal.
+ *
+ * Function needed: __ieee754_sqrt
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+static const double
+one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+pi = 3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */
+pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
+pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
+pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
+pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
+pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
+pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
+pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
+pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
+qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
+qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
+qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
+qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
+
+double
+__ieee754_acos(double x)
+{
+ double z,p,q,r,w,s,c,df;
+ int32_t hx,ix;
+ GET_HIGH_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x3ff00000) { /* |x| >= 1 */
+ u_int32_t lx;
+
+ GET_LOW_WORD(lx,x);
+ if(((ix-0x3ff00000)|lx)==0) { /* |x|==1 */
+ if(hx>0) return 0.0; /* acos(1) = 0 */
+ else return pi+2.0*pio2_lo; /* acos(-1)= pi */
+ }
+ return (x-x)/(x-x); /* acos(|x|>1) is NaN */
+ }
+ if(ix<0x3fe00000) { /* |x| < 0.5 */
+ if(ix<=0x3c600000) return pio2_hi+pio2_lo; /*if|x|<2**-57*/
+ z = x*x;
+ p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
+ q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
+ r = p/q;
+ return pio2_hi - (x - (pio2_lo-x*r));
+ }
+ else if (hx<0) { /* x < -0.5 */
+ z = (one+x)*0.5;
+ p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
+ q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
+ s = __ieee754_sqrt(z);
+ r = p/q;
+ w = r*s-pio2_lo;
+ return pi - 2.0*(s+w);
+ }
+ else { /* x > 0.5 */
+ z = (one-x)*0.5;
+ s = __ieee754_sqrt(z);
+ df = s;
+ SET_LOW_WORD(df,0);
+ c = (z-df*df)/(s+df);
+ p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
+ q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
+ r = p/q;
+ w = r*s+c;
+ return 2.0*(df+w);
+ }
+}
diff --git a/StdLib/LibC/Math/e_asin.c b/StdLib/LibC/Math/e_asin.c
new file mode 100644
index 0000000000..d1d4dc0019
--- /dev/null
+++ b/StdLib/LibC/Math/e_asin.c
@@ -0,0 +1,120 @@
+/* @(#)e_asin.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: e_asin.c,v 1.12 2002/05/26 22:01:48 wiz Exp $");
+#endif
+
+#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
+// C4723: potential divide by zero.
+#pragma warning ( disable : 4723 )
+#endif
+
+/* __ieee754_asin(x)
+ * Method :
+ * Since asin(x) = x + x^3/6 + x^5*3/40 + x^7*15/336 + ...
+ * we approximate asin(x) on [0,0.5] by
+ * asin(x) = x + x*x^2*R(x^2)
+ * where
+ * R(x^2) is a rational approximation of (asin(x)-x)/x^3
+ * and its remez error is bounded by
+ * |(asin(x)-x)/x^3 - R(x^2)| < 2^(-58.75)
+ *
+ * For x in [0.5,1]
+ * asin(x) = pi/2-2*asin(sqrt((1-x)/2))
+ * Let y = (1-x), z = y/2, s := sqrt(z), and pio2_hi+pio2_lo=pi/2;
+ * then for x>0.98
+ * asin(x) = pi/2 - 2*(s+s*z*R(z))
+ * = pio2_hi - (2*(s+s*z*R(z)) - pio2_lo)
+ * For x<=0.98, let pio4_hi = pio2_hi/2, then
+ * f = hi part of s;
+ * c = sqrt(z) - f = (z-f*f)/(s+f) ...f+c=sqrt(z)
+ * and
+ * asin(x) = pi/2 - 2*(s+s*z*R(z))
+ * = pio4_hi+(pio4-2s)-(2s*z*R(z)-pio2_lo)
+ * = pio4_hi+(pio4-2f)-(2s*z*R(z)-(pio2_lo+2c))
+ *
+ * Special cases:
+ * if x is NaN, return x itself;
+ * if |x|>1, return NaN with invalid signal.
+ *
+ */
+
+
+#include "math.h"
+#include "math_private.h"
+
+static const double
+one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+huge = 1.000e+300,
+pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
+pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
+pio4_hi = 7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */
+ /* coefficient for R(x^2) */
+pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
+pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
+pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
+pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
+pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
+pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
+qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
+qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
+qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
+qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
+
+double
+__ieee754_asin(double x)
+{
+ double t,w,p,q,c,r,s;
+ int32_t hx,ix;
+
+ t = 0;
+ GET_HIGH_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>= 0x3ff00000) { /* |x|>= 1 */
+ u_int32_t lx;
+ GET_LOW_WORD(lx,x);
+ if(((ix-0x3ff00000)|lx)==0)
+ /* asin(1)=+-pi/2 with inexact */
+ return x*pio2_hi+x*pio2_lo;
+ return (x-x)/(x-x); /* asin(|x|>1) is NaN */
+ } else if (ix<0x3fe00000) { /* |x|<0.5 */
+ if(ix<0x3e400000) { /* if |x| < 2**-27 */
+ if(huge+x>one) return x;/* return x with inexact if x!=0*/
+ } else
+ t = x*x;
+ p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5)))));
+ q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
+ w = p/q;
+ return x+x*w;
+ }
+ /* 1> |x|>= 0.5 */
+ w = one-fabs(x);
+ t = w*0.5;
+ p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5)))));
+ q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
+ s = __ieee754_sqrt(t);
+ if(ix>=0x3FEF3333) { /* if |x| > 0.975 */
+ w = p/q;
+ t = pio2_hi-(2.0*(s+s*w)-pio2_lo);
+ } else {
+ w = s;
+ SET_LOW_WORD(w,0);
+ c = (t-w*w)/(s+w);
+ r = p/q;
+ p = 2.0*s*r-(pio2_lo-2.0*c);
+ q = pio4_hi-2.0*w;
+ t = pio4_hi-(p-q);
+ }
+ if(hx>0) return t; else return -t;
+}
diff --git a/StdLib/LibC/Math/e_atan2.c b/StdLib/LibC/Math/e_atan2.c
new file mode 100644
index 0000000000..309447c0a5
--- /dev/null
+++ b/StdLib/LibC/Math/e_atan2.c
@@ -0,0 +1,128 @@
+/* @(#)e_atan2.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: e_atan2.c,v 1.12 2002/05/26 22:01:48 wiz Exp $");
+#endif
+
+#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
+ // unary minus operator applied to unsigned type, result still unsigned
+ #pragma warning ( disable : 4146 )
+#endif
+
+/* __ieee754_atan2(y,x)
+ * Method :
+ * 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x).
+ * 2. Reduce x to positive by (if x and y are unexceptional):
+ * ARG (x+iy) = arctan(y/x) ... if x > 0,
+ * ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0,
+ *
+ * Special cases:
+ *
+ * ATAN2((anything), NaN ) is NaN;
+ * ATAN2(NAN , (anything) ) is NaN;
+ * ATAN2(+-0, +(anything but NaN)) is +-0 ;
+ * ATAN2(+-0, -(anything but NaN)) is +-pi ;
+ * ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2;
+ * ATAN2(+-(anything but INF and NaN), +INF) is +-0 ;
+ * ATAN2(+-(anything but INF and NaN), -INF) is +-pi;
+ * ATAN2(+-INF,+INF ) is +-pi/4 ;
+ * ATAN2(+-INF,-INF ) is +-3pi/4;
+ * ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2;
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+static const double
+tiny = 1.0e-300,
+zero = 0.0,
+pi_o_4 = 7.8539816339744827900E-01, /* 0x3FE921FB, 0x54442D18 */
+pi_o_2 = 1.5707963267948965580E+00, /* 0x3FF921FB, 0x54442D18 */
+pi = 3.1415926535897931160E+00, /* 0x400921FB, 0x54442D18 */
+pi_lo = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */
+
+double
+__ieee754_atan2(double y, double x)
+{
+ double z;
+ int32_t k,m,hx,hy,ix,iy;
+ u_int32_t lx,ly;
+
+ EXTRACT_WORDS(hx,lx,x);
+ ix = hx&0x7fffffff;
+ EXTRACT_WORDS(hy,ly,y);
+ iy = hy&0x7fffffff;
+ if(((ix|((lx|-lx)>>31))>0x7ff00000)||
+ ((iy|((ly|-ly)>>31))>0x7ff00000)) /* x or y is NaN */
+ return x+y;
+ if(((hx-0x3ff00000)|lx)==0) return atan(y); /* x=1.0 */
+ m = ((hy>>31)&1)|((hx>>30)&2); /* 2*sign(x)+sign(y) */
+
+ /* when y = 0 */
+ if((iy|ly)==0) {
+ switch(m) {
+ case 0:
+ case 1: return y; /* atan(+-0,+anything)=+-0 */
+ case 2: return pi+tiny;/* atan(+0,-anything) = pi */
+ case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */
+ }
+ }
+ /* when x = 0 */
+ if((ix|lx)==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
+
+ /* when x is INF */
+ if(ix==0x7ff00000) {
+ if(iy==0x7ff00000) {
+ switch(m) {
+ case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */
+ case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */
+ case 2: return 3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/
+ case 3: return -3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/
+ }
+ } else {
+ switch(m) {
+ case 0: return zero ; /* atan(+...,+INF) */
+ case 1: return -zero ; /* atan(-...,+INF) */
+ case 2: return pi+tiny ; /* atan(+...,-INF) */
+ case 3: return -pi-tiny ; /* atan(-...,-INF) */
+ }
+ }
+ }
+ /* when y is INF */
+ if(iy==0x7ff00000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
+
+ /* compute y/x */
+ k = (iy-ix)>>20;
+ if(k > 60) z=pi_o_2+0.5*pi_lo; /* |y/x| > 2**60 */
+ else if(hx<0&&k<-60) z=0.0; /* |y|/x < -2**60 */
+ else z=atan(fabs(y/x)); /* safe to do y/x */
+ switch (m) {
+ case 0: return z ; /* atan(+,+) */
+ case 1: {
+ u_int32_t zh;
+ GET_HIGH_WORD(zh,z);
+ SET_HIGH_WORD(z,zh ^ 0x80000000);
+ }
+ return z ; /* atan(-,+) */
+ case 2: return pi-(z-pi_lo);/* atan(+,-) */
+ default: /* case 3 */
+ return (z-pi_lo)-pi;/* atan(-,-) */
+ }
+}
diff --git a/StdLib/LibC/Math/e_cosh.c b/StdLib/LibC/Math/e_cosh.c
new file mode 100644
index 0000000000..48ce6817d2
--- /dev/null
+++ b/StdLib/LibC/Math/e_cosh.c
@@ -0,0 +1,91 @@
+/* @(#)e_cosh.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: e_cosh.c,v 1.11 2002/05/26 22:01:49 wiz Exp $");
+#endif
+
+#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
+ // C4756: overflow in constant arithmetic
+ #pragma warning ( disable : 4756 )
+#endif
+
+/* __ieee754_cosh(x)
+ * Method :
+ * mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2
+ * 1. Replace x by |x| (cosh(x) = cosh(-x)).
+ * 2.
+ * [ exp(x) - 1 ]^2
+ * 0 <= x <= ln2/2 : cosh(x) := 1 + -------------------
+ * 2*exp(x)
+ *
+ * exp(x) + 1/exp(x)
+ * ln2/2 <= x <= 22 : cosh(x) := -------------------
+ * 2
+ * 22 <= x <= lnovft : cosh(x) := exp(x)/2
+ * lnovft <= x <= ln2ovft: cosh(x) := exp(x/2)/2 * exp(x/2)
+ * ln2ovft < x : cosh(x) := huge*huge (overflow)
+ *
+ * Special cases:
+ * cosh(x) is |x| if x is +INF, -INF, or NaN.
+ * only cosh(0)=1 is exact for finite x.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+static const double one = 1.0, half=0.5, huge = 1.0e300;
+
+double
+__ieee754_cosh(double x)
+{
+ double t,w;
+ int32_t ix;
+ u_int32_t lx;
+
+ /* High word of |x|. */
+ GET_HIGH_WORD(ix,x);
+ ix &= 0x7fffffff;
+
+ /* x is INF or NaN */
+ if(ix>=0x7ff00000) return x*x;
+
+ /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */
+ if(ix<0x3fd62e43) {
+ t = expm1(fabs(x));
+ w = one+t;
+ if (ix<0x3c800000) return w; /* cosh(tiny) = 1 */
+ return one+(t*t)/(w+w);
+ }
+
+ /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */
+ if (ix < 0x40360000) {
+ t = __ieee754_exp(fabs(x));
+ return half*t+half/t;
+ }
+
+ /* |x| in [22, log(maxdouble)] return half*exp(|x|) */
+ if (ix < 0x40862E42) return half*__ieee754_exp(fabs(x));
+
+ /* |x| in [log(maxdouble), overflowthresold] */
+ GET_LOW_WORD(lx,x);
+ if (ix<0x408633CE ||
+ ((ix==0x408633ce)&&(lx<=(u_int32_t)0x8fb9f87d))) {
+ w = __ieee754_exp(half*fabs(x));
+ t = half*w;
+ return t*w;
+ }
+
+ /* |x| > overflowthresold, cosh(x) overflow */
+ return huge*huge;
+}
diff --git a/StdLib/LibC/Math/e_exp.c b/StdLib/LibC/Math/e_exp.c
new file mode 100644
index 0000000000..f05f5397e6
--- /dev/null
+++ b/StdLib/LibC/Math/e_exp.c
@@ -0,0 +1,167 @@
+/* @(#)e_exp.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: e_exp.c,v 1.11 2002/05/26 22:01:49 wiz Exp $");
+#endif
+
+#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
+ // C4756: overflow in constant arithmetic
+ #pragma warning ( disable : 4756 )
+#endif
+
+/* __ieee754_exp(x)
+ * Returns the exponential of x.
+ *
+ * Method
+ * 1. Argument reduction:
+ * Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658.
+ * Given x, find r and integer k such that
+ *
+ * x = k*ln2 + r, |r| <= 0.5*ln2.
+ *
+ * Here r will be represented as r = hi-lo for better
+ * accuracy.
+ *
+ * 2. Approximation of exp(r) by a special rational function on
+ * the interval [0,0.34658]:
+ * Write
+ * R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ...
+ * We use a special Reme algorithm on [0,0.34658] to generate
+ * a polynomial of degree 5 to approximate R. The maximum error
+ * of this polynomial approximation is bounded by 2**-59. In
+ * other words,
+ * R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5
+ * (where z=r*r, and the values of P1 to P5 are listed below)
+ * and
+ * | 5 | -59
+ * | 2.0+P1*z+...+P5*z - R(z) | <= 2
+ * | |
+ * The computation of exp(r) thus becomes
+ * 2*r
+ * exp(r) = 1 + -------
+ * R - r
+ * r*R1(r)
+ * = 1 + r + ----------- (for better accuracy)
+ * 2 - R1(r)
+ * where
+ * 2 4 10
+ * R1(r) = r - (P1*r + P2*r + ... + P5*r ).
+ *
+ * 3. Scale back to obtain exp(x):
+ * From step 1, we have
+ * exp(x) = 2^k * exp(r)
+ *
+ * Special cases:
+ * exp(INF) is INF, exp(NaN) is NaN;
+ * exp(-INF) is 0, and
+ * for finite argument, only exp(0)=1 is exact.
+ *
+ * Accuracy:
+ * according to an error analysis, the error is always less than
+ * 1 ulp (unit in the last place).
+ *
+ * Misc. info.
+ * For IEEE double
+ * if x > 7.09782712893383973096e+02 then exp(x) overflow
+ * if x < -7.45133219101941108420e+02 then exp(x) underflow
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+static const double
+one = 1.0,
+halF[2] = {0.5,-0.5,},
+huge = 1.0e+300,
+twom1000= 9.33263618503218878990e-302, /* 2**-1000=0x01700000,0*/
+o_threshold= 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */
+u_threshold= -7.45133219101941108420e+02, /* 0xc0874910, 0xD52D3051 */
+ln2HI[2] ={ 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */
+ -6.93147180369123816490e-01,},/* 0xbfe62e42, 0xfee00000 */
+ln2LO[2] ={ 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */
+ -1.90821492927058770002e-10,},/* 0xbdea39ef, 0x35793c76 */
+invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */
+P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */
+P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */
+P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */
+P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */
+P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */
+
+
+double
+__ieee754_exp(double x) /* default IEEE double exp */
+{
+ double y,hi,lo,c,t;
+ int32_t k,xsb;
+ u_int32_t hx;
+
+ hi = lo = 0;
+ k = 0;
+ GET_HIGH_WORD(hx,x);
+ xsb = (hx>>31)&1; /* sign bit of x */
+ hx &= 0x7fffffff; /* high word of |x| */
+
+ /* filter out non-finite argument */
+ if(hx >= 0x40862E42) { /* if |x|>=709.78... */
+ if(hx>=0x7ff00000) {
+ u_int32_t lx;
+ GET_LOW_WORD(lx,x);
+ if(((hx&0xfffff)|lx)!=0)
+ return x+x; /* NaN */
+ else return (xsb==0)? x:0.0; /* exp(+-inf)={inf,0} */
+ }
+ if(x > o_threshold) return huge*huge; /* overflow */
+ if(x < u_threshold) return twom1000*twom1000; /* underflow */
+ }
+
+ /* argument reduction */
+ if(hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */
+ if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */
+ hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb;
+ } else {
+ k = (int32_t)(invln2*x+halF[xsb]);
+ t = k;
+ hi = x - t*ln2HI[0]; /* t*ln2HI is exact here */
+ lo = t*ln2LO[0];
+ }
+ x = hi - lo;
+ }
+ else if(hx < 0x3e300000) { /* when |x|<2**-28 */
+ if(huge+x>one) return one+x;/* trigger inexact */
+ }
+ else k = 0;
+
+ /* x is now in primary range */
+ t = x*x;
+ c = x - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
+ if(k==0) return one-((x*c)/(c-2.0)-x);
+ else y = one-((lo-(x*c)/(2.0-c))-hi);
+ if(k >= -1021) {
+ u_int32_t hy;
+ GET_HIGH_WORD(hy,y);
+ SET_HIGH_WORD(y,hy+(k<<20)); /* add k to y's exponent */
+ return y;
+ } else {
+ u_int32_t hy;
+ GET_HIGH_WORD(hy,y);
+ SET_HIGH_WORD(y,hy+((k+1000)<<20)); /* add k to y's exponent */
+ return y*twom1000;
+ }
+}
diff --git a/StdLib/LibC/Math/e_fmod.c b/StdLib/LibC/Math/e_fmod.c
new file mode 100644
index 0000000000..3cb06c12b0
--- /dev/null
+++ b/StdLib/LibC/Math/e_fmod.c
@@ -0,0 +1,138 @@
+/* @(#)e_fmod.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: e_fmod.c,v 1.11 2002/05/26 22:01:49 wiz Exp $");
+#endif
+
+/*
+ * __ieee754_fmod(x,y)
+ * Return x mod y in exact arithmetic
+ * Method: shift and subtract
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
+ // unary minus operator applied to unsigned type, result still unsigned
+ #pragma warning ( disable : 4146 )
+#endif
+
+static const double one = 1.0, Zero[] = {0.0, -0.0,};
+
+double
+__ieee754_fmod(double x, double y)
+{
+ int32_t n,hx,hy,hz,ix,iy,sx,i;
+ u_int32_t lx,ly,lz;
+
+ EXTRACT_WORDS(hx,lx,x);
+ EXTRACT_WORDS(hy,ly,y);
+ sx = hx&0x80000000; /* sign of x */
+ hx ^=sx; /* |x| */
+ hy &= 0x7fffffff; /* |y| */
+
+ /* purge off exception values */
+ if((hy|ly)==0||(hx>=0x7ff00000)|| /* y=0,or x not finite */
+ ((hy|((ly|-ly)>>31))>0x7ff00000)) /* or y is NaN */
+ return (x*y)/(x*y);
+ if(hx<=hy) {
+ if((hx<hy)||(lx<ly)) return x; /* |x|<|y| return x */
+ if(lx==ly)
+ return Zero[(u_int32_t)sx>>31]; /* |x|=|y| return x*0*/
+ }
+
+ /* determine ix = ilogb(x) */
+ if(hx<0x00100000) { /* subnormal x */
+ if(hx==0) {
+ for (ix = -1043, i=lx; i>0; i<<=1) ix -=1;
+ } else {
+ for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1;
+ }
+ } else ix = (hx>>20)-1023;
+
+ /* determine iy = ilogb(y) */
+ if(hy<0x00100000) { /* subnormal y */
+ if(hy==0) {
+ for (iy = -1043, i=ly; i>0; i<<=1) iy -=1;
+ } else {
+ for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1;
+ }
+ } else iy = (hy>>20)-1023;
+
+ /* set up {hx,lx}, {hy,ly} and align y to x */
+ if(ix >= -1022)
+ hx = 0x00100000|(0x000fffff&hx);
+ else { /* subnormal x, shift x to normal */
+ n = -1022-ix;
+ if(n<=31) {
+ hx = (hx<<n)|(lx>>(32-n));
+ lx <<= n;
+ } else {
+ hx = lx<<(n-32);
+ lx = 0;
+ }
+ }
+ if(iy >= -1022)
+ hy = 0x00100000|(0x000fffff&hy);
+ else { /* subnormal y, shift y to normal */
+ n = -1022-iy;
+ if(n<=31) {
+ hy = (hy<<n)|(ly>>(32-n));
+ ly <<= n;
+ } else {
+ hy = ly<<(n-32);
+ ly = 0;
+ }
+ }
+
+ /* fix point fmod */
+ n = ix - iy;
+ while(n--) {
+ hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
+ if(hz<0){hx = hx+hx+(lx>>31); lx = lx+lx;}
+ else {
+ if((hz|lz)==0) /* return sign(x)*0 */
+ return Zero[(u_int32_t)sx>>31];
+ hx = hz+hz+(lz>>31); lx = lz+lz;
+ }
+ }
+ hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
+ if(hz>=0) {hx=hz;lx=lz;}
+
+ /* convert back to floating value and restore the sign */
+ if((hx|lx)==0) /* return sign(x)*0 */
+ return Zero[(u_int32_t)sx>>31];
+ while(hx<0x00100000) { /* normalize x */
+ hx = hx+hx+(lx>>31); lx = lx+lx;
+ iy -= 1;
+ }
+ if(iy>= -1022) { /* normalize output */
+ hx = ((hx-0x00100000)|((iy+1023)<<20));
+ INSERT_WORDS(x,hx|sx,lx);
+ } else { /* subnormal output */
+ n = -1022 - iy;
+ if(n<=20) {
+ lx = (lx>>n)|((u_int32_t)hx<<(32-n));
+ hx >>= n;
+ } else if (n<=31) {
+ lx = (hx<<(32-n))|(lx>>n); hx = sx;
+ } else {
+ lx = hx>>(n-32); hx = sx;
+ }
+ INSERT_WORDS(x,hx|sx,lx);
+ x *= one; /* create necessary signal */
+ }
+ return x; /* exact output */
+}
diff --git a/StdLib/LibC/Math/e_log.c b/StdLib/LibC/Math/e_log.c
new file mode 100644
index 0000000000..979b7f9421
--- /dev/null
+++ b/StdLib/LibC/Math/e_log.c
@@ -0,0 +1,155 @@
+/** @file
+ Compute the logrithm of x.
+
+ Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+
+ e_log.c 5.1 93/09/24
+ NetBSD: e_log.c,v 1.12 2002/05/26 22:01:51 wiz Exp
+**/
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
+ // potential divide by 0 -- near line 118, (x-x)/zero is on purpose
+ #pragma warning ( disable : 4723 )
+#endif
+
+/* __ieee754_log(x)
+ * Return the logrithm of x
+ *
+ * Method :
+ * 1. Argument Reduction: find k and f such that
+ * x = 2^k * (1+f),
+ * where sqrt(2)/2 < 1+f < sqrt(2) .
+ *
+ * 2. Approximation of log(1+f).
+ * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
+ * = 2s + 2/3 s**3 + 2/5 s**5 + .....,
+ * = 2s + s*R
+ * We use a special Reme algorithm on [0,0.1716] to generate
+ * a polynomial of degree 14 to approximate R The maximum error
+ * of this polynomial approximation is bounded by 2**-58.45. In
+ * other words,
+ * 2 4 6 8 10 12 14
+ * R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s +Lg6*s +Lg7*s
+ * (the values of Lg1 to Lg7 are listed in the program)
+ * and
+ * | 2 14 | -58.45
+ * | Lg1*s +...+Lg7*s - R(z) | <= 2
+ * | |
+ * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2.
+ * In order to guarantee error in log below 1ulp, we compute log
+ * by
+ * log(1+f) = f - s*(f - R) (if f is not too large)
+ * log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy)
+ *
+ * 3. Finally, log(x) = k*ln2 + log(1+f).
+ * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo)))
+ * Here ln2 is split into two floating point number:
+ * ln2_hi + ln2_lo,
+ * where n*ln2_hi is always exact for |n| < 2000.
+ *
+ * Special cases:
+ * log(x) is NaN with signal if x < 0 (including -INF) ;
+ * log(+INF) is +INF; log(0) is -INF with signal;
+ * log(NaN) is that NaN with no signal.
+ *
+ * Accuracy:
+ * according to an error analysis, the error is always less than
+ * 1 ulp (unit in the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "math.h"
+#include "math_private.h"
+#include <errno.h>
+
+static const double
+ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */
+ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */
+two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */
+Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */
+Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */
+Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */
+Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */
+Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */
+Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */
+Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */
+
+static const double zero = 0.0;
+
+double
+__ieee754_log(double x)
+{
+ double hfsq,f,s,z,R,w,t1,t2,dk;
+ int32_t k,hx,i,j;
+ u_int32_t lx;
+
+ EXTRACT_WORDS(hx,lx,x);
+
+ k=0;
+ if (hx < 0x00100000) { /* x < 2**-1022 */
+ if (((hx&0x7fffffff)|lx)==0)
+ return -two54/zero; /* log(+-0)=-inf */
+ if (hx<0) {
+ errno = EDOM;
+ return (x-x)/zero; /* log(-#) = NaN */
+ }
+ k -= 54; x *= two54; /* subnormal number, scale up x */
+ GET_HIGH_WORD(hx,x);
+ }
+ if (hx >= 0x7ff00000) return x+x;
+ k += (hx>>20)-1023;
+ hx &= 0x000fffff;
+ i = (hx+0x95f64)&0x100000;
+ SET_HIGH_WORD(x,hx|(i^0x3ff00000)); /* normalize x or x/2 */
+ k += (i>>20);
+ f = x-1.0;
+ if((0x000fffff&(2+hx))<3) { /* |f| < 2**-20 */
+ if(f==zero) { if(k==0) return zero; else {dk=(double)k;
+ return dk*ln2_hi+dk*ln2_lo;}
+ }
+ R = f*f*(0.5-0.33333333333333333*f);
+ if(k==0) return f-R; else {dk=(double)k;
+ return dk*ln2_hi-((R-dk*ln2_lo)-f);}
+ }
+ s = f/(2.0+f);
+ dk = (double)k;
+ z = s*s;
+ i = hx-0x6147a;
+ w = z*z;
+ j = 0x6b851-hx;
+ t1= w*(Lg2+w*(Lg4+w*Lg6));
+ t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
+ i |= j;
+ R = t2+t1;
+ if(i>0) {
+ hfsq=0.5*f*f;
+ if(k==0) return f-(hfsq-s*(hfsq+R)); else
+ return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f);
+ } else {
+ if(k==0) return f-s*(f-R); else
+ return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f);
+ }
+}
diff --git a/StdLib/LibC/Math/e_log10.c b/StdLib/LibC/Math/e_log10.c
new file mode 100644
index 0000000000..141dd6752a
--- /dev/null
+++ b/StdLib/LibC/Math/e_log10.c
@@ -0,0 +1,106 @@
+/** @file
+ Compute the base 10 logrithm of x.
+
+ Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+
+ e_log10.c 5.1 93/09/24
+ NetBSD: e_log10.c,v 1.12 2002/05/26 22:01:51 wiz Exp
+**/
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+/* __ieee754_log10(x)
+ * Return the base 10 logarithm of x
+ *
+ * Method :
+ * Let log10_2hi = leading 40 bits of log10(2) and
+ * log10_2lo = log10(2) - log10_2hi,
+ * ivln10 = 1/log(10) rounded.
+ * Then
+ * n = ilogb(x),
+ * if(n<0) n = n+1;
+ * x = scalbn(x,-n);
+ * log10(x) := n*log10_2hi + (n*log10_2lo + ivln10*log(x))
+ *
+ * Note 1:
+ * To guarantee log10(10**n)=n, where 10**n is normal, the rounding
+ * mode must set to Round-to-Nearest.
+ * Note 2:
+ * [1/log(10)] rounded to 53 bits has error .198 ulps;
+ * log10 is monotonic at all binary break points.
+ *
+ * Special cases:
+ * log10(x) is NaN with signal if x < 0;
+ * log10(+INF) is +INF with no signal; log10(0) is -INF with signal;
+ * log10(NaN) is that NaN with no signal;
+ * log10(10**N) = N for N=0,1,...,22.
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include "math.h"
+#include "math_private.h"
+#include <errno.h>
+
+#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
+ // potential divide by 0 -- near line 80, (x-x)/zero is on purpose
+ #pragma warning ( disable : 4723 )
+#endif
+
+static const double
+two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
+ivln10 = 4.34294481903251816668e-01, /* 0x3FDBCB7B, 0x1526E50E */
+log10_2hi = 3.01029995663611771306e-01, /* 0x3FD34413, 0x509F6000 */
+log10_2lo = 3.69423907715893078616e-13; /* 0x3D59FEF3, 0x11F12B36 */
+
+static const double zero = 0.0;
+
+double
+__ieee754_log10(double x)
+{
+ double y,z;
+ int32_t i,k,hx;
+ u_int32_t lx;
+
+ EXTRACT_WORDS(hx,lx,x);
+
+ k=0;
+ if (hx < 0x00100000) { /* x < 2**-1022 */
+ if (((hx&0x7fffffff)|lx)==0)
+ return -two54/zero; /* log(+-0)=-inf */
+ if (hx<0) {
+ errno = EDOM;
+ return (x-x)/zero; /* log(-#) = NaN */
+ }
+ k -= 54; x *= two54; /* subnormal number, scale up x */
+ GET_HIGH_WORD(hx,x);
+ }
+ if (hx >= 0x7ff00000) return x+x;
+ k += (hx>>20)-1023;
+ i = ((u_int32_t)k&0x80000000)>>31;
+ hx = (hx&0x000fffff)|((0x3ff-i)<<20);
+ y = (double)(k+i);
+ SET_HIGH_WORD(x,hx);
+ z = y*log10_2lo + ivln10*__ieee754_log(x);
+ return z+y*log10_2hi;
+}
diff --git a/StdLib/LibC/Math/e_log2.c b/StdLib/LibC/Math/e_log2.c
new file mode 100644
index 0000000000..5d15cd3b01
--- /dev/null
+++ b/StdLib/LibC/Math/e_log2.c
@@ -0,0 +1,85 @@
+
+/* @(#)e_log.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: e_log2.c,v 1.1 2005/07/21 12:55:58 christos Exp $");
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
+ // potential divide by 0 -- near line 53, (x-x)/zero is on purpose
+ #pragma warning ( disable : 4723 )
+#endif
+
+static const double
+ln2 = 0.6931471805599452862268,
+two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */
+Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */
+Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */
+Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */
+Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */
+Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */
+Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */
+Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */
+
+static const double zero = 0.0;
+
+double
+__ieee754_log2(double x)
+{
+ double hfsq,f,s,z,R,w,t1,t2,dk;
+ int32_t k,hx,i,j;
+ u_int32_t lx;
+
+ EXTRACT_WORDS(hx,lx,x);
+
+ k=0;
+ if (hx < 0x00100000) { /* x < 2**-1022 */
+ if (((hx&0x7fffffff)|lx)==0)
+ return -two54/zero; /* log(+-0)=-inf */
+ if (hx<0) return (x-x)/zero; /* log(-#) = NaN */
+ k -= 54; x *= two54; /* subnormal number, scale up x */
+ GET_HIGH_WORD(hx,x);
+ }
+ if (hx >= 0x7ff00000) return x+x;
+ k += (hx>>20)-1023;
+ hx &= 0x000fffff;
+ i = (hx+0x95f64)&0x100000;
+ SET_HIGH_WORD(x,hx|(i^0x3ff00000)); /* normalize x or x/2 */
+ k += (i>>20);
+ f = x-1.0;
+ dk = (double)k;
+ if((0x000fffff&(2+hx))<3) { /* |f| < 2**-20 */
+ if (f==zero)
+ return (dk);
+ R = f*f*(0.5-0.33333333333333333*f);
+ return (dk-(R-f)/ln2);
+ }
+ s = f/(2.0+f);
+ z = s*s;
+ i = hx-0x6147a;
+ w = z*z;
+ j = 0x6b851-hx;
+ t1= w*(Lg2+w*(Lg4+w*Lg6));
+ t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
+ i |= j;
+ R = t2+t1;
+ if(i>0) {
+ hfsq=0.5*f*f;
+ return (dk-(hfsq-s*(hfsq+R)-f)/ln2);
+ } else
+ return (dk-((s*(f-R))-f)/ln2);
+}
diff --git a/StdLib/LibC/Math/e_pow.c b/StdLib/LibC/Math/e_pow.c
new file mode 100644
index 0000000000..6d2286b41a
--- /dev/null
+++ b/StdLib/LibC/Math/e_pow.c
@@ -0,0 +1,323 @@
+/** @file
+ Compute the base 10 logrithm of x.
+
+ Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+
+ e_pow.c 5.1 93/09/24
+ NetBSD: e_pow.c,v 1.13 2004/06/30 18:43:15 drochner Exp
+**/
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
+ // C4723: potential divide by zero.
+ #pragma warning ( disable : 4723 )
+ // C4756: overflow in constant arithmetic
+ #pragma warning ( disable : 4756 )
+#endif
+
+/* __ieee754_pow(x,y) return x**y
+ *
+ * n
+ * Method: Let x = 2 * (1+f)
+ * 1. Compute and return log2(x) in two pieces:
+ * log2(x) = w1 + w2,
+ * where w1 has 53-24 = 29 bit trailing zeros.
+ * 2. Perform y*log2(x) = n+y' by simulating multi-precision
+ * arithmetic, where |y'|<=0.5.
+ * 3. Return x**y = 2**n*exp(y'*log2)
+ *
+ * Special cases:
+ * 1. (anything) ** 0 is 1
+ * 2. (anything) ** 1 is itself
+ * 3. (anything) ** NAN is NAN
+ * 4. NAN ** (anything except 0) is NAN
+ * 5. +-(|x| > 1) ** +INF is +INF
+ * 6. +-(|x| > 1) ** -INF is +0
+ * 7. +-(|x| < 1) ** +INF is +0
+ * 8. +-(|x| < 1) ** -INF is +INF
+ * 9. +-1 ** +-INF is NAN
+ * 10. +0 ** (+anything except 0, NAN) is +0
+ * 11. -0 ** (+anything except 0, NAN, odd integer) is +0
+ * 12. +0 ** (-anything except 0, NAN) is +INF
+ * 13. -0 ** (-anything except 0, NAN, odd integer) is +INF
+ * 14. -0 ** (odd integer) = -( +0 ** (odd integer) )
+ * 15. +INF ** (+anything except 0,NAN) is +INF
+ * 16. +INF ** (-anything except 0,NAN) is +0
+ * 17. -INF ** (anything) = -0 ** (-anything)
+ * 18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer)
+ * 19. (-anything except 0 and inf) ** (non-integer) is NAN
+ *
+ * Accuracy:
+ * pow(x,y) returns x**y nearly rounded. In particular
+ * pow(integer,integer)
+ * always returns the correct integer provided it is
+ * representable.
+ *
+ * Constants :
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "math.h"
+#include "math_private.h"
+#include <errno.h>
+
+static const double
+bp[] = {1.0, 1.5,},
+dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */
+dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */
+zero = 0.0,
+one = 1.0,
+two = 2.0,
+two53 = 9007199254740992.0, /* 0x43400000, 0x00000000 */
+huge = 1.0e300,
+tiny = 1.0e-300,
+ /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
+L1 = 5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */
+L2 = 4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */
+L3 = 3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */
+L4 = 2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */
+L5 = 2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */
+L6 = 2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */
+P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */
+P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */
+P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */
+P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */
+P5 = 4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */
+lg2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */
+lg2_h = 6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */
+lg2_l = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */
+ovt = 8.0085662595372944372e-0017, /* -(1024-log2(ovfl+.5ulp)) */
+cp = 9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */
+cp_h = 9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */
+cp_l = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/
+ivln2 = 1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */
+ivln2_h = 1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/
+ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/
+
+double
+__ieee754_pow(double x, double y)
+{
+ double z,ax,z_h,z_l,p_h,p_l;
+ double y1,t1,t2,r,s,t,u,v,w;
+ int32_t i,j,k,yisint,n;
+ int32_t hx,hy,ix,iy;
+ u_int32_t lx,ly;
+
+ EXTRACT_WORDS(hx,lx,x);
+ EXTRACT_WORDS(hy,ly,y);
+ ix = hx&0x7fffffff; iy = hy&0x7fffffff;
+
+ /* y==zero: x**0 = 1 */
+ if((iy|ly)==0) return one;
+
+ /* +-NaN return x+y */
+ if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)) ||
+ iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0)))
+ return x+y;
+
+ /* determine if y is an odd int when x < 0
+ * yisint = 0 ... y is not an integer
+ * yisint = 1 ... y is an odd int
+ * yisint = 2 ... y is an even int
+ */
+ yisint = 0;
+ if(hx<0) {
+ if(iy>=0x43400000) yisint = 2; /* even integer y */
+ else if(iy>=0x3ff00000) {
+ k = (iy>>20)-0x3ff; /* exponent */
+ if(k>20) {
+ j = ly>>(52-k);
+ if((u_int32_t)(j<<(52-k))==ly) yisint = 2-(j&1);
+ } else if(ly==0) {
+ j = iy>>(20-k);
+ if((j<<(20-k))==iy) yisint = 2-(j&1);
+ }
+ }
+ }
+
+ /* special value of y */
+ if(ly==0) {
+ if (iy==0x7ff00000) { /* y is +-inf */
+ if(((ix-0x3ff00000)|lx)==0)
+ return y - y; /* inf**+-1 is NaN */
+ else if (ix >= 0x3ff00000)/* (|x|>1)**+-inf = inf,0 */
+ return (hy>=0)? y: zero;
+ else /* (|x|<1)**-,+inf = inf,0 */
+ return (hy<0)?-y: zero;
+ }
+ if(iy==0x3ff00000) { /* y is +-1 */
+ if(hy<0) return one/x; else return x;
+ }
+ if(hy==0x40000000) return x*x; /* y is 2 */
+ if(hy==0x3fe00000) { /* y is 0.5 */
+ if(hx>=0) /* x >= +0 */
+ return __ieee754_sqrt(x);
+ }
+ }
+
+ ax = fabs(x);
+ /* special value of x */
+ if(lx==0) {
+ if(ix==0x7ff00000||ix==0||ix==0x3ff00000){
+ z = ax; /*x is +-0,+-inf,+-1*/
+ if(hy<0) z = one/z; /* z = (1/|x|) */
+ if(hx<0) {
+ if(((ix-0x3ff00000)|yisint)==0) {
+ z = (z-z)/(z-z); /* (-1)**non-int is NaN */
+ } else if(yisint==1)
+ z = -z; /* (x<0)**odd = -(|x|**odd) */
+ }
+ return z;
+ }
+ }
+
+ n = (hx>>31)+1;
+
+ /* (x<0)**(non-int) is NaN */
+ if((n|yisint)==0) {
+ errno = EDOM;
+ return (x-x)/(x-x);
+ }
+
+ s = one; /* s (sign of result -ve**odd) = -1 else = 1 */
+ if((n|(yisint-1))==0) s = -one;/* (-ve)**(odd int) */
+
+ /* |y| is huge */
+ if(iy>0x41e00000) { /* if |y| > 2**31 */
+ if(iy>0x43f00000){ /* if |y| > 2**64, must o/uflow */
+ if(ix<=0x3fefffff) return (hy<0)? huge*huge:tiny*tiny;
+ if(ix>=0x3ff00000) return (hy>0)? huge*huge:tiny*tiny;
+ }
+ /* over/underflow if x is not close to one */
+ if(ix<0x3fefffff) return (hy<0)? s*huge*huge:s*tiny*tiny;
+ if(ix>0x3ff00000) return (hy>0)? s*huge*huge:s*tiny*tiny;
+ /* now |1-x| is tiny <= 2**-20, suffice to compute
+ log(x) by x-x^2/2+x^3/3-x^4/4 */
+ t = ax-one; /* t has 20 trailing zeros */
+ w = (t*t)*(0.5-t*(0.3333333333333333333333-t*0.25));
+ u = ivln2_h*t; /* ivln2_h has 21 sig. bits */
+ v = t*ivln2_l-w*ivln2;
+ t1 = u+v;
+ SET_LOW_WORD(t1,0);
+ t2 = v-(t1-u);
+ } else {
+ double ss,s2,s_h,s_l,t_h,t_l;
+ n = 0;
+ /* take care subnormal number */
+ if(ix<0x00100000)
+ {ax *= two53; n -= 53; GET_HIGH_WORD(ix,ax); }
+ n += ((ix)>>20)-0x3ff;
+ j = ix&0x000fffff;
+ /* determine interval */
+ ix = j|0x3ff00000; /* normalize ix */
+ if(j<=0x3988E) k=0; /* |x|<sqrt(3/2) */
+ else if(j<0xBB67A) k=1; /* |x|<sqrt(3) */
+ else {k=0;n+=1;ix -= 0x00100000;}
+ SET_HIGH_WORD(ax,ix);
+
+ /* compute ss = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
+ u = ax-bp[k]; /* bp[0]=1.0, bp[1]=1.5 */
+ v = one/(ax+bp[k]);
+ ss = u*v;
+ s_h = ss;
+ SET_LOW_WORD(s_h,0);
+ /* t_h=ax+bp[k] High */
+ t_h = zero;
+ SET_HIGH_WORD(t_h,((ix>>1)|0x20000000)+0x00080000+(k<<18));
+ t_l = ax - (t_h-bp[k]);
+ s_l = v*((u-s_h*t_h)-s_h*t_l);
+ /* compute log(ax) */
+ s2 = ss*ss;
+ r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6)))));
+ r += s_l*(s_h+ss);
+ s2 = s_h*s_h;
+ t_h = 3.0+s2+r;
+ SET_LOW_WORD(t_h,0);
+ t_l = r-((t_h-3.0)-s2);
+ /* u+v = ss*(1+...) */
+ u = s_h*t_h;
+ v = s_l*t_h+t_l*ss;
+ /* 2/(3log2)*(ss+...) */
+ p_h = u+v;
+ SET_LOW_WORD(p_h,0);
+ p_l = v-(p_h-u);
+ z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */
+ z_l = cp_l*p_h+p_l*cp+dp_l[k];
+ /* log2(ax) = (ss+..)*2/(3*log2) = n + dp_h + z_h + z_l */
+ t = (double)n;
+ t1 = (((z_h+z_l)+dp_h[k])+t);
+ SET_LOW_WORD(t1,0);
+ t2 = z_l-(((t1-t)-dp_h[k])-z_h);
+ }
+
+ /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
+ y1 = y;
+ SET_LOW_WORD(y1,0);
+ p_l = (y-y1)*t1+y*t2;
+ p_h = y1*t1;
+ z = p_l+p_h;
+ EXTRACT_WORDS(j,i,z);
+ if (j>=0x40900000) { /* z >= 1024 */
+ if(((j-0x40900000)|i)!=0) /* if z > 1024 */
+ return s*huge*huge; /* overflow */
+ else {
+ if(p_l+ovt>z-p_h) return s*huge*huge; /* overflow */
+ }
+ } else if((j&0x7fffffff)>=0x4090cc00 ) { /* z <= -1075 */
+ if(((j-0xc090cc00)|i)!=0) /* z < -1075 */
+ return s*tiny*tiny; /* underflow */
+ else {
+ if(p_l<=z-p_h) return s*tiny*tiny; /* underflow */
+ }
+ }
+ /*
+ * compute 2**(p_h+p_l)
+ */
+ i = j&0x7fffffff;
+ k = (i>>20)-0x3ff;
+ n = 0;
+ if(i>0x3fe00000) { /* if |z| > 0.5, set n = [z+0.5] */
+ n = j+(0x00100000>>(k+1));
+ k = ((n&0x7fffffff)>>20)-0x3ff; /* new k for n */
+ t = zero;
+ SET_HIGH_WORD(t,n&~(0x000fffff>>k));
+ n = ((n&0x000fffff)|0x00100000)>>(20-k);
+ if(j<0) n = -n;
+ p_h -= t;
+ }
+ t = p_l+p_h;
+ SET_LOW_WORD(t,0);
+ u = t*lg2_h;
+ v = (p_l-(t-p_h))*lg2+t*lg2_l;
+ z = u+v;
+ w = v-(z-u);
+ t = z*z;
+ t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
+ r = (z*t1)/(t1-two)-(w+z*w);
+ z = one-(r-z);
+ GET_HIGH_WORD(j,z);
+ j += (n<<20);
+ if((j>>20)<=0) z = scalbn(z,n); /* subnormal output */
+ else SET_HIGH_WORD(z,j);
+ return s*z;
+}
diff --git a/StdLib/LibC/Math/e_rem_pio2.c b/StdLib/LibC/Math/e_rem_pio2.c
new file mode 100644
index 0000000000..7b06d1775f
--- /dev/null
+++ b/StdLib/LibC/Math/e_rem_pio2.c
@@ -0,0 +1,169 @@
+/* @(#)e_rem_pio2.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: e_rem_pio2.c,v 1.11 2002/05/26 22:01:52 wiz Exp $");
+#endif
+
+/* __ieee754_rem_pio2(x,y)
+ *
+ * return the remainder of x rem pi/2 in y[0]+y[1]
+ * use __kernel_rem_pio2()
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+/*
+ * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi
+ */
+static const int32_t two_over_pi[] = {
+0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62,
+0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A,
+0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129,
+0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41,
+0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8,
+0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF,
+0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5,
+0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08,
+0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3,
+0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880,
+0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B,
+};
+
+static const int32_t npio2_hw[] = {
+0x3FF921FB, 0x400921FB, 0x4012D97C, 0x401921FB, 0x401F6A7A, 0x4022D97C,
+0x4025FDBB, 0x402921FB, 0x402C463A, 0x402F6A7A, 0x4031475C, 0x4032D97C,
+0x40346B9C, 0x4035FDBB, 0x40378FDB, 0x403921FB, 0x403AB41B, 0x403C463A,
+0x403DD85A, 0x403F6A7A, 0x40407E4C, 0x4041475C, 0x4042106C, 0x4042D97C,
+0x4043A28C, 0x40446B9C, 0x404534AC, 0x4045FDBB, 0x4046C6CB, 0x40478FDB,
+0x404858EB, 0x404921FB,
+};
+
+/*
+ * invpio2: 53 bits of 2/pi
+ * pio2_1: first 33 bit of pi/2
+ * pio2_1t: pi/2 - pio2_1
+ * pio2_2: second 33 bit of pi/2
+ * pio2_2t: pi/2 - (pio2_1+pio2_2)
+ * pio2_3: third 33 bit of pi/2
+ * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3)
+ */
+
+static const double
+zero = 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
+half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
+two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
+invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
+pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */
+pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */
+pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */
+pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */
+pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */
+pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */
+
+int32_t
+__ieee754_rem_pio2(double x, double *y)
+{
+ double z,w,t,r,fn;
+ double tx[3];
+ int32_t e0,i,j,nx,n,ix,hx;
+ u_int32_t low;
+
+ z = 0;
+ GET_HIGH_WORD(hx,x); /* high word of x */
+ ix = hx&0x7fffffff;
+ if(ix<=0x3fe921fb) /* |x| ~<= pi/4 , no need for reduction */
+ {y[0] = x; y[1] = 0; return 0;}
+ if(ix<0x4002d97c) { /* |x| < 3pi/4, special case with n=+-1 */
+ if(hx>0) {
+ z = x - pio2_1;
+ if(ix!=0x3ff921fb) { /* 33+53 bit pi is good enough */
+ y[0] = z - pio2_1t;
+ y[1] = (z-y[0])-pio2_1t;
+ } else { /* near pi/2, use 33+33+53 bit pi */
+ z -= pio2_2;
+ y[0] = z - pio2_2t;
+ y[1] = (z-y[0])-pio2_2t;
+ }
+ return 1;
+ } else { /* negative x */
+ z = x + pio2_1;
+ if(ix!=0x3ff921fb) { /* 33+53 bit pi is good enough */
+ y[0] = z + pio2_1t;
+ y[1] = (z-y[0])+pio2_1t;
+ } else { /* near pi/2, use 33+33+53 bit pi */
+ z += pio2_2;
+ y[0] = z + pio2_2t;
+ y[1] = (z-y[0])+pio2_2t;
+ }
+ return -1;
+ }
+ }
+ if(ix<=0x413921fb) { /* |x| ~<= 2^19*(pi/2), medium size */
+ t = fabs(x);
+ n = (int32_t) (t*invpio2+half);
+ fn = (double)n;
+ r = t-fn*pio2_1;
+ w = fn*pio2_1t; /* 1st round good to 85 bit */
+ if(n<32&&ix!=npio2_hw[n-1]) {
+ y[0] = r-w; /* quick check no cancellation */
+ } else {
+ u_int32_t high;
+ j = ix>>20;
+ y[0] = r-w;
+ GET_HIGH_WORD(high,y[0]);
+ i = j-((high>>20)&0x7ff);
+ if(i>16) { /* 2nd iteration needed, good to 118 */
+ t = r;
+ w = fn*pio2_2;
+ r = t-w;
+ w = fn*pio2_2t-((t-r)-w);
+ y[0] = r-w;
+ GET_HIGH_WORD(high,y[0]);
+ i = j-((high>>20)&0x7ff);
+ if(i>49) { /* 3rd iteration need, 151 bits acc */
+ t = r; /* will cover all possible cases */
+ w = fn*pio2_3;
+ r = t-w;
+ w = fn*pio2_3t-((t-r)-w);
+ y[0] = r-w;
+ }
+ }
+ }
+ y[1] = (r-y[0])-w;
+ if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
+ else return n;
+ }
+ /*
+ * all other (large) arguments
+ */
+ if(ix>=0x7ff00000) { /* x is inf or NaN */
+ y[0]=y[1]=x-x; return 0;
+ }
+ /* set z = scalbn(|x|,ilogb(x)-23) */
+ GET_LOW_WORD(low,x);
+ SET_LOW_WORD(z,low);
+ e0 = (ix>>20)-1046; /* e0 = ilogb(z)-23; */
+ SET_HIGH_WORD(z, ix - ((int32_t)(e0<<20)));
+ for(i=0;i<2;i++) {
+ tx[i] = (double)((int32_t)(z));
+ z = (z-tx[i])*two24;
+ }
+ tx[2] = z;
+ nx = 3;
+ while(tx[nx-1]==zero) nx--; /* skip zero term */
+ n = __kernel_rem_pio2(tx,y,e0,nx,2,two_over_pi);
+ if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
+ return n;
+}
diff --git a/StdLib/LibC/Math/e_sinh.c b/StdLib/LibC/Math/e_sinh.c
new file mode 100644
index 0000000000..421b515cd4
--- /dev/null
+++ b/StdLib/LibC/Math/e_sinh.c
@@ -0,0 +1,79 @@
+/* @(#)e_sinh.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: e_sinh.c,v 1.11 2002/05/26 22:01:52 wiz Exp $");
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+/* __ieee754_sinh(x)
+ * Method :
+ * mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2
+ * 1. Replace x by |x| (sinh(-x) = -sinh(x)).
+ * 2.
+ * E + E/(E+1)
+ * 0 <= x <= 22 : sinh(x) := --------------, E=expm1(x)
+ * 2
+ *
+ * 22 <= x <= lnovft : sinh(x) := exp(x)/2
+ * lnovft <= x <= ln2ovft: sinh(x) := exp(x/2)/2 * exp(x/2)
+ * ln2ovft < x : sinh(x) := x*shuge (overflow)
+ *
+ * Special cases:
+ * sinh(x) is |x| if x is +INF, -INF, or NaN.
+ * only sinh(0)=0 is exact for finite x.
+ */
+
+static const double one = 1.0, shuge = 1.0e307;
+
+double
+__ieee754_sinh(double x)
+{
+ double t,w,h;
+ int32_t ix,jx;
+ u_int32_t lx;
+
+ /* High word of |x|. */
+ GET_HIGH_WORD(jx,x);
+ ix = jx&0x7fffffff;
+
+ /* x is INF or NaN */
+ if(ix>=0x7ff00000) return x+x;
+
+ h = 0.5;
+ if (jx<0) h = -h;
+ /* |x| in [0,22], return sign(x)*0.5*(E+E/(E+1))) */
+ if (ix < 0x40360000) { /* |x|<22 */
+ if (ix<0x3e300000) /* |x|<2**-28 */
+ if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */
+ t = expm1(fabs(x));
+ if(ix<0x3ff00000) return h*(2.0*t-t*t/(t+one));
+ return h*(t+t/(t+one));
+ }
+
+ /* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */
+ if (ix < 0x40862E42) return h*__ieee754_exp(fabs(x));
+
+ /* |x| in [log(maxdouble), overflowthresold] */
+ GET_LOW_WORD(lx,x);
+ if (ix<0x408633CE || ((ix==0x408633ce)&&(lx<=(u_int32_t)0x8fb9f87d))) {
+ w = __ieee754_exp(0.5*fabs(x));
+ t = h*w;
+ return t*w;
+ }
+
+ /* |x| > overflowthresold, sinh(x) overflow */
+ return x*shuge;
+}
diff --git a/StdLib/LibC/Math/e_sqrt.c b/StdLib/LibC/Math/e_sqrt.c
new file mode 100644
index 0000000000..2a772f60b4
--- /dev/null
+++ b/StdLib/LibC/Math/e_sqrt.c
@@ -0,0 +1,464 @@
+/** @file
+ Compute the logrithm of x.
+
+ Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+
+ e_sqrt.c 5.1 93/09/24
+ NetBSD: e_sqrt.c,v 1.12 2002/05/26 22:01:52 wiz Exp
+**/
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#include <errno.h>
+#include "math.h"
+#include "math_private.h"
+
+#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
+// potential divide by 0 -- near line 129, (x-x)/(x-x) is on purpose
+#pragma warning ( disable : 4723 )
+#endif
+
+/* __ieee754_sqrt(x)
+ * Return correctly rounded sqrt.
+ * ------------------------------------------
+ * | Use the hardware sqrt if you have one |
+ * ------------------------------------------
+ * Method:
+ * Bit by bit method using integer arithmetic. (Slow, but portable)
+ * 1. Normalization
+ * Scale x to y in [1,4) with even powers of 2:
+ * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then
+ * sqrt(x) = 2^k * sqrt(y)
+ * 2. Bit by bit computation
+ * Let q = sqrt(y) truncated to i bit after binary point (q = 1),
+ * i 0
+ * i+1 2
+ * s = 2*q , and y = 2 * ( y - q ). (1)
+ * i i i i
+ *
+ * To compute q from q , one checks whether
+ * i+1 i
+ *
+ * -(i+1) 2
+ * (q + 2 ) <= y. (2)
+ * i
+ * -(i+1)
+ * If (2) is false, then q = q ; otherwise q = q + 2 .
+ * i+1 i i+1 i
+ *
+ * With some algebric manipulation, it is not difficult to see
+ * that (2) is equivalent to
+ * -(i+1)
+ * s + 2 <= y (3)
+ * i i
+ *
+ * The advantage of (3) is that s and y can be computed by
+ * i i
+ * the following recurrence formula:
+ * if (3) is false
+ *
+ * s = s , y = y ; (4)
+ * i+1 i i+1 i
+ *
+ * otherwise,
+ * -i -(i+1)
+ * s = s + 2 , y = y - s - 2 (5)
+ * i+1 i i+1 i i
+ *
+ * One may easily use induction to prove (4) and (5).
+ * Note. Since the left hand side of (3) contain only i+2 bits,
+ * it does not necessary to do a full (53-bit) comparison
+ * in (3).
+ * 3. Final rounding
+ * After generating the 53 bits result, we compute one more bit.
+ * Together with the remainder, we can decide whether the
+ * result is exact, bigger than 1/2ulp, or less than 1/2ulp
+ * (it will never equal to 1/2ulp).
+ * The rounding mode can be detected by checking whether
+ * huge + tiny is equal to huge, and whether huge - tiny is
+ * equal to huge for some floating point number "huge" and "tiny".
+ *
+ * Special cases:
+ * sqrt(+-0) = +-0 ... exact
+ * sqrt(inf) = inf
+ * sqrt(-ve) = NaN ... with invalid signal
+ * sqrt(NaN) = NaN ... with invalid signal for signaling NaN
+ *
+ * Other methods : see the appended file at the end of the program below.
+ *---------------
+ */
+
+static const double one = 1.0, tiny=1.0e-300;
+
+double
+__ieee754_sqrt(double x)
+{
+ double z;
+ int32_t sign = (int)0x80000000;
+ int32_t ix0,s0,q,m,t,i;
+ u_int32_t r,t1,s1,ix1,q1;
+
+ EXTRACT_WORDS(ix0,ix1,x);
+
+ /* take care of Inf and NaN */
+ if((ix0&0x7ff00000)==0x7ff00000) {
+ return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
+ sqrt(-inf)=sNaN */
+ }
+ /* take care of zero */
+ if(ix0<=0) {
+ if(((ix0&(~sign))|ix1)==0) return x;/* sqrt(+-0) = +-0 */
+ else if(ix0<0) {
+ errno = EDOM;
+ return (x-x)/(x-x); /* sqrt(-ve) = sNaN */
+ }
+ }
+ /* normalize x */
+ m = (ix0>>20);
+ if(m==0) { /* subnormal x */
+ while(ix0==0) {
+ m -= 21;
+ ix0 |= (ix1>>11); ix1 <<= 21;
+ }
+ for(i=0;(ix0&0x00100000)==0;i++) ix0<<=1;
+ m -= i-1;
+ ix0 |= (ix1>>(32-i));
+ ix1 <<= i;
+ }
+ m -= 1023; /* unbias exponent */
+ ix0 = (ix0&0x000fffff)|0x00100000;
+ if(m&1){ /* odd m, double x to make it even */
+ ix0 += ix0 + ((ix1&sign)>>31);
+ ix1 += ix1;
+ }
+ m >>= 1; /* m = [m/2] */
+
+ /* generate sqrt(x) bit by bit */
+ ix0 += ix0 + ((ix1&sign)>>31);
+ ix1 += ix1;
+ q = q1 = s0 = s1 = 0; /* [q,q1] = sqrt(x) */
+ r = 0x00200000; /* r = moving bit from right to left */
+
+ while(r!=0) {
+ t = s0+r;
+ if(t<=ix0) {
+ s0 = t+r;
+ ix0 -= t;
+ q += r;
+ }
+ ix0 += ix0 + ((ix1&sign)>>31);
+ ix1 += ix1;
+ r>>=1;
+ }
+
+ r = sign;
+ while(r!=0) {
+ t1 = s1+r;
+ t = s0;
+ if((t<ix0)||((t==ix0)&&(t1<=ix1))) {
+ s1 = t1+r;
+ if(((t1&sign)==(u_int32_t)sign)&&(s1&sign)==0) s0 += 1;
+ ix0 -= t;
+ if (ix1 < t1) ix0 -= 1;
+ ix1 -= t1;
+ q1 += r;
+ }
+ ix0 += ix0 + ((ix1&sign)>>31);
+ ix1 += ix1;
+ r>>=1;
+ }
+
+ /* use floating add to find out rounding direction */
+ if((ix0|ix1)!=0) {
+ z = one-tiny; /* trigger inexact flag */
+ if (z>=one) {
+ z = one+tiny;
+ if (q1==(u_int32_t)0xffffffff) { q1=0; q += 1;}
+ else if (z>one) {
+ if (q1==(u_int32_t)0xfffffffe) q+=1;
+ q1+=2;
+ } else
+ q1 += (q1&1);
+ }
+ }
+ ix0 = (q>>1)+0x3fe00000;
+ ix1 = q1>>1;
+ if ((q&1)==1) ix1 |= sign;
+ ix0 += (m <<20);
+ INSERT_WORDS(z,ix0,ix1);
+ return z;
+}
+
+/*
+Other methods (use floating-point arithmetic)
+-------------
+(This is a copy of a drafted paper by Prof W. Kahan
+and K.C. Ng, written in May, 1986)
+
+ Two algorithms are given here to implement sqrt(x)
+ (IEEE double precision arithmetic) in software.
+ Both supply sqrt(x) correctly rounded. The first algorithm (in
+ Section A) uses newton iterations and involves four divisions.
+ The second one uses reciproot iterations to avoid division, but
+ requires more multiplications. Both algorithms need the ability
+ to chop results of arithmetic operations instead of round them,
+ and the INEXACT flag to indicate when an arithmetic operation
+ is executed exactly with no roundoff error, all part of the
+ standard (IEEE 754-1985). The ability to perform shift, add,
+ subtract and logical AND operations upon 32-bit words is needed
+ too, though not part of the standard.
+
+A. sqrt(x) by Newton Iteration
+
+ (1) Initial approximation
+
+ Let x0 and x1 be the leading and the trailing 32-bit words of
+ a floating point number x (in IEEE double format) respectively
+
+ 1 11 52 ...widths
+ ------------------------------------------------------
+ x: |s| e | f |
+ ------------------------------------------------------
+ msb lsb msb lsb ...order
+
+
+ ------------------------ ------------------------
+ x0: |s| e | f1 | x1: | f2 |
+ ------------------------ ------------------------
+
+ By performing shifts and subtracts on x0 and x1 (both regarded
+ as integers), we obtain an 8-bit approximation of sqrt(x) as
+ follows.
+
+ k := (x0>>1) + 0x1ff80000;
+ y0 := k - T1[31&(k>>15)]. ... y ~ sqrt(x) to 8 bits
+ Here k is a 32-bit integer and T1[] is an integer array containing
+ correction terms. Now magically the floating value of y (y's
+ leading 32-bit word is y0, the value of its trailing word is 0)
+ approximates sqrt(x) to almost 8-bit.
+
+ Value of T1:
+ static int T1[32]= {
+ 0, 1024, 3062, 5746, 9193, 13348, 18162, 23592,
+ 29598, 36145, 43202, 50740, 58733, 67158, 75992, 85215,
+ 83599, 71378, 60428, 50647, 41945, 34246, 27478, 21581,
+ 16499, 12183, 8588, 5674, 3403, 1742, 661, 130,};
+
+ (2) Iterative refinement
+
+ Apply Heron's rule three times to y, we have y approximates
+ sqrt(x) to within 1 ulp (Unit in the Last Place):
+
+ y := (y+x/y)/2 ... almost 17 sig. bits
+ y := (y+x/y)/2 ... almost 35 sig. bits
+ y := y-(y-x/y)/2 ... within 1 ulp
+
+
+ Remark 1.
+ Another way to improve y to within 1 ulp is:
+
+ y := (y+x/y) ... almost 17 sig. bits to 2*sqrt(x)
+ y := y - 0x00100006 ... almost 18 sig. bits to sqrt(x)
+
+ 2
+ (x-y )*y
+ y := y + 2* ---------- ...within 1 ulp
+ 2
+ 3y + x
+
+
+ This formula has one division fewer than the one above; however,
+ it requires more multiplications and additions. Also x must be
+ scaled in advance to avoid spurious overflow in evaluating the
+ expression 3y*y+x. Hence it is not recommended uless division
+ is slow. If division is very slow, then one should use the
+ reciproot algorithm given in section B.
+
+ (3) Final adjustment
+
+ By twiddling y's last bit it is possible to force y to be
+ correctly rounded according to the prevailing rounding mode
+ as follows. Let r and i be copies of the rounding mode and
+ inexact flag before entering the square root program. Also we
+ use the expression y+-ulp for the next representable floating
+ numbers (up and down) of y. Note that y+-ulp = either fixed
+ point y+-1, or multiply y by nextafter(1,+-inf) in chopped
+ mode.
+
+ I := FALSE; ... reset INEXACT flag I
+ R := RZ; ... set rounding mode to round-toward-zero
+ z := x/y; ... chopped quotient, possibly inexact
+ If(not I) then { ... if the quotient is exact
+ if(z=y) {
+ I := i; ... restore inexact flag
+ R := r; ... restore rounded mode
+ return sqrt(x):=y.
+ } else {
+ z := z - ulp; ... special rounding
+ }
+ }
+ i := TRUE; ... sqrt(x) is inexact
+ If (r=RN) then z=z+ulp ... rounded-to-nearest
+ If (r=RP) then { ... round-toward-+inf
+ y = y+ulp; z=z+ulp;
+ }
+ y := y+z; ... chopped sum
+ y0:=y0-0x00100000; ... y := y/2 is correctly rounded.
+ I := i; ... restore inexact flag
+ R := r; ... restore rounded mode
+ return sqrt(x):=y.
+
+ (4) Special cases
+
+ Square root of +inf, +-0, or NaN is itself;
+ Square root of a negative number is NaN with invalid signal.
+
+
+B. sqrt(x) by Reciproot Iteration
+
+ (1) Initial approximation
+
+ Let x0 and x1 be the leading and the trailing 32-bit words of
+ a floating point number x (in IEEE double format) respectively
+ (see section A). By performing shifs and subtracts on x0 and y0,
+ we obtain a 7.8-bit approximation of 1/sqrt(x) as follows.
+
+ k := 0x5fe80000 - (x0>>1);
+ y0:= k - T2[63&(k>>14)]. ... y ~ 1/sqrt(x) to 7.8 bits
+
+ Here k is a 32-bit integer and T2[] is an integer array
+ containing correction terms. Now magically the floating
+ value of y (y's leading 32-bit word is y0, the value of
+ its trailing word y1 is set to zero) approximates 1/sqrt(x)
+ to almost 7.8-bit.
+
+ Value of T2:
+ static int T2[64]= {
+ 0x1500, 0x2ef8, 0x4d67, 0x6b02, 0x87be, 0xa395, 0xbe7a, 0xd866,
+ 0xf14a, 0x1091b,0x11fcd,0x13552,0x14999,0x15c98,0x16e34,0x17e5f,
+ 0x18d03,0x19a01,0x1a545,0x1ae8a,0x1b5c4,0x1bb01,0x1bfde,0x1c28d,
+ 0x1c2de,0x1c0db,0x1ba73,0x1b11c,0x1a4b5,0x1953d,0x18266,0x16be0,
+ 0x1683e,0x179d8,0x18a4d,0x19992,0x1a789,0x1b445,0x1bf61,0x1c989,
+ 0x1d16d,0x1d77b,0x1dddf,0x1e2ad,0x1e5bf,0x1e6e8,0x1e654,0x1e3cd,
+ 0x1df2a,0x1d635,0x1cb16,0x1be2c,0x1ae4e,0x19bde,0x1868e,0x16e2e,
+ 0x1527f,0x1334a,0x11051,0xe951, 0xbe01, 0x8e0d, 0x5924, 0x1edd,};
+
+ (2) Iterative refinement
+
+ Apply Reciproot iteration three times to y and multiply the
+ result by x to get an approximation z that matches sqrt(x)
+ to about 1 ulp. To be exact, we will have
+ -1ulp < sqrt(x)-z<1.0625ulp.
+
+ ... set rounding mode to Round-to-nearest
+ y := y*(1.5-0.5*x*y*y) ... almost 15 sig. bits to 1/sqrt(x)
+ y := y*((1.5-2^-30)+0.5*x*y*y)... about 29 sig. bits to 1/sqrt(x)
+ ... special arrangement for better accuracy
+ z := x*y ... 29 bits to sqrt(x), with z*y<1
+ z := z + 0.5*z*(1-z*y) ... about 1 ulp to sqrt(x)
+
+ Remark 2. The constant 1.5-2^-30 is chosen to bias the error so that
+ (a) the term z*y in the final iteration is always less than 1;
+ (b) the error in the final result is biased upward so that
+ -1 ulp < sqrt(x) - z < 1.0625 ulp
+ instead of |sqrt(x)-z|<1.03125ulp.
+
+ (3) Final adjustment
+
+ By twiddling y's last bit it is possible to force y to be
+ correctly rounded according to the prevailing rounding mode
+ as follows. Let r and i be copies of the rounding mode and
+ inexact flag before entering the square root program. Also we
+ use the expression y+-ulp for the next representable floating
+ numbers (up and down) of y. Note that y+-ulp = either fixed
+ point y+-1, or multiply y by nextafter(1,+-inf) in chopped
+ mode.
+
+ R := RZ; ... set rounding mode to round-toward-zero
+ switch(r) {
+ case RN: ... round-to-nearest
+ if(x<= z*(z-ulp)...chopped) z = z - ulp; else
+ if(x<= z*(z+ulp)...chopped) z = z; else z = z+ulp;
+ break;
+ case RZ:case RM: ... round-to-zero or round-to--inf
+ R:=RP; ... reset rounding mod to round-to-+inf
+ if(x<z*z ... rounded up) z = z - ulp; else
+ if(x>=(z+ulp)*(z+ulp) ...rounded up) z = z+ulp;
+ break;
+ case RP: ... round-to-+inf
+ if(x>(z+ulp)*(z+ulp)...chopped) z = z+2*ulp; else
+ if(x>z*z ...chopped) z = z+ulp;
+ break;
+ }
+
+ Remark 3. The above comparisons can be done in fixed point. For
+ example, to compare x and w=z*z chopped, it suffices to compare
+ x1 and w1 (the trailing parts of x and w), regarding them as
+ two's complement integers.
+
+ ...Is z an exact square root?
+ To determine whether z is an exact square root of x, let z1 be the
+ trailing part of z, and also let x0 and x1 be the leading and
+ trailing parts of x.
+
+ If ((z1&0x03ffffff)!=0) ... not exact if trailing 26 bits of z!=0
+ I := 1; ... Raise Inexact flag: z is not exact
+ else {
+ j := 1 - [(x0>>20)&1] ... j = logb(x) mod 2
+ k := z1 >> 26; ... get z's 25-th and 26-th
+ fraction bits
+ I := i or (k&j) or ((k&(j+j+1))!=(x1&3));
+ }
+ R:= r ... restore rounded mode
+ return sqrt(x):=z.
+
+ If multiplication is cheaper than the foregoing red tape, the
+ Inexact flag can be evaluated by
+
+ I := i;
+ I := (z*z!=x) or I.
+
+ Note that z*z can overwrite I; this value must be sensed if it is
+ True.
+
+ Remark 4. If z*z = x exactly, then bit 25 to bit 0 of z1 must be
+ zero.
+
+ --------------------
+ z1: | f2 |
+ --------------------
+ bit 31 bit 0
+
+ Further more, bit 27 and 26 of z1, bit 0 and 1 of x1, and the odd
+ or even of logb(x) have the following relations:
+
+ -------------------------------------------------
+ bit 27,26 of z1 bit 1,0 of x1 logb(x)
+ -------------------------------------------------
+ 00 00 odd and even
+ 01 01 even
+ 10 10 odd
+ 10 00 even
+ 11 01 even
+ -------------------------------------------------
+
+ (4) Special cases (see (4) of Section A).
+
+ */
+
diff --git a/StdLib/LibC/Math/k_cos.c b/StdLib/LibC/Math/k_cos.c
new file mode 100644
index 0000000000..e1746a11d3
--- /dev/null
+++ b/StdLib/LibC/Math/k_cos.c
@@ -0,0 +1,89 @@
+/* @(#)k_cos.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: k_cos.c,v 1.11 2002/05/26 22:01:53 wiz Exp $");
+#endif
+
+/*
+ * __kernel_cos( x, y )
+ * kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164
+ * Input x is assumed to be bounded by ~pi/4 in magnitude.
+ * Input y is the tail of x.
+ *
+ * Algorithm
+ * 1. Since cos(-x) = cos(x), we need only to consider positive x.
+ * 2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0.
+ * 3. cos(x) is approximated by a polynomial of degree 14 on
+ * [0,pi/4]
+ * 4 14
+ * cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x
+ * where the remez error is
+ *
+ * | 2 4 6 8 10 12 14 | -58
+ * |cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x +C6*x )| <= 2
+ * | |
+ *
+ * 4 6 8 10 12 14
+ * 4. let r = C1*x +C2*x +C3*x +C4*x +C5*x +C6*x , then
+ * cos(x) = 1 - x*x/2 + r
+ * since cos(x+y) ~ cos(x) - sin(x)*y
+ * ~ cos(x) - x*y,
+ * a correction term is necessary in cos(x) and hence
+ * cos(x+y) = 1 - (x*x/2 - (r - x*y))
+ * For better accuracy when x > 0.3, let qx = |x|/4 with
+ * the last 32 bits mask off, and if x > 0.78125, let qx = 0.28125.
+ * Then
+ * cos(x+y) = (1-qx) - ((x*x/2-qx) - (r-x*y)).
+ * Note that 1-qx and (x*x/2-qx) is EXACT here, and the
+ * magnitude of the latter is at least a quarter of x*x/2,
+ * thus, reducing the rounding error in the subtraction.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+static const double
+one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+C1 = 4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */
+C2 = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */
+C3 = 2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */
+C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */
+C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */
+C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */
+
+double
+__kernel_cos(double x, double y)
+{
+ double a,hz,z,r,qx;
+ int32_t ix;
+ GET_HIGH_WORD(ix,x);
+ ix &= 0x7fffffff; /* ix = |x|'s high word*/
+ if(ix<0x3e400000) { /* if x < 2**27 */
+ if(((int)x)==0) return one; /* generate inexact */
+ }
+ z = x*x;
+ r = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*C6)))));
+ if(ix < 0x3FD33333) /* if |x| < 0.3 */
+ return one - (0.5*z - (z*r - x*y));
+ else {
+ if(ix > 0x3fe90000) { /* x > 0.78125 */
+ qx = 0.28125;
+ } else {
+ INSERT_WORDS(qx,ix-0x00200000,0); /* x/4 */
+ }
+ hz = 0.5*z-qx;
+ a = one-qx;
+ return a - (hz - (z*r-x*y));
+ }
+}
diff --git a/StdLib/LibC/Math/k_rem_pio2.c b/StdLib/LibC/Math/k_rem_pio2.c
new file mode 100644
index 0000000000..af2857778d
--- /dev/null
+++ b/StdLib/LibC/Math/k_rem_pio2.c
@@ -0,0 +1,305 @@
+/* @(#)k_rem_pio2.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: k_rem_pio2.c,v 1.11 2003/01/04 23:43:03 wiz Exp $");
+#endif
+
+/*
+ * __kernel_rem_pio2(x,y,e0,nx,prec,ipio2)
+ * double x[],y[]; int e0,nx,prec; int ipio2[];
+ *
+ * __kernel_rem_pio2 return the last three digits of N with
+ * y = x - N*pi/2
+ * so that |y| < pi/2.
+ *
+ * The method is to compute the integer (mod 8) and fraction parts of
+ * (2/pi)*x without doing the full multiplication. In general we
+ * skip the part of the product that are known to be a huge integer (
+ * more accurately, = 0 mod 8 ). Thus the number of operations are
+ * independent of the exponent of the input.
+ *
+ * (2/pi) is represented by an array of 24-bit integers in ipio2[].
+ *
+ * Input parameters:
+ * x[] The input value (must be positive) is broken into nx
+ * pieces of 24-bit integers in double precision format.
+ * x[i] will be the i-th 24 bit of x. The scaled exponent
+ * of x[0] is given in input parameter e0 (i.e., x[0]*2^e0
+ * match x's up to 24 bits.
+ *
+ * Example of breaking a double positive z into x[0]+x[1]+x[2]:
+ * e0 = ilogb(z)-23
+ * z = scalbn(z,-e0)
+ * for i = 0,1,2
+ * x[i] = floor(z)
+ * z = (z-x[i])*2**24
+ *
+ *
+ * y[] output result in an array of double precision numbers.
+ * The dimension of y[] is:
+ * 24-bit precision 1
+ * 53-bit precision 2
+ * 64-bit precision 2
+ * 113-bit precision 3
+ * The actual value is the sum of them. Thus for 113-bit
+ * precison, one may have to do something like:
+ *
+ * long double t,w,r_head, r_tail;
+ * t = (long double)y[2] + (long double)y[1];
+ * w = (long double)y[0];
+ * r_head = t+w;
+ * r_tail = w - (r_head - t);
+ *
+ * e0 The exponent of x[0]
+ *
+ * nx dimension of x[]
+ *
+ * prec an integer indicating the precision:
+ * 0 24 bits (single)
+ * 1 53 bits (double)
+ * 2 64 bits (extended)
+ * 3 113 bits (quad)
+ *
+ * ipio2[]
+ * integer array, contains the (24*i)-th to (24*i+23)-th
+ * bit of 2/pi after binary point. The corresponding
+ * floating value is
+ *
+ * ipio2[i] * 2^(-24(i+1)).
+ *
+ * External function:
+ * double scalbn(), floor();
+ *
+ *
+ * Here is the description of some local variables:
+ *
+ * jk jk+1 is the initial number of terms of ipio2[] needed
+ * in the computation. The recommended value is 2,3,4,
+ * 6 for single, double, extended,and quad.
+ *
+ * jz local integer variable indicating the number of
+ * terms of ipio2[] used.
+ *
+ * jx nx - 1
+ *
+ * jv index for pointing to the suitable ipio2[] for the
+ * computation. In general, we want
+ * ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8
+ * is an integer. Thus
+ * e0-3-24*jv >= 0 or (e0-3)/24 >= jv
+ * Hence jv = max(0,(e0-3)/24).
+ *
+ * jp jp+1 is the number of terms in PIo2[] needed, jp = jk.
+ *
+ * q[] double array with integral value, representing the
+ * 24-bits chunk of the product of x and 2/pi.
+ *
+ * q0 the corresponding exponent of q[0]. Note that the
+ * exponent for q[i] would be q0-24*i.
+ *
+ * PIo2[] double precision array, obtained by cutting pi/2
+ * into 24 bits chunks.
+ *
+ * f[] ipio2[] in floating point
+ *
+ * iq[] integer array by breaking up q[] in 24-bits chunk.
+ *
+ * fq[] final product of x*(2/pi) in fq[0],..,fq[jk]
+ *
+ * ih integer. If >0 it indicates q[] is >= 0.5, hence
+ * it also indicates the *sign* of the result.
+ *
+ */
+
+
+/*
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+static const int init_jk[] = {2,3,4,6}; /* initial value for jk */
+
+static const double PIo2[] = {
+ 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */
+ 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */
+ 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */
+ 3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */
+ 1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */
+ 1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */
+ 2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */
+ 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */
+};
+
+static const double
+zero = 0.0,
+one = 1.0,
+two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
+twon24 = 5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */
+
+int
+__kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int32_t *ipio2)
+{
+ int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
+ double z,fw,f[20],fq[20],q[20];
+
+ /* initialize jk*/
+ jk = init_jk[prec];
+ jp = jk;
+
+ /* determine jx,jv,q0, note that 3>q0 */
+ jx = nx-1;
+ jv = (e0-3)/24; if(jv<0) jv=0;
+ q0 = e0-24*(jv+1);
+
+ /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
+ j = jv-jx; m = jx+jk;
+ for(i=0;i<=m;i++,j++) f[i] = (j<0)? zero : (double) ipio2[j];
+
+ /* compute q[0],q[1],...q[jk] */
+ for (i=0;i<=jk;i++) {
+ for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; q[i] = fw;
+ }
+
+ jz = jk;
+recompute:
+ /* distill q[] into iq[] reversingly */
+ for(i=0,j=jz,z=q[jz];j>0;i++,j--) {
+ fw = (double)((int32_t)(twon24* z));
+ iq[i] = (int32_t)(z-two24*fw);
+ z = q[j-1]+fw;
+ }
+
+ /* compute n */
+ z = scalbn(z,q0); /* actual value of z */
+ z -= 8.0*floor(z*0.125); /* trim off integer >= 8 */
+ n = (int32_t) z;
+ z -= (double)n;
+ ih = 0;
+ if(q0>0) { /* need iq[jz-1] to determine n */
+ i = (iq[jz-1]>>(24-q0)); n += i;
+ iq[jz-1] -= i<<(24-q0);
+ ih = iq[jz-1]>>(23-q0);
+ }
+ else if(q0==0) ih = iq[jz-1]>>23;
+ else if(z>=0.5) ih=2;
+
+ if(ih>0) { /* q > 0.5 */
+ n += 1; carry = 0;
+ for(i=0;i<jz ;i++) { /* compute 1-q */
+ j = iq[i];
+ if(carry==0) {
+ if(j!=0) {
+ carry = 1; iq[i] = 0x1000000- j;
+ }
+ } else iq[i] = 0xffffff - j;
+ }
+ if(q0>0) { /* rare case: chance is 1 in 12 */
+ switch(q0) {
+ case 1:
+ iq[jz-1] &= 0x7fffff; break;
+ case 2:
+ iq[jz-1] &= 0x3fffff; break;
+ }
+ }
+ if(ih==2) {
+ z = one - z;
+ if(carry!=0) z -= scalbn(one,q0);
+ }
+ }
+
+ /* check if recomputation is needed */
+ if(z==zero) {
+ j = 0;
+ for (i=jz-1;i>=jk;i--) j |= iq[i];
+ if(j==0) { /* need recomputation */
+ for(k=1;iq[jk-k]==0;k++); /* k = no. of terms needed */
+
+ for(i=jz+1;i<=jz+k;i++) { /* add q[jz+1] to q[jz+k] */
+ f[jx+i] = (double) ipio2[jv+i];
+ for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j];
+ q[i] = fw;
+ }
+ jz += k;
+ goto recompute;
+ }
+ }
+
+ /* chop off zero terms */
+ if(z==0.0) {
+ jz -= 1; q0 -= 24;
+ while(iq[jz]==0) { jz--; q0-=24;}
+ } else { /* break z into 24-bit if necessary */
+ z = scalbn(z,-q0);
+ if(z>=two24) {
+ fw = (double)((int32_t)(twon24*z));
+ iq[jz] = (int32_t)(z-two24*fw);
+ jz += 1; q0 += 24;
+ iq[jz] = (int32_t) fw;
+ } else iq[jz] = (int32_t) z ;
+ }
+
+ /* convert integer "bit" chunk to floating-point value */
+ fw = scalbn(one,q0);
+ for(i=jz;i>=0;i--) {
+ q[i] = fw*(double)iq[i]; fw*=twon24;
+ }
+
+ /* compute PIo2[0,...,jp]*q[jz,...,0] */
+ for(i=jz;i>=0;i--) {
+ for(fw=0.0,k=0;k<=jp&&k<=jz-i;k++) fw += PIo2[k]*q[i+k];
+ fq[jz-i] = fw;
+ }
+
+ /* compress fq[] into y[] */
+ switch(prec) {
+ case 0:
+ fw = 0.0;
+ for (i=jz;i>=0;i--) fw += fq[i];
+ y[0] = (ih==0)? fw: -fw;
+ break;
+ case 1:
+ case 2:
+ fw = 0.0;
+ for (i=jz;i>=0;i--) fw += fq[i];
+ y[0] = (ih==0)? fw: -fw;
+ fw = fq[0]-fw;
+ for (i=1;i<=jz;i++) fw += fq[i];
+ y[1] = (ih==0)? fw: -fw;
+ break;
+ case 3: /* painful */
+ for (i=jz;i>0;i--) {
+ fw = fq[i-1]+fq[i];
+ fq[i] += fq[i-1]-fw;
+ fq[i-1] = fw;
+ }
+ for (i=jz;i>1;i--) {
+ fw = fq[i-1]+fq[i];
+ fq[i] += fq[i-1]-fw;
+ fq[i-1] = fw;
+ }
+ for (fw=0.0,i=jz;i>=2;i--) fw += fq[i];
+ if(ih==0) {
+ y[0] = fq[0]; y[1] = fq[1]; y[2] = fw;
+ } else {
+ y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw;
+ }
+ }
+ return n&7;
+}
diff --git a/StdLib/LibC/Math/k_sin.c b/StdLib/LibC/Math/k_sin.c
new file mode 100644
index 0000000000..9e4c22d03d
--- /dev/null
+++ b/StdLib/LibC/Math/k_sin.c
@@ -0,0 +1,72 @@
+/* @(#)k_sin.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: k_sin.c,v 1.11 2002/05/26 22:01:53 wiz Exp $");
+#endif
+
+/* __kernel_sin( x, y, iy)
+ * kernel sin function on [-pi/4, pi/4], pi/4 ~ 0.7854
+ * Input x is assumed to be bounded by ~pi/4 in magnitude.
+ * Input y is the tail of x.
+ * Input iy indicates whether y is 0. (if iy=0, y assume to be 0).
+ *
+ * Algorithm
+ * 1. Since sin(-x) = -sin(x), we need only to consider positive x.
+ * 2. if x < 2^-27 (hx<0x3e400000 0), return x with inexact if x!=0.
+ * 3. sin(x) is approximated by a polynomial of degree 13 on
+ * [0,pi/4]
+ * 3 13
+ * sin(x) ~ x + S1*x + ... + S6*x
+ * where
+ *
+ * |sin(x) 2 4 6 8 10 12 | -58
+ * |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x +S6*x )| <= 2
+ * | x |
+ *
+ * 4. sin(x+y) = sin(x) + sin'(x')*y
+ * ~ sin(x) + (1-x*x/2)*y
+ * For better accuracy, let
+ * 3 2 2 2 2
+ * r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6))))
+ * then 3 2
+ * sin(x) = x + (S1*x + (x *(r-y/2)+y))
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+static const double
+half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
+S1 = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */
+S2 = 8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */
+S3 = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */
+S4 = 2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */
+S5 = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */
+S6 = 1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */
+
+double
+__kernel_sin(double x, double y, int iy)
+{
+ double z,r,v;
+ int32_t ix;
+ GET_HIGH_WORD(ix,x);
+ ix &= 0x7fffffff; /* high word of x */
+ if(ix<0x3e400000) /* |x| < 2**-27 */
+ {if((int)x==0) return x;} /* generate inexact */
+ z = x*x;
+ v = z*x;
+ r = S2+z*(S3+z*(S4+z*(S5+z*S6)));
+ if(iy==0) return x+v*(S1+z*r);
+ else return x-((z*(half*y-v*r)-y)-v*S1);
+}
diff --git a/StdLib/LibC/Math/k_tan.c b/StdLib/LibC/Math/k_tan.c
new file mode 100644
index 0000000000..ad83a21d3b
--- /dev/null
+++ b/StdLib/LibC/Math/k_tan.c
@@ -0,0 +1,156 @@
+/* @(#)k_tan.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: k_tan.c,v 1.12 2004/07/22 18:24:09 drochner Exp $");
+#endif
+
+/* __kernel_tan( x, y, k )
+ * kernel tan function on [-pi/4, pi/4], pi/4 ~ 0.7854
+ * Input x is assumed to be bounded by ~pi/4 in magnitude.
+ * Input y is the tail of x.
+ * Input k indicates whether tan (if k=1) or
+ * -1/tan (if k= -1) is returned.
+ *
+ * Algorithm
+ * 1. Since tan(-x) = -tan(x), we need only to consider positive x.
+ * 2. if x < 2^-28 (hx<0x3e300000 0), return x with inexact if x!=0.
+ * 3. tan(x) is approximated by a odd polynomial of degree 27 on
+ * [0,0.67434]
+ * 3 27
+ * tan(x) ~ x + T1*x + ... + T13*x
+ * where
+ *
+ * |tan(x) 2 4 26 | -59.2
+ * |----- - (1+T1*x +T2*x +.... +T13*x )| <= 2
+ * | x |
+ *
+ * Note: tan(x+y) = tan(x) + tan'(x)*y
+ * ~ tan(x) + (1+x*x)*y
+ * Therefore, for better accuracy in computing tan(x+y), let
+ * 3 2 2 2 2
+ * r = x *(T2+x *(T3+x *(...+x *(T12+x *T13))))
+ * then
+ * 3 2
+ * tan(x+y) = x + (T1*x + (x *(r+y)+y))
+ *
+ * 4. For x in [0.67434,pi/4], let y = pi/4 - x, then
+ * tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y))
+ * = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y)))
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+static const double xxx[] = {
+ 3.33333333333334091986e-01, /* 3FD55555, 55555563 */
+ 1.33333333333201242699e-01, /* 3FC11111, 1110FE7A */
+ 5.39682539762260521377e-02, /* 3FABA1BA, 1BB341FE */
+ 2.18694882948595424599e-02, /* 3F9664F4, 8406D637 */
+ 8.86323982359930005737e-03, /* 3F8226E3, E96E8493 */
+ 3.59207910759131235356e-03, /* 3F6D6D22, C9560328 */
+ 1.45620945432529025516e-03, /* 3F57DBC8, FEE08315 */
+ 5.88041240820264096874e-04, /* 3F4344D8, F2F26501 */
+ 2.46463134818469906812e-04, /* 3F3026F7, 1A8D1068 */
+ 7.81794442939557092300e-05, /* 3F147E88, A03792A6 */
+ 7.14072491382608190305e-05, /* 3F12B80F, 32F0A7E9 */
+ -1.85586374855275456654e-05, /* BEF375CB, DB605373 */
+ 2.59073051863633712884e-05, /* 3EFB2A70, 74BF7AD4 */
+/* one */ 1.00000000000000000000e+00, /* 3FF00000, 00000000 */
+/* pio4 */ 7.85398163397448278999e-01, /* 3FE921FB, 54442D18 */
+/* pio4lo */ 3.06161699786838301793e-17 /* 3C81A626, 33145C07 */
+};
+#define one xxx[13]
+#define pio4 xxx[14]
+#define pio4lo xxx[15]
+#define T xxx
+
+double
+__kernel_tan(double x, double y, int iy)
+{
+ double z, r, v, w, s;
+ int32_t ix, hx;
+
+ GET_HIGH_WORD(hx, x); /* high word of x */
+ ix = hx & 0x7fffffff; /* high word of |x| */
+ if (ix < 0x3e300000) { /* x < 2**-28 */
+ if ((int) x == 0) { /* generate inexact */
+ u_int32_t low;
+ GET_LOW_WORD(low, x);
+ if(((ix | low) | (iy + 1)) == 0)
+ return one / fabs(x);
+ else {
+ if (iy == 1)
+ return x;
+ else { /* compute -1 / (x+y) carefully */
+ double a, t;
+
+ z = w = x + y;
+ SET_LOW_WORD(z, 0);
+ v = y - (z - x);
+ t = a = -one / w;
+ SET_LOW_WORD(t, 0);
+ s = one + t * z;
+ return t + a * (s + t * v);
+ }
+ }
+ }
+ }
+ if (ix >= 0x3FE59428) { /* |x| >= 0.6744 */
+ if (hx < 0) {
+ x = -x;
+ y = -y;
+ }
+ z = pio4 - x;
+ w = pio4lo - y;
+ x = z + w;
+ y = 0.0;
+ }
+ z = x * x;
+ w = z * z;
+ /*
+ * Break x^5*(T[1]+x^2*T[2]+...) into
+ * x^5(T[1]+x^4*T[3]+...+x^20*T[11]) +
+ * x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12]))
+ */
+ r = T[1] + w * (T[3] + w * (T[5] + w * (T[7] + w * (T[9] +
+ w * T[11]))));
+ v = z * (T[2] + w * (T[4] + w * (T[6] + w * (T[8] + w * (T[10] +
+ w * T[12])))));
+ s = z * x;
+ r = y + z * (s * (r + v) + y);
+ r += T[0] * s;
+ w = x + r;
+ if (ix >= 0x3FE59428) {
+ v = (double) iy;
+ return (double) (1 - ((hx >> 30) & 2)) *
+ (v - 2.0 * (x - (w * w / (w + v) - r)));
+ }
+ if (iy == 1)
+ return w;
+ else {
+ /*
+ * if allow error up to 2 ulp, simply return
+ * -1.0 / (x+r) here
+ */
+ /* compute -1.0 / (x+r) accurately */
+ double a, t;
+ z = w;
+ SET_LOW_WORD(z, 0);
+ v = r - (z - x); /* z+v = r+x */
+ t = a = -1.0 / w; /* a = -1.0/w */
+ SET_LOW_WORD(t, 0);
+ s = 1.0 + t * z;
+ return t + a * (s + t * v);
+ }
+}
diff --git a/StdLib/LibC/Math/math_private.h b/StdLib/LibC/Math/math_private.h
new file mode 100644
index 0000000000..0aed7e7950
--- /dev/null
+++ b/StdLib/LibC/Math/math_private.h
@@ -0,0 +1,229 @@
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * from: @(#)fdlibm.h 5.1 93/09/24
+ * $NetBSD: math_private.h,v 1.12 2005/07/21 12:55:58 christos Exp $
+ */
+
+#ifndef _MATH_PRIVATE_H_
+#define _MATH_PRIVATE_H_
+
+#include <sys/types.h>
+
+/* The original fdlibm code used statements like:
+ n0 = ((*(int*)&one)>>29)^1; * index of high word *
+ ix0 = *(n0+(int*)&x); * high word of x *
+ ix1 = *((1-n0)+(int*)&x); * low word of x *
+ to dig two 32 bit words out of the 64 bit IEEE floating point
+ value. That is non-ANSI, and, moreover, the gcc instruction
+ scheduler gets it wrong. We instead use the following macros.
+ Unlike the original code, we determine the endianness at compile
+ time, not at run time; I don't see much benefit to selecting
+ endianness at run time. */
+
+/* A union which permits us to convert between a double and two 32 bit
+ ints. */
+
+/*
+ * The ARM ports are little endian except for the FPA word order which is
+ * big endian.
+ */
+
+#if (BYTE_ORDER == BIG_ENDIAN) || (defined(__arm__) && !defined(__VFP_FP__))
+
+typedef union
+{
+ double value;
+ struct
+ {
+ u_int32_t msw;
+ u_int32_t lsw;
+ } parts;
+} ieee_double_shape_type;
+
+#endif
+
+#if (BYTE_ORDER == LITTLE_ENDIAN) && \
+ !(defined(__arm__) && !defined(__VFP_FP__))
+
+typedef union
+{
+ double value;
+ struct
+ {
+ u_int32_t lsw;
+ u_int32_t msw;
+ } parts;
+} ieee_double_shape_type;
+
+#endif
+
+/* Get two 32 bit ints from a double. */
+
+#define EXTRACT_WORDS(ix0,ix1,d) \
+do { \
+ ieee_double_shape_type ew_u; \
+ ew_u.value = (d); \
+ (ix0) = ew_u.parts.msw; \
+ (ix1) = ew_u.parts.lsw; \
+} while (0)
+
+/* Get the more significant 32 bit int from a double. */
+
+#define GET_HIGH_WORD(i,d) \
+do { \
+ ieee_double_shape_type gh_u; \
+ gh_u.value = (d); \
+ (i) = gh_u.parts.msw; \
+} while (0)
+
+/* Get the less significant 32 bit int from a double. */
+
+#define GET_LOW_WORD(i,d) \
+do { \
+ ieee_double_shape_type gl_u; \
+ gl_u.value = (d); \
+ (i) = gl_u.parts.lsw; \
+} while (0)
+
+/* Set a double from two 32 bit ints. */
+
+#define INSERT_WORDS(d,ix0,ix1) \
+do { \
+ ieee_double_shape_type iw_u; \
+ iw_u.parts.msw = (ix0); \
+ iw_u.parts.lsw = (ix1); \
+ (d) = iw_u.value; \
+} while (0)
+
+/* Set the more significant 32 bits of a double from an int. */
+
+#define SET_HIGH_WORD(d,v) \
+do { \
+ ieee_double_shape_type sh_u; \
+ sh_u.value = (d); \
+ sh_u.parts.msw = (v); \
+ (d) = sh_u.value; \
+} while (0)
+
+/* Set the less significant 32 bits of a double from an int. */
+
+#define SET_LOW_WORD(d,v) \
+do { \
+ ieee_double_shape_type sl_u; \
+ sl_u.value = (d); \
+ sl_u.parts.lsw = (v); \
+ (d) = sl_u.value; \
+} while (0)
+
+/* A union which permits us to convert between a float and a 32 bit
+ int. */
+
+typedef union
+{
+ float value;
+ u_int32_t word;
+} ieee_float_shape_type;
+
+/* Get a 32 bit int from a float. */
+
+#define GET_FLOAT_WORD(i,d) \
+do { \
+ ieee_float_shape_type gf_u; \
+ gf_u.value = (d); \
+ (i) = gf_u.word; \
+} while (0)
+
+/* Set a float from a 32 bit int. */
+
+#define SET_FLOAT_WORD(d,i) \
+do { \
+ ieee_float_shape_type sf_u; \
+ sf_u.word = (i); \
+ (d) = sf_u.value; \
+} while (0)
+
+/* ieee style elementary functions */
+extern double __ieee754_sqrt (double);
+extern double __ieee754_acos (double);
+extern double __ieee754_acosh (double);
+extern double __ieee754_log (double);
+extern double __ieee754_atanh (double);
+extern double __ieee754_asin (double);
+extern double __ieee754_atan2 (double, double);
+extern double __ieee754_exp (double);
+extern double __ieee754_cosh (double);
+extern double __ieee754_fmod (double, double);
+extern double __ieee754_pow (double, double);
+extern double __ieee754_lgamma_r (double, int *);
+extern double __ieee754_gamma_r (double, int *);
+extern double __ieee754_lgamma (double);
+extern double __ieee754_gamma (double);
+extern double __ieee754_log10 (double);
+extern double __ieee754_log2 (double);
+extern double __ieee754_sinh (double);
+extern double __ieee754_hypot (double, double);
+extern double __ieee754_j0 (double);
+extern double __ieee754_j1 (double);
+extern double __ieee754_y0 (double);
+extern double __ieee754_y1 (double);
+extern double __ieee754_jn (int, double);
+extern double __ieee754_yn (int, double);
+extern double __ieee754_remainder (double, double);
+extern int __ieee754_rem_pio2 (double,double*);
+extern double __ieee754_scalb (double, double);
+
+/* fdlibm kernel function */
+extern double __kernel_standard (double, double, int);
+extern double __kernel_sin (double, double, int);
+extern double __kernel_cos (double, double);
+extern double __kernel_tan (double, double, int);
+extern int __kernel_rem_pio2 (double*,double*,int,int,int,const int*);
+
+
+///* ieee style elementary float functions */
+//extern float __ieee754_sqrtf __P((float));
+//extern float __ieee754_acosf __P((float));
+//extern float __ieee754_acoshf __P((float));
+//extern float __ieee754_logf __P((float));
+//extern float __ieee754_atanhf __P((float));
+//extern float __ieee754_asinf __P((float));
+//extern float __ieee754_atan2f __P((float,float));
+//extern float __ieee754_expf __P((float));
+//extern float __ieee754_coshf __P((float));
+//extern float __ieee754_fmodf __P((float,float));
+//extern float __ieee754_powf __P((float,float));
+//extern float __ieee754_lgammaf_r __P((float,int *));
+//extern float __ieee754_gammaf_r __P((float,int *));
+//extern float __ieee754_lgammaf __P((float));
+//extern float __ieee754_gammaf __P((float));
+//extern float __ieee754_log10f __P((float));
+//extern float __ieee754_log2f __P((float));
+//extern float __ieee754_sinhf __P((float));
+//extern float __ieee754_hypotf __P((float,float));
+//extern float __ieee754_j0f __P((float));
+//extern float __ieee754_j1f __P((float));
+//extern float __ieee754_y0f __P((float));
+//extern float __ieee754_y1f __P((float));
+//extern float __ieee754_jnf __P((int,float));
+//extern float __ieee754_ynf __P((int,float));
+//extern float __ieee754_remainderf __P((float,float));
+//extern int __ieee754_rem_pio2f __P((float,float*));
+//extern float __ieee754_scalbf __P((float,float));
+
+///* float versions of fdlibm kernel functions */
+//extern float __kernel_sinf __P((float,float,int));
+//extern float __kernel_cosf __P((float,float));
+//extern float __kernel_tanf __P((float,float,int));
+//extern int __kernel_rem_pio2f __P((float*,float*,int,int,int,const int*));
+
+#endif /* _MATH_PRIVATE_H_ */
diff --git a/StdLib/LibC/Math/s_atan.c b/StdLib/LibC/Math/s_atan.c
new file mode 100644
index 0000000000..cbaf359936
--- /dev/null
+++ b/StdLib/LibC/Math/s_atan.c
@@ -0,0 +1,120 @@
+/* @(#)s_atan.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: s_atan.c,v 1.11 2002/05/26 22:01:54 wiz Exp $");
+#endif
+
+/* atan(x)
+ * Method
+ * 1. Reduce x to positive by atan(x) = -atan(-x).
+ * 2. According to the integer k=4t+0.25 chopped, t=x, the argument
+ * is further reduced to one of the following intervals and the
+ * arctangent of t is evaluated by the corresponding formula:
+ *
+ * [0,7/16] atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...)
+ * [7/16,11/16] atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) )
+ * [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) )
+ * [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) )
+ * [39/16,INF] atan(x) = atan(INF) + atan( -1/t )
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+static const double atanhi[] = {
+ 4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */
+ 7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */
+ 9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */
+ 1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */
+};
+
+static const double atanlo[] = {
+ 2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */
+ 3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */
+ 1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */
+ 6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */
+};
+
+static const double aT[] = {
+ 3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */
+ -1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */
+ 1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */
+ -1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */
+ 9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */
+ -7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */
+ 6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */
+ -5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */
+ 4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */
+ -3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */
+ 1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */
+};
+
+ static const double
+one = 1.0,
+huge = 1.0e300;
+
+double
+atan(double x)
+{
+ double w,s1,s2,z;
+ int32_t ix,hx,id;
+
+ GET_HIGH_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x44100000) { /* if |x| >= 2^66 */
+ u_int32_t low;
+ GET_LOW_WORD(low,x);
+ if(ix>0x7ff00000||
+ (ix==0x7ff00000&&(low!=0)))
+ return x+x; /* NaN */
+ if(hx>0) return atanhi[3]+atanlo[3];
+ else return -atanhi[3]-atanlo[3];
+ } if (ix < 0x3fdc0000) { /* |x| < 0.4375 */
+ if (ix < 0x3e200000) { /* |x| < 2^-29 */
+ if(huge+x>one) return x; /* raise inexact */
+ }
+ id = -1;
+ } else {
+ x = fabs(x);
+ if (ix < 0x3ff30000) { /* |x| < 1.1875 */
+ if (ix < 0x3fe60000) { /* 7/16 <=|x|<11/16 */
+ id = 0; x = (2.0*x-one)/(2.0+x);
+ } else { /* 11/16<=|x|< 19/16 */
+ id = 1; x = (x-one)/(x+one);
+ }
+ } else {
+ if (ix < 0x40038000) { /* |x| < 2.4375 */
+ id = 2; x = (x-1.5)/(one+1.5*x);
+ } else { /* 2.4375 <= |x| < 2^66 */
+ id = 3; x = -1.0/x;
+ }
+ }}
+ /* end of argument reduction */
+ z = x*x;
+ w = z*z;
+ /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */
+ s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10])))));
+ s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9]))));
+ if (id<0) return x - x*(s1+s2);
+ else {
+ z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x);
+ return (hx<0)? -z:z;
+ }
+}
diff --git a/StdLib/LibC/Math/s_ceil.c b/StdLib/LibC/Math/s_ceil.c
new file mode 100644
index 0000000000..e9579fab72
--- /dev/null
+++ b/StdLib/LibC/Math/s_ceil.c
@@ -0,0 +1,74 @@
+/* @(#)s_ceil.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: s_ceil.c,v 1.11 2002/05/26 22:01:54 wiz Exp $");
+#endif
+
+/*
+ * ceil(x)
+ * Return x rounded toward -inf to integral value
+ * Method:
+ * Bit twiddling.
+ * Exception:
+ * Inexact flag raised if x not equal to ceil(x).
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+static const double huge = 1.0e300;
+
+double
+ceil(double x)
+{
+ int32_t i0,i1,j0;
+ u_int32_t i,j;
+
+ EXTRACT_WORDS(i0,i1,x);
+ j0 = ((i0>>20)&0x7ff)-0x3ff;
+ if(j0<20) {
+ if(j0<0) { /* raise inexact if x != 0 */
+ if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
+ if(i0<0) {i0=0x80000000;i1=0;}
+ else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;}
+ }
+ } else {
+ i = (0x000fffff)>>j0;
+ if(((i0&i)|i1)==0) return x; /* x is integral */
+ if(huge+x>0.0) { /* raise inexact flag */
+ if(i0>0) i0 += (0x00100000)>>j0;
+ i0 &= (~i); i1=0;
+ }
+ }
+ } else if (j0>51) {
+ if(j0==0x400) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ } else {
+ i = ((u_int32_t)(0xffffffff))>>(j0-20);
+ if((i1&i)==0) return x; /* x is integral */
+ if(huge+x>0.0) { /* raise inexact flag */
+ if(i0>0) {
+ if(j0==20) i0+=1;
+ else {
+ j = i1 + (1<<(52-j0));
+ if((int32_t)j<i1) i0+=1; /* got a carry */
+ i1 = j;
+ }
+ }
+ i1 &= (~i);
+ }
+ }
+ INSERT_WORDS(x,i0,i1);
+ return x;
+}
diff --git a/StdLib/LibC/Math/s_copysign.c b/StdLib/LibC/Math/s_copysign.c
new file mode 100644
index 0000000000..31a80af28f
--- /dev/null
+++ b/StdLib/LibC/Math/s_copysign.c
@@ -0,0 +1,35 @@
+/* @(#)s_copysign.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: s_copysign.c,v 1.11 2002/05/26 22:01:54 wiz Exp $");
+#endif
+
+/*
+ * copysign(double x, double y)
+ * copysign(x,y) returns a value with the magnitude of x and
+ * with the sign bit of y.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+double
+copysign(double x, double y)
+{
+ u_int32_t hx,hy;
+ GET_HIGH_WORD(hx,x);
+ GET_HIGH_WORD(hy,y);
+ SET_HIGH_WORD(x,(hx&0x7fffffff)|(hy&0x80000000));
+ return x;
+}
diff --git a/StdLib/LibC/Math/s_cos.c b/StdLib/LibC/Math/s_cos.c
new file mode 100644
index 0000000000..ef04e5d34c
--- /dev/null
+++ b/StdLib/LibC/Math/s_cos.c
@@ -0,0 +1,79 @@
+/* @(#)s_cos.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: s_cos.c,v 1.10 2002/05/26 22:01:54 wiz Exp $");
+#endif
+
+/* cos(x)
+ * Return cosine function of x.
+ *
+ * kernel function:
+ * __kernel_sin ... sine function on [-pi/4,pi/4]
+ * __kernel_cos ... cosine function on [-pi/4,pi/4]
+ * __ieee754_rem_pio2 ... argument reduction routine
+ *
+ * Method.
+ * Let S,C and T denote the sin, cos and tan respectively on
+ * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
+ * in [-pi/4 , +pi/4], and let n = k mod 4.
+ * We have
+ *
+ * n sin(x) cos(x) tan(x)
+ * ----------------------------------------------------------
+ * 0 S C T
+ * 1 C -S -1/T
+ * 2 -S -C T
+ * 3 -C S -1/T
+ * ----------------------------------------------------------
+ *
+ * Special cases:
+ * Let trig be any of sin, cos, or tan.
+ * trig(+-INF) is NaN, with signals;
+ * trig(NaN) is that NaN;
+ *
+ * Accuracy:
+ * TRIG(x) returns trig(x) nearly rounded
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+double
+cos(double x)
+{
+ double y[2],z=0.0;
+ int32_t n, ix;
+
+ /* High word of x. */
+ GET_HIGH_WORD(ix,x);
+
+ /* |x| ~< pi/4 */
+ ix &= 0x7fffffff;
+ if(ix <= 0x3fe921fb) return __kernel_cos(x,z);
+
+ /* cos(Inf or NaN) is NaN */
+ else if (ix>=0x7ff00000) return x-x;
+
+ /* argument reduction needed */
+ else {
+ n = __ieee754_rem_pio2(x,y);
+ switch(n&3) {
+ case 0: return __kernel_cos(y[0],y[1]);
+ case 1: return -__kernel_sin(y[0],y[1],1);
+ case 2: return -__kernel_cos(y[0],y[1]);
+ default:
+ return __kernel_sin(y[0],y[1],1);
+ }
+ }
+}
diff --git a/StdLib/LibC/Math/s_expm1.c b/StdLib/LibC/Math/s_expm1.c
new file mode 100644
index 0000000000..338f377fa4
--- /dev/null
+++ b/StdLib/LibC/Math/s_expm1.c
@@ -0,0 +1,228 @@
+/* @(#)s_expm1.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: s_expm1.c,v 1.12 2002/05/26 22:01:55 wiz Exp $");
+#endif
+
+#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
+ // C4756: overflow in constant arithmetic
+ #pragma warning ( disable : 4756 )
+#endif
+
+/* expm1(x)
+ * Returns exp(x)-1, the exponential of x minus 1.
+ *
+ * Method
+ * 1. Argument reduction:
+ * Given x, find r and integer k such that
+ *
+ * x = k*ln2 + r, |r| <= 0.5*ln2 ~ 0.34658
+ *
+ * Here a correction term c will be computed to compensate
+ * the error in r when rounded to a floating-point number.
+ *
+ * 2. Approximating expm1(r) by a special rational function on
+ * the interval [0,0.34658]:
+ * Since
+ * r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 - r^4/360 + ...
+ * we define R1(r*r) by
+ * r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 * R1(r*r)
+ * That is,
+ * R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r)
+ * = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r))
+ * = 1 - r^2/60 + r^4/2520 - r^6/100800 + ...
+ * We use a special Reme algorithm on [0,0.347] to generate
+ * a polynomial of degree 5 in r*r to approximate R1. The
+ * maximum error of this polynomial approximation is bounded
+ * by 2**-61. In other words,
+ * R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5
+ * where Q1 = -1.6666666666666567384E-2,
+ * Q2 = 3.9682539681370365873E-4,
+ * Q3 = -9.9206344733435987357E-6,
+ * Q4 = 2.5051361420808517002E-7,
+ * Q5 = -6.2843505682382617102E-9;
+ * (where z=r*r, and the values of Q1 to Q5 are listed below)
+ * with error bounded by
+ * | 5 | -61
+ * | 1.0+Q1*z+...+Q5*z - R1(z) | <= 2
+ * | |
+ *
+ * expm1(r) = exp(r)-1 is then computed by the following
+ * specific way which minimize the accumulation rounding error:
+ * 2 3
+ * r r [ 3 - (R1 + R1*r/2) ]
+ * expm1(r) = r + --- + --- * [--------------------]
+ * 2 2 [ 6 - r*(3 - R1*r/2) ]
+ *
+ * To compensate the error in the argument reduction, we use
+ * expm1(r+c) = expm1(r) + c + expm1(r)*c
+ * ~ expm1(r) + c + r*c
+ * Thus c+r*c will be added in as the correction terms for
+ * expm1(r+c). Now rearrange the term to avoid optimization
+ * screw up:
+ * ( 2 2 )
+ * ({ ( r [ R1 - (3 - R1*r/2) ] ) } r )
+ * expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- )
+ * ({ ( 2 [ 6 - r*(3 - R1*r/2) ] ) } 2 )
+ * ( )
+ *
+ * = r - E
+ * 3. Scale back to obtain expm1(x):
+ * From step 1, we have
+ * expm1(x) = either 2^k*[expm1(r)+1] - 1
+ * = or 2^k*[expm1(r) + (1-2^-k)]
+ * 4. Implementation notes:
+ * (A). To save one multiplication, we scale the coefficient Qi
+ * to Qi*2^i, and replace z by (x^2)/2.
+ * (B). To achieve maximum accuracy, we compute expm1(x) by
+ * (i) if x < -56*ln2, return -1.0, (raise inexact if x!=inf)
+ * (ii) if k=0, return r-E
+ * (iii) if k=-1, return 0.5*(r-E)-0.5
+ * (iv) if k=1 if r < -0.25, return 2*((r+0.5)- E)
+ * else return 1.0+2.0*(r-E);
+ * (v) if (k<-2||k>56) return 2^k(1-(E-r)) - 1 (or exp(x)-1)
+ * (vi) if k <= 20, return 2^k((1-2^-k)-(E-r)), else
+ * (vii) return 2^k(1-((E+2^-k)-r))
+ *
+ * Special cases:
+ * expm1(INF) is INF, expm1(NaN) is NaN;
+ * expm1(-INF) is -1, and
+ * for finite argument, only expm1(0)=0 is exact.
+ *
+ * Accuracy:
+ * according to an error analysis, the error is always less than
+ * 1 ulp (unit in the last place).
+ *
+ * Misc. info.
+ * For IEEE double
+ * if x > 7.09782712893383973096e+02 then expm1(x) overflow
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+static const double
+one = 1.0,
+huge = 1.0e+300,
+tiny = 1.0e-300,
+o_threshold = 7.09782712893383973096e+02,/* 0x40862E42, 0xFEFA39EF */
+ln2_hi = 6.93147180369123816490e-01,/* 0x3fe62e42, 0xfee00000 */
+ln2_lo = 1.90821492927058770002e-10,/* 0x3dea39ef, 0x35793c76 */
+invln2 = 1.44269504088896338700e+00,/* 0x3ff71547, 0x652b82fe */
+ /* scaled coefficients related to expm1 */
+Q1 = -3.33333333333331316428e-02, /* BFA11111 111110F4 */
+Q2 = 1.58730158725481460165e-03, /* 3F5A01A0 19FE5585 */
+Q3 = -7.93650757867487942473e-05, /* BF14CE19 9EAADBB7 */
+Q4 = 4.00821782732936239552e-06, /* 3ED0CFCA 86E65239 */
+Q5 = -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */
+
+double
+expm1(double x)
+{
+ double y,hi,lo,c,t,e,hxs,hfx,r1;
+ int32_t k,xsb;
+ u_int32_t hx;
+
+ c = 0;
+ GET_HIGH_WORD(hx,x);
+ xsb = hx&0x80000000; /* sign bit of x */
+ if(xsb==0) y=x; else y= -x; /* y = |x| */
+ hx &= 0x7fffffff; /* high word of |x| */
+
+ /* filter out huge and non-finite argument */
+ if(hx >= 0x4043687A) { /* if |x|>=56*ln2 */
+ if(hx >= 0x40862E42) { /* if |x|>=709.78... */
+ if(hx>=0x7ff00000) {
+ u_int32_t low;
+ GET_LOW_WORD(low,x);
+ if(((hx&0xfffff)|low)!=0)
+ return x+x; /* NaN */
+ else return (xsb==0)? x:-1.0;/* exp(+-inf)={inf,-1} */
+ }
+ if(x > o_threshold) return huge*huge; /* overflow */
+ }
+ if(xsb!=0) { /* x < -56*ln2, return -1.0 with inexact */
+ if(x+tiny<0.0) /* raise inexact */
+ return tiny-one; /* return -1 */
+ }
+ }
+
+ /* argument reduction */
+ if(hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */
+ if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */
+ if(xsb==0)
+ {hi = x - ln2_hi; lo = ln2_lo; k = 1;}
+ else
+ {hi = x + ln2_hi; lo = -ln2_lo; k = -1;}
+ } else {
+ k = (int32_t)(invln2*x+((xsb==0)?0.5:-0.5));
+ t = k;
+ hi = x - t*ln2_hi; /* t*ln2_hi is exact here */
+ lo = t*ln2_lo;
+ }
+ x = hi - lo;
+ c = (hi-x)-lo;
+ }
+ else if(hx < 0x3c900000) { /* when |x|<2**-54, return x */
+ t = huge+x; /* return x with inexact flags when x!=0 */
+ return x - (t-(huge+x));
+ }
+ else k = 0;
+
+ /* x is now in primary range */
+ hfx = 0.5*x;
+ hxs = x*hfx;
+ r1 = one+hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5))));
+ t = 3.0-r1*hfx;
+ e = hxs*((r1-t)/(6.0 - x*t));
+ if(k==0) return x - (x*e-hxs); /* c is 0 */
+ else {
+ e = (x*(e-c)-c);
+ e -= hxs;
+ if(k== -1) return 0.5*(x-e)-0.5;
+ if(k==1) {
+ if(x < -0.25) return -2.0*(e-(x+0.5));
+ else return one+2.0*(x-e);
+ }
+ if (k <= -2 || k>56) { /* suffice to return exp(x)-1 */
+ u_int32_t high;
+ y = one-(e-x);
+ GET_HIGH_WORD(high,y);
+ SET_HIGH_WORD(y,high+(k<<20)); /* add k to y's exponent */
+ return y-one;
+ }
+ t = one;
+ if(k<20) {
+ u_int32_t high;
+ SET_HIGH_WORD(t,0x3ff00000 - (0x200000>>k)); /* t=1-2^-k */
+ y = t-(e-x);
+ GET_HIGH_WORD(high,y);
+ SET_HIGH_WORD(y,high+(k<<20)); /* add k to y's exponent */
+ } else {
+ u_int32_t high;
+ SET_HIGH_WORD(t,((0x3ff-k)<<20)); /* 2^-k */
+ y = x-(e+t);
+ y += one;
+ GET_HIGH_WORD(high,y);
+ SET_HIGH_WORD(y,high+(k<<20)); /* add k to y's exponent */
+ }
+ }
+ return y;
+}
diff --git a/StdLib/LibC/Math/s_fabs.c b/StdLib/LibC/Math/s_fabs.c
new file mode 100644
index 0000000000..4cd5a5e52a
--- /dev/null
+++ b/StdLib/LibC/Math/s_fabs.c
@@ -0,0 +1,32 @@
+/* @(#)s_fabs.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: s_fabs.c,v 1.10 2002/05/26 22:01:55 wiz Exp $");
+#endif
+
+/*
+ * fabs(x) returns the absolute value of x.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+double
+fabs(double x)
+{
+ u_int32_t high;
+ GET_HIGH_WORD(high,x);
+ SET_HIGH_WORD(x,high&0x7fffffff);
+ return x;
+}
diff --git a/StdLib/LibC/Math/s_finite.c b/StdLib/LibC/Math/s_finite.c
new file mode 100644
index 0000000000..3f66feb981
--- /dev/null
+++ b/StdLib/LibC/Math/s_finite.c
@@ -0,0 +1,32 @@
+/* @(#)s_finite.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: s_finite.c,v 1.11 2002/05/26 22:01:55 wiz Exp $");
+#endif
+
+/*
+ * finite(x) returns 1 is x is finite, else 0;
+ * no branching!
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+int
+finite(double x)
+{
+ int32_t hx;
+ GET_HIGH_WORD(hx,x);
+ return (int)((u_int32_t)((hx&0x7fffffff)-0x7ff00000)>>31);
+}
diff --git a/StdLib/LibC/Math/s_floor.c b/StdLib/LibC/Math/s_floor.c
new file mode 100644
index 0000000000..d63ef13c0d
--- /dev/null
+++ b/StdLib/LibC/Math/s_floor.c
@@ -0,0 +1,74 @@
+/* @(#)s_floor.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: s_floor.c,v 1.11 2002/05/26 22:01:56 wiz Exp $");
+#endif
+
+/*
+ * floor(x)
+ * Return x rounded toward -inf to integral value
+ * Method:
+ * Bit twiddling.
+ * Exception:
+ * Inexact flag raised if x not equal to floor(x).
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+static const double huge = 1.0e300;
+
+double
+floor(double x)
+{
+ int32_t i0,i1,j0;
+ u_int32_t i,j;
+ EXTRACT_WORDS(i0,i1,x);
+ j0 = ((i0>>20)&0x7ff)-0x3ff;
+ if(j0<20) {
+ if(j0<0) { /* raise inexact if x != 0 */
+ if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
+ if(i0>=0) {i0=i1=0;}
+ else if(((i0&0x7fffffff)|i1)!=0)
+ { i0=0xbff00000;i1=0;}
+ }
+ } else {
+ i = (0x000fffff)>>j0;
+ if(((i0&i)|i1)==0) return x; /* x is integral */
+ if(huge+x>0.0) { /* raise inexact flag */
+ if(i0<0) i0 += (0x00100000)>>j0;
+ i0 &= (~i); i1=0;
+ }
+ }
+ } else if (j0>51) {
+ if(j0==0x400) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ } else {
+ i = ((u_int32_t)(0xffffffff))>>(j0-20);
+ if((i1&i)==0) return x; /* x is integral */
+ if(huge+x>0.0) { /* raise inexact flag */
+ if(i0<0) {
+ if(j0==20) i0+=1;
+ else {
+ j = i1+(1<<(52-j0));
+ if((int32_t)j<i1) i0 +=1 ; /* got a carry */
+ i1=j;
+ }
+ }
+ i1 &= (~i);
+ }
+ }
+ INSERT_WORDS(x,i0,i1);
+ return x;
+}
diff --git a/StdLib/LibC/Math/s_frexp.c b/StdLib/LibC/Math/s_frexp.c
new file mode 100644
index 0000000000..8e93600ef9
--- /dev/null
+++ b/StdLib/LibC/Math/s_frexp.c
@@ -0,0 +1,52 @@
+/* @(#)s_frexp.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: s_frexp.c,v 1.12 2002/05/26 22:01:56 wiz Exp $");
+#endif
+
+/*
+ * for non-zero x
+ * x = frexp(arg,&exp);
+ * return a double fp quantity x such that 0.5 <= |x| <1.0
+ * and the corresponding binary exponent "exp". That is
+ * arg = x*2^exp.
+ * If arg is inf, 0.0, or NaN, then frexp(arg,&exp) returns arg
+ * with *exp=0.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+static const double
+two54 = 1.80143985094819840000e+16; /* 0x43500000, 0x00000000 */
+
+double
+frexp(double x, int *eptr)
+{
+ int32_t hx, ix, lx;
+ EXTRACT_WORDS(hx,lx,x);
+ ix = 0x7fffffff&hx;
+ *eptr = 0;
+ if(ix>=0x7ff00000||((ix|lx)==0)) return x; /* 0,inf,nan */
+ if (ix<0x00100000) { /* subnormal */
+ x *= two54;
+ GET_HIGH_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ *eptr = -54;
+ }
+ *eptr += (ix>>20)-1022;
+ hx = (hx&0x800fffff)|0x3fe00000;
+ SET_HIGH_WORD(x,hx);
+ return x;
+}
diff --git a/StdLib/LibC/Math/s_infinity.c b/StdLib/LibC/Math/s_infinity.c
new file mode 100644
index 0000000000..9ee1abd0b4
--- /dev/null
+++ b/StdLib/LibC/Math/s_infinity.c
@@ -0,0 +1,27 @@
+/* $NetBSD: s_infinity.c,v 1.5 2003/07/26 19:25:05 salo Exp $ */
+
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+#include <LibConfig.h>
+
+#include <sys/types.h>
+
+#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
+ // Force 8-byte alignment
+ #define ALIGN8 __declspec(align(8))
+
+ // C4742: identifier has different alignment in 'X' and 'Y'
+ #pragma warning ( disable : 4742 )
+ // C4744: identifier has different type in 'X' and 'Y'
+ #pragma warning ( disable : 4744 )
+#else
+ #define ALIGN8
+#endif
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ALIGN8 char __infinity[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f };
+#else
+ALIGN8 char __infinity[] = { 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+#endif
diff --git a/StdLib/LibC/Math/s_ldexp.c b/StdLib/LibC/Math/s_ldexp.c
new file mode 100644
index 0000000000..6c843c7fe9
--- /dev/null
+++ b/StdLib/LibC/Math/s_ldexp.c
@@ -0,0 +1,29 @@
+/* @(#)s_ldexp.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: s_ldexp.c,v 1.9 2002/05/26 22:01:56 wiz Exp $");
+#endif
+
+#include <errno.h>
+#include "math.h"
+#include "math_private.h"
+
+double
+ldexp(double value, int exp)
+{
+ if(!finite(value)||value==0.0) return value;
+ value = scalbn(value,exp);
+ if(!finite(value)||value==0.0) errno = ERANGE;
+ return value;
+}
diff --git a/StdLib/LibC/Math/s_modf.c b/StdLib/LibC/Math/s_modf.c
new file mode 100644
index 0000000000..bf4faf42e0
--- /dev/null
+++ b/StdLib/LibC/Math/s_modf.c
@@ -0,0 +1,76 @@
+/* @(#)s_modf.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: s_modf.c,v 1.11 2002/05/26 22:01:57 wiz Exp $");
+#endif
+
+/*
+ * modf(double x, double *iptr)
+ * return fraction part of x, and return x's integral part in *iptr.
+ * Method:
+ * Bit twiddling.
+ *
+ * Exception:
+ * No exception.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+static const double one = 1.0;
+
+double
+modf(double x, double *iptr)
+{
+ int32_t i0,i1,j0;
+ u_int32_t i;
+ EXTRACT_WORDS(i0,i1,x);
+ j0 = ((i0>>20)&0x7ff)-0x3ff; /* exponent of x */
+ if(j0<20) { /* integer part in high x */
+ if(j0<0) { /* |x|<1 */
+ INSERT_WORDS(*iptr,i0&0x80000000,0); /* *iptr = +-0 */
+ return x;
+ } else {
+ i = (0x000fffff)>>j0;
+ if(((i0&i)|i1)==0) { /* x is integral */
+ u_int32_t high;
+ *iptr = x;
+ GET_HIGH_WORD(high,x);
+ INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */
+ return x;
+ } else {
+ INSERT_WORDS(*iptr,i0&(~i),0);
+ return x - *iptr;
+ }
+ }
+ } else if (j0>51) { /* no fraction part */
+ u_int32_t high;
+ *iptr = x*one;
+ GET_HIGH_WORD(high,x);
+ INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */
+ return x;
+ } else { /* fraction part in low x */
+ i = ((u_int32_t)(0xffffffff))>>(j0-20);
+ if((i1&i)==0) { /* x is integral */
+ u_int32_t high;
+ *iptr = x;
+ GET_HIGH_WORD(high,x);
+ INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */
+ return x;
+ } else {
+ INSERT_WORDS(*iptr,i0,i1&(~i));
+ return x - *iptr;
+ }
+ }
+}
diff --git a/StdLib/LibC/Math/s_scalbn.c b/StdLib/LibC/Math/s_scalbn.c
new file mode 100644
index 0000000000..072f1c7c89
--- /dev/null
+++ b/StdLib/LibC/Math/s_scalbn.c
@@ -0,0 +1,60 @@
+/* @(#)s_scalbn.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: s_scalbn.c,v 1.12 2002/05/26 22:01:58 wiz Exp $");
+#endif
+
+/*
+ * scalbn (double x, int n)
+ * scalbn(x,n) returns x* 2**n computed by exponent
+ * manipulation rather than by actually performing an
+ * exponentiation or a multiplication.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+static const double
+two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
+twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
+huge = 1.0e+300,
+tiny = 1.0e-300;
+
+double
+scalbn(double x, int n)
+{
+ int32_t k,hx,lx;
+ EXTRACT_WORDS(hx,lx,x);
+ k = (hx&0x7ff00000)>>20; /* extract exponent */
+ if (k==0) { /* 0 or subnormal x */
+ if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */
+ x *= two54;
+ GET_HIGH_WORD(hx,x);
+ k = ((hx&0x7ff00000)>>20) - 54;
+ if (n< -50000) return tiny*x; /*underflow*/
+ }
+ if (k==0x7ff) return x+x; /* NaN or Inf */
+ k = k+n;
+ if (k > 0x7fe) return huge*copysign(huge,x); /* overflow */
+ if (k > 0) /* normal result */
+ {SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); return x;}
+ if (k <= -54) {
+ if (n > 50000) /* in case integer overflow in n+k */
+ return huge*copysign(huge,x); /*overflow*/
+ else return tiny*copysign(tiny,x); /*underflow*/
+ }
+ k += 54; /* subnormal result */
+ SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20));
+ return x*twom54;
+}
diff --git a/StdLib/LibC/Math/s_sin.c b/StdLib/LibC/Math/s_sin.c
new file mode 100644
index 0000000000..2f373c984e
--- /dev/null
+++ b/StdLib/LibC/Math/s_sin.c
@@ -0,0 +1,79 @@
+/* @(#)s_sin.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: s_sin.c,v 1.10 2002/05/26 22:01:58 wiz Exp $");
+#endif
+
+/* sin(x)
+ * Return sine function of x.
+ *
+ * kernel function:
+ * __kernel_sin ... sine function on [-pi/4,pi/4]
+ * __kernel_cos ... cose function on [-pi/4,pi/4]
+ * __ieee754_rem_pio2 ... argument reduction routine
+ *
+ * Method.
+ * Let S,C and T denote the sin, cos and tan respectively on
+ * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
+ * in [-pi/4 , +pi/4], and let n = k mod 4.
+ * We have
+ *
+ * n sin(x) cos(x) tan(x)
+ * ----------------------------------------------------------
+ * 0 S C T
+ * 1 C -S -1/T
+ * 2 -S -C T
+ * 3 -C S -1/T
+ * ----------------------------------------------------------
+ *
+ * Special cases:
+ * Let trig be any of sin, cos, or tan.
+ * trig(+-INF) is NaN, with signals;
+ * trig(NaN) is that NaN;
+ *
+ * Accuracy:
+ * TRIG(x) returns trig(x) nearly rounded
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+double
+sin(double x)
+{
+ double y[2],z=0.0;
+ int32_t n, ix;
+
+ /* High word of x. */
+ GET_HIGH_WORD(ix,x);
+
+ /* |x| ~< pi/4 */
+ ix &= 0x7fffffff;
+ if(ix <= 0x3fe921fb) return __kernel_sin(x,z,0);
+
+ /* sin(Inf or NaN) is NaN */
+ else if (ix>=0x7ff00000) return x-x;
+
+ /* argument reduction needed */
+ else {
+ n = __ieee754_rem_pio2(x,y);
+ switch(n&3) {
+ case 0: return __kernel_sin(y[0],y[1],1);
+ case 1: return __kernel_cos(y[0],y[1]);
+ case 2: return -__kernel_sin(y[0],y[1],1);
+ default:
+ return -__kernel_cos(y[0],y[1]);
+ }
+ }
+}
diff --git a/StdLib/LibC/Math/s_tan.c b/StdLib/LibC/Math/s_tan.c
new file mode 100644
index 0000000000..6c2a26de5a
--- /dev/null
+++ b/StdLib/LibC/Math/s_tan.c
@@ -0,0 +1,73 @@
+/* @(#)s_tan.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: s_tan.c,v 1.10 2002/05/26 22:01:58 wiz Exp $");
+#endif
+
+/* tan(x)
+ * Return tangent function of x.
+ *
+ * kernel function:
+ * __kernel_tan ... tangent function on [-pi/4,pi/4]
+ * __ieee754_rem_pio2 ... argument reduction routine
+ *
+ * Method.
+ * Let S,C and T denote the sin, cos and tan respectively on
+ * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
+ * in [-pi/4 , +pi/4], and let n = k mod 4.
+ * We have
+ *
+ * n sin(x) cos(x) tan(x)
+ * ----------------------------------------------------------
+ * 0 S C T
+ * 1 C -S -1/T
+ * 2 -S -C T
+ * 3 -C S -1/T
+ * ----------------------------------------------------------
+ *
+ * Special cases:
+ * Let trig be any of sin, cos, or tan.
+ * trig(+-INF) is NaN, with signals;
+ * trig(NaN) is that NaN;
+ *
+ * Accuracy:
+ * TRIG(x) returns trig(x) nearly rounded
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+double
+tan(double x)
+{
+ double y[2],z=0.0;
+ int32_t n, ix;
+
+ /* High word of x. */
+ GET_HIGH_WORD(ix,x);
+
+ /* |x| ~< pi/4 */
+ ix &= 0x7fffffff;
+ if(ix <= 0x3fe921fb) return __kernel_tan(x,z,1);
+
+ /* tan(Inf or NaN) is NaN */
+ else if (ix>=0x7ff00000) return x-x; /* NaN */
+
+ /* argument reduction needed */
+ else {
+ n = __ieee754_rem_pio2(x,y);
+ return __kernel_tan(y[0],y[1],1-((n&1)<<1)); /* 1 -- n even
+ -1 -- n odd */
+ }
+}
diff --git a/StdLib/LibC/Math/s_tanh.c b/StdLib/LibC/Math/s_tanh.c
new file mode 100644
index 0000000000..f6e17a7b4f
--- /dev/null
+++ b/StdLib/LibC/Math/s_tanh.c
@@ -0,0 +1,79 @@
+/* @(#)s_tanh.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: s_tanh.c,v 1.10 2002/05/26 22:01:59 wiz Exp $");
+#endif
+
+/* Tanh(x)
+ * Return the Hyperbolic Tangent of x
+ *
+ * Method :
+ * x -x
+ * e - e
+ * 0. tanh(x) is defined to be -----------
+ * x -x
+ * e + e
+ * 1. reduce x to non-negative by tanh(-x) = -tanh(x).
+ * 2. 0 <= x <= 2**-55 : tanh(x) := x*(one+x)
+ * -t
+ * 2**-55 < x <= 1 : tanh(x) := -----; t = expm1(-2x)
+ * t + 2
+ * 2
+ * 1 <= x <= 22.0 : tanh(x) := 1- ----- ; t=expm1(2x)
+ * t + 2
+ * 22.0 < x <= INF : tanh(x) := 1.
+ *
+ * Special cases:
+ * tanh(NaN) is NaN;
+ * only tanh(0)=0 is exact for finite argument.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+static const double one=1.0, two=2.0, tiny = 1.0e-300;
+
+double
+tanh(double x)
+{
+ double t,z;
+ int32_t jx,ix;
+
+ /* High word of |x|. */
+ GET_HIGH_WORD(jx,x);
+ ix = jx&0x7fffffff;
+
+ /* x is INF or NaN */
+ if(ix>=0x7ff00000) {
+ if (jx>=0) return one/x+one; /* tanh(+-inf)=+-1 */
+ else return one/x-one; /* tanh(NaN) = NaN */
+ }
+
+ /* |x| < 22 */
+ if (ix < 0x40360000) { /* |x|<22 */
+ if (ix<0x3c800000) /* |x|<2**-55 */
+ return x*(one+x); /* tanh(small) = small */
+ if (ix>=0x3ff00000) { /* |x|>=1 */
+ t = expm1(two*fabs(x));
+ z = one - two/(t+two);
+ } else {
+ t = expm1(-two*fabs(x));
+ z= -t/(t+two);
+ }
+ /* |x| > 22, return +-1 */
+ } else {
+ z = one - tiny; /* raised inexact flag */
+ }
+ return (jx>=0)? z: -z;
+}
diff --git a/StdLib/LibC/Math/w_acos.c b/StdLib/LibC/Math/w_acos.c
new file mode 100644
index 0000000000..7e6aa10254
--- /dev/null
+++ b/StdLib/LibC/Math/w_acos.c
@@ -0,0 +1,40 @@
+/* @(#)w_acos.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: w_acos.c,v 1.9 2002/05/26 22:01:59 wiz Exp $");
+#endif
+
+/*
+ * wrap_acos(x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+
+double
+acos(double x) /* wrapper acos */
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_acos(x);
+#else
+ double z;
+ z = __ieee754_acos(x);
+ if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
+ if(fabs(x)>1.0) {
+ return __kernel_standard(x,x,1); /* acos(|x|>1) */
+ } else
+ return z;
+#endif
+}
diff --git a/StdLib/LibC/Math/w_asin.c b/StdLib/LibC/Math/w_asin.c
new file mode 100644
index 0000000000..988c42dc1f
--- /dev/null
+++ b/StdLib/LibC/Math/w_asin.c
@@ -0,0 +1,41 @@
+/* @(#)w_asin.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: w_asin.c,v 1.9 2002/05/26 22:01:59 wiz Exp $");
+#endif
+
+/*
+ * wrapper asin(x)
+ */
+
+
+#include "math.h"
+#include "math_private.h"
+
+
+double
+asin(double x) /* wrapper asin */
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_asin(x);
+#else
+ double z;
+ z = __ieee754_asin(x);
+ if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
+ if(fabs(x)>1.0) {
+ return __kernel_standard(x,x,2); /* asin(|x|>1) */
+ } else
+ return z;
+#endif
+}
diff --git a/StdLib/LibC/Math/w_atan2.c b/StdLib/LibC/Math/w_atan2.c
new file mode 100644
index 0000000000..dbf38de42f
--- /dev/null
+++ b/StdLib/LibC/Math/w_atan2.c
@@ -0,0 +1,40 @@
+/* @(#)w_atan2.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: w_atan2.c,v 1.9 2002/05/26 22:01:59 wiz Exp $");
+#endif
+
+/*
+ * wrapper atan2(y,x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+
+double
+atan2(double y, double x) /* wrapper atan2 */
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_atan2(y,x);
+#else
+ double z;
+ z = __ieee754_atan2(y,x);
+ if(_LIB_VERSION == _IEEE_||isnan(x)||isnan(y)) return z;
+ if(x==0.0&&y==0.0) {
+ return __kernel_standard(y,x,3); /* atan2(+-0,+-0) */
+ } else
+ return z;
+#endif
+}
diff --git a/StdLib/LibC/Math/w_cosh.c b/StdLib/LibC/Math/w_cosh.c
new file mode 100644
index 0000000000..3d73bff961
--- /dev/null
+++ b/StdLib/LibC/Math/w_cosh.c
@@ -0,0 +1,39 @@
+/* @(#)w_cosh.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: w_cosh.c,v 1.9 2002/05/26 22:02:00 wiz Exp $");
+#endif
+
+/*
+ * wrapper cosh(x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+double
+cosh(double x) /* wrapper cosh */
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_cosh(x);
+#else
+ double z;
+ z = __ieee754_cosh(x);
+ if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
+ if(fabs(x)>7.10475860073943863426e+02) {
+ return __kernel_standard(x,x,5); /* cosh overflow */
+ } else
+ return z;
+#endif
+}
diff --git a/StdLib/LibC/Math/w_exp.c b/StdLib/LibC/Math/w_exp.c
new file mode 100644
index 0000000000..29a2bb2906
--- /dev/null
+++ b/StdLib/LibC/Math/w_exp.c
@@ -0,0 +1,46 @@
+/* @(#)w_exp.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: w_exp.c,v 1.9 2002/05/26 22:02:00 wiz Exp $");
+#endif
+
+/*
+ * wrapper exp(x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+static const double
+o_threshold= 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */
+u_threshold= -7.45133219101941108420e+02; /* 0xc0874910, 0xD52D3051 */
+
+double
+exp(double x) /* wrapper exp */
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_exp(x);
+#else
+ double z;
+ z = __ieee754_exp(x);
+ if(_LIB_VERSION == _IEEE_) return z;
+ if(finite(x)) {
+ if(x>o_threshold)
+ return __kernel_standard(x,x,6); /* exp overflow */
+ else if(x<u_threshold)
+ return __kernel_standard(x,x,7); /* exp underflow */
+ }
+ return z;
+#endif
+}
diff --git a/StdLib/LibC/Math/w_fmod.c b/StdLib/LibC/Math/w_fmod.c
new file mode 100644
index 0000000000..ef1b1c6875
--- /dev/null
+++ b/StdLib/LibC/Math/w_fmod.c
@@ -0,0 +1,40 @@
+/* @(#)w_fmod.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: w_fmod.c,v 1.9 2002/05/26 22:02:00 wiz Exp $");
+#endif
+
+/*
+ * wrapper fmod(x,y)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+
+double
+fmod(double x, double y) /* wrapper fmod */
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_fmod(x,y);
+#else
+ double z;
+ z = __ieee754_fmod(x,y);
+ if(_LIB_VERSION == _IEEE_ ||isnan(y)||isnan(x)) return z;
+ if(y==0.0) {
+ return __kernel_standard(x,y,27); /* fmod(x,0) */
+ } else
+ return z;
+#endif
+}
diff --git a/StdLib/LibC/Math/w_log.c b/StdLib/LibC/Math/w_log.c
new file mode 100644
index 0000000000..ae8a5a2338
--- /dev/null
+++ b/StdLib/LibC/Math/w_log.c
@@ -0,0 +1,40 @@
+/* @(#)w_log.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: w_log.c,v 1.9 2002/05/26 22:02:02 wiz Exp $");
+#endif
+
+/*
+ * wrapper log(x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+
+double
+log(double x) /* wrapper log */
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_log(x);
+#else
+ double z;
+ z = __ieee754_log(x);
+ if(_LIB_VERSION == _IEEE_ || isnan(x) || x > 0.0) return z;
+ if(x==0.0)
+ return __kernel_standard(x,x,16); /* log(0) */
+ else
+ return __kernel_standard(x,x,17); /* log(x<0) */
+#endif
+}
diff --git a/StdLib/LibC/Math/w_log10.c b/StdLib/LibC/Math/w_log10.c
new file mode 100644
index 0000000000..4c82dfbccc
--- /dev/null
+++ b/StdLib/LibC/Math/w_log10.c
@@ -0,0 +1,43 @@
+/* @(#)w_log10.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: w_log10.c,v 1.9 2002/05/26 22:02:02 wiz Exp $");
+#endif
+
+/*
+ * wrapper log10(X)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+
+double
+log10(double x) /* wrapper log10 */
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_log10(x);
+#else
+ double z;
+ z = __ieee754_log10(x);
+ if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
+ if(x<=0.0) {
+ if(x==0.0)
+ return __kernel_standard(x,x,18); /* log10(0) */
+ else
+ return __kernel_standard(x,x,19); /* log10(x<0) */
+ } else
+ return z;
+#endif
+}
diff --git a/StdLib/LibC/Math/w_log2.c b/StdLib/LibC/Math/w_log2.c
new file mode 100644
index 0000000000..35e4d1fccd
--- /dev/null
+++ b/StdLib/LibC/Math/w_log2.c
@@ -0,0 +1,43 @@
+/* @(#)w_log10.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: w_log2.c,v 1.1 2005/07/21 16:58:39 christos Exp $");
+#endif
+
+/*
+ * wrapper log2(X)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+
+double
+log2(double x) /* wrapper log10 */
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_log2(x);
+#else
+ double z;
+ z = __ieee754_log2(x);
+ if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
+ if(x<=0.0) {
+ if(x==0.0)
+ return __kernel_standard(x,x,48); /* log2(0) */
+ else
+ return __kernel_standard(x,x,49); /* log2(x<0) */
+ } else
+ return z;
+#endif
+}
diff --git a/StdLib/LibC/Math/w_pow.c b/StdLib/LibC/Math/w_pow.c
new file mode 100644
index 0000000000..f5c4a39a90
--- /dev/null
+++ b/StdLib/LibC/Math/w_pow.c
@@ -0,0 +1,62 @@
+
+
+/* @(#)w_pow.c 5.2 93/10/01 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: w_pow.c,v 1.7 2002/05/26 22:02:02 wiz Exp $");
+#endif
+
+/*
+ * wrapper pow(x,y) return x**y
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+
+double
+pow(double x, double y) /* wrapper pow */
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_pow(x,y);
+#else
+ double z;
+ z=__ieee754_pow(x,y);
+ if(_LIB_VERSION == _IEEE_|| isnan(y)) return z;
+ if(isnan(x)) {
+ if(y==0.0)
+ return __kernel_standard(x,y,42); /* pow(NaN,0.0) */
+ else
+ return z;
+ }
+ if(x==0.0){
+ if(y==0.0)
+ return __kernel_standard(x,y,20); /* pow(0.0,0.0) */
+ if(finite(y)&&y<0.0)
+ return __kernel_standard(x,y,23); /* pow(0.0,negative) */
+ return z;
+ }
+ if(!finite(z)) {
+ if(finite(x)&&finite(y)) {
+ if(isnan(z))
+ return __kernel_standard(x,y,24); /* pow neg**non-int */
+ else
+ return __kernel_standard(x,y,21); /* pow overflow */
+ }
+ }
+ if(z==0.0&&finite(x)&&finite(y))
+ return __kernel_standard(x,y,22); /* pow underflow */
+ return z;
+#endif
+}
diff --git a/StdLib/LibC/Math/w_sinh.c b/StdLib/LibC/Math/w_sinh.c
new file mode 100644
index 0000000000..f653738a3c
--- /dev/null
+++ b/StdLib/LibC/Math/w_sinh.c
@@ -0,0 +1,39 @@
+/* @(#)w_sinh.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: w_sinh.c,v 1.9 2002/05/26 22:02:03 wiz Exp $");
+#endif
+
+/*
+ * wrapper sinh(x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+double
+sinh(double x) /* wrapper sinh */
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_sinh(x);
+#else
+ double z;
+ z = __ieee754_sinh(x);
+ if(_LIB_VERSION == _IEEE_) return z;
+ if(!finite(z)&&finite(x)) {
+ return __kernel_standard(x,x,25); /* sinh overflow */
+ } else
+ return z;
+#endif
+}
diff --git a/StdLib/LibC/Math/w_sqrt.c b/StdLib/LibC/Math/w_sqrt.c
new file mode 100644
index 0000000000..e55b4d8953
--- /dev/null
+++ b/StdLib/LibC/Math/w_sqrt.c
@@ -0,0 +1,39 @@
+/* @(#)w_sqrt.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBM_SCCS) && !defined(lint)
+__RCSID("$NetBSD: w_sqrt.c,v 1.9 2002/05/26 22:02:03 wiz Exp $");
+#endif
+
+/*
+ * wrapper sqrt(x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+double
+sqrt(double x) /* wrapper sqrt */
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_sqrt(x);
+#else
+ double z;
+ z = __ieee754_sqrt(x);
+ if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
+ if(x<0.0) {
+ return __kernel_standard(x,x,26); /* sqrt(negative) */
+ } else
+ return z;
+#endif
+}
diff --git a/StdLib/LibC/NetUtil/NetUtil.inf b/StdLib/LibC/NetUtil/NetUtil.inf
new file mode 100644
index 0000000000..537fe9cd42
--- /dev/null
+++ b/StdLib/LibC/NetUtil/NetUtil.inf
@@ -0,0 +1,59 @@
+## @file
+# BSD Socket Library, Infrastructure functions.
+#
+# Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = LibNetUtil
+ FILE_GUID = f3c9667b-c50c-4e9c-a1f1-78c3b1ddf2c2
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = LibNetUtil
+
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[Sources]
+ inet_addr.c #
+ inet_makeaddr.c #
+ inet_lnaof.c #
+ inet_netof.c #
+ inet_network.c #
+ inet_ntoa.c #
+ inet_ntop.c #
+
+[Packages]
+ StdLib/StdLib.dec
+ StdLibPrivateInternalFiles/DoNotUse.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ UefiLib
+ BaseLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ LibStdLib
+ LibStdio
+ LibString
+
+################################################################
+#
+# The Build Options, below, are only used when building the Socket library.
+# DO NOT use them when building your application!
+# Nasty things could happen if you do.
+#
+#[BuildOptions]
+# MSFT:*_*_IA32_CC_FLAGS = /GL-
diff --git a/StdLib/LibC/NetUtil/inet_addr.c b/StdLib/LibC/NetUtil/inet_addr.c
new file mode 100644
index 0000000000..fadc09de34
--- /dev/null
+++ b/StdLib/LibC/NetUtil/inet_addr.c
@@ -0,0 +1,225 @@
+/** @file
+ Convert a string internet address into an integer (32-bit) address.
+
+ Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ * Copyright (c) 1983, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ NetBSD: inet_addr.c,v 1.1 2005/12/20 19:28:51 christos Exp
+ inet_addr.c 8.1 (Berkeley) 6/17/93
+ inet_addr.c,v 1.2.206.2 2004/03/17 00:29:45 marka Exp
+**/
+
+#if !defined(_KERNEL) && !defined(_STANDALONE)
+#include <LibConfig.h>
+
+//#include "port_before.h"
+
+#include <namespace.h>
+#include <sys/types.h>
+#include <sys/param.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <ctype.h>
+
+//#include "port_after.h"
+
+#ifdef __weak_alias
+ __weak_alias(inet_aton,_inet_aton)
+#endif
+
+#else // NOT (!defined(_KERNEL) && !defined(_STANDALONE))
+ #include <lib/libkern/libkern.h>
+ #include <netinet/in.h>
+#endif
+
+/*
+ * Ascii internet address interpretation routine.
+ * The value returned is in network order.
+ */
+u_int32_t
+inet_addr(const char *cp) {
+ struct in_addr val;
+
+ if (inet_aton(cp, &val))
+ return (val.s_addr);
+ return (INADDR_NONE);
+}
+
+/*
+ * Check whether "cp" is a valid ascii representation
+ * of an Internet address and convert to a binary address.
+ * Returns 1 if the address is valid, 0 if not.
+ * This replaces inet_addr, the return value from which
+ * cannot distinguish between failure and a local broadcast address.
+ */
+int
+inet_aton(const char *cp, struct in_addr *addr) {
+ u_int32_t val;
+ int base, n;
+ char c;
+ u_int8_t parts[4];
+ u_int8_t *pp = parts;
+ int digit;
+
+ c = *cp;
+ for (;;) {
+ /*
+ * Collect number up to ``.''.
+ * Values are specified as for C:
+ * 0x=hex, 0=octal, isdigit=decimal.
+ */
+ if (!isdigit((unsigned char)c))
+ return (0);
+ val = 0; base = 10; digit = 0;
+ if (c == '0') {
+ c = *++cp;
+ if (c == 'x' || c == 'X')
+ base = 16, c = *++cp;
+ else {
+ base = 8;
+ digit = 1 ;
+ }
+ }
+ for (;;) {
+ if (isascii(c) && isdigit((unsigned char)c)) {
+ if (base == 8 && (c == '8' || c == '9'))
+ return (0);
+ val = (val * base) + (c - '0');
+ c = *++cp;
+ digit = 1;
+ } else if (base == 16 && isascii(c) &&
+ isxdigit((unsigned char)c)) {
+ val = (val << 4) |
+ (c + 10 - (islower((unsigned char)c) ? 'a' : 'A'));
+ c = *++cp;
+ digit = 1;
+ } else
+ break;
+ }
+ if (c == '.') {
+ /*
+ * Internet format:
+ * a.b.c.d
+ * a.b.c (with c treated as 16 bits)
+ * a.b (with b treated as 24 bits)
+ */
+ if (pp >= parts + 3 || val > 0xffU)
+ return (0);
+ *pp++ = (u_int8_t)val;
+ c = *++cp;
+ } else
+ break;
+ }
+ /*
+ * Check for trailing characters.
+ */
+ if (c != '\0' && (!isascii(c) || !isspace((unsigned char)c)))
+ return (0);
+ /*
+ * Did we get a valid digit?
+ */
+ if (!digit)
+ return (0);
+ /*
+ * Concoct the address according to
+ * the number of parts specified.
+ */
+ n = (int)(pp - parts + 1);
+ switch (n) {
+ case 1: /* a -- 32 bits */
+ break;
+
+ case 2: /* a.b -- 8.24 bits */
+ if (val > 0xffffffU)
+ return (0);
+ val |= parts[0] << 24;
+ break;
+
+ case 3: /* a.b.c -- 8.8.16 bits */
+ if (val > 0xffffU)
+ return (0);
+ val |= (parts[0] << 24) | (parts[1] << 16);
+ break;
+
+ case 4: /* a.b.c.d -- 8.8.8.8 bits */
+ if (val > 0xffU)
+ return (0);
+ val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
+ break;
+ }
+ if (addr != NULL)
+ addr->s_addr = htonl(val);
+ return (1);
+}
diff --git a/StdLib/LibC/NetUtil/inet_lnaof.c b/StdLib/LibC/NetUtil/inet_lnaof.c
new file mode 100644
index 0000000000..39f09d1fde
--- /dev/null
+++ b/StdLib/LibC/NetUtil/inet_lnaof.c
@@ -0,0 +1,70 @@
+/** @File
+ Return the local network address portion of an internet address.
+
+ Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+
+ NetBSD: inet_lnaof.c,v 1.1 2004/05/20 23:13:02 christos Exp
+ inet_lnaof.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include "namespace.h"
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#ifdef __weak_alias
+ __weak_alias(inet_lnaof,_inet_lnaof)
+#endif
+
+/*
+ * Return the local network address portion of an
+ * internet address; handles class a/b/c network
+ * number formats.
+ */
+in_addr_t
+inet_lnaof(struct in_addr in)
+{
+ in_addr_t i = ntohl(in.s_addr);
+
+ if (IN_CLASSA(i))
+ return ((i)&IN_CLASSA_HOST);
+ else if (IN_CLASSB(i))
+ return ((i)&IN_CLASSB_HOST);
+ else
+ return ((i)&IN_CLASSC_HOST);
+}
diff --git a/StdLib/LibC/NetUtil/inet_makeaddr.c b/StdLib/LibC/NetUtil/inet_makeaddr.c
new file mode 100644
index 0000000000..5ead092015
--- /dev/null
+++ b/StdLib/LibC/NetUtil/inet_makeaddr.c
@@ -0,0 +1,74 @@
+/** @File
+ Formulate an Internet address from network + host.
+
+ Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+
+ NetBSD: inet_makeaddr.c,v 1.1 2004/05/20 23:13:02 christos Exp
+ inet_makeaddr.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include "namespace.h"
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#ifdef __weak_alias
+__weak_alias(inet_makeaddr,_inet_makeaddr)
+#endif
+
+/*
+ * Formulate an Internet address from network + host. Used in
+ * building addresses stored in the ifnet structure.
+ */
+struct in_addr
+inet_makeaddr(in_addr_t net, in_addr_t host)
+{
+ in_addr_t addr;
+ struct in_addr ret;
+
+ if (net < 128)
+ addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST);
+ else if (net < 65536)
+ addr = (net << IN_CLASSB_NSHIFT) | (host & IN_CLASSB_HOST);
+ else if (net < 16777216L)
+ addr = (net << IN_CLASSC_NSHIFT) | (host & IN_CLASSC_HOST);
+ else
+ addr = net | host;
+ ret.s_addr = htonl(addr);
+ return ret;
+}
diff --git a/StdLib/LibC/NetUtil/inet_netof.c b/StdLib/LibC/NetUtil/inet_netof.c
new file mode 100644
index 0000000000..dabb768389
--- /dev/null
+++ b/StdLib/LibC/NetUtil/inet_netof.c
@@ -0,0 +1,69 @@
+/** @File
+ Return the network number from an internet address.
+
+ Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+
+ NetBSD: inet_netof.c,v 1.1 2004/05/20 23:13:02 christos Exp
+ inet_netof.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include "namespace.h"
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#ifdef __weak_alias
+__weak_alias(inet_netof,_inet_netof)
+#endif
+
+/*
+ * Return the network number from an internet
+ * address; handles class a/b/c network #'s.
+ */
+in_addr_t
+inet_netof(struct in_addr in)
+{
+ in_addr_t i = ntohl(in.s_addr);
+
+ if (IN_CLASSA(i))
+ return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
+ else if (IN_CLASSB(i))
+ return (((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
+ else
+ return (((i)&IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
+}
diff --git a/StdLib/LibC/NetUtil/inet_network.c b/StdLib/LibC/NetUtil/inet_network.c
new file mode 100644
index 0000000000..8cec75dc0c
--- /dev/null
+++ b/StdLib/LibC/NetUtil/inet_network.c
@@ -0,0 +1,120 @@
+/** @File
+ Internet network address interpretation routine.
+
+ Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+
+ NetBSD: inet_network.c,v 1.1 2004/05/20 23:13:02 christos Exp
+ inet_network.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include "namespace.h"
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <assert.h>
+#include <ctype.h>
+#ifdef _DIAGNOSTIC
+#include <stddef.h> /* for NULL */
+#endif
+
+#ifdef __weak_alias
+__weak_alias(inet_network,_inet_network)
+#endif
+
+/*
+ * Internet network address interpretation routine.
+ * The library routines call this routine to interpret
+ * network numbers.
+ */
+in_addr_t
+inet_network(const char *cp)
+{
+ in_addr_t val;
+ size_t i, n;
+ u_char c;
+ in_addr_t parts[4], *pp = parts;
+ int digit, base;
+
+ _DIAGASSERT(cp != NULL);
+
+again:
+ val = 0; base = 10; digit = 0;
+ if (*cp == '0')
+ digit = 1, base = 8, cp++;
+ if (*cp == 'x' || *cp == 'X')
+ base = 16, cp++;
+ while ((c = *cp) != 0) {
+ if (isdigit(c)) {
+ if (base == 8 && (c == '8' || c == '9'))
+ return (INADDR_NONE);
+ val = (val * base) + (c - '0');
+ cp++;
+ digit = 1;
+ continue;
+ }
+ if (base == 16 && isxdigit(c)) {
+ val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
+ cp++;
+ digit = 1;
+ continue;
+ }
+ break;
+ }
+ if (!digit)
+ return (INADDR_NONE);
+ if (*cp == '.') {
+ if (pp >= parts + 4 || val > 0xff)
+ return (INADDR_NONE);
+ *pp++ = val, cp++;
+ goto again;
+ }
+ if (*cp && !isspace((u_char) *cp))
+ return (INADDR_NONE);
+ if (pp >= parts + 4 || val > 0xff)
+ return (INADDR_NONE);
+ *pp++ = val;
+ n = pp - parts;
+ if (n > 4)
+ return (INADDR_NONE);
+ for (val = 0, i = 0; i < n; i++) {
+ val <<= 8;
+ val |= parts[i] & 0xff;
+ }
+ return (val);
+}
diff --git a/StdLib/LibC/NetUtil/inet_ntoa.c b/StdLib/LibC/NetUtil/inet_ntoa.c
new file mode 100644
index 0000000000..11bd842a48
--- /dev/null
+++ b/StdLib/LibC/NetUtil/inet_ntoa.c
@@ -0,0 +1,69 @@
+/** @File
+ Convert network-format internet address to base 256 d.d.d.d representation.
+
+ Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+
+ NetBSD: inet_ntoa.c,v 1.1 2004/05/20 23:13:02 christos Exp
+ inet_ntoa.c 8.1 (Berkeley) 6/4/93
+ */
+#include <LibConfig.h>
+
+#include "namespace.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef __weak_alias
+ __weak_alias(inet_ntoa,_inet_ntoa)
+#endif
+
+/*
+ * Convert network-format internet address
+ * to base 256 d.d.d.d representation.
+ */
+/*const*/ char *
+inet_ntoa(struct in_addr in) {
+ static char ret[18];
+
+ //strlcpy(ret, "[inet_ntoa error]", sizeof(ret));
+ strncpyX(ret, "[inet_ntoa error]", sizeof(ret));
+ (void) inet_ntop(AF_INET, &in, ret, sizeof ret);
+ return (ret);
+}
diff --git a/StdLib/LibC/NetUtil/inet_ntop.c b/StdLib/LibC/NetUtil/inet_ntop.c
new file mode 100644
index 0000000000..c16935c369
--- /dev/null
+++ b/StdLib/LibC/NetUtil/inet_ntop.c
@@ -0,0 +1,238 @@
+/** @File
+ Convert a binary network address into a presentable (printable) format.
+
+ Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996-1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ NetBSD: inet_ntop.c,v 1.3.4.2 2007/05/17 21:25:14 jdc Exp
+ inet_ntop.c,v 1.3.18.2 2005/11/03 23:02:22 marka Exp
+**/
+#include <LibConfig.h>
+
+//#include "port_before.h"
+
+#include "namespace.h"
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+//#include "port_after.h"
+
+#ifdef __weak_alias
+ __weak_alias(inet_ntop,_inet_ntop)
+#endif
+
+/*%
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static const char *inet_ntop4(const u_char *src, char *dst, socklen_t size);
+static const char *inet_ntop6(const u_char *src, char *dst, socklen_t size);
+
+/* char *
+ * inet_ntop(af, src, dst, size)
+ * convert a network format address to presentation format.
+ * return:
+ * pointer to presentation format address (`dst'), or NULL (see errno).
+ * author:
+ * Paul Vixie, 1996.
+ */
+const char *
+inet_ntop(int af, const void *src, char *dst, socklen_t size)
+{
+
+ _DIAGASSERT(src != NULL);
+ _DIAGASSERT(dst != NULL);
+
+ switch (af) {
+ case AF_INET:
+ return (inet_ntop4(src, dst, size));
+ case AF_INET6:
+ return (inet_ntop6(src, dst, size));
+ default:
+ errno = EAFNOSUPPORT;
+ return (NULL);
+ }
+ /* NOTREACHED */
+}
+
+/* const char *
+ * inet_ntop4(src, dst, size)
+ * format an IPv4 address, more or less like inet_ntoa()
+ * return:
+ * `dst' (as a const)
+ * notes:
+ * (1) uses no statics
+ * (2) takes a u_char* not an in_addr as input
+ * author:
+ * Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop4(const u_char *src, char *dst, socklen_t size)
+{
+ char tmp[sizeof "255.255.255.255"];
+ int l;
+
+ _DIAGASSERT(src != NULL);
+ _DIAGASSERT(dst != NULL);
+
+ l = snprintf(tmp, sizeof(tmp), "%u.%u.%u.%u",
+ src[0], src[1], src[2], src[3]);
+ if (l <= 0 || (socklen_t) l >= size) {
+ errno = ENOSPC;
+ return (NULL);
+ }
+ //strlcpy(dst, tmp, size);
+ strncpyX(dst, tmp, (size_t)size);
+ return (dst);
+}
+
+/* const char *
+ * inet_ntop6(src, dst, size)
+ * convert IPv6 binary address into presentation (printable) format
+ * author:
+ * Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop6(const u_char *src, char *dst, socklen_t size)
+{
+ /*
+ * Note that int32_t and int16_t need only be "at least" large enough
+ * to contain a value of the specified size. On some systems, like
+ * Crays, there is no such thing as an integer variable with 16 bits.
+ * Keep this in mind if you think this function should have been coded
+ * to use pointer overlays. All the world's not a VAX.
+ */
+ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
+ char *tp, *ep;
+ struct { int base, len; } best, cur;
+ unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ];
+ int i;
+ int advance;
+
+ _DIAGASSERT(src != NULL);
+ _DIAGASSERT(dst != NULL);
+
+ /*
+ * Preprocess:
+ * Copy the input (bytewise) array into a wordwise array.
+ * Find the longest run of 0x00's in src[] for :: shorthanding.
+ */
+ memset(words, '\0', sizeof words);
+ for (i = 0; i < NS_IN6ADDRSZ; i++)
+ words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
+ best.base = -1;
+ best.len = 0;
+ cur.base = -1;
+ cur.len = 0;
+ for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
+ if (words[i] == 0) {
+ if (cur.base == -1)
+ cur.base = i, cur.len = 1;
+ else
+ cur.len++;
+ } else {
+ if (cur.base != -1) {
+ if (best.base == -1 || cur.len > best.len)
+ best = cur;
+ cur.base = -1;
+ }
+ }
+ }
+ if (cur.base != -1) {
+ if (best.base == -1 || cur.len > best.len)
+ best = cur;
+ }
+ if (best.base != -1 && best.len < 2)
+ best.base = -1;
+
+ /*
+ * Format the result.
+ */
+ tp = tmp;
+ ep = tmp + sizeof(tmp);
+ for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
+ /* Are we inside the best run of 0x00's? */
+ if (best.base != -1 && i >= best.base &&
+ i < (best.base + best.len)) {
+ if (i == best.base)
+ *tp++ = ':';
+ continue;
+ }
+ /* Are we following an initial run of 0x00s or any real hex? */
+ if (i != 0) {
+ if (tp + 1 >= ep)
+ return (NULL);
+ *tp++ = ':';
+ }
+ /* Is this address an encapsulated IPv4? */
+ if (i == 6 && best.base == 0 &&
+ (best.len == 6 ||
+ (best.len == 7 && words[7] != 0x0001) ||
+ (best.len == 5 && words[5] == 0xffff))) {
+ if (!inet_ntop4(src+12, tp, (socklen_t)(ep - tp)))
+ return (NULL);
+ tp += strlen(tp);
+ break;
+ }
+ advance = snprintf(tp, (size_t)(ep - tp), "%x", words[i]);
+ if (advance <= 0 || advance >= ep - tp)
+ return (NULL);
+ tp += advance;
+ }
+ /* Was it a trailing run of 0x00's? */
+ if (best.base != -1 && (best.base + best.len) ==
+ (NS_IN6ADDRSZ / NS_INT16SZ)) {
+ if (tp + 1 >= ep)
+ return (NULL);
+ *tp++ = ':';
+ }
+ if (tp + 1 >= ep)
+ return (NULL);
+ *tp++ = '\0';
+
+ /*
+ * Check for overflow, copy, and we're done.
+ */
+ if ((size_t)(tp - tmp) > size) {
+ errno = ENOSPC;
+ return (NULL);
+ }
+ //strlcpy(dst, tmp, size);
+ strncpyX(dst, tmp, (size_t)size);
+ return (dst);
+}
+
+/*! \file */
diff --git a/StdLib/LibC/Signal/Signal.c b/StdLib/LibC/Signal/Signal.c
new file mode 100644
index 0000000000..15b9ecabc2
--- /dev/null
+++ b/StdLib/LibC/Signal/Signal.c
@@ -0,0 +1,93 @@
+/** @file
+ Implementation of the signal and raise functions as declared in <signal.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#include <Uefi.h>
+#include <Library/UefiLib.h>
+
+#include <LibConfig.h>
+#include <errno.h>
+#include <signal.h>
+#include <MainData.h>
+
+/** The signal function associates a "signal handler" with a signal number.
+
+ The signal function chooses one of three ways in which receipt of the
+ signal number, sig, is to be subsequently handled. If the value of func
+ is SIG_DFL, default handling for that signal will occur. If the value of
+ func is SIG_IGN, the signal will be ignored. Otherwise, func shall point
+ to a function to be called when that signal occurs. An invocation of such a
+ function because of a signal, or (recursively) of any further functions
+ called by that invocation (other than functions in the standard library),
+ is called a signal handler.
+
+ At program startup, the equivalent of signal(sig, SIG_IGN); may be executed
+ for some signals selected in an implementation-defined manner; the
+ equivalent of signal(sig, SIG_DFL); is executed for all other signals
+ defined by the implementation.
+
+ @return If the request can be honored, the signal function returns the
+ value of func for the most recent successful call to signal for
+ the specified signal sig. Otherwise, a value of SIG_ERR is
+ returned and a positive value is stored in errno.
+ */
+__sighandler_t *
+signal(int sig, __sighandler_t *func)
+{
+ __sighandler_t *OldHandler;
+
+ if (sig < 0 || sig >= SIG_LAST) {
+ errno = EINVAL;
+ return SIG_ERR;
+ }
+ OldHandler = gMD->sigarray[sig];
+ gMD->sigarray[sig] = func;
+
+ return OldHandler;
+}
+
+static
+void
+_defaultSignalHandler( int sig )
+{
+ Print(L"\nCaught signal %d.\n", sig);
+}
+
+/** Send a signal.
+
+ The raise function carries out the actions described for signal, above,
+ for the signal sig.
+
+ If a signal handler is called, the raise function shall not return until
+ after the signal handler does.
+
+ @return The raise function returns zero if successful,
+ nonzero if unsuccessful.
+**/
+int
+raise( int sig)
+{
+ __sighandler_t *Handler;
+
+ if (sig < 0 || sig >= SIG_LAST) {
+ return EINVAL;
+ }
+ Handler = gMD->sigarray[sig];
+
+ if(Handler == SIG_DFL) {
+ _defaultSignalHandler( sig );
+ }
+ else if( Handler != SIG_IGN) {
+ Handler( sig );
+ }
+ return 0;
+}
diff --git a/StdLib/LibC/Signal/Signal.inf b/StdLib/LibC/Signal/Signal.inf
new file mode 100644
index 0000000000..1d991887dd
--- /dev/null
+++ b/StdLib/LibC/Signal/Signal.inf
@@ -0,0 +1,39 @@
+## @file
+# Standard C library: StdLib implementations.
+#
+# Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = LibSignal
+ FILE_GUID = 00c86db8-013b-4ff4-b8e9-208f4fcf1c00
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = LibSignal
+
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[Sources]
+ Signal.c
+
+[Packages]
+ StdLib/StdLib.dec
+ StdLibPrivateInternalFiles/DoNotUse.dec
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+
+[LibraryClasses]
+ UefiLib
+ LibC
diff --git a/StdLib/LibC/StdLib/Bsearch.c b/StdLib/LibC/StdLib/Bsearch.c
new file mode 100644
index 0000000000..90a42bfd12
--- /dev/null
+++ b/StdLib/LibC/StdLib/Bsearch.c
@@ -0,0 +1,105 @@
+/** @file
+ Binary search utility function.
+
+ This utility makes use of a comparison function to search arrays of
+ unspecified type. Where an argument declared as size_t nmemb specifies the
+ length of the array for a function, nmemb can have the value zero on a call
+ to that function; the comparison function is not called, a search finds no
+ matching element. Pointer arguments on such a call shall still have valid
+ values.
+
+ The implementation shall ensure that the second argument of the comparison
+ function is a pointer to an element of the array. The first argument shall
+ equal key.
+
+ The comparison function shall not alter the contents of the array. The
+ implementation may reorder elements of the array between calls to the
+ comparison function, but shall not alter the contents of any individual
+ element.
+
+ When the same objects (consisting of size bytes, irrespective of their
+ current positions in the array) are passed more than once to the comparison
+ function, the results shall be consistent with one another. That is, the same
+ object shall always compare the same way with the key.
+
+ A sequence point occurs immediately before and immediately after each call to
+ the comparison function, and also between any call to the comparison function
+ and any movement of the objects passed as arguments to that call.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+
+ ("$FreeBSD: src/lib/libc/stdlib/bsearch.c,v 1.4.10.1.2.1 2009/10/25 01:10:29 kensmith Exp $");
+**/
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#include <stdlib.h>
+
+/*
+ * Perform a binary search.
+ *
+ * The code below is a bit sneaky. After a comparison fails, we
+ * divide the work in half by moving either left or right. If lim
+ * is odd, moving left simply involves halving lim: e.g., when lim
+ * is 5 we look at item 2, so we change lim to 2 so that we will
+ * look at items 0 & 1. If lim is even, the same applies. If lim
+ * is odd, moving right again involes halving lim, this time moving
+ * the base up one item past p: e.g., when lim is 5 we change base
+ * to item 3 and make lim 2 so that we will look at items 3 and 4.
+ * If lim is even, however, we have to shrink it by one before
+ * halving: e.g., when lim is 4, we still looked at item 2, so we
+ * have to make lim 3, then halve, obtaining 1, so that we will only
+ * look at item 3.
+ */
+void *
+bsearch(
+ const void *key,
+ const void *base0,
+ size_t nmemb,
+ size_t size,
+ int (*compar)(const void *, const void *)
+ )
+{
+ const char *base = base0;
+ size_t lim;
+ int cmp;
+ const void *p;
+
+ for (lim = nmemb; lim != 0; lim >>= 1) {
+ p = base + (lim >> 1) * size;
+ cmp = (*compar)(key, p);
+ if (cmp == 0)
+ return ((void *)p);
+ if (cmp > 0) { /* key > p: move right */
+ base = (char *)p + size;
+ lim--;
+ } /* else move left */
+ }
+ return (NULL);
+}
diff --git a/StdLib/LibC/StdLib/Environs.c b/StdLib/LibC/StdLib/Environs.c
new file mode 100644
index 0000000000..5d1584ddea
--- /dev/null
+++ b/StdLib/LibC/StdLib/Environs.c
@@ -0,0 +1,208 @@
+/** @file
+ Implementation of the <stdlib.h> functions responsible for communication with
+ the environment:
+ - abort(void)
+ - atexit(void(*handler)(void))
+ - exit(int status)
+ - _Exit(int status)
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#include <Uefi.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/ShellLib.h>
+
+#include <LibConfig.h>
+
+#include <errno.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <MainData.h>
+
+/* ################# Public Functions ################################### */
+
+/** The abort function causes abnormal program termination to occur, unless
+ the signal SIGABRT is being caught and the signal handler does not return.
+
+ Open streams with unwritten buffered data are not flushed, open
+ streams are not closed, and temporary files are not removed by abort.
+
+**/
+void
+abort(void)
+{
+ if (!gMD->aborting) {
+ gMD->aborting = TRUE;
+
+ if (gMD->cleanup != NULL) {
+ gMD->cleanup();
+ }
+ }
+ raise(SIGABRT);
+ _Exit(EXIT_FAILURE); // In case raise returns.
+}
+
+/** The atexit function registers the function pointed to by func, to be
+ called without arguments at normal program termination.
+
+ The implementation shall support the registration of
+ at least 32 functions.
+
+ @return The atexit function returns zero if the registration succeeds,
+ nonzero if it fails.
+**/
+int
+atexit(void (*handler)(void))
+{
+ int retval = 1;
+
+ if((handler != NULL) && (gMD->num_atexit < ATEXIT_MAX)) {
+ gMD->atexit_handler[gMD->num_atexit++] = handler;
+ retval = 0;
+ }
+ return retval;
+}
+
+/** The exit function causes normal program termination to occur. If more than
+ one call to the exit function is executed by a program,
+ the behavior is undefined.
+
+ First, all functions registered by the atexit function are called, in the
+ reverse order of their registration. If, during the call to any such function, a
+ call to the longjmp function is made that would terminate the call to the
+ registered function, the behavior is undefined.
+
+ Next, all open streams with unwritten buffered data are flushed, all open
+ streams are closed, and all files created by the tmpfile function
+ are removed.
+
+ The status returned to the host environment is determined in the same way
+ as for the _Exit function.
+**/
+void
+exit(int status)
+{
+ int i = gMD->num_atexit;
+
+ // Call all registered atexit functions in reverse order
+ if( i > 0) {
+ do {
+ (gMD->atexit_handler[--i])();
+ } while( i > 0);
+ }
+
+ if (gMD->cleanup != NULL) {
+ gMD->cleanup();
+ }
+ _Exit(status);
+}
+
+typedef
+EFI_STATUS
+(EFIAPI *ExitFuncPtr)(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_STATUS ExitStatus,
+ IN UINTN ExitDataSize,
+ IN CHAR16 *ExitData OPTIONAL
+) __noreturn;
+
+/** The _Exit function causes normal program termination to occur and control
+ to be returned to the host environment.
+
+ No functions registered by the atexit function or signal handlers
+ registered by the signal function are called. Open streams with unwritten
+ buffered data are not flushed, open streams are not closed, and temporary
+ files are not removed by abort.
+
+ Finally, control is returned to the host environment. If the value of
+ status is zero, or EXIT_SUCCESS, status is returned unchanged. If the value
+ of status is EXIT_FAILURE, RETURN_ABORTED is returned.
+ Otherwise, status is returned unchanged.
+**/
+void
+_Exit(int status)
+{
+ RETURN_STATUS ExitVal = (RETURN_STATUS)status;
+ ExitFuncPtr ExitFunc;
+
+ if( ExitVal == EXIT_FAILURE) {
+ ExitVal = RETURN_ABORTED;
+ }
+
+ ExitFunc = (ExitFuncPtr)gBS->Exit;
+
+ //gBS->Exit(gImageHandle, ExitVal, 0, NULL); /* abort() */
+ ExitFunc(gImageHandle, ExitVal, 0, NULL); /* abort() */
+}
+
+/** If string is a null pointer, the system function determines whether the
+ host environment has a command processor. If string is not a null pointer,
+ the system function passes the string pointed to by string to that command
+ processor to be executed in a manner which the implementation shall
+ document; this might then cause the program calling system to behave in a
+ non-conforming manner or to terminate.
+
+ @retval EXIT_FAILURE EFIerrno will contain the EFI status code
+ indicating the cause of failure.
+
+ @retval EXIT_SUCCESS EFIerrno will contain the EFI status returned
+ by the executed command string.
+ @retval 0 If string is NULL, 0 means a command processor
+ is not available.
+ @retval 1 If string is NULL, 1 means a command processor
+ is available.
+**/
+int
+system(const char *string)
+{
+ EFI_STATUS CmdStat;
+ EFI_STATUS OpStat;
+ EFI_HANDLE MyHandle = gImageHandle;
+
+ if( string == NULL) {
+ return 1;
+ }
+ (void)AsciiStrToUnicodeStr( string, gMD->UString);
+ OpStat = ShellExecute( &MyHandle, gMD->UString, FALSE, NULL, &CmdStat);
+ if(OpStat == RETURN_SUCCESS) {
+ EFIerrno = CmdStat;
+ return EXIT_SUCCESS;
+ }
+ EFIerrno = OpStat;
+ return EXIT_FAILURE;
+}
+
+/** The getenv function searches an environment list, provided by the host
+ environment, for a string that matches the string pointed to by name. The
+ set of environment names and the method for altering the environment list
+ are determined by the underlying UEFI Shell implementation.
+
+ @return The getenv function returns a pointer to a string associated with
+ the matched list member. The string pointed to shall not be
+ modified by the program, but may be overwritten by a subsequent
+ call to the getenv function. If the specified name cannot be
+ found, a null pointer is returned.
+**/
+char *getenv(const char *name)
+{
+ const CHAR16 *EfiEnv;
+ char *retval = NULL;
+
+ (void)AsciiStrToUnicodeStr( name, gMD->UString);
+ EfiEnv = ShellGetEnvironmentVariable(gMD->UString);
+ if(EfiEnv != NULL) {
+ retval = UnicodeStrToAsciiStr( EfiEnv, gMD->ASgetenv);
+ }
+
+ return retval;
+}
diff --git a/StdLib/LibC/StdLib/Malloc.c b/StdLib/LibC/StdLib/Malloc.c
new file mode 100644
index 0000000000..51068d3a06
--- /dev/null
+++ b/StdLib/LibC/StdLib/Malloc.c
@@ -0,0 +1,226 @@
+/** @file
+ Definitions for memory allocation routines: calloc, malloc, realloc, free.
+
+ The order and contiguity of storage allocated by successive calls to the
+ calloc, malloc, and realloc functions is unspecified. The pointer returned
+ if the allocation succeeds is suitably aligned so that it may be assigned to
+ a pointer of any type of object and then used to access such an object or an
+ array of such objects in the space allocated (until the space is explicitly
+ freed or reallocated). Each such allocation shall yield a pointer to an
+ object disjoint from any other object. The pointer returned points to the
+ start (lowest byte address) of the allocated space. If the space can not be
+ allocated, a null pointer is returned. If the size of the space requested
+ is zero, the behavior is implementation-defined; the value returned shall be
+ either a null pointer or a unique pointer. The value of a pointer that
+ refers to freed space is indeterminate.
+
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ */
+#include <Base.h>
+#include <Uefi.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <stdlib.h>
+#include <errno.h>
+
+/** The UEFI functions do not provide a way to determine the size of an
+ allocated region of memory given just a pointer to the start of that
+ region. Since this is required for the implementation of realloc,
+ the memory head structure from Core/Dxe/Mem/Pool.c has been reproduced
+ here.
+
+ NOTE: If the UEFI implementation is changed, the realloc function may cease
+ to function properly.
+**/
+#define POOL_HEAD_SIGNATURE SIGNATURE_32('p','h','d','0')
+typedef struct {
+ UINT32 Signature;
+ UINT32 Size;
+ EFI_MEMORY_TYPE Type;
+ UINTN Reserved;
+ CHAR8 Data[1];
+} POOL_HEAD;
+
+/****************************/
+
+/** The malloc function allocates space for an object whose size is specified
+ by size and whose value is indeterminate.
+
+ This implementation uses the UEFI memory allocation boot services to get a
+ region of memory that is 8-byte aligned and of the specified size. The
+ region is allocated with type EfiLoaderData.
+
+ @param size Size, in bytes, of the region to allocate.
+
+ @return NULL is returned if the space could not be allocated and errno
+ contains the cause. Otherwise, a pointer to an 8-byte aligned
+ region of the requested size is returned.<BR>
+ If NULL is returned, errno may contain:
+ - EINVAL: Requested Size is zero.
+ - ENOMEM: Memory could not be allocated.
+**/
+void *
+malloc(size_t Size)
+{
+ void *RetVal;
+ EFI_STATUS Status;
+
+ if( Size == 0) {
+ errno = EINVAL; // Make errno diffenent, just in case of a lingering ENOMEM.
+ return NULL;
+ }
+
+ Status = gBS->AllocatePool( EfiLoaderData, (UINTN)Size, &RetVal);
+ if( Status != EFI_SUCCESS) {
+ RetVal = NULL;
+ errno = ENOMEM;
+ }
+ return RetVal;
+}
+
+/** The calloc function allocates space for an array of Num objects, each of
+ whose size is Size. The space is initialized to all bits zero.
+
+ This implementation uses the UEFI memory allocation boot services to get a
+ region of memory that is 8-byte aligned and of the specified size. The
+ region is allocated with type EfiLoaderData.
+
+ @param Num Number of objects to allocate.
+ @param Size Size, in bytes, of the objects to allocate space for.
+
+ @return NULL is returned if the space could not be allocated and errno
+ contains the cause. Otherwise, a pointer to an 8-byte aligned
+ region of the requested size is returned.
+**/
+void *
+calloc(size_t Num, size_t Size)
+{
+ void *RetVal;
+ size_t NumSize;
+
+ NumSize = Num * Size;
+ if (NumSize == 0) {
+ return NULL;
+ }
+ RetVal = malloc(NumSize);
+ if( RetVal != NULL) {
+ (VOID)ZeroMem( RetVal, NumSize);
+ }
+ return RetVal;
+}
+
+/** The free function causes the space pointed to by Ptr to be deallocated,
+ that is, made available for further allocation.
+
+ If Ptr is a null pointer, no action occurs. Otherwise, if the argument
+ does not match a pointer earlier returned by the calloc, malloc, or realloc
+ function, or if the space has been deallocated by a call to free or
+ realloc, the behavior is undefined.
+
+ @param Ptr Pointer to a previously allocated region of memory to be freed.
+
+**/
+void
+free(void *Ptr)
+{
+ (void) gBS->FreePool (Ptr);
+}
+
+/** The realloc function changes the size of the object pointed to by Ptr to
+ the size specified by NewSize.
+
+ The contents of the object are unchanged up to the lesser of the new and
+ old sizes. If the new size is larger, the value of the newly allocated
+ portion of the object is indeterminate.
+
+ If Ptr is a null pointer, the realloc function behaves like the malloc
+ function for the specified size.
+
+ If Ptr does not match a pointer earlier returned by the calloc, malloc, or
+ realloc function, or if the space has been deallocated by a call to the free
+ or realloc function, the behavior is undefined.
+
+ If the space cannot be allocated, the object pointed to by Ptr is unchanged.
+
+ If NewSize is zero and Ptr is not a null pointer, the object it points to
+ is freed.
+
+ This implementation uses the UEFI memory allocation boot services to get a
+ region of memory that is 8-byte aligned and of the specified size. The
+ region is allocated with type EfiLoaderData.
+
+ The following combinations of Ptr and NewSize can occur:<BR>
+ Ptr NewSize<BR>
+ -------- -------------------<BR>
+ - NULL 0 Returns NULL;
+ - NULL > 0 Same as malloc(NewSize)
+ - invalid X Returns NULL;
+ - valid NewSize >= OldSize Returns malloc(NewSize) with Oldsize bytes copied from Ptr
+ - valid NewSize < OldSize Returns new buffer with Oldsize bytes copied from Ptr
+ - valid 0 Return NULL. Frees Ptr.
+
+
+ @param Ptr Pointer to a previously allocated region of memory to be resized.
+ @param NewSize Size, in bytes, of the new object to allocate space for.
+
+ @return NULL is returned if the space could not be allocated and errno
+ contains the cause. Otherwise, a pointer to an 8-byte aligned
+ region of the requested size is returned. If NewSize is zero,
+ NULL is returned and errno will be unchanged.
+**/
+void *
+realloc(void *Ptr, size_t NewSize)
+{
+ void *RetVal = NULL;
+ POOL_HEAD *Head;
+ UINTN OldSize = 0;
+ UINTN NumCpy;
+
+ // Find out the size of the OLD memory region
+ if( Ptr != NULL) {
+ Head = BASE_CR (Ptr, POOL_HEAD, Data);
+ assert(Head != NULL);
+ if (Head->Signature != POOL_HEAD_SIGNATURE) {
+ errno = EFAULT;
+ return NULL;
+ }
+ OldSize = Head->Size;
+ }
+
+ // At this point, Ptr is either NULL or a valid pointer to an allocated space
+
+ if( NewSize > 0) {
+ RetVal = malloc(NewSize); // Get the NEW memory region
+ if( Ptr != NULL) { // If there is an OLD region...
+ if( RetVal != NULL) { // and the NEW region was successfully allocated
+ NumCpy = OldSize;
+ if( OldSize > NewSize) {
+ NumCpy = NewSize;
+ }
+ (VOID)CopyMem( RetVal, Ptr, NumCpy); // Copy old data to the new region.
+ free( Ptr); // and reclaim the old region.
+ }
+ }
+ }
+ else {
+ if( Ptr != NULL) {
+ free( Ptr); // Reclaim the old region.
+ }
+ }
+
+ return RetVal;
+}
diff --git a/StdLib/LibC/StdLib/NumericInt.c b/StdLib/LibC/StdLib/NumericInt.c
new file mode 100644
index 0000000000..058ad04959
--- /dev/null
+++ b/StdLib/LibC/StdLib/NumericInt.c
@@ -0,0 +1,398 @@
+/** @file
+ Integer Numeric Conversion Functions.
+
+ The atoi, atol, and atoll functions convert the initial portion of the string
+ pointed to by nptr to int, long int, and long long int representation,
+ respectively. They are equivalent to:
+ - atoi: (int)strtol(nptr, (char **)NULL, 10)
+ - atol: strtol(nptr, (char **)NULL, 10)
+ - atoll: strtoll(nptr, (char **)NULL, 10)
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+
+#include <LibConfig.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+
+/** The atoi function converts the initial portion of the string pointed to by
+ nptr to int representation. Except for the behavior on error, it is
+ equivalent to:
+ - (int)strtol(nptr, (char **)NULL, 10)
+
+ @return The atoi function returns the converted value.
+**/
+int
+atoi(const char *nptr)
+{
+ int Retval;
+ BOOLEAN Negative = FALSE;
+
+ while(isspace((const unsigned char)*nptr)) ++nptr; // Skip leading spaces
+
+ if(*nptr == '+') {
+ Negative = FALSE;
+ ++nptr;
+ }
+ else if(*nptr == '-') {
+ Negative = TRUE;
+ ++nptr;
+ }
+ Retval = (int)AsciiStrDecimalToUintn(nptr);
+ if(Negative) {
+ Retval = -Retval;
+ }
+ return Retval;
+}
+
+/** The atol function converts the initial portion of the string pointed to by
+ nptr to long int representation. Except for the behavior on error, it is
+ equivalent to:
+ - strtol(nptr, (char **)NULL, 10)
+
+ @return The atol function returns the converted value.
+**/
+long int
+atol(const char *nptr)
+{
+ long int Retval;
+ BOOLEAN Negative = FALSE;
+
+ while(isspace(*nptr)) ++nptr; // Skip leading spaces
+
+ if(*nptr == '+') {
+ Negative = FALSE;
+ ++nptr;
+ }
+ else if(*nptr == '-') {
+ Negative = TRUE;
+ ++nptr;
+ }
+ Retval = (long int)AsciiStrDecimalToUint64(nptr);
+ if(Negative) {
+ Retval = -Retval;
+ }
+ return Retval;
+}
+
+/** The atoll function converts the initial portion of the string pointed to by
+ nptr to long long int representation. Except for the behavior on error, it
+ is equivalent to:
+ - strtoll(nptr, (char **)NULL, 10)
+
+ @return The atoll function returns the converted value.
+**/
+long long int
+atoll(const char *nptr)
+{
+ long long int Retval;
+ BOOLEAN Negative = FALSE;
+
+ while(isspace(*nptr)) ++nptr; // Skip leading spaces
+
+ if(*nptr == '+') {
+ Negative = FALSE;
+ ++nptr;
+ }
+ else if(*nptr == '-') {
+ Negative = TRUE;
+ ++nptr;
+ }
+ Retval = (long long int)AsciiStrDecimalToUint64(nptr);
+ if(Negative) {
+ Retval = -Retval;
+ }
+ return Retval;
+}
+
+static int
+Digit2Val( int c)
+{
+ if(__isHexLetter(c)) { /* If c is one of [A-Fa-f]... */
+ c = toupper(c) - 7; // Adjust so 'A' is ('9' + 1)
+ }
+ return c - '0'; // Value returned is between 0 and 35, inclusive.
+}
+
+/** The strtol, strtoll, strtoul, and strtoull functions convert the initial
+ portion of the string pointed to by nptr to long int, long long int,
+ unsigned long int, and unsigned long long int representation, respectively.
+ First, they decompose the input string into three parts: an initial,
+ possibly empty, sequence of white-space characters (as specified by the
+ isspace function), a subject sequence resembling an integer represented in
+ some radix determined by the value of base, and a final string of one or
+ more unrecognized characters, including the terminating null character of
+ the input string. Then, they attempt to convert the subject sequence to an
+ integer, and return the result.
+
+ If the value of base is zero, the expected form of the subject sequence is
+ that of an integer constant, optionally preceded
+ by a plus or minus sign, but not including an integer suffix. If the value
+ of base is between 2 and 36 (inclusive), the expected form of the subject
+ sequence is a sequence of letters and digits representing an integer with
+ the radix specified by base, optionally preceded by a plus or minus sign,
+ but not including an integer suffix. The letters from a (or A) through z
+ (or Z) are ascribed the values 10 through 35; only letters and digits whose
+ ascribed values are less than that of base are permitted. If the value of
+ base is 16, the characters 0x or 0X may optionally precede the sequence of
+ letters and digits, following the sign if present.
+
+ The subject sequence is defined as the longest initial subsequence of the
+ input string, starting with the first non-white-space character, that is of
+ the expected form. The subject sequence contains no characters if the input
+ string is empty or consists entirely of white space, or if the first
+ non-white-space character is other than a sign or a permissible letter or digit.
+
+ If the subject sequence has the expected form and the value of base is
+ zero, the sequence of characters starting with the first digit is
+ interpreted as an integer constant. If the subject sequence has the
+ expected form and the value of base is between 2 and 36, it is used as the
+ base for conversion, ascribing to each letter its value as given above. If
+ the subject sequence begins with a minus sign, the value resulting from the
+ conversion is negated (in the return type). A pointer to the final string
+ is stored in the object pointed to by endptr, provided that endptr is
+ not a null pointer.
+
+ In other than the "C" locale, additional locale-specific subject sequence
+ forms may be accepted.
+
+ If the subject sequence is empty or does not have the expected form, no
+ conversion is performed; the value of nptr is stored in the object pointed
+ to by endptr, provided that endptr is not a null pointer.
+
+ @return The strtol, strtoll, strtoul, and strtoull functions return the
+ converted value, if any. If no conversion could be performed, zero
+ is returned. If the correct value is outside the range of
+ representable values, LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX,
+ ULONG_MAX, or ULLONG_MAX is returned (according to the return type
+ and sign of the value, if any), and the value of the macro ERANGE
+ is stored in errno.
+**/
+long
+strtol(const char * __restrict nptr, char ** __restrict endptr, int base)
+{
+ long Result = 0;
+ long Previous;
+ int temp;
+ BOOLEAN Negative = FALSE;
+
+ if((base < 0) || (base == 1) || (base > 36)) {
+ *endptr = NULL;
+ return 0;
+ }
+ // Skip leading spaces.
+ while(isspace(*nptr)) ++nptr;
+
+ // Process Subject sequence: optional sign followed by digits.
+ if(*nptr == '+') {
+ Negative = FALSE;
+ ++nptr;
+ }
+ else if(*nptr == '-') {
+ Negative = TRUE;
+ ++nptr;
+ }
+ if( (base == 16) && (*nptr == '0') && (toupper(nptr[1]) == 'X')) {
+ nptr += 2;
+ }
+ while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
+ Previous = Result;
+ Result = (Result * base) + (long int)temp;
+ if( Result <= Previous) { // Detect Overflow
+ if(Negative) {
+ Result = LONG_MIN;
+ }
+ else {
+ Result = LONG_MAX;
+ }
+ Negative = FALSE;
+ errno = ERANGE;
+ break;
+ }
+ ++nptr;
+ }
+ if(Negative) {
+ Result = -Result;
+ }
+
+ // Save pointer to final sequence
+ if( endptr != NULL) {
+ *endptr = (char *)nptr;
+ }
+ return Result;
+}
+
+/** The strtoul function converts the initial portion of the string pointed to
+ by nptr to unsigned long int representation.
+
+ See the description for strtol for more information.
+
+ @return The strtoul function returns the converted value, if any. If no
+ conversion could be performed, zero is returned. If the correct
+ value is outside the range of representable values, ULONG_MAX is
+ returned and the value of the macro ERANGE is stored in errno.
+**/
+unsigned long
+strtoul(const char * __restrict nptr, char ** __restrict endptr, int base)
+{
+ unsigned long Result = 0;
+ unsigned long Previous;
+ int temp;
+
+ if((base < 0) || (base == 1) || (base > 36)) {
+ *endptr = NULL;
+ return 0;
+ }
+ // Skip leading spaces.
+ while(isspace(*nptr)) ++nptr;
+
+ // Process Subject sequence: optional + sign followed by digits.
+ if(*nptr == '+') {
+ ++nptr;
+ }
+ if( (base == 16) && (*nptr == '0') && (toupper(nptr[1]) == 'X')) {
+ nptr += 2;
+ }
+ while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
+ Previous = Result;
+ Result = (Result * base) + (unsigned long)temp;
+ if( Result < Previous) { // If we overflowed
+ Result = ULONG_MAX;
+ errno = ERANGE;
+ break;
+ }
+ ++nptr;
+ }
+
+ // Save pointer to final sequence
+ if( endptr != NULL) {
+ *endptr = (char *)nptr;
+ }
+ return Result;
+}
+
+/** The strtoll function converts the initial portion of the string pointed to
+ by nptr to long long int representation.
+
+ See the description for strtol for more information.
+
+ @return The strtoll function returns the converted value, if any. If no
+ conversion could be performed, zero is returned. If the correct
+ value is outside the range of representable values, LLONG_MIN or
+ LLONG_MAX is returned (according to the sign of the value, if any),
+ and the value of the macro ERANGE is stored in errno.
+**/
+long long
+strtoll(const char * __restrict nptr, char ** __restrict endptr, int base)
+{
+ long long Result = 0;
+ long long Previous;
+ int temp;
+ BOOLEAN Negative = FALSE;
+
+ if((base < 0) || (base == 1) || (base > 36)) {
+ *endptr = NULL;
+ return 0;
+ }
+ // Skip leading spaces.
+ while(isspace(*nptr)) ++nptr;
+
+ // Process Subject sequence: optional sign followed by digits.
+ if(*nptr == '+') {
+ Negative = FALSE;
+ ++nptr;
+ }
+ else if(*nptr == '-') {
+ Negative = TRUE;
+ ++nptr;
+ }
+ if( (base == 16) && (*nptr == '0') && (toupper(nptr[1]) == 'X')) {
+ nptr += 2;
+ }
+ while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
+ Previous = Result;
+ Result = (Result * base) + (long long int)temp;
+ if( Result <= Previous) { // Detect Overflow
+ if(Negative) {
+ Result = LLONG_MIN;
+ }
+ else {
+ Result = LLONG_MAX;
+ }
+ Negative = FALSE;
+ errno = ERANGE;
+ break;
+ }
+ ++nptr;
+ }
+ if(Negative) {
+ Result = -Result;
+ }
+
+ // Save pointer to final sequence
+ if( endptr != NULL) {
+ *endptr = (char *)nptr;
+ }
+ return Result;
+}
+
+/** The strtoull function converts the initial portion of the string pointed to
+ by nptr to unsigned long long int representation.
+
+ See the description for strtol for more information.
+
+ @return The strtoull function returns the converted value, if any. If no
+ conversion could be performed, zero is returned. If the correct
+ value is outside the range of representable values, ULLONG_MAX is
+ returned and the value of the macro ERANGE is stored in errno.
+**/
+unsigned long long
+strtoull(const char * __restrict nptr, char ** __restrict endptr, int base)
+{
+ unsigned long long Result = 0;
+ unsigned long long Previous;
+ int temp;
+
+ if((base < 0) || (base == 1) || (base > 36)) {
+ *endptr = NULL;
+ return 0;
+ }
+ // Skip leading spaces.
+ while(isspace(*nptr)) ++nptr;
+
+ // Process Subject sequence: optional + sign followed by digits.
+ if(*nptr == '+') {
+ ++nptr;
+ }
+ if( (base == 16) && (*nptr == '0') && (toupper(nptr[1]) == 'X')) {
+ nptr += 2;
+ }
+ while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
+ Previous = Result;
+ Result = (Result * base) + (unsigned long long)temp;
+ if( Result < Previous) { // If we overflowed
+ Result = ULLONG_MAX;
+ errno = ERANGE;
+ break;
+ }
+ ++nptr;
+ }
+
+ // Save pointer to final sequence
+ if( endptr != NULL) {
+ *endptr = (char *)nptr;
+ }
+ return Result;
+}
diff --git a/StdLib/LibC/StdLib/Qsort.c b/StdLib/LibC/StdLib/Qsort.c
new file mode 100644
index 0000000000..3c98c6aa9e
--- /dev/null
+++ b/StdLib/LibC/StdLib/Qsort.c
@@ -0,0 +1,205 @@
+/** @file
+ Quick Sort utility function.
+
+ This utility makes use of a comparison function to search arrays of
+ unspecified type. Where an argument declared as size_t nmemb specifies the
+ length of the array for a function, nmemb can have the value zero on a call
+ to that function; the comparison function is not called, a search finds no
+ matching element. Pointer arguments on such a call shall still have valid
+ values.
+
+ The implementation shall ensure that both arguments of the comparison
+ function are pointers to elements of the array.
+
+ The comparison function shall not alter the contents of the array. The
+ implementation may reorder elements of the array between calls to the
+ comparison function, but shall not alter the contents of any individual
+ element.
+
+ When the same objects (consisting of size bytes, irrespective of their
+ current positions in the array) are passed more than once to the comparison
+ function, the results shall be consistent with one another. That is, they
+ define a total ordering on the array.
+
+ A sequence point occurs immediately before and immediately after each call to
+ the comparison function, and also between any call to the comparison function
+ and any movement of the objects passed as arguments to that call.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+
+ ("$FreeBSD: src/lib/libc/stdlib/qsort.c,v 1.15.2.1.2.1 2009/10/25 01:10:29 kensmith Exp $");
+ */
+#include <LibConfig.h>
+
+#include <stdlib.h>
+
+typedef int cmp_t(const void *, const void *);
+
+static __inline char *med3(char *, char *, char *, cmp_t *);
+static __inline void swapfunc(char *, char *, size_t, int);
+
+/*
+ * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
+ */
+#define swapcode(TYPE, parmi, parmj, n) { \
+ size_t i = (n) / sizeof (TYPE); \
+ TYPE *pi = (TYPE *) (parmi); \
+ TYPE *pj = (TYPE *) (parmj); \
+ do { \
+ TYPE t = *pi; \
+ *pi++ = *pj; \
+ *pj++ = t; \
+ } while (--i > 0); \
+}
+
+#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
+ es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
+
+static __inline void
+swapfunc(char *a, char *b, size_t n, int swaptype)
+{
+ if(swaptype <= 1)
+ swapcode(long, a, b, n)
+ else
+ swapcode(char, a, b, n)
+}
+
+#define swap(a, b) \
+ if (swaptype == 0) { \
+ long t = *(long *)(a); \
+ *(long *)(a) = *(long *)(b); \
+ *(long *)(b) = t; \
+ } else \
+ swapfunc(a, b, es, swaptype)
+
+#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
+
+static __inline char *
+med3(char *a, char *b, char *c, cmp_t *cmp )
+{
+ return cmp(a, b) < 0 ?
+ (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))
+ :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));
+}
+
+/* The qsort function sorts an array of nmemb objects, the initial element of
+ which is pointed to by base. The size of each object is specified by size.
+
+ The contents of the array are sorted into ascending order according to a
+ comparison function pointed to by compar, which is called with two
+ arguments that point to the objects being compared. The function shall
+ return an integer less than, equal to, or greater than zero if the first
+ argument is considered to be respectively less than, equal to, or greater
+ than the second.
+
+ If two elements compare as equal, their order in the resulting sorted array
+ is unspecified.
+*/
+void
+qsort(void *a, size_t n, size_t es, cmp_t *cmp)
+{
+ char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
+ size_t d, r;
+ int cmp_result;
+ int swaptype, swap_cnt;
+
+loop: SWAPINIT(a, es);
+ swap_cnt = 0;
+ if (n < 7) {
+ for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
+ for (pl = pm;
+ pl > (char *)a && cmp(pl - es, pl) > 0;
+ pl -= es)
+ swap(pl, pl - es);
+ return;
+ }
+ pm = (char *)a + (n / 2) * es;
+ if (n > 7) {
+ pl = a;
+ pn = (char *)a + (n - 1) * es;
+ if (n > 40) {
+ d = (n / 8) * es;
+ pl = med3(pl, pl + d, pl + 2 * d, cmp);
+ pm = med3(pm - d, pm, pm + d, cmp);
+ pn = med3(pn - 2 * d, pn - d, pn, cmp);
+ }
+ pm = med3(pl, pm, pn, cmp);
+ }
+ swap(a, pm);
+ pa = pb = (char *)a + es;
+
+ pc = pd = (char *)a + (n - 1) * es;
+ for (;;) {
+ while (pb <= pc && (cmp_result = cmp(pb, a)) <= 0) {
+ if (cmp_result == 0) {
+ swap_cnt = 1;
+ swap(pa, pb);
+ pa += es;
+ }
+ pb += es;
+ }
+ while (pb <= pc && (cmp_result = cmp(pc, a)) >= 0) {
+ if (cmp_result == 0) {
+ swap_cnt = 1;
+ swap(pc, pd);
+ pd -= es;
+ }
+ pc -= es;
+ }
+ if (pb > pc)
+ break;
+ swap(pb, pc);
+ swap_cnt = 1;
+ pb += es;
+ pc -= es;
+ }
+ if (swap_cnt == 0) { /* Switch to insertion sort */
+ for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
+ for (pl = pm;
+ pl > (char *)a && cmp(pl - es, pl) > 0;
+ pl -= es)
+ swap(pl, pl - es);
+ return;
+ }
+
+ pn = (char *)a + n * es;
+ r = MIN(pa - (char *)a, pb - pa);
+ vecswap(a, pb - r, r);
+ r = MIN((size_t)(pd - pc), ((size_t)(pn - pd)) - es);
+ vecswap(pb, pn - r, r);
+ if ((size_t)(r = pb - pa) > es)
+ qsort(a, r / es, es, cmp);
+ if ((size_t)(r = pd - pc) > es) {
+ /* Iterate rather than recurse to save stack space */
+ a = pn - r;
+ n = r / es;
+ goto loop;
+ }
+/* qsort(pn - r, r / es, es, cmp);*/
+}
diff --git a/StdLib/LibC/StdLib/Rand.c b/StdLib/LibC/StdLib/Rand.c
new file mode 100644
index 0000000000..4e17ff1313
--- /dev/null
+++ b/StdLib/LibC/StdLib/Rand.c
@@ -0,0 +1,67 @@
+/*-
+ * Portions Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+//__FBSDID("$FreeBSD: src/lib/libc/stdlib/rand.c,v 1.17.2.1.2.1 2009/10/25 01:10:29 kensmith Exp $");
+#include <LibConfig.h>
+
+#include <stdlib.h>
+
+static UINT32 next = 1;
+
+/** Compute a pseudo-random number.
+ *
+ * Compute x = (7^5 * x) mod (2^31 - 1)
+ * without overflowing 31 bits:
+ * (2^31 - 1) = 127773 * (7^5) + 2836
+ * From "Random number generators: good ones are hard to find",
+ * Park and Miller, Communications of the ACM, vol. 31, no. 10,
+ * October 1988, p. 1195.
+**/
+int
+rand()
+{
+ INT32 hi, lo, x;
+
+ /* Can't be initialized with 0, so use another value. */
+ if (next == 0)
+ next = 123459876;
+ hi = next / 127773;
+ lo = next % 127773;
+ x = 16807 * lo - 2836 * hi;
+ if (x < 0)
+ x += 0x7fffffff;
+ return ((next = x) % ((UINT32)RAND_MAX + 1));
+}
+
+void
+srand(unsigned int seed)
+{
+ next = (UINT32)seed;
+}
diff --git a/StdLib/LibC/StdLib/StdLib.inf b/StdLib/LibC/StdLib/StdLib.inf
new file mode 100644
index 0000000000..21d1c1f4aa
--- /dev/null
+++ b/StdLib/LibC/StdLib/StdLib.inf
@@ -0,0 +1,67 @@
+## @file
+# Standard C library: StdLib implementations.
+#
+# Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = LibStdLib
+ FILE_GUID = f8a312f8-bccc-479f-b49b-ce129568b06a
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = LibStdLib
+
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[Sources]
+ Bsearch.c
+ Environs.c
+ Malloc.c
+ NumericInt.c
+ Qsort.c
+ Rand.c
+ strtoimax.c
+ strtoumax.c
+ Xabs.c
+ Xdiv.c
+
+[Packages]
+ StdLib/StdLib.dec
+ StdLibPrivateInternalFiles/DoNotUse.dec
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ DebugLib
+ BaseLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ ShellLib
+ LibC
+ LibCType
+ LibSignal
+
+################################################################
+#
+# The Build Options, below, are only used when building the C library.
+# DO NOT use them when building your application!
+# Nasty things could happen if you do.
+#
+# /Oi- is required for Microsoft VC++ to allow "intrinsic" functions to be
+# defined in this library.
+#
+[BuildOptions]
+ MSFT:*_*_*_CC_FLAGS = /Oi-
diff --git a/StdLib/LibC/StdLib/Xabs.c b/StdLib/LibC/StdLib/Xabs.c
new file mode 100644
index 0000000000..1b289857ab
--- /dev/null
+++ b/StdLib/LibC/StdLib/Xabs.c
@@ -0,0 +1,36 @@
+/** @file
+ The abs, labs, and llabs functions compute the absolute value of an integer j.
+ If the result cannot be represented, the behavior is undefined.
+
+ The abs, labs, and llabs, functions return the absolute value of their
+ parameter.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+int
+abs(int j)
+{
+ return(j < 0 ? -j : j);
+}
+
+long
+labs(long j)
+{
+ return(j < 0 ? -j : j);
+}
+
+long long
+llabs(long long j)
+{
+ return (j < 0 ? -j : j);
+}
diff --git a/StdLib/LibC/StdLib/Xdiv.c b/StdLib/LibC/StdLib/Xdiv.c
new file mode 100644
index 0000000000..111a0be1a2
--- /dev/null
+++ b/StdLib/LibC/StdLib/Xdiv.c
@@ -0,0 +1,76 @@
+/** @file
+ The div, ldiv, and lldiv, functions compute numer / denom and
+ numer % denom in a single operation.
+
+ The div, ldiv, and lldiv functions return a structure of type div_t, ldiv_t,
+ and lldiv_t, respectively, comprising both the quotient and the remainder.
+ The structures shall contain (in either order) the members quot
+ (the quotient) and rem (the remainder), each of which has the same type as
+ the arguments numer and denom. If either part of the result cannot be
+ represented, the behavior is undefined.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#include <Library/BaseLib.h>
+#include <stdlib.h> /* div_t, ldiv_t, lldiv_t */
+
+/* DivS64x64Remainder will write the remainder as a 64-bit value, so we store
+ it first into bigrem and then into r.rem. This avoids writing the remainder
+ beyond the end of the div_t structure.
+*/
+div_t
+div(int num, int denom)
+{
+ div_t r;
+ INT64 bigrem;
+
+ r.quot = (int)DivS64x64Remainder( (INT64)num, (INT64)denom, &bigrem);
+ r.rem = (int)bigrem;
+
+ return (r);
+}
+
+/* DivS64x64Remainder will write the remainder as a 64-bit value, so we store
+ it first into bigrem and then into r.rem. This avoids writing the remainder
+ beyond the end of the div_t structure.
+*/
+ldiv_t
+ldiv(long num, long denom)
+{
+ ldiv_t r;
+ INT64 bigrem;
+
+ r.quot = (long)DivS64x64Remainder( (INT64)num, (INT64)denom, &bigrem);
+ r.rem = (long)bigrem;
+
+ return (r);
+}
+
+/* DivS64x64Remainder will write the remainder as a 64-bit value, so we store
+ it first into bigrem and then into r.rem. This avoids writing the remainder
+ beyond the end of the div_t structure if r.rem is narrower than 64-bits.
+
+ Even though most implementations make long long 64 bits wide, we still go
+ through bigrem, just-in-case.
+*/
+lldiv_t
+lldiv(long long num, long long denom)
+{
+ lldiv_t r;
+ INT64 bigrem;
+
+ r.quot = (long long)DivS64x64Remainder( (INT64)num, (INT64)denom, &bigrem);
+ r.rem = (long long)bigrem;
+
+ return (r);
+}
diff --git a/StdLib/LibC/StdLib/strtoimax.c b/StdLib/LibC/StdLib/strtoimax.c
new file mode 100644
index 0000000000..c5c40abcb2
--- /dev/null
+++ b/StdLib/LibC/StdLib/strtoimax.c
@@ -0,0 +1,166 @@
+/* $NetBSD: strtoimax.c,v 1.4 2005/11/29 03:12:00 christos Exp $ */
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "from: @(#)strtoq.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: strtoimax.c,v 1.4 2005/11/29 03:12:00 christos Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <stddef.h>
+
+#ifdef __weak_alias
+__weak_alias(strtoimax, _strtoimax)
+#endif
+
+/*
+ * Convert a string to an intmax_t.
+ *
+ * Ignores `locale' stuff. Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+intmax_t
+_strtoimax(const char *nptr, char **endptr, int base)
+{
+ const char *s;
+ intmax_t acc, cutoff;
+ int c;
+ int neg, any, cutlim;
+
+ _DIAGASSERT(nptr != NULL);
+ /* endptr may be NULL */
+
+#ifdef __GNUC__
+ /* This outrageous construct just to shut up a GCC warning. */
+ (void) &acc; (void) &cutoff;
+#endif
+
+ /*
+ * Skip white space and pick up leading +/- sign if any.
+ * If base is 0, allow 0x for hex and 0 for octal, else
+ * assume decimal; if base is already 16, allow 0x.
+ */
+ s = nptr;
+ do {
+ c = (unsigned char) *s++;
+ } while (isspace(c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else {
+ neg = 0;
+ if (c == '+')
+ c = *s++;
+ }
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X')) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+
+ /*
+ * Compute the cutoff value between legal numbers and illegal
+ * numbers. That is the largest legal value, divided by the
+ * base. An input number that is greater than this value, if
+ * followed by a legal input character, is too big. One that
+ * is equal to this value may be valid or not; the limit
+ * between valid and invalid numbers is then based on the last
+ * digit. For instance, if the range for intmax_t is
+ * [-9223372036854775808..9223372036854775807] and the input base
+ * is 10, cutoff will be set to 922337203685477580 and cutlim to
+ * either 7 (neg==0) or 8 (neg==1), meaning that if we have
+ * accumulated a value > 922337203685477580, or equal but the
+ * next digit is > 7 (or 8), the number is too big, and we will
+ * return a range error.
+ *
+ * Set any if any `digits' consumed; make it negative to indicate
+ * overflow.
+ */
+ cutoff = neg ? INTMAX_MIN : INTMAX_MAX;
+ cutlim = (int)(cutoff % base);
+ cutoff /= base;
+ if (neg) {
+ if (cutlim > 0) {
+ cutlim -= base;
+ cutoff += 1;
+ }
+ cutlim = -cutlim;
+ }
+ for (acc = 0, any = 0;; c = (unsigned char) *s++) {
+ if (isdigit(c))
+ c -= '0';
+ else if (isalpha(c))
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0)
+ continue;
+ if (neg) {
+ if (acc < cutoff || (acc == cutoff && c > cutlim)) {
+ any = -1;
+ acc = INTMAX_MIN;
+ errno = ERANGE;
+ } else {
+ any = 1;
+ acc *= base;
+ acc -= c;
+ }
+ } else {
+ if (acc > cutoff || (acc == cutoff && c > cutlim)) {
+ any = -1;
+ acc = INTMAX_MAX;
+ errno = ERANGE;
+ } else {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
+ }
+ }
+ if (endptr != 0)
+ *endptr = (char *)(any ? s - 1 : nptr);
+ //*endptr = __UNCONST(any ? s - 1 : nptr);
+ return (acc);
+}
diff --git a/StdLib/LibC/StdLib/strtoumax.c b/StdLib/LibC/StdLib/strtoumax.c
new file mode 100644
index 0000000000..5bf64383d4
--- /dev/null
+++ b/StdLib/LibC/StdLib/strtoumax.c
@@ -0,0 +1,139 @@
+/* $NetBSD: strtoumax.c,v 1.1 2006/04/22 15:33:33 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#if !defined(_KERNEL) && !defined(_STANDALONE)
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "from: @(#)strtoul.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: strtoumax.c,v 1.1 2006/04/22 15:33:33 thorpej Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <stddef.h>
+
+#ifdef __weak_alias
+__weak_alias(strtoumax, _strtoumax)
+#endif
+
+#else /* !_KERNEL && !_STANDALONE */
+#include <sys/param.h>
+#include <lib/libkern/libkern.h>
+#endif /* !_KERNEL && !_STANDALONE */
+
+/*
+ * Convert a string to an uintmax_t.
+ *
+ * Ignores `locale' stuff. Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+uintmax_t
+strtoumax(const char *nptr, char **endptr, int base)
+{
+ const char *s;
+ uintmax_t acc, cutoff;
+ int c;
+ int neg, any, cutlim;
+
+ _DIAGASSERT(nptr != NULL);
+ /* endptr may be NULL */
+
+ /*
+ * See strtol for comments as to the logic used.
+ */
+ s = nptr;
+ do {
+ c = (unsigned char) *s++;
+ } while (isspace(c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else {
+ neg = 0;
+ if (c == '+')
+ c = *s++;
+ }
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X')) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+
+ cutoff = UINTMAX_MAX / (uintmax_t)base;
+ cutlim = (int)(UINTMAX_MAX % (uintmax_t)base);
+ for (acc = 0, any = 0;; c = (unsigned char) *s++) {
+ if (isdigit(c))
+ c -= '0';
+ else if (isalpha(c)) {
+#if defined(_KERNEL) || defined(_STANDALONE)
+ c = toupper(c) - 'A' + 10;
+#else
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+#endif
+ } else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0)
+ continue;
+ if (acc > cutoff || (acc == cutoff && c > cutlim)) {
+#if defined(_KERNEL) || defined(_STANDALONE)
+ if (endptr)
+ *endptr = __UNCONST(nptr);
+ return UINTMAX_MAX;
+#else
+ any = -1;
+ acc = UINTMAX_MAX;
+ errno = ERANGE;
+#endif
+ } else {
+ any = 1;
+ acc *= (uintmax_t)base;
+ acc += c;
+ }
+ }
+ if (neg && any > 0)
+ acc = (uintmax_t)(-((intmax_t)acc));
+ if (endptr != 0)
+ *endptr = __UNCONST(any ? s - 1 : nptr);
+ return (acc);
+}
diff --git a/StdLib/LibC/Stdio/Stdio.inf b/StdLib/LibC/Stdio/Stdio.inf
new file mode 100644
index 0000000000..56eaae3291
--- /dev/null
+++ b/StdLib/LibC/Stdio/Stdio.inf
@@ -0,0 +1,142 @@
+## @file
+# Standard C library: Implementation for <stdio.h>.
+#
+# Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = LibStdio
+ FILE_GUID = 7d2bd134-500d-4f42-aee2-26accfb6cb1d
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = LibStdio
+
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[Sources]
+ clrerr.c #
+ fclose.c #
+ fdopen.c #
+ feof.c #
+ ferror.c #
+ fflush.c #
+ fgetc.c #
+ fgetln.c #
+ fgetpos.c #
+ fgets.c #
+ fopen.c #
+ fprintf.c #
+ fputc.c #
+ fputs.c #
+ fread.c #
+ freopen.c #
+ fscanf.c #
+ fseek.c #
+ fsetpos.c #
+ ftell.c #
+ fwrite.c #
+ getc.c #
+ getchar.c #
+ gets.c #
+ perror.c #
+ printf.c #
+ putc.c #
+ putchar.c #
+ puts.c #
+ remove.c #
+ rewind.c #
+ scanf.c #
+ setbuf.c #
+ setvbuf.c #
+ sprintf.c #
+ sscanf.c #
+ tmpfile.c #
+ tmpnam.c #
+ ungetc.c #
+ vfprintf.c #
+ vfwprintf.c #
+ vprintf.c #
+ vsprintf.c #
+
+ # Wide character functions
+ fgetwc.c #
+ fgetws.c #
+ fputwc.c #
+ fputws.c #
+ fwide.c #
+ fwprintf.c #
+ fwscanf.c #
+ getwc.c #
+ getwchar.c #
+ putwc.c #
+ putwchar.c #
+ swprintf.c #
+ swscanf.c #
+ ungetwc.c #
+ vfwscanf.c #
+ vswprintf.c #
+ vswscanf.c #
+ vwprintf.c #
+ vwscanf.c #
+ wprintf.c #
+ wscanf.c #
+
+
+ # Files internal to the implementation
+ fgetstr.c #
+ findfp.c #
+ flags.c #
+ fseeko.c #
+ ftello.c #
+ fvwrite.c #
+ fwalk.c #
+ gettemp.c #
+ makebuf.c #
+ mkstemp.c #
+ mktemp.c #
+ refill.c #
+ rget.c #
+ snprintf.c #
+ stdio.c #
+ vfscanf.c #
+ wbuf.c #
+ wsetup.c #
+
+
+[Packages]
+ StdLib/StdLib.dec
+ StdLibPrivateInternalFiles/DoNotUse.dec
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+
+[LibraryClasses]
+ LibC
+ LibCType
+ LibGdtoa
+ LibLocale
+ LibStdLib
+ LibString
+ LibTime
+ LibUefi
+ LibWchar
+
+################################################################
+#
+# The Build Options, below, are only used when building the C library.
+# DO NOT use them when building your application!
+# Nasty things could happen if you do.
+#
+[BuildOptions]
+ GCC:*_*_*_CC_FLAGS = -fno-builtin -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast
diff --git a/StdLib/LibC/Stdio/clrerr.c b/StdLib/LibC/Stdio/clrerr.c
new file mode 100644
index 0000000000..bda0d04ce8
--- /dev/null
+++ b/StdLib/LibC/Stdio/clrerr.c
@@ -0,0 +1,63 @@
+/** @file
+ Implementation of clearerr as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: clrerr.c,v 1.10 2003/08/07 16:43:21 agc Exp
+ clrerr.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <stdio.h>
+#include "reentrant.h"
+#include "local.h"
+
+#undef clearerr
+
+void
+clearerr(FILE *fp)
+{
+ //_DIAGASSERT(fp != NULL);
+
+ FLOCKFILE(fp);
+ __sclearerr(fp);
+ FUNLOCKFILE(fp);
+}
diff --git a/StdLib/LibC/Stdio/fclose.c b/StdLib/LibC/Stdio/fclose.c
new file mode 100644
index 0000000000..3745e20f94
--- /dev/null
+++ b/StdLib/LibC/Stdio/fclose.c
@@ -0,0 +1,83 @@
+/** @file
+ Implementation of fclose as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: fclose.c,v 1.16 2003/08/07 16:43:22 agc Exp
+ fclose.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include "reentrant.h"
+#include "local.h"
+
+int
+fclose(FILE *fp)
+{
+ int r;
+
+ _DIAGASSERT(fp != NULL);
+
+ if (fp->_flags == 0) { /* not open! */
+ errno = EBADF;
+ return (EOF);
+ }
+ FLOCKFILE(fp);
+ WCIO_FREE(fp);
+ r = fp->_flags & __SWR ? __sflush(fp) : 0;
+ if (fp->_close != NULL && (*fp->_close)(fp->_cookie) < 0)
+ r = EOF;
+ if (fp->_flags & __SMBF)
+ free((char *)fp->_bf._base);
+ if (HASUB(fp))
+ FREEUB(fp);
+ if (HASLB(fp))
+ FREELB(fp);
+ FUNLOCKFILE(fp);
+ fp->_file = -1;
+ fp->_flags = 0; /* Release this FILE for reuse. */
+ fp->_r = fp->_w = 0; /* Mess up if reaccessed. */
+ return (r);
+}
diff --git a/StdLib/LibC/Stdio/fdopen.c b/StdLib/LibC/Stdio/fdopen.c
new file mode 100644
index 0000000000..3a728951f6
--- /dev/null
+++ b/StdLib/LibC/Stdio/fdopen.c
@@ -0,0 +1,108 @@
+/* $NetBSD: fdopen.c,v 1.14 2003/08/07 16:43:22 agc Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)fdopen.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: fdopen.c,v 1.14 2003/08/07 16:43:22 agc Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+#include <sys/types.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/EfiSysCall.h>
+#include <stdio.h>
+
+#include "reentrant.h"
+#include "local.h"
+
+#ifdef __weak_alias
+__weak_alias(fdopen,_fdopen)
+#endif
+
+FILE *
+fdopen(int fd, const char *mode)
+{
+ FILE *fp;
+ int flags, oflags, fdflags, tmp;
+
+ _DIAGASSERT(fd != -1);
+
+ if ((flags = __sflags(mode, &oflags)) == 0)
+ return (NULL);
+
+ /* Make sure the mode the user wants is a subset of the actual mode. */
+ if ((fdflags = fcntl(fd, F_GETFL, 0)) < 0)
+ return (NULL);
+ tmp = fdflags & O_ACCMODE;
+ if (tmp != O_RDWR && (tmp != (oflags & O_ACCMODE))) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ if (oflags & O_NONBLOCK) {
+ struct stat st;
+ if (fstat(fd, &st) == -1) {
+ return (NULL);
+ }
+ if (!S_ISREG(st.st_mode)) {
+ errno = EFTYPE;
+ return (NULL);
+ }
+ }
+
+ if ((fp = __sfp()) == NULL)
+ return (NULL);
+ fp->_flags = (unsigned short)flags;
+ /*
+ * If opened for appending, but underlying descriptor does not have
+ * O_APPEND bit set, assert __SAPP so that __swrite() will lseek to
+ * end before each write.
+ */
+ if ((oflags & O_APPEND) && !(fdflags & O_APPEND))
+ fp->_flags |= __SAPP;
+ fp->_file = (short)fd;
+ fp->_cookie = fp;
+ fp->_read = __sread;
+ fp->_write = __swrite;
+ fp->_seek = __sseek;
+ fp->_close = __sclose;
+ return (fp);
+}
diff --git a/StdLib/LibC/Stdio/feof.c b/StdLib/LibC/Stdio/feof.c
new file mode 100644
index 0000000000..70b5e5090e
--- /dev/null
+++ b/StdLib/LibC/Stdio/feof.c
@@ -0,0 +1,67 @@
+/** @file
+ Implementation of a subroutine version of the macro feof,
+ as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: feof.c,v 1.11 2003/08/07 16:43:22 agc Exp
+ feof.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <stdio.h>
+#include "reentrant.h"
+#include "local.h"
+
+#undef feof
+
+int
+feof(FILE *fp)
+{
+ int r;
+
+ _DIAGASSERT(fp != NULL);
+
+ FLOCKFILE(fp);
+ r = __sfeof(fp);
+ FUNLOCKFILE(fp);
+ return r;
+}
diff --git a/StdLib/LibC/Stdio/ferror.c b/StdLib/LibC/Stdio/ferror.c
new file mode 100644
index 0000000000..5641b48038
--- /dev/null
+++ b/StdLib/LibC/Stdio/ferror.c
@@ -0,0 +1,67 @@
+/** @file
+ Implementation of a subroutine version of the macro ferror,
+ as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: ferror.c,v 1.11 2003/08/07 16:43:22 agc Exp
+ ferror.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <stdio.h>
+#include "reentrant.h"
+#include "local.h"
+
+#undef ferror
+
+int
+ferror(FILE *fp)
+{
+ int r;
+
+ _DIAGASSERT(fp != NULL);
+
+ FLOCKFILE(fp);
+ r = __sferror(fp);
+ FUNLOCKFILE(fp);
+ return r;
+}
diff --git a/StdLib/LibC/Stdio/fflush.c b/StdLib/LibC/Stdio/fflush.c
new file mode 100644
index 0000000000..fd21e37a13
--- /dev/null
+++ b/StdLib/LibC/Stdio/fflush.c
@@ -0,0 +1,115 @@
+/** @file
+ Implementation of fflush as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: fflush.c,v 1.15 2003/08/07 16:43:22 agc Exp
+ fflush.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include "reentrant.h"
+#include "local.h"
+
+#ifdef _REENTRANT
+extern rwlock_t __sfp_lock;
+#endif
+
+/* Flush a single file, or (if fp is NULL) all files. */
+int
+fflush(FILE *fp)
+{
+ int r;
+
+ if (fp == NULL) {
+ rwlock_rdlock(&__sfp_lock);
+ r = _fwalk(__sflush);
+ rwlock_unlock(&__sfp_lock);
+ return r;
+ }
+
+ FLOCKFILE(fp);
+ if ((fp->_flags & (__SWR | __SRW)) == 0) {
+ errno = EBADF;
+ r = EOF;
+ } else {
+ r = __sflush(fp);
+ }
+ FUNLOCKFILE(fp);
+ return r;
+}
+
+int
+__sflush(FILE *fp)
+{
+ unsigned char *p;
+ INT64 n;
+ int t;
+
+ _DIAGASSERT(fp != NULL);
+
+ t = fp->_flags;
+ if ((t & __SWR) == 0)
+ return (0);
+
+ if ((p = fp->_bf._base) == NULL)
+ return (0);
+
+ n = fp->_p - p; /* write this much */
+
+ /*
+ * Set these immediately to avoid problems with longjmp and to allow
+ * exchange buffering (via setvbuf) in user write function.
+ */
+ fp->_p = p;
+ fp->_w = t & (__SLBF|__SNBF) ? 0 : fp->_bf._size;
+
+ for (; n > 0; n -= t, p += t) {
+ t = (*fp->_write)(fp->_cookie, (char *)p, (int)n);
+ if (t <= 0) {
+ fp->_flags |= __SERR;
+ return (EOF);
+ }
+ }
+ return (0);
+}
diff --git a/StdLib/LibC/Stdio/fgetc.c b/StdLib/LibC/Stdio/fgetc.c
new file mode 100644
index 0000000000..b6e1a258ba
--- /dev/null
+++ b/StdLib/LibC/Stdio/fgetc.c
@@ -0,0 +1,65 @@
+/** @file
+ Implementation of fgetc as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: fgetc.c,v 1.11 2003/08/07 16:43:22 agc Exp
+ fgetc.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include "reentrant.h"
+#include "local.h"
+
+int
+fgetc(FILE *fp)
+{
+ int r;
+
+ _DIAGASSERT(fp != NULL);
+
+ FLOCKFILE(fp);
+ r = __sgetc(fp);
+ FUNLOCKFILE(fp);
+ return r;
+}
diff --git a/StdLib/LibC/Stdio/fgetln.c b/StdLib/LibC/Stdio/fgetln.c
new file mode 100644
index 0000000000..b18c7b66c0
--- /dev/null
+++ b/StdLib/LibC/Stdio/fgetln.c
@@ -0,0 +1,71 @@
+/* $NetBSD: fgetln.c,v 1.14 2004/05/10 16:47:11 drochner Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)fgetline.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: fgetln.c,v 1.14 2004/05/10 16:47:11 drochner Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+
+#include <stdio.h>
+
+#include "reentrant.h"
+#include "local.h"
+
+#ifdef __weak_alias
+__weak_alias(fgetln,_fgetln)
+#endif
+
+/*
+ * Get an input line. The returned pointer often (but not always)
+ * points into a stdio buffer. Fgetline does not alter the text of
+ * the returned line (which is thus not a C string because it will
+ * not necessarily end with '\0'), but does allow callers to modify
+ * it if they wish. Thus, we set __SMOD in case the caller does.
+ */
+char *
+fgetln(FILE *fp, size_t *lenp)
+{
+ char *cp;
+
+ FLOCKFILE(fp);
+ cp = __fgetstr(fp, lenp, '\n');
+ FUNLOCKFILE(fp);
+ return cp;
+}
diff --git a/StdLib/LibC/Stdio/fgetpos.c b/StdLib/LibC/Stdio/fgetpos.c
new file mode 100644
index 0000000000..f076718278
--- /dev/null
+++ b/StdLib/LibC/Stdio/fgetpos.c
@@ -0,0 +1,60 @@
+/** @file
+ Implementation of fgetpos as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: fgetpos.c,v 1.11 2003/08/07 16:43:23 agc Exp
+ fgetpos.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include "namespace.h"
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+
+int
+fgetpos(FILE *fp, fpos_t *pos)
+{
+ _DIAGASSERT(fp != NULL);
+ _DIAGASSERT(pos != NULL);
+
+ return((*pos = (off_t)ftello(fp)) == (off_t)-1);
+}
diff --git a/StdLib/LibC/Stdio/fgets.c b/StdLib/LibC/Stdio/fgets.c
new file mode 100644
index 0000000000..cf107ab867
--- /dev/null
+++ b/StdLib/LibC/Stdio/fgets.c
@@ -0,0 +1,119 @@
+/** @file
+ Implementation of fgets as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: fgets.c,v 1.20 2003/12/14 23:56:28 lukem Exp
+ fgets.c 8.2 (Berkeley) 12/22/93
+**/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include "reentrant.h"
+#include "local.h"
+
+/*
+ * Read at most n-1 characters from the given file.
+ * Stop when a newline has been read, or the count runs out.
+ * Return first argument, or NULL if no characters were read.
+ */
+char *
+fgets(char *buf, int n, FILE *fp)
+{
+ size_t len;
+ char *s;
+ unsigned char *p, *t;
+
+ _DIAGASSERT(buf != NULL);
+ _DIAGASSERT(fp != NULL);
+ if (n <= 0) /* sanity check */
+ return (NULL);
+
+ FLOCKFILE(fp);
+ _SET_ORIENTATION(fp, -1);
+ s = buf;
+ n--; /* leave space for NUL */
+ while (n != 0) {
+ /*
+ * If the buffer is empty, refill it.
+ */
+ if (fp->_r <= 0) {
+ if (__srefill(fp)) {
+ /* EOF/error: stop with partial or no line */
+ if (s == buf) {
+ FUNLOCKFILE(fp);
+ return (NULL);
+ }
+ break;
+ }
+ }
+ len = fp->_r;
+ p = fp->_p;
+
+ /*
+ * Scan through at most n bytes of the current buffer,
+ * looking for '\n'. If found, copy up to and including
+ * newline, and stop. Otherwise, copy entire chunk
+ * and loop.
+ */
+ if (len > (size_t)n)
+ len = n;
+ t = memchr((void *)p, '\n', len);
+ if (t != NULL) {
+ len = ++t - p;
+ fp->_r -= (int)len;
+ fp->_p = t;
+ (void)memcpy((void *)s, (void *)p, len);
+ s[len] = 0;
+ FUNLOCKFILE(fp);
+ return (buf);
+ }
+ fp->_r -= (int)len;
+ fp->_p += len;
+ (void)memcpy((void *)s, (void *)p, len);
+ s += len;
+ n -= (int)len;
+ }
+ *s = 0;
+ FUNLOCKFILE(fp);
+ return (buf);
+}
diff --git a/StdLib/LibC/Stdio/fgetstr.c b/StdLib/LibC/Stdio/fgetstr.c
new file mode 100644
index 0000000000..7364d3b891
--- /dev/null
+++ b/StdLib/LibC/Stdio/fgetstr.c
@@ -0,0 +1,169 @@
+/* $NetBSD: fgetstr.c,v 1.4 2006/11/24 19:46:58 christos Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)fgetline.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: fgetstr.c,v 1.4 2006/11/24 19:46:58 christos Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "reentrant.h"
+#include "local.h"
+
+/*
+ * Expand the line buffer. Return -1 on error.
+#ifdef notdef
+ * The `new size' does not account for a terminating '\0',
+ * so we add 1 here.
+#endif
+ */
+int
+__slbexpand(FILE *fp, size_t newsize)
+{
+ void *p;
+
+#ifdef notdef
+ ++newsize;
+#endif
+ _DIAGASSERT(fp != NULL);
+
+ if ((size_t)fp->_lb._size >= newsize)
+ return (0);
+ if ((p = realloc(fp->_lb._base, newsize)) == NULL)
+ return (-1);
+ fp->_lb._base = p;
+ fp->_lb._size = (int)newsize;
+ return (0);
+}
+
+/*
+ * Get an input line. The returned pointer often (but not always)
+ * points into a stdio buffer. Fgetline does not alter the text of
+ * the returned line (which is thus not a C string because it will
+ * not necessarily end with '\0'), but does allow callers to modify
+ * it if they wish. Thus, we set __SMOD in case the caller does.
+ */
+char *
+__fgetstr(FILE *fp, size_t *lenp, int sep)
+{
+ unsigned char *p;
+ size_t len;
+ size_t off;
+
+ _DIAGASSERT(fp != NULL);
+ _DIAGASSERT(lenp != NULL);
+
+ /* make sure there is input */
+ if (fp->_r <= 0 && __srefill(fp)) {
+ *lenp = 0;
+ return (NULL);
+ }
+
+ /* look for a newline in the input */
+ if ((p = memchr((void *)fp->_p, sep, (size_t)fp->_r)) != NULL) {
+ char *ret;
+
+ /*
+ * Found one. Flag buffer as modified to keep fseek from
+ * `optimising' a backward seek, in case the user stomps on
+ * the text.
+ */
+ p++; /* advance over it */
+ ret = (char *)fp->_p;
+ *lenp = len = p - fp->_p;
+ fp->_flags |= __SMOD;
+ fp->_r -= (int)len;
+ fp->_p = p;
+ return (ret);
+ }
+
+ /*
+ * We have to copy the current buffered data to the line buffer.
+ * As a bonus, though, we can leave off the __SMOD.
+ *
+ * OPTIMISTIC is length that we (optimistically) expect will
+ * accommodate the `rest' of the string, on each trip through the
+ * loop below.
+ */
+#define OPTIMISTIC 80
+
+ for (len = fp->_r, off = 0;; len += fp->_r) {
+ size_t diff;
+
+ /*
+ * Make sure there is room for more bytes. Copy data from
+ * file buffer to line buffer, refill file and look for
+ * newline. The loop stops only when we find a newline.
+ */
+ if (__slbexpand(fp, len + OPTIMISTIC))
+ goto error;
+ (void)memcpy((void *)(fp->_lb._base + off), (void *)fp->_p,
+ len - off);
+ off = len;
+ if (__srefill(fp))
+ break; /* EOF or error: return partial line */
+ if ((p = memchr((void *)fp->_p, sep, (size_t)fp->_r)) == NULL)
+ continue;
+
+ /* got it: finish up the line (like code above) */
+ p++;
+ diff = p - fp->_p;
+ len += diff;
+ if (__slbexpand(fp, len))
+ goto error;
+ (void)memcpy((void *)(fp->_lb._base + off), (void *)fp->_p,
+ diff);
+ fp->_r -= (int)diff;
+ fp->_p = p;
+ break;
+ }
+ *lenp = len;
+#ifdef notdef
+ fp->_lb._base[len] = 0;
+#endif
+ return ((char *)fp->_lb._base);
+
+error:
+ *lenp = 0; /* ??? */
+ return (NULL); /* ??? */
+}
diff --git a/StdLib/LibC/Stdio/fgetwc.c b/StdLib/LibC/Stdio/fgetwc.c
new file mode 100644
index 0000000000..548192390d
--- /dev/null
+++ b/StdLib/LibC/Stdio/fgetwc.c
@@ -0,0 +1,100 @@
+/*-
+ * Copyright (c)2001 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Citrus$
+
+ NetBSD: fgetwc.c,v 1.5 2006/07/03 17:06:36 tnozaki Exp
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <wchar.h>
+#include "reentrant.h"
+#include "local.h"
+
+wint_t
+__fgetwc_unlock(FILE *fp)
+{
+ struct wchar_io_data *wcio;
+ mbstate_t *st;
+ wchar_t wc;
+ size_t size;
+
+ _DIAGASSERT(fp != NULL);
+
+ _SET_ORIENTATION(fp, 1);
+ wcio = WCIO_GET(fp);
+ if (wcio == 0) {
+ errno = ENOMEM;
+ return WEOF;
+ }
+
+ /* if there're ungetwc'ed wchars, use them */
+ if (wcio->wcio_ungetwc_inbuf) {
+ wc = wcio->wcio_ungetwc_buf[--wcio->wcio_ungetwc_inbuf];
+
+ return wc;
+ }
+
+ st = &wcio->wcio_mbstate_in;
+
+ do {
+ char c;
+ int ch = __sgetc(fp);
+
+ if (ch == EOF) {
+ return WEOF;
+ }
+
+ c = (char)ch;
+ size = mbrtowc(&wc, &c, 1, st);
+ if (size == (size_t)-1) {
+ errno = EILSEQ;
+ fp->_flags |= __SERR;
+ return WEOF;
+ }
+ } while (size == (size_t)-2);
+
+ _DIAGASSERT(size == 1);
+
+ return wc;
+}
+
+wint_t
+fgetwc(FILE *fp)
+{
+ wint_t r;
+
+ _DIAGASSERT(fp != NULL);
+
+ FLOCKFILE(fp);
+ r = __fgetwc_unlock(fp);
+ FUNLOCKFILE(fp);
+
+ return (r);
+}
diff --git a/StdLib/LibC/Stdio/fgetws.c b/StdLib/LibC/Stdio/fgetws.c
new file mode 100644
index 0000000000..0113557965
--- /dev/null
+++ b/StdLib/LibC/Stdio/fgetws.c
@@ -0,0 +1,92 @@
+/* $NetBSD: fgetws.c,v 1.2 2006/07/03 17:06:36 tnozaki Exp $ */
+
+/*-
+ * Copyright (c) 2002 Tim J. Robbins.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Original version ID:
+ * FreeBSD: src/lib/libc/stdio/fgetws.c,v 1.4 2002/09/20 13:25:40 tjr Exp
+ *
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIB_SCCS) && !defined(lint)
+__RCSID("$NetBSD: fgetws.c,v 1.2 2006/07/03 17:06:36 tnozaki Exp $");
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <wchar.h>
+#include "reentrant.h"
+#include "local.h"
+
+wchar_t *
+fgetws(
+ wchar_t * __restrict ws,
+ int n,
+ FILE * __restrict fp
+ )
+{
+ wchar_t *wsp;
+ wint_t wc;
+
+ _DIAGASSERT(fp != NULL);
+ _DIAGASSERT(ws != NULL);
+
+ FLOCKFILE(fp);
+ _SET_ORIENTATION(fp, 1);
+
+ if (n <= 0) {
+ errno = EINVAL;
+ goto error;
+ }
+
+ wsp = ws;
+ while (n-- > 1) {
+ wc = __fgetwc_unlock(fp);
+ if (__sferror(fp) != 0)
+ goto error;
+ if (__sfeof(fp) != 0) {
+ if (wsp == ws) {
+ /* EOF/error, no characters read yet. */
+ goto error;
+ }
+ break;
+ }
+ *wsp++ = (wchar_t)wc;
+ if (wc == L'\n') {
+ break;
+ }
+ }
+
+ *wsp++ = L'\0';
+ FUNLOCKFILE(fp);
+
+ return (ws);
+
+error:
+ FUNLOCKFILE(fp);
+ return (NULL);
+}
diff --git a/StdLib/LibC/Stdio/fileext.h b/StdLib/LibC/Stdio/fileext.h
new file mode 100644
index 0000000000..0ad78468b9
--- /dev/null
+++ b/StdLib/LibC/Stdio/fileext.h
@@ -0,0 +1,66 @@
+/* $NetBSD: fileext.h,v 1.5 2003/07/18 21:46:41 nathanw Exp $ */
+
+/*-
+ * Copyright (c)2001 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Citrus$
+ */
+
+/*
+ * file extension
+ */
+struct __sfileext {
+ struct __sbuf _ub; /* ungetc buffer */
+ struct wchar_io_data _wcio; /* wide char i/o status */
+#ifdef _REENTRANT
+ mutex_t _lock; /* Lock for FLOCKFILE/FUNLOCKFILE */
+ cond_t _lockcond; /* Condition variable for signalling lock releases */
+ thr_t _lockowner; /* The thread currently holding the lock */
+ int _lockcount; /* Count of recursive locks */
+ int _lockinternal; /* Flag of whether the lock is held inside stdio */
+ int _lockcancelstate; /* Stashed cancellation state on internal lock */
+#endif
+};
+
+#define _EXT(fp) ((struct __sfileext *)(void *)((fp)->_ext._base))
+#define _UB(fp) _EXT(fp)->_ub
+#ifdef _REENTRANT
+#define _LOCK(fp) (_EXT(fp)->_lock)
+#define _LOCKCOND(fp) (_EXT(fp)->_lockcond)
+#define _LOCKOWNER(fp) (_EXT(fp)->_lockowner)
+#define _LOCKCOUNT(fp) (_EXT(fp)->_lockcount)
+#define _LOCKINTERNAL(fp) (_EXT(fp)->_lockinternal)
+#define _LOCKCANCELSTATE(fp) (_EXT(fp)->_lockcancelstate)
+#define _FILEEXT_SETUP(f, fext) do { \
+ /* LINTED */(f)->_ext._base = (unsigned char *)(fext); \
+ mutex_init(&_LOCK(f), NULL); \
+ cond_init(&_LOCKCOND(f), 0, NULL); \
+ _LOCKOWNER(f) = NULL; \
+ _LOCKCOUNT(f) = 0; \
+ _LOCKINTERNAL(f) = 0; \
+ } while (/* LINTED */ 0)
+#else
+#define _FILEEXT_SETUP(f, fext) /* LINTED */(f)->_ext._base = (unsigned char *)(fext)
+#endif
diff --git a/StdLib/LibC/Stdio/fileno.c b/StdLib/LibC/Stdio/fileno.c
new file mode 100644
index 0000000000..b9468c7cfc
--- /dev/null
+++ b/StdLib/LibC/Stdio/fileno.c
@@ -0,0 +1,71 @@
+/* $NetBSD: fileno.c,v 1.12 2004/05/09 17:27:53 kleink Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)fileno.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: fileno.c,v 1.12 2004/05/09 17:27:53 kleink Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include "reentrant.h"
+#include "local.h"
+
+/*
+ * A subroutine version of the macro fileno.
+ */
+#undef fileno
+int _fileno __P((FILE *)); /* XXX */
+
+__weak_alias(fileno,_fileno)
+
+int
+_fileno(fp)
+ FILE *fp;
+{
+ int r;
+
+ _DIAGASSERT(fp != NULL);
+
+ FLOCKFILE(fp);
+ r = __sfileno(fp);
+ FUNLOCKFILE(fp);
+ return r;
+}
diff --git a/StdLib/LibC/Stdio/findfp.c b/StdLib/LibC/Stdio/findfp.c
new file mode 100644
index 0000000000..b6495c3bcb
--- /dev/null
+++ b/StdLib/LibC/Stdio/findfp.c
@@ -0,0 +1,211 @@
+/* $NetBSD: findfp.c,v 1.23 2006/10/07 21:40:46 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)findfp.c 8.2 (Berkeley) 1/4/94";
+#else
+__RCSID("$NetBSD: findfp.c,v 1.23 2006/10/07 21:40:46 thorpej Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+#include <sys/param.h>
+#include <sys/EfiSysCall.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include "reentrant.h"
+#include "local.h"
+#include "glue.h"
+#include <MainData.h>
+
+int __sdidinit;
+
+#define NDYNAMIC 10 /* add ten more whenever necessary */
+
+#define std(flags, file) \
+/* p r w flags file bf lfbsize cookie close */ \
+ { NULL, 0, 0, flags, file, { NULL, 0 }, 0, __sF + file, __sclose, \
+/* read seek write ext up */ \
+ __sread, __sseek, __swrite, { (void *)(__sFext + file), 0 }, NULL, \
+/* ur ubuf, nbuf lb blksize offset */ \
+ 0, { '\0', '\0', '\0' }, { '\0' }, { NULL, 0 }, 0, (fpos_t)0 }
+
+ /* the usual - (stdin + stdout + stderr) */
+static FILE usual[FOPEN_MAX - 3];
+static struct __sfileext usualext[FOPEN_MAX - 3];
+static struct glue uglue = { 0, FOPEN_MAX - 3, usual };
+
+#if defined(_REENTRANT) && !defined(__lint__) /* XXX lint is busted */
+#define STDEXT { ._lock = MUTEX_INITIALIZER, ._lockcond = COND_INITIALIZER }
+struct __sfileext __sFext[3] = { STDEXT,
+ STDEXT,
+ STDEXT};
+#else
+struct __sfileext __sFext[3];
+#endif
+
+FILE __sF[3] = {
+ std(__SRD, STDIN_FILENO), /* stdin */
+ std(__SWR, STDOUT_FILENO), /* stdout */
+ std(__SWR|__SNBF, STDERR_FILENO) /* stderr */
+};
+struct glue __sglue = { &uglue, 3, __sF };
+
+static struct glue *moreglue(int);
+void f_prealloc(void);
+
+#ifdef _REENTRANT
+rwlock_t __sfp_lock = RWLOCK_INITIALIZER;
+#endif
+
+static struct glue *
+moreglue(int n)
+{
+ struct glue *g;
+ FILE *p;
+ struct __sfileext *pext;
+ static FILE empty;
+
+ g = (struct glue *)malloc(sizeof(*g) + ALIGNBYTES + n * sizeof(FILE)
+ + n * sizeof(struct __sfileext));
+ if (g == NULL)
+ return (NULL);
+ p = (FILE *)ALIGN((g + 1));
+ g->next = NULL;
+ g->niobs = n;
+ g->iobs = p;
+ pext = (void *)(p + n);
+ while (--n >= 0) {
+ *p = empty;
+ _FILEEXT_SETUP(p, pext);
+ p++;
+ pext++;
+ }
+ return (g);
+}
+
+/*
+ * Find a free FILE for fopen et al.
+ */
+FILE *
+__sfp()
+{
+ FILE *fp;
+ int n;
+ struct glue *g;
+
+ if (!__sdidinit)
+ __sinit();
+
+ rwlock_wrlock(&__sfp_lock);
+ for (g = &__sglue;; g = g->next) {
+ for (fp = g->iobs, n = g->niobs; --n >= 0; fp++)
+ if (fp->_flags == 0)
+ goto found;
+ if (g->next == NULL && (g->next = moreglue(NDYNAMIC)) == NULL)
+ break;
+ }
+ rwlock_unlock(&__sfp_lock);
+ return (NULL);
+found:
+ fp->_flags = 1; /* reserve this slot; caller sets real flags */
+ fp->_p = NULL; /* no current pointer */
+ fp->_w = 0; /* nothing to read or write */
+ fp->_r = 0;
+ fp->_bf._base = NULL; /* no buffer */
+ fp->_bf._size = 0;
+ fp->_lbfsize = 0; /* not line buffered */
+ fp->_file = -1; /* no file */
+/* fp->_cookie = <any>; */ /* caller sets cookie, _read/_write etc */
+ _UB(fp)._base = NULL; /* no ungetc buffer */
+ _UB(fp)._size = 0;
+ fp->_lb._base = NULL; /* no line buffer */
+ fp->_lb._size = 0;
+ memset(WCIO_GET(fp), 0, sizeof(struct wchar_io_data));
+ rwlock_unlock(&__sfp_lock);
+ return (fp);
+}
+
+#if 0
+/*
+ * XXX. Force immediate allocation of internal memory. Not used by stdio,
+ * but documented historically for certain applications. Bad applications.
+ */
+void
+f_prealloc()
+{
+ struct glue *g;
+ int n;
+
+ n = (int)sysconf(_SC_OPEN_MAX) - FOPEN_MAX + 20; /* 20 for slop. */
+ for (g = &__sglue; (n -= g->niobs) > 0 && g->next; g = g->next)
+ /* void */;
+ if (n > 0)
+ g->next = moreglue(n);
+}
+#endif
+
+/*
+ * exit() calls _cleanup() through *gMD->cleanup, set whenever we
+ * open or buffer a file. This chicanery is done so that programs
+ * that do not use stdio need not link it all in.
+ *
+ * The name `_cleanup' is, alas, fairly well known outside stdio.
+ */
+void
+_cleanup( void )
+{
+ /* (void) _fwalk(fclose); */
+ (void) fflush(NULL); /* `cheating' */
+}
+
+/*
+ * __sinit() is called whenever stdio's internal variables must be set up.
+ */
+void
+__sinit( void )
+{
+ int i;
+
+ for (i = 0; i < FOPEN_MAX - 3; i++)
+ _FILEEXT_SETUP(&usual[i], &usualext[i]);
+
+ /* make sure we clean up on exit */
+ gMD->cleanup = _cleanup; /* conservative */
+ __sdidinit = 1;
+}
diff --git a/StdLib/LibC/Stdio/flags.c b/StdLib/LibC/Stdio/flags.c
new file mode 100644
index 0000000000..59ce8e30d6
--- /dev/null
+++ b/StdLib/LibC/Stdio/flags.c
@@ -0,0 +1,115 @@
+/** @file
+ Implementation of internal function to return the (stdio) flags for a given mode.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: flags.c,v 1.14 2003/08/07 16:43:23 agc Exp
+ flags.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#include <sys/types.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <errno.h>
+#include "reentrant.h"
+#include "local.h"
+
+/*
+ * Return the (stdio) flags for a given mode. Store the flags
+ * to be passed to an open() syscall through *optr.
+ * Return 0 on error.
+ */
+int
+__sflags(const char *mode, int *optr)
+{
+ int ret, m, o;
+
+ _DIAGASSERT(mode != NULL);
+
+ switch (*mode++) {
+
+ case 'r': /* open for reading */
+ ret = __SRD;
+ m = O_RDONLY;
+ o = 0;
+ break;
+
+ case 'w': /* open for writing */
+ ret = __SWR;
+ m = O_WRONLY;
+ o = O_CREAT | O_TRUNC;
+ break;
+
+ case 'a': /* open for appending */
+ ret = __SWR;
+ m = O_WRONLY;
+ o = O_CREAT | O_APPEND;
+ break;
+
+ default: /* illegal mode */
+ errno = EINVAL;
+ return (0);
+ }
+
+ /*
+ * [rwa]\+ or [rwa]b\+ means read and write
+ * f means open only plain files.
+ */
+ for (; *mode; mode++)
+ switch (*mode) {
+ case '+':
+ ret = __SRW;
+ m = O_RDWR;
+ break;
+ case 'f':
+ o |= O_NONBLOCK;
+ break;
+ case 'b':
+ break;
+ default: /* We could produce a warning here */
+ break;
+ }
+
+ *optr = m | o;
+ return (ret);
+}
diff --git a/StdLib/LibC/Stdio/floatio.h b/StdLib/LibC/Stdio/floatio.h
new file mode 100644
index 0000000000..1cb0bad181
--- /dev/null
+++ b/StdLib/LibC/Stdio/floatio.h
@@ -0,0 +1,55 @@
+/* $NetBSD: floatio.h,v 1.5 2005/05/14 23:51:02 christos Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)floatio.h 8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * Floating point scanf/printf (input/output) definitions.
+ */
+
+/* 11-bit exponent (VAX G floating point) is 308 decimal digits */
+#define MAXEXP 308
+/* 128 bit fraction takes up 39 decimal digits; max reasonable precision */
+#define MAXFRACT 39
+/*
+ * MAXEXPDIG is the maximum number of decimal digits needed to store a
+ * floating point exponent in the largest supported format. It should
+ * be ceil(log10(LDBL_MAX_10_EXP)) or, if hexadecimal floating point
+ * conversions are supported, ceil(log10(LDBL_MAX_EXP)). But since it
+ * is presently never greater than 5 in practice, we fudge it.
+ */
+#define MAXEXPDIG 6
+#if LDBL_MAX_EXP > 999999
+#error "floating point buffers too small"
+#endif
diff --git a/StdLib/LibC/Stdio/flockfile.c b/StdLib/LibC/Stdio/flockfile.c
new file mode 100644
index 0000000000..386164e89f
--- /dev/null
+++ b/StdLib/LibC/Stdio/flockfile.c
@@ -0,0 +1,192 @@
+/* $NetBSD: flockfile.c,v 1.8 2003/07/22 00:56:25 nathanw Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Nathan J. Williams.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: flockfile.c,v 1.8 2003/07/22 00:56:25 nathanw Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include "reentrant.h"
+#include "local.h"
+
+#ifdef __weak_alias
+__weak_alias(flockfile,_flockfile)
+__weak_alias(ftrylockfile,_ftrylockfile)
+__weak_alias(funlockfile,_funlockfile)
+#endif
+
+#ifdef _REENTRANT
+/*
+ * XXX This code makes the assumption that a thr_t (pthread_t) is a
+ * XXX pointer.
+ */
+
+extern int __isthreaded;
+
+void
+flockfile(FILE *fp)
+{
+
+ __flockfile_internal(fp, 0);
+}
+
+int
+ftrylockfile(FILE *fp)
+{
+ int retval;
+
+ if (__isthreaded == 0)
+ return 0;
+
+ retval = 0;
+ mutex_lock(&_LOCK(fp));
+
+ if (_LOCKOWNER(fp) == thr_self()) {
+ _LOCKCOUNT(fp)++;
+ } else if (_LOCKOWNER(fp) == NULL) {
+ _LOCKOWNER(fp) = thr_self();
+ _LOCKCOUNT(fp) = 1;
+ } else
+ retval = -1;
+
+ mutex_unlock(&_LOCK(fp));
+
+ return retval;
+}
+
+void
+funlockfile(FILE *fp)
+{
+
+ __funlockfile_internal(fp, 0);
+}
+
+void
+__flockfile_internal(FILE *fp, int internal)
+{
+
+ if (__isthreaded == 0)
+ return;
+
+ mutex_lock(&_LOCK(fp));
+
+ if (_LOCKOWNER(fp) == thr_self()) {
+ _LOCKCOUNT(fp)++;
+ if (internal)
+ _LOCKINTERNAL(fp)++;
+ } else {
+ /* danger! cond_wait() is a cancellation point. */
+ int oldstate;
+ thr_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
+ while (_LOCKOWNER(fp) != NULL)
+ cond_wait(&_LOCKCOND(fp), &_LOCK(fp));
+ thr_setcancelstate(oldstate, NULL);
+ _LOCKOWNER(fp) = thr_self();
+ _LOCKCOUNT(fp) = 1;
+ if (internal)
+ _LOCKINTERNAL(fp) = 1;
+ }
+
+ if (_LOCKINTERNAL(fp) == 1)
+ /* stash cancellation state and disable */
+ thr_setcancelstate(PTHREAD_CANCEL_DISABLE,
+ &_LOCKCANCELSTATE(fp));
+
+ mutex_unlock(&_LOCK(fp));
+}
+
+void
+__funlockfile_internal(FILE *fp, int internal)
+{
+
+ if (__isthreaded == 0)
+ return;
+
+ mutex_lock(&_LOCK(fp));
+
+ if (internal) {
+ _LOCKINTERNAL(fp)--;
+ if (_LOCKINTERNAL(fp) == 0)
+ thr_setcancelstate(_LOCKCANCELSTATE(fp), NULL);
+ }
+
+ _LOCKCOUNT(fp)--;
+ if (_LOCKCOUNT(fp) == 0) {
+ _LOCKOWNER(fp) = NULL;
+ cond_signal(&_LOCKCOND(fp));
+ }
+
+ mutex_unlock(&_LOCK(fp));
+}
+
+#else /* _REENTRANT */
+
+void
+flockfile(FILE *fp)
+{
+ /* LINTED deliberate lack of effect */
+ (void)fp;
+
+ return;
+}
+
+int
+ftrylockfile(FILE *fp)
+{
+ /* LINTED deliberate lack of effect */
+ (void)fp;
+
+ return (0);
+}
+
+void
+funlockfile(FILE *fp)
+{
+ /* LINTED deliberate lack of effect */
+ (void)fp;
+
+ return;
+}
+
+#endif /* _REENTRANT */
diff --git a/StdLib/LibC/Stdio/fopen.c b/StdLib/LibC/Stdio/fopen.c
new file mode 100644
index 0000000000..4b3c14cd28
--- /dev/null
+++ b/StdLib/LibC/Stdio/fopen.c
@@ -0,0 +1,109 @@
+/** @file
+ Implementation of fopen as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: fopen.c,v 1.12 2003/08/07 16:43:24 agc Exp
+ fopen.c 8.1 (Berkeley) 6/4/93"
+**/
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <sys/EfiSysCall.h>
+#include <stdio.h>
+#include <errno.h>
+#include "reentrant.h"
+#include "local.h"
+
+FILE *
+fopen(const char *file, const char *mode)
+{
+ FILE *fp;
+ int f;
+ int flags, oflags;
+
+ _DIAGASSERT(file != NULL);
+ if ((flags = __sflags(mode, &oflags)) == 0)
+ return (NULL);
+ if ((fp = __sfp()) == NULL)
+ return (NULL);
+ if ((f = open(file, oflags, DEFFILEMODE)) < 0)
+ goto release;
+ if (oflags & O_NONBLOCK) {
+ struct stat st;
+ if (fstat(f, &st) == -1) {
+ int sverrno = errno;
+ (void)close(f);
+ errno = sverrno;
+ goto release;
+ }
+ if (!S_ISREG(st.st_mode)) {
+ (void)close(f);
+ errno = EFTYPE;
+ goto release;
+ }
+ }
+ fp->_file = (short)f;
+ fp->_flags = (unsigned short)flags;
+ fp->_cookie = fp;
+ fp->_read = __sread;
+ fp->_write = __swrite;
+ fp->_seek = __sseek;
+ fp->_close = __sclose;
+
+ /*
+ * When opening in append mode, even though we use O_APPEND,
+ * we need to seek to the end so that ftell() gets the right
+ * answer. If the user then alters the seek pointer, or
+ * the file extends, this will fail, but there is not much
+ * we can do about this. (We could set __SAPP and check in
+ * fseek and ftell.)
+ */
+ if (oflags & O_APPEND)
+ (void) __sseek((void *)fp, (fpos_t)0, SEEK_END);
+ return (fp);
+release:
+ fp->_flags = 0; /* release */
+ return (NULL);
+}
diff --git a/StdLib/LibC/Stdio/fparseln.c b/StdLib/LibC/Stdio/fparseln.c
new file mode 100644
index 0000000000..c1ce12be2e
--- /dev/null
+++ b/StdLib/LibC/Stdio/fparseln.c
@@ -0,0 +1,248 @@
+/* $NetBSD: fparseln.c,v 1.5 2004/06/20 22:20:15 jmc Exp $ */
+
+/*
+ * Copyright (c) 1997 Christos Zoulas. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christos Zoulas.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: fparseln.c,v 1.5 2004/06/20 22:20:15 jmc Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef __weak_alias
+__weak_alias(fparseln,_fparseln)
+#endif
+
+#if ! HAVE_FPARSELN
+
+#ifndef HAVE_NBTOOL_CONFIG_H
+#include "reentrant.h"
+#include "local.h"
+#else
+#define FLOCKFILE(fp)
+#define FUNLOCKFILE(fp)
+#endif
+
+#if defined(_REENTRANT) && !HAVE_NBTOOL_CONFIG_H
+#define __fgetln(f, l) __fgetstr(f, l, '\n')
+#else
+#define __fgetln(f, l) fgetln(f, l)
+#endif
+
+static int isescaped(const char *, const char *, int);
+
+/* isescaped():
+ * Return true if the character in *p that belongs to a string
+ * that starts in *sp, is escaped by the escape character esc.
+ */
+static int
+isescaped(const char *sp, const char *p, int esc)
+{
+ const char *cp;
+ size_t ne;
+
+ _DIAGASSERT(sp != NULL);
+ _DIAGASSERT(p != NULL);
+
+ /* No escape character */
+ if (esc == '\0')
+ return 1;
+
+ /* Count the number of escape characters that precede ours */
+ for (ne = 0, cp = p; --cp >= sp && *cp == esc; ne++)
+ continue;
+
+ /* Return true if odd number of escape characters */
+ return (ne & 1) != 0;
+}
+
+
+/* fparseln():
+ * Read a line from a file parsing continuations ending in \
+ * and eliminating trailing newlines, or comments starting with
+ * the comment char.
+ */
+char *
+fparseln(FILE *fp, size_t *size, size_t *lineno, const char str[3], int flags)
+{
+ static const char dstr[3] = { '\\', '\\', '#' };
+
+ size_t s, len;
+ char *buf;
+ char *ptr, *cp;
+ int cnt;
+ char esc, con, nl, com;
+
+ _DIAGASSERT(fp != NULL);
+
+ len = 0;
+ buf = NULL;
+ cnt = 1;
+
+ if (str == NULL)
+ str = dstr;
+
+ esc = str[0];
+ con = str[1];
+ com = str[2];
+ /*
+ * XXX: it would be cool to be able to specify the newline character,
+ * but unfortunately, fgetln does not let us
+ */
+ nl = '\n';
+
+ FLOCKFILE(fp);
+
+ while (cnt) {
+ cnt = 0;
+
+ if (lineno)
+ (*lineno)++;
+
+ if ((ptr = __fgetln(fp, &s)) == NULL)
+ break;
+
+ if (s && com) { /* Check and eliminate comments */
+ for (cp = ptr; cp < ptr + s; cp++)
+ if (*cp == com && !isescaped(ptr, cp, esc)) {
+ s = cp - ptr;
+ cnt = s == 0 && buf == NULL;
+ break;
+ }
+ }
+
+ if (s && nl) { /* Check and eliminate newlines */
+ cp = &ptr[s - 1];
+
+ if (*cp == nl)
+ s--; /* forget newline */
+ }
+
+ if (s && con) { /* Check and eliminate continuations */
+ cp = &ptr[s - 1];
+
+ if (*cp == con && !isescaped(ptr, cp, esc)) {
+ s--; /* forget escape */
+ cnt = 1;
+ }
+ }
+
+ if (s == 0 && buf != NULL)
+ continue;
+
+ if ((cp = realloc(buf, len + s + 1)) == NULL) {
+ FUNLOCKFILE(fp);
+ free(buf);
+ return NULL;
+ }
+ buf = cp;
+
+ (void) memcpy(buf + len, ptr, s);
+ len += s;
+ buf[len] = '\0';
+ }
+
+ FUNLOCKFILE(fp);
+
+ if ((flags & FPARSELN_UNESCALL) != 0 && esc && buf != NULL &&
+ strchr(buf, esc) != NULL) {
+ ptr = cp = buf;
+ while (cp[0] != '\0') {
+ int skipesc;
+
+ while (cp[0] != '\0' && cp[0] != esc)
+ *ptr++ = *cp++;
+ if (cp[0] == '\0' || cp[1] == '\0')
+ break;
+
+ skipesc = 0;
+ if (cp[1] == com)
+ skipesc += (flags & FPARSELN_UNESCCOMM);
+ if (cp[1] == con)
+ skipesc += (flags & FPARSELN_UNESCCONT);
+ if (cp[1] == esc)
+ skipesc += (flags & FPARSELN_UNESCESC);
+ if (cp[1] != com && cp[1] != con && cp[1] != esc)
+ skipesc = (flags & FPARSELN_UNESCREST);
+
+ if (skipesc)
+ cp++;
+ else
+ *ptr++ = *cp++;
+ *ptr++ = *cp++;
+ }
+ *ptr = '\0';
+ len = strlen(buf);
+ }
+
+ if (size)
+ *size = len;
+ return buf;
+}
+
+#ifdef TEST
+
+int main(int, char **);
+
+int
+main(int argc, char **argv)
+{
+ char *ptr;
+ size_t size, line;
+
+ line = 0;
+ while ((ptr = fparseln(stdin, &size, &line, NULL,
+ FPARSELN_UNESCALL)) != NULL)
+ printf("line %d (%d) |%s|\n", line, size, ptr);
+ return 0;
+}
+
+/*
+
+# This is a test
+line 1
+line 2 \
+line 3 # Comment
+line 4 \# Not comment \\\\
+
+# And a comment \
+line 5 \\\
+line 6
+
+*/
+
+#endif /* TEST */
+#endif /* ! HAVE_FPARSELN */
diff --git a/StdLib/LibC/Stdio/fprintf.c b/StdLib/LibC/Stdio/fprintf.c
new file mode 100644
index 0000000000..ba6ec0c22e
--- /dev/null
+++ b/StdLib/LibC/Stdio/fprintf.c
@@ -0,0 +1,66 @@
+/** @file
+ Implementation of fprintf as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: fprintf.c,v 1.11 2003/08/07 16:43:24 agc Exp
+ fprintf.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+int
+fprintf(FILE *fp, const char *fmt, ...)
+{
+ int ret;
+ va_list ap;
+
+ _DIAGASSERT(fp != NULL);
+ _DIAGASSERT(fmt != NULL);
+
+ va_start(ap, fmt);
+ ret = vfprintf(fp, fmt, ap);
+ va_end(ap);
+ return (ret);
+}
diff --git a/StdLib/LibC/Stdio/fpurge.c b/StdLib/LibC/Stdio/fpurge.c
new file mode 100644
index 0000000000..cc649eee49
--- /dev/null
+++ b/StdLib/LibC/Stdio/fpurge.c
@@ -0,0 +1,76 @@
+/* $NetBSD: fpurge.c,v 1.13 2003/08/07 16:43:24 agc Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)fpurge.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: fpurge.c,v 1.13 2003/08/07 16:43:24 agc Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include "reentrant.h"
+#include "local.h"
+
+/*
+ * fpurge: like fflush, but without writing anything: leave the
+ * given FILE's buffer empty.
+ */
+int
+fpurge(fp)
+ FILE *fp;
+{
+
+ _DIAGASSERT(fp != NULL);
+
+ if (fp->_flags == 0) {
+ errno = EBADF;
+ return (EOF);
+ }
+ FLOCKFILE(fp);
+ if (HASUB(fp))
+ FREEUB(fp);
+ WCIO_FREE(fp);
+ fp->_p = fp->_bf._base;
+ fp->_r = 0;
+ fp->_w = fp->_flags & (__SLBF|__SNBF) ? 0 : fp->_bf._size;
+ FUNLOCKFILE(fp);
+ return (0);
+}
diff --git a/StdLib/LibC/Stdio/fputc.c b/StdLib/LibC/Stdio/fputc.c
new file mode 100644
index 0000000000..b9ae5aa828
--- /dev/null
+++ b/StdLib/LibC/Stdio/fputc.c
@@ -0,0 +1,65 @@
+/** @file
+ Implementation of fputc as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: fputc.c,v 1.12 2003/08/07 16:43:24 agc Exp
+ fputc.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include "reentrant.h"
+#include "local.h"
+
+int
+fputc(int c, FILE *fp)
+{
+ int r;
+
+ _DIAGASSERT(fp != NULL);
+
+ FLOCKFILE(fp);
+ r = __sputc(c, fp);
+ FUNLOCKFILE(fp);
+ return r;
+}
diff --git a/StdLib/LibC/Stdio/fputs.c b/StdLib/LibC/Stdio/fputs.c
new file mode 100644
index 0000000000..081ee1a099
--- /dev/null
+++ b/StdLib/LibC/Stdio/fputs.c
@@ -0,0 +1,81 @@
+/** @file
+ Implementation of fputs as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: fputs.c,v 1.14 2005/06/22 19:45:22 christos Exp
+ fputs.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include "reentrant.h"
+#include "local.h"
+#include "fvwrite.h"
+
+/*
+ * Write the given string to the given file.
+ */
+int
+fputs(const char *s, FILE *fp)
+{
+ struct __suio uio;
+ struct __siov iov;
+ int r;
+
+ _DIAGASSERT(s != NULL);
+ _DIAGASSERT(fp != NULL);
+
+ if (s == NULL)
+ s = "(null)";
+
+ iov.iov_base = __UNCONST(s);
+ uio.uio_resid = (int)(iov.iov_len = strlen(s));
+ uio.uio_iov = &iov;
+ uio.uio_iovcnt = 1;
+ FLOCKFILE(fp);
+ _SET_ORIENTATION(fp, -1);
+ r = __sfvwrite(fp, &uio);
+ FUNLOCKFILE(fp);
+ return r;
+}
diff --git a/StdLib/LibC/Stdio/fputwc.c b/StdLib/LibC/Stdio/fputwc.c
new file mode 100644
index 0000000000..49f6702227
--- /dev/null
+++ b/StdLib/LibC/Stdio/fputwc.c
@@ -0,0 +1,100 @@
+/* $NetBSD: fputwc.c,v 1.4 2005/06/12 05:21:27 lukem Exp $ */
+
+/*-
+ * Copyright (c)2001 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Citrus$
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: fputwc.c,v 1.4 2005/06/12 05:21:27 lukem Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <wchar.h>
+#include "reentrant.h"
+#include "local.h"
+#include "fvwrite.h"
+
+wint_t
+__fputwc_unlock(wchar_t wc, FILE *fp)
+{
+ struct wchar_io_data *wcio;
+ mbstate_t *st;
+ size_t size;
+ char buf[MB_LEN_MAX];
+ struct __suio uio;
+ struct __siov iov;
+
+ _DIAGASSERT(fp != NULL);
+
+ /* LINTED we don't play with buf */
+ iov.iov_base = (void *)buf;
+ uio.uio_iov = &iov;
+ uio.uio_iovcnt = 1;
+
+ _SET_ORIENTATION(fp, 1);
+ wcio = WCIO_GET(fp);
+ if (wcio == 0) {
+ errno = ENOMEM;
+ return WEOF;
+ }
+
+ wcio->wcio_ungetwc_inbuf = 0;
+ st = &wcio->wcio_mbstate_out;
+
+ size = wcrtomb(buf, wc, st);
+ if (size == (size_t)-1) {
+ errno = EILSEQ;
+ return WEOF;
+ }
+
+ _DIAGASSERT(size != 0);
+
+ uio.uio_resid = (int)(iov.iov_len = size);
+ if (__sfvwrite(fp, &uio)) {
+ return WEOF;
+ }
+
+ return (wint_t)wc;
+}
+
+wint_t
+fputwc(wchar_t wc, FILE *fp)
+{
+ wint_t r;
+
+ _DIAGASSERT(fp != NULL);
+
+ FLOCKFILE(fp);
+ r = __fputwc_unlock(wc, fp);
+ FUNLOCKFILE(fp);
+
+ return (r);
+}
diff --git a/StdLib/LibC/Stdio/fputws.c b/StdLib/LibC/Stdio/fputws.c
new file mode 100644
index 0000000000..ce373bb402
--- /dev/null
+++ b/StdLib/LibC/Stdio/fputws.c
@@ -0,0 +1,65 @@
+/* $NetBSD: fputws.c,v 1.1 2003/03/07 07:11:37 tshiozak Exp $ */
+
+/*-
+ * Copyright (c) 2002 Tim J. Robbins.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Original version ID:
+ * FreeBSD: src/lib/libc/stdio/fputws.c,v 1.4 2002/09/20 13:25:40 tjr Exp
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: fputws.c,v 1.1 2003/03/07 07:11:37 tshiozak Exp $");
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <wchar.h>
+#include "reentrant.h"
+#include "local.h"
+
+int
+fputws(
+ const wchar_t * __restrict ws,
+ FILE * __restrict fp
+ )
+{
+ _DIAGASSERT(fp != NULL);
+ _DIAGASSERT(ws != NULL);
+
+ FLOCKFILE(fp);
+ _SET_ORIENTATION(fp, 1);
+
+ while (*ws != '\0') {
+ if (__fputwc_unlock(*ws++, fp) == WEOF) {
+ FUNLOCKFILE(fp);
+ return (-1);
+ }
+ }
+ FUNLOCKFILE(fp);
+
+ return (0);
+}
diff --git a/StdLib/LibC/Stdio/fread.c b/StdLib/LibC/Stdio/fread.c
new file mode 100644
index 0000000000..21013d7ff4
--- /dev/null
+++ b/StdLib/LibC/Stdio/fread.c
@@ -0,0 +1,96 @@
+/** @file
+ Implementation of fread as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: fread.c,v 1.16 2003/08/07 16:43:25 agc Exp
+ fread.c 8.2 (Berkeley) 12/11/93
+**/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include "reentrant.h"
+#include "local.h"
+
+size_t
+fread(void *buf, size_t size, size_t count, FILE *fp)
+{
+ size_t resid;
+ char *p;
+ int r;
+ size_t total;
+
+ _DIAGASSERT(fp != NULL);
+ /*
+ * The ANSI standard requires a return value of 0 for a count
+ * or a size of 0. Whilst ANSI imposes no such requirements on
+ * fwrite, the SUSv2 does.
+ */
+ if ((resid = count * size) == 0)
+ return (0);
+
+ _DIAGASSERT(buf != NULL);
+
+ FLOCKFILE(fp);
+ if (fp->_r < 0)
+ fp->_r = 0;
+ total = resid;
+ p = buf;
+ while (resid > (size_t)(r = fp->_r)) {
+ (void)memcpy((void *)p, (void *)fp->_p, (size_t)r);
+ fp->_p += r;
+ /* fp->_r = 0 ... done in __srefill */
+ p += r;
+ resid -= r;
+ if (__srefill(fp)) {
+ /* no more input: return partial result */
+ FUNLOCKFILE(fp);
+ return ((total - resid) / size);
+ }
+ }
+ (void)memcpy((void *)p, (void *)fp->_p, resid);
+ fp->_r -= (int)resid;
+ fp->_p += resid;
+ FUNLOCKFILE(fp);
+ return (count);
+}
diff --git a/StdLib/LibC/Stdio/freopen.c b/StdLib/LibC/Stdio/freopen.c
new file mode 100644
index 0000000000..186ab9ad66
--- /dev/null
+++ b/StdLib/LibC/Stdio/freopen.c
@@ -0,0 +1,196 @@
+/** @file
+ Implementation of freopen as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: freopen.c,v 1.14 2003/08/07 16:43:25 agc Exp
+ freopen.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/EfiSysCall.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include "reentrant.h"
+#include "local.h"
+
+/*
+ * Re-direct an existing, open (probably) file to some other file.
+ * ANSI is written such that the original file gets closed if at
+ * all possible, no matter what.
+ */
+FILE *
+freopen(const char *file, const char *mode, FILE *fp)
+{
+ int f;
+ int flags, isopen, oflags, sverrno, wantfd;
+
+ _DIAGASSERT(file != NULL);
+ _DIAGASSERT(mode != NULL);
+ _DIAGASSERT(fp != NULL);
+
+ if ((flags = __sflags(mode, &oflags)) == 0) {
+ (void) fclose(fp);
+ return (NULL);
+ }
+
+ if (!__sdidinit)
+ __sinit();
+
+ /*
+ * There are actually programs that depend on being able to "freopen"
+ * descriptors that weren't originally open. Keep this from breaking.
+ * Remember whether the stream was open to begin with, and which file
+ * descriptor (if any) was associated with it. If it was attached to
+ * a descriptor, defer closing it; freopen("/dev/stdin", "r", stdin)
+ * should work. This is unnecessary if it was not a Unix file.
+ */
+ if (fp->_flags == 0) {
+ fp->_flags = __SEOF; /* hold on to it */
+ isopen = 0;
+ wantfd = -1;
+ } else {
+ /* flush the stream; ANSI doesn't require this. */
+ if (fp->_flags & __SWR)
+ (void) __sflush(fp);
+ /* if close is NULL, closing is a no-op, hence pointless */
+ isopen = fp->_close != NULL;
+ if ((wantfd = fp->_file) < 0 && isopen) {
+ (void) (*fp->_close)(fp->_cookie);
+ isopen = 0;
+ }
+ }
+
+ /* Get a new descriptor to refer to the new file. */
+ f = open(file, oflags, DEFFILEMODE);
+ if (f < 0 && isopen) {
+ /* If out of fd's close the old one and try again. */
+ if (errno == ENFILE || errno == EMFILE) {
+ (void) (*fp->_close)(fp->_cookie);
+ isopen = 0;
+ f = open(file, oflags, DEFFILEMODE);
+ }
+ }
+ sverrno = errno;
+
+ /*
+ * Finish closing fp. Even if the open succeeded above, we cannot
+ * keep fp->_base: it may be the wrong size. This loses the effect
+ * of any setbuffer calls, but stdio has always done this before.
+ */
+ if (isopen && f != wantfd)
+ (void) (*fp->_close)(fp->_cookie);
+ if (fp->_flags & __SMBF)
+ free((char *)fp->_bf._base);
+ fp->_w = 0;
+ fp->_r = 0;
+ fp->_p = NULL;
+ fp->_bf._base = NULL;
+ fp->_bf._size = 0;
+ fp->_lbfsize = 0;
+ if (HASUB(fp))
+ FREEUB(fp);
+ WCIO_FREE(fp);
+ _UB(fp)._size = 0;
+ if (HASLB(fp))
+ FREELB(fp);
+ fp->_lb._size = 0;
+
+ if (f < 0) { /* did not get it after all */
+ fp->_flags = 0; /* set it free */
+ errno = sverrno; /* restore in case _close clobbered */
+ return (NULL);
+ }
+
+ if (oflags & O_NONBLOCK) {
+ struct stat st;
+ if (fstat(f, &st) == -1) {
+ sverrno = errno;
+ (void)close(f);
+ errno = sverrno;
+ return (NULL);
+ }
+ if (!S_ISREG(st.st_mode)) {
+ (void)close(f);
+ errno = EFTYPE;
+ return (NULL);
+ }
+ }
+
+ /*
+ * If reopening something that was open before on a real file, try
+ * to maintain the descriptor. Various C library routines (perror)
+ * assume stderr is always fd STDERR_FILENO, even if being freopen'd.
+ */
+ if (wantfd >= 0 && f != wantfd) {
+ if (dup2(f, wantfd) >= 0) {
+ (void) close(f);
+ f = wantfd;
+ }
+ }
+
+ fp->_flags = (unsigned short)flags;
+ fp->_file = (short)f;
+ fp->_cookie = fp;
+ fp->_read = __sread;
+ fp->_write = __swrite;
+ fp->_seek = __sseek;
+ fp->_close = __sclose;
+
+ /*
+ * When reopening in append mode, even though we use O_APPEND,
+ * we need to seek to the end so that ftell() gets the right
+ * answer. If the user then alters the seek pointer, or
+ * the file extends, this will fail, but there is not much
+ * we can do about this. (We could set __SAPP and check in
+ * fseek and ftell.)
+ */
+ if (oflags & O_APPEND)
+ (void) __sseek((void *)fp, (fpos_t)0, SEEK_END);
+ return (fp);
+}
diff --git a/StdLib/LibC/Stdio/fscanf.c b/StdLib/LibC/Stdio/fscanf.c
new file mode 100644
index 0000000000..72d55e50cd
--- /dev/null
+++ b/StdLib/LibC/Stdio/fscanf.c
@@ -0,0 +1,66 @@
+/** @file
+ Implementation of fscanf as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: fscanf.c,v 1.12 2003/08/07 16:43:25 agc Exp
+ fscanf.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "reentrant.h"
+#include "local.h"
+
+int
+fscanf(FILE *fp, char const *fmt, ...)
+{
+ int ret;
+ va_list ap;
+
+ va_start(ap, fmt);
+ ret = __svfscanf(fp, fmt, ap);
+ va_end(ap);
+ return (ret);
+}
diff --git a/StdLib/LibC/Stdio/fseek.c b/StdLib/LibC/Stdio/fseek.c
new file mode 100644
index 0000000000..ac06f29fcb
--- /dev/null
+++ b/StdLib/LibC/Stdio/fseek.c
@@ -0,0 +1,74 @@
+/** @file
+ Implementation of fseek as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to The NetBSD Foundation
+ by David Laight.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: fseek.c,v 1.22 2006/01/26 10:48:18 kleink Exp
+**/
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "namespace.h"
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "reentrant.h"
+#include "local.h"
+
+/*
+ * Seek the given file to the given offset.
+ * Zero extend the offset if SEEK_SET to allow access to 4GB files
+ */
+int
+fseek(FILE *fp, long l_offset, int whence)
+{
+ off_t offset;
+
+ if (whence == SEEK_SET)
+ offset = (off_t)((UINT64)l_offset); // Coerce to unsigned to prevent sign extension
+ else
+ offset = (off_t)l_offset; // OK for this one to be negative
+ return fseeko(fp, offset, whence);
+}
diff --git a/StdLib/LibC/Stdio/fseeko.c b/StdLib/LibC/Stdio/fseeko.c
new file mode 100644
index 0000000000..3c406eaec8
--- /dev/null
+++ b/StdLib/LibC/Stdio/fseeko.c
@@ -0,0 +1,290 @@
+/* $NetBSD: fseeko.c,v 1.5 2005/03/04 16:04:58 dsl Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+//#include <Uefi.h> // REMOVE, For DEBUG only
+//#include <Library/UefiLib.h> // REMOVE, For DEBUG only
+
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: fseeko.c,v 1.5 2005/03/04 16:04:58 dsl Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "reentrant.h"
+#include "local.h"
+
+#ifdef __weak_alias
+__weak_alias(fseeko, _fseeko)
+#endif
+
+#define POS_ERR (-(fpos_t)1)
+
+/*
+ * Seek the given file to the given offset.
+ * `Whence' must be one of the three SEEK_* macros.
+ */
+int
+fseeko(FILE *fp, off_t offset, int whence)
+{
+ fpos_t (*seekfn)(void *, fpos_t, int);
+ fpos_t target, curoff;
+ size_t n;
+ struct stat st;
+ int havepos;
+
+ _DIAGASSERT(fp != NULL);
+
+#ifdef __GNUC__
+ /* This outrageous construct just to shut up a GCC warning. */
+ (void) &curoff;
+#endif
+
+ /* make sure stdio is set up */
+ if (!__sdidinit)
+ __sinit();
+
+//Print(L"%a( %d, %Ld, %d)\n", __func__, fp->_file, offset, whence);
+ FLOCKFILE(fp);
+
+ /*
+ * Have to be able to seek.
+ */
+ if ((seekfn = fp->_seek) == NULL) {
+ errno = ESPIPE; /* historic practice */
+ FUNLOCKFILE(fp);
+//Print(L"%a: %d\n", __func__, __LINE__);
+ return (-1);
+ }
+
+ /*
+ * Change any SEEK_CUR to SEEK_SET, and check `whence' argument.
+ * After this, whence is either SEEK_SET or SEEK_END.
+ */
+ switch (whence) {
+
+ case SEEK_CUR:
+ /*
+ * In order to seek relative to the current stream offset,
+ * we have to first find the current stream offset a la
+ * ftell (see ftell for details).
+ */
+ __sflush(fp); /* may adjust seek offset on append stream */
+ if (fp->_flags & __SOFF)
+ curoff = fp->_offset;
+ else {
+ curoff = (*seekfn)(fp->_cookie, (fpos_t)0, SEEK_CUR);
+ if (curoff == POS_ERR) {
+ FUNLOCKFILE(fp);
+//Print(L"%a: %d\n", __func__, __LINE__);
+ return (-1);
+ }
+ }
+ if (fp->_flags & __SRD) {
+ curoff -= fp->_r;
+ if (HASUB(fp))
+ curoff -= fp->_ur;
+ } else if (fp->_flags & __SWR && fp->_p != NULL)
+ curoff += fp->_p - fp->_bf._base;
+
+ offset += curoff;
+ whence = SEEK_SET;
+ havepos = 1;
+ break;
+
+ case SEEK_SET:
+ case SEEK_END:
+ curoff = 0; /* XXX just to keep gcc quiet */
+ havepos = 0;
+ break;
+
+ default:
+ errno = EINVAL;
+ FUNLOCKFILE(fp);
+//Print(L"%a: %d\n", __func__, __LINE__);
+ return (-1);
+ }
+
+ /*
+ * Can only optimise if:
+ * reading (and not reading-and-writing);
+ * not unbuffered; and
+ * this is a `regular' Unix file (and hence seekfn==__sseek).
+ * We must check __NBF first, because it is possible to have __NBF
+ * and __SOPT both set.
+ */
+ if (fp->_bf._base == NULL)
+ __smakebuf(fp);
+ if (fp->_flags & (__SWR | __SRW | __SNBF | __SNPT))
+ goto dumb;
+ if ((fp->_flags & __SOPT) == 0) {
+ if (seekfn != __sseek ||
+ fp->_file < 0 || fstat(fp->_file, &st) ||
+ !S_ISREG(st.st_mode)) {
+ fp->_flags |= __SNPT;
+ goto dumb;
+ }
+ fp->_blksize = st.st_blksize;
+ fp->_flags |= __SOPT;
+ }
+
+ /*
+ * We are reading; we can try to optimise.
+ * Figure out where we are going and where we are now.
+ */
+ if (whence == SEEK_SET)
+ target = offset;
+ else {
+ if (fstat(fp->_file, &st))
+ {
+//Print(L"%a: %d\n", __func__, __LINE__);
+ goto dumb;
+ }
+ target = st.st_size + offset;
+ }
+
+ if (!havepos) {
+ if (fp->_flags & __SOFF)
+ curoff = fp->_offset;
+ else {
+ curoff = (*seekfn)(fp->_cookie, (fpos_t)0, SEEK_CUR);
+ if (curoff == POS_ERR)
+ {
+//Print(L"%a: %d\n", __func__, __LINE__);
+ goto dumb;
+ }
+ }
+ curoff -= fp->_r;
+ if (HASUB(fp))
+ curoff -= fp->_ur;
+ }
+
+ /*
+ * Compute the number of bytes in the input buffer (pretending
+ * that any ungetc() input has been discarded). Adjust current
+ * offset backwards by this count so that it represents the
+ * file offset for the first byte in the current input buffer.
+ */
+ if (HASUB(fp)) {
+ curoff += fp->_r; /* kill off ungetc */
+ n = fp->_up - fp->_bf._base;
+ curoff -= n;
+ n += fp->_ur;
+ } else {
+ n = fp->_p - fp->_bf._base;
+ curoff -= n;
+ n += fp->_r;
+ }
+
+ /*
+ * If the target offset is within the current buffer,
+ * simply adjust the pointers, clear EOF, undo ungetc(),
+ * and return. (If the buffer was modified, we have to
+ * skip this; see fgetln.c.)
+ */
+ if ((fp->_flags & __SMOD) == 0 &&
+ target >= curoff && target < (fpos_t)(curoff + n)) {
+ int o = (int)(target - curoff);
+
+ fp->_p = fp->_bf._base + o;
+ fp->_r = (int)(n - o);
+ if (HASUB(fp))
+ FREEUB(fp);
+ fp->_flags &= ~__SEOF;
+ FUNLOCKFILE(fp);
+ return (0);
+ }
+
+ /*
+ * The place we want to get to is not within the current buffer,
+ * but we can still be kind to the kernel copyout mechanism.
+ * By aligning the file offset to a block boundary, we can let
+ * the kernel use the VM hardware to map pages instead of
+ * copying bytes laboriously. Using a block boundary also
+ * ensures that we only read one block, rather than two.
+ */
+ curoff = target & ~(fp->_blksize - 1);
+ if ((*seekfn)(fp->_cookie, curoff, SEEK_SET) == POS_ERR)
+ {
+//Print(L"%a: %d\n", __func__, __LINE__);
+ goto dumb;
+ }
+ fp->_r = 0;
+ fp->_p = fp->_bf._base;
+ if (HASUB(fp))
+ FREEUB(fp);
+ fp->_flags &= ~__SEOF;
+ n = (int)(target - curoff);
+ if (n) {
+ if (__srefill(fp) || fp->_r < (int)n)
+ {
+//Print(L"%a: %d\n", __func__, __LINE__);
+ goto dumb;
+ }
+ fp->_p += n;
+ fp->_r -= (int)n;
+ }
+ FUNLOCKFILE(fp);
+ return (0);
+
+ /*
+ * We get here if we cannot optimise the seek ... just
+ * do it. Allow the seek function to change fp->_bf._base.
+ */
+dumb:
+//Print(L"%a: %d\n", __func__, __LINE__);
+ if (__sflush(fp) ||
+ (*seekfn)(fp->_cookie, (fpos_t)offset, whence) == POS_ERR) {
+ FUNLOCKFILE(fp);
+//Print(L"%a: %d\n", __func__, __LINE__);
+ return (-1);
+ }
+ /* success: clear EOF indicator and discard ungetc() data */
+ if (HASUB(fp))
+ FREEUB(fp);
+ fp->_p = fp->_bf._base;
+ fp->_r = 0;
+ /* fp->_w = 0; */ /* unnecessary (I think...) */
+ fp->_flags &= ~__SEOF;
+ FUNLOCKFILE(fp);
+//Print(L"%a: %d\n", __func__, __LINE__);
+ return (0);
+}
diff --git a/StdLib/LibC/Stdio/fsetpos.c b/StdLib/LibC/Stdio/fsetpos.c
new file mode 100644
index 0000000000..c8c12f4e83
--- /dev/null
+++ b/StdLib/LibC/Stdio/fsetpos.c
@@ -0,0 +1,63 @@
+/** @file
+ Implementation of fsetpos as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: fsetpos.c,v 1.10 2003/08/07 16:43:25 agc Exp
+ fsetpos.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include "namespace.h"
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+
+/*
+ * fsetpos: like fseek.
+ */
+int
+fsetpos(FILE *iop, const fpos_t *pos)
+{
+ _DIAGASSERT(iop != NULL);
+ _DIAGASSERT(pos != NULL);
+
+ return (fseeko(iop, (off_t)*pos, SEEK_SET));
+}
diff --git a/StdLib/LibC/Stdio/ftell.c b/StdLib/LibC/Stdio/ftell.c
new file mode 100644
index 0000000000..1d325e90f9
--- /dev/null
+++ b/StdLib/LibC/Stdio/ftell.c
@@ -0,0 +1,103 @@
+/** @file
+ Implementation of ftell as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: ftell.c,v 1.15 2003/08/07 16:43:25 agc Exp
+ ftell.c 8.2 (Berkeley) 5/4/95
+**/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include "reentrant.h"
+#include "local.h"
+
+/*
+ * ftell: return current offset.
+ */
+long
+ftell(FILE *fp)
+{
+ fpos_t pos;
+
+ FLOCKFILE(fp);
+
+ if (fp->_seek == NULL) {
+ FUNLOCKFILE(fp);
+ errno = ESPIPE; /* historic practice */
+ return (-1L);
+ }
+
+ /*
+ * Find offset of underlying I/O object, then
+ * adjust for buffered bytes.
+ */
+ __sflush(fp); /* may adjust seek offset on append stream */
+ if (fp->_flags & __SOFF)
+ pos = fp->_offset;
+ else {
+ pos = (*fp->_seek)(fp->_cookie, (fpos_t)0, SEEK_CUR);
+ if (pos == -1L) {
+ FUNLOCKFILE(fp);
+ return (long)(pos);
+ }
+ }
+ if (fp->_flags & __SRD) {
+ /*
+ * Reading. Any unread characters (including
+ * those from ungetc) cause the position to be
+ * smaller than that in the underlying object.
+ */
+ pos -= fp->_r;
+ if (HASUB(fp))
+ pos -= fp->_ur;
+ } else if (fp->_flags & __SWR && fp->_p != NULL) {
+ /*
+ * Writing. Any buffered characters cause the
+ * position to be greater than that in the
+ * underlying object.
+ */
+ pos += fp->_p - fp->_bf._base;
+ }
+ FUNLOCKFILE(fp);
+ return (long)(pos);
+}
diff --git a/StdLib/LibC/Stdio/ftello.c b/StdLib/LibC/Stdio/ftello.c
new file mode 100644
index 0000000000..0677d1a355
--- /dev/null
+++ b/StdLib/LibC/Stdio/ftello.c
@@ -0,0 +1,100 @@
+/* $NetBSD: ftello.c,v 1.4 2003/08/07 16:43:26 agc Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: ftello.c,v 1.4 2003/08/07 16:43:26 agc Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include "reentrant.h"
+#include "local.h"
+
+#ifdef __weak_alias
+__weak_alias(ftello, _ftello)
+#endif
+
+/*
+ * ftell: return current offset.
+ */
+off_t
+ftello(FILE *fp)
+{
+ fpos_t pos;
+
+ FLOCKFILE(fp);
+
+ if (fp->_seek == NULL) {
+ FUNLOCKFILE(fp);
+ errno = ESPIPE; /* historic practice */
+ return ((off_t)-1);
+ }
+
+ /*
+ * Find offset of underlying I/O object, then
+ * adjust for buffered bytes.
+ */
+ __sflush(fp); /* may adjust seek offset on append stream */
+ if (fp->_flags & __SOFF)
+ pos = fp->_offset;
+ else {
+ pos = (*fp->_seek)(fp->_cookie, (fpos_t)0, SEEK_CUR);
+ if (pos == (fpos_t)-1) {
+ FUNLOCKFILE(fp);
+ return (pos);
+ }
+ }
+ if (fp->_flags & __SRD) {
+ /*
+ * Reading. Any unread characters (including
+ * those from ungetc) cause the position to be
+ * smaller than that in the underlying object.
+ */
+ pos -= fp->_r;
+ if (HASUB(fp))
+ pos -= fp->_ur;
+ } else if (fp->_flags & __SWR && fp->_p != NULL) {
+ /*
+ * Writing. Any buffered characters cause the
+ * position to be greater than that in the
+ * underlying object.
+ */
+ pos += fp->_p - fp->_bf._base;
+ }
+ FUNLOCKFILE(fp);
+ return (pos);
+}
diff --git a/StdLib/LibC/Stdio/funopen.c b/StdLib/LibC/Stdio/funopen.c
new file mode 100644
index 0000000000..313af4da08
--- /dev/null
+++ b/StdLib/LibC/Stdio/funopen.c
@@ -0,0 +1,82 @@
+/* $NetBSD: funopen.c,v 1.10 2005/11/29 03:12:00 christos Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)funopen.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: funopen.c,v 1.10 2005/11/29 03:12:00 christos Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <errno.h>
+#include "reentrant.h"
+#include "local.h"
+
+FILE *
+funopen(cookie, readfn, writefn, seekfn, closefn)
+ const void *cookie;
+ int (*readfn) __P((void *, char *, int));
+ int (*writefn) __P((void *, const char *, int));
+ fpos_t (*seekfn) __P((void *, fpos_t, int));
+ int (*closefn) __P((void *));
+{
+ FILE *fp;
+ int flags;
+
+ if (readfn == NULL) {
+ if (writefn == NULL) { /* illegal */
+ errno = EINVAL;
+ return (NULL);
+ } else
+ flags = __SWR; /* write only */
+ } else {
+ if (writefn == NULL)
+ flags = __SRD; /* read only */
+ else
+ flags = __SRW; /* read-write */
+ }
+ if ((fp = __sfp()) == NULL)
+ return (NULL);
+ fp->_flags = flags;
+ fp->_file = -1;
+ fp->_cookie = __UNCONST(cookie);
+ fp->_read = readfn;
+ fp->_write = writefn;
+ fp->_seek = seekfn;
+ fp->_close = closefn;
+ return (fp);
+}
diff --git a/StdLib/LibC/Stdio/fvwrite.c b/StdLib/LibC/Stdio/fvwrite.c
new file mode 100644
index 0000000000..fcbb256067
--- /dev/null
+++ b/StdLib/LibC/Stdio/fvwrite.c
@@ -0,0 +1,221 @@
+/* $NetBSD: fvwrite.c,v 1.16.2.1 2007/05/07 19:49:09 pavel Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)fvwrite.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: fvwrite.c,v 1.16.2.1 2007/05/07 19:49:09 pavel Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "reentrant.h"
+#include "local.h"
+#include "fvwrite.h"
+
+/*
+ * Write some memory regions. Return zero on success, EOF on error.
+ *
+ * This routine is large and unsightly, but most of the ugliness due
+ * to the three different kinds of output buffering is handled here.
+ */
+int
+__sfvwrite(FILE *fp, struct __suio *uio)
+{
+ size_t len;
+ char *p;
+ struct __siov *iov;
+ int w, s;
+ char *nl;
+ int nlknown, nldist;
+
+ _DIAGASSERT(fp != NULL);
+ _DIAGASSERT(uio != NULL);
+
+ if ((len = uio->uio_resid) == 0)
+ return (0);
+ /* make sure we can write */
+ if (cantwrite(fp)) {
+ errno = EBADF;
+ return (EOF);
+ }
+
+//#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define COPY(n) (void)memcpy((void *)fp->_p, (void *)p, (size_t)(n))
+
+ iov = uio->uio_iov;
+ p = iov->iov_base;
+ len = iov->iov_len;
+ iov++;
+#define GETIOV(extra_work) \
+ while (len == 0) { \
+ extra_work; \
+ p = iov->iov_base; \
+ len = iov->iov_len; \
+ iov++; \
+ }
+ if (fp->_flags & __SNBF) {
+ /*
+ * Unbuffered: write up to BUFSIZ bytes at a time.
+ */
+ do {
+ GETIOV(;);
+ w = (*fp->_write)(fp->_cookie, p,
+ (int)MIN(len, BUFSIZ));
+ if (w <= 0)
+ goto err;
+ p += w;
+ len -= w;
+ } while ((uio->uio_resid -= w) != 0);
+ } else if ((fp->_flags & __SLBF) == 0) {
+ /*
+ * Fully buffered: fill partially full buffer, if any,
+ * and then flush. If there is no partial buffer, write
+ * one _bf._size byte chunk directly (without copying).
+ *
+ * String output is a special case: write as many bytes
+ * as fit, but pretend we wrote everything. This makes
+ * snprintf() return the number of bytes needed, rather
+ * than the number used, and avoids its write function
+ * (so that the write function can be invalid).
+ */
+ do {
+ GETIOV(;);
+ if ((fp->_flags & (__SALC | __SSTR)) ==
+ (__SALC | __SSTR) && fp->_w < (int)len) {
+ size_t blen = fp->_p - fp->_bf._base;
+ unsigned char *_base;
+ int _size;
+
+ /* Allocate space exponentially. */
+ _size = fp->_bf._size;
+ do {
+ _size = (_size << 1) + 1;
+ } while (_size < (int)(blen + len));
+ _base = realloc(fp->_bf._base,
+ (size_t)(_size + 1));
+ if (_base == NULL)
+ goto err;
+ fp->_w += _size - fp->_bf._size;
+ fp->_bf._base = _base;
+ fp->_bf._size = _size;
+ fp->_p = _base + blen;
+ }
+ w = fp->_w;
+ if (fp->_flags & __SSTR) {
+ if (len < (size_t)w)
+ w = (int)len;
+ COPY(w); /* copy MIN(fp->_w,len), */
+ fp->_w -= w;
+ fp->_p += w;
+ w = (int)len; /* but pretend copied all */
+ } else if (fp->_p > fp->_bf._base && len > (size_t)w) {
+ /* fill and flush */
+ COPY(w);
+ /* fp->_w -= w; */ /* unneeded */
+ fp->_p += w;
+ if (fflush(fp))
+ goto err;
+ } else if (len >= (size_t)(w = fp->_bf._size)) {
+ /* write directly */
+ w = (*fp->_write)(fp->_cookie, p, w);
+ if (w <= 0)
+ goto err;
+ } else {
+ /* fill and done */
+ w = (int)len;
+ COPY(w);
+ fp->_w -= w;
+ fp->_p += w;
+ }
+ p += w;
+ len -= w;
+ } while ((uio->uio_resid -= w) != 0);
+ } else {
+ /*
+ * Line buffered: like fully buffered, but we
+ * must check for newlines. Compute the distance
+ * to the first newline (including the newline),
+ * or `infinity' if there is none, then pretend
+ * that the amount to write is MIN(len,nldist).
+ */
+ nlknown = 0;
+ nldist = 0; /* XXX just to keep gcc happy */
+ do {
+ GETIOV(nlknown = 0);
+ if (!nlknown) {
+ nl = memchr((void *)p, '\n', len); // Divide the string at the first '\n'
+ nldist = (int)(nl ? nl + 1 - p : len + 1);
+ nlknown = 1;
+ }
+ s = (int)(MIN((int)len, nldist));
+ w = fp->_w + fp->_bf._size;
+ if (fp->_p > fp->_bf._base && s > w) {
+ COPY(w);
+ /* fp->_w -= w; */
+ fp->_p += w;
+ if (fflush(fp))
+ goto err;
+ } else if (s >= (w = fp->_bf._size)) {
+ w = (*fp->_write)(fp->_cookie, p, w);
+ if (w <= 0)
+ goto err;
+ } else {
+ w = s;
+ COPY(w);
+ fp->_w -= w;
+ fp->_p += w;
+ }
+ if ((nldist -= w) == 0) {
+ /* copied the newline: flush and forget */
+ if (fflush(fp))
+ goto err;
+ nlknown = 0;
+ }
+ p += w;
+ len -= w;
+ } while ((uio->uio_resid -= w) != 0);
+ }
+ return (0);
+
+err:
+ fp->_flags |= __SERR;
+ return (EOF);
+}
diff --git a/StdLib/LibC/Stdio/fvwrite.h b/StdLib/LibC/Stdio/fvwrite.h
new file mode 100644
index 0000000000..bde2b4bc50
--- /dev/null
+++ b/StdLib/LibC/Stdio/fvwrite.h
@@ -0,0 +1,50 @@
+/* $NetBSD: fvwrite.h,v 1.7 2003/08/07 16:43:26 agc Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)fvwrite.h 8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * I/O descriptors for __sfvwrite().
+ */
+struct __siov {
+ void *iov_base;
+ size_t iov_len;
+};
+struct __suio {
+ struct __siov *uio_iov;
+ int uio_iovcnt;
+ int uio_resid;
+};
+
+extern int __sfvwrite(FILE *, struct __suio *);
diff --git a/StdLib/LibC/Stdio/fwalk.c b/StdLib/LibC/Stdio/fwalk.c
new file mode 100644
index 0000000000..fcc3ef3bdf
--- /dev/null
+++ b/StdLib/LibC/Stdio/fwalk.c
@@ -0,0 +1,70 @@
+/** @file
+ Implementation of the internal fwalk function for <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: fwalk.c,v 1.11 2003/08/07 16:43:26 agc Exp
+ fwalk.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include "reentrant.h"
+#include "local.h"
+#include "glue.h"
+
+int
+_fwalk(int (*function)(FILE *))
+{
+ FILE *fp;
+ int n, ret;
+ struct glue *g;
+
+ _DIAGASSERT(function != NULL);
+
+ ret = 0;
+ for (g = &__sglue; g != NULL; g = g->next)
+ for (fp = g->iobs, n = g->niobs; --n >= 0; fp++)
+ if (fp->_flags != 0)
+ ret |= (*function)(fp);
+ return (ret);
+}
diff --git a/StdLib/LibC/Stdio/fwide.c b/StdLib/LibC/Stdio/fwide.c
new file mode 100644
index 0000000000..b89b7a3811
--- /dev/null
+++ b/StdLib/LibC/Stdio/fwide.c
@@ -0,0 +1,72 @@
+/* $NetBSD: fwide.c,v 1.3 2005/06/12 05:21:27 lukem Exp $ */
+
+/*-
+ * Copyright (c)2001 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Citrus$
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: fwide.c,v 1.3 2005/06/12 05:21:27 lukem Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <assert.h>
+#include <stdio.h>
+#include <wchar.h>
+#include "reentrant.h"
+#include "local.h"
+
+int
+fwide(FILE *fp, int mode)
+{
+ struct wchar_io_data *wcio;
+
+ _DIAGASSERT(fp != NULL);
+
+ /*
+ * this implementation use only -1, 0, 1
+ * for mode value.
+ * (we don't need to do this, but
+ * this can make things simpler.)
+ */
+ if (mode > 0)
+ mode = 1;
+ else if (mode < 0)
+ mode = -1;
+
+ FLOCKFILE(fp);
+ wcio = WCIO_GET(fp);
+ if (!wcio)
+ return 0; /* XXX */
+
+ if (wcio->wcio_mode == 0 && mode != 0)
+ wcio->wcio_mode = mode;
+ else
+ mode = wcio->wcio_mode;
+ FUNLOCKFILE(fp);
+
+ return mode;
+}
diff --git a/StdLib/LibC/Stdio/fwprintf.c b/StdLib/LibC/Stdio/fwprintf.c
new file mode 100644
index 0000000000..8f65916fa3
--- /dev/null
+++ b/StdLib/LibC/Stdio/fwprintf.c
@@ -0,0 +1,53 @@
+/* $NetBSD: fwprintf.c,v 1.1 2005/05/14 23:51:02 christos Exp $ */
+
+/*-
+ * Copyright (c) 2002 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+__FBSDID("$FreeBSD: src/lib/libc/stdio/fwprintf.c,v 1.1 2002/09/21 13:00:30 tjr Exp $");
+#else
+__RCSID("$NetBSD: fwprintf.c,v 1.1 2005/05/14 23:51:02 christos Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <wchar.h>
+
+int
+fwprintf(FILE * __restrict fp, const wchar_t * __restrict fmt, ...)
+{
+ int ret;
+ va_list ap;
+
+ va_start(ap, fmt);
+ ret = vfwprintf(fp, fmt, ap);
+ va_end(ap);
+
+ return (ret);
+}
diff --git a/StdLib/LibC/Stdio/fwrite.c b/StdLib/LibC/Stdio/fwrite.c
new file mode 100644
index 0000000000..9416e67aea
--- /dev/null
+++ b/StdLib/LibC/Stdio/fwrite.c
@@ -0,0 +1,89 @@
+/** @file
+ Implementation of fwrite as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: fwrite.c,v 1.16 2005/11/29 03:12:00 christos Exp
+ fwrite.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include "reentrant.h"
+#include "local.h"
+#include "fvwrite.h"
+
+/*
+ * Write `count' objects (each size `size') from memory to the given file.
+ * Return the number of whole objects written.
+ */
+size_t
+fwrite(const void *buf, size_t size, size_t count, FILE *fp)
+{
+ size_t n;
+ struct __suio uio;
+ struct __siov iov;
+
+ _DIAGASSERT(fp != NULL);
+ /*
+ * SUSv2 requires a return value of 0 for a count or a size of 0.
+ */
+ if ((n = count * size) == 0)
+ return (0);
+ _DIAGASSERT(buf != NULL);
+
+ iov.iov_base = __UNCONST(buf);
+ uio.uio_resid = (int)(iov.iov_len = n);
+ uio.uio_iov = &iov;
+ uio.uio_iovcnt = 1;
+
+ /*
+ * The usual case is success (__sfvwrite returns 0);
+ * skip the divide if this happens, since divides are
+ * generally slow and since this occurs whenever size==0.
+ */
+ FLOCKFILE(fp);
+ if (__sfvwrite(fp, &uio) != 0)
+ count = ((n - uio.uio_resid) / size);
+ FUNLOCKFILE(fp);
+ return (count);
+}
diff --git a/StdLib/LibC/Stdio/fwscanf.c b/StdLib/LibC/Stdio/fwscanf.c
new file mode 100644
index 0000000000..462f7d0fff
--- /dev/null
+++ b/StdLib/LibC/Stdio/fwscanf.c
@@ -0,0 +1,53 @@
+/* $NetBSD: fwscanf.c,v 1.1 2005/05/14 23:51:02 christos Exp $ */
+
+/*-
+ * Copyright (c) 2002 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+__FBSDID("$FreeBSD: src/lib/libc/stdio/fwscanf.c,v 1.1 2002/09/23 12:40:06 tjr Exp $");
+#else
+__RCSID("$NetBSD: fwscanf.c,v 1.1 2005/05/14 23:51:02 christos Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <wchar.h>
+
+int
+fwscanf(FILE * __restrict fp, const wchar_t * __restrict fmt, ...)
+{
+ va_list ap;
+ int r;
+
+ va_start(ap, fmt);
+ r = vfwscanf(fp, fmt, ap);
+ va_end(ap);
+
+ return (r);
+}
diff --git a/StdLib/LibC/Stdio/getc.c b/StdLib/LibC/Stdio/getc.c
new file mode 100644
index 0000000000..c0f367b892
--- /dev/null
+++ b/StdLib/LibC/Stdio/getc.c
@@ -0,0 +1,80 @@
+/** @file
+ Implementation of getc as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: getc.c,v 1.11 2003/08/07 16:43:26 agc Exp
+ getc.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include "reentrant.h"
+#include "local.h"
+
+/*
+ * A subroutine version of the macro getc.
+ */
+#undef getc
+#undef getc_unlocked
+
+int
+getc(FILE *fp)
+{
+ int r;
+
+ _DIAGASSERT(fp != NULL);
+
+ FLOCKFILE(fp);
+ r = __sgetc(fp);
+ FUNLOCKFILE(fp);
+ return r;
+}
+
+int
+getc_unlocked(FILE *fp)
+{
+
+ _DIAGASSERT(fp != NULL);
+
+ return (__sgetc(fp));
+}
diff --git a/StdLib/LibC/Stdio/getchar.c b/StdLib/LibC/Stdio/getchar.c
new file mode 100644
index 0000000000..d074e03924
--- /dev/null
+++ b/StdLib/LibC/Stdio/getchar.c
@@ -0,0 +1,72 @@
+/** @file
+ Implementation of a subroutine version of the macro getchar,
+ as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: getchar.c,v 1.9 2003/08/07 16:43:27 agc Exp
+ getchar.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include <stdio.h>
+#include "reentrant.h"
+#include "local.h"
+
+#undef getchar
+#undef getchar_unlocked
+
+int
+getchar( void )
+{
+ FILE *fp = stdin;
+ int r;
+
+ FLOCKFILE(fp);
+ r = __sgetc(fp);
+ FUNLOCKFILE(fp);
+ return r;
+}
+
+int
+getchar_unlocked( void )
+{
+ return (__sgetc(stdin));
+}
diff --git a/StdLib/LibC/Stdio/gets.c b/StdLib/LibC/Stdio/gets.c
new file mode 100644
index 0000000000..093fb3f743
--- /dev/null
+++ b/StdLib/LibC/Stdio/gets.c
@@ -0,0 +1,80 @@
+/** @file
+ Implementation of gets as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: gets.c,v 1.15 2003/08/07 16:43:27 agc Exp
+ gets.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include "reentrant.h"
+#include "local.h"
+
+__warn_references(gets, "warning: this program uses gets(), which is unsafe.")
+
+char *
+gets(char *buf)
+{
+ int c;
+ char *s;
+
+ _DIAGASSERT(buf != NULL);
+
+ FLOCKFILE(stdin);
+ for (s = buf; (c = getchar_unlocked()) != '\n'; ) {
+ if (c == EOF) {
+ if (s == buf) {
+ FUNLOCKFILE(stdin);
+ return (NULL);
+ } else {
+ break;
+ }
+ } else {
+ *s++ = (char)c;
+ }
+ }
+ *s = 0;
+ FUNLOCKFILE(stdin);
+ return (buf);
+}
diff --git a/StdLib/LibC/Stdio/gettemp.c b/StdLib/LibC/Stdio/gettemp.c
new file mode 100644
index 0000000000..1bd7dd3924
--- /dev/null
+++ b/StdLib/LibC/Stdio/gettemp.c
@@ -0,0 +1,183 @@
+/** @file
+ Internal function to generate temporary file name for tmpnam.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1987, 1993
+ The Regents of the University of California. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ NetBSD: gettemp.c,v 1.13 2003/12/05 00:57:36 uebayasi Exp
+**/
+#include <LibConfig.h>
+
+#if HAVE_NBTOOL_CONFIG_H
+#include "nbtool_config.h"
+#endif
+
+#if !HAVE_NBTOOL_CONFIG_H || !HAVE_MKSTEMP || !HAVE_MKDTEMP
+
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)mktemp.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: gettemp.c,v 1.13 2003/12/05 00:57:36 uebayasi Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/EfiSysCall.h>
+
+#if HAVE_NBTOOL_CONFIG_H
+#define GETTEMP gettemp
+#else
+#include "reentrant.h"
+#include "local.h"
+#define GETTEMP __gettemp
+#endif
+
+int
+GETTEMP(
+ char *path,
+ int *doopen,
+ int domkdir
+ )
+{
+ char *start, *trv;
+ struct stat sbuf;
+
+ /* To guarantee multiple calls generate unique names even if
+ the file is not created. 676 different possibilities with 7
+ or more X's, 26 with 6 or less. */
+ static char xtra[] = "aa";
+ int xcnt = 0;
+
+ _DIAGASSERT(path != NULL);
+ /* doopen may be NULL */
+
+ /* Move to end of path and count trailing X's. */
+ for (trv = path; *trv; ++trv) {
+ if (*trv == 'X') {
+ xcnt++;
+ }
+ else {
+ xcnt = 0;
+ }
+ }
+
+ /* Use at least one from xtra. Use 2 if more than 6 X's. */
+ if (*(trv - 1) == 'X')
+ *--trv = xtra[0];
+ if (xcnt > 6 && *(trv - 1) == 'X')
+ *--trv = xtra[1];
+
+ /* Set remaining X's to 0's. */
+ while (*--trv == 'X') {
+ *trv = '0';
+ }
+
+ /* update xtra for next call. */
+ if (xtra[0] != 'z')
+ xtra[0]++;
+ else {
+ xtra[0] = 'a';
+ if (xtra[1] != 'z')
+ xtra[1]++;
+ else
+ xtra[1] = 'a';
+ }
+
+ /*
+ * check the target directory; if you have six X's and it
+ * doesn't exist this runs for a *very* long time.
+ */
+ for (start = trv + 1;; --trv) {
+ if (trv <= path)
+ break;
+ if (*trv == '/') {
+ *trv = '\0';
+ if (stat(path, &sbuf))
+ return (0);
+ if (!S_ISDIR(sbuf.st_mode)) {
+ errno = ENOTDIR;
+ return (0);
+ }
+ *trv = '/';
+ break;
+ }
+ }
+
+ for (;;) {
+ if (doopen) {
+ if ((*doopen =
+ open(path, O_CREAT | O_EXCL | O_RDWR, 0600)) >= 0)
+ return (1);
+ if (errno != EEXIST)
+ return (0);
+ } else if (domkdir) {
+ if (mkdir(path, 0700) >= 0)
+ return (1);
+ if (errno != EEXIST)
+ return (0);
+ } else if (lstat(path, &sbuf))
+ return (errno == ENOENT ? 1 : 0);
+
+ /* tricky little algorithm for backward compatibility */
+ for (trv = start;;) {
+ if (!*trv)
+ return (0);
+ if (*trv == 'z') {
+ *trv++ = 'a';
+ }
+ else {
+ if (isdigit((unsigned char)*trv))
+ *trv = 'a';
+ else
+ ++*trv;
+ break;
+ }
+ }
+ }
+ /*NOTREACHED*/
+}
+
+#endif /* !HAVE_NBTOOL_CONFIG_H || !HAVE_MKSTEMP || !HAVE_MKDTEMP */
diff --git a/StdLib/LibC/Stdio/getwc.c b/StdLib/LibC/Stdio/getwc.c
new file mode 100644
index 0000000000..128ff692bc
--- /dev/null
+++ b/StdLib/LibC/Stdio/getwc.c
@@ -0,0 +1,49 @@
+/* $NetBSD: getwc.c,v 1.3 2005/06/12 05:21:27 lukem Exp $ */
+
+/*-
+ * Copyright (c)2001 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Citrus$
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: getwc.c,v 1.3 2005/06/12 05:21:27 lukem Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <wchar.h>
+
+/*
+ * A subroutine version of the macro getwc.
+ */
+#undef getwc
+
+wint_t
+getwc(FILE *fp)
+{
+
+ return fgetwc(fp);
+}
diff --git a/StdLib/LibC/Stdio/getwchar.c b/StdLib/LibC/Stdio/getwchar.c
new file mode 100644
index 0000000000..df9e86bdc1
--- /dev/null
+++ b/StdLib/LibC/Stdio/getwchar.c
@@ -0,0 +1,49 @@
+/* $NetBSD: getwchar.c,v 1.3 2005/06/12 05:21:27 lukem Exp $ */
+
+/*-
+ * Copyright (c)2001 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Citrus$
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: getwchar.c,v 1.3 2005/06/12 05:21:27 lukem Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <wchar.h>
+
+/*
+ * A subroutine version of the macro getwchar.
+ */
+#undef getwchar
+
+wint_t
+getwchar()
+{
+
+ return fgetwc(stdin);
+}
diff --git a/StdLib/LibC/Stdio/glue.h b/StdLib/LibC/Stdio/glue.h
new file mode 100644
index 0000000000..f2e8fc0db3
--- /dev/null
+++ b/StdLib/LibC/Stdio/glue.h
@@ -0,0 +1,47 @@
+/* $NetBSD: glue.h,v 1.5 2003/08/07 16:43:27 agc Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)glue.h 8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * The first few FILEs are statically allocated; others are dynamically
+ * allocated and linked in via this glue structure.
+ */
+struct glue {
+ struct glue *next;
+ int niobs;
+ FILE *iobs;
+};
+
+extern struct glue __sglue;
diff --git a/StdLib/LibC/Stdio/local.h b/StdLib/LibC/Stdio/local.h
new file mode 100644
index 0000000000..f9eaba9989
--- /dev/null
+++ b/StdLib/LibC/Stdio/local.h
@@ -0,0 +1,113 @@
+/** @file
+ Information local to this implementation of stdio,
+ in particular, function declarations and macros.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: local.h,v 1.20 2005/05/14 23:51:02 christos Exp
+ local.h 8.3 (Berkeley) 7/3/94
+**/
+
+#include "wcio.h"
+#include "fileext.h"
+
+extern int __sflush(FILE *);
+extern FILE *__sfp(void);
+extern int __srefill(FILE *);
+extern int __sread(void *, char *, int);
+extern int __swrite(void *, char const *, int);
+extern fpos_t __sseek(void *, fpos_t, int);
+extern int __sclose(void *);
+extern void __sinit(void);
+extern void _cleanup(void);
+//extern void (*__cleanup)(void); // Now in MainData.h. Ref. as gMD->cleanup
+extern void __smakebuf(FILE *);
+extern int __swhatbuf(FILE *, size_t *, int *);
+extern int _fwalk(int (*)(FILE *));
+extern char *_mktemp(char *);
+extern int __swsetup(FILE *);
+extern int __sflags(const char *, int *);
+extern int __svfscanf(FILE * __restrict, const char * __restrict, _BSD_VA_LIST_)
+ __attribute__((__format__(__scanf__, 2, 0)));
+extern int __svfscanf_unlocked(FILE * __restrict, const char * __restrict, _BSD_VA_LIST_)
+ __attribute__((__format__(__scanf__, 2, 0)));
+extern int __vfprintf_unlocked(FILE * __restrict, const char * __restrict, _BSD_VA_LIST_);
+
+
+extern int __sdidinit;
+
+extern int __gettemp(char *, int *, int);
+
+extern wint_t __fgetwc_unlock(FILE *);
+extern wint_t __fputwc_unlock(wchar_t, FILE *);
+
+extern char *__fgetstr(FILE * __restrict, size_t * __restrict, int);
+extern int __slbexpand(FILE *, size_t);
+extern int __vfwprintf_unlocked(FILE *, const wchar_t *, _BSD_VA_LIST_);
+extern int __vfwscanf_unlocked(FILE * __restrict, const wchar_t * __restrict, _BSD_VA_LIST_);
+
+/*
+ * Return true iff the given FILE cannot be written now.
+ */
+#define cantwrite(fp) \
+ ((((fp)->_flags & __SWR) == 0 || (fp)->_bf._base == NULL) && __swsetup(fp))
+
+/*
+ * Test whether the given stdio file has an active ungetc buffer;
+ * release such a buffer, without restoring ordinary unread data.
+ */
+#define HASUB(fp) (_UB(fp)._base != NULL)
+#define FREEUB(fp) { \
+ if (_UB(fp)._base != (fp)->_ubuf) \
+ free((char *)_UB(fp)._base); \
+ _UB(fp)._base = NULL; \
+ }
+
+/*
+ * test for an fgetln() buffer.
+ */
+#define HASLB(fp) ((fp)->_lb._base != NULL)
+#define FREELB(fp) { \
+ free((char *)(fp)->_lb._base); \
+ (fp)->_lb._base = NULL; \
+ }
+
+extern void __flockfile_internal (FILE *, int);
+extern void __funlockfile_internal(FILE *, int);
diff --git a/StdLib/LibC/Stdio/makebuf.c b/StdLib/LibC/Stdio/makebuf.c
new file mode 100644
index 0000000000..75c475c3a5
--- /dev/null
+++ b/StdLib/LibC/Stdio/makebuf.c
@@ -0,0 +1,132 @@
+/** @file
+ Implementation of internal file buffer allocation functions.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: makebuf.c,v 1.14 2003/08/07 16:43:28 agc Exp
+ makebuf.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include "namespace.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/EfiSysCall.h>
+#include "reentrant.h"
+#include "local.h"
+#include <MainData.h>
+
+/*
+ * Allocate a file buffer, or switch to unbuffered I/O.
+ * Per the ANSI C standard, ALL tty devices default to line buffered.
+ *
+ * As a side effect, we set __SOPT or __SNPT (en/dis-able fseek
+ * optimisation) right after the fstat() that finds the buffer size.
+ */
+void
+__smakebuf(FILE *fp)
+{
+ void *p;
+ int flags;
+ size_t size;
+ int couldbetty;
+
+ _DIAGASSERT(fp != NULL);
+
+ if (fp->_flags & __SNBF) {
+ fp->_bf._base = fp->_p = fp->_nbuf;
+ fp->_bf._size = 1;
+ return;
+ }
+ flags = __swhatbuf(fp, &size, &couldbetty);
+ if ((p = malloc(size)) == NULL) {
+ fp->_flags |= __SNBF;
+ fp->_bf._base = fp->_p = fp->_nbuf;
+ fp->_bf._size = 1;
+ return;
+ }
+ gMD->cleanup = _cleanup;
+ flags |= __SMBF;
+ fp->_bf._base = fp->_p = p;
+ fp->_bf._size = (int)size;
+ if (couldbetty || isatty(fp->_file))
+ flags |= __SLBF;
+ fp->_flags |= flags;
+}
+
+/*
+ * Internal routine to determine `proper' buffering for a file.
+ */
+int
+__swhatbuf(FILE *fp, size_t *bufsize, int *couldbetty)
+{
+ struct stat st;
+
+ _DIAGASSERT(fp != NULL);
+ _DIAGASSERT(bufsize != NULL);
+ _DIAGASSERT(couldbetty != NULL);
+
+ if (fp->_file < 0 || fstat(fp->_file, &st) < 0) {
+ *couldbetty = 0;
+ *bufsize = BUFSIZ;
+ return (__SNPT);
+ }
+
+ /* could be a tty iff it is a character device */
+ *couldbetty = S_ISCHR(st.st_mode);
+ if (st.st_blksize == 0) {
+ *bufsize = BUFSIZ;
+ return (__SNPT);
+ }
+
+ /*
+ * Optimise fseek() only if it is a regular file. (The test for
+ * __sseek is mainly paranoia.) It is safe to set _blksize
+ * unconditionally; it will only be used if __SOPT is also set.
+ */
+ *bufsize = st.st_blksize;
+ fp->_blksize = st.st_blksize;
+ return ((st.st_mode & S_IFMT) == S_IFREG && fp->_seek == __sseek ?
+ __SOPT : __SNPT);
+}
diff --git a/StdLib/LibC/Stdio/mkdtemp.c b/StdLib/LibC/Stdio/mkdtemp.c
new file mode 100644
index 0000000000..e30c2f55e0
--- /dev/null
+++ b/StdLib/LibC/Stdio/mkdtemp.c
@@ -0,0 +1,69 @@
+/* $NetBSD: mkdtemp.c,v 1.9 2003/10/27 00:12:42 lukem Exp $ */
+
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+
+#if HAVE_NBTOOL_CONFIG_H
+#include "nbtool_config.h"
+#endif
+
+#if !HAVE_NBTOOL_CONFIG_H || !HAVE_MKDTEMP
+
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)mktemp.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: mkdtemp.c,v 1.9 2003/10/27 00:12:42 lukem Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#if HAVE_NBTOOL_CONFIG_H
+#define GETTEMP gettemp
+#else
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "reentrant.h"
+#include "local.h"
+#define GETTEMP __gettemp
+#endif
+
+char *
+mkdtemp(path)
+ char *path;
+{
+ _DIAGASSERT(path != NULL);
+
+ return (GETTEMP(path, (int *)NULL, 1) ? path : (char *)NULL);
+}
+
+#endif /* !HAVE_NBTOOL_CONFIG_H || !HAVE_MKDTEMP */
diff --git a/StdLib/LibC/Stdio/mkstemp.c b/StdLib/LibC/Stdio/mkstemp.c
new file mode 100644
index 0000000000..7ea578ce4a
--- /dev/null
+++ b/StdLib/LibC/Stdio/mkstemp.c
@@ -0,0 +1,76 @@
+/* $NetBSD: mkstemp.c,v 1.9 2005/02/09 21:35:47 kleink Exp $ */
+
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+
+#if HAVE_NBTOOL_CONFIG_H
+#include "nbtool_config.h"
+#endif
+
+#if !HAVE_NBTOOL_CONFIG_H || !HAVE_MKSTEMP
+
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)mktemp.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: mkstemp.c,v 1.9 2005/02/09 21:35:47 kleink Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+
+#if HAVE_NBTOOL_CONFIG_H
+#define GETTEMP gettemp
+#else
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "reentrant.h"
+#include "local.h"
+#define GETTEMP __gettemp
+#endif
+
+#ifdef __weak_alias
+__weak_alias(mkstemp,_mkstemp)
+#endif
+
+int
+mkstemp(char *path)
+{
+ int fd;
+
+ _DIAGASSERT(path != NULL);
+
+ return (GETTEMP(path, &fd, 0) ? fd : -1);
+}
+
+#endif /* !HAVE_NBTOOL_CONFIG_H || !HAVE_MKSTEMP */
diff --git a/StdLib/LibC/Stdio/mktemp.c b/StdLib/LibC/Stdio/mktemp.c
new file mode 100644
index 0000000000..4c9e4752cc
--- /dev/null
+++ b/StdLib/LibC/Stdio/mktemp.c
@@ -0,0 +1,71 @@
+/** @file
+ Internal function for tmpnam.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+NetBSD: mktemp.c,v 1.19 2003/08/07 16:43:28 agc Exp
+mktemp.c 8.1 (Berkeley) 6/4/93
+ **/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/EfiSysCall.h>
+#include "reentrant.h"
+#include "local.h"
+
+char *
+_mktemp(char *path)
+{
+ _DIAGASSERT(path != NULL);
+
+ return (__gettemp(path, (int *)NULL, 0) ? path : (char *)NULL);
+}
+
+__warn_references(mktemp,
+ "warning: mktemp() possibly used unsafely, use mkstemp() or mkdtemp()")
+
+char *
+mktemp(char *path)
+{
+
+ _DIAGASSERT(path != NULL);
+
+ return (__gettemp(path, (int *)NULL, 0) ? path : (char *)NULL);
+}
diff --git a/StdLib/LibC/Stdio/perror.c b/StdLib/LibC/Stdio/perror.c
new file mode 100644
index 0000000000..b34cd4c479
--- /dev/null
+++ b/StdLib/LibC/Stdio/perror.c
@@ -0,0 +1,72 @@
+/** @file
+ Implementation of perror as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Portions Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: perror.c,v 1.24 2006/01/26 11:13:42 kleink Exp
+ perror.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include "namespace.h"
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include "extern.h"
+
+/*
+ * Since perror() is not allowed to change the contents of strerror()'s
+ * static buffer, both functions supply their own buffers to strerror_r().
+ */
+
+void
+perror(const char *s)
+{
+ static char buf[ASCII_STRING_MAX];
+ const char *separator;
+
+ if (s == NULL)
+ s = "";
+ if (*s == '\0')
+ separator = "";
+ else
+ separator = ": ";
+
+ (void)strerror_r(errno, buf, sizeof(buf));
+ (void)fprintf(stderr, "%s%s%s\n", s, separator, buf);
+}
diff --git a/StdLib/LibC/Stdio/printf.c b/StdLib/LibC/Stdio/printf.c
new file mode 100644
index 0000000000..2a36757b08
--- /dev/null
+++ b/StdLib/LibC/Stdio/printf.c
@@ -0,0 +1,63 @@
+/** @file
+ Implementation of printf as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: printf.c,v 1.11 2003/08/07 16:43:29 agc Exp
+ printf.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+int
+printf(char const *fmt, ...)
+{
+ int ret;
+ va_list ap;
+
+ va_start(ap, fmt);
+ ret = vfprintf(stdout, fmt, ap);
+ va_end(ap);
+ return (ret);
+}
diff --git a/StdLib/LibC/Stdio/putc.c b/StdLib/LibC/Stdio/putc.c
new file mode 100644
index 0000000000..891e747a56
--- /dev/null
+++ b/StdLib/LibC/Stdio/putc.c
@@ -0,0 +1,80 @@
+/** @file
+ Implementation of a subroutine version of the macro putc,
+ as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: putc.c,v 1.11 2003/08/07 16:43:29 agc Exp
+ putc.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include "reentrant.h"
+#include "local.h"
+
+/*
+ * putc.
+ */
+#undef putc
+#undef putc_unlocked
+
+int
+putc(int c, FILE *fp)
+{
+ int r;
+
+ _DIAGASSERT(fp != NULL);
+
+ FLOCKFILE(fp);
+ r = __sputc(c, fp);
+ FUNLOCKFILE(fp);
+ return r;
+}
+
+int
+putc_unlocked(int c, FILE *fp)
+{
+ _DIAGASSERT(fp != NULL);
+
+ return (__sputc(c, fp));
+}
diff --git a/StdLib/LibC/Stdio/putchar.c b/StdLib/LibC/Stdio/putchar.c
new file mode 100644
index 0000000000..ac6edc888b
--- /dev/null
+++ b/StdLib/LibC/Stdio/putchar.c
@@ -0,0 +1,75 @@
+/** @file
+ Implementation of a subroutine version of the macro putchar,
+ as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: putchar.c,v 1.9 2003/08/07 16:43:29 agc Exp
+ putchar.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include <stdio.h>
+#include "reentrant.h"
+#include "local.h"
+
+#undef putchar
+#undef putchar_unlocked
+
+/*
+ * putchar
+ */
+int
+putchar(int c)
+{
+ FILE *fp = stdout;
+ int r;
+
+ FLOCKFILE(fp);
+ r = __sputc(c, fp);
+ FUNLOCKFILE(fp);
+ return r;
+}
+
+int
+putchar_unlocked(int c)
+{
+ return (__sputc(c, stdout));
+}
diff --git a/StdLib/LibC/Stdio/puts.c b/StdLib/LibC/Stdio/puts.c
new file mode 100644
index 0000000000..3585bb7f06
--- /dev/null
+++ b/StdLib/LibC/Stdio/puts.c
@@ -0,0 +1,85 @@
+/** @file
+ Implementation of puts as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: puts.c,v 1.15 2006/03/17 02:25:23 chris Exp
+ puts.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include "fvwrite.h"
+#include "reentrant.h"
+#include "local.h"
+
+/*
+ * Write the given string to stdout, appending a newline.
+ */
+int
+puts(char const *s)
+{
+ size_t c;
+ struct __suio uio;
+ struct __siov iov[2];
+ int r;
+
+ _DIAGASSERT(s != NULL);
+
+ if (s == NULL)
+ s = "(null)";
+
+ c = strlen(s);
+
+ iov[0].iov_base = __UNCONST(s);
+ iov[0].iov_len = c;
+ iov[1].iov_base = __UNCONST("\n");
+ iov[1].iov_len = 1;
+ uio.uio_resid = (int)(c + 1);
+ uio.uio_iov = &iov[0];
+ uio.uio_iovcnt = 2;
+ FLOCKFILE(stdout);
+ r = __sfvwrite(stdout, &uio);
+ FUNLOCKFILE(stdout);
+ return (r ? EOF : '\n');
+}
diff --git a/StdLib/LibC/Stdio/putwc.c b/StdLib/LibC/Stdio/putwc.c
new file mode 100644
index 0000000000..84354f1d92
--- /dev/null
+++ b/StdLib/LibC/Stdio/putwc.c
@@ -0,0 +1,49 @@
+/* $NetBSD: putwc.c,v 1.4 2005/06/12 05:21:27 lukem Exp $ */
+
+/*-
+ * Copyright (c)2001 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Citrus$
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: putwc.c,v 1.4 2005/06/12 05:21:27 lukem Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <wchar.h>
+
+/*
+ * A subroutine version of the macro putwc.
+ */
+#undef putwc
+
+wint_t
+putwc(wchar_t wc, FILE *fp)
+{
+
+ return fputwc(wc, fp);
+}
diff --git a/StdLib/LibC/Stdio/putwchar.c b/StdLib/LibC/Stdio/putwchar.c
new file mode 100644
index 0000000000..8bf91c5a88
--- /dev/null
+++ b/StdLib/LibC/Stdio/putwchar.c
@@ -0,0 +1,49 @@
+/* $NetBSD: putwchar.c,v 1.4 2005/06/12 05:21:27 lukem Exp $ */
+
+/*-
+ * Copyright (c)2001 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Citrus$
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: putwchar.c,v 1.4 2005/06/12 05:21:27 lukem Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <wchar.h>
+
+/*
+ * A subroutine version of the macro putwchar.
+ */
+#undef putwchar
+
+wint_t
+putwchar(wchar_t wc)
+{
+
+ return fputwc(wc, stdout);
+}
diff --git a/StdLib/LibC/Stdio/refill.c b/StdLib/LibC/Stdio/refill.c
new file mode 100644
index 0000000000..e2d162375b
--- /dev/null
+++ b/StdLib/LibC/Stdio/refill.c
@@ -0,0 +1,162 @@
+/* $NetBSD: refill.c,v 1.13 2003/08/07 16:43:30 agc Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <Uefi.h> // REMOVE, For DEBUG only
+#include <Library/UefiLib.h> // REMOVE, For DEBUG only
+
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)refill.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: refill.c,v 1.13 2003/08/07 16:43:30 agc Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "reentrant.h"
+#include "local.h"
+
+#ifdef _REENTRANT
+extern rwlock_t __sfp_lock;
+#endif
+
+static int lflush(FILE *);
+
+static int
+lflush(FILE *fp)
+{
+
+ //_DIAGASSERT(fp != NULL);
+
+ if ((fp->_flags & (__SLBF|__SWR)) == (__SLBF|__SWR))
+ return (__sflush(fp));
+ return (0);
+}
+
+/*
+ * Refill a stdio buffer.
+ * Return EOF on eof or error, 0 otherwise.
+ */
+int
+__srefill(FILE *fp)
+{
+
+ //_DIAGASSERT(fp != NULL);
+
+ /* make sure stdio is set up */
+ if (!__sdidinit)
+ __sinit();
+
+//Print(L"%a( %d)\n", __func__, fp->_file);
+ fp->_r = 0; /* largely a convenience for callers */
+
+ /* SysV does not make this test; take it out for compatibility */
+ if (fp->_flags & __SEOF) {
+//Print(L"%a: %d\n", __func__, __LINE__);
+ return (EOF);
+ }
+
+ /* if not already reading, have to be reading and writing */
+ if ((fp->_flags & __SRD) == 0) {
+//Print(L"%a: %d\n", __func__, __LINE__);
+ if ((fp->_flags & __SRW) == 0) {
+ errno = EBADF;
+ fp->_flags |= __SERR; //<dvm> Allows differentiation between errors and EOF
+//Print(L"%a: %d\n", __func__, __LINE__);
+ return (EOF);
+ }
+ /* switch to reading */
+ if (fp->_flags & __SWR) {
+ if (__sflush(fp)) {
+//Print(L"%a: %d\n", __func__, __LINE__);
+ return (EOF);
+ }
+ fp->_flags &= ~__SWR;
+ fp->_w = 0;
+ fp->_lbfsize = 0;
+ }
+ fp->_flags |= __SRD;
+ } else {
+//Print(L"%a: %d\n", __func__, __LINE__);
+ /*
+ * We were reading. If there is an ungetc buffer,
+ * we must have been reading from that. Drop it,
+ * restoring the previous buffer (if any). If there
+ * is anything in that buffer, return.
+ */
+ if (HASUB(fp)) {
+ FREEUB(fp);
+ if ((fp->_r = fp->_ur) != 0) {
+ fp->_p = fp->_up;
+//Print(L"%a: %d\n", __func__, __LINE__);
+ return (0);
+ }
+ }
+ }
+
+ if (fp->_bf._base == NULL)
+ __smakebuf(fp);
+
+//Print(L"%a: %d\n", __func__, __LINE__);
+ /*
+ * Before reading from a line buffered or unbuffered file,
+ * flush all line buffered output files, per the ANSI C
+ * standard.
+ */
+ if (fp->_flags & (__SLBF|__SNBF)) {
+ rwlock_rdlock(&__sfp_lock);
+ (void) _fwalk(lflush);
+ rwlock_unlock(&__sfp_lock);
+//Print(L"%a: %d\n", __func__, __LINE__);
+ }
+ fp->_p = fp->_bf._base;
+ fp->_r = (*fp->_read)(fp->_cookie, (char *)fp->_p, fp->_bf._size);
+ fp->_flags &= ~__SMOD; /* buffer contents are again pristine */
+ if (fp->_r <= 0) {
+ if (fp->_r == 0)
+ fp->_flags |= __SEOF;
+ else {
+ fp->_r = 0;
+ fp->_flags |= __SERR;
+ }
+//Print(L"%a: %d\n", __func__, __LINE__);
+ return (EOF);
+ }
+//Print(L"%a: %d\n", __func__, __LINE__);
+ return (0);
+}
diff --git a/StdLib/LibC/Stdio/remove.c b/StdLib/LibC/Stdio/remove.c
new file mode 100644
index 0000000000..826471cde5
--- /dev/null
+++ b/StdLib/LibC/Stdio/remove.c
@@ -0,0 +1,70 @@
+/* $NetBSD: remove.c,v 1.13 2003/08/07 16:43:30 agc Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)remove.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: remove.c,v 1.13 2003/08/07 16:43:30 agc Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <sys/EfiSysCall.h>
+
+int
+remove(const char *file)
+{
+ struct stat sb;
+
+ _DIAGASSERT(file != NULL);
+
+ if (lstat(file, &sb) < 0)
+ return (-1);
+
+ /*
+ * The file system may prohibit using unlink(2) on directories,
+ * so always use rmdir(2) in that case.
+ */
+ if (S_ISDIR(sb.st_mode))
+ return (rmdir(file));
+ else
+ return (unlink(file));
+}
diff --git a/StdLib/LibC/Stdio/rewind.c b/StdLib/LibC/Stdio/rewind.c
new file mode 100644
index 0000000000..4f2ab041a2
--- /dev/null
+++ b/StdLib/LibC/Stdio/rewind.c
@@ -0,0 +1,63 @@
+/** @file
+ Implementation of rewind as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: rewind.c,v 1.13 2003/08/07 16:43:30 agc Exp
+ rewind.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include "reentrant.h"
+#include "local.h"
+
+void
+rewind(FILE *fp)
+{
+ _DIAGASSERT(fp != NULL);
+
+ FLOCKFILE(fp);
+ (void) fseek(fp, 0L, SEEK_SET);
+ __sclearerr(fp);
+ FUNLOCKFILE(fp);
+}
diff --git a/StdLib/LibC/Stdio/rget.c b/StdLib/LibC/Stdio/rget.c
new file mode 100644
index 0000000000..ba97ac201b
--- /dev/null
+++ b/StdLib/LibC/Stdio/rget.c
@@ -0,0 +1,70 @@
+/** @file
+ Internal function to refill the buffer when getc() empties it.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: rget.c,v 1.12 2003/08/07 16:43:30 agc Exp
+ rget.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include "reentrant.h"
+#include "local.h"
+
+/*
+ * Handle getc() when the buffer ran out:
+ * Refill, then return the first character
+ * in the newly-filled buffer.
+ */
+int
+__srget(FILE *fp)
+{
+ _DIAGASSERT(fp != NULL);
+
+ _SET_ORIENTATION(fp, -1);
+ if (__srefill(fp) == 0) {
+ fp->_r--;
+ return (*fp->_p++);
+ }
+ return (EOF);
+}
diff --git a/StdLib/LibC/Stdio/scanf.c b/StdLib/LibC/Stdio/scanf.c
new file mode 100644
index 0000000000..1962fbaf74
--- /dev/null
+++ b/StdLib/LibC/Stdio/scanf.c
@@ -0,0 +1,64 @@
+/* $NetBSD: scanf.c,v 1.12 2003/08/07 16:43:31 agc Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)scanf.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: scanf.c,v 1.12 2003/08/07 16:43:31 agc Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "reentrant.h"
+#include "local.h"
+
+int
+scanf(char const *fmt, ...)
+{
+ int ret;
+ va_list ap;
+
+ _DIAGASSERT(fmt != NULL);
+
+ va_start(ap, fmt);
+ ret = __svfscanf(stdin, fmt, ap);
+ va_end(ap);
+ return (ret);
+}
diff --git a/StdLib/LibC/Stdio/setbuf.c b/StdLib/LibC/Stdio/setbuf.c
new file mode 100644
index 0000000000..7484832d50
--- /dev/null
+++ b/StdLib/LibC/Stdio/setbuf.c
@@ -0,0 +1,63 @@
+/** @file
+ Implementation of setbuf as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: setbuf.c,v 1.9 2003/08/07 16:43:31 agc Exp
+ setbuf.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include "reentrant.h"
+#include "local.h"
+
+void
+setbuf(FILE *fp, char *buf)
+{
+
+ _DIAGASSERT(fp != NULL);
+ /* buf may be NULL */
+
+ (void) setvbuf(fp, buf, buf ? _IOFBF : _IONBF, BUFSIZ);
+}
diff --git a/StdLib/LibC/Stdio/setbuffer.c b/StdLib/LibC/Stdio/setbuffer.c
new file mode 100644
index 0000000000..9527a4b3f6
--- /dev/null
+++ b/StdLib/LibC/Stdio/setbuffer.c
@@ -0,0 +1,72 @@
+/* $NetBSD: setbuffer.c,v 1.10 2003/08/07 16:43:31 agc Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)setbuffer.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: setbuffer.c,v 1.10 2003/08/07 16:43:31 agc Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+
+void
+setbuffer(fp, buf, size)
+ FILE *fp;
+ char *buf;
+ int size;
+{
+
+ _DIAGASSERT(fp != NULL);
+ /* buf may be NULL */
+
+ (void)setvbuf(fp, buf, buf ? _IOFBF : _IONBF, (size_t)size);
+}
+
+/*
+ * set line buffering
+ */
+int
+setlinebuf(fp)
+ FILE *fp;
+{
+
+ _DIAGASSERT(fp != NULL);
+
+ return (setvbuf(fp, (char *)NULL, _IOLBF, (size_t)0));
+}
diff --git a/StdLib/LibC/Stdio/setvbuf.c b/StdLib/LibC/Stdio/setvbuf.c
new file mode 100644
index 0000000000..3ea96ff6da
--- /dev/null
+++ b/StdLib/LibC/Stdio/setvbuf.c
@@ -0,0 +1,176 @@
+/** @file
+ Implementation of setvbuf as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: setvbuf.c,v 1.17 2003/08/07 16:43:31 agc Exp
+ setvbuf.c 8.2 (Berkeley) 11/16/93
+**/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include "reentrant.h"
+#include "local.h"
+#include <MainData.h>
+
+/*
+ * Set one of the three kinds of buffering, optionally including
+ * a buffer.
+ */
+int
+setvbuf(FILE *fp, char *buf, int mode, size_t size)
+{
+ int ret, flags;
+ size_t iosize;
+ int ttyflag;
+
+ _DIAGASSERT(fp != NULL);
+ /* buf may be NULL */
+
+ /*
+ * Verify arguments. The `int' limit on `size' is due to this
+ * particular implementation. Note, buf and size are ignored
+ * when setting _IONBF.
+ */
+ if (mode != _IONBF)
+ if ((mode != _IOFBF && mode != _IOLBF) || (int)size < 0)
+ return (-1);
+
+ FLOCKFILE(fp);
+ /*
+ * Write current buffer, if any. Discard unread input (including
+ * ungetc data), cancel line buffering, and free old buffer if
+ * malloc()ed. We also clear any eof condition, as if this were
+ * a seek.
+ */
+ ret = 0;
+ (void)__sflush(fp);
+ if (HASUB(fp))
+ FREEUB(fp);
+ WCIO_FREE(fp);
+ fp->_r = fp->_lbfsize = 0;
+ flags = fp->_flags;
+ if (flags & __SMBF)
+ free((void *)fp->_bf._base);
+ flags &= ~(__SLBF | __SNBF | __SMBF | __SOPT | __SNPT | __SEOF);
+
+ /* If setting unbuffered mode, skip all the hard work. */
+ if (mode == _IONBF)
+ goto nbf;
+
+ /*
+ * Find optimal I/O size for seek optimization. This also returns
+ * a `tty flag' to suggest that we check isatty(fd), but we do not
+ * care since our caller told us how to buffer.
+ */
+ flags |= __swhatbuf(fp, &iosize, &ttyflag);
+ if (size == 0) {
+ buf = NULL; /* force local allocation */
+ size = iosize;
+ }
+
+ /* Allocate buffer if needed. */
+ if (buf == NULL) {
+ if ((buf = malloc(size)) == NULL) {
+ /*
+ * Unable to honor user's request. We will return
+ * failure, but try again with file system size.
+ */
+ ret = -1;
+ if (size != iosize) {
+ size = iosize;
+ buf = malloc(size);
+ }
+ }
+ if (buf == NULL) {
+ /* No luck; switch to unbuffered I/O. */
+nbf:
+ fp->_flags = (unsigned short)(flags | __SNBF);
+ fp->_w = 0;
+ fp->_bf._base = fp->_p = fp->_nbuf;
+ fp->_bf._size = 1;
+ FUNLOCKFILE(fp);
+ return (ret);
+ }
+ flags |= __SMBF;
+ }
+
+ /*
+ * Kill any seek optimization if the buffer is not the
+ * right size.
+ *
+ * SHOULD WE ALLOW MULTIPLES HERE (i.e., ok iff (size % iosize) == 0)?
+ */
+ if (size != iosize)
+ flags |= __SNPT;
+
+ /*
+ * Fix up the FILE fields, and set gMD->cleanup for output flush on
+ * exit (since we are buffered in some way).
+ */
+ if (mode == _IOLBF)
+ flags |= __SLBF;
+ fp->_flags = (unsigned short)flags;
+ fp->_bf._base = fp->_p = (unsigned char *)buf;
+ fp->_bf._size = (int)size;
+ /* fp->_lbfsize is still 0 */
+ if (flags & __SWR) {
+ /*
+ * Begin or continue writing: see __swsetup(). Note
+ * that __SNBF is impossible (it was handled earlier).
+ */
+ if (flags & __SLBF) {
+ fp->_w = 0;
+ fp->_lbfsize = -fp->_bf._size;
+ } else
+ fp->_w = (int)size;
+ } else {
+ /* begin/continue reading, or stay in intermediate state */
+ fp->_w = 0;
+ }
+ gMD->cleanup = _cleanup;
+
+ FUNLOCKFILE(fp);
+ return (ret);
+}
diff --git a/StdLib/LibC/Stdio/snprintf.c b/StdLib/LibC/Stdio/snprintf.c
new file mode 100644
index 0000000000..c92641508c
--- /dev/null
+++ b/StdLib/LibC/Stdio/snprintf.c
@@ -0,0 +1,93 @@
+/** @file
+ Implementation of internal snprintf function for <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: snprintf.c,v 1.20 2005/02/09 21:35:47 kleink Exp
+ snprintf.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include "namespace.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "reentrant.h"
+#include "local.h"
+
+#ifdef __weak_alias
+__weak_alias(snprintf,_snprintf)
+#endif
+
+int
+snprintf(char *str, size_t n, char const *fmt, ...)
+{
+ int ret;
+ va_list ap;
+ FILE f;
+ struct __sfileext fext;
+ unsigned char dummy[1];
+
+ _DIAGASSERT(n == 0 || str != NULL);
+ _DIAGASSERT(fmt != NULL);
+
+ if ((int)n < 0) {
+ errno = EINVAL;
+ return (-1);
+ }
+ va_start(ap, fmt);
+ _FILEEXT_SETUP(&f, &fext);
+ f._file = -1;
+ f._flags = __SWR | __SSTR;
+ if (n == 0) {
+ f._bf._base = f._p = dummy;
+ f._bf._size = f._w = 0;
+ } else {
+ f._bf._base = f._p = (unsigned char *)str;
+ f._bf._size = f._w = (int)(n - 1);
+ }
+ ret = __vfprintf_unlocked(&f, fmt, ap);
+ *f._p = 0;
+ va_end(ap);
+ return (ret);
+}
diff --git a/StdLib/LibC/Stdio/snprintf_ss.c b/StdLib/LibC/Stdio/snprintf_ss.c
new file mode 100644
index 0000000000..e5047b15ab
--- /dev/null
+++ b/StdLib/LibC/Stdio/snprintf_ss.c
@@ -0,0 +1,69 @@
+/* $NetBSD: snprintf_ss.c,v 1.3.2.1 2007/05/07 19:49:08 pavel Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)snprintf.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: snprintf_ss.c,v 1.3.2.1 2007/05/07 19:49:08 pavel Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "reentrant.h"
+#include "extern.h"
+#include "local.h"
+
+#ifdef __weak_alias
+__weak_alias(snprintf_ss,_snprintf_ss)
+#endif
+
+int
+snprintf_ss(char *str, size_t n, char const *fmt, ...)
+{
+ va_list ap;
+ int ret;
+
+ va_start(ap, fmt);
+ ret = vsnprintf_ss(str, n, fmt, ap);
+ va_end(ap);
+ return ret;
+}
diff --git a/StdLib/LibC/Stdio/sprintf.c b/StdLib/LibC/Stdio/sprintf.c
new file mode 100644
index 0000000000..6861b4355e
--- /dev/null
+++ b/StdLib/LibC/Stdio/sprintf.c
@@ -0,0 +1,78 @@
+/** @file
+ Implementation of sprintf as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: sprintf.c,v 1.14 2005/02/09 21:35:47 kleink Exp
+ sprintf.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "reentrant.h"
+#include "local.h"
+
+int
+sprintf(char *str, char const *fmt, ...)
+{
+ int ret;
+ va_list ap;
+ FILE f;
+ struct __sfileext fext;
+
+ _DIAGASSERT(str != NULL);
+ _DIAGASSERT(fmt != NULL);
+
+ _FILEEXT_SETUP(&f, &fext);
+ f._file = -1;
+ f._flags = __SWR | __SSTR;
+ f._bf._base = f._p = (unsigned char *)str;
+ f._bf._size = f._w = INT_MAX;
+ va_start(ap, fmt);
+ ret = __vfprintf_unlocked(&f, fmt, ap);
+ va_end(ap);
+ *f._p = 0;
+ return (ret);
+}
diff --git a/StdLib/LibC/Stdio/sscanf.c b/StdLib/LibC/Stdio/sscanf.c
new file mode 100644
index 0000000000..c9fb87aaa5
--- /dev/null
+++ b/StdLib/LibC/Stdio/sscanf.c
@@ -0,0 +1,89 @@
+/** @file
+ Implementation of sscanf as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: sscanf.c,v 1.16 2005/11/29 03:12:00 christos Exp
+ sscanf.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "reentrant.h"
+#include "local.h"
+
+static int eofread(void *, char *, int);
+
+/* ARGSUSED */
+static int
+eofread(void *cookie, char *buf, int len)
+{
+
+ return (0);
+}
+
+int
+sscanf(const char *str, char const *fmt, ...)
+{
+ int ret;
+ va_list ap;
+ FILE f;
+ struct __sfileext fext;
+
+ _DIAGASSERT(str != NULL);
+ _DIAGASSERT(fmt != NULL);
+
+ _FILEEXT_SETUP(&f, &fext);
+ f._flags = __SRD;
+ f._bf._base = f._p = __UNCONST(str);
+ f._bf._size = f._r = (int)strlen(str);
+ f._read = eofread;
+ _UB(&f)._base = NULL;
+ f._lb._base = NULL;
+ va_start(ap, fmt);
+ ret = __svfscanf_unlocked(&f, fmt, ap);
+ va_end(ap);
+ return (ret);
+}
diff --git a/StdLib/LibC/Stdio/stdio.c b/StdLib/LibC/Stdio/stdio.c
new file mode 100644
index 0000000000..005a4388df
--- /dev/null
+++ b/StdLib/LibC/Stdio/stdio.c
@@ -0,0 +1,117 @@
+/** @file
+ Small standard I/O/seek/close functions.
+ These maintain the `known seek offset' for seek optimisation.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: stdio.c,v 1.13 2003/08/07 16:43:33 agc Exp
+ stdio.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include "namespace.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/EfiSysCall.h>
+
+#include "reentrant.h"
+#include "local.h"
+
+int
+__sread(void *cookie, char *buf, int n)
+{
+ FILE *fp = cookie;
+ int ret;
+
+ _DIAGASSERT(fp != NULL);
+ _DIAGASSERT(buf != NULL);
+
+ ret = (int)read(fp->_file, buf, (size_t)n);
+ /* if the read succeeded, update the current offset */
+ if (ret >= 0)
+ fp->_offset += ret;
+ else
+ fp->_flags &= ~__SOFF; /* paranoia */
+ return (ret);
+}
+
+int
+__swrite(void *cookie, char const *buf, int n)
+{
+ FILE *fp = cookie;
+
+ _DIAGASSERT(cookie != NULL);
+ _DIAGASSERT(buf != NULL);
+
+ if (fp->_flags & __SAPP)
+ (void) lseek(fp->_file, (off_t)0, SEEK_END);
+ fp->_flags &= ~__SOFF; /* in case FAPPEND mode is set */
+ return (int)(write(fp->_file, (char *)buf, (size_t)n));
+}
+
+fpos_t
+__sseek(void *cookie, fpos_t offset, int whence)
+{
+ FILE *fp = cookie;
+ off_t ret;
+
+ _DIAGASSERT(fp != NULL);
+
+ ret = lseek(fp->_file, (off_t)offset, whence);
+ if (ret == -1L)
+ fp->_flags &= ~__SOFF;
+ else {
+ fp->_flags |= __SOFF;
+ fp->_offset = ret;
+ }
+ return (ret);
+}
+
+int
+__sclose(void *cookie)
+{
+
+ _DIAGASSERT(cookie != NULL);
+
+ return (close(((FILE *)cookie)->_file));
+}
diff --git a/StdLib/LibC/Stdio/swprintf.c b/StdLib/LibC/Stdio/swprintf.c
new file mode 100644
index 0000000000..d0f05612f6
--- /dev/null
+++ b/StdLib/LibC/Stdio/swprintf.c
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 2002 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+
+ FreeBSD: src/lib/libc/stdio/swprintf.c,v 1.1 2002/09/21 13:00:30 tjr Exp
+ NetBSD: swprintf.c,v 1.1 2005/05/14 23:51:02 christos Exp
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <wchar.h>
+
+int
+swprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt, ...)
+{
+ int ret;
+ va_list ap;
+
+ va_start(ap, fmt);
+ ret = vswprintf(s, n, fmt, ap);
+ va_end(ap);
+
+ return (ret);
+}
diff --git a/StdLib/LibC/Stdio/swscanf.c b/StdLib/LibC/Stdio/swscanf.c
new file mode 100644
index 0000000000..03b90e827a
--- /dev/null
+++ b/StdLib/LibC/Stdio/swscanf.c
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 2002 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+
+ FreeBSD: src/lib/libc/stdio/swscanf.c,v 1.1 2002/09/23 12:40:06 tjr Exp
+ NetBSD: swscanf.c,v 1.1 2005/05/14 23:51:02 christos Exp
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <wchar.h>
+
+int
+swscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt, ...)
+{
+ va_list ap;
+ int r;
+
+ va_start(ap, fmt);
+ r = vswscanf(str, fmt, ap);
+ va_end(ap);
+
+ return (r);
+}
diff --git a/StdLib/LibC/Stdio/tempnam.c b/StdLib/LibC/Stdio/tempnam.c
new file mode 100644
index 0000000000..368da844d0
--- /dev/null
+++ b/StdLib/LibC/Stdio/tempnam.c
@@ -0,0 +1,102 @@
+/* $NetBSD: tempnam.c,v 1.19 2005/07/27 13:23:07 drochner Exp $ */
+
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)tempnam.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: tempnam.c,v 1.19 2005/07/27 13:23:07 drochner Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+#include <sys/param.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/EfiSysCall.h>
+#include <paths.h>
+#include "reentrant.h"
+#include "local.h"
+
+__warn_references(tempnam,
+ "warning: tempnam() possibly used unsafely, use mkstemp() or mkdtemp()")
+
+static const char *
+trailsl(const char *f)
+{
+ const char *s = f;
+ while (*s)
+ s++;
+ return (f != s && s[-1] == '/') ? "" : "/";
+}
+
+static char *
+gentemp(char *name, size_t len, const char *tmp, const char *pfx)
+{
+ (void)snprintf(name, len, "%s%s%sXXXX", tmp, trailsl(tmp), pfx);
+ return _mktemp(name);
+}
+
+char *
+tempnam(const char *dir, const char *pfx)
+{
+ int sverrno;
+ char *name, *f;
+ const char *tmp;
+
+ if (!(name = malloc((size_t)MAXPATHLEN)))
+ return NULL;
+
+ if (!pfx)
+ pfx = "tmp.";
+
+ if ((tmp = getenv("TMPDIR")) != NULL &&
+ (f = gentemp(name, (size_t)MAXPATHLEN, tmp, pfx)) != NULL)
+ return f;
+
+ if (dir != NULL &&
+ (f = gentemp(name, (size_t)MAXPATHLEN, dir, pfx)) != NULL)
+ return f;
+
+ //if ((f = gentemp(name, (size_t)MAXPATHLEN, P_tmpdir, pfx)) != NULL)
+ // return f;
+
+ if ((f = gentemp(name, (size_t)MAXPATHLEN, _PATH_TMP, pfx)) != NULL)
+ return f;
+
+ sverrno = errno;
+ free(name);
+ errno = sverrno;
+ return(NULL);
+}
diff --git a/StdLib/LibC/Stdio/tmpfile.c b/StdLib/LibC/Stdio/tmpfile.c
new file mode 100644
index 0000000000..bfcf77c49d
--- /dev/null
+++ b/StdLib/LibC/Stdio/tmpfile.c
@@ -0,0 +1,86 @@
+/* $NetBSD: tmpfile.c,v 1.11 2003/08/07 16:43:33 agc Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)tmpfile.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: tmpfile.c,v 1.11 2003/08/07 16:43:33 agc Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+#include <sys/types.h>
+#include <sys/EfiSysCall.h>
+#include <signal.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <paths.h>
+
+#define TRAILER "tmp.XXXX"
+
+FILE *
+tmpfile()
+{
+ //sigset_t set, oset;
+ FILE *fp;
+ int fd, sverrno;
+ char buf[sizeof(_PATH_TMP) + sizeof(TRAILER)];
+
+ (void)memcpy(buf, _PATH_TMP, sizeof(_PATH_TMP) - 1);
+ (void)memcpy(buf + sizeof(_PATH_TMP) - 1, TRAILER, sizeof(TRAILER));
+
+ //sigfillset(&set);
+ //(void)sigprocmask(SIG_BLOCK, &set, &oset);
+
+ fd = mkstemp(buf);
+ if (fd != -1)
+ (void)unlink(buf);
+
+ //(void)sigprocmask(SIG_SETMASK, &oset, NULL);
+
+ if (fd == -1)
+ return (NULL);
+
+ if ((fp = fdopen(fd, "w+")) == NULL) {
+ sverrno = errno;
+ (void)close(fd);
+ errno = sverrno;
+ return (NULL);
+ }
+ return (fp);
+}
diff --git a/StdLib/LibC/Stdio/tmpnam.c b/StdLib/LibC/Stdio/tmpnam.c
new file mode 100644
index 0000000000..74dd77325a
--- /dev/null
+++ b/StdLib/LibC/Stdio/tmpnam.c
@@ -0,0 +1,70 @@
+/** @file
+ Implementation of tmpnam as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: tmpnam.c,v 1.14 2003/08/07 16:43:33 agc Exp
+ tmpnam.c 8.3 (Berkeley) 3/28/94
+**/
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#include "namespace.h"
+#include <sys/types.h>
+#include <paths.h>
+#include <stdio.h>
+#include <sys/EfiSysCall.h>
+#include "reentrant.h"
+#include "local.h"
+
+__warn_references(tmpnam,"warning: tmpnam() possibly used unsafely, use mkstemp() or mkdtemp()")
+
+char *
+tmpnam(char *s)
+{
+ static long unsigned int tmpcount = 0; // Must be long to satisfy the %lu in snprintf below.
+ static char buf[L_tmpnam];
+
+ if (s == NULL)
+ s = buf;
+ (void)snprintf(s, L_tmpnam, "%stmp_%lu_XXXX", _PATH_TMP, tmpcount);
+ ++tmpcount;
+ return (_mktemp(s));
+}
diff --git a/StdLib/LibC/Stdio/ungetc.c b/StdLib/LibC/Stdio/ungetc.c
new file mode 100644
index 0000000000..e9d3807fcb
--- /dev/null
+++ b/StdLib/LibC/Stdio/ungetc.c
@@ -0,0 +1,172 @@
+/** @file
+ Implementation of ungetc as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: ungetc.c,v 1.14 2003/08/07 16:43:34 agc Exp
+ ungetc.c 8.2 (Berkeley) 11/3/93
+**/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "reentrant.h"
+#include "local.h"
+
+static int __submore(FILE *);
+/*
+ * Expand the ungetc buffer `in place'. That is, adjust fp->_p when
+ * the buffer moves, so that it points the same distance from the end,
+ * and move the bytes in the buffer around as necessary so that they
+ * are all at the end (stack-style).
+ */
+static int
+__submore(FILE *fp)
+{
+ int i;
+ unsigned char *p;
+
+ _DIAGASSERT(fp != NULL);
+
+ if (_UB(fp)._base == fp->_ubuf) {
+ /*
+ * Get a new buffer (rather than expanding the old one).
+ */
+ if ((p = malloc((size_t)BUFSIZ)) == NULL)
+ return (EOF);
+ _UB(fp)._base = p;
+ _UB(fp)._size = BUFSIZ;
+ p += BUFSIZ - sizeof(fp->_ubuf);
+ for (i = sizeof(fp->_ubuf); --i >= 0;)
+ p[i] = fp->_ubuf[i];
+ fp->_p = p;
+ return (0);
+ }
+ i = _UB(fp)._size;
+ p = realloc(_UB(fp)._base, (size_t)(i << 1));
+ if (p == NULL)
+ return (EOF);
+ /* no overlap (hence can use memcpy) because we doubled the size */
+ (void)memcpy((void *)(p + i), (void *)p, (size_t)i);
+ fp->_p = p + i;
+ _UB(fp)._base = p;
+ _UB(fp)._size = i << 1;
+ return (0);
+}
+
+int
+ungetc(int c, FILE *fp)
+{
+ _DIAGASSERT(fp != NULL);
+
+ if (c == EOF)
+ return (EOF);
+ if (!__sdidinit)
+ __sinit();
+ FLOCKFILE(fp);
+ _SET_ORIENTATION(fp, -1);
+ if ((fp->_flags & __SRD) == 0) {
+ /*
+ * Not already reading: no good unless reading-and-writing.
+ * Otherwise, flush any current write stuff.
+ */
+ if ((fp->_flags & __SRW) == 0) {
+ FUNLOCKFILE(fp);
+ return (EOF);
+ }
+ if (fp->_flags & __SWR) {
+ if (__sflush(fp)) {
+ FUNLOCKFILE(fp);
+ return (EOF);
+ }
+ fp->_flags &= ~__SWR;
+ fp->_w = 0;
+ fp->_lbfsize = 0;
+ }
+ fp->_flags |= __SRD;
+ }
+ c = (unsigned char)c;
+
+ /*
+ * If we are in the middle of ungetc'ing, just continue.
+ * This may require expanding the current ungetc buffer.
+ */
+ if (HASUB(fp)) {
+ if (fp->_r >= _UB(fp)._size && __submore(fp)) {
+ FUNLOCKFILE(fp);
+ return (EOF);
+ }
+ *--fp->_p = (unsigned char)c;
+ fp->_r++;
+ FUNLOCKFILE(fp);
+ return (c);
+ }
+ fp->_flags &= ~__SEOF;
+
+ /*
+ * If we can handle this by simply backing up, do so,
+ * but never replace the original character.
+ * (This makes sscanf() work when scanning `const' data.)
+ */
+ if (fp->_bf._base != NULL && fp->_p > fp->_bf._base &&
+ fp->_p[-1] == c) {
+ fp->_p--;
+ fp->_r++;
+ FUNLOCKFILE(fp);
+ return (c);
+ }
+
+ /*
+ * Create an ungetc buffer.
+ * Initially, we will use the `reserve' buffer.
+ */
+ fp->_ur = fp->_r;
+ fp->_up = fp->_p;
+ _UB(fp)._base = fp->_ubuf;
+ _UB(fp)._size = sizeof(fp->_ubuf);
+ fp->_ubuf[sizeof(fp->_ubuf) - 1] = (unsigned char)c;
+ fp->_p = &fp->_ubuf[sizeof(fp->_ubuf) - 1];
+ fp->_r = 1;
+ FUNLOCKFILE(fp);
+ return (c);
+}
diff --git a/StdLib/LibC/Stdio/ungetwc.c b/StdLib/LibC/Stdio/ungetwc.c
new file mode 100644
index 0000000000..8155043cf7
--- /dev/null
+++ b/StdLib/LibC/Stdio/ungetwc.c
@@ -0,0 +1,75 @@
+/*-
+ * Copyright (c)2001 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Citrus$
+
+ NetBSD: ungetwc.c,v 1.3 2005/06/12 05:21:27 lukem Exp
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <wchar.h>
+#include "reentrant.h"
+#include "local.h"
+
+wint_t
+ungetwc(wint_t wc, FILE *fp)
+{
+ struct wchar_io_data *wcio;
+
+ _DIAGASSERT(fp);
+
+ if (wc == WEOF)
+ return WEOF;
+
+ FLOCKFILE(fp);
+ _SET_ORIENTATION(fp, 1);
+ /*
+ * XXX since we have no way to transform a wchar string to
+ * a char string in reverse order, we can't use ungetc.
+ */
+ /* XXX should we flush ungetc buffer? */
+
+ wcio = WCIO_GET(fp);
+ if (wcio == 0) {
+ FUNLOCKFILE(fp);
+ errno = ENOMEM; /* XXX */
+ return WEOF;
+ }
+
+ if (wcio->wcio_ungetwc_inbuf >= WCIO_UNGETWC_BUFSIZE) {
+ FUNLOCKFILE(fp);
+ return WEOF;
+ }
+
+ wcio->wcio_ungetwc_buf[wcio->wcio_ungetwc_inbuf++] = (wchar_t)wc;
+ __sclearerr(fp);
+ FUNLOCKFILE(fp);
+
+ return wc;
+}
diff --git a/StdLib/LibC/Stdio/vasprintf.c b/StdLib/LibC/Stdio/vasprintf.c
new file mode 100644
index 0000000000..3a36468b49
--- /dev/null
+++ b/StdLib/LibC/Stdio/vasprintf.c
@@ -0,0 +1,79 @@
+/* $NetBSD: vasprintf.c,v 1.10 2005/02/09 21:35:47 kleink Exp $ */
+
+/*
+ * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: vasprintf.c,v 1.10 2005/02/09 21:35:47 kleink Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "reentrant.h"
+#include "local.h"
+
+int
+vasprintf(str, fmt, ap)
+ char **str;
+ const char *fmt;
+ _BSD_VA_LIST_ ap;
+{
+ int ret;
+ FILE f;
+ struct __sfileext fext;
+ unsigned char *_base;
+
+ _DIAGASSERT(str != NULL);
+ _DIAGASSERT(fmt != NULL);
+
+ _FILEEXT_SETUP(&f, &fext);
+ f._file = -1;
+ f._flags = __SWR | __SSTR | __SALC;
+ f._bf._base = f._p = (unsigned char *)malloc(128);
+ if (f._bf._base == NULL)
+ goto err;
+ f._bf._size = f._w = 127; /* Leave room for the NUL */
+ ret = __vfprintf_unlocked(&f, fmt, ap);
+ if (ret == -1)
+ goto err;
+ *f._p = '\0';
+ _base = realloc(f._bf._base, (size_t)(ret + 1));
+ if (_base == NULL)
+ goto err;
+ *str = (char *)_base;
+ return (ret);
+
+err:
+ if (f._bf._base)
+ free(f._bf._base);
+ *str = NULL;
+ errno = ENOMEM;
+ return (-1);
+}
diff --git a/StdLib/LibC/Stdio/vfprintf.c b/StdLib/LibC/Stdio/vfprintf.c
new file mode 100644
index 0000000000..8f5c649942
--- /dev/null
+++ b/StdLib/LibC/Stdio/vfprintf.c
@@ -0,0 +1,2 @@
+#define NARROW
+#include "vfwprintf.c"
diff --git a/StdLib/LibC/Stdio/vfscanf.c b/StdLib/LibC/Stdio/vfscanf.c
new file mode 100644
index 0000000000..724fd2a747
--- /dev/null
+++ b/StdLib/LibC/Stdio/vfscanf.c
@@ -0,0 +1,1129 @@
+/** @file
+ Implementation of scanf internals for <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: vfscanf.c,v 1.37.4.1 2007/05/07 19:49:08 pavel Exp
+ FreeBSD: src/lib/libc/stdio/vfscanf.c,v 1.41 2007/01/09 00:28:07 imp Exp
+ vfscanf.c 8.1 (Berkeley) 6/4/93
+**/
+//#include <Uefi.h> // REMOVE, For DEBUG only
+//#include <Library/UefiLib.h> // REMOVE, For DEBUG only
+
+#include <LibConfig.h>
+
+#include "namespace.h"
+#include <assert.h>
+#include <ctype.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdarg.h>
+#include <string.h>
+#include <sys/types.h>
+#include <wchar.h>
+#include <wctype.h>
+
+#include "reentrant.h"
+#include "local.h"
+
+#ifndef NO_FLOATING_POINT
+#include <locale.h>
+#endif
+
+/*
+ * Provide an external name for vfscanf. Note, we don't use the normal
+ * namespace.h method; stdio routines explicitly use the internal name
+ * __svfscanf.
+ */
+#ifdef __weak_alias
+__weak_alias(vfscanf,__svfscanf)
+#endif
+
+#define BUF 513 /* Maximum length of numeric string. */
+
+/*
+ * Flags used during conversion.
+ */
+#define LONG 0x0001 /* l: long or double */
+#define LONGDBL 0x0002 /* L: long double */
+#define SHORT 0x0004 /* h: short */
+#define SUPPRESS 0x0008 /* *: suppress assignment */
+#define POINTER 0x0010 /* p: void * (as hex) */
+#define NOSKIP 0x0020 /* [ or c: do not skip blanks */
+#define LONGLONG 0x0400 /* ll: long long (+ deprecated q: quad) */
+#define INTMAXT 0x0800 /* j: intmax_t */
+#define PTRDIFFT 0x1000 /* t: ptrdiff_t */
+#define SIZET 0x2000 /* z: size_t */
+#define SHORTSHORT 0x4000 /* hh: char */
+#define UNSIGNED 0x8000 /* %[oupxX] conversions */
+
+/*
+ * The following are used in integral conversions only:
+ * SIGNOK, NDIGITS, PFXOK, and NZDIGITS
+ */
+#define SIGNOK 0x00040 /* +/- is (still) legal */
+#define NDIGITS 0x00080 /* no digits detected */
+#define PFXOK 0x00100 /* 0x prefix is (still) legal */
+#define NZDIGITS 0x00200 /* no zero digits detected */
+#define HAVESIGN 0x10000 /* sign detected */
+
+/*
+ * Conversion types.
+ */
+#define CT_CHAR 0 /* %c conversion */
+#define CT_CCL 1 /* %[...] conversion */
+#define CT_STRING 2 /* %s conversion */
+#define CT_INT 3 /* %[dioupxX] conversion */
+#define CT_FLOAT 4 /* %[efgEFG] conversion */
+
+static const u_char *__sccl(char *, const u_char *);
+#ifndef NO_FLOATING_POINT
+ static int parsefloat(FILE *, char *, char *);
+#endif
+
+int __scanfdebug = 0;
+
+#define __collate_load_error /*CONSTCOND*/0
+static int
+__collate_range_cmp(int c1, int c2)
+{
+ static char s1[2], s2[2];
+
+ s1[0] = (char)c1;
+ s2[0] = (char)c2;
+ return strcoll(s1, s2);
+}
+
+
+/*
+ * __svfscanf - MT-safe version
+ */
+int
+__svfscanf(FILE *fp, char const *fmt0, va_list ap)
+{
+ int ret;
+
+ FLOCKFILE(fp);
+ ret = __svfscanf_unlocked(fp, fmt0, ap);
+ FUNLOCKFILE(fp);
+ return (ret);
+}
+
+/*
+ * __svfscanf_unlocked - non-MT-safe version of __svfscanf
+ */
+int
+__svfscanf_unlocked(FILE *fp, const char *fmt0, va_list ap)
+{
+ const u_char *fmt = (const u_char *)fmt0;
+ int c; /* character from format, or conversion */
+ size_t width; /* field width, or 0 */
+ char *p; /* points into all kinds of strings */
+ size_t n; /* handy size_t */
+ int flags; /* flags as defined above */
+ char *p0; /* saves original value of p when necessary */
+ int nassigned; /* number of fields assigned */
+ int nconversions; /* number of conversions */
+ int nread; /* number of characters consumed from fp */
+ int base; /* base argument to conversion function */
+ char ccltab[256]; /* character class table for %[...] */
+ char buf[BUF]; /* buffer for numeric and mb conversions */
+ wchar_t *wcp; /* handy wide character pointer */
+ size_t nconv; /* length of multibyte sequence converted */
+ static const mbstate_t initial = { 0 };
+ mbstate_t mbs;
+
+ /* `basefix' is used to avoid `if' tests in the integer scanner */
+ static const short basefix[17] =
+ { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
+
+ _DIAGASSERT(fp != NULL);
+ _DIAGASSERT(fmt0 != NULL);
+
+ _SET_ORIENTATION(fp, -1);
+
+//Print(L"%a( %d, \"%a\", ...)\n", __func__, fp->_file, fmt0);
+ nassigned = 0;
+ nconversions = 0;
+ nread = 0;
+ base = 0;
+ for (;;) {
+ c = (unsigned char)*fmt++;
+ if (c == 0)
+ return (nassigned);
+ if (isspace(c)) {
+ while ((fp->_r > 0 || __srefill(fp) == 0) &&
+ isspace(*fp->_p))
+ nread++, fp->_r--, fp->_p++;
+ continue;
+ }
+//Print(L"%a: %d\n", __func__, __LINE__);
+ if (c != '%')
+ goto literal;
+ width = 0;
+ flags = 0;
+ /*
+ * switch on the format. continue if done;
+ * break once format type is derived.
+ */
+again: c = *fmt++;
+//Print(L"%a: %d\n", __func__, __LINE__);
+ switch (c) {
+ case '%':
+literal:
+//Print(L"%a: %d\n", __func__, __LINE__);
+ if (fp->_r <= 0 && __srefill(fp))
+ goto input_failure;
+ if (*fp->_p != c)
+ goto match_failure;
+ fp->_r--, fp->_p++;
+ nread++;
+ continue;
+
+ case '*':
+ flags |= SUPPRESS;
+ goto again;
+ case 'j':
+ flags |= INTMAXT;
+ goto again;
+ case 'l':
+ if (flags & LONG) {
+ flags &= ~LONG;
+ flags |= LONGLONG;
+ } else
+ flags |= LONG;
+ goto again;
+ case 'q':
+ flags |= LONGLONG; /* not quite */
+ goto again;
+ case 't':
+ flags |= PTRDIFFT;
+ goto again;
+ case 'z':
+ flags |= SIZET;
+ goto again;
+ case 'L':
+ flags |= LONGDBL;
+ goto again;
+ case 'h':
+ if (flags & SHORT) {
+ flags &= ~SHORT;
+ flags |= SHORTSHORT;
+ } else
+ flags |= SHORT;
+ goto again;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ width = width * 10 + c - '0';
+ goto again;
+
+ /*
+ * Conversions.
+ */
+ case 'd':
+ c = CT_INT;
+ base = 10;
+ break;
+
+ case 'i':
+ c = CT_INT;
+ base = 0;
+ break;
+
+ case 'o':
+ c = CT_INT;
+ flags |= UNSIGNED;
+ base = 8;
+ break;
+
+ case 'u':
+ c = CT_INT;
+ flags |= UNSIGNED;
+ base = 10;
+ break;
+
+ case 'X':
+ case 'x':
+ flags |= PFXOK; /* enable 0x prefixing */
+ c = CT_INT;
+ flags |= UNSIGNED;
+ base = 16;
+ break;
+
+#ifndef NO_FLOATING_POINT
+ case 'A': case 'E': case 'F': case 'G':
+ case 'a': case 'e': case 'f': case 'g':
+ c = CT_FLOAT;
+ break;
+#endif
+
+ case 'S':
+ flags |= LONG;
+ /* FALLTHROUGH */
+ case 's':
+ c = CT_STRING;
+ break;
+
+ case '[':
+ fmt = __sccl(ccltab, fmt);
+ flags |= NOSKIP;
+ c = CT_CCL;
+ break;
+
+ case 'C':
+ flags |= LONG;
+ /* FALLTHROUGH */
+ case 'c':
+ flags |= NOSKIP;
+ c = CT_CHAR;
+ break;
+
+ case 'p': /* pointer format is like hex */
+ flags |= POINTER | PFXOK;
+ c = CT_INT; /* assumes sizeof(uintmax_t) */
+ flags |= UNSIGNED; /* >= sizeof(uintptr_t) */
+ base = 16;
+ break;
+
+ case 'n':
+ nconversions++;
+ if (flags & SUPPRESS) /* ??? */
+ continue;
+ if (flags & SHORTSHORT)
+ *va_arg(ap, char *) = (char)nread;
+ else if (flags & SHORT)
+ *va_arg(ap, short *) = (short)nread;
+ else if (flags & LONG)
+ *va_arg(ap, long *) = nread;
+ else if (flags & LONGLONG)
+ *va_arg(ap, long long *) = nread;
+ else if (flags & INTMAXT)
+ *va_arg(ap, intmax_t *) = nread;
+ else if (flags & SIZET)
+ *va_arg(ap, size_t *) = nread;
+ else if (flags & PTRDIFFT)
+ *va_arg(ap, ptrdiff_t *) = nread;
+ else
+ *va_arg(ap, int *) = nread;
+ continue;
+
+ default:
+ goto match_failure;
+
+ /*
+ * Disgusting backwards compatibility hack. XXX
+ */
+ case '\0': /* compat */
+ return (EOF);
+ }
+//Print(L"%a: %d\n", __func__, __LINE__);
+
+ /*
+ * We have a conversion that requires input.
+ */
+ if (fp->_r <= 0 && __srefill(fp))
+ {
+//Print(L"%a: %d\n", __func__, __LINE__);
+ goto input_failure;
+ }
+
+ /*
+ * Consume leading white space, except for formats
+ * that suppress this.
+ */
+ if ((flags & NOSKIP) == 0) {
+ while (isspace(*fp->_p)) {
+ nread++;
+ if (--fp->_r > 0)
+ fp->_p++;
+ else if (__srefill(fp))
+ {
+//Print(L"%a: %d\n", __func__, __LINE__);
+ goto input_failure;
+ }
+ }
+ /*
+ * Note that there is at least one character in
+ * the buffer, so conversions that do not set NOSKIP
+ * ca no longer result in an input failure.
+ */
+ }
+
+ /*
+ * Do the conversion.
+ */
+//Print(L"%a: %d\n", __func__, __LINE__);
+ switch (c) {
+
+ case CT_CHAR:
+ /* scan arbitrary characters (sets NOSKIP) */
+ if (width == 0)
+ width = 1;
+ if (flags & LONG) {
+ if ((flags & SUPPRESS) == 0)
+ wcp = va_arg(ap, wchar_t *);
+ else
+ wcp = NULL;
+ n = 0;
+ while (width != 0) {
+ if (n == MB_CUR_MAX) {
+ fp->_flags |= __SERR;
+ goto input_failure;
+ }
+ buf[n++] = *fp->_p;
+ fp->_p++;
+ fp->_r--;
+ mbs = initial;
+ nconv = mbrtowc(wcp, buf, n, &mbs);
+ if (nconv == (size_t)-1) {
+ fp->_flags |= __SERR;
+ goto input_failure;
+ }
+ if (nconv == 0 && !(flags & SUPPRESS))
+ *wcp = L'\0';
+ if (nconv != (size_t)-2) {
+ nread += (int)n;
+ width--;
+ if (!(flags & SUPPRESS))
+ wcp++;
+ n = 0;
+ }
+ if (fp->_r <= 0 && __srefill(fp)) {
+ if (n != 0) {
+ fp->_flags |= __SERR;
+ goto input_failure;
+ }
+ break;
+ }
+ }
+ if (!(flags & SUPPRESS))
+ nassigned++;
+ } else if (flags & SUPPRESS) {
+ size_t sum = 0;
+ for (;;) {
+ if ((n = fp->_r) < width) {
+ sum += n;
+ width -= n;
+ fp->_p += n;
+ if (__srefill(fp)) {
+ if (sum == 0)
+ goto input_failure;
+ break;
+ }
+ } else {
+ sum += width;
+ fp->_r -= (int)width;
+ fp->_p += width;
+ break;
+ }
+ }
+ nread += (int)sum;
+ } else {
+ size_t r = fread(va_arg(ap, char *), 1,
+ width, fp);
+
+ if (r == 0)
+ goto input_failure;
+ nread += (int)r;
+ nassigned++;
+ }
+ nconversions++;
+ break;
+
+ case CT_CCL:
+ /* scan a (nonempty) character class (sets NOSKIP) */
+ if (width == 0)
+ width = (size_t)~0; /* `infinity' */
+ /* take only those things in the class */
+ if (flags & LONG) {
+ wchar_t twc;
+ int nchars;
+
+ if ((flags & SUPPRESS) == 0)
+ wcp = va_arg(ap, wchar_t *);
+ else
+ wcp = &twc;
+ n = 0;
+ nchars = 0;
+ while (width != 0) {
+ if (n == MB_CUR_MAX) {
+ fp->_flags |= __SERR;
+ goto input_failure;
+ }
+ buf[n++] = *fp->_p;
+ fp->_p++;
+ fp->_r--;
+ mbs = initial;
+ nconv = mbrtowc(wcp, buf, n, &mbs);
+ if (nconv == (size_t)-1) {
+ fp->_flags |= __SERR;
+ goto input_failure;
+ }
+ if (nconv == 0)
+ *wcp = L'\0';
+ if (nconv != (size_t)-2) {
+ if (wctob(*wcp) != EOF &&
+ !ccltab[wctob(*wcp)]) {
+ while (n != 0) {
+ n--;
+ (void)ungetc(buf[n],
+ fp);
+ }
+ break;
+ }
+ nread += (int)n;
+ width--;
+ if (!(flags & SUPPRESS))
+ wcp++;
+ nchars++;
+ n = 0;
+ }
+ if (fp->_r <= 0 && __srefill(fp)) {
+ if (n != 0) {
+ fp->_flags |= __SERR;
+ goto input_failure;
+ }
+ break;
+ }
+ }
+ if (n != 0) {
+ fp->_flags |= __SERR;
+ goto input_failure;
+ }
+ n = nchars;
+ if (n == 0)
+ goto match_failure;
+ if (!(flags & SUPPRESS)) {
+ *wcp = L'\0';
+ nassigned++;
+ }
+ } else if (flags & SUPPRESS) {
+ n = 0;
+ while (ccltab[*fp->_p]) {
+ n++, fp->_r--, fp->_p++;
+ if (--width == 0)
+ break;
+ if (fp->_r <= 0 && __srefill(fp)) {
+ if (n == 0)
+ goto input_failure;
+ break;
+ }
+ }
+ if (n == 0)
+ goto match_failure;
+ } else {
+ p0 = p = va_arg(ap, char *);
+ while (ccltab[*fp->_p]) {
+ fp->_r--;
+ *p++ = *fp->_p++;
+ if (--width == 0)
+ break;
+ if (fp->_r <= 0 && __srefill(fp)) {
+ if (p == p0)
+ goto input_failure;
+ break;
+ }
+ }
+ n = p - p0;
+ if (n == 0)
+ goto match_failure;
+ *p = 0;
+ nassigned++;
+ }
+ nread += (int)n;
+ nconversions++;
+ break;
+
+ case CT_STRING:
+ /* like CCL, but zero-length string OK, & no NOSKIP */
+ if (width == 0)
+ width = (size_t)~0;
+ if (flags & LONG) {
+ wchar_t twc;
+
+ if ((flags & SUPPRESS) == 0)
+ wcp = va_arg(ap, wchar_t *);
+ else
+ wcp = &twc;
+ n = 0;
+ while (!isspace(*fp->_p) && width != 0) {
+ if (n == MB_CUR_MAX) {
+ fp->_flags |= __SERR;
+ goto input_failure;
+ }
+ buf[n++] = *fp->_p;
+ fp->_p++;
+ fp->_r--;
+ mbs = initial;
+ nconv = mbrtowc(wcp, buf, n, &mbs);
+ if (nconv == (size_t)-1) {
+ fp->_flags |= __SERR;
+ goto input_failure;
+ }
+ if (nconv == 0)
+ *wcp = L'\0';
+ if (nconv != (size_t)-2) {
+ if (iswspace(*wcp)) {
+ while (n != 0) {
+ n--;
+ (void)ungetc(buf[n],
+ fp);
+ }
+ break;
+ }
+ nread += (int)n;
+ width--;
+ if (!(flags & SUPPRESS))
+ wcp++;
+ n = 0;
+ }
+ if (fp->_r <= 0 && __srefill(fp)) {
+ if (n != 0) {
+ fp->_flags |= __SERR;
+ goto input_failure;
+ }
+ break;
+ }
+ }
+ if (!(flags & SUPPRESS)) {
+ *wcp = L'\0';
+ nassigned++;
+ }
+ } else if (flags & SUPPRESS) {
+ n = 0;
+ while (!isspace(*fp->_p)) {
+ n++, fp->_r--, fp->_p++;
+ if (--width == 0)
+ break;
+ if (fp->_r <= 0 && __srefill(fp))
+ break;
+ }
+ nread += (int)n;
+ } else {
+ p0 = p = va_arg(ap, char *);
+ while (!isspace(*fp->_p)) {
+ fp->_r--;
+ *p++ = *fp->_p++;
+ if (--width == 0)
+ break;
+ if (fp->_r <= 0 && __srefill(fp))
+ break;
+ }
+ *p = 0;
+ nread += (int)(p - p0);
+ nassigned++;
+ }
+ nconversions++;
+ continue;
+
+ case CT_INT:
+//Print(L"%a: %d\n", __func__, __LINE__);
+ /* scan an integer as if by the conversion function */
+#ifdef hardway
+ if (width == 0 || width > sizeof(buf) - 1)
+ width = sizeof(buf) - 1;
+#else
+ /* size_t is unsigned, hence this optimisation */
+ if (--width > sizeof(buf) - 2)
+ width = sizeof(buf) - 2;
+ width++;
+#endif
+ flags |= SIGNOK | NDIGITS | NZDIGITS;
+ for (p = buf; width; width--) {
+ c = *fp->_p;
+ /*
+ * Switch on the character; `goto ok'
+ * if we accept it as a part of number.
+ */
+ switch (c) {
+
+ /*
+ * The digit 0 is always legal, but is
+ * special. For %i conversions, if no
+ * digits (zero or nonzero) have been
+ * scanned (only signs), we will have
+ * base==0. In that case, we should set
+ * it to 8 and enable 0x prefixing.
+ * Also, if we have not scanned zero digits
+ * before this, do not turn off prefixing
+ * (someone else will turn it off if we
+ * have scanned any nonzero digits).
+ */
+ case '0':
+ if (base == 0) {
+ base = 8;
+ flags |= PFXOK;
+ }
+ if (flags & NZDIGITS)
+ flags &= ~(SIGNOK|NZDIGITS|NDIGITS);
+ else
+ flags &= ~(SIGNOK|PFXOK|NDIGITS);
+ goto ok;
+
+ /* 1 through 7 always legal */
+ case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ base = basefix[base];
+ flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ goto ok;
+
+ /* digits 8 and 9 ok iff decimal or hex */
+ case '8': case '9':
+ base = basefix[base];
+ if (base <= 8)
+ break; /* not legal here */
+ flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ goto ok;
+
+ /* letters ok iff hex */
+ case 'A': case 'B': case 'C':
+ case 'D': case 'E': case 'F':
+ case 'a': case 'b': case 'c':
+ case 'd': case 'e': case 'f':
+ /* no need to fix base here */
+ if (base <= 10)
+ break; /* not legal here */
+ flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ goto ok;
+
+ /* sign ok only as first character */
+ case '+': case '-':
+ if (flags & SIGNOK) {
+ flags &= ~SIGNOK;
+ flags |= HAVESIGN;
+ goto ok;
+ }
+ break;
+
+ /*
+ * x ok iff flag still set & 2nd char (or
+ * 3rd char if we have a sign).
+ */
+ case 'x': case 'X':
+ if (flags & PFXOK && p ==
+ buf + 1 + !!(flags & HAVESIGN)) {
+ base = 16; /* if %i */
+ flags &= ~PFXOK;
+ goto ok;
+ }
+ break;
+ }
+
+ /*
+ * If we got here, c is not a legal character
+ * for a number. Stop accumulating digits.
+ */
+ break;
+ ok:
+ /*
+ * c is legal: store it and look at the next.
+ */
+ *p++ = (char)c;
+ if (--fp->_r > 0)
+ fp->_p++;
+ else if (__srefill(fp))
+ break; /* EOF */
+ }
+ /*
+ * If we had only a sign, it is no good; push
+ * back the sign. If the number ends in `x',
+ * it was [sign] '0' 'x', so push back the x
+ * and treat it as [sign] '0'.
+ */
+ if (flags & NDIGITS) {
+ if (p > buf)
+ (void)ungetc(*(u_char *)--p, fp);
+ goto match_failure;
+ }
+ c = ((u_char *)p)[-1];
+ if (c == 'x' || c == 'X') {
+ --p;
+ (void)ungetc(c, fp);
+ }
+ if ((flags & SUPPRESS) == 0) {
+ //uintmax_t res;
+ // Use a union to get around the truncation warnings.
+ union {
+ uintmax_t umax;
+ intmax_t imax;
+ void *vp;
+ ptrdiff_t pdt;
+ size_t sz;
+ long long ll;
+ long lo;
+ int in;
+ short hw;
+ char ch;
+ } res;
+
+ *p = 0;
+ if ((flags & UNSIGNED) == 0)
+ res.imax = strtoimax(buf, (char **)NULL, base);
+ else
+ res.umax = strtoumax(buf, (char **)NULL, base);
+ if (flags & POINTER)
+ *va_arg(ap, void **) = res.vp;
+ //(void *)((uintptr_t)res);
+ else if (flags & SHORTSHORT)
+ *va_arg(ap, char *) = res.ch;
+ else if (flags & SHORT)
+ *va_arg(ap, short *) = res.hw;
+ else if (flags & LONG)
+ *va_arg(ap, long *) = res.lo;
+ else if (flags & LONGLONG)
+ *va_arg(ap, long long *) = res.ll;
+ else if (flags & INTMAXT)
+ *va_arg(ap, intmax_t *) = res.imax;
+ else if (flags & PTRDIFFT)
+ *va_arg(ap, ptrdiff_t *) = res.pdt;
+ //(ptrdiff_t)res;
+ else if (flags & SIZET)
+ *va_arg(ap, size_t *) = res.sz;
+ else
+ *va_arg(ap, int *) = res.in;
+ nassigned++;
+ }
+ nread += (int)(p - buf);
+ nconversions++;
+//Print(L"%a: %d\n", __func__, __LINE__);
+ break;
+
+#ifndef NO_FLOATING_POINT
+ case CT_FLOAT:
+ /* scan a floating point number as if by strtod */
+ if (width == 0 || width > sizeof(buf) - 1)
+ width = sizeof(buf) - 1;
+ if ((width = parsefloat(fp, buf, buf + width)) == 0)
+ goto match_failure;
+ if ((flags & SUPPRESS) == 0) {
+ if (flags & LONGDBL) {
+/*dvm*/ long double **mp = (long double **)ap;
+ long double res = strtold(buf, &p);
+
+/*dvm*/ *(*mp) = res;
+/*dvm*/ ap += sizeof(long double *);
+/*dvm*/ //*va_arg(ap, long double *) = res;
+ } else if (flags & LONG) {
+ double res = strtod(buf, &p);
+ *va_arg(ap, double *) = res;
+ } else {
+ float res = strtof(buf, &p);
+ *va_arg(ap, float *) = res;
+ }
+ if (__scanfdebug && p - buf != (ptrdiff_t)width)
+ abort();
+ nassigned++;
+ }
+ nread += (int)width;
+ nconversions++;
+ break;
+#endif /* !NO_FLOATING_POINT */
+ }
+ }
+input_failure:
+//Print(L"%a: %d\n", __func__, __LINE__);
+ return (nconversions != 0 ? nassigned : EOF);
+match_failure:
+ return (nassigned);
+}
+
+/*
+ * Fill in the given table from the scanset at the given format
+ * (just after `['). Return a pointer to the character past the
+ * closing `]'. The table has a 1 wherever characters should be
+ * considered part of the scanset.
+ */
+static const u_char *
+__sccl(char *tab, const u_char *fmt)
+{
+ int c, n, v, i;
+
+ _DIAGASSERT(tab != NULL);
+ _DIAGASSERT(fmt != NULL);
+ /* first `clear' the whole table */
+ c = *fmt++; /* first char hat => negated scanset */
+ if (c == '^') {
+ v = 1; /* default => accept */
+ c = *fmt++; /* get new first char */
+ } else
+ v = 0; /* default => reject */
+
+ /* XXX: Will not work if sizeof(tab*) > sizeof(char) */
+ (void)memset(tab, v, 256);
+
+ if (c == 0)
+ return (fmt - 1);/* format ended before closing ] */
+
+ /*
+ * Now set the entries corresponding to the actual scanset
+ * to the opposite of the above.
+ *
+ * The first character may be ']' (or '-') without being special;
+ * the last character may be '-'.
+ */
+ v = 1 - v;
+ for (;;) {
+ tab[c] = (char)v; /* take character c */
+doswitch:
+ n = *fmt++; /* and examine the next */
+ switch (n) {
+
+ case 0: /* format ended too soon */
+ return (fmt - 1);
+
+ case '-':
+ /*
+ * A scanset of the form
+ * [01+-]
+ * is defined as `the digit 0, the digit 1,
+ * the character +, the character -', but
+ * the effect of a scanset such as
+ * [a-zA-Z0-9]
+ * is implementation defined. The V7 Unix
+ * scanf treats `a-z' as `the letters a through
+ * z', but treats `a-a' as `the letter a, the
+ * character -, and the letter a'.
+ *
+ * For compatibility, the `-' is not considerd
+ * to define a range if the character following
+ * it is either a close bracket (required by ANSI)
+ * or is not numerically greater than the character
+ * we just stored in the table (c).
+ */
+ n = *fmt;
+ if (n == ']' || (__collate_load_error ? n < c :
+ __collate_range_cmp(n, c) < 0)) {
+ c = '-';
+ break; /* resume the for(;;) */
+ }
+ fmt++;
+ /* fill in the range */
+ if (__collate_load_error) {
+ do
+ tab[++c] = (char)v;
+ while (c < n);
+ } else {
+ for (i = 0; i < 256; i ++)
+ if (__collate_range_cmp(c, i) < 0 &&
+ __collate_range_cmp(i, n) <= 0)
+ tab[i] = (char)v;
+ }
+#if 1 /* XXX another disgusting compatibility hack */
+ c = n;
+ /*
+ * Alas, the V7 Unix scanf also treats formats
+ * such as [a-c-e] as `the letters a through e'.
+ * This too is permitted by the standard....
+ */
+ goto doswitch;
+#else
+ c = *fmt++;
+ if (c == 0)
+ return (fmt - 1);
+ if (c == ']')
+ return (fmt);
+#endif
+
+ case ']': /* end of scanset */
+ return (fmt);
+
+ default: /* just another character */
+ c = n;
+ break;
+ }
+ }
+ /* NOTREACHED */
+}
+
+#ifndef NO_FLOATING_POINT
+static int
+parsefloat(FILE *fp, char *buf, char *end)
+{
+ char *commit, *p;
+ int infnanpos = 0;
+ enum {
+ S_START, S_GOTSIGN, S_INF, S_NAN, S_MAYBEHEX,
+ S_DIGITS, S_FRAC, S_EXP, S_EXPDIGITS
+ } state = S_START;
+ unsigned char c;
+ char decpt = *localeconv()->decimal_point;
+ _Bool gotmantdig = 0, ishex = 0;
+
+ /*
+ * We set commit = p whenever the string we have read so far
+ * constitutes a valid representation of a floating point
+ * number by itself. At some point, the parse will complete
+ * or fail, and we will ungetc() back to the last commit point.
+ * To ensure that the file offset gets updated properly, it is
+ * always necessary to read at least one character that doesn't
+ * match; thus, we can't short-circuit "infinity" or "nan(...)".
+ */
+ commit = buf - 1;
+ for (p = buf; p < end; ) {
+ c = *fp->_p;
+reswitch:
+ switch (state) {
+ case S_START:
+ state = S_GOTSIGN;
+ if (c == '-' || c == '+')
+ break;
+ else
+ goto reswitch;
+ case S_GOTSIGN:
+ switch (c) {
+ case '0':
+ state = S_MAYBEHEX;
+ commit = p;
+ break;
+ case 'I':
+ case 'i':
+ state = S_INF;
+ break;
+ case 'N':
+ case 'n':
+ state = S_NAN;
+ break;
+ default:
+ state = S_DIGITS;
+ goto reswitch;
+ }
+ break;
+ case S_INF:
+ if (infnanpos > 6 ||
+ (c != "nfinity"[infnanpos] &&
+ c != "NFINITY"[infnanpos]))
+ goto parsedone;
+ if (infnanpos == 1 || infnanpos == 6)
+ commit = p; /* inf or infinity */
+ infnanpos++;
+ break;
+ case S_NAN:
+ switch (infnanpos) {
+ case -1: /* XXX kludge to deal with nan(...) */
+ goto parsedone;
+ case 0:
+ if (c != 'A' && c != 'a')
+ goto parsedone;
+ break;
+ case 1:
+ if (c != 'N' && c != 'n')
+ goto parsedone;
+ else
+ commit = p;
+ break;
+ case 2:
+ if (c != '(')
+ goto parsedone;
+ break;
+ default:
+ if (c == ')') {
+ commit = p;
+ infnanpos = -2;
+ } else if (!isalnum(c) && c != '_')
+ goto parsedone;
+ break;
+ }
+ infnanpos++;
+ break;
+ case S_MAYBEHEX:
+ state = S_DIGITS;
+ if (c == 'X' || c == 'x') {
+ ishex = 1;
+ break;
+ } else { /* we saw a '0', but no 'x' */
+ gotmantdig = 1;
+ goto reswitch;
+ }
+ case S_DIGITS:
+ if ((ishex && isxdigit(c)) || isdigit(c))
+ gotmantdig = 1;
+ else {
+ state = S_FRAC;
+ if (c != decpt)
+ goto reswitch;
+ }
+ if (gotmantdig)
+ commit = p;
+ break;
+ case S_FRAC:
+ if (((c == 'E' || c == 'e') && !ishex) ||
+ ((c == 'P' || c == 'p') && ishex)) {
+ if (!gotmantdig)
+ goto parsedone;
+ else
+ state = S_EXP;
+ } else if ((ishex && isxdigit(c)) || isdigit(c)) {
+ commit = p;
+ gotmantdig = 1;
+ } else
+ goto parsedone;
+ break;
+ case S_EXP:
+ state = S_EXPDIGITS;
+ if (c == '-' || c == '+')
+ break;
+ else
+ goto reswitch;
+ case S_EXPDIGITS:
+ if (isdigit(c))
+ commit = p;
+ else
+ goto parsedone;
+ break;
+ default:
+ abort();
+ }
+ *p++ = c;
+ if (--fp->_r > 0)
+ fp->_p++;
+ else if (__srefill(fp))
+ break; /* EOF */
+ }
+
+parsedone:
+ while (commit < --p)
+ (void)ungetc(*(u_char *)p, fp);
+ *++commit = '\0';
+ return (int)(commit - buf);
+}
+#endif
diff --git a/StdLib/LibC/Stdio/vfwprintf.c b/StdLib/LibC/Stdio/vfwprintf.c
new file mode 100644
index 0000000000..bf31ddb664
--- /dev/null
+++ b/StdLib/LibC/Stdio/vfwprintf.c
@@ -0,0 +1,2035 @@
+/** @file
+ Implementation of internals for printf and wprintf.
+
+ Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: vfwprintf.c,v 1.9.2.1.4.1 2008/04/08 21:10:55 jdc Exp
+ vfprintf.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include "namespace.h"
+#include <sys/types.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <limits.h>
+#include <locale.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <wchar.h>
+#include <wctype.h>
+
+#include "reentrant.h"
+#include "local.h"
+#include "extern.h"
+#include "fvwrite.h"
+
+#ifdef _MSC_VER
+ // Keep compiler quiet about conversions from larger to smaller types.
+ #pragma warning ( disable : 4244 )
+#endif
+
+#ifndef NARROW
+#define MCHAR_T char
+#define CHAR_T wchar_t
+#define STRLEN(a) wcslen(a)
+#define MEMCHR(a, b, c) wmemchr(a, b, c)
+#define SCONV(a, b) __mbsconv(a, b)
+#define STRCONST(a) L ## a
+#define WDECL(a, b) a ## w ## b
+#define END_OF_FILE WEOF
+#define MULTI 0
+#else
+#define MCHAR_T wchar_t
+#define CHAR_T char
+#define STRLEN(a) strlen(a)
+#define MEMCHR(a, b, c) memchr(a, b, c)
+#define SCONV(a, b) __wcsconv(a, b)
+#define STRCONST(a) a
+#define WDECL(a, b) a ## b
+#define END_OF_FILE EOF
+#define MULTI 1
+#endif
+
+union arg {
+ int intarg;
+ u_int uintarg;
+ long longarg;
+ unsigned long ulongarg;
+ long long longlongarg;
+ unsigned long long ulonglongarg;
+ ptrdiff_t ptrdiffarg;
+ size_t sizearg;
+ intmax_t intmaxarg;
+ uintmax_t uintmaxarg;
+ void *pvoidarg;
+ char *pchararg;
+ signed char *pschararg;
+ short *pshortarg;
+ int *pintarg;
+ long *plongarg;
+ long long *plonglongarg;
+ ptrdiff_t *pptrdiffarg;
+ size_t *psizearg;
+ intmax_t *pintmaxarg;
+#ifndef NO_FLOATING_POINT
+ double doublearg;
+ long double longdoublearg;
+#endif
+ wint_t wintarg;
+ wchar_t *pwchararg;
+};
+
+/*
+ * Type ids for argument type table.
+ */
+enum typeid {
+ T_UNUSED, TP_SHORT, T_INT, T_U_INT, TP_INT,
+ T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG,
+ TP_LLONG, T_PTRDIFFT, TP_PTRDIFFT, T_SIZET, TP_SIZET,
+ T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR,
+ TP_SCHAR, T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR
+};
+
+static int __sbprintf(FILE *, const CHAR_T *, va_list);
+static CHAR_T *__ujtoa(uintmax_t, CHAR_T *, int, int, const char *, int,
+ char, const char *);
+static CHAR_T *__ultoa(u_long, CHAR_T *, int, int, const char *, int,
+ char, const char *);
+#ifndef NARROW
+static CHAR_T *__mbsconv(char *, int);
+static wint_t __xfputwc(CHAR_T, FILE *);
+#else
+static char *__wcsconv(wchar_t *, int);
+static int __sprint(FILE *, struct __suio *);
+#endif
+static int __find_arguments(const CHAR_T *, va_list, union arg **);
+static int __grow_type_table(int, enum typeid **, int *);
+
+/*
+ * Helper function for `fprintf to unbuffered unix file': creates a
+ * temporary buffer. We only work on write-only files; this avoids
+ * worries about ungetc buffers and so forth.
+ */
+static int
+__sbprintf(FILE *fp, const CHAR_T *fmt, va_list ap)
+{
+ int ret;
+ FILE fake;
+ struct __sfileext fakeext;
+ unsigned char buf[BUFSIZ];
+
+ _DIAGASSERT(fp != NULL);
+ _DIAGASSERT(fmt != NULL);
+
+ _FILEEXT_SETUP(&fake, &fakeext);
+
+ /* copy the important variables */
+ fake._flags = fp->_flags & ~__SNBF;
+ fake._file = fp->_file;
+ fake._cookie = fp->_cookie;
+ fake._write = fp->_write;
+
+ /* set up the buffer */
+ fake._bf._base = fake._p = buf;
+ fake._bf._size = fake._w = sizeof(buf);
+ fake._lbfsize = 0; /* not actually used, but Just In Case */
+
+ /* do the work, then copy any error status */
+ ret = WDECL(__vf,printf_unlocked)(&fake, fmt, ap);
+ if (ret >= 0 && fflush(&fake))
+ ret = END_OF_FILE;
+ if (fake._flags & __SERR)
+ fp->_flags |= __SERR;
+ return (ret);
+}
+
+#ifndef NARROW
+/*
+ * Like __fputwc, but handles fake string (__SSTR) files properly.
+ * File must already be locked.
+ */
+static wint_t
+__xfputwc(wchar_t wc, FILE *fp)
+{
+ static const mbstate_t initial = { 0 };
+ mbstate_t mbs;
+ char buf[MB_LEN_MAX];
+ struct __suio uio;
+ struct __siov iov;
+ size_t len;
+
+ if ((fp->_flags & __SSTR) == 0)
+ return (__fputwc_unlock(wc, fp));
+
+ mbs = initial;
+ if ((len = wcrtomb(buf, wc, &mbs)) == (size_t)-1) {
+ fp->_flags |= __SERR;
+ return (END_OF_FILE);
+ }
+ uio.uio_iov = &iov;
+ uio.uio_resid = (int)len;
+ uio.uio_iovcnt = 1;
+ iov.iov_base = buf;
+ iov.iov_len = len;
+ return (__sfvwrite(fp, &uio) != EOF ? (wint_t)wc : END_OF_FILE);
+}
+#else
+/*
+ * Flush out all the vectors defined by the given uio,
+ * then reset it so that it can be reused.
+ */
+static int
+__sprint(FILE *fp, struct __suio *uio)
+{
+ int err;
+
+ _DIAGASSERT(fp != NULL);
+ _DIAGASSERT(uio != NULL);
+
+ if (uio->uio_resid == 0) {
+ uio->uio_iovcnt = 0;
+ return (0);
+ }
+ err = __sfvwrite(fp, uio);
+ uio->uio_resid = 0;
+ uio->uio_iovcnt = 0;
+ return (err);
+}
+#endif
+
+/*
+ * Macros for converting digits to letters and vice versa
+ */
+#define to_digit(c) ((c) - '0')
+#define is_digit(c) ((unsigned)to_digit(c) <= 9)
+#define to_char(n) (CHAR_T)((n) + '0')
+
+/*
+ * Convert an unsigned long to ASCII for printf purposes, returning
+ * a pointer to the first character of the string representation.
+ * Octal numbers can be forced to have a leading zero; hex numbers
+ * use the given digits.
+ */
+static CHAR_T *
+__ultoa(u_long val, CHAR_T *endp, int base, int octzero, const char *xdigs,
+ int needgrp, char thousep, const char *grp)
+{
+ CHAR_T *cp = endp;
+ LONGN sval;
+ int ndig;
+
+ /*
+ * Handle the three cases separately, in the hope of getting
+ * better/faster code.
+ */
+ switch (base) {
+ case 10:
+ if (val < 10) { /* many numbers are 1 digit */
+ *--cp = to_char(val);
+ return (cp);
+ }
+ ndig = 0;
+ /*
+ * On many machines, unsigned arithmetic is harder than
+ * signed arithmetic, so we do at most one unsigned mod and
+ * divide; this is sufficient to reduce the range of
+ * the incoming value to where signed arithmetic works.
+ */
+ if (val > LONG_MAX) {
+ *--cp = to_char(val % 10);
+ ndig++;
+ sval = (LONGN)(val / 10);
+ } else
+ sval = (LONGN)val;
+ do {
+ *--cp = to_char(sval % 10);
+ ndig++;
+ /*
+ * If (*grp == CHAR_MAX) then no more grouping
+ * should be performed.
+ */
+ if (needgrp && ndig == *grp && *grp != CHAR_MAX
+ && sval > 9) {
+ *--cp = thousep;
+ ndig = 0;
+ /*
+ * If (*(grp+1) == '\0') then we have to
+ * use *grp character (last grouping rule)
+ * for all next cases
+ */
+ if (*(grp+1) != '\0')
+ grp++;
+ }
+ sval /= 10;
+ } while (sval != 0);
+ break;
+
+ case 8:
+ do {
+ *--cp = to_char(val & 7);
+ val >>= 3;
+ } while (val);
+ if (octzero && *cp != '0')
+ *--cp = '0';
+ break;
+
+ case 16:
+ do {
+ *--cp = xdigs[(size_t)val & 15];
+ val >>= 4;
+ } while (val);
+ break;
+
+ default: /* oops */
+ abort();
+ }
+ return (cp);
+}
+
+/* Identical to __ultoa, but for intmax_t. */
+static CHAR_T *
+__ujtoa(uintmax_t val, CHAR_T *endp, int base, int octzero,
+ const char *xdigs, int needgrp, char thousep, const char *grp)
+{
+ CHAR_T *cp = endp;
+ intmax_t sval;
+ int ndig;
+
+ /* quick test for small values; __ultoa is typically much faster */
+ /* (perhaps instead we should run until small, then call __ultoa?) */
+ if (val <= ULONG_MAX)
+ return (__ultoa((u_long)val, endp, base, octzero, xdigs,
+ needgrp, thousep, grp));
+ switch (base) {
+ case 10:
+ if (val < 10) {
+ *--cp = to_char(val % 10);
+ return (cp);
+ }
+ ndig = 0;
+ if (val > INTMAX_MAX) {
+ *--cp = to_char(val % 10);
+ ndig++;
+ sval = val / 10;
+ } else
+ sval = val;
+ do {
+ *--cp = to_char(sval % 10);
+ ndig++;
+ /*
+ * If (*grp == CHAR_MAX) then no more grouping
+ * should be performed.
+ */
+ if (needgrp && *grp != CHAR_MAX && ndig == *grp
+ && sval > 9) {
+ *--cp = thousep;
+ ndig = 0;
+ /*
+ * If (*(grp+1) == '\0') then we have to
+ * use *grp character (last grouping rule)
+ * for all next cases
+ */
+ if (*(grp+1) != '\0')
+ grp++;
+ }
+ sval /= 10;
+ } while (sval != 0);
+ break;
+
+ case 8:
+ do {
+ *--cp = to_char(val & 7);
+ val >>= 3;
+ } while (val);
+ if (octzero && *cp != '0')
+ *--cp = '0';
+ break;
+
+ case 16:
+ do {
+ *--cp = xdigs[(size_t)val & 15];
+ val >>= 4;
+ } while (val);
+ break;
+
+ default:
+ abort();
+ }
+ return (cp);
+}
+
+#ifndef NARROW
+/*
+ * Convert a multibyte character string argument for the %s format to a wide
+ * string representation. ``prec'' specifies the maximum number of bytes
+ * to output. If ``prec'' is greater than or equal to zero, we can't assume
+ * that the multibyte char. string ends in a null character.
+ */
+static wchar_t *
+__mbsconv(char *mbsarg, int prec)
+{
+ static const mbstate_t initial = { 0 };
+ mbstate_t mbs;
+ wchar_t *convbuf, *wcp;
+ const char *p;
+ size_t insize, nchars, nconv;
+
+ if (mbsarg == NULL)
+ return (NULL);
+
+ /*
+ * Supplied argument is a multibyte string; convert it to wide
+ * characters first.
+ */
+ if (prec >= 0) {
+ /*
+ * String is not guaranteed to be NUL-terminated. Find the
+ * number of characters to print.
+ */
+ p = mbsarg;
+ insize = nchars = nconv = 0;
+ mbs = initial;
+ while (nchars != (size_t)prec) {
+ nconv = mbrlen(p, MB_CUR_MAX, &mbs);
+ if (nconv == 0 || nconv == (size_t)-1 ||
+ nconv == (size_t)-2)
+ break;
+ p += nconv;
+ nchars++;
+ insize += nconv;
+ }
+ if (nconv == (size_t)-1 || nconv == (size_t)-2)
+ return (NULL);
+ } else
+ insize = strlen(mbsarg);
+
+ /*
+ * Allocate buffer for the result and perform the conversion,
+ * converting at most `size' bytes of the input multibyte string to
+ * wide characters for printing.
+ */
+ convbuf = malloc((insize + 1) * sizeof(*convbuf));
+ if (convbuf == NULL)
+ return (NULL);
+ wcp = convbuf;
+ p = mbsarg;
+ mbs = initial;
+ nconv = 0;
+ while (insize != 0) {
+ nconv = mbrtowc(wcp, p, insize, &mbs);
+ if (nconv == 0 || nconv == (size_t)-1 || nconv == (size_t)-2)
+ break;
+ wcp++;
+ p += nconv;
+ insize -= nconv;
+ }
+ if (nconv == (size_t)-1 || nconv == (size_t)-2) {
+ free(convbuf);
+ return (NULL);
+ }
+ *wcp = L'\0';
+
+ return (convbuf);
+}
+#else
+/*
+ * Convert a wide character string argument for the %ls format to a multibyte
+ * string representation. If not -1, prec specifies the maximum number of
+ * bytes to output, and also means that we can't assume that the wide char.
+ * string ends is null-terminated.
+ */
+static char *
+__wcsconv(wchar_t *wcsarg, int prec)
+{
+ static const mbstate_t initial = { 0 };
+ mbstate_t mbs;
+ char buf[MB_LEN_MAX];
+ wchar_t *p;
+ char *convbuf;
+ size_t clen, nbytes;
+
+ /* Allocate space for the maximum number of bytes we could output. */
+ if (prec < 0) {
+ p = wcsarg;
+ mbs = initial;
+ nbytes = wcsrtombs(NULL, (const wchar_t **)&p, 0, &mbs);
+ if (nbytes == (size_t)-1)
+ return (NULL);
+ } else {
+ /*
+ * Optimisation: if the output precision is small enough,
+ * just allocate enough memory for the maximum instead of
+ * scanning the string.
+ */
+ if (prec < 128)
+ nbytes = prec;
+ else {
+ nbytes = 0;
+ p = wcsarg;
+ mbs = initial;
+ for (;;) {
+ clen = wcrtomb(buf, *p++, &mbs);
+ if (clen == 0 || clen == (size_t)-1 ||
+ nbytes + clen > (size_t)prec)
+ break;
+ nbytes += clen;
+ }
+ }
+ }
+ if ((convbuf = malloc(nbytes + 1)) == NULL)
+ return (NULL);
+
+ /* Fill the output buffer. */
+ p = wcsarg;
+ mbs = initial;
+ if ((nbytes = wcsrtombs(convbuf, (const wchar_t **)&p,
+ nbytes, &mbs)) == (size_t)-1) {
+ free(convbuf);
+ return (NULL);
+ }
+ convbuf[nbytes] = '\0';
+ return (convbuf);
+}
+#endif
+
+/*
+ * MT-safe version
+ */
+int
+WDECL(vf,printf)(FILE * __restrict fp, const CHAR_T * __restrict fmt0, va_list ap)
+{
+ int ret;
+
+ FLOCKFILE(fp);
+ ret = WDECL(__vf,printf_unlocked)(fp, fmt0, ap);
+ FUNLOCKFILE(fp);
+ return (ret);
+}
+
+#ifndef NO_FLOATING_POINT
+
+#include <float.h>
+#include <math.h>
+#include "floatio.h"
+
+#define DEFPREC 6
+
+static int exponent(CHAR_T *, int, int);
+#ifndef WIDE_DOUBLE
+static char *cvt(double, int, int, char *, int *, int, int *);
+#endif
+
+#endif /* !NO_FLOATING_POINT */
+
+/*
+ * The size of the buffer we use as scratch space for integer
+ * conversions, among other things. Technically, we would need the
+ * most space for base 10 conversions with thousands' grouping
+ * characters between each pair of digits. 100 bytes is a
+ * conservative overestimate even for a 128-bit uintmax_t.
+ */
+#define BUF 100
+
+#define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */
+
+/*
+ * Flags used during conversion.
+ */
+#define ALT 0x001 /* alternate form */
+#define LADJUST 0x004 /* left adjustment */
+#define LONGDBL 0x008 /* long double */
+#define LONGINT 0x010 /* long integer */
+#define LLONGINT 0x020 /* long long integer */
+#define SHORTINT 0x040 /* short integer */
+#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */
+#define FPT 0x100 /* Floating point number */
+#define GROUPING 0x200 /* use grouping ("'" flag) */
+ /* C99 additional size modifiers: */
+#define SIZET 0x400 /* size_t */
+#define PTRDIFFT 0x800 /* ptrdiff_t */
+#define INTMAXT 0x1000 /* intmax_t */
+#define CHARINT 0x2000 /* print char using int format */
+
+/*
+ * Non-MT-safe version
+ */
+int
+WDECL(__vf,printf_unlocked)(FILE *fp, const CHAR_T *fmt0, va_list ap)
+{
+ CHAR_T *fmt; /* format string */
+ int ch; /* character from fmt */
+ int n, n2; /* handy integer (short term usage) */
+ CHAR_T *cp; /* handy char pointer (short term usage) */
+ int flags; /* flags as above */
+ int ret; /* return value accumulator (number of items converted)*/
+ int width; /* width from format (%8d), or 0 */
+ int prec; /* precision from format; <0 for N/A */
+ CHAR_T sign; /* sign prefix (' ', '+', '-', or \0) */
+ char thousands_sep; /* locale specific thousands separator */
+ const char *grouping; /* locale specific numeric grouping rules */
+#ifndef NO_FLOATING_POINT
+ /*
+ * We can decompose the printed representation of floating
+ * point numbers into several parts, some of which may be empty:
+ *
+ * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ
+ * A B ---C--- D E F
+ *
+ * A: 'sign' holds this value if present; '\0' otherwise
+ * B: ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal
+ * C: cp points to the string MMMNNN. Leading and trailing
+ * zeros are not in the string and must be added.
+ * D: expchar holds this character; '\0' if no exponent, e.g. %f
+ * F: at least two digits for decimal, at least one digit for hex
+ */
+ char *decimal_point; /* locale specific decimal point */
+#ifdef WIDE_DOUBLE
+ int signflag; /* true if float is negative */
+ union { /* floating point arguments %[aAeEfFgG] */
+ double dbl;
+ long double ldbl;
+ } fparg;
+ char *dtoaend; /* pointer to end of converted digits */
+#else
+ double _double; /* double precision arguments %[eEfgG] */
+ char softsign; /* temporary negative sign for floats */
+#endif
+ char *dtoaresult; /* buffer allocated by dtoa */
+ int expt = 0; /* integer value of exponent */
+ char expchar; /* exponent character: [eEpP\0] */
+ int expsize; /* character count for expstr */
+ int lead; /* sig figs before decimal or group sep */
+ int ndig; /* actual number of digits returned by dtoa */
+ CHAR_T expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */
+ int nseps; /* number of group separators with ' */
+ int nrepeats; /* number of repeats of the last group */
+#endif
+ u_long ulval; /* integer arguments %[diouxX] */
+ uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */
+ int base; /* base for [diouxX] conversion */
+ int dprec; /* a copy of prec if [diouxX], 0 otherwise */
+ int realsz; /* field size expanded by dprec, sign, etc */
+ int size; /* size of converted field or string */
+ int prsize; /* max size of printed field */
+ const char *xdigs; /* digits for %[xX] conversion */
+#ifdef NARROW
+#define NIOV 8
+ struct __siov *iovp; /* for PRINT macro */
+ struct __suio uio; /* output information: summary */
+ struct __siov iov[NIOV];/* ... and individual io vectors */
+#else
+ int n3;
+#endif
+ CHAR_T buf[BUF]; /* buffer with space for digits of uintmax_t */
+ CHAR_T ox[2]; /* space for 0x hex-prefix */
+ union arg *argtable; /* args, built due to positional arg */
+ union arg statargtable [STATIC_ARG_TBL_SIZE];
+ int nextarg; /* 1-based argument index */
+ va_list orgap; /* original argument pointer */
+ CHAR_T *convbuf; /* multibyte to wide conversion result */
+
+ /*
+ * Choose PADSIZE to trade efficiency vs. size. If larger printf
+ * fields occur frequently, increase PADSIZE and make the initialisers
+ * below longer.
+ */
+#define PADSIZE 16 /* pad chunk size */
+ static CHAR_T blanks[PADSIZE] =
+ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
+ static CHAR_T zeroes[PADSIZE] =
+ {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
+
+ static const char xdigs_lower[17] = "0123456789abcdef";
+ static const char xdigs_upper[17] = "0123456789ABCDEF";
+
+ /*
+ * BEWARE, these `goto error' on error, PRINT uses `n2' and
+ * PAD uses `n'.
+ */
+#ifndef NARROW
+#define PRINT(ptr, len) do { \
+ for (n3 = 0; n3 < (len); n3++) \
+ __xfputwc((ptr)[n3], fp); \
+} while (/*CONSTCOND*/0)
+#define FLUSH()
+#else
+#define PRINT(ptr, len) do { \
+ iovp->iov_base = __UNCONST(ptr); \
+ iovp->iov_len = (len); \
+ uio.uio_resid += (len); \
+ iovp++; \
+ if (++uio.uio_iovcnt >= NIOV) { \
+ if (__sprint(fp, &uio)) \
+ goto error; \
+ iovp = iov; \
+ } \
+} while (/*CONSTCOND*/0)
+#define FLUSH() do { \
+ if (uio.uio_resid && __sprint(fp, &uio)) \
+ goto error; \
+ uio.uio_iovcnt = 0; \
+ iovp = iov; \
+} while (/*CONSTCOND*/0)
+#endif /* NARROW */
+
+#define PAD(howmany, with) do { \
+ if ((n = (howmany)) > 0) { \
+ while (n > PADSIZE) { \
+ PRINT(with, PADSIZE); \
+ n -= PADSIZE; \
+ } \
+ PRINT(with, n); \
+ } \
+} while (/*CONSTCOND*/0)
+#define PRINTANDPAD(p, ep, len, with) do { \
+ n2 = (ep) - (p); \
+ if (n2 > (len)) \
+ n2 = (len); \
+ if (n2 > 0) \
+ PRINT((p), n2); \
+ PAD((len) - (n2 > 0 ? n2 : 0), (with)); \
+} while(/*CONSTCOND*/0)
+
+ /*
+ * Get the argument indexed by nextarg. If the argument table is
+ * built, use it to get the argument. If its not, get the next
+ * argument (and arguments must be gotten sequentially).
+ */
+#define GETARG(type) \
+ ((/*CONSTCOND*/argtable != NULL) ? *((type*)(void*)(&argtable[nextarg++])) : \
+ (nextarg++, va_arg(ap, type)))
+
+ /*
+ * To extend shorts properly, we need both signed and unsigned
+ * argument extraction methods.
+ */
+#define SARG() \
+ ((long)(flags&LONGINT ? GETARG(long) : \
+ flags&SHORTINT ? (short)GETARG(int) : \
+ flags&CHARINT ? (signed char)GETARG(int) : \
+ GETARG(int)))
+
+#define UARG() \
+ ((u_long)(flags&LONGINT ? GETARG(u_long) : \
+ flags&SHORTINT ? (u_long)(u_short)GETARG(int) : \
+ flags&CHARINT ? (u_long)(u_char)GETARG(int) : \
+ (u_long)GETARG(u_int)))
+
+#define INTMAX_SIZE (INTMAXT|SIZET|PTRDIFFT|LLONGINT)
+
+#define SJARG() \
+ (flags&INTMAXT ? GETARG(intmax_t) : \
+ flags&SIZET ? (intmax_t)GETARG(size_t) : \
+ flags&PTRDIFFT ? (intmax_t)GETARG(ptrdiff_t) : \
+ (intmax_t)GETARG(long long))
+
+#define UJARG() \
+ (flags&INTMAXT ? GETARG(uintmax_t) : \
+ flags&SIZET ? (uintmax_t)GETARG(size_t) : \
+ flags&PTRDIFFT ? (uintmax_t)GETARG(ptrdiff_t) : \
+ (uintmax_t)GETARG(unsigned long long))
+
+ /*
+ * Get * arguments, including the form *nn$. Preserve the nextarg
+ * that the argument can be gotten once the type is determined.
+ */
+#define GETASTER(val) \
+ n2 = 0; \
+ cp = fmt; \
+ while (is_digit(*cp)) { \
+ n2 = 10 * n2 + to_digit(*cp); \
+ cp++; \
+ } \
+ if (*cp == '$') { \
+ int hold = nextarg; \
+ if (argtable == NULL) { \
+ argtable = statargtable; \
+ if (__find_arguments(fmt0, orgap, &argtable) == -1) \
+ goto oomem; \
+ } \
+ nextarg = n2; \
+ val = GETARG (int); \
+ nextarg = hold; \
+ fmt = ++cp; \
+ } else { \
+ val = GETARG (int); \
+ }
+
+ _DIAGASSERT(fp != NULL);
+ _DIAGASSERT(fmt0 != NULL);
+
+ _SET_ORIENTATION(fp, -1);
+
+ ndig = -1; /* XXX gcc */
+
+ thousands_sep = '\0';
+ grouping = NULL;
+#ifndef NO_FLOATING_POINT
+ decimal_point = localeconv()->decimal_point;
+ expsize = 0; /* XXXGCC -Wuninitialized [sh3,m68000] */
+#endif
+ convbuf = NULL;
+ /* sorry, f{w,}printf(read_only_file, L"") returns {W,}EOF, not 0 */
+ if (cantwrite(fp)) {
+ errno = EBADF;
+ return (END_OF_FILE);
+ }
+
+ /* optimise fprintf(stderr) (and other unbuffered Unix files) */
+ if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
+ fp->_file >= 0)
+ return (__sbprintf(fp, fmt0, ap));
+
+ fmt = (CHAR_T *)__UNCONST(fmt0);
+ argtable = NULL;
+ nextarg = 1;
+ va_copy(orgap, ap);
+#ifdef NARROW
+ uio.uio_iov = iovp = iov;
+ uio.uio_resid = 0;
+ uio.uio_iovcnt = 0;
+#endif
+ ret = 0;
+
+ /*
+ * Scan the format for conversions (`%' character).
+ */
+ for (;;)
+ {
+ const CHAR_T *result;
+
+ for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
+ continue;
+ if ((n = (int)(fmt - cp)) != 0) {
+ if ((unsigned)ret + n > INT_MAX) {
+ ret = END_OF_FILE;
+ goto error;
+ }
+ PRINT(cp, n);
+ ret += n;
+ }
+ if (ch == '\0')
+ goto done;
+ fmt++; /* skip over '%' */
+
+ flags = 0;
+ dprec = 0;
+ width = 0;
+ prec = -1;
+ sign = '\0';
+ ox[1] = '\0';
+ expchar = '\0';
+ lead = 0;
+ nseps = nrepeats = 0;
+ ulval = 0;
+ ujval = 0;
+ xdigs = NULL;
+
+rflag: ch = *fmt++;
+reswitch: switch (ch) {
+ case ' ':
+ /*-
+ * ``If the space and + flags both appear, the space
+ * flag will be ignored.''
+ * -- ANSI X3J11
+ */
+ if (!sign)
+ sign = ' ';
+ goto rflag;
+ case '#':
+ flags |= ALT;
+ goto rflag;
+ case '*':
+ /*-
+ * ``A negative field width argument is taken as a
+ * - flag followed by a positive field width.''
+ * -- ANSI X3J11
+ * They don't exclude field widths read from args.
+ */
+ GETASTER (width);
+ if (width >= 0)
+ goto rflag;
+ width = -width;
+ /* FALLTHROUGH */
+ case '-':
+ flags |= LADJUST;
+ goto rflag;
+ case '+':
+ sign = '+';
+ goto rflag;
+ case '\'':
+ flags |= GROUPING;
+ thousands_sep = *(localeconv()->thousands_sep);
+ grouping = localeconv()->grouping;
+ goto rflag;
+ case '.':
+ if ((ch = *fmt++) == '*') {
+ GETASTER (prec);
+ goto rflag;
+ }
+ prec = 0;
+ while (is_digit(ch)) {
+ prec = 10 * prec + to_digit(ch);
+ ch = *fmt++;
+ }
+ goto reswitch;
+ case '0':
+ /*-
+ * ``Note that 0 is taken as a flag, not as the
+ * beginning of a field width.''
+ * -- ANSI X3J11
+ */
+ flags |= ZEROPAD;
+ goto rflag;
+ case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ n = 0;
+ do {
+ n = 10 * n + to_digit(ch);
+ ch = *fmt++;
+ } while (is_digit(ch));
+ if (ch == '$') {
+ nextarg = n;
+ if (argtable == NULL) {
+ argtable = statargtable;
+ if (__find_arguments(fmt0, orgap,
+ &argtable) == -1)
+ goto oomem;
+ }
+ goto rflag;
+ }
+ width = n;
+ goto reswitch;
+#ifndef NO_FLOATING_POINT
+ case 'L':
+ flags |= LONGDBL;
+ goto rflag;
+#endif
+ case 'h':
+ if (flags & SHORTINT) {
+ flags &= ~SHORTINT;
+ flags |= CHARINT;
+ } else
+ flags |= SHORTINT;
+ goto rflag;
+ case 'j':
+ flags |= INTMAXT;
+ goto rflag;
+ case 'l':
+ if (flags & LONGINT) {
+ flags &= ~LONGINT;
+ flags |= LLONGINT;
+ } else
+ flags |= LONGINT;
+ goto rflag;
+ case 'q':
+ flags |= LLONGINT; /* not necessarily */
+ goto rflag;
+ case 't':
+ flags |= PTRDIFFT;
+ goto rflag;
+ case 'z':
+ flags |= SIZET;
+ goto rflag;
+ case 'C':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'c':
+#ifdef NARROW
+ if (flags & LONGINT) {
+ static const mbstate_t initial = { 0 };
+ mbstate_t mbs;
+ size_t mbseqlen;
+
+ mbs = initial;
+ mbseqlen = wcrtomb(buf,
+ (wchar_t)GETARG(wint_t), &mbs);
+ if (mbseqlen == (size_t)-1) {
+ fp->_flags |= __SERR;
+ goto error;
+ }
+ size = (int)mbseqlen;
+ } else {
+ *buf = (char)(GETARG(int));
+ size = 1;
+ }
+#else
+ if (flags & LONGINT)
+ *buf = (wchar_t)GETARG(wint_t);
+ else
+ *buf = (wchar_t)btowc(GETARG(int));
+ size = 1;
+#endif
+ result = buf;
+ sign = '\0';
+ break;
+ case 'D':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'd':
+ case 'i':
+ if (flags & INTMAX_SIZE) {
+ ujval = SJARG();
+ if ((intmax_t)ujval < 0) {
+ ujval = (uintmax_t)(-((intmax_t)ujval));
+ sign = '-';
+ }
+ } else {
+ ulval = SARG();
+ if ((long)ulval < 0) {
+ ulval = (u_long)(-((long)ulval));
+ sign = '-';
+ }
+ }
+ base = 10;
+ goto number;
+#ifndef NO_FLOATING_POINT
+#ifdef WIDE_DOUBLE
+ case 'a':
+ case 'A':
+ if (ch == 'a') {
+ ox[1] = 'x';
+ xdigs = xdigs_lower;
+ expchar = 'p';
+ } else {
+ ox[1] = 'X';
+ xdigs = xdigs_upper;
+ expchar = 'P';
+ }
+ if (prec >= 0)
+ prec++;
+ if (flags & LONGDBL) {
+ fparg.ldbl = GETARG(long double);
+ dtoaresult =
+ __hldtoa(fparg.ldbl, xdigs, prec,
+ &expt, &signflag, &dtoaend);
+ } else {
+ fparg.dbl = GETARG(double);
+ dtoaresult =
+ __hdtoa(fparg.dbl, xdigs, prec,
+ &expt, &signflag, &dtoaend);
+ }
+ if (dtoaresult == NULL)
+ goto oomem;
+
+ if (prec < 0)
+ prec = dtoaend - dtoaresult;
+ if (expt == INT_MAX)
+ ox[1] = '\0';
+ ndig = dtoaend - dtoaresult;
+ if (convbuf != NULL)
+ free(convbuf);
+#ifndef NARROW
+ result = convbuf = __mbsconv(dtoaresult, -1);
+#else
+ /*XXX inefficient*/
+ result = convbuf = strdup(dtoaresult);
+#endif
+ if (result == NULL)
+ goto oomem;
+ __freedtoa(dtoaresult);
+ goto fp_common;
+ case 'e':
+ case 'E':
+ expchar = ch;
+ if (prec < 0) /* account for digit before decpt */
+ prec = DEFPREC + 1;
+ else
+ prec++;
+ goto fp_begin;
+ case 'f':
+ case 'F':
+ expchar = '\0';
+ goto fp_begin;
+ case 'g':
+ case 'G':
+ expchar = ch - ('g' - 'e');
+ if (prec == 0)
+ prec = 1;
+fp_begin:
+ if (prec < 0)
+ prec = DEFPREC;
+ if (flags & LONGDBL) {
+ fparg.ldbl = GETARG(long double);
+ dtoaresult =
+ __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec,
+ &expt, &signflag, &dtoaend);
+ } else {
+ fparg.dbl = GETARG(double);
+ dtoaresult =
+ __dtoa(fparg.dbl, expchar ? 2 : 3, prec,
+ &expt, &signflag, &dtoaend);
+ if (expt == 9999)
+ expt = INT_MAX;
+ }
+ if (dtoaresult == NULL)
+ goto oomem;
+ ndig = dtoaend - dtoaresult;
+ if (convbuf != NULL)
+ free(convbuf);
+#ifndef NARROW
+ result = convbuf = __mbsconv(dtoaresult, -1);
+#else
+ /*XXX inefficient*/
+ result = convbuf = strdup(dtoaresult);
+#endif
+ if (result == NULL)
+ goto oomem;
+ __freedtoa(dtoaresult);
+fp_common:
+ if (signflag)
+ sign = '-';
+ if (expt == INT_MAX) { /* inf or nan */
+ if (*result == 'N') {
+ result = (ch >= 'a') ? STRCONST("nan") :
+ STRCONST("NAN");
+ sign = '\0';
+ } else
+ result = (ch >= 'a') ? STRCONST("inf") :
+ STRCONST("INF");
+ size = 3;
+ break;
+ }
+#else
+ //case 'e':
+ //case 'E':
+ //case 'f':
+ //case 'F':
+ //case 'g':
+ //case 'G':
+ // if (prec == -1) {
+ // prec = DEFPREC;
+ // } else if ((ch == 'g' || ch == 'G') && prec == 0) {
+ // prec = 1;
+ // }
+ case 'e':
+ case 'E':
+ expchar = ch;
+ if (prec < 0) /* account for digit before decpt */
+ prec = DEFPREC /* + 1*/ ;
+ else
+ prec++;
+ goto fp_begin;
+ case 'f':
+ case 'F':
+ expchar = '\0';
+ goto fp_begin;
+ case 'g':
+ case 'G':
+ expchar = ch - ('g' - 'e');
+ if (prec == 0)
+ prec = 1;
+fp_begin:
+ if (prec < 0)
+ prec = DEFPREC;
+
+ if (flags & LONGDBL) {
+ _double = (double) GETARG(long double);
+ } else {
+ _double = GETARG(double);
+ }
+
+ /* do this before tricky precision changes */
+ if (isinf(_double)) {
+ if (_double < 0)
+ sign = '-';
+ if (ch == 'E' || ch == 'F' || ch == 'G')
+ result = STRCONST("INF");
+ else
+ result = STRCONST("inf");
+ size = 3;
+ break;
+ }
+ if (isnan(_double)) {
+ if (ch == 'E' || ch == 'F' || ch == 'G')
+ result = STRCONST("NAN");
+ else
+ result = STRCONST("nan");
+ size = 3;
+ break;
+ }
+
+ flags |= FPT;
+ dtoaresult = cvt(_double, prec, flags, &softsign, &expt, ch, &ndig);
+ if (dtoaresult == NULL)
+ goto oomem;
+ if (convbuf != NULL)
+ free(convbuf);
+#ifndef NARROW
+ result = convbuf = __mbsconv(dtoaresult, -1);
+#else
+ /*XXX inefficient*/
+ result = convbuf = strdup(dtoaresult);
+#endif
+ if (result == NULL)
+ goto oomem;
+ __freedtoa(dtoaresult);
+ if (softsign)
+ sign = '-';
+#endif
+ flags |= FPT;
+ if (ch == 'g' || ch == 'G') {
+ if (expt > -4 && expt <= prec) {
+ /* Make %[gG] smell like %[fF] */
+ expchar = '\0';
+ if (flags & ALT)
+ prec -= expt;
+ else
+ prec = ndig - expt;
+ if (prec < 0)
+ prec = 0;
+ } else {
+ /*
+ * Make %[gG] smell like %[eE], but
+ * trim trailing zeroes if no # flag.
+ */
+ if (!(flags & ALT))
+ prec = ndig;
+ }
+ }
+ if (expchar) {
+ expsize = exponent(expstr, expt - 1, expchar);
+ size = expsize + prec;
+ if (prec > 1 || flags & ALT)
+ ++size;
+ } else {
+ /* space for digits before decimal point */
+ if (expt > 0)
+ size = expt;
+ else /* "0" */
+ size = 1;
+ /* space for decimal pt and following digits */
+ if (prec || flags & ALT)
+ size += prec + 1;
+ if (grouping && expt > 0) {
+ /* space for thousands' grouping */
+ nseps = nrepeats = 0;
+ lead = expt;
+ while (*grouping != CHAR_MAX) {
+ if (lead <= *grouping)
+ break;
+ lead -= *grouping;
+ if (*(grouping+1)) {
+ nseps++;
+ grouping++;
+ } else
+ nrepeats++;
+ }
+ size += nseps + nrepeats;
+ } else
+ lead = expt;
+ }
+ break;
+#endif /* !NO_FLOATING_POINT */
+ case 'n':
+ /*
+ * Assignment-like behavior is specified if the
+ * value overflows or is otherwise unrepresentable.
+ * C99 says to use `signed char' for %hhn conversions.
+ */
+ if (flags & LLONGINT)
+ *GETARG(long long *) = ret;
+ else if (flags & SIZET)
+ *GETARG(ssize_t *) = (ssize_t)ret;
+ else if (flags & PTRDIFFT)
+ *GETARG(ptrdiff_t *) = ret;
+ else if (flags & INTMAXT)
+ *GETARG(intmax_t *) = ret;
+ else if (flags & LONGINT)
+ *GETARG(long *) = ret;
+ else if (flags & SHORTINT)
+ *GETARG(short *) = ret;
+ else if (flags & CHARINT)
+ *GETARG(signed char *) = ret;
+ else
+ *GETARG(int *) = ret;
+ continue; /* no output */
+ case 'O':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'o':
+ if (flags & INTMAX_SIZE)
+ ujval = UJARG();
+ else
+ ulval = UARG();
+ base = 8;
+ goto nosign;
+ case 'p':
+ /*-
+ * ``The argument shall be a pointer to void. The
+ * value of the pointer is converted to a sequence
+ * of printable characters, in an implementation-
+ * defined manner.''
+ * -- ANSI X3J11
+ */
+ ujval = (uintmax_t)GETARG(void *);
+ base = 16;
+ xdigs = xdigs_lower;
+ flags = flags | INTMAXT;
+ ox[1] = 'x';
+ goto nosign;
+ case 'S':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 's':
+ if ((flags & LONGINT) != MULTI) {
+ if ((result = GETARG(CHAR_T *)) == NULL)
+ result = STRCONST("(null)");
+ } else {
+ MCHAR_T *mc;
+
+ if (convbuf != NULL)
+ free(convbuf);
+ if ((mc = GETARG(MCHAR_T *)) == NULL)
+ result = STRCONST("(null)");
+ else {
+ convbuf = SCONV(mc, prec);
+ if (convbuf == NULL) {
+ fp->_flags |= __SERR;
+ goto error;
+ }
+ result = convbuf;
+ }
+ }
+
+ if (prec >= 0) {
+ /*
+ * can't use STRLEN; can only look for the
+ * NUL in the first `prec' characters, and
+ * STRLEN() will go further.
+ */
+ CHAR_T *p = MEMCHR(result, 0, (size_t)prec);
+
+ if (p != NULL) {
+ size = p - result;
+ if (size > prec)
+ size = prec;
+ } else
+ size = prec;
+ } else
+ size = (int)STRLEN(result);
+ sign = '\0';
+ break;
+ case 'U':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'u':
+ if (flags & INTMAX_SIZE)
+ ujval = UJARG();
+ else
+ ulval = UARG();
+ base = 10;
+ goto nosign;
+ case 'X':
+ xdigs = xdigs_upper;
+ goto hex;
+ case 'x':
+ xdigs = xdigs_lower;
+hex:
+ if (flags & INTMAX_SIZE)
+ ujval = UJARG();
+ else
+ ulval = UARG();
+ base = 16;
+ /* leading 0x/X only if non-zero */
+ if (flags & ALT &&
+ (flags & INTMAX_SIZE ? ujval != 0 : ulval != 0))
+ ox[1] = ch;
+
+ flags &= ~GROUPING;
+ /* unsigned conversions */
+nosign: sign = '\0';
+ /*-
+ * ``... diouXx conversions ... if a precision is
+ * specified, the 0 flag will be ignored.''
+ * -- ANSI X3J11
+ */
+number: if ((dprec = prec) >= 0)
+ flags &= ~ZEROPAD;
+
+ /*-
+ * ``The result of converting a zero value with an
+ * explicit precision of zero is no characters.''
+ * -- ANSI X3J11
+ *
+ * ``The C Standard is clear enough as is. The call
+ * printf("%#.0o", 0) should print 0.''
+ * -- Defect Report #151
+ */
+ result = cp = buf + BUF;
+ if (flags & INTMAX_SIZE) {
+ if (ujval != 0 || prec != 0 ||
+ (flags & ALT && base == 8))
+ {
+ result = __ujtoa(ujval, cp, base,
+ flags & ALT, xdigs,
+ flags & GROUPING, thousands_sep,
+ grouping);
+ }
+ } else {
+ if (ulval != 0 || prec != 0 ||
+ (flags & ALT && base == 8))
+ result = __ultoa(ulval, cp, base,
+ flags & ALT, xdigs,
+ flags & GROUPING, thousands_sep,
+ grouping);
+ }
+ size = buf + BUF - result;
+ if (size > BUF) /* should never happen */
+ abort();
+ break;
+ default: /* "%?" prints ?, unless ? is NUL */
+ if (ch == '\0')
+ goto done;
+ /* pretend it was %c with argument ch */
+ *buf = ch;
+ result = buf;
+ size = 1;
+ sign = '\0';
+ break;
+ }
+
+ /*
+ * All reasonable formats wind up here. At this point, `result'
+ * points to a string which (if not flags&LADJUST) should be
+ * padded out to `width' places. If flags&ZEROPAD, it should
+ * first be prefixed by any sign or other prefix; otherwise,
+ * it should be blank padded before the prefix is emitted.
+ * After any left-hand padding and prefixing, emit zeroes
+ * required by a decimal [diouxX] precision, then print the
+ * string proper, then emit zeroes required by any leftover
+ * floating precision; finally, if LADJUST, pad with blanks.
+ *
+ * Compute actual size, so we know how much to pad.
+ * size excludes decimal prec; realsz includes it.
+ */
+ realsz = dprec > size ? dprec : size;
+ if (sign)
+ realsz++;
+ if (ox[1])
+ realsz += 2;
+
+ prsize = width > realsz ? width : realsz;
+ if ((unsigned)ret + prsize > INT_MAX) {
+ ret = END_OF_FILE;
+ goto error;
+ }
+
+ /* right-adjusting blank padding */
+ if ((flags & (LADJUST|ZEROPAD)) == 0)
+ PAD(width - realsz, blanks);
+
+ /* prefix */
+ if (sign)
+ PRINT(&sign, 1);
+
+ if (ox[1]) { /* ox[1] is either x, X, or \0 */
+ ox[0] = '0';
+ PRINT(ox, 2);
+ }
+
+ /* right-adjusting zero padding */
+ if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
+ PAD(width - realsz, zeroes);
+
+ /* leading zeroes from decimal precision */
+ PAD(dprec - size, zeroes);
+
+ /* the string or number proper */
+#ifndef NO_FLOATING_POINT
+ if ((flags & FPT) == 0) {
+ PRINT(result, size);
+ } else { /* glue together f_p fragments */
+ if (!expchar) { /* %[fF] or sufficiently short %[gG] */
+ if (expt <= 0) {
+ PRINT(zeroes, 1);
+ if (prec || flags & ALT)
+ PRINT(decimal_point, 1);
+ PAD(-expt, zeroes);
+ /* already handled initial 0's */
+ prec += expt;
+ } else {
+ PRINTANDPAD(result, convbuf + ndig,
+ lead, zeroes);
+ result += lead;
+ if (grouping) {
+ while (nseps>0 || nrepeats>0) {
+ if (nrepeats > 0)
+ nrepeats--;
+ else {
+ grouping--;
+ nseps--;
+ }
+ PRINT(&thousands_sep,
+ 1);
+ PRINTANDPAD(result,
+ convbuf + ndig,
+ *grouping, zeroes);
+ result += *grouping;
+ }
+ if (result > convbuf + ndig)
+ result = convbuf + ndig;
+ }
+ if (prec || flags & ALT) {
+ buf[0] = *decimal_point;
+ PRINT(buf, 1);
+ }
+ }
+ PRINTANDPAD(result, convbuf + ndig, prec,
+ zeroes);
+ } else { /* %[eE] or sufficiently long %[gG] */
+ if (prec > 1 || flags & ALT) {
+ buf[0] = *result++;
+ buf[1] = *decimal_point;
+ PRINT(buf, 2);
+ PRINT(result, ndig-1);
+ PAD(prec - ndig, zeroes);
+ } else /* XeYYY */
+ PRINT(result, 1);
+ PRINT(expstr, expsize);
+ }
+ }
+#else
+ PRINT(result, size);
+#endif
+ /* left-adjusting padding (always blank) */
+ if (flags & LADJUST)
+ PAD(width - realsz, blanks);
+
+ /* finally, adjust ret */
+ ret += prsize;
+ FLUSH();
+ }
+done:
+ FLUSH();
+error:
+ va_end(orgap);
+ if (convbuf != NULL)
+ free(convbuf);
+ if (__sferror(fp))
+ ret = END_OF_FILE;
+ if ((argtable != NULL) && (argtable != statargtable))
+ free (argtable);
+ return (ret);
+ /* NOTREACHED */
+oomem:
+ errno = ENOMEM;
+ ret = END_OF_FILE;
+ goto error;
+}
+
+/*
+ * Find all arguments when a positional parameter is encountered. Returns a
+ * table, indexed by argument number, of pointers to each arguments. The
+ * initial argument table should be an array of STATIC_ARG_TBL_SIZE entries.
+ * It will be replaces with a malloc-ed one if it overflows.
+ */
+static int
+__find_arguments(const CHAR_T *fmt0, va_list ap, union arg **argtable)
+{
+ CHAR_T *fmt; /* format string */
+ int ch; /* character from fmt */
+ int n, n2; /* handy integer (short term usage) */
+ CHAR_T *cp; /* handy char pointer (short term usage) */
+ int flags; /* flags as above */
+ enum typeid *typetable; /* table of types */
+ enum typeid stattypetable [STATIC_ARG_TBL_SIZE];
+ int tablesize; /* current size of type table */
+ int tablemax; /* largest used index in table */
+ int nextarg; /* 1-based argument index */
+
+ /*
+ * Add an argument type to the table, expanding if necessary.
+ */
+#define ADDTYPE(type) \
+ do { \
+ if (nextarg >= tablesize) \
+ if (__grow_type_table(nextarg, &typetable, \
+ &tablesize) == -1) \
+ return -1; \
+ if (nextarg > tablemax) \
+ tablemax = nextarg; \
+ typetable[nextarg++] = type; \
+ } while (/*CONSTCOND*/0)
+
+#define ADDSARG() \
+ do { \
+ if (flags & INTMAXT) \
+ ADDTYPE(T_INTMAXT); \
+ else if (flags & SIZET) \
+ ADDTYPE(T_SIZET); \
+ else if (flags & PTRDIFFT) \
+ ADDTYPE(T_PTRDIFFT); \
+ else if (flags & LLONGINT) \
+ ADDTYPE(T_LLONG); \
+ else if (flags & LONGINT) \
+ ADDTYPE(T_LONG); \
+ else \
+ ADDTYPE(T_INT); \
+ } while (/*CONSTCOND*/0)
+
+#define ADDUARG() \
+ do { \
+ if (flags & INTMAXT) \
+ ADDTYPE(T_UINTMAXT); \
+ else if (flags & SIZET) \
+ ADDTYPE(T_SIZET); \
+ else if (flags & PTRDIFFT) \
+ ADDTYPE(T_PTRDIFFT); \
+ else if (flags & LLONGINT) \
+ ADDTYPE(T_U_LLONG); \
+ else if (flags & LONGINT) \
+ ADDTYPE(T_U_LONG); \
+ else \
+ ADDTYPE(T_U_INT); \
+ } while (/*CONSTCOND*/0)
+ /*
+ * Add * arguments to the type array.
+ */
+#define ADDASTER() \
+ n2 = 0; \
+ cp = fmt; \
+ while (is_digit(*cp)) { \
+ n2 = 10 * n2 + to_digit(*cp); \
+ cp++; \
+ } \
+ if (*cp == '$') { \
+ int hold = nextarg; \
+ nextarg = n2; \
+ ADDTYPE(T_INT); \
+ nextarg = hold; \
+ fmt = ++cp; \
+ } else { \
+ ADDTYPE(T_INT); \
+ }
+ fmt = (CHAR_T *)__UNCONST(fmt0);
+ typetable = stattypetable;
+ tablesize = STATIC_ARG_TBL_SIZE;
+ tablemax = 0;
+ nextarg = 1;
+ for (n = 0; n < STATIC_ARG_TBL_SIZE; n++)
+ typetable[n] = T_UNUSED;
+
+ /*
+ * Scan the format for conversions (`%' character).
+ */
+ for (;;) {
+ for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
+ /* void */;
+ if (ch == '\0')
+ goto done;
+ fmt++; /* skip over '%' */
+
+ flags = 0;
+
+rflag: ch = *fmt++;
+reswitch: switch (ch) {
+ case ' ':
+ case '#':
+ goto rflag;
+ case '*':
+ ADDASTER ();
+ goto rflag;
+ case '-':
+ case '+':
+ case '\'':
+ goto rflag;
+ case '.':
+ if ((ch = *fmt++) == '*') {
+ ADDASTER ();
+ goto rflag;
+ }
+ while (is_digit(ch)) {
+ ch = *fmt++;
+ }
+ goto reswitch;
+ case '0':
+ goto rflag;
+ case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ n = 0;
+ do {
+ n = 10 * n + to_digit(ch);
+ ch = *fmt++;
+ } while (is_digit(ch));
+ if (ch == '$') {
+ nextarg = n;
+ goto rflag;
+ }
+ goto reswitch;
+#ifndef NO_FLOATING_POINT
+ case 'L':
+ flags |= LONGDBL;
+ goto rflag;
+#endif
+ case 'h':
+ if (flags & SHORTINT) {
+ flags &= ~SHORTINT;
+ flags |= CHARINT;
+ } else
+ flags |= SHORTINT;
+ goto rflag;
+ case 'j':
+ flags |= INTMAXT;
+ goto rflag;
+ case 'l':
+ if (flags & LONGINT) {
+ flags &= ~LONGINT;
+ flags |= LLONGINT;
+ } else
+ flags |= LONGINT;
+ goto rflag;
+ case 'q':
+ flags |= LLONGINT; /* not necessarily */
+ goto rflag;
+ case 't':
+ flags |= PTRDIFFT;
+ goto rflag;
+ case 'z':
+ flags |= SIZET;
+ goto rflag;
+ case 'C':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'c':
+ if (flags & LONGINT)
+ ADDTYPE(T_WINT);
+ else
+ ADDTYPE(T_INT);
+ break;
+ case 'D':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'd':
+ case 'i':
+ ADDSARG();
+ break;
+#ifndef NO_FLOATING_POINT
+ case 'a':
+ case 'A':
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'g':
+ case 'G':
+ if (flags & LONGDBL)
+ ADDTYPE(T_LONG_DOUBLE);
+ else
+ ADDTYPE(T_DOUBLE);
+ break;
+#endif /* !NO_FLOATING_POINT */
+ case 'n':
+ if (flags & INTMAXT)
+ ADDTYPE(TP_INTMAXT);
+ else if (flags & PTRDIFFT)
+ ADDTYPE(TP_PTRDIFFT);
+ else if (flags & SIZET)
+ ADDTYPE(TP_SIZET);
+ else if (flags & LLONGINT)
+ ADDTYPE(TP_LLONG);
+ else if (flags & LONGINT)
+ ADDTYPE(TP_LONG);
+ else if (flags & SHORTINT)
+ ADDTYPE(TP_SHORT);
+ else if (flags & CHARINT)
+ ADDTYPE(TP_SCHAR);
+ else
+ ADDTYPE(TP_INT);
+ continue; /* no output */
+ case 'O':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'o':
+ ADDUARG();
+ break;
+ case 'p':
+ ADDTYPE(TP_VOID);
+ break;
+ case 'S':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 's':
+ if (flags & LONGINT)
+ ADDTYPE(TP_WCHAR);
+ else
+ ADDTYPE(TP_CHAR);
+ break;
+ case 'U':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'u':
+ case 'X':
+ case 'x':
+ ADDUARG();
+ break;
+ default: /* "%?" prints ?, unless ? is NUL */
+ if (ch == '\0')
+ goto done;
+ break;
+ }
+ }
+done:
+ /*
+ * Build the argument table.
+ */
+ if (tablemax >= STATIC_ARG_TBL_SIZE) {
+ *argtable = (union arg *)
+ malloc (sizeof (union arg) * (tablemax + 1));
+ if (*argtable == NULL)
+ return -1;
+ }
+
+ (*argtable) [0].intarg = 0;
+ for (n = 1; n <= tablemax; n++) {
+ switch (typetable [n]) {
+ case T_UNUSED: /* whoops! */
+ (*argtable) [n].intarg = va_arg (ap, int);
+ break;
+ case TP_SCHAR:
+ (*argtable) [n].pschararg = va_arg (ap, signed char *);
+ break;
+ case TP_SHORT:
+ (*argtable) [n].pshortarg = va_arg (ap, short *);
+ break;
+ case T_INT:
+ (*argtable) [n].intarg = va_arg (ap, int);
+ break;
+ case T_U_INT:
+ (*argtable) [n].uintarg = va_arg (ap, unsigned int);
+ break;
+ case TP_INT:
+ (*argtable) [n].pintarg = va_arg (ap, int *);
+ break;
+ case T_LONG:
+ (*argtable) [n].longarg = va_arg (ap, long);
+ break;
+ case T_U_LONG:
+ (*argtable) [n].ulongarg = va_arg (ap, unsigned long);
+ break;
+ case TP_LONG:
+ (*argtable) [n].plongarg = va_arg (ap, long *);
+ break;
+ case T_LLONG:
+ (*argtable) [n].longlongarg = va_arg (ap, long long);
+ break;
+ case T_U_LLONG:
+ (*argtable) [n].ulonglongarg = va_arg (ap, unsigned long long);
+ break;
+ case TP_LLONG:
+ (*argtable) [n].plonglongarg = va_arg (ap, long long *);
+ break;
+ case T_PTRDIFFT:
+ (*argtable) [n].ptrdiffarg = va_arg (ap, ptrdiff_t);
+ break;
+ case TP_PTRDIFFT:
+ (*argtable) [n].pptrdiffarg = va_arg (ap, ptrdiff_t *);
+ break;
+ case T_SIZET:
+ (*argtable) [n].sizearg = va_arg (ap, size_t);
+ break;
+ case TP_SIZET:
+ (*argtable) [n].psizearg = va_arg (ap, size_t *);
+ break;
+ case T_INTMAXT:
+ (*argtable) [n].intmaxarg = va_arg (ap, intmax_t);
+ break;
+ case T_UINTMAXT:
+ (*argtable) [n].uintmaxarg = va_arg (ap, uintmax_t);
+ break;
+ case TP_INTMAXT:
+ (*argtable) [n].pintmaxarg = va_arg (ap, intmax_t *);
+ break;
+ case T_DOUBLE:
+#ifndef NO_FLOATING_POINT
+ (*argtable) [n].doublearg = va_arg (ap, double);
+#endif
+ break;
+ case T_LONG_DOUBLE:
+#ifndef NO_FLOATING_POINT
+ (*argtable) [n].longdoublearg = va_arg (ap, long double);
+#endif
+ break;
+ case TP_CHAR:
+ (*argtable) [n].pchararg = va_arg (ap, char *);
+ break;
+ case TP_VOID:
+ (*argtable) [n].pvoidarg = va_arg (ap, void *);
+ break;
+ case T_WINT:
+ (*argtable) [n].wintarg = va_arg (ap, wint_t);
+ break;
+ case TP_WCHAR:
+ (*argtable) [n].pwchararg = va_arg (ap, wchar_t *);
+ break;
+ }
+ }
+
+ if ((typetable != NULL) && (typetable != stattypetable))
+ free (typetable);
+ return 0;
+}
+
+/*
+ * Increase the size of the type table.
+ */
+static int
+__grow_type_table (int nextarg, enum typeid **typetable, int *tablesize)
+{
+ enum typeid *const oldtable = *typetable;
+ const int oldsize = *tablesize;
+ enum typeid *newtable;
+ int n, newsize = oldsize * 2;
+
+ if (newsize < nextarg + 1)
+ newsize = nextarg + 1;
+ if (oldsize == STATIC_ARG_TBL_SIZE) {
+ if ((newtable = malloc(newsize * sizeof(enum typeid))) == NULL)
+ return -1;
+ memcpy(newtable, oldtable, oldsize * sizeof(enum typeid));
+ } else {
+ newtable = realloc(oldtable, newsize * sizeof(enum typeid));
+ if (newtable == NULL) {
+ free(oldtable);
+ return -1;
+ }
+ }
+ for (n = oldsize; n < newsize; n++)
+ newtable[n] = T_UNUSED;
+
+ *typetable = newtable;
+ *tablesize = newsize;
+ return 0;
+}
+
+
+#ifndef NO_FLOATING_POINT
+#ifndef WIDE_DOUBLE
+static char *
+cvt(double value, int ndigits, int flags, char *sign, int *decpt, int ch,
+ int *length)
+{
+ int mode, dsgn;
+ char *digits, *bp, *rve;
+
+ _DIAGASSERT(decpt != NULL);
+ _DIAGASSERT(length != NULL);
+ _DIAGASSERT(sign != NULL);
+
+ if (ch == 'f') {
+ mode = 3; /* ndigits after the decimal point */
+ } else {
+ /* To obtain ndigits after the decimal point for the 'e'
+ * and 'E' formats, round to ndigits + 1 significant
+ * figures.
+ */
+ if (ch == 'e' || ch == 'E') {
+ ndigits++;
+ }
+ mode = 2; /* ndigits significant digits */
+ }
+
+ digits = __dtoa(value, mode, ndigits, decpt, &dsgn, &rve);
+ if (digits == NULL)
+ return NULL;
+ if (dsgn) {
+ value = -value;
+ *sign = '-';
+ } else
+ *sign = '\000';
+ if ((ch != 'g' && ch != 'G') || flags & ALT) { /* Print trailing zeros */
+ bp = digits + ndigits;
+ if (ch == 'f') {
+ if (*digits == '0' && value)
+ *decpt = -ndigits + 1;
+ bp += *decpt;
+ }
+ if (value == 0) /* kludge for __dtoa irregularity */
+ rve = bp;
+ while (rve < bp)
+ *rve++ = '0';
+ }
+ *length = rve - digits;
+ return digits;
+}
+#endif
+
+static int
+exponent(CHAR_T *p0, int expo, int fmtch)
+{
+ CHAR_T *p, *t;
+ CHAR_T expbuf[MAXEXPDIG];
+
+ p = p0;
+ *p++ = fmtch;
+ if (expo < 0) {
+ expo = -expo;
+ *p++ = '-';
+ }
+ else
+ *p++ = '+';
+ t = expbuf + MAXEXPDIG;
+ if (expo > 9) {
+ do {
+ *--t = to_char(expo % 10);
+ } while ((expo /= 10) > 9);
+ *--t = to_char(expo);
+ for (; t < expbuf + MAXEXPDIG; *p++ = *t++);
+ }
+ else {
+ /*
+ * Exponents for decimal floating point conversions
+ * (%[eEgG]) must be at least two characters long,
+ * whereas exponents for hexadecimal conversions can
+ * be only one character long.
+ */
+ if (fmtch == 'e' || fmtch == 'E')
+ *p++ = '0';
+ *p++ = to_char(expo);
+ }
+ return (p - p0);
+}
+#endif /* !NO_FLOATING_POINT */
diff --git a/StdLib/LibC/Stdio/vfwscanf.c b/StdLib/LibC/Stdio/vfwscanf.c
new file mode 100644
index 0000000000..3d7404171b
--- /dev/null
+++ b/StdLib/LibC/Stdio/vfwscanf.c
@@ -0,0 +1,909 @@
+/*-
+ Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+
+ FreeBSD: src/lib/libc/stdio/vfwscanf.c,v 1.12 2004/05/02 20:13:29 obrien Exp
+ NetBSD: vfwscanf.c,v 1.2 2005/06/12 05:48:41 lukem Exp
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#include "namespace.h"
+#include <ctype.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdarg.h>
+#include <string.h>
+#include <limits.h>
+#include <wchar.h>
+#include <wctype.h>
+
+#include "reentrant.h"
+#include "local.h"
+
+#ifndef NO_FLOATING_POINT
+#include <locale.h>
+#endif
+
+#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
+ #pragma warning ( disable : 4244 ) // Allow wint_t to wchar_t conversions
+ #pragma warning ( disable : 4305 ) // Allow truncation from UINT64 to void*
+ #pragma warning ( disable : 4701 ) // Disable false warning for local variable p near line 375
+#endif
+
+
+#define BUF 513 /* Maximum length of numeric string. */
+
+/*
+ * Flags used during conversion.
+ */
+#define LONG 0x01 /* l: long or double */
+#define LONGDBL 0x02 /* L: long double */
+#define SHORT 0x04 /* h: short */
+#define SUPPRESS 0x08 /* *: suppress assignment */
+#define POINTER 0x10 /* p: void * (as hex) */
+#define NOSKIP 0x20 /* [ or c: do not skip blanks */
+#define LONGLONG 0x400 /* ll: quad_t (+ deprecated q: quad) */
+#define INTMAXT 0x800 /* j: intmax_t */
+#define PTRDIFFT 0x1000 /* t: ptrdiff_t */
+#define SIZET 0x2000 /* z: size_t */
+#define SHORTSHORT 0x4000 /* hh: char */
+#define UNSIGNED 0x8000 /* %[oupxX] conversions */
+
+/*
+ * The following are used in integral conversions only:
+ * SIGNOK, NDIGITS, PFXOK, and NZDIGITS
+ */
+#define SIGNOK 0x40 /* +/- is (still) legal */
+#define NDIGITS 0x80 /* no digits detected */
+#define PFXOK 0x100 /* 0x prefix is (still) legal */
+#define NZDIGITS 0x200 /* no zero digits detected */
+#define HAVESIGN 0x10000 /* sign detected */
+
+/*
+ * Conversion types.
+ */
+#define CT_CHAR 0 /* %c conversion */
+#define CT_CCL 1 /* %[...] conversion */
+#define CT_STRING 2 /* %s conversion */
+#define CT_INT 3 /* %[dioupxX] conversion */
+#define CT_FLOAT 4 /* %[efgEFG] conversion */
+
+static int parsefloat(FILE *, wchar_t *, wchar_t *);
+
+#define INCCL(_c) \
+ (cclcompl ? (wmemchr(ccls, (_c), (size_t)(ccle - ccls)) == NULL) : \
+ (wmemchr(ccls, (_c), (size_t)(ccle - ccls)) != NULL))
+
+/*
+ * MT-safe version.
+ */
+int
+vfwscanf(FILE * __restrict fp, const wchar_t * __restrict fmt, va_list ap)
+{
+ int ret;
+
+ FLOCKFILE(fp);
+ _SET_ORIENTATION(fp, 1);
+ ret = __vfwscanf_unlocked(fp, fmt, ap);
+ FUNLOCKFILE(fp);
+ return (ret);
+}
+
+/*
+ * Non-MT-safe version.
+ */
+int
+__vfwscanf_unlocked(FILE * __restrict fp, const wchar_t * __restrict fmt, va_list ap)
+{
+ wint_t c; /* character from format, or conversion */
+ size_t width; /* field width, or 0 */
+ wchar_t *p; /* points into all kinds of strings */
+ int n; /* handy integer */
+ int flags; /* flags as defined above */
+ wchar_t *p0; /* saves original value of p when necessary */
+ int nassigned; /* number of fields assigned */
+ int nconversions; /* number of conversions */
+ int nread; /* number of characters consumed from fp */
+ int base; /* base argument to conversion function */
+ wchar_t buf[BUF]; /* buffer for numeric conversions */
+ const wchar_t *ccls; /* character class start */
+ const wchar_t *ccle; /* character class end */
+ int cclcompl; /* ccl is complemented? */
+ wint_t wi; /* handy wint_t */
+ char *mbp; /* multibyte string pointer for %c %s %[ */
+ size_t nconv; /* number of bytes in mb. conversion */
+ char mbbuf[MB_LEN_MAX]; /* temporary mb. character buffer */
+ static const mbstate_t initial = { 0 };
+ mbstate_t mbs;
+
+ /* `basefix' is used to avoid `if' tests in the integer scanner */
+ static short basefix[17] =
+ { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
+
+ nassigned = 0;
+ nconversions = 0;
+ nread = 0;
+ ccls = ccle = NULL;
+ base = 0;
+ cclcompl = 0;
+ mbp = NULL;
+ for (;;) {
+ c = *fmt++;
+ if (c == 0)
+ return (nassigned);
+ if (iswspace(c)) {
+ while ((c = __fgetwc_unlock(fp)) != WEOF &&
+ iswspace(c))
+ ;
+ if (c != WEOF)
+ ungetwc(c, fp);
+ continue;
+ }
+ if (c != '%')
+ goto literal;
+ width = 0;
+ flags = 0;
+ /*
+ * switch on the format. continue if done;
+ * break once format type is derived.
+ */
+again: c = *fmt++;
+ switch (c) {
+ case '%':
+literal:
+ if ((wi = __fgetwc_unlock(fp)) == WEOF)
+ goto input_failure;
+ if (wi != c) {
+ ungetwc(wi, fp);
+ goto input_failure;
+ }
+ nread++;
+ continue;
+
+ case '*':
+ flags |= SUPPRESS;
+ goto again;
+ case 'j':
+ flags |= INTMAXT;
+ goto again;
+ case 'l':
+ if (flags & LONG) {
+ flags &= ~LONG;
+ flags |= LONGLONG;
+ } else
+ flags |= LONG;
+ goto again;
+ case 'q':
+ flags |= LONGLONG; /* not quite */
+ goto again;
+ case 't':
+ flags |= PTRDIFFT;
+ goto again;
+ case 'z':
+ flags |= SIZET;
+ goto again;
+ case 'L':
+ flags |= LONGDBL;
+ goto again;
+ case 'h':
+ if (flags & SHORT) {
+ flags &= ~SHORT;
+ flags |= SHORTSHORT;
+ } else
+ flags |= SHORT;
+ goto again;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ width = width * 10 + c - '0';
+ goto again;
+
+ /*
+ * Conversions.
+ */
+ case 'd':
+ c = CT_INT;
+ base = 10;
+ break;
+
+ case 'i':
+ c = CT_INT;
+ base = 0;
+ break;
+
+ case 'o':
+ c = CT_INT;
+ flags |= UNSIGNED;
+ base = 8;
+ break;
+
+ case 'u':
+ c = CT_INT;
+ flags |= UNSIGNED;
+ base = 10;
+ break;
+
+ case 'X':
+ case 'x':
+ flags |= PFXOK; /* enable 0x prefixing */
+ c = CT_INT;
+ flags |= UNSIGNED;
+ base = 16;
+ break;
+
+#ifndef NO_FLOATING_POINT
+ //case 'A':
+ case 'E': case 'F': case 'G':
+ //case 'a':
+ case 'e': case 'f': case 'g':
+ c = CT_FLOAT;
+ break;
+#endif
+
+ case 'S':
+ flags |= LONG;
+ /* FALLTHROUGH */
+ case 's':
+ c = CT_STRING;
+ break;
+
+ case '[':
+ ccls = fmt;
+ if (*fmt == '^') {
+ cclcompl = 1;
+ fmt++;
+ } else
+ cclcompl = 0;
+ if (*fmt == ']')
+ fmt++;
+ while (*fmt != '\0' && *fmt != ']')
+ fmt++;
+ ccle = fmt;
+ fmt++;
+ flags |= NOSKIP;
+ c = CT_CCL;
+ break;
+
+ case 'C':
+ flags |= LONG;
+ /* FALLTHROUGH */
+ case 'c':
+ flags |= NOSKIP;
+ c = CT_CHAR;
+ break;
+
+ case 'p': /* pointer format is like hex */
+ flags |= POINTER | PFXOK;
+ c = CT_INT; /* assumes sizeof(uintmax_t) */
+ flags |= UNSIGNED; /* >= sizeof(uintptr_t) */
+ base = 16;
+ break;
+
+ case 'n':
+ nconversions++;
+ if (flags & SUPPRESS) /* ??? */
+ continue;
+ if (flags & SHORTSHORT)
+ *va_arg(ap, char *) = (char)nread;
+ else if (flags & SHORT)
+ *va_arg(ap, short *) = (short)nread;
+ else if (flags & LONG)
+ *va_arg(ap, long *) = (long)nread;
+ else if (flags & LONGLONG)
+ *va_arg(ap, INT64 *) = (INT64)nread; // was quad_t
+ else if (flags & INTMAXT)
+ *va_arg(ap, intmax_t *) = (intmax_t)nread;
+ else if (flags & SIZET)
+ *va_arg(ap, size_t *) = (size_t)nread;
+ else if (flags & PTRDIFFT)
+ *va_arg(ap, ptrdiff_t *) = (ptrdiff_t)nread;
+ else
+ *va_arg(ap, int *) = nread;
+ continue;
+
+ default:
+ goto match_failure;
+
+ /*
+ * Disgusting backwards compatibility hack. XXX
+ */
+ case '\0': /* compat */
+ return (EOF);
+ }
+
+ /*
+ * Consume leading white space, except for formats
+ * that suppress this.
+ */
+ if ((flags & NOSKIP) == 0) {
+ while ((wi = __fgetwc_unlock(fp)) != WEOF && iswspace(wi))
+ nread++;
+ if (wi == WEOF)
+ goto input_failure;
+ ungetwc(wi, fp);
+ }
+
+ /*
+ * Do the conversion.
+ */
+ switch (c) {
+
+ case CT_CHAR:
+ /* scan arbitrary characters (sets NOSKIP) */
+ if (width == 0)
+ width = 1;
+ if (flags & LONG) {
+ if (!(flags & SUPPRESS))
+ p = va_arg(ap, wchar_t *);
+ n = 0;
+ while (width-- != 0 &&
+ (wi = __fgetwc_unlock(fp)) != WEOF) {
+ if (!(flags & SUPPRESS))
+ *p++ = (wchar_t)wi;
+ n++;
+ }
+ if (n == 0)
+ goto input_failure;
+ nread += n;
+ if (!(flags & SUPPRESS))
+ nassigned++;
+ } else {
+ if (!(flags & SUPPRESS))
+ mbp = va_arg(ap, char *);
+ n = 0;
+ mbs = initial;
+ while (width != 0 &&
+ (wi = __fgetwc_unlock(fp)) != WEOF) {
+ if (width >= MB_CUR_MAX &&
+ !(flags & SUPPRESS)) {
+ nconv = wcrtomb(mbp, (wchar_t)wi, &mbs);
+ if (nconv == (size_t)-1)
+ goto input_failure;
+ } else {
+ nconv = wcrtomb(mbbuf, (wchar_t)wi,
+ &mbs);
+ if (nconv == (size_t)-1)
+ goto input_failure;
+ if (nconv > width) {
+ ungetwc(wi, fp);
+ break;
+ }
+ if (!(flags & SUPPRESS))
+ memcpy(mbp, mbbuf,
+ nconv);
+ }
+ if (!(flags & SUPPRESS))
+ mbp += nconv;
+ width -= nconv;
+ n++;
+ }
+ if (n == 0)
+ goto input_failure;
+ nread += n;
+ if (!(flags & SUPPRESS))
+ nassigned++;
+ }
+ nconversions++;
+ break;
+
+ case CT_CCL:
+ /* scan a (nonempty) character class (sets NOSKIP) */
+ if (width == 0)
+ width = (size_t)~0; /* `infinity' */
+ /* take only those things in the class */
+ if ((flags & SUPPRESS) && (flags & LONG)) {
+ n = 0;
+ while ((wi = __fgetwc_unlock(fp)) != WEOF &&
+ width-- != 0 && INCCL(wi))
+ n++;
+ if (wi != WEOF)
+ ungetwc(wi, fp);
+ if (n == 0)
+ goto match_failure;
+ } else if (flags & LONG) {
+ p0 = p = va_arg(ap, wchar_t *);
+ while ((wi = __fgetwc_unlock(fp)) != WEOF &&
+ width-- != 0 && INCCL(wi))
+ *p++ = (wchar_t)wi;
+ if (wi != WEOF)
+ ungetwc(wi, fp);
+ n = p - p0;
+ if (n == 0)
+ goto match_failure;
+ *p = 0;
+ nassigned++;
+ } else {
+ if (!(flags & SUPPRESS))
+ mbp = va_arg(ap, char *);
+ n = 0;
+ mbs = initial;
+ while ((wi = __fgetwc_unlock(fp)) != WEOF &&
+ width != 0 && INCCL(wi)) {
+ if (width >= MB_CUR_MAX &&
+ !(flags & SUPPRESS)) {
+ nconv = wcrtomb(mbp, wi, &mbs);
+ if (nconv == (size_t)-1)
+ goto input_failure;
+ } else {
+ nconv = wcrtomb(mbbuf, wi,
+ &mbs);
+ if (nconv == (size_t)-1)
+ goto input_failure;
+ if (nconv > width)
+ break;
+ if (!(flags & SUPPRESS))
+ memcpy(mbp, mbbuf,
+ nconv);
+ }
+ if (!(flags & SUPPRESS))
+ mbp += nconv;
+ width -= nconv;
+ n++;
+ }
+ if (wi != WEOF)
+ ungetwc(wi, fp);
+ if (!(flags & SUPPRESS)) {
+ *mbp = 0;
+ nassigned++;
+ }
+ }
+ nread += n;
+ nconversions++;
+ break;
+
+ case CT_STRING:
+ /* like CCL, but zero-length string OK, & no NOSKIP */
+ if (width == 0)
+ width = (size_t)~0;
+ if ((flags & SUPPRESS) && (flags & LONG)) {
+ while ((wi = __fgetwc_unlock(fp)) != WEOF &&
+ width-- != 0 &&
+ !iswspace(wi))
+ nread++;
+ if (wi != WEOF)
+ ungetwc(wi, fp);
+ } else if (flags & LONG) {
+ p0 = p = va_arg(ap, wchar_t *);
+ while ((wi = __fgetwc_unlock(fp)) != WEOF &&
+ width-- != 0 &&
+ !iswspace(wi)) {
+ *p++ = (wchar_t)wi;
+ nread++;
+ }
+ if (wi != WEOF)
+ ungetwc(wi, fp);
+ *p = '\0';
+ nassigned++;
+ } else {
+ if (!(flags & SUPPRESS))
+ mbp = va_arg(ap, char *);
+ mbs = initial;
+ while ((wi = __fgetwc_unlock(fp)) != WEOF &&
+ width != 0 &&
+ !iswspace(wi)) {
+ if (width >= MB_CUR_MAX &&
+ !(flags & SUPPRESS)) {
+ nconv = wcrtomb(mbp, wi, &mbs);
+ if (nconv == (size_t)-1)
+ goto input_failure;
+ } else {
+ nconv = wcrtomb(mbbuf, wi,
+ &mbs);
+ if (nconv == (size_t)-1)
+ goto input_failure;
+ if (nconv > width)
+ break;
+ if (!(flags & SUPPRESS))
+ memcpy(mbp, mbbuf,
+ nconv);
+ }
+ if (!(flags & SUPPRESS))
+ mbp += nconv;
+ width -= nconv;
+ nread++;
+ }
+ if (wi != WEOF)
+ ungetwc(wi, fp);
+ if (!(flags & SUPPRESS)) {
+ *mbp = 0;
+ nassigned++;
+ }
+ }
+ nconversions++;
+ continue;
+
+ case CT_INT:
+ /* scan an integer as if by the conversion function */
+ if (width == 0 || width > sizeof(buf) /
+ sizeof(*buf) - 1)
+ width = sizeof(buf) / sizeof(*buf) - 1;
+ flags |= SIGNOK | NDIGITS | NZDIGITS;
+ for (p = buf; width; width--) {
+ c = __fgetwc_unlock(fp);
+ /*
+ * Switch on the character; `goto ok'
+ * if we accept it as a part of number.
+ */
+ switch (c) {
+
+ /*
+ * The digit 0 is always legal, but is
+ * special. For %i conversions, if no
+ * digits (zero or nonzero) have been
+ * scanned (only signs), we will have
+ * base==0. In that case, we should set
+ * it to 8 and enable 0x prefixing.
+ * Also, if we have not scanned zero digits
+ * before this, do not turn off prefixing
+ * (someone else will turn it off if we
+ * have scanned any nonzero digits).
+ */
+ case '0':
+ if (base == 0) {
+ base = 8;
+ flags |= PFXOK;
+ }
+ if (flags & NZDIGITS)
+ flags &= ~(SIGNOK|NZDIGITS|NDIGITS);
+ else
+ flags &= ~(SIGNOK|PFXOK|NDIGITS);
+ goto ok;
+
+ /* 1 through 7 always legal */
+ case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ base = basefix[base];
+ flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ goto ok;
+
+ /* digits 8 and 9 ok iff decimal or hex */
+ case '8': case '9':
+ base = basefix[base];
+ if (base <= 8)
+ break; /* not legal here */
+ flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ goto ok;
+
+ /* letters ok iff hex */
+ case 'A': case 'B': case 'C':
+ case 'D': case 'E': case 'F':
+ case 'a': case 'b': case 'c':
+ case 'd': case 'e': case 'f':
+ /* no need to fix base here */
+ if (base <= 10)
+ break; /* not legal here */
+ flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ goto ok;
+
+ /* sign ok only as first character */
+ case '+': case '-':
+ if (flags & SIGNOK) {
+ flags &= ~SIGNOK;
+ flags |= HAVESIGN;
+ goto ok;
+ }
+ break;
+
+ /*
+ * x ok iff flag still set & 2nd char (or
+ * 3rd char if we have a sign).
+ */
+ case 'x': case 'X':
+ if (flags & PFXOK && p ==
+ buf + 1 + !!(flags & HAVESIGN)) {
+ base = 16; /* if %i */
+ flags &= ~PFXOK;
+ goto ok;
+ }
+ break;
+ }
+
+ /*
+ * If we got here, c is not a legal character
+ * for a number. Stop accumulating digits.
+ */
+ if (c != WEOF)
+ ungetwc(c, fp);
+ break;
+ ok:
+ /*
+ * c is legal: store it and look at the next.
+ */
+ *p++ = (wchar_t)c;
+ }
+ /*
+ * If we had only a sign, it is no good; push
+ * back the sign. If the number ends in `x',
+ * it was [sign] '0' 'x', so push back the x
+ * and treat it as [sign] '0'.
+ */
+ if (flags & NDIGITS) {
+ if (p > buf)
+ ungetwc(*--p, fp);
+ goto match_failure;
+ }
+ c = p[-1];
+ if (c == 'x' || c == 'X') {
+ --p;
+ ungetwc(c, fp);
+ }
+ if ((flags & SUPPRESS) == 0) {
+ uintmax_t res;
+
+ *p = 0;
+ if ((flags & UNSIGNED) == 0)
+ res = wcstoimax(buf, NULL, base);
+ else
+ res = wcstoumax(buf, NULL, base);
+
+ if (flags & POINTER) {
+ *va_arg(ap, void **) = (void *)res;
+ }
+ else if (flags & SHORTSHORT) {
+ *va_arg(ap, char *) = (char)res;
+ }
+ else if (flags & SHORT) {
+ *va_arg(ap, short *) = (short)res;
+ }
+ else if (flags & LONG) {
+ *va_arg(ap, long *) = (long)res;
+ }
+ else if (flags & LONGLONG) {
+ *va_arg(ap, INT64 *) = res; // was quad_t
+ }
+ else if (flags & INTMAXT) {
+ *va_arg(ap, intmax_t *) = res;
+ }
+ else if (flags & PTRDIFFT) {
+ *va_arg(ap, ptrdiff_t *) = (ptrdiff_t)res;
+ }
+ else if (flags & SIZET) {
+ *va_arg(ap, size_t *) = (size_t)res;
+ }
+ else {
+ *va_arg(ap, int *) = (int)res;
+ }
+ nassigned++;
+ }
+ nread += p - buf;
+ nconversions++;
+ break;
+
+#ifndef NO_FLOATING_POINT
+ case CT_FLOAT:
+ /* scan a floating point number as if by strtod */
+ if (width == 0 || width > sizeof(buf) /
+ sizeof(*buf) - 1)
+ width = sizeof(buf) / sizeof(*buf) - 1;
+ if ((width = parsefloat(fp, buf, buf + width)) == 0)
+ goto match_failure;
+ if ((flags & SUPPRESS) == 0) {
+#ifdef notyet
+ if (flags & LONGDBL) {
+ long double res = wcstold(buf, &p);
+ *va_arg(ap, long double *) = res;
+ } else
+#endif
+ if (flags & LONG) {
+ double res = wcstod(buf, &p);
+ *va_arg(ap, double *) = res;
+#ifdef notyet
+ } else {
+ float res = wcstof(buf, &p);
+ *va_arg(ap, float *) = res;
+#endif
+ }
+#ifdef DEBUG
+ if (p - buf != width)
+ abort();
+#endif
+ nassigned++;
+ }
+ nread += (int)width;
+ nconversions++;
+ break;
+#endif /* !NO_FLOATING_POINT */
+ }
+ }
+input_failure:
+ return (nconversions != 0 ? nassigned : EOF);
+match_failure:
+ return (nassigned);
+}
+
+#ifndef NO_FLOATING_POINT
+static int
+parsefloat(FILE *fp, wchar_t *buf, wchar_t *end)
+{
+ wchar_t *commit, *p;
+ int infnanpos = 0;
+ enum {
+ S_START, S_GOTSIGN, S_INF, S_NAN, S_MAYBEHEX,
+ S_DIGITS, S_FRAC, S_EXP, S_EXPDIGITS
+ } state = S_START;
+ wchar_t c;
+ wchar_t decpt = (wchar_t)(unsigned char)*localeconv()->decimal_point;
+ int gotmantdig = 0, ishex = 0;
+
+ /*
+ * We set commit = p whenever the string we have read so far
+ * constitutes a valid representation of a floating point
+ * number by itself. At some point, the parse will complete
+ * or fail, and we will ungetc() back to the last commit point.
+ * To ensure that the file offset gets updated properly, it is
+ * always necessary to read at least one character that doesn't
+ * match; thus, we can't short-circuit "infinity" or "nan(...)".
+ */
+ commit = buf - 1;
+ c = (wchar_t)WEOF;
+ for (p = buf; p < end; ) {
+ if ((wint_t)(c = __fgetwc_unlock(fp)) == WEOF)
+ break;
+reswitch:
+ switch (state) {
+ case S_START:
+ state = S_GOTSIGN;
+ if (c == '-' || c == '+')
+ break;
+ else
+ goto reswitch;
+ case S_GOTSIGN:
+ switch (c) {
+ case '0':
+ state = S_MAYBEHEX;
+ commit = p;
+ break;
+ case 'I':
+ case 'i':
+ state = S_INF;
+ break;
+ case 'N':
+ case 'n':
+ state = S_NAN;
+ break;
+ default:
+ state = S_DIGITS;
+ goto reswitch;
+ }
+ break;
+ case S_INF:
+ if (infnanpos > 6 ||
+ (c != "nfinity"[infnanpos] &&
+ c != "NFINITY"[infnanpos]))
+ goto parsedone;
+ if (infnanpos == 1 || infnanpos == 6)
+ commit = p; /* inf or infinity */
+ infnanpos++;
+ break;
+ case S_NAN:
+ switch (infnanpos) {
+ case -1: /* XXX kludge to deal with nan(...) */
+ goto parsedone;
+ case 0:
+ if (c != 'A' && c != 'a')
+ goto parsedone;
+ break;
+ case 1:
+ if (c != 'N' && c != 'n')
+ goto parsedone;
+ else
+ commit = p;
+ break;
+ case 2:
+ if (c != '(')
+ goto parsedone;
+ break;
+ default:
+ if (c == ')') {
+ commit = p;
+ infnanpos = -2;
+ } else if (!iswalnum(c) && c != '_')
+ goto parsedone;
+ break;
+ }
+ infnanpos++;
+ break;
+ case S_MAYBEHEX:
+ state = S_DIGITS;
+ if (c == 'X' || c == 'x') {
+ ishex = 1;
+ break;
+ } else { /* we saw a '0', but no 'x' */
+ gotmantdig = 1;
+ goto reswitch;
+ }
+ case S_DIGITS:
+ if ((ishex && iswxdigit(c)) || iswdigit(c))
+ gotmantdig = 1;
+ else {
+ state = S_FRAC;
+ if (c != decpt)
+ goto reswitch;
+ }
+ if (gotmantdig)
+ commit = p;
+ break;
+ case S_FRAC:
+ if (((c == 'E' || c == 'e') && !ishex) ||
+ ((c == 'P' || c == 'p') && ishex)) {
+ if (!gotmantdig)
+ goto parsedone;
+ else
+ state = S_EXP;
+ } else if ((ishex && iswxdigit(c)) || iswdigit(c)) {
+ commit = p;
+ gotmantdig = 1;
+ } else
+ goto parsedone;
+ break;
+ case S_EXP:
+ state = S_EXPDIGITS;
+ if (c == '-' || c == '+')
+ break;
+ else
+ goto reswitch;
+ case S_EXPDIGITS:
+ if (iswdigit(c))
+ commit = p;
+ else
+ goto parsedone;
+ break;
+ default:
+ abort();
+ }
+ *p++ = c;
+ c = (wchar_t)WEOF;
+ }
+
+parsedone:
+ if ((wint_t)c != WEOF)
+ ungetwc(c, fp);
+ while (commit < --p)
+ ungetwc(*p, fp);
+ *++commit = '\0';
+ return (commit - buf);
+}
+#endif
diff --git a/StdLib/LibC/Stdio/vprintf.c b/StdLib/LibC/Stdio/vprintf.c
new file mode 100644
index 0000000000..96d43ee7a0
--- /dev/null
+++ b/StdLib/LibC/Stdio/vprintf.c
@@ -0,0 +1,58 @@
+/** @file
+ Implementation of vprintf as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: vprintf.c,v 1.10 2003/08/07 16:43:34 agc Exp
+ vprintf.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+
+int
+vprintf(char const *fmt, _BSD_VA_LIST_ ap)
+{
+ _DIAGASSERT(fmt != NULL);
+
+ return (vfprintf(stdout, fmt, ap));
+}
diff --git a/StdLib/LibC/Stdio/vscanf.c b/StdLib/LibC/Stdio/vscanf.c
new file mode 100644
index 0000000000..518a8010da
--- /dev/null
+++ b/StdLib/LibC/Stdio/vscanf.c
@@ -0,0 +1,60 @@
+/* $NetBSD: vscanf.c,v 1.12 2003/08/07 16:43:35 agc Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Donn Seeley at UUNET Technologies, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)vscanf.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: vscanf.c,v 1.12 2003/08/07 16:43:35 agc Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+
+#include "reentrant.h"
+#include "local.h"
+
+int
+vscanf(fmt, ap)
+ const char *fmt;
+ _BSD_VA_LIST_ ap;
+{
+
+ _DIAGASSERT(fmt != NULL);
+
+ return (__svfscanf(stdin, fmt, ap));
+}
diff --git a/StdLib/LibC/Stdio/vsnprintf.c b/StdLib/LibC/Stdio/vsnprintf.c
new file mode 100644
index 0000000000..b2a2f63a91
--- /dev/null
+++ b/StdLib/LibC/Stdio/vsnprintf.c
@@ -0,0 +1,89 @@
+/* $NetBSD: vsnprintf.c,v 1.20 2005/02/09 21:35:47 kleink Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)vsnprintf.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: vsnprintf.c,v 1.20 2005/02/09 21:35:47 kleink Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include "reentrant.h"
+#include "local.h"
+
+#ifdef __weak_alias
+__weak_alias(vsnprintf,_vsnprintf)
+#endif
+
+int
+vsnprintf(str, n, fmt, ap)
+ char *str;
+ size_t n;
+ const char *fmt;
+ _BSD_VA_LIST_ ap;
+{
+ int ret;
+ FILE f;
+ struct __sfileext fext;
+ unsigned char dummy[1];
+
+ _DIAGASSERT(n == 0 || str != NULL);
+ _DIAGASSERT(fmt != NULL);
+
+ if ((int)n < 0) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ _FILEEXT_SETUP(&f, &fext);
+ f._file = -1;
+ f._flags = __SWR | __SSTR;
+ if (n == 0) {
+ f._bf._base = f._p = dummy;
+ f._bf._size = f._w = 0;
+ } else {
+ f._bf._base = f._p = (unsigned char *)str;
+ f._bf._size = f._w = n - 1;
+ }
+ ret = __vfprintf_unlocked(&f, fmt, ap);
+ *f._p = 0;
+ return (ret);
+}
diff --git a/StdLib/LibC/Stdio/vsnprintf_ss.c b/StdLib/LibC/Stdio/vsnprintf_ss.c
new file mode 100644
index 0000000000..77a2887ea6
--- /dev/null
+++ b/StdLib/LibC/Stdio/vsnprintf_ss.c
@@ -0,0 +1,494 @@
+/* $NetBSD: vsnprintf_ss.c,v 1.2.2.1 2007/05/07 19:49:09 pavel Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)vsnprintf.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: vsnprintf_ss.c,v 1.2.2.1 2007/05/07 19:49:09 pavel Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <assert.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <string.h>
+#include "reentrant.h"
+#include "extern.h"
+#include "local.h"
+
+#ifdef __weak_alias
+__weak_alias(vsnprintf_ss,_vsnprintf_ss)
+#endif
+
+/*
+ * vsnprintf_ss: scaled down version of printf(3).
+ *
+ * this version based on vfprintf() from libc which was derived from
+ * software contributed to Berkeley by Chris Torek.
+ *
+ */
+
+/*
+ * macros for converting digits to letters and vice versa
+ */
+#define to_digit(c) ((c) - '0')
+#define is_digit(c) ((unsigned)to_digit(c) <= 9)
+#define to_char(n) (char)((n) + '0')
+
+/*
+ * flags used during conversion.
+ */
+#define ALT 0x001 /* alternate form */
+#define HEXPREFIX 0x002 /* add 0x or 0X prefix */
+#define LADJUST 0x004 /* left adjustment */
+#define LONGDBL 0x008 /* long double; unimplemented */
+#define LONGINT 0x010 /* long integer */
+#define QUADINT 0x020 /* quad integer */
+#define SHORTINT 0x040 /* short integer */
+#define MAXINT 0x080 /* intmax_t */
+#define PTRINT 0x100 /* intptr_t */
+#define SIZEINT 0x200 /* size_t */
+#define ZEROPAD 0x400 /* zero (as opposed to blank) pad */
+#define FPT 0x800 /* Floating point number */
+
+ /*
+ * To extend shorts properly, we need both signed and unsigned
+ * argument extraction methods.
+ */
+#define SARG() \
+ ((INT64)(flags&MAXINT ? va_arg(ap, intmax_t) : \
+ flags&PTRINT ? va_arg(ap, intptr_t) : \
+ flags&SIZEINT ? va_arg(ap, ssize_t) : /* XXX */ \
+ flags&QUADINT ? va_arg(ap, quad_t) : \
+ flags&LONGINT ? va_arg(ap, long) : \
+ flags&SHORTINT ? (short)va_arg(ap, int) : \
+ va_arg(ap, int)))
+
+#define UARG() \
+ ((UINT64)(flags&MAXINT ? va_arg(ap, uintmax_t) : \
+ flags&PTRINT ? va_arg(ap, uintptr_t) : \
+ flags&SIZEINT ? va_arg(ap, size_t) : \
+ flags&QUADINT ? va_arg(ap, u_quad_t) : \
+ flags&LONGINT ? va_arg(ap, unsigned long) : \
+ flags&SHORTINT ? (u_short)va_arg(ap, int) : \
+ va_arg(ap, u_int)))
+
+#define PUTCHAR(C) do { \
+ if (sbuf < tailp) \
+ *sbuf++ = (C); \
+} while (/*CONSTCOND*/0)
+
+int
+vsnprintf_ss(char *sbuf, size_t slen, const char *fmt0, _BSD_VA_LIST_ ap)
+{
+ const char *fmt; /* format string */
+ int ch; /* character from fmt */
+ int n; /* handy integer (short term usage) */
+ char *cp; /* handy char pointer (short term usage) */
+ int flags; /* flags as above */
+ int ret; /* return value accumulator */
+ int width; /* width from format (%8d), or 0 */
+ int prec; /* precision from format (%.3d), or -1 */
+ char sign; /* sign prefix (' ', '+', '-', or \0) */
+
+ u_quad_t _uquad; /* integer arguments %[diouxX] */
+ enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */
+ int dprec; /* a copy of prec if [diouxX], 0 otherwise */
+ int realsz; /* field size expanded by dprec */
+ int size; /* size of converted field or string */
+ const char *xdigs; /* digits for [xX] conversion */
+ char bf[128]; /* space for %c, %[diouxX] */
+ char *tailp; /* tail pointer for snprintf */
+
+ static const char xdigs_lower[16] = "0123456789abcdef";
+ static const char xdigs_upper[16] = "0123456789ABCDEF";
+
+
+ _DIAGASSERT(n == 0 || sbuf != NULL);
+ _DIAGASSERT(fmt != NULL);
+
+ tailp = sbuf + slen;
+
+ cp = NULL; /* XXX: shutup gcc */
+ size = 0; /* XXX: shutup gcc */
+
+ fmt = fmt0;
+ ret = 0;
+
+ xdigs = NULL; /* XXX: shut up gcc warning */
+
+ /*
+ * Scan the format for conversions (`%' character).
+ */
+ for (;;) {
+ while (*fmt != '%' && *fmt) {
+ ret++;
+ PUTCHAR(*fmt++);
+ }
+ if (*fmt == 0)
+ goto done;
+
+ fmt++; /* skip over '%' */
+
+ flags = 0;
+ dprec = 0;
+ width = 0;
+ prec = -1;
+ sign = '\0';
+
+rflag: ch = *fmt++;
+reswitch: switch (ch) {
+ case ' ':
+ /*
+ * ``If the space and + flags both appear, the space
+ * flag will be ignored.''
+ * -- ANSI X3J11
+ */
+ if (!sign)
+ sign = ' ';
+ goto rflag;
+ case '#':
+ flags |= ALT;
+ goto rflag;
+ case '*':
+ /*
+ * ``A negative field width argument is taken as a
+ * - flag followed by a positive field width.''
+ * -- ANSI X3J11
+ * They don't exclude field widths read from args.
+ */
+ if ((width = va_arg(ap, int)) >= 0)
+ goto rflag;
+ width = -width;
+ /* FALLTHROUGH */
+ case '-':
+ flags |= LADJUST;
+ goto rflag;
+ case '+':
+ sign = '+';
+ goto rflag;
+ case '.':
+ if ((ch = *fmt++) == '*') {
+ n = va_arg(ap, int);
+ prec = n < 0 ? -1 : n;
+ goto rflag;
+ }
+ n = 0;
+ while (is_digit(ch)) {
+ n = 10 * n + to_digit(ch);
+ ch = *fmt++;
+ }
+ prec = n < 0 ? -1 : n;
+ goto reswitch;
+ case '0':
+ /*
+ * ``Note that 0 is taken as a flag, not as the
+ * beginning of a field width.''
+ * -- ANSI X3J11
+ */
+ flags |= ZEROPAD;
+ goto rflag;
+ case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ n = 0;
+ do {
+ n = 10 * n + to_digit(ch);
+ ch = *fmt++;
+ } while (is_digit(ch));
+ width = n;
+ goto reswitch;
+ case 'h':
+ flags |= SHORTINT;
+ goto rflag;
+ case 'j':
+ flags |= MAXINT;
+ goto rflag;
+ case 'l':
+ if (*fmt == 'l') {
+ fmt++;
+ flags |= QUADINT;
+ } else {
+ flags |= LONGINT;
+ }
+ goto rflag;
+ case 'q':
+ flags |= QUADINT;
+ goto rflag;
+ case 't':
+ flags |= PTRINT;
+ goto rflag;
+ case 'z':
+ flags |= SIZEINT;
+ goto rflag;
+ case 'c':
+ *(cp = bf) = va_arg(ap, int);
+ size = 1;
+ sign = '\0';
+ break;
+ case 'D':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'd':
+ case 'i':
+ _uquad = SARG();
+ if ((quad_t)_uquad < 0) {
+ _uquad = -_uquad;
+ sign = '-';
+ }
+ base = DEC;
+ goto number;
+ case 'n':
+ if (flags & MAXINT)
+ *va_arg(ap, intmax_t *) = ret;
+ else if (flags & PTRINT)
+ *va_arg(ap, intptr_t *) = ret;
+ else if (flags & SIZEINT)
+ *va_arg(ap, ssize_t *) = ret;
+ else if (flags & QUADINT)
+ *va_arg(ap, quad_t *) = ret;
+ else if (flags & LONGINT)
+ *va_arg(ap, long *) = (long)ret;
+ else if (flags & SHORTINT)
+ *va_arg(ap, short *) = (short)ret;
+ else
+ *va_arg(ap, int *) = ret;
+ continue; /* no output */
+ case 'O':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'o':
+ _uquad = UARG();
+ base = OCT;
+ goto nosign;
+ case 'p':
+ /*
+ * ``The argument shall be a pointer to void. The
+ * value of the pointer is converted to a sequence
+ * of printable characters, in an implementation-
+ * defined manner.''
+ * -- ANSI X3J11
+ */
+ /* NOSTRICT */
+ _uquad = (u_long)va_arg(ap, void *);
+ base = HEX;
+ xdigs = xdigs_lower;
+ flags |= HEXPREFIX;
+ ch = 'x';
+ goto nosign;
+ case 's':
+ if ((cp = va_arg(ap, char *)) == NULL)
+ /*XXXUNCONST*/
+ cp = __UNCONST("(null)");
+ if (prec >= 0) {
+ /*
+ * can't use strlen; can only look for the
+ * NUL in the first `prec' characters, and
+ * strlen() will go further.
+ */
+ char *p = memchr(cp, 0, (size_t)prec);
+
+ if (p != NULL) {
+ size = p - cp;
+ if (size > prec)
+ size = prec;
+ } else
+ size = prec;
+ } else
+ size = strlen(cp);
+ sign = '\0';
+ break;
+ case 'U':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'u':
+ _uquad = UARG();
+ base = DEC;
+ goto nosign;
+ case 'X':
+ xdigs = xdigs_upper;
+ goto hex;
+ case 'x':
+ xdigs = xdigs_lower;
+hex: _uquad = UARG();
+ base = HEX;
+ /* leading 0x/X only if non-zero */
+ if (flags & ALT && _uquad != 0)
+ flags |= HEXPREFIX;
+
+ /* unsigned conversions */
+nosign: sign = '\0';
+ /*
+ * ``... diouXx conversions ... if a precision is
+ * specified, the 0 flag will be ignored.''
+ * -- ANSI X3J11
+ */
+number: if ((dprec = prec) >= 0)
+ flags &= ~ZEROPAD;
+
+ /*
+ * ``The result of converting a zero value with an
+ * explicit precision of zero is no characters.''
+ * -- ANSI X3J11
+ */
+ cp = bf + sizeof(bf);
+ if (_uquad != 0 || prec != 0) {
+ /*
+ * Unsigned mod is hard, and unsigned mod
+ * by a constant is easier than that by
+ * a variable; hence this switch.
+ */
+ switch (base) {
+ case OCT:
+ do {
+ *--cp = to_char(_uquad & 7);
+ _uquad >>= 3;
+ } while (_uquad);
+ /* handle octal leading 0 */
+ if (flags & ALT && *cp != '0')
+ *--cp = '0';
+ break;
+
+ case DEC:
+ /* many numbers are 1 digit */
+ while (_uquad >= 10) {
+ *--cp = to_char(_uquad % 10);
+ _uquad /= 10;
+ }
+ *--cp = to_char(_uquad);
+ break;
+
+ case HEX:
+ do {
+ *--cp = xdigs[(size_t)_uquad & 15];
+ _uquad >>= 4;
+ } while (_uquad);
+ break;
+
+ default:
+ /*XXXUNCONST*/
+ cp = __UNCONST("bug bad base");
+ size = strlen(cp);
+ goto skipsize;
+ }
+ }
+ size = bf + sizeof(bf) - cp;
+ skipsize:
+ break;
+ default: /* "%?" prints ?, unless ? is NUL */
+ if (ch == '\0')
+ goto done;
+ /* pretend it was %c with argument ch */
+ cp = bf;
+ *cp = ch;
+ size = 1;
+ sign = '\0';
+ break;
+ }
+
+ /*
+ * All reasonable formats wind up here. At this point, `cp'
+ * points to a string which (if not flags&LADJUST) should be
+ * padded out to `width' places. If flags&ZEROPAD, it should
+ * first be prefixed by any sign or other prefix; otherwise,
+ * it should be blank padded before the prefix is emitted.
+ * After any left-hand padding and prefixing, emit zeroes
+ * required by a decimal [diouxX] precision, then print the
+ * string proper, then emit zeroes required by any leftover
+ * floating precision; finally, if LADJUST, pad with blanks.
+ *
+ * Compute actual size, so we know how much to pad.
+ * size excludes decimal prec; realsz includes it.
+ */
+ realsz = dprec > size ? dprec : size;
+ if (sign)
+ realsz++;
+ else if (flags & HEXPREFIX)
+ realsz+= 2;
+
+ /* adjust ret */
+ ret += width > realsz ? width : realsz;
+
+ /* right-adjusting blank padding */
+ if ((flags & (LADJUST|ZEROPAD)) == 0) {
+ n = width - realsz;
+ while (n-- > 0)
+ PUTCHAR(' ');
+ }
+
+ /* prefix */
+ if (sign) {
+ PUTCHAR(sign);
+ } else if (flags & HEXPREFIX) {
+ PUTCHAR('0');
+ PUTCHAR(ch);
+ }
+
+ /* right-adjusting zero padding */
+ if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) {
+ n = width - realsz;
+ while (n-- > 0)
+ PUTCHAR('0');
+ }
+
+ /* leading zeroes from decimal precision */
+ n = dprec - size;
+ while (n-- > 0)
+ PUTCHAR('0');
+
+ /* the string or number proper */
+ while (size--)
+ PUTCHAR(*cp++);
+ /* left-adjusting padding (always blank) */
+ if (flags & LADJUST) {
+ n = width - realsz;
+ while (n-- > 0)
+ PUTCHAR(' ');
+ }
+ }
+
+done:
+ if (sbuf == tailp)
+ sbuf[-1] = '\0';
+ else
+ *sbuf = '\0';
+ return (ret);
+ /* NOTREACHED */
+}
diff --git a/StdLib/LibC/Stdio/vsprintf.c b/StdLib/LibC/Stdio/vsprintf.c
new file mode 100644
index 0000000000..4fb8d28155
--- /dev/null
+++ b/StdLib/LibC/Stdio/vsprintf.c
@@ -0,0 +1,74 @@
+/** @file
+ Implementation of vsprintf as declared in <stdio.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License that accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+ This code is derived from software contributed to Berkeley by
+ Chris Torek.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: vsprintf.c,v 1.14 2005/02/09 21:35:47 kleink Exp
+ vsprintf.c 8.1 (Berkeley) 6/4/93
+**/
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include "reentrant.h"
+#include "local.h"
+
+int
+vsprintf(char *str, const char *fmt, _BSD_VA_LIST_ ap)
+{
+ int ret;
+ FILE f;
+ struct __sfileext fext;
+
+ _DIAGASSERT(str != NULL);
+ _DIAGASSERT(fmt != NULL);
+
+ _FILEEXT_SETUP(&f, &fext);
+ f._file = -1;
+ f._flags = __SWR | __SSTR;
+ f._bf._base = f._p = (unsigned char *)str;
+ f._bf._size = f._w = INT_MAX;
+ ret = __vfprintf_unlocked(&f, fmt, ap);
+ *f._p = 0;
+
+ return (ret);
+}
diff --git a/StdLib/LibC/Stdio/vsscanf.c b/StdLib/LibC/Stdio/vsscanf.c
new file mode 100644
index 0000000000..34b08cc30d
--- /dev/null
+++ b/StdLib/LibC/Stdio/vsscanf.c
@@ -0,0 +1,83 @@
+/* $NetBSD: vsscanf.c,v 1.14 2005/11/29 03:12:00 christos Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Donn Seeley at UUNET Technologies, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)vsscanf.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: vsscanf.c,v 1.14 2005/11/29 03:12:00 christos Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include "reentrant.h"
+#include "local.h"
+
+static int eofread __P((void *, char *, int));
+
+/* ARGSUSED */
+static int
+eofread(cookie, buf, len)
+ void *cookie;
+ char *buf;
+ int len;
+{
+ return (0);
+}
+
+int
+vsscanf(str, fmt, ap)
+ const char *str;
+ const char *fmt;
+ _BSD_VA_LIST_ ap;
+{
+ FILE f;
+ struct __sfileext fext;
+
+ _DIAGASSERT(str != NULL);
+ _DIAGASSERT(fmt != NULL);
+
+ _FILEEXT_SETUP(&f, &fext);
+ f._flags = __SRD;
+ f._bf._base = f._p = __UNCONST(str);
+ f._bf._size = f._r = strlen(str);
+ f._read = eofread;
+ _UB(&f)._base = NULL;
+ f._lb._base = NULL;
+ return (__svfscanf_unlocked(&f, fmt, ap));
+}
diff --git a/StdLib/LibC/Stdio/vswprintf.c b/StdLib/LibC/Stdio/vswprintf.c
new file mode 100644
index 0000000000..6d4cc3e656
--- /dev/null
+++ b/StdLib/LibC/Stdio/vswprintf.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ FreeBSD: src/lib/libc/stdio/vswprintf.c,v 1.6 2005/02/21 19:41:44 fjoe Exp
+ NetBSD: vswprintf.c,v 1.1 2005/05/14 23:51:02 christos Exp
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <stdarg.h>
+#include "reentrant.h"
+#include "local.h"
+
+int
+vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt,
+ va_list ap)
+{
+ static const mbstate_t initial = { 0 };
+ mbstate_t mbs;
+ FILE f;
+ char *mbp;
+ int ret, sverrno;
+ size_t nwc;
+ struct __sfileext fext;
+
+ if (n == 0) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ _FILEEXT_SETUP(&f, &fext);
+ f._file = -1;
+ f._flags = __SWR | __SSTR | __SALC;
+ f._bf._base = f._p = (unsigned char *)malloc(128);
+ if (f._bf._base == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+ f._bf._size = f._w = 127; /* Leave room for the NUL */
+ ret = __vfwprintf_unlocked(&f, fmt, ap);
+ if (ret < 0) {
+ sverrno = errno;
+ free(f._bf._base);
+ errno = sverrno;
+ return (-1);
+ }
+ *f._p = '\0';
+ mbp = (char *)f._bf._base;
+ /*
+ * XXX Undo the conversion from wide characters to multibyte that
+ * fputwc() did in __vfwprintf().
+ */
+ mbs = initial;
+ nwc = mbsrtowcs(s, (const char **)&mbp, n, &mbs);
+ free(f._bf._base);
+ if (nwc == (size_t)-1) {
+ errno = EILSEQ;
+ return (-1);
+ }
+ if (nwc == n) {
+ s[n - 1] = L'\0';
+ errno = EOVERFLOW;
+ return (-1);
+ }
+
+ return (ret);
+}
diff --git a/StdLib/LibC/Stdio/vswscanf.c b/StdLib/LibC/Stdio/vswscanf.c
new file mode 100644
index 0000000000..3f62666652
--- /dev/null
+++ b/StdLib/LibC/Stdio/vswscanf.c
@@ -0,0 +1,100 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Donn Seeley at UUNET Technologies, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+
+ FreeBSD: src/lib/libc/stdio/vswscanf.c,v 1.3 2004/04/07 09:55:05 tjr Exp
+ NetBSD: vswscanf.c,v 1.3 2005/12/02 13:51:22 yamt Exp
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#include <limits.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <sys/types.h>
+#include "reentrant.h"
+#include "local.h"
+
+static int eofread(void *, char *, int);
+
+static int
+/*ARGSUSED*/
+eofread(void *cookie, char *buf, int len)
+{
+ return (0);
+}
+
+int
+vswscanf(
+ const wchar_t * __restrict str,
+ const wchar_t * __restrict fmt,
+ va_list ap
+ )
+{
+ static const mbstate_t initial = { 0 };
+ mbstate_t mbs;
+ FILE f;
+ char *mbstr;
+ size_t mlen;
+ int r;
+ const wchar_t *rstr = str;
+ struct __sfileext fext = { 0 };
+
+ /*
+ * XXX Convert the wide character string to multibyte, which
+ * __vfwscanf() will convert back to wide characters.
+ */
+ if ((mbstr = malloc(wcslen(str) * MB_CUR_MAX + 1)) == NULL)
+ return (EOF);
+ mbs = initial;
+ if ((mlen = wcsrtombs(mbstr, &rstr, SIZE_T_MAX, &mbs)) == (size_t)-1) {
+ free(mbstr);
+ return (EOF);
+ }
+ _FILEEXT_SETUP(&f, &fext);
+ f._file = -1;
+ f._flags = __SRD;
+ f._bf._base = f._p = (unsigned char *)mbstr;
+ f._bf._size = f._r = (int)mlen;
+ f._read = eofread;
+ _UB(&f)._base = NULL;
+ f._lb._base = NULL;
+ r = __vfwscanf_unlocked(&f, fmt, ap);
+ free(mbstr);
+
+ return (r);
+}
diff --git a/StdLib/LibC/Stdio/vwprintf.c b/StdLib/LibC/Stdio/vwprintf.c
new file mode 100644
index 0000000000..ebd42b07d4
--- /dev/null
+++ b/StdLib/LibC/Stdio/vwprintf.c
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 2002 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+
+ FreeBSD: src/lib/libc/stdio/vwprintf.c,v 1.1 2002/09/21 13:00:30 tjr Exp
+ NetBSD: vwprintf.c,v 1.1 2005/05/14 23:51:02 christos Exp
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <wchar.h>
+
+int
+vwprintf(const wchar_t * __restrict fmt, va_list ap)
+{
+
+ return (vfwprintf(stdout, fmt, ap));
+}
diff --git a/StdLib/LibC/Stdio/vwscanf.c b/StdLib/LibC/Stdio/vwscanf.c
new file mode 100644
index 0000000000..25f795f157
--- /dev/null
+++ b/StdLib/LibC/Stdio/vwscanf.c
@@ -0,0 +1,47 @@
+/* $NetBSD: vwscanf.c,v 1.1 2005/05/14 23:51:02 christos Exp $ */
+
+/*-
+ * Copyright (c) 2002 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+__FBSDID("$FreeBSD: src/lib/libc/stdio/vwscanf.c,v 1.1 2002/09/23 12:40:06 tjr Exp $");
+#else
+__RCSID("$NetBSD: vwscanf.c,v 1.1 2005/05/14 23:51:02 christos Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <wchar.h>
+
+int
+vwscanf(const wchar_t * __restrict fmt, va_list ap)
+{
+
+ return (vfwscanf(stdin, fmt, ap));
+}
diff --git a/StdLib/LibC/Stdio/wbuf.c b/StdLib/LibC/Stdio/wbuf.c
new file mode 100644
index 0000000000..8482a18e87
--- /dev/null
+++ b/StdLib/LibC/Stdio/wbuf.c
@@ -0,0 +1,99 @@
+/* $NetBSD: wbuf.c,v 1.13 2003/08/07 16:43:35 agc Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)wbuf.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: wbuf.c,v 1.13 2003/08/07 16:43:35 agc Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include "reentrant.h"
+#include "local.h"
+
+/*
+ * Write the given character into the (probably full) buffer for
+ * the given file. Flush the buffer out if it is or becomes full,
+ * or if c=='\n' and the file is line buffered.
+ */
+int
+__swbuf(int c, FILE *fp)
+{
+ int n;
+
+ //_DIAGASSERT(fp != NULL);
+
+ _SET_ORIENTATION(fp, -1);
+
+ /*
+ * In case we cannot write, or longjmp takes us out early,
+ * make sure _w is 0 (if fully- or un-buffered) or -_bf._size
+ * (if line buffered) so that we will get called again.
+ * If we did not do this, a sufficient number of putc()
+ * calls might wrap _w from negative to positive.
+ */
+ fp->_w = fp->_lbfsize;
+ if (cantwrite(fp)) {
+ errno = EBADF;
+ return (EOF);
+ }
+ c = (unsigned char)c;
+
+ /*
+ * If it is completely full, flush it out. Then, in any case,
+ * stuff c into the buffer. If this causes the buffer to fill
+ * completely, or if c is '\n' and the file is line buffered,
+ * flush it (perhaps a second time). The second flush will always
+ * happen on unbuffered streams, where _bf._size==1; fflush()
+ * guarantees that putc() will always call wbuf() by setting _w
+ * to 0, so we need not do anything else.
+ */
+ n = (int)(fp->_p - fp->_bf._base);
+ if (n >= fp->_bf._size) {
+ if (fflush(fp))
+ return (EOF);
+ n = 0;
+ }
+ fp->_w--;
+ *fp->_p++ = (unsigned char)c;
+ if (++n == fp->_bf._size || (fp->_flags & __SLBF && c == '\n'))
+ if (fflush(fp))
+ return (EOF);
+ return (c);
+}
diff --git a/StdLib/LibC/Stdio/wcio.h b/StdLib/LibC/Stdio/wcio.h
new file mode 100644
index 0000000000..ab15bb53d5
--- /dev/null
+++ b/StdLib/LibC/Stdio/wcio.h
@@ -0,0 +1,72 @@
+/* $NetBSD: wcio.h,v 1.3 2003/01/18 11:30:00 thorpej Exp $ */
+
+/*-
+ * Copyright (c)2001 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Citrus$
+ */
+
+#ifndef _WCIO_H_
+#define _WCIO_H_
+
+#include <wchar.h> /* for mbstate_t and wchar_t */
+
+/* minimal requirement of SUSv2 */
+#define WCIO_UNGETWC_BUFSIZE 1
+
+#define WCIO_GET(fp) (&(_EXT(fp)->_wcio))
+
+struct wchar_io_data {
+ mbstate_t wcio_mbstate_in;
+ mbstate_t wcio_mbstate_out;
+
+ wchar_t wcio_ungetwc_buf[WCIO_UNGETWC_BUFSIZE];
+ size_t wcio_ungetwc_inbuf;
+
+ int wcio_mode; /* orientation */
+};
+
+#define _SET_ORIENTATION(fp, mode) \
+do {\
+ struct wchar_io_data *_wcio = WCIO_GET(fp);\
+ if (_wcio && _wcio->wcio_mode == 0)\
+ _wcio->wcio_mode = (mode);\
+} while (/*CONSTCOND*/0)
+
+/*
+ * WCIO_FREE should be called by fclose
+ */
+#define WCIO_FREE(fp) \
+do {\
+ _EXT(fp)->_wcio.wcio_mode = 0;\
+ WCIO_FREEUB(fp);\
+} while (/*CONSTCOND*/0)
+
+#define WCIO_FREEUB(fp) \
+do {\
+ _EXT(fp)->_wcio.wcio_ungetwc_inbuf = 0;\
+} while (/*CONSTCOND*/0)
+
+#endif /*_WCIO_H_*/
diff --git a/StdLib/LibC/Stdio/wprintf.c b/StdLib/LibC/Stdio/wprintf.c
new file mode 100644
index 0000000000..18b83a7927
--- /dev/null
+++ b/StdLib/LibC/Stdio/wprintf.c
@@ -0,0 +1,53 @@
+/* $NetBSD: wprintf.c,v 1.1 2005/05/14 23:51:02 christos Exp $ */
+
+/*-
+ * Copyright (c) 2002 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+__FBSDID("$FreeBSD: src/lib/libc/stdio/wprintf.c,v 1.1 2002/09/21 13:00:30 tjr Exp $");
+#else
+__RCSID("$NetBSD: wprintf.c,v 1.1 2005/05/14 23:51:02 christos Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <wchar.h>
+
+int
+wprintf(const wchar_t * __restrict fmt, ...)
+{
+ int ret;
+ va_list ap;
+
+ va_start(ap, fmt);
+ ret = vfwprintf(stdout, fmt, ap);
+ va_end(ap);
+
+ return (ret);
+}
diff --git a/StdLib/LibC/Stdio/wscanf.c b/StdLib/LibC/Stdio/wscanf.c
new file mode 100644
index 0000000000..4240c72056
--- /dev/null
+++ b/StdLib/LibC/Stdio/wscanf.c
@@ -0,0 +1,53 @@
+/* $NetBSD: wscanf.c,v 1.1 2005/05/14 23:51:02 christos Exp $ */
+
+/*-
+ * Copyright (c) 2002 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+__FBSDID("$FreeBSD: src/lib/libc/stdio/wscanf.c,v 1.1 2002/09/23 12:40:06 tjr Exp $");
+#else
+__RCSID("$NetBSD: wscanf.c,v 1.1 2005/05/14 23:51:02 christos Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <wchar.h>
+
+int
+wscanf(const wchar_t * __restrict fmt, ...)
+{
+ va_list ap;
+ int r;
+
+ va_start(ap, fmt);
+ r = vfwscanf(stdin, fmt, ap);
+ va_end(ap);
+
+ return (r);
+}
diff --git a/StdLib/LibC/Stdio/wsetup.c b/StdLib/LibC/Stdio/wsetup.c
new file mode 100644
index 0000000000..c1077bc9df
--- /dev/null
+++ b/StdLib/LibC/Stdio/wsetup.c
@@ -0,0 +1,99 @@
+/* $NetBSD: wsetup.c,v 1.11 2003/08/07 16:43:35 agc Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)wsetup.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: wsetup.c,v 1.11 2003/08/07 16:43:35 agc Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "reentrant.h"
+#include "local.h"
+
+/*
+ * Various output routines call wsetup to be sure it is safe to write,
+ * because either _flags does not include __SWR, or _buf is NULL.
+ * _wsetup returns 0 if OK to write, nonzero otherwise.
+ */
+int
+__swsetup(FILE *fp)
+{
+
+ _DIAGASSERT(fp != NULL);
+
+ /* make sure stdio is set up */
+ if (!__sdidinit)
+ __sinit();
+
+ /*
+ * If we are not writing, we had better be reading and writing.
+ */
+ if ((fp->_flags & __SWR) == 0) {
+ if ((fp->_flags & __SRW) == 0)
+ return (EOF);
+ if (fp->_flags & __SRD) {
+ /* clobber any ungetc data */
+ if (HASUB(fp))
+ FREEUB(fp);
+ fp->_flags &= ~(__SRD|__SEOF);
+ fp->_r = 0;
+ fp->_p = fp->_bf._base;
+ }
+ fp->_flags |= __SWR;
+ }
+
+ /*
+ * Make a buffer if necessary, then set _w.
+ */
+ if (fp->_bf._base == NULL)
+ __smakebuf(fp);
+ if (fp->_flags & __SLBF) {
+ /*
+ * It is line buffered, so make _lbfsize be -_bufsize
+ * for the putc() macro. We will change _lbfsize back
+ * to 0 whenever we turn off __SWR.
+ */
+ fp->_w = 0;
+ fp->_lbfsize = -fp->_bf._size;
+ } else
+ fp->_w = fp->_flags & __SNBF ? 0 : fp->_bf._size;
+ return (0);
+}
diff --git a/StdLib/LibC/String/Comparison.c b/StdLib/LibC/String/Comparison.c
new file mode 100644
index 0000000000..e656fe73f5
--- /dev/null
+++ b/StdLib/LibC/String/Comparison.c
@@ -0,0 +1,118 @@
+/** @file
+ Comparison Functions for <string.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include <LibConfig.h>
+
+#include <ctype.h>
+#include <string.h>
+
+/** The memcmp function compares the first n characters of the object pointed
+ to by s1 to the first n characters of the object pointed to by s2.
+
+ @return The memcmp function returns an integer greater than, equal to, or
+ less than zero, accordingly as the object pointed to by s1 is
+ greater than, equal to, or less than the object pointed to by s2.
+**/
+int memcmp(const void *s1, const void *s2, size_t n)
+{
+ return (int)CompareMem( s1, s2, n);
+}
+
+/** The strcmp function compares the string pointed to by s1 to the string
+ pointed to by s2.
+
+ @return The strcmp function returns an integer greater than, equal to, or
+ less than zero, accordingly as the string pointed to by s1 is
+ greater than, equal to, or less than the string pointed to by s2.
+**/
+int strcmp(const char *s1, const char *s2)
+{
+ return (int)AsciiStriCmp( s1, s2);
+}
+
+/** The strcoll function compares the string pointed to by s1 to the string
+ pointed to by s2, both interpreted as appropriate to the LC_COLLATE
+ category of the current locale.
+
+ @return The strcoll function returns an integer greater than, equal to,
+ or less than zero, accordingly as the string pointed to by s1 is
+ greater than, equal to, or less than the string pointed to by s2
+ when both are interpreted as appropriate to the current locale.
+**/
+int strcoll(const char *s1, const char *s2)
+{
+ /* LC_COLLATE is unimplemented, hence always "C" */
+ return (strcmp(s1, s2));
+}
+
+/** The strncmp function compares not more than n characters (characters that
+ follow a null character are not compared) from the array pointed to by s1
+ to the array pointed to by s2.
+
+ @return The strncmp function returns an integer greater than, equal to,
+ or less than zero, accordingly as the possibly null-terminated
+ array pointed to by s1 is greater than, equal to, or less than
+ the possibly null-terminated array pointed to by s2.
+**/
+int strncmp(const char *s1, const char *s2, size_t n)
+{
+ return (int)AsciiStrnCmp( s1, s2, n);
+}
+
+/** The strxfrm function transforms the string pointed to by s2 and places the
+ resulting string into the array pointed to by s1. The transformation is
+ such that if the strcmp function is applied to two transformed strings, it
+ returns a value greater than, equal to, or less than zero, corresponding to
+ the result of the strcoll function applied to the same two original
+ strings. No more than n characters are placed into the resulting array
+ pointed to by s1, including the terminating null character. If n is zero,
+ s1 is permitted to be a null pointer. If copying takes place between
+ objects that overlap, the behavior is undefined.
+
+ @return The strxfrm function returns the length of the transformed string
+ (not including the terminating null character). If the value
+ returned is n or more, the contents of the array pointed to by s1
+ are indeterminate.
+**/
+size_t strxfrm(char * __restrict s1, const char * __restrict s2, size_t n)
+{
+ size_t srclen, copysize;
+
+ /*
+ * Since locales are unimplemented, this is just a copy.
+ */
+ srclen = strlen(s2);
+ if (n != 0) {
+ copysize = srclen < n ? srclen : n - 1;
+ (void)memcpy(s1, s2, copysize);
+ s1[copysize] = 0;
+ }
+ return (srclen);
+}
+
+/** Case agnostic string comparison for NetBSD compatibility. **/
+int
+strcasecmp(const char *s1, const char *s2)
+{
+ const unsigned char *us1 = (const unsigned char *)s1,
+ *us2 = (const unsigned char *)s2;
+
+ while (tolower(*us1) == tolower(*us2++))
+ if (*us1++ == '\0')
+ return (0);
+ return (tolower(*us1) - tolower(*--us2));
+}
+
diff --git a/StdLib/LibC/String/Concatenation.c b/StdLib/LibC/String/Concatenation.c
new file mode 100644
index 0000000000..e76bea0bf8
--- /dev/null
+++ b/StdLib/LibC/String/Concatenation.c
@@ -0,0 +1,83 @@
+/** @file
+ Concatenation Functions for <string.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+
+#include <LibConfig.h>
+
+#include <string.h>
+
+/** The strcat function appends a copy of the string pointed to by s2
+ (including the terminating null character) to the end of the string pointed
+ to by s1. The initial character of s2 overwrites the null character at the
+ end of s1. If copying takes place between objects that overlap, the
+ behavior is undefined.
+
+ @return The strcat function returns the value of s1.
+**/
+char *
+strcat(char * __restrict s1, const char * __restrict s2)
+{
+ return AsciiStrCat( s1, s2);
+}
+
+/** The strncat function appends not more than n characters (a null character
+ and characters that follow it are not appended) from the array pointed to
+ by s2 to the end of the string pointed to by s1. The initial character of
+ s2 overwrites the null character at the end of s1. A terminating null
+ character is always appended to the result. If copying takes place
+ between objects that overlap, the behavior is undefined.
+
+ @return The strncat function returns the value of s1.
+**/
+char *
+strncat(char * __restrict s1, const char * __restrict s2, size_t n)
+{
+ return AsciiStrnCat( s1, s2, n);
+}
+
+/** The strncatX function appends not more than n characters (a null character
+ and characters that follow it are not appended) from the array pointed to
+ by s2 to the end of the string pointed to by s1. The initial character of
+ s2 overwrites the null character at the end of s1. The result is always
+ terminated with a null character. If copying takes place between objects
+ that overlap, the behavior is undefined.
+
+ strncatX exists because normal strncat does not indicate if the operation
+ was terminated because of exhausting n or reaching the end of s2.
+
+ @return The strncatX function returns 0 if the operation was terminated
+ because it reached the end of s1. Otherwise, a non-zero value is
+ returned indicating how many characters remain in s1.
+**/
+int
+strncatX(char * __restrict s1, const char * __restrict s2, size_t n)
+{
+ int NumLeft;
+
+ // Find s1's terminating NUL
+ for( ; n != 0; --n) {
+ if( *s1++ == '\0') break;
+ }
+
+ // Now copy *s2 into s1, overwriting s1's terminating NUL
+ for( --s1; n != 0; --n) {
+ if((*s1++ = *s2++) == '\0') break;
+ }
+ NumLeft = (int)n;
+
+ // Guarantee that s1 is NUL terminated.
+ *--s1 = '\0';
+
+ return NumLeft; // Zero if we ran out of buffer ( strlen(s1) < strlen(s2) )
+}
diff --git a/StdLib/LibC/String/Copying.c b/StdLib/LibC/String/Copying.c
new file mode 100644
index 0000000000..2d5200e3c5
--- /dev/null
+++ b/StdLib/LibC/String/Copying.c
@@ -0,0 +1,141 @@
+/** @file
+ Copying Functions for <string.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+//#include <sys/EfiCdefs.h>
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include <LibConfig.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+/** The memcpy function copies n characters from the object pointed to by s2
+ into the object pointed to by s1.
+
+ The implementation is reentrant and handles the case where s2 overlaps s1.
+
+ @return The memcpy function returns the value of s1.
+**/
+void *
+memcpy(void * __restrict s1, const void * __restrict s2, size_t n)
+{
+ return CopyMem( s1, s2, n);
+}
+
+/** The memmove function copies n characters from the object pointed to by s2
+ into the object pointed to by s1. Copying takes place as if the n
+ characters from the object pointed to by s2 are first copied into a
+ temporary array of n characters that does not overlap the objects pointed
+ to by s1 and s2, and then the n characters from the temporary array are
+ copied into the object pointed to by s1.
+
+ This is a version of memcpy that is guaranteed to work when s1 and s2
+ overlap. Since our implementation of memcpy already handles overlap,
+ memmove can be identical to memcpy.
+
+ @return The memmove function returns the value of s1.
+**/
+void *
+memmove(void *s1, const void *s2, size_t n)
+{
+ return CopyMem( s1, s2, n);
+}
+
+/** The strcpy function copies the string pointed to by s2 (including the
+ terminating null character) into the array pointed to by s1. If copying
+ takes place between objects that overlap, the behavior is undefined.
+
+ @return The strcpy function returns the value of s1.
+**/
+char *
+strcpy(char * __restrict s1, const char * __restrict s2)
+{
+ //char *s1ret = s1;
+
+ //while ( *s1++ = *s2++) /* Empty Body */;
+ //return(s1ret);
+ return AsciiStrCpy( s1, s2);
+}
+
+/** The strncpy function copies not more than n characters (characters that
+ follow a null character are not copied) from the array pointed to by s2 to
+ the array pointed to by s1. If copying takes place between objects that
+ overlap, the behavior is undefined.
+
+ If the array pointed to by s2 is a string that is shorter than n
+ characters, null characters are appended to the copy in the array pointed
+ to by s1, until n characters in all have been written.
+
+ @return The strncpy function returns the value of s1.
+**/
+char *strncpy(char * __restrict s1, const char * __restrict s2, size_t n)
+{
+ return AsciiStrnCpy( s1, s2, n);
+ //char *dest = s1;
+
+ //while(n != 0) {
+ // --n;
+ // if((*dest++ = *s2++) == '\0') break;
+ //}
+ //while(n != 0) {
+ // *dest++ = '\0';
+ // --n;
+ //}
+ //return (s1);
+}
+
+/** The strncpyX function copies not more than n-1 characters (characters that
+ follow a null character are not copied) from the array pointed to by s2 to
+ the array pointed to by s1. Array s1 is guaranteed to be NULL terminated.
+ If copying takes place between objects that overlap,
+ the behavior is undefined.
+
+ strncpyX exists because normal strncpy does not indicate if the copy was
+ terminated because of exhausting the buffer or reaching the end of s2.
+
+ @return The strncpyX function returns 0 if the copy operation was
+ terminated because it reached the end of s1. Otherwise,
+ a non-zero value is returned indicating how many characters
+ remain in s1.
+**/
+int strncpyX(char * __restrict s1, const char * __restrict s2, size_t n)
+{
+ int NumLeft;
+
+ for( ; n != 0; --n) {
+ if((*s1++ = *s2++) == '\0') break;
+ }
+ NumLeft = (int)n;
+
+ for( --s1; n != 0; --n) {
+ *s1++ = '\0';
+ }
+
+ return NumLeft; // Zero if we ran out of buffer ( strlen(s1) < strlen(s2) )
+}
+
+/** NetBSD Compatibility Function strdup creates a duplicate copy of a string. **/
+char *
+strdup(const char *str)
+{
+ size_t len;
+ char *copy;
+
+ len = strlen(str) + 1;
+ if ((copy = malloc(len)) == NULL)
+ return (NULL);
+ memcpy(copy, str, len);
+ return (copy);
+}
diff --git a/StdLib/LibC/String/ErrorList.c b/StdLib/LibC/String/ErrorList.c
new file mode 100644
index 0000000000..56c286011f
--- /dev/null
+++ b/StdLib/LibC/String/ErrorList.c
@@ -0,0 +1,144 @@
+/** @file
+ This header defines the human readable descriptions of the errors declared
+ in errno.h.
+
+ The string literals defined in this file must be kept in sync with the
+ error numbers declared in <errno.h>. This is because the error numbers are
+ used to index into the sys_errlist array to retrieve its associated
+ string literal.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+/* Describe the error numbers, sequentially, beginning at 0. */
+const char *const
+sys_errlist[] = {
+ "No Error Detected", /* 0 errno reset or no error yet detected */
+ "Operation not permitted", /* 1 EPERM */
+ "No such file or directory", /* 2 ENOENT */
+ "No such process", /* 3 ESRCH */
+ "Interrupted system call", /* 4 EINTR */
+ "Input/output error", /* 5 EIO */
+ "Device not configured", /* 6 ENXIO */
+ "Argument list too long", /* 7 E2BIG */
+ "Exec format error", /* 8 ENOEXEC */
+ "Bad file descriptor", /* 9 EBADF */
+ "No child processes", /* 10 ECHILD */
+ "Resource deadlock avoided", /* 11 EDEADLK */
+ "Cannot allocate memory", /* 12 ENOMEM */
+ "Permission denied", /* 13 EACCES */
+ "Bad address", /* 14 EFAULT */
+ "Block device required", /* 15 ENOTBLK */
+ "Device busy", /* 16 EBUSY */
+ "File exists", /* 17 EEXIST */
+ "Cross-device link", /* 18 EXDEV */
+ "Operation not supported by device", /* 19 ENODEV */
+ "Not a directory", /* 20 ENOTDIR */
+ "Is a directory", /* 21 EISDIR */
+ "Invalid argument", /* 22 EINVAL */
+ "Too many open files in system", /* 23 ENFILE */
+ "Too many open files", /* 24 EMFILE */
+ "Inappropriate ioctl for device", /* 25 ENOTTY */
+ "Text file busy", /* 26 ETXTBSY */
+ "File too large", /* 27 EFBIG */
+ "No space left on device", /* 28 ENOSPC */
+ "Illegal seek", /* 29 ESPIPE */
+ "Read-only filesystem", /* 30 EROFS */
+ "Too many links", /* 31 EMLINK */
+ "Broken pipe", /* 32 EPIPE */
+
+ /* math software -- these are the only two values required by the C Standard */
+ "Numerical argument out of domain", /* 33 EDOM */
+ "Result too large", /* 34 ERANGE */
+
+ /* non-blocking and interrupt i/o */
+ "Resource temporarily unavailable", /* 35 EAGAIN or EWOULDBLOCK */
+ "Operation now in progress", /* 36 EINPROGRESS */
+ "Operation already in progress", /* 37 EALREADY */
+
+ /* ipc/network software -- argument errors */
+ "Socket operation on non-socket", /* 38 ENOTSOCK */
+ "Destination address required", /* 39 EDESTADDRREQ */
+ "Message too long", /* 40 EMSGSIZE */
+ "Protocol wrong type for socket", /* 41 EPROTOTYPE */
+ "Protocol not available", /* 42 ENOPROTOOPT */
+ "Protocol not supported", /* 43 EPROTONOSUPPORT */
+ "Socket type not supported", /* 44 ESOCKTNOSUPPORT */
+ "Operation not supported", /* 45 EOPNOTSUPP or ENOTSUP */
+ "Protocol family not supported", /* 46 EPFNOSUPPORT */
+ "Address family not supported by protocol family", /* 47 EAFNOSUPPORT */
+ "Address already in use", /* 48 EADDRINUSE */
+ "Can't assign requested address", /* 49 EADDRNOTAVAIL */
+
+ /* ipc/network software -- operational errors */
+ "Network is down", /* 50 ENETDOWN */
+ "Network is unreachable", /* 51 ENETUNREACH */
+ "Network dropped connection on reset", /* 52 ENETRESET */
+ "Software caused connection abort", /* 53 ECONNABORTED */
+ "Connection reset by peer", /* 54 ECONNRESET */
+ "No buffer space available", /* 55 ENOBUFS */
+ "Socket is already connected", /* 56 EISCONN */
+ "Socket is not connected", /* 57 ENOTCONN */
+ "Can't send after socket shutdown", /* 58 ESHUTDOWN */
+ "Too many references: can't splice", /* 59 ETOOMANYREFS */
+ "Operation timed out", /* 60 ETIMEDOUT */
+ "Connection refused", /* 61 ECONNREFUSED */
+ "Too many levels of symbolic links", /* 62 ELOOP */
+ "File name too long", /* 63 ENAMETOOLONG */
+ "Host is down", /* 64 EHOSTDOWN */
+ "No route to host", /* 65 EHOSTUNREACH */
+ "Directory not empty", /* 66 ENOTEMPTY */
+
+ /* quotas, etc. */
+ "Too many processes", /* 67 EPROCLIM */
+ "Too many users", /* 68 EUSERS */
+ "Disc quota exceeded", /* 69 EDQUOT */
+
+ /* Network File System */
+ "Stale NFS file handle", /* 70 ESTALE */
+ "Too many levels of remote in path", /* 71 EREMOTE */
+ "RPC struct is bad", /* 72 EBADRPC */
+ "RPC version wrong", /* 73 ERPCMISMATCH */
+ "RPC prog. not avail", /* 74 EPROGUNAVAIL */
+ "Program version wrong", /* 75 EPROGMISMATCH */
+ "Bad procedure for program", /* 76 EPROCUNAVAIL */
+ "No locks available", /* 77 ENOLCK */
+ "Function not implemented", /* 78 ENOSYS */
+ "Inappropriate file type or format", /* 79 EFTYPE */
+ "Authentication error", /* 80 EAUTH */
+ "Need authenticator", /* 81 ENEEDAUTH */
+ "Identifier removed", /* 82 EIDRM */
+ "No message of desired type", /* 83 ENOMSG */
+ "Value too large to be stored in data type", /* 84 EOVERFLOW */
+ "Illegal byte sequence", /* 85 EILSEQ */
+ "Bad errno 86", /* 86 ENOTHING_1 */
+ "Operation canceled", /* 87 ECANCELED */
+
+ "Bad message", /* 88 EBADMSG */
+ "No message available", /* 89 ENODATA */
+ "No STREAM resources", /* 90 ENOSR */
+ "Not a STREAM", /* 91 ENOSTR */
+ "STREAM ioctl timeout", /* 92 ETIME */
+
+ "Attribute not found", /* 93 ENOATTR */
+
+ "Programming error", /* 94 EDOOFUS */
+
+ "Multihop attempted", /* 95 EMULTIHOP */
+ "Link has been severed", /* 96 ENOLINK */
+ "Protocol error", /* 97 EPROTO */
+
+ "Buffer too small to hold result", /* 98 EBUFSIZE */
+
+ "System Error list and errno.h are out-of-sync" /* EMAXERRORVAL - Should always be last. */
+};
diff --git a/StdLib/LibC/String/Misc.c b/StdLib/LibC/String/Misc.c
new file mode 100644
index 0000000000..99328252ed
--- /dev/null
+++ b/StdLib/LibC/String/Misc.c
@@ -0,0 +1,99 @@
+/** @file
+ Miscellaneous Functions for <string.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+//#include <sys/EfiCdefs.h>
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PrintLib.h>
+
+#include <LibConfig.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <string.h>
+
+extern char *sys_errlist[];
+
+/** The memset function copies the value of c (converted to an unsigned char)
+ into each of the first n characters of the object pointed to by s.
+
+ @return The memset function returns the value of s.
+**/
+void *
+memset(void *s, int c, size_t n)
+{
+ return SetMem( s, (UINTN)n, (UINT8)c);
+}
+
+int
+strerror_r(int errnum, char *buf, size_t buflen)
+{
+ const char *estring;
+ INTN i;
+ int retval = 0;
+
+ if( (errnum < 0) || (errnum >= EMAXERRORVAL)) {
+ (void) AsciiSPrint( buf, ASCII_STRING_MAX, "Unknown Error: %d.", errnum);
+ retval = EINVAL;
+ }
+ else {
+ estring = sys_errlist[errnum];
+ for( i = buflen; i > 0; --i) {
+ if( (*buf++ = *estring++) == '\0') {
+ break;
+ }
+ }
+ if(i == 0) {
+ retval = ERANGE;
+ }
+ }
+ return retval;
+}
+
+/** The strerror function maps the number in errnum to a message string.
+ Typically, the values for errnum come from errno, but strerror shall map
+ any value of type int to a message.
+
+ The implementation shall behave as if no library function calls the
+ strerror function.
+
+ @return The strerror function returns a pointer to the string, the
+ contents of which are locale specific. The array pointed to
+ shall not be modified by the program, but may be overwritten by
+ a subsequent call to the strerror function.
+**/
+char *
+strerror(int errnum)
+{
+ static char errorbuf[ASCII_STRING_MAX];
+ int status;
+
+ status = strerror_r(errnum, errorbuf, sizeof(errorbuf));
+ if(status != 0) {
+ errno = status;
+ }
+ return errorbuf;
+}
+
+/** The strlen function computes the length of the string pointed to by s.
+
+ @return The strlen function returns the number of characters that
+ precede the terminating null character.
+**/
+size_t
+strlen(const char *s)
+{
+ return (size_t)AsciiStrLen( s);
+}
diff --git a/StdLib/LibC/String/Searching.c b/StdLib/LibC/String/Searching.c
new file mode 100644
index 0000000000..e22655621c
--- /dev/null
+++ b/StdLib/LibC/String/Searching.c
@@ -0,0 +1,262 @@
+/** @file
+ Search Functions for <string.h>.
+
+ Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include <LibConfig.h>
+#include <limits.h>
+#include <string.h>
+
+/** The memchr function locates the first occurrence of c (converted to an
+ unsigned char) in the initial n characters (each interpreted as
+ unsigned char) of the object pointed to by s.
+
+ @return The memchr function returns a pointer to the located character,
+ or a null pointer if the character does not occur in the object.
+**/
+void *
+memchr(const void *s, int c, size_t n)
+{
+ return ScanMem8( s, (UINTN)n, (UINT8)c);
+}
+
+/** The strchr function locates the first occurrence of c (converted to a char)
+ in the string pointed to by s. The terminating null character is considered
+ to be part of the string.
+
+ @return The strchr function returns a pointer to the located character,
+ or a null pointer if the character does not occur in the string.
+**/
+char *
+strchr(const char *s, int c)
+{
+ char tgt = (char)c;
+
+ do {
+ if( *s == tgt) {
+ return (char *)s;
+ }
+ } while(*s++ != '\0');
+ return NULL;
+}
+
+static UINT8 BitMask[] = {
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
+ };
+
+#define WHICH8(c) ((unsigned char)(c) >> 3)
+#define WHICH_BIT(c) (BitMask[((c) & 0x7)])
+#define BITMAP64 ((UINT64 *)bitmap)
+
+static
+void
+BuildBitmap(unsigned char * bitmap, const char *s2, int n)
+{
+ unsigned char bit;
+ int index;
+
+ // Initialize bitmap. Bit 0 is always 1 which corresponds to '\0'
+ for (BITMAP64[0] = index = 1; index < n; index++)
+ BITMAP64[index] = 0;
+
+ // Set bits in bitmap corresponding to the characters in s2
+ for (; *s2 != '\0'; s2++) {
+ index = WHICH8(*s2);
+ bit = WHICH_BIT(*s2);
+ bitmap[index] = bitmap[index] | bit;
+ }
+}
+
+/** The strcspn function computes the length of the maximum initial segment of
+ the string pointed to by s1 which consists entirely of characters not from
+ the string pointed to by s2.
+
+ @return The strcspn function returns the length of the segment.
+**/
+size_t
+strcspn(const char *s1, const char *s2)
+{
+ UINT8 bitmap[ (((UCHAR_MAX + 1) / CHAR_BIT) + (CHAR_BIT - 1)) & ~7U];
+ const char *str;
+ UINT8 bit;
+ int index;
+
+ if(*s1 == '\0') return 0;
+
+ BuildBitmap( bitmap, s2, sizeof(bitmap) / sizeof(UINT64));
+
+ for(str = s1; ; str++) {
+ index = WHICH8(*str);
+ bit = WHICH_BIT(*str);
+ if ((bitmap[index] & bit) != 0)
+ break;
+ }
+ return (str - s1);
+}
+
+/** The strpbrk function locates the first occurrence in the string pointed to
+ by s1 of any character from the string pointed to by s2.
+
+ @return The strpbrk function returns a pointer to the character, or a
+ null pointer if no character from s2 occurs in s1.
+**/
+char *
+strpbrk(const char *s1, const char *s2)
+{
+ UINT8 bitmap[ (((UCHAR_MAX + 1) / CHAR_BIT) + (CHAR_BIT - 1)) & ~7U];
+ UINT8 bit;
+ int index;
+
+ BuildBitmap( bitmap, s2, sizeof(bitmap) / sizeof(UINT64));
+
+ for( ; *s1 != '\0'; ++s1) {
+ index = WHICH8(*s1);
+ bit = WHICH_BIT(*s1);
+ if( (bitmap[index] & bit) != 0) {
+ return (char *)s1;
+ }
+ }
+ return NULL;
+}
+
+/** The strrchr function locates the last occurrence of c (converted to a char)
+ in the string pointed to by s. The terminating null character is considered
+ to be part of the string.
+
+ @return The strrchr function returns a pointer to the character, or a
+ null pointer if c does not occur in the string.
+**/
+char *
+strrchr(const char *s, int c)
+{
+ char *found = NULL;
+ char tgt = (char)c;
+
+ do {
+ if( *s == tgt) found = (char *)s;
+ } while( *s++ != '\0');
+
+ return found;
+}
+
+/** The strspn function computes the length of the maximum initial segment of
+ the string pointed to by s1 which consists entirely of characters from the
+ string pointed to by s2.
+
+ @return The strspn function returns the length of the segment.
+**/
+size_t
+strspn(const char *s1 , const char *s2)
+{
+ UINT8 bitmap[ (((UCHAR_MAX + 1) / CHAR_BIT) + (CHAR_BIT - 1)) & ~7U];
+ size_t length = 0;
+ int index;
+ UINT8 bit;
+
+ BuildBitmap( bitmap, s2, sizeof(bitmap) / sizeof(UINT64));
+
+ for( ; *s1 != '\0'; ++s1) {
+ index = WHICH8(*s1);
+ bit = WHICH_BIT(*s1);
+ if( (bitmap[index] & bit) == 0) break;
+ ++length;
+ }
+ return length;
+}
+
+/** The strstr function locates the first occurrence in the string pointed to
+ by s1 of the sequence of characters (excluding the terminating null
+ character) in the string pointed to by s2.
+
+ @return The strstr function returns a pointer to the located string, or a
+ null pointer if the string is not found. If s2 points to a string
+ with zero length, the function returns s1.
+**/
+char *
+strstr(const char *s1 , const char *s2)
+{
+ return AsciiStrStr( s1, s2);
+}
+
+/** A sequence of calls to the strtok function breaks the string pointed to by
+ s1 into a sequence of tokens, each of which is delimited by a character
+ from the string pointed to by s2. The first call in the sequence has a
+ non-null first argument; subsequent calls in the sequence have a null first
+ argument. The separator string pointed to by s2 may be different from call
+ to call.
+
+ The first call in the sequence searches the string pointed to by s1 for the
+ first character that is not contained in the current separator string
+ pointed to by s2. If no such character is found, then there are no tokens
+ in the string pointed to by s1 and the strtok function returns a null
+ pointer. If such a character is found, it is the start of the first token.
+
+ The strtok function then searches from there for a character that is
+ contained in the current separator string. If no such character is found,
+ the current token extends to the end of the string pointed to by s1, and
+ subsequent searches for a token will return a null pointer. If such a
+ character is found, it is overwritten by a null character, which terminates
+ the current token. The strtok function saves a pointer to the following
+ character, from which the next search for a token will start.
+
+ Each subsequent call, with a null pointer as the value of the first
+ argument, starts searching from the saved pointer and behaves as
+ described above.
+
+ @return The strtok function returns a pointer to the first character of a
+ token, or a null pointer if there is no token.
+**/
+char *
+strtok(char * __restrict s1, const char * __restrict s2)
+{
+ static char *Next = NULL;
+ UINT8 bitmap[ (((UCHAR_MAX + 1) / CHAR_BIT) + (CHAR_BIT - 1)) & ~7U];
+ char *Token = NULL;
+ int index;
+ UINT8 bit;
+
+ if( (s1 == NULL)
+ && ((s1 = Next) == NULL))
+ {
+ return NULL;
+ }
+
+ // s2 can be different on each call, so build the bitmap each time.
+ BuildBitmap( bitmap, s2, sizeof(bitmap) / sizeof(UINT64));
+
+ // skip leading delimiters: all chars in s2
+ for( ; *s1 != '\0'; ++s1) {
+ index = WHICH8(*s1);
+ bit = WHICH_BIT(*s1);
+ if( (bitmap[index] & bit) == 0) break;
+ }
+ if( *s1 != 0)
+ {
+ // Remember this point, it is the start of the token
+ Token = s1++;
+
+ // find the next delimiter and replace it with a '\0'
+ for( ; *s1 != '\0'; ++s1) {
+ index = WHICH8(*s1);
+ bit = WHICH_BIT(*s1);
+ if( (bitmap[index] & bit) != 0) {
+ *s1++ = '\0';
+ Next = s1;
+ return Token;
+ }
+ }
+ }
+ Next = NULL;
+ return Token;
+}
diff --git a/StdLib/LibC/String/String.inf b/StdLib/LibC/String/String.inf
new file mode 100644
index 0000000000..1614b1cb11
--- /dev/null
+++ b/StdLib/LibC/String/String.inf
@@ -0,0 +1,62 @@
+## @file
+# Standard C library: Miscelaneous implementations.
+#
+# Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = LibString
+ FILE_GUID = caee2f3b-3191-4da0-ad10-a5c07e636cd1
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = LibString
+
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[Sources]
+ Misc.c
+ Copying.c
+ Concatenation.c
+ Comparison.c
+ Searching.c
+ ErrorList.c
+
+[Packages]
+ StdLib/StdLib.dec
+ StdLibPrivateInternalFiles/DoNotUse.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ PrintLib # Used for strerror()
+ PcdLib
+ LibC
+ LibCType
+ LibStdLib
+
+################################################################
+#
+# The Build Options, below, are only used when building the C library.
+# DO NOT use them when building your application!
+# Nasty things could happen if you do.
+#
+# /Oi- is required for Microsoft VC++ to allow "intrinsic" functions to be
+# defined in this library.
+# /GL- is required so that LTCG generated references to functions in this library,
+# such as memcpy(), can be resolved.
+#
+[BuildOptions]
+ MSFT:*_*_*_CC_FLAGS = /Oi- /GL-
diff --git a/StdLib/LibC/Time/Theory.txt b/StdLib/LibC/Time/Theory.txt
new file mode 100644
index 0000000000..f8e77adbdf
--- /dev/null
+++ b/StdLib/LibC/Time/Theory.txt
@@ -0,0 +1,553 @@
+# $NetBSD: Theory,v 1.8 2004/05/27 20:39:49 kleink Exp $
+@(#)Theory 7.15
+
+
+----- Outline -----
+
+ Time and date functions
+ Names of time zone regions
+ Time zone abbreviations
+ Calendrical issues
+ Time and time zones on Mars
+
+
+----- Time and date functions -----
+
+These time and date functions are upwards compatible with POSIX.1,
+an international standard for UNIX-like systems.
+As of this writing, the current edition of POSIX.1 is:
+
+ Information technology --Portable Operating System Interface (POSIX (R))
+ -- Part 1: System Application Program Interface (API) [C Language]
+ ISO/IEC 9945-1:1996
+ ANSI/IEEE Std 1003.1, 1996 Edition
+ 1996-07-12
+
+POSIX.1 has the following properties and limitations.
+
+* In POSIX.1, time display in a process is controlled by the
+ environment variable TZ. Unfortunately, the POSIX.1 TZ string takes
+ a form that is hard to describe and is error-prone in practice.
+ Also, POSIX.1 TZ strings can't deal with other (for example, Israeli)
+ daylight saving time rules, or situations where more than two
+ time zone abbreviations are used in an area.
+
+ The POSIX.1 TZ string takes the following form:
+
+ stdoffset[dst[offset],date[/time],date[/time]]
+
+ where:
+
+ std and dst
+ are 3 or more characters specifying the standard
+ and daylight saving time (DST) zone names.
+ offset
+ is of the form `[-]hh:[mm[:ss]]' and specifies the
+ offset west of UTC. The default DST offset is one hour
+ ahead of standard time.
+ date[/time],date[/time]
+ specifies the beginning and end of DST. If this is absent,
+ the system supplies its own rules for DST, and these can
+ differ from year to year; typically US DST rules are used.
+ time
+ takes the form `hh:[mm[:ss]]' and defaults to 02:00.
+ date
+ takes one of the following forms:
+ Jn (1<=n<=365)
+ origin-1 day number not counting February 29
+ n (0<=n<=365)
+ origin-0 day number counting February 29 if present
+ Mm.n.d (0[Sunday]<=d<=6[Saturday], 1<=n<=5, 1<=m<=12)
+ for the dth day of week n of month m of the year,
+ where week 1 is the first week in which day d appears,
+ and `5' stands for the last week in which day d appears
+ (which may be either the 4th or 5th week).
+
+* In POSIX.1, when a TZ value like "EST5EDT" is parsed,
+ typically the current US DST rules are used,
+ but this means that the US DST rules are compiled into each program
+ that does time conversion. This means that when US time conversion
+ rules change (as in the United States in 1987), all programs that
+ do time conversion must be recompiled to ensure proper results.
+
+* In POSIX.1, there's no tamper-proof way for a process to learn the
+ system's best idea of local wall clock. (This is important for
+ applications that an administrator wants used only at certain times--
+ without regard to whether the user has fiddled the "TZ" environment
+ variable. While an administrator can "do everything in UTC" to get
+ around the problem, doing so is inconvenient and precludes handling
+ daylight saving time shifts--as might be required to limit phone
+ calls to off-peak hours.)
+
+* POSIX.1 requires that systems ignore leap seconds.
+
+These are the extensions that have been made to the POSIX.1 functions:
+
+* The "TZ" environment variable is used in generating the name of a file
+ from which time zone information is read (or is interpreted a la
+ POSIX); "TZ" is no longer constrained to be a three-letter time zone
+ name followed by a number of hours and an optional three-letter
+ daylight time zone name. The daylight saving time rules to be used
+ for a particular time zone are encoded in the time zone file;
+ the format of the file allows U.S., Australian, and other rules to be
+ encoded, and allows for situations where more than two time zone
+ abbreviations are used.
+
+ It was recognized that allowing the "TZ" environment variable to
+ take on values such as "America/New_York" might cause "old" programs
+ (that expect "TZ" to have a certain form) to operate incorrectly;
+ consideration was given to using some other environment variable
+ (for example, "TIMEZONE") to hold the string used to generate the
+ time zone information file name. In the end, however, it was decided
+ to continue using "TZ": it is widely used for time zone purposes;
+ separately maintaining both "TZ" and "TIMEZONE" seemed a nuisance;
+ and systems where "new" forms of "TZ" might cause problems can simply
+ use TZ values such as "EST5EDT" which can be used both by
+ "new" programs (a la POSIX) and "old" programs (as zone names and
+ offsets).
+
+* To handle places where more than two time zone abbreviations are used,
+ the functions "localtime" and "gmtime" set tzname[tmp->tm_isdst]
+ (where "tmp" is the value the function returns) to the time zone
+ abbreviation to be used. This differs from POSIX.1, where the elements
+ of tzname are only changed as a result of calls to tzset.
+
+* Since the "TZ" environment variable can now be used to control time
+ conversion, the "daylight" and "timezone" variables are no longer
+ needed. (These variables are defined and set by "tzset"; however, their
+ values will not be used by "localtime.")
+
+* The "localtime" function has been set up to deliver correct results
+ for near-minimum or near-maximum time_t values. (A comment in the
+ source code tells how to get compatibly wrong results).
+
+* A function "tzsetwall" has been added to arrange for the system's
+ best approximation to local wall clock time to be delivered by
+ subsequent calls to "localtime." Source code for portable
+ applications that "must" run on local wall clock time should call
+ "tzsetwall();" if such code is moved to "old" systems that don't
+ provide tzsetwall, you won't be able to generate an executable program.
+ (These time zone functions also arrange for local wall clock time to be
+ used if tzset is called--directly or indirectly--and there's no "TZ"
+ environment variable; portable applications should not, however, rely
+ on this behavior since it's not the way SVR2 systems behave.)
+
+* These functions can account for leap seconds, thanks to Bradley White
+ (bww@k.cs.cmu.edu).
+
+Points of interest to folks with other systems:
+
+* This package is already part of many POSIX-compliant hosts,
+ including BSD, HP, Linux, Network Appliance, SCO, SGI, and Sun.
+ On such hosts, the primary use of this package
+ is to update obsolete time zone rule tables.
+ To do this, you may need to compile the time zone compiler
+ `zic' supplied with this package instead of using the system `zic',
+ since the format of zic's input changed slightly in late 1994,
+ and many vendors still do not support the new input format.
+
+* The UNIX Version 7 "timezone" function is not present in this package;
+ it's impossible to reliably map timezone's arguments (a "minutes west
+ of GMT" value and a "daylight saving time in effect" flag) to a
+ time zone abbreviation, and we refuse to guess.
+ Programs that in the past used the timezone function may now examine
+ tzname[localtime(&clock)->tm_isdst] to learn the correct time
+ zone abbreviation to use. Alternatively, use
+ localtime(&clock)->tm_zone if this has been enabled.
+
+* The 4.2BSD gettimeofday function is not used in this package.
+ This formerly let users obtain the current UTC offset and DST flag,
+ but this functionality was removed in later versions of BSD.
+
+* In SVR2, time conversion fails for near-minimum or near-maximum
+ time_t values when doing conversions for places that don't use UTC.
+ This package takes care to do these conversions correctly.
+
+The functions that are conditionally compiled if STD_INSPIRED is defined
+should, at this point, be looked on primarily as food for thought. They are
+not in any sense "standard compatible"--some are not, in fact, specified in
+*any* standard. They do, however, represent responses of various authors to
+standardization proposals.
+
+Other time conversion proposals, in particular the one developed by folks at
+Hewlett Packard, offer a wider selection of functions that provide capabilities
+beyond those provided here. The absence of such functions from this package
+is not meant to discourage the development, standardization, or use of such
+functions. Rather, their absence reflects the decision to make this package
+contain valid extensions to POSIX.1, to ensure its broad
+acceptability. If more powerful time conversion functions can be standardized,
+so much the better.
+
+
+----- Names of time zone rule files -----
+
+The time zone rule file naming conventions attempt to strike a balance
+among the following goals:
+
+ * Uniquely identify every national region where clocks have all
+ agreed since 1970. This is essential for the intended use: static
+ clocks keeping local civil time.
+
+ * Indicate to humans as to where that region is. This simplifes use.
+
+ * Be robust in the presence of political changes. This reduces the
+ number of updates and backward-compatibility hacks. For example,
+ names of countries are ordinarily not used, to avoid
+ incompatibilities when countries change their name
+ (e.g. Zaire->Congo) or when locations change countries
+ (e.g. Hong Kong from UK colony to China).
+
+ * Be portable to a wide variety of implementations.
+ This promotes use of the technology.
+
+ * Use a consistent naming convention over the entire world.
+ This simplifies both use and maintenance.
+
+This naming convention is not intended for use by inexperienced users
+to select TZ values by themselves (though they can of course examine
+and reuse existing settings). Distributors should provide
+documentation and/or a simple selection interface that explains the
+names; see the 'tzselect' program supplied with this distribution for
+one example.
+
+Names normally have the form AREA/LOCATION, where AREA is the name
+of a continent or ocean, and LOCATION is the name of a specific
+location within that region. North and South America share the same
+area, `America'. Typical names are `Africa/Cairo', `America/New_York',
+and `Pacific/Honolulu'.
+
+Here are the general rules used for choosing location names,
+in decreasing order of importance:
+
+ Use only valid POSIX file name components (i.e., the parts of
+ names other than `/'). Within a file name component,
+ use only ASCII letters, `.', `-' and `_'. Do not use
+ digits, as that might create an ambiguity with POSIX
+ TZ strings. A file name component must not exceed 14
+ characters or start with `-'. E.g., prefer `Brunei'
+ to `Bandar_Seri_Begawan'.
+ Include at least one location per time zone rule set per country.
+ One such location is enough. Use ISO 3166 (see the file
+ iso3166.tab) to help decide whether something is a country.
+ If all the clocks in a country's region have agreed since 1970,
+ don't bother to include more than one location
+ even if subregions' clocks disagreed before 1970.
+ Otherwise these tables would become annoyingly large.
+ If a name is ambiguous, use a less ambiguous alternative;
+ e.g. many cities are named San Jose and Georgetown, so
+ prefer `Costa_Rica' to `San_Jose' and `Guyana' to `Georgetown'.
+ Keep locations compact. Use cities or small islands, not countries
+ or regions, so that any future time zone changes do not split
+ locations into different time zones. E.g. prefer `Paris'
+ to `France', since France has had multiple time zones.
+ Use mainstream English spelling, e.g. prefer `Rome' to `Roma', and
+ prefer `Athens' to the true name (which uses Greek letters).
+ The POSIX file name restrictions encourage this rule.
+ Use the most populous among locations in a country's time zone,
+ e.g. prefer `Shanghai' to `Beijing'. Among locations with
+ similar populations, pick the best-known location,
+ e.g. prefer `Rome' to `Milan'.
+ Use the singular form, e.g. prefer `Canary' to `Canaries'.
+ Omit common suffixes like `_Islands' and `_City', unless that
+ would lead to ambiguity. E.g. prefer `Cayman' to
+ `Cayman_Islands' and `Guatemala' to `Guatemala_City',
+ but prefer `Mexico_City' to `Mexico' because the country
+ of Mexico has several time zones.
+ Use `_' to represent a space.
+ Omit `.' from abbreviations in names, e.g. prefer `St_Helena'
+ to `St._Helena'.
+ Do not change established names if they only marginally
+ violate the above rules. For example, don't change
+ the existing name `Rome' to `Milan' merely because
+ Milan's population has grown to be somewhat greater
+ than Rome's.
+ If a name is changed, put its old spelling in the `backward' file.
+
+The file `zone.tab' lists the geographical locations used to name
+time zone rule files.
+
+Older versions of this package used a different naming scheme,
+and these older names are still supported.
+See the file `backward' for most of these older names
+(e.g. `US/Eastern' instead of `America/New_York').
+The other old-fashioned names still supported are
+`WET', `CET', `MET', `EET' (see the file `europe'),
+and `Factory' (see the file `factory').
+
+
+----- Time zone abbreviations -----
+
+When this package is installed, it generates time zone abbreviations
+like `EST' to be compatible with human tradition and POSIX.1.
+Here are the general rules used for choosing time zone abbreviations,
+in decreasing order of importance:
+
+ Use abbreviations that consist of three or more ASCII letters.
+ Previous editions of this database also used characters like
+ ' ' and '?', but these characters have a special meaning to
+ the shell and cause commands like
+ set `date`
+ to have unexpected effects.
+ Previous editions of this rule required upper-case letters,
+ but the Congressman who introduced Chamorro Standard Time
+ preferred "ChST", so the rule has been relaxed.
+
+ This rule guarantees that all abbreviations could have
+ been specified by a POSIX.1 TZ string. POSIX.1
+ requires at least three characters for an
+ abbreviation. POSIX.1-1996 says that an abbreviation
+ cannot start with ':', and cannot contain ',', '-',
+ '+', NUL, or a digit. Draft 7 of POSIX 1003.1-200x
+ changes this rule to say that an abbreviation can
+ contain only '-', '+', and alphanumeric characters in
+ the current locale. To be portable to both sets of
+ rules, an abbreviation must therefore use only ASCII
+ letters, as these are the only letters that are
+ alphabetic in all locales.
+
+ Use abbreviations that are in common use among English-speakers,
+ e.g. `EST' for Eastern Standard Time in North America.
+ We assume that applications translate them to other languages
+ as part of the normal localization process; for example,
+ a French application might translate `EST' to `HNE'.
+
+ For zones whose times are taken from a city's longitude, use the
+ traditional xMT notation, e.g. `PMT' for Paris Mean Time.
+ The only name like this in current use is `GMT'.
+
+ If there is no common English abbreviation, abbreviate the English
+ translation of the usual phrase used by native speakers.
+ If this is not available or is a phrase mentioning the country
+ (e.g. ``Cape Verde Time''), then:
+
+ When a country has a single or principal time zone region,
+ append `T' to the country's ISO code, e.g. `CVT' for
+ Cape Verde Time. For summer time append `ST';
+ for double summer time append `DST'; etc.
+ When a country has multiple time zones, take the first three
+ letters of an English place name identifying each zone
+ and then append `T', `ST', etc. as before;
+ e.g. `VLAST' for VLAdivostok Summer Time.
+
+ Use "zzz" for locations while uninhabited. The mnemonic is that
+ these locations are, in some sense, asleep.
+
+Application writers should note that these abbreviations are ambiguous
+in practice: e.g. `EST' has a different meaning in Australia than
+it does in the United States. In new applications, it's often better
+to use numeric UTC offsets like `-0500' instead of time zone
+abbreviations like `EST'; this avoids the ambiguity.
+
+
+----- Calendrical issues -----
+
+Calendrical issues are a bit out of scope for a time zone database,
+but they indicate the sort of problems that we would run into if we
+extended the time zone database further into the past. An excellent
+resource in this area is Nachum Dershowitz and Edward M. Reingold,
+<a href="http://emr.cs.uiuc.edu/home/reingold/calendar-book/index.shtml">
+Calendrical Calculations
+</a>, Cambridge University Press (1997). Other information and
+sources are given below. They sometimes disagree.
+
+
+France
+
+Gregorian calendar adopted 1582-12-20.
+French Revolutionary calendar used 1793-11-24 through 1805-12-31,
+and (in Paris only) 1871-05-06 through 1871-05-23.
+
+
+Russia
+
+From Chris Carrier <72157.3334@CompuServe.COM> (1996-12-02):
+On 1929-10-01 the Soviet Union instituted an ``Eternal Calendar''
+with 30-day months plus 5 holidays, with a 5-day week.
+On 1931-12-01 it changed to a 6-day week; in 1934 it reverted to the
+Gregorian calendar while retaining the 6-day week; on 1940-06-27 it
+reverted to the 7-day week. With the 6-day week the usual days
+off were the 6th, 12th, 18th, 24th and 30th of the month.
+(Source: Evitiar Zerubavel, _The Seven Day Circle_)
+
+
+Mark Brader reported a similar story in "The Book of Calendars", edited
+by Frank Parise (1982, Facts on File, ISBN 0-8719-6467-8), page 377. But:
+
+From: Petteri Sulonen (via Usenet)
+Date: 14 Jan 1999 00:00:00 GMT
+Message-ID: <Petteri.Sulonen-1401991626030001@lapin-kulta.in.helsinki.fi>
+
+If your source is correct, how come documents between 1929 -- 1940 were
+still dated using the conventional, Gregorian calendar?
+
+I can post a scan of a document dated December 1, 1934, signed by
+Yenukidze, the secretary, on behalf of Kalinin, the President of the
+Executive Committee of the Supreme Soviet, if you like.
+
+
+
+Sweden (and Finland)
+
+From: msb@sq.com (Mark Brader)
+<a href="news:1996Jul6.012937.29190@sq.com">
+Subject: Re: Gregorian reform -- a part of locale?
+</a>
+Date: 1996-07-06
+
+In 1700, Denmark made the transition from Julian to Gregorian. Sweden
+decided to *start* a transition in 1700 as well, but rather than have one of
+those unsightly calendar gaps :-), they simply decreed that the next leap
+year after 1696 would be in 1744 -- putting the whole country on a calendar
+different from both Julian and Gregorian for a period of 40 years.
+
+However, in 1704 something went wrong and the plan was not carried through;
+they did, after all, have a leap year that year. And one in 1708. In 1712
+they gave it up and went back to Julian, putting 30 days in February that
+year!...
+
+Then in 1753, Sweden made the transition to Gregorian in the usual manner,
+getting there only 13 years behind the original schedule.
+
+(A previous posting of this story was challenged, and Swedish readers
+produced the following references to support it: "Tiderakning och historia"
+by Natanael Beckman (1924) and "Tid, en bok om tiderakning och
+kalendervasen" by Lars-Olof Lode'n (no date was given).)
+
+
+Grotefend's data
+
+From: "Michael Palmer" <mpalmer@netcom.com> [with one obvious typo fixed]
+Subject: Re: Gregorian Calendar (was Re: Another FHC related question
+Newsgroups: soc.genealogy.german
+Date: Tue, 9 Feb 1999 02:32:48 -800
+Message-ID: <199902091032.CAA09644@netcom10.netcom.com>
+
+The following is a(n incomplete) listing, arranged chronologically, of
+European states, with the date they converted from the Julian to the
+Gregorian calendar:
+
+04/15 Oct 1582 - Italy (with exceptions), Spain, Portugal, Poland (Roman
+ Catholics and Danzig only)
+09/20 Dec 1582 - France, Lorraine
+
+21 Dec 1582/
+ 01 Jan 1583 - Holland, Brabant, Flanders, Hennegau
+10/21 Feb 1583 - bishopric of Liege (L"uttich)
+13/24 Feb 1583 - bishopric of Augsburg
+04/15 Oct 1583 - electorate of Trier
+05/16 Oct 1583 - Bavaria, bishoprics of Freising, Eichstedt, Regensburg,
+ Salzburg, Brixen
+13/24 Oct 1583 - Austrian Oberelsass and Breisgau
+20/31 Oct 1583 - bishopric of Basel
+02/13 Nov 1583 - duchy of J"ulich-Berg
+02/13 Nov 1583 - electorate and city of K"oln
+04/15 Nov 1583 - bishopric of W"urzburg
+11/22 Nov 1583 - electorate of Mainz
+16/27 Nov 1583 - bishopric of Strassburg and the margraviate of Baden
+17/28 Nov 1583 - bishopric of M"unster and duchy of Cleve
+14/25 Dec 1583 - Steiermark
+
+06/17 Jan 1584 - Austria and Bohemia
+11/22 Jan 1584 - Luzern, Uri, Schwyz, Zug, Freiburg, Solothurn
+12/23 Jan 1584 - Silesia and the Lausitz
+22 Jan/
+ 02 Feb 1584 - Hungary (legally on 21 Oct 1587)
+ Jun 1584 - Unterwalden
+01/12 Jul 1584 - duchy of Westfalen
+
+16/27 Jun 1585 - bishopric of Paderborn
+
+14/25 Dec 1590 - Transylvania
+
+22 Aug/
+ 02 Sep 1612 - duchy of Prussia
+
+13/24 Dec 1614 - Pfalz-Neuburg
+
+ 1617 - duchy of Kurland (reverted to the Julian calendar in
+ 1796)
+
+ 1624 - bishopric of Osnabr"uck
+
+ 1630 - bishopric of Minden
+
+15/26 Mar 1631 - bishopric of Hildesheim
+
+ 1655 - Kanton Wallis
+
+05/16 Feb 1682 - city of Strassburg
+
+18 Feb/
+ 01 Mar 1700 - Protestant Germany (including Swedish possessions in
+ Germany), Denmark, Norway
+30 Jun/
+ 12 Jul 1700 - Gelderland, Zutphen
+10 Nov/
+ 12 Dec 1700 - Utrecht, Overijssel
+
+31 Dec 1700/
+ 12 Jan 1701 - Friesland, Groningen, Z"urich, Bern, Basel, Geneva,
+ Turgau, and Schaffhausen
+
+ 1724 - Glarus, Appenzell, and the city of St. Gallen
+
+01 Jan 1750 - Pisa and Florence
+
+02/14 Sep 1752 - Great Britain
+
+17 Feb/
+ 01 Mar 1753 - Sweden
+
+1760-1812 - Graub"unden
+
+The Russian empire (including Finland and the Baltic states) did not
+convert to the Gregorian calendar until the Soviet revolution of 1917.
+
+Source: H. Grotefend, _Taschenbuch der Zeitrechnung des deutschen
+Mittelalters und der Neuzeit_, herausgegeben von Dr. O. Grotefend
+(Hannover: Hahnsche Buchhandlung, 1941), pp. 26-28.
+
+
+----- Time and time zones on Mars -----
+
+Some people have adjusted their work schedules to fit Mars time.
+Dozens of special Mars watches were built for Jet Propulsion
+Laboratory workers who kept Mars time during the Mars Exploration
+Rovers mission (2004). These timepieces look like normal Seikos and
+Citizens but use Mars seconds rather than terrestrial seconds.
+
+A Mars solar day is called a "sol" and has a mean period equal to
+about 24 hours 39 minutes 35.244 seconds in terrestrial time. It is
+divided into a conventional 24-hour clock, so each Mars second equals
+about 1.02749125 terrestrial seconds.
+
+The prime meridian of Mars goes through the center of the crater
+Airy-0, named in honor of the British astronomer who built the
+Greenwich telescope that defines Earth's prime meridian. Mean solar
+time on the Mars prime meridian is called Mars Coordinated Time (MTC).
+
+Each landed mission on Mars has adopted a different reference for
+solar time keeping, so there is no real standard for Mars time zones.
+For example, the Mars Exploration Rover project (2004) defined two
+time zones "Local Solar Time A" and "Local Solar Time B" for its two
+missions, each zone designed so that its time equals local true solar
+time at approximately the middle of the nominal mission. Such a "time
+zone" is not particularly suited for any application other than the
+mission itself.
+
+Many calendars have been proposed for Mars, but none have achieved
+wide acceptance. Astronomers often use Mars Sol Date (MSD) which is a
+sequential count of Mars solar days elapsed since about 1873-12-29
+12:00 GMT.
+
+The tz database does not currently support Mars time, but it is
+documented here in the hopes that support will be added eventually.
+
+Sources:
+
+Michael Allison and Robert Schmunk,
+"Technical Notes on Mars Solar Time as Adopted by the Mars24 Sunclock"
+<http://www.giss.nasa.gov/tools/mars24/help/notes.html> (2004-03-15).
+
+Jia-Rui Chong, "Workdays Fit for a Martian", Los Angeles Times
+(2004-01-14), pp A1, A20-A21.
diff --git a/StdLib/LibC/Time/Time.c b/StdLib/LibC/Time/Time.c
new file mode 100644
index 0000000000..3192696f4a
--- /dev/null
+++ b/StdLib/LibC/Time/Time.c
@@ -0,0 +1,780 @@
+/**
+ Definitions and Implementation for <time.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Portions derived from the NIH time zone package file, localtime.c,
+ which contains the following notice:
+
+ This file is in the public domain, so clarified as of
+ 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
+
+ NetBSD: localtime.c,v 1.39 2006/03/22 14:01:30 christos Exp
+**/
+#include <Uefi.h>
+#include <Library/UefiLib.h>
+#include <Library/TimerLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+//#include <Library/UefiRuntimeLib.h>
+
+#include <LibConfig.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <time.h>
+#include <reentrant.h>
+#include "tzfile.h"
+#include "TimeVals.h"
+#include <MainData.h>
+#include <extern.h> // Library/include/extern.h: Private to implementation
+
+#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
+// Keep compiler quiet about casting from function to data pointers
+#pragma warning ( disable : 4054 )
+#endif /* defined(_MSC_VER) */
+
+/* ####################### Private Data ################################# */
+
+#if 0
+static EFI_TIME TimeBuffer;
+
+ static UINT16 MonthOffs[12] = {
+ 00,
+ 31, 59, 90, 120,
+ 151, 181, 212, 243,
+ 273, 304, 334
+ };
+ static clock_t y2kOffs = 730485;
+#endif
+
+const int mon_lengths[2][MONSPERYEAR] = {
+ { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+ { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
+};
+
+const int year_lengths[2] = {
+ DAYSPERNYEAR, DAYSPERLYEAR
+};
+
+
+static const char *wday_name[7] = {
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+};
+
+static const char *mon_name[12] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+static int gmt_is_set;
+
+/* ############### Implementation Functions ############################ */
+// Forward reference
+static void
+localsub(const time_t * const timep, const long offset, struct tm * const tmp);
+
+clock_t
+EFIAPI
+__getCPS(void)
+{
+ return gMD->ClocksPerSecond;
+}
+
+static void
+timesub(
+ const time_t * const timep,
+ const long offset,
+ const struct state * const sp,
+ struct tm * const tmp
+ )
+{
+ const struct lsinfo * lp;
+ time_t /*INTN*/ days;
+ time_t /*INTN*/ rem;
+ time_t /*INTN*/ y;
+ int yleap;
+ const int * ip;
+ time_t /*INTN*/ corr;
+ int hit;
+ int i;
+
+ corr = 0;
+ hit = 0;
+#ifdef ALL_STATE
+ i = (sp == NULL) ? 0 : sp->leapcnt;
+#endif /* defined ALL_STATE */
+#ifndef ALL_STATE
+ i = sp->leapcnt;
+#endif /* State Farm */
+ while (--i >= 0) {
+ lp = &sp->lsis[i];
+ if (*timep >= lp->ls_trans) {
+ if (*timep == lp->ls_trans) {
+ hit = ((i == 0 && lp->ls_corr > 0) ||
+ lp->ls_corr > sp->lsis[i - 1].ls_corr);
+ if (hit)
+ while (i > 0 &&
+ sp->lsis[i].ls_trans == sp->lsis[i - 1].ls_trans + 1 &&
+ sp->lsis[i].ls_corr == sp->lsis[i - 1].ls_corr + 1 )
+ {
+ ++hit;
+ --i;
+ }
+ }
+ corr = lp->ls_corr;
+ break;
+ }
+ }
+ days = *timep / SECSPERDAY;
+ rem = *timep % SECSPERDAY;
+ rem += (offset - corr);
+ while (rem < 0) {
+ rem += SECSPERDAY;
+ --days;
+ }
+ while (rem >= SECSPERDAY) {
+ rem -= SECSPERDAY;
+ ++days;
+ }
+ tmp->tm_hour = (int) (rem / SECSPERHOUR);
+ rem = rem % SECSPERHOUR;
+ tmp->tm_min = (int) (rem / SECSPERMIN);
+ /*
+ ** A positive leap second requires a special
+ ** representation. This uses "... ??:59:60" et seq.
+ */
+ tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
+ tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK);
+ if (tmp->tm_wday < 0)
+ tmp->tm_wday += DAYSPERWEEK;
+ y = EPOCH_YEAR;
+ while (days < 0 || days >= (LONG32) year_lengths[yleap = isleap(y)]) {
+ time_t /*INTN*/ newy;
+
+ newy = (y + days / DAYSPERNYEAR);
+ if (days < 0)
+ --newy;
+ days -= (newy - y) * DAYSPERNYEAR +
+ LEAPS_THRU_END_OF(newy - 1) -
+ LEAPS_THRU_END_OF(y - 1);
+ y = newy;
+ }
+ tmp->tm_year = (int)(y - TM_YEAR_BASE);
+ tmp->tm_yday = (int) days;
+ ip = mon_lengths[yleap];
+ for (tmp->tm_mon = 0; days >= (LONG32) ip[tmp->tm_mon]; ++(tmp->tm_mon))
+ days = days - (LONG32) ip[tmp->tm_mon];
+ tmp->tm_mday = (int) (days + 1);
+ tmp->tm_isdst = 0;
+#ifdef TM_GMTOFF
+ tmp->TM_GMTOFF = offset;
+#endif /* defined TM_GMTOFF */
+}
+
+/* ############### Time Manipulation Functions ########################## */
+
+/** The clock function determines the processor time used.
+
+ @return The clock function returns the implementation’s best
+ approximation to the processor time used by the program since the
+ beginning of an implementation-defined era related only to the
+ program invocation. To determine the time in seconds, the value
+ returned by the clock function should be divided by the value of
+ the macro CLOCKS_PER_SEC. If the processor time used is not
+ available or its value cannot be represented, the function
+ returns the value (clock_t)(-1).
+
+ On IA32 or X64 platforms, the value returned is the number of
+ CPU TimeStamp Counter ticks since the appliation started.
+**/
+clock_t
+EFIAPI
+clock(void)
+{
+ clock_t temp;
+
+#ifdef NT32dvm
+ temp = 0;
+#else
+ temp = (clock_t)GetPerformanceCounter();
+#endif /* NT32dvm */
+
+ return temp - gMD->AppStartTime;
+}
+
+/**
+**/
+double
+EFIAPI
+difftime(time_t time1, time_t time0)
+{
+ return (double)(time1 - time0);
+}
+
+/*
+** Adapted from code provided by Robert Elz, who writes:
+** The "best" way to do mktime I think is based on an idea of Bob
+** Kridle's (so its said...) from a long time ago.
+** [kridle@xinet.com as of 1996-01-16.]
+** It does a binary search of the time_t space. Since time_t's are
+** just 32 bits, its a max of 32 iterations (even at 64 bits it
+** would still be very reasonable).
+*/
+
+#ifndef WRONG
+#define WRONG (-1)
+#endif /* !defined WRONG */
+
+/*
+** Simplified normalize logic courtesy Paul Eggert (eggert@twinsun.com).
+*/
+
+static int
+increment_overflow(int * number, int delta)
+{
+ int number0;
+
+ number0 = *number;
+ *number += delta;
+ return (*number < number0) != (delta < 0);
+}
+
+static int
+normalize_overflow(int * const tensptr, int * const unitsptr, const int base)
+{
+ register int tensdelta;
+
+ tensdelta = (*unitsptr >= 0) ?
+ (*unitsptr / base) : (-1 - (-1 - *unitsptr) / base);
+ *unitsptr -= tensdelta * base;
+ return increment_overflow(tensptr, tensdelta);
+}
+
+static int
+tmcomp(const struct tm * const atmp, const struct tm * const btmp)
+{
+ register int result;
+
+ if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
+ (result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
+ (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
+ (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
+ (result = (atmp->tm_min - btmp->tm_min)) == 0)
+ result = atmp->tm_sec - btmp->tm_sec;
+ return result;
+}
+
+static time_t
+time2sub(
+ struct tm * const tmp,
+ void (* const funcp)(const time_t*, long, struct tm*),
+ const long offset,
+ int * const okayp,
+ const int do_norm_secs
+ )
+{
+ register const struct state * sp;
+ register int dir;
+ register int bits;
+ register int i, j ;
+ register int saved_seconds;
+ time_t newt;
+ time_t t;
+ struct tm yourtm, mytm;
+
+ *okayp = FALSE;
+ yourtm = *tmp; // Create a copy of tmp
+ if (do_norm_secs) {
+ if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,
+ SECSPERMIN))
+ return WRONG;
+ }
+ if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))
+ return WRONG;
+ if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
+ return WRONG;
+ if (normalize_overflow(&yourtm.tm_year, &yourtm.tm_mon, MONSPERYEAR))
+ return WRONG;
+ /*
+ ** Turn yourtm.tm_year into an actual year number for now.
+ ** It is converted back to an offset from TM_YEAR_BASE later.
+ */
+ if (increment_overflow(&yourtm.tm_year, TM_YEAR_BASE))
+ return WRONG;
+ while (yourtm.tm_mday <= 0) {
+ if (increment_overflow(&yourtm.tm_year, -1))
+ return WRONG;
+ i = yourtm.tm_year + (1 < yourtm.tm_mon);
+ yourtm.tm_mday += year_lengths[isleap(i)];
+ }
+ while (yourtm.tm_mday > DAYSPERLYEAR) {
+ i = yourtm.tm_year + (1 < yourtm.tm_mon);
+ yourtm.tm_mday -= year_lengths[isleap(i)];
+ if (increment_overflow(&yourtm.tm_year, 1))
+ return WRONG;
+ }
+ for ( ; ; ) {
+ i = mon_lengths[isleap(yourtm.tm_year)][yourtm.tm_mon];
+ if (yourtm.tm_mday <= i)
+ break;
+ yourtm.tm_mday -= i;
+ if (++yourtm.tm_mon >= MONSPERYEAR) {
+ yourtm.tm_mon = 0;
+ if (increment_overflow(&yourtm.tm_year, 1))
+ return WRONG;
+ }
+ }
+ if (increment_overflow(&yourtm.tm_year, -TM_YEAR_BASE))
+ return WRONG;
+ if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
+ saved_seconds = 0;
+ else if (yourtm.tm_year + TM_YEAR_BASE < EPOCH_YEAR) {
+ /*
+ ** We can't set tm_sec to 0, because that might push the
+ ** time below the minimum representable time.
+ ** Set tm_sec to 59 instead.
+ ** This assumes that the minimum representable time is
+ ** not in the same minute that a leap second was deleted from,
+ ** which is a safer assumption than using 58 would be.
+ */
+ if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN))
+ return WRONG;
+ saved_seconds = yourtm.tm_sec;
+ yourtm.tm_sec = SECSPERMIN - 1;
+ } else {
+ saved_seconds = yourtm.tm_sec;
+ yourtm.tm_sec = 0;
+ }
+ /*
+ ** Divide the search space in half
+ ** (this works whether time_t is signed or unsigned).
+ */
+ bits = TYPE_BIT(time_t) - 1;
+ /*
+ ** Set t to the midpoint of our binary search.
+ **
+ ** If time_t is signed, then 0 is just above the median,
+ ** assuming two's complement arithmetic.
+ ** If time_t is unsigned, then (1 << bits) is just above the median.
+ */
+ t = TYPE_SIGNED(time_t) ? 0 : (((time_t) 1) << bits);
+ for ( ; ; ) {
+ (*funcp)(&t, offset, &mytm); // Convert t to broken-down time in mytm
+ dir = tmcomp(&mytm, &yourtm); // Is mytm larger, equal, or less than yourtm?
+ if (dir != 0) { // If mytm != yourtm...
+ if (bits-- < 0) // If we have exhausted all the bits..
+ return WRONG; // Return that we failed
+ if (bits < 0) // If on the last bit...
+ --t; /* may be needed if new t is minimal */
+ else if (dir > 0) // else if mytm > yourtm...
+ t -= ((time_t) 1) << bits; // subtract half the remaining time-space
+ else t += ((time_t) 1) << bits; // otherwise add half the remaining time-space
+ continue; // Repeat for the next half
+ }
+ if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
+ break;
+ /*
+ ** Right time, wrong type.
+ ** Hunt for right time, right type.
+ ** It's okay to guess wrong since the guess
+ ** gets checked.
+ */
+ /*
+ ** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's.
+ */
+ sp = (const struct state *)
+ (((void *) funcp == (void *) localsub) ?
+ lclptr : gmtptr);
+#ifdef ALL_STATE
+ if (sp == NULL)
+ return WRONG;
+#endif /* defined ALL_STATE */
+ for (i = sp->typecnt - 1; i >= 0; --i) {
+ if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
+ continue;
+ for (j = sp->typecnt - 1; j >= 0; --j) {
+ if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
+ continue;
+ newt = t + sp->ttis[j].tt_gmtoff -
+ sp->ttis[i].tt_gmtoff;
+ (*funcp)(&newt, offset, &mytm);
+ if (tmcomp(&mytm, &yourtm) != 0)
+ continue;
+ if (mytm.tm_isdst != yourtm.tm_isdst)
+ continue;
+ /*
+ ** We have a match.
+ */
+ t = newt;
+ goto label;
+ }
+ }
+ return WRONG;
+ }
+ label:
+ newt = t + saved_seconds;
+ if ((newt < t) != (saved_seconds < 0))
+ return WRONG;
+ t = newt;
+ (*funcp)(&t, offset, tmp);
+ *okayp = TRUE;
+ return t;
+}
+
+static time_t
+time2(struct tm * const tmp, void (* const funcp)(const time_t*, long, struct tm*),
+ const long offset, int * const okayp)
+{
+ time_t t;
+
+ /*
+ ** First try without normalization of seconds
+ ** (in case tm_sec contains a value associated with a leap second).
+ ** If that fails, try with normalization of seconds.
+ */
+ t = time2sub(tmp, funcp, offset, okayp, FALSE);
+ return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE);
+}
+
+static time_t
+time1(
+ struct tm * const tmp,
+ void (* const funcp)(const time_t *, long, struct tm *),
+ const long offset
+ )
+{
+ register time_t t;
+ register const struct state * sp;
+ register int samei, otheri;
+ register int sameind, otherind;
+ register int i;
+ register int nseen;
+ int seen[TZ_MAX_TYPES];
+ int types[TZ_MAX_TYPES];
+ int okay;
+
+ if (tmp->tm_isdst > 1)
+ tmp->tm_isdst = 1;
+ t = time2(tmp, funcp, offset, &okay);
+#ifdef PCTS
+ /*
+ ** PCTS code courtesy Grant Sullivan (grant@osf.org).
+ */
+ if (okay)
+ return t;
+ if (tmp->tm_isdst < 0)
+ tmp->tm_isdst = 0; /* reset to std and try again */
+#endif /* defined PCTS */
+#ifndef PCTS
+ if (okay || tmp->tm_isdst < 0)
+ return t;
+#endif /* !defined PCTS */
+ /*
+ ** We're supposed to assume that somebody took a time of one type
+ ** and did some math on it that yielded a "struct tm" that's bad.
+ ** We try to divine the type they started from and adjust to the
+ ** type they need.
+ */
+ /*
+ ** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's.
+ */
+ sp = (const struct state *) (((void *) funcp == (void *) localsub) ?
+ lclptr : gmtptr);
+#ifdef ALL_STATE
+ if (sp == NULL)
+ return WRONG;
+#endif /* defined ALL_STATE */
+ for (i = 0; i < sp->typecnt; ++i)
+ seen[i] = FALSE;
+ nseen = 0;
+ for (i = sp->timecnt - 1; i >= 0; --i)
+ if (!seen[sp->types[i]]) {
+ seen[sp->types[i]] = TRUE;
+ types[nseen++] = sp->types[i];
+ }
+ for (sameind = 0; sameind < nseen; ++sameind) {
+ samei = types[sameind];
+ if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
+ continue;
+ for (otherind = 0; otherind < nseen; ++otherind) {
+ otheri = types[otherind];
+ if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
+ continue;
+ tmp->tm_sec += (int)(sp->ttis[otheri].tt_gmtoff -
+ sp->ttis[samei].tt_gmtoff);
+ tmp->tm_isdst = !tmp->tm_isdst;
+ t = time2(tmp, funcp, offset, &okay);
+ if (okay)
+ return t;
+ tmp->tm_sec -= (int)(sp->ttis[otheri].tt_gmtoff -
+ sp->ttis[samei].tt_gmtoff);
+ tmp->tm_isdst = !tmp->tm_isdst;
+ }
+ }
+ return WRONG;
+}
+
+/** The mktime function converts the broken-down time, expressed as local time,
+ in the structure pointed to by timeptr into a calendar time value with the
+ same encoding as that of the values returned by the time function. The
+ original values of the tm_wday and tm_yday components of the structure are
+ ignored, and the original values of the other components are not restricted
+ to the ranges indicated above. Thus, a positive or zero value for tm_isdst
+ causes the mktime function to presume initially that Daylight Saving Time,
+ respectively, is or is not in effect for the specified time. A negative
+ value causes it to attempt to determine whether Daylight Saving Time is in
+ effect for the specified time. On successful completion, the values of the
+ tm_wday and tm_yday components of the structure are set appropriately, and
+ the other components are set to represent the specified calendar time, but
+ with their values forced to the ranges indicated above; the final value of
+ tm_mday is not set until tm_mon and tm_year are determined.
+
+ @return The mktime function returns the specified calendar time encoded
+ as a value of type time_t. If the calendar time cannot be
+ represented, the function returns the value (time_t)(-1).
+**/
+time_t
+EFIAPI
+mktime(struct tm *timeptr)
+{
+ /* From NetBSD */
+ time_t result;
+
+ rwlock_wrlock(&lcl_lock);
+ tzset();
+ result = time1(timeptr, &localsub, 0L);
+ rwlock_unlock(&lcl_lock);
+ return (result);
+}
+
+/** The time function determines the current calendar time. The encoding of
+ the value is unspecified.
+
+ @return The time function returns the implementation’s best approximation
+ to the current calendar time. The value (time_t)(-1) is returned
+ if the calendar time is not available. If timer is not a null
+ pointer, the return value is also assigned to the object it
+ points to.
+**/
+time_t
+EFIAPI
+time(time_t *timer)
+{
+ time_t CalTime;
+ EFI_STATUS Status;
+ EFI_TIME *ET;
+ struct tm *BT;
+
+ ET = &gMD->TimeBuffer;
+ BT = &gMD->BDTime;
+
+ // Get EFI Time
+ Status = gRT->GetTime( ET, NULL);
+// Status = EfiGetTime( ET, NULL);
+ EFIerrno = Status;
+ if( Status != RETURN_SUCCESS) {
+ return (time_t)-1;
+ }
+
+ // Convert EFI time to broken-down time.
+ Efi2Tm( ET, BT);
+
+ // Convert to time_t
+ CalTime = mktime(&gMD->BDTime);
+
+ if( timer != NULL) {
+ *timer = CalTime;
+ }
+ return CalTime; // Return calendar time in microseconds
+}
+
+/* ################# Time Conversion Functions ########################## */
+/*
+ Except for the strftime function, these functions each return a pointer to
+ one of two types of static objects: a broken-down time structure or an
+ array of char. Execution of any of the functions that return a pointer to
+ one of these object types may overwrite the information in any object of
+ the same type pointed to by the value returned from any previous call to
+ any of them. The implementation shall behave as if no other library
+ functions call these functions.
+*/
+
+/** The asctime function converts the broken-down time in the structure pointed
+ to by timeptr into a string in the form
+ Sun Sep 16 01:03:52 1973\n\0
+ using the equivalent of the following algorithm.
+
+ char *asctime(const struct tm *timeptr)
+ {
+ static const char wday_name[7][3] = {
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+ };
+ static const char mon_name[12][3] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+ };
+ static char result[26];
+ sprintf(result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
+ wday_name[timeptr->tm_wday],
+ mon_name[timeptr->tm_mon],
+ timeptr->tm_mday, timeptr->tm_hour,
+ timeptr->tm_min, timeptr->tm_sec,
+ 1900 + timeptr->tm_year);
+ return result;
+ }
+ @return The asctime function returns a pointer to the string.
+**/
+char *
+EFIAPI
+asctime(const struct tm *timeptr)
+{
+ register const char * wn;
+ register const char * mn;
+
+ if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK)
+ wn = "???";
+ else wn = wday_name[timeptr->tm_wday];
+ if (timeptr->tm_mon < 0 || timeptr->tm_mon >= MONSPERYEAR)
+ mn = "???";
+ else mn = mon_name[timeptr->tm_mon];
+ /*
+ ** The X3J11-suggested format is
+ ** "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %d\n"
+ ** Since the .2 in 02.2d is ignored, we drop it.
+ */
+ (void)snprintf(gMD->ASasctime,
+ sizeof (char[ASCTIME_BUFLEN]),
+ "%.3s %.3s%3d %02d:%02d:%02d %d\r\n", // explicit CRLF for EFI
+ wn, mn,
+ timeptr->tm_mday, timeptr->tm_hour,
+ timeptr->tm_min, timeptr->tm_sec,
+ TM_YEAR_BASE + timeptr->tm_year);
+ return gMD->ASasctime;
+}
+
+/**
+**/
+char *
+EFIAPI
+ctime(const time_t *timer)
+{
+ return asctime(localtime(timer));
+}
+
+/*
+** gmtsub is to gmtime as localsub is to localtime.
+*/
+static void
+gmtsub(
+ const time_t * const timep,
+ const long offset,
+ struct tm * const tmp
+ )
+{
+#ifdef _REENTRANT
+ static mutex_t gmt_mutex = MUTEX_INITIALIZER;
+#endif
+
+ mutex_lock(&gmt_mutex);
+ if (!gmt_is_set) {
+ gmt_is_set = TRUE;
+#ifdef ALL_STATE
+ gmtptr = (struct state *) malloc(sizeof *gmtptr);
+ if (gmtptr != NULL)
+#endif /* defined ALL_STATE */
+ gmtload(gmtptr);
+ }
+ mutex_unlock(&gmt_mutex);
+ timesub(timep, offset, gmtptr, tmp);
+#ifdef TM_ZONE
+ /*
+ ** Could get fancy here and deliver something such as
+ ** "UTC+xxxx" or "UTC-xxxx" if offset is non-zero,
+ ** but this is no time for a treasure hunt.
+ */
+ if (offset != 0)
+ tmp->TM_ZONE = (__aconst char *)__UNCONST(wildabbr);
+ else {
+#ifdef ALL_STATE
+ if (gmtptr == NULL)
+ tmp->TM_ZONE = (__aconst char *)__UNCONST(gmt);
+ else tmp->TM_ZONE = gmtptr->chars;
+#endif /* defined ALL_STATE */
+#ifndef ALL_STATE
+ tmp->TM_ZONE = gmtptr->chars;
+#endif /* State Farm */
+ }
+#endif /* defined TM_ZONE */
+}
+
+/**
+**/
+struct tm *
+EFIAPI
+gmtime(const time_t *timer)
+{
+ gmtsub(timer, 0L, &gMD->BDTime);
+ return &gMD->BDTime;
+}
+
+static void
+localsub(const time_t * const timep, const long offset, struct tm * const tmp)
+{
+ register struct state * sp;
+ register const struct ttinfo * ttisp;
+ register int i;
+ const time_t t = *timep;
+
+ sp = lclptr;
+#ifdef ALL_STATE
+ if (sp == NULL) {
+ gmtsub(timep, offset, tmp);
+ return;
+ }
+#endif /* defined ALL_STATE */
+ if (sp->timecnt == 0 || t < sp->ats[0]) {
+ i = 0;
+ while (sp->ttis[i].tt_isdst)
+ if (++i >= sp->typecnt) {
+ i = 0;
+ break;
+ }
+ } else {
+ for (i = 1; i < sp->timecnt; ++i)
+ if (t < sp->ats[i])
+ break;
+ i = sp->types[i - 1];
+ }
+ ttisp = &sp->ttis[i];
+ /*
+ ** To get (wrong) behavior that's compatible with System V Release 2.0
+ ** you'd replace the statement below with
+ ** t += ttisp->tt_gmtoff;
+ ** timesub(&t, 0L, sp, tmp);
+ */
+ timesub(&t, ttisp->tt_gmtoff, sp, tmp);
+ tmp->tm_isdst = ttisp->tt_isdst;
+ tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind];
+#ifdef TM_ZONE
+ tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind];
+#endif /* defined TM_ZONE */
+}
+
+/**
+**/
+struct tm *
+EFIAPI
+localtime(const time_t *timer)
+{
+ tzset();
+ localsub(timer, 0L, &gMD->BDTime);
+ return &gMD->BDTime;
+}
diff --git a/StdLib/LibC/Time/Time.inf b/StdLib/LibC/Time/Time.inf
new file mode 100644
index 0000000000..8bbb248bd1
--- /dev/null
+++ b/StdLib/LibC/Time/Time.inf
@@ -0,0 +1,53 @@
+## @file
+# Standard C library: Time implementations.
+#
+# Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = LibTime
+ FILE_GUID = c5847038-ff75-4074-9e4c-c36a2eb398a5
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = LibTime
+
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[Sources]
+ Time.c
+ ZoneProc.c
+ strftime.c
+ TimeEfi.c
+
+[Packages]
+ StdLib/StdLib.dec
+ StdLibPrivateInternalFiles/DoNotUse.dec
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+
+[LibraryClasses]
+ UefiLib
+ TimerLib
+ BaseLib
+ UefiRuntimeServicesTableLib
+
+################################################################
+#
+# The Build Options, below, are only used when building the C library.
+# DO NOT use them when building your application!
+# Nasty things could happen if you do.
+#
+[BuildOptions]
+ GCC:*_*_*_CC_FLAGS = -fno-strict-overflow -fno-builtin-strftime
diff --git a/StdLib/LibC/Time/TimeEfi.c b/StdLib/LibC/Time/TimeEfi.c
new file mode 100644
index 0000000000..7b062c917b
--- /dev/null
+++ b/StdLib/LibC/Time/TimeEfi.c
@@ -0,0 +1,48 @@
+/** @file
+ Transformations between the EFI_TIME structure and struct tm or time_t.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#include <Uefi.h>
+
+#include <LibConfig.h>
+
+#include <time.h>
+#include "tzfile.h"
+#include <MainData.h>
+
+/* Convert an EFI_TIME structure into a C Standard tm structure. */
+void
+EFIAPI
+Efi2Tm( EFI_TIME *ET, struct tm *BT)
+{
+ // Convert EFI time to broken-down time.
+ BT->tm_year = ET->Year - TM_YEAR_BASE;
+ BT->tm_mon = ET->Month - 1; // BD time is zero based, EFI is 1 based
+ BT->tm_mday = ET->Day;
+ BT->tm_hour = ET->Hour;
+ BT->tm_min = ET->Minute;
+ BT->tm_sec = ET->Second;
+ BT->tm_isdst = -1;
+ BT->tm_zoneoff = ET->TimeZone;
+ BT->tm_daylight = ET->Daylight;
+ BT->tm_Nano = ET->Nanosecond;
+}
+
+/* Convert an EFI_TIME structure into a time_t value. */
+time_t
+EFIAPI
+Efi2Time( EFI_TIME *EfiBDtime)
+{
+ Efi2Tm( EfiBDtime, &gMD->BDTime);
+
+ return mktime( &gMD->BDTime);
+}
diff --git a/StdLib/LibC/Time/TimeVals.h b/StdLib/LibC/Time/TimeVals.h
new file mode 100644
index 0000000000..72827f9a91
--- /dev/null
+++ b/StdLib/LibC/Time/TimeVals.h
@@ -0,0 +1,117 @@
+/** @file
+ Definitions private to the Implementation of <time.h>.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Portions derived from the NIH time zone package files,
+ which contain the following notice:
+
+ This file is in the public domain, so clarified as of
+ 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
+**/
+#ifndef _TIMEVAL_H
+#define _TIMEVAL_H
+
+extern struct state * lclptr;
+extern struct state * gmtptr;
+extern char * tzname[2];
+extern const char gmt[4];
+extern const char wildabbr[9];
+extern const int year_lengths[2];
+extern const int mon_lengths[2][MONSPERYEAR];
+extern long int timezone;
+extern int daylight;
+
+#define EFI_UNSPECIFIED_TIMEZONE 0x07FF
+
+/*
+** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
+** We default to US rules as of 1999-08-17.
+** POSIX 1003.1 section 8.1.1 says that the default DST rules are
+** implementation dependent; for historical reasons, US rules are a
+** common default.
+*/
+#ifndef TZDEFRULESTRING
+#define TZDEFRULESTRING ",M4.1.0,M10.5.0"
+#endif
+
+// Facilities for external time-zone definition files do not currently exist
+#define NO_ZONEINFO_FILES
+
+#define EPOCH_DAY 5
+#define DAY_TO_uSEC 86400000000
+
+/* Rule type values for the r_type member of a rule structure */
+#define JULIAN_DAY 0 /* Jn - Julian day */
+#define DAY_OF_YEAR 1 /* n - day of year */
+#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
+
+#ifdef TZNAME_MAX
+ #define MY_TZNAME_MAX TZNAME_MAX
+#endif /* defined TZNAME_MAX */
+
+#ifndef TZNAME_MAX
+ #define MY_TZNAME_MAX 255
+#endif /* !defined TZNAME_MAX */
+
+/* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX. */
+#define is_digit(c) ((unsigned)(c) - '0' <= 9)
+
+#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
+
+#define BIGGEST(a, b) (((a) > (b)) ? (a) : (b))
+
+#ifndef INITIALIZE
+#define INITIALIZE(x) ((x) = 0)
+#endif /* !defined INITIALIZE */
+
+struct ttinfo { /* time type information */
+ LONG32 tt_gmtoff; /* UTC offset in seconds */
+ int tt_isdst; /* used to set tm_isdst */
+ int tt_abbrind; /* abbreviation list index */
+ int tt_ttisstd; /* TRUE if transition is std time */
+ int tt_ttisgmt; /* TRUE if transition is UTC */
+};
+
+struct lsinfo { /* leap second information */
+ time_t ls_trans; /* transition time */
+ LONG32 ls_corr; /* correction to apply */
+};
+
+struct state {
+ int leapcnt;
+ int timecnt;
+ int typecnt;
+ int charcnt;
+ time_t ats[TZ_MAX_TIMES];
+ unsigned char types[TZ_MAX_TIMES];
+ struct ttinfo ttis[TZ_MAX_TYPES];
+ char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt), (2 * (MY_TZNAME_MAX + 1)))];
+ struct lsinfo lsis[TZ_MAX_LEAPS];
+};
+
+struct rule {
+ int r_type; /* type of rule--see below */
+ int r_day; /* day number of rule */
+ int r_week; /* week number of rule */
+ int r_mon; /* month number of rule */
+ LONG32 r_time; /* transition time of rule */
+};
+
+#define JULIAN_DAY 0 /* Jn - Julian day */
+#define DAY_OF_YEAR 1 /* n - day of year */
+#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
+
+__BEGIN_DECLS
+extern void EFIAPI gmtload(struct state * const sp);
+extern void EFIAPI tzset(void);
+__END_DECLS
+
+#endif /* _TIMEVAL_H */
diff --git a/StdLib/LibC/Time/ZoneProc.c b/StdLib/LibC/Time/ZoneProc.c
new file mode 100644
index 0000000000..e33b99ed68
--- /dev/null
+++ b/StdLib/LibC/Time/ZoneProc.c
@@ -0,0 +1,830 @@
+/** @file
+ Time Zone processing.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Portions derived from the NIH time zone package file, localtime.c,
+ which contains the following notice:
+
+ This file is in the public domain, so clarified as of
+ 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
+
+ NetBSD: localtime.c,v 1.39 2006/03/22 14:01:30 christos Exp
+**/
+#include <LibConfig.h>
+#include <sys/EfiSysCall.h>
+
+#include <ctype.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "tzfile.h"
+#include "TimeVals.h"
+
+#ifndef WILDABBR
+/*
+** Someone might make incorrect use of a time zone abbreviation:
+** 1. They might reference tzname[0] before calling tzset (explicitly
+** or implicitly).
+** 2. They might reference tzname[1] before calling tzset (explicitly
+** or implicitly).
+** 3. They might reference tzname[1] after setting to a time zone
+** in which Daylight Saving Time is never observed.
+** 4. They might reference tzname[0] after setting to a time zone
+** in which Standard Time is never observed.
+** 5. They might reference tm.TM_ZONE after calling offtime.
+** What's best to do in the above cases is open to debate;
+** for now, we just set things up so that in any of the five cases
+** WILDABBR is used. Another possibility: initialize tzname[0] to the
+** string "tzname[0] used before set", and similarly for the other cases.
+** And another: initialize tzname[0] to "ERA", with an explanation in the
+** manual page of what this "time zone abbreviation" means (doing this so
+** that tzname[0] has the "normal" length of three characters).
+*/
+#define WILDABBR " "
+#endif /* !defined WILDABBR */
+
+const char wildabbr[9] = "WILDABBR";
+const char gmt[4] = "GMT";
+
+struct state * lclptr = NULL;
+struct state * gmtptr = NULL;
+
+#ifndef TZ_STRLEN_MAX
+#define TZ_STRLEN_MAX 255
+#endif /* !defined TZ_STRLEN_MAX */
+
+static char lcl_TZname[TZ_STRLEN_MAX + 1];
+static int lcl_is_set = 0;
+//static int gmt_is_set = 0;
+
+char * tzname[2] = {
+ (char *)__UNCONST(wildabbr),
+ (char *)__UNCONST(wildabbr)
+};
+
+long int timezone = 0;
+int daylight = 0;
+
+#ifndef NO_ZONEINFO_FILES
+/** Get first 4 characters of codep as a 32-bit integer.
+
+ The first character of codep becomes the MSB of the resultant integer.
+**/
+static INT32
+detzcode(const char * const codep)
+{
+ register INT32 result;
+
+ /*
+ ** The first character must be sign extended on systems with >32bit
+ ** longs. This was solved differently in the master tzcode sources
+ ** (the fix first appeared in tzcode95c.tar.gz). But I believe
+ ** that this implementation is superior.
+ */
+#define SIGN_EXTEND_CHAR(x) ((signed char) x)
+
+ result = (SIGN_EXTEND_CHAR(codep[0]) << 24) \
+ | (codep[1] & 0xff) << 16 \
+ | (codep[2] & 0xff) << 8
+ | (codep[3] & 0xff);
+ return result;
+}
+#endif /* NO_ZONEINFO_FILES */
+
+static void
+settzname (void)
+{
+ register struct state * const sp = lclptr;
+ register int i;
+
+ tzname[0] = (char *)__UNCONST(wildabbr);
+ tzname[1] = (char *)__UNCONST(wildabbr);
+ daylight = 0;
+ timezone = 0;
+ if (sp == NULL) {
+ tzname[0] = tzname[1] = (char *)__UNCONST(gmt);
+ return;
+ }
+ for (i = 0; i < sp->typecnt; ++i) {
+ register const struct ttinfo * const ttisp = &sp->ttis[i];
+
+ tzname[ttisp->tt_isdst] =
+ &sp->chars[ttisp->tt_abbrind];
+ if (ttisp->tt_isdst)
+ daylight = 1;
+ if (i == 0 || !ttisp->tt_isdst)
+ timezone = -(ttisp->tt_gmtoff);
+ }
+ /*
+ ** And to get the latest zone names into tzname. . .
+ */
+ for (i = 0; i < sp->timecnt; ++i) {
+ register const struct ttinfo * const ttisp =
+ &sp->ttis[ sp->types[i] ];
+
+ tzname[ttisp->tt_isdst] =
+ &sp->chars[ttisp->tt_abbrind];
+ }
+}
+
+/*
+** Given a pointer into a time zone string, scan until a character that is not
+** a valid character in a zone name is found. Return a pointer to that
+** character.
+*/
+static const char *
+getzname(register const char *strp)
+{
+ register char c;
+
+ while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
+ c != '+')
+ ++strp;
+ return strp;
+}
+
+/*
+** Given a pointer into a time zone string, extract a number from that string.
+** Check that the number is within a specified range; if it is not, return
+** NULL.
+** Otherwise, return a pointer to the first character not part of the number.
+*/
+static const char *
+getnum(
+ register const char *strp,
+ int * const nump,
+ const int min,
+ const int max
+ )
+{
+ register char c;
+ register int num;
+
+ if (strp == NULL || !is_digit(c = *strp))
+ return NULL;
+ num = 0;
+ do {
+ num = num * 10 + (c - '0');
+ if (num > max)
+ return NULL; /* illegal value */
+ c = *++strp;
+ } while (is_digit(c));
+ if (num < min)
+ return NULL; /* illegal value */
+ *nump = num;
+ return strp;
+}
+
+/*
+** Given a pointer into a time zone string, extract a number of seconds,
+** in hh[:mm[:ss]] form, from the string.
+** If any error occurs, return NULL.
+** Otherwise, return a pointer to the first character not part of the number
+** of seconds.
+*/
+static const char *
+getsecs(
+ register const char *strp,
+ LONG32 * const secsp
+ )
+{
+ int num;
+
+ /*
+ ** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
+ ** "M10.4.6/26", which does not conform to Posix,
+ ** but which specifies the equivalent of
+ ** ``02:00 on the first Sunday on or after 23 Oct''.
+ */
+ strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
+ if (strp == NULL)
+ return NULL;
+ *secsp = (long)(num * SECSPERHOUR);
+ if (*strp == ':') {
+ ++strp;
+ strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
+ if (strp == NULL)
+ return NULL;
+ *secsp += num * SECSPERMIN;
+ if (*strp == ':') {
+ ++strp;
+ /* `SECSPERMIN' allows for leap seconds. */
+ strp = getnum(strp, &num, 0, SECSPERMIN);
+ if (strp == NULL)
+ return NULL;
+ *secsp += num;
+ }
+ }
+ return strp;
+}
+
+/*
+** Given a pointer into a time zone string, extract an offset, in
+** [+-]hh[:mm[:ss]] form, from the string.
+** If any error occurs, return NULL.
+** Otherwise, return a pointer to the first character not part of the time.
+*/
+static const char *
+getoffset(
+ register const char *strp,
+ LONG32 * const offsetp
+ )
+{
+ register int neg = 0;
+
+ if (*strp == '-') {
+ neg = 1;
+ ++strp;
+ } else if (*strp == '+')
+ ++strp;
+ strp = getsecs(strp, offsetp);
+ if (strp == NULL)
+ return NULL; /* illegal time */
+ if (neg)
+ *offsetp = -*offsetp;
+ return strp;
+}
+
+/*
+** Given a pointer into a time zone string, extract a rule in the form
+** date[/time]. See POSIX section 8 for the format of "date" and "time".
+** If a valid rule is not found, return NULL.
+** Otherwise, return a pointer to the first character not part of the rule.
+*/
+static const char *
+getrule(
+ const char *strp,
+ register struct rule * const rulep
+ )
+{
+ if (*strp == 'J') {
+ /*
+ ** Julian day.
+ */
+ rulep->r_type = JULIAN_DAY;
+ ++strp;
+ strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
+ } else if (*strp == 'M') {
+ /*
+ ** Month, week, day.
+ */
+ rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
+ ++strp;
+ strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
+ if (strp == NULL)
+ return NULL;
+ if (*strp++ != '.')
+ return NULL;
+ strp = getnum(strp, &rulep->r_week, 1, 5);
+ if (strp == NULL)
+ return NULL;
+ if (*strp++ != '.')
+ return NULL;
+ strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
+ } else if (is_digit(*strp)) {
+ /*
+ ** Day of year.
+ */
+ rulep->r_type = DAY_OF_YEAR;
+ strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
+ } else return NULL; /* invalid format */
+ if (strp == NULL)
+ return NULL;
+ if (*strp == '/') {
+ /*
+ ** Time specified.
+ */
+ ++strp;
+ strp = getsecs(strp, &rulep->r_time);
+ } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
+ return strp;
+}
+
+static int
+tzload(register const char *name, register struct state * const sp)
+{
+#ifndef NO_ZONEINFO_FILES
+ register const char * p;
+ register int i;
+ register int fid;
+
+ if (name == NULL && (name = TZDEFAULT) == NULL)
+ return -1;
+
+ {
+ register int doaccess;
+ /*
+ ** Section 4.9.1 of the C standard says that
+ ** "FILENAME_MAX expands to an integral constant expression
+ ** that is the size needed for an array of char large enough
+ ** to hold the longest file name string that the implementation
+ ** guarantees can be opened."
+ */
+ char fullname[FILENAME_MAX + 1];
+
+ if (name[0] == ':')
+ ++name;
+ doaccess = name[0] == '/';
+ if (!doaccess) {
+ if ((p = TZDIR) == NULL)
+ return -1;
+ if ((strlen(p) + strlen(name) + 1) >= sizeof fullname)
+ return -1;
+ (void) strcpy(fullname, p); /* XXX strcpy is safe */
+ (void) strcat(fullname, "/"); /* XXX strcat is safe */
+ (void) strcat(fullname, name); /* XXX strcat is safe */
+ /*
+ ** Set doaccess if '.' (as in "../") shows up in name.
+ */
+ if (strchr(name, '.') != NULL)
+ doaccess = TRUE;
+ name = fullname;
+ }
+ if (doaccess && access(name, R_OK) != 0)
+ return -1;
+ /*
+ * XXX potential security problem here if user of a set-id
+ * program has set TZ (which is passed in as name) here,
+ * and uses a race condition trick to defeat the access(2)
+ * above.
+ */
+ if ((fid = open(name, OPEN_MODE)) == -1)
+ return -1;
+ }
+ {
+ struct tzhead * tzhp;
+ union {
+ struct tzhead tzhead;
+ char buf[sizeof *sp + sizeof *tzhp];
+ } u;
+ int ttisstdcnt;
+ int ttisgmtcnt;
+
+ i = read(fid, u.buf, sizeof u.buf);
+ if (close(fid) != 0)
+ return -1;
+ ttisstdcnt = (int) detzcode(u.tzhead.tzh_ttisstdcnt);
+ ttisgmtcnt = (int) detzcode(u.tzhead.tzh_ttisgmtcnt);
+ sp->leapcnt = (int) detzcode(u.tzhead.tzh_leapcnt);
+ sp->timecnt = (int) detzcode(u.tzhead.tzh_timecnt);
+ sp->typecnt = (int) detzcode(u.tzhead.tzh_typecnt);
+ sp->charcnt = (int) detzcode(u.tzhead.tzh_charcnt);
+ p = u.tzhead.tzh_charcnt + sizeof u.tzhead.tzh_charcnt;
+ if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS ||
+ sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES ||
+ sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES ||
+ sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS ||
+ (ttisstdcnt != sp->typecnt && ttisstdcnt != 0) ||
+ (ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0))
+ return -1;
+ if (i - (p - u.buf) < sp->timecnt * 4 + /* ats */
+ sp->timecnt + /* types */
+ sp->typecnt * (4 + 2) + /* ttinfos */
+ sp->charcnt + /* chars */
+ sp->leapcnt * (4 + 4) + /* lsinfos */
+ ttisstdcnt + /* ttisstds */
+ ttisgmtcnt) /* ttisgmts */
+ return -1;
+ for (i = 0; i < sp->timecnt; ++i) {
+ sp->ats[i] = detzcode(p);
+ p += 4;
+ }
+ for (i = 0; i < sp->timecnt; ++i) {
+ sp->types[i] = (unsigned char) *p++;
+ if (sp->types[i] >= sp->typecnt)
+ return -1;
+ }
+ for (i = 0; i < sp->typecnt; ++i) {
+ register struct ttinfo * ttisp;
+
+ ttisp = &sp->ttis[i];
+ ttisp->tt_gmtoff = detzcode(p);
+ p += 4;
+ ttisp->tt_isdst = (unsigned char) *p++;
+ if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1)
+ return -1;
+ ttisp->tt_abbrind = (unsigned char) *p++;
+ if (ttisp->tt_abbrind < 0 ||
+ ttisp->tt_abbrind > sp->charcnt)
+ return -1;
+ }
+ for (i = 0; i < sp->charcnt; ++i)
+ sp->chars[i] = *p++;
+ sp->chars[i] = '\0'; /* ensure '\0' at end */
+ for (i = 0; i < sp->leapcnt; ++i) {
+ register struct lsinfo * lsisp;
+
+ lsisp = &sp->lsis[i];
+ lsisp->ls_trans = detzcode(p);
+ p += 4;
+ lsisp->ls_corr = detzcode(p);
+ p += 4;
+ }
+ for (i = 0; i < sp->typecnt; ++i) {
+ register struct ttinfo * ttisp;
+
+ ttisp = &sp->ttis[i];
+ if (ttisstdcnt == 0)
+ ttisp->tt_ttisstd = FALSE;
+ else {
+ ttisp->tt_ttisstd = *p++;
+ if (ttisp->tt_ttisstd != TRUE &&
+ ttisp->tt_ttisstd != FALSE)
+ return -1;
+ }
+ }
+ for (i = 0; i < sp->typecnt; ++i) {
+ register struct ttinfo * ttisp;
+
+ ttisp = &sp->ttis[i];
+ if (ttisgmtcnt == 0)
+ ttisp->tt_ttisgmt = FALSE;
+ else {
+ ttisp->tt_ttisgmt = *p++;
+ if (ttisp->tt_ttisgmt != TRUE &&
+ ttisp->tt_ttisgmt != FALSE)
+ return -1;
+ }
+ }
+ }
+ return 0;
+#else /* ! NO_ZONEINFO_FILES */
+ return -1;
+#endif
+}
+
+/*
+** Given the Epoch-relative time of January 1, 00:00:00 UTC, in a year, the
+** year, a rule, and the offset from UTC at the time that rule takes effect,
+** calculate the Epoch-relative time that rule takes effect.
+*/
+static
+time_t
+transtime(
+ const time_t janfirst,
+ const int year,
+ const struct rule * const rulep,
+ const LONG32 offset
+ )
+{
+ register int leapyear;
+ register time_t value;
+ register int i;
+ int d, m1, yy0, yy1, yy2, dow;
+
+ INITIALIZE(value);
+ leapyear = isleap(year);
+ switch (rulep->r_type) {
+
+ case JULIAN_DAY:
+ /*
+ ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
+ ** years.
+ ** In non-leap years, or if the day number is 59 or less, just
+ ** add SECSPERDAY times the day number-1 to the time of
+ ** January 1, midnight, to get the day.
+ */
+ value = janfirst + (rulep->r_day - 1) * SECSPERDAY;
+ if (leapyear && rulep->r_day >= 60)
+ value += SECSPERDAY;
+ break;
+
+ case DAY_OF_YEAR:
+ /*
+ ** n - day of year.
+ ** Just add SECSPERDAY times the day number to the time of
+ ** January 1, midnight, to get the day.
+ */
+ value = janfirst + rulep->r_day * SECSPERDAY;
+ break;
+
+ case MONTH_NTH_DAY_OF_WEEK:
+ /*
+ ** Mm.n.d - nth "dth day" of month m.
+ */
+ value = janfirst;
+ for (i = 0; i < rulep->r_mon - 1; ++i)
+ value += mon_lengths[leapyear][i] * SECSPERDAY;
+
+ /*
+ ** Use Zeller's Congruence to get day-of-week of first day of
+ ** month.
+ */
+ m1 = (rulep->r_mon + 9) % 12 + 1;
+ yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
+ yy1 = yy0 / 100;
+ yy2 = yy0 % 100;
+ dow = ((26 * m1 - 2) / 10 +
+ 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
+ if (dow < 0)
+ dow += DAYSPERWEEK;
+
+ /*
+ ** "dow" is the day-of-week of the first day of the month. Get
+ ** the day-of-month (zero-origin) of the first "dow" day of the
+ ** month.
+ */
+ d = rulep->r_day - dow;
+ if (d < 0)
+ d += DAYSPERWEEK;
+ for (i = 1; i < rulep->r_week; ++i) {
+ if (d + DAYSPERWEEK >=
+ mon_lengths[leapyear][rulep->r_mon - 1])
+ break;
+ d += DAYSPERWEEK;
+ }
+
+ /*
+ ** "d" is the day-of-month (zero-origin) of the day we want.
+ */
+ value += d * SECSPERDAY;
+ break;
+ }
+
+ /*
+ ** "value" is the Epoch-relative time of 00:00:00 UTC on the day in
+ ** question. To get the Epoch-relative time of the specified local
+ ** time on that day, add the transition time and the current offset
+ ** from UTC.
+ */
+ return value + rulep->r_time + offset;
+}
+
+/*
+** Given a POSIX section 8-style TZ string, fill in the rule tables as
+** appropriate.
+*/
+static int
+tzparse(
+ const char * name,
+ struct state * const sp,
+ const int lastditch
+ )
+{
+ const char *stdname;
+ const char *dstname;
+ size_t stdlen;
+ size_t dstlen;
+ LONG32 stdoffset;
+ LONG32 dstoffset;
+ time_t *atp;
+ unsigned char *typep;
+ char *cp;
+ int load_result;
+
+ dstname = NULL;
+ stdname = name;
+ if (lastditch) {
+ stdlen = strlen(name); /* length of standard zone name */
+ name += stdlen;
+ if (stdlen >= sizeof sp->chars)
+ stdlen = (sizeof sp->chars) - 1;
+ stdoffset = 0;
+ } else {
+ name = getzname(name);
+ stdlen = name - stdname;
+ if (stdlen < 3)
+ return -1;
+ if (*name == '\0')
+ return -1;
+ name = getoffset(name, &stdoffset);
+ if (name == NULL)
+ return -1;
+ }
+ load_result = tzload(TZDEFRULES, sp);
+ if (load_result != 0)
+ sp->leapcnt = 0; /* so, we're off a little */
+ if (*name != '\0') {
+ dstname = name;
+ name = getzname(name);
+ dstlen = name - dstname; /* length of DST zone name */
+ if (dstlen < 3)
+ return -1;
+ if (*name != '\0' && *name != ',' && *name != ';') {
+ name = getoffset(name, &dstoffset);
+ if (name == NULL)
+ return -1;
+ } else dstoffset = stdoffset - SECSPERHOUR;
+ if (*name == '\0' && load_result != 0)
+ name = TZDEFRULESTRING;
+ if (*name == ',' || *name == ';') {
+ struct rule start;
+ struct rule end;
+ register int year;
+ register time_t janfirst;
+ time_t starttime;
+ time_t endtime;
+
+ ++name;
+ if ((name = getrule(name, &start)) == NULL)
+ return -1;
+ if (*name++ != ',')
+ return -1;
+ if ((name = getrule(name, &end)) == NULL)
+ return -1;
+ if (*name != '\0')
+ return -1;
+ sp->typecnt = 2; /* standard time and DST */
+ /*
+ ** Two transitions per year, from EPOCH_YEAR to 2037.
+ */
+ sp->timecnt = 2 * (2037 - EPOCH_YEAR + 1);
+ if (sp->timecnt > TZ_MAX_TIMES)
+ return -1;
+ sp->ttis[0].tt_gmtoff = -dstoffset;
+ sp->ttis[0].tt_isdst = 1;
+ sp->ttis[0].tt_abbrind = (int)stdlen + 1;
+ sp->ttis[1].tt_gmtoff = -stdoffset;
+ sp->ttis[1].tt_isdst = 0;
+ sp->ttis[1].tt_abbrind = 0;
+ atp = sp->ats;
+ typep = sp->types;
+ janfirst = 0;
+ for (year = EPOCH_YEAR; year <= 2037; ++year) {
+ starttime = transtime(janfirst, year, &start,
+ stdoffset);
+ endtime = transtime(janfirst, year, &end,
+ dstoffset);
+ if (starttime > endtime) {
+ *atp++ = endtime;
+ *typep++ = 1; /* DST ends */
+ *atp++ = starttime;
+ *typep++ = 0; /* DST begins */
+ } else {
+ *atp++ = starttime;
+ *typep++ = 0; /* DST begins */
+ *atp++ = endtime;
+ *typep++ = 1; /* DST ends */
+ }
+ janfirst += year_lengths[isleap(year)] *
+ SECSPERDAY;
+ }
+ } else {
+ register LONG32 theirstdoffset;
+ register LONG32 theiroffset;
+ register int i;
+ register int j;
+
+ if (*name != '\0')
+ return -1;
+ /*
+ ** Initial values of theirstdoffset
+ */
+ theirstdoffset = 0;
+ for (i = 0; i < sp->timecnt; ++i) {
+ j = sp->types[i];
+ if (!sp->ttis[j].tt_isdst) {
+ theirstdoffset =
+ -sp->ttis[j].tt_gmtoff;
+ break;
+ }
+ }
+ /*
+ ** Initially we're assumed to be in standard time.
+ */
+ theiroffset = theirstdoffset;
+ /*
+ ** Now juggle transition times and types
+ ** tracking offsets as you do.
+ */
+ for (i = 0; i < sp->timecnt; ++i) {
+ j = sp->types[i];
+ sp->types[i] = (unsigned char)sp->ttis[j].tt_isdst;
+ if (sp->ttis[j].tt_ttisgmt) {
+ /* No adjustment to transition time */
+ } else {
+ /*
+ ** If summer time is in effect, and the
+ ** transition time was not specified as
+ ** standard time, add the summer time
+ ** offset to the transition time;
+ ** otherwise, add the standard time
+ ** offset to the transition time.
+ */
+ /*
+ ** Transitions from DST to DDST
+ ** will effectively disappear since
+ ** POSIX provides for only one DST
+ ** offset.
+ */
+ sp->ats[i] += stdoffset -
+ theirstdoffset;
+ }
+ theiroffset = -sp->ttis[j].tt_gmtoff;
+ if (!sp->ttis[j].tt_isdst)
+ theirstdoffset = theiroffset;
+ }
+ /*
+ ** Finally, fill in ttis.
+ ** ttisstd and ttisgmt need not be handled.
+ */
+ sp->ttis[0].tt_gmtoff = -stdoffset;
+ sp->ttis[0].tt_isdst = FALSE;
+ sp->ttis[0].tt_abbrind = 0;
+ sp->ttis[1].tt_gmtoff = -dstoffset;
+ sp->ttis[1].tt_isdst = TRUE;
+ sp->ttis[1].tt_abbrind = (int)stdlen + 1;
+ sp->typecnt = 2;
+ }
+ } else {
+ dstlen = 0;
+ sp->typecnt = 1; /* only standard time */
+ sp->timecnt = 0;
+ sp->ttis[0].tt_gmtoff = -stdoffset;
+ sp->ttis[0].tt_isdst = 0;
+ sp->ttis[0].tt_abbrind = 0;
+ }
+ sp->charcnt = (int)stdlen + 1;
+ if (dstlen != 0)
+ sp->charcnt += (int)dstlen + 1;
+ if ((size_t) sp->charcnt > sizeof sp->chars)
+ return -1;
+ cp = sp->chars;
+ (void) strncpy(cp, stdname, stdlen);
+ cp += stdlen;
+ *cp++ = '\0';
+ if (dstlen != 0) {
+ (void) strncpy(cp, dstname, dstlen);
+ *(cp + dstlen) = '\0';
+ }
+ return 0;
+}
+
+void
+EFIAPI
+gmtload(struct state * const sp)
+{
+ if (tzload(gmt, sp) != 0)
+ (void) tzparse(gmt, sp, TRUE);
+}
+
+static void
+tzsetwall(void)
+{
+ if (lcl_is_set < 0)
+ return;
+ lcl_is_set = -1;
+
+ if (lclptr == NULL) {
+ lclptr = (struct state *) malloc(sizeof *lclptr);
+ if (lclptr == NULL) {
+ settzname(); /* all we can do */
+ return;
+ }
+ }
+ if (tzload((char *) NULL, lclptr) != 0)
+ gmtload(lclptr);
+ settzname();
+}
+
+void
+EFIAPI
+tzset(void)
+{
+ register const char * name;
+
+ name = getenv("TZ");
+ if (name == NULL) {
+ tzsetwall();
+ return;
+ }
+
+ if (lcl_is_set > 0 && strcmp(lcl_TZname, name) == 0)
+ return;
+ lcl_is_set = strlen(name) < sizeof lcl_TZname;
+ if (lcl_is_set)
+ (void)strncpyX(lcl_TZname, name, sizeof(lcl_TZname));
+
+ if (lclptr == NULL) {
+ lclptr = (struct state *) malloc(sizeof *lclptr);
+ if (lclptr == NULL) {
+ settzname(); /* all we can do */
+ return;
+ }
+ }
+ if (*name == '\0') {
+ /*
+ ** User wants it fast rather than right.
+ */
+ lclptr->leapcnt = 0; /* so, we're off a little */
+ lclptr->timecnt = 0;
+ lclptr->typecnt = 0;
+ lclptr->ttis[0].tt_isdst = 0;
+ lclptr->ttis[0].tt_gmtoff = 0;
+ lclptr->ttis[0].tt_abbrind = 0;
+ (void)strncpyX(lclptr->chars, gmt, sizeof(lclptr->chars));
+ } else if (tzload(name, lclptr) != 0)
+ if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0)
+ (void) gmtload(lclptr);
+ settzname();
+}
diff --git a/StdLib/LibC/Time/strftime.c b/StdLib/LibC/Time/strftime.c
new file mode 100644
index 0000000000..a9da3e2f7d
--- /dev/null
+++ b/StdLib/LibC/Time/strftime.c
@@ -0,0 +1,602 @@
+/** @file
+ Implementation of the strftime function for <time.h>.
+
+ Based on the UCB version with the ID appearing below.
+ This is ANSIish only when "multibyte character == plain character".
+
+ Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Copyright (c) 1989, 1993
+ The Regents of the University of California. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. All advertising materials mentioning features or use of this software
+ must display the following acknowledgement:
+ This product includes software developed by the University of
+ California, Berkeley and its contributors.
+ 4. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ NetBSD: strftime.c,v 1.17.4.1 2007/08/21 20:08:21 liamjfoy Exp
+**/
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#include "namespace.h"
+#include <time.h>
+#include "tzfile.h"
+#include <TimeVals.h>
+#include "fcntl.h"
+#include "locale.h"
+
+#include "sys/localedef.h"
+#include <MainData.h>
+
+/*
+** We don't use these extensions in strftime operation even when
+** supported by the local tzcode configuration. A strictly
+** conforming C application may leave them in undefined state.
+*/
+
+#ifdef _LIBC
+#undef TM_ZONE
+#undef TM_GMTOFF
+#endif
+
+#define Locale _CurrentTimeLocale
+
+static char * EFIAPI _add(const char *, char *, const char * const);
+static char * EFIAPI _conv(const int, const char * const, char * const, const char * const);
+static char * EFIAPI _fmt(const char *, const struct tm * const, char *, const char * const, int *);
+
+#define NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU
+
+#ifndef YEAR_2000_NAME
+#define YEAR_2000_NAME "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS"
+#endif /* !defined YEAR_2000_NAME */
+
+
+#define IN_NONE 0
+#define IN_SOME 1
+#define IN_THIS 2
+#define IN_ALL 3
+
+size_t
+EFIAPI
+strftime(
+ char * __restrict s,
+ size_t maxsize,
+ const char * __restrict format,
+ const struct tm * __restrict timeptr
+ )
+{
+ char * p;
+ int warn;
+
+ tzset();
+ warn = IN_NONE;
+ p = _fmt(((format == NULL) ? "%c" : format), timeptr, s, s + maxsize, &warn);
+
+#ifndef NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU
+ if (warn != IN_NONE && getenv(YEAR_2000_NAME) != NULL) {
+ (void) fprintf(stderr, "\n");
+ if (format == NULL)
+ (void) fprintf(stderr, "NULL strftime format ");
+ else (void) fprintf(stderr, "strftime format \"%s\" ",
+ format);
+ (void) fprintf(stderr, "yields only two digits of years in ");
+ if (warn == IN_SOME)
+ (void) fprintf(stderr, "some locales");
+ else if (warn == IN_THIS)
+ (void) fprintf(stderr, "the current locale");
+ else (void) fprintf(stderr, "all locales");
+ (void) fprintf(stderr, "\n");
+ }
+#endif /* !defined NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU */
+
+ if (p == s + maxsize)
+ return 0;
+ *p = '\0';
+ return p - s;
+}
+
+static char *
+EFIAPI
+_fmt(
+ const char * format,
+ const struct tm * const t,
+ char * pt,
+ const char * const ptlim,
+ int * warnp
+ )
+{
+ for ( ; *format; ++format) {
+ if (*format == '%') {
+label:
+ switch (*++format) {
+ case '\0':
+ --format;
+ break;
+ case 'A':
+ pt = _add((t->tm_wday < 0 ||
+ t->tm_wday >= DAYSPERWEEK) ?
+ "?" : Locale->day[t->tm_wday],
+ pt, ptlim);
+ continue;
+ case 'a':
+ pt = _add((t->tm_wday < 0 ||
+ t->tm_wday >= DAYSPERWEEK) ?
+ "?" : Locale->abday[t->tm_wday],
+ pt, ptlim);
+ continue;
+ case 'B':
+ pt = _add((t->tm_mon < 0 ||
+ t->tm_mon >= MONSPERYEAR) ?
+ "?" : Locale->mon[t->tm_mon],
+ pt, ptlim);
+ continue;
+ case 'b':
+ case 'h':
+ pt = _add((t->tm_mon < 0 ||
+ t->tm_mon >= MONSPERYEAR) ?
+ "?" : Locale->abmon[t->tm_mon],
+ pt, ptlim);
+ continue;
+ case 'C':
+ /*
+ ** %C used to do a...
+ ** _fmt("%a %b %e %X %Y", t);
+ ** ...whereas now POSIX 1003.2 calls for
+ ** something completely different.
+ ** (ado, 1993-05-24)
+ */
+ pt = _conv((t->tm_year + TM_YEAR_BASE) / 100,
+ "%02d", pt, ptlim);
+ continue;
+ case 'c':
+ {
+ int warn2 = IN_SOME;
+
+ pt = _fmt(Locale->d_t_fmt, t, pt, ptlim, &warn2);
+ if (warn2 == IN_ALL)
+ warn2 = IN_THIS;
+ if (warn2 > *warnp)
+ *warnp = warn2;
+ }
+ continue;
+ case 'D':
+ pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp);
+ continue;
+ case 'd':
+ pt = _conv(t->tm_mday, "%02d", pt, ptlim);
+ continue;
+ case 'E':
+ case 'O':
+ /*
+ ** C99 locale modifiers.
+ ** The sequences
+ ** %Ec %EC %Ex %EX %Ey %EY
+ ** %Od %oe %OH %OI %Om %OM
+ ** %OS %Ou %OU %OV %Ow %OW %Oy
+ ** are supposed to provide alternate
+ ** representations.
+ */
+ goto label;
+ case 'e':
+ pt = _conv(t->tm_mday, "%2d", pt, ptlim);
+ continue;
+ case 'F':
+ pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp);
+ continue;
+ case 'H':
+ pt = _conv(t->tm_hour, "%02d", pt, ptlim);
+ continue;
+ case 'I':
+ pt = _conv((t->tm_hour % 12) ?
+ (t->tm_hour % 12) : 12,
+ "%02d", pt, ptlim);
+ continue;
+ case 'j':
+ pt = _conv(t->tm_yday + 1, "%03d", pt, ptlim);
+ continue;
+ case 'k':
+ /*
+ ** This used to be...
+ ** _conv(t->tm_hour % 12 ?
+ ** t->tm_hour % 12 : 12, 2, ' ');
+ ** ...and has been changed to the below to
+ ** match SunOS 4.1.1 and Arnold Robbins'
+ ** strftime version 3.0. That is, "%k" and
+ ** "%l" have been swapped.
+ ** (ado, 1993-05-24)
+ */
+ pt = _conv(t->tm_hour, "%2d", pt, ptlim);
+ continue;
+#ifdef KITCHEN_SINK
+ case 'K':
+ /*
+ ** After all this time, still unclaimed!
+ */
+ pt = _add("kitchen sink", pt, ptlim);
+ continue;
+#endif /* defined KITCHEN_SINK */
+ case 'l':
+ /*
+ ** This used to be...
+ ** _conv(t->tm_hour, 2, ' ');
+ ** ...and has been changed to the below to
+ ** match SunOS 4.1.1 and Arnold Robbin's
+ ** strftime version 3.0. That is, "%k" and
+ ** "%l" have been swapped.
+ ** (ado, 1993-05-24)
+ */
+ pt = _conv((t->tm_hour % 12) ?
+ (t->tm_hour % 12) : 12,
+ "%2d", pt, ptlim);
+ continue;
+ case 'M':
+ pt = _conv(t->tm_min, "%02d", pt, ptlim);
+ continue;
+ case 'm':
+ pt = _conv(t->tm_mon + 1, "%02d", pt, ptlim);
+ continue;
+ case 'n':
+ pt = _add("\n", pt, ptlim);
+ continue;
+ case 'p':
+ pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ?
+ Locale->am_pm[1] :
+ Locale->am_pm[0],
+ pt, ptlim);
+ continue;
+ case 'R':
+ pt = _fmt("%H:%M", t, pt, ptlim, warnp);
+ continue;
+ case 'r':
+ pt = _fmt(Locale->t_fmt_ampm, t, pt, ptlim,
+ warnp);
+ continue;
+ case 'S':
+ pt = _conv(t->tm_sec, "%02d", pt, ptlim);
+ continue;
+ case 's':
+ {
+ struct tm tm;
+ char buf[INT_STRLEN_MAXIMUM(
+ time_t) + 1];
+ time_t mkt;
+
+ tm = *t;
+ mkt = mktime(&tm);
+ /* CONSTCOND */
+ if (TYPE_SIGNED(time_t))
+ (void) sprintf(buf, "%ld",
+ (long) mkt);
+ else (void) sprintf(buf, "%lu",
+ (unsigned long) mkt);
+ pt = _add(buf, pt, ptlim);
+ }
+ continue;
+ case 'T':
+ pt = _fmt("%H:%M:%S", t, pt, ptlim, warnp);
+ continue;
+ case 't':
+ pt = _add("\t", pt, ptlim);
+ continue;
+ case 'U':
+ pt = _conv((t->tm_yday + DAYSPERWEEK -
+ t->tm_wday) / DAYSPERWEEK,
+ "%02d", pt, ptlim);
+ continue;
+ case 'u':
+ /*
+ ** From Arnold Robbins' strftime version 3.0:
+ ** "ISO 8601: Weekday as a decimal number
+ ** [1 (Monday) - 7]"
+ ** (ado, 1993-05-24)
+ */
+ pt = _conv((t->tm_wday == 0) ?
+ DAYSPERWEEK : t->tm_wday,
+ "%d", pt, ptlim);
+ continue;
+ case 'V': /* ISO 8601 week number */
+ case 'G': /* ISO 8601 year (four digits) */
+ case 'g': /* ISO 8601 year (two digits) */
+/*
+** From Arnold Robbins' strftime version 3.0: "the week number of the
+** year (the first Monday as the first day of week 1) as a decimal number
+** (01-53)."
+** (ado, 1993-05-24)
+**
+** From "http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html" by Markus Kuhn:
+** "Week 01 of a year is per definition the first week which has the
+** Thursday in this year, which is equivalent to the week which contains
+** the fourth day of January. In other words, the first week of a new year
+** is the week which has the majority of its days in the new year. Week 01
+** might also contain days from the previous year and the week before week
+** 01 of a year is the last week (52 or 53) of the previous year even if
+** it contains days from the new year. A week starts with Monday (day 1)
+** and ends with Sunday (day 7). For example, the first week of the year
+** 1997 lasts from 1996-12-30 to 1997-01-05..."
+** (ado, 1996-01-02)
+*/
+ {
+ int year;
+ int yday;
+ int wday;
+ int w;
+
+ year = t->tm_year + TM_YEAR_BASE;
+ yday = t->tm_yday;
+ wday = t->tm_wday;
+ for ( ; ; ) {
+ int len;
+ int bot;
+ int top;
+
+ len = isleap(year) ?
+ DAYSPERLYEAR :
+ DAYSPERNYEAR;
+ /*
+ ** What yday (-3 ... 3) does
+ ** the ISO year begin on?
+ */
+ bot = ((yday + 11 - wday) %
+ DAYSPERWEEK) - 3;
+ /*
+ ** What yday does the NEXT
+ ** ISO year begin on?
+ */
+ top = bot -
+ (len % DAYSPERWEEK);
+ if (top < -3)
+ top += DAYSPERWEEK;
+ top += len;
+ if (yday >= top) {
+ ++year;
+ w = 1;
+ break;
+ }
+ if (yday >= bot) {
+ w = 1 + ((yday - bot) /
+ DAYSPERWEEK);
+ break;
+ }
+ --year;
+ yday += isleap(year) ?
+ DAYSPERLYEAR :
+ DAYSPERNYEAR;
+ }
+#ifdef XPG4_1994_04_09
+ if ((w == 52
+ && t->tm_mon == TM_JANUARY)
+ || (w == 1
+ && t->tm_mon == TM_DECEMBER))
+ w = 53;
+#endif /* defined XPG4_1994_04_09 */
+ if (*format == 'V')
+ pt = _conv(w, "%02d",
+ pt, ptlim);
+ else if (*format == 'g') {
+ *warnp = IN_ALL;
+ pt = _conv(year % 100, "%02d",
+ pt, ptlim);
+ } else pt = _conv(year, "%04d",
+ pt, ptlim);
+ }
+ continue;
+ case 'v':
+ /*
+ ** From Arnold Robbins' strftime version 3.0:
+ ** "date as dd-bbb-YYYY"
+ ** (ado, 1993-05-24)
+ */
+ pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp);
+ continue;
+ case 'W':
+ pt = _conv((t->tm_yday + DAYSPERWEEK -
+ (t->tm_wday ?
+ (t->tm_wday - 1) :
+ (DAYSPERWEEK - 1))) / DAYSPERWEEK,
+ "%02d", pt, ptlim);
+ continue;
+ case 'w':
+ pt = _conv(t->tm_wday, "%d", pt, ptlim);
+ continue;
+ case 'X':
+ pt = _fmt(Locale->t_fmt, t, pt, ptlim, warnp);
+ continue;
+ case 'x':
+ {
+ int warn2 = IN_SOME;
+
+ pt = _fmt(Locale->d_fmt, t, pt, ptlim, &warn2);
+ if (warn2 == IN_ALL)
+ warn2 = IN_THIS;
+ if (warn2 > *warnp)
+ *warnp = warn2;
+ }
+ continue;
+ case 'y':
+ *warnp = IN_ALL;
+ pt = _conv((t->tm_year + TM_YEAR_BASE) % 100,
+ "%02d", pt, ptlim);
+ continue;
+ case 'Y':
+ pt = _conv(t->tm_year + TM_YEAR_BASE, "%04d",
+ pt, ptlim);
+ continue;
+ case 'Z':
+#ifdef TM_ZONE
+ if (t->TM_ZONE != NULL)
+ pt = _add(t->TM_ZONE, pt, ptlim);
+ else
+#endif /* defined TM_ZONE */
+ if (t->tm_isdst >= 0)
+ pt = _add(tzname[t->tm_isdst != 0],
+ pt, ptlim);
+ /*
+ ** C99 says that %Z must be replaced by the
+ ** empty string if the time zone is not
+ ** determinable.
+ */
+ continue;
+ case 'z':
+ {
+ int diff;
+ char const * sign;
+
+ if (t->tm_isdst < 0)
+ continue;
+#ifdef TM_GMTOFF
+ diff = (int)t->TM_GMTOFF;
+#else /* !defined TM_GMTOFF */
+ /*
+ ** C99 says that the UTC offset must
+ ** be computed by looking only at
+ ** tm_isdst. This requirement is
+ ** incorrect, since it means the code
+ ** must rely on magic (in this case
+ ** altzone and timezone), and the
+ ** magic might not have the correct
+ ** offset. Doing things correctly is
+ ** tricky and requires disobeying C99;
+ ** see GNU C strftime for details.
+ ** For now, punt and conform to the
+ ** standard, even though it's incorrect.
+ **
+ ** C99 says that %z must be replaced by the
+ ** empty string if the time zone is not
+ ** determinable, so output nothing if the
+ ** appropriate variables are not available.
+ */
+#ifndef STD_INSPIRED
+ if (t->tm_isdst == 0)
+#ifdef USG_COMPAT
+ diff = -timezone;
+#else /* !defined USG_COMPAT */
+ continue;
+#endif /* !defined USG_COMPAT */
+ else
+#ifdef ALTZONE
+ diff = -altzone;
+#else /* !defined ALTZONE */
+ continue;
+#endif /* !defined ALTZONE */
+#else /* defined STD_INSPIRED */
+ {
+ struct tm tmp;
+ time_t lct, gct;
+
+ /*
+ ** Get calendar time from t
+ ** being treated as local.
+ */
+ tmp = *t; /* mktime discards const */
+ lct = mktime(&tmp);
+
+ if (lct == (time_t)-1)
+ continue;
+
+ /*
+ ** Get calendar time from t
+ ** being treated as GMT.
+ **/
+ tmp = *t; /* mktime discards const */
+ gct = timegm(&tmp);
+
+ if (gct == (time_t)-1)
+ continue;
+
+ /* LINTED difference will fit int */
+ diff = (intmax_t)gct - (intmax_t)lct;
+ }
+#endif /* defined STD_INSPIRED */
+#endif /* !defined TM_GMTOFF */
+ if (diff < 0) {
+ sign = "-";
+ diff = -diff;
+ } else sign = "+";
+ pt = _add(sign, pt, ptlim);
+ diff /= 60;
+ pt = _conv((diff/60)*100 + diff%60,
+ "%04d", pt, ptlim);
+ }
+ continue;
+#if 0
+ case '+':
+ pt = _fmt(Locale->date_fmt, t, pt, ptlim,
+ warnp);
+ continue;
+#endif
+ case '%':
+ /*
+ ** X311J/88-090 (4.12.3.5): if conversion char is
+ ** undefined, behavior is undefined. Print out the
+ ** character itself as printf(3) also does.
+ */
+ default:
+ break;
+ }
+ }
+ if (pt == ptlim)
+ break;
+ *pt++ = *format;
+ }
+ return pt;
+}
+
+static char *
+EFIAPI
+_conv(
+ const int n,
+ const char * const format,
+ char * const pt,
+ const char * const ptlim
+)
+{
+ char buf[INT_STRLEN_MAXIMUM(int) + 1];
+
+ (void) sprintf(buf, format, n);
+ return _add(buf, pt, ptlim);
+}
+
+static char *
+EFIAPI
+_add(
+ const char * str,
+ char * pt,
+ const char * const ptlim
+)
+{
+ while (pt < ptlim && (*pt = *str++) != '\0')
+ ++pt;
+ return pt;
+}
diff --git a/StdLib/LibC/Time/tzfile.h b/StdLib/LibC/Time/tzfile.h
new file mode 100644
index 0000000000..11c20ebd39
--- /dev/null
+++ b/StdLib/LibC/Time/tzfile.h
@@ -0,0 +1,168 @@
+/** @file
+ Time Zone processing, declarations and macros.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Derived from the NIH time zone package file, tzfile.h, which contains the following notice:
+
+ This file is in the public domain, so clarified as of
+ 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
+
+ This header is for use ONLY with the time conversion code.
+ There is no guarantee that it will remain unchanged,
+ or that it will remain at all.
+ Do NOT copy it to any system include directory.
+ Thank you!
+
+ NetBSD: tzfile.h,v 1.8 1998/01/22 07:06:59 jtc Exp
+**/
+#ifndef TZFILE_H
+#define TZFILE_H
+
+/*
+** Information about time zone files.
+*/
+
+#ifndef TZDIR /* Time zone object file directory */
+#define TZDIR "/usr/share/zoneinfo"
+#endif /* !defined TZDIR */
+
+#ifndef TZDEFAULT
+#define TZDEFAULT "/etc/localtime"
+#endif /* !defined TZDEFAULT */
+
+#ifndef TZDEFRULES
+#define TZDEFRULES "posixrules"
+#endif /* !defined TZDEFRULES */
+
+/*
+** Each file begins with. . .
+*/
+
+#define TZ_MAGIC "TZif"
+
+struct tzhead {
+ char tzh_magic[4]; /* TZ_MAGIC */
+ char tzh_reserved[16]; /* reserved for future use */
+ char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */
+ char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */
+ char tzh_leapcnt[4]; /* coded number of leap seconds */
+ char tzh_timecnt[4]; /* coded number of transition times */
+ char tzh_typecnt[4]; /* coded number of local time types */
+ char tzh_charcnt[4]; /* coded number of abbr. chars */
+};
+
+/*
+** . . .followed by. . .
+**
+** tzh_timecnt (char [4])s coded transition times a la time(2)
+** tzh_timecnt (unsigned char)s types of local time starting at above
+** tzh_typecnt repetitions of
+** one (char [4]) coded UTC offset in seconds
+** one (unsigned char) used to set tm_isdst
+** one (unsigned char) that's an abbreviation list index
+** tzh_charcnt (char)s '\0'-terminated zone abbreviations
+** tzh_leapcnt repetitions of
+** one (char [4]) coded leap second transition times
+** one (char [4]) total correction after above
+** tzh_ttisstdcnt (char)s indexed by type; if TRUE, transition
+** time is standard time, if FALSE,
+** transition time is wall clock time
+** if absent, transition times are
+** assumed to be wall clock time
+** tzh_ttisgmtcnt (char)s indexed by type; if TRUE, transition
+** time is UTC, if FALSE,
+** transition time is local time
+** if absent, transition times are
+** assumed to be local time
+*/
+
+/*
+** In the current implementation, "tzset()" refuses to deal with files that
+** exceed any of the limits below.
+*/
+
+#ifndef TZ_MAX_TIMES
+/*
+** The TZ_MAX_TIMES value below is enough to handle a bit more than a
+** year's worth of solar time (corrected daily to the nearest second) or
+** 138 years of Pacific Presidential Election time
+** (where there are three time zone transitions every fourth year).
+*/
+#define TZ_MAX_TIMES 370
+#endif /* !defined TZ_MAX_TIMES */
+
+#ifndef TZ_MAX_TYPES
+#ifndef NOSOLAR
+#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
+#endif /* !defined NOSOLAR */
+#ifdef NOSOLAR
+/*
+** Must be at least 14 for Europe/Riga as of Jan 12 1995,
+** as noted by Earl Chew <earl@hpato.aus.hp.com>.
+*/
+#define TZ_MAX_TYPES 20 /* Maximum number of local time types */
+#endif /* !defined NOSOLAR */
+#endif /* !defined TZ_MAX_TYPES */
+
+#ifndef TZ_MAX_CHARS
+#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
+ /* (limited by what unsigned chars can hold) */
+#endif /* !defined TZ_MAX_CHARS */
+
+#ifndef TZ_MAX_LEAPS
+#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
+#endif /* !defined TZ_MAX_LEAPS */
+
+#define SECSPERMIN 60
+#define MINSPERHOUR 60
+#define HOURSPERDAY 24
+#define DAYSPERWEEK 7
+#define DAYSPERNYEAR 365
+#define DAYSPERLYEAR 366
+#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
+#define SECSPERDAY ((LONG32)(SECSPERHOUR * HOURSPERDAY))
+#define MONSPERYEAR 12
+
+#define TM_SUNDAY 0
+#define TM_MONDAY 1
+#define TM_TUESDAY 2
+#define TM_WEDNESDAY 3
+#define TM_THURSDAY 4
+#define TM_FRIDAY 5
+#define TM_SATURDAY 6
+
+#define TM_JANUARY 0
+#define TM_FEBRUARY 1
+#define TM_MARCH 2
+#define TM_APRIL 3
+#define TM_MAY 4
+#define TM_JUNE 5
+#define TM_JULY 6
+#define TM_AUGUST 7
+#define TM_SEPTEMBER 8
+#define TM_OCTOBER 9
+#define TM_NOVEMBER 10
+#define TM_DECEMBER 11
+
+#define TM_YEAR_BASE 1900
+
+#define EPOCH_YEAR 1970
+#define EPOCH_WDAY TM_THURSDAY // Use this for 32-bit time_t
+//#define EPOCH_WDAY TM_SUNDAY // Use this for 64-bit time_t
+
+/*
+** Accurate only for the past couple of centuries;
+** that will probably do.
+*/
+
+#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
+
+#endif /* !defined TZFILE_H */
diff --git a/StdLib/LibC/Uefi/Console.c b/StdLib/LibC/Uefi/Console.c
new file mode 100644
index 0000000000..0c3a21cf45
--- /dev/null
+++ b/StdLib/LibC/Uefi/Console.c
@@ -0,0 +1,393 @@
+/** @file
+ File abstractions of the console.
+
+ Manipulates EFI_FILE_PROTOCOL abstractions for stdin, stdout, stderr.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#include <stdio.h>
+#include <sys/fcntl.h>
+#include <MainData.h>
+#include <Efi/Console.h>
+
+static const CHAR16 * stdioNames[NUM_SPECIAL] = {
+ L"stdin:", L"stdout:", L"stderr:"
+};
+static const int stdioFlags[NUM_SPECIAL] = {
+ O_RDONLY, // stdin
+ O_WRONLY, // stdout
+ O_WRONLY // stderr
+};
+
+static const int stdioMode[NUM_SPECIAL] = {
+ 0444, // stdin
+ 0222, // stdout
+ 0222 // stderr
+};
+
+static
+EFI_STATUS
+EFIAPI
+ConClose(
+ IN EFI_FILE_PROTOCOL *This
+ )
+{
+ ConInstance *Stream;
+
+ Stream = BASE_CR(This, ConInstance, Abstraction);
+ // Quick check to see if Stream looks reasonable
+ if(Stream->Cookie != 0x62416F49) { // Cookie == 'IoAb'
+ return RETURN_INVALID_PARAMETER; // Looks like a bad This pointer
+ }
+ // Nothing to Flush.
+ // Mark the Stream as closed.
+ Stream->Dev = NULL;
+
+ return RETURN_SUCCESS;
+}
+
+static
+EFI_STATUS
+EFIAPI
+ConDelete(
+ IN EFI_FILE_PROTOCOL *This
+ )
+{
+ return RETURN_UNSUPPORTED;
+}
+
+static
+EFI_STATUS
+EFIAPI
+ConRead(
+ IN EFI_FILE_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL *Proto;
+ ConInstance *Stream;
+ CHAR16 *OutPtr;
+ EFI_INPUT_KEY Key;
+ UINTN NumChar;
+ UINTN Edex;
+ EFI_STATUS Status;
+ UINTN i;
+
+ Stream = BASE_CR(This, ConInstance, Abstraction);
+ // Quick check to see if Stream looks reasonable
+ if(Stream->Cookie != 0x62416F49) { // Cookie == 'IoAb'
+ return RETURN_INVALID_PARAMETER; // Looks like a bad This pointer
+ }
+ if(Stream->Dev == NULL) {
+ // Can't read from an unopened Stream
+ return RETURN_DEVICE_ERROR;
+ }
+ if(Stream != &gMD->StdIo[0]) {
+ // Read only valid for stdin
+ return RETURN_UNSUPPORTED;
+ }
+ // It looks like things are OK for trying to read
+ // We will accumulate *BufferSize characters or until we encounter
+ // an "activation" character. Currently any control character.
+ Proto = (EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)Stream->Dev;
+ OutPtr = Buffer;
+ NumChar = (*BufferSize - 1) / sizeof(CHAR16);
+ i = 0;
+ do {
+ Status = gBS->WaitForEvent( 1, &Proto->WaitForKey, &Edex);
+ if(Status != EFI_SUCCESS) {
+ break;
+ }
+ Status = Proto->ReadKeyStroke(Proto, &Key);
+ if(Status != EFI_SUCCESS) {
+ break;
+ }
+ if(Key.ScanCode == SCAN_NULL) {
+ *OutPtr++ = Key.UnicodeChar;
+ ++i;
+ }
+ if(Key.UnicodeChar < 0x0020) { // If a control character, or a scan code
+ break;
+ }
+ } while(i < NumChar);
+ *BufferSize = i * sizeof(CHAR16);
+ return Status;
+}
+
+/* Write a NULL terminated WCS to the EFI console.
+
+ @param[in,out] BufferSize Number of bytes in Buffer. Set to zero if
+ the string couldn't be displayed.
+ @parem[in] Buffer The WCS string to be displayed
+
+*/
+static
+EFI_STATUS
+EFIAPI
+ConWrite(
+ IN EFI_FILE_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Proto;
+ ConInstance *Stream;
+ CHAR16 *MyBuf;
+ UINTN NumChar;
+
+ Stream = BASE_CR(This, ConInstance, Abstraction);
+ // Quick check to see if Stream looks reasonable
+ if(Stream->Cookie != 0x62416F49) { // Cookie == 'IoAb'
+ return RETURN_INVALID_PARAMETER; // Looks like a bad This pointer
+ }
+ if(Stream->Dev == NULL) {
+ // Can't write to an unopened Stream
+ return RETURN_DEVICE_ERROR;
+ }
+ if(Stream == &gMD->StdIo[0]) {
+ // Write is not valid for stdin
+ return RETURN_UNSUPPORTED;
+ }
+ // Everything is OK to do the write.
+ Proto = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)Stream->Dev;
+ MyBuf = (CHAR16 *)Buffer;
+ NumChar = *BufferSize;
+
+ // Send MyBuf to the console
+ Status = Proto->OutputString( Proto, MyBuf);
+ // Depending on status, update BufferSize and return
+ if(Status != EFI_SUCCESS) {
+ *BufferSize = 0; // We don't really know how many characters made it out
+ }
+ else {
+ *BufferSize = NumChar;
+ Stream->NumWritten += NumChar;
+ }
+ return Status;
+}
+
+static
+EFI_STATUS
+EFIAPI
+ConGetPosition(
+ IN EFI_FILE_PROTOCOL *This,
+ OUT UINT64 *Position
+ )
+{
+ ConInstance *Stream;
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Proto;
+ XYoffset CursorPos;
+
+ Stream = BASE_CR(This, ConInstance, Abstraction);
+ // Quick check to see if Stream looks reasonable
+ if(Stream->Cookie != 0x62416F49) { // Cookie == 'IoAb'
+ return RETURN_INVALID_PARAMETER; // Looks like a bad This pointer
+ }
+ if(Stream == &gMD->StdIo[0]) {
+ // This is stdin
+ *Position = Stream->NumRead;
+ }
+ else {
+ Proto = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)Stream->Dev;
+ CursorPos.XYpos.Column = (UINT32)Proto->Mode->CursorColumn;
+ CursorPos.XYpos.Row = (UINT32)Proto->Mode->CursorRow;
+ *Position = CursorPos.Offset;
+ }
+ return RETURN_SUCCESS;
+}
+
+static
+EFI_STATUS
+EFIAPI
+ConSetPosition(
+ IN EFI_FILE_PROTOCOL *This,
+ IN UINT64 Position
+ )
+{
+ ConInstance *Stream;
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Proto;
+ XYoffset CursorPos;
+
+ Stream = BASE_CR(This, ConInstance, Abstraction);
+ // Quick check to see if Stream looks reasonable
+ if(Stream->Cookie != 0x62416F49) { // Cookie == 'IoAb'
+ return RETURN_INVALID_PARAMETER; // Looks like a bad This pointer
+ }
+ if(Stream->Dev == NULL) {
+ // Can't write to an unopened Stream
+ return RETURN_DEVICE_ERROR;
+ }
+ if(Stream == &gMD->StdIo[0]) {
+ // Seek is not valid for stdin
+ return RETURN_UNSUPPORTED;
+ }
+ // Everything is OK to do the final verification and "seek".
+ Proto = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)Stream->Dev;
+ CursorPos.Offset = Position;
+
+ return Proto->SetCursorPosition(Proto,
+ (INTN)CursorPos.XYpos.Column,
+ (INTN)CursorPos.XYpos.Row);
+}
+
+static
+EFI_STATUS
+EFIAPI
+ConGetInfo(
+ IN EFI_FILE_PROTOCOL *This,
+ IN EFI_GUID *InformationType,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ EFI_FILE_INFO *InfoBuf;
+ ConInstance *Stream;
+
+ Stream = BASE_CR(This, ConInstance, Abstraction);
+ // Quick check to see if Stream looks reasonable
+ if((Stream->Cookie != 0x62416F49) || // Cookie == 'IoAb'
+ (Buffer == NULL))
+ {
+ return RETURN_INVALID_PARAMETER;
+ }
+ if(*BufferSize < sizeof(EFI_FILE_INFO)) {
+ *BufferSize = sizeof(EFI_FILE_INFO);
+ return RETURN_BUFFER_TOO_SMALL;
+ }
+ // All of our parameters are correct, so fill in the information.
+ (void) ZeroMem(Buffer, sizeof(EFI_FILE_INFO));
+ InfoBuf = (EFI_FILE_INFO *)Buffer;
+ InfoBuf->Size = sizeof(EFI_FILE_INFO);
+ InfoBuf->FileSize = 1;
+ InfoBuf->PhysicalSize = 1;
+ *BufferSize = sizeof(EFI_FILE_INFO);
+
+ return RETURN_SUCCESS;
+}
+
+static
+EFI_STATUS
+EFIAPI
+ConSetInfo(
+ IN EFI_FILE_PROTOCOL *This,
+ IN EFI_GUID *InformationType,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ )
+{
+ return RETURN_UNSUPPORTED;
+}
+
+static
+EFI_STATUS
+EFIAPI
+ConFlush(
+ IN EFI_FILE_PROTOCOL *This
+ )
+{
+ return RETURN_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+ConOpen(
+ IN EFI_FILE_PROTOCOL *This,
+ OUT EFI_FILE_PROTOCOL **NewHandle,
+ IN CHAR16 *FileName,
+ IN UINT64 OpenMode, // Ignored
+ IN UINT64 Attributes // Ignored
+ )
+{
+ ConInstance *Stream;
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Proto;
+ UINTN Columns;
+ UINTN Rows;
+ int i;
+
+ if((NewHandle == NULL) ||
+ (FileName == NULL))
+ {
+ return RETURN_INVALID_PARAMETER;
+ }
+ // Process FileName
+ for(i = 0; i < NUM_SPECIAL; ++i) {
+ if(StrCmp( stdioNames[i], FileName) == 0) {
+ break;
+ }
+ }
+ if(i >= NUM_SPECIAL) {
+ return RETURN_NO_MAPPING;
+ }
+ // Get pointer to instance.
+ Stream = &gMD->StdIo[i];
+ if(Stream->Dev == NULL) {
+ // If this stream has been closed, then
+ // Initialize instance.
+ Stream->Cookie = 0x62416F49;
+ Stream->NumRead = 0;
+ Stream->NumWritten = 0;
+ switch(i) {
+ case 0:
+ Stream->Dev = gST->ConIn;
+ break;
+ case 1:
+ Stream->Dev = gST->ConOut;
+ break;
+ case 2:
+ if(gST->StdErr == NULL) {
+ Stream->Dev = gST->ConOut;
+ }
+ else {
+ Stream->Dev = gST->StdErr;
+ }
+ break;
+ default:
+ return RETURN_VOLUME_CORRUPTED; // This is a "should never happen" case.
+ }
+ Stream->Abstraction.Revision = 0x00010000;
+ Stream->Abstraction.Open = &ConOpen;
+ Stream->Abstraction.Close = &ConClose;
+ Stream->Abstraction.Delete = &ConDelete;
+ Stream->Abstraction.Read = &ConRead;
+ Stream->Abstraction.Write = &ConWrite;
+ Stream->Abstraction.GetPosition = &ConGetPosition;
+ Stream->Abstraction.SetPosition = &ConSetPosition;
+ Stream->Abstraction.GetInfo = &ConGetInfo;
+ Stream->Abstraction.SetInfo = &ConSetInfo;
+ Stream->Abstraction.Flush = &ConFlush;
+ // Get additional information if this is an Output stream
+ if(i != 0) {
+ Proto = Stream->Dev;
+ Stream->ConOutMode = Proto->Mode->Mode;
+ if( Proto->QueryMode(Proto, Stream->ConOutMode, &Columns, &Rows) != RETURN_SUCCESS) {
+ Stream->Dev = NULL; // Mark this stream as closed
+ return RETURN_INVALID_PARAMETER;
+ }
+ Stream->MaxConXY.XYpos.Column = (UINT32)Columns;
+ Stream->MaxConXY.XYpos.Row = (UINT32)Rows;
+ }
+ }
+ // Save NewHandle and return.
+ *NewHandle = &Stream->Abstraction;
+
+ return RETURN_SUCCESS;
+}
diff --git a/StdLib/LibC/Uefi/SysCalls.c b/StdLib/LibC/Uefi/SysCalls.c
new file mode 100644
index 0000000000..624d45878e
--- /dev/null
+++ b/StdLib/LibC/Uefi/SysCalls.c
@@ -0,0 +1,1198 @@
+/** @file
+ EFI versions of NetBSD system calls.
+
+ Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#include <Uefi.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/ShellLib.h>
+
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#include <sys/ansi.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <string.h>
+#include <wchar.h>
+#include <sys/fcntl.h>
+#include <sys/stat.h>
+#include <sys/syslimits.h>
+#include "SysEfi.h"
+#include <MainData.h>
+#include <extern.h> // Library/include/extern.h: Private to implementation
+#include <Efi/Console.h>
+
+/* Macros only used in this file. */
+// Parameters for the ValidateFD function.
+#define VALID_OPEN 1
+#define VALID_CLOSED 0
+#define VALID_DONT_CARE -1
+
+
+/* EFI versions of BSD system calls used in stdio */
+
+/* Normalize path so that forward slashes are replaced with backslashes.
+ Backslashes are required for UEFI.
+*/
+static void
+NormalizePath( const CHAR16 *path)
+{
+ CHAR16 *temp;
+
+ for( temp = (CHAR16 *)path; *temp; ++temp) {
+ if(*temp == L'/') {
+ *temp = L'\\';
+ }
+ }
+}
+
+/* Validate that fd refers to a valid file descriptor.
+ IsOpen is interpreted as follows:
+ - Positive fd must be OPEN
+ - Zero fd must be CLOSED
+ - Negative fd may be OPEN or CLOSED
+
+ @retval TRUE fd is VALID
+ @retval FALSE fd is INVALID
+*/
+static BOOLEAN
+ValidateFD( int fd, int IsOpen)
+{
+ BOOLEAN retval = FALSE;
+
+ if((fd >= 0) && (fd < OPEN_MAX)) {
+ retval = TRUE;
+ if(IsOpen >= 0) {
+ retval = (BOOLEAN)(gMD->fdarray[fd].State != 0); // TRUE if OPEN
+ if(IsOpen == VALID_CLOSED) {
+ retval = (BOOLEAN)!retval; // We want TRUE if CLOSED
+ }
+ }
+ }
+ return retval;
+}
+
+/* Find and reserve a free File Descriptor.
+
+ Returns the first free File Descriptor greater than or equal to the,
+ already validated, fd specified by Minfd.
+
+ @return Returns -1 if there are no free FDs. Otherwise returns the
+ found fd.
+*/
+static int
+FindFreeFD( int MinFd )
+{
+ struct __filedes *Mfd;
+ int i;
+ int fd = -1;
+
+ Mfd = gMD->fdarray;
+
+ // Get an available fd
+ for(i=MinFd; i < OPEN_MAX; ++i) {
+ if(Mfd[i].State == 0) {
+ Mfd[i].State = S_ISYSTEM; // Temporarily mark this fd as reserved
+ fd = i;
+ break;
+ }
+ }
+ return fd;
+}
+
+/** The isatty() function tests whether fildes, an open file descriptor,
+ is associated with a terminal device.
+
+ @retval 1 fildes is associated with a terminal.
+ @retval 0 fildes is not associated with a terminal. errno is set to
+ EBADF if fildes is not a valid open FD.
+**/
+int
+isatty (int fildes)
+{
+ int retval = 0;
+ EFI_FILE_HANDLE FileHandle;
+
+ if(ValidateFD( fildes, VALID_OPEN)) {
+ FileHandle = gMD->fdarray[fildes].FileHandle;
+ retval = (FileHandle >= &gMD->StdIo[0].Abstraction) &&
+ (FileHandle <= &gMD->StdIo[2].Abstraction);
+ }
+ else {
+ errno = EBADF;
+ }
+ return retval;
+}
+
+static BOOLEAN
+IsDupFd( int fd)
+{
+ EFI_FILE_HANDLE FileHandle;
+ int i;
+ BOOLEAN Ret = FALSE;
+
+ if(ValidateFD( fd, VALID_OPEN )) {
+ FileHandle = gMD->fdarray[fd].FileHandle;
+ for(i=0; i < OPEN_MAX; ++i) {
+ if(i == fd) continue;
+ if(gMD->fdarray[i].State != 0) { // TRUE if fd is OPEN
+ if(gMD->fdarray[i].FileHandle == FileHandle) {
+ Ret = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ return Ret;
+}
+
+static int
+_closeX (int fd, int NewState)
+{
+ struct __filedes *Mfd;
+ RETURN_STATUS Status;
+ int retval = 0;
+
+ Status = EFIerrno = RETURN_SUCCESS; // In case of error before the EFI call.
+
+ // Verify my pointers and get my FD.
+ if(ValidateFD( fd, VALID_OPEN )) {
+ Mfd = &gMD->fdarray[fd];
+ // Check if there are duplicates using this FileHandle
+ if(! IsDupFd(fd)) {
+ // Only do the close if no one else is using the FileHandle
+ if(isatty(fd)) {
+ Status = Mfd->FileHandle->Close( Mfd->FileHandle);
+ }
+ else {
+ Status = ShellCloseFile( (SHELL_FILE_HANDLE *)&Mfd->FileHandle);
+ }
+ }
+ Mfd->State = NewState; // Close this FD or reserve it
+ if(Status != RETURN_SUCCESS) {
+ errno = EFI2errno(Status);
+ EFIerrno = Status;
+ retval = -1;
+ }
+ }
+ else {
+ // Bad FD
+ errno = EBADF;
+ retval = -1;
+ }
+ return retval;
+}
+
+/** The close() function shall deallocate the file descriptor indicated by fd.
+ To deallocate means to make the file descriptor available for return by
+ subsequent calls to open() or other functions that allocate file
+ descriptors. All outstanding record locks owned by the process on the file
+ associated with the file descriptor shall be removed (that is, unlocked).
+
+ @return Upon successful completion, 0 shall be returned; otherwise,
+ -1 shall be returned and errno set to indicate the error.
+**/
+int
+close (int fd)
+{
+ //Print(L"Closing fd %d\n", fd);
+ return _closeX(fd, 0);
+}
+
+/* Wide character version of unlink */
+int
+Uunlink (const wchar_t *Path)
+{
+ EFI_FILE_HANDLE FileHandle;
+ RETURN_STATUS Status;
+
+ EFIerrno = RETURN_SUCCESS;
+
+ NormalizePath( Path);
+ // We can only delete open files.
+ Status = ShellOpenFileByName( Path, (SHELL_FILE_HANDLE *)&FileHandle, 3, 0);
+ if(Status != RETURN_SUCCESS) {
+ errno = EFI2errno(Status);
+ EFIerrno = Status;
+ return -1;
+ }
+ Status = ShellDeleteFile( (SHELL_FILE_HANDLE *)&FileHandle);
+ if(Status != RETURN_SUCCESS) {
+ errno = EFI2errno(Status);
+ EFIerrno = Status;
+ return -1;
+ }
+ return 0;
+}
+
+/**
+**/
+int
+unlink (const char *path)
+{
+ // Convert path from MBCS to WCS
+ (void)AsciiStrToUnicodeStr( path, gMD->UString);
+
+ return Uunlink(gMD->UString);
+}
+
+/** The fcntl() function shall perform the operations described below on open
+ files. The fildes argument is a file descriptor.
+
+ The available values for cmd are defined in <fcntl.h> and are as follows:
+ - F_DUPFD - Return a new file descriptor which shall be the lowest
+ numbered available (that is, not already open) file
+ descriptor greater than or equal to the third argument, arg,
+ taken as an integer of type int. The new file descriptor
+ shall refer to the same open file description as the original
+ file descriptor, and shall share any locks. The FD_CLOEXEC
+ flag associated with the new file descriptor shall be cleared
+ to keep the file open across calls to one of the exec functions.
+ - F_GETFD - Get the file descriptor flags defined in <fcntl.h> that are
+ associated with the file descriptor fildes. File descriptor
+ flags are associated with a single file descriptor and do not
+ affect other file descriptors that refer to the same file.
+ - F_SETFD - Set the file descriptor flags defined in <fcntl.h>, that are
+ associated with fildes, to the third argument, arg, taken
+ as type int. If the FD_CLOEXEC flag in the third argument
+ is 0, the file shall remain open across the exec
+ functions; otherwise, the file shall be closed upon
+ successful execution of one of the exec functions.
+ - F_GETFL - Get the file status flags and file access modes, defined in
+ <fcntl.h>, for the file description associated with fildes.
+ The file access modes can be extracted from the return
+ value using the mask O_ACCMODE, which is defined in
+ <fcntl.h>. File status flags and file access modes are
+ associated with the file description and do not affect
+ other file descriptors that refer to the same file with
+ different open file descriptions.
+ - F_SETFL - Set the file status flags, defined in <fcntl.h>, for the file
+ description associated with fildes from the corresponding
+ bits in the third argument, arg, taken as type int. Bits
+ corresponding to the file access mode and the file creation
+ flags, as defined in <fcntl.h>, that are set in arg shall
+ be ignored. If any bits in arg other than those mentioned
+ here are changed by the application, the result is unspecified.
+ - F_GETOWN - If fildes refers to a socket, get the process or process group
+ ID specified to receive SIGURG signals when out-of-band
+ data is available. Positive values indicate a process ID;
+ negative values, other than -1, indicate a process group
+ ID. If fildes does not refer to a socket, the results are
+ unspecified.
+ - F_SETOWN - If fildes refers to a socket, set the process or process
+ group ID specified to receive SIGURG signals when
+ out-of-band data is available, using the value of the third
+ argument, arg, taken as type int. Positive values indicate
+ a process ID; negative values, other than -1, indicate a
+ process group ID. If fildes does not refer to a socket, the
+ results are unspecified.
+
+ The fcntl() function shall fail if:
+
+ [EBADF] The fildes argument is not a valid open file descriptor.
+ [EINVAL] The cmd argument is invalid, or the cmd argument is F_DUPFD
+ and arg is negative or greater than or equal to {OPEN_MAX}.
+ [EMFILE] The argument cmd is F_DUPFD and {OPEN_MAX} file descriptors
+ are currently open in the calling process, or no file
+ descriptors greater than or equal to arg are available.
+ [EOVERFLOW] One of the values to be returned cannot be represented correctly.
+
+ @return Upon successful completion, the value returned shall depend on
+ cmd as follows:
+ - F_DUPFD - A new file descriptor.
+ - F_GETFD - Value of flags defined in <fcntl.h>. The return value
+ shall not be negative.
+ - F_SETFD - Value other than -1.
+ - F_GETFL - Value of file status flags and access modes. The return
+ value is not negative.
+ - F_SETFL - Value other than -1.
+ - F_GETOWN - Value of the socket owner process or process group;
+ this will not be -1.
+ - F_SETOWN - Value other than -1.
+ Otherwise, -1 shall be returned and errno set to indicate the error.
+
+**/
+int
+fcntl (int fildes, int cmd, ...)
+{
+ va_list p3;
+ struct __filedes *MyFd;
+ int retval = -1;
+ int temp;
+
+//Print(L"%a( %d, %d, ...)\n", __func__, fildes, cmd);
+ va_start(p3, cmd);
+
+ if(ValidateFD( fildes, VALID_OPEN )) {
+ MyFd = &gMD->fdarray[fildes];
+
+ switch(cmd) {
+ case F_DUPFD:
+ temp = va_arg(p3, int);
+ if(ValidateFD( temp, VALID_DONT_CARE )) {
+ temp = FindFreeFD( temp );
+ if(temp < 0) {
+ errno = EMFILE;
+ break;
+ }
+ /* temp is now a valid fd reserved for further use
+ so copy fd into temp.
+ */
+ (void)memcpy(&gMD->fdarray[temp], MyFd, sizeof(struct __filedes));
+ retval = temp;
+ }
+ else {
+ errno = EINVAL;
+ }
+ break;
+ //case F_SETFD:
+ case F_SETFL:
+ retval = MyFd->Oflags; // Get original value
+ temp = va_arg(p3, int);
+ temp &= O_SETMASK; // Only certain bits can be set
+ temp |= retval & O_SETMASK;
+ MyFd->Oflags = temp; // Set new value
+ break;
+ //case F_SETFL:
+ case F_SETFD:
+ retval = MyFd->State;
+ break;
+ case F_SETOWN:
+ retval = MyFd->SocProc;
+ MyFd->SocProc = va_arg(p3, int);
+ break;
+ case F_GETFD:
+ //retval = MyFd->Oflags;
+ retval = MyFd->State;
+ break;
+ case F_GETFL:
+ //retval = MyFd->State;
+ retval = MyFd->Oflags;
+ break;
+ case F_GETOWN:
+ retval = MyFd->SocProc;
+ break;
+ default:
+ errno = EINVAL;
+ break;
+ }
+ }
+ else {
+ // Bad FD
+ errno = EBADF;
+ }
+ va_end(p3);
+ return retval;;
+}
+
+/** The dup() function provides an alternative interface to the
+ service provided by fcntl() using the F_DUPFD command. The call:
+ - fid = dup(fildes);
+ shall be equivalent to:
+ - fid = fcntl(fildes, F_DUPFD, 0);
+
+ @return Upon successful completion a non-negative integer, namely the
+ file descriptor, shall be returned; otherwise, -1 shall be
+ returned and errno set to indicate the error.
+**/
+int
+dup (int fildes)
+{
+ return fcntl(fildes, F_DUPFD, 0);
+}
+
+/** The dup2() function provides an alternative interface to the
+ service provided by fcntl() using the F_DUPFD command. The call:
+ - fid = dup2(fildes, fildes2);
+ shall be equivalent to:
+ - close(fildes2);
+ - fid = fcntl(fildes, F_DUPFD, fildes2);
+ except for the following:
+ - If fildes2 is less than 0 or greater than or equal to {OPEN_MAX},
+ dup2() shall return -1 with errno set to [EBADF].
+ - If fildes is a valid file descriptor and is equal to fildes2, dup2()
+ shall return fildes2 without closing it.
+ - If fildes is not a valid file descriptor, dup2() shall return -1 and
+ shall not close fildes2.
+ - The value returned shall be equal to the value of fildes2 upon
+ successful completion, or -1 upon failure.
+
+ @return Upon successful completion a non-negative integer, namely
+ fildes2, shall be returned; otherwise, -1 shall be
+ returned and errno set to EBADF indicate the error.
+**/
+int
+dup2 (int fildes, int fildes2)
+{
+ int retval = -1;
+
+ if(ValidateFD( fildes, VALID_OPEN)) {
+ retval = fildes2;
+ if( fildes != fildes2) {
+ if(ValidateFD( fildes2, VALID_DONT_CARE)) {
+ gMD->fdarray[fildes2].State = S_ISYSTEM; // Mark the file closed, but reserved
+ (void)memcpy(&gMD->fdarray[fildes2], // Duplicate fildes into fildes2
+ &gMD->fdarray[fildes], sizeof(struct __filedes));
+ }
+ else {
+ errno = EBADF;
+ retval = -1;
+ }
+ }
+ }
+ else {
+ errno = EBADF;
+ }
+ return retval;
+}
+
+/** Reposition a file's read/write offset.
+
+ The lseek() function repositions the offset of the file descriptor fildes
+ to the argument offset according to the directive how. The argument
+ fildes must be an open file descriptor. lseek() repositions the file
+ pointer fildes as follows:
+
+ If how is SEEK_SET, the offset is set to offset bytes.
+
+ If how is SEEK_CUR, the offset is set to its current location
+ plus offset bytes.
+
+ If how is SEEK_END, the offset is set to the size of the file
+ plus offset bytes.
+
+ The lseek() function allows the file offset to be set beyond the end of
+ the existing end-of-file of the file. If data is later written at this
+ point, subsequent reads of the data in the gap return bytes of zeros
+ (until data is actually written into the gap).
+
+ Some devices are incapable of seeking. The value of the pointer associ-
+ ated with such a device is undefined.
+
+ @return Upon successful completion, lseek() returns the resulting offset
+ location as measured in bytes from the beginning of the file.
+ Otherwise, a value of -1 is returned and errno is set to
+ indicate the error.
+**/
+__off_t
+lseek (int fildes, __off_t offset, int how)
+{
+ __off_t CurPos = -1;
+ RETURN_STATUS Status = RETURN_SUCCESS;
+ EFI_FILE_HANDLE FileHandle;
+
+ EFIerrno = RETURN_SUCCESS; // In case of error without an EFI call
+
+ if( how == SEEK_SET || how == SEEK_CUR || how == SEEK_END) {
+ if(ValidateFD( fildes, VALID_OPEN)) {
+ // Both of our parameters have been verified as valid
+ FileHandle = gMD->fdarray[fildes].FileHandle;
+ CurPos = 0;
+ if(isatty(fildes)) {
+ Status = FileHandle->SetPosition( FileHandle, offset);
+ CurPos = offset;
+ }
+ else {
+ if(how != SEEK_SET) {
+ // We are doing a relative seek
+ if(how == SEEK_END) {
+ // seeking relative to EOF, so position there first.
+ Status = ShellSetFilePosition( (SHELL_FILE_HANDLE)FileHandle, 0xFFFFFFFFFFFFFFFFULL);
+ }
+ if(Status == RETURN_SUCCESS) {
+ // Now, determine our current position.
+ Status = ShellGetFilePosition( (SHELL_FILE_HANDLE)FileHandle, (UINT64 *)&CurPos);
+ }
+ }
+ if(Status == RETURN_SUCCESS) {
+ /* CurPos now indicates the point we are seeking from, so seek... */
+ Status = ShellSetFilePosition( (SHELL_FILE_HANDLE)FileHandle, (UINT64)(CurPos + offset));
+ if(Status == RETURN_SUCCESS) {
+ // Now, determine our final position.
+ Status = ShellGetFilePosition( (SHELL_FILE_HANDLE)FileHandle, (UINT64 *)&CurPos);
+ }
+ }
+ if(Status != RETURN_SUCCESS) {
+ EFIerrno = Status;
+ CurPos = -1;
+ if(Status == EFI_UNSUPPORTED) {
+ errno = EISDIR;
+ }
+ else {
+ errno = EFI2errno(Status);
+ }
+ }
+ }
+ }
+ else {
+ errno = EBADF; // Bad File Descriptor
+ }
+ }
+ else {
+ errno = EINVAL; // Invalid how argument
+ }
+ return CurPos;
+}
+
+/** The directory path is created with the access permissions specified by
+ perms.
+
+ The directory is closed after it is created.
+
+ @retval 0 The directory was created successfully.
+ @retval -1 An error occurred and an error code is stored in errno.
+**/
+int
+mkdir (const char *path, __mode_t perms)
+{
+ EFI_FILE_HANDLE FileHandle;
+ RETURN_STATUS Status;
+ EFI_FILE_INFO *FileInfo;
+
+ // Convert name from MBCS to WCS
+ (void)AsciiStrToUnicodeStr( path, gMD->UString);
+ NormalizePath( gMD->UString);
+
+//Print(L"%a( \"%s\", 0x%8X)\n", __func__, gMD->UString, perms);
+ Status = ShellCreateDirectory( gMD->UString, (SHELL_FILE_HANDLE *)&FileHandle);
+ if(Status == RETURN_SUCCESS) {
+ FileInfo = ShellGetFileInfo( FileHandle);
+ if(FileInfo != NULL) {
+ FileInfo->Attribute = Omode2EFI(perms);
+ Status = ShellSetFileInfo( FileHandle, FileInfo);
+ FreePool(FileInfo);
+ if(Status == RETURN_SUCCESS) {
+ (void)ShellCloseFile((SHELL_FILE_HANDLE *)&FileHandle);
+ return 0;
+ }
+ }
+ }
+ errno = EFI2errno(Status);
+ EFIerrno = Status;
+
+ return -1;
+}
+
+/** Open a file.
+
+ The EFI ShellOpenFileByName() function is used to perform the low-level
+ file open operation. The primary task of open() is to translate from the
+ flags used in the <stdio.h> environment to those used by the EFI function.
+
+ The only valid flag combinations for ShellOpenFileByName() are:
+ - Read
+ - Read/Write
+ - Create/Read/Write
+
+ The mode value is saved in the FD to indicate permissions for further operations.
+
+ O_RDONLY -- flags = EFI_FILE_MODE_READ -- this is always done
+ O_WRONLY -- flags |= EFI_FILE_MODE_WRITE
+ O_RDWR -- flags |= EFI_FILE_MODE_WRITE -- READ is already set
+
+ O_NONBLOCK -- ignored
+ O_APPEND -- Seek to EOF before every write
+ O_CREAT -- flags |= EFI_FILE_MODE_CREATE
+ O_TRUNC -- delete first then create new
+ O_EXCL -- if O_CREAT is also set, open will fail if the file already exists.
+**/
+int
+open (const char *name, int oflags, int mode)
+{
+ EFI_FILE_HANDLE FileHandle;
+ struct __filedes *Mfd;
+ RETURN_STATUS Status;
+ UINT64 OpenMode;
+ UINT64 Attributes;
+ int fd = -1;
+ UINT32 NewState;
+
+ EFIerrno = RETURN_SUCCESS;
+ Mfd = gMD->fdarray;
+
+ // Convert name from MBCS to WCS
+ (void)AsciiStrToUnicodeStr( name, gMD->UString);
+ NormalizePath( gMD->UString);
+
+ // Convert oflags to Attributes
+ OpenMode = Oflags2EFI(oflags);
+ if(OpenMode == 0) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ //Attributes = Omode2EFI(mode);
+ Attributes = 0;
+
+ // Could add a test to see if the file name begins with a period.
+ // If it does, then add the HIDDEN flag to Attributes.
+
+ // Get an available fd
+ fd = FindFreeFD( 0 );
+
+ if( fd < 0 ) {
+ // All available FDs are in use
+ errno = EMFILE;
+ return -1;
+ }
+
+ Status = ConOpen( NULL, &FileHandle, gMD->UString, OpenMode, Attributes);
+ if(Status == RETURN_NO_MAPPING) {
+ // Not a console device, how about a regular file device?
+
+ /* Do we care if the file already exists?
+ If O_TRUNC, then delete the file. It will be created anew subsequently.
+ If O_EXCL, then error if the file exists and O_CREAT is set.
+
+ !!!!!!!!! Change this to use ShellSetFileInfo() to actually truncate the file
+ !!!!!!!!! instead of deleting and re-creating it.
+ */
+ if((oflags & O_TRUNC) || ((oflags & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT))) {
+ Status = ShellIsFile( gMD->UString );
+ if(Status == RETURN_SUCCESS) {
+ // The file exists
+ if(oflags & O_TRUNC) {
+ // We do a truncate by deleting the existing file and creating a new one.
+ if(Uunlink(gMD->UString) != 0) {
+ Mfd[fd].State = 0; // Release our reservation on this FD
+ return -1; // errno and EFIerrno are already set.
+ }
+ }
+ else if(oflags & (O_EXCL | O_CREAT)) {
+ errno = EEXIST;
+ EFIerrno = Status;
+ Mfd[fd].State = 0; // Release our reservation on this FD
+ return -1;
+ }
+ }
+ }
+ // Call the EFI Shell's Open function
+ Status = ShellOpenFileByName( gMD->UString, (SHELL_FILE_HANDLE *)&FileHandle, OpenMode, Attributes);
+ if(RETURN_ERROR(Status)) {
+ Mfd[fd].State = 0; // Release our reservation on this FD
+ // Set errno based upon Status
+ errno = EFI2errno(Status);
+ EFIerrno = Status;
+ return -1;
+ }
+ // Successfully got a regular File
+ NewState = S_IFREG;
+ }
+ else if(Status != RETURN_SUCCESS) {
+ // Set errno based upon Status
+ errno = EFI2errno(Status);
+ EFIerrno = Status;
+ return -1;
+ }
+ else {
+ // Succesfully got a Console stream
+ NewState = S_IFREG | _S_ITTY | _S_IFCHR;
+ }
+
+ // Update the info in the fd
+ Mfd[fd].FileHandle = FileHandle;
+ Mfd[fd].Oflags = oflags;
+ Mfd[fd].Omode = mode;
+
+ // Re-use OpenMode in order to build our final State value
+ OpenMode = ( mode & S_ACC_READ ) ? S_ACC_READ : 0;
+ OpenMode |= ( mode & S_ACC_WRITE ) ? S_ACC_WRITE : 0;
+
+ Mfd[fd].State = NewState | (UINT32)OpenMode;
+
+ // return the fd of our now open file
+ return fd;
+}
+
+/** The rename() function changes the name of a file.
+ The old argument points to the pathname of the file to be renamed. The new
+ argument points to the new pathname of the file.
+
+ If the old argument points to the pathname of a file that is not a
+ directory, the new argument shall not point to the pathname of a
+ directory. If the file named by the new argument exists, it shall be
+ removed and old renamed to new. Write access permission is required for
+ both the directory containing old and the directory containing new.
+
+ If the old argument points to the pathname of a directory, the new
+ argument shall not point to the pathname of a file that is not a
+ directory. If the directory named by the new argument exists, it shall be
+ removed and old renamed to new.
+
+ The new pathname shall not contain a path prefix that names old. Write
+ access permission is required for the directory containing old and the
+ directory containing new. If the old argument points to the pathname of a
+ directory, write access permission may be required for the directory named
+ by old, and, if it exists, the directory named by new.
+
+ If the rename() function fails for any reason other than [EIO], any file
+ named by new shall be unaffected.
+
+ @return Upon successful completion, rename() shall return 0; otherwise,
+ -1 shall be returned, errno shall be set to indicate the error,
+ and neither the file named by old nor the file named by new
+ shall be changed or created.
+**/
+int
+rename (const char *old, const char *new)
+{
+ // UINT64 InfoSize;
+ // RETURN_STATUS Status;
+ // EFI_FILE_INFO *NewFileInfo = NULL;
+ // EFI_FILE_INFO *OldFileInfo;
+ // char *Newfn;
+ // int OldFd;
+
+ //// Open old file
+ // OldFd = open(old, O_RDONLY, 0);
+ // if(OldFd >= 0) {
+ // NewFileInfo = malloc(sizeof(EFI_FILE_INFO) + PATH_MAX);
+ // if(NewFileInfo != NULL) {
+ // OldFileInfo = ShellGetFileInfo( FileHandle);
+ // if(OldFileInfo != NULL) {
+ // // Copy the Old file info into our new buffer, and free the old.
+ // memcpy(OldFileInfo, NewFileInfo, sizeof(EFI_FILE_INFO));
+ // FreePool(OldFileInfo);
+ // // Strip off all but the file name portion of new
+ // NewFn = strrchr(new, '/');
+ // if(NewFn == NULL) {
+ // NewFn = strrchr(new '\\');
+ // if(NewFn == NULL) {
+ // NewFn = new;
+ // }
+ // }
+ // // Convert new name from MBCS to WCS
+ // (void)AsciiStrToUnicodeStr( NewFn, gMD->UString);
+ // // Copy the new file name into our new file info buffer
+ // wcsncpy(NewFileInfo->FileName, gMD->UString, wcslen(gMD->UString)+1);
+ // // Apply the new file name
+ // Status = ShellSetFileInfo(FileHandle);
+ // if(Status == EFI_SUCCESS) {
+ // // File has been successfully renamed. We are DONE!
+ // return 0;
+ // }
+ // errno = EFI2errno( Status );
+ // EFIerrno = Status;
+ // }
+ // else {
+ // errno = EIO;
+ // }
+ // }
+ // else {
+ // errno = ENOMEM;
+ // }
+ // }
+ return -1;
+}
+
+/**
+**/
+int
+rmdir (const char *path)
+{
+ EFI_FILE_HANDLE FileHandle;
+ RETURN_STATUS Status;
+ EFI_FILE_INFO *FileInfo = NULL;
+ int Count = 0;
+ BOOLEAN NoFile = FALSE;
+
+ errno = 0; // Make it easier to see if we have an error later
+
+ // Convert name from MBCS to WCS
+ (void)AsciiStrToUnicodeStr( path, gMD->UString);
+ NormalizePath( gMD->UString);
+
+//Print(L"%a( \"%s\")\n", __func__, gMD->UString);
+ Status = ShellOpenFileByName( gMD->UString, (SHELL_FILE_HANDLE *)&FileHandle,
+ (EFI_FILE_MODE_READ || EFI_FILE_MODE_WRITE), 0);
+ if(Status == RETURN_SUCCESS) {
+ FileInfo = ShellGetFileInfo( (SHELL_FILE_HANDLE)FileHandle);
+ if(FileInfo != NULL) {
+ if((FileInfo->Attribute & EFI_FILE_DIRECTORY) == 0) {
+ errno = ENOTDIR;
+ }
+ else {
+ // See if the directory has any entries other than ".." and ".".
+ FreePool(FileInfo); // Free up the buffer from ShellGetFileInfo()
+ Status = ShellFindFirstFile( (SHELL_FILE_HANDLE)FileHandle, &FileInfo);
+ if(Status == RETURN_SUCCESS) {
+ ++Count;
+ while(Count < 3) {
+ Status = ShellFindNextFile( (SHELL_FILE_HANDLE)FileHandle, FileInfo, &NoFile);
+ if(Status == RETURN_SUCCESS) {
+ if(NoFile) {
+ break;
+ }
+ ++Count;
+ }
+ else {
+ Count = 99;
+ }
+ }
+ FreePool(FileInfo); // Free buffer from ShellFindFirstFile()
+ if(Count < 3) {
+ // Directory is empty
+ Status = ShellDeleteFile( (SHELL_FILE_HANDLE *)&FileHandle);
+ if(Status == RETURN_SUCCESS) {
+ EFIerrno = RETURN_SUCCESS;
+ return 0;
+ /* ######## SUCCESSFUL RETURN ######## */
+ }
+ }
+ else {
+ if(Count == 99) {
+ errno = EIO;
+ }
+ else {
+ errno = ENOTEMPTY;
+ }
+ }
+ }
+ }
+ }
+ else {
+ errno = EIO;
+ }
+ }
+ EFIerrno = Status;
+ if(errno == 0) {
+ errno = EFI2errno( Status );
+ }
+ return -1;
+}
+
+/* Internal File Info. worker function for stat and fstat. */
+static
+EFI_STATUS
+_EFI_FileInfo( EFI_FILE_INFO *FileInfo, struct stat *statbuf)
+{
+ UINT64 Attributes;
+ RETURN_STATUS Status;
+ mode_t newmode;
+
+ if(FileInfo != NULL) {
+ // Got the info, now populate statbuf with it
+ statbuf->st_blksize = S_BLKSIZE;
+ statbuf->st_size = FileInfo->Size;
+ statbuf->st_physsize = FileInfo->PhysicalSize;
+ statbuf->st_birthtime = Efi2Time( &FileInfo->CreateTime);
+ statbuf->st_atime = Efi2Time( &FileInfo->LastAccessTime);
+ statbuf->st_mtime = Efi2Time( &FileInfo->ModificationTime);
+ Attributes = FileInfo->Attribute;
+ newmode = (mode_t)(Attributes << S_EFISHIFT) | S_ACC_READ;
+ if((Attributes & EFI_FILE_DIRECTORY) == 0) {
+ newmode |= _S_IFREG;
+ if((Attributes & EFI_FILE_READ_ONLY) == 0) {
+ statbuf->st_mode |= S_ACC_WRITE;
+ }
+ }
+ else {
+ newmode |= _S_IFDIR;
+ }
+ statbuf->st_mode = newmode;
+ Status = RETURN_SUCCESS;
+ }
+ else {
+ Status = RETURN_DEVICE_ERROR;
+ }
+ return Status;
+}
+
+/** The fstat() function obtains information about an open file associated
+ with the file descriptor fildes, and shall write it to the area pointed to
+ by buf.
+
+ The buf argument is a pointer to a stat structure, as defined
+ in <sys/stat.h>, into which information is placed concerning the file.
+
+ The structure members st_mode, st_ino, st_dev, st_uid, st_gid, st_atime,
+ st_ctime, and st_mtime shall have meaningful values. The value of the
+ member st_nlink shall be set to the number of links to the file.
+
+ The fstat() function shall update any time-related fields before writing
+ into the stat structure.
+
+ The fstat() function is implemented using the ShellGetFileInfo()
+ function.
+
+ The stat structure members which don't have direct analogs to EFI file
+ information are filled in as follows:
+ - st_mode Populated with information from fildes
+ - st_ino Set to zero. (inode)
+ - st_dev Set to zero.
+ - st_uid Set to zero.
+ - st_gid Set to zero.
+ - st_nlink Set to one.
+
+ @param[in] fildes File descriptor as returned from open().
+ @param[out] statbuf Buffer in which the file status is put.
+
+ @retval 0 Successful Completion.
+ @retval -1 An error has occurred and errno has been set to
+ identify the error.
+**/
+int
+fstat (int fildes, struct stat *statbuf)
+{
+ EFI_FILE_HANDLE FileHandle;
+ RETURN_STATUS Status = RETURN_SUCCESS;
+ EFI_FILE_INFO *FileInfo = NULL;
+ UINTN FinfoSize = sizeof(EFI_FILE_INFO);
+
+ if(ValidateFD( fildes, VALID_OPEN)) {
+ FileHandle = gMD->fdarray[fildes].FileHandle;
+ if(isatty(fildes)) {
+ FileInfo = AllocateZeroPool(FinfoSize);
+ if(FileInfo != NULL) {
+ Status = FileHandle->GetInfo( FileHandle, 0, &FinfoSize, FileInfo);
+ }
+ else {
+ Status = RETURN_OUT_OF_RESOURCES;
+ }
+ }
+ else {
+ FileInfo = ShellGetFileInfo( FileHandle);
+ }
+ Status = _EFI_FileInfo( FileInfo, statbuf);
+ }
+ errno = EFI2errno(Status);
+ EFIerrno = Status;
+
+ if(FileInfo != NULL) {
+ FreePool(FileInfo); // Release the buffer allocated by the GetInfo function
+ }
+
+ return errno? -1 : 0;
+}
+
+/** Obtains information about the file pointed to by path.
+
+ Opens the file pointed to by path, calls _EFI_FileInfo with the file's handle,
+ then closes the file.
+
+ @retval 0 Successful Completion.
+ @retval -1 An error has occurred and errno has been set to
+ identify the error.
+**/
+int
+stat (const char *path, void *statbuf)
+{
+ EFI_FILE_HANDLE FileHandle;
+ RETURN_STATUS Status;
+ EFI_FILE_INFO *FileInfo;
+
+ errno = 0; // Make it easier to see if we have an error later
+
+ // Convert name from MBCS to WCS
+ (void)AsciiStrToUnicodeStr( path, gMD->UString);
+ NormalizePath( gMD->UString);
+
+ Status = ShellOpenFileByName( gMD->UString, (SHELL_FILE_HANDLE *)&FileHandle, EFI_FILE_MODE_READ, 0ULL);
+ if(Status == RETURN_SUCCESS) {
+ FileInfo = ShellGetFileInfo( FileHandle);
+ Status = _EFI_FileInfo( FileInfo, (struct stat *)statbuf);
+ (void)ShellCloseFile( (SHELL_FILE_HANDLE *)&FileHandle);
+ }
+ errno = EFI2errno(Status);
+ EFIerrno = Status;
+
+ return errno? -1 : 0;
+}
+
+/** Same as stat since EFI doesn't have symbolic links. **/
+int
+lstat (const char *path, struct stat *statbuf)
+{
+ return stat(path, statbuf);
+}
+
+/** Read from a file.
+
+ The read() function shall attempt to read nbyte bytes from the file
+ associated with the open file descriptor, fildes, into the buffer pointed
+ to by buf.
+
+ Before any action described below is taken, and if nbyte is zero, the
+ read() function may detect and return errors as described below. In the
+ absence of errors, or if error detection is not performed, the read()
+ function shall return zero and have no other results.
+
+ On files that support seeking (for example, a regular file), the read()
+ shall start at a position in the file given by the file offset associated
+ with fildes. The file offset shall be incremented by the number of bytes
+ actually read.
+
+ Files that do not support seeking - for example, terminals - always read
+ from the current position. The value of a file offset associated with
+ such a file is undefined.
+
+ No data transfer shall occur past the current end-of-file. If the
+ starting position is at or after the end-of-file, 0 shall be returned.
+
+ The read() function reads data previously written to a file. If any
+ portion of a regular file prior to the end-of-file has not been written,
+ read() shall return bytes with value 0. For example, lseek() allows the
+ file offset to be set beyond the end of existing data in the file. If data
+ is later written at this point, subsequent reads in the gap between the
+ previous end of data and the newly written data shall return bytes with
+ value 0 until data is written into the gap.
+
+ Upon successful completion, where nbyte is greater than 0, read() shall
+ mark for update the st_atime field of the file, and shall return the
+ number of bytes read. This number shall never be greater than nbyte. The
+ value returned may be less than nbyte if the number of bytes left in the
+ file is less than nbyte, if the read() request was interrupted by a
+ signal, or if the file is a pipe or FIFO or special file and has fewer
+ than nbyte bytes immediately available for reading. For example, a read()
+ from a file associated with a terminal may return one typed line of data.
+
+ If fildes does not refer to a directory, the function reads the requested
+ number of bytes from the file at the file’s current position and returns
+ them in buf. If the read goes beyond the end of the file, the read
+ length is truncated to the end of the file. The file’s current position is
+ increased by the number of bytes returned.
+
+ If fildes refers to a directory, the function reads the directory entry at
+ the file’s current position and returns the entry in buf. If buf
+ is not large enough to hold the current directory entry, then
+ errno is set to EBUFSIZE, EFIerrno is set to EFI_BUFFER_TOO_SMALL, and the
+ current file position is not updated. The size of the buffer needed to read
+ the entry will be returned as a negative number. On success, the current
+ position is updated to the next directory entry. If there are no more
+ directory entries, the read returns a zero-length buffer.
+ EFI_FILE_INFO is the structure returned as the directory entry.
+
+ @return Upon successful completion, read() returns a non-negative integer
+ indicating the number of bytes actually read. Otherwise, the
+ functions return a negative value and sets errno to indicate the
+ error. If errno is EBUFSIZE, the absolute value of the
+ return value indicates the size of the buffer needed to read
+ the directory entry.
+**/
+ssize_t
+read (int fildes, void *buf, size_t nbyte)
+{
+ ssize_t BufSize;
+ EFI_FILE_HANDLE FileHandle;
+ RETURN_STATUS Status;
+
+ BufSize = (ssize_t)nbyte;
+ if(ValidateFD( fildes, VALID_OPEN)) {
+ FileHandle = gMD->fdarray[fildes].FileHandle;
+ if(isatty(fildes)) {
+ Status = FileHandle->Read( FileHandle, (UINTN *)&BufSize, buf);
+ }
+ else {
+ Status = ShellReadFile( FileHandle, (UINTN *)&BufSize, buf);
+ }
+ if(Status != RETURN_SUCCESS) {
+ EFIerrno = Status;
+ errno = EFI2errno(Status);
+ if(Status == RETURN_BUFFER_TOO_SMALL) {
+ BufSize = -BufSize;
+ }
+ else {
+ BufSize = -1;
+ }
+ }
+ }
+ else {
+ errno = EBADF;
+ }
+ return BufSize;
+}
+
+ssize_t
+WideTtyCvt( CHAR16 *dest, const char *buf, size_t n)
+{
+ UINTN i;
+ wint_t wc;
+
+ for(i = 0; i < n; ++i) {
+ wc = btowc(*buf++);
+ if( wc == 0) {
+ break;
+ };
+ if(wc < 0) {
+ wc = BLOCKELEMENT_LIGHT_SHADE;
+ }
+ if(wc == L'\n') {
+ *dest++ = L'\r';
+ }
+ *dest++ = (CHAR16)wc;
+ }
+ *dest = 0;
+ return (ssize_t)i;
+}
+
+/** Write data to a file.
+
+ This function writes the specified number of bytes to the file at the current
+ file position. The current file position is advanced the actual number of bytes
+ written, which is returned in BufferSize. Partial writes only occur when there
+ has been a data error during the write attempt (such as "volume space full").
+ The file is automatically grown to hold the data if required. Direct writes to
+ opened directories are not supported.
+
+ If fildes refers to a terminal device, isatty() returns TRUE, a partial write
+ will occur if a NULL or EOF character is encountered before n characters have
+ been written. Characters inserted due to line-end translations will not be
+ counted. Unconvertable characters are translated into the UEFI character
+ BLOCKELEMENT_LIGHT_SHADE.
+
+ Since the UEFI console device works on wide characters, the buffer is assumed
+ to contain a single-byte character stream which is then translated to wide
+ characters using the btowc() functions. The resulting wide character stream
+ is what is actually sent to the UEFI console.
+
+ QUESTION: Should writes to stdout or stderr always succeed?
+**/
+ssize_t
+write (int fildes, const void *buf, size_t n)
+{
+ ssize_t BufSize;
+ EFI_FILE_HANDLE FileHandle;
+ RETURN_STATUS Status = RETURN_SUCCESS;
+ ssize_t UniBufSz;
+
+ BufSize = (ssize_t)n;
+
+ if(ValidateFD( fildes, VALID_OPEN)) {
+ FileHandle = gMD->fdarray[fildes].FileHandle;
+ if(isatty(fildes)) {
+ // Convert string from MBCS to WCS and translate \n to \r\n.
+ UniBufSz = WideTtyCvt(gMD->UString, (const char *)buf, n);
+ if(UniBufSz > 0) {
+ BufSize = (ssize_t)(UniBufSz * sizeof(CHAR16));
+ Status = FileHandle->Write( FileHandle, (UINTN *)&BufSize, (void *)gMD->UString);
+ BufSize = (ssize_t)n; // Always pretend all was output
+ }
+ }
+ else {
+ Status = ShellWriteFile( FileHandle, (UINTN *)&BufSize, (void *)buf);
+ }
+ if(Status != RETURN_SUCCESS) {
+ EFIerrno = Status;
+ errno = EFI2errno(Status);
+ if(Status == EFI_UNSUPPORTED) {
+ errno = EISDIR;
+ }
+ BufSize = -1;
+ }
+ }
+ else {
+ errno = EBADF;
+ }
+ return BufSize;
+}
diff --git a/StdLib/LibC/Uefi/SysEfi.h b/StdLib/LibC/Uefi/SysEfi.h
new file mode 100644
index 0000000000..fa9dc38cdd
--- /dev/null
+++ b/StdLib/LibC/Uefi/SysEfi.h
@@ -0,0 +1,37 @@
+/** @file
+ Declarations local to the Uefi SysCalls module of the Standard C Library.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#ifndef _SYSEFI_H
+#define _SYSEFI_H
+#include <Protocol/SimpleFileSystem.h>
+
+#define EFI_FILE_MODE_MASK ( EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE )
+#define OMODE_MASK 0xFFFF00UL
+#define OMODE_SHIFT 8
+
+#define S_ACC_READ ( S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | S_IXGRP | S_IXOTH )
+#define S_ACC_WRITE ( S_IWUSR | S_IWGRP | S_IWOTH )
+#define S_ACC_MASK ( S_IRWXU | S_IRWXG | S_IRWXO )
+
+UINT64
+Oflags2EFI( int oflags);
+
+UINT64
+Omode2EFI( int mode);
+
+/* Converts the first several EFI status values into the appropriate errno value.
+*/
+int
+EFI2errno( RETURN_STATUS Status);
+
+#endif /* _SYSEFI_H */
diff --git a/StdLib/LibC/Uefi/Uefi.inf b/StdLib/LibC/Uefi/Uefi.inf
new file mode 100644
index 0000000000..ca6437abe0
--- /dev/null
+++ b/StdLib/LibC/Uefi/Uefi.inf
@@ -0,0 +1,49 @@
+## @file
+# Standard C library: UEFI "system calls".
+#
+# Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = LibUefi
+ FILE_GUID = 39356e02-26bf-4cfb-9564-378ce25e702f
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = LibUefi
+
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[Sources]
+ SysCalls.c
+ Xform.c
+ Console.c
+
+[Packages]
+ StdLib/StdLib.dec
+ StdLibPrivateInternalFiles/DoNotUse.dec
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+
+[LibraryClasses]
+ UefiLib
+ BaseLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ ShellLib
+ LibC
+ LibLocale
+ LibString
+ LibTime
diff --git a/StdLib/LibC/Uefi/Xform.c b/StdLib/LibC/Uefi/Xform.c
new file mode 100644
index 0000000000..21eff6fb9d
--- /dev/null
+++ b/StdLib/LibC/Uefi/Xform.c
@@ -0,0 +1,173 @@
+/** @file
+ Value transformations between stdio and the UEFI environment.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#include <Uefi.h>
+
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include "SysEfi.h"
+
+/** Translate the Open flags into a Uefi Open Modes value.
+
+ The Open Flags are:
+ O_RDONLY, O_WRONLY, O_RDWR // Pick only one
+
+ O_NONBLOCK, O_APPEND, O_CREAT, O_TRUNC, O_EXCL // ORed with one of the previous
+
+ The UEFI Open modes are:
+ // ******************************************************
+ // Open Modes
+ // ******************************************************
+ #define EFI_FILE_MODE_READ 0x0000000000000001
+ #define EFI_FILE_MODE_WRITE 0x0000000000000002
+ #define EFI_FILE_MODE_CREATE 0x8000000000000000
+
+
+*/
+UINT64
+Oflags2EFI( int oflags )
+{
+ UINT64 flags;
+
+ // Build the Open Modes
+ flags = (UINT64)((oflags & O_ACCMODE) + 1); // Handle the Read/Write flags
+ if(oflags & (O_CREAT | O_TRUNC)) { // Now add the Create flag.
+ // Also added if O_TRUNC set since we will need to create a new file.
+ // We just set the flags here since the only valid EFI mode with create
+ // is Read+Write+Create.
+ flags = EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE;
+ }
+ return flags;
+}
+
+/* Transform the permissions flags from the open() call into the
+ Attributes bits needed by UEFI.
+
+ The UEFI File attributes are:
+ // ******************************************************
+ // File Attributes
+ // ******************************************************
+ #define EFI_FILE_READ_ONLY 0x0000000000000001
+ #define EFI_FILE_HIDDEN 0x0000000000000002
+ #define EFI_FILE_SYSTEM 0x0000000000000004
+ #define EFI_FILE_RESERVED 0x0000000000000008
+ #define EFI_FILE_DIRECTORY 0x0000000000000010
+ #define EFI_FILE_ARCHIVE 0x0000000000000020
+ #define EFI_FILE_VALID_ATTR 0x0000000000000037
+
+ The input permission flags consist of two groups:
+ ( S_IRUSR | S_IRGRP | S_IROTH ) -- S_ACC_READ
+ ( S_IWUSR | S_IWGRP | S_IWOTH ) -- S_ACC_WRITE
+
+ The only thing we can set, at this point, is whether or not
+ this is a SYSTEM file. If the group and other bits are
+ zero and the user bits are non-zero then set SYSTEM. Otherwise
+ the attributes are zero.
+
+ The attributes can be set later using fcntl().
+*/
+UINT64
+Omode2EFI( int mode)
+{
+ UINT64 flags = 0;
+
+ if((mode & (S_IRWXG | S_IRWXO)) == 0) {
+ if((mode & S_IRWXU) != 0) {
+ // Only user permissions so set system
+ flags = EFI_FILE_SYSTEM;
+ }
+ }
+ return flags;
+}
+
+/* Converts the first several EFI status values into the appropriate errno value.
+*/
+int
+EFI2errno( RETURN_STATUS Status)
+{
+ int retval;
+
+ switch(Status) {
+ case RETURN_SUCCESS:
+ retval = 0;
+ break;
+ case RETURN_INVALID_PARAMETER:
+ retval = EINVAL;
+ break;
+ case RETURN_UNSUPPORTED:
+ retval = ENODEV;
+ break;
+ case RETURN_BAD_BUFFER_SIZE:
+ case RETURN_BUFFER_TOO_SMALL:
+ retval = EBUFSIZE;
+ break;
+ case RETURN_NOT_READY:
+ retval = EBUSY;
+ break;
+ case RETURN_WRITE_PROTECTED:
+ retval = EROFS;
+ break;
+ case RETURN_OUT_OF_RESOURCES: // May be overridden by specific functions
+ retval = ENOMEM;
+ break;
+ case RETURN_VOLUME_FULL:
+ retval = ENOSPC;
+ break;
+ case RETURN_NOT_FOUND:
+ case RETURN_NO_MAPPING:
+ retval = ENOENT;
+ break;
+ case RETURN_TIMEOUT:
+ retval = ETIMEDOUT;
+ break;
+ case RETURN_NOT_STARTED:
+ retval = EAGAIN;
+ break;
+ case RETURN_ALREADY_STARTED:
+ retval = EALREADY;
+ break;
+ case RETURN_ABORTED:
+ retval = EINTR;
+ break;
+ case RETURN_ICMP_ERROR:
+ case RETURN_TFTP_ERROR:
+ case RETURN_PROTOCOL_ERROR:
+ retval = EPROTO;
+ break;
+ case RETURN_INCOMPATIBLE_VERSION:
+ retval = EPERM;
+ break;
+ case RETURN_ACCESS_DENIED:
+ case RETURN_SECURITY_VIOLATION:
+ retval = EACCES;
+ break;
+/* case RETURN_LOAD_ERROR:
+ case RETURN_DEVICE_ERROR:
+ case RETURN_VOLUME_CORRUPTED:
+ case RETURN_NO_MEDIA:
+ case RETURN_MEDIA_CHANGED:
+ case RETURN_NO_RESPONSE:
+ case RETURN_CRC_ERROR:
+ case RETURN_END_OF_MEDIA:
+ case RETURN_END_OF_FILE:
+ case RETURN_INVALID_LANGUAGE:
+*/
+ default:
+ retval = EIO;
+ break;
+ }
+ return retval;
+}
diff --git a/StdLib/LibC/Wchar/Comparison.c b/StdLib/LibC/Wchar/Comparison.c
new file mode 100644
index 0000000000..17244b4ccb
--- /dev/null
+++ b/StdLib/LibC/Wchar/Comparison.c
@@ -0,0 +1,97 @@
+/** @file
+ Comparison Functions for <wchar.h>.
+
+ Unless explicitly stated otherwise, the functions defined in this file order
+ two wide characters the same way as two integers of the underlying integer
+ type designated by wchar_t.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include <LibConfig.h>
+
+#include <wchar.h>
+
+/** The wcscmp function compares the wide string pointed to by s1 to the wide
+ string pointed to by s2.
+
+ @return The wcscmp function returns an integer greater than, equal to, or
+ less than zero, accordingly as the wide string pointed to by s1
+ is greater than, equal to, or less than the wide string
+ pointed to by s2.
+**/
+int wcscmp(const wchar_t *s1, const wchar_t *s2)
+{
+ return (int)StrCmp( (CONST CHAR16 *)s1, (CONST CHAR16 *)s2);
+}
+
+/** The wcscoll function compares the wide string pointed to by s1 to the wide
+ string pointed to by s2, both interpreted as appropriate to the LC_COLLATE
+ category of the current locale.
+
+ @return The wcscoll function returns an integer greater than, equal to,
+ or less than zero, accordingly as the wide string pointed to by
+ s1 is greater than, equal to, or less than the wide string
+ pointed to by s2 when both are interpreted as appropriate to
+ the current locale.
+**/
+//int wcscoll(const wchar_t *s1, const wchar_t *s2)
+//{
+// return -1; // STUBB
+//}
+
+/** The wcsncmp function compares not more than n wide characters (those that
+ follow a null wide character are not compared) from the array pointed to by
+ s1 to the array pointed to by s2.
+
+ @return The wcsncmp function returns an integer greater than, equal to,
+ or less than zero, accordingly as the possibly null-terminated
+ array pointed to by s1 is greater than, equal to, or less than
+ the possibly null-terminated array pointed to by s2.
+**/
+int wcsncmp(const wchar_t *s1, const wchar_t *s2, size_t n)
+{
+ return (int)StrnCmp( (CONST CHAR16 *)s1, (CONST CHAR16 *)s2, (UINTN)n);
+}
+
+/** The wcsxfrm function transforms the wide string pointed to by s2 and places
+ the resulting wide string into the array pointed to by s1. The
+ transformation is such that if the wcscmp function is applied to two
+ transformed wide strings, it returns a value greater than, equal to, or
+ less than zero, corresponding to the result of the wcscoll function applied
+ to the same two original wide strings. No more than n wide characters are
+ placed into the resulting array pointed to by s1, including the terminating
+ null wide character. If n is zero, s1 is permitted to be a null pointer.
+
+ @return The wcsxfrm function returns the length of the transformed wide
+ string (not including the terminating null wide character). If
+ the value returned is n or greater, the contents of the array
+ pointed to by s1 are indeterminate.
+**/
+//size_t wcsxfrm(wchar_t * __restrict s1, const wchar_t * __restrict s2, size_t n)
+//{
+// return n; // STUBB
+//}
+
+/** The wmemcmp function compares the first n wide characters of the object
+ pointed to by s1 to the first n wide characters of the object pointed to
+ by s2.
+
+ @return The wmemcmp function returns an integer greater than, equal to,
+ or less than zero, accordingly as the object pointed to by s1 is
+ greater than, equal to, or less than the object pointed to by s2.
+**/
+int wmemcmp(const wchar_t *s1, const wchar_t *s2, size_t n)
+{
+ return (int)CompareMem( s1, s2, (UINTN)(n * sizeof(wchar_t)));
+}
diff --git a/StdLib/LibC/Wchar/Concatenation.c b/StdLib/LibC/Wchar/Concatenation.c
new file mode 100644
index 0000000000..cf595a461f
--- /dev/null
+++ b/StdLib/LibC/Wchar/Concatenation.c
@@ -0,0 +1,48 @@
+/** @file
+ Concatenation Functions for <wchar.h>.
+
+ Unless explicitly stated otherwise, if the execution of a function declared
+ in this file causes copying to take place between objects that overlap, the
+ behavior is undefined.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include <LibConfig.h>
+
+#include <wchar.h>
+
+/** The wcscat function appends a copy of the wide string pointed to by s2
+ (including the terminating null wide character) to the end of the wide
+ string pointed to by s1. The initial wide character of s2 overwrites the
+ null wide character at the end of s1.
+
+ @return The wcscat function returns the value of s1.
+**/
+wchar_t *wcscat(wchar_t * __restrict s1, const wchar_t * __restrict s2)
+{
+ return (wchar_t *)StrCat( (CHAR16 *)s1, (CONST CHAR16 *)s2);
+}
+
+/** The wcsncat function appends not more than n wide characters (a null wide
+ character and those that follow it are not appended) from the array pointed
+ to by s2 to the end of the wide string pointed to by s1. The initial wide
+ character of s2 overwrites the null wide character at the end of s1.
+ A terminating null wide character is always appended to the result.
+
+ @return The wcsncat function returns the value of s1.
+**/
+wchar_t *wcsncat(wchar_t * __restrict s1, const wchar_t * __restrict s2, size_t n)
+{
+ return (wchar_t *)StrnCat( (CHAR16 *)s1, (CONST CHAR16 *)s2, (UINTN)n);
+}
diff --git a/StdLib/LibC/Wchar/ConsDecons.c b/StdLib/LibC/Wchar/ConsDecons.c
new file mode 100644
index 0000000000..ab139405fc
--- /dev/null
+++ b/StdLib/LibC/Wchar/ConsDecons.c
@@ -0,0 +1,64 @@
+/** @file
+ Constructor and Deconstructor functions for <wchar.h>.
+
+ Unless explicitly stated otherwise, the functions defined in this file order
+ two wide characters the same way as two integers of the underlying integer
+ type designated by wchar_t.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <LibConfig.h>
+
+#include <errno.h>
+#include <wchar.h>
+
+/* Data initialized by the library constructor */
+UINT8 *__wchar_bitmap = NULL;
+UINTN __wchar_bitmap_size;
+UINTN __wchar_bitmap_64;
+
+EFI_STATUS
+EFIAPI
+__wchar_construct(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ if( __wchar_bitmap == NULL) {
+ __wchar_bitmap_size = (WCHAR_MAX + 8) / 8U;
+ __wchar_bitmap = AllocatePool(__wchar_bitmap_size);
+ if( __wchar_bitmap == NULL) {
+ EFIerrno = RETURN_OUT_OF_RESOURCES;
+ errno = ENOMEM;
+ return EFIerrno;
+ }
+ return RETURN_SUCCESS;
+ }
+ return RETURN_ALREADY_STARTED;
+}
+
+EFI_STATUS
+EFIAPI
+__wchar_deconstruct(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ if( __wchar_bitmap != NULL) {
+ FreePool( __wchar_bitmap);
+ __wchar_bitmap = NULL;
+ }
+ return RETURN_SUCCESS;
+}
diff --git a/StdLib/LibC/Wchar/Copying.c b/StdLib/LibC/Wchar/Copying.c
new file mode 100644
index 0000000000..7075437965
--- /dev/null
+++ b/StdLib/LibC/Wchar/Copying.c
@@ -0,0 +1,80 @@
+/** @file
+ Copying Functions for <wchar.h>.
+
+ Unless explicitly stated otherwise, if the execution of a function declared
+ in this file causes copying to take place between objects that overlap, the
+ behavior is undefined.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include <LibConfig.h>
+
+#include <wchar.h>
+
+/** The wcscpy function copies the wide string pointed to by s2 (including the
+ terminating null wide character) into the array pointed to by s1.
+
+ @return The wcscpy function returns the value of s1.
+**/
+wchar_t *wcscpy(wchar_t * __restrict s1, const wchar_t * __restrict s2)
+{
+ return (wchar_t *)StrCpy( (CHAR16 *)s1, (CONST CHAR16 *)s2);
+}
+
+/** The wcsncpy function copies not more than n wide characters (those that
+ follow a null wide character are not copied) from the array pointed to by
+ s2 to the array pointed to by s1.
+
+ If the array pointed to by s2 is a wide string that is shorter than n wide
+ characters, null wide characters are appended to the copy in the array
+ pointed to by s1, until n wide characters in all have been written.
+
+ @return The wcsncpy function returns the value of s1.
+**/
+wchar_t *wcsncpy(wchar_t * __restrict s1, const wchar_t * __restrict s2, size_t n)
+{
+ return (wchar_t *)StrnCpy( (CHAR16 *)s1, (CONST CHAR16 *)s2, (UINTN)n);
+}
+
+/** The wmemcpy function copies n wide characters from the object pointed to by
+ s2 to the object pointed to by s1.
+
+ Use this function if you know that s1 and s2 DO NOT Overlap. Otherwise,
+ use wmemmove.
+
+ @return The wmemcpy function returns the value of s1.
+**/
+wchar_t *wmemcpy(wchar_t * __restrict s1, const wchar_t * __restrict s2, size_t n)
+{
+ return (wchar_t *)CopyMem( s1, s2, (UINTN)(n * sizeof(wchar_t)));
+}
+
+/** The wmemmove function copies n wide characters from the object pointed to by
+ s2 to the object pointed to by s1. The objects pointed to by s1 and s2 are
+ allowed to overlap.
+
+ Because the UEFI BaseMemoryLib function CopyMem explicitly handles
+ overlapping source and destination objects, this function and wmemcpy are
+ implemented identically.
+
+ For programming clarity, it is recommended that you use wmemcpy if you know
+ that s1 and s2 DO NOT Overlap. If s1 and s2 might possibly overlap, then
+ use wmemmove.
+
+ @return The wmemmove function returns the value of s1.
+**/
+wchar_t *wmemmove(wchar_t *s1, const wchar_t *s2, size_t n)
+{
+ return (wchar_t *)CopyMem( s1, s2, (UINTN)(n * sizeof(wchar_t)));
+}
diff --git a/StdLib/LibC/Wchar/Searching.c b/StdLib/LibC/Wchar/Searching.c
new file mode 100644
index 0000000000..c345dfe838
--- /dev/null
+++ b/StdLib/LibC/Wchar/Searching.c
@@ -0,0 +1,268 @@
+/** @file
+ Search Functions for <wchar.h>.
+
+ Unless explicitly stated otherwise, the functions defined in this file order
+ two wide characters the same way as two integers of the underlying integer
+ type designated by wchar_t.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <LibConfig.h>
+
+#include <wchar.h>
+
+/* Data initialized by the library constructor */
+extern UINT8 *__wchar_bitmap;
+extern UINTN __wchar_bitmap_size;
+extern UINTN __wchar_bitmap_64;
+
+/** The wcschr function locates the first occurrence of c in the wide string
+ pointed to by s. The terminating null wide character is considered to be
+ part of the wide string.
+
+ @return The wcschr function returns a pointer to the located wide
+ character, or a null pointer if the wide character does not occur
+ in the wide string.
+**/
+wchar_t *wcschr(const wchar_t *s, wchar_t c)
+{
+ do {
+ if( *s == c) {
+ return (wchar_t *)s;
+ }
+ } while(*s++ != 0);
+ return NULL;
+}
+
+static UINT8 BitMask[] = {
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
+ };
+
+#define WHICH8(c) ((unsigned short)(c) >> 3)
+#define WHICH_BIT(c) (BitMask[((c) & 0x7)])
+#define BITMAP64 ((UINT64 *)bitmap)
+
+static
+void
+BuildBitmap(unsigned char * bitmap, const wchar_t *s2, UINTN n)
+{
+ UINT8 bit;
+ UINTN index;
+
+ //// Initialize bitmap. Bit 0 is always 1 which corresponds to '\0'
+ //for (BITMAP64[0] = index = 1; index < n; index++)
+ // BITMAP64[index] = 0;
+ (void)wmemset( (wchar_t *)bitmap, 0, n / sizeof(wchar_t));
+ bitmap[0] = 1;
+
+ // Set bits in bitmap corresponding to the characters in s2
+ for (; *s2 != 0; ++s2) {
+ index = WHICH8(*s2);
+ bit = WHICH_BIT(*s2);
+ bitmap[index] |= bit;
+ }
+}
+
+/** The wcscspn function computes the length of the maximum initial segment of
+ the wide string pointed to by s1 which consists entirely of wide characters
+ not from the wide string pointed to by s2.
+
+ @return The wcscspn function returns the length of the segment.
+**/
+size_t wcscspn(const wchar_t *s1, const wchar_t *s2)
+{
+ const wchar_t *str;
+ UINT8 bit;
+ int index;
+
+ if(*s1 == 0) return 0;
+
+ BuildBitmap( __wchar_bitmap, s2, __wchar_bitmap_size);
+
+ for(str = s1; ; str++) {
+ index = WHICH8(*str);
+ bit = WHICH_BIT(*str);
+ if ((__wchar_bitmap[index] & bit) != 0)
+ break;
+ }
+ return (str - s1);
+}
+
+/** The wcspbrk function locates the first occurrence in the wide string
+ pointed to by s1 of any wide character from the wide string
+ pointed to by s2.
+
+ @return The wcspbrk function returns a pointer to the wide character
+ in s1, or a null pointer if no wide character from s2 occurs
+ in s1.
+**/
+wchar_t *wcspbrk(const wchar_t *s1, const wchar_t *s2)
+{
+ UINT8 bit;
+ int index;
+
+ BuildBitmap( __wchar_bitmap, s2, __wchar_bitmap_size);
+
+ for( ; *s1 != 0; ++s1) {
+ index = WHICH8(*s1);
+ bit = WHICH_BIT(*s1);
+ if( (__wchar_bitmap[index] & bit) != 0) {
+ return (wchar_t *)s1;
+ }
+ }
+ return NULL;
+}
+
+/** The wcsrchr function locates the last occurrence of c in the wide string
+ pointed to by s. The terminating null wide character is considered to be
+ part of the wide string.
+
+ @return The wcsrchr function returns a pointer to the wide character,
+ or a null pointer if c does not occur in the wide string.
+**/
+wchar_t *wcsrchr(const wchar_t *s, wchar_t c)
+{
+ wchar_t *found = NULL;
+
+ do {
+ if( *s == c) found = (wchar_t *)s;
+ } while( *s++ != 0);
+
+ return found;
+}
+
+/** The wcsspn function computes the length of the maximum initial segment of
+ the wide string pointed to by s1 which consists entirely of wide characters
+ from the wide string pointed to by s2.
+
+ @return The wcsspn function returns the length of the segment.
+**/
+size_t wcsspn(const wchar_t *s1, const wchar_t *s2)
+{
+ size_t length = 0;
+ int index;
+ UINT8 bit;
+
+ BuildBitmap( __wchar_bitmap, s2, __wchar_bitmap_size);
+
+ for( ; *s1 != 0; ++s1) {
+ index = WHICH8(*s1);
+ bit = WHICH_BIT(*s1);
+ if( (__wchar_bitmap[index] & bit) == 0) break;
+ ++length;
+ }
+ return length;
+}
+
+/** The wcsstr function locates the first occurrence in the wide string pointed
+ to by s1 of the sequence of wide characters (excluding the terminating null
+ wide character) in the wide string pointed to by s2.
+
+ @return The wcsstr function returns a pointer to the located wide string,
+ or a null pointer if the wide string is not found. If s2 points
+ to a wide string with zero length, the function returns s1.
+**/
+wchar_t *wcsstr(const wchar_t *s1, const wchar_t *s2)
+{
+ return (wchar_t *)StrStr( (CONST CHAR16 *)s1, (CONST CHAR16 *)s2);
+}
+
+/** A sequence of calls to the wcstok function breaks the wide string pointed
+ to by s1 into a sequence of tokens, each of which is delimited by a wide
+ character from the wide string pointed to by s2. The third argument points
+ to a caller-provided wchar_t pointer into which the wcstok function stores
+ information necessary for it to continue scanning the same wide string.
+
+ The first call in a sequence has a non-null first argument and stores an
+ initial value in the object pointed to by ptr. Subsequent calls in the
+ sequence have a null first argument and the object pointed to by ptr is
+ required to have the value stored by the previous call in the sequence,
+ which is then updated. The separator wide string pointed to by s2 may be
+ different from call to call.
+
+ The first call in the sequence searches the wide string pointed to by s1
+ for the first wide character that is not contained in the current separator
+ wide string pointed to by s2. If no such wide character is found, then
+ there are no tokens in the wide string pointed to by s1 and the wcstok
+ function returns a null pointer. If such a wide character is found, it is
+ the start of the first token.
+
+ The wcstok function then searches from there for a wide character that is
+ contained in the current separator wide string. If no such wide character
+ is found, the current token extends to the end of the wide string pointed
+ to by s1, and subsequent searches in the same wide string for a token
+ return a null pointer. If such a wide character is found, it is overwritten
+ by a null wide character, which terminates the current token.
+
+ In all cases, the wcstok function stores sufficient information in the
+ pointer pointed to by ptr so that subsequent calls, with a null pointer for
+ s1 and the unmodified pointer value for ptr, shall start searching just
+ past the element overwritten by a null wide character (if any).
+
+ @return The wcstok function returns a pointer to the first wide character
+ of a token, or a null pointer if there is no token.
+**/
+wchar_t *wcstok(wchar_t * __restrict s1, const wchar_t * __restrict s2, wchar_t ** __restrict ptr)
+{
+ wchar_t *Token = NULL;
+ int index;
+ UINT8 bit;
+
+ if( (s1 == NULL)
+ && ((s1 = *ptr) == NULL))
+ {
+ return NULL;
+ }
+
+ // s2 can be different on each call, so build the bitmap each time.
+ BuildBitmap( __wchar_bitmap, s2, __wchar_bitmap_size);
+
+ // skip leading delimiters: all chars in s2
+ for( ; *s1 != 0; ++s1) {
+ index = WHICH8(*s1);
+ bit = WHICH_BIT(*s1);
+ if( (__wchar_bitmap[index] & bit) == 0) break;
+ }
+ if( *s1 != 0)
+ {
+ // Remember this point, it is the start of the token
+ Token = s1++;
+
+ // find the next delimiter and replace it with a '\0'
+ for( ; *s1 != 0; ++s1) {
+ index = WHICH8(*s1);
+ bit = WHICH_BIT(*s1);
+ if( (__wchar_bitmap[index] & bit) != 0) {
+ *s1++ = 0;
+ *ptr = s1;
+ return Token;
+ }
+ }
+ }
+ *ptr = NULL;
+ return Token;
+}
+
+/** The wmemchr function locates the first occurrence of c in the initial n
+ wide characters of the object pointed to by s.
+
+ @return The wmemchr function returns a pointer to the located wide
+ character, or a null pointer if the wide character does not occur
+ in the object.
+**/
+wchar_t *wmemchr(const wchar_t *s, wchar_t c, size_t n)
+{
+ return (wchar_t *)ScanMem16( s, (UINTN)(n * sizeof(wchar_t)), (UINT16)c);
+}
diff --git a/StdLib/LibC/Wchar/String.c b/StdLib/LibC/Wchar/String.c
new file mode 100644
index 0000000000..70f6d9aedf
--- /dev/null
+++ b/StdLib/LibC/Wchar/String.c
@@ -0,0 +1,43 @@
+/** @file
+ Miscelaneous Functions for <wchar.h>.
+
+ Unless explicitly stated otherwise, if the execution of a function declared
+ in this file causes copying to take place between objects that overlap, the
+ behavior is undefined.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include <LibConfig.h>
+
+#include <wchar.h>
+
+/** The wcslen function computes the length of the wide string pointed to by s.
+
+ @return The wcslen function returns the number of wide characters that
+ precede the terminating null wide character.
+**/
+size_t wcslen(const wchar_t *s)
+{
+ return (size_t)StrLen( (CONST CHAR16 *)s);
+}
+
+/** The wmemset function copies the value of c into each of the first n wide
+ characters of the object pointed to by s.
+
+ @return The wmemset function returns the value of s.
+**/
+wchar_t *wmemset(wchar_t *s, wchar_t c, size_t n)
+{
+ return (wchar_t *)SetMem16( s, (UINTN)(n * sizeof(wchar_t)), (UINT16)c);
+}
diff --git a/StdLib/LibC/Wchar/Wchar.inf b/StdLib/LibC/Wchar/Wchar.inf
new file mode 100644
index 0000000000..427d615742
--- /dev/null
+++ b/StdLib/LibC/Wchar/Wchar.inf
@@ -0,0 +1,59 @@
+## @file
+# Standard C library: Miscelaneous implementations.
+#
+# Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = LibWchar
+ FILE_GUID = 42c078ef-14a8-4e30-9329-6f12d796e54a
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = LibWchar
+ CONSTRUCTOR = __wchar_construct
+ DESTRUCTOR = __wchar_deconstruct
+
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[Sources]
+ ConsDecons.c
+ Copying.c
+ Concatenation.c
+ Comparison.c
+ Searching.c
+ String.c
+
+[Packages]
+ StdLib/StdLib.dec
+ StdLibPrivateInternalFiles/DoNotUse.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ LibC
+
+################################################################
+#
+# The Build Options, below, are only used when building the C library.
+# DO NOT use them when building your application!
+# Nasty things could happen if you do.
+#
+# /Oi is required for Microsoft VC++ to allow "intrinsic" functions to be
+# defined in this library.
+#
+[BuildOptions]
+ MSFT:*_*_*_CC_FLAGS = /Oi-
diff --git a/StdLib/LibC/gdtoa/Ipf/strtold.c b/StdLib/LibC/gdtoa/Ipf/strtold.c
new file mode 100644
index 0000000000..0cddae36f4
--- /dev/null
+++ b/StdLib/LibC/gdtoa/Ipf/strtold.c
@@ -0,0 +1,18 @@
+/** @file
+ Wrapper for strtold so that it just calls strtod(). This is because the IPF implementation doesn't have
+ long double. (actually MS VC++ makes long double a distinct type that is identical to double.) VC++
+ also doesn't support the {strong, weak}_alias feature so we actually have to have an object.
+
+**/
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#include "namespace.h"
+#include "../gdtoaimp.h"
+#include "../gdtoa.h"
+
+long double
+strtold(const char * __restrict nptr, char ** __restrict endptr)
+{
+ return (long double)strtod( nptr, endptr);
+}
diff --git a/StdLib/LibC/gdtoa/_strtof.c b/StdLib/LibC/gdtoa/_strtof.c
new file mode 100644
index 0000000000..50073350dc
--- /dev/null
+++ b/StdLib/LibC/gdtoa/_strtof.c
@@ -0,0 +1,46 @@
+/* $NetBSD: _strtof.c,v 1.1 2006/03/15 17:35:18 kleink Exp $ */
+
+/*
+ * Copyright (c) 1996 Christos Zoulas. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christos Zoulas.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#if defined(__indr_reference)
+__indr_reference(_strtof, strtof)
+#else
+
+#include <stdlib.h>
+float _strtof(const char * __restrict, char ** __restrict);
+
+float
+strtof(const char *nptr, char **endptr)
+{
+ return _strtof(nptr, endptr);
+}
+#endif
diff --git a/StdLib/LibC/gdtoa/_strtold.c b/StdLib/LibC/gdtoa/_strtold.c
new file mode 100644
index 0000000000..f714b4e1ec
--- /dev/null
+++ b/StdLib/LibC/gdtoa/_strtold.c
@@ -0,0 +1,47 @@
+/** @file
+ *
+ * Copyright (c) 1996 Christos Zoulas. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christos Zoulas.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ NetBSD: _strtold.c,v 1.1 2006/03/15 17:35:18 kleink Exp
+**/
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#if defined(__indr_reference)
+ __indr_reference(_strtold, strtold)
+#else
+
+#include <stdlib.h>
+long double _strtold(const char * __restrict, char ** __restrict);
+
+long double
+strtold(const char *nptr, char **endptr)
+{
+ return _strtold(nptr, endptr);
+}
+#endif
diff --git a/StdLib/LibC/gdtoa/atof.c b/StdLib/LibC/gdtoa/atof.c
new file mode 100644
index 0000000000..fe2b7f0889
--- /dev/null
+++ b/StdLib/LibC/gdtoa/atof.c
@@ -0,0 +1,22 @@
+/** @file
+ Convert a string into a floating-point double value.
+
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <LibConfig.h>
+
+#include <stdlib.h>
+
+double
+atof(const char *string)
+{
+ return (strtod(string, NULL));
+}
diff --git a/StdLib/LibC/gdtoa/dmisc.c b/StdLib/LibC/gdtoa/dmisc.c
new file mode 100644
index 0000000000..ff95b427fc
--- /dev/null
+++ b/StdLib/LibC/gdtoa/dmisc.c
@@ -0,0 +1,228 @@
+/* $NetBSD: dmisc.c,v 1.2.4.1.4.1 2008/04/08 21:10:55 jdc Exp $ */
+
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+#include <LibConfig.h>
+
+#include "gdtoaimp.h"
+
+#ifndef MULTIPLE_THREADS
+ char *dtoa_result;
+#endif
+
+ char *
+#ifdef KR_headers
+rv_alloc(i) size_t i;
+#else
+rv_alloc(size_t i)
+#endif
+{
+ size_t j;
+ int k, *r;
+
+ j = sizeof(ULong);
+ for(k = 0;
+ sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i;
+ j <<= 1)
+ k++;
+ r = (int*)(void*)Balloc(k);
+ if (r == NULL)
+ return NULL;
+ *r = k;
+ return
+#ifndef MULTIPLE_THREADS
+ dtoa_result =
+#endif
+ (char *)(void *)(r+1);
+ }
+
+ char *
+#ifdef KR_headers
+nrv_alloc(s, rve, n) CONST char *s; char **rve; size_t n;
+#else
+nrv_alloc(CONST char *s, char **rve, size_t n)
+#endif
+{
+ char *rv, *t;
+
+ t = rv = rv_alloc(n);
+ if (t == NULL)
+ return NULL;
+ while((*t = *s++) !=0)
+ t++;
+ if (rve)
+ *rve = t;
+ return rv;
+ }
+
+/* freedtoa(s) must be used to free values s returned by dtoa
+ * when MULTIPLE_THREADS is #defined. It should be used in all cases,
+ * but for consistency with earlier versions of dtoa, it is optional
+ * when MULTIPLE_THREADS is not defined.
+ */
+
+ void
+#ifdef KR_headers
+freedtoa(s) char *s;
+#else
+freedtoa(char *s)
+#endif
+{
+ Bigint *b = (Bigint *)(void *)((int *)(void *)s - 1);
+ b->maxwds = 1 << (b->k = *(int*)(void*)b);
+ Bfree(b);
+#ifndef MULTIPLE_THREADS
+ if (s == dtoa_result)
+ dtoa_result = 0;
+#endif
+ }
+
+ int
+quorem
+#ifdef KR_headers
+ (b, S) Bigint *b, *S;
+#else
+ (Bigint *b, Bigint *S)
+#endif
+{
+ int n;
+ ULong *bx, *bxe, q, *sx, *sxe;
+#ifdef ULLong
+ ULLong borrow, carry, y, ys;
+#else
+ ULong borrow, carry, y, ys;
+#ifdef Pack_32
+ ULong si, z, zs;
+#endif
+#endif
+
+ n = S->wds;
+#ifdef DEBUG
+ /*debug*/ if (b->wds > n)
+ /*debug*/ Bug("oversize b in quorem");
+#endif
+ if (b->wds < n)
+ return 0;
+ sx = S->x;
+ sxe = sx + --n;
+ bx = b->x;
+ bxe = bx + n;
+ q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
+#ifdef DEBUG
+ /*debug*/ if (q > 9)
+ /*debug*/ Bug("oversized quotient in quorem");
+#endif
+ if (q) {
+ borrow = 0;
+ carry = 0;
+ do {
+#ifdef ULLong
+ ys = *sx++ * (ULLong)q + carry;
+ carry = ys >> 32;
+ /* LINTED conversion */
+ y = *bx - (ys & 0xffffffffUL) - borrow;
+ borrow = y >> 32 & 1UL;
+ /* LINTED conversion */
+ *bx++ = (UINT32)(y & 0xffffffffUL);
+#else
+#ifdef Pack_32
+ si = *sx++;
+ ys = (si & 0xffff) * q + carry;
+ zs = (si >> 16) * q + (ys >> 16);
+ carry = zs >> 16;
+ y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
+ borrow = (y & 0x10000) >> 16;
+ z = (*bx >> 16) - (zs & 0xffff) - borrow;
+ borrow = (z & 0x10000) >> 16;
+ Storeinc(bx, z, y);
+#else
+ ys = *sx++ * q + carry;
+ carry = ys >> 16;
+ y = *bx - (ys & 0xffff) - borrow;
+ borrow = (y & 0x10000) >> 16;
+ *bx++ = y & 0xffff;
+#endif
+#endif
+ }
+ while(sx <= sxe);
+ if (!*bxe) {
+ bx = b->x;
+ while(--bxe > bx && !*bxe)
+ --n;
+ b->wds = n;
+ }
+ }
+ if (cmp(b, S) >= 0) {
+ q++;
+ borrow = 0;
+ carry = 0;
+ bx = b->x;
+ sx = S->x;
+ do {
+#ifdef ULLong
+ ys = *sx++ + carry;
+ carry = ys >> 32;
+ /* LINTED conversion */
+ y = *bx - (ys & 0xffffffffUL) - borrow;
+ borrow = y >> 32 & 1UL;
+ /* LINTED conversion */
+ *bx++ = (UINT32)(y & 0xffffffffUL);
+#else
+#ifdef Pack_32
+ si = *sx++;
+ ys = (si & 0xffff) + carry;
+ zs = (si >> 16) + (ys >> 16);
+ carry = zs >> 16;
+ y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
+ borrow = (y & 0x10000) >> 16;
+ z = (*bx >> 16) - (zs & 0xffff) - borrow;
+ borrow = (z & 0x10000) >> 16;
+ Storeinc(bx, z, y);
+#else
+ ys = *sx++ + carry;
+ carry = ys >> 16;
+ y = *bx - (ys & 0xffff) - borrow;
+ borrow = (y & 0x10000) >> 16;
+ *bx++ = y & 0xffff;
+#endif
+#endif
+ }
+ while(sx <= sxe);
+ bx = b->x;
+ bxe = bx + n;
+ if (!*bxe) {
+ while(--bxe > bx && !*bxe)
+ --n;
+ b->wds = n;
+ }
+ }
+ return (int)q;
+ }
diff --git a/StdLib/LibC/gdtoa/dtoa.c b/StdLib/LibC/gdtoa/dtoa.c
new file mode 100644
index 0000000000..42098426fd
--- /dev/null
+++ b/StdLib/LibC/gdtoa/dtoa.c
@@ -0,0 +1,821 @@
+/* $NetBSD: dtoa.c,v 1.3.4.1.4.1 2008/04/08 21:10:55 jdc Exp $ */
+
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998, 1999 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+#include <LibConfig.h>
+
+#include "gdtoaimp.h"
+
+/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
+ *
+ * Inspired by "How to Print Floating-Point Numbers Accurately" by
+ * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126].
+ *
+ * Modifications:
+ * 1. Rather than iterating, we use a simple numeric overestimate
+ * to determine k = floor(log10(d)). We scale relevant
+ * quantities using O(log2(k)) rather than O(k) multiplications.
+ * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
+ * try to generate digits strictly left to right. Instead, we
+ * compute with fewer bits and propagate the carry if necessary
+ * when rounding the final digit up. This is often faster.
+ * 3. Under the assumption that input will be rounded nearest,
+ * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
+ * That is, we allow equality in stopping tests when the
+ * round-nearest rule will give the same floating-point value
+ * as would satisfaction of the stopping test with strict
+ * inequality.
+ * 4. We remove common factors of powers of 2 from relevant
+ * quantities.
+ * 5. When converting floating-point integers less than 1e16,
+ * we use floating-point arithmetic rather than resorting
+ * to multiple-precision integers.
+ * 6. When asked to produce fewer than 15 digits, we first try
+ * to get by with floating-point arithmetic; we resort to
+ * multiple-precision integer arithmetic only if we cannot
+ * guarantee that the floating-point calculation has given
+ * the correctly rounded result. For k requested digits and
+ * "uniformly" distributed input, the probability is
+ * something like 10^(k-15) that we must resort to the Long
+ * calculation.
+ */
+
+#ifdef Honor_FLT_ROUNDS
+#define Rounding rounding
+#undef Check_FLT_ROUNDS
+#define Check_FLT_ROUNDS
+#else
+#define Rounding Flt_Rounds
+#endif
+
+#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
+// Disable: warning C4700: uninitialized local variable 'xx' used
+#pragma warning ( disable : 4700 )
+#endif /* defined(_MSC_VER) */
+
+ char *
+dtoa
+#ifdef KR_headers
+ (d, mode, ndigits, decpt, sign, rve)
+ double d; int mode, ndigits, *decpt, *sign; char **rve;
+#else
+ (double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
+#endif
+{
+ /* Arguments ndigits, decpt, sign are similar to those
+ of ecvt and fcvt; trailing zeros are suppressed from
+ the returned string. If not null, *rve is set to point
+ to the end of the return value. If d is +-Infinity or NaN,
+ then *decpt is set to 9999.
+
+ mode:
+ 0 ==> shortest string that yields d when read in
+ and rounded to nearest.
+ 1 ==> like 0, but with Steele & White stopping rule;
+ e.g. with IEEE P754 arithmetic , mode 0 gives
+ 1e23 whereas mode 1 gives 9.999999999999999e22.
+ 2 ==> max(1,ndigits) significant digits. This gives a
+ return value similar to that of ecvt, except
+ that trailing zeros are suppressed.
+ 3 ==> through ndigits past the decimal point. This
+ gives a return value similar to that from fcvt,
+ except that trailing zeros are suppressed, and
+ ndigits can be negative.
+ 4,5 ==> similar to 2 and 3, respectively, but (in
+ round-nearest mode) with the tests of mode 0 to
+ possibly return a shorter string that rounds to d.
+ With IEEE arithmetic and compilation with
+ -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same
+ as modes 2 and 3 when FLT_ROUNDS != 1.
+ 6-9 ==> Debugging modes similar to mode - 4: don't try
+ fast floating-point estimate (if applicable).
+
+ Values of mode other than 0-9 are treated as mode 0.
+
+ Sufficient space is allocated to the return value
+ to hold the suppressed trailing zeros.
+ */
+
+ int bbits, b2, b5, be, dig, i, ieps, ilim0,
+ j, jj1, k, k0, k_check, leftright, m2, m5, s2, s5,
+ spec_case, try_quick;
+ int ilim = 0, ilim1 = 0; /* pacify gcc */
+ Long L;
+#ifndef Sudden_Underflow
+ int denorm;
+ ULong x;
+#endif
+ Bigint *b, *b1, *delta, *mhi, *S;
+ Bigint *mlo = NULL; /* pacify gcc */
+ double d2, ds, eps;
+ char *s, *s0;
+#ifdef Honor_FLT_ROUNDS
+ int rounding;
+#endif
+#ifdef SET_INEXACT
+ int inexact, oldinexact;
+#endif
+
+#ifndef MULTIPLE_THREADS
+ if (dtoa_result) {
+ freedtoa(dtoa_result);
+ dtoa_result = 0;
+ }
+#endif
+
+ if (word0(d) & Sign_bit) {
+ /* set sign for everything, including 0's and NaNs */
+ *sign = 1;
+ word0(d) &= ~Sign_bit; /* clear sign bit */
+ }
+ else
+ *sign = 0;
+
+#if defined(IEEE_Arith) + defined(VAX)
+#ifdef IEEE_Arith
+ if ((word0(d) & Exp_mask) == Exp_mask)
+#else
+ if (word0(d) == 0x8000)
+#endif
+ {
+ /* Infinity or NaN */
+ *decpt = 9999;
+#ifdef IEEE_Arith
+ if (!word1(d) && !(word0(d) & 0xfffff))
+ return nrv_alloc("Infinity", rve, 8);
+#endif
+ return nrv_alloc("NaN", rve, 3);
+ }
+#endif
+#ifdef IBM
+ dval(d) += 0; /* normalize */
+#endif
+ if (!dval(d)) {
+ *decpt = 1;
+ return nrv_alloc("0", rve, 1);
+ }
+
+#ifdef SET_INEXACT
+ try_quick = oldinexact = get_inexact();
+ inexact = 1;
+#endif
+#ifdef Honor_FLT_ROUNDS
+ if ((rounding = Flt_Rounds) >= 2) {
+ if (*sign)
+ rounding = rounding == 2 ? 0 : 2;
+ else
+ if (rounding != 2)
+ rounding = 0;
+ }
+#endif
+
+ b = d2b(dval(d), &be, &bbits);
+ if (b == NULL)
+ return NULL;
+#ifdef Sudden_Underflow
+ i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
+#else
+ if (( i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)) )!=0) {
+#endif
+ dval(d2) = dval(d);
+ word0(d2) &= Frac_mask1;
+ word0(d2) |= Exp_11;
+#ifdef IBM
+ if (( j = 11 - hi0bits(word0(d2) & Frac_mask) )!=0)
+ dval(d2) /= 1 << j;
+#endif
+
+ /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
+ * log10(x) = log(x) / log(10)
+ * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
+ * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
+ *
+ * This suggests computing an approximation k to log10(d) by
+ *
+ * k = (i - Bias)*0.301029995663981
+ * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
+ *
+ * We want k to be too large rather than too small.
+ * The error in the first-order Taylor series approximation
+ * is in our favor, so we just round up the constant enough
+ * to compensate for any error in the multiplication of
+ * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
+ * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
+ * adding 1e-13 to the constant term more than suffices.
+ * Hence we adjust the constant term to 0.1760912590558.
+ * (We could get a more accurate k by invoking log10,
+ * but this is probably not worthwhile.)
+ */
+
+ i -= Bias;
+#ifdef IBM
+ i <<= 2;
+ i += j;
+#endif
+#ifndef Sudden_Underflow
+ denorm = 0;
+ }
+ else {
+ /* d is denormalized */
+
+ i = bbits + be + (Bias + (P-1) - 1);
+ x = i > 32 ? word0(d) << (64 - i) | word1(d) >> (i - 32)
+ : word1(d) << (32 - i);
+ dval(d2) = (double)x;
+ word0(d2) -= 31*Exp_msk1; /* adjust exponent */
+ i -= (Bias + (P-1) - 1) + 1;
+ denorm = 1;
+ }
+#endif
+ ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
+ k = (int)ds;
+ if (ds < 0. && ds != k)
+ k--; /* want k = floor(ds) */
+ k_check = 1;
+ if (k >= 0 && k <= Ten_pmax) {
+ if (dval(d) < tens[k])
+ k--;
+ k_check = 0;
+ }
+ j = bbits - i - 1;
+ if (j >= 0) {
+ b2 = 0;
+ s2 = j;
+ }
+ else {
+ b2 = -j;
+ s2 = 0;
+ }
+ if (k >= 0) {
+ b5 = 0;
+ s5 = k;
+ s2 += k;
+ }
+ else {
+ b2 -= k;
+ b5 = -k;
+ s5 = 0;
+ }
+ if (mode < 0 || mode > 9)
+ mode = 0;
+
+#ifndef SET_INEXACT
+#ifdef Check_FLT_ROUNDS
+ try_quick = Rounding == 1;
+#else
+ try_quick = 1;
+#endif
+#endif /*SET_INEXACT*/
+
+ if (mode > 5) {
+ mode -= 4;
+ try_quick = 0;
+ }
+ leftright = 1;
+ switch(mode) {
+ case 0:
+ case 1:
+ ilim = ilim1 = -1;
+ i = 18;
+ ndigits = 0;
+ break;
+ case 2:
+ leftright = 0;
+ /* FALLTHROUGH */
+ case 4:
+ if (ndigits <= 0)
+ ndigits = 1;
+ ilim = ilim1 = i = ndigits;
+ break;
+ case 3:
+ leftright = 0;
+ /* FALLTHROUGH */
+ case 5:
+ i = ndigits + k + 1;
+ ilim = i;
+ ilim1 = i - 1;
+ if (i <= 0)
+ i = 1;
+ }
+ s = s0 = rv_alloc((size_t)i);
+ if (s == NULL)
+ return NULL;
+
+#ifdef Honor_FLT_ROUNDS
+ if (mode > 1 && rounding != 1)
+ leftright = 0;
+#endif
+
+ if (ilim >= 0 && ilim <= Quick_max && try_quick) {
+
+ /* Try to get by with floating-point arithmetic. */
+
+ i = 0;
+ dval(d2) = dval(d);
+ k0 = k;
+ ilim0 = ilim;
+ ieps = 2; /* conservative */
+ if (k > 0) {
+ ds = tens[k&0xf];
+ j = (unsigned int)k >> 4;
+ if (j & Bletch) {
+ /* prevent overflows */
+ j &= Bletch - 1;
+ dval(d) /= bigtens[n_bigtens-1];
+ ieps++;
+ }
+ for(; j; j = (unsigned int)j >> 1, i++)
+ if (j & 1) {
+ ieps++;
+ ds *= bigtens[i];
+ }
+ dval(d) /= ds;
+ }
+ else if (( jj1 = -k )!=0) {
+ dval(d) *= tens[jj1 & 0xf];
+ for(j = jj1 >> 4; j; j >>= 1, i++)
+ if (j & 1) {
+ ieps++;
+ dval(d) *= bigtens[i];
+ }
+ }
+ if (k_check && dval(d) < 1. && ilim > 0) {
+ if (ilim1 <= 0)
+ goto fast_failed;
+ ilim = ilim1;
+ k--;
+ dval(d) *= 10.;
+ ieps++;
+ }
+ dval(eps) = ieps*dval(d) + 7.;
+ word0(eps) -= (P-1)*Exp_msk1;
+ if (ilim == 0) {
+ S = mhi = 0;
+ dval(d) -= 5.;
+ if (dval(d) > dval(eps))
+ goto one_digit;
+ if (dval(d) < -dval(eps))
+ goto no_digits;
+ goto fast_failed;
+ }
+#ifndef No_leftright
+ if (leftright) {
+ /* Use Steele & White method of only
+ * generating digits needed.
+ */
+ dval(eps) = 0.5/tens[ilim-1] - dval(eps);
+ for(i = 0;;) {
+ L = (INT32)dval(d);
+ dval(d) -= L;
+ *s++ = (char)('0' + (int)L);
+ if (dval(d) < dval(eps))
+ goto ret1;
+ if (1. - dval(d) < dval(eps))
+ goto bump_up;
+ if (++i >= ilim)
+ break;
+ dval(eps) *= 10.;
+ dval(d) *= 10.;
+ }
+ }
+ else {
+#endif
+ /* Generate ilim digits, then fix them up. */
+ dval(eps) *= tens[ilim-1];
+ for(i = 1;; i++, dval(d) *= 10.) {
+ L = (Long)(dval(d));
+ if (!(dval(d) -= L))
+ ilim = i;
+ *s++ = (char)('0' + (int)L);
+ if (i == ilim) {
+ if (dval(d) > 0.5 + dval(eps))
+ goto bump_up;
+ else if (dval(d) < 0.5 - dval(eps)) {
+ while(*--s == '0');
+ s++;
+ goto ret1;
+ }
+ break;
+ }
+ }
+#ifndef No_leftright
+ }
+#endif
+ fast_failed:
+ s = s0;
+ dval(d) = dval(d2);
+ k = k0;
+ ilim = ilim0;
+ }
+
+ /* Do we have a "small" integer? */
+
+ if (be >= 0 && k <= Int_max) {
+ /* Yes. */
+ ds = tens[k];
+ if (ndigits < 0 && ilim <= 0) {
+ S = mhi = 0;
+ if (ilim < 0 || dval(d) <= 5*ds)
+ goto no_digits;
+ goto one_digit;
+ }
+ for(i = 1;; i++, dval(d) *= 10.) {
+ L = (Long)(dval(d) / ds);
+ dval(d) -= L*ds;
+#ifdef Check_FLT_ROUNDS
+ /* If FLT_ROUNDS == 2, L will usually be high by 1 */
+ if (dval(d) < 0) {
+ L--;
+ dval(d) += ds;
+ }
+#endif
+ *s++ = (char)('0' + (int)L);
+ if (!dval(d)) {
+#ifdef SET_INEXACT
+ inexact = 0;
+#endif
+ break;
+ }
+ if (i == ilim) {
+#ifdef Honor_FLT_ROUNDS
+ if (mode > 1)
+ switch(rounding) {
+ case 0: goto ret1;
+ case 2: goto bump_up;
+ }
+#endif
+ dval(d) += dval(d);
+ if (dval(d) > ds || (dval(d) == ds && L & 1)) {
+ bump_up:
+ while(*--s == '9')
+ if (s == s0) {
+ k++;
+ *s = '0';
+ break;
+ }
+ ++*s++;
+ }
+ break;
+ }
+ }
+ goto ret1;
+ }
+
+ m2 = b2;
+ m5 = b5;
+ mhi = mlo = 0;
+ if (leftright) {
+ i =
+#ifndef Sudden_Underflow
+ denorm ? be + (Bias + (P-1) - 1 + 1) :
+#endif
+#ifdef IBM
+ 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
+#else
+ 1 + P - bbits;
+#endif
+ b2 += i;
+ s2 += i;
+ mhi = i2b(1);
+ if (mhi == NULL)
+ return NULL;
+ }
+ if (m2 > 0 && s2 > 0) {
+ i = m2 < s2 ? m2 : s2;
+ b2 -= i;
+ m2 -= i;
+ s2 -= i;
+ }
+ if (b5 > 0) {
+ if (leftright) {
+ if (m5 > 0) {
+ mhi = pow5mult(mhi, m5);
+ if (mhi == NULL)
+ return NULL;
+ b1 = mult(mhi, b);
+ if (b1 == NULL)
+ return NULL;
+ Bfree(b);
+ b = b1;
+ }
+ if (( j = b5 - m5 )!=0)
+ b = pow5mult(b, j);
+ if (b == NULL)
+ return NULL;
+ }
+ else
+ b = pow5mult(b, b5);
+ if (b == NULL)
+ return NULL;
+ }
+ S = i2b(1);
+ if (S == NULL)
+ return NULL;
+ if (s5 > 0) {
+ S = pow5mult(S, s5);
+ if (S == NULL)
+ return NULL;
+ }
+
+ /* Check for special case that d is a normalized power of 2. */
+
+ spec_case = 0;
+ if ((mode < 2 || leftright)
+#ifdef Honor_FLT_ROUNDS
+ && rounding == 1
+#endif
+ ) {
+ if (!word1(d) && !(word0(d) & Bndry_mask)
+#ifndef Sudden_Underflow
+ && word0(d) & (Exp_mask & ~Exp_msk1)
+#endif
+ ) {
+ /* The special case */
+ b2 += Log2P;
+ s2 += Log2P;
+ spec_case = 1;
+ }
+ }
+
+ /* Arrange for convenient computation of quotients:
+ * shift left if necessary so divisor has 4 leading 0 bits.
+ *
+ * Perhaps we should just compute leading 28 bits of S once
+ * and for all and pass them and a shift to quorem, so it
+ * can do shifts and ors to compute the numerator for q.
+ */
+#ifdef Pack_32
+ if (( i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f )!=0)
+ i = 32 - i;
+#else
+ if (( i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf )!=0)
+ i = 16 - i;
+#endif
+ if (i > 4) {
+ i -= 4;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+ else if (i < 4) {
+ i += 28;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+ if (b2 > 0) {
+ b = lshift(b, b2);
+ if (b == NULL)
+ return NULL;
+ }
+ if (s2 > 0) {
+ S = lshift(S, s2);
+ if (S == NULL)
+ return NULL;
+ }
+ if (k_check) {
+ if (cmp(b,S) < 0) {
+ k--;
+ b = multadd(b, 10, 0); /* we botched the k estimate */
+ if (b == NULL)
+ return NULL;
+ if (leftright) {
+ mhi = multadd(mhi, 10, 0);
+ if (mhi == NULL)
+ return NULL;
+ }
+ ilim = ilim1;
+ }
+ }
+ if (ilim <= 0 && (mode == 3 || mode == 5)) {
+ if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
+ /* no digits, fcvt style */
+ no_digits:
+ k = -1 - ndigits;
+ goto ret;
+ }
+ one_digit:
+ *s++ = '1';
+ k++;
+ goto ret;
+ }
+ if (leftright) {
+ if (m2 > 0) {
+ mhi = lshift(mhi, m2);
+ if (mhi == NULL)
+ return NULL;
+ }
+
+ /* Compute mlo -- check for special case
+ * that d is a normalized power of 2.
+ */
+
+ mlo = mhi;
+ if (spec_case) {
+ mhi = Balloc(mhi->k);
+ if (mhi == NULL)
+ return NULL;
+ Bcopy(mhi, mlo);
+ mhi = lshift(mhi, Log2P);
+ if (mhi == NULL)
+ return NULL;
+ }
+
+ for(i = 1;;i++) {
+ dig = quorem(b,S) + '0';
+ /* Do we yet have the shortest decimal string
+ * that will round to d?
+ */
+ j = cmp(b, mlo);
+ delta = diff(S, mhi);
+ if (delta == NULL)
+ return NULL;
+ jj1 = delta->sign ? 1 : cmp(b, delta);
+ Bfree(delta);
+#ifndef ROUND_BIASED
+ if (jj1 == 0 && mode != 1 && !(word1(d) & 1)
+#ifdef Honor_FLT_ROUNDS
+ && rounding >= 1
+#endif
+ ) {
+ if (dig == '9')
+ goto round_9_up;
+ if (j > 0)
+ dig++;
+#ifdef SET_INEXACT
+ else if (!b->x[0] && b->wds <= 1)
+ inexact = 0;
+#endif
+ *s++ = (char)dig;
+ goto ret;
+ }
+#endif
+ if (j < 0 || (j == 0 && mode != 1
+#ifndef ROUND_BIASED
+ && !(word1(d) & 1)
+#endif
+ )) {
+ if (!b->x[0] && b->wds <= 1) {
+#ifdef SET_INEXACT
+ inexact = 0;
+#endif
+ goto accept_dig;
+ }
+#ifdef Honor_FLT_ROUNDS
+ if (mode > 1)
+ switch(rounding) {
+ case 0: goto accept_dig;
+ case 2: goto keep_dig;
+ }
+#endif /*Honor_FLT_ROUNDS*/
+ if (jj1 > 0) {
+ b = lshift(b, 1);
+ if (b == NULL)
+ return NULL;
+ jj1 = cmp(b, S);
+ if ((jj1 > 0 || (jj1 == 0 && dig & 1))
+ && dig++ == '9')
+ goto round_9_up;
+ }
+ accept_dig:
+ *s++ = (char)dig;
+ goto ret;
+ }
+ if (jj1 > 0) {
+#ifdef Honor_FLT_ROUNDS
+ if (!rounding)
+ goto accept_dig;
+#endif
+ if (dig == '9') { /* possible if i == 1 */
+ round_9_up:
+ *s++ = '9';
+ goto roundoff;
+ }
+ *s++ = (char)(dig + 1);
+ goto ret;
+ }
+#ifdef Honor_FLT_ROUNDS
+ keep_dig:
+#endif
+ *s++ = (char)dig;
+ if (i == ilim)
+ break;
+ b = multadd(b, 10, 0);
+ if (b == NULL)
+ return NULL;
+ if (mlo == mhi) {
+ mlo = mhi = multadd(mhi, 10, 0);
+ if (mlo == NULL)
+ return NULL;
+ }
+ else {
+ mlo = multadd(mlo, 10, 0);
+ if (mlo == NULL)
+ return NULL;
+ mhi = multadd(mhi, 10, 0);
+ if (mhi == NULL)
+ return NULL;
+ }
+ }
+ }
+ else
+ for(i = 1;; i++) {
+ *s++ = (char)(dig = (int)(quorem(b,S) + '0'));
+ if (!b->x[0] && b->wds <= 1) {
+#ifdef SET_INEXACT
+ inexact = 0;
+#endif
+ goto ret;
+ }
+ if (i >= ilim)
+ break;
+ b = multadd(b, 10, 0);
+ if (b == NULL)
+ return NULL;
+ }
+
+ /* Round off last digit */
+
+#ifdef Honor_FLT_ROUNDS
+ switch(rounding) {
+ case 0: goto trimzeros;
+ case 2: goto roundoff;
+ }
+#endif
+ b = lshift(b, 1);
+ j = cmp(b, S);
+ if (j > 0 || (j == 0 && dig & 1)) {
+ roundoff:
+ while(*--s == '9')
+ if (s == s0) {
+ k++;
+ *s++ = '1';
+ goto ret;
+ }
+ ++*s++;
+ }
+ else {
+#ifdef Honor_FLT_ROUNDS
+ trimzeros:
+#endif
+ while(*--s == '0');
+ s++;
+ }
+ ret:
+ Bfree(S);
+ if (mhi) {
+ if (mlo && mlo != mhi)
+ Bfree(mlo);
+ Bfree(mhi);
+ }
+ ret1:
+#ifdef SET_INEXACT
+ if (inexact) {
+ if (!oldinexact) {
+ word0(d) = Exp_1 + (70 << Exp_shift);
+ word1(d) = 0;
+ dval(d) += 1.;
+ }
+ }
+ else if (!oldinexact)
+ clear_inexact();
+#endif
+ Bfree(b);
+ if (s == s0) { /* don't return empty string */
+ *s++ = '0';
+ k = 0;
+ }
+ *s = 0;
+ *decpt = k + 1;
+ if (rve)
+ *rve = s;
+ return s0;
+ }
diff --git a/StdLib/LibC/gdtoa/gdtoa.c b/StdLib/LibC/gdtoa/gdtoa.c
new file mode 100644
index 0000000000..b1457c1470
--- /dev/null
+++ b/StdLib/LibC/gdtoa/gdtoa.c
@@ -0,0 +1,814 @@
+/* $NetBSD: gdtoa.c,v 1.1.1.1.4.1.4.1 2008/04/08 21:10:55 jdc Exp $ */
+
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998, 1999 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+#include <LibConfig.h>
+
+#include "gdtoaimp.h"
+
+#if defined(_MSC_VER)
+ /* Disable warnings about conversions to narrower data types. */
+ #pragma warning ( disable : 4244 )
+ // Squelch bogus warnings about uninitialized variable use.
+ #pragma warning ( disable : 4701 )
+#endif
+
+static Bigint *
+bitstob(ULong *bits, int nbits, int *bbits)
+{
+ int i, k;
+ Bigint *b;
+ ULong *be, *x, *x0;
+
+ i = ULbits;
+ k = 0;
+ while(i < nbits) {
+ i <<= 1;
+ k++;
+ }
+#ifndef Pack_32
+ if (!k)
+ k = 1;
+#endif
+ b = Balloc(k);
+ if (b == NULL)
+ return NULL;
+ be = bits + (((unsigned int)nbits - 1) >> kshift);
+ x = x0 = b->x;
+ do {
+ *x++ = *bits & ALL_ON;
+#ifdef Pack_16
+ *x++ = (*bits >> 16) & ALL_ON;
+#endif
+ } while(++bits <= be);
+ i = x - x0;
+ while(!x0[--i])
+ if (!i) {
+ b->wds = 0;
+ *bbits = 0;
+ goto ret;
+ }
+ b->wds = i + 1;
+ *bbits = i*ULbits + 32 - hi0bits(b->x[i]);
+ ret:
+ return b;
+ }
+
+/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
+ *
+ * Inspired by "How to Print Floating-Point Numbers Accurately" by
+ * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126].
+ *
+ * Modifications:
+ * 1. Rather than iterating, we use a simple numeric overestimate
+ * to determine k = floor(log10(d)). We scale relevant
+ * quantities using O(log2(k)) rather than O(k) multiplications.
+ * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
+ * try to generate digits strictly left to right. Instead, we
+ * compute with fewer bits and propagate the carry if necessary
+ * when rounding the final digit up. This is often faster.
+ * 3. Under the assumption that input will be rounded nearest,
+ * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
+ * That is, we allow equality in stopping tests when the
+ * round-nearest rule will give the same floating-point value
+ * as would satisfaction of the stopping test with strict
+ * inequality.
+ * 4. We remove common factors of powers of 2 from relevant
+ * quantities.
+ * 5. When converting floating-point integers less than 1e16,
+ * we use floating-point arithmetic rather than resorting
+ * to multiple-precision integers.
+ * 6. When asked to produce fewer than 15 digits, we first try
+ * to get by with floating-point arithmetic; we resort to
+ * multiple-precision integer arithmetic only if we cannot
+ * guarantee that the floating-point calculation has given
+ * the correctly rounded result. For k requested digits and
+ * "uniformly" distributed input, the probability is
+ * something like 10^(k-15) that we must resort to the Long
+ * calculation.
+ */
+
+ char *
+gdtoa
+ (FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, int *decpt, char **rve)
+{
+ /* Arguments ndigits and decpt are similar to the second and third
+ arguments of ecvt and fcvt; trailing zeros are suppressed from
+ the returned string. If not null, *rve is set to point
+ to the end of the return value. If d is +-Infinity or NaN,
+ then *decpt is set to 9999.
+
+ mode:
+ 0 ==> shortest string that yields d when read in
+ and rounded to nearest.
+ 1 ==> like 0, but with Steele & White stopping rule;
+ e.g. with IEEE P754 arithmetic , mode 0 gives
+ 1e23 whereas mode 1 gives 9.999999999999999e22.
+ 2 ==> max(1,ndigits) significant digits. This gives a
+ return value similar to that of ecvt, except
+ that trailing zeros are suppressed.
+ 3 ==> through ndigits past the decimal point. This
+ gives a return value similar to that from fcvt,
+ except that trailing zeros are suppressed, and
+ ndigits can be negative.
+ 4-9 should give the same return values as 2-3, i.e.,
+ 4 <= mode <= 9 ==> same return as mode
+ 2 + (mode & 1). These modes are mainly for
+ debugging; often they run slower but sometimes
+ faster than modes 2-3.
+ 4,5,8,9 ==> left-to-right digit generation.
+ 6-9 ==> don't try fast floating-point estimate
+ (if applicable).
+
+ Values of mode other than 0-9 are treated as mode 0.
+
+ Sufficient space is allocated to the return value
+ to hold the suppressed trailing zeros.
+ */
+
+ int bbits, b2, b5, be0, dig, i, ieps, ilim = 0, ilim0, ilim1 = 0, inex;
+ int j, jj1, k, k0, k_check, kind, leftright, m2, m5, nbits;
+ int rdir, s2, s5, spec_case, try_quick;
+ Long L;
+ Bigint *b, *b1, *delta, *mlo, *mhi, *mhi1, *S;
+ double d, d2, ds, eps;
+ char *s, *s0;
+
+#ifndef MULTIPLE_THREADS
+ if (dtoa_result) {
+ freedtoa(dtoa_result);
+ dtoa_result = 0;
+ }
+#endif
+ inex = 0;
+ if (*kindp & STRTOG_NoMemory)
+ return NULL;
+ kind = *kindp &= ~STRTOG_Inexact;
+ switch(kind & STRTOG_Retmask) {
+ case STRTOG_Zero:
+ goto ret_zero;
+ case STRTOG_Normal:
+ case STRTOG_Denormal:
+ break;
+ case STRTOG_Infinite:
+ *decpt = -32768;
+ return nrv_alloc("Infinity", rve, 8);
+ case STRTOG_NaN:
+ *decpt = -32768;
+ return nrv_alloc("NaN", rve, 3);
+ default:
+ return 0;
+ }
+ b = bitstob(bits, nbits = fpi->nbits, &bbits);
+ if (b == NULL)
+ return NULL;
+ be0 = be;
+ if ( (i = trailz(b)) !=0) {
+ rshift(b, i);
+ be += i;
+ bbits -= i;
+ }
+ if (!b->wds) {
+ Bfree(b);
+ ret_zero:
+ *decpt = 1;
+ return nrv_alloc("0", rve, 1);
+ }
+
+ dval(d) = b2d(b, &i);
+ i = be + bbits - 1;
+ word0(d) &= Frac_mask1;
+ word0(d) |= Exp_11;
+#ifdef IBM
+ if ( (j = 11 - hi0bits(word0(d) & Frac_mask)) !=0)
+ dval(d) /= 1 << j;
+#endif
+
+ /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
+ * log10(x) = log(x) / log(10)
+ * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
+ * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
+ *
+ * This suggests computing an approximation k to log10(d) by
+ *
+ * k = (i - Bias)*0.301029995663981
+ * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
+ *
+ * We want k to be too large rather than too small.
+ * The error in the first-order Taylor series approximation
+ * is in our favor, so we just round up the constant enough
+ * to compensate for any error in the multiplication of
+ * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
+ * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
+ * adding 1e-13 to the constant term more than suffices.
+ * Hence we adjust the constant term to 0.1760912590558.
+ * (We could get a more accurate k by invoking log10,
+ * but this is probably not worthwhile.)
+ */
+#ifdef IBM
+ i <<= 2;
+ i += j;
+#endif
+ ds = (dval(d)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
+
+ /* correct assumption about exponent range */
+ if ((j = i) < 0)
+ j = -j;
+ if ((j -= 1077) > 0)
+ ds += j * 7e-17;
+
+ k = (int)ds;
+ if (ds < 0. && ds != k)
+ k--; /* want k = floor(ds) */
+ k_check = 1;
+#ifdef IBM
+ j = be + bbits - 1;
+ if ( (jj1 = j & 3) !=0)
+ dval(d) *= 1 << jj1;
+ word0(d) += j << Exp_shift - 2 & Exp_mask;
+#else
+ word0(d) += (be + bbits - 1) << Exp_shift;
+#endif
+ if (k >= 0 && k <= Ten_pmax) {
+ if (dval(d) < tens[k])
+ k--;
+ k_check = 0;
+ }
+ j = bbits - i - 1;
+ if (j >= 0) {
+ b2 = 0;
+ s2 = j;
+ }
+ else {
+ b2 = -j;
+ s2 = 0;
+ }
+ if (k >= 0) {
+ b5 = 0;
+ s5 = k;
+ s2 += k;
+ }
+ else {
+ b2 -= k;
+ b5 = -k;
+ s5 = 0;
+ }
+ if (mode < 0 || mode > 9)
+ mode = 0;
+ try_quick = 1;
+ if (mode > 5) {
+ mode -= 4;
+ try_quick = 0;
+ }
+ leftright = 1;
+ switch(mode) {
+ case 0:
+ case 1:
+ ilim = ilim1 = -1;
+ i = (int)(nbits * .30103) + 3;
+ ndigits = 0;
+ break;
+ case 2:
+ leftright = 0;
+ /*FALLTHROUGH*/
+ case 4:
+ if (ndigits <= 0)
+ ndigits = 1;
+ ilim = ilim1 = i = ndigits;
+ break;
+ case 3:
+ leftright = 0;
+ /*FALLTHROUGH*/
+ case 5:
+ i = ndigits + k + 1;
+ ilim = i;
+ ilim1 = i - 1;
+ if (i <= 0)
+ i = 1;
+ }
+ s = s0 = rv_alloc((size_t)i);
+ if (s == NULL)
+ return NULL;
+
+ if ( (rdir = fpi->rounding - 1) !=0) {
+ if (rdir < 0)
+ rdir = 2;
+ if (kind & STRTOG_Neg)
+ rdir = 3 - rdir;
+ }
+
+ /* Now rdir = 0 ==> round near, 1 ==> round up, 2 ==> round down. */
+
+ if (ilim >= 0 && ilim <= Quick_max && try_quick && !rdir
+#ifndef IMPRECISE_INEXACT
+ && k == 0
+#endif
+ ) {
+
+ /* Try to get by with floating-point arithmetic. */
+
+ i = 0;
+ d2 = dval(d);
+#ifdef IBM
+ if ( (j = 11 - hi0bits(word0(d) & Frac_mask)) !=0)
+ dval(d) /= 1 << j;
+#endif
+ k0 = k;
+ ilim0 = ilim;
+ ieps = 2; /* conservative */
+ if (k > 0) {
+ ds = tens[k&0xf];
+ j = (unsigned int)k >> 4;
+ if (j & Bletch) {
+ /* prevent overflows */
+ j &= Bletch - 1;
+ dval(d) /= bigtens[n_bigtens-1];
+ ieps++;
+ }
+ for(; j; j /= 2, i++)
+ if (j & 1) {
+ ieps++;
+ ds *= bigtens[i];
+ }
+ }
+ else {
+ ds = 1.;
+ if ( (jj1 = -k) !=0) {
+ dval(d) *= tens[jj1 & 0xf];
+ for(j = jj1 >> 4; j; j >>= 1, i++)
+ if (j & 1) {
+ ieps++;
+ dval(d) *= bigtens[i];
+ }
+ }
+ }
+ if (k_check && dval(d) < 1. && ilim > 0) {
+ if (ilim1 <= 0)
+ goto fast_failed;
+ ilim = ilim1;
+ k--;
+ dval(d) *= 10.;
+ ieps++;
+ }
+ dval(eps) = ieps*dval(d) + 7.;
+ word0(eps) -= (P-1)*Exp_msk1;
+ if (ilim == 0) {
+ S = mhi = 0;
+ dval(d) -= 5.;
+ if (dval(d) > dval(eps))
+ goto one_digit;
+ if (dval(d) < -dval(eps))
+ goto no_digits;
+ goto fast_failed;
+ }
+#ifndef No_leftright
+ if (leftright) {
+ /* Use Steele & White method of only
+ * generating digits needed.
+ */
+ dval(eps) = ds*0.5/tens[ilim-1] - dval(eps);
+ for(i = 0;;) {
+ L = (Long)(dval(d)/ds);
+ dval(d) -= L*ds;
+ *s++ = '0' + (int)L;
+ if (dval(d) < dval(eps)) {
+ if (dval(d))
+ inex = STRTOG_Inexlo;
+ goto ret1;
+ }
+ if (ds - dval(d) < dval(eps))
+ goto bump_up;
+ if (++i >= ilim)
+ break;
+ dval(eps) *= 10.;
+ dval(d) *= 10.;
+ }
+ }
+ else {
+#endif
+ /* Generate ilim digits, then fix them up. */
+ dval(eps) *= tens[ilim-1];
+ for(i = 1;; i++, dval(d) *= 10.) {
+ if ( (L = (Long)(dval(d)/ds)) !=0)
+ dval(d) -= L*ds;
+ *s++ = '0' + (int)L;
+ if (i == ilim) {
+ ds *= 0.5;
+ if (dval(d) > ds + dval(eps))
+ goto bump_up;
+ else if (dval(d) < ds - dval(eps)) {
+ while(*--s == '0'){}
+ s++;
+ if (dval(d))
+ inex = STRTOG_Inexlo;
+ goto ret1;
+ }
+ break;
+ }
+ }
+#ifndef No_leftright
+ }
+#endif
+ fast_failed:
+ s = s0;
+ dval(d) = d2;
+ k = k0;
+ ilim = ilim0;
+ }
+
+ /* Do we have a "small" integer? */
+
+ if (be >= 0 && k <= Int_max) {
+ /* Yes. */
+ ds = tens[k];
+ if (ndigits < 0 && ilim <= 0) {
+ S = mhi = 0;
+ if (ilim < 0 || dval(d) <= 5*ds)
+ goto no_digits;
+ goto one_digit;
+ }
+ for(i = 1;; i++, dval(d) *= 10.) {
+ L = dval(d) / ds;
+ dval(d) -= L*ds;
+#ifdef Check_FLT_ROUNDS
+ /* If FLT_ROUNDS == 2, L will usually be high by 1 */
+ if (dval(d) < 0) {
+ L--;
+ dval(d) += ds;
+ }
+#endif
+ *s++ = '0' + (int)L;
+ if (dval(d) == 0.)
+ break;
+ if (i == ilim) {
+ if (rdir) {
+ if (rdir == 1)
+ goto bump_up;
+ inex = STRTOG_Inexlo;
+ goto ret1;
+ }
+ dval(d) += dval(d);
+ if (dval(d) > ds || (dval(d) == ds && L & 1)) {
+ bump_up:
+ inex = STRTOG_Inexhi;
+ while(*--s == '9')
+ if (s == s0) {
+ k++;
+ *s = '0';
+ break;
+ }
+ ++*s++;
+ }
+ else
+ inex = STRTOG_Inexlo;
+ break;
+ }
+ }
+ goto ret1;
+ }
+
+ m2 = b2;
+ m5 = b5;
+ mhi = mlo = 0;
+ if (leftright) {
+ if (mode < 2) {
+ i = nbits - bbits;
+ if (be - i++ < fpi->emin)
+ /* denormal */
+ i = be - fpi->emin + 1;
+ }
+ else {
+ j = ilim - 1;
+ if (m5 >= j)
+ m5 -= j;
+ else {
+ s5 += j -= m5;
+ b5 += j;
+ m5 = 0;
+ }
+ if ((i = ilim) < 0) {
+ m2 -= i;
+ i = 0;
+ }
+ }
+ b2 += i;
+ s2 += i;
+ mhi = i2b(1);
+ }
+ if (m2 > 0 && s2 > 0) {
+ i = m2 < s2 ? m2 : s2;
+ b2 -= i;
+ m2 -= i;
+ s2 -= i;
+ }
+ if (b5 > 0) {
+ if (leftright) {
+ if (m5 > 0) {
+ mhi = pow5mult(mhi, m5);
+ if (mhi == NULL)
+ return NULL;
+ b1 = mult(mhi, b);
+ if (b1 == NULL)
+ return NULL;
+ Bfree(b);
+ b = b1;
+ }
+ if ( (j = b5 - m5) !=0) {
+ b = pow5mult(b, j);
+ if (b == NULL)
+ return NULL;
+ }
+ }
+ else {
+ b = pow5mult(b, b5);
+ if (b == NULL)
+ return NULL;
+ }
+ }
+ S = i2b(1);
+ if (S == NULL)
+ return NULL;
+ if (s5 > 0) {
+ S = pow5mult(S, s5);
+ if (S == NULL)
+ return NULL;
+ }
+
+ /* Check for special case that d is a normalized power of 2. */
+
+ spec_case = 0;
+ if (mode < 2) {
+ if (bbits == 1 && be0 > fpi->emin + 1) {
+ /* The special case */
+ b2++;
+ s2++;
+ spec_case = 1;
+ }
+ }
+
+ /* Arrange for convenient computation of quotients:
+ * shift left if necessary so divisor has 4 leading 0 bits.
+ *
+ * Perhaps we should just compute leading 28 bits of S once
+ * and for all and pass them and a shift to quorem, so it
+ * can do shifts and ors to compute the numerator for q.
+ */
+#ifdef Pack_32
+ if ( (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) !=0)
+ i = 32 - i;
+#else
+ if ( (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) !=0)
+ i = 16 - i;
+#endif
+ if (i > 4) {
+ i -= 4;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+ else if (i < 4) {
+ i += 28;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+ if (b2 > 0)
+ b = lshift(b, b2);
+ if (s2 > 0)
+ S = lshift(S, s2);
+ if (k_check) {
+ if (cmp(b,S) < 0) {
+ k--;
+ b = multadd(b, 10, 0); /* we botched the k estimate */
+ if (b == NULL)
+ return NULL;
+ if (leftright) {
+ mhi = multadd(mhi, 10, 0);
+ if (mhi == NULL)
+ return NULL;
+ }
+ ilim = ilim1;
+ }
+ }
+ if (ilim <= 0 && mode > 2) {
+ if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
+ /* no digits, fcvt style */
+ no_digits:
+ k = -1 - ndigits;
+ inex = STRTOG_Inexlo;
+ goto ret;
+ }
+ one_digit:
+ inex = STRTOG_Inexhi;
+ *s++ = '1';
+ k++;
+ goto ret;
+ }
+ if (leftright) {
+ if (m2 > 0) {
+ mhi = lshift(mhi, m2);
+ if (mhi == NULL)
+ return NULL;
+ }
+
+ /* Compute mlo -- check for special case
+ * that d is a normalized power of 2.
+ */
+
+ mlo = mhi;
+ if (spec_case) {
+ mhi = Balloc(mhi->k);
+ if (mhi == NULL)
+ return NULL;
+ Bcopy(mhi, mlo);
+ mhi = lshift(mhi, 1);
+ if (mhi == NULL)
+ return NULL;
+ }
+
+ for(i = 1;;i++) {
+ dig = quorem(b,S) + '0';
+ /* Do we yet have the shortest decimal string
+ * that will round to d?
+ */
+ j = cmp(b, mlo);
+ delta = diff(S, mhi);
+ if (delta == NULL)
+ return NULL;
+ jj1 = delta->sign ? 1 : cmp(b, delta);
+ Bfree(delta);
+#ifndef ROUND_BIASED
+ if (jj1 == 0 && !mode && !(bits[0] & 1) && !rdir) {
+ if (dig == '9')
+ goto round_9_up;
+ if (j <= 0) {
+ if (b->wds > 1 || b->x[0])
+ inex = STRTOG_Inexlo;
+ }
+ else {
+ dig++;
+ inex = STRTOG_Inexhi;
+ }
+ *s++ = dig;
+ goto ret;
+ }
+#endif
+ if (j < 0 || (j == 0 && !mode
+#ifndef ROUND_BIASED
+ && !(bits[0] & 1)
+#endif
+ )) {
+ if (rdir && (b->wds > 1 || b->x[0])) {
+ if (rdir == 2) {
+ inex = STRTOG_Inexlo;
+ goto accept;
+ }
+ while (cmp(S,mhi) > 0) {
+ *s++ = dig;
+ mhi1 = multadd(mhi, 10, 0);
+ if (mhi1 == NULL)
+ return NULL;
+ if (mlo == mhi)
+ mlo = mhi1;
+ mhi = mhi1;
+ b = multadd(b, 10, 0);
+ if (b == NULL)
+ return NULL;
+ dig = quorem(b,S) + '0';
+ }
+ if (dig++ == '9')
+ goto round_9_up;
+ inex = STRTOG_Inexhi;
+ goto accept;
+ }
+ if (jj1 > 0) {
+ b = lshift(b, 1);
+ if (b == NULL)
+ return NULL;
+ jj1 = cmp(b, S);
+ if ((jj1 > 0 || (jj1 == 0 && dig & 1))
+ && dig++ == '9')
+ goto round_9_up;
+ inex = STRTOG_Inexhi;
+ }
+ if (b->wds > 1 || b->x[0])
+ inex = STRTOG_Inexlo;
+ accept:
+ *s++ = dig;
+ goto ret;
+ }
+ if (jj1 > 0 && rdir != 2) {
+ if (dig == '9') { /* possible if i == 1 */
+ round_9_up:
+ *s++ = '9';
+ inex = STRTOG_Inexhi;
+ goto roundoff;
+ }
+ inex = STRTOG_Inexhi;
+ *s++ = dig + 1;
+ goto ret;
+ }
+ *s++ = dig;
+ if (i == ilim)
+ break;
+ b = multadd(b, 10, 0);
+ if (b == NULL)
+ return NULL;
+ if (mlo == mhi) {
+ mlo = mhi = multadd(mhi, 10, 0);
+ if (mlo == NULL)
+ return NULL;
+ }
+ else {
+ mlo = multadd(mlo, 10, 0);
+ if (mlo == NULL)
+ return NULL;
+ mhi = multadd(mhi, 10, 0);
+ if (mhi == NULL)
+ return NULL;
+ }
+ }
+ }
+ else
+ for(i = 1;; i++) {
+ *s++ = dig = quorem(b,S) + '0';
+ if (i >= ilim)
+ break;
+ b = multadd(b, 10, 0);
+ if (b == NULL)
+ return NULL;
+ }
+
+ /* Round off last digit */
+
+ if (rdir) {
+ if (rdir == 2 || (b->wds <= 1 && !b->x[0]))
+ goto chopzeros;
+ goto roundoff;
+ }
+ b = lshift(b, 1);
+ if (b == NULL)
+ return NULL;
+ j = cmp(b, S);
+ if (j > 0 || (j == 0 && dig & 1)) {
+ roundoff:
+ inex = STRTOG_Inexhi;
+ while(*--s == '9')
+ if (s == s0) {
+ k++;
+ *s++ = '1';
+ goto ret;
+ }
+ ++*s++;
+ }
+ else {
+ chopzeros:
+ if (b->wds > 1 || b->x[0])
+ inex = STRTOG_Inexlo;
+ while(*--s == '0'){}
+ s++;
+ }
+ ret:
+ Bfree(S);
+ if (mhi) {
+ if (mlo && mlo != mhi)
+ Bfree(mlo);
+ Bfree(mhi);
+ }
+ ret1:
+ Bfree(b);
+ *s = 0;
+ *decpt = k + 1;
+ if (rve)
+ *rve = s;
+ *kindp |= inex;
+ return s0;
+ }
diff --git a/StdLib/LibC/gdtoa/gdtoa.h b/StdLib/LibC/gdtoa/gdtoa.h
new file mode 100644
index 0000000000..82f126caf2
--- /dev/null
+++ b/StdLib/LibC/gdtoa/gdtoa.h
@@ -0,0 +1,159 @@
+/* $NetBSD: gdtoa.h,v 1.6.4.1.4.1 2008/04/08 21:10:55 jdc Exp $ */
+
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#ifndef GDTOA_H_INCLUDED
+#define GDTOA_H_INCLUDED
+#include <LibConfig.h>
+
+#include "arith.h"
+
+#ifndef Long
+#define Long EFI_LONG_T
+#endif
+#ifndef ULong
+#define ULong EFI_ULONG_T
+#endif
+#ifndef UShort
+#define UShort uint16_t
+#endif
+
+#ifndef ANSI
+#define ANSI(x) x
+#define Void void
+#endif /* ANSI */
+
+#ifndef CONST
+#define CONST const
+#endif /* CONST */
+
+enum { /* return values from strtodg */
+ STRTOG_Zero = 0,
+ STRTOG_Normal = 1,
+ STRTOG_Denormal = 2,
+ STRTOG_Infinite = 3,
+ STRTOG_NaN = 4,
+ STRTOG_NaNbits = 5,
+ STRTOG_NoNumber = 6,
+ STRTOG_Retmask = 7,
+
+ /* The following may be or-ed into one of the above values. */
+
+ STRTOG_Neg = 0x08,
+ STRTOG_Inexlo = 0x10,
+ STRTOG_Inexhi = 0x20,
+ STRTOG_Inexact = 0x30,
+ STRTOG_Underflow= 0x40,
+ STRTOG_Overflow = 0x80,
+ STRTOG_NoMemory = 0x100
+};
+
+ typedef struct
+FPI {
+ int nbits;
+ int emin;
+ int emax;
+ int rounding;
+ int sudden_underflow;
+} FPI;
+
+enum { /* FPI.rounding values: same as FLT_ROUNDS */
+ FPI_Round_zero = 0,
+ FPI_Round_near = 1,
+ FPI_Round_up = 2,
+ FPI_Round_down = 3
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define dtoa __dtoa
+#define gdtoa __gdtoa
+#define ldtoa __ldtoa
+#define hldtoa __hldtoa
+#define hdtoa __hdtoa
+#define freedtoa __freedtoa
+#define strtodg __strtodg_D2A
+#define strtopQ __strtopQ_D2A
+#define strtopx __strtopx_D2A
+#define strtopxL __strtopxL_D2A
+#define strtord __strtord_D2A
+
+extern char* dtoa ANSI((double d, int mode, int ndigits, int *decpt,
+ int *sign, char **rve));
+extern char* hdtoa ANSI((double d, const char *xdigs, int ndigits, int *decpt,
+ int *sign, char **rve));
+extern char* ldtoa ANSI((long double *ld, int mode, int ndigits, int *decpt,
+ int *sign, char **rve));
+extern char* hldtoa ANSI((long double e, const char *xdigs, int ndigits,
+ int *decpt, int *sign, char **rve));
+
+extern char* gdtoa ANSI((FPI *fpi, int be, ULong *bits, int *kindp,
+ int mode, int ndigits, int *decpt, char **rve));
+extern void freedtoa ANSI((char*));
+extern float strtof ANSI((CONST char *, char **));
+extern double strtod ANSI((CONST char *, char **));
+extern int strtodg ANSI((CONST char*, char**, CONST FPI*, Long*, ULong*));
+
+extern char* g_ddfmt ANSI((char*, double*, int, unsigned));
+extern char* g_dfmt ANSI((char*, double*, int, unsigned));
+extern char* g_ffmt ANSI((char*, float*, int, unsigned));
+extern char* g_Qfmt ANSI((char*, void*, int, unsigned));
+extern char* g_xfmt ANSI((char*, void*, int, unsigned));
+extern char* g_xLfmt ANSI((char*, void*, int, unsigned));
+
+extern int strtoId ANSI((CONST char*, char**, double*, double*));
+extern int strtoIdd ANSI((CONST char*, char**, double*, double*));
+extern int strtoIf ANSI((CONST char*, char**, float*, float*));
+extern int strtoIQ ANSI((CONST char*, char**, void*, void*));
+extern int strtoIx ANSI((CONST char*, char**, void*, void*));
+extern int strtoIxL ANSI((CONST char*, char**, void*, void*));
+extern int strtord ANSI((CONST char*, char**, int, double*));
+extern int strtordd ANSI((CONST char*, char**, int, double*));
+extern int strtorf ANSI((CONST char*, char**, int, float*));
+extern int strtorQ ANSI((CONST char*, char**, int, void*));
+extern int strtorx ANSI((CONST char*, char**, int, void*));
+extern int strtorxL ANSI((CONST char*, char**, int, void*));
+
+extern int strtodI ANSI((CONST char*, char**, double*));
+extern int strtopd ANSI((CONST char*, char**, double*));
+extern int strtopdd ANSI((CONST char*, char**, double*));
+extern int strtopf ANSI((CONST char*, char**, float*));
+extern int strtopQ ANSI((CONST char*, char**, void*));
+extern int strtopx ANSI((CONST char*, char**, void*));
+extern int strtopxL ANSI((CONST char*, char**, void*));
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* GDTOA_H_INCLUDED */
diff --git a/StdLib/LibC/gdtoa/gdtoa.inf b/StdLib/LibC/gdtoa/gdtoa.inf
new file mode 100644
index 0000000000..fbe3ac1b63
--- /dev/null
+++ b/StdLib/LibC/gdtoa/gdtoa.inf
@@ -0,0 +1,77 @@
+## @file
+# This module contains source for a library of binary -> decimal
+# and decimal -> binary conversion routines, for single-, double-,
+# and extended-precision IEEE binary floating-point arithmetic, and
+# other IEEE-like binary floating-point, including "double double".
+#
+# Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = LibGdtoa
+ FILE_GUID = 5c98de6e-cb69-465f-b6b9-f661e26e6f9d
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = LibGdtoa
+
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[Sources.X64]
+ strtof.c
+ strtold_px.c
+ strtopx.c
+
+[Sources.IPF]
+ strtof.c
+ Ipf/strtold.c
+
+[Sources.IA32]
+ strtof.c
+ strtold_px.c
+ strtopx.c
+
+[Sources.ARM]
+ strtof.c
+
+[Sources]
+ strtod.c # Public interfaces
+ atof.c
+
+ # Private interfaces interfacing to libc
+ dtoa.c
+ ldtoa.c
+ gdtoa.c
+
+ # private interfaces
+ dmisc.c
+ gmisc.c
+ hd_init.c
+ hexnan.c
+ misc.c
+ smisc.c
+ strtodg.c
+ sum.c
+ ulp.c
+
+[Packages]
+ StdLib/StdLib.dec
+ StdLibPrivateInternalFiles/DoNotUse.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ LibC
+ LibLocale
+ LibStdLib
+ LibString
diff --git a/StdLib/LibC/gdtoa/gdtoaimp.h b/StdLib/LibC/gdtoa/gdtoaimp.h
new file mode 100644
index 0000000000..635a177544
--- /dev/null
+++ b/StdLib/LibC/gdtoa/gdtoaimp.h
@@ -0,0 +1,661 @@
+/** @file
+ This is a variation on dtoa.c that converts arbitary binary
+ floating-point formats to and from decimal notation. It uses
+ double-precision arithmetic internally, so there are still
+ various #ifdefs that adapt the calculations to the native
+ double-precision arithmetic (any of IEEE, VAX D_floating,
+ or IBM mainframe arithmetic).
+
+ Please send bug reports to David M. Gay (dmg at acm dot org,
+ with " at " changed at "@" and " dot " changed to ".").
+
+ Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ The author of this software is David M. Gay.
+
+ Copyright (C) 1998-2000 by Lucent Technologies
+ All Rights Reserved
+
+ Permission to use, copy, modify, and distribute this software and
+ its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of Lucent or any of its entities
+ not be used in advertising or publicity pertaining to
+ distribution of the software without specific, written prior
+ permission.
+
+ LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+ IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+ SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ THIS SOFTWARE.
+
+$NetBSD: gdtoaimp.h,v 1.5.4.1 2007/05/07 19:49:06 pavel Exp
+**/
+
+/* On a machine with IEEE extended-precision registers, it is
+ * necessary to specify double-precision (53-bit) rounding precision
+ * before invoking strtod or dtoa. If the machine uses (the equivalent
+ * of) Intel 80x87 arithmetic, the call
+ * _control87(PC_53, MCW_PC);
+ * does this with many compilers. Whether this or another call is
+ * appropriate depends on the compiler; for this to work, it may be
+ * necessary to #include "float.h" or another system-dependent header
+ * file.
+ */
+
+/* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
+ *
+ * This strtod returns a nearest machine number to the input decimal
+ * string (or sets errno to ERANGE). With IEEE arithmetic, ties are
+ * broken by the IEEE round-even rule. Otherwise ties are broken by
+ * biased rounding (add half and chop).
+ *
+ * Inspired loosely by William D. Clinger's paper "How to Read Floating
+ * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 112-126].
+ *
+ * Modifications:
+ *
+ * 1. We only require IEEE, IBM, or VAX double-precision
+ * arithmetic (not IEEE double-extended).
+ * 2. We get by with floating-point arithmetic in a case that
+ * Clinger missed -- when we're computing d * 10^n
+ * for a small integer d and the integer n is not too
+ * much larger than 22 (the maximum integer k for which
+ * we can represent 10^k exactly), we may be able to
+ * compute (d*10^k) * 10^(e-k) with just one roundoff.
+ * 3. Rather than a bit-at-a-time adjustment of the binary
+ * result in the hard case, we use floating-point
+ * arithmetic to determine the adjustment to within
+ * one bit; only in really hard cases do we need to
+ * compute a second residual.
+ * 4. Because of 3., we don't need a large table of powers of 10
+ * for ten-to-e (just some small tables, e.g. of 10^k
+ * for 0 <= k <= 22).
+ */
+
+/*
+ * #define IEEE_LITTLE_ENDIAN for IEEE-arithmetic machines where the least
+ * significant byte has the lowest address.
+ * #define IEEE_BIG_ENDIAN for IEEE-arithmetic machines where the most
+ * significant byte has the lowest address.
+ * #define Long int on machines with 32-bit ints and 64-bit longs.
+ * #define Sudden_Underflow for IEEE-format machines without gradual
+ * underflow (i.e., that flush to zero on underflow).
+ * #define IBM for IBM mainframe-style floating-point arithmetic.
+ * #define VAX for VAX-style floating-point arithmetic (D_floating).
+ * #define No_leftright to omit left-right logic in fast floating-point
+ * computation of dtoa.
+ * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3.
+ * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines
+ * that use extended-precision instructions to compute rounded
+ * products and quotients) with IBM.
+ * #define ROUND_BIASED for IEEE-format with biased rounding.
+ * #define Inaccurate_Divide for IEEE-format with correctly rounded
+ * products but inaccurate quotients, e.g., for Intel i860.
+ * #define NO_LONG_LONG on machines that do not have a "long long"
+ * integer type (of >= 64 bits). On such machines, you can
+ * #define Just_16 to store 16 bits per 32-bit Long when doing
+ * high-precision integer arithmetic. Whether this speeds things
+ * up or slows things down depends on the machine and the number
+ * being converted. If long long is available and the name is
+ * something other than "long long", #define Llong to be the name,
+ * and if "unsigned Llong" does not work as an unsigned version of
+ * Llong, #define #ULLong to be the corresponding unsigned type.
+ * #define KR_headers for old-style C function headers.
+ * #define Bad_float_h if your system lacks a float.h or if it does not
+ * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
+ * FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
+ * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n)
+ * if memory is available and otherwise does something you deem
+ * appropriate. If MALLOC is undefined, malloc will be invoked
+ * directly -- and assumed always to succeed.
+ * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making
+ * memory allocations from a private pool of memory when possible.
+ * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes,
+ * unless #defined to be a different length. This default length
+ * suffices to get rid of MALLOC calls except for unusual cases,
+ * such as decimal-to-binary conversion of a very long string of
+ * digits. When converting IEEE double precision values, the
+ * longest string gdtoa can return is about 751 bytes long. For
+ * conversions by strtod of strings of 800 digits and all gdtoa
+ * conversions of IEEE doubles in single-threaded executions with
+ * 8-byte pointers, PRIVATE_MEM >= 7400 appears to suffice; with
+ * 4-byte pointers, PRIVATE_MEM >= 7112 appears adequate.
+ * #define INFNAN_CHECK on IEEE systems to cause strtod to check for
+ * Infinity and NaN (case insensitively).
+ * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined,
+ * strtodg also accepts (case insensitively) strings of the form
+ * NaN(x), where x is a string of hexadecimal digits and spaces;
+ * if there is only one string of hexadecimal digits, it is taken
+ * for the fraction bits of the resulting NaN; if there are two or
+ * more strings of hexadecimal digits, each string is assigned
+ * to the next available sequence of 32-bit words of fractions
+ * bits (starting with the most significant), right-aligned in
+ * each sequence.
+ * #define MULTIPLE_THREADS if the system offers preemptively scheduled
+ * multiple threads. In this case, you must provide (or suitably
+ * #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed
+ * by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed
+ * in pow5mult, ensures lazy evaluation of only one copy of high
+ * powers of 5; omitting this lock would introduce a small
+ * probability of wasting memory, but would otherwise be harmless.)
+ * You must also invoke freedtoa(s) to free the value s returned by
+ * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined.
+ * #define IMPRECISE_INEXACT if you do not care about the setting of
+ * the STRTOG_Inexact bits in the special case of doing IEEE double
+ * precision conversions (which could also be done by the strtog in
+ * dtoa.c).
+ * #define NO_HEX_FP to disable recognition of C9x's hexadecimal
+ * floating-point constants.
+ * #define -DNO_ERRNO to suppress setting errno (in strtod.c and
+ * strtodg.c).
+ * #define NO_STRING_H to use private versions of memcpy.
+ * On some K&R systems, it may also be necessary to
+ * #define DECLARE_SIZE_T in this case.
+ * #define YES_ALIAS to permit aliasing certain double values with
+ * arrays of ULongs. This leads to slightly better code with
+ * some compilers and was always used prior to 19990916, but it
+ * is not strictly legal and can cause trouble with aggressively
+ * optimizing compilers (e.g., gcc 2.95.1 under -O2).
+ * #define USE_LOCALE to use the current locale's decimal_point value.
+ */
+
+/* #define IEEE_{BIG,LITTLE}_ENDIAN in ${ARCHDIR}/gdtoa/arith.h */
+#include <LibConfig.h>
+
+#include <stdint.h>
+#define Short int16_t
+#define UShort uint16_t
+#define Long EFI_LONG_T
+#define ULong EFI_ULONG_T
+#define LLong int64_t
+#define ULLong uint64_t
+
+#define INFNAN_CHECK
+#ifdef _REENTRANT
+#define MULTIPLE_THREADS
+#endif
+#define USE_LOCALE
+
+#ifndef GDTOAIMP_H_INCLUDED
+#define GDTOAIMP_H_INCLUDED
+#include "gdtoa.h"
+#include "gd_qnan.h"
+
+#ifdef DEBUG
+#include "stdio.h"
+#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
+#endif
+
+#include "stdlib.h"
+#include "string.h"
+
+#ifdef KR_headers
+#define Char char
+#else
+#define Char void
+#endif
+
+#ifdef MALLOC
+extern Char *MALLOC ANSI((size_t));
+#else
+#define MALLOC malloc
+#endif
+
+#undef IEEE_Arith
+#undef Avoid_Underflow
+#ifdef IEEE_BIG_ENDIAN
+#define IEEE_Arith
+#endif
+#ifdef IEEE_LITTLE_ENDIAN
+#define IEEE_Arith
+#endif
+
+#include "errno.h"
+#ifdef Bad_float_h
+
+#ifdef IEEE_Arith
+#define DBL_DIG 15
+#define DBL_MAX_10_EXP 308
+#define DBL_MAX_EXP 1024
+#define FLT_RADIX 2
+#define DBL_MAX 1.7976931348623157e+308
+#endif
+
+#ifdef IBM
+#define DBL_DIG 16
+#define DBL_MAX_10_EXP 75
+#define DBL_MAX_EXP 63
+#define FLT_RADIX 16
+#define DBL_MAX 7.2370055773322621e+75
+#endif
+
+#ifdef VAX
+#define DBL_DIG 16
+#define DBL_MAX_10_EXP 38
+#define DBL_MAX_EXP 127
+#define FLT_RADIX 2
+#define DBL_MAX 1.7014118346046923e+38
+#define n_bigtens 2
+#endif
+
+#ifndef LONG_MAX
+#define LONG_MAX 2147483647
+#endif
+
+#else /* ifndef Bad_float_h */
+#include "float.h"
+#endif /* Bad_float_h */
+
+#ifdef IEEE_Arith
+#define Scale_Bit 0x10
+#define n_bigtens 5
+#endif
+
+#ifdef IBM
+#define n_bigtens 3
+#endif
+
+#ifdef VAX
+#define n_bigtens 2
+#endif
+
+#include "math.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + defined(IBM) != 1
+Exactly one of IEEE_LITTLE_ENDIAN, IEEE_BIG_ENDIAN, VAX, or IBM should be defined.
+#endif
+
+typedef union { double d; ULong L[2]; } U;
+//typedef union { double d; UINT32 L[2]; } U;
+
+#ifdef YES_ALIAS
+#define dval(x) x
+#ifdef IEEE_LITTLE_ENDIAN
+#define word0(x) ((ULong *)&x)[1]
+#define word1(x) ((ULong *)&x)[0]
+#else
+#define word0(x) ((ULong *)&x)[0]
+#define word1(x) ((ULong *)&x)[1]
+#endif
+#else /* !YES_ALIAS */
+#ifdef IEEE_LITTLE_ENDIAN
+#define word0(x) ( /* LINTED */ (U*)&x)->L[1]
+#define word1(x) ( /* LINTED */ (U*)&x)->L[0]
+#else
+#define word0(x) ( /* LINTED */ (U*)&x)->L[0]
+#define word1(x) ( /* LINTED */ (U*)&x)->L[1]
+#endif
+#define dval(x) ( /* LINTED */ (U*)&x)->d
+#endif /* YES_ALIAS */
+
+/* The following definition of Storeinc is appropriate for MIPS processors.
+ * An alternative that might be better on some machines is
+ * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
+ */
+#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX)
+#define Storeinc(a,b,c) \
+ (((unsigned short *)(void *)a)[1] = (unsigned short)b, \
+ ((unsigned short *)(void *)a)[0] = (unsigned short)c, \
+ a++)
+#else
+#define Storeinc(a,b,c) \
+ (((unsigned short *)(void *)a)[0] = (unsigned short)b, \
+ ((unsigned short *)(void *)a)[1] = (unsigned short)c, \
+ a++)
+#endif
+
+/* #define P DBL_MANT_DIG */
+/* Ten_pmax = floor(P*log(2)/log(5)) */
+/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
+/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
+/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
+
+#ifdef IEEE_Arith
+#define Exp_shift 20
+#define Exp_shift1 20
+#define Exp_msk1 0x100000
+#define Exp_msk11 0x100000
+#define Exp_mask 0x7ff00000
+#define P 53
+#define Bias 1023
+#define Emin (-1022)
+#define Exp_1 0x3ff00000
+#define Exp_11 0x3ff00000
+#define Ebits 11
+#define Frac_mask 0xfffffU
+#define Frac_mask1 0xfffffU
+#define Ten_pmax 22
+#define Bletch 0x10
+#define Bndry_mask 0xfffffU
+#define Bndry_mask1 0xfffffU
+#define LSB 1
+#define Sign_bit 0x80000000
+#define Log2P 1
+#define Tiny0 0
+#define Tiny1 1
+#define Quick_max 14
+#define Int_max 14
+
+#ifndef Flt_Rounds
+#ifdef FLT_ROUNDS
+#define Flt_Rounds FLT_ROUNDS
+#else
+#define Flt_Rounds 1
+#endif
+#endif /*Flt_Rounds*/
+
+#else /* ifndef IEEE_Arith */
+#undef Sudden_Underflow
+#define Sudden_Underflow
+#ifdef IBM
+#undef Flt_Rounds
+#define Flt_Rounds 0
+#define Exp_shift 24
+#define Exp_shift1 24
+#define Exp_msk1 0x1000000
+#define Exp_msk11 0x1000000
+#define Exp_mask 0x7f000000
+#define P 14
+#define Bias 65
+#define Exp_1 0x41000000
+#define Exp_11 0x41000000
+#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */
+#define Frac_mask 0xffffff
+#define Frac_mask1 0xffffff
+#define Bletch 4
+#define Ten_pmax 22
+#define Bndry_mask 0xefffff
+#define Bndry_mask1 0xffffff
+#define LSB 1
+#define Sign_bit 0x80000000
+#define Log2P 4
+#define Tiny0 0x100000
+#define Tiny1 0
+#define Quick_max 14
+#define Int_max 15
+#else /* VAX */
+#undef Flt_Rounds
+#define Flt_Rounds 1
+#define Exp_shift 23
+#define Exp_shift1 7
+#define Exp_msk1 0x80
+#define Exp_msk11 0x800000
+#define Exp_mask 0x7f80
+#define P 56
+#define Bias 129
+#define Exp_1 0x40800000
+#define Exp_11 0x4080
+#define Ebits 8
+#define Frac_mask 0x7fffff
+#define Frac_mask1 0xffff007f
+#define Ten_pmax 24
+#define Bletch 2
+#define Bndry_mask 0xffff007f
+#define Bndry_mask1 0xffff007f
+#define LSB 0x10000
+#define Sign_bit 0x8000
+#define Log2P 1
+#define Tiny0 0x80
+#define Tiny1 0
+#define Quick_max 15
+#define Int_max 15
+#endif /* IBM, VAX */
+#endif /* IEEE_Arith */
+
+#ifndef IEEE_Arith
+#define ROUND_BIASED
+#endif
+
+#ifdef RND_PRODQUOT
+#define rounded_product(a,b) a = rnd_prod(a, b)
+#define rounded_quotient(a,b) a = rnd_quot(a, b)
+#ifdef KR_headers
+extern double rnd_prod(), rnd_quot();
+#else
+extern double rnd_prod(double, double), rnd_quot(double, double);
+#endif
+#else
+#define rounded_product(a,b) a *= b
+#define rounded_quotient(a,b) a /= b
+#endif
+
+#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
+#define Big1 0xffffffffU
+
+#undef Pack_16
+#ifndef Pack_32
+#define Pack_32
+#endif
+
+#ifdef NO_LONG_LONG
+#undef ULLong
+#ifdef Just_16
+#undef Pack_32
+#define Pack_16
+/* When Pack_32 is not defined, we store 16 bits per 32-bit Long.
+ * This makes some inner loops simpler and sometimes saves work
+ * during multiplications, but it often seems to make things slightly
+ * slower. Hence the default is now to store 32 bits per Long.
+ */
+#endif
+#else /* long long available */
+#ifndef Llong
+#define Llong long long
+#endif
+#ifndef ULLong
+#define ULLong unsigned Llong
+#endif
+#endif /* NO_LONG_LONG */
+
+#ifdef Pack_32
+#define ULbits 32
+#define kshift 5
+#define kmask 31
+#define ALL_ON 0xffffffff
+#else
+#define ULbits 16
+#define kshift 4
+#define kmask 15
+#define ALL_ON 0xffff
+#endif
+
+#ifndef MULTIPLE_THREADS
+#define ACQUIRE_DTOA_LOCK(n) /*nothing*/
+#define FREE_DTOA_LOCK(n) /*nothing*/
+#else
+#include "reentrant.h"
+
+extern mutex_t __gdtoa_locks[2];
+
+#define ACQUIRE_DTOA_LOCK(n) \
+ do { \
+ if (__isthreaded) \
+ mutex_lock(&__gdtoa_locks[n]); \
+ } while (/* CONSTCOND */ 0)
+#define FREE_DTOA_LOCK(n) \
+ do { \
+ if (__isthreaded) \
+ mutex_unlock(&__gdtoa_locks[n]); \
+ } while (/* CONSTCOND */ 0)
+#endif
+
+#define Kmax 15
+
+ struct
+Bigint {
+ struct Bigint *next;
+ int k, maxwds, sign, wds;
+ ULong x[1];
+ };
+
+ typedef struct Bigint Bigint;
+
+#ifdef NO_STRING_H
+#ifdef DECLARE_SIZE_T
+typedef unsigned int size_t;
+#endif
+extern void memcpy_D2A ANSI((void*, const void*, size_t));
+#define Bcopy(x,y) memcpy_D2A(&x->sign,&y->sign,y->wds*sizeof(ULong) + 2*sizeof(int))
+#else /* !NO_STRING_H */
+#define Bcopy(x,y) memcpy(&x->sign,&y->sign,y->wds*sizeof(ULong) + 2*sizeof(int))
+#endif /* NO_STRING_H */
+
+#define Balloc __Balloc_D2A
+#define Bfree __Bfree_D2A
+#define ULtoQ __ULtoQ_D2A
+#define ULtof __ULtof_D2A
+#define ULtod __ULtod_D2A
+#define ULtodd __ULtodd_D2A
+#define ULtox __ULtox_D2A
+#define ULtoxL __ULtoxL_D2A
+#define any_on __any_on_D2A
+#define b2d __b2d_D2A
+#define bigtens __bigtens_D2A
+#define cmp __cmp_D2A
+#define copybits __copybits_D2A
+#define d2b __d2b_D2A
+#define decrement __decrement_D2A
+#define diff __diff_D2A
+#define dtoa_result __dtoa_result_D2A
+#define g__fmt __g__fmt_D2A
+#define gethex __gethex_D2A
+#define hexdig __hexdig_D2A
+#define hexdig_init_D2A __hexdig_init_D2A
+#define hexnan __hexnan_D2A
+#define hi0bits __hi0bits_D2A
+#define hi0bits_D2A __hi0bits_D2A
+#define i2b __i2b_D2A
+#define increment __increment_D2A
+#define lo0bits __lo0bits_D2A
+#define lshift __lshift_D2A
+#define match __match_D2A
+#define mult __mult_D2A
+#define multadd __multadd_D2A
+#define nrv_alloc __nrv_alloc_D2A
+#define pow5mult __pow5mult_D2A
+#define quorem __quorem_D2A
+#define ratio __ratio_D2A
+#define rshift __rshift_D2A
+#define rv_alloc __rv_alloc_D2A
+#define s2b __s2b_D2A
+#define set_ones __set_ones_D2A
+#define strcp __strcp_D2A
+#define strcp_D2A __strcp_D2A
+#define strtoIg __strtoIg_D2A
+#define sum __sum_D2A
+#define tens __tens_D2A
+#define tinytens __tinytens_D2A
+#define tinytens __tinytens_D2A
+#define trailz __trailz_D2A
+#define ulp __ulp_D2A
+
+extern char *dtoa_result;
+extern CONST double bigtens[], tens[], tinytens[];
+extern unsigned char hexdig[];
+
+extern Bigint *Balloc (int);
+extern void Bfree (Bigint*);
+extern void ULtof (ULong*, ULong*, Long, int);
+extern void ULtod (ULong*, ULong*, Long, int);
+extern void ULtodd (ULong*, ULong*, Long, int);
+extern void ULtoQ (ULong*, ULong*, Long, int);
+extern void ULtox (UShort*, ULong*, Long, int);
+extern void ULtoxL (ULong*, ULong*, Long, int);
+extern ULong any_on (Bigint*, int);
+extern double b2d (Bigint*, int*);
+extern int cmp (Bigint*, Bigint*);
+extern void copybits (ULong*, int, Bigint*);
+extern Bigint *d2b (double, int*, int*);
+extern int decrement (Bigint*);
+extern Bigint *diff (Bigint*, Bigint*);
+extern char *dtoa (double d, int mode, int ndigits,
+ int *decpt, int *sign, char **rve);
+extern char *g__fmt (char*, char*, char*, int, ULong);
+extern int gethex (CONST char**, CONST FPI*, Long*, Bigint**, int);
+extern void hexdig_init_D2A(Void);
+extern int hexnan (CONST char**, CONST FPI*, ULong*);
+extern int hi0bits_D2A (ULong);
+extern Bigint *i2b (int);
+extern Bigint *increment (Bigint*);
+extern int lo0bits (ULong*);
+extern Bigint *lshift (Bigint*, int);
+extern int match (CONST char**, CONST char*);
+extern Bigint *mult (Bigint*, Bigint*);
+extern Bigint *multadd (Bigint*, int, int);
+extern char *nrv_alloc (CONST char*, char **, size_t);
+extern Bigint *pow5mult (Bigint*, int);
+extern int quorem (Bigint*, Bigint*);
+extern double ratio (Bigint*, Bigint*);
+extern void rshift (Bigint*, int);
+extern char *rv_alloc (size_t);
+extern Bigint *s2b (CONST char*, int, int, ULong);
+extern Bigint *set_ones (Bigint*, int);
+extern char *strcp (char*, const char*);
+extern int strtoIg (CONST char*, char**, FPI*, Long*, Bigint**, int*);
+extern double strtod (const char *s00, char **se);
+extern Bigint *sum (Bigint*, Bigint*);
+extern int trailz (CONST Bigint*);
+extern double ulp (double);
+
+#ifdef __cplusplus
+}
+#endif
+/*
+ * NAN_WORD0 and NAN_WORD1 are only referenced in strtod.c. Prior to
+ * 20050115, they used to be hard-wired here (to 0x7ff80000 and 0,
+ * respectively), but now are determined by compiling and running
+ * qnan.c to generate gd_qnan.h, which specifies d_QNAN0 and d_QNAN1.
+ * Formerly gdtoaimp.h recommended supplying suitable -DNAN_WORD0=...
+ * and -DNAN_WORD1=... values if necessary. This should still work.
+ * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.)
+ */
+#ifdef IEEE_Arith
+#ifdef IEEE_BIG_ENDIAN
+#define _0 0
+#define _1 1
+#ifndef NAN_WORD0
+#define NAN_WORD0 d_QNAN0
+#endif
+#ifndef NAN_WORD1
+#define NAN_WORD1 d_QNAN1
+#endif
+#else
+#define _0 1
+#define _1 0
+#ifndef NAN_WORD0
+#define NAN_WORD0 d_QNAN1
+#endif
+#ifndef NAN_WORD1
+#define NAN_WORD1 d_QNAN0
+#endif
+#endif
+#else
+#undef INFNAN_CHECK
+#endif
+
+#undef SI
+#ifdef Sudden_Underflow
+#define SI 1
+#else
+#define SI 0
+#endif
+
+#endif /* GDTOAIMP_H_INCLUDED */
diff --git a/StdLib/LibC/gdtoa/gethex.c b/StdLib/LibC/gdtoa/gethex.c
new file mode 100644
index 0000000000..02920e748c
--- /dev/null
+++ b/StdLib/LibC/gdtoa/gethex.c
@@ -0,0 +1,249 @@
+/* $NetBSD: gethex.c,v 1.3.14.1 2008/04/08 21:10:55 jdc Exp $ */
+
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+#include <LibConfig.h>
+
+#include "gdtoaimp.h"
+
+#ifdef USE_LOCALE
+#include "locale.h"
+#endif
+
+ int
+gethex( CONST char **sp, CONST FPI *fpi, Long *expt, Bigint **bp, int sign)
+{
+ Bigint *b;
+ CONST unsigned char *decpt, *s0, *s, *s1;
+ int esign, havedig, irv, k, n, nbits, up, zret;
+ ULong L, lostbits, *x;
+ Long e, e1;
+#ifdef USE_LOCALE
+ unsigned char decimalpoint = *localeconv()->decimal_point;
+#else
+#define decimalpoint '.'
+#endif
+
+ if (!hexdig['0'])
+ hexdig_init_D2A();
+ havedig = 0;
+ s0 = *(CONST unsigned char **)sp + 2;
+ while(s0[havedig] == '0')
+ havedig++;
+ s0 += havedig;
+ s = s0;
+ decpt = 0;
+ zret = 0;
+ e = 0;
+ if (!hexdig[*s]) {
+ zret = 1;
+ if (*s != decimalpoint)
+ goto pcheck;
+ decpt = ++s;
+ if (!hexdig[*s])
+ goto pcheck;
+ while(*s == '0')
+ s++;
+ if (hexdig[*s])
+ zret = 0;
+ havedig = 1;
+ s0 = s;
+ }
+ while(hexdig[*s])
+ s++;
+ if (*s == decimalpoint && !decpt) {
+ decpt = ++s;
+ while(hexdig[*s])
+ s++;
+ }
+ if (decpt)
+ e = -(((Long)(s-decpt)) << 2);
+ pcheck:
+ s1 = s;
+ switch(*s) {
+ case 'p':
+ case 'P':
+ esign = 0;
+ switch(*++s) {
+ case '-':
+ esign = 1;
+ /* FALLTHROUGH */
+ case '+':
+ s++;
+ }
+ if ((n = hexdig[*s]) == 0 || n > 0x19) {
+ s = s1;
+ break;
+ }
+ e1 = n - 0x10;
+ while((n = hexdig[*++s]) !=0 && n <= 0x19)
+ e1 = 10*e1 + n - 0x10;
+ if (esign)
+ e1 = -e1;
+ e += e1;
+ }
+ *sp = __UNCONST(s);
+ if (zret)
+ return havedig ? STRTOG_Zero : STRTOG_NoNumber;
+ n = (int)(s1 - s0 - 1);
+ for(k = 0; n > 7; n = (unsigned int)n >> 1)
+ k++;
+ b = Balloc(k);
+ if (b == NULL)
+ return STRTOG_NoMemory;
+ x = b->x;
+ n = 0;
+ L = 0;
+ while(s1 > s0) {
+ if (*--s1 == decimalpoint)
+ continue;
+ if (n == 32) {
+ *x++ = L;
+ L = 0;
+ n = 0;
+ }
+ L |= (hexdig[*s1] & 0x0f) << n;
+ n += 4;
+ }
+ *x++ = L;
+ b->wds = n = (int)(x - b->x);
+ n = 32*n - hi0bits(L);
+ nbits = fpi->nbits;
+ lostbits = 0;
+ x = b->x;
+ if (n > nbits) {
+ n -= nbits;
+ if (any_on(b,n)) {
+ lostbits = 1;
+ k = n - 1;
+ if (x[(unsigned int)k>>kshift] & 1 << (k & kmask)) {
+ lostbits = 2;
+ if (k > 1 && any_on(b,k-1))
+ lostbits = 3;
+ }
+ }
+ rshift(b, n);
+ e += n;
+ }
+ else if (n < nbits) {
+ n = nbits - n;
+ b = lshift(b, n);
+ if (b == NULL)
+ return STRTOG_NoMemory;
+ e -= n;
+ x = b->x;
+ }
+ if (e > fpi->emax) {
+ ovfl:
+ Bfree(b);
+ *bp = 0;
+ return STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi;
+ }
+ irv = STRTOG_Normal;
+ if (e < fpi->emin) {
+ irv = STRTOG_Denormal;
+ n = fpi->emin - e;
+ if (n >= nbits) {
+ switch (fpi->rounding) {
+ case FPI_Round_near:
+ if (n == nbits && (n < 2 || any_on(b,n-1)))
+ goto one_bit;
+ break;
+ case FPI_Round_up:
+ if (!sign)
+ goto one_bit;
+ break;
+ case FPI_Round_down:
+ if (sign) {
+ one_bit:
+ *expt = fpi->emin;
+ x[0] = b->wds = 1;
+ *bp = b;
+ return STRTOG_Denormal | STRTOG_Inexhi
+ | STRTOG_Underflow;
+ }
+ }
+ Bfree(b);
+ *bp = 0;
+ return STRTOG_Zero | STRTOG_Inexlo | STRTOG_Underflow;
+ }
+ k = n - 1;
+ if (lostbits)
+ lostbits = 1;
+ else if (k > 0)
+ lostbits = any_on(b,k);
+ if (x[(unsigned int)k>>kshift] & 1 << (k & kmask))
+ lostbits |= 2;
+ nbits -= n;
+ rshift(b,n);
+ e = fpi->emin;
+ }
+ if (lostbits) {
+ up = 0;
+ switch(fpi->rounding) {
+ case FPI_Round_zero:
+ break;
+ case FPI_Round_near:
+ if (lostbits & 2
+ && (lostbits & 1) | (x[0] & 1))
+ up = 1;
+ break;
+ case FPI_Round_up:
+ up = 1 - sign;
+ break;
+ case FPI_Round_down:
+ up = sign;
+ }
+ if (up) {
+ k = b->wds;
+ b = increment(b);
+ x = b->x;
+ if (irv == STRTOG_Denormal) {
+ if (nbits == fpi->nbits - 1
+ && x[(unsigned int)nbits >> kshift] & 1 << (nbits & kmask))
+ irv = STRTOG_Normal;
+ }
+ else if (b->wds > k
+ || ((n = nbits & kmask) !=0
+ && hi0bits(x[k-1]) < 32-n)) {
+ rshift(b,1);
+ if (++e > fpi->emax)
+ goto ovfl;
+ }
+ irv |= STRTOG_Inexhi;
+ }
+ else
+ irv |= STRTOG_Inexlo;
+ }
+ *bp = b;
+ *expt = e;
+ return irv;
+ }
diff --git a/StdLib/LibC/gdtoa/gmisc.c b/StdLib/LibC/gdtoa/gmisc.c
new file mode 100644
index 0000000000..e185940ad8
--- /dev/null
+++ b/StdLib/LibC/gdtoa/gmisc.c
@@ -0,0 +1,82 @@
+/* $NetBSD: gmisc.c,v 1.3 2006/03/11 18:38:14 kleink Exp $ */
+
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+#include <LibConfig.h>
+
+#include "gdtoaimp.h"
+
+ void
+rshift(Bigint *b, int k)
+{
+ ULong *x, *x1, *xe, y;
+ int n;
+
+ x = x1 = b->x;
+ n = (unsigned int)k >> kshift;
+ if (n < b->wds) {
+ xe = x + b->wds;
+ x += n;
+ if (k &= kmask) {
+ n = ULbits - k;
+ y = *x++ >> k;
+ while(x < xe) {
+ *x1++ = (y | (*x << n)) & ALL_ON;
+ y = *x++ >> k;
+ }
+ if ((*x1 = y) !=0)
+ x1++;
+ }
+ else
+ while(x < xe)
+ *x1++ = *x++;
+ }
+ if ((b->wds = (int)(x1 - b->x)) == 0)
+ b->x[0] = 0;
+ }
+
+ int
+trailz(CONST Bigint *b)
+{
+ ULong L;
+ CONST ULong *x, *xe;
+ int n = 0;
+
+ x = b->x;
+ xe = x + b->wds;
+ for(n = 0; x < xe && !*x; x++)
+ n += ULbits;
+ if (x < xe) {
+ L = *x;
+ n += lo0bits(&L);
+ }
+ return n;
+ }
diff --git a/StdLib/LibC/gdtoa/hd_init.c b/StdLib/LibC/gdtoa/hd_init.c
new file mode 100644
index 0000000000..bcf76c2468
--- /dev/null
+++ b/StdLib/LibC/gdtoa/hd_init.c
@@ -0,0 +1,58 @@
+/* $NetBSD: hd_init.c,v 1.2 2006/01/25 15:27:42 kleink Exp $ */
+
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 2000 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+#include <LibConfig.h>
+
+#include "gdtoaimp.h"
+
+ unsigned char hexdig[256];
+
+ static void
+#ifdef KR_headers
+htinit(h, s, inc) unsigned char *h; CONST unsigned char *s; int inc;
+#else
+htinit(unsigned char *h, CONST unsigned char *s, int inc)
+#endif
+{
+ int i, j;
+ for(i = 0; (j = s[i]) !=0; i++)
+ h[j] = (unsigned char)(i + inc);
+ }
+
+ void
+hexdig_init_D2A(Void)
+{
+#define USC (CONST unsigned char *)
+ htinit(hexdig, USC "0123456789", 0x10);
+ htinit(hexdig, USC "abcdef", 0x10 + 10);
+ htinit(hexdig, USC "ABCDEF", 0x10 + 10);
+ }
diff --git a/StdLib/LibC/gdtoa/hexnan.c b/StdLib/LibC/gdtoa/hexnan.c
new file mode 100644
index 0000000000..971e217552
--- /dev/null
+++ b/StdLib/LibC/gdtoa/hexnan.c
@@ -0,0 +1,134 @@
+/* $NetBSD: hexnan.c,v 1.3 2006/03/11 18:38:14 kleink Exp $ */
+
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 2000 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+#include <LibConfig.h>
+
+#include "gdtoaimp.h"
+
+ static void
+#ifdef KR_headers
+L_shift(x, x1, i) ULong *x; ULong *x1; int i;
+#else
+L_shift(ULong *x, ULong *x1, int i)
+#endif
+{
+ int j;
+
+ i = 8 - i;
+ i <<= 2;
+ j = ULbits - i;
+ do {
+ *x |= x[1] << j;
+ x[1] >>= i;
+ } while(++x < x1);
+ }
+
+ int
+#ifdef KR_headers
+hexnan(sp, fpi, x0)
+ CONST char **sp; CONST FPI *fpi; ULong *x0;
+#else
+hexnan( CONST char **sp, CONST FPI *fpi, ULong *x0)
+#endif
+{
+ ULong c, h, *x, *x1, *xe;
+ CONST char *s;
+ int havedig, hd0, i, nbits;
+
+ if (!hexdig['0'])
+ hexdig_init_D2A();
+ nbits = fpi->nbits;
+ x = x0 + ((unsigned int)nbits >> kshift);
+ if (nbits & kmask)
+ x++;
+ *--x = 0;
+ x1 = xe = x;
+ havedig = hd0 = i = 0;
+ s = *sp;
+ while((c = *(CONST unsigned char*)++s) != 0) {
+ if ((h = hexdig[c]) == 0) {
+ if (c <= ' ') {
+ if (hd0 < havedig) {
+ if (x < x1 && i < 8)
+ L_shift(x, x1, i);
+ if (x <= x0) {
+ i = 8;
+ continue;
+ }
+ hd0 = havedig;
+ *--x = 0;
+ x1 = x;
+ i = 0;
+ }
+ continue;
+ }
+ if (/*(*/ c == ')' && havedig) {
+ *sp = s + 1;
+ break;
+ }
+ return STRTOG_NaN;
+ }
+ havedig++;
+ if (++i > 8) {
+ if (x <= x0)
+ continue;
+ i = 1;
+ *--x = 0;
+ }
+ *x = (*x << 4) | (h & 0xf);
+ }
+ if (!havedig)
+ return STRTOG_NaN;
+ if (x < x1 && i < 8)
+ L_shift(x, x1, i);
+ if (x > x0) {
+ x1 = x0;
+ do *x1++ = *x++;
+ while(x <= xe);
+ do *x1++ = 0;
+ while(x1 <= xe);
+ }
+ else {
+ /* truncate high-order word if necessary */
+ if ( (i = nbits & (ULbits-1)) !=0)
+ *xe &= ((ULong)0xffffffff) >> (ULbits - i);
+ }
+ for(x1 = xe;; --x1) {
+ if (*x1 != 0)
+ break;
+ if (x1 == x0) {
+ *x1 = 1;
+ break;
+ }
+ }
+ return STRTOG_NaNbits;
+ }
diff --git a/StdLib/LibC/gdtoa/ldtoa.c b/StdLib/LibC/gdtoa/ldtoa.c
new file mode 100644
index 0000000000..8e38b624e4
--- /dev/null
+++ b/StdLib/LibC/gdtoa/ldtoa.c
@@ -0,0 +1,113 @@
+/* $NetBSD: ldtoa.c,v 1.4.2.1 2007/05/07 19:49:06 pavel Exp $ */
+
+/*-
+ * Copyright (c) 2003 David Schultz <das@FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#include <float.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <math.h>
+#include <stdlib.h>
+#include <machine/ieee.h>
+#include "gdtoaimp.h"
+
+#if defined(_MSC_VER)
+ /* Disable warnings about conversions to narrower data types,
+ primarily for the fpclassify() macro.
+ */
+ #pragma warning ( disable : 4244 )
+ // Squelch bogus warnings about uninitialized variable use.
+ #pragma warning ( disable : 4700 )
+#endif
+
+/*
+ * ldtoa() is a wrapper for gdtoa() that makes it smell like dtoa(),
+ * except that the floating point argument is passed by reference.
+ * When dtoa() is passed a NaN or infinity, it sets expt to 9999.
+ * However, a long double could have a valid exponent of 9999, so we
+ * use INT_MAX in ldtoa() instead.
+ */
+char *
+ldtoa(long double *ld, int mode, int ndigits, int *decpt, int *sign, char **rve)
+{
+#ifdef EXT_EXPBITS
+ static FPI fpi = {
+ LDBL_MANT_DIG, /* nbits */
+ LDBL_MIN_EXP - LDBL_MANT_DIG, /* emin */
+ LDBL_MAX_EXP - LDBL_MANT_DIG, /* emax */
+ FPI_Round_near, /* rounding */
+#ifdef Sudden_Underflow /* unused, but correct anyway */
+ 1
+#else
+ 0
+#endif
+ };
+ int be, kind;
+ char *ret;
+ union ieee_ext_u u;
+ uint32_t bits[(LDBL_MANT_DIG + 31) / 32];
+
+ u.extu_ld = *ld;
+ *sign = (int)(u.extu_ext.ext_sign);
+ be = (int)(u.extu_ext.ext_exp - (LDBL_MAX_EXP - 1) - (LDBL_MANT_DIG - 1));
+ EXT_TO_ARRAY32(u, bits);
+
+ switch (fpclassify(u.extu_ld)) {
+ case FP_NORMAL:
+ kind = STRTOG_Normal;
+#ifdef LDBL_IMPLICIT_NBIT
+ bits[LDBL_MANT_DIG / 32] |= 1 << ((LDBL_MANT_DIG - 1) % 32);
+#endif /* LDBL_IMPLICIT_NBIT */
+ break;
+ case FP_ZERO:
+ kind = STRTOG_Zero;
+ break;
+ case FP_SUBNORMAL:
+ kind = STRTOG_Denormal;
+#ifdef LDBL_IMPLICIT_NBIT
+ be++;
+#endif
+ break;
+ case FP_INFINITE:
+ kind = STRTOG_Infinite;
+ break;
+ case FP_NAN:
+ kind = STRTOG_NaN;
+ break;
+ default:
+ abort();
+ }
+
+ ret = gdtoa(&fpi, be, (ULong *)bits, &kind, mode, ndigits, decpt, rve);
+ if (*decpt == -32768)
+ *decpt = INT_MAX;
+ return ret;
+#else
+ return dtoa((double)*ld, mode, ndigits, decpt, sign, rve);
+#endif
+}
diff --git a/StdLib/LibC/gdtoa/misc.c b/StdLib/LibC/gdtoa/misc.c
new file mode 100644
index 0000000000..902074530f
--- /dev/null
+++ b/StdLib/LibC/gdtoa/misc.c
@@ -0,0 +1,909 @@
+/* $NetBSD: misc.c,v 1.3.12.1 2008/04/08 21:10:55 jdc Exp $ */
+
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998, 1999 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+#include <LibConfig.h>
+
+#include "gdtoaimp.h"
+
+#if defined(_MSC_VER)
+ // Disable warnings about assignment within conditional expressions.
+ #pragma warning ( disable : 4706 )
+#endif
+
+static Bigint *freelist[Kmax+1];
+#ifndef Omit_Private_Memory
+#ifndef PRIVATE_MEM
+#define PRIVATE_MEM 2304
+#endif
+#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
+static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
+#endif
+
+ Bigint *
+Balloc
+#ifdef KR_headers
+ (k) int k;
+#else
+ (int k)
+#endif
+{
+ int x;
+ Bigint *rv;
+#ifndef Omit_Private_Memory
+ unsigned int len;
+#endif
+
+ ACQUIRE_DTOA_LOCK(0);
+ if ( (rv = freelist[k]) !=0) {
+ freelist[k] = rv->next;
+ }
+ else {
+ x = 1 << k;
+#ifdef Omit_Private_Memory
+ rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
+#else
+ len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
+ /sizeof(double);
+ if (pmem_next - private_mem + len <= PRIVATE_mem) {
+ rv = (Bigint*)(void *)pmem_next;
+ pmem_next += len;
+ }
+ else
+ rv = (Bigint*)MALLOC(len*sizeof(double));
+#endif
+ if (rv == NULL)
+ return NULL;
+ rv->k = k;
+ rv->maxwds = x;
+ }
+ FREE_DTOA_LOCK(0);
+ rv->sign = rv->wds = 0;
+ return rv;
+ }
+
+ void
+Bfree
+#ifdef KR_headers
+ (v) Bigint *v;
+#else
+ (Bigint *v)
+#endif
+{
+ if (v) {
+ ACQUIRE_DTOA_LOCK(0);
+ v->next = freelist[v->k];
+ freelist[v->k] = v;
+ FREE_DTOA_LOCK(0);
+ }
+ }
+
+ int
+lo0bits
+#ifdef KR_headers
+ (y) ULong *y;
+#else
+ (ULong *y)
+#endif
+{
+ int k;
+ ULong x = *y;
+
+ if (x & 7) {
+ if (x & 1)
+ return 0;
+ if (x & 2) {
+ *y = x >> 1;
+ return 1;
+ }
+ *y = x >> 2;
+ return 2;
+ }
+ k = 0;
+ if (!(x & 0xffff)) {
+ k = 16;
+ x >>= 16;
+ }
+ if (!(x & 0xff)) {
+ k += 8;
+ x >>= 8;
+ }
+ if (!(x & 0xf)) {
+ k += 4;
+ x >>= 4;
+ }
+ if (!(x & 0x3)) {
+ k += 2;
+ x >>= 2;
+ }
+ if (!(x & 1)) {
+ k++;
+ x >>= 1;
+ if (!x)
+ return 32;
+ }
+ *y = x;
+ return k;
+ }
+
+ Bigint *
+multadd
+#ifdef KR_headers
+ (b, m, a) Bigint *b; int m, a;
+#else
+ (Bigint *b, int m, int a) /* multiply by m and add a */
+#endif
+{
+ int i, wds;
+#ifdef ULLong
+ ULong *x;
+ ULLong carry, y;
+#else
+ ULong carry, *x, y;
+#ifdef Pack_32
+ ULong xi, z;
+#endif
+#endif
+ Bigint *b1;
+
+ wds = b->wds;
+ x = b->x;
+ i = 0;
+ carry = a;
+ do {
+#ifdef ULLong
+ y = *x * (ULLong)m + carry;
+ carry = y >> 32;
+ /* LINTED conversion */
+ *x++ = (uint32_t)(y & 0xffffffffUL);
+#else
+#ifdef Pack_32
+ xi = *x;
+ y = (xi & 0xffff) * m + carry;
+ z = (xi >> 16) * m + (y >> 16);
+ carry = z >> 16;
+ *x++ = (z << 16) + (y & 0xffff);
+#else
+ y = *x * m + carry;
+ carry = y >> 16;
+ *x++ = y & 0xffff;
+#endif
+#endif
+ }
+ while(++i < wds);
+ if (carry) {
+ if (wds >= b->maxwds) {
+ b1 = Balloc(b->k+1);
+ if (b1 == NULL) {
+ Bfree(b);
+ return NULL;
+ }
+ Bcopy(b1, b);
+ Bfree(b);
+ b = b1;
+ }
+ /* LINTED conversion */
+ b->x[wds++] = (uint32_t)carry;
+ b->wds = wds;
+ }
+ return b;
+ }
+
+ int
+hi0bits_D2A
+#ifdef KR_headers
+ (x) ULong x;
+#else
+ (ULong x)
+#endif
+{
+ int k = 0;
+
+ if (!(x & 0xffff0000)) {
+ k = 16;
+ x <<= 16;
+ }
+ if (!(x & 0xff000000)) {
+ k += 8;
+ x <<= 8;
+ }
+ if (!(x & 0xf0000000)) {
+ k += 4;
+ x <<= 4;
+ }
+ if (!(x & 0xc0000000)) {
+ k += 2;
+ x <<= 2;
+ }
+ if (!(x & 0x80000000)) {
+ k++;
+ if (!(x & 0x40000000))
+ return 32;
+ }
+ return k;
+ }
+
+ Bigint *
+i2b
+#ifdef KR_headers
+ (i) int i;
+#else
+ (int i)
+#endif
+{
+ Bigint *b;
+
+ b = Balloc(1);
+ if (b == NULL)
+ return NULL;
+ b->x[0] = i;
+ b->wds = 1;
+ return b;
+ }
+
+ Bigint *
+mult
+#ifdef KR_headers
+ (a, b) Bigint *a, *b;
+#else
+ (Bigint *a, Bigint *b)
+#endif
+{
+ Bigint *c;
+ int k, wa, wb, wc;
+ ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
+ ULong y;
+#ifdef ULLong
+ ULLong carry, z;
+#else
+ ULong carry, z;
+#ifdef Pack_32
+ ULong z2;
+#endif
+#endif
+
+ if (a->wds < b->wds) {
+ c = a;
+ a = b;
+ b = c;
+ }
+ k = a->k;
+ wa = a->wds;
+ wb = b->wds;
+ wc = wa + wb;
+ if (wc > a->maxwds)
+ k++;
+ c = Balloc(k);
+ if (c == NULL)
+ return NULL;
+ for(x = c->x, xa = x + wc; x < xa; x++)
+ *x = 0;
+ xa = a->x;
+ xae = xa + wa;
+ xb = b->x;
+ xbe = xb + wb;
+ xc0 = c->x;
+#ifdef ULLong
+ for(; xb < xbe; xc0++) {
+ if ( (y = *xb++) !=0) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do {
+ z = *x++ * (ULLong)y + *xc + carry;
+ carry = z >> 32;
+ /* LINTED conversion */
+ *xc++ = (uint32_t)(z & 0xffffffffUL);
+ }
+ while(x < xae);
+ /* LINTED conversion */
+ *xc = (uint32_t)carry;
+ }
+ }
+#else
+#ifdef Pack_32
+ for(; xb < xbe; xb++, xc0++) {
+ if ( (y = *xb & 0xffff) !=0) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do {
+ z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
+ carry = z >> 16;
+ z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
+ carry = z2 >> 16;
+ Storeinc(xc, z2, z);
+ }
+ while(x < xae);
+ *xc = carry;
+ }
+ if ( (y = *xb >> 16) !=0) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ z2 = *xc;
+ do {
+ z = (*x & 0xffff) * y + (*xc >> 16) + carry;
+ carry = z >> 16;
+ Storeinc(xc, z, z2);
+ z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
+ carry = z2 >> 16;
+ }
+ while(x < xae);
+ *xc = z2;
+ }
+ }
+#else
+ for(; xb < xbe; xc0++) {
+ if ( (y = *xb++) !=0) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do {
+ z = *x++ * y + *xc + carry;
+ carry = z >> 16;
+ *xc++ = z & 0xffff;
+ }
+ while(x < xae);
+ *xc = carry;
+ }
+ }
+#endif
+#endif
+ for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
+ c->wds = wc;
+ return c;
+ }
+
+ static Bigint *p5s;
+
+ Bigint *
+pow5mult
+#ifdef KR_headers
+ (b, k) Bigint *b; int k;
+#else
+ (Bigint *b, int k)
+#endif
+{
+ Bigint *b1, *p5, *p51;
+ int i;
+ static CONST int p05[3] = { 5, 25, 125 };
+
+ if ( (i = k & 3) !=0) {
+ b = multadd(b, p05[i-1], 0);
+ if (b == NULL)
+ return NULL;
+ }
+
+ if ((k = (unsigned int)k >> 2) == 0)
+ return b;
+ if ((p5 = p5s) == 0) {
+ /* first time */
+#ifdef MULTIPLE_THREADS
+ ACQUIRE_DTOA_LOCK(1);
+ if (!(p5 = p5s)) {
+ p5 = p5s = i2b(625);
+ if (p5 == NULL)
+ return NULL;
+ p5->next = 0;
+ }
+ FREE_DTOA_LOCK(1);
+#else
+ p5 = p5s = i2b(625);
+ if (p5 == NULL)
+ return NULL;
+ p5->next = 0;
+#endif
+ }
+ for(;;) {
+ if (k & 1) {
+ b1 = mult(b, p5);
+ if (b1 == NULL)
+ return NULL;
+ b = b1;
+ }
+ if ((k = (unsigned int)k >> 1) == 0)
+ break;
+ if ((p51 = p5->next) == 0) {
+#ifdef MULTIPLE_THREADS
+ ACQUIRE_DTOA_LOCK(1);
+ if (!(p51 = p5->next)) {
+ p51 = p5->next = mult(p5,p5);
+ if (p51 == NULL)
+ return NULL;
+ p51->next = 0;
+ }
+ FREE_DTOA_LOCK(1);
+#else
+ p51 = p5->next = mult(p5,p5);
+ if (p51 == NULL)
+ return NULL;
+ p51->next = 0;
+#endif
+ }
+ p5 = p51;
+ }
+ return b;
+ }
+
+ Bigint *
+lshift
+#ifdef KR_headers
+ (b, k) Bigint *b; int k;
+#else
+ (Bigint *b, int k)
+#endif
+{
+ int i, k1, n, n1;
+ Bigint *b1;
+ ULong *x, *x1, *xe, z;
+
+ n = (unsigned int)k >> kshift;
+ k1 = b->k;
+ n1 = n + b->wds + 1;
+ for(i = b->maxwds; n1 > i; i <<= 1)
+ k1++;
+ b1 = Balloc(k1);
+ if (b1 == NULL)
+ return NULL;
+ x1 = b1->x;
+ for(i = 0; i < n; i++)
+ *x1++ = 0;
+ x = b->x;
+ xe = x + b->wds;
+ if (k &= kmask) {
+#ifdef Pack_32
+ k1 = 32 - k;
+ z = 0;
+ do {
+ *x1++ = *x << k | z;
+ z = *x++ >> k1;
+ }
+ while(x < xe);
+ if ((*x1 = z) !=0)
+ ++n1;
+#else
+ k1 = 16 - k;
+ z = 0;
+ do {
+ *x1++ = *x << k & 0xffff | z;
+ z = *x++ >> k1;
+ }
+ while(x < xe);
+ if (*x1 = z)
+ ++n1;
+#endif
+ }
+ else do
+ *x1++ = *x++;
+ while(x < xe);
+ b1->wds = n1 - 1;
+ Bfree(b);
+ return b1;
+ }
+
+ int
+cmp
+#ifdef KR_headers
+ (a, b) Bigint *a, *b;
+#else
+ (Bigint *a, Bigint *b)
+#endif
+{
+ ULong *xa, *xa0, *xb, *xb0;
+ int i, j;
+
+ i = a->wds;
+ j = b->wds;
+#ifdef DEBUG
+ if (i > 1 && !a->x[i-1])
+ Bug("cmp called with a->x[a->wds-1] == 0");
+ if (j > 1 && !b->x[j-1])
+ Bug("cmp called with b->x[b->wds-1] == 0");
+#endif
+ if (i -= j)
+ return i;
+ xa0 = a->x;
+ xa = xa0 + j;
+ xb0 = b->x;
+ xb = xb0 + j;
+ for(;;) {
+ if (*--xa != *--xb)
+ return *xa < *xb ? -1 : 1;
+ if (xa <= xa0)
+ break;
+ }
+ return 0;
+ }
+
+ Bigint *
+diff
+#ifdef KR_headers
+ (a, b) Bigint *a, *b;
+#else
+ (Bigint *a, Bigint *b)
+#endif
+{
+ Bigint *c;
+ int i, wa, wb;
+ ULong *xa, *xae, *xb, *xbe, *xc;
+#ifdef ULLong
+ ULLong borrow, y;
+#else
+ ULong borrow, y;
+#ifdef Pack_32
+ ULong z;
+#endif
+#endif
+
+ i = cmp(a,b);
+ if (!i) {
+ c = Balloc(0);
+ if (c == NULL)
+ return NULL;
+ c->wds = 1;
+ c->x[0] = 0;
+ return c;
+ }
+ if (i < 0) {
+ c = a;
+ a = b;
+ b = c;
+ i = 1;
+ }
+ else
+ i = 0;
+ c = Balloc(a->k);
+ if (c == NULL)
+ return NULL;
+ c->sign = i;
+ wa = a->wds;
+ xa = a->x;
+ xae = xa + wa;
+ wb = b->wds;
+ xb = b->x;
+ xbe = xb + wb;
+ xc = c->x;
+ borrow = 0;
+#ifdef ULLong
+ do {
+ y = (ULLong)*xa++ - *xb++ - borrow;
+ borrow = y >> 32 & 1UL;
+ /* LINTED conversion */
+ *xc++ = (uint32_t)(y & 0xffffffffUL);
+ }
+ while(xb < xbe);
+ while(xa < xae) {
+ y = *xa++ - borrow;
+ borrow = y >> 32 & 1UL;
+ /* LINTED conversion */
+ *xc++ = (uint32_t)(y & 0xffffffffUL);
+ }
+#else
+#ifdef Pack_32
+ do {
+ y = (*xa & 0xffff) - (*xb & 0xffff) - borrow;
+ borrow = (y & 0x10000) >> 16;
+ z = (*xa++ >> 16) - (*xb++ >> 16) - borrow;
+ borrow = (z & 0x10000) >> 16;
+ Storeinc(xc, z, y);
+ }
+ while(xb < xbe);
+ while(xa < xae) {
+ y = (*xa & 0xffff) - borrow;
+ borrow = (y & 0x10000) >> 16;
+ z = (*xa++ >> 16) - borrow;
+ borrow = (z & 0x10000) >> 16;
+ Storeinc(xc, z, y);
+ }
+#else
+ do {
+ y = *xa++ - *xb++ - borrow;
+ borrow = (y & 0x10000) >> 16;
+ *xc++ = y & 0xffff;
+ }
+ while(xb < xbe);
+ while(xa < xae) {
+ y = *xa++ - borrow;
+ borrow = (y & 0x10000) >> 16;
+ *xc++ = y & 0xffff;
+ }
+#endif
+#endif
+ while(!*--xc)
+ wa--;
+ c->wds = wa;
+ return c;
+ }
+
+ double
+b2d
+#ifdef KR_headers
+ (a, e) Bigint *a; int *e;
+#else
+ (Bigint *a, int *e)
+#endif
+{
+ ULong *xa, *xa0, w, y, z;
+ int k;
+ double d;
+#ifdef VAX
+ ULong d0, d1;
+#else
+#define d0 word0(d)
+#define d1 word1(d)
+#endif
+
+ xa0 = a->x;
+ xa = xa0 + a->wds;
+ y = *--xa;
+#ifdef DEBUG
+ if (!y) Bug("zero y in b2d");
+#endif
+ k = hi0bits(y);
+ *e = 32 - k;
+#ifdef Pack_32
+ if (k < Ebits) {
+ d0 = (UINT32)(Exp_1 | y >> (Ebits - k));
+ w = xa > xa0 ? *--xa : 0;
+ d1 = (UINT32)(y << ((32-Ebits) + k) | w >> (Ebits - k));
+ goto ret_d;
+ }
+ z = xa > xa0 ? *--xa : 0;
+ if (k -= Ebits) {
+ d0 = (UINT32)(Exp_1 | y << k | z >> (32 - k));
+ y = xa > xa0 ? *--xa : 0;
+ d1 = (UINT32)(z << k | y >> (32 - k));
+ }
+ else {
+ d0 = (UINT32)(Exp_1 | y);
+ d1 = (UINT32)z;
+ }
+#else
+ if (k < Ebits + 16) {
+ z = xa > xa0 ? *--xa : 0;
+ d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
+ w = xa > xa0 ? *--xa : 0;
+ y = xa > xa0 ? *--xa : 0;
+ d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
+ goto ret_d;
+ }
+ z = xa > xa0 ? *--xa : 0;
+ w = xa > xa0 ? *--xa : 0;
+ k -= Ebits + 16;
+ d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
+ y = xa > xa0 ? *--xa : 0;
+ d1 = w << k + 16 | y << k;
+#endif
+ ret_d:
+#ifdef VAX
+ word0(d) = d0 >> 16 | d0 << 16;
+ word1(d) = d1 >> 16 | d1 << 16;
+#endif
+ return dval(d);
+ }
+#undef d0
+#undef d1
+
+ Bigint *
+d2b
+#ifdef KR_headers
+ (d, e, bits) double d; int *e, *bits;
+#else
+ (double d, int *e, int *bits)
+#endif
+{
+ Bigint *b;
+#ifndef Sudden_Underflow
+ int i;
+#endif
+ int de, k;
+ ULong *x, y, z;
+#ifdef VAX
+ ULong d0, d1;
+ d0 = word0(d) >> 16 | word0(d) << 16;
+ d1 = word1(d) >> 16 | word1(d) << 16;
+#else
+#define d0 word0(d)
+#define d1 word1(d)
+#endif
+
+#ifdef Pack_32
+ b = Balloc(1);
+#else
+ b = Balloc(2);
+#endif
+ if (b == NULL)
+ return NULL;
+ x = b->x;
+
+ z = d0 & Frac_mask;
+ d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
+#ifdef Sudden_Underflow
+ de = (int)(d0 >> Exp_shift);
+#ifndef IBM
+ z |= Exp_msk11;
+#endif
+#else
+ if ( (de = (int)(d0 >> Exp_shift)) !=0)
+ z |= Exp_msk1;
+#endif
+#ifdef Pack_32
+ if ( (y = d1) !=0) {
+ if ( (k = lo0bits(&y)) !=0) {
+ x[0] = y | z << (32 - k);
+ z >>= k;
+ }
+ else
+ x[0] = y;
+#ifndef Sudden_Underflow
+ i =
+#endif
+ b->wds = (x[1] = z) !=0 ? 2 : 1;
+ }
+ else {
+#ifdef DEBUG
+ if (!z)
+ Bug("Zero passed to d2b");
+#endif
+ k = lo0bits(&z);
+ x[0] = z;
+#ifndef Sudden_Underflow
+ i =
+#endif
+ b->wds = 1;
+ k += 32;
+ }
+#else
+ if ( (y = d1) !=0) {
+ if ( (k = lo0bits(&y)) !=0)
+ if (k >= 16) {
+ x[0] = y | z << 32 - k & 0xffff;
+ x[1] = z >> k - 16 & 0xffff;
+ x[2] = z >> k;
+ i = 2;
+ }
+ else {
+ x[0] = y & 0xffff;
+ x[1] = y >> 16 | z << 16 - k & 0xffff;
+ x[2] = z >> k & 0xffff;
+ x[3] = z >> k+16;
+ i = 3;
+ }
+ else {
+ x[0] = y & 0xffff;
+ x[1] = y >> 16;
+ x[2] = z & 0xffff;
+ x[3] = z >> 16;
+ i = 3;
+ }
+ }
+ else {
+#ifdef DEBUG
+ if (!z)
+ Bug("Zero passed to d2b");
+#endif
+ k = lo0bits(&z);
+ if (k >= 16) {
+ x[0] = z;
+ i = 0;
+ }
+ else {
+ x[0] = z & 0xffff;
+ x[1] = z >> 16;
+ i = 1;
+ }
+ k += 32;
+ }
+ while(!x[i])
+ --i;
+ b->wds = i + 1;
+#endif
+#ifndef Sudden_Underflow
+ if (de) {
+#endif
+#ifdef IBM
+ *e = (de - Bias - (P-1) << 2) + k;
+ *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
+#else
+ *e = de - Bias - (P-1) + k;
+ *bits = P - k;
+#endif
+#ifndef Sudden_Underflow
+ }
+ else {
+ *e = de - Bias - (P-1) + 1 + k;
+#ifdef Pack_32
+ *bits = 32*i - hi0bits(x[i-1]);
+#else
+ *bits = (i+2)*16 - hi0bits(x[i]);
+#endif
+ }
+#endif
+ return b;
+ }
+#undef d0
+#undef d1
+
+ CONST double
+#ifdef IEEE_Arith
+bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
+CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256
+ };
+#else
+#ifdef IBM
+bigtens[] = { 1e16, 1e32, 1e64 };
+CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };
+#else
+bigtens[] = { 1e16, 1e32 };
+CONST double tinytens[] = { 1e-16, 1e-32 };
+#endif
+#endif
+
+ CONST double
+tens[] = {
+ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+ 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+ 1e20, 1e21, 1e22
+#ifdef VAX
+ , 1e23, 1e24
+#endif
+ };
+
+ char *
+#ifdef KR_headers
+strcp_D2A(a, b) char *a; char *b;
+#else
+strcp_D2A(char *a, CONST char *b)
+#endif
+{
+ while((*a = *b++))
+ a++;
+ return a;
+ }
+
+#ifdef NO_STRING_H
+
+ Char *
+#ifdef KR_headers
+memcpy_D2A(a, b, len) Char *a; Char *b; size_t len;
+#else
+memcpy_D2A(void *a1, void *b1, size_t len)
+#endif
+{
+ char *a = (char*)a1, *ae = a + len;
+ char *b = (char*)b1, *a0 = a;
+ while(a < ae)
+ *a++ = *b++;
+ return a0;
+ }
+
+#endif /* NO_STRING_H */
diff --git a/StdLib/LibC/gdtoa/smisc.c b/StdLib/LibC/gdtoa/smisc.c
new file mode 100644
index 0000000000..59e4f97dcc
--- /dev/null
+++ b/StdLib/LibC/gdtoa/smisc.c
@@ -0,0 +1,209 @@
+/* $NetBSD: smisc.c,v 1.2.14.1 2008/04/08 21:10:55 jdc Exp $ */
+
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998, 1999 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+#include <LibConfig.h>
+
+#include "gdtoaimp.h"
+
+#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
+// Disable: warning C4700: uninitialized local variable 'xx' used
+#pragma warning ( disable : 4700 )
+#endif /* defined(_MSC_VER) */
+
+Bigint *
+s2b
+#ifdef KR_headers
+ (s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9;
+#else
+ (CONST char *s, int nd0, int nd, ULong y9)
+#endif
+{
+ Bigint *b;
+ int i, k;
+ Long x, y;
+
+ x = (nd + 8) / 9;
+ for(k = 0, y = 1; x > y; y <<= 1, k++) ;
+#ifdef Pack_32
+ b = Balloc(k);
+ if (b == NULL)
+ return NULL;
+ b->x[0] = y9;
+ b->wds = 1;
+#else
+ b = Balloc(k+1);
+ if (b == NULL)
+ return NULL;
+ b->x[0] = y9 & 0xffff;
+ b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
+#endif
+
+ i = 9;
+ if (9 < nd0) {
+ s += 9;
+ do {
+ b = multadd(b, 10, *s++ - '0');
+ if (b == NULL)
+ return NULL;
+ } while(++i < nd0);
+ s++;
+ }
+ else
+ s += 10;
+ for(; i < nd; i++) {
+ b = multadd(b, 10, *s++ - '0');
+ if (b == NULL)
+ return NULL;
+ }
+ return b;
+ }
+
+ double
+ratio
+#ifdef KR_headers
+ (a, b) Bigint *a, *b;
+#else
+ (Bigint *a, Bigint *b)
+#endif
+{
+ double da, db;
+ int k, ka, kb;
+
+ dval(da) = b2d(a, &ka);
+ dval(db) = b2d(b, &kb);
+ k = ka - kb + ULbits*(a->wds - b->wds);
+#ifdef IBM
+ if (k > 0) {
+ word0(da) += (k >> 2)*Exp_msk1;
+ if (k &= 3)
+ dval(da) *= 1 << k;
+ }
+ else {
+ k = -k;
+ word0(db) += (k >> 2)*Exp_msk1;
+ if (k &= 3)
+ dval(db) *= 1 << k;
+ }
+#else
+ if (k > 0)
+ word0(da) += k*Exp_msk1;
+ else {
+ k = -k;
+ word0(db) += k*Exp_msk1;
+ }
+#endif
+ return dval(da) / dval(db);
+ }
+
+#ifdef INFNAN_CHECK
+
+ int
+match
+#ifdef KR_headers
+ (sp, t) CONST char **sp, *t;
+#else
+ (CONST char **sp, CONST char *t)
+#endif
+{
+ int c, d;
+ CONST char *s = *sp;
+
+ while( (d = *t++) !=0) {
+ if ((c = *++s) >= 'A' && c <= 'Z')
+ c += 'a' - 'A';
+ if (c != d)
+ return 0;
+ }
+ *sp = s + 1;
+ return 1;
+ }
+#endif /* INFNAN_CHECK */
+
+ void
+#ifdef KR_headers
+copybits(c, n, b) ULong *c; int n; Bigint *b;
+#else
+copybits(ULong *c, int n, Bigint *b)
+#endif
+{
+ ULong *ce, *x, *xe;
+#ifdef Pack_16
+ int nw, nw1;
+#endif
+
+ ce = c + ((unsigned int)(n-1) >> kshift) + 1;
+ x = b->x;
+#ifdef Pack_32
+ xe = x + b->wds;
+ while(x < xe)
+ *c++ = *x++;
+#else
+ nw = b->wds;
+ nw1 = nw & 1;
+ for(xe = x + (nw - nw1); x < xe; x += 2)
+ Storeinc(c, x[1], x[0]);
+ if (nw1)
+ *c++ = *x;
+#endif
+ while(c < ce)
+ *c++ = 0;
+ }
+
+ ULong
+#ifdef KR_headers
+any_on(b, k) Bigint *b; int k;
+#else
+any_on(Bigint *b, int k)
+#endif
+{
+ int n, nwds;
+ ULong *x, *x0, x1, x2;
+
+ x = b->x;
+ nwds = b->wds;
+ n = (unsigned int)k >> kshift;
+ if (n > nwds)
+ n = nwds;
+ else if (n < nwds && (k &= kmask)) {
+ x1 = x2 = x[n];
+ x1 >>= k;
+ x1 <<= k;
+ if (x1 != x2)
+ return 1;
+ }
+ x0 = x;
+ x += n;
+ while(x > x0)
+ if (*--x)
+ return 1;
+ return 0;
+ }
diff --git a/StdLib/LibC/gdtoa/strtod.c b/StdLib/LibC/gdtoa/strtod.c
new file mode 100644
index 0000000000..989663a01e
--- /dev/null
+++ b/StdLib/LibC/gdtoa/strtod.c
@@ -0,0 +1,1022 @@
+/* $NetBSD: strtod.c,v 1.4.14.1 2008/04/08 21:10:55 jdc Exp $ */
+
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998-2001 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+#include <LibConfig.h>
+
+#include "gdtoaimp.h"
+#ifndef NO_FENV_H
+#include <fenv.h>
+#endif
+
+#ifdef USE_LOCALE
+#include "locale.h"
+#endif
+
+#ifdef IEEE_Arith
+#ifndef NO_IEEE_Scale
+#define Avoid_Underflow
+#undef tinytens
+/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */
+/* flag unnecessarily. It leads to a song and dance at the end of strtod. */
+static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
+ 9007199254740992.e-256
+ };
+#endif
+#endif
+
+#ifdef Honor_FLT_ROUNDS
+#define Rounding rounding
+#undef Check_FLT_ROUNDS
+#define Check_FLT_ROUNDS
+#else
+#define Rounding Flt_Rounds
+#endif
+
+//#ifndef __HAVE_LONG_DOUBLE
+//__strong_alias(_strtold, strtod)
+//__weak_alias(strtold, _strtold)
+//#endif
+
+#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
+// Disable: warning C4700: uninitialized local variable 'xx' used
+#pragma warning ( disable : 4700 )
+#endif /* defined(_MSC_VER) */
+
+double
+strtod(CONST char *s00, char **se)
+{
+#ifdef Avoid_Underflow
+ int scale;
+ #endif
+ int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, dsign,
+ e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
+ CONST char *s, *s0, *s1;
+ double aadj, aadj1, adj, rv, rv0;
+ Long L;
+ ULong y, z;
+ Bigint *bb = NULL, *bb1, *bd0;
+ Bigint *bd = NULL, *bs = NULL, *delta = NULL; /* pacify gcc */
+#ifdef SET_INEXACT
+ int inexact, oldinexact;
+#endif
+#ifdef Honor_FLT_ROUNDS
+ int rounding;
+#endif
+
+ sign = nz0 = nz = decpt = 0;
+ dval(rv) = 0.;
+ for(s = s00;;s++) {
+ switch(*s) {
+ case '-':
+ sign = 1;
+ /* FALLTHROUGH */
+ case '+':
+ if (*++s)
+ goto break2;
+ /* FALLTHROUGH */
+ case 0:
+ goto ret0;
+ case '\t':
+ case '\n':
+ case '\v':
+ case '\f':
+ case '\r':
+ case ' ':
+ continue;
+ default:
+ goto break2;
+ }
+ }
+ break2:
+ if (*s == '0') {
+#ifndef NO_HEX_FP
+ {
+ static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI };
+ Long expt;
+ ULong bits[2];
+ switch(s[1]) {
+ case 'x':
+ case 'X':
+ {
+#if defined(FE_DOWNWARD) && defined(FE_TONEAREST) && defined(FE_TOWARDZERO) && defined(FE_UPWARD)
+ FPI fpi1 = fpi;
+ switch(fegetround()) {
+ case FE_TOWARDZERO: fpi1.rounding = 0; break;
+ case FE_UPWARD: fpi1.rounding = 2; break;
+ case FE_DOWNWARD: fpi1.rounding = 3;
+ }
+#else
+#endif
+ switch((i = gethex(&s, &fpi, &expt, &bb, sign)) & STRTOG_Retmask) {
+ case STRTOG_NoNumber:
+ s = s00;
+ sign = 0;
+ /* FALLTHROUGH */
+ case STRTOG_Zero:
+ break;
+ default:
+ if (bb) {
+ copybits(bits, fpi.nbits, bb);
+ Bfree(bb);
+ }
+ ULtod((/* LINTED */(U*)&rv)->L, bits, expt, i);
+ }}
+ goto ret;
+ }
+ }
+#endif
+ nz0 = 1;
+ while(*++s == '0') ;
+ if (!*s)
+ goto ret;
+ }
+ s0 = s;
+ y = z = 0;
+ for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
+ if (nd < 9)
+ y = 10*y + c - '0';
+ else if (nd < 16)
+ z = 10*z + c - '0';
+ nd0 = nd;
+#ifdef USE_LOCALE
+ if (c == *localeconv()->decimal_point)
+#else
+ if (c == '.')
+#endif
+ {
+ decpt = 1;
+ c = *++s;
+ if (!nd) {
+ for(; c == '0'; c = *++s)
+ nz++;
+ if (c > '0' && c <= '9') {
+ s0 = s;
+ nf += nz;
+ nz = 0;
+ goto have_dig;
+ }
+ goto dig_done;
+ }
+ for(; c >= '0' && c <= '9'; c = *++s) {
+ have_dig:
+ nz++;
+ if (c -= '0') {
+ nf += nz;
+ for(i = 1; i < nz; i++)
+ if (nd++ < 9)
+ y *= 10;
+ else if (nd <= DBL_DIG + 1)
+ z *= 10;
+ if (nd++ < 9)
+ y = 10*y + c;
+ else if (nd <= DBL_DIG + 1)
+ z = 10*z + c;
+ nz = 0;
+ }
+ }
+ }
+ dig_done:
+ e = 0;
+ if (c == 'e' || c == 'E') {
+ if (!nd && !nz && !nz0) {
+ goto ret0;
+ }
+ s00 = s;
+ esign = 0;
+ switch(c = *++s) {
+ case '-':
+ esign = 1;
+ /* FALLTHROUGH */
+ case '+':
+ c = *++s;
+ }
+ if (c >= '0' && c <= '9') {
+ while(c == '0')
+ c = *++s;
+ if (c > '0' && c <= '9') {
+ L = c - '0';
+ s1 = s;
+ while((c = *++s) >= '0' && c <= '9')
+ L = 10*L + c - '0';
+ if (s - s1 > 8 || L > 19999)
+ /* Avoid confusion from exponents
+ * so large that e might overflow.
+ */
+ e = 19999; /* safe for 16 bit ints */
+ else
+ e = (int)L;
+ if (esign)
+ e = -e;
+ }
+ else
+ e = 0;
+ }
+ else
+ s = s00;
+ }
+ if (!nd) {
+ if (!nz && !nz0) {
+#ifdef INFNAN_CHECK
+ /* Check for Nan and Infinity */
+#ifndef No_Hex_NaN
+ ULong bits[2];
+ static FPI fpinan = /* only 52 explicit bits */
+ { 52, 1-1023-53+1, 2046-1023-53+1, 1, SI };
+#endif // No_Hex_NaN
+ if (!decpt)
+ switch(c) {
+ case 'i':
+ case 'I':
+ if (match(&s,"nf")) {
+ --s;
+ if (!match(&s,"inity"))
+ ++s;
+ word0(rv) = 0x7ff00000;
+ word1(rv) = 0;
+ goto ret;
+ }
+ break;
+ case 'n':
+ case 'N':
+ if (match(&s, "an")) {
+#ifndef No_Hex_NaN
+ if (*s == '(' /*)*/
+ && hexnan(&s, &fpinan, bits)
+ == STRTOG_NaNbits) {
+ word0(rv) = (UINT32)(0x7ff00000U | bits[1]);
+ word1(rv) = (UINT32)bits[0];
+ }
+ else {
+#endif
+ word0(rv) = NAN_WORD0;
+ word1(rv) = NAN_WORD1;
+#ifndef No_Hex_NaN
+ }
+#endif
+ goto ret;
+ }
+ }
+#endif /* INFNAN_CHECK */
+ ret0:
+ s = s00;
+ sign = 0;
+ }
+ goto ret;
+ }
+ e1 = e -= nf;
+
+ /* Now we have nd0 digits, starting at s0, followed by a
+ * decimal point, followed by nd-nd0 digits. The number we're
+ * after is the integer represented by those digits times
+ * 10**e */
+
+ if (!nd0)
+ nd0 = nd;
+ k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
+ dval(rv) = (double)y;
+ if (k > 9) {
+#ifdef SET_INEXACT
+ if (k > DBL_DIG)
+ oldinexact = get_inexact();
+#endif
+ dval(rv) = tens[k - 9] * dval(rv) + z;
+ }
+ bd0 = 0;
+ if (nd <= DBL_DIG
+#ifndef RND_PRODQUOT
+#ifndef Honor_FLT_ROUNDS
+ && Flt_Rounds == 1
+#endif
+#endif
+ ) {
+ if (!e)
+ goto ret;
+ if (e > 0) {
+ if (e <= Ten_pmax) {
+#ifdef VAX
+ goto vax_ovfl_check;
+#else
+#ifdef Honor_FLT_ROUNDS
+ /* round correctly FLT_ROUNDS = 2 or 3 */
+ if (sign) {
+ rv = -rv;
+ sign = 0;
+ }
+#endif
+ /* rv = */ rounded_product(dval(rv), tens[e]);
+ goto ret;
+#endif
+ }
+ i = DBL_DIG - nd;
+ if (e <= Ten_pmax + i) {
+ /* A fancier test would sometimes let us do
+ * this for larger i values.
+ */
+#ifdef Honor_FLT_ROUNDS
+ /* round correctly FLT_ROUNDS = 2 or 3 */
+ if (sign) {
+ rv = -rv;
+ sign = 0;
+ }
+#endif
+ e -= i;
+ dval(rv) *= tens[i];
+#ifdef VAX
+ /* VAX exponent range is so narrow we must
+ * worry about overflow here...
+ */
+ vax_ovfl_check:
+ word0(rv) -= P*Exp_msk1;
+ /* rv = */ rounded_product(dval(rv), tens[e]);
+ if ((word0(rv) & Exp_mask)
+ > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
+ goto ovfl;
+ word0(rv) += P*Exp_msk1;
+#else
+ /* rv = */ rounded_product(dval(rv), tens[e]);
+#endif
+ goto ret;
+ }
+ }
+#ifndef Inaccurate_Divide
+ else if (e >= -Ten_pmax) {
+#ifdef Honor_FLT_ROUNDS
+ /* round correctly FLT_ROUNDS = 2 or 3 */
+ if (sign) {
+ rv = -rv;
+ sign = 0;
+ }
+#endif
+ /* rv = */ rounded_quotient(dval(rv), tens[-e]);
+ goto ret;
+ }
+#endif
+ }
+ e1 += nd - k;
+
+#ifdef IEEE_Arith
+#ifdef SET_INEXACT
+ inexact = 1;
+ if (k <= DBL_DIG)
+ oldinexact = get_inexact();
+#endif
+#ifdef Avoid_Underflow
+ scale = 0;
+#endif
+#ifdef Honor_FLT_ROUNDS
+ if ((rounding = Flt_Rounds) >= 2) {
+ if (sign)
+ rounding = rounding == 2 ? 0 : 2;
+ else
+ if (rounding != 2)
+ rounding = 0;
+ }
+#endif
+#endif /*IEEE_Arith*/
+
+ /* Get starting approximation = rv * 10**e1 */
+
+ if (e1 > 0) {
+ if ( (i = e1 & 15) !=0)
+ dval(rv) *= tens[i];
+ if (e1 &= ~15) {
+ if (e1 > DBL_MAX_10_EXP) {
+ ovfl:
+#ifndef NO_ERRNO
+ errno = ERANGE;
+#endif
+ /* Can't trust HUGE_VAL */
+#ifdef IEEE_Arith
+#ifdef Honor_FLT_ROUNDS
+ switch(rounding) {
+ case 0: /* toward 0 */
+ case 3: /* toward -infinity */
+ word0(rv) = Big0;
+ word1(rv) = Big1;
+ break;
+ default:
+ word0(rv) = Exp_mask;
+ word1(rv) = 0;
+ }
+#else /*Honor_FLT_ROUNDS*/
+ word0(rv) = Exp_mask;
+ word1(rv) = 0;
+#endif /*Honor_FLT_ROUNDS*/
+#ifdef SET_INEXACT
+ /* set overflow bit */
+ dval(rv0) = 1e300;
+ dval(rv0) *= dval(rv0);
+#endif
+#else /*IEEE_Arith*/
+ word0(rv) = Big0;
+ word1(rv) = Big1;
+#endif /*IEEE_Arith*/
+ if (bd0)
+ goto retfree;
+ goto ret;
+ }
+ e1 = (unsigned int)e1 >> 4;
+ for(j = 0; e1 > 1; j++, e1 = (unsigned int)e1 >> 1)
+ if (e1 & 1)
+ dval(rv) *= bigtens[j];
+ /* The last multiplication could overflow. */
+ word0(rv) -= P*Exp_msk1;
+ dval(rv) *= bigtens[j];
+ if ((z = word0(rv) & Exp_mask)
+ > Exp_msk1*(DBL_MAX_EXP+Bias-P))
+ goto ovfl;
+ if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
+ /* set to largest number */
+ /* (Can't trust DBL_MAX) */
+ word0(rv) = Big0;
+ word1(rv) = Big1;
+ }
+ else
+ word0(rv) += P*Exp_msk1;
+ }
+ }
+ else if (e1 < 0) {
+ e1 = -e1;
+ if ( (i = e1 & 15) !=0)
+ dval(rv) /= tens[i];
+ if (e1 >>= 4) {
+ if (e1 >= 1 << n_bigtens)
+ goto undfl;
+#ifdef Avoid_Underflow
+ if (e1 & Scale_Bit)
+ scale = 2*P;
+ for(j = 0; e1 > 0; j++, e1 = (unsigned int)e1 >> 1)
+ if (e1 & 1)
+ dval(rv) *= tinytens[j];
+ if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask)
+ >> Exp_shift)) > 0) {
+ /* scaled rv is denormal; zap j low bits */
+ if (j >= 32) {
+ word1(rv) = 0;
+ if (j >= 53)
+ word0(rv) = (P+2)*Exp_msk1;
+ else
+ word0(rv) &= 0xffffffff << (j-32);
+ }
+ else
+ word1(rv) &= 0xffffffff << j;
+ }
+#else
+ for(j = 0; e1 > 1; j++, e1 >>= 1)
+ if (e1 & 1)
+ dval(rv) *= tinytens[j];
+ /* The last multiplication could underflow. */
+ dval(rv0) = dval(rv);
+ dval(rv) *= tinytens[j];
+ if (!dval(rv)) {
+ dval(rv) = 2.*dval(rv0);
+ dval(rv) *= tinytens[j];
+#endif
+ if (!dval(rv)) {
+ undfl:
+ dval(rv) = 0.;
+#ifndef NO_ERRNO
+ errno = ERANGE;
+#endif
+ if (bd0)
+ goto retfree;
+ goto ret;
+ }
+#ifndef Avoid_Underflow
+ word0(rv) = Tiny0;
+ word1(rv) = Tiny1;
+ /* The refinement below will clean
+ * this approximation up.
+ */
+ }
+#endif
+ }
+ }
+
+ /* Now the hard part -- adjusting rv to the correct value.*/
+
+ /* Put digits into bd: true value = bd * 10^e */
+
+ bd0 = s2b(s0, nd0, nd, y);
+ if (bd0 == NULL)
+ goto ovfl;
+
+ for(;;) {
+ bd = Balloc(bd0->k);
+ if (bd == NULL)
+ goto ovfl;
+ Bcopy(bd, bd0);
+ bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */
+ if (bb == NULL)
+ goto ovfl;
+ bs = i2b(1);
+ if (bs == NULL)
+ goto ovfl;
+
+ if (e >= 0) {
+ bb2 = bb5 = 0;
+ bd2 = bd5 = e;
+ }
+ else {
+ bb2 = bb5 = -e;
+ bd2 = bd5 = 0;
+ }
+ if (bbe >= 0)
+ bb2 += bbe;
+ else
+ bd2 -= bbe;
+ bs2 = bb2;
+#ifdef Honor_FLT_ROUNDS
+ if (rounding != 1)
+ bs2++;
+#endif
+#ifdef Avoid_Underflow
+ j = bbe - scale;
+ i = j + bbbits - 1; /* logb(rv) */
+ if (i < Emin) /* denormal */
+ j += P - Emin;
+ else
+ j = P + 1 - bbbits;
+#else /*Avoid_Underflow*/
+#ifdef Sudden_Underflow
+#ifdef IBM
+ j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
+#else
+ j = P + 1 - bbbits;
+#endif
+#else /*Sudden_Underflow*/
+ j = bbe;
+ i = j + bbbits - 1; /* logb(rv) */
+ if (i < Emin) /* denormal */
+ j += P - Emin;
+ else
+ j = P + 1 - bbbits;
+#endif /*Sudden_Underflow*/
+#endif /*Avoid_Underflow*/
+ bb2 += j;
+ bd2 += j;
+#ifdef Avoid_Underflow
+ bd2 += scale;
+#endif
+ i = bb2 < bd2 ? bb2 : bd2;
+ if (i > bs2)
+ i = bs2;
+ if (i > 0) {
+ bb2 -= i;
+ bd2 -= i;
+ bs2 -= i;
+ }
+ if (bb5 > 0) {
+ bs = pow5mult(bs, bb5);
+ if (bs == NULL)
+ goto ovfl;
+ bb1 = mult(bs, bb);
+ if (bb1 == NULL)
+ goto ovfl;
+ Bfree(bb);
+ bb = bb1;
+ }
+ if (bb2 > 0) {
+ bb = lshift(bb, bb2);
+ if (bb == NULL)
+ goto ovfl;
+ }
+ if (bd5 > 0) {
+ bd = pow5mult(bd, bd5);
+ if (bd == NULL)
+ goto ovfl;
+ }
+ if (bd2 > 0) {
+ bd = lshift(bd, bd2);
+ if (bd == NULL)
+ goto ovfl;
+ }
+ if (bs2 > 0) {
+ bs = lshift(bs, bs2);
+ if (bs == NULL)
+ goto ovfl;
+ }
+ delta = diff(bb, bd);
+ if (delta == NULL)
+ goto ovfl;
+ dsign = delta->sign;
+ delta->sign = 0;
+ i = cmp(delta, bs);
+#ifdef Honor_FLT_ROUNDS
+ if (rounding != 1) {
+ if (i < 0) {
+ /* Error is less than an ulp */
+ if (!delta->x[0] && delta->wds <= 1) {
+ /* exact */
+#ifdef SET_INEXACT
+ inexact = 0;
+#endif
+ break;
+ }
+ if (rounding) {
+ if (dsign) {
+ adj = 1.;
+ goto apply_adj;
+ }
+ }
+ else if (!dsign) {
+ adj = -1.;
+ if (!word1(rv)
+ && !(word0(rv) & Frac_mask)) {
+ y = word0(rv) & Exp_mask;
+#ifdef Avoid_Underflow
+ if (!scale || y > 2*P*Exp_msk1)
+#else
+ if (y)
+#endif
+ {
+ delta = lshift(delta,Log2P);
+ if (cmp(delta, bs) <= 0)
+ adj = -0.5;
+ }
+ }
+ apply_adj:
+#ifdef Avoid_Underflow
+ if (scale && (y = word0(rv) & Exp_mask)
+ <= 2*P*Exp_msk1)
+ word0(adj) += (2*P+1)*Exp_msk1 - y;
+#else
+#ifdef Sudden_Underflow
+ if ((word0(rv) & Exp_mask) <=
+ P*Exp_msk1) {
+ word0(rv) += P*Exp_msk1;
+ dval(rv) += adj*ulp(dval(rv));
+ word0(rv) -= P*Exp_msk1;
+ }
+ else
+#endif /*Sudden_Underflow*/
+#endif /*Avoid_Underflow*/
+ dval(rv) += adj*ulp(dval(rv));
+ }
+ break;
+ }
+ adj = ratio(delta, bs);
+ if (adj < 1.)
+ adj = 1.;
+ if (adj <= 0x7ffffffe) {
+ /* adj = rounding ? ceil(adj) : floor(adj); */
+ y = adj;
+ if (y != adj) {
+ if (!((rounding>>1) ^ dsign))
+ y++;
+ adj = y;
+ }
+ }
+#ifdef Avoid_Underflow
+ if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
+ word0(adj) += (2*P+1)*Exp_msk1 - y;
+#else
+#ifdef Sudden_Underflow
+ if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
+ word0(rv) += P*Exp_msk1;
+ adj *= ulp(dval(rv));
+ if (dsign)
+ dval(rv) += adj;
+ else
+ dval(rv) -= adj;
+ word0(rv) -= P*Exp_msk1;
+ goto cont;
+ }
+#endif /*Sudden_Underflow*/
+#endif /*Avoid_Underflow*/
+ adj *= ulp(dval(rv));
+ if (dsign)
+ dval(rv) += adj;
+ else
+ dval(rv) -= adj;
+ goto cont;
+ }
+#endif /*Honor_FLT_ROUNDS*/
+
+ if (i < 0) {
+ /* Error is less than half an ulp -- check for
+ * special case of mantissa a power of two.
+ */
+ if (dsign || word1(rv) || word0(rv) & Bndry_mask
+#ifdef IEEE_Arith
+#ifdef Avoid_Underflow
+ || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1
+#else
+ || (word0(rv) & Exp_mask) <= Exp_msk1
+#endif
+#endif
+ ) {
+#ifdef SET_INEXACT
+ if (!delta->x[0] && delta->wds <= 1)
+ inexact = 0;
+#endif
+ break;
+ }
+ if (!delta->x[0] && delta->wds <= 1) {
+ /* exact result */
+#ifdef SET_INEXACT
+ inexact = 0;
+#endif
+ break;
+ }
+ delta = lshift(delta,Log2P);
+ if (cmp(delta, bs) > 0)
+ goto drop_down;
+ break;
+ }
+ if (i == 0) {
+ /* exactly half-way between */
+ if (dsign) {
+ if ((word0(rv) & Bndry_mask1) == Bndry_mask1
+ && word1(rv) == (
+#ifdef Avoid_Underflow
+ (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
+ ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) :
+#endif
+ 0xffffffff)) {
+ /*boundary case -- increment exponent*/
+ word0(rv) = (word0(rv) & Exp_mask)
+ + Exp_msk1
+#ifdef IBM
+ | Exp_msk1 >> 4
+#endif
+ ;
+ word1(rv) = 0;
+#ifdef Avoid_Underflow
+ dsign = 0;
+#endif
+ break;
+ }
+ }
+ else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
+ drop_down:
+ /* boundary case -- decrement exponent */
+#ifdef Sudden_Underflow /*{{*/
+ L = word0(rv) & Exp_mask;
+#ifdef IBM
+ if (L < Exp_msk1)
+#else
+#ifdef Avoid_Underflow
+ if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1))
+#else
+ if (L <= Exp_msk1)
+#endif /*Avoid_Underflow*/
+#endif /*IBM*/
+ goto undfl;
+ L -= Exp_msk1;
+#else /*Sudden_Underflow}{*/
+#ifdef Avoid_Underflow
+ if (scale) {
+ L = word0(rv) & Exp_mask;
+ if (L <= (2*P+1)*Exp_msk1) {
+ if (L > (P+2)*Exp_msk1)
+ /* round even ==> */
+ /* accept rv */
+ break;
+ /* rv = smallest denormal */
+ goto undfl;
+ }
+ }
+#endif /*Avoid_Underflow*/
+ L = (word0(rv) & Exp_mask) - Exp_msk1;
+#endif /*Sudden_Underflow}*/
+ word0(rv) = (UINT32)(L | Bndry_mask1);
+ word1(rv) = 0xffffffffU;
+#ifdef IBM
+ goto cont;
+#else
+ break;
+#endif
+ }
+#ifndef ROUND_BIASED
+ if (!(word1(rv) & LSB))
+ break;
+#endif
+ if (dsign)
+ dval(rv) += ulp(dval(rv));
+#ifndef ROUND_BIASED
+ else {
+ dval(rv) -= ulp(dval(rv));
+#ifndef Sudden_Underflow
+ if (!dval(rv))
+ goto undfl;
+#endif
+ }
+#ifdef Avoid_Underflow
+ dsign = 1 - dsign;
+#endif
+#endif
+ break;
+ }
+ if ((aadj = ratio(delta, bs)) <= 2.) {
+ if (dsign)
+ aadj = aadj1 = 1.;
+ else if (word1(rv) || word0(rv) & Bndry_mask) {
+#ifndef Sudden_Underflow
+ if (word1(rv) == Tiny1 && !word0(rv))
+ goto undfl;
+#endif
+ aadj = 1.;
+ aadj1 = -1.;
+ }
+ else {
+ /* special case -- power of FLT_RADIX to be */
+ /* rounded down... */
+
+ if (aadj < 2./FLT_RADIX)
+ aadj = 1./FLT_RADIX;
+ else
+ aadj *= 0.5;
+ aadj1 = -aadj;
+ }
+ }
+ else {
+ aadj *= 0.5;
+ aadj1 = dsign ? aadj : -aadj;
+#ifdef Check_FLT_ROUNDS
+ switch(Rounding) {
+ case 2: /* towards +infinity */
+ aadj1 -= 0.5;
+ break;
+ case 0: /* towards 0 */
+ case 3: /* towards -infinity */
+ aadj1 += 0.5;
+ }
+#else
+ if (Flt_Rounds == 0)
+ aadj1 += 0.5;
+#endif /*Check_FLT_ROUNDS*/
+ }
+ y = word0(rv) & Exp_mask;
+
+ /* Check for overflow */
+
+ if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
+ dval(rv0) = dval(rv);
+ word0(rv) -= P*Exp_msk1;
+ adj = aadj1 * ulp(dval(rv));
+ dval(rv) += adj;
+ if ((word0(rv) & Exp_mask) >=
+ Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
+ if (word0(rv0) == Big0 && word1(rv0) == Big1)
+ goto ovfl;
+ word0(rv) = Big0;
+ word1(rv) = Big1;
+ goto cont;
+ }
+ else
+ word0(rv) += P*Exp_msk1;
+ }
+ else {
+#ifdef Avoid_Underflow
+ if (scale && y <= 2*P*Exp_msk1) {
+ if (aadj <= 0x7fffffff) {
+ if ((z = (uint32_t)aadj) == 0)
+ z = 1;
+ aadj = (double)z;
+ aadj1 = dsign ? aadj : -aadj;
+ }
+ word0(aadj1) += (UINT32)((2*P+1)*Exp_msk1 - y);
+ }
+ adj = aadj1 * ulp(dval(rv));
+ dval(rv) += adj;
+#else
+#ifdef Sudden_Underflow
+ if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
+ dval(rv0) = dval(rv);
+ word0(rv) += P*Exp_msk1;
+ adj = aadj1 * ulp(dval(rv));
+ dval(rv) += adj;
+#ifdef IBM
+ if ((word0(rv) & Exp_mask) < P*Exp_msk1)
+#else
+ if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
+#endif
+ {
+ if (word0(rv0) == Tiny0
+ && word1(rv0) == Tiny1)
+ goto undfl;
+ word0(rv) = Tiny0;
+ word1(rv) = Tiny1;
+ goto cont;
+ }
+ else
+ word0(rv) -= P*Exp_msk1;
+ }
+ else {
+ adj = aadj1 * ulp(dval(rv));
+ dval(rv) += adj;
+ }
+#else /*Sudden_Underflow*/
+ /* Compute adj so that the IEEE rounding rules will
+ * correctly round rv + adj in some half-way cases.
+ * If rv * ulp(rv) is denormalized (i.e.,
+ * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
+ * trouble from bits lost to denormalization;
+ * example: 1.2e-307 .
+ */
+ if (y <= (P-1)*Exp_msk1 && aadj > 1.) {
+ aadj1 = (double)(int)(aadj + 0.5);
+ if (!dsign)
+ aadj1 = -aadj1;
+ }
+ adj = aadj1 * ulp(dval(rv));
+ dval(rv) += adj;
+#endif /*Sudden_Underflow*/
+#endif /*Avoid_Underflow*/
+ }
+ z = word0(rv) & Exp_mask;
+#ifndef SET_INEXACT
+#ifdef Avoid_Underflow
+ if (!scale)
+#endif
+ if (y == z) {
+ /* Can we stop now? */
+ L = (Long)aadj;
+ aadj -= L;
+ /* The tolerances below are conservative. */
+ if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
+ if (aadj < .4999999 || aadj > .5000001)
+ break;
+ }
+ else if (aadj < .4999999/FLT_RADIX)
+ break;
+ }
+#endif
+ cont:
+ Bfree(bb);
+ Bfree(bd);
+ Bfree(bs);
+ Bfree(delta);
+ }
+#ifdef SET_INEXACT
+ if (inexact) {
+ if (!oldinexact) {
+ word0(rv0) = Exp_1 + (70 << Exp_shift);
+ word1(rv0) = 0;
+ dval(rv0) += 1.;
+ }
+ }
+ else if (!oldinexact)
+ clear_inexact();
+#endif
+#ifdef Avoid_Underflow
+ if (scale) {
+ word0(rv0) = Exp_1 - 2*P*Exp_msk1;
+ word1(rv0) = 0;
+ dval(rv) *= dval(rv0);
+#ifndef NO_ERRNO
+ /* try to avoid the bug of testing an 8087 register value */
+ if (word0(rv) == 0 && word1(rv) == 0)
+ errno = ERANGE;
+#endif
+ }
+#endif /* Avoid_Underflow */
+#ifdef SET_INEXACT
+ if (inexact && !(word0(rv) & Exp_mask)) {
+ /* set underflow bit */
+ dval(rv0) = 1e-300;
+ dval(rv0) *= dval(rv0);
+ }
+#endif
+ retfree:
+ Bfree(bb);
+ Bfree(bd);
+ Bfree(bs);
+ Bfree(bd0);
+ Bfree(delta);
+ ret:
+ if (se)
+ *se = __UNCONST(s);
+ return sign ? -dval(rv) : dval(rv);
+}
+
diff --git a/StdLib/LibC/gdtoa/strtodg.c b/StdLib/LibC/gdtoa/strtodg.c
new file mode 100644
index 0000000000..fc0ae7cf38
--- /dev/null
+++ b/StdLib/LibC/gdtoa/strtodg.c
@@ -0,0 +1,1075 @@
+/* $NetBSD: strtodg.c,v 1.5.14.1 2008/04/08 21:10:55 jdc Exp $ */
+
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998-2001 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+#include <LibConfig.h>
+
+#include "gdtoaimp.h"
+
+#ifdef USE_LOCALE
+#include "locale.h"
+#endif
+
+#if defined(_MSC_VER)
+ // Disable warnings about assignment within conditional expressions.
+ #pragma warning ( disable : 4706 )
+#endif
+
+ static CONST int
+fivesbits[] = { 0, 3, 5, 7, 10, 12, 14, 17, 19, 21,
+ 24, 26, 28, 31, 33, 35, 38, 40, 42, 45,
+ 47, 49, 52
+#ifdef VAX
+ , 54, 56
+#endif
+ };
+
+ Bigint *
+#ifdef KR_headers
+increment(b) Bigint *b;
+#else
+increment(Bigint *b)
+#endif
+{
+ ULong *x, *xe;
+ Bigint *b1;
+#ifdef Pack_16
+ ULong carry = 1, y;
+#endif
+
+ x = b->x;
+ xe = x + b->wds;
+#ifdef Pack_32
+ do {
+ if (*x < (ULong)0xffffffffL) {
+ ++*x;
+ return b;
+ }
+ *x++ = 0;
+ } while(x < xe);
+#else
+ do {
+ y = *x + carry;
+ carry = y >> 16;
+ *x++ = y & 0xffff;
+ if (!carry)
+ return b;
+ } while(x < xe);
+ if (carry)
+#endif
+ {
+ if (b->wds >= b->maxwds) {
+ b1 = Balloc(b->k+1);
+ if (b1 == NULL)
+ return NULL;
+ Bcopy(b1,b);
+ Bfree(b);
+ b = b1;
+ }
+ b->x[b->wds++] = 1;
+ }
+ return b;
+ }
+
+ int
+#ifdef KR_headers
+decrement(b) Bigint *b;
+#else
+decrement(Bigint *b)
+#endif
+{
+ ULong *x, *xe;
+#ifdef Pack_16
+ ULong borrow = 1, y;
+#endif
+
+ x = b->x;
+ xe = x + b->wds;
+#ifdef Pack_32
+ do {
+ if (*x) {
+ --*x;
+ break;
+ }
+ *x++ = 0xffffffffUL;
+ }
+ while(x < xe);
+#else
+ do {
+ y = *x - borrow;
+ borrow = (y & 0x10000) >> 16;
+ *x++ = y & 0xffff;
+ } while(borrow && x < xe);
+#endif
+ return STRTOG_Inexlo;
+ }
+
+ static int
+#ifdef KR_headers
+all_on(b, n) CONST Bigint *b; int n;
+#else
+all_on(CONST Bigint *b, int n)
+#endif
+{
+ CONST ULong *x, *xe;
+
+ x = b->x;
+ xe = x + ((unsigned int)n >> kshift);
+ while(x < xe)
+ if ((*x++ & ALL_ON) != ALL_ON)
+ return 0;
+ if (n &= kmask)
+ return ((*x | (ALL_ON << n)) & ALL_ON) == ALL_ON;
+ return 1;
+ }
+
+ Bigint *
+#ifdef KR_headers
+set_ones(b, n) Bigint *b; int n;
+#else
+set_ones(Bigint *b, int n)
+#endif
+{
+ int k;
+ ULong *x, *xe;
+
+ k = (unsigned int)(n + ((1 << kshift) - 1)) >> kshift;
+ if (b->k < k) {
+ Bfree(b);
+ b = Balloc(k);
+ if (b == NULL)
+ return NULL;
+ }
+ k = (unsigned int)n >> kshift;
+ if (n &= kmask)
+ k++;
+ b->wds = k;
+ x = b->x;
+ xe = x + k;
+ while(x < xe)
+ *x++ = ALL_ON;
+ if (n)
+ x[-1] >>= ULbits - n;
+ return b;
+ }
+
+ static int
+rvOK
+#ifdef KR_headers
+ (d, fpi, expt, bits, exact, rd, irv)
+ double d; CONST FPI *fpi; Long *expt; ULong *bits; int exact, rd, *irv;
+#else
+ (double d, CONST FPI *fpi, Long *expt, ULong *bits, int exact, int rd, int *irv)
+#endif
+{
+ Bigint *b;
+ ULong carry, inex, lostbits;
+ int bdif, e, j, k, k1, nb, rv;
+
+ carry = rv = 0;
+ b = d2b(d, &e, &bdif);
+ bdif -= nb = fpi->nbits;
+ e += bdif;
+ if (bdif <= 0) {
+ if (exact)
+ goto trunc;
+ goto ret;
+ }
+ if (P == nb) {
+ if (
+#ifndef IMPRECISE_INEXACT
+ exact &&
+#endif
+ fpi->rounding ==
+#ifdef RND_PRODQUOT
+ FPI_Round_near
+#else
+ Flt_Rounds
+#endif
+ ) goto trunc;
+ goto ret;
+ }
+ switch(rd) {
+ case 1:
+ goto trunc;
+ case 2:
+ break;
+ default: /* round near */
+ k = bdif - 1;
+ if (!k) {
+ if (!exact)
+ goto ret;
+ if (b->x[0] & 2)
+ break;
+ goto trunc;
+ }
+ if (b->x[(unsigned int)k>>kshift] & ((ULong)1 << (k & kmask)))
+ break;
+ goto trunc;
+ }
+ /* "break" cases: round up 1 bit, then truncate; bdif > 0 */
+ carry = 1;
+ trunc:
+ inex = lostbits = 0;
+ if (bdif > 0) {
+ if ( (lostbits = any_on(b, bdif)) !=0)
+ inex = STRTOG_Inexlo;
+ rshift(b, bdif);
+ if (carry) {
+ inex = STRTOG_Inexhi;
+ b = increment(b);
+ if ( (j = nb & kmask) !=0)
+ j = ULbits - j;
+ if (hi0bits(b->x[b->wds - 1]) != j) {
+ if (!lostbits)
+ lostbits = b->x[0] & 1;
+ rshift(b, 1);
+ e++;
+ }
+ }
+ }
+ else if (bdif < 0)
+ b = lshift(b, -bdif);
+ if (e < fpi->emin) {
+ k = fpi->emin - e;
+ e = fpi->emin;
+ if (k > nb || fpi->sudden_underflow) {
+ inex = b->wds = 0;
+ *irv = STRTOG_Underflow | STRTOG_Inexlo;
+ }
+ else {
+ k1 = k - 1;
+ if (k1 > 0 && !lostbits)
+ lostbits = any_on(b, k1);
+ if (!lostbits && !exact)
+ goto ret;
+ lostbits |=
+ carry = b->x[(unsigned int)k1>>kshift] &
+ (ULong)(1 << ((unsigned int)k1 & kmask));
+ rshift(b, k);
+ *irv = STRTOG_Denormal;
+ if (carry) {
+ b = increment(b);
+ inex = STRTOG_Inexhi | STRTOG_Underflow;
+ }
+ else if (lostbits)
+ inex = STRTOG_Inexlo | STRTOG_Underflow;
+ }
+ }
+ else if (e > fpi->emax) {
+ e = fpi->emax + 1;
+ *irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi;
+#ifndef NO_ERRNO
+ errno = ERANGE;
+#endif
+ inex = b->wds = 0;
+ }
+ *expt = e;
+ copybits(bits, nb, b);
+ *irv |= inex;
+ rv = 1;
+ ret:
+ Bfree(b);
+ return rv;
+ }
+
+#ifndef VAX
+ static int
+#ifdef KR_headers
+mantbits(d) double d;
+#else
+mantbits(double d)
+#endif
+{
+ ULong L;
+#ifdef VAX
+ L = word1(d) << 16 | word1(d) >> 16;
+ if (L)
+#else
+ if ( (L = word1(d)) !=0)
+#endif
+ return P - lo0bits(&L);
+#ifdef VAX
+ L = word0(d) << 16 | word0(d) >> 16 | Exp_msk11;
+#else
+ L = word0(d) | Exp_msk1;
+#endif
+ return P - 32 - lo0bits(&L);
+ }
+#endif /* !VAX */
+
+ int
+strtodg
+#ifdef KR_headers
+ (s00, se, fpi, expt, bits)
+ CONST char *s00; char **se; CONST FPI *fpi; Long *expt; ULong *bits;
+#else
+ (CONST char *s00, char **se, CONST FPI *fpi, Long *expt, ULong *bits)
+#endif
+{
+ int abe, abits, asub;
+ int bb0, bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, denorm;
+ int dsign, e, e1, e2, emin, esign, finished, i, inex, irv;
+ int j, k, nbits, nd, nd0, nf, nz, nz0, rd, rvbits, rve, rve1, sign;
+ int sudden_underflow = 0; /* pacify gcc */
+ CONST char *s, *s0, *s1;
+ double adj, adj0, rv, tol;
+ Long L;
+ ULong y, z;
+ Bigint *ab, *bb, *bb1, *bd, *bd0, *bs, *delta, *rvb, *rvb0;
+
+ e2 = 0; /* XXX gcc */
+
+ irv = STRTOG_Zero;
+ denorm = sign = nz0 = nz = 0;
+ dval(rv) = 0.;
+ rvb = 0;
+ nbits = fpi->nbits;
+ for(s = s00;;s++) switch(*s) {
+ case '-':
+ sign = 1;
+ /* FALLTHROUGH */
+ case '+':
+ if (*++s)
+ goto break2;
+ /* FALLTHROUGH */
+ case 0:
+ sign = 0;
+ irv = STRTOG_NoNumber;
+ s = s00;
+ goto ret;
+ case '\t':
+ case '\n':
+ case '\v':
+ case '\f':
+ case '\r':
+ case ' ':
+ continue;
+ default:
+ goto break2;
+ }
+ break2:
+ if (*s == '0') {
+#ifndef NO_HEX_FP
+ switch(s[1]) {
+ case 'x':
+ case 'X':
+ irv = gethex(&s, fpi, expt, &rvb, sign);
+ if (irv == STRTOG_NoNumber) {
+ s = s00;
+ sign = 0;
+ }
+ goto ret;
+ }
+#endif
+ nz0 = 1;
+ while(*++s == '0') ;
+ if (!*s)
+ goto ret;
+ }
+ sudden_underflow = fpi->sudden_underflow;
+ s0 = s;
+ y = z = 0;
+ for(decpt = nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
+ if (nd < 9)
+ y = 10*y + c - '0';
+ else if (nd < 16)
+ z = 10*z + c - '0';
+ nd0 = nd;
+#ifdef USE_LOCALE
+ if (c == *localeconv()->decimal_point)
+#else
+ if (c == '.')
+#endif
+ {
+ decpt = 1;
+ c = *++s;
+ if (!nd) {
+ for(; c == '0'; c = *++s)
+ nz++;
+ if (c > '0' && c <= '9') {
+ s0 = s;
+ nf += nz;
+ nz = 0;
+ goto have_dig;
+ }
+ goto dig_done;
+ }
+ for(; c >= '0' && c <= '9'; c = *++s) {
+ have_dig:
+ nz++;
+ if (c -= '0') {
+ nf += nz;
+ for(i = 1; i < nz; i++)
+ if (nd++ < 9)
+ y *= 10;
+ else if (nd <= DBL_DIG + 1)
+ z *= 10;
+ if (nd++ < 9)
+ y = 10*y + c;
+ else if (nd <= DBL_DIG + 1)
+ z = 10*z + c;
+ nz = 0;
+ }
+ }
+ }
+ dig_done:
+ e = 0;
+ if (c == 'e' || c == 'E') {
+ if (!nd && !nz && !nz0) {
+ irv = STRTOG_NoNumber;
+ s = s00;
+ goto ret;
+ }
+ s00 = s;
+ esign = 0;
+ switch(c = *++s) {
+ case '-':
+ esign = 1;
+ /* FALLTHROUGH */
+ case '+':
+ c = *++s;
+ }
+ if (c >= '0' && c <= '9') {
+ while(c == '0')
+ c = *++s;
+ if (c > '0' && c <= '9') {
+ L = c - '0';
+ s1 = s;
+ while((c = *++s) >= '0' && c <= '9')
+ L = 10*L + c - '0';
+ if (s - s1 > 8 || L > 19999)
+ /* Avoid confusion from exponents
+ * so large that e might overflow.
+ */
+ e = 19999; /* safe for 16 bit ints */
+ else
+ e = (int)L;
+ if (esign)
+ e = -e;
+ }
+ else
+ e = 0;
+ }
+ else
+ s = s00;
+ }
+ if (!nd) {
+ if (!nz && !nz0) {
+#ifdef INFNAN_CHECK
+ /* Check for Nan and Infinity */
+ if (!decpt)
+ switch(c) {
+ case 'i':
+ case 'I':
+ if (match(&s,"nf")) {
+ --s;
+ if (!match(&s,"inity"))
+ ++s;
+ irv = STRTOG_Infinite;
+ goto infnanexp;
+ }
+ break;
+ case 'n':
+ case 'N':
+ if (match(&s, "an")) {
+ irv = STRTOG_NaN;
+ *expt = fpi->emax + 1;
+#ifndef No_Hex_NaN
+ if (*s == '(') /*)*/
+ irv = hexnan(&s, fpi, bits);
+#endif
+ goto infnanexp;
+ }
+ }
+#endif /* INFNAN_CHECK */
+ irv = STRTOG_NoNumber;
+ s = s00;
+ }
+ goto ret;
+ }
+
+ irv = STRTOG_Normal;
+ e1 = e -= nf;
+ rd = 0;
+ switch(fpi->rounding & 3) {
+ case FPI_Round_up:
+ rd = 2 - sign;
+ break;
+ case FPI_Round_zero:
+ rd = 1;
+ break;
+ case FPI_Round_down:
+ rd = 1 + sign;
+ }
+
+ /* Now we have nd0 digits, starting at s0, followed by a
+ * decimal point, followed by nd-nd0 digits. The number we're
+ * after is the integer represented by those digits times
+ * 10**e */
+
+ if (!nd0)
+ nd0 = nd;
+ k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
+ dval(rv) = (double)y;
+ if (k > 9)
+ dval(rv) = tens[k - 9] * dval(rv) + z;
+ bd0 = 0;
+ if (nbits <= P && nd <= DBL_DIG) {
+ if (!e) {
+ if (rvOK(dval(rv), fpi, expt, bits, 1, rd, &irv))
+ goto ret;
+ }
+ else if (e > 0) {
+ if (e <= Ten_pmax) {
+#ifdef VAX
+ goto vax_ovfl_check;
+#else
+ i = fivesbits[e] + mantbits(dval(rv)) <= P;
+ /* rv = */ rounded_product(dval(rv), tens[e]);
+ if (rvOK(dval(rv), fpi, expt, bits, i, rd, &irv))
+ goto ret;
+ e1 -= e;
+ goto rv_notOK;
+#endif
+ }
+ i = DBL_DIG - nd;
+ if (e <= Ten_pmax + i) {
+ /* A fancier test would sometimes let us do
+ * this for larger i values.
+ */
+ e2 = e - i;
+ e1 -= i;
+ dval(rv) *= tens[i];
+#ifdef VAX
+ /* VAX exponent range is so narrow we must
+ * worry about overflow here...
+ */
+ vax_ovfl_check:
+ dval(adj) = dval(rv);
+ word0(adj) -= P*Exp_msk1;
+ /* adj = */ rounded_product(dval(adj), tens[e2]);
+ if ((word0(adj) & Exp_mask)
+ > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
+ goto rv_notOK;
+ word0(adj) += P*Exp_msk1;
+ dval(rv) = dval(adj);
+#else
+ /* rv = */ rounded_product(dval(rv), tens[e2]);
+#endif
+ if (rvOK(dval(rv), fpi, expt, bits, 0, rd, &irv))
+ goto ret;
+ e1 -= e2;
+ }
+ }
+#ifndef Inaccurate_Divide
+ else if (e >= -Ten_pmax) {
+ /* rv = */ rounded_quotient(dval(rv), tens[-e]);
+ if (rvOK(dval(rv), fpi, expt, bits, 0, rd, &irv))
+ goto ret;
+ e1 -= e;
+ }
+#endif
+ }
+ rv_notOK:
+ e1 += nd - k;
+
+ /* Get starting approximation = rv * 10**e1 */
+
+ e2 = 0;
+ if (e1 > 0) {
+ if ( (i = e1 & 15) !=0)
+ dval(rv) *= tens[i];
+ if (e1 &= ~15) {
+ e1 = (unsigned int)e1 >> 4;
+ while(e1 >= (1 << (n_bigtens-1))) {
+ e2 += ((word0(rv) & Exp_mask)
+ >> Exp_shift1) - Bias;
+ word0(rv) &= ~Exp_mask;
+ word0(rv) |= Bias << Exp_shift1;
+ dval(rv) *= bigtens[n_bigtens-1];
+ e1 -= 1 << (n_bigtens-1);
+ }
+ e2 += ((word0(rv) & Exp_mask) >> Exp_shift1) - Bias;
+ word0(rv) &= ~Exp_mask;
+ word0(rv) |= Bias << Exp_shift1;
+ for(j = 0; e1 > 0; j++, e1 = (unsigned int)e1 >> 1)
+ if (e1 & 1)
+ dval(rv) *= bigtens[j];
+ }
+ }
+ else if (e1 < 0) {
+ e1 = -e1;
+ if ( (i = e1 & 15) !=0)
+ dval(rv) /= tens[i];
+ if (e1 &= ~15) {
+ e1 = (unsigned int)e1 >> 4;
+ while(e1 >= (1 << (n_bigtens-1))) {
+ e2 += ((word0(rv) & Exp_mask)
+ >> Exp_shift1) - Bias;
+ word0(rv) &= ~Exp_mask;
+ word0(rv) |= Bias << Exp_shift1;
+ dval(rv) *= tinytens[n_bigtens-1];
+ e1 -= 1 << (n_bigtens-1);
+ }
+ e2 += ((word0(rv) & Exp_mask) >> Exp_shift1) - Bias;
+ word0(rv) &= ~Exp_mask;
+ word0(rv) |= Bias << Exp_shift1;
+ for(j = 0; e1 > 0; j++, e1 = (unsigned int)e1 >> 1)
+ if (e1 & 1)
+ dval(rv) *= tinytens[j];
+ }
+ }
+#ifdef IBM
+ /* e2 is a correction to the (base 2) exponent of the return
+ * value, reflecting adjustments above to avoid overflow in the
+ * native arithmetic. For native IBM (base 16) arithmetic, we
+ * must multiply e2 by 4 to change from base 16 to 2.
+ */
+ e2 <<= 2;
+#endif
+ rvb = d2b(dval(rv), &rve, &rvbits); /* rv = rvb * 2^rve */
+ if (rvb == NULL)
+ return STRTOG_NoMemory;
+ rve += e2;
+ if ((j = rvbits - nbits) > 0) {
+ rshift(rvb, j);
+ rvbits = nbits;
+ rve += j;
+ }
+ bb0 = 0; /* trailing zero bits in rvb */
+ e2 = rve + rvbits - nbits;
+ if (e2 > fpi->emax + 1)
+ goto huge;
+ rve1 = rve + rvbits - nbits;
+ if (e2 < (emin = fpi->emin)) {
+ denorm = 1;
+ j = rve - emin;
+ if (j > 0) {
+ rvb = lshift(rvb, j);
+ rvbits += j;
+ }
+ else if (j < 0) {
+ rvbits += j;
+ if (rvbits <= 0) {
+ if (rvbits < -1) {
+ ufl:
+ rvb->wds = 0;
+ rvb->x[0] = 0;
+ *expt = emin;
+ irv = STRTOG_Underflow | STRTOG_Inexlo;
+ goto ret;
+ }
+ rvb->x[0] = rvb->wds = rvbits = 1;
+ }
+ else
+ rshift(rvb, -j);
+ }
+ rve = rve1 = emin;
+ if (sudden_underflow && e2 + 1 < emin)
+ goto ufl;
+ }
+
+ /* Now the hard part -- adjusting rv to the correct value.*/
+
+ /* Put digits into bd: true value = bd * 10^e */
+
+ bd0 = s2b(s0, nd0, nd, y);
+
+ for(;;) {
+ bd = Balloc(bd0->k);
+ if (bd == NULL)
+ return STRTOG_NoMemory;
+ Bcopy(bd, bd0);
+ bb = Balloc(rvb->k);
+ if (bb == NULL)
+ return STRTOG_NoMemory;
+ Bcopy(bb, rvb);
+ bbbits = rvbits - bb0;
+ bbe = rve + bb0;
+ bs = i2b(1);
+ if (bs == NULL)
+ return STRTOG_NoMemory;
+
+ if (e >= 0) {
+ bb2 = bb5 = 0;
+ bd2 = bd5 = e;
+ }
+ else {
+ bb2 = bb5 = -e;
+ bd2 = bd5 = 0;
+ }
+ if (bbe >= 0)
+ bb2 += bbe;
+ else
+ bd2 -= bbe;
+ bs2 = bb2;
+ j = nbits + 1 - bbbits;
+ i = bbe + bbbits - nbits;
+ if (i < emin) /* denormal */
+ j += i - emin;
+ bb2 += j;
+ bd2 += j;
+ i = bb2 < bd2 ? bb2 : bd2;
+ if (i > bs2)
+ i = bs2;
+ if (i > 0) {
+ bb2 -= i;
+ bd2 -= i;
+ bs2 -= i;
+ }
+ if (bb5 > 0) {
+ bs = pow5mult(bs, bb5);
+ if (bs == NULL)
+ return STRTOG_NoMemory;
+ bb1 = mult(bs, bb);
+ if (bb1 == NULL)
+ return STRTOG_NoMemory;
+ Bfree(bb);
+ bb = bb1;
+ }
+ bb2 -= bb0;
+ if (bb2 > 0) {
+ bb = lshift(bb, bb2);
+ if (bb == NULL)
+ return STRTOG_NoMemory;
+ }
+ else if (bb2 < 0)
+ rshift(bb, -bb2);
+ if (bd5 > 0) {
+ bd = pow5mult(bd, bd5);
+ if (bd == NULL)
+ return STRTOG_NoMemory;
+ }
+ if (bd2 > 0) {
+ bd = lshift(bd, bd2);
+ if (bd == NULL)
+ return STRTOG_NoMemory;
+ }
+ if (bs2 > 0) {
+ bs = lshift(bs, bs2);
+ if (bs == NULL)
+ return STRTOG_NoMemory;
+ }
+ asub = 1;
+ inex = STRTOG_Inexhi;
+ delta = diff(bb, bd);
+ if (delta == NULL)
+ return STRTOG_NoMemory;
+ if (delta->wds <= 1 && !delta->x[0])
+ break;
+ dsign = delta->sign;
+ delta->sign = finished = 0;
+ L = 0;
+ i = cmp(delta, bs);
+ if (rd && i <= 0) {
+ irv = STRTOG_Normal;
+ if ( (finished = dsign ^ (rd&1)) !=0) {
+ if (dsign != 0) {
+ irv |= STRTOG_Inexhi;
+ goto adj1;
+ }
+ irv |= STRTOG_Inexlo;
+ if (rve1 == emin)
+ goto adj1;
+ for(i = 0, j = nbits; j >= ULbits;
+ i++, j -= ULbits) {
+ if (rvb->x[i] & ALL_ON)
+ goto adj1;
+ }
+ if (j > 1 && lo0bits(rvb->x + i) < j - 1)
+ goto adj1;
+ rve = rve1 - 1;
+ rvb = set_ones(rvb, rvbits = nbits);
+ if (rvb == NULL)
+ return STRTOG_NoMemory;
+ break;
+ }
+ irv |= dsign ? STRTOG_Inexlo : STRTOG_Inexhi;
+ break;
+ }
+ if (i < 0) {
+ /* Error is less than half an ulp -- check for
+ * special case of mantissa a power of two.
+ */
+ irv = dsign
+ ? STRTOG_Normal | STRTOG_Inexlo
+ : STRTOG_Normal | STRTOG_Inexhi;
+ if (dsign || bbbits > 1 || denorm || rve1 == emin)
+ break;
+ delta = lshift(delta,1);
+ if (delta == NULL)
+ return STRTOG_NoMemory;
+ if (cmp(delta, bs) > 0) {
+ irv = STRTOG_Normal | STRTOG_Inexlo;
+ goto drop_down;
+ }
+ break;
+ }
+ if (i == 0) {
+ /* exactly half-way between */
+ if (dsign) {
+ if (denorm && all_on(rvb, rvbits)) {
+ /*boundary case -- increment exponent*/
+ rvb->wds = 1;
+ rvb->x[0] = 1;
+ rve = emin + nbits - (rvbits = 1);
+ irv = STRTOG_Normal | STRTOG_Inexhi;
+ denorm = 0;
+ break;
+ }
+ irv = STRTOG_Normal | STRTOG_Inexlo;
+ }
+ else if (bbbits == 1) {
+ irv = STRTOG_Normal;
+ drop_down:
+ /* boundary case -- decrement exponent */
+ if (rve1 == emin) {
+ irv = STRTOG_Normal | STRTOG_Inexhi;
+ if (rvb->wds == 1 && rvb->x[0] == 1)
+ sudden_underflow = 1;
+ break;
+ }
+ rve -= nbits;
+ rvb = set_ones(rvb, rvbits = nbits);
+ if (rvb == NULL)
+ return STRTOG_NoMemory;
+ break;
+ }
+ else
+ irv = STRTOG_Normal | STRTOG_Inexhi;
+ if ((bbbits < nbits && !denorm) || !(rvb->x[0] & 1))
+ break;
+ if (dsign) {
+ rvb = increment(rvb);
+ if (rvb == NULL)
+ return STRTOG_NoMemory;
+ if ( (j = rvbits & kmask) !=0)
+ j = ULbits - j;
+ if (hi0bits(rvb->x[(unsigned int)(rvb->wds - 1)
+ >> kshift])
+ != j)
+ rvbits++;
+ irv = STRTOG_Normal | STRTOG_Inexhi;
+ }
+ else {
+ if (bbbits == 1)
+ goto undfl;
+ decrement(rvb);
+ irv = STRTOG_Normal | STRTOG_Inexlo;
+ }
+ break;
+ }
+ if ((dval(adj) = ratio(delta, bs)) <= 2.) {
+ adj1:
+ inex = STRTOG_Inexlo;
+ if (dsign) {
+ asub = 0;
+ inex = STRTOG_Inexhi;
+ }
+ else if (denorm && bbbits <= 1) {
+ undfl:
+ rvb->wds = 0;
+ rve = emin;
+ irv = STRTOG_Underflow | STRTOG_Inexlo;
+ break;
+ }
+ adj0 = dval(adj) = 1.;
+ }
+ else {
+ adj0 = dval(adj) *= 0.5;
+ if (dsign) {
+ asub = 0;
+ inex = STRTOG_Inexlo;
+ }
+ if (dval(adj) < 2147483647.) {
+ L = (INT32)adj0;
+ adj0 -= L;
+ switch(rd) {
+ case 0:
+ if (adj0 >= .5)
+ goto inc_L;
+ break;
+ case 1:
+ if (asub && adj0 > 0.)
+ goto inc_L;
+ break;
+ case 2:
+ if (!asub && adj0 > 0.) {
+ inc_L:
+ L++;
+ inex = STRTOG_Inexact - inex;
+ }
+ }
+ dval(adj) = (double)L;
+ }
+ }
+ y = rve + rvbits;
+
+ /* adj *= ulp(dval(rv)); */
+ /* if (asub) rv -= adj; else rv += adj; */
+
+ if (!denorm && rvbits < nbits) {
+ rvb = lshift(rvb, j = nbits - rvbits);
+ if (rvb == NULL)
+ return STRTOG_NoMemory;
+ rve -= j;
+ rvbits = nbits;
+ }
+ ab = d2b(dval(adj), &abe, &abits);
+ if (ab == NULL)
+ return STRTOG_NoMemory;
+ if (abe < 0)
+ rshift(ab, -abe);
+ else if (abe > 0)
+ ab = lshift(ab, abe);
+ rvb0 = rvb;
+ if (asub) {
+ /* rv -= adj; */
+ j = hi0bits(rvb->x[rvb->wds-1]);
+ rvb = diff(rvb, ab);
+ if (rvb == NULL)
+ return STRTOG_NoMemory;
+ k = rvb0->wds - 1;
+ if (denorm)
+ /* do nothing */;
+ else if (rvb->wds <= k
+ || hi0bits( rvb->x[k]) >
+ hi0bits(rvb0->x[k])) {
+ /* unlikely; can only have lost 1 high bit */
+ if (rve1 == emin) {
+ --rvbits;
+ denorm = 1;
+ }
+ else {
+ rvb = lshift(rvb, 1);
+ if (rvb == NULL)
+ return STRTOG_NoMemory;
+ --rve;
+ --rve1;
+ L = finished = 0;
+ }
+ }
+ }
+ else {
+ rvb = sum(rvb, ab);
+ if (rvb == NULL)
+ return STRTOG_NoMemory;
+ k = rvb->wds - 1;
+ if (k >= rvb0->wds
+ || hi0bits(rvb->x[k]) < hi0bits(rvb0->x[k])) {
+ if (denorm) {
+ if (++rvbits == nbits)
+ denorm = 0;
+ }
+ else {
+ rshift(rvb, 1);
+ rve++;
+ rve1++;
+ L = 0;
+ }
+ }
+ }
+ Bfree(ab);
+ Bfree(rvb0);
+ if (finished)
+ break;
+
+ z = rve + rvbits;
+ if (y == z && L) {
+ /* Can we stop now? */
+ tol = dval(adj) * 5e-16; /* > max rel error */
+ dval(adj) = adj0 - .5;
+ if (dval(adj) < -tol) {
+ if (adj0 > tol) {
+ irv |= inex;
+ break;
+ }
+ }
+ else if (dval(adj) > tol && adj0 < 1. - tol) {
+ irv |= inex;
+ break;
+ }
+ }
+ bb0 = denorm ? 0 : trailz(rvb);
+ Bfree(bb);
+ Bfree(bd);
+ Bfree(bs);
+ Bfree(delta);
+ }
+ if (!denorm && (j = nbits - rvbits)) {
+ if (j > 0)
+ rvb = lshift(rvb, j);
+ else
+ rshift(rvb, -j);
+ rve -= j;
+ }
+ *expt = rve;
+ Bfree(bb);
+ Bfree(bd);
+ Bfree(bs);
+ Bfree(bd0);
+ Bfree(delta);
+ if (rve > fpi->emax) {
+ huge:
+ rvb->wds = 0;
+ irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi;
+#ifndef NO_ERRNO
+ errno = ERANGE;
+#endif
+#ifdef INFNAN_CHECK
+ infnanexp:
+#endif
+ *expt = fpi->emax + 1;
+ }
+ ret:
+ if (denorm) {
+ if (sudden_underflow) {
+ rvb->wds = 0;
+ irv = STRTOG_Underflow | STRTOG_Inexlo;
+ }
+ else {
+ irv = (irv & ~STRTOG_Retmask) |
+ (rvb->wds > 0 ? STRTOG_Denormal : STRTOG_Zero);
+ if (irv & STRTOG_Inexact)
+ irv |= STRTOG_Underflow;
+ }
+ }
+ if (se)
+ *se = __UNCONST(s);
+ if (sign)
+ irv |= STRTOG_Neg;
+ if (rvb) {
+ copybits(bits, nbits, rvb);
+ Bfree(rvb);
+ }
+ return irv;
+ }
diff --git a/StdLib/LibC/gdtoa/strtof.c b/StdLib/LibC/gdtoa/strtof.c
new file mode 100644
index 0000000000..44a4cb3746
--- /dev/null
+++ b/StdLib/LibC/gdtoa/strtof.c
@@ -0,0 +1,85 @@
+/* $NetBSD: strtof.c,v 1.2.14.1 2008/04/08 21:10:55 jdc Exp $ */
+
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998, 2000 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+#include <LibConfig.h>
+
+#include "namespace.h"
+#include "gdtoaimp.h"
+
+#ifdef __weak_alias
+__weak_alias(strtof, _strtof)
+#endif
+
+ float
+#ifdef KR_headers
+strtof(s, sp) CONST char *s; char **sp;
+#else
+strtof(CONST char *s, char **sp)
+#endif
+{
+ static CONST FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, SI };
+ ULong bits[1];
+ Long expt;
+ int k;
+ union { ULong L[1]; float f; } u = { 0 };
+
+ k = strtodg(s, sp, &fpi, &expt, bits);
+ if (k == STRTOG_NoMemory) {
+ errno = ERANGE;
+ return HUGE_VALF;
+ }
+ switch(k & STRTOG_Retmask) {
+ case STRTOG_NoNumber:
+ case STRTOG_Zero:
+ u.L[0] = 0;
+ break;
+
+ case STRTOG_Normal:
+ case STRTOG_NaNbits:
+ u.L[0] = (bits[0] & 0x7fffff) | ((expt + 0x7f + 23) << 23);
+ break;
+
+ case STRTOG_Denormal:
+ u.L[0] = bits[0];
+ break;
+
+ case STRTOG_Infinite:
+ u.L[0] = 0x7f800000;
+ break;
+
+ case STRTOG_NaN:
+ u.L[0] = f_QNAN;
+ }
+ if (k & STRTOG_Neg)
+ u.L[0] |= 0x80000000L;
+ return u.f;
+ }
diff --git a/StdLib/LibC/gdtoa/strtold_px.c b/StdLib/LibC/gdtoa/strtold_px.c
new file mode 100644
index 0000000000..f5920b2c4c
--- /dev/null
+++ b/StdLib/LibC/gdtoa/strtold_px.c
@@ -0,0 +1,4 @@
+/* $NetBSD: strtold_px.c,v 1.1 2006/03/15 17:35:18 kleink Exp $ */
+
+#define GDTOA_LD_FMT x
+#include "strtold_subr.c"
diff --git a/StdLib/LibC/gdtoa/strtold_subr.c b/StdLib/LibC/gdtoa/strtold_subr.c
new file mode 100644
index 0000000000..db85fe8f23
--- /dev/null
+++ b/StdLib/LibC/gdtoa/strtold_subr.c
@@ -0,0 +1,45 @@
+/* $NetBSD: strtold_subr.c,v 1.1 2006/03/15 17:35:18 kleink Exp $ */
+
+/*
+ * Written by Klaus Klein <kleink@NetBSD.org>, November 16, 2005.
+ * Public domain.
+ */
+
+/*
+ * NOTICE: This is not a standalone file. To use it, #include it in
+ * the format-specific strtold_*.c, like so:
+ *
+ * #define GDTOA_LD_FMT <gdtoa extended-precision format code>
+ * #include "strtold_subr.c"
+ */
+#include <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+#include "namespace.h"
+#include <math.h>
+#include <sys/stdint.h>
+#include <stdlib.h>
+#include "gdtoa.h"
+
+#ifdef __weak_alias
+__weak_alias(strtold, _strtold)
+#endif
+
+#ifndef __HAVE_LONG_DOUBLE
+#error no extended-precision long double type
+#endif
+
+#ifndef GDTOA_LD_FMT
+#error GDTOA_LD_FMT must be defined by format-specific source file
+#endif
+
+#define STRTOP(x) __CONCAT(strtop, x)
+
+long double
+strtold(const char *nptr, char **endptr)
+{
+ long double ld;
+
+ (void)STRTOP(GDTOA_LD_FMT)(nptr, endptr, &ld);
+ return ld;
+}
diff --git a/StdLib/LibC/gdtoa/strtopx.c b/StdLib/LibC/gdtoa/strtopx.c
new file mode 100644
index 0000000000..5dce12e0c6
--- /dev/null
+++ b/StdLib/LibC/gdtoa/strtopx.c
@@ -0,0 +1,108 @@
+/* $NetBSD: strtopx.c,v 1.3.14.1 2008/04/08 21:10:55 jdc Exp $ */
+
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998, 2000 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+#include <LibConfig.h>
+
+#include "gdtoaimp.h"
+
+#undef _0
+#undef _1
+
+/* one or the other of IEEE_BIG_ENDIAN or IEEE_LITTLE_ENDIAN should be #defined */
+
+#ifdef IEEE_BIG_ENDIAN
+#define _0 0
+#define _1 1
+#define _2 2
+#define _3 3
+#define _4 4
+#endif
+#ifdef IEEE_LITTLE_ENDIAN
+#define _0 4
+#define _1 3
+#define _2 2
+#define _3 1
+#define _4 0
+#endif
+
+ int
+#ifdef KR_headers
+strtopx(s, sp, V) CONST char *s; char **sp; void *V;
+#else
+strtopx(CONST char *s, char **sp, void *V)
+#endif
+{
+ static CONST FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI };
+ ULong bits[2];
+ Long expt;
+ int k;
+ UShort *L = (UShort*)V;
+
+ k = strtodg(s, sp, &fpi, &expt, bits);
+ if (k == STRTOG_NoMemory)
+ return k;
+ switch(k & STRTOG_Retmask) {
+ case STRTOG_NoNumber:
+ case STRTOG_Zero:
+ L[0] = L[1] = L[2] = L[3] = L[4] = 0;
+ break;
+
+ case STRTOG_Denormal:
+ L[_0] = 0;
+ goto normal_bits;
+
+ case STRTOG_Normal:
+ case STRTOG_NaNbits:
+ L[_0] = (UShort)(expt + 0x3fff + 63);
+ normal_bits:
+ L[_4] = (UShort)bits[0];
+ L[_3] = (UShort)(bits[0] >> 16);
+ L[_2] = (UShort)bits[1];
+ L[_1] = (UShort)(bits[1] >> 16);
+ break;
+
+ case STRTOG_Infinite:
+ L[_0] = 0x7fff;
+ L[_1] = L[_2] = L[_3] = L[_4] = 0;
+ break;
+
+ case STRTOG_NaN:
+ L[0] = ldus_QNAN0;
+ L[1] = ldus_QNAN1;
+ L[2] = ldus_QNAN2;
+ L[3] = ldus_QNAN3;
+ L[4] = ldus_QNAN4;
+ }
+ if (k & STRTOG_Neg)
+ L[_0] |= 0x8000;
+ return k;
+ }
diff --git a/StdLib/LibC/gdtoa/sum.c b/StdLib/LibC/gdtoa/sum.c
new file mode 100644
index 0000000000..850c1f0134
--- /dev/null
+++ b/StdLib/LibC/gdtoa/sum.c
@@ -0,0 +1,105 @@
+/* $NetBSD: sum.c,v 1.1.1.1.14.1 2008/04/08 21:10:55 jdc Exp $ */
+
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+#include <LibConfig.h>
+
+#include "gdtoaimp.h"
+
+ Bigint *
+#ifdef KR_headers
+sum(a, b) Bigint *a; Bigint *b;
+#else
+sum(Bigint *a, Bigint *b)
+#endif
+{
+ Bigint *c;
+ ULong carry, *xc, *xa, *xb, *xe, y;
+#ifdef Pack_32
+ ULong z;
+#endif
+
+ if (a->wds < b->wds) {
+ c = b; b = a; a = c;
+ }
+ c = Balloc(a->k);
+ if (c == NULL)
+ return NULL;
+ c->wds = a->wds;
+ carry = 0;
+ xa = a->x;
+ xb = b->x;
+ xc = c->x;
+ xe = xc + b->wds;
+#ifdef Pack_32
+ do {
+ y = (*xa & 0xffff) + (*xb & 0xffff) + carry;
+ carry = (y & 0x10000) >> 16;
+ z = (*xa++ >> 16) + (*xb++ >> 16) + carry;
+ carry = (z & 0x10000) >> 16;
+ Storeinc(xc, z, y);
+ }
+ while(xc < xe);
+ xe += a->wds - b->wds;
+ while(xc < xe) {
+ y = (*xa & 0xffff) + carry;
+ carry = (y & 0x10000) >> 16;
+ z = (*xa++ >> 16) + carry;
+ carry = (z & 0x10000) >> 16;
+ Storeinc(xc, z, y);
+ }
+#else
+ do {
+ y = *xa++ + *xb++ + carry;
+ carry = (y & 0x10000) >> 16;
+ *xc++ = y & 0xffff;
+ }
+ while(xc < xe);
+ xe += a->wds - b->wds;
+ while(xc < xe) {
+ y = *xa++ + carry;
+ carry = (y & 0x10000) >> 16;
+ *xc++ = y & 0xffff;
+ }
+#endif
+ if (carry) {
+ if (c->wds == c->maxwds) {
+ b = Balloc(c->k + 1);
+ if (b == NULL)
+ return NULL;
+ Bcopy(b, c);
+ Bfree(c);
+ c = b;
+ }
+ c->x[c->wds++] = 1;
+ }
+ return c;
+ }
diff --git a/StdLib/LibC/gdtoa/ulp.c b/StdLib/LibC/gdtoa/ulp.c
new file mode 100644
index 0000000000..6f2780cf02
--- /dev/null
+++ b/StdLib/LibC/gdtoa/ulp.c
@@ -0,0 +1,73 @@
+/* $NetBSD: ulp.c,v 1.2 2006/01/25 15:27:42 kleink Exp $ */
+
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998, 1999 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+#include <LibConfig.h>
+
+#include "gdtoaimp.h"
+
+ double
+ulp
+#ifdef KR_headers
+ (x) double x;
+#else
+ (double x)
+#endif
+{
+ Long L;
+ double a;
+
+ L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
+#ifndef Sudden_Underflow
+ if (L > 0) {
+#endif
+#ifdef IBM
+ L |= Exp_msk1 >> 4;
+#endif
+ word0(a) = (UINT32)L;
+ word1(a) = 0;
+#ifndef Sudden_Underflow
+ }
+ else {
+ L = (unsigned int)-L >> Exp_shift;
+ if (L < Exp_shift) {
+ word0(a) = 0x80000 >> L;
+ word1(a) = 0;
+ }
+ else {
+ word0(a) = 0;
+ L -= Exp_shift;
+ word1(a) = L >= 31 ? 1 : 1 << (31 - L);
+ }
+ }
+#endif
+ return a;
+ }