From e611b132f9b8abe35b362e5870b74bce94a1e58e Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 16 May 2020 20:51:50 -0700 Subject: initial commit --- private/crt32/buildcrt.cmd | 52 + private/crt32/convert/_ctype.c | 156 ++ private/crt32/convert/_fptostr.c | 104 + private/crt32/convert/_mbslen.c | 99 + private/crt32/convert/_wctype.c | 140 ++ private/crt32/convert/atof.c | 81 + private/crt32/convert/atox.c | 96 + private/crt32/convert/fcvt.c | 252 +++ private/crt32/convert/gcvt.c | 122 ++ private/crt32/convert/isctype.c | 119 ++ private/crt32/convert/iswctype.c | 128 ++ private/crt32/convert/makefile | 6 + private/crt32/convert/mblen.c | 109 ++ private/crt32/convert/mbstowcs.c | 197 ++ private/crt32/convert/mbtowc.c | 174 ++ private/crt32/convert/sources | 64 + private/crt32/convert/strtod.c | 121 ++ private/crt32/convert/strtol.c | 227 +++ private/crt32/convert/strtoq.c | 236 +++ private/crt32/convert/swab.c | 58 + private/crt32/convert/testconv.c | 152 ++ private/crt32/convert/tolower.c | 155 ++ private/crt32/convert/toupper.c | 189 ++ private/crt32/convert/towlower.c | 84 + private/crt32/convert/towupper.c | 94 + private/crt32/convert/wcstod.c | 115 ++ private/crt32/convert/wcstol.c | 215 +++ private/crt32/convert/wcstombs.c | 213 +++ private/crt32/convert/wctomb.c | 136 ++ private/crt32/convert/wtox.c | 82 + private/crt32/convert/xtoa.c | 127 ++ private/crt32/convert/xtow.c | 85 + private/crt32/crt32.def | 95 + private/crt32/direct/drivemap.c | 39 + private/crt32/direct/drivfree.c | 69 + private/crt32/direct/findfile.c | 224 +++ private/crt32/direct/makefile | 6 + private/crt32/direct/peekpoke.c | 95 + private/crt32/direct/seterrm.c | 63 + private/crt32/direct/slbeep.c | 105 + private/crt32/direct/sources | 40 + private/crt32/dirs | 43 + private/crt32/dllstuff/cinitexe.c | 92 + private/crt32/dllstuff/crtdll.c | 376 ++++ private/crt32/dllstuff/crtexe.c | 215 +++ private/crt32/dllstuff/crtexew.c | 4 + private/crt32/dllstuff/crtlib.c | 258 +++ private/crt32/dllstuff/dllargv.c | 49 + private/crt32/dllstuff/i386/dllsupp.asm | 39 + private/crt32/dllstuff/makefile | 6 + private/crt32/dllstuff/sources | 44 + private/crt32/dos/access.c | 116 ++ private/crt32/dos/chdir.c | 138 ++ private/crt32/dos/chmod.c | 121 ++ private/crt32/dos/dosmap.c | 252 +++ private/crt32/dos/drive.c | 208 ++ private/crt32/dos/fullpath.c | 318 ++++ private/crt32/dos/getcwd.c | 451 +++++ private/crt32/dos/getpid.c | 72 + private/crt32/dos/makefile | 6 + private/crt32/dos/mkdir.c | 80 + private/crt32/dos/rename.c | 83 + private/crt32/dos/rmdir.c | 83 + private/crt32/dos/sources | 48 + private/crt32/dos/stat.c | 397 ++++ private/crt32/dos/unlink.c | 101 + private/crt32/exec/cenvarg.c | 373 ++++ private/crt32/exec/cfinfo.c | 22 + private/crt32/exec/dospawn.c | 303 +++ private/crt32/exec/execl.c | 76 + private/crt32/exec/execle.c | 79 + private/crt32/exec/execlp.c | 77 + private/crt32/exec/execlpe.c | 82 + private/crt32/exec/execv.c | 60 + private/crt32/exec/execve.c | 2 + private/crt32/exec/execvp.c | 62 + private/crt32/exec/execvpe.c | 171 ++ private/crt32/exec/fileinfo.c | 22 + private/crt32/exec/getproc.c | 62 + private/crt32/exec/loaddll.c | 70 + private/crt32/exec/makefile | 6 + private/crt32/exec/sources | 58 + private/crt32/exec/spawnl.c | 83 + private/crt32/exec/spawnle.c | 83 + private/crt32/exec/spawnlp.c | 85 + private/crt32/exec/spawnlpe.c | 87 + private/crt32/exec/spawnv.c | 67 + private/crt32/exec/spawnve.c | 318 ++++ private/crt32/exec/spawnvp.c | 62 + private/crt32/exec/spawnvpe.c | 209 ++ private/crt32/exec/system.c | 95 + private/crt32/exec/wait.c | 199 ++ private/crt32/h/assert.h | 89 + private/crt32/h/cmacros.mas | 3050 ++++++++++++++++++++++++++++++ private/crt32/h/cmsgs.h | 71 + private/crt32/h/conio.h | 127 ++ private/crt32/h/cruntime.h | 277 +++ private/crt32/h/cruntime.inc | 826 ++++++++ private/crt32/h/ctime.h | 41 + private/crt32/h/ctype.h | 321 ++++ private/crt32/h/cvt.h | 41 + private/crt32/h/defsects.inc | 58 + private/crt32/h/direct.h | 134 ++ private/crt32/h/dos.h | 222 +++ private/crt32/h/doscalls.h | 545 ++++++ private/crt32/h/dostypes.h | 112 ++ private/crt32/h/errmsg.h | 36 + private/crt32/h/errno.h | 127 ++ private/crt32/h/error.h | 383 ++++ private/crt32/h/error2.h | 277 +++ private/crt32/h/except.inc | 100 + private/crt32/h/excpt.h | 209 ++ private/crt32/h/exsup.inc | 79 + private/crt32/h/fcntl.h | 84 + private/crt32/h/file2.h | 71 + private/crt32/h/float.h | 493 +++++ private/crt32/h/fltintrn.h | 192 ++ private/crt32/h/fpieee.h | 362 ++++ private/crt32/h/fstream.h | 145 ++ private/crt32/h/heap.h | 433 +++++ private/crt32/h/internal.h | 359 ++++ private/crt32/h/io.h | 236 +++ private/crt32/h/iomanip.h | 133 ++ private/crt32/h/ios.h | 272 +++ private/crt32/h/iostream.h | 90 + private/crt32/h/istream.h | 165 ++ private/crt32/h/jctype.h | 111 ++ private/crt32/h/limits.h | 89 + private/crt32/h/locale.h | 125 ++ private/crt32/h/malloc.h | 168 ++ private/crt32/h/math.h | 283 +++ private/crt32/h/mbctype.h | 146 ++ private/crt32/h/mbdata.h | 130 ++ private/crt32/h/mbstring.h | 227 +++ private/crt32/h/memory.h | 101 + private/crt32/h/msdos.h | 83 + private/crt32/h/msdos.inc | 276 +++ private/crt32/h/mtest.h | 68 + private/crt32/h/new.h | 67 + private/crt32/h/nlsint.h | 60 + private/crt32/h/os2dll.h | 260 +++ private/crt32/h/oscalls.h | 141 ++ private/crt32/h/ostream.h | 135 ++ private/crt32/h/process.h | 244 +++ private/crt32/h/pversion.inc | 28 + private/crt32/h/rterr.h | 76 + private/crt32/h/search.h | 104 + private/crt32/h/setjmp.h | 299 +++ private/crt32/h/setjmpex.h | 41 + private/crt32/h/setlocal.h | 142 ++ private/crt32/h/share.h | 35 + private/crt32/h/signal.h | 129 ++ private/crt32/h/sizeptr.h | 45 + private/crt32/h/stdarg.h | 153 ++ private/crt32/h/stddef.h | 153 ++ private/crt32/h/stdio.h | 503 +++++ private/crt32/h/stdiostr.h | 59 + private/crt32/h/stdlib.h | 552 ++++++ private/crt32/h/streamb.h | 184 ++ private/crt32/h/string.h | 228 +++ private/crt32/h/strstrea.h | 93 + private/crt32/h/sys/locking.h | 38 + private/crt32/h/sys/stat.h | 151 ++ private/crt32/h/sys/timeb.h | 129 ++ private/crt32/h/sys/types.h | 58 + private/crt32/h/sys/utime.h | 106 ++ private/crt32/h/syserr.h | 44 + private/crt32/h/tchar.h | 587 ++++++ private/crt32/h/time.h | 242 +++ private/crt32/h/timeb.inc | 37 + private/crt32/h/v2tov3.h | 74 + private/crt32/h/varargs.h | 160 ++ private/crt32/h/wchar.h | 352 ++++ private/crt32/h/winheap.h | 25 + private/crt32/hack/makefile | 6 + private/crt32/hack/sources | 36 + private/crt32/hack/stubs.c | 42 + private/crt32/heap/calloc.c | 88 + private/crt32/heap/delete.cxx | 28 + private/crt32/heap/findaddr.c | 108 ++ private/crt32/heap/free.c | 171 ++ private/crt32/heap/handler.cxx | 53 + private/crt32/heap/heapadd.c | 413 ++++ private/crt32/heap/heapchk.c | 330 ++++ private/crt32/heap/heapdump.c | 334 ++++ private/crt32/heap/heapgrow.c | 490 +++++ private/crt32/heap/heapinit.c | 266 +++ private/crt32/heap/heapmin.c | 520 +++++ private/crt32/heap/heapprm.c | 87 + private/crt32/heap/heapsrch.c | 150 ++ private/crt32/heap/heapwalk.c | 170 ++ private/crt32/heap/hpabort.c | 47 + private/crt32/heap/makefile | 7 + private/crt32/heap/malloc.c | 474 +++++ private/crt32/heap/msize.c | 112 ++ private/crt32/heap/new.cxx | 28 + private/crt32/heap/realloc.c | 477 +++++ private/crt32/heap/sources | 71 + private/crt32/helper/empty.c | 5 + private/crt32/helper/makefile | 8 + private/crt32/helper/mips/llabsdiv.c | 62 + private/crt32/helper/mips/llbit.c | 127 ++ private/crt32/helper/mips/llcvt.s | 364 ++++ private/crt32/helper/mips/lldefs.h | 92 + private/crt32/helper/mips/lldiv.c | 251 +++ private/crt32/helper/mips/lldivrem.s | 237 +++ private/crt32/helper/mips/llmul.s | 57 + private/crt32/helper/mips/llshift.s | 226 +++ private/crt32/helper/mips/llshiftt.c | 146 ++ private/crt32/helper/sources | 65 + private/crt32/iostream/cerrinit.cxx | 28 + private/crt32/iostream/cininit.cxx | 28 + private/crt32/iostream/cloginit.cxx | 28 + private/crt32/iostream/filebuf.cxx | 460 +++++ private/crt32/iostream/filebuf1.cxx | 231 +++ private/crt32/iostream/fstream.cxx | 261 +++ private/crt32/iostream/ifstream.cxx | 240 +++ private/crt32/iostream/ios.cxx | 323 ++++ private/crt32/iostream/iostream.cxx | 83 + private/crt32/iostream/iostrini.cxx | 83 + private/crt32/iostream/istrchar.cxx | 40 + private/crt32/iostream/istrdbl.cxx | 46 + private/crt32/iostream/istream.cxx | 278 +++ private/crt32/iostream/istream1.cxx | 98 + private/crt32/iostream/istrflt.cxx | 58 + private/crt32/iostream/istrgdbl.cxx | 105 + private/crt32/iostream/istrget.cxx | 65 + private/crt32/iostream/istrgetl.cxx | 70 + private/crt32/iostream/istrgint.cxx | 145 ++ private/crt32/iostream/istrint.cxx | 71 + private/crt32/iostream/istrldbl.cxx | 48 + private/crt32/iostream/istrlong.cxx | 63 + private/crt32/iostream/istrshrt.cxx | 71 + private/crt32/iostream/istruint.cxx | 72 + private/crt32/iostream/istrulng.cxx | 65 + private/crt32/iostream/istrusht.cxx | 73 + private/crt32/iostream/makefile | 7 + private/crt32/iostream/mtlock.c | 943 +++++++++ private/crt32/iostream/ofstream.cxx | 239 +++ private/crt32/iostream/ostrchar.cxx | 39 + private/crt32/iostream/ostrdbl.cxx | 65 + private/crt32/iostream/ostream.cxx | 229 +++ private/crt32/iostream/ostream1.cxx | 70 + private/crt32/iostream/ostrint.cxx | 55 + private/crt32/iostream/ostrldbl.cxx | 61 + private/crt32/iostream/ostrlong.cxx | 55 + private/crt32/iostream/ostrptr.cxx | 41 + private/crt32/iostream/ostrput.cxx | 42 + private/crt32/iostream/ostrshrt.cxx | 56 + private/crt32/iostream/ostruint.cxx | 55 + private/crt32/iostream/ostrulng.cxx | 55 + private/crt32/iostream/ostrusht.cxx | 56 + private/crt32/iostream/sources | 83 + private/crt32/iostream/stdiostr.cxx | 266 +++ private/crt32/iostream/streamb.cxx | 514 +++++ private/crt32/iostream/streamb1.cxx | 165 ++ private/crt32/iostream/strmbdbp.cxx | 48 + private/crt32/iostream/strstrea.cxx | 440 +++++ private/crt32/linkopts/binmode.c | 28 + private/crt32/linkopts/commode.c | 26 + private/crt32/linkopts/makefile | 6 + private/crt32/linkopts/setargv.c | 43 + private/crt32/linkopts/sources | 38 + private/crt32/lowio/cgets.c | 129 ++ private/crt32/lowio/chsize.c | 231 +++ private/crt32/lowio/close.c | 135 ++ private/crt32/lowio/commit.c | 115 ++ private/crt32/lowio/cputs.c | 100 + private/crt32/lowio/creat.c | 52 + private/crt32/lowio/dup.c | 156 ++ private/crt32/lowio/dup2.c | 200 ++ private/crt32/lowio/eof.c | 90 + private/crt32/lowio/flength.c | 84 + private/crt32/lowio/fstat.c | 352 ++++ private/crt32/lowio/getch.c | 672 +++++++ private/crt32/lowio/i386/_initcon.asm | 17 + private/crt32/lowio/i386/cinitcon.asm | 99 + private/crt32/lowio/initcon.c | 113 ++ private/crt32/lowio/ioinit.c | 242 +++ private/crt32/lowio/isatty.c | 62 + private/crt32/lowio/locking.c | 187 ++ private/crt32/lowio/lseek.c | 187 ++ private/crt32/lowio/makefile | 6 + private/crt32/lowio/mktemp.c | 115 ++ private/crt32/lowio/open.c | 590 ++++++ private/crt32/lowio/osfinfo.c | 319 ++++ private/crt32/lowio/pipe.c | 180 ++ private/crt32/lowio/ppc/cinitcon.s | 53 + private/crt32/lowio/putch.c | 129 ++ private/crt32/lowio/read.c | 349 ++++ private/crt32/lowio/setmode.c | 155 ++ private/crt32/lowio/sources | 62 + private/crt32/lowio/tell.c | 46 + private/crt32/lowio/txtmode.c | 19 + private/crt32/lowio/write.c | 324 ++++ private/crt32/makefile | 597 ++++++ private/crt32/mbstring/i386/ismbbyte.sav | 205 ++ private/crt32/mbstring/i386/mbcsinit.os2 | 55 + private/crt32/mbstring/i386/mbscat.asm | 18 + private/crt32/mbstring/i386/mbsdup.asm | 16 + private/crt32/mbstring/ismbalph.c | 67 + private/crt32/mbstring/ismbbyte.c | 148 ++ private/crt32/mbstring/ismbdgt.c | 60 + private/crt32/mbstring/ismbknj.c | 93 + private/crt32/mbstring/ismblgl.c | 42 + private/crt32/mbstring/ismblwr.c | 63 + private/crt32/mbstring/ismbprn.c | 60 + private/crt32/mbstring/ismbsle.c | 58 + private/crt32/mbstring/ismbspc.c | 61 + private/crt32/mbstring/ismbstr.c | 58 + private/crt32/mbstring/ismbupr.c | 63 + private/crt32/mbstring/makefile | 6 + private/crt32/mbstring/makefile.knj | 508 +++++ private/crt32/mbstring/mbascii0.c | 33 + private/crt32/mbstring/mbascii1.opt | 19 + private/crt32/mbstring/mbbtype.c | 70 + private/crt32/mbstring/mbccpy.c | 47 + private/crt32/mbstring/mbclen.c | 42 + private/crt32/mbstring/mbclevel.c | 92 + private/crt32/mbstring/mbctype.c | 318 ++++ private/crt32/mbstring/mbsbtype.c | 64 + private/crt32/mbstring/mbscat.c | 21 + private/crt32/mbstring/mbschr.c | 67 + private/crt32/mbstring/mbscmp.c | 61 + private/crt32/mbstring/mbscspn.c | 105 + private/crt32/mbstring/mbsdec.c | 84 + private/crt32/mbstring/mbsdup.c | 18 + private/crt32/mbstring/mbsicmp.c | 90 + private/crt32/mbstring/mbsinc.c | 48 + private/crt32/mbstring/mbslen.c | 51 + private/crt32/mbstring/mbslwr.c | 76 + private/crt32/mbstring/mbsnbcat.c | 99 + private/crt32/mbstring/mbsnbcmp.c | 75 + private/crt32/mbstring/mbsnbcnt.c | 62 + private/crt32/mbstring/mbsnbcpy.c | 79 + private/crt32/mbstring/mbsnbicm.c | 101 + private/crt32/mbstring/mbsnbset.c | 102 + private/crt32/mbstring/mbsncat.c | 95 + private/crt32/mbstring/mbsnccnt.c | 59 + private/crt32/mbstring/mbsncmp.c | 69 + private/crt32/mbstring/mbsncpy.c | 74 + private/crt32/mbstring/mbsnextc.c | 50 + private/crt32/mbstring/mbsnicmp.c | 97 + private/crt32/mbstring/mbsninc.c | 50 + private/crt32/mbstring/mbsnset.c | 110 ++ private/crt32/mbstring/mbspbrk.c | 18 + private/crt32/mbstring/mbsrchr.c | 67 + private/crt32/mbstring/mbsrev.c | 72 + private/crt32/mbstring/mbsset.c | 76 + private/crt32/mbstring/mbsspn.c | 101 + private/crt32/mbstring/mbsspnp.c | 18 + private/crt32/mbstring/mbsstr.c | 80 + private/crt32/mbstring/mbstok.c | 174 ++ private/crt32/mbstring/mbsupr.c | 72 + private/crt32/mbstring/mbtohira.c | 53 + private/crt32/mbstring/mbtokata.c | 51 + private/crt32/mbstring/mbtolwr.c | 72 + private/crt32/mbstring/mbtoupr.c | 72 + private/crt32/mbstring/sources | 105 + private/crt32/mbstring/strdec.c | 46 + private/crt32/mbstring/strinc.c | 44 + private/crt32/mbstring/strncnt.c | 52 + private/crt32/mbstring/strnextc.c | 44 + private/crt32/mbstring/strninc.c | 47 + private/crt32/mbstring/strspnp.c | 65 + private/crt32/mbstring/tojisjms.c | 116 ++ private/crt32/mbstring/tombbmbc.c | 312 +++ private/crt32/misc/_strerr.c | 143 ++ private/crt32/misc/abort.c | 96 + private/crt32/misc/abs.c | 51 + private/crt32/misc/alpha/chandler.c | 296 +++ private/crt32/misc/alpha/divdat.s | 597 ++++++ private/crt32/misc/alpha/divide.s | 1319 +++++++++++++ private/crt32/misc/alpha/divide2.s | 1002 ++++++++++ private/crt32/misc/alpha/extv.s | 82 + private/crt32/misc/alpha/extvvol.s | 98 + private/crt32/misc/alpha/extzv.s | 83 + private/crt32/misc/alpha/extzvvol.s | 101 + private/crt32/misc/alpha/fastdiv.s | 662 +++++++ private/crt32/misc/alpha/ghandler.c | 435 +++++ private/crt32/misc/alpha/insv.s | 158 ++ private/crt32/misc/alpha/insvvol.s | 137 ++ private/crt32/misc/alpha/jmpuwind.s | 167 ++ private/crt32/misc/alpha/longjmp.s | 192 ++ private/crt32/misc/alpha/ots_as.hs | 38 + private/crt32/misc/alpha/ots_defs.hs | 3 + private/crt32/misc/alpha/otsdiv.s | 1178 ++++++++++++ private/crt32/misc/alpha/otsjmp.s | 117 ++ private/crt32/misc/alpha/otsjmpex.s | 84 + private/crt32/misc/alpha/otsnote.txt | 115 ++ private/crt32/misc/alpha/otsuwind.s | 80 + private/crt32/misc/alpha/scmpeql.s | 295 +++ private/crt32/misc/alpha/scmpeqlp.s | 443 +++++ private/crt32/misc/alpha/scmpleq.s | 338 ++++ private/crt32/misc/alpha/scmpleqp.s | 478 +++++ private/crt32/misc/alpha/scmplss.s | 339 ++++ private/crt32/misc/alpha/scmplssp.s | 478 +++++ private/crt32/misc/alpha/setjmp.s | 111 ++ private/crt32/misc/alpha/setjmpex.s | 147 ++ private/crt32/misc/alpha/sfill.s | 161 ++ private/crt32/misc/alpha/sloc.s | 702 +++++++ private/crt32/misc/alpha/smove.s | 652 +++++++ private/crt32/misc/alpha/smovem.s | 667 +++++++ private/crt32/misc/alpha/strans.s | 122 ++ private/crt32/misc/alpha/strcmp_.s | 357 ++++ private/crt32/misc/alpha/strcpy_.s | 257 +++ private/crt32/misc/alpha/strlen_.s | 95 + private/crt32/misc/alpha/szero.s | 137 ++ private/crt32/misc/assert.c | 66 + private/crt32/misc/bsearch.c | 99 + private/crt32/misc/cmiscdat.c | 68 + private/crt32/misc/ctype.c | 161 ++ private/crt32/misc/div.c | 59 + private/crt32/misc/getenv.c | 167 ++ private/crt32/misc/getpath.c | 174 ++ private/crt32/misc/getqloc.c | 736 +++++++ private/crt32/misc/i386/_initone.asm | 17 + private/crt32/misc/i386/cinitone.asm | 78 + private/crt32/misc/i386/exsup.asm | 299 +++ private/crt32/misc/i386/exsup2.asm | 271 +++ private/crt32/misc/i386/exsup3.asm | 290 +++ private/crt32/misc/i386/longjmp.asm | 150 ++ private/crt32/misc/i386/sehsupp.c | 59 + private/crt32/misc/i386/setjmp.asm | 151 ++ private/crt32/misc/i386/setjmp3.asm | 148 ++ private/crt32/misc/i386/setjmpex.asm | 55 + private/crt32/misc/initcoll.c | 51 + private/crt32/misc/initctyp.c | 212 +++ private/crt32/misc/inithelp.c | 143 ++ private/crt32/misc/initmon.c | 191 ++ private/crt32/misc/initnum.c | 129 ++ private/crt32/misc/inittime.c | 301 +++ private/crt32/misc/labs.c | 52 + private/crt32/misc/lconv.c | 86 + private/crt32/misc/ldiv.c | 59 + private/crt32/misc/lfind.c | 79 + private/crt32/misc/lsearch.c | 87 + private/crt32/misc/makefile | 6 + private/crt32/misc/makepath.c | 128 ++ private/crt32/misc/mbval.c | 22 + private/crt32/misc/mips/chandler.c | 219 +++ private/crt32/misc/mips/jmpuwind.s | 138 ++ private/crt32/misc/mips/longjmp.s | 128 ++ private/crt32/misc/mips/setjmp.s | 101 + private/crt32/misc/mips/setjmpex.s | 156 ++ private/crt32/misc/mtest.c | 530 ++++++ private/crt32/misc/nlsdata1.c | 38 + private/crt32/misc/nlsdata2.c | 34 + private/crt32/misc/nlsdata3.c | 34 + private/crt32/misc/onexit.c | 286 +++ private/crt32/misc/perror.c | 78 + private/crt32/misc/ppc/chandler.c | 222 +++ private/crt32/misc/ppc/cinitone.s | 41 + private/crt32/misc/ppc/jmpuwind.s | 162 ++ private/crt32/misc/ppc/longjmp.s | 143 ++ private/crt32/misc/ppc/miscasm.s | 273 +++ private/crt32/misc/ppc/setjmp.s | 138 ++ private/crt32/misc/ppc/setjmpex.s | 194 ++ private/crt32/misc/ppc/sources | 6 + private/crt32/misc/purevirt.c | 42 + private/crt32/misc/putenv.c | 453 +++++ private/crt32/misc/qsort.c | 329 ++++ private/crt32/misc/rand.c | 133 ++ private/crt32/misc/rotl.c | 90 + private/crt32/misc/rotr.c | 90 + private/crt32/misc/searchen.c | 114 ++ private/crt32/misc/setlocal.c | 620 ++++++ private/crt32/misc/setmbval.c | 35 + private/crt32/misc/sources | 129 ++ private/crt32/misc/splitpat.c | 201 ++ private/crt32/misc/strerror.c | 142 ++ private/crt32/misc/syserr.c | 85 + private/crt32/misc/umask.c | 55 + private/crt32/misc/winsig.c | 709 +++++++ private/crt32/misc/winxfltr.c | 618 ++++++ private/crt32/misc/wrt2err.c | 84 + private/crt32/small/crt0dat.c | 1 + private/crt32/small/ctype.c | 1 + private/crt32/small/makefile | 6 + private/crt32/small/makefile.inc | 19 + private/crt32/small/mips/huge.s | 2 + private/crt32/small/nlsdata1.c | 1 + private/crt32/small/nlsdata2.c | 1 + private/crt32/small/nlsdata3.c | 1 + private/crt32/small/sources | 54 + private/crt32/small/syserr.c | 1 + private/crt32/small/timeset.c | 1 + private/crt32/small/tlssup.c | 1 + private/crt32/startup/_setargv.c | 18 + private/crt32/startup/alpha/chkstk.s | 131 ++ private/crt32/startup/crt0.c | 594 ++++++ private/crt32/startup/crt0dat.c | 794 ++++++++ private/crt32/startup/crt0fp.c | 57 + private/crt32/startup/crt0init.c | 69 + private/crt32/startup/crt0msg.c | 231 +++ private/crt32/startup/dllcrt0.c | 306 +++ private/crt32/startup/dllmain.c | 42 + private/crt32/startup/i386/atlssup.asm | 15 + private/crt32/startup/i386/chkstk.asm | 127 ++ private/crt32/startup/makefile | 6 + private/crt32/startup/makefile.inc | 3 + private/crt32/startup/mips/chkstk.s | 104 + private/crt32/startup/mlock.c | 382 ++++ private/crt32/startup/ppc/chkstk.s | 190 ++ private/crt32/startup/ppc/sources | 3 + private/crt32/startup/sources | 65 + private/crt32/startup/stdargv.c | 501 +++++ private/crt32/startup/stdenvp.c | 192 ++ private/crt32/startup/thread.c | 254 +++ private/crt32/startup/tidprint.c | 286 +++ private/crt32/startup/tidtable.c | 324 ++++ private/crt32/startup/tlssup.c | 52 + private/crt32/startup/wild.c | 341 ++++ private/crt32/startup/wincrt0.c | 6 + private/crt32/stdio/_filbuf.c | 195 ++ private/crt32/stdio/_file.c | 86 + private/crt32/stdio/_filwbuf.c | 25 + private/crt32/stdio/_flsbuf.c | 275 +++ private/crt32/stdio/_flswbuf.c | 25 + private/crt32/stdio/_freebuf.c | 72 + private/crt32/stdio/_getbuf.c | 102 + private/crt32/stdio/_open.c | 272 +++ private/crt32/stdio/_sftbuf.c | 223 +++ private/crt32/stdio/clearerr.c | 77 + private/crt32/stdio/closeall.c | 71 + private/crt32/stdio/cprintf.c | 15 + private/crt32/stdio/cscanf.c | 15 + private/crt32/stdio/fclose.c | 221 +++ private/crt32/stdio/fdopen.c | 191 ++ private/crt32/stdio/feoferr.c | 78 + private/crt32/stdio/fflush.c | 424 +++++ private/crt32/stdio/fgetc.c | 79 + private/crt32/stdio/fgetchar.c | 62 + private/crt32/stdio/fgetpos.c | 55 + private/crt32/stdio/fgets.c | 111 ++ private/crt32/stdio/fgetwc.c | 154 ++ private/crt32/stdio/fgetwchr.c | 52 + private/crt32/stdio/fileno.c | 50 + private/crt32/stdio/fopen.c | 125 ++ private/crt32/stdio/fprintf.c | 93 + private/crt32/stdio/fputc.c | 89 + private/crt32/stdio/fputchar.c | 63 + private/crt32/stdio/fputs.c | 81 + private/crt32/stdio/fputwc.c | 159 ++ private/crt32/stdio/fputwchr.c | 53 + private/crt32/stdio/fread.c | 197 ++ private/crt32/stdio/freopen.c | 105 + private/crt32/stdio/fscanf.c | 83 + private/crt32/stdio/fseek.c | 258 +++ private/crt32/stdio/fsetpos.c | 51 + private/crt32/stdio/ftell.c | 257 +++ private/crt32/stdio/fwprintf.c | 79 + private/crt32/stdio/fwrite.c | 202 ++ private/crt32/stdio/fwscanf.c | 72 + private/crt32/stdio/gets.c | 89 + private/crt32/stdio/getw.c | 86 + private/crt32/stdio/i386/_initstd.asm | 17 + private/crt32/stdio/i386/_inittmp.asm | 17 + private/crt32/stdio/i386/cinitstd.asm | 88 + private/crt32/stdio/i386/cinittmp.asm | 92 + private/crt32/stdio/input.c | 1130 +++++++++++ private/crt32/stdio/makefile | 6 + private/crt32/stdio/makefile.inc | 17 + private/crt32/stdio/maketab.c | 101 + private/crt32/stdio/maketabc.c | 128 ++ private/crt32/stdio/ncommode.c | 18 + private/crt32/stdio/output.c | 1393 ++++++++++++++ private/crt32/stdio/popen.c | 562 ++++++ private/crt32/stdio/ppc/cinitstd.s | 47 + private/crt32/stdio/ppc/cinittmp.s | 52 + private/crt32/stdio/printf.c | 92 + private/crt32/stdio/puts.c | 91 + private/crt32/stdio/putw.c | 87 + private/crt32/stdio/rewind.c | 117 ++ private/crt32/stdio/rmtmp.c | 116 ++ private/crt32/stdio/scanf.c | 86 + private/crt32/stdio/setbuf.c | 61 + private/crt32/stdio/setvbuf.c | 180 ++ private/crt32/stdio/snprintf.c | 17 + private/crt32/stdio/snwprint.c | 17 + private/crt32/stdio/sources | 115 ++ private/crt32/stdio/sprintf.c | 130 ++ private/crt32/stdio/sscanf.c | 95 + private/crt32/stdio/stream.c | 95 + private/crt32/stdio/swprintf.c | 115 ++ private/crt32/stdio/swscanf.c | 81 + private/crt32/stdio/tempnam.c | 262 +++ private/crt32/stdio/test_out.c | 224 +++ private/crt32/stdio/tmpfile.c | 418 ++++ private/crt32/stdio/ungetc.c | 174 ++ private/crt32/stdio/ungetwc.c | 206 ++ private/crt32/stdio/vfprintf.c | 90 + private/crt32/stdio/vfwprint.c | 76 + private/crt32/stdio/vprintf.c | 81 + private/crt32/stdio/vsnprint.c | 17 + private/crt32/stdio/vsnwprnt.c | 17 + private/crt32/stdio/vsprintf.c | 126 ++ private/crt32/stdio/vswprint.c | 111 ++ private/crt32/stdio/vwprintf.c | 68 + private/crt32/stdio/winput.c | 29 + private/crt32/stdio/woutput.c | 31 + private/crt32/stdio/wprintf.c | 79 + private/crt32/stdio/wscanf.c | 74 + private/crt32/string/alpha/strcat.c | 63 + private/crt32/string/alpha/strcmps.s | 357 ++++ private/crt32/string/alpha/strcpys.s | 257 +++ private/crt32/string/alpha/strlens.s | 95 + private/crt32/string/i386/memccpy.asm | 103 + private/crt32/string/i386/memchr.asm | 96 + private/crt32/string/i386/memcmp.asm | 101 + private/crt32/string/i386/memcpy.asm | 354 ++++ private/crt32/string/i386/memicmp.asm | 132 ++ private/crt32/string/i386/memmove.asm | 19 + private/crt32/string/i386/memset.asm | 127 ++ private/crt32/string/i386/strcat.asm | 155 ++ private/crt32/string/i386/strchr.asm | 94 + private/crt32/string/i386/strcmp.asm | 104 + private/crt32/string/i386/strcspn.asm | 19 + private/crt32/string/i386/strdup.asm | 126 ++ private/crt32/string/i386/stricmp.asm | 127 ++ private/crt32/string/i386/strlen.asm | 84 + private/crt32/string/i386/strlwr.asm | 104 + private/crt32/string/i386/strncat.asm | 117 ++ private/crt32/string/i386/strncmp.asm | 120 ++ private/crt32/string/i386/strncpy.asm | 108 ++ private/crt32/string/i386/strnicmp.asm | 153 ++ private/crt32/string/i386/strnset.asm | 104 + private/crt32/string/i386/strpbrk.asm | 19 + private/crt32/string/i386/strrchr.asm | 105 + private/crt32/string/i386/strrev.asm | 121 ++ private/crt32/string/i386/strset.asm | 93 + private/crt32/string/i386/strspn.asm | 277 +++ private/crt32/string/i386/strstr.asm | 135 ++ private/crt32/string/i386/strupr.asm | 104 + private/crt32/string/makefile | 6 + private/crt32/string/makefile.inc | 9 + private/crt32/string/memccpy.c | 59 + private/crt32/string/memchr.c | 57 + private/crt32/string/memcmp.c | 65 + private/crt32/string/memcpy.c | 80 + private/crt32/string/memicmp.c | 77 + private/crt32/string/memmove.c | 93 + private/crt32/string/memset.c | 70 + private/crt32/string/mips/memcmpm.s | 125 ++ private/crt32/string/mips/memcmpt.c | 334 ++++ private/crt32/string/mips/memcpym.s | 298 +++ private/crt32/string/mips/memorym.s | 1218 ++++++++++++ private/crt32/string/mips/memsetm.s | 105 + private/crt32/string/mips/memsett.c | 20 + private/crt32/string/mips/strcatm.s | 98 + private/crt32/string/mips/strchrm.s | 26 + private/crt32/string/mips/strchrt.c | 20 + private/crt32/string/mips/strcmpm.s | 50 + private/crt32/string/mips/strcpym.s | 148 ++ private/crt32/string/mips/strcpyt.c | 23 + private/crt32/string/mips/strlenm.s | 19 + private/crt32/string/mips/strrchrm.s | 24 + private/crt32/string/mips/strrchrt.c | 20 + private/crt32/string/mips/wcscmpm.s | 67 + private/crt32/string/mips/wcscmpt.c | 62 + private/crt32/string/mips/wcscpym.s | 139 ++ private/crt32/string/mips/wcslenm.s | 45 + private/crt32/string/ppc/memccpyp.s | 78 + private/crt32/string/ppc/memchrp.s | 74 + private/crt32/string/ppc/memcmpp.s | 71 + private/crt32/string/ppc/strcatp.s | 137 ++ private/crt32/string/ppc/strchrp.s | 70 + private/crt32/string/ppc/strcmpp.s | 74 + private/crt32/string/ppc/stricmpp.s | 89 + private/crt32/string/ppc/strlenp.s | 164 ++ private/crt32/string/ppc/strrchrp.s | 87 + private/crt32/string/sources | 175 ++ private/crt32/string/strcat.c | 90 + private/crt32/string/strchr.c | 52 + private/crt32/string/strcmp.c | 68 + private/crt32/string/strcoll.c | 103 + private/crt32/string/strcspn.c | 2 + private/crt32/string/strdup.c | 60 + private/crt32/string/stricmp.c | 80 + private/crt32/string/stricoll.c | 95 + private/crt32/string/strlen.c | 54 + private/crt32/string/strlwr.c | 137 ++ private/crt32/string/strncat.c | 63 + private/crt32/string/strncmp.c | 61 + private/crt32/string/strncpy.c | 59 + private/crt32/string/strnicmp.c | 76 + private/crt32/string/strnset.c | 54 + private/crt32/string/strpbrk.c | 2 + private/crt32/string/strrchr.c | 59 + private/crt32/string/strrev.c | 58 + private/crt32/string/strset.c | 58 + private/crt32/string/strspn.c | 179 ++ private/crt32/string/strstr.c | 68 + private/crt32/string/strtok.c | 125 ++ private/crt32/string/strupr.c | 138 ++ private/crt32/string/strxfrm.c | 149 ++ private/crt32/string/wcscat.c | 87 + private/crt32/string/wcschr.c | 48 + private/crt32/string/wcscmp.c | 59 + private/crt32/string/wcscoll.c | 70 + private/crt32/string/wcscspn.c | 61 + private/crt32/string/wcsdup.c | 57 + private/crt32/string/wcsicmp.c | 90 + private/crt32/string/wcsicoll.c | 73 + private/crt32/string/wcslen.c | 45 + private/crt32/string/wcslwr.c | 100 + private/crt32/string/wcsncat.c | 61 + private/crt32/string/wcsncmp.c | 57 + private/crt32/string/wcsncpy.c | 57 + private/crt32/string/wcsnicmp.c | 91 + private/crt32/string/wcsnset.c | 51 + private/crt32/string/wcspbrk.c | 56 + private/crt32/string/wcsrchr.c | 56 + private/crt32/string/wcsrev.c | 56 + private/crt32/string/wcsset.c | 51 + private/crt32/string/wcsspn.c | 67 + private/crt32/string/wcsstr.c | 62 + private/crt32/string/wcstok.c | 174 ++ private/crt32/string/wcsupr.c | 104 + private/crt32/string/wcsxfrm.c | 126 ++ private/crt32/time/asctime.c | 194 ++ private/crt32/time/clock.c | 169 ++ private/crt32/time/ctime.c | 56 + private/crt32/time/days.c | 26 + private/crt32/time/difftime.c | 53 + private/crt32/time/dtoxtime.c | 113 ++ private/crt32/time/ftime.c | 107 ++ private/crt32/time/gmtime.c | 185 ++ private/crt32/time/i386/_initclk.asm | 17 + private/crt32/time/i386/cinitclk.asm | 93 + private/crt32/time/localtim.c | 252 +++ private/crt32/time/makefile | 6 + private/crt32/time/mktime.c | 315 +++ private/crt32/time/ppc/cinitclk.s | 49 + private/crt32/time/sources | 54 + private/crt32/time/strdate.c | 99 + private/crt32/time/strftime.c | 891 +++++++++ private/crt32/time/strtime.c | 98 + private/crt32/time/systime.c | 104 + private/crt32/time/time.c | 78 + private/crt32/time/timeset.c | 92 + private/crt32/time/tzset.c | 927 +++++++++ private/crt32/time/utime.c | 202 ++ private/crt32/time/wcsftime.c | 67 + private/crt32/tools/i386mips.c | 368 ++++ private/crt32/tools/win32/relinc.cmd | 172 ++ private/crt32/tools/win32/relinc.if | 74 + private/crt32/tools/win32/relinc.sed | 8 + private/crt32/winheap/calloc.c | 81 + private/crt32/winheap/delete.cxx | 28 + private/crt32/winheap/expand.c | 92 + private/crt32/winheap/handler.cxx | 53 + private/crt32/winheap/heapchk.c | 131 ++ private/crt32/winheap/heapinit.c | 52 + private/crt32/winheap/heapmin.c | 73 + private/crt32/winheap/heapwalk.c | 101 + private/crt32/winheap/hpabort.c | 47 + private/crt32/winheap/makefile | 7 + private/crt32/winheap/malloc.c | 104 + private/crt32/winheap/msize.c | 49 + private/crt32/winheap/new.cxx | 28 + private/crt32/winheap/realloc.c | 85 + private/crt32/winheap/sources | 51 + private/crt32/wstring/makefile | 6 + private/crt32/wstring/sources | 53 + 765 files changed, 113842 insertions(+) create mode 100644 private/crt32/buildcrt.cmd create mode 100644 private/crt32/convert/_ctype.c create mode 100644 private/crt32/convert/_fptostr.c create mode 100644 private/crt32/convert/_mbslen.c create mode 100644 private/crt32/convert/_wctype.c create mode 100644 private/crt32/convert/atof.c create mode 100644 private/crt32/convert/atox.c create mode 100644 private/crt32/convert/fcvt.c create mode 100644 private/crt32/convert/gcvt.c create mode 100644 private/crt32/convert/isctype.c create mode 100644 private/crt32/convert/iswctype.c create mode 100644 private/crt32/convert/makefile create mode 100644 private/crt32/convert/mblen.c create mode 100644 private/crt32/convert/mbstowcs.c create mode 100644 private/crt32/convert/mbtowc.c create mode 100644 private/crt32/convert/sources create mode 100644 private/crt32/convert/strtod.c create mode 100644 private/crt32/convert/strtol.c create mode 100644 private/crt32/convert/strtoq.c create mode 100644 private/crt32/convert/swab.c create mode 100644 private/crt32/convert/testconv.c create mode 100644 private/crt32/convert/tolower.c create mode 100644 private/crt32/convert/toupper.c create mode 100644 private/crt32/convert/towlower.c create mode 100644 private/crt32/convert/towupper.c create mode 100644 private/crt32/convert/wcstod.c create mode 100644 private/crt32/convert/wcstol.c create mode 100644 private/crt32/convert/wcstombs.c create mode 100644 private/crt32/convert/wctomb.c create mode 100644 private/crt32/convert/wtox.c create mode 100644 private/crt32/convert/xtoa.c create mode 100644 private/crt32/convert/xtow.c create mode 100644 private/crt32/crt32.def create mode 100644 private/crt32/direct/drivemap.c create mode 100644 private/crt32/direct/drivfree.c create mode 100644 private/crt32/direct/findfile.c create mode 100644 private/crt32/direct/makefile create mode 100644 private/crt32/direct/peekpoke.c create mode 100644 private/crt32/direct/seterrm.c create mode 100644 private/crt32/direct/slbeep.c create mode 100644 private/crt32/direct/sources create mode 100644 private/crt32/dirs create mode 100644 private/crt32/dllstuff/cinitexe.c create mode 100644 private/crt32/dllstuff/crtdll.c create mode 100644 private/crt32/dllstuff/crtexe.c create mode 100644 private/crt32/dllstuff/crtexew.c create mode 100644 private/crt32/dllstuff/crtlib.c create mode 100644 private/crt32/dllstuff/dllargv.c create mode 100644 private/crt32/dllstuff/i386/dllsupp.asm create mode 100644 private/crt32/dllstuff/makefile create mode 100644 private/crt32/dllstuff/sources create mode 100644 private/crt32/dos/access.c create mode 100644 private/crt32/dos/chdir.c create mode 100644 private/crt32/dos/chmod.c create mode 100644 private/crt32/dos/dosmap.c create mode 100644 private/crt32/dos/drive.c create mode 100644 private/crt32/dos/fullpath.c create mode 100644 private/crt32/dos/getcwd.c create mode 100644 private/crt32/dos/getpid.c create mode 100644 private/crt32/dos/makefile create mode 100644 private/crt32/dos/mkdir.c create mode 100644 private/crt32/dos/rename.c create mode 100644 private/crt32/dos/rmdir.c create mode 100644 private/crt32/dos/sources create mode 100644 private/crt32/dos/stat.c create mode 100644 private/crt32/dos/unlink.c create mode 100644 private/crt32/exec/cenvarg.c create mode 100644 private/crt32/exec/cfinfo.c create mode 100644 private/crt32/exec/dospawn.c create mode 100644 private/crt32/exec/execl.c create mode 100644 private/crt32/exec/execle.c create mode 100644 private/crt32/exec/execlp.c create mode 100644 private/crt32/exec/execlpe.c create mode 100644 private/crt32/exec/execv.c create mode 100644 private/crt32/exec/execve.c create mode 100644 private/crt32/exec/execvp.c create mode 100644 private/crt32/exec/execvpe.c create mode 100644 private/crt32/exec/fileinfo.c create mode 100644 private/crt32/exec/getproc.c create mode 100644 private/crt32/exec/loaddll.c create mode 100644 private/crt32/exec/makefile create mode 100644 private/crt32/exec/sources create mode 100644 private/crt32/exec/spawnl.c create mode 100644 private/crt32/exec/spawnle.c create mode 100644 private/crt32/exec/spawnlp.c create mode 100644 private/crt32/exec/spawnlpe.c create mode 100644 private/crt32/exec/spawnv.c create mode 100644 private/crt32/exec/spawnve.c create mode 100644 private/crt32/exec/spawnvp.c create mode 100644 private/crt32/exec/spawnvpe.c create mode 100644 private/crt32/exec/system.c create mode 100644 private/crt32/exec/wait.c create mode 100644 private/crt32/h/assert.h create mode 100644 private/crt32/h/cmacros.mas create mode 100644 private/crt32/h/cmsgs.h create mode 100644 private/crt32/h/conio.h create mode 100644 private/crt32/h/cruntime.h create mode 100644 private/crt32/h/cruntime.inc create mode 100644 private/crt32/h/ctime.h create mode 100644 private/crt32/h/ctype.h create mode 100644 private/crt32/h/cvt.h create mode 100644 private/crt32/h/defsects.inc create mode 100644 private/crt32/h/direct.h create mode 100644 private/crt32/h/dos.h create mode 100644 private/crt32/h/doscalls.h create mode 100644 private/crt32/h/dostypes.h create mode 100644 private/crt32/h/errmsg.h create mode 100644 private/crt32/h/errno.h create mode 100644 private/crt32/h/error.h create mode 100644 private/crt32/h/error2.h create mode 100644 private/crt32/h/except.inc create mode 100644 private/crt32/h/excpt.h create mode 100644 private/crt32/h/exsup.inc create mode 100644 private/crt32/h/fcntl.h create mode 100644 private/crt32/h/file2.h create mode 100644 private/crt32/h/float.h create mode 100644 private/crt32/h/fltintrn.h create mode 100644 private/crt32/h/fpieee.h create mode 100644 private/crt32/h/fstream.h create mode 100644 private/crt32/h/heap.h create mode 100644 private/crt32/h/internal.h create mode 100644 private/crt32/h/io.h create mode 100644 private/crt32/h/iomanip.h create mode 100644 private/crt32/h/ios.h create mode 100644 private/crt32/h/iostream.h create mode 100644 private/crt32/h/istream.h create mode 100644 private/crt32/h/jctype.h create mode 100644 private/crt32/h/limits.h create mode 100644 private/crt32/h/locale.h create mode 100644 private/crt32/h/malloc.h create mode 100644 private/crt32/h/math.h create mode 100644 private/crt32/h/mbctype.h create mode 100644 private/crt32/h/mbdata.h create mode 100644 private/crt32/h/mbstring.h create mode 100644 private/crt32/h/memory.h create mode 100644 private/crt32/h/msdos.h create mode 100644 private/crt32/h/msdos.inc create mode 100644 private/crt32/h/mtest.h create mode 100644 private/crt32/h/new.h create mode 100644 private/crt32/h/nlsint.h create mode 100644 private/crt32/h/os2dll.h create mode 100644 private/crt32/h/oscalls.h create mode 100644 private/crt32/h/ostream.h create mode 100644 private/crt32/h/process.h create mode 100644 private/crt32/h/pversion.inc create mode 100644 private/crt32/h/rterr.h create mode 100644 private/crt32/h/search.h create mode 100644 private/crt32/h/setjmp.h create mode 100644 private/crt32/h/setjmpex.h create mode 100644 private/crt32/h/setlocal.h create mode 100644 private/crt32/h/share.h create mode 100644 private/crt32/h/signal.h create mode 100644 private/crt32/h/sizeptr.h create mode 100644 private/crt32/h/stdarg.h create mode 100644 private/crt32/h/stddef.h create mode 100644 private/crt32/h/stdio.h create mode 100644 private/crt32/h/stdiostr.h create mode 100644 private/crt32/h/stdlib.h create mode 100644 private/crt32/h/streamb.h create mode 100644 private/crt32/h/string.h create mode 100644 private/crt32/h/strstrea.h create mode 100644 private/crt32/h/sys/locking.h create mode 100644 private/crt32/h/sys/stat.h create mode 100644 private/crt32/h/sys/timeb.h create mode 100644 private/crt32/h/sys/types.h create mode 100644 private/crt32/h/sys/utime.h create mode 100644 private/crt32/h/syserr.h create mode 100644 private/crt32/h/tchar.h create mode 100644 private/crt32/h/time.h create mode 100644 private/crt32/h/timeb.inc create mode 100644 private/crt32/h/v2tov3.h create mode 100644 private/crt32/h/varargs.h create mode 100644 private/crt32/h/wchar.h create mode 100644 private/crt32/h/winheap.h create mode 100644 private/crt32/hack/makefile create mode 100644 private/crt32/hack/sources create mode 100644 private/crt32/hack/stubs.c create mode 100644 private/crt32/heap/calloc.c create mode 100644 private/crt32/heap/delete.cxx create mode 100644 private/crt32/heap/findaddr.c create mode 100644 private/crt32/heap/free.c create mode 100644 private/crt32/heap/handler.cxx create mode 100644 private/crt32/heap/heapadd.c create mode 100644 private/crt32/heap/heapchk.c create mode 100644 private/crt32/heap/heapdump.c create mode 100644 private/crt32/heap/heapgrow.c create mode 100644 private/crt32/heap/heapinit.c create mode 100644 private/crt32/heap/heapmin.c create mode 100644 private/crt32/heap/heapprm.c create mode 100644 private/crt32/heap/heapsrch.c create mode 100644 private/crt32/heap/heapwalk.c create mode 100644 private/crt32/heap/hpabort.c create mode 100644 private/crt32/heap/makefile create mode 100644 private/crt32/heap/malloc.c create mode 100644 private/crt32/heap/msize.c create mode 100644 private/crt32/heap/new.cxx create mode 100644 private/crt32/heap/realloc.c create mode 100644 private/crt32/heap/sources create mode 100644 private/crt32/helper/empty.c create mode 100644 private/crt32/helper/makefile create mode 100644 private/crt32/helper/mips/llabsdiv.c create mode 100644 private/crt32/helper/mips/llbit.c create mode 100644 private/crt32/helper/mips/llcvt.s create mode 100644 private/crt32/helper/mips/lldefs.h create mode 100644 private/crt32/helper/mips/lldiv.c create mode 100644 private/crt32/helper/mips/lldivrem.s create mode 100644 private/crt32/helper/mips/llmul.s create mode 100644 private/crt32/helper/mips/llshift.s create mode 100644 private/crt32/helper/mips/llshiftt.c create mode 100644 private/crt32/helper/sources create mode 100644 private/crt32/iostream/cerrinit.cxx create mode 100644 private/crt32/iostream/cininit.cxx create mode 100644 private/crt32/iostream/cloginit.cxx create mode 100644 private/crt32/iostream/filebuf.cxx create mode 100644 private/crt32/iostream/filebuf1.cxx create mode 100644 private/crt32/iostream/fstream.cxx create mode 100644 private/crt32/iostream/ifstream.cxx create mode 100644 private/crt32/iostream/ios.cxx create mode 100644 private/crt32/iostream/iostream.cxx create mode 100644 private/crt32/iostream/iostrini.cxx create mode 100644 private/crt32/iostream/istrchar.cxx create mode 100644 private/crt32/iostream/istrdbl.cxx create mode 100644 private/crt32/iostream/istream.cxx create mode 100644 private/crt32/iostream/istream1.cxx create mode 100644 private/crt32/iostream/istrflt.cxx create mode 100644 private/crt32/iostream/istrgdbl.cxx create mode 100644 private/crt32/iostream/istrget.cxx create mode 100644 private/crt32/iostream/istrgetl.cxx create mode 100644 private/crt32/iostream/istrgint.cxx create mode 100644 private/crt32/iostream/istrint.cxx create mode 100644 private/crt32/iostream/istrldbl.cxx create mode 100644 private/crt32/iostream/istrlong.cxx create mode 100644 private/crt32/iostream/istrshrt.cxx create mode 100644 private/crt32/iostream/istruint.cxx create mode 100644 private/crt32/iostream/istrulng.cxx create mode 100644 private/crt32/iostream/istrusht.cxx create mode 100644 private/crt32/iostream/makefile create mode 100644 private/crt32/iostream/mtlock.c create mode 100644 private/crt32/iostream/ofstream.cxx create mode 100644 private/crt32/iostream/ostrchar.cxx create mode 100644 private/crt32/iostream/ostrdbl.cxx create mode 100644 private/crt32/iostream/ostream.cxx create mode 100644 private/crt32/iostream/ostream1.cxx create mode 100644 private/crt32/iostream/ostrint.cxx create mode 100644 private/crt32/iostream/ostrldbl.cxx create mode 100644 private/crt32/iostream/ostrlong.cxx create mode 100644 private/crt32/iostream/ostrptr.cxx create mode 100644 private/crt32/iostream/ostrput.cxx create mode 100644 private/crt32/iostream/ostrshrt.cxx create mode 100644 private/crt32/iostream/ostruint.cxx create mode 100644 private/crt32/iostream/ostrulng.cxx create mode 100644 private/crt32/iostream/ostrusht.cxx create mode 100644 private/crt32/iostream/sources create mode 100644 private/crt32/iostream/stdiostr.cxx create mode 100644 private/crt32/iostream/streamb.cxx create mode 100644 private/crt32/iostream/streamb1.cxx create mode 100644 private/crt32/iostream/strmbdbp.cxx create mode 100644 private/crt32/iostream/strstrea.cxx create mode 100644 private/crt32/linkopts/binmode.c create mode 100644 private/crt32/linkopts/commode.c create mode 100644 private/crt32/linkopts/makefile create mode 100644 private/crt32/linkopts/setargv.c create mode 100644 private/crt32/linkopts/sources create mode 100644 private/crt32/lowio/cgets.c create mode 100644 private/crt32/lowio/chsize.c create mode 100644 private/crt32/lowio/close.c create mode 100644 private/crt32/lowio/commit.c create mode 100644 private/crt32/lowio/cputs.c create mode 100644 private/crt32/lowio/creat.c create mode 100644 private/crt32/lowio/dup.c create mode 100644 private/crt32/lowio/dup2.c create mode 100644 private/crt32/lowio/eof.c create mode 100644 private/crt32/lowio/flength.c create mode 100644 private/crt32/lowio/fstat.c create mode 100644 private/crt32/lowio/getch.c create mode 100644 private/crt32/lowio/i386/_initcon.asm create mode 100644 private/crt32/lowio/i386/cinitcon.asm create mode 100644 private/crt32/lowio/initcon.c create mode 100644 private/crt32/lowio/ioinit.c create mode 100644 private/crt32/lowio/isatty.c create mode 100644 private/crt32/lowio/locking.c create mode 100644 private/crt32/lowio/lseek.c create mode 100644 private/crt32/lowio/makefile create mode 100644 private/crt32/lowio/mktemp.c create mode 100644 private/crt32/lowio/open.c create mode 100644 private/crt32/lowio/osfinfo.c create mode 100644 private/crt32/lowio/pipe.c create mode 100644 private/crt32/lowio/ppc/cinitcon.s create mode 100644 private/crt32/lowio/putch.c create mode 100644 private/crt32/lowio/read.c create mode 100644 private/crt32/lowio/setmode.c create mode 100644 private/crt32/lowio/sources create mode 100644 private/crt32/lowio/tell.c create mode 100644 private/crt32/lowio/txtmode.c create mode 100644 private/crt32/lowio/write.c create mode 100644 private/crt32/makefile create mode 100644 private/crt32/mbstring/i386/ismbbyte.sav create mode 100644 private/crt32/mbstring/i386/mbcsinit.os2 create mode 100644 private/crt32/mbstring/i386/mbscat.asm create mode 100644 private/crt32/mbstring/i386/mbsdup.asm create mode 100644 private/crt32/mbstring/ismbalph.c create mode 100644 private/crt32/mbstring/ismbbyte.c create mode 100644 private/crt32/mbstring/ismbdgt.c create mode 100644 private/crt32/mbstring/ismbknj.c create mode 100644 private/crt32/mbstring/ismblgl.c create mode 100644 private/crt32/mbstring/ismblwr.c create mode 100644 private/crt32/mbstring/ismbprn.c create mode 100644 private/crt32/mbstring/ismbsle.c create mode 100644 private/crt32/mbstring/ismbspc.c create mode 100644 private/crt32/mbstring/ismbstr.c create mode 100644 private/crt32/mbstring/ismbupr.c create mode 100644 private/crt32/mbstring/makefile create mode 100644 private/crt32/mbstring/makefile.knj create mode 100644 private/crt32/mbstring/mbascii0.c create mode 100644 private/crt32/mbstring/mbascii1.opt create mode 100644 private/crt32/mbstring/mbbtype.c create mode 100644 private/crt32/mbstring/mbccpy.c create mode 100644 private/crt32/mbstring/mbclen.c create mode 100644 private/crt32/mbstring/mbclevel.c create mode 100644 private/crt32/mbstring/mbctype.c create mode 100644 private/crt32/mbstring/mbsbtype.c create mode 100644 private/crt32/mbstring/mbscat.c create mode 100644 private/crt32/mbstring/mbschr.c create mode 100644 private/crt32/mbstring/mbscmp.c create mode 100644 private/crt32/mbstring/mbscspn.c create mode 100644 private/crt32/mbstring/mbsdec.c create mode 100644 private/crt32/mbstring/mbsdup.c create mode 100644 private/crt32/mbstring/mbsicmp.c create mode 100644 private/crt32/mbstring/mbsinc.c create mode 100644 private/crt32/mbstring/mbslen.c create mode 100644 private/crt32/mbstring/mbslwr.c create mode 100644 private/crt32/mbstring/mbsnbcat.c create mode 100644 private/crt32/mbstring/mbsnbcmp.c create mode 100644 private/crt32/mbstring/mbsnbcnt.c create mode 100644 private/crt32/mbstring/mbsnbcpy.c create mode 100644 private/crt32/mbstring/mbsnbicm.c create mode 100644 private/crt32/mbstring/mbsnbset.c create mode 100644 private/crt32/mbstring/mbsncat.c create mode 100644 private/crt32/mbstring/mbsnccnt.c create mode 100644 private/crt32/mbstring/mbsncmp.c create mode 100644 private/crt32/mbstring/mbsncpy.c create mode 100644 private/crt32/mbstring/mbsnextc.c create mode 100644 private/crt32/mbstring/mbsnicmp.c create mode 100644 private/crt32/mbstring/mbsninc.c create mode 100644 private/crt32/mbstring/mbsnset.c create mode 100644 private/crt32/mbstring/mbspbrk.c create mode 100644 private/crt32/mbstring/mbsrchr.c create mode 100644 private/crt32/mbstring/mbsrev.c create mode 100644 private/crt32/mbstring/mbsset.c create mode 100644 private/crt32/mbstring/mbsspn.c create mode 100644 private/crt32/mbstring/mbsspnp.c create mode 100644 private/crt32/mbstring/mbsstr.c create mode 100644 private/crt32/mbstring/mbstok.c create mode 100644 private/crt32/mbstring/mbsupr.c create mode 100644 private/crt32/mbstring/mbtohira.c create mode 100644 private/crt32/mbstring/mbtokata.c create mode 100644 private/crt32/mbstring/mbtolwr.c create mode 100644 private/crt32/mbstring/mbtoupr.c create mode 100644 private/crt32/mbstring/sources create mode 100644 private/crt32/mbstring/strdec.c create mode 100644 private/crt32/mbstring/strinc.c create mode 100644 private/crt32/mbstring/strncnt.c create mode 100644 private/crt32/mbstring/strnextc.c create mode 100644 private/crt32/mbstring/strninc.c create mode 100644 private/crt32/mbstring/strspnp.c create mode 100644 private/crt32/mbstring/tojisjms.c create mode 100644 private/crt32/mbstring/tombbmbc.c create mode 100644 private/crt32/misc/_strerr.c create mode 100644 private/crt32/misc/abort.c create mode 100644 private/crt32/misc/abs.c create mode 100644 private/crt32/misc/alpha/chandler.c create mode 100644 private/crt32/misc/alpha/divdat.s create mode 100644 private/crt32/misc/alpha/divide.s create mode 100644 private/crt32/misc/alpha/divide2.s create mode 100644 private/crt32/misc/alpha/extv.s create mode 100644 private/crt32/misc/alpha/extvvol.s create mode 100644 private/crt32/misc/alpha/extzv.s create mode 100644 private/crt32/misc/alpha/extzvvol.s create mode 100644 private/crt32/misc/alpha/fastdiv.s create mode 100644 private/crt32/misc/alpha/ghandler.c create mode 100644 private/crt32/misc/alpha/insv.s create mode 100644 private/crt32/misc/alpha/insvvol.s create mode 100644 private/crt32/misc/alpha/jmpuwind.s create mode 100644 private/crt32/misc/alpha/longjmp.s create mode 100644 private/crt32/misc/alpha/ots_as.hs create mode 100644 private/crt32/misc/alpha/ots_defs.hs create mode 100644 private/crt32/misc/alpha/otsdiv.s create mode 100644 private/crt32/misc/alpha/otsjmp.s create mode 100644 private/crt32/misc/alpha/otsjmpex.s create mode 100644 private/crt32/misc/alpha/otsnote.txt create mode 100644 private/crt32/misc/alpha/otsuwind.s create mode 100644 private/crt32/misc/alpha/scmpeql.s create mode 100644 private/crt32/misc/alpha/scmpeqlp.s create mode 100644 private/crt32/misc/alpha/scmpleq.s create mode 100644 private/crt32/misc/alpha/scmpleqp.s create mode 100644 private/crt32/misc/alpha/scmplss.s create mode 100644 private/crt32/misc/alpha/scmplssp.s create mode 100644 private/crt32/misc/alpha/setjmp.s create mode 100644 private/crt32/misc/alpha/setjmpex.s create mode 100644 private/crt32/misc/alpha/sfill.s create mode 100644 private/crt32/misc/alpha/sloc.s create mode 100644 private/crt32/misc/alpha/smove.s create mode 100644 private/crt32/misc/alpha/smovem.s create mode 100644 private/crt32/misc/alpha/strans.s create mode 100644 private/crt32/misc/alpha/strcmp_.s create mode 100644 private/crt32/misc/alpha/strcpy_.s create mode 100644 private/crt32/misc/alpha/strlen_.s create mode 100644 private/crt32/misc/alpha/szero.s create mode 100644 private/crt32/misc/assert.c create mode 100644 private/crt32/misc/bsearch.c create mode 100644 private/crt32/misc/cmiscdat.c create mode 100644 private/crt32/misc/ctype.c create mode 100644 private/crt32/misc/div.c create mode 100644 private/crt32/misc/getenv.c create mode 100644 private/crt32/misc/getpath.c create mode 100644 private/crt32/misc/getqloc.c create mode 100644 private/crt32/misc/i386/_initone.asm create mode 100644 private/crt32/misc/i386/cinitone.asm create mode 100644 private/crt32/misc/i386/exsup.asm create mode 100644 private/crt32/misc/i386/exsup2.asm create mode 100644 private/crt32/misc/i386/exsup3.asm create mode 100644 private/crt32/misc/i386/longjmp.asm create mode 100644 private/crt32/misc/i386/sehsupp.c create mode 100644 private/crt32/misc/i386/setjmp.asm create mode 100644 private/crt32/misc/i386/setjmp3.asm create mode 100644 private/crt32/misc/i386/setjmpex.asm create mode 100644 private/crt32/misc/initcoll.c create mode 100644 private/crt32/misc/initctyp.c create mode 100644 private/crt32/misc/inithelp.c create mode 100644 private/crt32/misc/initmon.c create mode 100644 private/crt32/misc/initnum.c create mode 100644 private/crt32/misc/inittime.c create mode 100644 private/crt32/misc/labs.c create mode 100644 private/crt32/misc/lconv.c create mode 100644 private/crt32/misc/ldiv.c create mode 100644 private/crt32/misc/lfind.c create mode 100644 private/crt32/misc/lsearch.c create mode 100644 private/crt32/misc/makefile create mode 100644 private/crt32/misc/makepath.c create mode 100644 private/crt32/misc/mbval.c create mode 100644 private/crt32/misc/mips/chandler.c create mode 100644 private/crt32/misc/mips/jmpuwind.s create mode 100644 private/crt32/misc/mips/longjmp.s create mode 100644 private/crt32/misc/mips/setjmp.s create mode 100644 private/crt32/misc/mips/setjmpex.s create mode 100644 private/crt32/misc/mtest.c create mode 100644 private/crt32/misc/nlsdata1.c create mode 100644 private/crt32/misc/nlsdata2.c create mode 100644 private/crt32/misc/nlsdata3.c create mode 100644 private/crt32/misc/onexit.c create mode 100644 private/crt32/misc/perror.c create mode 100644 private/crt32/misc/ppc/chandler.c create mode 100644 private/crt32/misc/ppc/cinitone.s create mode 100644 private/crt32/misc/ppc/jmpuwind.s create mode 100644 private/crt32/misc/ppc/longjmp.s create mode 100644 private/crt32/misc/ppc/miscasm.s create mode 100644 private/crt32/misc/ppc/setjmp.s create mode 100644 private/crt32/misc/ppc/setjmpex.s create mode 100644 private/crt32/misc/ppc/sources create mode 100644 private/crt32/misc/purevirt.c create mode 100644 private/crt32/misc/putenv.c create mode 100644 private/crt32/misc/qsort.c create mode 100644 private/crt32/misc/rand.c create mode 100644 private/crt32/misc/rotl.c create mode 100644 private/crt32/misc/rotr.c create mode 100644 private/crt32/misc/searchen.c create mode 100644 private/crt32/misc/setlocal.c create mode 100644 private/crt32/misc/setmbval.c create mode 100644 private/crt32/misc/sources create mode 100644 private/crt32/misc/splitpat.c create mode 100644 private/crt32/misc/strerror.c create mode 100644 private/crt32/misc/syserr.c create mode 100644 private/crt32/misc/umask.c create mode 100644 private/crt32/misc/winsig.c create mode 100644 private/crt32/misc/winxfltr.c create mode 100644 private/crt32/misc/wrt2err.c create mode 100644 private/crt32/small/crt0dat.c create mode 100644 private/crt32/small/ctype.c create mode 100644 private/crt32/small/makefile create mode 100644 private/crt32/small/makefile.inc create mode 100644 private/crt32/small/mips/huge.s create mode 100644 private/crt32/small/nlsdata1.c create mode 100644 private/crt32/small/nlsdata2.c create mode 100644 private/crt32/small/nlsdata3.c create mode 100644 private/crt32/small/sources create mode 100644 private/crt32/small/syserr.c create mode 100644 private/crt32/small/timeset.c create mode 100644 private/crt32/small/tlssup.c create mode 100644 private/crt32/startup/_setargv.c create mode 100644 private/crt32/startup/alpha/chkstk.s create mode 100644 private/crt32/startup/crt0.c create mode 100644 private/crt32/startup/crt0dat.c create mode 100644 private/crt32/startup/crt0fp.c create mode 100644 private/crt32/startup/crt0init.c create mode 100644 private/crt32/startup/crt0msg.c create mode 100644 private/crt32/startup/dllcrt0.c create mode 100644 private/crt32/startup/dllmain.c create mode 100644 private/crt32/startup/i386/atlssup.asm create mode 100644 private/crt32/startup/i386/chkstk.asm create mode 100644 private/crt32/startup/makefile create mode 100644 private/crt32/startup/makefile.inc create mode 100644 private/crt32/startup/mips/chkstk.s create mode 100644 private/crt32/startup/mlock.c create mode 100644 private/crt32/startup/ppc/chkstk.s create mode 100644 private/crt32/startup/ppc/sources create mode 100644 private/crt32/startup/sources create mode 100644 private/crt32/startup/stdargv.c create mode 100644 private/crt32/startup/stdenvp.c create mode 100644 private/crt32/startup/thread.c create mode 100644 private/crt32/startup/tidprint.c create mode 100644 private/crt32/startup/tidtable.c create mode 100644 private/crt32/startup/tlssup.c create mode 100644 private/crt32/startup/wild.c create mode 100644 private/crt32/startup/wincrt0.c create mode 100644 private/crt32/stdio/_filbuf.c create mode 100644 private/crt32/stdio/_file.c create mode 100644 private/crt32/stdio/_filwbuf.c create mode 100644 private/crt32/stdio/_flsbuf.c create mode 100644 private/crt32/stdio/_flswbuf.c create mode 100644 private/crt32/stdio/_freebuf.c create mode 100644 private/crt32/stdio/_getbuf.c create mode 100644 private/crt32/stdio/_open.c create mode 100644 private/crt32/stdio/_sftbuf.c create mode 100644 private/crt32/stdio/clearerr.c create mode 100644 private/crt32/stdio/closeall.c create mode 100644 private/crt32/stdio/cprintf.c create mode 100644 private/crt32/stdio/cscanf.c create mode 100644 private/crt32/stdio/fclose.c create mode 100644 private/crt32/stdio/fdopen.c create mode 100644 private/crt32/stdio/feoferr.c create mode 100644 private/crt32/stdio/fflush.c create mode 100644 private/crt32/stdio/fgetc.c create mode 100644 private/crt32/stdio/fgetchar.c create mode 100644 private/crt32/stdio/fgetpos.c create mode 100644 private/crt32/stdio/fgets.c create mode 100644 private/crt32/stdio/fgetwc.c create mode 100644 private/crt32/stdio/fgetwchr.c create mode 100644 private/crt32/stdio/fileno.c create mode 100644 private/crt32/stdio/fopen.c create mode 100644 private/crt32/stdio/fprintf.c create mode 100644 private/crt32/stdio/fputc.c create mode 100644 private/crt32/stdio/fputchar.c create mode 100644 private/crt32/stdio/fputs.c create mode 100644 private/crt32/stdio/fputwc.c create mode 100644 private/crt32/stdio/fputwchr.c create mode 100644 private/crt32/stdio/fread.c create mode 100644 private/crt32/stdio/freopen.c create mode 100644 private/crt32/stdio/fscanf.c create mode 100644 private/crt32/stdio/fseek.c create mode 100644 private/crt32/stdio/fsetpos.c create mode 100644 private/crt32/stdio/ftell.c create mode 100644 private/crt32/stdio/fwprintf.c create mode 100644 private/crt32/stdio/fwrite.c create mode 100644 private/crt32/stdio/fwscanf.c create mode 100644 private/crt32/stdio/gets.c create mode 100644 private/crt32/stdio/getw.c create mode 100644 private/crt32/stdio/i386/_initstd.asm create mode 100644 private/crt32/stdio/i386/_inittmp.asm create mode 100644 private/crt32/stdio/i386/cinitstd.asm create mode 100644 private/crt32/stdio/i386/cinittmp.asm create mode 100644 private/crt32/stdio/input.c create mode 100644 private/crt32/stdio/makefile create mode 100644 private/crt32/stdio/makefile.inc create mode 100644 private/crt32/stdio/maketab.c create mode 100644 private/crt32/stdio/maketabc.c create mode 100644 private/crt32/stdio/ncommode.c create mode 100644 private/crt32/stdio/output.c create mode 100644 private/crt32/stdio/popen.c create mode 100644 private/crt32/stdio/ppc/cinitstd.s create mode 100644 private/crt32/stdio/ppc/cinittmp.s create mode 100644 private/crt32/stdio/printf.c create mode 100644 private/crt32/stdio/puts.c create mode 100644 private/crt32/stdio/putw.c create mode 100644 private/crt32/stdio/rewind.c create mode 100644 private/crt32/stdio/rmtmp.c create mode 100644 private/crt32/stdio/scanf.c create mode 100644 private/crt32/stdio/setbuf.c create mode 100644 private/crt32/stdio/setvbuf.c create mode 100644 private/crt32/stdio/snprintf.c create mode 100644 private/crt32/stdio/snwprint.c create mode 100644 private/crt32/stdio/sources create mode 100644 private/crt32/stdio/sprintf.c create mode 100644 private/crt32/stdio/sscanf.c create mode 100644 private/crt32/stdio/stream.c create mode 100644 private/crt32/stdio/swprintf.c create mode 100644 private/crt32/stdio/swscanf.c create mode 100644 private/crt32/stdio/tempnam.c create mode 100644 private/crt32/stdio/test_out.c create mode 100644 private/crt32/stdio/tmpfile.c create mode 100644 private/crt32/stdio/ungetc.c create mode 100644 private/crt32/stdio/ungetwc.c create mode 100644 private/crt32/stdio/vfprintf.c create mode 100644 private/crt32/stdio/vfwprint.c create mode 100644 private/crt32/stdio/vprintf.c create mode 100644 private/crt32/stdio/vsnprint.c create mode 100644 private/crt32/stdio/vsnwprnt.c create mode 100644 private/crt32/stdio/vsprintf.c create mode 100644 private/crt32/stdio/vswprint.c create mode 100644 private/crt32/stdio/vwprintf.c create mode 100644 private/crt32/stdio/winput.c create mode 100644 private/crt32/stdio/woutput.c create mode 100644 private/crt32/stdio/wprintf.c create mode 100644 private/crt32/stdio/wscanf.c create mode 100644 private/crt32/string/alpha/strcat.c create mode 100644 private/crt32/string/alpha/strcmps.s create mode 100644 private/crt32/string/alpha/strcpys.s create mode 100644 private/crt32/string/alpha/strlens.s create mode 100644 private/crt32/string/i386/memccpy.asm create mode 100644 private/crt32/string/i386/memchr.asm create mode 100644 private/crt32/string/i386/memcmp.asm create mode 100644 private/crt32/string/i386/memcpy.asm create mode 100644 private/crt32/string/i386/memicmp.asm create mode 100644 private/crt32/string/i386/memmove.asm create mode 100644 private/crt32/string/i386/memset.asm create mode 100644 private/crt32/string/i386/strcat.asm create mode 100644 private/crt32/string/i386/strchr.asm create mode 100644 private/crt32/string/i386/strcmp.asm create mode 100644 private/crt32/string/i386/strcspn.asm create mode 100644 private/crt32/string/i386/strdup.asm create mode 100644 private/crt32/string/i386/stricmp.asm create mode 100644 private/crt32/string/i386/strlen.asm create mode 100644 private/crt32/string/i386/strlwr.asm create mode 100644 private/crt32/string/i386/strncat.asm create mode 100644 private/crt32/string/i386/strncmp.asm create mode 100644 private/crt32/string/i386/strncpy.asm create mode 100644 private/crt32/string/i386/strnicmp.asm create mode 100644 private/crt32/string/i386/strnset.asm create mode 100644 private/crt32/string/i386/strpbrk.asm create mode 100644 private/crt32/string/i386/strrchr.asm create mode 100644 private/crt32/string/i386/strrev.asm create mode 100644 private/crt32/string/i386/strset.asm create mode 100644 private/crt32/string/i386/strspn.asm create mode 100644 private/crt32/string/i386/strstr.asm create mode 100644 private/crt32/string/i386/strupr.asm create mode 100644 private/crt32/string/makefile create mode 100644 private/crt32/string/makefile.inc create mode 100644 private/crt32/string/memccpy.c create mode 100644 private/crt32/string/memchr.c create mode 100644 private/crt32/string/memcmp.c create mode 100644 private/crt32/string/memcpy.c create mode 100644 private/crt32/string/memicmp.c create mode 100644 private/crt32/string/memmove.c create mode 100644 private/crt32/string/memset.c create mode 100644 private/crt32/string/mips/memcmpm.s create mode 100644 private/crt32/string/mips/memcmpt.c create mode 100644 private/crt32/string/mips/memcpym.s create mode 100644 private/crt32/string/mips/memorym.s create mode 100644 private/crt32/string/mips/memsetm.s create mode 100644 private/crt32/string/mips/memsett.c create mode 100644 private/crt32/string/mips/strcatm.s create mode 100644 private/crt32/string/mips/strchrm.s create mode 100644 private/crt32/string/mips/strchrt.c create mode 100644 private/crt32/string/mips/strcmpm.s create mode 100644 private/crt32/string/mips/strcpym.s create mode 100644 private/crt32/string/mips/strcpyt.c create mode 100644 private/crt32/string/mips/strlenm.s create mode 100644 private/crt32/string/mips/strrchrm.s create mode 100644 private/crt32/string/mips/strrchrt.c create mode 100644 private/crt32/string/mips/wcscmpm.s create mode 100644 private/crt32/string/mips/wcscmpt.c create mode 100644 private/crt32/string/mips/wcscpym.s create mode 100644 private/crt32/string/mips/wcslenm.s create mode 100644 private/crt32/string/ppc/memccpyp.s create mode 100644 private/crt32/string/ppc/memchrp.s create mode 100644 private/crt32/string/ppc/memcmpp.s create mode 100644 private/crt32/string/ppc/strcatp.s create mode 100644 private/crt32/string/ppc/strchrp.s create mode 100644 private/crt32/string/ppc/strcmpp.s create mode 100644 private/crt32/string/ppc/stricmpp.s create mode 100644 private/crt32/string/ppc/strlenp.s create mode 100644 private/crt32/string/ppc/strrchrp.s create mode 100644 private/crt32/string/sources create mode 100644 private/crt32/string/strcat.c create mode 100644 private/crt32/string/strchr.c create mode 100644 private/crt32/string/strcmp.c create mode 100644 private/crt32/string/strcoll.c create mode 100644 private/crt32/string/strcspn.c create mode 100644 private/crt32/string/strdup.c create mode 100644 private/crt32/string/stricmp.c create mode 100644 private/crt32/string/stricoll.c create mode 100644 private/crt32/string/strlen.c create mode 100644 private/crt32/string/strlwr.c create mode 100644 private/crt32/string/strncat.c create mode 100644 private/crt32/string/strncmp.c create mode 100644 private/crt32/string/strncpy.c create mode 100644 private/crt32/string/strnicmp.c create mode 100644 private/crt32/string/strnset.c create mode 100644 private/crt32/string/strpbrk.c create mode 100644 private/crt32/string/strrchr.c create mode 100644 private/crt32/string/strrev.c create mode 100644 private/crt32/string/strset.c create mode 100644 private/crt32/string/strspn.c create mode 100644 private/crt32/string/strstr.c create mode 100644 private/crt32/string/strtok.c create mode 100644 private/crt32/string/strupr.c create mode 100644 private/crt32/string/strxfrm.c create mode 100644 private/crt32/string/wcscat.c create mode 100644 private/crt32/string/wcschr.c create mode 100644 private/crt32/string/wcscmp.c create mode 100644 private/crt32/string/wcscoll.c create mode 100644 private/crt32/string/wcscspn.c create mode 100644 private/crt32/string/wcsdup.c create mode 100644 private/crt32/string/wcsicmp.c create mode 100644 private/crt32/string/wcsicoll.c create mode 100644 private/crt32/string/wcslen.c create mode 100644 private/crt32/string/wcslwr.c create mode 100644 private/crt32/string/wcsncat.c create mode 100644 private/crt32/string/wcsncmp.c create mode 100644 private/crt32/string/wcsncpy.c create mode 100644 private/crt32/string/wcsnicmp.c create mode 100644 private/crt32/string/wcsnset.c create mode 100644 private/crt32/string/wcspbrk.c create mode 100644 private/crt32/string/wcsrchr.c create mode 100644 private/crt32/string/wcsrev.c create mode 100644 private/crt32/string/wcsset.c create mode 100644 private/crt32/string/wcsspn.c create mode 100644 private/crt32/string/wcsstr.c create mode 100644 private/crt32/string/wcstok.c create mode 100644 private/crt32/string/wcsupr.c create mode 100644 private/crt32/string/wcsxfrm.c create mode 100644 private/crt32/time/asctime.c create mode 100644 private/crt32/time/clock.c create mode 100644 private/crt32/time/ctime.c create mode 100644 private/crt32/time/days.c create mode 100644 private/crt32/time/difftime.c create mode 100644 private/crt32/time/dtoxtime.c create mode 100644 private/crt32/time/ftime.c create mode 100644 private/crt32/time/gmtime.c create mode 100644 private/crt32/time/i386/_initclk.asm create mode 100644 private/crt32/time/i386/cinitclk.asm create mode 100644 private/crt32/time/localtim.c create mode 100644 private/crt32/time/makefile create mode 100644 private/crt32/time/mktime.c create mode 100644 private/crt32/time/ppc/cinitclk.s create mode 100644 private/crt32/time/sources create mode 100644 private/crt32/time/strdate.c create mode 100644 private/crt32/time/strftime.c create mode 100644 private/crt32/time/strtime.c create mode 100644 private/crt32/time/systime.c create mode 100644 private/crt32/time/time.c create mode 100644 private/crt32/time/timeset.c create mode 100644 private/crt32/time/tzset.c create mode 100644 private/crt32/time/utime.c create mode 100644 private/crt32/time/wcsftime.c create mode 100644 private/crt32/tools/i386mips.c create mode 100644 private/crt32/tools/win32/relinc.cmd create mode 100644 private/crt32/tools/win32/relinc.if create mode 100644 private/crt32/tools/win32/relinc.sed create mode 100644 private/crt32/winheap/calloc.c create mode 100644 private/crt32/winheap/delete.cxx create mode 100644 private/crt32/winheap/expand.c create mode 100644 private/crt32/winheap/handler.cxx create mode 100644 private/crt32/winheap/heapchk.c create mode 100644 private/crt32/winheap/heapinit.c create mode 100644 private/crt32/winheap/heapmin.c create mode 100644 private/crt32/winheap/heapwalk.c create mode 100644 private/crt32/winheap/hpabort.c create mode 100644 private/crt32/winheap/makefile create mode 100644 private/crt32/winheap/malloc.c create mode 100644 private/crt32/winheap/msize.c create mode 100644 private/crt32/winheap/new.cxx create mode 100644 private/crt32/winheap/realloc.c create mode 100644 private/crt32/winheap/sources create mode 100644 private/crt32/wstring/makefile create mode 100644 private/crt32/wstring/sources (limited to 'private/crt32') diff --git a/private/crt32/buildcrt.cmd b/private/crt32/buildcrt.cmd new file mode 100644 index 000000000..4e2142739 --- /dev/null +++ b/private/crt32/buildcrt.cmd @@ -0,0 +1,52 @@ +@setlocal +@set CRTLIBDEBUG= +@set CRTLIBTYPE= +@set 386_USE_LIBCMT= + +@set _helpdir= +@if "%MIPS%" == "1" set _helpdir=helper +@if "%PPC%" == "1" set _helpdir=helper +@if "%_targetcpu%" == "mips" set _helpdir=helper +@if "%_targetcpu%" == "ppc" set _helpdir=helper + +:bldtype +@if "%1" == "DLL" (set CRTLIBTYPE=DLL) && goto blddll +@if "%1" == "Dll" (set CRTLIBTYPE=DLL) && goto blddll +@if "%1" == "dll" (set CRTLIBTYPE=DLL) && goto blddll +@if "%1" == "posix" (set CRTLIBTYPE=POSIX) && goto bldpsx +@if "%1" == "POSIX" (set CRTLIBTYPE=POSIX) && goto bldpsx +@if "%1" == "Posix" (set CRTLIBTYPE=POSIX) && goto bldpsx +@if "%1" == "st" (set CRTLIBTYPE=ST) && goto bldst +@if "%1" == "ST" (set CRTLIBTYPE=ST) && goto bldst +@if "%1" == "St" (set CRTLIBTYPE=ST) && goto bldst +@if "%1" == "nt" (set CRTLIBTYPE=NT) && goto bldnt +@if "%1" == "NT" (set CRTLIBTYPE=NT) && goto bldnt +@if "%1" == "Nt" (set CRTLIBTYPE=NT) && goto bldnt +@if "%1" == "mt" set CRTLIBTYPE=MT +@if "%1" == "MT" set CRTLIBTYPE=MT +@if "%1" == "Mt" set CRTLIBTYPE=MT +@if "%CRTLIBTYPE%" == "" goto bogus + +build %2 %3 %4 %5 startup time winheap direct dos exec iostream lowio mbstring %_helpdir% +@goto done + +:bldst +build %2 %3 %4 %5 linkopts startup time winheap direct dos exec iostream lowio small mbstring %_helpdir% %2 %3 %4 %5 +@goto done + +:blddll +build %2 %3 %4 %5 startup time winheap dllstuff direct dos exec iostream lowio mbstring %_helpdir% %2 %3 %4 +@goto done + +:bldpsx +build %2 %3 %4 %5 startup time winheap mbstring %_helpdir% %2 %3 %4 %5 %6 %7 %8 %9 +@goto done + +:bldnt +build %2 %3 %4 %5 hack %_helpdir% %2 %3 %4 %5 %6 %7 %8 %9 +@goto done + +:bogus +@echo Usage: BUILDCRT (NT, ST, MT, DLL, or POSIX) [BuildOptions] +:done +@endlocal diff --git a/private/crt32/convert/_ctype.c b/private/crt32/convert/_ctype.c new file mode 100644 index 000000000..7e65d82b5 --- /dev/null +++ b/private/crt32/convert/_ctype.c @@ -0,0 +1,156 @@ +/*** +*_ctype.c - function versions of ctype macros +* +* Copyright (c) 1989-1992, Microsoft Corporation. All rights reserved. +* +*Purpose: +* This files provides function versions of the character +* classification and conversion macros in ctype.h. +* +*Revision History: +* 06-05-89 PHG Module created +* 03-05-90 GJF Fixed calling type, #include , fixed +* copyright. +* 09-27-90 GJF New-style function declarators. +* 01-16-91 GJF ANSI naming. +* 02-03-92 GJF Got rid of #undef/#include-s, the MIPS compiler didn't +* like 'em. +* 08-07-92 GJF Fixed function calling type macros. +* +*******************************************************************************/ + +/*** +*ctype - Function versions of ctype macros +* +*Purpose: +* Function versions of the macros in ctype.h. In order to define +* these, we use a trick -- we undefine the macro so we can use the +* name in the function declaration, then re-include the file so +* we can use the macro in the definition part. +* +* Functions defined: +* isalpha isupper islower +* isdigit isxdigit isspace +* ispunct isalnum isprint +* isgraph isctrl __isascii +* __toascii __iscsym __iscsymf +* +*Entry: +* int c = character to be tested +*Exit: +* returns non-zero = character is of the requested type +* 0 = character is NOT of the requested type +* +*Exceptions: +* None. +* +*******************************************************************************/ + +#include +#define __STDC__ 1 +#include + +int (_CRTAPI1 isalpha) ( + int c + ) +{ + return isalpha(c); +} + +int (_CRTAPI1 isupper) ( + int c + ) +{ + return isupper(c); +} + +int (_CRTAPI1 islower) ( + int c + ) +{ + return islower(c); +} + +int (_CRTAPI1 isdigit) ( + int c + ) +{ + return isdigit(c); +} + +int (_CRTAPI1 isxdigit) ( + int c + ) +{ + return isxdigit(c); +} + +int (_CRTAPI1 isspace) ( + int c + ) +{ + return isspace(c); +} + +int (_CRTAPI1 ispunct) ( + int c + ) +{ + return ispunct(c); +} + +int (_CRTAPI1 isalnum) ( + int c + ) +{ + return isalnum(c); +} + +int (_CRTAPI1 isprint) ( + int c + ) +{ + return isprint(c); +} + +int (_CRTAPI1 isgraph) ( + int c + ) +{ + return isgraph(c); +} + +int (_CRTAPI1 iscntrl) ( + int c + ) +{ + return iscntrl(c); +} + +int (_CRTAPI1 __isascii) ( + int c + ) +{ + return __isascii(c); +} + +int (_CRTAPI1 __toascii) ( + int c + ) +{ + return __toascii(c); +} + +int (_CRTAPI1 __iscsymf) ( + int c + ) +{ + return __iscsymf(c); +} + +int (_CRTAPI1 __iscsym) ( + int c + ) +{ + return __iscsym(c); +} diff --git a/private/crt32/convert/_fptostr.c b/private/crt32/convert/_fptostr.c new file mode 100644 index 000000000..287716842 --- /dev/null +++ b/private/crt32/convert/_fptostr.c @@ -0,0 +1,104 @@ +/*** +*_fptostr.c - workhorse routine for converting floating point to string +* +* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Workhorse routine for fcvt, ecvt. +* +*Revision History: +* 09-17-84 DFW created +* 03-05-90 GJF Fixed calling type, added #include , +* removed #include , fixed copyright. Also, +* cleaned up the formatting a bit. +* 07-20-90 SBM Compiles cleanly with -W3 (added #include ) +* 08-01-90 SBM Renamed to +* 09-27-90 GJF New-style function declarator. +* 06-11-92 GDP Bug fix: Shorten string if leadig (overflow) digit is 1 +* 10-09-92 GDP Backed out last fix for ecvt (printf regressed) +* +*******************************************************************************/ + +#include +#include +#include + +/*** +*void _fptostr(buf, digits, pflt) - workhorse floating point conversion +* +*Purpose: +* This is the workhorse routine for fcvt, ecvt. Here is where +* all the digits are put into a buffer and the rounding is +* performed and indicators of the decimal point position are set. Note, +* this must not change the mantissa field of pflt since routines which +* use this routine rely on this being unchanged. +* +*Entry: +* char *buf - the buffer in which the digits are to be put +* int digits - the number of digits which are to go into the buffer +* STRFLT pflt - a pointer to a structure containing information on the +* floating point value, including a string containing the +* non-zero significant digits of the mantissa. +* +*Exit: +* Changes the contents of the buffer and also may increment the decpt +* field of the structure pointer to by the 'pflt' parameter if overflow +* occurs during rounding (e.g. 9.999999... gets rounded to 10.000...). +* +*Exceptions: +* +*******************************************************************************/ + +void _CALLTYPE1 _fptostr ( + char *buf, + REG4 int digits, + REG3 STRFLT pflt + ) +{ + REG1 char *pbuf = buf; + REG2 char *mantissa = pflt->mantissa; + + /* initialize the first digit in the buffer to '0' (NOTE - NOT '\0') + * and set the pointer to the second digit of the buffer. The first + * digit is used to handle overflow on rounding (e.g. 9.9999... + * becomes 10.000...) which requires a carry into the first digit. + */ + + *pbuf++ = '0'; + + /* Copy the digits of the value into the buffer (with 0 padding) + * and insert the terminating null character. + */ + + while (digits > 0) { + *pbuf++ = (*mantissa) ? *mantissa++ : (char)'0'; + digits--; + } + *pbuf = '\0'; + + /* do any rounding which may be needed. Note - if digits < 0 don't + * do any rounding since in this case, the rounding occurs in a digit + * which will not be output beause of the precision requested + */ + + if (digits >= 0 && *mantissa >= '5') { + pbuf--; + while (*pbuf == '9') + *pbuf-- = '0'; + *pbuf += 1; + } + + if (*buf == '1') { + /* the rounding caused overflow into the leading digit (e.g. + * 9.999.. went to 10.000...), so increment the decpt position + * by 1 + */ + pflt->decpt++; + } + else { + /* move the entire string to the left one digit to remove the + * unused overflow digit. + */ + strcpy(buf, buf+1); + } +} diff --git a/private/crt32/convert/_mbslen.c b/private/crt32/convert/_mbslen.c new file mode 100644 index 000000000..3b9710a9c --- /dev/null +++ b/private/crt32/convert/_mbslen.c @@ -0,0 +1,99 @@ +/*** +*_mbslen.c - Return number of multibyte characters in a multibyte string +* +* Copyright (c) 1989-1993, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Return number of multibyte characters in a multibyte string +* excluding the terminal null. Locale-dependent. +* +*Revision History: +* 10-01-91 ETC Created. +* 12-08-91 ETC Add multithread lock. +* 12-18-92 CFW Ported to Cuda tree, changed _CALLTYPE1 to _CRTAPI1. +* 04-29-93 CFW Change to const char *s. +* 06-01-93 CFW Test for bad MB chars. +* 06-02-93 SRW ignore _INTL if _NTSUBSET_ defined. +* 06-03-93 KRS Change name to avoid conflict with mbstring function. +* Change return type to size_t. +* 08-19-93 CFW Disallow skipping LB:NULL combos. +* 10-26-93 CFW Test for invalid MB chars using global preset flag. +* 01-14-94 SRW if _NTSUBSET_ defined call Rtl functions +* +*******************************************************************************/ + +#ifdef _INTL +#ifdef _NTSUBSET_ +#include +#include +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +/*** +*_mbstrlen - Return number of multibyte characters in a multibyte string +* +*Purpose: +* Return number of multibyte characters in a multibyte string +* excluding the terminal null. Locale-dependent. +* +*Entry: +* char *s = string +* +*Exit: +* Returns the number of multibyte characters in the string, or +* (size_t)-1 if the string contains an invalid multibyte character. +* +*Exceptions: +* +*******************************************************************************/ + +size_t _CRTAPI1 _mbstrlen( + const char *s + ) +{ + int n; + + assert (MB_CUR_MAX == 1 || MB_CUR_MAX == 2); + + if ( MB_CUR_MAX == 1 ) + /* handle single byte character sets */ + return (int)strlen(s); + +#ifndef _NTSUBSET_ + _mlock (_LC_CTYPE_LOCK); + + /* verify all valid MB chars */ + if ( MultiByteToWideChar(_lc_codepage, MB_PRECOMPOSED|__invalid_mb_chars, + s, -1, NULL, 0) == 0 ) { + /* bad MB char */ + n = (size_t)-1; + } else { + /* count MB chars */ + for (n = 0; *s; n++, s++) { + if ( isleadbyte((unsigned char)*s) && *++s == '\0') + break; + } + } + _munlock (_LC_CTYPE_LOCK); +#else + { + char *s1 = (char *)s; + + + n = 0; + while (RtlAnsiCharToUnicodeChar( &s1 ) != UNICODE_NULL) + n += 1; + } +#endif + + return(n); +} +#endif /* _INTL */ diff --git a/private/crt32/convert/_wctype.c b/private/crt32/convert/_wctype.c new file mode 100644 index 000000000..989d1a2a3 --- /dev/null +++ b/private/crt32/convert/_wctype.c @@ -0,0 +1,140 @@ +/*** +*_wctype.c - function versions of wctype macros +* +* Copyright (c) 1991-1992, Microsoft Corporation. All rights reserved. +* +*Purpose: +* This file provides function versions of the wide character +* classification and conversion macros in ctype.h. +* +*Revision History: +* 10-11-91 ETC Created from _ctype.c +* 12-08-91 ETC Surround with #ifdef _INTL +* 04-06-92 KRS Remove _INTL rwitches again +* 10-26-92 GJF Cleaned up a bit. +* +*******************************************************************************/ + +/*** +*wctype - Function versions of wctype macros +* +*Purpose: +* Function versions of the wide char macros in ctype.h, +* including isleadbyte and iswascii. In order to define +* these, we use a trick -- we undefine the macro so we can use the +* name in the function declaration, then re-include the file so +* we can use the macro in the definition part. +* +* Functions defined: +* iswalpha iswupper iswlower +* iswdigit iswxdigit iswspace +* iswpunct iswalnum iswprint +* iswgraph iswctrl iswascii +* isleadbyte +* +*Entry: +* wchar_t c = character to be tested +*Exit: +* returns non-zero = character is of the requested type +* 0 = character is NOT of the requested type +* +*Exceptions: +* None. +* +*******************************************************************************/ + +#include +#define __STDC__ 1 +#include +#include + +int (_CRTAPI1 isleadbyte) ( + int c + ) +{ + return isleadbyte(c); +} + +int (_CRTAPI1 iswalpha) ( + wchar_t c + ) +{ + return iswalpha(c); +} + +int (_CRTAPI1 iswupper) ( + wchar_t c + ) +{ + return iswupper(c); +} + +int (_CRTAPI1 iswlower) ( + wchar_t c + ) +{ + return iswlower(c); +} + +int (_CRTAPI1 iswdigit) ( + wchar_t c + ) +{ + return iswdigit(c); +} + +int (_CRTAPI1 iswxdigit) ( + wchar_t c + ) +{ + return iswxdigit(c); +} + +int (_CRTAPI1 iswspace) ( + wchar_t c + ) +{ + return iswspace(c); +} + +int (_CRTAPI1 iswpunct) ( + wchar_t c + ) +{ + return iswpunct(c); +} + +int (_CRTAPI1 iswalnum) ( + wchar_t c + ) +{ + return iswalnum(c); +} + +int (_CRTAPI1 iswprint) ( + wchar_t c + ) +{ + return iswprint(c); +} + +int (_CRTAPI1 iswgraph) ( + wchar_t c + ) +{ + return iswgraph(c); +} + +int (_CRTAPI1 iswcntrl) ( + wchar_t c + ) +{ + return iswcntrl(c); +} + +int (_CRTAPI1 iswascii) ( + wchar_t c + ) +{ + return iswascii(c); +} diff --git a/private/crt32/convert/atof.c b/private/crt32/convert/atof.c new file mode 100644 index 000000000..debc9635c --- /dev/null +++ b/private/crt32/convert/atof.c @@ -0,0 +1,81 @@ +/*** +*atof.c - convert char string to floating point number +* +* Copyright (c) 1985-1992, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Converts a character string into a floating point number. +* +*Revision History: +* 09-09-87 RKW written +* 04-13-87 JCR added const to declaration +* 11-09-87 BCM different interface under ifdef MTHREAD +* 12-11-87 JCR Added "_LOAD_DS" to declaration +* 05-24-88 PHG Merged DLL and normal versions +* 08-18-88 PHG now calls isspace to process all kinds of whitespce +* 10-04-88 JCR 386: Removed 'far' keyword +* 11-20-89 JCR atof() is always _cdecl in 386 (not pascal) +* 03-05-90 GJF Fixed calling type, added #include , +* removed #include , removed some redundant +* prototypes, removed some leftover 16-bit support and +* fixed the copyright. Also, cleaned up the formatting +* a bit. +* 07-20-90 SBM Compiles cleanly with -W3 (added/removed appropriate +* #includes) +* 08-01-90 SBM Renamed to +* 09-27-90 GJF New-style function declarator. +* 10-21-92 GJF Made char-to-int conversion unsigned. +* +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include + +/*** +*double atof(nptr) - convert string to floating point number +* +*Purpose: +* atof recognizes an optional string of whitespace, then +* an optional sign, then a string of digits optionally +* containing a decimal point, then an optional e or E followed +* by an optionally signed integer, and converts all this to +* to a floating point number. The first unrecognized +* character ends the string. +* +*Entry: +* nptr - pointer to string to convert +* +*Exit: +* returns floating point value of character representation +* +*Exceptions: +* +*******************************************************************************/ + +double _CRTAPI1 atof( + REG1 const char *nptr + ) +{ + +#ifdef MTHREAD + struct _flt fltstruct; /* temporary structure */ +#endif + + /* scan past leading space/tab characters */ + + while ( isspace((int)(unsigned char)*nptr) ) + nptr++; + + /* let _fltin routine do the rest of the work */ + +#ifdef MTHREAD + return( *(double *)&(_fltin2( &fltstruct, nptr, strlen(nptr), 0, 0 )-> + dval) ); +#else + return( *(double *)&(_fltin( nptr, strlen(nptr), 0, 0 )->dval) ); +#endif +} diff --git a/private/crt32/convert/atox.c b/private/crt32/convert/atox.c new file mode 100644 index 000000000..4e3934735 --- /dev/null +++ b/private/crt32/convert/atox.c @@ -0,0 +1,96 @@ +/*** +*atox.c - atoi and atol conversion +* +* Copyright (c) 1989-1992, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Converts a character string into an int or long. +* +*Revision History: +* 06-05-89 PHG Module created, based on asm version +* 03-05-90 GJF Fixed calling type, added #include and +* cleaned up the formatting a bit. Also, fixed the +* copyright. +* 09-27-90 GJF New-style function declarators. +* 10-21-92 GJF Fixed conversions of char to int. +* +*******************************************************************************/ + +#include +#include +#include + +/*** +*long atol(char *nptr) - Convert string to long +* +*Purpose: +* Converts ASCII string pointed to by nptr to binary. +* Overflow is not detected. +* +*Entry: +* nptr = ptr to string to convert +* +*Exit: +* return long int value of the string +* +*Exceptions: +* None - overflow is not detected. +* +*******************************************************************************/ + +long _CRTAPI1 atol( + const char *nptr + ) +{ + int c; /* current char */ + long total; /* current total */ + int sign; /* if '-', then negative, otherwise positive */ + + /* skip whitespace */ + while ( isspace((int)(unsigned char)*nptr) ) + ++nptr; + + c = (int)(unsigned char)*nptr++; + sign = c; /* save sign indication */ + if (c == '-' || c == '+') + c = (int)(unsigned char)*nptr++; /* skip sign */ + + total = 0; + + while (isdigit(c)) { + total = 10 * total + (c - '0'); /* accumulate digit */ + c = (int)(unsigned char)*nptr++; /* get next char */ + } + + if (sign == '-') + return -total; + else + return total; /* return result, negated if necessary */ +} + + +/*** +*int atoi(char *nptr) - Convert string to long +* +*Purpose: +* Converts ASCII string pointed to by nptr to binary. +* Overflow is not detected. Because of this, we can just use +* atol(). +* +*Entry: +* nptr = ptr to string to convert +* +*Exit: +* return int value of the string +* +*Exceptions: +* None - overflow is not detected. +* +*******************************************************************************/ + +int _CRTAPI1 atoi( + const char *nptr + ) +{ + return (int)atol(nptr); +} diff --git a/private/crt32/convert/fcvt.c b/private/crt32/convert/fcvt.c new file mode 100644 index 000000000..92bb49b3f --- /dev/null +++ b/private/crt32/convert/fcvt.c @@ -0,0 +1,252 @@ +/*** +*fcvt.c - convert floating point value to string +* +* Copyright (c) 1985-1993, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Converts a floating point value to a string. +* +*Revision History: +* 09-09-83 RKW written +* 09-14-84 DFW fixed problems with buffer overflow and +* streamlined the code +* 11-09-87 BCM different interface under ifdef MTHREAD +* 11-19-87 WAJ fcvt now uses emulator data area for buffer +* 12-11-87 JCR Added "_LOAD_DS" to declaration +* 05-24-88 PHG Merged DLL and normal versions +* 10-04-88 JCR 386: Removed 'far' keyword +* 10-20-88 JCR Changed 'DOUBLE' to 'double' for 386 +* 03-02-90 GJF Added #include . Removed some (now) useless +* preprocessor directives. Also, fixed copyright. +* 03-06-90 GJF Fixed calling type, removed some leftover 16-bit +* support. +* 03-23-90 GJF Made _fpcvt() _CALLTYPE4 and removed prototype for +* _fptostr() (now in struct.h). +* 08-01-90 SBM Renamed to +* 09-27-90 GJF New-style function declarators. +* 01-21-91 GJF ANSI naming. +* 10-03-91 JCR Fixed mthread buffer allocation +* 02-16-93 GJF Changed for new _getptd(). +* +*******************************************************************************/ + +#include +#include +#include +#include +#include + +/* + * The static character array buf[CVTBUFSIZE] is used by the _fpcvt routine + * (the workhorse for _ecvt and _fcvt) for storage of its output. The routine + * gcvt expects the user to have set up their own storage. CVTBUFSIZE is set + * large enough to accomodate the largest double precision number plus 40 + * decimal places (even though you only have 16 digits of accuracy in a + * double precision IEEE number, the user may ask for more to effect 0 + * padding; but there has to be a limit somewhere). + */ + +/* + * define a maximum size for the conversion buffer. It should be at least + * as long as the number of digits in the largest double precision value + * (?.?e308 in IEEE arithmetic). We will use the same size buffer as is + * used in the printf support routine (_output) + */ + +#ifdef MTHREAD +char * _CRTAPI3 _fpcvt(STRFLT, int, int *, int *); +#else +static char * _CRTAPI3 _fpcvt(STRFLT, int, int *, int *); +static char buf[CVTBUFSIZE]; +#endif + +/*** +*char *_fcvt(value, ndec, decpr, sign) - convert floating point to char string +* +*Purpose: +* _fcvt like _ecvt converts the value to a null terminated +* string of ASCII digits, and returns a pointer to the +* result. The routine prepares data for Fortran F-format +* output with the number of digits following the decimal +* point specified by ndec. The position of the decimal +* point relative to the beginning of the string is returned +* indirectly through decpt. The correct digit for Fortran +* F-format is rounded. +* NOTE - to avoid the possibility of generating floating +* point instructions in this code we fool the compiler +* about the type of the 'value' parameter using a struct. +* This is OK since all we do is pass it off as a +* parameter. +* +*Entry: +* double value - number to be converted +* int ndec - number of digits after decimal point +* +*Exit: +* returns pointer to the character string representation of value. +* also, the output is written into the static char array buf. +* int *decpt - pointer to int with pos. of dec. point +* int *sign - pointer to int with sign (0 = pos, non-0 = neg) +* +*Exceptions: +* +*******************************************************************************/ + +char * _CRTAPI1 _fcvt ( + double value, + int ndec, + int *decpt, + int *sign + ) +{ + REG1 STRFLT pflt; + +#ifdef MTHREAD + struct _strflt strfltstruct; + char resultstring[21]; + + /* ok to take address of stack struct here; fltout2 knows to use ss */ + pflt = _fltout2( value, &strfltstruct, resultstring ); + + +#else + pflt = _fltout( value ); +#endif + + return( _fpcvt( pflt, pflt->decpt + ndec, decpt, sign ) ); +} + + +/*** +*char *_ecvt( value, ndigit, decpt, sign ) - convert floating point to string +* +*Purpose: +* _ecvt converts value to a null terminated string of +* ASCII digits, and returns a pointer to the result. +* The position of the decimal point relative to the +* begining of the string is stored indirectly through +* decpt, where negative means to the left of the returned +* digits. If the sign of the result is negative, the +* word pointed to by sign is non zero, otherwise it is +* zero. The low order digit is rounded. +* +*Entry: +* double value - number to be converted +* int ndigit - number of digits after decimal point +* +*Exit: +* returns pointer to the character representation of value. +* also the output is written into the statuc char array buf. +* int *decpt - pointer to int with position of decimal point +* int *sign - pointer to int with sign in it (0 = pos, non-0 = neg) +* +*Exceptions: +* +*******************************************************************************/ + +char * _CRTAPI1 _ecvt ( + double value, + int ndigit, + int *decpt, + int *sign + ) +{ + +#ifdef MTHREAD + REG1 STRFLT pflt; + + struct _strflt strfltstruct; /* temporary buffers */ + char resultstring[21]; + + /* ok to take address of stack struct here; fltout2 knows to use ss */ + pflt = _fltout2( value, &strfltstruct, resultstring ); + + return( _fpcvt( pflt, ndigit, decpt, sign ) ); + +#else + return( _fpcvt( _fltout(value), ndigit, decpt, sign ) ); +#endif +} + + +/*** +*char *_fpcvt() - gets final string and sets decpt and sign [STATIC] +* +*Purpose: +* This is a small common routine used by [ef]cvt. It calls fptostr +* to get the final string and sets the decpt and sign indicators. +* +*Entry: +* +*Exit: +* +*Exceptions: +* +*******************************************************************************/ + +#ifdef MTHREAD +char * _CRTAPI3 _fpcvt ( +#else +static char * _CRTAPI3 _fpcvt ( +#endif + REG2 STRFLT pflt, + REG3 int digits, + int *decpt, + int *sign + ) +{ + +#ifdef MTHREAD + + /* use a per-thread buffer */ + + char *buf; + +#ifdef _CRUISER_ + + struct _tiddata * tdata; + + tdata = _gettidtab(); /* get tid's data address */ + if (tdata->_cvtbuf == NULL) + if ( (tdata->_cvtbuf = malloc(CVTBUFSIZE)) == NULL) + return(NULL); + buf = tdata->_cvtbuf; + +#else /* ndef _CRUISER_ */ + +#ifdef _WIN32_ + + _ptiddata ptd; + + ptd = _getptd(); + if ( ptd->_cvtbuf == NULL ) + if ( (ptd->_cvtbuf = malloc(CVTBUFSIZE)) == NULL ) + return(NULL); + buf = ptd->_cvtbuf; + +#else /* ndef _WIN32_ */ + +#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED! + +#endif /* _WIN32_ */ + +#endif /* _CRUISER_ */ + +#endif /* MTHREAD */ + + + /* make sure we don't overflow the buffer size. If the user asks for + * more digits than the buffer can handle, truncate it to the maximum + * size allowed in the buffer. The maximum size is CVTBUFSIZE - 2 + * since we useone character for overflow and one for the terminating + * null character. + */ + + _fptostr(buf, (digits > CVTBUFSIZE - 2) ? CVTBUFSIZE - 2 : digits, pflt); + + /* set the sign flag and decimal point position */ + + *sign = (pflt->sign == '-') ? 1 : 0; + *decpt = pflt->decpt; + return(buf); +} diff --git a/private/crt32/convert/gcvt.c b/private/crt32/convert/gcvt.c new file mode 100644 index 000000000..a720725fc --- /dev/null +++ b/private/crt32/convert/gcvt.c @@ -0,0 +1,122 @@ +/*** +*gcvt.c - convert floating point number to character string +* +* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Converts floating point number into character string representation. +* +*Revision History: +* 09-09-93 RKW written +* 11-09-87 BCM different interface under ifdef MTHREAD +* 12-11-87 JCR Added "_LOAD_DS" to declaration +* 05-24-88 PHG Merged DLL and normal versions +* 10-20-88 JCR Changed 'DOUBLE' to 'double' for 386 +* 06-27-89 PHG Changed "ndec" to "ndec-1" to correct significant +* digits in exponential format (C6 bug #2124) +* 03-05-90 GJF Fixed calling type, added #include , +* removed #include , removed redundant +* prototypes, removed some leftover 16-bit support and +* fixed the copyright. Also, cleaned up the formatting +* a bit. +* 07-20-90 SBM Compiles cleanly with -W3 (added/removed appropriate +* #includes) +* 08-01-90 SBM Renamed to +* 09-27-90 GJF New-style function declarators. +* 01-21-91 GJF ANSI naming. +* 08-13-92 SKS An old bug that was fixed in C 6.0 but that did not +* make it into C 7.0, an off by 1 error when switching +* from fixed point to scientific notation +* +*******************************************************************************/ + +#include +#include +#include + +/*** +*double _gcvt(value, ndec, buffer) - convert floating point value to char +* string +* +*Purpose: +* _gcvt converts the value to a null terminated ASCII string +* buf. It attempts to produce ndigit significant digits +* in Fortran F format if possible, ortherwise E format, +* ready for printing. Trailing zeros may be suppressed. +* No error checking or overflow protection is provided. +* NOTE - to avoid the possibility of generating floating +* point instructions in this code we fool the compiler +* about the type of the 'value' parameter using a struct. +* This is OK since all we do is pass it off as a +* parameter. +* +*Entry: +* value - double - number to be converted +* ndec - int - number of significant digits +* buf - char * - buffer to place result +* +*Exit: +* result is written into buffer; it will be overwritten if it has +* not been made big enough. +* +*Exceptions: +* +*******************************************************************************/ + +char * _CALLTYPE1 _gcvt ( + double value, + int ndec, + char *buf + ) +{ + +#ifdef MTHREAD + struct _strflt strfltstruct; /* temporary buffers */ + char resultstring[21]; +#endif + + STRFLT string; + int magnitude; + char *rc; + + REG1 char *str; + REG2 char *stop; + + /* get the magnitude of the number */ + +#ifdef MTHREAD + string = _fltout2( value, &strfltstruct, resultstring ); +#else + string = _fltout( value ); +#endif + + magnitude = string->decpt - 1; + + /* output the result according to the Fortran G format as outlined in + Fortran language specification */ + + if ( magnitude < -1 || magnitude > ndec-1 ) + /* then Ew.d d = ndec */ + rc = str = _cftoe( &value, buf, ndec-1, 0); + else + /* Fw.d where d = ndec-string->decpt */ + rc = str = _cftof( &value, buf, ndec-string->decpt ); + + while (*str && *str != '.') + str++; + + if (*str++) { + while (*str && *str != 'e') + str++; + + stop = str--; + + while (*str == '0') + str--; + + while (*++str = *stop++) + ; + } + + return(rc); +} diff --git a/private/crt32/convert/isctype.c b/private/crt32/convert/isctype.c new file mode 100644 index 000000000..730470b92 --- /dev/null +++ b/private/crt32/convert/isctype.c @@ -0,0 +1,119 @@ +/*** +*isctype.c - support is* ctype functions/macros for two-byte multibyte chars +* +* Copyright (c) 1991-1992, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Defines _isctype.c - support is* ctype functions/macros for +* two-byte multibyte chars. +* +*Revision History: +* 10-11-91 ETC Created. +* 12-08-91 ETC Updated api; added multhread lock; check char masks. +* 04-06-92 KRS Fix logic error in return value. +* 08-07-92 GJF _CALLTYPE4 (bogus usage) -> _CRTAPI1 (legit). +* 01-19-93 CFW Change C1_* to new names, call new APIs. +* 03-04-93 CFW Removed CTRL-Z. +* 04-01-93 CFW Remove EOF test (handled by array), return masked. +* 06-02-93 SRW ignore _INTL if _NTSUBSET_ defined. +* +*******************************************************************************/ +#include +#include +#include +#include +#include +#include + +#if defined(_INTL) && !defined(_NTSUBSET_) + +/* + * Use GetCharType() API so check that character type masks agree between + * ctype.h and winnls.h + */ +#if _UPPER != C1_UPPER || \ + _LOWER != C1_LOWER || \ + _DIGIT != C1_DIGIT || \ + _SPACE != C1_SPACE || \ + _PUNCT != C1_PUNCT || \ + _CONTROL != C1_CNTRL +#error Character type masks do not agree in ctype and winnls +#endif + +/*** +*_isctype - support is* ctype functions/macros for two-byte multibyte chars +* +*Purpose: +* This function is called by the is* ctype functions/macros +* (e.g. isalpha()) when their argument is a two-byte multibyte char. +* Returns true or false depending on whether the argument satisfies +* the character class property encoded by the mask. +* +*Entry: +* int c - the multibyte character whose type is to be tested +* unsigned int mask - the mask used by the is* functions/macros +* corresponding to each character class property +* +* The leadbyte and the trailbyte should be packed into the int c as: +* +* H.......|.......|.......|.......L +* 0 0 leadbyte trailbyte +* +*Exit: +* Returns non-zero if c is of the character class. +* Returns 0 if c is not of the character class. +* +*Exceptions: +* Returns 0 on any error. +* +*******************************************************************************/ + +int _CRTAPI1 _isctype ( + int c, + int mask + ) +{ + wchar_t widechar[2], chartype; + char buffer[3]; + + /* c valid between -1 and 255 */ + if (((unsigned)(c + 1)) <= 256) + return _pctype[c] & mask; + + _mlock (_LC_CTYPE_LOCK); + + if (isleadbyte(c>>8 & 0xff)) + { + buffer[0] = (c>>8 & 0xff); /* put lead-byte at start of str */ + buffer[1] = (char)c; + buffer[2] = 0; + } + else + { + buffer[0] = (char)c; + buffer[1] = 0; + } + if (MultiByteToWideChar(_lc_codepage, MB_PRECOMPOSED, + buffer, -1, widechar, 2) == 0) + return 0; + + _munlock (_LC_CTYPE_LOCK); + + if (GetStringTypeW(CT_CTYPE1, widechar, 2, &chartype) != NO_ERROR) { + return 0; + } + + return (int)(chartype & mask); +} + +#else /* defined(_INTL) && !defined(_NTSUBSET_) */ + +int _CRTAPI1 _isctype ( + int c, + int mask + ) +{ + return 0; +} + +#endif /* _INTL */ diff --git a/private/crt32/convert/iswctype.c b/private/crt32/convert/iswctype.c new file mode 100644 index 000000000..c8f9629b0 --- /dev/null +++ b/private/crt32/convert/iswctype.c @@ -0,0 +1,128 @@ +/*** +*iswctype.c - support isw* wctype functions/macros for wide characters +* +* Copyright (c) 1991-1992, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Defines iswctype - support isw* wctype functions/macros for +* wide characters (esp. > 255). +* +*Revision History: +* 10-11-91 ETC Created. +* 12-08-91 ETC Updated api; check type masks. +* 04-06-92 KRS Change to match ISO proposal. Fix logic error. +* 08-07-92 GJF _CALLTYPE4 (bogus usage) -> _CRTAPI1 (legit). +* 08-20-92 KRS Activated NLS support. +* 08-22-92 SRW Allow INTL definition to be conditional for building ntcrt.lib +* 09-02-92 SRW Get _INTL definition via ..\crt32.def +* 09-03-92 GJF Merged last 4 changes. +* 01-15-93 CFW Put #ifdef _INTL around wint_t d def to avoid warnings +* 02-12-93 CFW Return d not c, remove CTRL-Z. +* 02-17-93 CFW Include locale.h. +* 05-05-93 CFW Change name from is_wctype to iswctype as per ISO. +* 06-02-93 SRW ignore _INTL if _NTSUBSET_ defined. +* 06-26-93 CFW Support is_wctype forever. +* +*******************************************************************************/ + +#include +#include +#include +#include +#include + +/* + * Use GetStringTypeW() API so check that character type masks agree between + * ctype.h and winnls.h + */ +#if defined(_INTL) && !defined(_NTSUBSET_) +#if _UPPER != C1_UPPER || \ + _LOWER != C1_LOWER || \ + _DIGIT != C1_DIGIT || \ + _SPACE != C1_SPACE || \ + _PUNCT != C1_PUNCT || \ + _CONTROL != C1_CNTRL +#error Character type masks do not agree in ctype and winnls +#endif +#endif + + +/*** +*iswctype - support isw* wctype functions/macros. +* +*Purpose: +* This function is called by the isw* wctype functions/macros +* (e.g. iswalpha()) when their argument is a wide character > 255. +* It is also a standard ITSCJ (proposed) ISO routine and can be called +* by the user, even for characters < 256. +* Returns true or false depending on whether the argument satisfies +* the character class property encoded by the mask. Returns 0 if the +* argument is WEOF. +* +* NOTE: The isw* functions are neither locale nor codepage dependent. +* +*Entry: +* wchar_t c - the wide character whose type is to be tested +* wchar_t mask - the mask used by the isw* functions/macros +* corresponding to each character class property +* +*Exit: +* Returns non-zero if c is of the character class. +* Returns 0 if c is not of the character class. +* +*Exceptions: +* Returns 0 on any error. +* +*******************************************************************************/ + +int _CRTAPI1 iswctype ( + wchar_t c, + wctype_t mask + ) +{ + wint_t d; + + if (c == WEOF) + return 0; + + if (c < 256) /* consider: necessary? */ + d = _pwctype[c]; + else + { +#if defined(_INTL) && !defined(_NTSUBSET_) + if (_lc_handle[LC_CTYPE] == _CLOCALEHANDLE + || GetStringTypeW(CT_CTYPE1, &c, 1, &d) == 0) +#endif /* _INTL */ + return 0; + } + + return (int)(d & mask); +} + + +/*** +*is_wctype - support obsolete name +* +*Purpose: +* Name changed from is_wctype to iswctype. is_wctype must be supported. +* +*Entry: +* wchar_t c - the wide character whose type is to be tested +* wchar_t mask - the mask used by the isw* functions/macros +* corresponding to each character class property +* +*Exit: +* Returns non-zero if c is of the character class. +* Returns 0 if c is not of the character class. +* +*Exceptions: +* Returns 0 on any error. +* +*******************************************************************************/ +int _CRTAPI1 is_wctype ( + wchar_t c, + wctype_t mask + ) +{ + return iswctype(c, mask); +} diff --git a/private/crt32/convert/makefile b/private/crt32/convert/makefile new file mode 100644 index 000000000..6ee4f43fa --- /dev/null +++ b/private/crt32/convert/makefile @@ -0,0 +1,6 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/crt32/convert/mblen.c b/private/crt32/convert/mblen.c new file mode 100644 index 000000000..5e9d7473b --- /dev/null +++ b/private/crt32/convert/mblen.c @@ -0,0 +1,109 @@ +/*** +*mblen.c - length of multibyte character +* +* Copyright (c) 1990-1993, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Return the number of bytes contained in a multibyte character. +* +*Revision History: +* 03-19-90 KRS Module created. +* 12-20-90 KRS Include ctype.h. +* 03-20-91 KRS Ported from 16-bit tree. +* 12-09-91 ETC Updated comments; move __mb_cur_max to nlsdata1.c; +* add multithread. +* 06-01-93 CFW Re-write; verify valid MB char, proper error return, +* optimize, correct conversion bug. +* 06-02-93 SRW ignore _INTL if _NTSUBSET_ defined. +* 10-26-93 CFW Test for invalid MB chars using global preset flag. +* 01-14-94 SRW if _NTSUBSET_ defined call Rtl functions +* +*******************************************************************************/ + +#ifdef _NTSUBSET_ +#include +#include +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +/*** +*int mblen() - length of multibyte character +* +*Purpose: +* Return the number of bytes contained in a multibyte character. +* [ANSI]. +* +*Entry: +* const char *s = pointer to multibyte character +* size_t n = maximum length of multibyte character to consider +* +*Exit: +* If s = NULL, returns 0, indicating we use (only) state-independent +* character encodings. +* If s != NULL, returns: 0 (if *s = null char) +* -1 (if the next n or fewer bytes not valid mbc) +* number of bytes contained in multibyte char +* +*Exceptions: +* +*******************************************************************************/ + +int _CRTAPI1 mblen + ( + const char * s, + size_t n + ) +{ + assert (MB_CUR_MAX == 1 || MB_CUR_MAX == 2); + + if ( !s || !(*s) || (n == 0) ) + /* indicate do not have state-dependent encodings, + empty string length is 0 */ + return 0; + +#if defined(_INTL) && !defined(_NTSUBSET_) + if ( isleadbyte((unsigned char)*s) ) + { + /* multi-byte char */ + + /* verify valid MB char */ + if ( MB_CUR_MAX <= 1 || (int)n < MB_CUR_MAX || + MultiByteToWideChar(_lc_codepage, MB_PRECOMPOSED|__invalid_mb_chars, + s, MB_CUR_MAX, NULL, 0) == 0 ) + /* bad MB char */ + return -1; + else + return MB_CUR_MAX; + } + else { + /* single byte char */ + + /* verify valid SB char */ + if ( MultiByteToWideChar(_lc_codepage, MB_PRECOMPOSED|__invalid_mb_chars, + s, 1, NULL, 0) == 0 ) + return -1; + + return sizeof(char); + } +#else /* defined(_INTL) && !defined(_NTSUBSET_) */ + +#ifdef _NTSUBSET_ + { + char *s1 = (char *)s; + + RtlAnsiCharToUnicodeChar( &s1 ); + return s1 - s; + } +#else + return sizeof(char); +#endif +#endif /* _INTL */ +} diff --git a/private/crt32/convert/mbstowcs.c b/private/crt32/convert/mbstowcs.c new file mode 100644 index 000000000..739b91c5e --- /dev/null +++ b/private/crt32/convert/mbstowcs.c @@ -0,0 +1,197 @@ +/*** +*mbstowcs.c - Convert multibyte char string to wide char string. +* +* Copyright (c) 1990-1993, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Convert a multibyte char string into the equivalent wide char string. +* +*Revision History: +* 08-24-90 KRS Module created. +* 03-20-91 KRS Ported from 16-bit tree. +* 10-16-91 ETC Locale support under _INTL switch. +* 12-09-91 ETC Updated nlsapi; added multithread. +* 08-20-92 KRS Activated NLSAPI support. +* 08-31-92 SRW Allow INTL definition to be conditional for building ntcrt.lib +* 09-02-92 SRW Get _INTL definition via ..\crt32.def +* 02-09-93 CFW Always stuff WC 0 at end of output string of room (non _INTL). +* 04-06-93 SKS Replace _CRTAPI* with _cdecl +* 05-03-93 CFW Return pointer == NULL, return size, plus massive cleanup. +* 06-02-93 SRW ignore _INTL if _NTSUBSET_ defined. +* 09-27-93 CFW Avoid cast bug. +* 10-26-93 CFW Test for invalid MB chars using global preset flag. +* 01-14-94 SRW if _NTSUBSET_ defined call Rtl functions +* 07-06-94 SRW Call mblen instead of _mbstrlen for input to Rtl function +* 07-07-94 MMS/IJH Undo previous change, Call _mbstrlen +* +*******************************************************************************/ + +#ifdef _NTSUBSET_ +#include +#include +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +/*** +*size_t mbstowcs() - Convert multibyte char string to wide char string. +* +*Purpose: +* Convert a multi-byte char string into the equivalent wide char string, +* according to the LC_CTYPE category of the current locale. +* [ANSI]. +* +* NOTE: Currently, the C libraries support the "C" locale only. +* Non-C locale support now available under _INTL switch. +*Entry: +* wchar_t *pwcs = pointer to destination wide character string buffer +* const char *s = pointer to source multibyte character string +* size_t n = maximum number of wide characters to store +* +*Exit: +* If s != NULL, returns: number of words modified (<=n) +* (size_t)-1 (if invalid mbcs) +* +*Exceptions: +* Returns (size_t)-1 if s is NULL or invalid mbcs character encountered +* +*******************************************************************************/ + +#ifdef MTHREAD +size_t _CRTAPI1 mbstowcs + ( + wchar_t *pwcs, + const char *s, + size_t n + ) +{ + size_t retval; + + _mlock (_LC_CTYPE_LOCK); + retval = _mbstowcs_lk(pwcs, s, n); + _munlock (_LC_CTYPE_LOCK); + return retval; +} +#endif /* MTHREAD */ + +#ifdef MTHREAD +size_t _CRTAPI1 _mbstowcs_lk +#else +size_t _CRTAPI1 mbstowcs +#endif + ( + wchar_t *pwcs, + const char *s, + size_t n + ) +{ + int retval = 0; + size_t count = 0; + + if (pwcs && n == 0) + return (size_t) 0; + + assert(s != NULL); + + /* if destination string exists, fill it in */ + if (pwcs) + { +#if defined(_INTL) && !defined(_NTSUBSET_) + if (_lc_handle[LC_CTYPE] == _CLOCALEHANDLE && + _lc_codepage == _CLOCALECP) + { +#endif /* _INTL */ +#ifdef _NTSUBSET_ + { + NTSTATUS Status; + int size; + + size = _mbstrlen(s); + Status = RtlMultiByteToUnicodeN(pwcs, n * sizeof( *pwcs ), (PULONG)&size, s, size+1 ); + if (!NT_SUCCESS(Status)) + { + errno = EILSEQ; + size = -1; + } else { + size = size / sizeof( *pwcs ); + if (pwcs[size-1] == L'\0') { + size -= 1; + } + } + + return size; + } +#else + /* C locale: easy and fast */ + while (count < n) + { + *pwcs = (wchar_t) ((unsigned char)s[count]); + if (!s[count]) + return count; + count++; + pwcs++; + } +#endif + return count; +#if defined(_INTL) && !defined(_NTSUBSET_) + } else { + /* Assume that usually the buffer is large enough */ + if ((count=MultiByteToWideChar(_lc_codepage, MB_PRECOMPOSED|__invalid_mb_chars, + s, -1, pwcs, n)) != 0) + return count - 1; + + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) + { + errno = EILSEQ; + return (size_t)-1; + } + + /* buffer not large enough, must do char by char */ + while (count < n) + { + if ((retval = MultiByteToWideChar (_lc_codepage, MB_PRECOMPOSED, + s, MB_CUR_MAX, pwcs, 1)) == 0) + { + errno = EILSEQ; + return (size_t)-1; + } + if (!*s) + return count; + if (isleadbyte((unsigned char)*s)) + s++; + s++; + count++; + pwcs++; + } + return count; + } +#endif /* _INTL */ + } + else { /* pwcs == NULL, get size only, s must be NUL-terminated */ +#if defined(_INTL) && !defined(_NTSUBSET_) + if (_lc_handle[LC_CTYPE] == _CLOCALEHANDLE && + _lc_codepage == _CLOCALECP) +#endif /* _INTL */ + return strlen(s); + +#if defined(_INTL) && !defined(_NTSUBSET_) + else { + if ((count=MultiByteToWideChar(_lc_codepage, MB_PRECOMPOSED|__invalid_mb_chars, + s, -1, NULL, 0)) == 0) + { + errno = EILSEQ; + return (size_t)-1; + } + + return count - 1; + } +#endif /* _INTL */ + } +} diff --git a/private/crt32/convert/mbtowc.c b/private/crt32/convert/mbtowc.c new file mode 100644 index 000000000..7f8aea165 --- /dev/null +++ b/private/crt32/convert/mbtowc.c @@ -0,0 +1,174 @@ +/*** +*mbtowc.c - Convert multibyte char to wide char. +* +* Copyright (c) 1990-1993, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Convert a multibyte character into the equivalent wide character. +* +*Revision History: +* 03-19-90 KRS Module created. +* 12-20-90 KRS Put some intl stuff here for now... +* 03-18-91 KRS Fixed bogus cast involving wchar_t. Fix copyright. +* 03-20-91 KRS Ported from 16-bit tree. +* 07-22-91 KRS C700 3525: Check for s==0 before calling mblen. +* 07-23-91 KRS Hard-coded for "C" locale to avoid bogus interim #'s. +* 10-15-91 ETC Locale support under _INTL (finally!). +* 12-09-91 ETC Updated nlsapi; added multithread. +* 08-20-92 KRS Activated NLSAPI support. +* 08-31-92 SRW Allow INTL definition to be conditional for building ntcrt.lib +* 09-02-92 SRW Get _INTL definition via ..\crt32.def +* 04-26-93 CFW Remove unused variable. +* 05-04-93 CFW Kinder, gentler error handling. +* 06-01-93 CFW Re-write; verify valid MB char, proper error return, +* optimize, fix bugs. +* 06-02-93 SRW ignore _INTL if _NTSUBSET_ defined. +* 10-26-93 CFW Test for invalid MB chars using global preset flag. +* 01-14-94 SRW if _NTSUBSET_ defined call Rtl functions +* +*******************************************************************************/ + +#ifdef _NTSUBSET_ +#include +#include +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +/*** +*int mbtowc() - Convert multibyte char to wide character. +* +*Purpose: +* Convert a multi-byte character into the equivalent wide character, +* according to the LC_CTYPE category of the current locale. +* [ANSI]. +* +* NOTE: Currently, the C libraries support the "C" locale only. +* Non-C locale support now available under _INTL switch. +*Entry: +* wchar_t *pwc = pointer to destination wide character +* const char *s = pointer to multibyte character +* size_t n = maximum length of multibyte character to consider +* +*Exit: +* If s = NULL, returns 0, indicating we only use state-independent +* character encodings. +* If s != NULL, returns: 0 (if *s = null char) +* -1 (if the next n or fewer bytes not valid mbc) +* number of bytes comprising converted mbc +* +*Exceptions: +* +*******************************************************************************/ + +#ifdef MTHREAD +int _CRTAPI1 mbtowc + ( + wchar_t *pwc, + const char *s, + size_t n + ) +{ + int retval; + + _mlock (_LC_CTYPE_LOCK); + retval = _mbtowc_lk(pwc, s, n); + _munlock (_LC_CTYPE_LOCK); + return retval; +} +#endif /* MTHREAD */ + +#ifdef MTHREAD +int _CRTAPI1 _mbtowc_lk +#else +int _CRTAPI1 mbtowc +#endif + ( + wchar_t *pwc, + const char *s, + size_t n + ) +{ + assert (MB_CUR_MAX == 1 || MB_CUR_MAX == 2); + + if ( !s || n == 0 ) + /* indicate do not have state-dependent encodings, + handle zero length string */ + return 0; + + if ( !*s ) + { + /* handle NULL char */ + if (pwc) + *pwc = 0; + return 0; + } + +#if defined(_INTL) && !defined(_NTSUBSET_) + + if ( _lc_handle[LC_CTYPE] == _CLOCALEHANDLE ) + { + +#endif /* _INTL */ + +#ifdef _NTSUBSET_ + { + NTSTATUS Status; + int size; + + Status = RtlMultiByteToUnicodeN(pwc, (pwc) ? sizeof( *pwc ) : 0, (PULONG)&size, s, n ); + if (!NT_SUCCESS(Status)) + { + errno = EILSEQ; + size = -1; + + + } else + size = mblen(s, n); + + return size; + } +#else + if (pwc) + *pwc = (wchar_t)(unsigned char)*s; + return sizeof(char); +#endif + +#if defined(_INTL) && !defined(_NTSUBSET_) + + } + + if ( isleadbyte((unsigned char)*s) ) + { + /* multi-byte char */ + + if ( MB_CUR_MAX <= 1 || (int)n < MB_CUR_MAX || + (MultiByteToWideChar(_lc_codepage, MB_PRECOMPOSED|__invalid_mb_chars, + s, MB_CUR_MAX, pwc, (pwc) ? 1 : 0) == 0) ) + { + errno = EILSEQ; + return -1; + } + return MB_CUR_MAX; + } + else { + /* single byte char */ + + if ( MultiByteToWideChar(_lc_codepage, MB_PRECOMPOSED|__invalid_mb_chars, + s, 1, pwc, (pwc) ? 1 : 0) == 0 ) + { + errno = EILSEQ; + return -1; + } + + return sizeof(char); + } +#endif /* _INTL */ +} diff --git a/private/crt32/convert/sources b/private/crt32/convert/sources new file mode 100644 index 000000000..15815f858 --- /dev/null +++ b/private/crt32/convert/sources @@ -0,0 +1,64 @@ +!IF 0 + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + This file specifies the target component being built and the list of + sources files needed to build that component. Also specifies optional + compiler switches and libraries that are unique for the component being + built. + + +Author: + + Steve Wood (stevewo) 12-Apr-1990 + jeffrob 29-sep-1990, use crt32.def + +NOTE: Commented description of this file is in \nt\bak\bin\sources.tpl + +!ENDIF + +MAJORCOMP=crt +MINORCOMP=convert + +TARGETNAME=convert +TARGETPATH=..\obj +TARGETTYPE=LIBRARY +386_STDCALL=0 + +!INCLUDE ..\crt32.def + +SOURCES=_ctype.c \ + _fptostr.c \ + _mbslen.c \ + _wctype.c \ + atof.c \ + atox.c \ + fcvt.c \ + gcvt.c \ + isctype.c \ + iswctype.c \ + mblen.c \ + mbstowcs.c \ + mbtowc.c \ + strtod.c \ + strtol.c \ + swab.c \ + tolower.c \ + toupper.c \ + towlower.c \ + towupper.c \ + wcstod.c \ + wcstol.c \ + wcstombs.c \ + wctomb.c \ + wtox.c \ + xtoa.c \ + xtow.c + +ALPHA_SOURCES=strtoq.c diff --git a/private/crt32/convert/strtod.c b/private/crt32/convert/strtod.c new file mode 100644 index 000000000..68e3b5d76 --- /dev/null +++ b/private/crt32/convert/strtod.c @@ -0,0 +1,121 @@ +/*** +*strtod.c - convert string to floating point number +* +* Copyright (c) 1985-1992, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Convert character string to floating point number +* +*Revision History: +* 09-09-83 RKW Module created +* 08-19-85 TDC changed to strtod +* 04-13-87 JCR Added "const" to declaration +* 04-20-87 BCM Added checks for negative overflow and for underflow +* 11-09-87 BCM different interface under ifdef MTHREAD +* 12-11-87 JCR Added "_LOAD_DS" to declaration +* 02-22-88 JCR Added cast to nptr to get rid of cl const warning +* 05-24-88 PHG Merged DLL and normal versions +* 08-24-88 PHG No digits found => *endptr = nptr [ANSI] +* Revised test order so invalid detection works always +* 10-20-88 JCR Changed 'DOUBLE' to 'double' for 386 +* 11-20-89 JCR atof() is always _cdecl in 386 (not pascal) +* 03-05-90 GJF Fixed calling type, added #include , +* removed #include , removed redundant +* prototypes, removed some leftover 16-bit support and +* fixed the copyright. Also, cleaned up the formatting +* a bit. +* 07-23-90 SBM Compiles cleanly with -W3 (added/removed appropriate +* #includes) +* 08-01-90 SBM Renamed to +* 09-27-90 GJF New-style function declarators. +* 10-21-92 GJF Made char-to-int conversion unsigned. +* +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +/*** +*double strtod(nptr, endptr) - convert string to double +* +*Purpose: +* strtod recognizes an optional string of tabs and spaces, +* then an optional sign, then a string of digits optionally +* containing a decimal point, then an optional e or E followed +* by an optionally signed integer, and converts all this to +* to a floating point number. The first unrecognized +* character ends the string, and is pointed to by endptr. +* +*Entry: +* nptr - pointer to string to convert +* +*Exit: +* returns value of character string +* char **endptr - if not NULL, points to character which stopped +* the scan +* +*Exceptions: +* +*******************************************************************************/ + +double _CRTAPI1 strtod ( + const char *nptr, + REG2 char **endptr + ) +{ + +#ifdef MTHREAD + struct _flt answerstruct; +#endif + + FLT answer; + double tmp; + unsigned int flags; + REG1 char *ptr = (char *) nptr; + + /* scan past leading space/tab characters */ + + while ( isspace((int)(unsigned char)*ptr) ) + ptr++; + + /* let _fltin routine do the rest of the work */ + +#ifdef MTHREAD + /* ok to take address of stack variable here; fltin2 knows to use ss */ + answer = _fltin2( &answerstruct, ptr, strlen(ptr), 0, 0); +#else + answer = _fltin(ptr, strlen(ptr), 0, 0); +#endif + + if ( endptr != NULL ) + *endptr = (char *) ptr + answer->nbytes; + + flags = answer->flags; + if ( flags & (512 | 64)) { + /* no digits found or invalid format: + ANSI says return 0.0, and *endptr = nptr */ + tmp = 0.0; + if ( endptr != NULL ) + *endptr = (char *) nptr; + } + else if ( flags & (128 | 1) ) { + if ( *ptr == '-' ) + tmp = -HUGE_VAL; /* negative overflow */ + else + tmp = HUGE_VAL; /* positive overflow */ + errno = ERANGE; + } + else if ( flags & 256 ) { + tmp = 0.0; /* underflow */ + errno = ERANGE; + } + else + tmp = answer->dval; + + return(tmp); +} diff --git a/private/crt32/convert/strtol.c b/private/crt32/convert/strtol.c new file mode 100644 index 000000000..d74bde7be --- /dev/null +++ b/private/crt32/convert/strtol.c @@ -0,0 +1,227 @@ +/*** +*strtol.c - Contains C runtimes strtol and strtoul +* +* Copyright (c) 1989-1993, Microsoft Corporation. All rights reserved. +* +*Purpose: +* strtol - convert ascii string to long signed integer +* strtoul - convert ascii string to long unsigned integer +* +*Revision History: +* 06-05-89 PHG Module created, based on strtol.asm +* 03-06-90 GJF Fixed calling type, added #include +* and fixed the copyright. Also, cleaned up the +* formatting a bit. +* 03-07-90 GJF Fixed compiler warnings (added const qualifier to +* an arg type and local var type). +* 03-23-90 GJF Made strtoxl() _CALLTYPE4. +* 08-13-90 SBM Compiles cleanly with -W3 +* 09-27-90 GJF New-style function declarators. +* 10-24-91 GJF Had to cast LONG_MAX to unsigned long in expr. to +* mollify MIPS compiler. +* 10-21-92 GJF Made char-to-int conversions unsigned. +* 04-21-93 GJF Removed assumption that LONG_MIN == -LONG_MAX. +* 05-10-93 GJF Fixed error check. +* 05-20-93 GJF Nothing like taking ugly code and making prettier... +* and wrong. Fixed bug introduced on 5-10. +* +*******************************************************************************/ + +#include +#include +#include +#include +#include + + +/*** +*strtol, strtoul(nptr,endptr,ibase) - Convert ascii string to long un/signed +* int. +* +*Purpose: +* Convert an ascii string to a long 32-bit value. The base +* used for the caculations is supplied by the caller. The base +* must be in the range 0, 2-36. If a base of 0 is supplied, the +* ascii string must be examined to determine the base of the +* number: +* (a) First char = '0', second char = 'x' or 'X', +* use base 16. +* (b) First char = '0', use base 8 +* (c) First char in range '1' - '9', use base 10. +* +* If the 'endptr' value is non-NULL, then strtol/strtoul places +* a pointer to the terminating character in this value. +* See ANSI standard for details +* +*Entry: +* nptr == NEAR/FAR pointer to the start of string. +* endptr == NEAR/FAR pointer to the end of the string. +* ibase == integer base to use for the calculations. +* +* string format: [whitespace] [sign] [0] [x] [digits/letters] +* +*Exit: +* Good return: +* result +* +* Overflow return: +* strtol -- LONG_MAX or LONG_MIN +* strtoul -- ULONG_MAX +* strtol/strtoul -- errno == ERANGE +* +* No digits or bad base return: +* 0 +* endptr = nptr* +* +*Exceptions: +* None. +*******************************************************************************/ + +/* flag values */ +#define FL_UNSIGNED 1 /* strtoul called */ +#define FL_NEG 2 /* negative sign found */ +#define FL_OVERFLOW 4 /* overflow occured */ +#define FL_READDIGIT 8 /* we've read at least one correct digit */ + + +static unsigned long _CRTAPI3 strtoxl ( + const char *nptr, + const char **endptr, + int ibase, + int flags + ) +{ + const char *p; + char c; + unsigned long number; + unsigned digval; + unsigned long maxval; + + p = nptr; /* p is our scanning pointer */ + number = 0; /* start with zero */ + + c = *p++; /* read char */ + while ( isspace((int)(unsigned char)c) ) + c = *p++; /* skip whitespace */ + + if (c == '-') { + flags |= FL_NEG; /* remember minus sign */ + c = *p++; + } + else if (c == '+') + c = *p++; /* skip sign */ + + if (ibase < 0 || ibase == 1 || ibase > 36) { + /* bad base! */ + if (endptr) + /* store beginning of string in endptr */ + *endptr = nptr; + return 0L; /* return 0 */ + } + else if (ibase == 0) { + /* determine base free-lance, based on first two chars of + string */ + if (c != '0') + ibase = 10; + else if (*p == 'x' || *p == 'X') + ibase = 16; + else + ibase = 8; + } + + if (ibase == 16) { + /* we might have 0x in front of number; remove if there */ + if (c == '0' && (*p == 'x' || *p == 'X')) { + ++p; + c = *p++; /* advance past prefix */ + } + } + + /* if our number exceeds this, we will overflow on multiply */ + maxval = ULONG_MAX / ibase; + + + for (;;) { /* exit in middle of loop */ + /* convert c to value */ + if ( isdigit((int)(unsigned char)c) ) + digval = c - '0'; + else if ( isalpha((int)(unsigned char)c) ) + digval = toupper(c) - 'A' + 10; + else + break; + if (digval >= (unsigned)ibase) + break; /* exit loop if bad digit found */ + + /* record the fact we have read one digit */ + flags |= FL_READDIGIT; + + /* we now need to compute number = number * base + digval, + but we need to know if overflow occured. This requires + a tricky pre-check. */ + + if (number < maxval || (number == maxval && + (unsigned long)digval <= ULONG_MAX % ibase)) { + /* we won't overflow, go ahead and multiply */ + number = number * ibase + digval; + } + else { + /* we would have overflowed -- set the overflow flag */ + flags |= FL_OVERFLOW; + } + + c = *p++; /* read next digit */ + } + + --p; /* point to place that stopped scan */ + + if (!(flags & FL_READDIGIT)) { + /* no number there; return 0 and point to beginning of + string */ + if (endptr) + /* store beginning of string in endptr later on */ + p = nptr; + number = 0L; /* return 0 */ + } + else if ( (flags & FL_OVERFLOW) || + ( !(flags & FL_UNSIGNED) && + ( ( (flags & FL_NEG) && (number > -LONG_MIN) ) || + ( !(flags & FL_NEG) && (number > LONG_MAX) ) ) ) ) + { + /* overflow or signed overflow occurred */ + errno = ERANGE; + if ( flags & FL_UNSIGNED ) + number = ULONG_MAX; + else if ( flags & FL_NEG ) + number = (unsigned long)(-LONG_MIN); + else + number = LONG_MAX; + } + + if (endptr != NULL) + /* store pointer to char that stopped the scan */ + *endptr = p; + + if (flags & FL_NEG) + /* negate result if there was a neg sign */ + number = (unsigned long)(-(long)number); + + return number; /* done. */ +} + +long _CRTAPI1 strtol ( + const char *nptr, + char **endptr, + int ibase + ) +{ + return (long) strtoxl(nptr, endptr, ibase, 0); +} + +unsigned long _CRTAPI1 strtoul ( + const char *nptr, + char **endptr, + int ibase + ) +{ + return strtoxl(nptr, endptr, ibase, FL_UNSIGNED); +} diff --git a/private/crt32/convert/strtoq.c b/private/crt32/convert/strtoq.c new file mode 100644 index 000000000..b0e370a1f --- /dev/null +++ b/private/crt32/convert/strtoq.c @@ -0,0 +1,236 @@ +/*** +*strtoq.c - Contains C runtimes strtoq and strtouq +* +* Copyright (c) 1989-1992, Microsoft Corporation. All rights reserved. +* Copyright (c) 1992, Digital Equipment Corporation. +* +*Purpose: +* strtoq - convert ascii string to QUAD (signed quad) integer +* strtouq - convert ascii string to UQUAD (unsigned quad) integer +* +*Revision History: +* 06-05-89 PHG Module created, based on strtol.asm +* 03-06-90 GJF Fixed calling type, added #include +* and fixed the copyright. Also, cleaned up the +* formatting a bit. +* 03-07-90 GJF Fixed compiler warnings (added const qualifier to +* an arg type and local var type). +* 03-23-90 GJF Made strtoxl() _CALLTYPE4. +* 08-13-90 SBM Compiles cleanly with -W3 +* 09-27-90 GJF New-style function declarators. +* 10-24-91 GJF Had to cast LONG_MAX to unsigned long in expr. to +* mollify MIPS compiler. +* 08-28-92 TVB Created strtoq.c directly from strtol.c. +* 10-21-92 GJF Made char-to-int conversions unsigned. +* +*******************************************************************************/ + +#include +#include +#include +#include +#include + +#ifdef _ALPHA_ + +#ifdef _MSC_VER +typedef __int64 quad; +typedef unsigned __int64 uquad; +#else +typedef long long quad; +typedef unsigned long long uquad; +#endif + +#define QUAD_MIN ((quad)-9223372036854775807) /* minimum (signed) quad value */ +#define QUAD_MAX ((quad) 9223372036854775807) /* maximum (signed) quad value */ +#define UQUAD_MAX ((uquad)0xffffffffffffffff) /* maximum unsigned quad value */ + +#endif + +/*** +*strtoq, strtouq(nptr,endptr,ibase) - Convert ascii string to QUAD un/signed +* int. +* +*Purpose: +* Convert an ascii string to a 64-bit quad value. The base +* used for the caculations is supplied by the caller. The base +* must be in the range 0, 2-36. If a base of 0 is supplied, the +* ascii string must be examined to determine the base of the +* number: +* (a) First char = '0', second char = 'x' or 'X', +* use base 16. +* (b) First char = '0', use base 8 +* (c) First char in range '1' - '9', use base 10. +* +* If the 'endptr' value is non-NULL, then strtoq/strtouq places +* a pointer to the terminating character in this value. +* See ANSI standard for details +* +*Entry: +* nptr == NEAR/FAR pointer to the start of string. +* endptr == NEAR/FAR pointer to the end of the string. +* ibase == integer base to use for the calculations. +* +* string format: [whitespace] [sign] [0] [x] [digits/letters] +* +*Exit: +* Good return: +* result +* +* Overflow return: +* strtoq -- QUAD_MAX or QUAD_MIN +* strtouq -- UQUAD_MAX +* strtoq/strtouq -- errno == ERANGE +* +* No digits or bad base return: +* 0 +* endptr = nptr* +* +*Exceptions: +* None. +*******************************************************************************/ + +/* flag values */ +#define FL_UNSIGNED 1 /* strtouq called */ +#define FL_NEG 2 /* negative sign found */ +#define FL_OVERFLOW 4 /* overflow occured */ +#define FL_READDIGIT 8 /* we've read at least one correct digit */ + + +static uquad _CRTAPI3 strtoxq ( + const char *nptr, + const char **endptr, + int ibase, + int flags + ) +{ + const char *p; + char c; + uquad number; + unsigned digval; + uquad maxval; + + p = nptr; /* p is our scanning pointer */ + number = 0; /* start with zero */ + + c = *p++; /* read char */ + while ( isspace((int)(unsigned char)c) ) + c = *p++; /* skip whitespace */ + + if (c == '-') { + flags |= FL_NEG; /* remember minus sign */ + c = *p++; + } + else if (c == '+') + c = *p++; /* skip sign */ + + if (ibase < 0 || ibase == 1 || ibase > 36) { + /* bad base! */ + if (endptr) + /* store beginning of string in endptr */ + *endptr = nptr; + return 0L; /* return 0 */ + } + else if (ibase == 0) { + /* determine base free-lance, based on first two chars of + string */ + if (c != '0') + ibase = 10; + else if (*p == 'x' || *p == 'X') + ibase = 16; + else + ibase = 8; + } + + if (ibase == 16) { + /* we might have 0x in front of number; remove if there */ + if (c == '0' && (*p == 'x' || *p == 'X')) { + ++p; + c = *p++; /* advance past prefix */ + } + } + + /* if our number exceeds this, we will overflow on multiply */ + maxval = UQUAD_MAX / ibase; + + + for (;;) { /* exit in middle of loop */ + /* convert c to value */ + if ( isdigit((int)(unsigned char)c) ) + digval = c - '0'; + else if ( isalpha((int)(unsigned char)c) ) + digval = toupper(c) - 'A' + 10; + else + break; + if (digval >= (unsigned)ibase) + break; /* exit loop if bad digit found */ + + /* record the fact we have read one digit */ + flags |= FL_READDIGIT; + + /* we now need to compute number = number * base + digval, + but we need to know if overflow occured. This requires + a tricky pre-check. */ + + if (number < maxval || (number == maxval && + (uquad)digval <= UQUAD_MAX % ibase)) { + /* we won't overflow, go ahead and multiply */ + number = number * ibase + digval; + } + else { + /* we would have overflowed -- set the overflow flag */ + flags |= FL_OVERFLOW; + } + + c = *p++; /* read next digit */ + } + + --p; /* point to place that stopped scan */ + + if (!(flags & FL_READDIGIT)) { + /* no number there; return 0 and point to beginning of + string */ + if (endptr) + /* store beginning of string in endptr later on */ + p = nptr; + number = 0L; /* return 0 */ + } + else if ((flags & FL_OVERFLOW) || (!(flags & FL_UNSIGNED) && + (number & ((uquad)QUAD_MAX+1)))) { + /* overflow occurred or signed overflow occurred */ + errno = ERANGE; + if (flags & FL_UNSIGNED) + number = UQUAD_MAX; + else + /* set error code, will be negated if necc. */ + number = QUAD_MAX; + } + + if (endptr != NULL) + /* store pointer to char that stopped the scan */ + *endptr = p; + + if (flags & FL_NEG) + /* negate result if there was a neg sign */ + number = (uquad)(-(quad)number); + + return number; /* done. */ +} + +quad _CRTAPI1 strtoq ( + const char *nptr, + char **endptr, + int ibase + ) +{ + return (quad) strtoxq(nptr, endptr, ibase, 0); +} + +uquad _CRTAPI1 strtouq ( + const char *nptr, + char **endptr, + int ibase + ) +{ + return strtoxq(nptr, endptr, ibase, FL_UNSIGNED); +} diff --git a/private/crt32/convert/swab.c b/private/crt32/convert/swab.c new file mode 100644 index 000000000..1b8fdbf4a --- /dev/null +++ b/private/crt32/convert/swab.c @@ -0,0 +1,58 @@ +/*** +*swab.c - block copy, while swapping even/odd bytes +* +* Copyright (c) 1989-1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* This module contains the routine _swab() which swaps the odd/even +* bytes of words during a block copy. +* +*Revision History: +* 06-02-89 PHG module created, based on asm version +* 03-06-90 GJF Fixed calling type, added #include and +* fixed copyright. Also, cleaned up the formatting a +* bit. +* 09-27-90 GJF New-style function declarators. +* 01-21-91 GJF ANSI naming. +* +*******************************************************************************/ + +#include +#include + +/*** +*void _swab(srcptr, dstptr, nbytes) - swap ODD/EVEN bytes during word move +* +*Purpose: +* This routine copys a block of words and swaps the odd and even +* bytes. nbytes must be > 0, otherwise nothing is copied. If +* nbytes is odd, then only (nbytes-1) bytes are copied. +* +*Entry: +* srcptr = pointer to the source block +* dstptr = pointer to the destination block +* nbytes = number of bytes to swap +* +*Returns: +* None. +* +*Exceptions: +* +*******************************************************************************/ + +void _CALLTYPE1 _swab ( + char *src, + char *dest, + int nbytes + ) +{ + char b1, b2; + + while (nbytes > 1) { + b1 = *src++; + b2 = *src++; + *dest++ = b2; + *dest++ = b1; + nbytes -= 2; + } +} diff --git a/private/crt32/convert/testconv.c b/private/crt32/convert/testconv.c new file mode 100644 index 000000000..6749cce26 --- /dev/null +++ b/private/crt32/convert/testconv.c @@ -0,0 +1,152 @@ +/* incomplete test suite for convert functions + + Current functions tested: + all isxxxxx functions + toupper + tolower + atoi + atol + strtol + strtoul + swab + itoa + ltoa + ultoa +*/ + +#include +#include +#include +#include + +fail(int n) +{ + printf("Test #%d failed.\n", n); +} + +main() +{ + char s[512]; + char t[512]; + char *p; + + /* test isxxxx functions */ + if (!iscntrl(0x7)) fail(1); + if (iscntrl('c')) fail(2); + if (!isdigit('0')) fail(3); + if (isdigit('A')) fail(4); + if (!isgraph(';')) fail(5); + if (isgraph(' ')) fail(6); + if (!islower('f')) fail(7); + if (islower('F')) fail(8); + if (!isprint('S')) fail(9); + if (isprint('\v')) fail(10); + if (!ispunct('.')) fail(11); + if (ispunct('A')) fail(12); + if (!isspace('\v')) fail(13); + if (isspace('D')) fail(14); + if (!isupper('D')) fail(15); + if (isupper('z')) fail(16); + if (!isxdigit('D')) fail(17); + if (isxdigit('G')) fail(18); + if (!isalnum('7')) fail(19); + if (isalnum(';')) fail(20); + if (!isalpha('j')) fail(21); + if (isalpha('$')) fail(22); + if (!isascii(0x3)) fail(23); + if (isascii(234)) fail(24); + if (!iscsym('d')) fail(25); + if (iscsym('$')) fail(26); + if (!iscsymf('A')) fail(27); + if (iscsymf('5')) fail(28); + + + /* test toupper and tolower */ + if (tolower('C') != 'c') fail(29); + if (tolower('d') != 'd') fail(30); + if (tolower('$') != '$') fail(31); + if (toupper('q') != 'Q') fail(32); + if (toupper('A') != 'A') fail(33); + if (toupper(';') != ';') fail(34); + + + /* test atol/atoi */ + if (atol("-123") != -123) fail(35); + if (atoi("32767") != 32767) fail(36); + if (atoi("-32767") != -32767) fail(36); + if (atol("0") != 0) fail(37); + if (atol("2147483647") != 2147483647) fail(38); + if (atol("-2147483647") != -2147483647) fail(39); + if (atol("123456") != 123456) fail(40); + if (atol("-123456") != -123456) fail(41); + + /* test strtol */ + if (strtol("-123", NULL, 10) != -123) fail(42); + if (strtol(" 2147483646", NULL, 10) != 2147483646) fail(43); + if (strtol("-2147483646$$", NULL, 10) != -2147483646) fail(44); + if (strtol(" 2147483648x", NULL, 10) != LONG_MAX) fail(45); + if (strtol(" -2147483648", NULL, 10) != LONG_MIN) fail(46); + if (strtol("0", NULL, 10) != 0) fail(47); + if (strtol("981235b", NULL, 10) != 981235) fail(48); + if (strtol(" -1234567a", NULL, 10) != -1234567) fail(49); + if (strtol("FFDE", NULL, 16) != 0xFFDE) fail(50); + if (strtol("7FFFFFFE", NULL, 16) != 0x7FFFFFFE) fail(51); + if (strtol("-0x45", NULL, 16) != -0x45) fail(52); + if (strtol("23478", NULL, 8) != 02347) fail(53); + if (strtol(" -0x123D", NULL, 0) != -0x123d) fail(54); + if (strtol(" 01238", NULL, 0) != 0123) fail(55); + if (strtol(" -678899", NULL, 0) != -678899) fail(56); + + errno = 0; + strtol("2147483647", NULL, 10); + if (errno != 0) fail(57); + errno = 0; + strtol("2147483648", NULL, 10); + if (errno != ERANGE) fail(58); + errno = 0; + strtol("63234283743", NULL, 10); + if (errno != ERANGE) fail(59); + strcpy(s, " 8983"); + strtol(s, &p, 8); + if (s != p) fail(60); + strcpy(s, "12345678901234567890XX"); + strtol(s, &p, 0); + if (p != s+20) fail(61); + strcpy(s, " 111"); + strtol(s, &p, 1); + if (p != s) fail(62); + + errno = 0; + if (strtoul("4294967295", NULL, 10) != ULONG_MAX) fail(63); + if (errno != 0) fail(64); + errno = 0; + strtoul("4294967296", NULL, 10); + if (errno != ERANGE) fail(65); + errno = 0; + strtoul("63234283743", NULL, 10); + if (errno != ERANGE) fail(66); + + /* test swab */ + strcpy(s, "abcdefghijklmn"); + swab(s, t, 14); + if (strcmp(t, "badcfehgjilknm") != 0) fail(67); + strcpy(t, s); + swab(s, t, 7); + if (strcmp(t, "badcfeghijklmn") != 0) fail(68); + strcpy(t, s); + swab(s, t, -5); + if (strcmp(s, t) != 0) fail(69); + + /* test itoa/ltoa/ultoa */ + if (strcmp(itoa(345, s, 10), "345") != 0) fail(70); + if (strcmp(itoa(-345, s, 10), "-345") != 0) fail(71); + if (strcmp(itoa(33, s, 36), "x") != 0) fail(72); + if (strcmp(itoa(65535U, s, 16), "ffff") != 0) fail(73); + if (strcmp(ltoa(123457, s, 10), "123457") != 0) fail(74); + if (strcmp(ltoa(-123457, s, 10), "-123457") != 0) fail(75); + if (strcmp(ltoa(076512L, s, 8), "76512") != 0) fail(76); + if (strcmp(ltoa(-1L, s, 10), "-1") != 0) fail(77); + if (strcmp(ltoa(-1L, s, 16), "ffffffff") != 0) fail(78); + if (strcmp(ultoa(-1L, s, 10), "4294967295") != 0) fail(79); + +} diff --git a/private/crt32/convert/tolower.c b/private/crt32/convert/tolower.c new file mode 100644 index 000000000..604026f4c --- /dev/null +++ b/private/crt32/convert/tolower.c @@ -0,0 +1,155 @@ +/*** +*tolower.c - convert character to lower case +* +* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Defines function versions of _tolower() and tolower(). +* +*Revision History: +* 11-09-84 DFW created +* 12-11-87 JCR Added "_LOAD_DS" to declaration +* 02-23-89 GJF Added function version of _tolower and cleaned up. +* 03-26-89 GJF Migrated to 386 tree +* 03-06-90 GJF Fixed calling type, added #include and +* fixed copyright. +* 09-27-90 GJF New-style function declarators. +* 10-11-91 ETC Locale support for tolower under _INTL switch. +* 12-10-91 ETC Updated nlsapi; added multithread. +* 12-17-92 KRS Updated and optimized for latest NLSAPI. Bug-fixes. +* 01-19-93 CFW Fixed typo. +* 03-25-93 CFW _tolower now defined when _INTL. +* 06-02-93 SRW ignore _INTL if _NTSUBSET_ defined. +* 09-15-93 CFW Change buffer to unsigned char to fix nasty cast bug. +* +*******************************************************************************/ + +#include +#include +#include +#ifdef _INTL +#include +#include +#include +#endif + +/* remove macro defintions of _tolower() and tolower() + */ +#undef _tolower +#undef tolower + +/* define function-like macro equivalent to _tolower() + */ +#define mklower(c) ( (c)-'A'+'a' ) + +/*** +*int _tolower(c) - convert character to lower case +* +*Purpose: +* _tolower() is simply a function version of the macro of the same name. +* +*Entry: +* c - int value of character to be converted +* +*Exit: +* returns int value of lower case representation of c +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE1 _tolower ( + int c + ) +{ + return(mklower(c)); +} + +/*** +*int tolower(c) - convert character to lower case +* +*Purpose: +* tolower() is simply a function version of the macro of the same name. +* +*Entry: +* c - int value of character to be converted +* +*Exit: +* if c is an upper case letter, returns int value of lower case +* representation of c. otherwise, it returns c. +* +*Exceptions: +* +*******************************************************************************/ + + +int _CALLTYPE1 tolower ( + int c + ) +{ +#if defined(_INTL) && !defined(_NTSUBSET_) + wchar_t widechar1[2], widechar2[2]; + int size; + unsigned char buffer[3]; + + _mlock (_LC_CTYPE_LOCK); + + if ((_lc_handle[LC_CTYPE] == _CLOCALEHANDLE) && + (_lc_codepage == _CLOCALECP)) { + if (isupper(c)) + c = c + ('a' - 'A'); + _munlock (_LC_CTYPE_LOCK); + return c; + } + + /* if checking case of c does not require API call, do it */ + if (c < 256) { + if (!isupper(c)) { + _munlock (_LC_CTYPE_LOCK); + return c; + } + } + + /* convert c to wide char */ + if (isleadbyte(c>>8 & 0xff)) + { + buffer[0] = (c>>8 & 0xff); /* put lead-byte at start of str */ + buffer[1] = (unsigned char)c; + buffer[2] = 0; + } + else + { + buffer[0] = (unsigned char)c; + buffer[1] = 0; + } + if (!(size=MultiByteToWideChar(_lc_codepage,MB_PRECOMPOSED, + buffer, -1, widechar1, 2))) { + _munlock (_LC_CTYPE_LOCK); + return c; + } + + /* convert wide char to uppercase */ + if (!(size=LCMapStringW(_lc_handle[LC_CTYPE], LCMAP_LOWERCASE, + widechar1, size, widechar2, 2))) { + _munlock (_LC_CTYPE_LOCK); + return c; + } + + /* convert wide char back to multibyte */ + if (!(size=WideCharToMultiByte(_lc_codepage,(WC_COMPOSITECHECK|WC_DISCARDNS), + widechar2, size, buffer, 2, NULL, NULL))) { + _munlock (_LC_CTYPE_LOCK); + return c; + } + + _munlock (_LC_CTYPE_LOCK); + + /* construct integer return value */ + if (size == 1) + return ((int)buffer[0]); + else + return ((int)buffer[0] | ((int)buffer[1] << 8)); +#else + return(isupper(c) ? mklower(c) : c); +#endif /* _INTL */ +} diff --git a/private/crt32/convert/toupper.c b/private/crt32/convert/toupper.c new file mode 100644 index 000000000..4dd0e8176 --- /dev/null +++ b/private/crt32/convert/toupper.c @@ -0,0 +1,189 @@ +/*** +*toupper.c - convert character to uppercase +* +* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Defines function versions of _toupper() and toupper(). +* +*Revision History: +* 11-09-84 DFW created +* 12-11-87 JCR Added "_LOAD_DS" to declaration +* 02-23-89 GJF Added function version of _toupper and cleaned up. +* 03-26-89 GJF Migrated to 386 tree +* 03-06-90 GJF Fixed calling type, added #include and +* fixed copyright. +* 09-27-90 GJF New-style function declarators. +* 10-11-91 ETC Locale support for toupper under _INTL switch. +* 12-10-91 ETC Updated nlsapi; added multithread. +* 12-17-92 KRS Updated and optimized for latest NLSAPI. Bug-fixes. +* 01-19-93 CFW Fixed typo. +* 03-25-93 CFW _toupper now defined when _INTL. +* 06-02-93 SRW ignore _INTL if _NTSUBSET_ defined. +* 09-15-93 CFW Change buffer to unsigned char to fix nasty cast bug. +* 01-14-94 SRW if _NTSUBSET_ defined call Rtl functions +* +*******************************************************************************/ + +#ifdef _NTSUBSET_ +#include +#include +#include +#endif +#include +#include +#include +#ifdef _INTL +#include +#include +#include +#endif + +/* remove macro definitions of _toupper() and toupper() + */ +#undef _toupper +#undef toupper + +/* define function-like macro equivalent to _toupper() + */ +#define mkupper(c) ( (c)-'a'+'A' ) + +/*** +*int _toupper(c) - convert character to uppercase +* +*Purpose: +* _toupper() is simply a function version of the macro of the same name. +* +*Entry: +* c - int value of character to be converted +* +*Exit: +* returns int value of uppercase representation of c +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE1 _toupper ( + int c + ) +{ + return(mkupper(c)); +} + + +/*** +*int toupper(c) - convert character to uppercase +* +*Purpose: +* toupper() is simply a function version of the macro of the same name. +* +*Entry: +* c - int value of character to be converted +* +*Exit: +* if c is a lower case letter, returns int value of uppercase +* representation of c. otherwise, it returns c. +* +*Exceptions: +* +*******************************************************************************/ + + +int _CALLTYPE1 toupper ( + int c + ) +{ +#if defined(_INTL) && !defined(_NTSUBSET_) + wchar_t widechar1[2], widechar2[2]; + int size; + unsigned char buffer[3]; + + _mlock (_LC_CTYPE_LOCK); + + if ((_lc_handle[LC_CTYPE] == _CLOCALEHANDLE) && + (_lc_codepage == _CLOCALECP)) { + if (islower(c)) + c = c - ('a' - 'A'); + _munlock (_LC_CTYPE_LOCK); + return c; + } + + /* if checking case of c does not require API call, do it */ + if (c < 256) { + if (!islower(c)) { + _munlock (_LC_CTYPE_LOCK); + return c; + } + } + + /* convert c to wide char */ + if (isleadbyte(c>>8 & 0xff)) + { + buffer[0] = (c>>8 & 0xff); /* put lead-byte at start of str */ + buffer[1] = (unsigned char)c; + buffer[2] = 0; + } + else + { + buffer[0] = (unsigned char)c; + buffer[1] = 0; + } + if (!(size=MultiByteToWideChar(_lc_codepage,MB_PRECOMPOSED, + buffer, -1, widechar1, 2))) { + _munlock (_LC_CTYPE_LOCK); + return c; + } + + /* convert wide char to uppercase */ + if (!(size=LCMapStringW(_lc_handle[LC_CTYPE], LCMAP_UPPERCASE, + widechar1, size, widechar2, 2))) { + _munlock (_LC_CTYPE_LOCK); + return c; + } + + /* convert wide char back to multibyte */ + if (!(size=WideCharToMultiByte(_lc_codepage,(WC_COMPOSITECHECK|WC_DISCARDNS), + widechar2, size, buffer, 2, NULL, NULL))) { + _munlock (_LC_CTYPE_LOCK); + return c; + } + + _munlock (_LC_CTYPE_LOCK); + + /* construct integer return value */ + if (size == 1) + return ((int)buffer[0]); + else + return ((int)buffer[0] | ((int)buffer[1] << 8)); +#else +#ifdef _NTSUBSET_ + { + NTSTATUS Status; + char *s = &c; + WCHAR Unicode; + ULONG UnicodeSize; + ULONG MultiSize; + UCHAR MultiByte[2]; + + Unicode = RtlAnsiCharToUnicodeChar( &s ); + Status = RtlUpcaseUnicodeToMultiByteN( MultiByte, + sizeof( MultiByte ), + &MultiSize, + &Unicode, + sizeof( Unicode ) + ); + if (!NT_SUCCESS( Status )) + return c; + else + if (MultiSize == 1) + return ((int)MultiByte[0]); + else + return ((int)MultiByte[0] | ((int)MultiByte[1] << 8)); + + } +#else + return(islower(c) ? mkupper(c) : c); +#endif +#endif /* _INTL */ +} diff --git a/private/crt32/convert/towlower.c b/private/crt32/convert/towlower.c new file mode 100644 index 000000000..1f4c2abb2 --- /dev/null +++ b/private/crt32/convert/towlower.c @@ -0,0 +1,84 @@ +/*** +*towlower.c - convert wide character to lower case +* +* Copyright (c) 1985-1992, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Defines towlower(). +* +*Revision History: +* 10-11-91 ETC Created. +* 12-10-91 ETC Updated nlsapi; added multithread. +* 04-06-92 KRS Make work without _INTL also. +* 01-19-93 CFW Changed LCMapString to LCMapStringW. +* 06-02-93 SRW ignore _INTL if _NTSUBSET_ defined. +* 06-11-93 CFW Fix error handling bug. +* +*******************************************************************************/ + +#include +#include +#include +#include +#ifdef _INTL +#include +#include +#endif + +/*** +*wchar_t towlower(c) - convert wide character to lower case +* +*Purpose: +* towlower() returns the lowercase equivalent of its argument +* +*Entry: +* c - wchar_t value of character to be converted +* +*Exit: +* if c is an upper case letter, returns wchar_t value of lower case +* representation of c. otherwise, it returns c. +* +*Exceptions: +* +*******************************************************************************/ + +wchar_t _CALLTYPE1 towlower ( + wchar_t c + ) +{ +#if defined(_INTL) && !defined(_NTSUBSET_) + wchar_t widechar; + + if (c == WEOF) + return c; + + _mlock (_LC_CTYPE_LOCK); + + if (_lc_handle[LC_CTYPE] == _CLOCALEHANDLE) { + if (iswupper(c)) + c = c - L'A' + L'a'; + _munlock (_LC_CTYPE_LOCK); + return c; + } + + /* if checking case of c does not require API call, do it */ + if (c < 256) { + if (!iswupper(c)) { + _munlock (_LC_CTYPE_LOCK); + return c; + } + } + + /* convert wide char to lowercase */ + if (LCMapStringW(_lc_handle[LC_CTYPE], LCMAP_LOWERCASE, + (LPCWSTR)&c, 1, (LPWSTR)&widechar, 1) == 0) { + _munlock (_LC_CTYPE_LOCK); + return c; + } + + _munlock (_LC_CTYPE_LOCK); + return widechar; +#else + return (iswupper(c) ? (c + (wchar_t)(L'a' - L'A')) : c); +#endif /* _INTL */ +} diff --git a/private/crt32/convert/towupper.c b/private/crt32/convert/towupper.c new file mode 100644 index 000000000..177da7e07 --- /dev/null +++ b/private/crt32/convert/towupper.c @@ -0,0 +1,94 @@ +/*** +*towupper.c - convert wide character to upper case +* +* Copyright (c) 1985-1992, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Defines towupper(). +* +*Revision History: +* 10-11-91 ETC Created. +* 12-10-91 ETC Updated nlsapi; added multithread. +* 04-06-92 KRS Make work without _INTL also. +* 01-19-93 CFW Changed LCMapString to LCMapStringW. +* 06-02-93 SRW ignore _INTL if _NTSUBSET_ defined. +* 06-11-93 CFW Fix error handling bug. +* 01-14-94 SRW if _NTSUBSET_ defined call Rtl functions +* +*******************************************************************************/ + +#ifdef _NTSUBSET_ +#include +#include +#include +#endif +#include +#include +#include +#include +#ifdef _INTL +#include +#include +#endif + +/*** +*wchar_t towupper(c) - convert wide character to upper case +* +*Purpose: +* towupper() returns the uppercase equivalent of its argument +* +*Entry: +* c - wchar_t value of character to be converted +* +*Exit: +* if c is a lower case letter, returns wchar_t value of upper case +* representation of c. otherwise, it returns c. +* +*Exceptions: +* +*******************************************************************************/ + +wchar_t _CALLTYPE1 towupper ( + wchar_t c + ) +{ +#if defined(_INTL) && !defined(_NTSUBSET_) + wchar_t widechar; + + if (c == WEOF) + return c; + + _mlock (_LC_CTYPE_LOCK); + + if (_lc_handle[LC_CTYPE] == _CLOCALEHANDLE) { + if (iswlower(c)) + c = c - L'a' + L'A'; + _munlock (_LC_CTYPE_LOCK); + return c; + } + + /* if checking case of c does not require API call, do it */ + if (c < 256) { + if (!iswlower(c)) { + _munlock (_LC_CTYPE_LOCK); + return c; + } + } + + /* convert wide char to uppercase */ + if (LCMapStringW(_lc_handle[LC_CTYPE], LCMAP_UPPERCASE, + (LPCWSTR)&c, 1, (LPWSTR)&widechar, 1) == 0) { + _munlock (_LC_CTYPE_LOCK); + return c; + } + + _munlock (_LC_CTYPE_LOCK); + return widechar; +#else +#ifdef _NTSUBSET_ + return RtlUpcaseUnicodeChar( c ); +#else + return (iswlower(c) ? (c - (wchar_t)(L'a' - L'A')) : c); +#endif +#endif /* _INTL */ +} diff --git a/private/crt32/convert/wcstod.c b/private/crt32/convert/wcstod.c new file mode 100644 index 000000000..18db8b193 --- /dev/null +++ b/private/crt32/convert/wcstod.c @@ -0,0 +1,115 @@ +/*** +*wcstod.c - convert wide char string to floating point number +* +* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Convert character string to floating point number +* +*Revision History: +* 06-15-92 KRS Created from strtod.c. +* 11-06-92 KRS Fix bugs in wctomb() loop. +* +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +/*** +*double wcstod(nptr, endptr) - convert wide string to double +* +*Purpose: +* wcstod recognizes an optional string of tabs and spaces, +* then an optional sign, then a string of digits optionally +* containing a decimal point, then an optional e or E followed +* by an optionally signed integer, and converts all this to +* to a floating point number. The first unrecognized +* character ends the string, and is pointed to by endptr. +* +*Entry: +* nptr - pointer to wide string to convert +* +*Exit: +* returns value of wide character string +* wchar_t **endptr - if not NULL, points to character which stopped +* the scan +* +*Exceptions: +* +*******************************************************************************/ + +double _CALLTYPE1 wcstod ( + const wchar_t *nptr, + REG2 wchar_t **endptr + ) +{ + +#ifdef MTHREAD + struct _flt answerstruct; +#endif + + FLT answer; + double tmp; + unsigned int flags; + REG1 wchar_t *ptr = (wchar_t *) nptr; + char * cptr; + int retval, len; + int clen = 0; + + /* scan past leading space/tab characters */ + + while (iswspace(*ptr)) + ptr++; + + cptr = (char *)malloc((wcslen(ptr)+1) * sizeof(wchar_t)); + // UNDONE: check for errors + for (len = 0; ptr[len]; len++) + { + if ((retval = wctomb(cptr+len,ptr[len]))<=0) + break; + clen += retval; + } + cptr[clen++] = '\0'; + + /* let _fltin routine do the rest of the work */ + +#ifdef MTHREAD + /* ok to take address of stack variable here; fltin2 knows to use ss */ + answer = _fltin2( &answerstruct, cptr, clen, 0, 0); +#else + answer = _fltin(cptr, clen, 0, 0); +#endif + + if ( endptr != NULL ) + *endptr = (wchar_t *) ptr + answer->nbytes; + /* UNDONE: assumes no multi-byte chars in string */ + + flags = answer->flags; + if ( flags & (512 | 64)) { + /* no digits found or invalid format: + ANSI says return 0.0, and *endptr = nptr */ + tmp = 0.0; + if ( endptr != NULL ) + *endptr = (wchar_t *) nptr; + } + else if ( flags & (128 | 1) ) { + if ( *ptr == '-' ) + tmp = -HUGE_VAL; /* negative overflow */ + else + tmp = HUGE_VAL; /* positive overflow */ + errno = ERANGE; + } + else if ( flags & 256 ) { + tmp = 0.0; /* underflow */ + errno = ERANGE; + } + else + tmp = answer->dval; + + return(tmp); +} diff --git a/private/crt32/convert/wcstol.c b/private/crt32/convert/wcstol.c new file mode 100644 index 000000000..6d3c3d201 --- /dev/null +++ b/private/crt32/convert/wcstol.c @@ -0,0 +1,215 @@ +/*** +*wcstol.c - Contains C runtimes wcstol and wcstoul +* +* Copyright (c) 1989-1993, Microsoft Corporation. All rights reserved. +* +*Purpose: +* wcstol - convert wchar_t string to long signed integer +* wcstoul - convert wchar_t string to long unsigned integer +* +*Revision History: +* 06-15-92 KRS Module created, based on strtol.c +* 04-21-93 GJF Removed assumption that LONG_MIN == -LONG_MAX. +* 05-10-93 GJF Fixed error check. +* 05-20-93 GJF Nothing like taking ugly code and making prettier... +* and wrong. Fixed bug introduced on 5-10. +* +*******************************************************************************/ + +#include +#include +#include +#include +#include + +/*** +*wcstol, wcstoul(nptr,endptr,ibase) - Convert ascii string to long un/signed +* int. +* +*Purpose: +* Convert an ascii string to a long 32-bit value. The base +* used for the caculations is supplied by the caller. The base +* must be in the range 0, 2-36. If a base of 0 is supplied, the +* ascii string must be examined to determine the base of the +* number: +* (a) First char = '0', second char = 'x' or 'X', +* use base 16. +* (b) First char = '0', use base 8 +* (c) First char in range '1' - '9', use base 10. +* +* If the 'endptr' value is non-NULL, then wcstol/wcstoul places +* a pointer to the terminating character in this value. +* See ANSI standard for details +* +*Entry: +* nptr == NEAR/FAR pointer to the start of string. +* endptr == NEAR/FAR pointer to the end of the string. +* ibase == integer base to use for the calculations. +* +* string format: [whitespace] [sign] [0] [x] [digits/letters] +* +*Exit: +* Good return: +* result +* +* Overflow return: +* wcstol -- LONG_MAX or LONG_MIN +* wcstoul -- ULONG_MAX +* wcstol/wcstoul -- errno == ERANGE +* +* No digits or bad base return: +* 0 +* endptr = nptr* +* +*Exceptions: +* None. +*******************************************************************************/ + +/* flag values */ +#define FL_UNSIGNED 1 /* wcstoul called */ +#define FL_NEG 2 /* negative sign found */ +#define FL_OVERFLOW 4 /* overflow occured */ +#define FL_READDIGIT 8 /* we've read at least one correct digit */ + + +static unsigned long _CRTAPI3 wcstoxl ( + const wchar_t *nptr, + const wchar_t **endptr, + int ibase, + int flags + ) +{ + const wchar_t *p; + wchar_t c; + unsigned long number; + unsigned digval; + unsigned long maxval; + + p = nptr; /* p is our scanning pointer */ + number = 0; /* start with zero */ + + c = *p++; /* read char */ + while (iswspace(c)) + c = *p++; /* skip whitespace */ + + if (c == '-') { + flags |= FL_NEG; /* remember minus sign */ + c = *p++; + } + else if (c == '+') + c = *p++; /* skip sign */ + + if (ibase < 0 || ibase == 1 || ibase > 36) { + /* bad base! */ + if (endptr) + /* store beginning of string in endptr */ + *endptr = nptr; + return 0L; /* return 0 */ + } + else if (ibase == 0) { + /* determine base free-lance, based on first two chars of + string */ + if (c != L'0') + ibase = 10; + else if (*p == L'x' || *p == L'X') + ibase = 16; + else + ibase = 8; + } + + if (ibase == 16) { + /* we might have 0x in front of number; remove if there */ + if (c == L'0' && (*p == L'x' || *p == L'X')) { + ++p; + c = *p++; /* advance past prefix */ + } + } + + /* if our number exceeds this, we will overflow on multiply */ + maxval = ULONG_MAX / ibase; + + + for (;;) { /* exit in middle of loop */ + /* convert c to value */ + if (iswdigit(c)) + digval = c - L'0'; + else if (iswalpha(c)) + digval = towupper(c) - L'A' + 10; + else + break; + if (digval >= (unsigned)ibase) + break; /* exit loop if bad digit found */ + + /* record the fact we have read one digit */ + flags |= FL_READDIGIT; + + /* we now need to compute number = number * base + digval, + but we need to know if overflow occured. This requires + a tricky pre-check. */ + + if (number < maxval || (number == maxval && + (unsigned long)digval <= ULONG_MAX % ibase)) { + /* we won't overflow, go ahead and multiply */ + number = number * ibase + digval; + } + else { + /* we would have overflowed -- set the overflow flag */ + flags |= FL_OVERFLOW; + } + + c = *p++; /* read next digit */ + } + + --p; /* point to place that stopped scan */ + + if (!(flags & FL_READDIGIT)) { + /* no number there; return 0 and point to beginning of + string */ + if (endptr) + /* store beginning of string in endptr later on */ + p = nptr; + number = 0L; /* return 0 */ + } + else if ( (flags & FL_OVERFLOW) || + ( !(flags & FL_UNSIGNED) && + ( ( (flags & FL_NEG) && (number > -LONG_MIN) ) || + ( !(flags & FL_NEG) && (number > LONG_MAX) ) ) ) ) + { + /* overflow or signed overflow occurred */ + errno = ERANGE; + if ( flags & FL_UNSIGNED ) + number = ULONG_MAX; + else if ( flags & FL_NEG ) + number = (unsigned long)(-LONG_MIN); + else + number = LONG_MAX; + } + + if (endptr != NULL) + /* store pointer to char that stopped the scan */ + *endptr = p; + + if (flags & FL_NEG) + /* negate result if there was a neg sign */ + number = (unsigned long)(-(long)number); + + return number; /* done. */ +} + +long _CRTAPI1 wcstol ( + const wchar_t *nptr, + wchar_t **endptr, + int ibase + ) +{ + return (long) wcstoxl(nptr, endptr, ibase, 0); +} + +unsigned long _CRTAPI1 wcstoul ( + const wchar_t *nptr, + wchar_t **endptr, + int ibase + ) +{ + return wcstoxl(nptr, endptr, ibase, FL_UNSIGNED); +} diff --git a/private/crt32/convert/wcstombs.c b/private/crt32/convert/wcstombs.c new file mode 100644 index 000000000..2b7f97194 --- /dev/null +++ b/private/crt32/convert/wcstombs.c @@ -0,0 +1,213 @@ +/*** +*wcstombs.c - Convert wide char string to multibyte char string. +* +* Copyright (c) 1990-1993, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Convert a wide char string into the equivalent multibyte char string. +* +*Revision History: +* 08-24-90 KRS Module created. +* 01-14-91 KRS Added _WINSTATIC for Windows DLL. Fix wctomb() call. +* 03-18-91 KRS Fix check for NUL. +* 03-20-91 KRS Ported from 16-bit tree. +* 10-16-91 ETC Locale support under _INTL switch. +* 12-09-91 ETC Updated nlsapi; added multithread. +* 08-20-92 KRS Activated NLSAPI support. +* 08-22-92 SRW Allow INTL definition to be conditional for building ntcrt.lib +* 09-02-92 SRW Get _INTL definition via ..\crt32.def +* 01-06-93 CFW Added (count < n) to outer loop - avoid bad wctomb calls +* 01-07-93 KRS Major code cleanup. Fix error return, comments. +* 05-03-93 CFW Return pointer == NULL, return size, plus massive cleanup. +* 06-02-93 SRW ignore _INTL if _NTSUBSET_ defined. +* 01-14-94 SRW if _NTSUBSET_ defined call Rtl functions +* +*******************************************************************************/ + +#ifdef _NTSUBSET_ +#include +#include +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*** +*size_t wcstombs() - Convert wide char string to multibyte char string. +* +*Purpose: +* Convert a wide char string into the equivalent multibyte char string, +* according to the LC_CTYPE category of the current locale. +* [ANSI]. +* +* NOTE: Currently, the C libraries support the "C" locale only. +* Non-C locale support now available under _INTL switch. +*Entry: +* char *s = pointer to destination multibyte char string +* const wchar_t *pwc = pointer to source wide character string +* size_t n = maximum number of bytes to store in s +* +*Exit: +* If s != NULL, returns (size_t)-1 (if a wchar cannot be converted) +* Otherwise: Number of bytes modified (<=n), not including +* the terminating NUL, if any. +* +*Exceptions: +* Returns (size_t)-1 if s is NULL or invalid mb character encountered. +* +*******************************************************************************/ + +#ifdef MTHREAD +size_t _CRTAPI1 wcstombs + ( + char *s, + const wchar_t *pwcs, + size_t n + ) +{ + int retval; + + _mlock (_LC_CTYPE_LOCK); + retval = _wcstombs_lk(s, pwcs, n); + _munlock (_LC_CTYPE_LOCK); + return retval; +} +#endif /* MTHREAD */ + +#ifdef MTHREAD +size_t _CRTAPI1 _wcstombs_lk +#else +size_t _CRTAPI1 wcstombs +#endif + ( + char *s, + const wchar_t *pwcs, + size_t n + ) +{ + int i, retval; + size_t count = 0; + char buffer[MB_LEN_MAX]; /* UNDONE: what about MTHREAD ? */ + BOOL defused = 0; + + if (s && n == 0) + return (size_t) 0; + + assert(pwcs != NULL); + + /* if destination string exists, fill it in */ + if (s) + { +#if defined(_INTL) && !defined(_NTSUBSET_) + if (_lc_handle[LC_CTYPE] == _CLOCALEHANDLE && + _lc_codepage == _CLOCALECP) + { +#endif /* _INTL */ +#ifdef _NTSUBSET_ + { + NTSTATUS Status; + + Status = RtlUnicodeToMultiByteN(s, n, (PULONG)&count, (wchar_t *)pwcs, (wcslen(pwcs)+1)*sizeof(WCHAR)); + if (NT_SUCCESS(Status)) + { + return count - 1; /* don't count NUL */ + } else { + errno = EILSEQ; + count = (size_t)-1; + } + } +#else + /* C locale: easy and fast */ + while(count < n) + { + if (*pwcs > 255) /* validate high byte */ + { + errno = EILSEQ; + return (size_t)-1; /* error */ + } + s[count] = (char) *pwcs; + if (*pwcs++ == L'\0') + return count; + count++; + } +#endif + return count; +#if defined(_INTL) && !defined(_NTSUBSET_) + } else { + /* Assume that usually the buffer is large enough */ + if (((count=WideCharToMultiByte(_lc_codepage, + WC_COMPOSITECHECK | WC_SEPCHARS, + pwcs, -1, s, n, NULL, &defused)) != 0) && (!defused)) + return count - 1; /* don't count NUL */ + + if (defused || GetLastError() != ERROR_INSUFFICIENT_BUFFER) + { + errno = EILSEQ; + return (size_t)-1; + } + + /* buffer not large enough, must do char by char */ + while (count < n) + { + if (((retval = WideCharToMultiByte (_lc_codepage, 0, + pwcs, 1, buffer, MB_CUR_MAX, NULL, &defused)) == 0) || defused) + { + errno = EILSEQ; + return (size_t)-1; + } + + if (count + retval > n) + return count; + + for (i = 0; i < retval; i++, count++) /* store character */ + if((s[count] = buffer[i])=='\0') + return count; /* done if NUL */ + pwcs++; + } + return count; + } +#endif /* _INTL */ + } + else { /* s == NULL, get size only, pwcs must be NUL-terminated */ +#if defined(_INTL) && !defined(_NTSUBSET_) + if (_lc_handle[LC_CTYPE] == _CLOCALEHANDLE && + _lc_codepage == _CLOCALECP) +#endif /* _INTL */ +#ifdef _NTSUBSET_ + { + NTSTATUS Status; + + Status = RtlUnicodeToMultiByteSize((PULONG)&count, (wchar_t *)pwcs, (wcslen(pwcs)+1)*sizeof(WCHAR)); + if (NT_SUCCESS(Status)) + { + return count - 1; /* don't count NUL */ + } else { + errno = EILSEQ; + count = (size_t)-1; + } + } +#else + return wcslen(pwcs); +#endif +#if defined(_INTL) && !defined(_NTSUBSET_) + else { + if (((count=WideCharToMultiByte(_lc_codepage, + WC_COMPOSITECHECK | WC_SEPCHARS, + pwcs, -1, NULL, 0, NULL, &defused)) == 0) || (defused)) + { + errno = EILSEQ; + return (size_t)-1; + } + + return count - 1; + } +#endif /* _INTL */ + } +} diff --git a/private/crt32/convert/wctomb.c b/private/crt32/convert/wctomb.c new file mode 100644 index 000000000..5b2fd734c --- /dev/null +++ b/private/crt32/convert/wctomb.c @@ -0,0 +1,136 @@ +/*** +*wctomb.c - Convert wide character to multibyte character. +* +* Copyright (c) 1990-1993, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Convert a wide character into the equivalent multibyte character. +* +*Revision History: +* 03-19-90 KRS Module created. +* 12-20-90 KRS Include ctype.h. +* 01-14-91 KRS Fix argument error: wchar is pass-by-value. +* 03-20-91 KRS Ported from 16-bit tree. +* 07-23-91 KRS Hard-coded for "C" locale to avoid bogus interim #'s. +* 10-15-91 ETC Locale support under _INTL (finally!). +* 12-09-91 ETC Updated nlsapi; added multithread. +* 08-20-92 KRS Activated NLSAPI support. +* 08-22-92 SRW Allow INTL definition to be conditional for building ntcrt.lib +* 09-02-92 SRW Get _INTL definition via ..\crt32.def +* 05-04-93 CFW Kinder, gentler error handling. +* 06-02-93 SRW ignore _INTL if _NTSUBSET_ defined. +* 01-14-94 SRW if _NTSUBSET_ defined call Rtl functions +* +*******************************************************************************/ + +#ifdef _NTSUBSET_ +#include +#include +#include +#endif +#include +#include +#include +#include +#include +#include + +/*** +*int wctomb() - Convert wide character to multibyte character. +* +*Purpose: +* Convert a wide character into the equivalent multi-byte character, +* according to the LC_CTYPE category of the current locale. +* [ANSI]. +* +* NOTE: Currently, the C libraries support the "C" locale only. +* Non-C locale support now available under _INTL switch. +*Entry: +* char *s = pointer to multibyte character +* wchar_t wchar = source wide character +* +*Exit: +* If s = NULL, returns 0, indicating we only use state-independent +* character encodings. +* If s != NULL, returns: +* -1 (if error) or number of bytes comprising +* converted mbc +* +*Exceptions: +* +*******************************************************************************/ + +#ifdef MTHREAD +int _CRTAPI1 wctomb + ( + char *s, + wchar_t wchar + ) +{ + int retval; + + _mlock (_LC_CTYPE_LOCK); + retval = _wctomb_lk(s, wchar); + _munlock (_LC_CTYPE_LOCK); + return retval; +} +#endif /* MTHREAD */ + +#ifdef MTHREAD +int _CRTAPI1 _wctomb_lk +#else +int _CRTAPI1 wctomb +#endif + ( + char *s, + wchar_t wchar + ) +{ + if (!s) + return 0; + +#if defined(_INTL) && !defined(_NTSUBSET_) + if ((_lc_handle[LC_CTYPE] == _CLOCALEHANDLE) && + (_lc_codepage == _CLOCALECP)) + { +#endif /* _INTL */ +#ifdef _NTSUBSET_ + { + NTSTATUS Status; + int size; + + Status = RtlUnicodeToMultiByteN(s, MB_CUR_MAX, (PULONG)&size, &wchar, sizeof( wchar )); + if (!NT_SUCCESS(Status)) + { + errno = EILSEQ; + size = -1; + } + return size; + } +#else + if (wchar>255) /* validate high byte */ + { + errno = EILSEQ; + return -1; + } + + *s = (char) wchar; + return sizeof(char); +#endif +#if defined(_INTL) && !defined(_NTSUBSET_) + } else { + int size; + BOOL defused = 0; + + if (((size=WideCharToMultiByte(_lc_codepage, + WC_COMPOSITECHECK | WC_SEPCHARS, &wchar, 1, + s, MB_CUR_MAX, NULL, &defused)) == 0) || (defused)) + { + errno = EILSEQ; + size = -1; + } + + return size; + } +#endif /* _INTL */ +} diff --git a/private/crt32/convert/wtox.c b/private/crt32/convert/wtox.c new file mode 100644 index 000000000..c151692af --- /dev/null +++ b/private/crt32/convert/wtox.c @@ -0,0 +1,82 @@ +/*** +*wtox.c - _wtoi and _wtol conversion +* +* Copyright (c) 1993, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Converts a wide character string into an int or long. +* +*Revision History: +* 09-10-93 CFW Module created, based on ASCII version. +* +*******************************************************************************/ + +#include +#include + +#define INT_SIZE_LENGTH 20 +#define LONG_SIZE_LENGTH 40 + +/*** +*long _wtol(wchar_t *nptr) - Convert wide string to long +* +*Purpose: +* Converts wide string pointed to by nptr to binary. +* Overflow is not detected. Because of this, we can just use +* atol(). +* +*Entry: +* nptr = ptr to wide string to convert +* +*Exit: +* return long value of the string +* +*Exceptions: +* None - overflow is not detected. +* +*******************************************************************************/ + +long _CRTAPI1 _wtol( + const wchar_t *nptr + ) +{ + char astring[INT_SIZE_LENGTH]; + int defused; + + WideCharToMultiByte (CP_ACP, 0, nptr, -1, + astring, INT_SIZE_LENGTH, NULL, &defused); + + return (atol(astring)); +} + +/*** +*int _wtoi(wchar_t *nptr) - Convert wide string to int +* +*Purpose: +* Converts wide string pointed to by nptr to binary. +* Overflow is not detected. Because of this, we can just use +* atol(). +* +*Entry: +* nptr = ptr to wide string to convert +* +*Exit: +* return int value of the string +* +*Exceptions: +* None - overflow is not detected. +* +*******************************************************************************/ + +int _CRTAPI1 _wtoi( + const wchar_t *nptr + ) +{ + char astring[INT_SIZE_LENGTH]; + int defused; + + WideCharToMultiByte (CP_ACP, 0, nptr, -1, + astring, INT_SIZE_LENGTH, NULL, &defused); + + return ((int)atol(astring)); +} diff --git a/private/crt32/convert/xtoa.c b/private/crt32/convert/xtoa.c new file mode 100644 index 000000000..72fcfb265 --- /dev/null +++ b/private/crt32/convert/xtoa.c @@ -0,0 +1,127 @@ +/*** +*xtoa.c - convert integers/longs to ASCII string +* +* Copyright (c) 1989-1992, Microsoft Corporation. All rights reserved. +* +*Purpose: +* The module has code to convert integers/longs to ASCII strings. See +* +*Revision History: +* 06-06-89 PHG Module created, based on asm version +* 03-06-90 GJF Fixed calling type, added #include and +* fixed copyright. +* 03-23-90 GJF Made xtoa() _CALLTYPE4. +* 09-27-90 GJF New-style function declarators. +* 01-21-91 GJF ANSI naming. +* +*******************************************************************************/ + +#include +#include +#include + +/*** +*char *_itoa, *_ltoa, *_ultoa(val, buf, radix) - convert binary int to ASCII +* string +* +*Purpose: +* Converts an int to a character string. +* +*Entry: +* val - number to be converted (int, long or unsigned long) +* int radix - base to convert into +* char *buf - ptr to buffer to place result +* +*Exit: +* fills in space pointed to by buf with string result +* returns a pointer to this buffer +* +*Exceptions: +* +*******************************************************************************/ + +/* helper routine that does the main job. */ + +static void _CALLTYPE4 xtoa ( + unsigned long val, + char *buf, + unsigned radix, + int is_neg + ) +{ + char *p; /* pointer to traverse string */ + char *firstdig; /* pointer to first digit */ + char temp; /* temp char */ + unsigned digval; /* value of digit */ + + p = buf; + + if (is_neg) { + /* negative, so output '-' and negate */ + *p++ = '-'; + val = (unsigned long)(-(long)val); + } + + firstdig = p; /* save pointer to first digit */ + + do { + digval = (unsigned) (val % radix); + val /= radix; /* get next digit */ + + /* convert to ascii and store */ + if (digval > 9) + *p++ = (char) (digval - 10 + 'a'); /* a letter */ + else + *p++ = (char) (digval + '0'); /* a digit */ + } while (val > 0); + + /* We now have the digit of the number in the buffer, but in reverse + order. Thus we reverse them now. */ + + *p-- = '\0'; /* terminate string; p points to last digit */ + + do { + temp = *p; + *p = *firstdig; + *firstdig = temp; /* swap *p and *firstdig */ + --p; + ++firstdig; /* advance to next two digits */ + } while (firstdig < p); /* repeat until halfway */ +} + + +/* Actual functions just call conversion helper with neg flag set correctly, + and return pointer to buffer. */ + +char * _CALLTYPE1 _itoa ( + int val, + char *buf, + int radix + ) +{ + if (radix == 10 && val < 0) + xtoa((unsigned long)val, buf, radix, 1); + else + xtoa((unsigned long)(unsigned int)val, buf, radix, 0); + return buf; +} + +char * _CALLTYPE1 _ltoa ( + long val, + char *buf, + int radix + ) +{ + xtoa((unsigned long)val, buf, radix, (radix == 10 && val < 0)); + return buf; +} + +char * _CALLTYPE1 _ultoa ( + unsigned long val, + char *buf, + int radix + ) +{ + xtoa(val, buf, radix, 0); + return buf; +} diff --git a/private/crt32/convert/xtow.c b/private/crt32/convert/xtow.c new file mode 100644 index 000000000..2b1c0605a --- /dev/null +++ b/private/crt32/convert/xtow.c @@ -0,0 +1,85 @@ +/*** +*xtow.c - convert integers/longs to wide char string +* +* Copyright (c) 1993, Microsoft Corporation. All rights reserved. +* +*Purpose: +* The module has code to convert integers/longs to wide char strings. +* +*Revision History: +* 09-10-93 CFW Module created, based on ASCII version. +* +*******************************************************************************/ + +#include +#include + +#define INT_SIZE_LENGTH 20 +#define LONG_SIZE_LENGTH 40 + +/*** +*wchar_t *_itow, *_ltow, *_ultow(val, buf, radix) - convert binary int to wide +* char string +* +*Purpose: +* Converts an int to a wide character string. +* +*Entry: +* val - number to be converted (int, long or unsigned long) +* int radix - base to convert into +* wchar_t *buf - ptr to buffer to place result +* +*Exit: +* calls ASCII version to convert, converts ASCII to wide char into buf +* returns a pointer to this buffer +* +*Exceptions: +* +*******************************************************************************/ + +wchar_t * _CRTAPI1 _itow ( + int val, + wchar_t *buf, + int radix + ) +{ + char astring[INT_SIZE_LENGTH]; + + _itoa (val, astring, radix); + MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, astring, -1, + buf, INT_SIZE_LENGTH); + + return (buf); +} + +wchar_t * _CRTAPI1 _ltow ( + long val, + wchar_t *buf, + int radix + ) +{ + char astring[LONG_SIZE_LENGTH]; + + _ltoa (val, astring, radix); + MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, astring, -1, + buf, LONG_SIZE_LENGTH); + + return (buf); +} + +wchar_t * _CRTAPI1 _ultow ( + unsigned long val, + wchar_t *buf, + int radix + ) +{ + char astring[LONG_SIZE_LENGTH]; + + _ultoa (val, astring, radix); + MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, astring, -1, + buf, LONG_SIZE_LENGTH); + + return (buf); +} + + diff --git a/private/crt32/crt32.def b/private/crt32/crt32.def new file mode 100644 index 000000000..43add7b8f --- /dev/null +++ b/private/crt32/crt32.def @@ -0,0 +1,95 @@ +#### +#crt32.def - definitions for the crt32 build +# +# Copyright (c) 1991-1992, Microsoft Corporation. All rights reserved. +# +#Purpose: +# This file is included in the 'sources' files in this tree +# +# Key to CRT32 environment variables: +# +# CRTLIBDEBUG = debug flag (define for debug libs) +# CRTLIBTYPE = [dll/mt/st], dll = dynalink, mt = multithread, +# st = singlethread +# +# [Other variables are used directly by the NT build tool.] +# +#Revision History: +# 09-29-91 JCR File created. +# 10-04-91 JCR Added mt vs st build +# 01-06-92 GJF Added DLL support. Cleaned up a bit. +# 04-16-92 DJM POSIX support. +# 08-28-92 GJF Fixed POSIX support. +# 09-02-92 SRW Removed -D_INTL from all versions until +# Win32 NLS API calls are faster. When that +# happens, add it back to all but Posix version. +# 12-03-92 KRS Added optional _MBCS defines. +# 05-22-93 SRW Compile runtines with no debug info except globals. +# 06-03-93 SRW Okay to allow FPO now, as crt32\startup\mlock.c has +# been fixed to explicitly disable FPO for itself. +# 10-18-93 SRW Disable intrinsics on Alpha +# +################################################################################ + +NTDEBUG= + +NTLEGO=1 + +!IF "$(CRTLIBTYPE)" == "DLL" +TARGETNAMESUFFIX=dll +TARGETTYPE=LIBRARY +MTOPTION=-DMTHREAD -D_MT -DCRTDLL +C_DEFINES1=-D_WIN32_=1 -D_INTL -D_MBCS -D_KANJI +ASM_DEFINES1=-D_WIN32_=1 -D_INTL +INCLUDES=..\h +!ELSE +!IF "$(CRTLIBTYPE)" == "MT" +TARGETNAMESUFFIX=mt +TARGETTYPE=LIBRARY +MTOPTION=-DMTHREAD -D_MT +C_DEFINES1=-D_WIN32_=1 -D_INTL -D_MBCS -D_KANJI +ASM_DEFINES1=-D_WIN32_=1 -D_INTL +INCLUDES=..\h +!ELSE +!IF "$(CRTLIBTYPE)" == "ST" +TARGETNAMESUFFIX= +TARGETTYPE=LIBRARY +MTOPTION= +C_DEFINES1=-D_WIN32_=1 -D_INTL -D_MBCS -D_KANJI +ASM_DEFINES1=-D_WIN32_=1 -D_INTL +INCLUDES=..\h +!ELSE +!IF "$(CRTLIBTYPE)" == "NT" +TARGETNAMESUFFIX=nt +TARGETTYPE=LIBRARY +MTOPTION= +C_DEFINES1=-D_WIN32_=1 -D_NTSUBSET_=1 -D_NTSYSTEM_=1 -D_INTL +ASM_DEFINES1=-D_WIN32_=1 -D_NTSUBSET_=1 -D_NTSYSTEM_=1 -D_INTL +INCLUDES=..\h +!ELSE +!IF "$(CRTLIBTYPE)" == "POSIX" +TARGETNAMESUFFIX=psx +TARGETTYPE=LIBRARY +MTOPTION= +C_DEFINES1=-D_POSIX_=1 -D_CRTHEAP_ -D_INTL -D_MBCS -D_KANJI -D_NTSUBSET_ +ASM_DEFINES1=-D_POSIX_=1 -D_INTL +INCLUDES=$(BASEDIR)\public\sdk\inc\posix;..\h +!ELSE +!ERROR Unsupported Library CRTLIBTYPE: $(CRTLIBTYPE) +!ENDIF +!ENDIF +!ENDIF +!ENDIF +!ENDIF + + +!IF "$(CRTLIBDEBUG)" == "" +C_DEFINES=-DNDEBUG $(C_DEFINES1) $(MTOPTION) $(MBCS_DEFINES) +ASM_DEFINES=$(ASM_DEFINES1) $(MTOPTION) $(MBCS_DEFINES) +!ELSE +C_DEFINES=$(C_DEFINES1) -DDEBUG=1 $(MTOPTION) $(MBCS_DEFINES) +ASM_DEFINES=$(ASM_DEFINES1) -DDEBUG=1 $(MTOPTION) $(MBCS_DEFINES) +!ENDIF + +# Disable intrinsics on Alpha as it will not allow redefinition of intrinsics +ALPHA_OPTIMIZATION=/Ox /Oi- diff --git a/private/crt32/direct/drivemap.c b/private/crt32/direct/drivemap.c new file mode 100644 index 000000000..160eab54c --- /dev/null +++ b/private/crt32/direct/drivemap.c @@ -0,0 +1,39 @@ +/*** +*drivemap.c - _getdrives +* +* Copyright (c) 1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* defines _getdrives() +* +*Revision History: +* 08-22-91 BWM Wrote module. +* +*******************************************************************************/ + +#include +#include +#include + +#if !defined(_WIN32_) +#error ERROR - ONLY WIN32 TARGET SUPPORTED! +#endif + +/*** +*void _getdrivemap(void) - Get bit map of all available drives +* +*Purpose: +* +*Entry: +* +*Exit: +* drive map with drive A in bit 0, B in 1, etc. +* +*Exceptions: +* +*******************************************************************************/ + +unsigned long _CALLTYPE1 _getdrives() +{ + return (GetLogicalDrives()); +} diff --git a/private/crt32/direct/drivfree.c b/private/crt32/direct/drivfree.c new file mode 100644 index 000000000..3ff8b77a5 --- /dev/null +++ b/private/crt32/direct/drivfree.c @@ -0,0 +1,69 @@ +/*** +*drivfree.c - Get the size of a disk +* +* Copyright (c) 1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* This file has _getdiskfree() +* +*Revision History: +* 08-21-91 PHG Module created for Win32 +* 10-24-91 GJF Added LPDWORD casts to make MIPS compiler happy. +* ASSUMES THAT sizeof(unsigned) == sizeof(DWORD). +* +*******************************************************************************/ + +#include +#include +#include + +/*** +*int _getdiskfree(drivenum, diskfree) - get size of a specified disk +* +*Purpose: +* Gets the size of the current or specified disk drive +* +*Entry: +* int drivenum - 0 for current drive, or drive 1-26 +* +*Exit: +* returns 0 if succeeds +* returns system error code on error. +* +*Exceptions: +* +*******************************************************************************/ + +#if !defined(_WIN32_) +#error ERROR - ONLY WIN32 TARGET SUPPORTED! +#endif + +unsigned _CALLTYPE1 _getdiskfree(unsigned uDrive, struct _diskfree_t * pdf) +{ + char szRoot[] = "?:\\"; + char szCur[MAX_PATH]; + + if (uDrive == 0) { + GetCurrentDirectory(MAX_PATH, szCur); + if ((szCur[0] == '\\') && (szCur[1] == '\\')) { + return (ERROR_INVALID_PARAMETER); + } + szRoot[0] = szCur[0]; + } + else if (uDrive > 26) { + return (ERROR_INVALID_PARAMETER); + } + else { + szRoot[0] = (char)uDrive + (char)('A' - 1); + } + + + if (!GetDiskFreeSpace(szRoot, + (LPDWORD)&(pdf->sectors_per_cluster), + (LPDWORD)&(pdf->bytes_per_sector), + (LPDWORD)&(pdf->avail_clusters), + (LPDWORD)&(pdf->total_clusters))) { + return ((int)GetLastError()); + } + return (0); +} diff --git a/private/crt32/direct/findfile.c b/private/crt32/direct/findfile.c new file mode 100644 index 000000000..346c63f78 --- /dev/null +++ b/private/crt32/direct/findfile.c @@ -0,0 +1,224 @@ +/*** +*findfile.c - C find file functions +* +* Copyright (c) 1991-1993, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Defines findfirst(), findnext(), and findclose(). +* +*Revision History: +* 08-21-91 BWM Wrote Win32 versions. +* 09-13-91 BWM Changed handle type to long. +* 08-18-92 SKS Add a call to FileTimeToLocalFileTime +* as a temporary fix until _dtoxtime takes UTC +* 08-26-92 SKS creation and last access time should be same as the +* last write time if ctime/atime are not available. +* 01-08-93 SKS Remove change I made 8-26-92. Previous behavior +* was deemed "by design" and preferable. +* 03-30-93 GJF Replaced reference to _dtoxtime with __gmtotime_t. Also +* made _timet_from_ft a static function. +* +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(_WIN32_) +#error ERROR - ONLY WIN32 TARGET SUPPORTED! +#endif + +static time_t _CRTAPI3 _timet_from_ft(FILETIME * pft); + +/*** +*long findfirst(wildspec, finddata) - Find first matching file +* +*Purpose: +* Finds the first file matching a given wild card filespec and +* returns data about the file. +* +*Entry: +* char * wild - file spec optionally containing wild cards +* +* struct _finddata_t * finddata - structure to receive file data +* +*Exit: +* Good return: +* Unique handle identifying the group of files matching the spec +* +* Error return: +* Returns -1 and errno is set to error value +* +*Exceptions: +* None. +* +*******************************************************************************/ + +long _CRTAPI1 _findfirst(char * szWild, struct _finddata_t * pfd) +{ + WIN32_FIND_DATA wfd; + HANDLE hFile; + DWORD err; + + if ((hFile = FindFirstFile(szWild, &wfd)) == INVALID_HANDLE_VALUE) { + err = GetLastError(); + switch (err) { + case ERROR_NO_MORE_FILES: + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + errno = ENOENT; + break; + + case ERROR_NOT_ENOUGH_MEMORY: + errno = ENOMEM; + break; + + default: + errno = EINVAL; + break; + } + return (-1); + } + + pfd->attrib = (wfd.dwFileAttributes == FILE_ATTRIBUTE_NORMAL) + ? 0 : wfd.dwFileAttributes; + pfd->time_create = _timet_from_ft(&wfd.ftCreationTime); + pfd->time_access = _timet_from_ft(&wfd.ftLastAccessTime); + pfd->time_write = _timet_from_ft(&wfd.ftLastWriteTime); + pfd->size = wfd.nFileSizeLow; + strcpy(pfd->name, wfd.cFileName); + + return ((long)hFile); +} + +/*** +*int _findnext(hfind, finddata) - Find next matching file +* +*Purpose: +* Finds the next file matching a given wild card filespec and +* returns data about the file. +* +*Entry: +* hfind - handle from _findfirst +* +* struct _finddata_t * finddata - structure to receive file data +* +*Exit: +* Good return: +* 0 if file found +* -1 if error or file not found +* errno set +* +*Exceptions: +* None. +* +*******************************************************************************/ + +int _CRTAPI1 _findnext(long hFile, struct _finddata_t * pfd) +{ + WIN32_FIND_DATA wfd; + DWORD err; + + if (!FindNextFile((HANDLE)hFile, &wfd)) { + err = GetLastError(); + switch (err) { + case ERROR_NO_MORE_FILES: + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + errno = ENOENT; + break; + + case ERROR_NOT_ENOUGH_MEMORY: + errno = ENOMEM; + break; + + default: + errno = EINVAL; + break; + } + return (-1); + } + + pfd->attrib = (wfd.dwFileAttributes == FILE_ATTRIBUTE_NORMAL) + ? 0 : wfd.dwFileAttributes; + pfd->time_create = _timet_from_ft(&wfd.ftCreationTime); + pfd->time_access = _timet_from_ft(&wfd.ftLastAccessTime); + pfd->time_write = _timet_from_ft(&wfd.ftLastWriteTime); + pfd->size = wfd.nFileSizeLow; + strcpy(pfd->name, wfd.cFileName); + + return (0); +} + +/*** +*int _findclose(hfind) - Release resources of find +* +*Purpose: +* Releases resources of a group of files found by _findfirst and +* _findnext +* +*Entry: +* hfind - handle from _findfirst +* +*Exit: +* Good return: +* 0 if success +* -1 if fail, errno set +* +*Exceptions: +* None. +* +*******************************************************************************/ + +int _CRTAPI1 _findclose(long hFile) +{ + if (!FindClose((HANDLE)hFile)) { + errno = EINVAL; + return (-1); + } + return (0); +} + +/*** +*time_t _fttotimet(ft) - convert Win32 file time to Xenix time +* +*Purpose: +* converts a Win32 file time value to Xenix time_t +* +*Entry: +* int yr, mo, dy - date +* int hr, mn, sc - time +* +*Exit: +* returns Xenix time value +* +*Exceptions: +* +*******************************************************************************/ + +static time_t _CRTAPI3 _timet_from_ft(FILETIME * pft) +{ + SYSTEMTIME st; + + // 0 FILETIME returns a -1 time_t + + if (!pft->dwLowDateTime && !pft->dwHighDateTime) { + return (-1L); + } + + if (!FileTimeToSystemTime(pft, &st)) { + return (-1L); + } + + return ( __gmtotime_t(st.wYear, + st.wMonth, + st.wDay, + st.wHour, + st.wMinute, + st.wSecond) ); +} diff --git a/private/crt32/direct/makefile b/private/crt32/direct/makefile new file mode 100644 index 000000000..6ee4f43fa --- /dev/null +++ b/private/crt32/direct/makefile @@ -0,0 +1,6 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/crt32/direct/peekpoke.c b/private/crt32/direct/peekpoke.c new file mode 100644 index 000000000..f00ffb6c2 --- /dev/null +++ b/private/crt32/direct/peekpoke.c @@ -0,0 +1,95 @@ +/*** +*peekpoke.c - Peek or poke absolute memory. +* +* Copyright (c) 1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* defines _peek(), _poke(), and _getvideoaddress(). +* +*Revision History: +* 08-21-91 BWM Wrote module. +* +*******************************************************************************/ + +#include +#include +#include +#include + +#if !defined(_DOSX32_) +#error ERROR - ONLY DOSX32 TARGET SUPPORTED! +#endif + +/*** +*void _peek(src, dst, size) - Peek at memory +* +*Purpose: +* +*Entry: +* _absaddr_t src - address to be peeked +* void * dst - pointer to location to receive copy +* unsigned short size - number of bytes to peek +* +*Exit: +* None +* +*Exceptions: +* +*******************************************************************************/ + +void _CALLTYPE1 _peek(_absaddr_t aaSrc, void * pvDst, unsigned short cb) +{ + PeekAddress((WORD)((aaSrc & 0xffff0000) >> 16), + (WORD) (aaSrc & 0x0000ffff), + pvDst, cb); +} + +/*** +*void _poke(src, dst, size) - Poke into memory +* +*Purpose: +* +*Entry: +* void * src - pointer to data to be poked +* _absaddr_t dst - address where data will be poked +* unsigned short size - number of bytes to poke +* +*Exit: +* None +* +*Exceptions: +* +*******************************************************************************/ + +void _CALLTYPE1 _poke(void * pvSrc, _absaddr_t aaDst, unsigned short cb) +{ + PokeAddress(pvSrc, + (WORD)((aaDst & 0xffff0000) >> 16), + (WORD) (aaDst & 0x0000ffff), cb); +} + + +/*** +*void _getvideoaddr(region) - Get flat address of video memory +* +*Purpose: +* +*Entry: +* unsigned region - screen memory region: +* +* _ADDR_NO_PALETTE_GRAPHICS - Absolute B800:0000 +* _ADDR_PALETTE_GRAPHICS - Absolute A000:0000 +* _ADDR_COLOR_TEXT - Absolute B800:0000 +* _ADDR_MONO_TEXT - Absolute B000:0000 +* +*Exit: +* None +* +*Exceptions: +* +*******************************************************************************/ + +void * _CALLTYPE1 _getvideoaddr(unsigned dwRegion) +{ + return (GetVideoAddress(dwRegion)); +} diff --git a/private/crt32/direct/seterrm.c b/private/crt32/direct/seterrm.c new file mode 100644 index 000000000..838854db0 --- /dev/null +++ b/private/crt32/direct/seterrm.c @@ -0,0 +1,63 @@ +/*** +*seterrm.c - Set mode for handling critical errors +* +* Copyright (c) 1991, Microsoft Corporation. All rights reserved +* +*Purpose: +* Defines signal() and raise(). +* +*Revision History: +* 08-21-92 BWM Wrote for Win32. +* +*******************************************************************************/ + +#include +#include + +/*** +*void _seterrormode(mode) - set the critical error mode +* +*Purpose: +* +*Entry: +* int mode - error mode: +* +* 0 means system displays a prompt asking user how to +* respond to the error. Choices differ depending on the +* error but may include Abort, Retry, Ignore, and Fail. +* +* 1 means the call system call causing the error will fail +* and return an error indicating the cause. +* +*Exit: +* none +* +*Exceptions: +* +*******************************************************************************/ + +void _CALLTYPE1 _seterrormode(int mode) +{ +#ifdef _CRUISER_ + + if (mode == 1) { + DOSERROR(1); + else if (mode == 0) { + DOSERROR(0); + } + +#else /* ndef _CRUISER_ */ + +#ifdef _WIN32_ + + SetErrorMode(mode); + +#else /* ndef _WIN32_ */ + +#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED! + +#endif /* _WIN32_ */ + +#endif /* _CRUISER_ */ + +} diff --git a/private/crt32/direct/slbeep.c b/private/crt32/direct/slbeep.c new file mode 100644 index 000000000..a549e4a5e --- /dev/null +++ b/private/crt32/direct/slbeep.c @@ -0,0 +1,105 @@ +/*** +*slbeep.c - Sleep and beep +* +* Copyright (c) 1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* defines _sleep() and _beep() +* +*Revision History: +* 08-22-91 BWM Wrote module. +* +*******************************************************************************/ + +#include +#include +#include + +/*** +*void _sleep(duration) - Length of sleep +* +*Purpose: +* +*Entry: +* unsigned long duration - length of sleep in milliseconds or +* one of the following special values: +* +* _SLEEP_MINIMUM - Sends a yield message without any delay +* _SLEEP_FOREVER - Never return +* +*Exit: +* None +* +*Exceptions: +* +*******************************************************************************/ + +void _CALLTYPE1 _sleep(unsigned long dwDuration) +{ +#ifdef _CRUISER_ + + if (dwDuration == _SLEEP_FOREVER) { + while(1) { + DOSSLEEP(dwDuration); + } + } + else { + DOSSLEEP(dwDuration); + } + +#else /* ndef _CRUISER_ */ + +#ifdef _WIN32_ + + if (dwDuration == 0) { + dwDuration++; + } + Sleep(dwDuration); + +#else /* ndef _WIN32_ */ + +#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED! + +#endif /* _WIN32_ */ + +#endif /* _CRUISER_ */ + +} + +/*** +*void _beep(frequency, duration) - Length of sleep +* +*Purpose: +* +*Entry: +* unsigned frequency - frequency in hertz +* unsigned duration - length of beep in milliseconds +* +*Exit: +* None +* +*Exceptions: +* +*******************************************************************************/ + +void _CALLTYPE1 _beep(unsigned dwFrequency, unsigned dwDuration) +{ +#ifdef _CRUISER_ + + DOSBEEP(dwFrequency, dwDuration); + +#else /* ndef _CRUISER_ */ + +#ifdef _WIN32_ + + Beep(dwFrequency, dwDuration); + +#else /* ndef _WIN32_ */ + +#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED! + +#endif /* _WIN32_ */ + +#endif /* _CRUISER_ */ + +} diff --git a/private/crt32/direct/sources b/private/crt32/direct/sources new file mode 100644 index 000000000..2fe65d1d1 --- /dev/null +++ b/private/crt32/direct/sources @@ -0,0 +1,40 @@ +!IF 0 + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + This file specifies the target component being built and the list of + sources files needed to build that component. Also specifies optional + compiler switches and libraries that are unique for the component being + built. + + +Author: + + Steve Wood (stevewo) 12-Apr-1990 + jeffrob 29-sep-1990, use crt32.def + +NOTE: Commented description of this file is in \nt\bak\bin\sources.tpl + +!ENDIF + +MAJORCOMP=crt +MINORCOMP=direct + +TARGETNAME=direct +TARGETPATH=..\obj +TARGETTYPE=LIBRARY +386_STDCALL=0 + +!INCLUDE ..\crt32.def + +SOURCES=drivemap.c \ + drivfree.c \ + findfile.c \ + seterrm.c \ + slbeep.c diff --git a/private/crt32/dirs b/private/crt32/dirs new file mode 100644 index 000000000..57fcf957c --- /dev/null +++ b/private/crt32/dirs @@ -0,0 +1,43 @@ +!IF 0 + +Copyright (c) 1989 - 1992, Microsoft Corporation. All rights reserved. + +Module Name: + + dirs. + +Abstract: + + This file specifies the subdirectories of the current directory that + contain component makefiles. + + +Author: + + Steve Wood (stevewo) 17-Apr-1990 + KarlSi 15-Jun-1992 Added iostream. + +NOTE: Commented description of this file is in \nt\bak\bin\dirs.tpl + +!ENDIF + +DIRS=convert \ + misc \ + startup \ + stdio \ + string + +OPTIONAL_DIRS=iostream \ + linkopts \ + time \ + winheap \ + dllstuff \ + direct \ + dos \ + exec \ + hack \ + heap \ + lowio \ + small \ + helper \ + mbstring diff --git a/private/crt32/dllstuff/cinitexe.c b/private/crt32/dllstuff/cinitexe.c new file mode 100644 index 000000000..ac7c875af --- /dev/null +++ b/private/crt32/dllstuff/cinitexe.c @@ -0,0 +1,92 @@ +/*** +*cinitexe.asm - C Run-Time Startup Initialization for WIN32 +* +* Copyright (c) 1992-1994, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Do C++ initialization segment declarations for the EXE in CRT DLL +* model +* +*Notes: +* The C++ initializers will exist in the user EXE's data segment +* so the special segments to contain them must be in the user EXE. +* +*Revision History: +* 03-19-92 SKS Module created (based on CRT0INIT.ASM) +* 08-06-92 SKS Revised to use new section names and macros +* 04-12-93 CFW Added xia..xiz initializers. +* 10-20-93 SKS Add .DiRECTiVE section for MIPS, too! +* 10-28-93 GJF Rewritten in C +* 10-28-94 SKS Add user32.lib as a default library +* 02-27-95 CFW Remove user32.lib as a default library +* +*******************************************************************************/ + +#ifdef _WIN32 + +#ifdef _MSC_VER + +#include +#include + +#pragma data_seg(".CRT$XCA") +_PVFV __xc_a[] = { NULL }; + +#pragma data_seg(".CRT$XCZ") +_PVFV __xc_z[] = { NULL }; + +#pragma data_seg(".drectve") +static char __drectve_win32lib[] = + "-merge:.CRT=.rdata"; +#pragma data_seg() /* reset */ + +#endif /* _MSC_VER */ + +#else /* _WIN32 */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * pointers to initialization functions + */ + +#pragma data_seg(".CRT$XIA") +PFV __xi_a = 0; /* C initializers */ + +#pragma data_seg(".CRT$XIZ") +PFV __xi_z = 0; + +#pragma data_seg(".CRT$XCA") +PFV __xc_a = 0; /* C++ initializers */ + +#pragma data_seg(".CRT$XCZ") +PFV __xc_z = 0; + +#pragma data_seg(".CRT$XPA") +PFV __xp_a = 0; /* C pre-terminators */ + +#pragma data_seg(".CRT$XPZ") +PFV __xp_z = 0; + +#pragma data_seg(".CRT$XTA") +PFV __xt_a = 0; /* C terminators */ + +#pragma data_seg(".CRT$XTZ") +PFV __xt_z = 0; + +#pragma data_seg() + + +#endif diff --git a/private/crt32/dllstuff/crtdll.c b/private/crt32/dllstuff/crtdll.c new file mode 100644 index 000000000..a03adc428 --- /dev/null +++ b/private/crt32/dllstuff/crtdll.c @@ -0,0 +1,376 @@ +#ifdef CRTDLL +/*** +*crtdll.c - CRT initialization for a DLL using the CRTDLL model of C run-time +* +* Copyright (c) 1991-1994, Microsoft Corporation. All rights reserved. +* +*Purpose: +* This module contains the initialization entry point for the C run-time +* stub in this DLL. All C run-time code is located in the C Run-Time +* Library DLL "CRTDLL.DLL", except for a little bit of start-up code in +* the EXE, and this code in each DLL. This code is necessary to invoke +* the C++ constructors for the C++ code in this DLL. +* +* This entry point should either be specified as the DLL initialization +* entry point, or else it must be called by the DLL initialization entry +* point of the DLL with the same arguments that the entry point receives. +* +*Revision History: +* 05-19-92 SKS Initial version +* 08-01-92 SRW winxcpt.h replaced bu excpt.h which is included by oscalls.h +* 09-16-92 SKS Prepare for C8 C++ for MIPS by calling C++ constructors +* 09-29-92 SKS _CRT_DLL must be a WINAPI function! +* 05-11-93 SKS Add _DllMainCRTStartup as an alternative to _CRT_INIT +* 06-05-93 SRW Pin CRTDLL.DLL in memory once loaded. +* 06-07-93 GJF Added __proc_attached flag. +* 06-07-93 GJF Backed out SteveWo's change of 06-05 and put it into +* crtlib.c +* 06-08-93 SKS Clean up failure handling in _CRT_INIT +* 07-16-93 SRW ALPHA Merge +* 12-02-93 SKS Add atexit/_onexit support. These routines must be +* defined here so that DLL's that are linked with +* CRTDLL.LIB will get these versions (suitable for DLLs), +* not the versions of atexit/_onexit from CRTDLL.DLL, +* which are only suitable for an EXE file. +* 07-18-94 GJF Moved over Win32s support from VC 2.0 tree. +* +*******************************************************************************/ + +/* + * SPECIAL BUILD MACRO! Note that crtexe.c (and crtexew.c) is linked in with + * the client's code. It does not go into crtdll.dll! Therefore, it must be + * built under the _DLL switch (like user code) and CRTDLL must be undefined. + */ +#undef CRTDLL +#define _DLL + +#include +#include +#include +#include +#define _DECL_DLLMAIN /* enable prototypes for DllMain and _CRT_INIT */ +#include + +/* + * routine in DLL to do initialization (in this case, C++ constructors) + */ +typedef void (_CALLTYPE1 *PF)(void); + +extern void _CALLTYPE4 _initterm(PF *, PF *); + +/* + * pointers to initialization sections + */ +extern PF __xc_a[], __xc_z[]; /* C++ initializers */ + +/* + * Flag identifying the host as Win32s or not-Win32s. + */ +int __win32sflag = 0; + +static int onexitflag = 0; + +/* + * flag set iff _CRTDLL_INIT was called with DLL_PROCESS_ATTACH + */ +static int __proc_attached = 0; + +/* + * Pointers to beginning and end of the table of function pointers manipulated + * by _onexit()/atexit(). The atexit/_onexit code is shared for both EXE's and + * DLL's but different behavior is required. These values are initialized to + * 0 by default and will be set to point to a malloc-ed memory block to mark + * this module as an DLL. + */ + +PF *__onexitbegin; +PF *__onexitend; + + +/* + * User routine DllMain is called on all notifications + */ + +extern BOOL WINAPI DllMain( + HANDLE hDllHandle, + DWORD dwReason, + LPVOID lpreserved + ) ; + +/*** +*BOOL WINAPI _CRT_INIT(hDllHandle, dwReason, lpreserved) - C++ DLL initialization. +* +*Purpose: +* This routine does the C runtime initialization for a DLL using CRTDLL. +* It may be specified as the entry point for the DLL, or it may be +* called by the routine that is the DLL entry point. +* +* On DLL_PROCESS_ATTACH, the C++ constructors for the DLL will be called. +* +* On DLL_PROCESS_DETACH, the C++ destructors and _onexit/atexit routines +* will be called. +* +*Entry: +* +*Exit: +* +*******************************************************************************/ + +BOOL WINAPI _CRT_INIT( + HANDLE hDllHandle, + DWORD dwReason, + LPVOID lpreserved + ) +{ + unsigned osver; + + /* + * First, set the __proc_attached flag + */ + if ( dwReason == DLL_PROCESS_ATTACH ) + __proc_attached++; + else if ( dwReason == DLL_PROCESS_DETACH ) { + if ( __proc_attached > 0 ) + __proc_attached--; + else + /* + * no prior process attach. just return failure. + */ + return FALSE; + } + + /* + * Get the host version (on first call). + */ + if ( __win32sflag == 0 ) { + osver = GetVersion(); + if ( ((osver & 0x00ff) == 3) && ((osver >> 31) & 1) ) + __win32sflag++; + else + __win32sflag--; + } + + + /* + * do C++ constructors (initializers) specific to this DLL + */ + + if ( dwReason == DLL_PROCESS_ATTACH ) { + + /* + * If the host is Win32s, create the onexit table and do C++ + * constructors only for the first connecting process. + */ + if ( (__win32sflag < 0) || (__proc_attached == 1) ) { + + if ( __win32sflag < 0 ) { + /* + * not Win32s! just malloc the table. + */ + if ( (__onexitbegin = (PF *)malloc(32 * + sizeof(PF))) == NULL ) + /* + * cannot allocate minimal required + * size. generate failure to load DLL + */ + return FALSE; + } + else if ( __proc_attached == 1 ) { + if ( (__onexitbegin = + (PF *)GlobalAlloc( GMEM_FIXED | + GMEM_SHARE, 32 * sizeof(PF) )) == + NULL ) + /* + * cannot allocate minimal required + * size. generate failure to load DLL + */ + return FALSE; + } + + *(__onexitbegin) = (PF) NULL; + + __onexitend = __onexitbegin; + + /* + * Invoke C++ constructors + */ + _initterm(__xc_a,__xc_z); + + } + } + else if ( dwReason == DLL_PROCESS_DETACH ) { + + if ( (__win32sflag < 0) || (__proc_attached == 0) ) + { + /* + * Any basic clean-up code that goes here must be + * duplicated below in _DllMainCRTStartup for the + * case where the user's DllMain() routine fails on a + * Process Attach notification. This does not include + * calling user C++ destructors, etc. + */ + + /* + * do _onexit/atexit() terminators + * (if there are any) + * + * These terminators MUST be executed in + * reverse order (LIFO)! + * + * NOTE: + * This code assumes that __onexitbegin + * points to the first valid onexit() + * entry and that __onexitend points + * past the last valid entry. If + * __onexitbegin == __onexitend, the + * table is empty and there are no + * routines to call. + */ + + if (__onexitbegin) { + PF * pfend = __onexitend; + + while ( -- pfend >= __onexitbegin ) + /* + * if current table entry is not + * NULL, call thru it. + */ + if ( *pfend != NULL ) + (**pfend)(); + + /* + * just in case Win32s doesn't clean up after + * us (any bets?), free the block holding + * onexit table + */ + if ( __win32sflag > 0 ) + GlobalFree( (HGLOBAL)__onexitbegin ); + else + free(__onexitbegin); + } + } + } + + return TRUE; +} + +/*** +*BOOL WINAPI _DllMainCRTStartup(hDllHandle, dwReason, lpreserved) - C++ DLL initialization. +* +*Purpose: +* This is an alternative entry point for DLL's linked with the C run-time +* libs, rather than using _CRT_INIT. The user should specify this routine +* as the DLL entry point, and define his/her own routine DllMain to get +* notifications in his/her code. CRT initialization/termination will be +* done before or after calling DllMain, as appropriate. +* +*Entry: +* +*Exit: +* +*******************************************************************************/ +BOOL WINAPI _DllMainCRTStartup( + HANDLE hDllHandle, + DWORD dwReason, + LPVOID lpreserved + ) +{ + BOOL retcode = TRUE; + + /* + * If this is a process detach notification, check that there has + * been a prior process attach notification. + */ + if ( (dwReason == DLL_PROCESS_DETACH) && (__proc_attached == 0) ) + return FALSE; + + if ( dwReason == DLL_PROCESS_ATTACH || dwReason == DLL_THREAD_ATTACH ) + retcode = _CRT_INIT(hDllHandle, dwReason, lpreserved); + + if ( retcode ) + retcode = DllMain(hDllHandle, dwReason, lpreserved); + + /* + * If _CRT_INIT successfully handles a Process Attach notification + * but the user's DllMain routine returns failure, we need to do + * clean-up of the C run-time similar to what _CRT_INIT does on a + * Process Detach Notification. + */ + + if ( dwReason == DLL_PROCESS_DETACH || dwReason == DLL_THREAD_DETACH ) + { + if ( _CRT_INIT(hDllHandle, dwReason, lpreserved) == FALSE ) + retcode = FALSE ; + } + + return retcode ; +} + +/*** +*_onexit, atexit - calls to DLL versioons of _onexit & atexit in CRTDLL.DLL +* +*Purpose: +* A DLL linked with CRTDLL.LIB must not call the standard _onexit or +* atexit exported from CRTDLL.DLL, but an EXE linked with CRTDLL.LIB +* will call the standard versions of those two routines. Since the +* names are exported from CRTDLL.DLL, we must define them here for DLLs. +* All DLLs linked with CRTDLL.LIB must pull in this startup object. +* +*Entry: +* Same as the regular versions of _onexit, atexit. +* +*Exit: +* Same as the regular versions of _onexit, atexit. +* +*Exceptions: +* +*******************************************************************************/ + +extern _onexit_t _CALLTYPE1 __dllonexit(_onexit_t, PF **, PF **); + +_onexit_t _CALLTYPE1 _onexit ( + _onexit_t func + ) +{ + unsigned osver; + _onexit_t retval; + + /* + * Get the host version (on first call). + */ + if ( __win32sflag == 0 ) { + osver = GetVersion(); + if ( ((osver & 0x00ff) == 3) && ((osver >> 31) & 1) ) + __win32sflag++; + else + __win32sflag--; + } + + /* + * If we are running in Win32s, test and set the flag used to + * serialize access. Note that we assume no process switch can take + * place between a successful test of the flag and the setting of + * the flag. + */ + if ( __win32sflag > 0 ) { + while ( onexitflag > 0 ) + Sleep(0); + onexitflag++; + } + + retval = __dllonexit(func, &__onexitbegin, &__onexitend); + + if ( __win32sflag > 0 ) + onexitflag--; + + return retval; +} + +int _CALLTYPE1 atexit ( + PF func + ) +{ + return (_onexit((_onexit_t)func) == NULL) ? -1 : 0; +} + +#endif /* CRTDLL */ diff --git a/private/crt32/dllstuff/crtexe.c b/private/crt32/dllstuff/crtexe.c new file mode 100644 index 000000000..fbaa86fff --- /dev/null +++ b/private/crt32/dllstuff/crtexe.c @@ -0,0 +1,215 @@ +#ifdef CRTDLL +/*** +*crtexe.c - Initialization for client EXE using CRT DLL (Win32, Dosx32) +* +* Copyright (c) 1991-1993, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Set up call to client's main() or WinMain(). +* +*Revision History: +* 08-12-91 GJF Module created. +* 01-05-92 GJF Substantially revised +* 01-17-92 GJF Restored Stevewo's scheme for unhandled exceptions. +* 01-29-92 GJF Added support for linked-in options (equivalents of +* binmode.obj, commode.obj and setargv.obj). +* 04-17-92 SKS Add call to _initterm() to do C++ constructors (I386) +* 08-01-92 SRW winxcpt.h replaced bu excpt.h which is included by oscalls.h +* 09-16-92 SKS Prepare for C8 C++ for MIPS by calling C++ constructors +* 04-26-93 GJF Made lpszCommandLine (unsigned char *) to deal with +* chars > 127 in the command line. +* 04-27-93 GJF Removed support for _RT_STACK, _RT_INTDIV, +* _RT_INVALDISP and _RT_NONCONT. +* 05-14-93 GJF Added support for quoted program names. +* 07-16-93 SRW ALPHA Merge +* 12-07-93 GJF MS C++ front-end now used on Alpha +* 05-24-94 SRW Fix call to WinMain to match one in ..\startup\crt0.c +* +*******************************************************************************/ + +/* + * SPECIAL BUILD MACRO! Note that crtexe.c (and crtexew.c) is linked in with + * the client's code. It does not go into crtdll.dll! Therefore, it must be + * built under the _DLL switch (like user code) and CRTDLL must be undefined. + */ +#undef CRTDLL +#define _DLL + +#include +#include +#include +#include +#include + +#undef _fmode /* undefine these so that we can reference the */ +#undef _commode /* local version as well as the DLL variables */ + +extern int _CRTVAR1 _fmode; /* must match the definition in */ +extern int _commode; /* must match the definition in */ + +static int _dowildcard = 0; /* passed to __GetMainArgs() */ + +/* + * routine in DLL to do initialization (in this case, C++ constructors) + */ +typedef void (_CALLTYPE1 *PF)(void); + +extern void _CALLTYPE4 _initterm(PF *, PF *); + +/* + * pointers to initialization sections + */ +extern PF __xc_a[], __xc_z[]; /* C++ initializers */ + +/*** +*void mainCRTStartup(void) +* +*Purpose: +* This routine does the C runtime initialization, calls main(), and +* then exits. It never returns. +* +*Entry: +* +*Exit: +* +*******************************************************************************/ + +#ifdef _WINMAIN_ +void WinMainCRTStartup( +#else +void mainCRTStartup( +#endif + void + ) +{ + int argc; /* three standard arguments to main */ + char **argv; + char **envp; + + int mainret; + +#ifdef _WINMAIN_ + unsigned char *lpszCommandLine; + STARTUPINFOA StartupInfo; +#endif + + /* + * Propogate the _fmode and _commode variables to the DLL + */ + + *_fmode_dll = _fmode; + *_commode_dll = _commode; + + /* + * Call _setargv(), which will call the __setargv() in this module + * if SETARGV.OBJ is linked with the EXE. If SETARGV.OBJ is not + * linked with the EXE, a _dummy setargv() will be called. + */ + + _setargv(); + + /* + * Get the arguments for the call to main. Note this must be done + * explicitly, rather than as part of the dll's initialization, to + * implement optional expansion of wild card chars in filename args + */ + __GetMainArgs(&argc, &argv, &envp, _dowildcard); + + /* + * do C++ constructors (initializers) specific to this EXE + */ + _initterm( __xc_a, __xc_z ); + + try { +#ifdef _WINMAIN_ + /* + * Skip past program name (first token in command line). + * Check for and handle quoted program name. + */ + lpszCommandLine = (unsigned char *)_acmdln; + + if ( *lpszCommandLine == '\"' ) { + /* + * Scan, and skip over, subsequent characters until + * another double-quote or a null is encountered. + */ + while ( *++lpszCommandLine && (*lpszCommandLine + != '\"') ); + /* + * If we stopped on a double-quote (usual case), skip + * over it. + */ + if ( *lpszCommandLine == '\"' ) + lpszCommandLine++; + } + else { + while (*lpszCommandLine > ' ') + lpszCommandLine++; + } + + /* + * Skip past any white space preceeding the second token. + */ + while (*lpszCommandLine && (*lpszCommandLine <= ' ')) { + lpszCommandLine++; + } + + StartupInfo.dwFlags = 0; + GetStartupInfoA( &StartupInfo ); + + mainret = WinMain( GetModuleHandle(NULL), + NULL, + lpszCommandLine, + StartupInfo.dwFlags & STARTF_USESHOWWINDOW + ? StartupInfo.wShowWindow + : SW_SHOWDEFAULT + ); +#else + mainret = main(argc, argv, envp); +#endif + exit(mainret); + } + except ( _XcptFilter(GetExceptionCode(), GetExceptionInformation()) ) + { + /* + * Should never reach here + */ + _exit( GetExceptionCode() ); + + } /* end of try - except */ + +} + +/*** +*__setargv - dummy version (for wildcard expansion) for CRTDLL.DLL model only +* +*Purpose: +* If the EXE that is linked with CRTDLL.LIB is linked explicitly with +* SETARGV.OBJ, the call to _setargv() in the C Run-Time start-up code +* (above) will call this routine, instead of calling a dummy version of +* _setargv() which will do nothing. This will set to one the static +* variable which is passed to __GetMainArgs(), thus enabling wildcard +* expansion of the command line arguments. +* +* In the statically-linked C Run-Time models, _setargv() and __setargv() +* are the actual routines that do the work, but this code exists in +* CRTDLL.DLL and so some tricks have to be played to make the same +* SETARGV.OBJ work for EXE's linked with both LIBC.LIB and CRTDLL.LIB. +* +*Entry: +* The static variable _dowildcard is zero (presumably). +* +*Exit: +* The static variable _dowildcard is set to one, meaning that the +* routine __GetMainArgs() in CRTDLL.DLL *will* do wildcard expansion on +* the command line arguments. (The default behavior is that it won't.) +* +*Exceptions: +* +*******************************************************************************/ + +void _CALLTYPE1 __setargv ( void ) +{ + _dowildcard = 1; +} +#endif /* CRTDLL */ diff --git a/private/crt32/dllstuff/crtexew.c b/private/crt32/dllstuff/crtexew.c new file mode 100644 index 000000000..276fae13a --- /dev/null +++ b/private/crt32/dllstuff/crtexew.c @@ -0,0 +1,4 @@ +#ifdef CRTDLL +#define _WINMAIN_ +#include "crtexe.c" +#endif /* CRTDLL */ diff --git a/private/crt32/dllstuff/crtlib.c b/private/crt32/dllstuff/crtlib.c new file mode 100644 index 000000000..8a813c580 --- /dev/null +++ b/private/crt32/dllstuff/crtlib.c @@ -0,0 +1,258 @@ +#ifdef CRTDLL +/*** +*crtlib.c - CRT DLL initialization and termination routine (Win32, Dosx32) +* +* Copyright (c) 1991-1993, Microsoft Corporation. All rights reserved. +* +*Purpose: +* This module contains initialization entry point for the CRT DLL in +* Win32 and Dosx32 environments. It also contains some of the supporting +* initialization and termination code. +* +*Revision History: +* 08-12-91 GJF Module created. Sort of. +* 01-17-92 GJF Return exception code value for RTEs corresponding +* to exceptions. +* 01-29-92 GJF Support for wildcard expansion in filenames on the +* command line. +* 02-14-92 GJF Moved file inheritance stuff to ioinit.c. Call to +* inherit() is replace by call to _ioinit(). +* 08-26-92 SKS Add _osver, _winver, _winmajor, _winminor +* 09-04-92 GJF Replaced _CALLTYPE3 with WINAPI. +* 09-30-92 SRW Call _heap_init before _mtinit +* 10-19-92 SKS Add "dowildcard" parameter to GetMainArgs() +* Prepend a second "_" to name since it is internal-only +* 04-16-93 SKS Change call to _mtdeletelocks to _mtterm. _mtterm +* calls _mtdeletelocks and also frees up the TLS index. +* 04-27-93 GJF Removed support for _RT_STACK, _RT_INTDIV, +* _RT_INVALDISP and _RT_NONCONT. +* 05-11-93 SKS Change _CRTDLL_INIT to fail loading on failure to +* initialize/clean up, rather than calling _amsg_exit(). +* 06-03-93 GJF Added __proc_attached flag. +* 06-07-93 GJF Incorporated SteveWo's code to call LoadLibrary, from +* crtdll.c. +* 12-14-93 SKS Add _freeptd(), which frees up the per-thread data +* maintained by the C run-time library. +* +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * flag set iff _CRTDLL_INIT was called with DLL_PROCESS_ATTACH + */ +static int __proc_attached = 0; + +/* + * command line, environment, and a few other globals + */ +char *_acmdln; /* points to command line */ +char *_aenvptr; /* points to environment block */ + +void (_CALLTYPE1 * _aexit_rtn)(int) = _exit; /* RT message return procedure */ + +static void _CALLTYPE4 inherit(void); /* local function */ + + +/*** +*void __GetMainArgs(pargc, pargv, penvp, dowildcard) - get values for args to main() +* +*Purpose: +* This function invokes the command line parsing and copies the args +* to main back through the passsed pointers. The reason for doing +* this here, rather than having _CRTDLL_INIT do the work and exporting +* the __argc and __argv, is to support the linked-in option to have +* wildcard characters in filename arguments expanded. +* +*Entry: +* int *pargc - pointer to argc +* char ***pargv - pointer to argv +* char ***penvp - pointer to envp +* int dowildcard - flag (true means expand wildcards in cmd line) +* +*Exit: +* No return value. Values for the arguments to main() are copied through +* the passed pointers. +* +*******************************************************************************/ + + +void _CALLTYPE1 __GetMainArgs ( + int *pargc, + char ***pargv, + char ***penvp, + int dowildcard) +{ + if ( dowildcard ) + __setargv(); /* do wildcard expansion after parsing args */ + else + _setargv(); /* NO wildcard expansion; just parse args */ + + *pargc = __argc; + *pargv = __argv; + *penvp = _environ; +} + + +/*** +*BOOL _CRTDLL_INIT(hDllHandle, dwReason, lpreserved) - C DLL initialization. +* +*Purpose: +* This routine does the C runtime initialization. +* +*Entry: +* +*Exit: +* +*******************************************************************************/ + +BOOL WINAPI _CRTDLL_INIT( + HANDLE hDllHandle, + DWORD dwReason, + LPVOID lpreserved + ) +{ + char szDllName[ MAX_PATH ]; + + if ( dwReason == DLL_PROCESS_ATTACH ) { + + /* + * Increment flag indicating process attach notification + * has been received. + */ + __proc_attached++; + + /* + * Pin ourselves in memory since we dont clean up if we + * unload. + */ + if ( !GetModuleFileName( hDllHandle, + szDllName, + sizeof(szDllName)) + ) + { + strcpy(szDllName, "CRTDLL"); + } + LoadLibrary(szDllName); + } + else if ( dwReason == DLL_PROCESS_DETACH ) { + /* + * if this is a process detach notification, make sure there + * has been a prior process attach notification. + */ + if ( __proc_attached > 0 ) + __proc_attached--; + else + /* no prior process attach, just return */ + return FALSE; + } + else if ( dwReason == DLL_THREAD_DETACH ) + { + _freeptd(NULL); /* free up per-thread CRT data */ + } + + + /* + * Only do initialization when a client process attaches to + * the DLL. + */ + if ( dwReason != DLL_PROCESS_ATTACH ) { + /* + * if a client process is detaching, make sure minimal + * runtime termination is performed and clean up our + * 'locks' (i.e., delete critical sections). + */ + if ( dwReason == DLL_PROCESS_DETACH ) { + + if ( _C_Termination_Done == FALSE ) + _c_exit(); +#ifdef MTHREAD + _mtterm(); /* free TLS index, call _mtdeletelocks() */ +#endif + } + + return TRUE; + } + + _acmdln = (char *)GetCommandLine(); + _aenvptr = (char *)GetEnvironmentStrings(); + + /* + * Get the full Win32 version + */ + _osversion = /* OBSOLETE */ + _osver = GetVersion(); + + _winminor = (_osver >> 8) & 0x00FF ; + _winmajor = _osver & 0x00FF ; + _winver = (_winmajor << 8) + _winminor; + _osver = (_osver >> 16) & 0x00FFFF ; + + /* --------- The following block is OBSOLETE --------- */ + + /* + * unpack base version info + */ + _baseversion = (_osversion & 0xFFFF0000) >> 16; + _baseminor = _baseversion & 0x00FF; + _basemajor = (_baseversion & 0xFF00) >> 8; + + /* + * unpack top-level version info (Windows version) + */ + _osversion &= 0x0000FFFF; + _osmajor = _osversion & 0x00FF; + _osminor = (_osversion & 0xFF00) >> 8; + + /* --------- The preceding block is OBSOLETE --------- */ + + _heap_init(); /* initialize heap */ +#ifdef MTHREAD + if(!_mtinit()) /* initialize multi-thread */ + return FALSE; /* fail DLL load on failure */ +#endif + _ioinit(); /* inherit file info */ + _setenvp(); /* get environ info */ + + _cinit(); /* do C data initialize */ + + return TRUE; +} + +/*** +*_amsg_exit(rterrnum) - Fast exit fatal errors +* +*Purpose: +* Exit the program with error code of 255 and appropriate error +* message. +* +*Entry: +* int rterrnum - error message number (amsg_exit only). +* +*Exit: +* Calls exit() (for integer divide-by-0) or _exit() indirectly +* through _aexit_rtn [amsg_exit]. +* For multi-thread: calls _exit() function +* +*Exceptions: +* +*******************************************************************************/ + +void _CALLTYPE1 _amsg_exit ( + int rterrnum + ) +{ + _FF_MSGBANNER(); /* write run-time error banner */ + _NMSG_WRITE(rterrnum); /* write message */ + + _aexit_rtn(255); /* normally _exit(255) */ +} +#endif /* CRTDLL */ diff --git a/private/crt32/dllstuff/dllargv.c b/private/crt32/dllstuff/dllargv.c new file mode 100644 index 000000000..9b6875a00 --- /dev/null +++ b/private/crt32/dllstuff/dllargv.c @@ -0,0 +1,49 @@ +#ifndef _POSIX_ +#ifdef CRTDLL +/*** +*dllargv.c - Dummy _setargv() routine for use with C Run-Time as a DLL (CRTDLL) +* +* Copyright (c) 1992, Microsoft Corporation. All rights reserved. +* +*Purpose: +* This object goes into CRTDLL.LIB, which is linked with user programs +* to use CRTDLL.DLL for C run-time library functions. If the user +* program links explicitly with SETARGV.OBJ, this object will not be +* linked in, and the _setargv() that does get called with set the flag +* that will enable wildcard expansion. If SETARGV.OBJ is not linked +* into the EXE, this object will get called by the CRT start-up stub +* and the flag to enable wildcard expansion will not be set. +* +*Revision History: +* 10-19-92 SKS Initial version +* +*******************************************************************************/ + +#include +#include + +/*** +*_setargv - dummy version for CRTDLL.DLL model only +* +*Purpose: +* This routine gets called by the C Run-Time start-up code in CRTEXE.C +* which gets linked into an EXE file linked with CRTDLL.LIB. It does +* nothing, but if the user links the EXE with SETARGV.OBJ, this routine +* will not get called but instead __setargv() will be called. (In the +* CRTDLL model, it will set the variable that is passed to _GetMainArgs +* and enable wildcard expansion in the command line arguments.) +* +*Entry: +* +*Exit: +* +*Exceptions: +* +*******************************************************************************/ + +void _CALLTYPE1 _setargv ( void ) +{ + /* NOTHING */ +} +#endif /* !_POSIX_ */ +#endif /* CRTDLL */ diff --git a/private/crt32/dllstuff/i386/dllsupp.asm b/private/crt32/dllstuff/i386/dllsupp.asm new file mode 100644 index 000000000..33ae13262 --- /dev/null +++ b/private/crt32/dllstuff/i386/dllsupp.asm @@ -0,0 +1,39 @@ + page ,132 + title dllsupp - defines some public constants +;*** +;dllsupp.asm - Definitions of public constants +; +; Copyright (c) 1992, Microsoft Corporation. All rights reserved. +; +;Purpose: +; Provides definitions for public constants (absolutes) that are +; 'normally' defined in objects in the C library, but must be defined +; here for clients of crtdll.dll. These constants are: +; +; _except_list +; _fltused +; _ldused +; +;Revision History: +; 01-23-92 GJF Module created. +; +;******************************************************************************* + +.xlist +include cruntime.inc +include except.inc +.list + +; offset, with respect to FS, of pointer to currently active exception handler. +; referenced by compiler generated code for SEH and by _setjmp(). + + public _except_list +_except_list equ 0 + + public _fltused +_fltused equ 9876h + + public _ldused +_ldused equ 9876h + + end diff --git a/private/crt32/dllstuff/makefile b/private/crt32/dllstuff/makefile new file mode 100644 index 000000000..6ee4f43fa --- /dev/null +++ b/private/crt32/dllstuff/makefile @@ -0,0 +1,6 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/crt32/dllstuff/sources b/private/crt32/dllstuff/sources new file mode 100644 index 000000000..7ea3dcdfa --- /dev/null +++ b/private/crt32/dllstuff/sources @@ -0,0 +1,44 @@ +!IF 0 + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + This file specifies the target component being built and the list of + sources files needed to build that component. Also specifies optional + compiler switches and libraries that are unique for the component being + built. + + +Author: + + Steve Wood (stevewo) 12-Apr-1990 + jeffrob 29-sep-1990, use crt32.def + +NOTE: Commented description of this file is in \nt\bak\bin\sources.tpl + +!ENDIF + +MAJORCOMP=crt +MINORCOMP=dllstuff + +TARGETNAME=dllstuff +TARGETPATH=..\obj +TARGETTYPE=LIBRARY +386_STDCALL=0 + +!INCLUDE ..\crt32.def + +SOURCES=dllargv.c \ + cinitexe.c \ + crtexe.c \ + crtexew.c \ + crtdll.c \ + crtlib.c + +i386_SOURCES=i386\dllsupp.asm + diff --git a/private/crt32/dos/access.c b/private/crt32/dos/access.c new file mode 100644 index 000000000..3dc318d22 --- /dev/null +++ b/private/crt32/dos/access.c @@ -0,0 +1,116 @@ +/*** +*access.c - OS/2 access function +* +* Copyright (c) 1989-1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* This file has the _access() function which checks on file accessability. +* +*Revision History: +* 06-06-89 PHG Module created, based on asm version +* 11-10-89 JCR Replaced DOS32QUERYFILEMODE with DOS32QUERYPATHINFO +* 03-07-90 GJF Made calling type _CALLTYPE2 (for now), added #include +* , fixed copyright and fixed compiler +* warnings. Also, cleaned up the formatting a bit. +* 03-30-90 GJF Now _CALLTYPE1. +* 07-24-90 SBM Removed '32' from API names +* 09-27-90 GJF New-style function declarator. +* 12-04-90 SRW Changed to include instead of +* 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals. +* 01-16-91 GJF ANSI naming. +* 04-09-91 PNT Added _MAC_ conditional +* +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +/*** +*int _access(path, amode) - check whether file can be accessed under mode +* +*Purpose: +* Checks to see if the specified file exists and can be accessed +* in the given mode. +* +*Entry: +* char *path - pathname +* int amode - access mode +* (0 = exist only, 2 = write, 4 = read, 6 = read/write) +* +*Exit: +* returns 0 if file has given mode +* returns -1 and sets errno if file does not have given mode or +* does not exist +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE1 _access ( + const char *path, + int amode + ) +{ +#ifdef _CRUISER_ + FILESTATUS fs; + ULONG dosretval; + + /* ask OS/2 about the file mode */ + if (dosretval = DOSQUERYPATHINFO((char *)path, 1, &fs, sizeof(fs))) { + /* error occured -- map error code and return */ + _dosmaperr(dosretval); + return -1; + } + + /* no error; see if returned premission settings OK */ + if (fs.attrFile & FILE_READONLY + +#else /* ndef _CRUISER_ */ + +#ifdef _WIN32_ + DWORD attr; + + attr = GetFileAttributes((LPSTR)path); + if (attr == 0xffffffff) { + /* error occured -- map error code and return */ + _dosmaperr(GetLastError()); + return -1; + } + + /* no error; see if returned premission settings OK */ + if (attr & FILE_ATTRIBUTE_READONLY + +#else /* ndef _WIN32_ */ + +#ifdef _MAC_ + + TBD(); + + if (0 + +#else /* ndef _MAC_ */ + +#error ERROR - ONLY CRUISER, WIN32, OR MAC TARGET SUPPORTED! + +#endif /* _MAC_ */ + +#endif /* _WIN32_ */ + +#endif /* _CRUISER_ */ + + && (amode & 2)) { + /* no write permission on file, return error */ + errno = EACCES; + _doserrno = E_access; + return -1; + } + else + /* file exists and has requested permission setting */ + return 0; + +} diff --git a/private/crt32/dos/chdir.c b/private/crt32/dos/chdir.c new file mode 100644 index 000000000..2d4429d73 --- /dev/null +++ b/private/crt32/dos/chdir.c @@ -0,0 +1,138 @@ +/*** +*chdir.c - OS/2 change directory +* +* Copyright (c) 1989-1992, Microsoft Corporation. All rights reserved. +* +*Purpose: +* This file has the _chdir() function - change current directory. +* +*Revision History: +* 06-06-89 PHG Module created, based on asm version +* 03-07-90 GJF Made calling type _CALLTYPE2 (for now), added #include +* , fixed copyright and fixed compiler +* warnings. Also, cleaned up the formatting a bit. +* 03-30-90 GJF Now _CALLTYPE1. +* 07-24-90 SBM Removed '32' from API names +* 09-27-90 GJF New-style function declarator. +* 12-04-90 SRW Changed to include instead of +* 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals. +* 01-16-91 GJF ANSI naming. +* 05-19-92 GJF Revised to support the 'current directory' environment +* variables of Win32/NT. +* +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include + +/*** +*int _chdir(path) - change current directory +* +*Purpose: +* Changes the current working directory to that given in path. +* +*Entry: +* char *path - directory to change to +* +*Exit: +* returns 0 if successful, +* returns -1 and sets errno if unsuccessful +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE1 _chdir ( + const char *path + ) +{ +#ifdef _CRUISER_ + + ULONG dosretval; + + /* call OS/2 to set current directory */ + dosretval = DOSSETCURRENTDIR((char *)path, 0); + + if (dosretval) { + /* error occured -- map error code and return */ + _dosmaperr(dosretval); + return -1; + } + + return 0; + +#else /* ndef _CRUISER_ */ + +#ifdef _WIN32_ + + + char *envcurdir; + char dirtmp[4]; + unsigned dirlen; + + _mlock(_ENV_LOCK); + + if ( SetCurrentDirectory((LPSTR)path) ) { + + /* + * Try to update the environment variable that specifies the + * current directory for the drive which is the current drive. + * To do this, get the full current directory, build the + * environment variable string and call _putenv(). If an error + * occurs, just return to the caller. + * + * The current directory should have the form of the example + * below: + * + * D:\nt\private\mytests + * + * so that the environment variable should be of the form: + * + * =D:=D:\nt\private\mytests + * + */ + if ( (dirlen = GetCurrentDirectory(0L, dirtmp)) && + ((envcurdir = malloc(dirlen + 5)) != NULL) ) { + + if ( GetCurrentDirectory(dirlen, &envcurdir[4])&& + (envcurdir[5] == ':') ) { + /* + * The current directory string has been + * copied into &envcurdir[3]. Prepend the + * special environment variable name and the + * '='. + */ + envcurdir[0] = envcurdir[3] = '='; + envcurdir[1] = envcurdir[4]; + envcurdir[2] = ':'; + if ( _putenv_lk(envcurdir) ) + free(envcurdir); + } + else + free(envcurdir); + + } + + _munlock(_ENV_LOCK); + return 0; + } + else { + _dosmaperr(GetLastError()); + _munlock(_ENV_LOCK); + return -1; + } + + +#else /* ndef _WIN32_ */ + +#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED! + +#endif /* _WIN32_ */ + +#endif /* _CRUISER_ */ + +} diff --git a/private/crt32/dos/chmod.c b/private/crt32/dos/chmod.c new file mode 100644 index 000000000..8ab9137fe --- /dev/null +++ b/private/crt32/dos/chmod.c @@ -0,0 +1,121 @@ +/*** +*chmod.c - OS/2 change file attributes +* +* Copyright (c) 1989-1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Defines _chmod() - change file attributes +* +*Revision History: +* 06-06-89 PHG Module created, based on asm version +* 11-10-89 JCR Replaced DOS32QUERYFILEMODE with DOS32QUERYPATHINFO +* 03-07-90 GJF Made calling type _CALLTYPE2 (for now), added #include +* , fixed copyright and fixed compiler +* warnings. Also, cleaned up the formatting a bit. +* 03-30-90 GJF Now _CALLTYPE1. +* 07-24-90 SBM Removed '32' from API names +* 09-27-90 GJF New-style function declarator. +* 12-04-90 SRW Changed to include instead of +* 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals. +* 01-16-91 GJF ANSI naming. +* +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include + +/*** +*int _chmod(path, mode) - change file mode +* +*Purpose: +* Changes file mode permission setting to that specified in +* mode. The only XENIX mode bit supported is user write. +* +*Entry: +* char *path - file name +* int mode - mode to change to +* +*Exit: +* returns 0 if successful +* returns -1 and sets errno if not successful +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE1 _chmod ( + const char *path, + int mode + ) +{ +#ifdef _CRUISER_ + ULONG dosretval; + FILESTATUS fs; + + /* query OS/2 for file attribute */ + if (dosretval = DOSQUERYPATHINFO((char *)path, 1, &fs, sizeof(fs))) { + /* error occured -- map error code and return */ + _dosmaperr(dosretval); + return -1; + } + + if (mode & _S_IWRITE) { + /* clear read only bit */ + fs.attrFile &= ~FILE_READONLY; + } + else { + /* set read only bit */ + fs.attrFile |= FILE_READONLY; + } + + /* set new attribute */ + if (dosretval = DOSSETPATHINFO((char *)path, 1, &fs, sizeof(fs),0)) { + /* error occured -- map error code and return */ + _dosmaperr(dosretval); + return -1; + } + +#else /* ndef _CRUISER_ */ + +#ifdef _WIN32_ + DWORD attr; + + attr = GetFileAttributes((LPSTR)path); + if (attr == 0xffffffff) { + /* error occured -- map error code and return */ + _dosmaperr(GetLastError()); + return -1; + } + + if (mode & _S_IWRITE) { + /* clear read only bit */ + attr &= ~FILE_ATTRIBUTE_READONLY; + } + else { + /* set read only bit */ + attr |= FILE_ATTRIBUTE_READONLY; + } + + /* set new attribute */ + if (!SetFileAttributes((LPSTR)path, attr)) { + /* error occured -- map error code and return */ + _dosmaperr(GetLastError()); + return -1; + } + +#else /* ndef _WIN32_ */ + +#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED! + +#endif /* _WIN32_ */ + +#endif /* _CRUISER_ */ + + + + return 0; +} diff --git a/private/crt32/dos/dosmap.c b/private/crt32/dos/dosmap.c new file mode 100644 index 000000000..c84e399eb --- /dev/null +++ b/private/crt32/dos/dosmap.c @@ -0,0 +1,252 @@ +/*** +*dosmap.c - Maps OS errors to errno values +* +* Copyright (c) 1989-1993, Microsoft Corporation. All rights reserved. +* +*Purpose: +* _dosmaperr: Maps OS errors to errno values +* +*Revision History: +* 06-06-89 PHG Module created, based on asm version +* 06-16-89 PHG Changed name to _dosmaperr +* 08-22-89 JCR ERROR_INVALID_DRIVE (15) now maps to ENOENT not EXDEV +* 03-07-90 GJF Made calling type _CALLTYPE1, added #include +* and fixed copyright. Also, cleaned up the +* formatting a bit. +* 09-27-90 GJF New-style function declarator. +* 12-04-90 SRW Changed to include instead of +* 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals. +* 04-26-91 SRW Added ERROR_LOCK_VIOLATION translation to EACCES +* 08-15-91 GJF Multi-thread support for Win32. +* 03-31-92 GJF Added more error codes (Win32 only) and removed OS/2 +* specific nomenclature. +* 07-29-92 GJF Added ERROR_FILE_EXISTS to table for Win32. It gets +* mapped it to EEXIST. +* 09-14-92 SRW Added ERROR_BAD_PATHNAME table for Win32. It gets +* mapped it to ENOENT. +* 10-02-92 GJF Map ERROR_INVALID_PARAMETER to EINVAL (rather than +* EACCES). Added ERROR_NOT_LOCKED and mapped it to +* EACCES. Added ERROR_DIR_NOT_EMPTY and mapped it to +* ENOTEMPTY. +* 02-16-93 GJF Changed for new _getptd(). +* +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include + +/* This is the error table that defines the mapping between OS/2 and + System V error values */ + +struct errentry { + unsigned char oscode; /* OS return value */ + unsigned char errnocode; /* System V error code */ +}; + +#ifdef _CRUISER_ + +static struct errentry errtable[] = { + { ERROR_INVALID_FUNCTION, EINVAL }, /* 1 */ + { ERROR_FILE_NOT_FOUND, ENOENT }, /* 2 */ + { ERROR_PATH_NOT_FOUND, ENOENT }, /* 3 */ + { ERROR_TOO_MANY_OPEN_FILES, EMFILE }, /* 4 */ + { ERROR_ACCESS_DENIED, EACCES }, /* 5 */ + { ERROR_INVALID_HANDLE, EBADF }, /* 6 */ + { ERROR_ARENA_TRASHED, ENOMEM }, /* 7 */ + { ERROR_NOT_ENOUGH_MEMORY, ENOMEM }, /* 8 */ + { ERROR_INVALID_BLOCK, ENOMEM }, /* 9 */ + { ERROR_BAD_ENVIRONMENT, E2BIG }, /* 10 */ + { ERROR_BAD_FORMAT, ENOEXEC }, /* 11 */ + { ERROR_INVALID_ACCESS, EINVAL }, /* 12 */ + { ERROR_INVALID_DATA, EINVAL }, /* 13 */ + { ERROR_INVALID_DRIVE, ENOENT }, /* 15 */ + { ERROR_CURRENT_DIRECTORY, EACCES }, /* 16 */ + { ERROR_NOT_SAME_DEVICE, EXDEV }, /* 17 */ + { ERROR_NO_MORE_FILES, ENOENT }, /* 18 */ + { ERROR_LOCK_VIOLATION, EACCES }, /* 33 */ + { ERROR_BAD_NETPATH, ENOENT }, /* 53 */ + { ERROR_NETWORK_ACCESS_DENIED, EACCES }, /* 65 */ + { ERROR_BAD_NET_NAME, ENOENT }, /* 67 */ + { ERROR_CANNOT_MAKE, EACCES }, /* 82 */ + { ERROR_FAIL_I24, EACCES }, /* 83 */ + { ERROR_INVALID_PARAMETER, EINVAL }, /* 87 */ + { ERROR_NO_PROC_SLOTS, EAGAIN }, /* 89 */ + { ERROR_DRIVE_LOCKED, EACCES }, /* 108 */ + { ERROR_BROKEN_PIPE, EPIPE }, /* 109 */ + { ERROR_DISK_FULL, ENOSPC }, /* 112 */ + { ERROR_INVALID_TARGET_HANDLE, EBADF }, /* 114 */ + { ERROR_INVALID_HANDLE, EINVAL }, /* 124 */ + { ERROR_WAIT_NO_CHILDREN, ECHILD }, /* 128 */ + { ERROR_CHILD_NOT_COMPLETE, ECHILD }, /* 129 */ + { ERROR_DIRECT_ACCESS_HANDLE, EBADF }, /* 130 */ + { ERROR_SEEK_ON_DEVICE, EACCES }, /* 132 */ + { ERROR_MAX_THRDS_REACHED, EAGAIN }, /* 164 */ + { ERROR_FILENAME_EXCED_RANGE, ENOENT }, /* 206 */ + { ERROR_NESTING_NOT_ALLOWED, EAGAIN } /* 215 */ +}; + +#else /* ndef _CRUISER_ */ + +#ifdef _WIN32_ + +static struct errentry errtable[] = { + { ERROR_INVALID_FUNCTION, EINVAL }, /* 1 */ + { ERROR_FILE_NOT_FOUND, ENOENT }, /* 2 */ + { ERROR_PATH_NOT_FOUND, ENOENT }, /* 3 */ + { ERROR_TOO_MANY_OPEN_FILES, EMFILE }, /* 4 */ + { ERROR_ACCESS_DENIED, EACCES }, /* 5 */ + { ERROR_INVALID_HANDLE, EBADF }, /* 6 */ + { ERROR_ARENA_TRASHED, ENOMEM }, /* 7 */ + { ERROR_NOT_ENOUGH_MEMORY, ENOMEM }, /* 8 */ + { ERROR_INVALID_BLOCK, ENOMEM }, /* 9 */ + { ERROR_BAD_ENVIRONMENT, E2BIG }, /* 10 */ + { ERROR_BAD_FORMAT, ENOEXEC }, /* 11 */ + { ERROR_INVALID_ACCESS, EINVAL }, /* 12 */ + { ERROR_INVALID_DATA, EINVAL }, /* 13 */ + { ERROR_INVALID_DRIVE, ENOENT }, /* 15 */ + { ERROR_CURRENT_DIRECTORY, EACCES }, /* 16 */ + { ERROR_NOT_SAME_DEVICE, EXDEV }, /* 17 */ + { ERROR_NO_MORE_FILES, ENOENT }, /* 18 */ + { ERROR_LOCK_VIOLATION, EACCES }, /* 33 */ + { ERROR_BAD_NETPATH, ENOENT }, /* 53 */ + { ERROR_NETWORK_ACCESS_DENIED, EACCES }, /* 65 */ + { ERROR_BAD_NET_NAME, ENOENT }, /* 67 */ + { ERROR_FILE_EXISTS, EEXIST }, /* 80 */ + { ERROR_CANNOT_MAKE, EACCES }, /* 82 */ + { ERROR_FAIL_I24, EACCES }, /* 83 */ + { ERROR_INVALID_PARAMETER, EINVAL }, /* 87 */ + { ERROR_NO_PROC_SLOTS, EAGAIN }, /* 89 */ + { ERROR_DRIVE_LOCKED, EACCES }, /* 108 */ + { ERROR_BROKEN_PIPE, EPIPE }, /* 109 */ + { ERROR_DISK_FULL, ENOSPC }, /* 112 */ + { ERROR_INVALID_TARGET_HANDLE, EBADF }, /* 114 */ + { ERROR_INVALID_HANDLE, EINVAL }, /* 124 */ + { ERROR_WAIT_NO_CHILDREN, ECHILD }, /* 128 */ + { ERROR_CHILD_NOT_COMPLETE, ECHILD }, /* 129 */ + { ERROR_DIRECT_ACCESS_HANDLE, EBADF }, /* 130 */ + { ERROR_NEGATIVE_SEEK, EINVAL }, /* 131 */ + { ERROR_SEEK_ON_DEVICE, EACCES }, /* 132 */ + { ERROR_DIR_NOT_EMPTY, ENOTEMPTY }, /* 145 */ + { ERROR_NOT_LOCKED, EACCES }, /* 158 */ + { ERROR_BAD_PATHNAME, ENOENT }, /* 161 */ + { ERROR_MAX_THRDS_REACHED, EAGAIN }, /* 164 */ + { ERROR_LOCK_FAILED, EACCES }, /* 167 */ + { ERROR_ALREADY_EXISTS, EEXIST }, /* 183 */ + { ERROR_FILENAME_EXCED_RANGE, ENOENT }, /* 206 */ + { ERROR_NESTING_NOT_ALLOWED, EAGAIN } /* 215 */ +}; + +#else /* ndef _WIN32 */ + +#error ERROR - ONLY CRUISER, WIN32, OR MAC TARGET SUPPORTED! + +#endif /* _WIN32_ */ + +#endif /* _CRUISER_ */ + +/* size of the table */ +#define ERRTABLESIZE (sizeof(errtable)/sizeof(errtable[0])) + +/* The following two constants must be the minimum and maximum + values in the (contiguous) range of Exec Failure errors. */ +#define MIN_EXEC_ERROR ERROR_INVALID_STARTING_CODESEG +#define MAX_EXEC_ERROR ERROR_INFLOOP_IN_RELOC_CHAIN + +/* These are the low and high value in the range of errors that are + access violations */ +#define MIN_EACCES_RANGE ERROR_WRITE_PROTECT +#define MAX_EACCES_RANGE ERROR_SHARING_BUFFER_EXCEEDED + + +/*** +*void _dosmaperr(ULONG oserrno) - Map function number +* +*Purpose: +* This function takes an OS error number, and maps it to the +* corresponding errno value (based on UNIX System V values). The +* OS error number is stored in _doserrno (and the mapped value is +* stored in errno) +* +*Entry: +* ULONG os2errno = OS error value +* +*Exit: +* sets _doserrno and errno. +* +*Exceptions: +* +*******************************************************************************/ + +void _CRTAPI1 _dosmaperr ( + ULONG oserrno + ) +{ + int i; + + _doserrno = oserrno; /* set _doserrno */ + + /* check the table for the OS error code */ + for (i = 0; i < ERRTABLESIZE; ++i) { + if (oserrno == errtable[i].oscode) { + errno = errtable[i].errnocode; + return; + } + } + + /* The error code wasn't in the table. We check for a range of */ + /* EACCES errors or exec failure errors (ENOEXEC). Otherwise */ + /* EINVAL is returned. */ + + if (oserrno >= MIN_EACCES_RANGE && oserrno <= MAX_EACCES_RANGE) + errno = EACCES; + else if (oserrno >= MIN_EXEC_ERROR && oserrno <= MAX_EXEC_ERROR) + errno = ENOEXEC; + else + errno = EINVAL; +} + +#ifdef MTHREAD + +#ifdef _WIN32_ + +/*** +*int * _errno() - return pointer to thread's errno +*unsigned long * __doserrno() - return pointer to thread's _doserrno +* +*Purpose: +* _errno() returns a pointer to the _terrno field in the current +* thread's _tiddata structure. +* __doserrno returns a pointer to the _tdoserrno field in the current +* thread's _tiddata structure +* +*Entry: +* None. +* +*Exit: +* See above. +* +*Exceptions: +* +*******************************************************************************/ + +int * _CRTAPI1 _errno( + void + ) +{ + return ( &(_getptd()->_terrno) ); +} + +unsigned long * _CRTAPI1 __doserrno( + void + ) +{ + return ( &(_getptd()->_tdoserrno) ); +} + +#endif /* _WIN32_ */ + +#endif /* MTHREAD */ diff --git a/private/crt32/dos/drive.c b/private/crt32/dos/drive.c new file mode 100644 index 000000000..02b85263b --- /dev/null +++ b/private/crt32/dos/drive.c @@ -0,0 +1,208 @@ +/*** +*drive.c - get and change current drive +* +* Copyright (c) 1989-1995, Microsoft Corporation. All rights reserved. +* +*Purpose: +* This file has the _getdrive() and _chdrive() functions +* +*Revision History: +* 06-06-89 PHG Module created, based on asm version +* 03-07-90 GJF Made calling type _CALLTYPE1, added #include +* and fixed copyright. Also, cleaned up +* the formatting a bit. +* 07-24-90 SBM Removed '32' from API names +* 09-27-90 GJF New-style function declarators. +* 12-04-90 SRW Changed to include instead of +* 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals. +* 05-10-91 GJF Fixed off-by-1 error in Win32 version and updated the +* function descriptions a bit [_WIN32_]. +* 05-19-92 GJF Revised to use the 'current directory' environment +* variables of Win32/NT. +* 06-09-92 GJF Use _putenv instead of Win32 API call. Also, defer +* adding env var until after the successful call to +* change the dir/drive. +* 04-06-93 SKS Replace _CRTAPI* with __cdecl +* 11-24-93 CFW Rip out Cruiser. +* 11-24-93 CFW No longer store current drive in CRT env strings. +* 02-08-95 JWM Spliced _WIN32 & Mac versions. +* +*******************************************************************************/ + +#ifdef _WIN32 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/*** +*int _getdrive() - get current drive (1=A:, 2=B:, etc.) +* +*Purpose: +* Returns the current disk drive +* +*Entry: +* No parameters. +* +*Exit: +* returns 1 for A:, 2 for B:, 3 for C:, etc. +* returns 0 if current drive cannot be determined. +* +*Exceptions: +* +*******************************************************************************/ + +int __cdecl _getdrive ( + void + ) +{ + ULONG drivenum; + UCHAR curdirstr[_MAX_PATH]; + + drivenum = 0; + if (GetCurrentDirectory(sizeof(curdirstr), curdirstr)) + if (curdirstr[1] == ':') + drivenum = toupper(curdirstr[0]) - 64; + + return drivenum; +} + + +/*** +*int _chdrive(int drive) - set the current drive (1=A:, 2=B:, etc.) +* +*Purpose: +* Allows the user to change the current disk drive +* +*Entry: +* drive - the number of drive which should become the current drive +* +*Exit: +* returns 0 if successful, else -1 +* +*Exceptions: +* +*******************************************************************************/ + +int __cdecl _chdrive ( + int drive + ) +{ + char newdrive[3]; + + if (drive < 1 || drive > 31) { + errno = EACCES; + _doserrno = ERROR_INVALID_DRIVE; + return -1; + } + + _mlock(_ENV_LOCK); + + newdrive[0] = (char)('A' + (char)drive - (char)1); + newdrive[1] = ':'; + newdrive[2] = '\0'; + + /* + * Set new drive. If current directory on new drive exists, it + * will become the cwd. Otherwise defaults to root directory. + */ + + if ( SetCurrentDirectory((LPSTR)newdrive) ) { + _munlock(_ENV_LOCK); + return 0; + } + else { + _dosmaperr(GetLastError()); + _munlock(_ENV_LOCK); + return -1; + } +} + +#else /* ndef _WIN32 */ + +#include +#include +#include +#include +#include +#include + +/*** +*int _getdrive() - get current drive (-1=BootDisk, -2=Second mounted drive, etc.) +* +*Purpose: +* Returns the current disk drive +* +*Entry: +* No parameters. +* +*Exit: +* returns 1 for BootDisk, 2 for Second mounted drive, etc. +* returns 0 if current drive cannot be determined. +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE1 _getdrive ( + void + ) +{ + OSErr osErr; + WDPBRec wdPB; + char st[256]; + + wdPB.ioNamePtr = &st[0]; + osErr = PBHGetVolSync(&wdPB); + if (osErr) { + return 0; + } + + + return wdPB.ioWDVRefNum; +} + + +/*** +*int _chdrive(int drive) - set the current drive (-1=BootDisk, -2=Second drive, etc.) +* +*Purpose: +* Allows the user to change the current disk drive +* +* +*Entry: +* drive - the number of drive which should become the current drive +* +*Exit: +* returns 0 if successful, else -1 +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE1 _chdrive ( + int drive + ) +{ + OSErr osErr; + WDPBRec wdPB; + + wdPB.ioNamePtr = NULL; + wdPB.ioWDDirID = 0; + wdPB.ioVRefNum = drive; + osErr = PBHSetVolSync(&wdPB); + if (osErr) { + return -1; + } + + return 0; +} + +#endif /* _WIN32 */ diff --git a/private/crt32/dos/fullpath.c b/private/crt32/dos/fullpath.c new file mode 100644 index 000000000..30f27dfe4 --- /dev/null +++ b/private/crt32/dos/fullpath.c @@ -0,0 +1,318 @@ +/*** +*fullpath.c - +* +* Copyright (c) 1987-1992, Microsoft Corporation. All rights reserved. +* +*Purpose: contains the function _fullpath which makes an absolute path out +* of a relative path. i.e. ..\pop\..\main.c => c:\src\main.c if the +* current directory is c:\src\src +* +*Revision History: +* +* 12-21-87 WAJ Initial version +* 01-08-88 WAJ now treats / as an \ +* 06-22-88 WAJ now handles network paths ie \\sl\users +* 01-31-89 SKS/JCR Renamed _canonic to _fullpath +* 04-03-89 WAJ Now returns "d:\dir" for "." +* 05-09-89 SKS Do not change the case of arguments +* 11-30-89 JCR Preserve errno setting from _getdcwd() call on errors +* 03-07-90 GJF Replaced _LOAD_DS with _CALLTYPE1, added #include +* , removed #include and fixed +* the copyright. +* 04-25-90 JCR Fixed an incorrect errno setting +* 06-14-90 SBM Fixed bugs in which case of user provided drive letter +* was not always preserved, and c:\foo\\bar did not +* generate an error +* 08-10-90 SBM Compiles cleanly with -W3 +* 08-28-90 SBM Fixed bug in which UNC names were being rejected +* 09-27-90 GJF New-style function declarator. +* 01-18-91 GJF ANSI naming. +* 11-30-92 KRS Ported _MBCS code from 16-bit tree. +* 08-03-93 KRS Change to use _ismbstrail instead of isdbcscode. +* 09-27-93 CFW Avoid cast bug. +* +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef _MBCS +#include +#include +#endif + + +#define ISSLASH(a) ((a) == '\\' || (a) == '/') + +/*** +*char *_fullpath( char *buf, const char *path, maxlen ); +* +*Purpose: +* +* _fullpath - combines the current directory with path to form +* an absolute path. i.e. _fullpath takes care of .\ and ..\ +* in the path. +* +* The result is placed in buf. If the length of the result +* is greater than maxlen NULL is returned, otherwise +* the address of buf is returned. +* +* If buf is NULL then a buffer is malloc'ed and maxlen is +* ignored. If there are no errors then the address of this +* buffer is returned. +* +* If path specifies a drive, the curent directory of this +* drive is combined with path. If the drive is not valid +* and _fullpath needs the current directory of this drive +* then NULL is returned. If the current directory of this +* non existant drive is not needed then a proper value is +* returned. +* For example: path = "z:\\pop" does not need z:'s current +* directory but path = "z:pop" does. +* +* +* +*Entry: +* char *buf - pointer to a buffer maintained by the user; +* char *path - path to "add" to the current directory +* int maxlen - length of the buffer pointed to by buf +* +*Exit: +* Returns pointer to the buffer containing the absolute path +* (same as buf if non-NULL; otherwise, malloc is +* used to allocate a buffer) +* +*Exceptions: +* +*******************************************************************************/ + + +char * _CALLTYPE1 _fullpath ( + char *UserBuf, + const char *path, + size_t maxlen + ) +{ + char *RetValue; + char *buf; + char *StartBuf; + char *EndBuf; + char *SaveBuf; + char c; + int count; + unsigned drive; +#ifdef _MBCS +const char *StartPath = path; +#endif + + + if( !path || !*path ) /* no work to do */ + return( _getcwd( UserBuf, maxlen ) ); + + /* allocate buffer if necessary */ + + if( !UserBuf ) + if( !(buf = malloc(_MAX_PATH)) ){ + errno = ENOMEM; + return( NULL ); + } + else + maxlen = _MAX_PATH; + + else { + if( maxlen < _MAX_DRIVE+1 ){ /* we need at least 4 chars for "A:\" */ + errno = ERANGE; + return( NULL ); + } + buf = UserBuf; + } + + RetValue = buf; + EndBuf = buf + maxlen - 1; + + if( ISSLASH(*(path+1)) && ISSLASH(*path) ){ /* check for network drive */ + + count = 0; /* count the '\\'s */ + while( (c = *path) ){ + *buf = c; + path++; + + if( buf >= EndBuf ){ +ReturnError1: + errno = ERANGE; +ReturnError2: + if( UserBuf == NULL ) + free( RetValue ); + return( NULL ); + } + +#ifdef _MBCS + if ( !_ISLEADBYTE(*(buf-2))) +#endif + if( ISSLASH( c ) ){ + /* ensure that path contains a '\\', not a '/' */ + *buf = '\\'; + + /* ensure that '\\\\' is followed by something */ + if( ++count == 2 ){ + if( !*path ){ + errno = EINVAL; + goto ReturnError2; + } + } + + /* check that third and fourth '\\'are preceded by non-'\\' */ + if( count >= 3 ){ + if( *(buf-1) == '\\' ){ + errno = EINVAL; + goto ReturnError2; + } + } + + /* stop on fourth '\\', \\foo\bar\ <-- namely this one */ + if( count == 4 ) + break; + } + + buf++; + } + + *buf = '\\'; + StartBuf = buf; + } + + else { /* not a UNC path */ + + if( path[1] == ':' && isalpha((unsigned char)path[0]) ) { /* get drive information */ + *buf = *path; + /* + ** drive must be in the range 1-26 + ** "*buf" may be upper or lower case + */ + drive = (*buf++ - 'A' + 1) & 0x1F; + *buf++ = ':'; + path += 2; + } + else + drive = 0; + + if( ISSLASH( *path ) ){ + if( drive == 0 ){ + *buf++ = (char)(_getdrive() + 'A' - 1); + *buf++ = ':'; + } + + path++; + } + + else { + /* preserve the driveletter in original case from path, + since _getdcwd will always return it in upper case */ + if (drive) + c = *(path-2); + if( !_getdcwd( drive, RetValue, maxlen ) ) + goto ReturnError2; /* error: preserve errno value */ + buf = RetValue + strlen( RetValue ); + /* restore drive letter in original case */ + if (drive) + *RetValue = c; +#ifdef _MBCS + if (!_ISLEADBYTE(*(buf-2))) +#endif + if( ISSLASH( *(buf-1) ) ) /* buf must point to last slash */ + buf--; /* if this is a root directory */ + } + + *buf = '\\'; + StartBuf = RetValue + 2; + } + + + while( *path ){ + + if( *path == '.' + && *(path+1) == '.' + && ( ISSLASH(*(path+2)) || !*(path+2) ) ){ /* handle .. */ + + do{ + buf--; +#ifdef _MBCS + if (ISSLASH(*buf)) + if (_ismbstrail(StartBuf,buf)) + buf--; +#endif + } + while( !ISSLASH( *buf ) && buf > StartBuf ); + + if( buf < StartBuf ) { /* unable to do cd .. */ + errno = EACCES; + goto ReturnError2; + } + + path += 2; + if( *path ) /* if it was "..\" */ + path++; + } + + else if( *path == '.' && ( ISSLASH(*(path+1)) || !*(path+1) )){ + + path++; /* handle . */ + if( *path ) /* if it was ".\" */ + path++; + } + + else { + SaveBuf = buf; /* save for DBCS-safe test for null path */ + + while((*path) && (!ISSLASH(*path)) && (buf < EndBuf)) { + *++buf = *path++; +#ifdef _MBCS + if (_ISLEADBYTE(*(path-1))) + { + if ((*path) && (buf < EndBuf)) + *++buf = *path++; + else + { /* ill-formed DBCS character */ + errno = EINVAL; + goto ReturnError2; + } + } +#endif + } + + if( buf >= EndBuf ) /* if buf == EndBuf then */ + goto ReturnError1; /* no room for '\0' */ + + /* DBCS-safe test for non-empty path component */ + if ((buf==SaveBuf) /* && (*buf=='\\') */ ) /* 2nd test redundent */ + { + errno = EINVAL; + goto ReturnError2; + } + + *++buf = '\\'; + if( ISSLASH( *path ) ) +#ifdef _MBCS + if (!_ismbstrail(StartPath,path)) +#endif + path++; + } + } + + + /* buf points to last character in the string which is an '\\' */ + + if( *(buf-1) == ':' ) /* keep trailing '\' if */ +#ifdef _MBCS + if (!_ismbstrail(StartBuf,buf-1)) +#endif + buf++; /* this is a root directory */ + *buf = '\0'; + + return( RetValue ); +} diff --git a/private/crt32/dos/getcwd.c b/private/crt32/dos/getcwd.c new file mode 100644 index 000000000..e2c8042a2 --- /dev/null +++ b/private/crt32/dos/getcwd.c @@ -0,0 +1,451 @@ +/*** +*getcwd.c - get current working directory (OS/2 version) +* +* Copyright (c) 1985-1993, Microsoft Corporation. All rights reserved. +* +*Purpose: +* +* contains functions _getcwd, _getdcwd and _getcdrv for getting the +* current working directory. getcwd gets the c.w.d. for the default disk +* drive, whereas _getdcwd allows one to get the c.w.d. for whatever disk +* drive is specified. _getcdrv gets the current drive. +* +*Revision History: +* 09-09-83 RKW created +* 05-??-84 DCW added conditional compilation to handle case of library +* where SS != DS (can't take address of a stack variable). +* 09-??-84 DCW changed comparison of path length to maxlen to take the +* terminating null character into account. +* 11-28-84 DCW changed to return errno values compatibly with the +* System 3 version. +* 05-19-86 SKS adapted for OS/2 +* 11-19-86 SKS if pnbuf==NULL, maxlen is ignored; +* eliminated use of intermediate buffer "buf[]"; added +* entry point "_getdcwd()" which takes a drive number. +* 12-03-86 SKS if pnbuf==NULL, maxlen is the minimum allocation size +* 02-05-87 BCM fixed comparison in _getdcwd, +* (unsigned)(len+3) > (int)(maxlen), to handle maxlen < 0, +* since implicit cast to (unsigned) was occurring. +* 12-11-87 JCR Added "_LOAD_DS" to declaration +* 12-21-87 WAJ Added _getcdrv() +* 06-22-88 WAJ _getcdrv() is now made for all OS/2 libs +* 10-03-88 JCR 386: Change DOS calls to SYS calls +* 10-04-88 JCR 386: Removed 'far' keyword +* 10-10-88 GJF Made API names match DOSCALLS.H +* 01-31-89 JCR Remove _getcdrv(), which has been renamed _getdrive() +* 04-12-89 JCR Use new OS/2 system calls +* 05-25-89 JCR 386 OS/2 calls use '_syscall' calling convention +* 11-27-89 JCR Corrected ERRNO values +* 12-12-89 JCR Fixed bogus syscall introduced in previous fix (oops) +* 03-07-90 GJF Replaced _LOAD_DS by _CALLTYPE1, added #include +* , removed #include , removed +* some leftover 16-bit support and fixed the copyright. +* Also, cleaned up the formatting a bit. +* 07-24-90 SBM Compiles cleanly with -W3 (removed unreferenced +* variable), removed redundant includes, removed +* '32' from API names +* 08-10-90 SBM Compiles cleanly with -W3 with new build of compiler +* 09-27-90 GJF New-style function declarator. +* 12-04-90 SRW Changed to include instead of +* 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals. +* 01-16-91 GJF ANSI naming. +* 08-21-91 JCR Test DOSQUERYCURRENTDIR call for error return (bug fix) +* 04-23-92 GJF Fixed initialization of DriveVar[]. +* 04-28-92 GJF Revised Win32 version. +* 12-13-93 GJF In _getdcwd(), was using local array to hold env +* string which was _putenv-ed. Ouch! +* +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#ifdef _CRUISER_ + +/*** +*char *_getcwd(pnbuf, maxlen) - get current working directory of default drive +* +*Purpose: +* _getcwd gets the current working directory for the user, +* placing it in the buffer pointed to by pnbuf. It returns +* the length of the string put in the buffer. If the length +* of the string exceeds the length of the buffer, maxlen, +* then NULL is returned. If pnbuf = NULL, maxlen is ignored. +* An entry point "_getdcwd()" is defined with takes the above +* parameters, plus a drive number. "_getcwd()" is implemented +* as a call to "_getcwd()" with the default drive (0). +* +* If pnbuf = NULL, maxlen is ignored, and a buffer is automatically +* allocated using malloc() -- a pointer to which is returned by +* _getcwd(). +* +* side effects: no global data is used or affected +* +*Entry: +* char *pnbuf = pointer to a buffer maintained by the user; +* int maxlen = length of the buffer pointed to by pnbuf; +* +*Exit: +* Returns pointer to the buffer containing the c.w.d. name +* (same as pnbuf if non-NULL; otherwise, malloc is +* used to allocate a buffer) +* +*Exceptions: +*******************************************************************************/ + +/* +** _getcwd() is just a call to _getdcwd() with the default drive +*/ + +char * _CALLTYPE1 _getcwd ( + char *pnbuf, + int maxlen + ) +{ + return(_getdcwd(0, pnbuf, maxlen)); +} + + +/*** +*char *_getdcwd(drive, pnbuf, maxlen) - get c.w.d. for given drive +* +*Purpose: +* _getdcwd gets the current working directory for the user, +* placing it in the buffer pointed to by pnbuf. It returns +* the length of the string put in the buffer. If the length +* of the string exceeds the length of the buffer, maxlen, +* then NULL is returned. If pnbuf = NULL, maxlen is ignored, +* and a buffer is automatically allocated using malloc() -- +* a pointer to which is returned by _getdcwd(). +* +* side effects: no global data is used or affected +* +*Entry: +* int drive - number of the drive being inquired about +* 0 = default, 1 = 'a:', 2 = 'b:', etc. +* char *pnbuf - pointer to a buffer maintained by the user; +* int maxlen - length of the buffer pointed to by pnbuf; +* +*Exit: +* Returns pointer to the buffer containing the c.w.d. name +* (same as pnbuf if non-NULL; otherwise, malloc is +* used to allocate a buffer) +* +*Exceptions: +* +*******************************************************************************/ + +char * _CALLTYPE1 _getdcwd ( + int drive, + char *pnbuf, + REG2 int maxlen + ) +{ + REG1 char *p; + char dirbuf[1]; + + unsigned len = 1; + unsigned oserr; + + /* + ** Get default drive if necessary + */ + if (drive == 0) + drive = _getdrive(); + + /* + ** Ask DOS the length of the current directory string + */ + + if ((oserr = DOSQUERYCURRENTDIR(drive,(char *)dirbuf,(unsigned *)&len)) + != ERROR_BUFFER_OVERFLOW) { + oserr_rtn: /* common error return */ + errno = EACCES; /* probably bogus drive */ + _doserrno = oserr; + return(NULL); + } + + /* see if need to try to allocate buffer in heap */ + + if (!(p = pnbuf)) { + if (((int)len+3) > maxlen) + maxlen = len+3; + if (!(p = malloc(maxlen))) { + errno = ENOMEM; + _doserrno = E_nomem; + return(p); + } + pnbuf = p; + } + + /* set up string - prepend drive letter + colon to the path name + */ + + *p++ = (char)(drive + 'A' - 1); /* drive specifier */ + *p++ = ':'; + *p++ = '\\'; + + /* check to make sure it all fits in the supplied (or created) buffer. + */ + + if ((int)len+3 > maxlen) { + errno = ERANGE; /* Won't fit in user buffer */ + return(NULL); + } + + /* get root relative path name + */ + + if (oserr = DOSQUERYCURRENTDIR(drive,(char *)p,(unsigned *)&len)) + goto oserr_rtn; /* join other DOSQUERYCURRENTDIRDIR error return */ + + return(p-3); + +} + + +#else /* ndef _CRUISER_ */ + +#ifdef _WIN32_ + + +/*** +*char *_getcwd(pnbuf, maxlen) - get current working directory of default drive +* +*Purpose: +* _getcwd gets the current working directory for the user, +* placing it in the buffer pointed to by pnbuf. It returns +* the length of the string put in the buffer. If the length +* of the string exceeds the length of the buffer, maxlen, +* then NULL is returned. If pnbuf = NULL, maxlen is ignored. +* An entry point "_getdcwd()" is defined with takes the above +* parameters, plus a drive number. "_getcwd()" is implemented +* as a call to "_getcwd()" with the default drive (0). +* +* If pnbuf = NULL, maxlen is ignored, and a buffer is automatically +* allocated using malloc() -- a pointer to which is returned by +* _getcwd(). +* +* side effects: no global data is used or affected +* +*Entry: +* char *pnbuf = pointer to a buffer maintained by the user; +* int maxlen = length of the buffer pointed to by pnbuf; +* +*Exit: +* Returns pointer to the buffer containing the c.w.d. name +* (same as pnbuf if non-NULL; otherwise, malloc is +* used to allocate a buffer) +* +*Exceptions: +* +*******************************************************************************/ + + +char * _CALLTYPE1 _getcwd ( + char *pnbuf, + int maxlen + ) +{ + char *retval; + + _mlock(_ENV_LOCK); + + retval = _getdcwd_lk(0, pnbuf, maxlen); + + _munlock(_ENV_LOCK); + + return retval; +} + + +/*** +*char *_getdcwd(drive, pnbuf, maxlen) - get c.w.d. for given drive +* +*Purpose: +* _getdcwd gets the current working directory for the user, +* placing it in the buffer pointed to by pnbuf. It returns +* the length of the string put in the buffer. If the length +* of the string exceeds the length of the buffer, maxlen, +* then NULL is returned. If pnbuf = NULL, maxlen is ignored, +* and a buffer is automatically allocated using malloc() -- +* a pointer to which is returned by _getdcwd(). +* +* side effects: no global data is used or affected +* +*Entry: +* int drive - number of the drive being inquired about +* 0 = default, 1 = 'a:', 2 = 'b:', etc. +* char *pnbuf - pointer to a buffer maintained by the user; +* int maxlen - length of the buffer pointed to by pnbuf; +* +*Exit: +* Returns pointer to the buffer containing the c.w.d. name +* (same as pnbuf if non-NULL; otherwise, malloc is +* used to allocate a buffer) +* +*Exceptions: +* +*******************************************************************************/ + + +#ifdef MTHREAD + +char * _CALLTYPE1 _getdcwd ( + int drive, + char *pnbuf, + int maxlen + ) +{ + char *retval; + + _mlock(_ENV_LOCK); + + retval = _getdcwd_lk(drive, pnbuf, maxlen); + + _munlock(_ENV_LOCK); + + return retval; +} + +char * _CALLTYPE1 _getdcwd_lk ( + int drive, + char *pnbuf, + int maxlen + ) +#else + +char * _CALLTYPE1 _getdcwd ( + int drive, + char *pnbuf, + int maxlen + ) +#endif + +{ + char *p; + char dirbuf[1]; + int len; + char DirOnDriveVar[4]; + char *envval; + + /* + * Only works for default drive in Win32 environment. + */ + if ( drive != 0 ) { + /* + * Not the default drive - make sure it's valid. + */ + if ( !_ValidDrive(drive) ) { + errno = EACCES; + return NULL; + } + + /* + * Get special environment variable that specifies the current + * directory on drive. + */ + DirOnDriveVar[0] = '='; + DirOnDriveVar[1] = (char)('A' + (char)drive - (char)1); + DirOnDriveVar[2] = ':'; + DirOnDriveVar[3] = '\0'; + + if ( (envval = _getenv_lk(DirOnDriveVar)) == NULL ) { + + /* + * Need to define the environment variable, allocate + * space from the heap to hold the string + */ + if ( (envval = malloc( 8 * sizeof(char) )) == NULL ) { + errno = ENOMEM; /* must be out of heap memory */ + return NULL; + } + + /* + * Environment variable not defined! Define it to be the + * root on that drive. + */ + envval[0] = envval[3] = '='; + envval[1] = envval[4] = (char)('A' + (char)drive + - (char)1); + envval[2] = envval[5] = ':'; + envval[6] = '\\'; + envval[7] = '\0'; + if ( _putenv_lk(envval) != 0 ) { + errno = ENOMEM; /* must be out of heap memory */ + return NULL; + } + envval += 4; + } + + len = strlen(envval) + 1; + + } else { + + /* + * Ask OS the length of the current directory string + */ + len = GetCurrentDirectory(sizeof(dirbuf), (LPSTR)dirbuf) + 1; + } + + /* + * Set up the buffer. + */ + if ( (p = pnbuf) == NULL ) { + /* + * Allocate a buffer for the user. + */ + if ( (p = malloc(__max(len, maxlen))) == NULL ) { + errno = ENOMEM; + return NULL; + } + } + else if ( len > maxlen ) { + /* + * Won't fit in the user-supplied buffer! + */ + errno = ERANGE; /* Won't fit in user buffer */ + return NULL; + } + + /* + * Place the current directory string into the user buffer + */ + + if ( drive != 0 ) + /* + * Copy value of special environment variable into user buffer. + */ + strcpy(p, envval); + else + /* + * Get the current directory directly from the OS + */ + if ( GetCurrentDirectory(len,p) == 0 ) { + /* + * Oops. For lack of a better idea, assume some sort + * of access error has occurred. + */ + errno = EACCES; + _doserrno = GetLastError(); + return NULL; + } + + return p; +} + +#else /* ndef _WIN32_ */ + +#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED! + +#endif /* _WIN32_ */ + +#endif /* _CRUISER_ */ diff --git a/private/crt32/dos/getpid.c b/private/crt32/dos/getpid.c new file mode 100644 index 000000000..b3967bf87 --- /dev/null +++ b/private/crt32/dos/getpid.c @@ -0,0 +1,72 @@ +/*** +*getpid.c - OS/2 get current process id +* +* Copyright (c) 1989-1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Defines _getpid() - get current process id +* +*Revision History: +* 06-06-89 PHG Module created, based on asm version +* 10-27-89 JCR Added new Dos32GetThreadInfo code (under DCR757 switch) +* 11-17-89 JCR Enabled DOS32GETTHREADINFO code (DCR757) +* 03-07-90 GJF Made calling type _CALLTYPE1, added #include +* and fixed copyright. Also, cleaned up the +* formatting a bit. +* 07-02-90 GJF Removed pre-DCR757 stuff. +* 08-08-90 GJF Changed API prefix from DOS32 to DOS +* 10-03-90 GJF New-style function declarator. +* 12-04-90 SRW Changed to include instead of +* 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals. +* 01-28-91 GJF ANSI naming. +* +*******************************************************************************/ + +#include +#include + +/*** +*int _getpid() - get current process id +* +*Purpose: +* Returns the current process id for the calling process. +* +*Entry: +* None. +* +*Exit: +* Returns the current process id. +* +*Uses: +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE1 _getpid ( + void + ) +{ +#ifdef _CRUISER_ + PTIB tid_info; /* thread info */ + PPIB pid_info; /* process info */ + + DOSGETTHREADINFO(&tid_info, &pid_info); + + return(pid_info->pib_ulpid); /* return process id */ + +#else /* ndef _CRUISER_ */ + +#ifdef _WIN32_ + + return GetCurrentProcessId(); + +#else /* ndef _WIN32_ */ + +#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED! + +#endif /* _WIN32_ */ + +#endif /* _CRUISER_ */ + +} diff --git a/private/crt32/dos/makefile b/private/crt32/dos/makefile new file mode 100644 index 000000000..6ee4f43fa --- /dev/null +++ b/private/crt32/dos/makefile @@ -0,0 +1,6 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/crt32/dos/mkdir.c b/private/crt32/dos/mkdir.c new file mode 100644 index 000000000..42431ab9e --- /dev/null +++ b/private/crt32/dos/mkdir.c @@ -0,0 +1,80 @@ +/*** +*mkdir.c - OS/2 make directory +* +* Copyright (c) 1989-1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Defines function _mkdir() - make a directory +* +*Revision History: +* 06-06-89 PHG Module created, based on asm version +* 03-07-90 GJF Made calling type _CALLTYPE2 (for now), added #include +* , fixed compiler warnings and fixed the +* copyright. Also, cleaned up the formatting a bit. +* 03-30-90 GJF Now _CALLTYPE1. +* 07-24-90 SBM Removed '32' from API names +* 09-27-90 GJF New-style function declarator. +* 12-04-90 SRW Changed to include instead of +* 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals. +* 01-16-91 GJF ANSI naming. +* +*******************************************************************************/ + +#include +#include +#include +#include + +/*** +*int _mkdir(path) - make a directory +* +*Purpose: +* creates a new directory with the specified name +* +*Entry: +* char *path - name of new directory +* +*Exit: +* returns 0 if successful +* returns -1 and sets errno if unsuccessful +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE1 _mkdir ( + const char *path + ) +{ + ULONG dosretval; + + /* ask OS to create directory */ +#ifdef _CRUISER_ + + dosretval = DOSCREATEDIR((char *)path, 0, 0); + +#else /* ndef _CRUISER_ */ + +#ifdef _WIN32_ + + if (!CreateDirectory((LPSTR)path, (LPSECURITY_ATTRIBUTES)NULL)) + dosretval = GetLastError(); + else + dosretval = 0; + +#else /* ndef _WIN32_ */ + +#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED! + +#endif /* _WIN32_ */ + +#endif /* _CRUISER_ */ + + if (dosretval) { + /* error occured -- map error code and return */ + _dosmaperr(dosretval); + return -1; + } + + return 0; +} diff --git a/private/crt32/dos/rename.c b/private/crt32/dos/rename.c new file mode 100644 index 000000000..5aeec210b --- /dev/null +++ b/private/crt32/dos/rename.c @@ -0,0 +1,83 @@ +/*** +*rename.c - OS/2 rename file +* +* Copyright (c) 1989-1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Defines rename() - rename a file +* +*Revision History: +* 06-06-89 PHG Module created, based on asm version +* 03-07-90 GJF Made calling type _CALLTYPE2 (for now), added #include +* , fixed compiler warnings and fixed the +* copyright. Also, cleaned up the formatting a bit. +* 03-30-90 GJF Now _CALLTYPE1. +* 07-24-90 SBM Removed '32' from API names +* 09-27-90 GJF New-style function declarator. +* 12-04-90 SRW Changed to include instead of +* 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals. +* +*******************************************************************************/ + +#include +#include +#include +#include + +/*** +*int rename(oldname, newname) - rename a file +* +*Purpose: +* Renames a file to a new name -- no file with new name must +* currently exist. +* +*Entry: +* char *oldname - name of file to rename +* char *newname - new name for file +* +*Exit: +* returns 0 if successful +* returns not 0 and sets errno if not successful +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE1 rename ( + const char *oldname, + const char *newname + ) +{ + ULONG dosretval; + + /* ask OS to move file */ + +#ifdef _CRUISER_ + + dosretval = DOSMOVE((char *)oldname, (char *)newname, 0); + +#else /* ndef _CRUISER_ */ + +#ifdef _WIN32_ + + if (!MoveFile((LPSTR)oldname, (LPSTR)newname)) + dosretval = GetLastError(); + else + dosretval = 0; + +#else /* ndef _WIN32_ */ + +#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED! + +#endif /* _WIN32_ */ + +#endif /* _CRUISER_ */ + + if (dosretval) { + /* error occured -- map error code and return */ + _dosmaperr(dosretval); + return -1; + } + + return 0; +} diff --git a/private/crt32/dos/rmdir.c b/private/crt32/dos/rmdir.c new file mode 100644 index 000000000..2f387cb11 --- /dev/null +++ b/private/crt32/dos/rmdir.c @@ -0,0 +1,83 @@ +/*** +*rmdir.c - OS/2 remove directory +* +* Copyright (c) 1989-1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* defines _rmdir() - remove a directory +* +*Revision History: +* 06-06-89 PHG Module created, based on asm version +* 03-07-90 GJF Made calling type _CALLTYPE2 (for now), added #include +* , fixed compiler warnings and fixed the +* copyright. Also, cleaned up the formatting a bit. +* 03-30-90 GJF Now _CALLTYPE1. +* 07-24-90 SBM Removed '32' from API names +* 09-27-90 GJF New-style function declarator. +* 12-04-90 SRW Changed to include instead of +* 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals. +* 01-16-91 GJF ANSI naming. +* +*******************************************************************************/ + +#include +#include +#include +#include + +/*** +*int _rmdir(path) - remove a directory +* +*Purpose: +* deletes the directory speicifed by path. The directory must +* be empty, and it must not be the current working directory or +* the root directory. +* +*Entry: +* char *path - directory to remove +* +*Exit: +* returns 0 if successful +* returns -1 and sets errno if unsuccessful +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE1 _rmdir ( + const char *path + ) +{ + ULONG dosretval; + + /* ask OS to remove directory */ + +#ifdef _CRUISER_ + + dosretval = DOSDELETEDIR((char *)path, 0); + +#else /* ndef _CRUISER_ */ + +#ifdef _WIN32_ + + if (!RemoveDirectory((LPSTR)path)) + dosretval = GetLastError(); + else + dosretval = 0; + +#else /* ndef _WIN32_ */ + +#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED! + +#endif /* _WIN32_ */ + +#endif /* _CRUISER_ */ + + if (dosretval) { + /* error occured -- map error code and return */ + _dosmaperr(dosretval); + return -1; + } + + return 0; +} diff --git a/private/crt32/dos/sources b/private/crt32/dos/sources new file mode 100644 index 000000000..ce098d931 --- /dev/null +++ b/private/crt32/dos/sources @@ -0,0 +1,48 @@ +!IF 0 + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + This file specifies the target component being built and the list of + sources files needed to build that component. Also specifies optional + compiler switches and libraries that are unique for the component being + built. + + +Author: + + Steve Wood (stevewo) 12-Apr-1990 + jeffrob 29-sep-1990, use crt32.def + +NOTE: Commented description of this file is in \nt\bak\bin\sources.tpl + +!ENDIF + +MAJORCOMP=crt +MINORCOMP=dos + +TARGETNAME=dos +TARGETPATH=..\obj +TARGETTYPE=LIBRARY +386_STDCALL=0 + +!INCLUDE ..\crt32.def + +SOURCES=access.c \ + chmod.c \ + chdir.c \ + dosmap.c \ + drive.c \ + fullpath.c \ + getcwd.c \ + getpid.c \ + mkdir.c \ + rename.c \ + rmdir.c \ + stat.c \ + unlink.c diff --git a/private/crt32/dos/stat.c b/private/crt32/dos/stat.c new file mode 100644 index 000000000..976d96009 --- /dev/null +++ b/private/crt32/dos/stat.c @@ -0,0 +1,397 @@ +/*** +*stat.c - get file status +* +* Copyright (c) 1985-1993, Microsoft Corporation. All rights reserved. +* +*Purpose: +* defines _stat() - get file status +* +*Revision History: +* 03-??-84 RLB Module created +* 05-??-84 DCW Some cleanup and addition of register variables +* 05-17-86 SKS Ported to OS/2 +* 11-19-86 SKS Better check for root directory; KANJI support +* 05-22-87 SKS Cleaned up declarations and include files +* 11-18-87 SKS Make _dtoxmode a static near procedure +* 12-11-87 JCR Added "_LOAD_DS" to declaration +* 12-21-87 WAJ stat no longer uses chdir to figure out if it has been +* passed a root directory in the MTHREAD case. +* 01-05-88 WAJ now uses _MAX_PATH (defined in stdlib.h) +* 06-22-88 SKS find Hidden and System files, not just normal ones +* 06-22-88 SKS Always use better algorithm to detect root dirs +* 06-29-88 WAJ When looking for root dir makes sure it exists +* 09-28-88 JCR Use new 386 dostypes.h structures +* 10-03-88 JCR 386: Change DOS calls to SYS calls +* 10-04-88 JCR 386: Removed 'far' keyword +* 10-10-88 GJF Made API names match DOSCALLS.H +* 11-24-88 GJF ".cmd" should be considered executable, not ".bat" +* 01-31-89 JCR _canonic() is now _fullpath() and args reversed +* 04-12-89 JCR New syscall interace +* 05-25-89 JCR 386 OS/2 calls use '_syscall' calling convention +* 03-07-90 GJF Replaced _LOAD_DS with _CALLTYPE1, added #include +* , removed #include and +* removed some leftover 16-bit support. Also, fixed +* the copyright. +* 04-02-90 GJF Made _ValidDrive() and _dtoxmode() _CALLTYPE1. Removed +* #include . +* 07-23-90 SBM Compiles cleanly with -W3 (added/removed appropriate +* includes), removed '32' from API names +* 08-10-90 SBM Compiles cleanly with -W3 with new build of compiler +* 09-03-90 SBM Removed EXT macro +* 09-27-90 GJF New-style function declarators. +* 12-04-90 SRW Changed to include instead of +* 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals. +* 12-28-90 SRW Added cast of void * to char * for Mips C Compiler +* 01-18-91 GJF ANSI naming. +* 01-28-91 GJF Fixed call to DOSFINDFIRST (removed last arg). +* 02-28-91 SRW Fixed bug in _dtoxtime calls [_WIN32_] +* 03-05-91 MHL Fixed stat to not use _ValidDrive for stat of root +* 05-19-92 SKS .BAT is a valid "executable" extension for NT, as +* well as CMD. Also, File Creation and File Last Access +* timestamps may be 0 on some file systems (e.g. FAT) +* in which case the File Last Write time should be used. +* 05-29-92 SKS Files with SYSTEM bit set should NOT be marked +* READ-ONLY; these two attributes are independent. +* 08-18-92 SKS Add a call to FileTimeToLocalFileTime +* as a temporary fix until _dtoxtime takes UTC +* 11-20-92 SKS _doserrno must always be set whenever errno is. +* 11-30-92 KRS Port _MBCS support from 16-bit tree. +* 03-29-93 GJF Converted from using _dtoxtime() to __gmtotime_t(). +* 04-07-93 GJF Changed first arg type to const char *. +* +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int _CRTAPI1 _ValidDrive( unsigned drive ); + +#define ISSLASH(a) ((a) == '\\' || (a) == '/') + +/*** +*static unsigned _dtoxmode(attr, name) - +* +*Purpose: +* +*Entry: +* +*Exit: +* +*Exceptions: +* +*******************************************************************************/ + +static unsigned short _CRTAPI3 _dtoxmode ( + int attr, + const char *name + ) +{ + REG1 unsigned short uxmode; + unsigned dosmode; + REG2 const char *p; + + dosmode = attr & 0xff; + if ((p = name)[1] == ':') + p += 2; + + /* check to see if this is a directory - note we must make a special + * check for the root, which DOS thinks is not a directory + */ + + uxmode = (unsigned short) + (((ISSLASH(*p) && !p[1]) || (dosmode & A_D) || !*p) + ? _S_IFDIR|_S_IEXEC : _S_IFREG); + + /* If attribute byte does not have read-only bit, it is read-write */ + + uxmode |= (dosmode & A_RO) ? _S_IREAD : (_S_IREAD|_S_IWRITE); + + /* see if file appears to be executable - check extension of name */ + + if (p = strrchr(name, '.')) { + if ( !_stricmp(p, ".exe") || + !_stricmp(p, ".cmd") || +#ifndef _CRUISER_ + !_stricmp(p, ".bat") || +#endif + !_stricmp(p, ".com") ) + uxmode |= _S_IEXEC; + } + + /* propagate user read/write/execute bits to group/other fields */ + + uxmode |= (uxmode & 0700) >> 3; + uxmode |= (uxmode & 0700) >> 6; + + return(uxmode); +} + + +/*** +*int _stat(name, buf) - get file status info +* +*Purpose: +* _stat obtains information about the file and stores it in the structure +* pointed to by buf. +* +*Entry: +* char *name - pathname of given file +* struct _stat *buffer - pointer to buffer to store info in +* +*Exit: +* fills in structure pointed to by buffer +* returns 0 if successful +* returns -1 and sets errno if unsuccessful +* +*Exceptions: +* +*******************************************************************************/ + +int _CRTAPI1 _stat ( + REG1 const char *name, + REG2 struct _stat *buf + ) +{ + char * path; + char pathbuf[ _MAX_PATH ]; + int drive; /* A: = 1, B: = 2, etc. */ + +#ifdef _CRUISER_ + HDIR findhandle = -1; /* any unused handle */ + struct _FILEFINDBUF findbuf; + unsigned findcount = 1; /* Find only 1 match */ + unsigned long dmap; /* Valid Drive Map (ignored) */ + +#else /* ndef _CRUISER_ */ + +#ifdef _WIN32_ + HANDLE findhandle; + WIN32_FIND_DATA findbuf; + +#else /* ndef _WIN32_ */ + +#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED! + +#endif /* _WIN32_ */ + +#endif /* _CRUISER_ */ + + /* Don't allow wildcards to be interpreted by system */ + + if (_mbspbrk(name, "?*")) { + errno = ENOENT; + _doserrno = E_nofile; + return(-1); + } + + /* Try to get disk from name. If none, get current disk. */ + + if (name[1] == ':'){ + if ( *name && !name[2] ){ + errno = ENOENT; /* return an error if name is */ + _doserrno = E_nofile; /* just drive letter then colon */ + return( -1 ); + } + drive = tolower(*name) - 'a' + 1; + } +#ifdef _CRUISER_ + else + (void)DOSQUERYCURRENTDISK((unsigned long *) &drive, + (unsigned long *) &dmap); + + /* Call Find Match File */ + + if (DOSFINDFIRST((char *)name, (HDIR *)&findhandle, + A_D + A_H + A_S, /* find everything except volume labels */ + (struct _FILEFINDBUF *) &findbuf, sizeof(findbuf), + (unsigned *) &findcount, 1L)) { + + if ( !( _mbspbrk(name, "./\\") && + (path = _fullpath( pathbuf, name, _MAX_PATH )) && + (strlen( path ) == 3) && + _ValidDrive( drive ) ) ) { + errno = ENOENT; + _doserrno = E_nofile; + return( -1 ); + } + + findbuf.attrFile = A_D; + findbuf.cbFile = 0L; + _DATECAST(findbuf.fdateLastWrite) = (1 << 5) + 1; /* 1 January 1980 */ + _TIMECAST(findbuf.ftimeLastWrite) = 0; /* 00:00:00 */ + _DATECAST(findbuf.fdateLastAccess) = + _DATECAST(findbuf.fdateCreation) = + _TIMECAST(findbuf.ftimeLastAccess) = + _TIMECAST(findbuf.ftimeCreation) = 0; + } + else + DOSFINDCLOSE(findhandle); /* Release Find handle */ + + /* Fill in buf */ + + buf->st_mode = _dtoxmode(findbuf.attrFile, name); + buf->st_nlink = 1; + buf->st_size = findbuf.cbFile; + buf->st_mtime = XTIME(findbuf.fdateLastWrite, findbuf.ftimeLastWrite); + + /* + * If create and access times are 0L, use modification time instead + */ + if( _DATECAST(findbuf.fdateCreation) || _TIMECAST(findbuf.ftimeCreation) ) + buf->st_ctime = XTIME(findbuf.fdateCreation, findbuf.ftimeCreation); + else + buf->st_ctime = buf->st_mtime; + + if( _DATECAST(findbuf.fdateLastAccess) || _TIMECAST(findbuf.ftimeLastAccess) ) + buf->st_atime = XTIME(findbuf.fdateLastAccess, findbuf.ftimeLastAccess); + else + buf->st_atime = buf->st_mtime; + + +#else /* ndef _CRUISER_ */ + +#ifdef _WIN32_ + else + drive = _getdrive(); + + /* Call Find Match File */ + findhandle = FindFirstFile((char *)name, &findbuf); + if ( findhandle == (HANDLE)0xffffffff ) { + if ( !( _mbspbrk(name, "./\\") && + (path = _fullpath( pathbuf, name, _MAX_PATH )) && + (strlen( path ) == 3) && + (GetDriveType( path ) > 1) ) ) { + errno = ENOENT; + _doserrno = E_nofile; + return( -1 ); + } + + findbuf.dwFileAttributes = A_D; + findbuf.nFileSizeHigh = 0; + findbuf.nFileSizeLow = 0; + findbuf.cFileName[0] = '\0'; + + buf->st_mtime = __gmtotime_t(80,1,1,0,0,0); + buf->st_atime = buf->st_mtime; + buf->st_ctime = buf->st_mtime; + } + else { + SYSTEMTIME SystemTime; + + FileTimeToSystemTime(&findbuf.ftLastWriteTime, &SystemTime); + + buf->st_mtime = __gmtotime_t(SystemTime.wYear, + SystemTime.wMonth, + SystemTime.wDay, + SystemTime.wHour, + SystemTime.wMinute, + SystemTime.wSecond + ); + + if ( findbuf.ftLastAccessTime.dwLowDateTime || + findbuf.ftLastAccessTime.dwHighDateTime ) + { + FileTimeToSystemTime(&findbuf.ftLastAccessTime, &SystemTime); + + buf->st_atime = __gmtotime_t(SystemTime.wYear, + SystemTime.wMonth, + SystemTime.wDay, + SystemTime.wHour, + SystemTime.wMinute, + SystemTime.wSecond + ); + } else + buf->st_atime = buf->st_mtime ; + + if ( findbuf.ftCreationTime.dwLowDateTime || + findbuf.ftCreationTime.dwHighDateTime ) + { + FileTimeToSystemTime(&findbuf.ftCreationTime, &SystemTime); + + buf->st_ctime = __gmtotime_t(SystemTime.wYear, + SystemTime.wMonth, + SystemTime.wDay, + SystemTime.wHour, + SystemTime.wMinute, + SystemTime.wSecond + ); + } else + buf->st_ctime = buf->st_mtime ; + + FindClose(findhandle); + } + + /* Fill in buf */ + + buf->st_mode = _dtoxmode(findbuf.dwFileAttributes, name); + buf->st_nlink = 1; + buf->st_size = findbuf.nFileSizeLow; + +#else /* ndef _WIN32_ */ + +#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED! + +#endif /* _WIN32_ */ + +#endif /* _CRUISER_ */ + + /* now set the common fields */ + + buf->st_uid = buf->st_gid = buf->st_ino = 0; + + buf->st_rdev = buf->st_dev = (_dev_t)(drive - 1); /* A=0, B=1, etc. */ + + return(0); +} + + +/*** +*int _ValidDrive( unsigned drive ) - +* +*Purpose: returns non zero if drive is a valid drive number. +* +*Entry: drive = 0 => default drive, 1 => a:, 2 => b: ... +* +*Exit: 0 => drive does not exist. +* +*Exceptions: +* +*******************************************************************************/ + +int _CRTAPI1 _ValidDrive ( + unsigned drive + ) +{ + unsigned long DriveMap; + +#ifdef _CRUISER_ + unsigned int CurDrive; + + DOSQUERYCURRENTDISK( &CurDrive, &DriveMap ); + +#else /* ndef _CRUISER_ */ + +#ifdef _WIN32_ + + DriveMap = GetLogicalDrives(); + +#else /* ndef _WIN32_ */ + +#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED! + +#endif /* _WIN32_ */ + +#endif /* _CRUISER_ */ + return( ( DriveMap>>(drive-1) ) & 1l ); +} diff --git a/private/crt32/dos/unlink.c b/private/crt32/dos/unlink.c new file mode 100644 index 000000000..f4fa237ec --- /dev/null +++ b/private/crt32/dos/unlink.c @@ -0,0 +1,101 @@ +/*** +*unlink.c - OS/2 unlink a file +* +* Copyright (c) 1989-1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* defines unlink() - unlink a file +* +*Revision History: +* 06-06-89 PHG Module created, based on asm version +* 03-07-90 GJF Made calling type _CALLTYPE2 (for now), added #include +* , fixed compiler warnings and fixed the +* copyright. Also, cleaned up the formatting a bit. +* 07-24-90 SBM Removed '32' from API names +* 09-27-90 GJF New-style function declarators. +* 12-04-90 SRW Changed to include instead of +* 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals. +* 01-16-91 GJF ANSI naming. +* 04-10-91 PNT Added _MAC_ conditional +* +*******************************************************************************/ + +#include +#include +#include +#include + +/*** +*int _unlink(path) - unlink(delete) the given file +* +*Purpose: +* This version deletes the given file because there are no +* links under OS/2. +* +* NOTE: remove() is an alternative entry point to the _unlink() +* routine* interface is identical. +* +*Entry: +* char *path - file to unlink/delete +* +*Exit: +* returns 0 if successful +* returns -1 and sets errno if unsuccessful +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE1 remove ( + const char *path + ) +{ + ULONG dosretval; + + /* ask OS/2 to remove the file */ +#ifdef _CRUISER_ + + dosretval = DOSDELETE((char *)path, 0); + +#else /* ndef _CRUISER_ */ + +#ifdef _WIN32_ + + if (!DeleteFile((LPSTR)path)) + dosretval = GetLastError(); + else + dosretval = 0; + +#else /* ndef _WIN32_ */ + +#ifdef _MAC_ + + TBD(); + +#else /* ndef _MAC_ */ + +#error ERROR - ONLY CRUISER, WIN32, OR MAC TARGET SUPPORTED! + +#endif /* _MAC_ */ + +#endif /* _WIN32_ */ + +#endif /* _CRUISER_ */ + + + if (dosretval) { + /* error occured -- map error code and return */ + _dosmaperr(dosretval); + return -1; + } + + return 0; +} + +int _CALLTYPE1 _unlink ( + const char *path + ) +{ + /* remove is synonym for unlink */ + return remove(path); +} diff --git a/private/crt32/exec/cenvarg.c b/private/crt32/exec/cenvarg.c new file mode 100644 index 000000000..0a0755748 --- /dev/null +++ b/private/crt32/exec/cenvarg.c @@ -0,0 +1,373 @@ +/*** +*cenvarg.c - OS/2 set up environment, command line blocks +* +* Copyright (c) 1986-1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* defines _cenvarg() - setup environment/command line blocks +* +*Revision History: +* 05-20-86 SKS Module created +* 10-03-86 SKS Wasn't clearing final null byte in environment block +* 10-13-86 SKS Check for environment segment > 32 KB (esp. > 64 KB) +* 10-23-86 SKS New format for C_FILE_INFO for Prot-Mode execution +* 12-17-86 SKS Support for new command line format +* 01-21-87 BCM Removed DCR475 switch, new command line format official +* 07-07-87 JCR Corrected bug in ENV_MAX check +* 05-24-88 SJM Removed support for ;C_FILE_INFO for Real-Mode execution +* 06-01-88 SJM Added support for .cmd files via comname/cmdname +* 12-27-88 JCR Added support for _fileinfo option +* 03-08-90 GJF Made calling type _CALLTYPE1, added #include +* , removed #include and fixed +* the copyright. Also, cleaned up the formatting a bit. +* 04-02-90 GJF Added const to arg types. +* 08-10-90 SBM Compiles cleanly with -W3 +* 09-27-90 GJF New-style function declarator. +* 12-06-90 GJF Added Win32 support. That is, support for encoding +* _osfinfo[] data into _C_FILE_INFO environment variable. +* 01-18-91 GJF ANSI naming. +* 02-05-91 SRW Removed usage of _C_FILE_INFO to pass binary data +* to child process. [_WIN32_] +* 05-07-92 SKS Remove code which stripped the extension from a batch +* file while building arguments to CMD.EXE. This was +* done long ago (1988) for DOS 3.X, I think. +* 10-24-92 SKS Remove special code for batch files - not needed on NT +* 07-15-93 SRW Added _capture_argv function +* +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define ENV_MAX 32767 + +/*** +*int _cenvarg(argv, envp, argblk, envblk, name) - set up cmd line/environ +* +*Purpose: +* Set up the block forms of the environment and the command line. +* If "envp" is null, "_environ" is used instead. +* File handle info is passed in the environment if _fileinfo is !0. +* +*Entry: +* char **argv - argument vector +* char **envp - environment vector +* char **argblk - pointer to pointer set to malloc'ed space for args +* char **envblk - pointer to pointer set to malloc'ed space for env +* char *name - name of program being invoked +* +*Exit: +* returns 0 if ok, -1 if fails +* stores through argblk and envblk +* (calls malloc) +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE1 _cenvarg ( + const char * const *argv, + const char * const *envp, + char **argblk, + char **envblk, + const char *name + ) +{ + REG1 const char * const *vp; + REG2 unsigned tmp; + REG3 char *cptr; + unsigned arg_len; + int cfi_len; /* counts the number of file handles in CFI */ + + /* + * Null environment pointer "envp" means use global variable "_environ" + */ + +#ifdef _CRUISER_ + int i; /* loop counter */ + + if (!envp) + envp = _environ; +#endif /* _CRUISER_ */ + + /* + * Allocate space for command line string + * tmp counts the number of bytes in the command line string + * including spaces between arguments + * An empty string is special -- 2 bytes + */ + + for (vp = argv, tmp = 2; *vp; tmp += strlen(*vp++) + 1) + if( tmp > ENV_MAX ) + break; + + /* + * Make sure there are not already > 32 KB in strings + */ + + if ((arg_len = tmp) >= ENV_MAX) { + *envblk = NULL; + errno = E2BIG; + _doserrno = E_badenv; + return(-1); + } + + /* + * Allocate space for the command line plus 2 null bytes + */ + + if ( (*argblk = malloc(tmp)) == NULL) { + *envblk = NULL; + errno = ENOMEM; + _doserrno = E_nomem; + return(-1); + } + + /* + * Allocate space for environment strings + * tmp counts the number of bytes in the environment strings + * including nulls between strings + * Also add "_C_FILE_INFO=" string + */ + +#ifdef _WIN32_ + if (envp) +#endif /* _WIN32_ */ + + for (vp = envp, tmp = 2; *vp; tmp += strlen(*vp++) + 1) + if( tmp > ENV_MAX ) + break; + +#ifdef _CRUISER_ + if (_fileinfo) + for (cfi_len = _nfile; cfi_len && !_osfile[cfi_len-1]; + cfi_len--) ; + else + cfi_len = 0; /* no _C_FILE_INFO */ + + /* + * mode-independent C-FILE-INFO calculation + */ + + if (cfi_len) /* Add 1 (each) for the "=" & null byte */ + /* Plus 2 bytes for each value in _osfile */ + tmp += /* strlen(_acfinfo) */ CFI_LENGTH + 2 + cfi_len + + cfi_len; + +#else /* ndef _CRUISER_ */ + +#ifdef _WIN32_ + + /* + ** The _osfile and _osfhnd arrays are passed as binary data in + ** dospawn.c + */ + + cfi_len = 0; /* no _C_FILE_INFO */ + +#else /* ndef _WIN32_ */ + +#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED! + +#endif /* _WIN32_ */ + +#endif /* _CRUISER_ */ + +#ifdef _WIN32_ + if (!envp) + *envblk = NULL; + else { +#endif /* _WIN32_ */ + + /* + * Check for too many strings to be placed in the environment + * Increment tmp for final null byte after environment strings + * "tmp + arg_len + strlen(name) + 1" must also be < ENV_MAX + * Do (long) comparison in case tmp > ENV_MAX from C_FILE_INFO + */ + + if( (long) tmp + arg_len + strlen(name) > ENV_MAX - 1 ) { + free(*argblk); + *argblk = NULL; + errno = E2BIG; + _doserrno = E_badenv; + return(-1); + } + + /* + * Allocate space for the environment strings plus extra null byte + */ + + if( !(*envblk = malloc(tmp)) ) { + free(*argblk); + *argblk = NULL; + errno = ENOMEM; + _doserrno = E_nomem; + return(-1); + } + +#ifdef _WIN32_ + } +#endif /* _WIN32_ */ + + /* + * Build the command line by concatenating the argument strings + * with spaces between, and two null bytes at the end + * NOTE: The argv[0] argument is followed by a null. + */ + + cptr = *argblk; + vp = argv; + + if (!*vp) /* Empty argument list ? */ + ++cptr; /* just two null bytes */ + else { /* argv[0] must be followed by a null */ + strcpy(cptr, *vp); + cptr += strlen(*vp++) + 1; + } + + while( *vp ) { + strcpy(cptr, *vp); + cptr += strlen(*vp++); + *cptr++ = ' '; + } + + * cptr = cptr[ -1 ] = '\0'; /* remove extra blank, add double null */ + +#ifdef _WIN32_ + if (envp) { +#endif /* _WIN32_ */ + + /* + * Build the environment block by concatenating the environment strings + * with nulls between and two null bytes at the end + * C_FILE_INFO is stored as if it were an environment string + */ + + cptr = *envblk; + vp = envp; + + if( !(*vp || cfi_len) ) /* No environment strings? */ + *cptr++ = '\0'; /* just two null bytes */ + + while( *vp ) { + strcpy(cptr, *vp); + cptr += 1 + strlen(*vp++); + } + +#ifdef _CRUISER_ + + if(cfi_len) { + strcpy(cptr,_acfinfo); + cptr += /* strlen(_acfinfo) */ CFI_LENGTH; + + i = cfi_len; + for(tmp = 0; i--; ++tmp) { + *cptr++ = (char)(((_osfile[tmp] >> 4) & 0xF) + 'A'); + *cptr++ = (char)((_osfile[tmp] & 0xF) + 'A'); + } + *cptr++ = '\0'; + } + +#else /* ndef _CRUISER_ */ + +#ifdef _WIN32_ + + /* + ** The _osfile and _osfhnd arrays are passed as binary data in + ** dospawn.c + */ + +#else /* ndef _WIN32_ */ + +#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED! + +#endif /* _WIN32_ */ + +#endif /* _CRUISER_ */ + +#ifdef _WIN32_ + } +#endif /* _WIN32_ */ + + /* + * Extra null terminates the segment + */ + *cptr = '\0'; + + return(0); +} + + +/*** +*int _capture_argv(arglist, static_argv, max_static_entries) - set up argv array +* for exec?? functions +* +*Purpose: +* Set up the argv array for the exec?? functions by captures the arguments +* from the passed va_list into the static_argv array. If the size of the +* static_argv array as specified by the max_static_entries parameter is +* not large enough, then allocates a dynamic array to hold the arguments. +* Return the address of the final argv array. If NULL then not enough +* memory to hold argument array. If different from static_argv parameter +* then call must free the return argv array when done with it. +* +* The scan of the arglist is terminated when a NULL argument is reached. +* The terminating NULL parameter is stored in the resulting argv array. +* +*Entry: +* va_list *arglist - pointer to variable length argument list. +* char *firstarg - first argument to store in array +* char **static_argv - pointer to static argv to use. +* size_t max_static_entries - maximum number of entries that can be placed +* in static_argv array. +* +*Exit: +* returns NULL if no memory. +* Otherwise returns pointer to argv array. +* (sometimes calls malloc) +* +*Exceptions: +* +*******************************************************************************/ + +char ** _CALLTYPE1 _capture_argv( + va_list *arglist, + const char *firstarg, + char **static_argv, + size_t max_static_entries + ) +{ + char ** argv; + char * nextarg; + size_t i; + size_t max_entries; + + nextarg = (char *)firstarg; + argv = static_argv; + max_entries = max_static_entries; + i = 0; + for (;;) { + if (i >= max_entries) { + if (argv == static_argv) + argv = malloc((max_entries * 2) * sizeof(char *)); + else + argv = realloc(argv, (max_entries * 2) * sizeof(char *)); + + if (argv == NULL) break; + max_entries += max_entries; + } + + argv[ i++ ] = nextarg; + if (nextarg == NULL) break; + nextarg = va_arg(*arglist, char *); + } + + return argv; +} diff --git a/private/crt32/exec/cfinfo.c b/private/crt32/exec/cfinfo.c new file mode 100644 index 000000000..e761a1f68 --- /dev/null +++ b/private/crt32/exec/cfinfo.c @@ -0,0 +1,22 @@ +/*** +*cfinfo.c - clears C file info flag +* +* Copyright (c) 1989-1992, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Clears the C file info flag. By default, the openfile information +* is NOT passed along to children on spawn/exec calls. If the flag +* is set, openfile information WILL get passed on to children on +* spawn/exec calls. +* +*Revision History: +* 06-07-89 PHG Module created, based on asm version +* 04-03-90 GJF Added #include . Also, fixed the copyright. +* 01-23-92 GJF Added #include (contains decl of _fileinfo). +* +*******************************************************************************/ + +#include +#include + +int _fileinfo = 0; diff --git a/private/crt32/exec/dospawn.c b/private/crt32/exec/dospawn.c new file mode 100644 index 000000000..900c2996d --- /dev/null +++ b/private/crt32/exec/dospawn.c @@ -0,0 +1,303 @@ +/*** +*dospawn.c - OS/2 spawn a child process +* +* Copyright (c) 1989-1992, Microsoft Corporation. All rights reserved. +* +*Purpose: +* defines _dospawn - spawn a child process +* +*Revision History: +* 06-07-89 PHG Module created, based on asm version +* 03-08-90 GJF Made calling type _CALLTYPE2 (for now), added #include +* and fixed the copyright. Also, cleaned +* up the formatting a bit. +* 04-02-90 GJF Now _CALLTYPE1. Added const to type of name arg. +* 07-24-90 SBM Removed '32' from API names +* 09-27-90 GJF New-style function declarator. +* 10-30-90 GJF Added _p_overlay (temporary hack). +* 12-04-90 SRW Changed to include instead of +* 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals. +* 01-16-91 SRW Fixed return value for dospawn [_WIN32_] +* 01-17-91 GJF ANSI naming. +* 01-25-91 SRW Changed CreateProcess parameters [_WIN32_] +* 01-29-91 SRW Changed CreateProcess parameters again [_WIN32_] +* 02-05-91 SRW Changed to pass _osfile and _osfhnd arrays as binary +* data to child process. [_WIN32_] +* 02-18-91 SRW Fixed code to return correct process handle and close +* handle for P_WAIT case. [_WIN32_] +* 04-05-91 SRW Fixed code to free StartupInfo.lpReserved2 after +* CreateProcess call. [_WIN32_] +* 04-26-91 SRW Removed level 3 warnings (_WIN32_) +* 12-02-91 SRW Fixed command line setup code to not append an extra +* space [_WIN32_] +* 12-16-91 GJF Return full 32-bit exit code from the child process +* [_WIN32_]. +* 02-14-92 GJF Replaced _nfile with _nhandle for Win32. +* 02-18-92 GJF Merged in 12-16-91 change from \\vangogh version +* 11-20-92 SKS errno/_doserrno must be 0 in case of success. This +* will distinguish a child process return code of -1L +* (errno == 0) from an actual error (where errno != 0). +* 01-08-93 CFW Added code to handle _P_DETACH case; add fdwCreate variable, +* nuke stdin, stdout, stderr entries of _osfile & _osfhnd tables, +* close process handle to completely detach process +* +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +int _VARTYPE1 _p_overlay = 2; + +/*** +*int _dospawn(mode, name, cmdblk, envblk) - spawn a child process +* +*Purpose: +* Spawns a child process +* +*Entry: +* int mode - _P_WAIT, _P_NOWAIT, _P_NOWAITO, _P_OVERLAY, or _P_DETACH +* char *name - name of program to execute +* char *cmdblk - parameter block +* char *envblk - environment block +* +*Exit: +* _P_OVERLAY: -1 = error, otherwise doesn't return +* _P_WAIT: termination code << 8 + result code +* _P_DETACH: -1 = error, 0 = success +* others: PID of process +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE1 _dospawn ( + int mode, + const char *name, + char *cmdblk, + char *envblk + ) +{ + char syncexec, asyncresult, background; +#ifdef _CRUISER_ + + RESULTCODES result_codes; /* result code of DosExecPgm */ + ULONG exec_flags; /* flags for DosExecPgm */ + ULONG dosretval; /* OS/2 return value */ + +#else /* ndef _CRUISER_ */ + +#ifdef _WIN32_ + + LPSTR CommandLine; + STARTUPINFO StartupInfo; + PROCESS_INFORMATION ProcessInformation; + BOOL CreateProcessStatus; + ULONG dosretval; /* OS return value */ + DWORD retval; + DWORD fdwCreate = 0; /* Flags for CreateProcess */ + int cfi_len; /* counts the number of file handles in CFI */ + +#else /* ndef _WIN32_ */ + +#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED! + +#endif /* _WIN32_ */ + +#endif /* _CRUISER_ */ + + /* translate input mode value to individual flags */ + syncexec = asyncresult = background = 0; + switch (mode) { + case _P_WAIT: syncexec=1; break; /* synchronous execution */ + case 2: /* _P_OVERLAY */ + case _P_NOWAITO: break; /* asynchronous execution */ + case _P_NOWAIT: asyncresult=1; break; /* asynch + remember result */ + case _P_DETACH: background=1; break; /* detached in null scrn grp */ + default: + /* invalid mode */ + errno = EINVAL; + _doserrno = 0; /* not a Dos error */ + return -1; + } + +#ifdef _CRUISER_ + /* translate input mode value to system call value */ + if (syncexec) + exec_flags = EXEC_SYNC; + else + if (asyncresult) + exec_flags = EXEC_ASYNCRESULT; + else + if (background) + exec_flags = EXEC_BACKGROUND; + else + exec_flags = EXEC_ASYNC; + + /* issue system call to run process, want no DynaLink failure name */ + if (dosretval = DOSEXECPGM(NULL, 0, exec_flags, cmdblk, envblk, + &result_codes, (char *)name)) { + /* error -- map error code and return */ + _dosmaperr(dosretval); + return -1; + } + + if (mode == 2 /* _P_OVERLAY */) { + /* destroy ourselves */ + _exit(0); + } + else if (mode == _P_WAIT) { + /* return termination code and exit code -- note we only + return low byte of result code, although OS/2 allows a + word -- this is for XENIX compatability */ + return ((result_codes.codeTerminate & 0xFF) << 8) + + (result_codes.codeResult & 0xFF); + } + else { + /* asynchronous spawn -- return PID */ + return result_codes.codeTerminate; + } + +#else /* ndef _CRUISER_ */ + +#ifdef _WIN32_ + // + // Loop over null separate arguments, and replace null separators + // with spaces to turn it back into a single null terminated + // command line. + // + CommandLine = cmdblk; + while (*cmdblk) { + while (*cmdblk) { + cmdblk++; + } + + // + // If not last argument, turn null separator into a space. + // + if (cmdblk[1] != '\0') { + *cmdblk++ = ' '; + } + } + + memset(&StartupInfo,0,sizeof(StartupInfo)); + StartupInfo.cb = sizeof(StartupInfo); + + for (cfi_len = _nhandle; cfi_len && !_osfile[cfi_len-1];cfi_len--) { + } + + StartupInfo.cbReserved2 = (WORD)(sizeof( int ) + + (cfi_len * + (sizeof( char ) + sizeof( long ) ) + ) + ); + StartupInfo.lpReserved2 = calloc( StartupInfo.cbReserved2, 1 ); + memcpy( StartupInfo.lpReserved2, + &cfi_len, + sizeof( int ) + ); + memcpy( StartupInfo.lpReserved2 + sizeof( int ), + _osfile, + cfi_len * sizeof( char ) + ); + memcpy( StartupInfo.lpReserved2 + sizeof( int ) + + (cfi_len * sizeof( char )), + _osfhnd, + cfi_len * sizeof( long ) + ); + + if (background) + { + int fh; + + /* child process is detached, cannot access console, must nuke first + three entries (stdin, stdout, stderr) in _osfile & _osfhnd tables */ + + // set _osfile[] + for ( fh = 0 ; fh <= 2 ; ++fh ) + { + *(char *)(StartupInfo.lpReserved2 + + sizeof(int) + + fh * sizeof(char)) = 0; + } + + // set _osfhnd[] + for ( fh = 0 ; fh <= 2 ; ++fh ) + { + *(long *)(StartupInfo.lpReserved2 + + sizeof(int) + + cfi_len * sizeof(char) + + fh * sizeof(long)) = (long)INVALID_HANDLE_VALUE; + } + + fdwCreate |= DETACHED_PROCESS; + } + + /** + * Set errno to 0 to distinguish a child process + * which returns -1L from an error in the spawning + * (which will set errno to something non-zero + **/ + + _doserrno = errno = 0 ; + + CreateProcessStatus = CreateProcess( (LPSTR)name, + CommandLine, + NULL, + NULL, + TRUE, + fdwCreate, + envblk, + NULL, + &StartupInfo, + &ProcessInformation + ); + + dosretval = GetLastError(); + free( StartupInfo.lpReserved2 ); + + if (!CreateProcessStatus) + { + _dosmaperr(dosretval); + return -1; + } + + if (mode == 2 /* _P_OVERLAY */) { + /* destroy ourselves */ + _exit(0); + } + else if (mode == _P_WAIT) { + WaitForSingleObject(ProcessInformation.hProcess, (DWORD)(-1L)); + + /* return termination code and exit code -- note we return + the full exit code */ + GetExitCodeProcess(ProcessInformation.hProcess, &retval); + + CloseHandle(ProcessInformation.hProcess); + } + else if (mode == _P_DETACH) { + /* like totally detached asynchronous spawn, dude, + close process handle, return 0 for success */ + CloseHandle(ProcessInformation.hProcess); + retval = (DWORD)0; + } + else { + /* asynchronous spawn -- return PID */ + retval = (DWORD)ProcessInformation.hProcess; + } + + CloseHandle(ProcessInformation.hThread); + return retval; + +#else /* ndef _WIN32_ */ + +#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED! + +#endif /* _WIN32_ */ + +#endif /* _CRUISER_ */ +} diff --git a/private/crt32/exec/execl.c b/private/crt32/exec/execl.c new file mode 100644 index 000000000..3c2d5efd5 --- /dev/null +++ b/private/crt32/exec/execl.c @@ -0,0 +1,76 @@ +/*** +*execl.c - execute a file with a list of arguments +* +* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* defines _execl() - execute a file with a list of arguments +* +*Revision History: +* 10-14-83 RN written +* 12-11-87 JCR Added "_LOAD_DS" to declaration +* 11-20-89 GJF Fixed copyright, indents. Added const attribute to +* types of filename and arglist. #include-d PROCESS.H +* and added ellipsis to match prototype. +* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE2, added #include +* and removed #include . +* 07-24-90 SBM Removed redundant includes, replaced by +* +* 09-27-90 GJF New-style function declarator. +* 01-17-91 GJF ANSI naming. +* 02-14-90 SRW Use NULL instead of _environ to get default. +* 07-16-93 SRW ALPHA Merge +* +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include + +/*** +*int _execl(filename, arglist) - execute a file with arg list +* +*Purpose: +* Transform the argument list so it is a vector, then pass its address +* to execve. Use a pointer to the default environment vector. +* +*Entry: +* char *filename - file to execute +* char *arglist - list of arguments +* call as _execl(path, arg0, arg1, ..., argn, NULL); +* +*Exit: +* destroys the calling process, hopefully +* returns -1 if fails +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE2 _execl ( + const char *filename, + const char *arglist, + ... + ) +{ + va_list vargs; + char * argbuf[64]; + char ** argv; + int result; + + assert(filename != NULL); + assert(*filename != '\0'); + assert(arglist != NULL); + assert(*arglist != '\0'); + + va_start(vargs, arglist); + argv = _capture_argv(&vargs, arglist, argbuf, 64); + va_end(vargs); + + result = _execve(filename,argv,NULL); + if (argv && argv != argbuf) free(argv); + return result; +} diff --git a/private/crt32/exec/execle.c b/private/crt32/exec/execle.c new file mode 100644 index 000000000..2b74e4d31 --- /dev/null +++ b/private/crt32/exec/execle.c @@ -0,0 +1,79 @@ +/*** +*execle.c - execute a file with arg list and environment +* +* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* defines _execle() - execute a file +* +*Revision History: +* 10-14-83 RN written +* 12-11-87 JCR Added "_LOAD_DS" to declaration +* 11-20-89 GJF Fixed copyright, indents. Added const attribute to +* types of filename and arglist. #include-d PROCESS.H +* and added ellipsis to match prototype. +* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE2, added #include +* and removed #include +* 07-24-90 SBM Removed redundant includes, replaced by +* +* 09-27-90 GJF New-style function declarator. +* 01-17-91 GJF ANSI naming. +* 07-16-93 SRW ALPHA Merge +* +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +/*** +*int _execle(filename, arglist) - execute a file +* +*Purpose: +* Execute the given file (overlays the calling process). +* We must dig the environment vector out of the stack and pass it +* and address of argument vector to execve. +* +*Entry: +* char *filename - file to execute +* char *arglist - argument list followed by environment +* should be called like _execle(path, arg0, arg1, ..., argn, NULL, envp); +* +*Exit: +* destroys calling process (hopefully) +* if fails, returns -1. +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE2 _execle ( + const char *filename, + const char *arglist, + ... + ) +{ + va_list vargs; + char * argbuf[64]; + char ** argv; + char ** envp; + int result; + + assert(filename != NULL); + assert(*filename != '\0'); + assert(arglist != NULL); + assert(*arglist != '\0'); + + va_start(vargs, arglist); + argv = _capture_argv(&vargs, arglist, argbuf, 64); + envp = va_arg(vargs, char **); + va_end(vargs); + + result = _execve(filename,argv,envp); + if (argv && argv != argbuf) free(argv); + return result; +} diff --git a/private/crt32/exec/execlp.c b/private/crt32/exec/execlp.c new file mode 100644 index 000000000..4e622be61 --- /dev/null +++ b/private/crt32/exec/execlp.c @@ -0,0 +1,77 @@ +/*** +*execlp.c - execute a file (search along PATH) +* +* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* defines _execlp() - execute a file and search along PATH +* +*Revision History: +* 10-17-83 RN written +* 12-11-87 JCR Added "_LOAD_DS" to declaration +* 11-20-89 GJF Fixed copyright, indents. Added const attribute to +* types of filename and arglist. #include-d PROCESS.H +* and added ellipsis to match prototype. +* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE2, added #include +* and removed #include . +* 07-24-90 SBM Removed redundant includes, replaced by +* +* 09-27-90 GJF New-style function declarator. +* 01-17-91 GJF ANSI naming. +* 07-16-93 SRW ALPHA Merge +* +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +/*** +*int _execlp(filename, arglist) - execute a file, search along PATH +* +*Purpose: +* Execute the given file with the given arguments; search along PATH +* for the file. We pass the arguments to execvp where several paths +* will be tried until one works. +* +*Entry: +* char *filename - file to execute +* char *arglist - argument list +* call as _execlp(path, arg0, arg1, ..., argn, NULL); +* +*Exit: +* destroys calling process (hopefully) +* returns -1 if fails. +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE2 _execlp ( + const char *filename, + const char *arglist, + ... + ) +{ + va_list vargs; + char * argbuf[64]; + char ** argv; + int result; + + assert(filename != NULL); + assert(*filename != '\0'); + assert(arglist != NULL); + assert(*arglist != '\0'); + + va_start(vargs, arglist); + argv = _capture_argv(&vargs, arglist, argbuf, 64); + va_end(vargs); + + result = _execvp(filename,argbuf); + if (argv && argv != argbuf) free(argv); + return result; +} diff --git a/private/crt32/exec/execlpe.c b/private/crt32/exec/execlpe.c new file mode 100644 index 000000000..991cf757a --- /dev/null +++ b/private/crt32/exec/execlpe.c @@ -0,0 +1,82 @@ +/*** +*execlpe.c - execute a file with environ, search along path +* +* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* defines _execlpe() - execute a file with environ and search along PATH +* +*Revision History: +* 10-17-83 RN written +* ??-??-?? TC added execlpe +* 06-18-86 JMB added environment pointer which was erroneously missing +* 06-11-87 PHG removed unnecessary environment pointer (isn't this +* fun!) +* 12-11-87 JCR Added "_LOAD_DS" to declaration +* 11-20-89 GJF Fixed copyright, indents. Added const attribute to +* types of filename and arglist. #include-d PROCESS.H +* and added ellipsis to match prototype. +* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE2, added #include +* and removed #include +* 07-24-90 SBM Removed redundant includes, replaced by +* +* 09-27-90 GJF New-style function declarator. +* 01-17-91 GJF ANSI naming. +* 07-16-93 SRW ALPHA Merge +* +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include + +/*** +*int _execlpe(filename, arglist) - execute a file with environ +* +*Purpose: +* Executes the given file with the parameters and the environment +* which is passed after the parameters. Searches along the PATH +* for the file (done by execvp). +* +*Entry: +* char *filename - file to execute +* char *arglist - argument list (environment is at the end) +* call as _execlpe(path, arg0, arg1, ..., argn, NULL, envp); +* +*Exit: +* destroys the calling process (hopefully) +* if fails, returns -1 +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE2 _execlpe ( + const char *filename, + const char *arglist, + ... + ) +{ + va_list vargs; + char * argbuf[64]; + char ** argv; + char ** envp; + int result; + + assert(filename != NULL); + assert(*filename != '\0'); + assert(arglist != NULL); + assert(*arglist != '\0'); + + va_start(vargs, arglist); + argv = _capture_argv(&vargs, arglist, argbuf, 64); + envp = va_arg(vargs, char **); + va_end(vargs); + + result = _execvpe(filename,argv,envp); + if (argv && argv != argbuf) free(argv); + return result; +} diff --git a/private/crt32/exec/execv.c b/private/crt32/exec/execv.c new file mode 100644 index 000000000..a369e3738 --- /dev/null +++ b/private/crt32/exec/execv.c @@ -0,0 +1,60 @@ +/*** +*execv.c - execute a file +* +* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* defines _execv() - execute a file +* +*Revision History: +* 10-14-83 RN written +* 12-11-87 JCR Added "_LOAD_DS" to declaration +* 11-20-89 GJF Fixed copyright, indents. Added const attribute to +* types of filename and argvector. +* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE1, added #include +* and removed #include +* 07-24-90 SBM Removed redundant includes, replaced by +* +* 09-27-90 GJF New-style function declarator. +* 01-17-91 GJF ANSI naming. +* 02-14-90 SRW Use NULL instead of _environ to get default. +* +*******************************************************************************/ + +#include +#include +#include +#include + +/*** +*int _execv(filename, argvector) - execute a file +* +*Purpose: +* Executes a file with given arguments. Passes arguments to _execve and +* uses pointer to the default environment. +* +*Entry: +* char *filename - file to execute +* char **argvector - vector of arguments. +* +*Exit: +* destroys calling process (hopefully) +* if fails, returns -1 +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE1 _execv ( + const char *filename, + const char * const *argvector + ) +{ + assert(filename != NULL); + assert(*filename != '\0'); + assert(argvector != NULL); + assert(*argvector != NULL); + assert(**argvector != '\0'); + + return(_execve(filename,argvector,NULL)); +} diff --git a/private/crt32/exec/execve.c b/private/crt32/exec/execve.c new file mode 100644 index 000000000..386ed4d0f --- /dev/null +++ b/private/crt32/exec/execve.c @@ -0,0 +1,2 @@ +#define EXECVE +#include "spawnve.c" diff --git a/private/crt32/exec/execvp.c b/private/crt32/exec/execvp.c new file mode 100644 index 000000000..f6b94de8b --- /dev/null +++ b/private/crt32/exec/execvp.c @@ -0,0 +1,62 @@ +/*** +*execvp.c - execute a file and search along PATH +* +* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* defines _execvp() - execute a file and search along PATH +* +*Revision History: +* 10-17-83 RN written +* 10-29-85 TC added execvpe capability +* 12-11-87 JCR Added "_LOAD_DS" to declaration +* 11-20-89 GJF Fixed copyright, indents. Added const attribute to +* types of filename and argvector. +* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE1, added #include +* and removed #include +* 05-21-90 GJF Fixed stack checking pragma syntax. +* 08-24-90 SBM Removed check_stack pragma since workhorse execve +* does stack checks +* 09-27-90 GJF New-style function declarator. +* 01-17-91 GJF ANSI naming. +* 02-14-90 SRW Use NULL instead of _environ to get default. +* +*******************************************************************************/ + +#include +#include +#include + +/*** +*int _execvp(filename, argvector) - execute file; search along PATH +* +*Purpose: +* Execute the given file with given path and current environ. +* try to execute the file. start with the name itself (directory '.'), +* and if that doesn't work start prepending pathnames from the +* environment until one works or we run out. if the file is a pathname, +* don't go to the environment to get alternate paths. if errno comes +* back ENOEXEC, try it as a shell command file with up to MAXARGS-2 +* arguments from the original vector. if a needed text file is busy, +* wait a little while and try again before despairing completely +* Actually calls _execvpe() to do all the work. +* +*Entry: +* char *filename - file to execute +* char **argvector - vector of arguments +* +*Exit: +* destroys the calling process (hopefully) +* if fails, returns -1 +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE1 _execvp ( + REG3 const char *filename, + const char * const *argvector + ) +{ + return _execvpe( filename, argvector, NULL ); +} diff --git a/private/crt32/exec/execvpe.c b/private/crt32/exec/execvpe.c new file mode 100644 index 000000000..650f34b2a --- /dev/null +++ b/private/crt32/exec/execvpe.c @@ -0,0 +1,171 @@ +/*** +*execvpe.c - execute a file with given environ; search along PATH +* +* Copyright (c) 1985-1992, Microsoft Corporation. All rights reserved. +* +*Purpose: +* defines _execvpe() - execute a file with given environ +* +*Revision History: +* 10-17-83 RN written +* 10-29-85 TC added execvpe capability +* 11-19-86 SKS handle both kinds of slashes +* 12-01-86 JMB added Kanji file name support under conditional KANJI +* switches, corrected header info +* removed bogus check for env = b after call to strncpy(). +* 12-11-87 JCR Added "_LOAD_DS" to declaration +* 09-05-88 SKS Treat EACCES the same as ENOENT -- keep trying +* 10-18-88 GJF Removed copy of PATH string to local array, changed +* bbuf to be a malloc-ed buffer. Removed bogus limits +* on the size of that PATH string. +* 10-26-88 GJF Don't search PATH when relative pathname is given (per +* Stevesa). Also, if the name built from PATH component +* and filename is a UNC name, allow any error. +* 11-20-89 GJF Fixed copyright. Added const attribute to types of +* filename, argvector and envptr. Also, added "#include +* " under KANJI switch (same as 5-17-89 change +* to CRT version). +* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE1, added #include +* and removed #include . Also, +* cleaned up the formatting a bit. +* 07-24-90 SBM Removed redundant includes, replaced by +* +* 09-27-90 GJF New-style function declarator. +* 01-17-91 GJF ANSI naming. +* 11-30-92 KRS Port _MBCS code from 16-bit tree. +* +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#define SLASH "\\" +#define SLASHCHAR '\\' +#define XSLASHCHAR '/' +#define DELIMITER ";" + +#ifdef _MBCS +/* note, the macro below assumes p is to pointer to a single-byte character + * or the 1st byte of a double-byte character, in a string. + */ +#define ISPSLASH(p) ( ((p) == _mbschr((p), SLASHCHAR)) || ((p) == \ +_mbschr((p), XSLASHCHAR)) ) +#else +#define ISSLASH(c) ( ((c) == SLASHCHAR) || ((c) == XSLASHCHAR) ) +#endif + + +/*** +*int _execvpe(filename, argvector, envvector) - execute a file +* +*Purpose: +* Executes a file with given arguments and environment. +* try to execute the file. start with the name itself (directory '.'), +* and if that doesn't work start prepending pathnames from the +* environment until one works or we run out. if the file is a pathname, +* don't go to the environment to get alternate paths. If a needed text +* file is busy, wait a little while and try again before despairing +* completely +* +*Entry: +* char *filename - file to execute +* char **argvector - vector of arguments +* char **envvector - vector of environment variables +* +*Exit: +* destroys the calling process (hopefully) +* if fails, returns -1 +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE1 _execvpe ( + REG3 const char *filename, + const char * const *argvector, + const char * const *envptr + ) +{ + REG1 char *env; + char *bbuf = NULL; + REG2 char *buf; + char *pfin; + + assert(filename != NULL); + assert(*filename != '\0'); + assert(argvector != NULL); + assert(*argvector != NULL); + assert(**argvector != '\0'); + + _execve(filename,argvector,envptr); + + /* In a SBCS build, _mbschr will map to strchr. */ + + if ( (errno != ENOENT) + || (_mbschr(filename, SLASHCHAR) != NULL) + || (_mbschr(filename, XSLASHCHAR) != NULL) + || *filename && *(filename+1) == ':' + || !(env=getenv("PATH")) ) + goto reterror; + + /* allocate a buffer to hold alternate pathnames for the executable + */ + if ( (buf = bbuf = (char *)malloc(_MAX_PATH)) == NULL ) goto reterror; + + do { + /* copy a component into bbuf[], taking care not to overflow it + */ + /* UNDONE: make sure ';' isn't 2nd byte of DBCS char */ + while ( (*env) && (*env != ';') && (buf < bbuf+_MAX_PATH-2) ) + *buf++ = *env++; + + *buf = '\0'; + pfin = --buf; + buf = bbuf; + +#ifdef _MBCS + if (*pfin == SLASHCHAR) { + if (pfin != _mbsrchr(buf,SLASHCHAR)) + /* *pfin is the second byte of a double-byte + * character + */ + strcat( buf, SLASH ); + } + else if (*pfin != XSLASHCHAR) + strcat(buf, SLASH); +#else + if (*pfin != SLASHCHAR && *pfin != XSLASHCHAR) + strcat(buf, SLASH); +#endif + + /* check that the final path will be of legal size. if so, + * build it. otherwise, return to the caller (return value + * and errno rename set from initial call to _execve()). + */ + if ( (strlen(buf) + strlen(filename)) < _MAX_PATH ) + strcat(buf, filename); + else + break; + + _execve(buf, argvector, envptr); + + if ( (errno != ENOENT) +#ifdef _MBCS + && (!ISPSLASH(buf) || !ISPSLASH(buf+1)) ) +#else + && (!ISSLASH(*buf) || !ISSLASH(*(buf+1))) ) +#endif + break; + } while ( *env && env++ ); + +reterror: + if (bbuf != NULL) + free(bbuf); + + return(-1); +} diff --git a/private/crt32/exec/fileinfo.c b/private/crt32/exec/fileinfo.c new file mode 100644 index 000000000..c617cf8c4 --- /dev/null +++ b/private/crt32/exec/fileinfo.c @@ -0,0 +1,22 @@ +/*** +*fileinfo.c - sets C file info flag +* +* Copyright (c) 1989-1992, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Sets the C file info flag. By default, the openfile information +* is NOT passed along to children on spawn/exec calls. If the flag +* is set, openfile information WILL get passed on to children on +* spawn/exec calls. +* +*Revision History: +* 06-07-89 PHG Module created, based on asm version +* 04-03-90 GJF Added #include . Also, fixed the copyright. +* 01-23-92 GJF Added #include (contains decl of _fileinfo). +* +*******************************************************************************/ + +#include +#include + +int _fileinfo = -1; diff --git a/private/crt32/exec/getproc.c b/private/crt32/exec/getproc.c new file mode 100644 index 000000000..2cb78323e --- /dev/null +++ b/private/crt32/exec/getproc.c @@ -0,0 +1,62 @@ +/*** +*getproc.c - Get the address of a procedure in a DLL. +* +* Copyright (c) 1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* defines _getdllprocadd() - gets a procedure address by name or +* ordinal +* +*Revision History: +* 08-21-91 BWM Wrote module. +* +*******************************************************************************/ + +#include +#include +#include + +#if !defined(_WIN32_) +#error ERROR - ONLY WIN32 TARGET SUPPORTED! +#endif + +/*** +*int (*)() _getdllprocaddr(handle, name, ordinal) - Get the address of a +* DLL procedure specified by name or ordinal +* +*Purpose: +* +*Entry: +* int handle - a DLL handle from _loaddll +* char * name - Name of the procedure, or NULL to get by ordinal +* int ordinal - Ordinal of the procedure, or -1 to get by name +* +* +*Exit: +* returns a pointer to the procedure if found +* returns NULL if not found +* +*Exceptions: +* +*******************************************************************************/ + +int (_CALLTYPE1 * _CALLTYPE1 _getdllprocaddr(int hMod, + char * szProcName, + int iOrdinal))() +{ + typedef int (_CALLTYPE1 * PFN)(); + + if (szProcName == NULL) { + if (iOrdinal <= 65535) { + return ((PFN)GetProcAddress((HANDLE)hMod, (LPSTR)iOrdinal)); + } + } + else { + if (iOrdinal == -1) { + return ((PFN)GetProcAddress((HANDLE)hMod, szProcName)); + } + } + + return (NULL); + +} diff --git a/private/crt32/exec/loaddll.c b/private/crt32/exec/loaddll.c new file mode 100644 index 000000000..a6f41b7e2 --- /dev/null +++ b/private/crt32/exec/loaddll.c @@ -0,0 +1,70 @@ +/*** +*loaddll.c - load or free a Dynamic Link Library +* +* Copyright (c) 1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* defines _loaddll() and _unloaddll() - load and unload DLL +* +*Revision History: +* 08-21-91 BWM Wrote module. +* +*******************************************************************************/ + +#include +#include +#include +#include +#include + +#if !defined(_WIN32_) +#error ERROR - ONLY WIN32 TARGET SUPPORTED! +#endif + +/*** +*int _loaddll(filename) - Load a dll +* +*Purpose: +* Load a DLL into memory +* +*Entry: +* char *filename - file to load +* +*Exit: +* returns a unique DLL (module) handle if succeeds +* returns 0 if fails +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE1 _loaddll(char * szName) +{ + return ((int)LoadLibrary(szName)); +} + +/*** +*int _unloaddll(handle) - Unload a dll +* +*Purpose: +* Unloads a DLL. The resources of the DLL will be freed if no other +* processes are using it. +* +*Entry: +* int handle - handle from _loaddll +* +*Exit: +* returns 0 if succeeds +* returns DOS error if fails +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE1 _unloaddll(int hMod) +{ + if (!FreeLibrary((HANDLE)hMod)) { + return ((int)GetLastError()); + } + return (0); +} diff --git a/private/crt32/exec/makefile b/private/crt32/exec/makefile new file mode 100644 index 000000000..6ee4f43fa --- /dev/null +++ b/private/crt32/exec/makefile @@ -0,0 +1,6 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/crt32/exec/sources b/private/crt32/exec/sources new file mode 100644 index 000000000..ed4f1c187 --- /dev/null +++ b/private/crt32/exec/sources @@ -0,0 +1,58 @@ +!IF 0 + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + This file specifies the target component being built and the list of + sources files needed to build that component. Also specifies optional + compiler switches and libraries that are unique for the component being + built. + + +Author: + + Steve Wood (stevewo) 12-Apr-1990 + jeffrob 29-sep-1990, use crt32.def + +NOTE: Commented description of this file is in \nt\bak\bin\sources.tpl + +!ENDIF + +MAJORCOMP=crt +MINORCOMP=exec + +TARGETNAME=exec +TARGETPATH=..\obj +TARGETTYPE=LIBRARY +386_STDCALL=0 + +!INCLUDE ..\crt32.def + +SOURCES=cenvarg.c \ + fileinfo.c \ + dospawn.c \ + execl.c \ + execle.c \ + execlp.c \ + execlpe.c \ + execv.c \ + execve.c \ + execvp.c \ + execvpe.c \ + getproc.c \ + loaddll.c \ + spawnl.c \ + spawnle.c \ + spawnlp.c \ + spawnlpe.c \ + spawnv.c \ + spawnve.c \ + spawnvp.c \ + spawnvpe.c \ + system.c \ + wait.c diff --git a/private/crt32/exec/spawnl.c b/private/crt32/exec/spawnl.c new file mode 100644 index 000000000..826e5be46 --- /dev/null +++ b/private/crt32/exec/spawnl.c @@ -0,0 +1,83 @@ +/*** +*spawnl.c - spawn a child process +* +* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* defines _spawnl() - spawn a child process +* +*Revision History: +* 04-15-84 DFW Re-do to correspond to similar exec call format +* 12-11-87 JCR Added "_LOAD_DS" to declaration +* 11-20-89 GJF Fixed copyright, alignment. Added const to arg types +* for pathname and arglist. #include-d PROCESS.H and +* added ellipsis to match prototype. +* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE2 and added #include +* . +* 07-24-90 SBM Removed redundant includes, replaced by +* +* 09-27-90 GJF New-style function declarator. +* 01-17-91 GJF ANSI naming. +* 02-14-90 SRW Use NULL instead of _environ to get default. +* 07-16-93 SRW ALPHA Merge +* +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +/*** +*int _spawnl(modeflag, pathname, arglist) - spawn a child process +* +*Purpose: +* Spawns a child process. +* formats the parameters and calls spawnve to do the actual work. The +* new process will inherit the parent's environment. NOTE - at least +* one argument must be present. This argument is always, by convention, +* the name of the file being spawned. +* +*Entry: +* int modeflag - defines which mode of spawn (WAIT, NOWAIT, or OVERLAY) +* only WAIT and OVERLAY are currently implemented +* char *pathname - file to be spawned +* char *arglist - list of argument +* call as _spawnl(modeflag, path, arg0, arg1, ..., argn, NULL); +* +*Exit: +* returns exit code of child process +* returns -1 if fails +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE2 _spawnl ( + int modeflag, + const char *pathname, + const char *arglist, + ... + ) +{ + va_list vargs; + char * argbuf[64]; + char ** argv; + int result; + + assert(pathname != NULL); + assert(*pathname != '\0'); + assert(arglist != NULL); + assert(*arglist != '\0'); + + va_start(vargs, arglist); + argv = _capture_argv(&vargs, arglist, argbuf, 64); + va_end(vargs); + + result = _spawnve(modeflag,pathname,argv,NULL); + if (argv && argv != argbuf) free(argv); + return result; +} diff --git a/private/crt32/exec/spawnle.c b/private/crt32/exec/spawnle.c new file mode 100644 index 000000000..5b09417f2 --- /dev/null +++ b/private/crt32/exec/spawnle.c @@ -0,0 +1,83 @@ +/*** +*spawnle.c - spawn a child process with given environment +* +* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* defines _spawnle() - spawn a child process with given environ +* +*Revision History: +* 04-15-84 DFW written +* 12-11-87 JCR Added "_LOAD_DS" to declaration +* 11-20-89 GJF Fixed copyright, alignment. Added const to arg types +* for pathname and arglist. #include-d PROCESS.H and +* added ellipsis to match prototype +* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE2, added #include +* and removed #include +* 07-24-90 SBM Removed redundant includes, replaced by +* +* 09-27-90 GJF New-style function declarator. +* 01-17-91 GJF ANSI naming. +* 07-16-93 SRW ALPHA Merge +* +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +/*** +*int _spawnle(modeflag, pathname, arglist) - spawn a child process with env. +* +*Purpose: +* Spawns a child process with given parameters and environment. +* formats the parameters and calls _spawnve to do the actual work. +* NOTE - at least one argument must be present. This argument is always, +* by convention, the name of the file being spawned. +* +*Entry: +* int modeflag - mode of spawn (WAIT, NOWAIT, OVERLAY) +* only WAIT, and OVERLAY currently implemented +* char *pathname - name of file to spawn +* char *arglist - argument list, environment is at the end +* call as _spawnle(modeflag, path, arg0, arg1, ..., argn, NULL, envp); +* +*Exit: +* returns exit code of spawned process +* if fails, return -1 +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE2 _spawnle ( + int modeflag, + const char *pathname, + const char *arglist, + ... + ) +{ + va_list vargs; + char * argbuf[64]; + char ** argv; + char ** envp; + int result; + + assert(pathname != NULL); + assert(*pathname != '\0'); + assert(arglist != NULL); + assert(*arglist != '\0'); + + va_start(vargs, arglist); + argv = _capture_argv(&vargs, arglist, argbuf, 64); + envp = va_arg(vargs, char **); + va_end(vargs); + + result = _spawnve(modeflag,pathname,argv,envp); + if (argv && argv != argbuf) free(argv); + return result; +} diff --git a/private/crt32/exec/spawnlp.c b/private/crt32/exec/spawnlp.c new file mode 100644 index 000000000..22516c929 --- /dev/null +++ b/private/crt32/exec/spawnlp.c @@ -0,0 +1,85 @@ +/*** +*spawnlp.c - spawn a file; search along PATH +* +* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* defines _spawnlp() - spawn a file with search along PATH +* +*Revision History: +* 04-15-84 DFW written +* 10-29-85 TC added spawnlpe +* 12-11-87 JCR Added "_LOAD_DS" to declaration +* 11-20-89 GJF Fixed copyright, alignment. Added const to arg types +* for filename and arglist. #include-d PROCESS.H and +* added ellipsis to match prototype. +* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE2 and added #include +* . +* 07-24-90 SBM Removed redundant includes, replaced by +* +* 09-27-90 GJF New-style function declarator. +* 01-17-91 GJF ANSI naming. +* 07-16-93 SRW ALPHA Merge +* +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +/*** +*_spawnlp(modeflag, filename, arglist) - spawn file and search along PATH +* +*Purpose: +* Spawns a child process. +* formats the parameters and calls _spawnvp to do the work of searching +* the PATH environment variable and calling _spawnve. The NULL +* environment pointer indicates that the new process will inherit the +* parents process's environment. NOTE - at least one argument must be +* present. This argument is always, by convention, the name of the file +* being spawned. +* +*Entry: +* int modeflag - mode of spawn (WAIT, NOWAIT, OVERLAY) +* only WAIT, OVERLAY currently implemented +* char *pathname - file to spawn +* char *arglist - argument list +* call as _spawnlp(modeflag, path, arg0, arg1, ..., argn, NULL); +* +*Exit: +* returns exit code of child process +* returns -1 if fails +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE2 _spawnlp ( + int modeflag, + const char *filename, + const char *arglist, + ... + ) +{ + va_list vargs; + char * argbuf[64]; + char ** argv; + int result; + + assert(filename != NULL); + assert(*filename != '\0'); + assert(arglist != NULL); + assert(*arglist != '\0'); + + va_start(vargs, arglist); + argv = _capture_argv(&vargs, arglist, argbuf, 64); + va_end(vargs); + + result = _spawnvp(modeflag,filename,argv); + if (argv && argv != argbuf) free(argv); + return result; +} diff --git a/private/crt32/exec/spawnlpe.c b/private/crt32/exec/spawnlpe.c new file mode 100644 index 000000000..10520aecb --- /dev/null +++ b/private/crt32/exec/spawnlpe.c @@ -0,0 +1,87 @@ +/*** +*spawnlpe.c - spawn a child process with environ and search along PATH +* +* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* defines _spawnlpe() - spawn a child process with environ/PATH search +* +*Revision History: +* 04-15-84 DFW written +* 10-29-85 TC added spawnlpe +* 12-11-87 JCR Added "_LOAD_DS" to declaration +* 11-20-89 GJF Fixed copyright, alignment. Added const to arg types +* for filename and arglist. #include-d PROCESS.H and +* added ellipsis to match prototype. +* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE2, added #include +* and removed #include . +* 07-24-90 SBM Removed redundant includes, replaced by +* +* 09-27-90 GJF New-style function declarator. +* 01-17-91 GJF ANSI naming. +* 07-16-93 SRW ALPHA Merge +* +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +/*** +*int _spawnlpe(modeflag, filename, arglist) - spawn a child process +* +*Purpose: +* Spawns a child process. +* formats the parameters and calls _spawnvpe to do the work of searching +* the PATH environment variable and calling _spawnve. The NULL +* environment pointer indicates that the new process will inherit the +* parents process's environment. NOTE - at least one argument must be +* present. This argument is always, by convention, the name of the file +* being spawned. +* +*Entry: +* int modeflag - defines what mode of spawn (WAIT, NOWAIT, OVERLAY) +* only WAIT and OVERLAY currently supported +* char *pathname - file to spawn +* char *arglist - list of arguments (environ at end) +* call as _spawnlpe(modeflag, path, arg0, arg1, ..., argn, NULL, envp); +* +*Exit: +* returns exit code of spawned process +* returns -1 if fails +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE2 _spawnlpe ( + int modeflag, + const char *filename, + const char *arglist, + ... + ) +{ + va_list vargs; + char * argbuf[64]; + char ** argv; + char ** envp; + int result; + + assert(filename != NULL); + assert(*filename != '\0'); + assert(arglist != NULL); + assert(*arglist != '\0'); + + va_start(vargs, arglist); + argv = _capture_argv(&vargs, arglist, argbuf, 64); + envp = va_arg(vargs, char **); + va_end(vargs); + + result = _spawnvpe(modeflag,filename,argv,envp); + if (argv && argv != argbuf) free(argv); + return result; +} diff --git a/private/crt32/exec/spawnv.c b/private/crt32/exec/spawnv.c new file mode 100644 index 000000000..fe90c213f --- /dev/null +++ b/private/crt32/exec/spawnv.c @@ -0,0 +1,67 @@ +/*** +*spawnv.c - spawn a child process +* +* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* defines _spawnv() - spawn a child process +* +*Revision History: +* 04-15-84 DFW written +* 12-11-87 JCR Added "_LOAD_DS" to declaration +* 11-20-89 GJF Fixed copyright, alignment. Added const to arg types +* for pathname and argv. +* 03-08-90 GJF Replace _LOAD_DS with _CALLTYPE1 and added #include +* . +* 07-24-90 SBM Removed redundant includes, replaced by +* +* 09-27-90 GJF New-style function declarator. +* 01-17-91 GJF ANSI naming. +* 02-14-90 SRW Use NULL instead of _environ to get default. +* +*******************************************************************************/ + +#include +#include +#include +#include + +/*** +*int _spawnv(modeflag, pathname, argv) - spawn a child process +* +*Purpose: +* Spawns a child process. +* formats the parameters and calls _spawnve to do the actual work. The +* NULL environment pointer indicates that the new process will inherit +* the parents process's environment. NOTE - at least one argument must +* be present. This argument is always, by convention, the name of the +* file being spawned. +* +*Entry: +* int modeflag - mode to spawn (WAIT, NOWAIT, or OVERLAY) +* only WAIT and OVERLAY currently implemented +* char *pathname - file to spawn +* char **argv - vector of arguments +* +*Exit: +* returns exit code of child process +* if fails, returns -1 +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE1 _spawnv ( + int modeflag, + const char *pathname, + const char * const *argv + ) +{ + assert(pathname != NULL); + assert(*pathname != '\0'); + assert(argv != NULL); + assert(*argv != NULL); + assert(**argv != '\0'); + + return(_spawnve(modeflag,pathname,argv,NULL)); +} diff --git a/private/crt32/exec/spawnve.c b/private/crt32/exec/spawnve.c new file mode 100644 index 000000000..00e321dd2 --- /dev/null +++ b/private/crt32/exec/spawnve.c @@ -0,0 +1,318 @@ +/*** +*spawnve.c - OS/2 low level routine eventually called by all _spawnXX routines +* also contains all code for _execve, called by _execXX routines +* +* Copyright (c) 1985-1992, Microsoft Corporation. All rights reserved. +* +*Purpose: +* +* This is the low level routine which is eventually invoked by all the +* _spawnXX routines. +* +* This is also the low-level routine which is eventually invoked by +* all of the _execXX routines. +* +*Revision History: +* 03-??-84 RLB created +* 05-??-84 DCW modified to fix bug in initialization of envblock +* pointer (used int 0 which would fail in long model) and +* changed (char *)0 to NULL. +* 03-31-86 SKS modified for OS/2; no OVERLAY mode, +* new format for DOS Exec function +* also check for Xenix or DOS style slash characters +* 10-13-86 SKS pass program name to _cenvarg() +* 11-19-86 SKS handle both kinds of slashes, with support for Kanji +* 01-29-87 BCM don't try ".com" extension in protected mode (OS/2) +* 12-11-87 JCR Added "_LOAD_DS" to declaration +* 05/31/88 SJM Re-written to allow spawn of .CMD files, increase +* speed. Added comexecmd routine. +* 06/01/88 SJM added #ifdef statements for execve.obj compilation +* 10-30-88 GJF Call _dospawn() for EXECVE, not _doexec(). +* 07-21-89 GJF Progagated fixes of 11-23-88 and 05-27-89 from CRT tree. +* 11-16-89 GJF Added code to execve/spawnve to ensure a relative or +* or absolute pathname is always used for the executable, +* not just a filename (otherwise DOSEXECPGM will search +* the PATH!). Also, cleaned up some of the erratic +* formatting. Same as 9-15-89 change to CRT version +* 11-20-89 GJF Added const attribute to types of appropriate args. +* 02-08-90 GJF Fixed bug in comexecmd (must free(comname) if and only +* if comname points to a malloc-ed block). Propagated +* from 02-07-90 change in crt6 version. +* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE1, added #include +* and removed #include . +* 04-02-90 GJF Made comexecmd() _CALLTYPE4. Added #include +* and a prototype for comexecmd() to fix compiler +* warnings (-W3). +* 05-21-90 GJF Fixed stack checking pragma syntax. +* 07-24-90 SBM Removed redundant include, minor optimization +* 09-27-90 GJF New-style function declarators. +* 12-28-90 SRW Added _CRUISER_ conditional around check_stack pragma +* 01-17-91 GJF ANSI naming. +* 08-21-91 JCR Call access() in before comexecmd (bug fix) +* 01-24-92 JCR upgraded for Win32 +* 10-24-92 SKS Remove special treatment for batch files - +* Windows NT will spawn %COMSPEC% automatically +* 11-30-92 KRS Ported _MBCS support from 16-bit tree. +* +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _CRUISER_ +#pragma check_stack(on) /* turn on stack checking */ +#endif /* ndef _CRUISER_ */ + +#define SLASHCHAR '\\' +#define XSLASHCHAR '/' + +#ifndef EXECVE +static int _CALLTYPE4 comexecmd(int mode, const char * name, + const char * const * argv, const char * const * envp); +#else +static int _CALLTYPE4 comexecmd(const char * name, + const char * const * argv, const char * const * envp); +#endif /* EXECVE */ + +/*** +*static int comexecmd(mode, name, argv, envp) - do the exec +* or spawn after name fixup +* +*Purpose: +* Spawns a child process with given parameters and environment. Either +* overlays current process or loads in free memory while parent process +* waits. If the named file is a .cmd file, modifies the calling sequence +* and prepends the /c and filename arguments into the command string +* +* Exec doesn't take a mode; instead, the parent process goes away as +* the child process is brought in. +* +*Entry: +* int mode - mode to spawn (WAIT, NOWAIT, or OVERLAY) +* only WAIT and OVERLAY currently supported +* +* **** mode is only used in the spawnve() version **** +* +* char *name - pathname of file to spawn. Includes the extension +* char **argv - vector of parameter strings +* char **envp - vector of environment variables +* +*Exit: +* returns exit code of child process +* if fails, returns -1 +* +*Exceptions: +* Returns a value of (-1) to indicate an error in exec'ing the child +* process. errno may be set to: +* +* E2BIG = failed in argument/environment processing (_cenvarg) +* argument list or environment too big; +* EACCESS = locking or sharing violation on file; +* EMFILE = too many files open; +* ENOENT = failed to find program name - no such file or directory; +* ENOEXEC = failed in exec - bad executable format; +* ENOMEM = failed in memory allocation (during malloc, or in +* setting up memory for executing child process). +* +*******************************************************************************/ + +static int _CALLTYPE4 comexecmd ( + +#ifndef EXECVE + REG3 int mode, +#endif /* EXECVE */ + + REG2 const char *name, + const char * const *argv, + const char * const *envp + ) +{ + char *argblk; + char *envblk; + REG4 int rc; + + if (_cenvarg(argv, envp, &argblk, &envblk, name) == -1) + return -1; + +#ifndef EXECVE + rc = _dospawn(mode, name, argblk, envblk); +#else + rc = _dospawn(_P_OVERLAY, name, argblk, envblk); +#endif + /* free memory */ + + free(argblk); + free(envblk); + + return rc; +} + +/*** +*int _spawnve(mode, name, argv, envp) - low level _spawnXX library function +*int _execve(name, argv, envp) - low level _execXX library function +* +*Purpose: +* spawns or execs a child process; takes a single pointer to an argument +* list as well as a pointer to the environment; unlike _spawnvpe, +* _spawnve does not search the PATH= list in processing the name +* parameter; mode specifies the parent's execution mode. +* +*Entry: +* int mode - parent process's execution mode: +* must be one of _P_OVERLAY, _P_WAIT, _P_NOWAIT; +* not used for _execve +* char *name - path name of program to spawn; +* char **argv - pointer to array of pointers to child's arguments; +* char **envp - pointer to array of pointers to child's environment +* settings. +* +*Exit: +* Returns : (int) a status value whose meaning is as follows: +* 0 = normal termination of child process; +* positive = exit code of child upon error termination +* (abort or exit(nonzero)); +* -1 = child process was not spawned; +* errno indicates what kind of error: +* (E2BIG, EINVAL, ENOENT, ENOEXEC, ENOMEM). +* +*Exceptions: +* Returns a value of (-1) to indicate an error in spawning the child +* process. errno may be set to: +* +* E2BIG = failed in argument/environment processing (_cenvarg) - +* argument list or environment too big; +* EINVAL = invalid mode argument; +* ENOENT = failed to find program name - no such file or directory; +* ENOEXEC = failed in spawn - bad executable format; +* ENOMEM = failed in memory allocation (during malloc, or in +* setting up memory for spawning child process). +* +*******************************************************************************/ + +/* Extension array - ordered in search order from right to left. + + ext_strings = array of extensions +*/ + +#ifdef _CRUISER_ +static char *ext_strings[] = { NULL, ".exe", ".com" }; +enum {CMD, EXE, COM, EXTFIRST=CMD, EXTLAST=COM}; +#else +static char *ext_strings[] = { ".cmd", ".bat", ".exe" , ".com" }; +enum {CMD, BAT, EXE, COM, EXTFIRST=CMD, EXTLAST=COM}; +#endif + +int _CALLTYPE1 + +#ifndef EXECVE + +_spawnve ( + REG3 int mode, + +#else + +_execve ( + +#endif /* EXECVE */ + + const char *name, + const char * const *argv, + const char * const *envp + ) +{ + char *ext; /* where the extension goes if we have to add one */ + REG1 char *p; + char *q; + REG2 char *pathname = (char *)name; + REG4 int rc; + REG5 int i; + +#ifdef _CRUISER_ + exstrings[CMD] = _osmode ? ".cmd" : ".bat"; +#endif + + p = _mbsrchr(pathname, SLASHCHAR); + q = strrchr(pathname, XSLASHCHAR); /* No need for _mbsrchr with "/" */ + + /* ensure that pathname is an absolute or relative pathname. also, + * position p to point at the filename portion of pathname (i.e., just + * after the last occurence of a colon, slash or backslash character */ + + if (!q) { + if (!p) + if (!(p = strchr(pathname, ':'))) { + + /* pathname is a filename only, force it to be + * a relative pathname. note that an extra byte + * is malloc-ed just in case pathname is NULL, + * to keep the heap from being trashed by + * strcpy */ + if (!(pathname = malloc(strlen(pathname) + 3))) + return(-1); + + strcpy(pathname, ".\\"); + strcat(pathname, name); + + /* set p to point to the start of the filename + * (i.e., past the ".\\" prefix) */ + p = pathname + 2; + } + /* else pathname has drive specifier prefix and p is + * is pointing to the ':' */ + } + else if (!p || q > p) /* p == NULL or q > p */ + p = q; + + + rc = -1; /* init to error value */ + + if (ext = strrchr(p, '.')) { + + /* extension given; only do filename */ + + if (_access(pathname, 0) != -1) { +#ifndef EXECVE + rc = comexecmd(mode, pathname, argv, envp); +#else + rc = comexecmd(pathname, argv, envp); +#endif + } + + } + else { + + /* no extension; try .cmd/.bat, then .com and .exe */ + + if (!(p = malloc(strlen(pathname) + 5))) + return(-1); + + strcpy(p, pathname); + ext = p + strlen(pathname); + + for (i = EXTLAST; i >= EXTFIRST; --i) { + strcpy(ext, ext_strings[i]); + + if (_access(p, 0) != -1) { +#ifndef EXECVE + rc = comexecmd(mode, p, argv, envp); +#else + rc = comexecmd(p, argv, envp); +#endif /* EXECVE */ + break; + } + } + free(p); + } + + if (pathname != name) + free(pathname); + + return rc; +} diff --git a/private/crt32/exec/spawnvp.c b/private/crt32/exec/spawnvp.c new file mode 100644 index 000000000..f31dc2c60 --- /dev/null +++ b/private/crt32/exec/spawnvp.c @@ -0,0 +1,62 @@ +/*** +*spawnvp.c - spawn a child process; search along PATH +* +* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* defines _spawnvp() - spawn a child process; search along PATH +* +*Revision History: +* 04-15-84 DFW written +* 10-29-85 TC added spawnvpe capability +* 12-11-87 JCR Added "_LOAD_DS" to declaration +* 11-20-89 GJF Fixed copyright, alignment. Added const to arg types +* for filename and argv. +* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE1, added #include +* and removed #include +* 05-21-90 GJF Fixed stack checking pragma syntax. +* 08-24-90 SBM Removed check_stack pragma since workhorse _spawnve +* does stack checks +* 09-27-90 GJF New-style function declarator. +* 01-17-91 GJF ANSI naming. +* 02-14-90 SRW Use NULL instead of _environ to get default. +* +*******************************************************************************/ + +#include +#include +#include + +/*** +*int _spawnvp(modeflag, filename, argv) - spawn a child process (search PATH) +* +*Purpose: +* Spawns a child process, with search along PATH variable. +* formats the parameters and calls _spawnve to do the actual work. The +* NULL environment pointer indicates the new process will inherit the +* parents process's environment. NOTE - at least one argument must be +* present. This argument is always, by convention, the name of the file +* being spawned. +* +*Entry: +* int modeflag - mode to spawn (WAIT, NOWAIT, or OVERLAY) +* only WAIT and OVERLAY currently supported +* char *pathname - name of file to spawn +* char **argv - vector of arguments +* +*Exit: +* returns exit code of child process +* returns -1 if fails +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE1 _spawnvp ( + int modeflag, + REG3 const char *filename, + const char * const *argv + ) +{ + return _spawnvpe(modeflag, filename, argv, NULL); +} diff --git a/private/crt32/exec/spawnvpe.c b/private/crt32/exec/spawnvpe.c new file mode 100644 index 000000000..ffbdbb55a --- /dev/null +++ b/private/crt32/exec/spawnvpe.c @@ -0,0 +1,209 @@ +/*** +*spawnvpe.c - spawn a child process with given environ (search PATH) +* +* Copyright (c) 1985-1992, Microsoft Corporation. All rights reserved. +* +*Purpose: +* defines _spawnvpe() - spawn a child process with given environ (search +* PATH) +* +*Revision History: +* 04-15-84 DFW written +* 10-29-85 TC added spawnvpe capability +* 11-19-86 SKS handle both kinds of slashes +* 12-01-86 JMB added Kanji file name support under conditional KANJI +* switches. Corrected header info. Removed bogus check +* for env = b after call to strncpy +* 12-11-87 JCR Added "_LOAD_DS" to declaration +* 09-05-88 SKS Treat EACCES the same as ENOENT -- keep trying +* 10-17-88 GJF Removed copy of PATH string to local array, changed +* bbuf to be a malloc-ed buffer. Removed bogus limits +* on the size of that PATH string. +* 10-25-88 GJF Don't search PATH when relative pathname is given (per +* Stevesa). Also, if the name built from PATH component +* and filename is a UNC name, allow any error. +* 05-17-89 MT Added "include " under KANJI switch +* 05-24-89 PHG Reduce _amblksiz to use minimal memory (DOS only) +* 08-29-89 GJF Use _getpath() to retrieve PATH components, fixing +* several problems in handling unusual or bizarre +* PATH's. +* 11-20-89 GJF Added const attribute to types of filename, argv and +* envptr. +* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE1, added #include +* and removed #include +* 07-24-90 SBM Removed redundant includes, replaced by +* +* 09-27-90 GJF New-style function declarator. +* 01-17-91 GJF ANSI naming. +* 09-25-91 JCR Changed ifdef "OS2" to "_DOS_" (unused in 32-bit tree) +* 11-30-92 KRS Port _MBCS code from 16-bit tree. +* +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SLASH "\\" +#define SLASHCHAR '\\' +#define XSLASHCHAR '/' +#define DELIMITER ";" + +#ifdef _MBCS +/* note, the macro below assumes p is to pointer to a single-byte character + * or the 1st byte of a double-byte character, in a string. + */ +#define ISPSLASH(p) ( ((p) == _mbschr((p), SLASHCHAR)) || ((p) == \ +_mbschr((p), XSLASHCHAR)) ) +#else +#define ISSLASH(c) ( ((c) == SLASHCHAR) || ((c) == XSLASHCHAR) ) +#endif + +/*** +*_spawnvpe(modeflag, filename, argv, envptr) - spawn a child process +* +*Purpose: +* Spawns a child process with the given arguments and environ, +* searches along PATH for given file until found. +* Formats the parameters and calls _spawnve to do the actual work. The +* NULL environment pointer indicates that the new process will inherit +* the parents process's environment. NOTE - at least one argument must +* be present. This argument is always, by convention, the name of the +* file being spawned. +* +*Entry: +* int modeflag - defines mode of spawn (WAIT, NOWAIT, or OVERLAY) +* only WAIT and OVERLAY supported +* char *filename - name of file to execute +* char **argv - vector of parameters +* char **envptr - vector of environment variables +* +*Exit: +* returns exit code of spawned process +* if fails, returns -1 +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE1 _spawnvpe ( + int modeflag, + REG3 const char *filename, + const char * const *argv, + const char * const *envptr + ) +{ + int i; + REG1 char *env; + REG2 char *buf = NULL; + char *pfin; +#ifdef _DOS_ + int tempamblksiz; /* old _amblksiz */ +#endif + assert(filename != NULL); + assert(*filename != '\0'); + assert(argv != NULL); + assert(*argv != NULL); + assert(**argv != '\0'); + +#ifdef _DOS_ + tempamblksiz = _amblksiz; + _amblksiz = 0x10; /* reduce _amblksiz for efficient mallocs */ +#endif + + if ( + (i = _spawnve(modeflag, filename, argv, envptr)) != -1 + /* everything worked just fine; return i */ + + || (errno != ENOENT) + /* couldn't spawn the process, return failure */ + + /* In a SBCS build, _mbschr will map to strchr. */ + + || (_mbschr(filename, XSLASHCHAR) != NULL) + /* filename contains a '/', return failure */ + +#ifdef _DOS_ + || (_mbschr(filename,SLASHCHAR) != NULL) + /* filename contains a '\', return failure */ + + || *filename && *(filename+1) == ':' + /* drive specification, return failure */ +#endif + + || !(env = getenv("PATH")) + /* no PATH environment string name, return failure */ + + || ( (buf = (char *)malloc(_MAX_PATH)) == NULL ) + /* cannot allocate buffer to build alternate pathnames, return + * failure */ + ) { +#ifdef _DOS_ + _amblksiz = tempamblksiz; /* restore old _amblksiz */ +#endif + goto done; + } + +#ifdef _DOS_ + _amblksiz = tempamblksiz; /* restore old _amblksiz */ +#endif + + + /* could not find the file as specified, search PATH. try each + * component of the PATH until we get either no error return, or the + * error is not ENOENT and the component is not a UNC name, or we run + * out of components to try. + */ + + while ( (env = _getpath(env, buf, _MAX_PATH - 1)) && (*buf) ) { + + pfin = buf + strlen(buf) - 1; + + /* if necessary, append a '/' + */ +#ifdef _MBCS + if (*pfin == SLASHCHAR) { + if (pfin != _mbsrchr(buf,SLASHCHAR)) + /* fin is the second byte of a double-byte char */ + strcat(buf, SLASH ); + } + else if (*pfin !=XSLASHCHAR) + strcat(buf, SLASH); +#else + if (*pfin != SLASHCHAR && *pfin != XSLASHCHAR) + strcat(buf, SLASH); +#endif + /* check that the final path will be of legal size. if so, + * build it. otherwise, return to the caller (return value + * and errno rename set from initial call to _spawnve()). + */ + if ( (strlen(buf) + strlen(filename)) < _MAX_PATH ) + strcat(buf, filename); + else + break; + + /* try spawning it. if successful, or if errno comes back with a + * value other than ENOENT and the pathname is not a UNC name, + * return to the caller. + */ + if ( (i = _spawnve(modeflag, buf, argv, envptr)) != -1 + || ((errno != ENOENT) +#ifdef _MBCS + && (!ISPSLASH(buf) || !ISPSLASH(buf+1))) ) +#else + && (!ISSLASH(*buf) || !ISSLASH(*(buf+1)))) ) +#endif + break; + + } + +done: + if (buf != NULL) free(buf); + return(i); +} diff --git a/private/crt32/exec/system.c b/private/crt32/exec/system.c new file mode 100644 index 000000000..44536cf38 --- /dev/null +++ b/private/crt32/exec/system.c @@ -0,0 +1,95 @@ +/*** +*system.c - pass a command line to the shell +* +* Copyright (c) 1985-1993, Microsoft Corporation. All rights reserved. +* +*Purpose: +* defines system() - passes a command to the shell +* +*Revision History: +* 12-01-83 RN written +* 10-23-86 SKS Fixed use of strtok(), added check for NULL rtn from getenv +* 12-18-86 SKS PROTMODE symbol used for dual-modal version +* 02-23-86 JCR Put in support for NULL command pointer (MSDOS only) +* 04-13-86 JCR Added const to declaration +* 06-30-87 JCR Re-wrote system to use spawnvpe, removed XENIX conditional +* code, lots of general cleaning up. +* 07-01-87 PHG removed P->PROTMODE compile switch hack +* 09-22-87 SKS remove extern variable declarations, add ";" to assert()'s +* 11-10-87 SKS Removed IBMC20 switch, change PROTMODE to OS2 +* 12-11-87 JCR Added "_LOAD_DS" to declaration +* 02-22-88 JCR Added cast to get rid of cl const warning +* 09-05-88 SKS Treat EACCES the same as ENOENT -- keep trying +* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE1, added #include +* , removed some leftover DOS support and +* fixed the copyright. Also, cleaned up the formatting +* formatting a bit. +* 07-23-90 SBM Compiles cleanly with -W3 (removed unreferenced +* variable), removed redundant includes, replaced +* by , minor optimizations +* 09-27-90 GJF New-style function declarator. +* 01-17-91 GJF ANSI naming. +* 02-14-90 SRW Use NULL instead of _environ to get default. +* 02-23-93 SKS Remove reference to _osmode and use of "command.com" +* +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include + +/*** +*int system(command) - send the command line to a shell +* +*Purpose: +* Executes a shell and passes the command line to it. +* If command is NULL, determine if a command processor exists. +* +*Entry: +* char *command - command to pass to the shell (if NULL, just determine +* if command processor exists) +* +*Exit: +* if command != NULL returns status of the shell +* if command == NULL returns non-zero if CP exists, zero if CP doesn't exist +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE1 system ( + const char *command + ) +{ + int catch; + char *argv[4]; + + argv[0] = getenv("COMSPEC"); + + if (command == NULL) { + return (!_access(argv[0],0)); + } + + assert(*command != '\0'); + + argv[1] = "/c"; + argv[2] = (char *) command; + argv[3] = NULL; + + /* If there is a COMSPEC defined, try spawning the shell */ + + if (argv[0]) /* Do not try to spawn the null string */ + if ((catch = _spawnve(_P_WAIT,argv[0],argv,NULL)) != -1 + || (errno != ENOENT && errno != EACCES)) + return(catch); + + /* No COMSPEC so set argv[0] to what COMSPEC should be. */ + argv[0] = "cmd.exe"; + + /* Let the _spawnvpe routine do the path search and spawn. */ + + return(_spawnvpe(_P_WAIT,argv[0],argv,NULL)); +} diff --git a/private/crt32/exec/wait.c b/private/crt32/exec/wait.c new file mode 100644 index 000000000..c6ba4cae4 --- /dev/null +++ b/private/crt32/exec/wait.c @@ -0,0 +1,199 @@ +/*** +*wait.c - OS/2 wait for child process to terminate +* +* Copyright (c) 1989-1993, Microsoft Corporation. All rights reserved. +* +*Purpose: +* defines _wait() - wait for child process to terminate +* +*Revision History: +* 06-08-89 PHG Module created, based on asm version +* 03-08-90 GJF Made calling type _CALLTYPE2 (for now), added #include +* and fixed the copyright. Also, cleaned up +* the formatting a bit. +* 04-02-90 GJF Now _CALLTYPE1. +* 07-24-90 SBM Removed '32' from API names +* 09-27-90 GJF New-style function declarators. +* 12-04-90 SRW Changed to include instead of +* 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals. +* 01-17-91 GJF ANSI naming +* 02-18-91 SRW Fixed code to close process handle. [_WIN32_] +* 04-26-91 SRW Removed level 3 warnings [_WIN32_] +* 12-17-91 GJF Fixed _cwait for Win32. However, _wait is still +* broken [_WIN32_]. +* 07-21-92 GJF Removed _wait for Win32, not implemented and no good +* way to implement. +* 12-14-92 GJF For Win32, map ERROR_INVALID_HANDLE to ECHILD. +* +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include + +/*** +*int _cwait(stat_loc, process_id, action_code) - wait for specific child +* process +* +*Purpose: +* The function _cwait() suspends the calling-process until the specified +* child-process terminates. If the specifed child-process terminated +* prior to the call to _cwait(), return is immediate. +* +*Entry: +* int *stat_loc - pointer to where status is stored or NULL +* process_id - specific process id to be interrogated (0 means any) +* action_code - specific action to perform on process ID +* either _WAIT_CHILD or _WAIT_GRANDCHILD +* +*Exit: +* process ID of terminated child or -1 on error +* +* *stat_loc is updated to contain the following: +* Normal termination: lo-byte = 0, hi-byte = child exit code +* Abnormal termination: lo-byte = term status, hi-byte = 0 +* +*Exceptions: +* +*******************************************************************************/ + +int _CRTAPI1 _cwait ( + int *stat_loc, + int process_id, + int action_code + ) +{ +#ifdef _CRUISER_ + ULONG retstatus; /* return status from child */ + ULONG retval; /* return value from wait */ + char abnormend; /* child terminated abnormally */ + ULONG dosretval; /* return value from OS/2 call */ + RESULTCODES retcodes; /* return codes from child process */ + PID pid_finished; /* process id of child that finished */ + + /* call OS/2 wait for child routine */ + if (dosretval = DOSWAITCHILD(action_code, DCWW_WAIT, &retcodes, + &pid_finished, process_id)) { + /* error occured -- map error code and return */ + _dosmaperr(dosretval); + return -1; + } + + /* set status code values -- note that return value is + truncated to a byte for XENIX compatibility */ + + if (retcodes.codeTerminate != 0) { + abnormend = 1; + retstatus = retcodes.codeTerminate & 0xFF; + } + else { + abnormend = 0; + retstatus = (retcodes.codeResult & 0xFF) << 8 + + (retcodes.codeTerminate & 0xFF); + } + + if (stat_loc != NULL) + *stat_loc = retstatus; + + if (abnormend) { + /* abnormal termination, set errno and return -1 */ + errno = EINTR; + _doserrno = 0; /* no OS/2 error */ + return -1; + } + + return retval; + +#else /* ndef _CRUISER_ */ + +#ifdef _WIN32_ + + int retval; + int retstatus; + unsigned long oserror; + + DBG_UNREFERENCED_PARAMETER(action_code); + + /* Explicitly check for process_id being -1 or -2. In Windows NT, + * -1 is a handle on the current process, -2 is a handle on the + * current thread, and it is perfectly legal to to wait (forever) + * on either */ + if ( (process_id == -1) || (process_id == -2) ) { + errno = ECHILD; + return -1; + } + + /* wait for child process, then fetch its exit code */ + if ( (WaitForSingleObject((HANDLE)process_id, (DWORD)(-1L)) == 0) && + GetExitCodeProcess((HANDLE)process_id, (LPDWORD)&retstatus) ) { + retval = process_id; + } + else { + /* one of the API calls failed. map the error and set up to + return failure. note the invalid handle error is mapped in- + line to ECHILD */ + if ( (oserror = GetLastError()) == ERROR_INVALID_HANDLE ) { + errno = ECHILD; + _doserrno = oserror; + } + else + _dosmaperr(GetLastError()); + + retval = -1; + retstatus = -1; + } + + CloseHandle((HANDLE)process_id); + + if (stat_loc != NULL) + *stat_loc = retstatus; + + return retval; + +#else /* ndef _WIN32_ */ + +#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED! + +#endif /* _WIN32_ */ + +#endif /* _CRUISER_ */ +} + + +#ifndef _WIN32_ + +/*** +*int _wait(stat_loc) - wait for a child to terminate +* +*Purpose: +* The function _wait() suspends the calling-process until one of the +* immediate children terminates. If a child-process terminated prior to +* the call on the function _wait(), return is immediate. +* +*Entry: +* int *stat_loc - pointer to where status is stored or NULL +* +*Exit: +* returns process id or -1 on errors. +* +* *stat_loc is updated to contain the following: +* Normal termination: lo-byte = 0, hi-byte = child exit code +* Abnormal termination: lo-byte = term status, hi-byte = 0 +* +*Exceptions: +* +*******************************************************************************/ + +/* _wait calls _cwait to do all the real work */ +int _CRTAPI1 _wait ( + int *stat_loc + ) +{ + return _cwait(stat_loc, 0, _WAIT_CHILD); +} + + +#endif diff --git a/private/crt32/h/assert.h b/private/crt32/h/assert.h new file mode 100644 index 000000000..944ba02b4 --- /dev/null +++ b/private/crt32/h/assert.h @@ -0,0 +1,89 @@ +/*** +*assert.h - define the assert macro +* +* Copyright (c) 1985-1993, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Defines the assert(exp) macro. +* [ANSI/System V] +* +*Revision History: +* 12-18-87 JCR Added _FAR_ to declarations +* 01-18-88 JCR Added fflush(stderr) to go with new stderr buffering scheme +* 02-10-88 JCR Cleaned up white space +* 05-19-88 JCR Use routine _assert() to save space +* 07-14-88 JCR Allow user's to enable/disable assert multiple times in +* a single module [ANSI] +* 10-19-88 JCR Revised to also work for the 386 (small model only) +* 12-22-88 JCR Assert() must be an expression (no 'if' statements) +* 05-03-89 JCR Added _INTERNAL_IFSTRIP for relinc usage +* 07-27-89 GJF Cleanup, now specific to the 386 +* 10-30-89 GJF Fixed copyright +* 11-02-89 JCR Changed "DLL" to "_DLL" +* 02-27-90 GJF Added #include stuff. Also, removed some +* (now) useless preprocessor directives. +* 03-21-90 GJF Replaced _cdecl with _CALLTYPE1 in prototype. +* 07-31-90 SBM added ((void)0) to NDEBUG definition, now ANSI +* 08-20-91 JCR C++ and ANSI naming +* 08-26-92 GJF Function calling type and variable type macros. +* 09-25-92 SRW Don't use ? in assert macro to keep CFRONT happy. +* 01-21-93 GJF Removed support for C6-386's _cdecl. +* 02-01-93 GJF Replaced SteveWo's assert macro with an ANSI-conformant +* one. Also got rid of '//' comment characters. +* +****/ + +#ifndef _INTERNAL_IFSTRIP_ +#include +#endif /* _INTERNAL_IFSTRIP_ */ + +/* + * Conditional macro definition for function calling type and variable type + * qualifiers. + */ +#if ( (_MSC_VER >= 800) && (_M_IX86 >= 300) ) + +/* + * Definitions for MS C8-32 (386/486) compiler + */ +#define _CRTAPI1 __cdecl +#define _CRTAPI2 __cdecl + +#else + +/* + * Other compilers (e.g., MIPS) + */ +#define _CRTAPI1 +#define _CRTAPI2 + +#endif + +#undef assert + +#ifdef NDEBUG + +#define assert(exp) ((void)0) + +#else + +#ifdef __cplusplus +extern "C" { +#endif +void _CRTAPI1 _assert(void *, void *, unsigned); +#ifdef __cplusplus +} +#endif + +#define assert(exp) (void)( (exp) || (_assert(#exp, __FILE__, __LINE__), 0) ) + +#ifndef _INTERNAL_IFSTRIP_ +/* + * CFRONT chokes on ? if uses on a cdecl function call. So use if + * for now, until we convert to c8 + * + * ( (exp) ? (void) 0 : _assert(#exp, __FILE__, __LINE__) ) + */ +#endif /* _INTERNAL_IFSTRIP_ */ + +#endif /* NDEBUG */ diff --git a/private/crt32/h/cmacros.mas b/private/crt32/h/cmacros.mas new file mode 100644 index 000000000..a39638c24 --- /dev/null +++ b/private/crt32/h/cmacros.mas @@ -0,0 +1,3050 @@ +comment $ + + SCCSID = "@(#)cmacros.mas:1.12" + +cmacros - assembly macros for interfacing to hhls + +(C)Copyright Microsoft Corp. 1984-1987 + +$ + +;; Revision History +;; +;; 1.00 05/03/84 Initial Release +;; +;; 1.01 05/06/84 Greg Whitten +;; Added defgrp and changed cMerge to Microsoft C +;; Added copyright message and changed to 1.01 +;; Changes should have no affect on working programs +;; +;; 1.02 07/10/84 Steve Wood +;; Added labelx macros +;; +;; 1.03 07/14/84 Greg Whitten +;; Added defines for ?pu, ?adj, ?lblpu +;; (removes undefined errors) +;; Changes should have no affect on working programs +;; +;; 1.04 07/18/84 Greg Whitten +;; Added local control from PL/M or C conventions +;; except for cCall macro +;; +;; 1.05 08/06/84 Steve Wood +;; Made ?PLM and ?WIN be the defaults +;; +;; 1.06 01/02/85 Steve Wood +;; Changed createSeg and defgrp to automatically +;; define the ln_assumes macro and the lnoffset +;; and lnbase equates for each logical segment +;; name. +;; +;; 1.07 02/19/85 Walt Moore +;; Added farptr macro for defining a far pointer +;; to be used in a cCall. Folded regptr into +;; farptr. Space compaction in macros. Changed +;; ?pp to be smaller. Moved ?ia out of ?al1 into +;; ?aloc. Merged cProc and ?pd into one macro. +;; Changed some %outs to use the error macro so +;; an error would be generated. Added makeframe +;; and parmR to cProc. Changed error to also put +;; the error message in the listing. +;; Deleted the smashes macro. +;; +;; 1.08 03/18/85 Steve Wood +;; Added NODATA support. +;; +;; 1.09 03/27/85 Steve Wood +;; Added ?definitions +;; +;; 2.00 04/01/85 Steve Wood +;; April fools +;; +;; 2.01 06/17/85 Steve Wood +;; Changed NODATA to always generate POP DS +;; for return address patching +;; +;; 2.02 02/11/86 Steve Wood +;; Added ATOMIC keyword to cProc macro +;; Changed far epilog to use LEA SP,BP-2 +;; Changed error macro to ??error to avoid +;; conflict +;; +;; 2.03 03/06/86 Steve Wood +;; Fixed bug with ATOMIC and locals in far proc +;; Added DOS5 switch to disable INC/DEC BP +;; instructions in special far prologs/epilogs +;; +;; 2.04 08/07/86 Scott Randell +;; Fixed bug with ATOMIC and ?TF +;; (was doing unnecessary MOV SP,BP) +;; Added pcode profile ?PROFILE +;; +;; 2.05 08/12/86 Walt Moore +;; Changed _TEXT alignment to word. +;; Added/corrected some comments. +;; Removed redundant init of ?pc in cProc +;; Made ATOMIC require NODATA +;; Moved definition of non-underscored 'C' label +;; from the cProc to the cBegin macro +;; Minor clean-up of code +;; +;; 2.06 09/11/86 Walt Moore +;; Added private stack checking +;; Put local control for PL/M or C into cCall +;; +;; +;; 2.07 09/19/86 Steve Wood +;; Added ?SMALL, ?MEDIUM, etc. symbols +;; Added forceframe keyword to cProc macro. +;; Interpret ?TF for all epilogs. +;; +;; 3.xx.a 02/26/87 Walt Moore +;; Massive rework. Documentation coming. +;; +;; 3.xx.b 04/08/87 NeilK +;; Added parmH, which is like parmW except +;; that it reserves 4 bytes on frame. +;; +;; 3.xx.c 05/11/87 Walt Moore +;; Added <> to ?ap so that arg +;; can be used. +;; +;; 3.01 07/03/87 Walt Moore +;; parm_bytes_&procname is now generated for +;; all cProcs, and is the number of bytes of +;; parameters to the cProc. +;; +;; NO_BP added as a keyword to cProc which +;; causes all equates to be generated without +;; reference to BP for the procedure. All type +;; info is still generated, but the user must +;; supply any segment and base register. +;; ?NO_BP, if defined, makes this the default. +;; +;; USE_BP can be specified on the cProc line +;; to force the generation of BP in equates. +;; +;; Moved definition of xxxxBASE. The equ was to +;; a forward reference. +;; +;; Don't generate a warning for a nogen if only +;; parameters are present. +;; +;; Keywords for cProc, cBegin, cEnd, and registers +;; are now allowed to be either all upper case or +;; all lower case. +;; +;; Only generate warnings on pass 2. +;; +;; 3.02 07/06/87 Walt Moore +;; Boy did I screw up If the text is +;; recognized as nogen, then process it as such, +;; else ignore it and generate frame as needed. +;; +;; 3.03 07/14/87 Walt Moore +;; Added keyword to the cBegin macro +;; to only allocate locals and save registers. +;; Used in conjunction with dispatching in the +;; Winthorn engine and drivers. +;; +;; Added cleanframe macro which will take the +;; frame down, but not generate the RET statement. +;; Used in conjunction with dispatching in the +;; Winthorn engine and drivers. +;; +;; 3.04 07/16/87 Walt Moore +;; globalD was generating off and seg name +;; without word ptr override, giving them a +;; dword attribute +;; +;; 3.05 07/17/87 Walt Moore +;; .xcref cleanframe +;; +;; 3.06 07/24/87 Hans Spiller +;; 32 bit small model (?SMALL32): +;; new entry exit sequences using pseudoregs +;; mach independant register names (IAX, etc) +;; parmI/localI (int size variables) +;; mpush/mpop uses mach independant names +;; IPUSHF, IPOPF, IPUSHA,IPOPA,IIRET +;; +;; case sensitivity bugfix. the compiler +;; generates "CODE", not "Code" +;; +;; 32 bit issues as yet undone: allocation +;; macros for dealing with 32 bit mode far +;; pointers, globalI, staticI, parmR, saving +;; si,di vs. esi,edi,ebx +;; +;; 3.06a 09/29/87 Mark Roberts +;; 32 bit small model (?SMALL32): +;; fix a few bugs and add staticI +;; +;; 3.06b 07/20/87 Scott Randell +;; Fix up for ?COW compatibility, added ?NOATOMIC +;; to 3.xx version. +;; +;; 3.06c 04/29/88 Jim Schaad +;; Put in ?DFDATA to force data segments even if +;; ?NODATA is set. +;; +;; 3.06d 05/02/88 Andy Padawer +;; Bug fixes for 3.06b (cEnd), 3.06c (general). +;; +;; 3.06e 08/31/88 Andy Padawer +;; use "if memS32" not "ifdef ?SMALL32". +;; +;; 3.06f 05/12/89 Mark Roberts +;; fix staticI, globalDP and add globalI +;; +;; 3.06g 12/07/89 Mark Roberts +;; add externI +;; +;; 3.06h 01/25/90 Jan de Rie +;; add ?DFCODE to allow suppressing code segments +;; +;; Assembly macros for interfacing to C +;; +;; User settable conditional assembly flags used within the cmacros +;; +;; Memory model flags. Set only one of the following. memS is the +;; default. The symbols with ? are for defining from the command line +;; and the memx symbols are numeric symbols that can be set in your source +;; file prior to including this file. +;; +;; ?SMALL memS - small model +;; ?MEDIUM memM - medium model +;; ?LARGE memL - large model +;; ?COMPACT memC - compact model +;; ?HUGE memH - huge model +;; ?SMALL32 memS32 - 32 bit small model +;; +;; ?DF Define flag. If this flag is 0, then defines default segment +;; and group definitions based on the compiler flag. If this +;; flag is 1, then does not define any segments or groups. +;; +;; ?DFDATA Define Data Flag. If this flag is 0, then defines default +;; data segment and group definitions based on compiler flag. +;; If this flag is 1, then does not define any data segments +;; or groups. +;; +;; ?DFCODE Define Code Flag. If this flag is 0, then defines default +;; code segments based on the compiler flag. If this flag is 1, +;; then does not define the code segments. Inactive if +;; ?DF is 1. +;; +;; ?TF Tight flag. If this flag is 0, then use longer epilog +;; sequence that safely cleans up a stack frame. If this flag is +;; 1, then use more efficient epilog that assumes the stack is +;; valid (SP) +;; +;; ?WIN Windows flag. Enables generation of special prolog/epilog +;; for far procedures. Default value is 1 (Windows). +;; +;; ?COW Character Windows flag. To be used in conjunction with ?WIN, +;; If defined will not save DS for ?NODATA far prolog/epilog +;; (CW does not modify the DS on the stack). +;; +;; DOS5 If defined, then special far prolog/epilog seqeuences will not +;; include the INC/DEC BP instructions. +;; +;; ?PLM Calling convention flag. If this flag is 0, then the +;; calling convention used is that of C. If this flag +;; is 1, then the PL/M calling convention is used. +;; The default value is 1. The PL/M calling convention +;; is used by pascal, fortran, basic, and cobol. +;; +;; In the C calling convention, arguments are passed +;; in reverse order; arg0 is the last pushed, argn is the +;; first pushed. also, it is the callers responsibility +;; to remove the arguments from the stack upon a return +;; from a call. +;; +;; In the PL/M calling comvention, arguments are passed +;; as encountered; arg0 is the first pushed, argn is the +;; last pushed. also, it is the called procedure's +;; responsibility to remove parameters from the stack +;; before returning (using the RET n instruction) +;; +;; ?NODATA If defined, then no data segment or DGROUP is defined and +;; the special prolog/epilog sequences will not contain the +;; code needed to setup DS. +;; +;; ?CHKSTK If defined, then prolog sequences for cProcs with local +;; parameters will call the CHKSTK procedure to allocate +;; the stack space. +;; +;; ?CHKSTKPROC If defined, then this macro will be invoked to +;; perform the stack checking, otherwise the +;; standard stack checking procedure will be +;; performed. ?CHKSTKPROC must be declared +;; before the cmacros are included in the source +;; else the standard chkstk routine will be declared +;; as an external symbol. +;; +;; On entry to the user's stack checking procedure, +;; the frame has been setup except for allocating +;; local variable space and saving autosave registers. +;; +;; The user supplied macro is passed as an argument +;; the number of byte of stack space requested. +;; +;; ?PROFILE If defined then all far cBegin entries will have StartNMeas, +;; and all cEnd will have StopNMeas calls, StartNMeas and +;; StopNMeas will be defined as externfp +;; +;; ?NOPARMR If defined, then the "parmR" macro will not be defined. +;; +;; ?NOGLOBAL If defined, then the "globalx" macros will not be defined. +;; +;; ?NOSTATIC If defined, then the "staticx" macros will not be defined. +;; +;; ?NOEXTERN If defined, then the "externx" macros will not be defined. +;; +;; ?NOLABEL If defined, then the "labelx" macros will not be defined. +;; +;; ?NODEF If defined, then the "defx" macros will not be defined. +;; +;; ?NOPTR If defined, then "farptr & regptr" will not be defined. +;; +;; ?QUIET If defined, then only error messages will be issued to +;; the console. If undefined, then certain cmacro text will +;; be generated to the console. +;; +;; ?NOATOMIC If defined, then ATOMIC will be ignored (for giving real +;; frames to all procedures (and profiling). +;; +;; ?NO_BP If defined, then equates generated for parms and locals +;; will not explicitly reference BP. +;; IAX, ICX, IDX, IBX, ISP, IBP, ISI, IDI +;; these pseudo registers expand to either ax..., or eax... +;; depending upon 32bit mode being enabled. they should be +;; used whenever a pointer or integer is being used in order +;; to make source code machine independant + + + +.xcref ;;Get rid of a lot of symbols + + +; ??_out - output given message to the console unless ?QUIET has +; been specified. +; +; usage: +; ??_out +; +; where: +; is the message to output + +.xcref ??_out +??_out macro t + ifndef ?QUIET + %out t + endif +endm + + + +; outif - output msg if name is non-zero. if name is undefined, +; set name = 0, else set name to the default value. +; +; usage: +; outif name,defval,onmsg,offmsg +; where: +; name name of symbol +; defval default value to give symbol if not defined +; if blank, then 0 will be used +; onmsg text to display if symbol is non-zero +; offmsg test to be displayed if symbol is zero + + +outif macro name,defval,onmsg,offmsg + ifndef name + ifb + name=0 + else + name=defval + endif + endif + if name + name=1 + ifnb + ??_out + endif + else + ifnb + ??_out + endif + endif +endm + + + +; ??error - output msg and generate an assembly time error +; on regardess of assembler pass +; usage: +; ??error +; where: +; t is the text to be output + + +.xcref ??error +??error macro msg + %out e r r o r ----- msg ;;to console + .err e r r o r ----- msg ;;forced error by assembler +endm + + +; ??error2 - output msg and generate an assembly time error +; on pass 2 only +; usage: +; ??error2 +; where: +; t is the text to be output + + +.xcref ??error2 +??error2 macro msg + if2 + %out e r r o r ----- msg ;;to console + .err e r r o r ----- msg ;;forced error by assembler + endif +endm + + +.xcref ASMpass +.xcref memS,memM,memL,memC,memH,memMOD,sizec,sized,memS32,sizeI,wordI + +;if1 ;;Only on pass 1 + ASMpass=1 + ifdef ?SMALL ;;inform user what is going on + memS=1 + endif + ifdef ?MEDIUM + memM=1 + endif + ifdef ?COMPACT + memC=1 + endif + ifdef ?LARGE + memL=1 + endif + ifdef ?HUGE + memH=1 + endif + ifdef ?SMALL32 + memS32=1 + endif + ifdef ?FLAT32 + memF32=1 + endif + + ??_out + ??_out + outif memS,0, + outif memM,0, + outif memL,0, + outif memC,0, + outif memH,0, + outif memS32,0,<32 Bit Small Model> + outif memF32,0,<32 Bit Flat Model> + + memMOD= memS + memM + memL + memC + memH + memS32 + if memMOD ne 1 + if memMOD eq 0 + memS = 1 ; assume small model + outif memS,0, + else + ??error + endif + endif + + sizec= memM + memL + memH ; large code + sized= memL + memC + (memH*2) ; large data (2 if huge) + ;; note that memS32 is used generaly to indicate 32 bitness. I + ;; doubt very much whether anyone will ever do other models in + ;; 32 bit code... + if memS32 + sizeI = 4 ; size of a push + wordI equ + asmdI equ
+ else + sizeI = 2 + wordI equ + asmdI equ + endif + + outif ?DF,0, + outif ?DFDATA,0, + outif ?DFCODE,0, + outif ?TF,0, + outif ?WIN,1, + outif ?COW,0, + outif ?PLM,1, + outif ?NOATOMIC,0, + outif ?NODATA,0, + + ife ?NODATA + ?nodata1=0 + else + ?nodata1=1 + endif + + ifndef ?CHKSTK + ?chkstk1=0 + else + ?chkstk1=1 + ifdef ?CHKSTKPROC + ??_out + else + ??_out + endif + endif + + ifndef DOS5 + ?DOS5=0 + else + ?DOS5=1 + ??_out + endif + + ifdef ?PROFILE + ??_out + endif + + ifndef ?NO_BP + ?no_bp1=0 + else + ?no_bp1=1 + ??_out + endif +;else + ASMpass=2 +;endif + +;; define pseudo registers and instructions for 386/8086 independance +if memS32 + .386 + IAX equ + ICX equ + IDX equ + IBX equ + ISP equ + IBP equ + ISI equ + IDI equ + IPUSHF equ pushfd + IPOPF equ popfd + IPUSHA equ pushad + IPOPA equ popad + IIRET equ iretd +else + IAX equ + ICX equ + IDX equ + IBX equ + ISP equ + IBP equ + ISI equ + IDI equ + IPUSHF equ pushf + IPOPF equ popf +; IPUSHA equ pusha +; IPOPA equ popa + IIRET equ iret +endif + +;; Initialize all symbols used in the macros. Theses symbols will not be +;; included in any cross reference listing. + + .xcref ?n,?ax,?ah,?al,?bx,?bh + .xcref ?bl,?cx,?ch,?cl,?dx,?dh + .xcref ?dl,?si,?di,?es,?ds,?bp + .xcref ?sp,?ss,?cs + .xcref ?n,?AX,?AH,?AL,?BX,?BH + .xcref ?BL,?CX,?CH,?CL,?DX,?DH + .xcref ?DL,?SI,?DI,?ES,?DS,?BP + .xcref ?SP,?SS,?CS + .xcref ?EAX,?EBX,?ECX,?EDX,?ESI,?EDI,?ESP,?EBP + .xcref ?eax,?ebx,?ecx,?edx,?esi,?edi,?esp,?ebp + .xcref ?IAX,?IBX,?ICX,?IDX,?ISI,?IDI,?ISP,?IBP + + .xcref ?rsl,?cpd,?argl,?argc,?ba + .xcref ?acb,???,?po + .xcref ?pas,?pc + + .xcref uconcat,mpush,mpop + .xcref ?ri,?pp,?pp1,?al1 + .xcref ?ad,?ap,?atal,?dd,?dd1,?dd2 + .xcref ?pg,?pg1,?aloc,?cs1,?cs2 + .xcref ?DF,?TF,?ff,?PLM,?WIN,?ia,?pu,?adj + .xcref ?uf,?rp,?nx,?nd,?nodata1,?chkstk1,?DOS5 + .xcref ?wfp,arg,cCall,cProc,assumes,?cs3,?cs2,?cs1 + .xcref defgrp,addseg,createSeg + .xcref save,outif,errnz,errn$,errnz1 + .xcref ?PLMPrevParm,?gcc + .xcref ?cCall1,?pcc,?no_bp1,?no_bp2 + .xcref ?cbe,?pcbe + + + +;; conditionals set by the macros +;; +;; ?pc Procedure class. If this is set to 1, then the procedure +;; is a far procedure, else it is a near procedure. +;; +;; ?ia Interface adjustment count for far procedures. The +;; interface adjustment defines the number of bytes of +;; storage allocated between BP and the first frame variable +;; allocated on the stack. +;; +;; Normally zero, it will be adjusted for both far windows +;; procedures and by register parameters. +;; +;; ?cpd Current procedure defined. This is set to a non-zero +;; value if a procedure is being defined (i.e a cProc has +;; been encountered, and cBegin has not). +;; +;; ?ba Begin active. This is set to a non-zero value if a +;; cBegin is active (i.e. a cBegin has been encountered, +;; and cEnd has not). +;; +;; ?wfp Windows far procedure. Set if a windows far procedure +;; +;; ?pcc procedure calling conventing. Calling convention for +;; this procedure. May be different than the default set +;; via ?PLM +;; +;; +;; Other variables that are defined once so that the .xcref command +;; doesn't get too upset if they show up missing! + +?rsl = 0 ;;0 = no register to save +?cpd = 0 ;;<> 0 if in a procedure definition +?argl = 0 ;;length of arguments pushed on stack +?argc = 0 ;;# of arguments so far +?ba = 0 ;;<>0 if in a procedure (xbegin) +?acb = 0 ;;number of arguments to a call +??? = 0 ;;byte count of local storage +?po = 0 ;;byte count of parameters +?pas = 0 ;;autosave value for procedure +?pc = 0 ;;class of a procedure (near/far) +?ia = 0 ;;no adjustment +?pu = 0 ;;public flag for some macros +?adj = 0 ;;initial define for .xcref +?rp = 0 ;;count of register parameters +?uf = 0 ;;user's frame code specified +?nd = 0 ;;NODATA keyword specified +?nx = 0 ;;ATOMIC keyword specified +?wfp = 0 ;;window far procedure +?ff = 0 ;;forceframe keyword specified +?dd2 = 0 ;;used for globalx and staticx +?cCall1 = 0 ;;used for cCalls +?pcc = ?PLM ;;procedure calling convention +?PLMPrevParm = 0 ;;Used in parameter processing +?no_bp2 = ?no_bp1 ;;BP / No BP flag +?cbe = 0 ;;cbegin/cEnd keyword flag + + .xcref ?casen +if1 ;;only define ?casen on pass 1 +?casen = 0 ;;case sensitive assembly if <> 0 +endif + + + +?n = 0000000000000000b ;;register none +?ax = 0000000000000011b ;;register ax +?ah = 0000000000000001b ;;register ah +?al = 0000000000000010b ;;register al +?bx = 0000000000001100b ;;register bx +?bh = 0000000000000100b ;;register bh +?bl = 0000000000001000b ;;register bl +?cx = 0000000000110000b ;;register cx +?ch = 0000000000010000b ;;register ch +?cl = 0000000000100000b ;;register cl +?dx = 0000000011000000b ;;register dx +?dh = 0000000001000000b ;;register dh +?dl = 0000000010000000b ;;register dl +?si = 0000000100000000b ;;register si +?di = 0000001000000000b ;;register di +?es = 0000010000000000b ;;register es +?ds = 0000100000000000b ;;register ds +?bp = 0001000000000000b ;;register bp +?sp = 0010000000000000b ;;register sp +?ss = 0100000000000000b ;;register ss +?cs = 1000000000000000b ;;register cs + ;;Incase we're case sensitive +?AX = 0000000000000011b ;;register ax +?AH = 0000000000000001b ;;register ah +?AL = 0000000000000010b ;;register al +?BX = 0000000000001100b ;;register bx +?BH = 0000000000000100b ;;register bh +?BL = 0000000000001000b ;;register bl +?CX = 0000000000110000b ;;register cx +?CH = 0000000000010000b ;;register ch +?CL = 0000000000100000b ;;register cl +?DX = 0000000011000000b ;;register dx +?DH = 0000000001000000b ;;register dh +?DL = 0000000010000000b ;;register dl +?SI = 0000000100000000b ;;register si +?DI = 0000001000000000b ;;register di +?ES = 0000010000000000b ;;register es +?DS = 0000100000000000b ;;register ds +?BP = 0001000000000000b ;;register bp +?SP = 0010000000000000b ;;register sp +?SS = 0100000000000000b ;;register ss +?CS = 1000000000000000b ;;register cs + +?EAX = 0000000000000011b ;;register ax +?EBX = 0000000000001100b ;;register bx +?ECX = 0000000000110000b ;;register cx +?EDX = 0000000011000000b ;;register dx +?ESI = 0000000100000000b ;;register si +?EDI = 0000001000000000b ;;register di +?EBP = 0001000000000000b ;;register bp +?ESP = 0010000000000000b ;;register sp + +?eax = 0000000000000011b ;;register ax +?ebx = 0000000000001100b ;;register bx +?ecx = 0000000000110000b ;;register cx +?edx = 0000000011000000b ;;register dx +?esi = 0000000100000000b ;;register si +?edi = 0000001000000000b ;;register di +?ebp = 0001000000000000b ;;register bp +?esp = 0010000000000000b ;;register sp + +?IAX = 0000000000000011b ;;register ax +?IBX = 0000000000001100b ;;register bx +?ICX = 0000000000110000b ;;register cx +?IDX = 0000000011000000b ;;register dx +?ISI = 0000000100000000b ;;register si +?IDI = 0000001000000000b ;;register di +?IBP = 0001000000000000b ;;register bp +?ISP = 0010000000000000b ;;register sp + + .cref + + + +;; uconcat - unconditionally generate a statement from a field +;; of given parameters +;; +;; usage: +;; uconcat a,b,c,d,e,f,g +;; +;; where: +;; a,b are concatenated for field 1 +;; c,d are concatenated for field 2 +;; e,f,g are concatenated for field 3 + +uconcat macro a,b,c,d,e,f,g + a&b c&d e&f&g +endm + + + +;; mpush pushes multiple registers onto the stack according to +;; a register specification. +;; +;; format: +;; mpush r +;; +;; where: +;; r is a numeric expression returned from ?ri +;; or any other valid register expression + +mpush macro r + irp x, + if (r and ?&&x) + push x ;@ + endif + endm +endm + + + +;; mpop pops multiple registers from the stack according to +;; a register specification. +;; +;; format: +;; mpop r +;; +;; where: +;; r is a numeric expression returned from ?ri +;; or any other valid register expression + +mpop macro r + irp x, + if (r and ?&&x) + pop x ;@ + endif + endm +endm + + +;; save - flag that the indicated registers are to be saved/restored +;; +;; A flag is created which indicates which registers are to be saved +;; when the cCall macro is invoked, and then restored after the call. +;; +;; usage: +;; save +;; +;; where r is the list of registers to save, which may be: +;; +;; register saves +;; AX AX +;; AH AX +;; AL AX +;; BX BX +;; BH BX +;; BL BX +;; CX CX +;; CH CX +;; CL CX +;; DX DX +;; DH DX +;; DL DX +;; SI SI +;; DI DI +;; ES ES +;; DS DS +;; BP BP +;; +;; none nothing +;; +;; the macro generates a value for the variable ?rsl + +save macro r + ?rsl=0 ;;initialize save list + ?ri ?rsl, ;;generate magic number +endm + + + +;; ?ri - or register indexes to variable +;; +;; ?ri is a macro that examines the passed argument list and computes +;; a register index variable. +;; +;; The values ORed with the variable are: +;; +;; ?n equ 0000000000000000b; +;; ?AX equ 0000000000000011b; +;; ?AH equ 0000000000000001b; +;; ?AL equ 0000000000000010b; +;; ?BX equ 0000000000001100b; +;; ?BH equ 0000000000000100b; +;; ?BL equ 0000000000001000b; +;; ?CX equ 0000000000110000b; +;; ?CH equ 0000000000010000b; +;; ?CL equ 0000000000100000b; +;; ?DX equ 0000000011000000b; +;; ?DH equ 0000000001000000b; +;; ?DL equ 0000000010000000b; +;; ?SI equ 0000000100000000b; +;; ?DI equ 0000001000000000b; +;; ?ES equ 0000010000000000b; +;; ?DS equ 0000100000000000b; +;; ?BP equ 0001000000000000b; +;; ?SP equ 0010000000000000b; +;; ?SS equ 0100000000000000b; +;; ?CS equ 1000000000000000b; +;; usage: +;; ?ri n, +;s mach independant names; where: +;; n is the variable to contain the new index value +;; r is the register list + +?ri macro n,r + irp x, + ifdef ?&&x ;;if defined, then add to list + n=n or ?&&x + else + ??error2 + .err + endif + endm +endm + + + +;; parmx - generate reference to parameter(s) on the stack +;; +;; An equate is generated for addressing a paramter(s) +;; on the stack for the current procedural frame. +;; +;; An error message is generated if there isn't a current frame. +;; +;; usage: +;; parmX n +;; where: +;; X is the type of the argument(s) B=byte, W=word, D=dword +;; I = machine independant int size +;; n is the name(s) to be given the parameter(s). +;; +;; Bytes are considered to be two bytes long for alignment. +;; +;; The parmd form of the macro generates three equates: +;; +;; name - for accessing the parameter as a double word +;; off_name - for accessing the offset (lsw) of the parameter +;; seg_name - for accessing the segment (msw) of the parameter + +.xcref +.xcref parmB,parmW,parmD,parmQ,parmT,parmCP,parmDP,parmH,parmI +.cref + +parmB macro n + ?pp ,,sizeI,1 +endm + +parmW macro n + ?pp ,,sizeI,2 +endm + +parmI macro n + ?pp ,wordI,sizeI,sizeI +endm + +parmD macro n + ife ?pcc ;;if to assemble for C + irp x, + ?pp <&&x>,,0,4 + ?pp ,,2,2 + ?pp ,,2,2 + endm + else ;;if to assemble for PL/M + irp x, + ?pp ,,2,2 + ?pp ,,2,2 + ?pp <&&x>,,0,4 + endm + endif +endm + +parmH macro n + ?pp ,,4,2 +endm + +parmQ macro n + ?pp ,,8,8 +endm + +parmT macro n + ?pp ,,10,10 +endm + +if sizec + parmCP macro n + parmD + endm +else + parmCP macro n + parmW + endm +endif + +if sized + parmDP macro n + parmD + endm +else + parmDP macro n + parmI + endm +endif + + + +;; ?pp is the generalized parameter definition macro +;; +;; usage: +;; ?pp m,t,l,s +;; +;; where: +;; n is the name(s) of the parameters +;; t is the type (word, dword) +;; l is the length to update parameter byte count by +;; s is the internal typing size + + +?pp macro n,t,l,s ;;process parameter + if ?cpd ;;must be in a procedure definition + .xcref + irp x, + .xcref ?t&&x ;;don't want this in xref + ?t&&x=s ;;save size info + ife ?pcc ;;if C calling convention + ?pp1 x,,,,%(?po+?adj) + ?po=?po+l ;;update parameter offset + else ;;else assemble for PL/M + ?PLMPrevParm=?PLMPrevParm+1 ;;Show next parameter + ?po=?po+l ;;update parameter offset + ?pp1 x,,%?po,%?adj,,%?PLMPrevParm,%(?PLMPrevParm-1) + endif + endm + .cref + else + ??error2 + endif +endm + + + +;; ?pp1 is the macro that generates the text equate for the +;; parameter. Two options exist, one for the C calling +;; convention where the last parameter was the first pushed onto +;; the stack ('C' convention), and one for the PL/M calling +;; convention where the first parameter was the first +;; pushed (also the same as ms-pascal). +;; +;; The text generated will be of one of two forms: +;; +;; name equ (type ptr [bp+(adj+offset)]) for C +;; or +;; name equ (type ptr [bp+adj+?po-offset]) for PL/M +;; +;; +;; For C, since parameters are pushed first last, the offset +;; plus the adjust will point to the correct parameter. +;; +;; For PL/M, since parameters are pushed first first, the offset +;; of a parameter is much more complicated. A known portion of +;; the offset can be computed when the text equate is generated. +;; +;; What is known is the number of garbage bytes between BP and +;; the nearest parameter (in this case the last parameter), and +;; also how many bytes of parameters have preceeded this parameter. +;; +;; What is unknown is how many total bytes of parameters there will +;; be, which affects all the generated text equates since the offset +;; from bp must be determined at some point. +;; +;; Well, the offset from BP can be computed with one variable if +;; the following is remembered: +;; +;; the offset of any parameter from the first parameter is always +;; the current parameter offset (?po). +;; +;; With this in mind, you just have to figure out where the first +;; parameter is, which is: +;; +;; bp + garbage adjustment + distance to first parameter +;; or +;; bp + ?adj + ?po +;; +;; This implies that any parameter can be defined as: +;; +;; bp + ?adj + ?po -%?po +;; +;; Make any sense? +;; +;; For PL/M, a chain of self-purging macros will be generated +;; which will pass the evaluated ?po to any previous incarnation +;; of the macro. This will allow the text equate to be generated +;; with the actual offset instead of the symbolic ?po. +;; +;; +;; usage: +;; ?pp1 n,t,o,a,b,cpc,ppc +;; +;; where: +;; n is the name to be given the equate +;; t is the type (byte, word, dword) +;; o is the offset from the first parameter +;; a is the adjustment +;; b is the adjustment plus the offset from the first parameter +;; cpc is the number of parameters so far +;; ppc is cpc - 1 + + +?pp1 macro n,t,o,a,b,cpc,ppc + ife ?pcc ;;if to generate for C + if ?no_bp2 + n equ (t ptr [+b]) + else + n equ (t ptr [IBP][+b]) + endif + else ;;else generate for PL/M + .xcref + .xcref ?PLMParm&cpc + .cref + if ?no_bp2 + ?PLMParm&cpc ¯o po + uconcat ,,,,<(t ptr [+>,%(a+po-o),<])> + ?PLMParm&ppc po + purge ?PLMParm&cpc + &endm + else + ?PLMParm&cpc ¯o po + uconcat ,,,,<(t ptr [IBP][+>,%(a+po-o),<])> + ?PLMParm&ppc po + purge ?PLMParm&cpc + &endm + endif + endif +endm + + + +;; parmR - register parameter +;; +;; parmR is the macro used for generating register parameters. +;; The space allocated for the register parameters will be +;; the ?ia (interface adjust) area which is between the old +;; BP and the first parameter. Normally this is empty (?ia=0), +;; or has the saved ds for a windows far procedure. +;; +;; Byte and dword register parameters will be allowed. +;; +;; usage: +;; parmR n,r,r2 +;; where: +;; n is the name of the parameter +;; r is the register it is in +;; r2 is the offset register if a dword + + +ifndef ?NOPARMR + .xcref + .xcref ?pr,parmR + .cref + + parmR macro n,r,r2 + ?pr n,r,r2,%?rp,%(?ia+2) + endm + + ;; ?pr - register parameter + ;; + ;; ?pr is the actual macro for generating the equates for + ;; register parameters. + ;; + ;; usage: + ;; parmR n,r,r2,i,o + ;; where: + ;; n is the name of the parameter + ;; r is the register it is in + ;; r2 is the offset register if a dword + ;; i is the index of the ?rp to generate + ;; o is the offset from bp where the parm will be + + ?pr macro n,r,r2,i,o + .xcref + ifnb ;;if a dword parameter + parmR seg_&n,r ;;define segment equate + parmR off_&n,r2 ;;define offset equate + if ?no_bp2 + n equ (dword ptr [-o-2]) ;;define dword equate + else + n equ (dword ptr [bp][-o-2]) ;;define dword equate + endif + .xcref ?t&n + ?t&n=4 ;;show a dword to cmacros + else + .xcref ?rp&i + ?rp&i=0 ;;show no register(s) + ifdef ?&r ;;define register if valid + ?rp&i=?&r + endif + + if ??? or (?cpd eq 0) or (?rp&i eq 0) + ??error2 + exitm + endif + + if ?no_bp2 + n equ (word ptr [-o]) ;;assume a word register + else + n equ (word ptr [bp][-o]) ;;assume a word register + endif + .xcref ?t&n + ?t&n=2 ;;show a word to cmacros + irp x, + if ?&&x eq ?&r ;;if really a byte register + if ?no_bp2 + n equ (byte ptr [-o]) ;; then make it a byte + else + n equ (byte ptr [bp][-o]) ;; then make it a byte + endif + ?t&n=1 ;;show a byte to cmacros + exitm + endif + endm + ?ia=?ia+2 ;;show this guy is out there + ?rp=?rp+1 ;;show one more register parameter + endif + .cref + endm +endif + + + +;; localx - generate reference to a local variable on the stack +;; +;; An equate is generated for addressing a local variable +;; on the stack for the current procedural frame. +;; +;; usage: +;; localx n +;; where: +;; x is the type b=byte, w=word, d=dword, v=variable size +;; n is the name(s) to be given the variable(s). +;; +;; Bytes are considered to be two bytes long for alignment reasons +;; +;; The locald form of the macro generates three equates: +;; +;; name - for accessing the variable as a double word +;; off_name - for accessing the offset (lsw) of the variable +;; seg_name - for accessing the segment (msw) of the variable + + +.xcref +.xcref localB,localW,localD,localQ,localT,localCP,localDP,localV,localI +.cref + +localB macro n + ?aloc ,,1,1,0 ;; no alignment +endm + +localW macro n + ?aloc ,,2,2,1 ;; word aligned +endm + +localI macro n + ?aloc ,&wordI&< ptr>,sizeI,sizeI,1 ;; dword aligned +endm + +localD macro n + irp x, + ?aloc ,,2,2,1 ;; word aligned + ?aloc ,,2,2,1 ;; word aligned + ?aloc <&&x>,,0,4,1 ;; word aligned + endm +endm + +localQ macro n + ?aloc ,,8,8,1 ;; word aligned +endm + +localT macro n + ?aloc ,,10,10,1 ;; word aligned +endm + +if sizec + localCP macro n + localD + endm +else + localCP macro n + localW + endm +endif + +if sized + localDP macro n + localD + endm +else + localDP macro n + localI + endm +endif + +localV macro n,a + ?aloc ,,%(a),0,1 ;; word aligned +endm + + +;; ?aloc is the macro that actually allocates local storage. +;; it is only invoked by the localx macros. +;; +;; usage: +;; ?aloc n,t,l,s,a +;; where: +;; n is a list of names of local variable of the +;; given type. +;; t is the text string for the given variable +;; and is one of: +;; word ptr +;; dword ptr +;; byte ptr +;; or alternatively left blank for variable size +;; allocations (no implicit type). +;; l is the size of the variable in bytes +;; s is the internal type flag (size), and is one of: +;; word - 2 +;; dword - 4 +;; byte - 1 +;; variable - 0 +;; a is a flag indicating that word alignment is to be +;; forced for this type of item. +;; +;; NOTE: It is assumed that the stack is already aligned on a word +;; boundary when the cProc is invoked. The macros will guarantee +;; to allocate an even number of bytes on the stack to maintain +;; word alignment. + + +?aloc macro n,t,l,s,a + if ?cpd ;;must be in a proc def + .xcref + irp x, ;;generate symbol equates + ???=???+l ;;update length of locals + if a ;;if align, then force word alignment + if memS32 and l GT 2 + ???=((??? + 3) and 0fffffffch) ;; dword alignment + else + ???=((??? + 1) and 0fffeh) + endif + endif + ?al1 x,,%(???+?ia) ;;?ia will always be valid (0 or 2) + .xcref ?t&&x + ?t&&x=s ;;save size info + endm + .cref + else + ??error2 + endif +endm + + + +;; ?al1 - allocate local, continued. +;; +;; ?al1 actually generates the text equate for the local variable. +;; The form of the text equate generated is more or less: +;; +;; name equ (type ptr [bp-?ia-nn]) +;; or +;; name equ ([bp-?ia-nn]) +;; +;; where: +;; ?ia is defined to be either zero, or is defined to be +;; the number of bytes between the saved BP and the first +;; local. ?ia is only applicable if the current cProc is +;; a windows far procedure or if parmRs have been +;; encountered. If not, the ?ia will be zero. since ?ia +;; is determinable prior to invoking this macro, it will be +;; added into the offset ("nn") passed to this macro +;; +;; usage: +;; ?al1 n,t,o +;; where: +;; n is the name for the text equate +;; t is the type of the equate +;; o is the offset of the equate + + +?al1 macro n,t,o + if ?no_bp2 + n equ (t [-o]) + else + n equ (t [IBP][-o]) + endif +endm + + +;; ?gcc - get calling convention +;; +;; ?gcv sets the given symbol to the calling convention +;; to be used. +;; +;; usage: +;; ?gcc s,i,cc +;; +;; where: +;; s is the symbol to return the convention in +;; s = 0 if 'C' calling convention +;; s = 1 if PL/M (PASCAL) calling convention +;; i is the initial value for s +;; cc is the calling convention override, and may be one of +;; C use 'C' convention +;; PLM use PL/M calling convention +;; PASCAL use PL/M calling convention + +?gcc macro s,i,cc + s = i ;;Set default calling convention + ifnb + ifidn , ;;If overriding default + s=0 ;; 'C' calling convention + endif + ifidn , + s=1 ;; PL/M calling convention + endif + ifidn , + s=1 ;; PL/M calling convention + endif + endif +endm + + + +ifndef ?NOGLOBAL + .xcref + .xcref globalB,globalW,globalD,globalQ,globalT,globalCP,globalDP,globalI + .cref + + ;; globalx - define global data of type x + ;; + ;; usage: + ;; globalx n,i,s,c + ;; where: + ;; x is the type of the variable b=byte, w=word, d=dword + ;; q=quad word, t=tenbytes, cp=code pointer, dp=data pointer + ;; n is the name to be given the variable. + ;; i is the initial value of the variable. + ;; s is the duplication factor + ;; c is the convention, C for C, PLM or PASCAL for PL/M. + ;; The default (?PLM flag) will be used if not specified. + ;; + ;; The D form will generate two extra equates of the form off_n and seg_n. + + globalB macro n,i,s,c + ?ad ,1 + ?dd n,1,,,,, + endm + + globalW macro n,i,s,c + ?ad ,2 + ?dd n,1,,,,, + endm + + globalI macro n,i,s,c + ?ad ,2 + ?dd n,1,wordI,%asmdI,,, + endm + + globalD macro n,i,s,c + ?ad ,4 + ?dd n,1,,
,,, + off_&n equ word ptr n[0] + seg_&n equ word ptr n[2] + endm + + globalQ macro n,i,s,c + ?ad ,8 + ?dd n,1,,,,, + endm + + globalT macro n,i,s,c + ?ad ,10 + ?dd n,1,,
,,, + endm + + if sizec + globalCP macro n,i,s,c + globalD n,,, + endm + else + globalCP macro n,i,s,c + globalW n,,, + endm + endif + + if sized + globalDP macro n,i,s,c + globalD n,,, + endm + else + globalDP macro n,i,s,c + globalI n,,, + endm + endif + +endif + + +ifndef ?NOSTATIC + .xcref + .xcref staticB,staticW,staticD,staticQ,staticT,staticCP,staticDP,staticI + .cref + + ;; staticx - define static data of type x + ;; + ;; usage: + ;; staticx n,i,s + ;; where: + ;; x is the type of the variable b=byte, w=word, d=dword + ;; q=quad word, t=tenbytes, cp=code pointer, dp=data pointer + ;; n is the name to be given the variable. + ;; i is the initial value of the variable. + ;; s is the duplication factor + ;; + ;; statics do not generate an underscored version of the symbol + ;; since they are intended to be internal symbols. If they are + ;; required to be public, use globlax. + + + staticB macro n,i,s + ?ad ,1 + ?dd n,0,,,,, ;;PLM to keep from generating _ + endm + + staticW macro n,i,s + ?ad ,2 + ?dd n,0,,,,, + endm + + staticD macro n,i,s + ?ad ,4 + ?dd n,0,,
,,, + endm + + staticI macro n,i,s + ?ad ,sizeI + ?dd n,0,wordI,%asmdI,,, + endm + + staticQ macro n,i,s + ?ad ,8 + ?dd n,0,,,,, + endm + + staticT macro n,i,s + ?ad ,10 + ?dd n,0,,
,,, + endm + + if sizec + staticCP macro n,i,s + staticD n,, + endm + else + staticCP macro n,i,s + staticW n,, + endm + endif + + if sized + staticDP macro n,i,s + staticD n,, + endm + else + staticDP macro n,i,s + staticI n,, + endm + endif +endif + + + +;; ?dd is the generalized data definition macro. +;; +;; format: +;; ?dd n,p,t,d,i,s,c +;; where: +;; n is the name of the procedure +;; p is the public flag +;; t is the assembler type (byte, word, dword) +;; d is the assembler directive (db,dw or dd) +;; i is the initial value +;; s is a duplication factor +;; c is the convention, C for C, PLM or PSACAL for PL/M. +;; The default (?PLM flag) will be used if not specified. + + +?dd macro n,p,t,d,i,s,c + ?gcc ?dd2,%?PLM, ;;Set calling convention + ife ?dd2 ;;If 'C' + n label t + ?dd1 _&n,p,,, ;;Microsoft C uses leading underscores + else + ?dd1 n,p,,, ;;If PL/M + endif +endm + + + +;; ?dd1 is the generalized data definition macro. +;; +;; format: +;; ?dd1 n,p,d,i,s +;; where: +;; n is the name of the procedure +;; p is the public flag +;; d is the assembler directive (db,dw or dd) +;; i is the initial value +;; s is a duplication factor + + +?dd1 macro n,p,d,i,s + if p + public n + endif + ifb + n d i + else + ifb + n d s dup (?) + else + n d s dup (i) + endif + endif +endm + + + +ifndef ?NOEXTERN + .xcref + .xcref ?ex1,?ex2,externB,externW,externD,externQ,externT,externI + .xcref externNP,externFP,externP,externCP,externDP,externA + .cref + ?ex2 = 0 + + ;; externx - define external data of type x + ;; + ;; usage: + ;; externx n,c + ;; where: + ;; x is the type of the variable b=byte, w=word, d=dword + ;; q=quad word, t=tenbytes, cp=code pointer + ;; dp=data pointer, a=absolute + ;; n is a list of names to define + ;; c is the convention, C for C, PLM or PSACAL forPL/M. + ;; The default (?PLM flag) will be used if not specified. + + externA macro n,c ;;40h is reserved for whatever will + ?ex1 ,40h,,,<> ;; be done in the future for ASB + endm ;; externals + + externB macro n,c + ?ex1 ,1,,,<> + endm + + externW macro n,c + ?ex1 ,2,,,<> + endm + + externD macro n,c + ?ex1 ,4,,,<> + endm + + externI macro n,c + ?ex1 ,sizeI,%wordI,,<> + endm + + externQ macro n,c + ?ex1 ,8,,,<> + endm + + externT macro n,c + ?ex1 ,10,,,<> + endm + + externNP macro n,c + ?ex1 ,2,,, + endm + + externFP macro n,c + ?ex1 ,4,,, + endm + + if sizec + externP macro n,c + ?ex1 ,4,,, + endm + else + externP macro n,c + ?ex1 ,2,,, + endm + endif + + if sizec + externCP macro n,c + ?ex1 ,4,,,<> + endm + else + externCP macro n,c + ?ex1 ,2,,,<> + endm + endif + + if sized + externDP macro n,c + ?ex1 ,4,,,<> + endm + else + externDP macro n,c + ?ex1 ,2,,,<> + endm + endif + + + + ;; ?ex1 is the generalized external definition macro + ;; + ;; format: + ;; ?ex1 n,s,d,c,scv + ;; where: + ;; n is are the names of the externals + ;; s is the size in bytes (used for typing) + ;; d is the type + ;; c is the convention, C for C, PLM or PSACAL for PL/M. + ;; The default (?PLM flag) will be used if not specified. + ;; scv save calling convention. If this field is "cc", then + ;; the calling convention will be saved in a ?CCn equ. + + ?ex1 macro n,s,d,c,scv + ?gcc ?ex2,%?PLM, + irp x, + .xcref + .xcref ?t&&x + .cref + ?t&&x=s ;;save size info + ife ?ex2 + extrn _&&x:&d + x equ _&&x + else + extrn x:&d + endif + ifidn , ;;save calling convention (C or PL/M) + .xcref ;; if NP, FP, or P + .xcref ?CC&&x + .cref + ?CC&&x=?ex2 + endif + endm + endm +endif + + + +ifndef ?NOLABEL + .xcref + .xcref ?lb1,?lblpu,?lb2 + .xcref labelB,labelW,labelD,labelQ,labelT + .xcref labelNP,labelFP,labelP,labelCP,labelDP + .cref + ?lblpu = 0 + ?lb2 = 0 + + ;; labelx - define label of data type x + ;; + ;; usage: + ;; labelx n,c + ;; where: + ;; x is the type of the variable b=byte, w=word, d=dword + ;; q=quad word, t=tenbytes, cp=code pointer, dp=data pointer + ;; n is a list of names to define, the first of which can + ;; be the keyword public + ;; c is the convention, C for C, PLM or PSACAL for PL/M. + ;; The default (?PLM flag) will be used if not specified. + + labelB macro n,c + ?lb1 ,1,, + endm + + labelW macro n,c + ?lb1 ,2,, + endm + + labelD macro n,c + ?lb1 ,4,, + endm + + labelQ macro n,c + ?lb1 ,8,, + endm + + labelT macro n,c + ?lb1 ,10,, + endm + + labelNP macro n,c + ?lb1 ,2,, + endm + + labelFP macro n,c + ?lb1 ,4,, + endm + + if sizec + labelP macro n,c + ?lb1 ,4,, + endm + else + labelP macro n,c + ?lb1 ,2,, + endm + endif + + if sizec + labelCP macro n,c + ?lb1 ,4,, + endm + else + labelCP macro n,c + ?lb1 ,2,, + endm + endif + + if sized + labelDP macro n,c + ?lb1 ,4,, + endm + else + labelDP macro n,c + ?lb1 ,2,, + endm + endif + + + ;; ?lb1 is the generalized label definition macro + ;; + ;; format: + ;; ?lb1 n,s,d + ;; where: + ;; n are the names of the labels + ;; s is the size in bytes (used for typing) + ;; d is the type + ;; c is the convention, C for C, PLM or PSACAL for PL/M. + ;; The default (?PLM flag) will be used if not specified. + + ?lb1 macro n,s,d,c + ?gcc ?lb2,%?PLM, + ?lblpu=0 + irp x, + ifidn , + ?lblpu=1 + else + .xcref + .xcref ?t&&x + .cref + ?t&&x=s ;;save size info + ife ?lb2 ;;If C + if ?lblpu + public _&&x + endif + _&&x label &d + x equ _&&x + else ;;If PL/M + if ?lblpu + public x + endif + x label &d + endif + endif + endm + endm +endif + + + +ifndef ?NODEF + + ;; defx - inform macros that name is of type x + ;; + ;; The given name(s) is flaged to be of the given type. This macro + ;; is intended for giving types to variables that were not generated + ;; by the macros (i.e., static storage). There must be a type definition + ;; for all parameters in a call list. + ;; + ;; usage: + ;; defx n + ;; where: + ;; x is the type of the variable b=byte, w=word, d=dword + ;; n is the name(s) to be given the variable(s). + ;; + ;; Bytes are considered to be two bytes long for alignment reasons + + .xcref + .xcref defB,defW,defD,defQ,defT,defCP,defDP + .cref + + defB macro n + ?ad ,1 + endm + + defW macro n + ?ad ,2 + endm + + defD macro n + ?ad ,4 + endm + + defQ macro n + ?ad ,8 + endm + + defT macro n + ?ad ,10 + endm + + if sizec + defCP macro n + defD + endm + else + defCP macro n + defW + endm + endif + + if sized + defDP macro n + defD + endm + else + defDP macro n + defW + endm + endif +endif + + + +; ?ad is the macro which creates a definition for the given +; symbol +; +; usage: +; ?ad ,s +; where: +; n is a list of names to define +; s is the size info (1,2,4,8,10) + + +?ad macro n,s + irp x, + .xcref + .xcref ?t&&x + .cref + ?t&&x=s ;;save size info + endm +endm + + + +ifndef ?NOPTR + .xcref + .xcref regPtr,farPtr + .cref + + ;; regPtr generates information allowing a 32-bit pointer currently + ;; in a register to be pushed as a parameter to a subroutine using + ;; the cCall macro. + ;; + ;; usage: + ;; regptr n,s,o + ;; where: + ;; n is the name the argument will be known as + ;; s is the register containing the segment portion + ;; of the pointer + ;; o is the register containing the offset portion + ;; of the pointer + ;; + ;; 2/14/85 - made obsolete with farptr + + regPtr macro n,s,o + farPtr n,s,o + endm + + + + ;; farPtr generates information allowing a 32-bit pointer to be + ;; pushed as a parameter to a subroutine using the cCall macro. + ;; + ;; usage: + ;; farptr n,s,o + ;; where: + ;; n is the name the argument will be known as + ;; s is the segment portion of the pointer + ;; o is the offset portion of the pointer + ;; + ;; Note that any cast must have been made in the argument itself + ;; (i.e. regptr ptr1,ds,) + + + farPtr macro n,s,o + .xcref + .xcref ?t&n + .cref + n ¯o + push s ;@ + push o ;@ + &endm + ?t&n=80h + endm +endif + + + +;; arg - declare argument +;; +;; The given argument(s) is added to the argument list structure +;; +;; format: +;; arg a +;; +;; where: +;; a is any valid argument to push. +;; +;; If any element in arglist has not been defined or isn't a 16-bit +;; register, then a complete specification must have been given in a +;; text equate and a defx also given (if not, you'll pay the penalty!) + + +arg macro a + irp x, + ?argc=?argc+1 ;;increment the arg count + ?atal ,%?argc ;;generate argument + endm +endm + + + +;; ?atal (add to argument list) generates a macro that will cause +;; the given argument to be processed when invoked. It is used by +;; the arg macro only. + + +?atal macro n,i + .xcref + .xcref ?ali&i + .cref + ?ali&i ¯o + ?ap + &endm +endm + + + +;; ?ap - process arguments and place onto stack +;; +;; The given argument is processed (type checking) and place on +;; the stack for a pending call. There must be a type definition +;; for all arguments (except words). This can be done by using +;; text equates and the defx macro. +;; +;; format: +;; ?ap n +;; where: +;; n is the name of the argument to be pushed +;; +;; The variable ?argl is updated by the length of the arguments +;; pushed so that the stack can be cleaned up after the call. + + +?ap macro n + ?argl=?argl+2 ;;assume one word is pushed + ifdef ?t&n + ife ?t&n-1 ;;byte type + push word ptr (n) ;@ + exitm + endif + + ife ?t&n-2 ;;word type + push n ;@ + exitm + endif + + ife ?t&n-4 ;;dword type + push word ptr (n)[2] ;@ + push word ptr (n) ;@ + ?argl=?argl+2 + exitm + endif + + ife ?t&n-8 ;;qword type + push word ptr (n)[6] ;@ + push word ptr (n)[4] ;@ + push word ptr (n)[2] ;@ + push word ptr (n) ;@ + ?argl=?argl+6 + exitm + endif + + if ?t&n and 80h ;;far pointer type + n + ?argl=?argl+2 + exitm + endif + + ife ?t&n ;;variable storage + push word ptr (n) ;@ + exitm + endif + endif + + push n ;;unknown or register or immediate ;@ +endm + + + +;; cCall - call a 'c' language procedure +;; +;; The given procedure is called with the given parameters. +;; If the calling convention is C, the arguments are pushed +;; in reverse order, and removed after the called procedure +;; returns. If the calling conventing is PL/M, the arguments +;; are pushed as they were encountered, and the called procedure +;; is assumed to have removed them from the stack. +;; +;; The calling convention priority will be: +;; 1) that specified on the cCall if present +;; 2) that defined by the target +;; 3) the default (?PLM flag) +;; +;; format: +;; ccall n,,c +;; +;; where: +;; n is the name of the procedure to call +;; a are arguments to be pushed (optional, may be +;; specified with the "arg" macro. +;; c is the convention, C for C, PLM or PSACAL for PL/M. +;; The default (?PLM flag) will be used if not specified. + + +cCall macro n,a,c + ifnb ;;add any arguments to list + arg + endif + mpush %?rsl ;;save registers (if any) + + ifdef ?CC&n ;;if calling convention has been + ?cCall1=?CC&n ;; defined for target, use it + else ;;else use the default + ?cCall1=?PLM + endif + + ifnb ;;If possible override, check it out + ?gcc ?cCall1,%?cCall1, + endif + + ?argl=0 ;;init argument length + ife ?cCall1 ;;if C calling convention + ?acb=?argc ;;initialize for looping + else + ?acb=1 ;;initialize for looping + endif + + rept ?argc ;;push arguments and purge macros + uconcat ,%?acb + uconcat ,,,%?acb + ife ?cCall1 ;;if C calling convention + ?acb=?acb-1 + else + ?acb=?acb+1 + endif + endm + call n ;;call the procedure ;@ + if ((?cCall1 eq 0) and (?argl ne 0)) ;;If C calling convention and arguments + add sp,?argl ;; then remove them ;@ + endif + mpop %?rsl ;;pop all specified regs + ?rsl=0 ;;invalidate save list + ?argc= 0 ;; " arguments + ?argl= 0 +endm + + + + +;; cProc - define a 'c' procedure +;; +;; cProc is the procedure definition for procedures. +;; +;; format: +;; cProc n,cf,a +;; where: +;; n is the name of the procedure +;; +;; cf controls certain definitions, and may be: +;; NEAR proc is to be a near label +;; FAR proc is to be a far label +;; PUBLIC proc is to be defined as public +;; SMALL call makeframe procedure +;; NODATA dont create prolog code to setup DS +;; ATOMIC don't link stack if not needed +;; NODATA must be specified for ATOMIC +;; FORCEFRAME Force generation of a frame +;; C proc is to be a C procedure +;; PLM proc is to be a PL/M procedure +;; PASCAL proc is to be a PL/M procedure +;; WIN proc is to be a windows procedure +;; NONWIN proc isn't to be a windows procedure +;; NO_BP don't generate BP in text equates +;; BP generate BP in text equates +;; +;; a is a list of registers that are to be saved whenever +;; the procedure is invoked. +;; +;; makeframe procedure: If small is specified, then +;; the "makeframe procedure" is invoked instead of +;; generating normal prologues/epilogues +;; +;; A call is performed to the makeframe procedure. The +;; call is followed by two bytes. the first byte is the +;; number of locals to allocate for the frame, the second +;; is the number of bytes of parameters. The makeframe +;; procedure will in turn call the cProc routine at the +;; address following the data bytes. When the cProc is +;; finished, it will do a near return to the makeframe +;; procedure to clean up the frame and exit. +;; +;; Note that register parameters and makeframe are +;; incompatible and cannot be used together. +;; +;; The makeframe procedure will save SI, DI, and also +;; DS if a far procedure. These registers will be +;; removed from the autosave list if specified. + + +cProc macro n,cf,a + if ?cpd + ?utpe ;;generate unterminated proc error + endif + + ?cpd=1 ;;a procdef is active now + ???=0 ;;no locals are defined yet + ?argc=0 ;;no arguments are defined + ?ba=0 ;;not in a procedure + ?po=0 ;;initial parameter offset + ?pu=0 ;;initial public setting + ?ia=0 ;;no special prolog/epilog + ?adj=2*sizeI ;;parameter adjustment (near ret+bp) + ?rp=0 ;;no register parameters + ?uf=0 ;;don't use makeframe + ?wfp=?WIN ;;default far procedure (win or not) + ?ff=0 ;;don't force frame setup + ?pas=0 ;;process register save list + ?pcc=?PLM ;;calling convention (C or PL/M) + ?no_bp2=?no_bp1 ;;Default base register generation + + ifnb ;;register save list + ?ri ?pas, + endif + + ?pc=sizec ;;default size + ?nd=?nodata1 ;;default NODATA flag + ?nx=0 ;;default is not ATOMIC + + irp x, + ifdef ??_cproc_&&x + ??_cproc_&&x + else + ??error2 + .err + endif + + endm + + if ?pcc ;;If PLM + ?PLMPrevParm=0 ;; show no previous parameter + .xcref + .xcref ?PLMParm0 + .cref + ?PLMParm0 ¯o ;;Null macro to terminate + purge ?PLMParm0 + &endm + endif + + .xcref + .xcref ?CC&n + .cref + ?CC&n=?pcc ;;Save procedure type + + if (?nx eq 1) and (?nd eq 0) ;;ATOMIC requires NODATA + ?nx = 0 ;;clear the ATOMIC keyword + ??error2 + endif + + if ?pc ;;if a far procedure + if ?wfp ;;if windows + ife ?nx ;;if not ATOMIC + ife ?COW ;; COW dos not save DS + ?ia=2 ;; adjust locals for saved ds + ?pas = ?pas and (not ?ds) ;;no need for extra save + endif + endif + endif + ?adj=?adj+sizeI ;;far, make parameter adjustment + else + ?wfp=0 ;;not a far windows procedure + endif + + ?pas = ?pas and (not (?sp+?cs+?ss)) ;;make no sense to save these + + if ?uf ;;don't save these if user frame + ?pas = ?pas and (not (?bp+?si+?di)) + endif + + ife ?pcc + ?pg <_&n>,%?pu,%?pc,%?pas,%?wfp,,%?pcc + else + ?pg ,%?pu,%?pc,%?pas,%?wfp,,%?pcc + endif +endm + + + + +;; ?pg - generate begin and nested macros for current procedure +;; +;; format: +;; ?pg n,p,c,a,w,nnu,cc +;; where: +;; n is the name of the procedure +;; p is the public flag +;; c is the class definition for the procedure +;; a is an enumerated list of registers to save +;; at entry and restore at exit +;; w true if a far windows procedure +;; nnu procedure name without any underscore +;; cc calling convention (C or PL/M) +;; +;; +;; local stack allocation will be forced to an even byte count to +;; maintain stack word alignment. + + +?pg macro n,p,c,a,w,nnu,cc + .xcref + if ?uf ;;if user frame + if ?nd + ??error2 + ?uf=0 + endif + endif + + .xcref cBegin + cBegin ¯o g ;;generate cBegin macro + .xcref + if cc ;;Finish definition of parameters + uconcat ,%?PLMPrevParm,%?po + endif + + if ?uf ;;if user frame + if ?rp ;;If register parameters + ??error2 + ?uf=0 + endif + endif + ?pg1 ,c,a,%?po,w,%?uf,%?nd,%?rp,cc,,%??? ;;generate cEnd macro + ?cpd=0 ;;terminate current proc def + ?argc=0 ;;no arguments are defined yet + ?ba=1 ;;have reached a begin + ???=(???+1) and 0fffeh ;;word align local storage + + if p ;;If to be public + public n + endif + + ife c ;;declare procedure type + n proc near + else + n proc far + endif + + ife cc ;;if 'C' calling convention + nnu equ n ;; generate label without underscore + endif + + ?cbe = 0 ;;Assume no command on cBegin line + ifnb + ?pcbe ,, + endif + if ?cbe eq 1 ;;if nogen, then cannot have locals + if ???+a+?rp ;; saved regs, or parmRs + if2 + ??_out + endif + endif + else ;;else must generate a frame + if ?uf ;;if user frame code specified + ?mf c,%???,%?po ;; call user's makeframe + mpush a ;; save specified registers + else + ife ?cbe ;;If full frame to be set up + if w ;;if a far windows procedure + ife ?nd ;;if not NODATA, + mov IAX,ds ;; then set AX = current ds, and ;@ + nop ;; leave room for MOV AX,1234h ;@ + endif + ife ?nx ;;if not ATOMIC, far frame must be set + ife ?DOS5 ;;if not DOS5, then set far frame flag + inc IBP ;; by incrementing the old bp ;@ + endif + push IBP ;@ + mov IBP,ISP ;@ + ife ?COW ;; save DS not needed for CW + push ds ;@ + endif + else ;;ATOMIC procedure + if ?ff+???+?po+?rp ;;if any locals or parameters + push IBP ;; then must set frame pointer ;@ + mov IBP,ISP ;; to be able to access them ;@ + endif + endif + ife ?nd ;;if not NODATA, then AX should + mov ds,IAX ;; have the ds to use ;@ + endif + else ;;not windows. use standard prolog + if ?ff+???+?po+?rp ;;if any locals or parameters + push IBP ;; then must set frame pointer ;@ + mov IBP,ISP ;; to be able to access them ;@ + endif + endif + if ?rp ;;if parmR's, push them before + ?uf=0 ;; allocating locals and saving + rept ?rp ;; the autosave registers + uconcat mpush,,?rp,%?uf + ?uf=?uf+1 + endm + endif + if ??? ;;if locals to allocate + if ?chkstk1 ;;if stack checking enabled + ifdef ?CHKSTKPROC ;;if user supplied stack checking + ?CHKSTKPROC %??? ;; invoke it with bytes requested + else + mov IAX,??? ;;invoke default stack checking ;@ + ife cc + call _chkstk ;@ + else + call chkstk ;@ + endif + endif + else ;;no stack checking + sub ISP,??? ;; allocate any local storage ;@ + endif + endif + else ;;partial frame, only set locals + if ?rp ;;If parmRs, error + ??error2 + else + if ??? ;;Only realloc frame if locals + lea ISP,[IBP][-???-?ia] ;;?ia will adjust for saved BP ;@ + endif + endif + endif + mpush a ;;save autosave registers + endif + + ifdef ?PROFILE ;;if profiling enabled + if c ;; and a far procedure + call StartNMeas ;; invoke profile start procedure ;@ + endif + endif + + endif + + .cref + purge cBegin ;;remove the macro + &endm ;;end of cBegin macro + + .xcref ?utpe + ?utpe ¯o + ??error2 + &endm + .cref +endm ;;end of ?pg macro + + + + +;; ?pg1 - generate end macro for current procedure +;; +;; format: +;; ?pg1 n,c,a,o,w,f,d,r,cc,nnu,lc +;; where: +;; n is the name of the procedure +;; c is the class definition for the procedure +;; a is an enumerated list of registers to save +;; at entry and restore at exit +;; o is the number of bytes of paramteres to remove at exit +;; w true if a far windows procedure +;; f is 1 if to use the user's makeframe procedure +;; d is 1 if NODATA procedure +;; r number of register parameters +;; cc calling convention (C or PL/M) +;; nnu procedure name without any underscore +;; lc locals byte count + + +?pg1 macro n,c,a,o,w,f,d,r,cc,nnu,lc + .xcref + .xcref cEnd + + parm_bytes_&nnu = o ;;Define number of parameter bytes + + cEnd ¯o g ;;start of cEnd macro + .xcref + ?ba=0 ;;no longer in a procedure + ?cbe = 0 ;;Assume no command on cBegin line + ifnb + ?pcbe ,, + endif + if ?cbe eq 1 ;;if nogen, then cannot have parmRs + if a+r+lc ;; locals, or saved registers + if2 + ??_out + endif + endif + else ;;else must remove the frame + ifdef ?PROFILE ;;if profiling enabled + if c ;; and a far procedure + call StopNMeas ;; invoke profile stop procedure + endif ;; (doesn't trash DX:AX) + endif + mpop a ;;restore autosaved registers + if f ;;if to use the "makeframe" procedure + db 0c3h ;; near return to user's makeframe @ + else + if w ;;if far win proc, use special epilog + ife ?nx ;;if not ATOMIC, bp was pushed + ife ?COW ;; restore DS not needed for CW + if (?TF eq 0) or (???+r) ;;if cannot assume valid sp + lea sp,-2[bp] ;; or locals or parmR's, get valid SP @ + endif + pop ds ;;restore saved ds and bp @ + else + if (?TF eq 0) or (???+r) ;;if cannot assume valid sp + mov sp,bp + endif + endif + pop IBP ;; @ + ife ?DOS5 ;;if not DOS5, bp was + dec IBP ;; incremented to mark far frame @ + endif + else ;;ATOMIC frame was set up + if memS32 + leave + else + if (?TF eq 0) or (???+r) ;;if cannot assume valid sp + mov ISP,IBP ;; or locals or parmR's, get valid SP @ + endif + if ???+?po+r + pop IBP ;@ + endif + endif + endif + else ;;non-windows standard epilog + if ?ff+???+?po+r ;;if any parameters + if (?TF eq 0) or (???+r) ;;if cannot assume valid SP + mov ISP,IBP ;; or locals or parmR's, get valid SP;@ + endif + pop IBP ;@ + endif + endif + if ?cbe ne 4 ;;Don't generate ret if ??cleanframe?? e + ife cc ;;if C calling convention + ret ;; return ;@ + else ;;else + ret o ;; return and remove paramteres ;@ + endif + endif + endif + endif + if ?cbe ne 4 ;;Don't delete macro if ??cleanframe?? e + n endp ;;end of process + .cref + purge cEnd ;;remove the macro + else + .cref + endif + &endm + .cref +endm + + +;; cleanframe +;; +;; cleanframe removes a cMacros generated frame, invoking cEnd +;; with a special keyword which will keep the cEnd macro from +;; generating a return statement and purging itself. + +.xcref +.xcref cleanframe +cleanframe macro + cEnd +endm +.cref + + + +;; The following macros are used to speed up the processing of the +;; command allowed on a cProc command line. They simply set or clear +;; the correct flag as needed. + +.xcref +.xcref ??_cproc_FAR,??_cproc_NEAR,??_cproc_PUBLIC,??_cproc_SMALL +.xcref ??_cproc_DATA,??_cproc_NODATA,??_cproc_ATOMIC,??_cproc_C +.xcref ??_cproc_PLM,??_cproc_PASCAL,??_cproc_WIN,??_cproc_NONWIN +.xcref ??_cproc_NO_BP,??_cproc_BP + +.xcref ??_cproc_far,??_cproc_near,??_cproc_public,??_cproc_small +.xcref ??_cproc_data,??_cproc_nodata,??_cproc_atomic,??_cproc_c +.xcref ??_cproc_plm,??_cproc_pascal,??_cproc_win,??_cproc_nonwin +.xcref ??_cproc_no_bp,??_cproc_bp +.cref + +??_cproc_FAR macro + ?pc=1 +endm + +??_cproc_NEAR macro + ?pc=0 +endm + +??_cproc_PUBLIC macro + ?pu=1 +endm + +??_cproc_SMALL macro + ?uf=1 +endm + +??_cproc_DATA macro + ?nd=0 +endm + +??_cproc_NODATA macro + ?nd=1 +endm + +??_cproc_ATOMIC macro + ?nx=1 +endm + +??_cproc_C macro + ?pcc=0 +endm + +??_cproc_PLM macro + ?pcc=1 +endm + +??_cproc_PASCAL macro + ?pcc=1 +endm + +??_cproc_WIN macro + ?wfp=1 +endm + +??_cproc_NONWIN macro + ?wfp=0 +endm + +??_cproc_NO_BP macro + ?no_bp2=1 +endm + +??_cproc_BP macro + ?no_bp2=0 +endm + +??_cproc_far macro + ?pc=1 +endm + +??_cproc_near macro + ?pc=0 +endm + +??_cproc_public macro + ?pu=1 +endm + +??_cproc_small macro + ?uf=1 +endm + +??_cproc_data macro + ?nd=0 +endm + +??_cproc_nodata macro + ?nd=1 +endm + +??_cproc_atomic macro + ?nx=1 +endm + +??_cproc_c macro + ?pcc=0 +endm + +??_cproc_plm macro + ?pcc=1 +endm + +??_cproc_pascal macro + ?pcc=1 +endm + +??_cproc_win macro + ?wfp=1 +endm + +??_cproc_nonwin macro + ?wfp=0 +endm + +??_cproc_no_bp macro + ?no_bp2=1 +endm + +??_cproc_bp macro + ?no_bp2=0 +endm + + +; ?pcbe is the macro which processes the text on cBegin/cEnd +; The text is allowed to be: +; +; NOGEN nogen +; PARTIAL partial +; the procedure name as given on the cProc line +; +; usage: +; ?pcbe ,, +; where: +; g is the text on the cBegin/cEnd line +; nnu is the procedure name without any underscores +; mt macro type (cBegin/cEnd) +; +; The variable ?cbe is set to the following value +; +; 0 = invalid (defualt action> +; 1 = nogen +; 2 = partial frame +; 4 = clean frame + + +?pcbe macro g,nnu,mt + ifidn , + ?cbe = 1 + else + ifidn , + ?cbe = 1 + else + ifidn , + ifidn , + ?cbe = 2 + else + ifidn , + ?cbe = 2 + else + ifdif , + ??error2 + endif + endif + endif + else + ifidn , + ?cbe = 4 + else + ifdif , + ??error2 + endif + endif + endif + endif + endif +endm + + + +; assumes is a macro that will set up the assumes for a segment +; or group created with the createSeg macro. If the assumed +; value passed in isn't known, then a normal assume is made. +; +; usage: +; assumes s,g +; +; where: +; s is the register to make the assumption about +; g is the value to assume is in it +; +; as a hack, substitute FLAT for g if memF32 is set + + +assumes macro s,ln + if memF32 + assume s:FLAT + endif + ife memF32 + ifndef ln&_assumes + assume s:ln + else + ln&_assumes s + endif + endif +endm + + + +; createSeg is a macro that sets up a segment definition and +; a logical name for that segment. The logical name can be +; used to enter the segment, but it cannot be used for anything +; else. +; +; usage: +; createSeg n,ln,a,co,cl,grp +; where: +; n is the physical name of the segment +; ln is the name it is to be invoked by +; a is the alignment, and is optional +; co is the combine type, and is optional +; cl is the class, and is optional +; grp is the name of the group that contains this segment + + +createSeg macro n,ln,a,co,cl,grp + ifnb + n segment a co '&cl' + else + n segment a co + endif + n ends + ifnb + addseg grp,n + else + ln&OFFSET equ offset n: + ln&BASE equ n + ?cs3 , + endif + ?cs1 , +endm + + +addseg macro grp,seg + .xcref + .xcref grp&_def + .cref + ifndef grp&_def + grp&_def=0 + endif + if grp&_def ne ASMpass + .xcref + .xcref grp&_add + .cref + grp&_add ¯o s + grp&_in ,s + &endm + .xcref + .xcref grp&_in + .cref + grp&_in ¯o sl,s + ifb + grp group sl + else + grp&_add ¯o ns + grp&_in ,ns + &endm + endif + &endm + grp&_def=ASMpass + else + grp&_add seg + endif +endm + + +defgrp macro grp,ln + addseg grp + ifnb + irp x, + ?cs3 <&x>, + x&&OFFSET equ offset grp: + x&&BASE equ grp + endm + endif +endm + + +?cs1 macro ln,n + .xcref + .xcref ln&_sbegin + .cref + ln&_sbegin ¯o + .xcref + .xcref ?mf + .cref + ?mf &¯o c,l,p ;;when sBegin is invoked, generate + if c ;; the makeframe macro + extrn n&_FARFRAME:near ;; make frame for far procedures ;@ + call n&_FARFRAME ;@ + else + extrn n&_NEARFRAME:near ;; make frame for near procedures ;@ + call n&_NEARFRAME ;@ + endif + db l shr 1 ;;define number of locals ;@ + db p shr 1 ;;define number of parameters ;@ + &&endm + ?cs2 , + n segment + &endm +endm + + +?cs2 macro ln,n + .xcref + .xcref sEnd + .cref + sEnd ¯o + n ends + purge ?mf ;;delete the makeframe macro + purge sEnd + &endm +endm + + +?cs3 macro ln,n + .xcref + .xcref ln&_assumes + .cref + ln&_assumes ¯o s + assume s:&n + &endm +endm + + + +; sBegin is the macro that opens up the definition of a segment. +; The segment must have already been defined with the createSeg +; macro. +; +; usage: +; sBegin ln +; +; where: +; ln is the logical name given to the segment when +; it was declared. + +.xcref +.xcref sBegin +.cref +sBegin macro ln + ln&_sbegin +endm + +BeginDATA macro + ife memF32 + sBegin DATA + else + .data + endif +endm + +BeginCODE macro + ife memF32 + sBegin CODE + else + .code + endif +endm + +EndDATA macro + ife memF32 + sEnd DATA + endif +endm + +EndCODE macro + ife memF32 + sEnd CODE + endif +endm + +ife ?DF + + ; Define all segments that will be used. This will allow the + ; assume and groups to be set up at one given place, and also + ; allow quick changes to be made + ; + ; createSeg name,logname,align,combine,class,group + +ife ?DFCODE + createSeg _TEXT,CODE,%wordI,public,CODE +endif + ife ?nodata1 + createSeg _DATA,DATA,%wordI,public,DATA,DGROUP + defgrp DGROUP,DATA + else + ife ?DFDATA + createSeg _DATA,DATA,%wordI,public,DATA,DGROUP + defgrp DGROUP,DATA + endif + endif + + if ?chkstk1 + ifndef ?CHKSTKPROC + externp + endif + endif +endif + + +; errnz exp - generate error message if expression isn't zero +; +; The errnz will generate an error message if the expression "exp" +; does not evaluate to zero. This macro is very useful for testing +; relationships between items, labels, and data that was coded into +; an application. +; +; errnz ;error if not at "label" +; errnz ;eofflag must be bit 0 +; +; For expressions involving more than one token, the angle brackets +; must be used. +; +; The macro is only evaluated on pass 2, so forward references may be +; used in the expression. + +errnz macro x ;;display error if expression is <>0 + if2 + if x ;;if expression is non-zero, + errnz1 ,%(x) + endif + endif +endm + +errnz1 macro x1,x2 + = *errnz* x1 = x2 + .err +endm + + + +; errn$ label,exp - generate error message if label (exp) <> $ +; +; The errnz will generate an error message if the label and "exp" +; does not evaluate to the current value of the location counter. +; This macro is very useful for testing relationships between +; labels and the location counter that was coded into an application. +; +; examples: errn$ label ;error if not at "label" +; errn$ label,+3 ;error if not three bytes from "label" +; errn$ label,-3 ;error if not three bytes past "label" +; +; If no "exp" is given, it is the same as specifying 0 +; +; The macro is only evaluated on pass 2, so forward references may be +; used in the expression. + +errn$ macro l,x ;;error if <$-label1 (exp2)> <>0 + errnz +endm + + + +;; If profile has been specified, declare the profile routines +;; to be external and far. It would be best if this could be done +;; when the call is actually made, but then the fix-up would be +;; generated as segment-relative. + + +ifdef ?PROFILE + externFP +endif + +if memF32 + .model small +endif + diff --git a/private/crt32/h/cmsgs.h b/private/crt32/h/cmsgs.h new file mode 100644 index 000000000..7aa737e3b --- /dev/null +++ b/private/crt32/h/cmsgs.h @@ -0,0 +1,71 @@ +/*** +*cmsgs.h - runtime errors +* +* Copyright (c) 1990-1993, Microsoft Corporation. All rights reserved. +* +*Purpose: +* The file defines, in one place, all error message strings used within +* the C run-time library. +* +*Revision History: +* 06-04-90 GJF Module created. +* 08-08-90 GJF Added _RT_CONIO_TXT +* 10-11-90 GJF Added _RT_ABORT_TXT, _RT_FLOAT_TXT, _RT_HEAP_TXT. +* 09-08-91 GJF Added _RT_ONEXIT_TXT for Win32 (_WIN32_). +* 09-18-91 GJF Fixed _RT_NONCONT_TXT and _RT_INVALDISP_TXT to +* avoid conflict with RTE messages in 16-bit Windows +* libs. Also, added math error messages. +* 10-23-92 GJF Added _RT_PUREVIRT_TXT. +* 02-23-93 SKS Update copyright to 1993 +* +****/ + +/* + * runtime error and termination messages + */ + +#define _RT_STACK_TXT "R6000\r\n- stack overflow\r\n" + +#define _RT_FLOAT_TXT "R6002\r\n- floating point not loaded\r\n" + +#define _RT_INTDIV_TXT "R6003\r\n- integer divide by 0\r\n" + +#define _RT_SPACEARG_TXT "R6008\r\n- not enough space for arguments\r\n" + +#define _RT_SPACEENV_TXT "R6009\r\n- not enough space for environment\r\n" + +#define _RT_ABORT_TXT "\r\nabnormal program termination\r\n" + +#define _RT_THREAD_TXT "R6016\r\n- not enough space for thread data\r\n" + +#define _RT_LOCK_TXT "R6017\r\n- unexpected multithread lock error\r\n" + +#define _RT_HEAP_TXT "R6018\r\n- unexpected heap error\r\n" + +#define _RT_OPENCON_TXT "R6019\r\n- unable to open console device\r\n" + +#define _RT_NONCONT_TXT "R6022\r\n- non-continuable exception\r\n" + +#define _RT_INVALDISP_TXT "R6023\r\n- invalid exception disposition\r\n" + +/* + * _RT_ONEXIT_TXT is specific to Win32 and Dosx32 platforms + */ +#define _RT_ONEXIT_TXT "R6024\r\n- not enough space for _onexit/atexit table" + +#define _RT_PUREVIRT_TXT "R6025\r\n- pure virtual function call\r\n" + +/* + * _RT_DOMAIN_TXT, _RT_SING_TXT and _RT_TLOSS_TXT are used by the floating + * point library. + */ +#define _RT_DOMAIN_TXT "DOMAIN error\r\n" + +#define _RT_SING_TXT "SING error\r\n" + +#define _RT_TLOSS_TXT "TLOSS error\r\n" + + +#define _RT_CRNL_TXT "\r\n" + +#define _RT_BANNER_TXT "runtime error " diff --git a/private/crt32/h/conio.h b/private/crt32/h/conio.h new file mode 100644 index 000000000..8baadaab5 --- /dev/null +++ b/private/crt32/h/conio.h @@ -0,0 +1,127 @@ +/*** +*conio.h - console and port I/O declarations +* +* Copyright (c) 1985-1993, Microsoft Corporation. All rights reserved. +* +*Purpose: +* This include file contains the function declarations for +* the MS C V2.03 compatible console I/O routines. +* +*Revision History: +* 07-27-87 SKS Added inpw(), outpw() +* 08-05-87 SKS Change outpw() from "int" return to "unsigned" +* 11-16-87 JCR Multi-thread support +* 12-11-87 JCR Added "_loadds" functionality +* 12-17-87 JCR Added _MTHREAD_ONLY +* 12-18-87 JCR Added _FAR_ to declarations +* 02-10-88 JCR Cleaned up white space +* 08-19-88 GJF Modified to also work for the 386 (small model only) +* 05-03-89 JCR Added _INTERNAL_IFSTRIP for relinc usage +* 07-27-89 GJF Cleanup, now specific to the 386 +* 10-30-89 GJF Fixed copyright +* 11-02-89 JCR Changed "DLL" to "_DLL" +* 11-17-89 GJF Added const to appropriate arg types of cprintf(), +* cputs() and cscanf(). +* 02-27-90 GJF Added #ifndef _INC_CONIO and #include +* stuff. Also, removed some (now) useless preprocessor +* directives. +* 03-21-90 GJF Replaced _cdecl with _CALLTYPE1 or _CALLTYPE2 in +* prototypes. +* 07-23-90 SBM Added _getch_lk() prototype/macro +* 01-16-91 GJF ANSI support. Also, removed prototypes for port i/o +* functions (not supported in 32-bit). +* 08-20-91 JCR C++ and ANSI naming +* 09-28-91 JCR ANSI names: DOSX32=prototypes, WIN32=#defines for now +* 08-26-92 GJF Function calling type and variable type macros. +* 01-21-93 GJF Removed support for C6-386's _cdecl. +* +****/ + +#ifndef _INC_CONIO + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _INTERNAL_IFSTRIP_ +#include +#endif /* _INTERNAL_IFSTRIP_ */ + +/* + * Conditional macro definition for function calling type and variable type + * qualifiers. + */ +#if ( (_MSC_VER >= 800) && (_M_IX86 >= 300) ) + +/* + * Definitions for MS C8-32 (386/486) compiler + */ +#define _CRTAPI1 __cdecl +#define _CRTAPI2 __cdecl + +#else + +/* + * Other compilers (e.g., MIPS) + */ +#define _CRTAPI1 +#define _CRTAPI2 + +#endif + + +/* function prototypes */ + +char * _CRTAPI1 _cgets(char *); +int _CRTAPI2 _cprintf(const char *, ...); +int _CRTAPI1 _cputs(const char *); +int _CRTAPI2 _cscanf(const char *, ...); +int _CRTAPI1 _getch(void); +int _CRTAPI1 _getche(void); +int _CRTAPI1 _kbhit(void); +int _CRTAPI1 _putch(int); +int _CRTAPI1 _ungetch(int); + +#ifdef MTHREAD /* _MTHREAD_ONLY */ +int _CRTAPI1 _getch_lk(void); /* _MTHREAD_ONLY */ +int _CRTAPI1 _getche_lk(void); /* _MTHREAD_ONLY */ +int _CRTAPI1 _putch_lk(int); /* _MTHREAD_ONLY */ +int _CRTAPI1 _ungetch_lk(int); /* _MTHREAD_ONLY */ +#else /* _MTHREAD_ONLY */ +#define _getch_lk() _getch() /* _MTHREAD_ONLY */ +#define _getche_lk() _getche() /* _MTHREAD_ONLY */ +#define _putch_lk(c) _putch(c) /* _MTHREAD_ONLY */ +#define _ungetch_lk(c) _ungetch(c) /* _MTHREAD_ONLY */ +#endif /* _MTHREAD_ONLY */ + +#if !__STDC__ +/* Non-ANSI names for compatibility */ +#ifndef _DOSX32_ +#define cgets _cgets +#define cprintf _cprintf +#define cputs _cputs +#define cscanf _cscanf +#define getch _getch +#define getche _getche +#define kbhit _kbhit +#define putch _putch +#define ungetch _ungetch +#else +char * _CRTAPI1 cgets(char *); +int _CRTAPI2 cprintf(const char *, ...); +int _CRTAPI1 cputs(const char *); +int _CRTAPI2 cscanf(const char *, ...); +int _CRTAPI1 getch(void); +int _CRTAPI1 getche(void); +int _CRTAPI1 kbhit(void); +int _CRTAPI1 putch(int); +int _CRTAPI1 ungetch(int); +#endif +#endif /* __STDC__ */ + +#ifdef __cplusplus +} +#endif + +#define _INC_CONIO +#endif /* _INC_CONIO */ diff --git a/private/crt32/h/cruntime.h b/private/crt32/h/cruntime.h new file mode 100644 index 000000000..de8549076 --- /dev/null +++ b/private/crt32/h/cruntime.h @@ -0,0 +1,277 @@ +/*** +*cruntime.h - definitions specific to the target operating system and +* hardware +* +* Copyright (c) 1990-1993, Microsoft Corporation. All rights reserved. +* +*Purpose: +* This header file contains widely used definitions specific to the +* host operating system and hardware. It is included by every C source +* and most every other header file. +* [Internal] +* +*Revision History: +* 02-27-90 GJF File created +* 03-06-90 GJF Added register macros (REG1,...,etc.) +* 04-11-90 GJF Set _CALLTYPE1 and _CALLTYPE4 to _stdcall. +* 10-30-90 GJF Added macros defining variable args interface. +* 10-31-90 GJF Added definition of _JBLEN (from setjmp.h). +* 11-13-90 GJF Revised #ifdef-s, now use symbolic constants +* representing target OS and target processor, with +* #error directives for unsupported targets. Note the +* general grouping of only OS-dependent definitions +* followed by OS and processor dependent definitions. +* 02-25-91 SRW Move _JBLEN definition back to setjmp.h [_WIN32_] +* 04-09-91 PNT Added _MAC_ definitions +* 05-09-91 GJF Restored _JBLEN definitions. Also fixed the macros +* defining the target processor so both Stevewo's stuff +* and mine would work. +* 05-13-91 GJF Changed _CALLTYPE1 and _CALLTYPE4 to _cdecl for +* Cruiser (_CRUISER_). +* 08-28-91 JCR ANSI keywords +* 11-01-91 GDP _JBLEN back to setjmp.h, stdarg macros back to stdarg.h +* 03-30-92 DJM POSIX support. +* 08-07-92 GJF Revised various macros. +* 09-08-92 GJF Restored definition of _MIPS_ (temporarily). +* 11-09-92 GJF Revised preprocessing conditionals for MIPS. +* 01-09-93 SRW Remove usage of MIPS and ALPHA to conform to ANSI +* Use _MIPS_ and _ALPHA_ instead. +* 02-01-93 GJF Removed support for C6-386. +* +****/ + +#ifndef _INC_CRUNTIME + +/* + * Some CRT sources have code conditioned on _MIPS_. Continue to define + * _MIPS_ when MIPS is defined until these sources are fixed. + */ +#if defined(MIPS) && !defined(_MIPS_) +#define _MIPS_ +#endif + +#if defined(_M_MRX000) || defined(_M_ALPHA) || defined(_M_PPC) +#define UNALIGNED __unaligned +#else +#define UNALIGNED +#endif + +/* + * Conditional macro definition for function calling type and variable type + * qualifiers. + */ +#if ( (_MSC_VER >= 800) && (_M_IX86 >= 300) ) + +/* + * Definitions for MS C8-32 (386/486) compiler + */ +#define _CRTAPI1 __cdecl /* User-visible CRT function */ +#define _CRTAPI2 __cdecl /* User-visible CRT function */ +#define _CRTAPI3 __cdecl /* Internal CRT function */ +#define _CRTVAR1 /* C global variable */ + +#else + +/* + * Other compilers (e.g., MIPS) + */ +#define _CRTAPI1 +#define _CRTAPI2 +#define _CRTAPI3 +#define _CRTVAR1 + +#endif + +/* + * Old function calling type and variable type qualifier macros + */ +#define _CALLTYPE1 _CRTAPI1 +#define _CALLTYPE2 _CRTAPI2 +#define _CALLTYPE4 _CRTAPI3 +#define _VARTYPE1 _CRTVAR1 + + +#ifdef _CRUISER_ + +/* + * DEFINITIONS FOR CRUISER (AKA OS/2 2.0). + */ + +#define _CALLTYPE3 __syscall /* OS API functions */ + + +/* + * Macros for register variable declarations + */ + +#define REG1 register +#define REG2 register +#define REG3 register +#define REG4 +#define REG5 +#define REG6 +#define REG7 +#define REG8 +#define REG9 + +/* + * Macros for varargs support + */ + +#define _VA_LIST_T char * + +#else /* ndef _CRUISER_ */ + +#ifdef _WIN32_ + +/* + * DEFINITIONS FOR WIN32 + */ + +#ifdef _ALPHA_ +#define _VA_LIST_T \ + struct { \ + char *a0; /* pointer to first homed integer argument */ \ + int offset; /* byte offset of next parameter */ \ + } +#else +#define _VA_LIST_T char * +#endif + +#if defined(_M_IX86) +/* + * 386/486 + */ +#define REG1 register +#define REG2 register +#define REG3 register +#define REG4 +#define REG5 +#define REG6 +#define REG7 +#define REG8 +#define REG9 + +#elif defined(_M_MRX000) || defined(_M_ALPHA) || defined(_M_PPC) +/* + * MIPS or ALPHA + */ +#define REG1 register +#define REG2 register +#define REG3 register +#define REG4 register +#define REG5 register +#define REG6 register +#define REG7 register +#define REG8 register +#define REG9 register + +#else + +#error ERROR - SUPPORT FOR WIN32 NT-X86, NT-MIPS, NT-ALPHA, AND NT-PPC ONLY + +#endif + +#else /* ndef _WIN32_ */ + +#ifdef _POSIX_ +/* + * DEFINITIONS FOR POSIX + */ + + +#ifdef _ALPHA_ + +#define _VA_LIST_T \ + struct { \ + char *a0; /* pointer to first homed integer argument */ \ + int offset; /* byte offset of next parameter */ \ + } +#else + +#define _VA_LIST_T char * + +#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) ) + +#define _VA_START(ap,v) ap = (va_list)&v + _INTSIZEOF(v) +#define _VA_ARG(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) +#define _VA_END(ap) ap = (va_list)0 + +#endif + +#if defined(_M_IX86) +/* + * 386/486 + */ +#define REG1 register +#define REG2 register +#define REG3 register +#define REG4 +#define REG5 +#define REG6 +#define REG7 +#define REG8 +#define REG9 + +#elif defined(_M_MRX000) || defined(_M_ALPHA) || defined(_M_PPC) +/* + * MIPS/Alpha/PPC + */ +#define REG1 register +#define REG2 register +#define REG3 register +#define REG4 register +#define REG5 register +#define REG6 register +#define REG7 register +#define REG8 register +#define REG9 register + +#else + +#error ERROR - SUPPORT FOR POSIX NT-X86, NT-MIPS, NT-ALPHA, AND NT_PPC ONLY + +#endif + +#else /* ndef _POSIX_ */ + +#ifdef _MAC_ + +/* + * DEFINITIONS FOR MAC. + */ + +/* + * Macros for register variable declarations + */ + +#define REG1 +#define REG2 +#define REG3 +#define REG4 +#define REG5 +#define REG6 +#define REG7 +#define REG8 +#define REG9 + +/* + * Macros for varargs support + */ + +#define _VA_LIST_T char * + +#else /* ndef _MAC_ */ + +#error ERROR - ONLY CRUISER, WIN32, OR MAC TARGET SUPPORTED! + +#endif /* _MAC_ */ + +#endif /* _WIN32_ */ + +#endif /* _POSIX_ */ + +#endif /* _CRUISER_ */ + +#define _INC_CRUNTIME +#endif /* _INC_CRUNTIME */ diff --git a/private/crt32/h/cruntime.inc b/private/crt32/h/cruntime.inc new file mode 100644 index 000000000..bbd96710b --- /dev/null +++ b/private/crt32/h/cruntime.inc @@ -0,0 +1,826 @@ +;*** +;cruntime.inc - multi-model assembly macros for interfacing to HLLs +; +; Copyright (c) 1988-1992, Microsoft Corporation. All rights reserved. +; +;Purpose: +; This file defines the current memory model being used. +; +;Revision History: +; 08-04-88 SJM Initial version to handle all four memory models +; in 16-bit mode and small model in 32-bit mode +; 08-08-88 JCR Added CPDIST, ?WIN, PCS, ISHIFT/LSHIFT, OS2, +; DNPTR/DFPTR, DFLOAT/DDOUBLE/DLDOUBLE +; 08-16-88 PHG Added FPES, LFPES, CBI, ZXAL, ZXBL, ZXCL, ZXDL +; 08-17-88 JCR Added CAXDX, modified FPSIZE +; 08-20-88 PHG Added diagnostic messages, removed 386 16-bit support +; and 386 large code/data support, added mucho comments, +; PSS now defined as es: only if SS_NEQ_GROUP defined +; 08-24-88 JCR Added RBXSAVE and RBXONLY for use in 'proc uses' +; 08-25-88 JCR Added savereg macro, removed rbxsave/rbxonly... +; 08-26-88 GJF Added codeseg (text) macro +; 09-15-88 JCR Corrected savelist/reglist macro to go with new MASM +; 09-21-88 WAJ Added JS*, static*, global*, and label*, and lab macros +; 09-22-88 JCR Change 'plm' to 'pascal' in label macro +; 09-26-88 WAJ Added PUSH16 which will do a 16 bit push in a USE32 seg. +; 09-28-88 WAJ Added CPWORD and DPWORD +; 09-29-88 WAJ Added JMPFAR16 macro +; 10-12-88 JCR Made PCS evaluate to 'cs:' for 16/32 stub testbed +; 04-24-89 JCR Added 'assume seg:flat' for 386 to avoid masm/link bug +; 05-25-89 GJF Added APIEXT, a macro that expands to the proper extrn +; declaration for an API function +; 06-13-89 JCR Added 'flat:' to DCPTR and DDPTR +; 09-15-89 JCR Added DCPTR? and DDPTR?, always use "FLAT" not "flat" +; 10-27-92 SKS Miscellaneous minor changes for MASM 6.10 compatibility +; +;******************************************************************************* + +;============================================================================== +; +;Use the following defines to control processor/segment model +; +; -DI86 8086/8088 processor +; -DI286 80286 processor +; -DI386 80386 processor with 32-bit code/data segment +; +; -Dmem_S Small memory model (near code, near data) +; -Dmem_M Medium memory model (far code, near data) +; -Dmem_C Compact memory model (near code, fat data) +; -Dmem_L Large memory model (far code, far data) +; +; -DSS_NEQ_DGROUP SS and DS point to different segments +; +; default is -DI86 -Dmem_S +; +;============================================================================== +; +;The following variables are defined by this file: +; cpu 86, 286, or 386 +; sizeC code distance; 1 = far code, 0 = near code +; sizeD data distance; 1 = far data, 0 = near data +; mmodel english name of the memory model, i.e. "Medium" +; ISIZE, LSIZE, NSIZE size of ints, longs, shorts +; FLTSIZE, DBLSIZE, LDBLSIZE size of float, double, long double +; NPSIZE, FPSIZE size of near/far pointers +; CPSIZE, DPSIZE size of code/data pointers +; ISHIFT, LSHIFT bits to shift to convert byte to int/long +; +;The following macros allow easy writing of combined 16/32 bit code: +; +; 16/32 bit registers: +; rax, rbx, rcx, rdx, expand to native registers (rax = eax or ax) +; rsi, rdi, rsp, rbp +; 16/32 bit register instructions: +; JRCXZ jump when rcx is zero +; CBI convert byte to int (al to rax) +; CAXDX convert rax to rax:rdx +; ZXAL, ZXBL, ZXCL, ZXDL zero extend al,bl,cl,dl to rax,rbx,rcx,rdx +; Pointer instructions: +; LPDS, LPES load data pointer with ES or DS +; PDS, PES segment overrides when pointer loaded as above +; PCS, PSS segment override to get at code/stack segment +; LFPDS, LFPES load far pointer with ES or DS +; FPDS, FPES segment overrides when pointer loaded as above +; CPTR data type of code pointer +; CPDIST distance of code (near/far) +; DNPTR, DFPTR define near/far pointer +; DCPTR, DDPTR define code/data pointer +; DCPTR?, DDPTR? define uninitialized code/data pointer +; CPWORD, DPWORD data type of code or data pointer +; Numeric type instructions: +; IWORD, LWORD, SWORD data type of int, long, short +; DINT, DLONG, DSHORT define int, long, short +; DFLOAT, DDOUBLE, DLDOUBLE define float, double, long double +; Offsets: +; codeoffset, dataoffset offsets from code and data segments +; API calls: +; APIDIST distance of API calls (near/far) +; APIEXT ApiName extrn declaration for an API function +; +;The following utility macros are provided: +; codeseg define/declare code segment +; error stop assembly with message +; display display a message, unless QUIET defined +; savelist [ ...] init list of regs to be save by 'proc uses' +; _if cond assemble instruction only if cond is TRUE +; _ife cond assemble instruction only if cond is FALSE +; _ifd symbol assemble instruction only if symbol defined +; _ifnd symbol assemble instruction only if symbol not defined +; +; lab LabelName assembles to "LabelName:" If DEBUG is defined +; LabelName is made public +; +; JS* (ex. JSE,JSZ,JSB ...) assemble to "je short","jz short","jb short" +; +; Cmacro look alikes +; static* Name, InitialValue, Repeat defines a static variable of type * +; global* Name, InitialValue, Repeat defines a global variable of type * +; label* Name, {PUBLIC,PASCAL,C} defines a label of type * +; +; PUSH16 SegmentReg pushes 16 bits in a use32 segment +; JMPFAR16 label will do a far 16:16 jmp from a use32 segment +; +;============================================================================== + +; error - Output message and generate error + +error MACRO msg +if2 ;; only on pass 2 can we generate errors + %out ********************************************************** + %out *** E r r o r -- msg + %out ********************************************************** + .err +endif + ENDM + +; display msg - Output message unless QUIET defined + +display MACRO msg +ifndef QUIET ;; only when quiet flag not set +if1 ;; and on pass 1, then display message + %out msg +endif +endif + ENDM + +; One line conditionals: +; here we create the capability of writing code lines like +; +; _if sizeD as opposed to if sizeD +; push ds +; endif + +_if MACRO cond,text + if cond + text + endif + ENDM + +_ife MACRO cond,text + ife cond + text + endif + ENDM + +_ifd MACRO cond,text + ifdef cond + text + endif + ENDM + +_ifnd MACRO cond,text + ifndef cond + text + endif + ENDM + +; set windows flag to 0 + + ?WIN equ 0 ; disable windows-specific code + +; check for MTHREAD, requires 286 or greater processor + +ifdef MTHREAD +ifndef I386 +ifndef I286 +; MTHREAD implies 286 processor +display +I286 equ <> +endif +endif +endif + +; Process memory-model arguments + +ifdef mem_M + ; Medium model + sizeC equ 1 + sizeD equ 0 + mmodel equ +elseifdef mem_C + ; Compact model + sizeC equ 0 + sizeD equ 1 + mmodel equ +elseifdef mem_L + ; Large model + sizeC equ 1 + sizeD equ 1 + mmodel equ +else + ; Small model - default + sizeC equ 0 + sizeD equ 0 + mmodel equ +endif + +; Process processor arguments + +ifdef I286 + display + cpu equ 286 + .286 +elseifdef I386 + display + cpu equ 386 + OS2 equ <> ; Define "OS2" since 386 can only run on that OS + .386 +else + display + cpu equ 86 + .8086 +endif + +; 386 32-bit checking. Currently we are only expecting small model +; 32 bit segments, so we make a few checks to be sure nothing is +; incorrectly being defined. + +ifdef I386 + if sizeC or sizeD + error + endif + + ifdef _LOAD_DGROUP + error + endif + + ifdef SS_NEQ_DGROUP + error + endif +endif + +; Set memory model + +% display +% .model mmodel, C + +; +; *** Temporary Workaround *** +; Currently, MASM will not recognize the 'FLAT' keyword unless it previously +; appears in an 'assume' statement. Presumably, when the '.model FLAT' feature +; is implemented, this will go away. [Use 'gs:' since we never use that +; segment register. +; + +ifdef I386 + ; ensure that MASM recognizes 'FLAT' + assume gs:FLAT +endif + + +; Define registers: +; Instead of using the "word" registers directly, we will use a set of +; text equates. This will allow you to use the native word size instead of +; hard coded to 16 bit words. We also have some instruction equates for +; instruction with the register type hard coded in. + +ifdef I386 + + rax equ + rbx equ + rcx equ + rdx equ + rdi equ + rsi equ + rbp equ + rsp equ + + JRCXZ equ + CBI equ ; convert byte to int (al to rax) + CAXDX equ ; convert rax to rdx:rax + ZXAL equ ; zero extend al + ZXBL equ ; zero extend bl + ZXCL equ ; zero extend cl + ZXDL equ ; zero extend dl + +else + + rax equ + rbx equ + rcx equ + rdx equ + rdi equ + rsi equ + rbp equ + rsp equ + + JRCXZ equ + CBI equ ; convert byte to int (al to rax) + CAXDX equ ; convert rax to rdx:rax + ZXAL equ ; zero extend al + ZXBL equ ; zero extend bl + ZXCL equ ; zero extend cl + ZXDL equ ; zero extend dl + +endif + +; The following equates deal with the differences in near versus +; far data pointers, and segment overrides. +; +; Use LPES and PES when loading a default size pointer -- it loads +; a 16-bit pointer register in 286 Small/Medium model, +; a 16-bit pointer register and 16-bit segment register in 8086/286 +; Compact/Large model, and a 32-bit pointer register in 386 mode. +; +; Use LFPES and FPES when loading an always far pointer -- it loads a +; 16-bit pointer register and 16-bit segment register in 8086/286, +; all models; a 32-bit pointer register in 386 mode. + +if sizeD + LPES equ + LPDS equ + PDS equ + PES equ +else + LPES equ + LPDS equ + PDS equ <> + PES equ <> +endif + +ifdef I386 + LFPES equ + LFPDS equ + FPES equ <> + FPDS equ <> +else + LFPES equ + LFPDS equ + FPES equ + FPDS equ +endif + +if sizeC or @WordSize eq 2 + PCS equ ; large code model or non-386 +else + IF 1 ;*** TEMP 16/32 TESTBED *** + PCS equ + ELSE + PCS equ <> ; 386 small code model + ENDIF ;*** END TEMP CODE +endif + +ifdef SS_NEQ_DGROUP + PSS equ ; SS != DS +else + PSS equ <> ; SS == DS +endif + +; Define offset macros: +; The 32-bit segments will not have 'groups' + +ifdef I386 + codeoffset equ + dataoffset equ +else + codeoffset equ + dataoffset equ +endif + +; The next set of equates deals with the size of SHORTS, INTS, LONGS, and +; pointers in the 16 and 32 bit versions. + +ifdef I386 ;--- 32 bit segment --- + + ; parameters and locals + IWORD equ + LWORD equ +if @Version LT 600 + SWORD equ +endif + + ; static storage + DINT equ
+ DLONG equ
+ DSHORT equ + + ; sizes for fixing SP, stepping through tables, etc. + ISIZE equ 4 + LSIZE equ 4 + SSIZE equ 2 + NPSIZE equ 4 + FPSIZE equ 4 + + ; bit shift count to convert byte cnt/ptr to int/long cnt/ptr + ISHIFT equ 2 ; byte-to-int shift count + LSHIFT equ 2 ; byte-to-long shift count + + ; sizes dependent upon memory model. dq -vs- df is not yet clear + DNPTR equ
; near pointer + DFPTR equ
; far pointer + + DCPTR equ
; 32 bit offset only + DCPTR? equ
; No seg override for uninitialized values + CPSIZE equ 4 + CPDIST equ ; code pointers are near + CPTR equ + + DDPTR equ
+ DDPTR? equ
+ DPSIZE equ 4 + + CPWORD equ ; code pointers are dwords + DPWORD equ ; data pointers are dwords + + APIDIST equ ; all API calls are NEAR in the 32 bit model + +; macro to declare API functions +EXTAPI macro apiname + extrn pascal apiname:near +endm + +else ;--- 16-bit segment --- + + ; parameters and locals + IWORD equ + LWORD equ +if @Version LT 600 + SWORD equ +endif + + ; static storage + DINT equ + DLONG equ
+ DSHORT equ + + ; sizes for fixing SP, stepping through tables, etc + ISIZE equ 2 + LSIZE equ 4 + SSIZE equ 2 + NPSIZE equ 2 + FPSIZE equ 4 + + ; bit shift count to convert byte cnt/ptr to int/long cnt/ptr + ISHIFT equ 1 ; byte-to-int shift count + LSHIFT equ 2 ; byte-to-long shift count + + ; sizes dependent upon memory model + DNPTR equ ; near pointer + DFPTR equ
; far pointer + + if sizeC + DCPTR equ
; 16 bit segment and 16 bit offset + DCPTR? equ
+ CPSIZE equ 4 + CPDIST equ ; code pointers are far + CPTR equ + CPWORD equ ; code pointers are dwords + else + DCPTR equ ; 16 bit offset only + DCPTR? equ + CPSIZE equ 2 + CPDIST equ ; code pointers are near + CPTR equ + CPWORD equ ; code pointers are words + endif + + if sizeD + DDPTR equ
+ DDPTR? equ
+ DPSIZE equ 4 + DPWORD equ ; data pointers are dwords + else + DDPTR equ + DDPTR? equ + DPSIZE equ 2 + DPWORD equ ; data pointers are words + endif + + APIDIST equ ; API calls are FAR in 16 bit model + +; macro to declare API functions +EXTAPI macro apiname + extrn pascal apiname:far +endm + +endif ; --- 16/32 segment --- + +; Float/double definitions +; (currently the same for 16- and 32-bit segments) + +FLTSIZE equ 4 ; float +DBLSIZE equ 8 ; double +LDBLSIZE equ 10 ; long double + +DFLOAT equ
+DDOUBLE equ +DLDOUBLE equ
+ +; +; savelist - Generate a list of regs to be saved by the proc 'uses' option. +; +; Input: +; reg1, reg2, reg3, reg4 = registers to be saved across function +; Output: +; reglist = text string of registers that can be passed to the 'uses' +; option on the 'proc' command. +; + +savelist MACRO reg1, reg2, reg3, reg4 + local ws, listsize + ws catstr < > ; whitespace char + + IFNDEF I386 + rbx equ <> ; 8086/286 don't save rbx + ENDIF + + IFNB + reglist catstr reg1, ws, reg2, ws, reg3, ws, reg4 + ELSEIFNB + reglist catstr reg1, ws, reg2, ws, reg3, ws + ELSEIFNB + reglist catstr reg1, ws, reg2, ws, ws + ELSEIFNB + reglist catstr reg1, ws, ws, ws + ELSE + reglist catstr <> + ENDIF + + listsize sizestr reglist ; size of register list + + IF listsize LE 3 ; if list is only the 3 ws chars... + reglist catstr <> + ENDIF + + IFNDEF I386 + rbx equ ; restore rbx + ENDIF + + ENDM ; savelist + +; +; codeseg - Define/declare the standard code segment. Maps to the proper +; form of the .code directive. +; +; Input: +; +; Output: +; .code _TEXT ; for large code models +; .code ; for small code models +; assume cs:FLAT ; for 386 +; assume ds:FLAT ; for 386 +; assume es:FLAT ; for 386 +; assume ss:FLAT ; for 386 +; + +codeseg MACRO + +if sizeC + .code _TEXT +else + .code +endif + +ifdef I386 +if @Version LT 600 + assume cs:FLAT +endif ;@Version LT 600 + assume ds:FLAT + assume es:FLAT + assume ss:FLAT +endif + + ENDM + +;*************************************************************** +;* +;* Debug lab macro +;* +;*************************************************************** + +lab macro name +ifdef DEBUG + public pascal name ;; define label public for Symdeb +endif +name: + endm + + +;*************************************************************** +;* +;* Conditional jump short macros +;* +;*************************************************************** + + + irp x, +JS&x equ + endm + + +;*************************************************************** +;* +;* Global data definition macros +;* +;* Usage: +;* globalI Name, InitialValue, Repeat +;* +;*************************************************************** + + +MakeGlobal macro suffix, DataType ;; makes all of the global* macros + +global&suffix macro name, data, rep +public name +ifb + _repeat = 1 +else + _repeat = (rep) +endif + +name &DataType _repeat dup( data ) + endm + + endm + + + MakeGlobal T, dt ; globalT + MakeGlobal Q, dq ; globalQ + MakeGlobal D, dd ; globalD + MakeGlobal W, dw ; globalW + MakeGlobal B, db ; globalB + +% MakeGlobal I, ; globalI + +% MakeGlobal DP, ; globalDP +% MakeGlobal CP, ; globalCP +% MakeGlobal FP, ; globalFP +% MakeGlobal NP, ; globalNP + + + +;*************************************************************** +;* +;* Static data definition macros +;* +;* Usage: +;* staticI Name, InitialValue, Repeat +;* +;*************************************************************** + + +MakeStatic macro suffix, DataType ;; makes all of the static* macros + +static&suffix macro name, data, rep + +ifdef DEBUG + public pascal name ;; make statics public if DEBUG +endif + +ifb + _repeat = 1 +else + _repeat = (rep) +endif + +name &DataType _repeat dup( data ) + endm + + endm + + + MakeStatic T, dt ; staticT + MakeStatic Q, dq ; staticQ + MakeStatic D, dd ; staticD + MakeStatic W, dw ; staticW + MakeStatic B, db ; staticB + +% MakeStatic I, ; staticI + +% MakeStatic DP, ; staticDP +% MakeStatic CP, ; staticCP +% MakeStatic FP, ; staticFP +% MakeStatic NP, ; staticNP + +;*************************************************************** +;* +;* Label definition macros +;* +;*************************************************************** +;* +;* Label definition macros +;* +;* Usage: +;* labelI Name, {PUBLIC, PASCAL, C} +;* +;*************************************************************** + +__MakePublic macro name, option ;; decides if a label should be +ifidni